From edec9d7bdc4eb3845ec7a3f9610f0d54a7152e90 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 14 Mar 2017 10:15:40 +0000 Subject: KVM: MIPS/VZ: Trace guest mode changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a trace event for guest mode changes, and enable VZ's GuestCtl0.MC bit after the trace event is enabled to trap all guest mode changes. The MC bit causes Guest Hardware Field Change (GHFC) exceptions whenever a guest mode change occurs (such as an exception entry or return from exception), so we need to handle this exception now. The MC bit is only enabled when restoring register state, so enabling the trace event won't take immediate effect. Tracing guest mode changes can be particularly handy when trying to work out what a guest OS gets up to before something goes wrong, especially if the problem occurs as a result of some previous guest userland exception which would otherwise be invisible in the trace. Signed-off-by: James Hogan Cc: Paolo Bonzini Cc: "Radim Krčmář" Cc: Steven Rostedt Cc: Ingo Molnar Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org --- arch/mips/kvm/vz.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'arch/mips/kvm/vz.c') diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c index 44dad9ae5d02..33bb8c6e1b05 100644 --- a/arch/mips/kvm/vz.c +++ b/arch/mips/kvm/vz.c @@ -1322,6 +1322,18 @@ static enum emulation_result kvm_trap_vz_handle_gsfc(u32 cause, u32 *opc, return er; } +static enum emulation_result kvm_trap_vz_handle_ghfc(u32 cause, u32 *opc, + struct kvm_vcpu *vcpu) +{ + /* + * Presumably this is due to MC (guest mode change), so lets trace some + * relevant info. + */ + trace_kvm_guest_mode_change(vcpu); + + return EMULATE_DONE; +} + static enum emulation_result kvm_trap_vz_handle_hc(u32 cause, u32 *opc, struct kvm_vcpu *vcpu) { @@ -1407,8 +1419,7 @@ static int kvm_trap_vz_handle_guest_exit(struct kvm_vcpu *vcpu) break; case MIPS_GCTL0_GEXC_GHFC: ++vcpu->stat.vz_ghfc_exits; - er = kvm_trap_vz_no_handler_guest_exit(gexccode, cause, opc, - vcpu); + er = kvm_trap_vz_handle_ghfc(cause, opc, vcpu); break; case MIPS_GCTL0_GEXC_GPA: ++vcpu->stat.vz_gpa_exits; @@ -2459,6 +2470,12 @@ static int kvm_vz_vcpu_load(struct kvm_vcpu *vcpu, int cpu) */ kvm_vz_restore_timer(vcpu); + /* Set MC bit if we want to trace guest mode changes */ + if (kvm_trace_guest_mode_change) + set_c0_guestctl0(MIPS_GCTL0_MC); + else + clear_c0_guestctl0(MIPS_GCTL0_MC); + /* Don't bother restoring registers multiple times unless necessary */ if (!all) return 0; -- cgit v1.2.3-73-gaa49b