blob: 52f40a4c5803bf5980308b18fbfb6459ab42bdec [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 - os kernal
* Author: fire3 <fire3@example.com> yangzh <yangzh@gmail.com>
* linhn <linhn@example.com>
*/
#include <asm/hmcall.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_timer.h>
#include <linux/kvm.h>
int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
int exception_index, struct hcall_args *hargs)
{
gfn_t gfn;
switch (exception_index) {
case SW64_KVM_EXIT_IO:
return io_mem_abort(vcpu, run, hargs);
case SW64_KVM_MIGRATION_SET_DIRTY_HM:
case SW64_KVM_MIGRATION_SET_DIRTY:
gfn = hargs->arg2 >> 24;
mutex_lock(&vcpu->kvm->slots_lock);
kvm_vcpu_mark_page_dirty(vcpu, gfn);
mutex_unlock(&vcpu->kvm->slots_lock);
return 1;
case SW64_KVM_EXIT_HALT:
vcpu->arch.halted = 1;
kvm_vcpu_block(vcpu);
return 1;
case SW64_KVM_EXIT_SHUTDOWN:
vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
vcpu->run->system_event.type = KVM_SYSTEM_EVENT_SHUTDOWN;
return 0;
case SW64_KVM_EXIT_RESTART:
vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
vcpu->run->system_event.type = KVM_SYSTEM_EVENT_RESET;
return 0;
case SW64_KVM_EXIT_TIMER:
set_timer(vcpu, hargs->arg0);
return 1;
case SW64_KVM_EXIT_IPI:
vcpu_send_ipi(vcpu, hargs->arg0);
return 1;
#ifdef CONFIG_KVM_MEMHOTPLUG
case SW64_KVM_EXIT_MEMHOTPLUG:
vcpu_mem_hotplug(vcpu, hargs->arg0);
return 1;
#endif
case SW64_KVM_EXIT_FATAL_ERROR:
printk("Guest fatal error: Reason=[%lx], EXC_PC=[%lx], DVA=[%lx]", hargs->arg0, hargs->arg1, hargs->arg2);
vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
vcpu->run->hw.hardware_exit_reason = hargs->arg0;
return 0;
}
return 1;
}