KVM: MIPS: Add guest exit exception callback
Add a callback for MIPS KVM implementations to handle the VZ guest exit exception. Currently the trap & emulate implementation contains a stub which reports an internal error, but the callback will be used properly by the VZ implementation. Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: "Radim Krčmář" <rkrcmar@redhat.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org
This commit is contained in:
parent
edab4fe1f6
commit
28c1e762b0
@ -542,6 +542,7 @@ struct kvm_mips_callbacks {
|
|||||||
int (*handle_msa_fpe)(struct kvm_vcpu *vcpu);
|
int (*handle_msa_fpe)(struct kvm_vcpu *vcpu);
|
||||||
int (*handle_fpe)(struct kvm_vcpu *vcpu);
|
int (*handle_fpe)(struct kvm_vcpu *vcpu);
|
||||||
int (*handle_msa_disabled)(struct kvm_vcpu *vcpu);
|
int (*handle_msa_disabled)(struct kvm_vcpu *vcpu);
|
||||||
|
int (*handle_guest_exit)(struct kvm_vcpu *vcpu);
|
||||||
int (*hardware_enable)(void);
|
int (*hardware_enable)(void);
|
||||||
void (*hardware_disable)(void);
|
void (*hardware_disable)(void);
|
||||||
int (*check_extension)(struct kvm *kvm, long ext);
|
int (*check_extension)(struct kvm *kvm, long ext);
|
||||||
|
@ -1348,6 +1348,11 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
|
|||||||
ret = kvm_mips_callbacks->handle_msa_disabled(vcpu);
|
ret = kvm_mips_callbacks->handle_msa_disabled(vcpu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EXCCODE_GE:
|
||||||
|
/* defer exit accounting to handler */
|
||||||
|
ret = kvm_mips_callbacks->handle_guest_exit(vcpu);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (cause & CAUSEF_BD)
|
if (cause & CAUSEF_BD)
|
||||||
opc += 1;
|
opc += 1;
|
||||||
|
@ -62,6 +62,7 @@ DEFINE_EVENT(kvm_transition, kvm_out,
|
|||||||
#define KVM_TRACE_EXIT_MSA_FPE 14
|
#define KVM_TRACE_EXIT_MSA_FPE 14
|
||||||
#define KVM_TRACE_EXIT_FPE 15
|
#define KVM_TRACE_EXIT_FPE 15
|
||||||
#define KVM_TRACE_EXIT_MSA_DISABLED 21
|
#define KVM_TRACE_EXIT_MSA_DISABLED 21
|
||||||
|
#define KVM_TRACE_EXIT_GUEST_EXIT 27
|
||||||
/* Further exit reasons */
|
/* Further exit reasons */
|
||||||
#define KVM_TRACE_EXIT_WAIT 32
|
#define KVM_TRACE_EXIT_WAIT 32
|
||||||
#define KVM_TRACE_EXIT_CACHE 33
|
#define KVM_TRACE_EXIT_CACHE 33
|
||||||
@ -92,6 +93,7 @@ DEFINE_EVENT(kvm_transition, kvm_out,
|
|||||||
{ KVM_TRACE_EXIT_MSA_FPE, "MSA FPE" }, \
|
{ KVM_TRACE_EXIT_MSA_FPE, "MSA FPE" }, \
|
||||||
{ KVM_TRACE_EXIT_FPE, "FPE" }, \
|
{ KVM_TRACE_EXIT_FPE, "FPE" }, \
|
||||||
{ KVM_TRACE_EXIT_MSA_DISABLED, "MSA Disabled" }, \
|
{ KVM_TRACE_EXIT_MSA_DISABLED, "MSA Disabled" }, \
|
||||||
|
{ KVM_TRACE_EXIT_GUEST_EXIT, "Guest Exit" }, \
|
||||||
{ KVM_TRACE_EXIT_WAIT, "WAIT" }, \
|
{ KVM_TRACE_EXIT_WAIT, "WAIT" }, \
|
||||||
{ KVM_TRACE_EXIT_CACHE, "CACHE" }, \
|
{ KVM_TRACE_EXIT_CACHE, "CACHE" }, \
|
||||||
{ KVM_TRACE_EXIT_SIGNAL, "Signal" }, \
|
{ KVM_TRACE_EXIT_SIGNAL, "Signal" }, \
|
||||||
|
@ -40,6 +40,29 @@ static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva)
|
|||||||
return gpa;
|
return gpa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int kvm_trap_emul_no_handler(struct kvm_vcpu *vcpu)
|
||||||
|
{
|
||||||
|
u32 __user *opc = (u32 __user *) vcpu->arch.pc;
|
||||||
|
u32 cause = vcpu->arch.host_cp0_cause;
|
||||||
|
u32 exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
|
||||||
|
unsigned long badvaddr = vcpu->arch.host_cp0_badvaddr;
|
||||||
|
u32 inst = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fetch the instruction.
|
||||||
|
*/
|
||||||
|
if (cause & CAUSEF_BD)
|
||||||
|
opc += 1;
|
||||||
|
kvm_get_badinstr(opc, vcpu, &inst);
|
||||||
|
|
||||||
|
kvm_err("Exception Code: %d not handled @ PC: %p, inst: 0x%08x BadVaddr: %#lx Status: %#lx\n",
|
||||||
|
exccode, opc, inst, badvaddr,
|
||||||
|
kvm_read_c0_guest_status(vcpu->arch.cop0));
|
||||||
|
kvm_arch_vcpu_dump_regs(vcpu);
|
||||||
|
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||||
|
return RESUME_HOST;
|
||||||
|
}
|
||||||
|
|
||||||
static int kvm_trap_emul_handle_cop_unusable(struct kvm_vcpu *vcpu)
|
static int kvm_trap_emul_handle_cop_unusable(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct mips_coproc *cop0 = vcpu->arch.cop0;
|
struct mips_coproc *cop0 = vcpu->arch.cop0;
|
||||||
@ -1262,6 +1285,7 @@ static struct kvm_mips_callbacks kvm_trap_emul_callbacks = {
|
|||||||
.handle_msa_fpe = kvm_trap_emul_handle_msa_fpe,
|
.handle_msa_fpe = kvm_trap_emul_handle_msa_fpe,
|
||||||
.handle_fpe = kvm_trap_emul_handle_fpe,
|
.handle_fpe = kvm_trap_emul_handle_fpe,
|
||||||
.handle_msa_disabled = kvm_trap_emul_handle_msa_disabled,
|
.handle_msa_disabled = kvm_trap_emul_handle_msa_disabled,
|
||||||
|
.handle_guest_exit = kvm_trap_emul_no_handler,
|
||||||
|
|
||||||
.hardware_enable = kvm_trap_emul_hardware_enable,
|
.hardware_enable = kvm_trap_emul_hardware_enable,
|
||||||
.hardware_disable = kvm_trap_emul_hardware_disable,
|
.hardware_disable = kvm_trap_emul_hardware_disable,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user