Commit 28c1e762 authored by James Hogan's avatar James Hogan
Browse files

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: default avatarJames 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
parent edab4fe1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+5 −0
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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" },		\
+24 −0
Original line number Diff line number Diff line
@@ -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,