KVM: MIPS: Add guest exit exception callback
authorJames Hogan <james.hogan@imgtec.com>
Tue, 14 Mar 2017 10:15:24 +0000 (10:15 +0000)
committerJames Hogan <james.hogan@imgtec.com>
Tue, 28 Mar 2017 13:53:49 +0000 (14:53 +0100)
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
arch/mips/include/asm/kvm_host.h
arch/mips/kvm/mips.c
arch/mips/kvm/trace.h
arch/mips/kvm/trap_emul.c

index acfe7e4e8a3c365e5bea66d10a7e4ff1124202ab..32229a1a4a795341415e7e4195b2122fc1654378 100644 (file)
@@ -542,6 +542,7 @@ struct kvm_mips_callbacks {
        int (*handle_msa_fpe)(struct kvm_vcpu *vcpu);
        int (*handle_fpe)(struct kvm_vcpu *vcpu);
        int (*handle_msa_disabled)(struct kvm_vcpu *vcpu);
+       int (*handle_guest_exit)(struct kvm_vcpu *vcpu);
        int (*hardware_enable)(void);
        void (*hardware_disable)(void);
        int (*check_extension)(struct kvm *kvm, long ext);
index 5681117083af55bb58fff716b362242218ef8731..6e91c24162788e0875cc18947b101be59a412c35 100644 (file)
@@ -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);
                break;
 
+       case EXCCODE_GE:
+               /* defer exit accounting to handler */
+               ret = kvm_mips_callbacks->handle_guest_exit(vcpu);
+               break;
+
        default:
                if (cause & CAUSEF_BD)
                        opc += 1;
index 6e43c89114b831ecfa6adbc63934a80da78196b3..0c59282a2f7d4bf9300f4754503226fe1f2bc5b9 100644 (file)
@@ -62,6 +62,7 @@ DEFINE_EVENT(kvm_transition, kvm_out,
 #define KVM_TRACE_EXIT_MSA_FPE         14
 #define KVM_TRACE_EXIT_FPE             15
 #define KVM_TRACE_EXIT_MSA_DISABLED    21
+#define KVM_TRACE_EXIT_GUEST_EXIT      27
 /* Further exit reasons */
 #define KVM_TRACE_EXIT_WAIT            32
 #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_FPE,           "FPE" },                \
        { KVM_TRACE_EXIT_MSA_DISABLED,  "MSA Disabled" },       \
+       { KVM_TRACE_EXIT_GUEST_EXIT,    "Guest Exit" },         \
        { KVM_TRACE_EXIT_WAIT,          "WAIT" },               \
        { KVM_TRACE_EXIT_CACHE,         "CACHE" },              \
        { KVM_TRACE_EXIT_SIGNAL,        "Signal" },             \
index 50b812bfe083214f1ac2c67b316f808c61668657..fda45b4bdebcb62b62f69638863c01340c9ecd68 100644 (file)
@@ -40,6 +40,29 @@ static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva)
        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)
 {
        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_fpe = kvm_trap_emul_handle_fpe,
        .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_disable = kvm_trap_emul_hardware_disable,