KVM: Trace failed msr reads and writes
Avi Kivity [Mon, 25 Jan 2010 17:47:02 +0000 (19:47 +0200)]
Record failed msrs reads and writes, and the fact that they failed as well.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

arch/x86/kvm/svm.c
arch/x86/kvm/trace.h
arch/x86/kvm/vmx.c

index 9596cc8..52f78dd 100644 (file)
@@ -2177,9 +2177,10 @@ static int rdmsr_interception(struct vcpu_svm *svm)
        u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX];
        u64 data;
 
-       if (svm_get_msr(&svm->vcpu, ecx, &data))
+       if (svm_get_msr(&svm->vcpu, ecx, &data)) {
+               trace_kvm_msr_read_ex(ecx);
                kvm_inject_gp(&svm->vcpu, 0);
-       else {
+       } else {
                trace_kvm_msr_read(ecx, data);
 
                svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff;
@@ -2271,13 +2272,15 @@ static int wrmsr_interception(struct vcpu_svm *svm)
        u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u)
                | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32);
 
-       trace_kvm_msr_write(ecx, data);
 
        svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
-       if (svm_set_msr(&svm->vcpu, ecx, data))
+       if (svm_set_msr(&svm->vcpu, ecx, data)) {
+               trace_kvm_msr_write_ex(ecx, data);
                kvm_inject_gp(&svm->vcpu, 0);
-       else
+       } else {
+               trace_kvm_msr_write(ecx, data);
                skip_emulated_instruction(&svm->vcpu);
+       }
        return 1;
 }
 
index 45903a9..6ad30a2 100644 (file)
@@ -246,28 +246,33 @@ TRACE_EVENT(kvm_page_fault,
  * Tracepoint for guest MSR access.
  */
 TRACE_EVENT(kvm_msr,
-       TP_PROTO(unsigned write, u32 ecx, u64 data),
-       TP_ARGS(write, ecx, data),
+       TP_PROTO(unsigned write, u32 ecx, u64 data, bool exception),
+       TP_ARGS(write, ecx, data, exception),
 
        TP_STRUCT__entry(
                __field(        unsigned,       write           )
                __field(        u32,            ecx             )
                __field(        u64,            data            )
+               __field(        u8,             exception       )
        ),
 
        TP_fast_assign(
                __entry->write          = write;
                __entry->ecx            = ecx;
                __entry->data           = data;
+               __entry->exception      = exception;
        ),
 
-       TP_printk("msr_%s %x = 0x%llx",
+       TP_printk("msr_%s %x = 0x%llx%s",
                  __entry->write ? "write" : "read",
-                 __entry->ecx, __entry->data)
+                 __entry->ecx, __entry->data,
+                 __entry->exception ? " (#GP)" : "")
 );
 
-#define trace_kvm_msr_read(ecx, data)          trace_kvm_msr(0, ecx, data)
-#define trace_kvm_msr_write(ecx, data)         trace_kvm_msr(1, ecx, data)
+#define trace_kvm_msr_read(ecx, data)      trace_kvm_msr(0, ecx, data, false)
+#define trace_kvm_msr_write(ecx, data)     trace_kvm_msr(1, ecx, data, false)
+#define trace_kvm_msr_read_ex(ecx)         trace_kvm_msr(0, ecx, 0, true)
+#define trace_kvm_msr_write_ex(ecx, data)  trace_kvm_msr(1, ecx, data, true)
 
 /*
  * Tracepoint for guest CR access.
index 7a56879..334b016 100644 (file)
@@ -3158,6 +3158,7 @@ static int handle_rdmsr(struct kvm_vcpu *vcpu)
        u64 data;
 
        if (vmx_get_msr(vcpu, ecx, &data)) {
+               trace_kvm_msr_read_ex(ecx);
                kvm_inject_gp(vcpu, 0);
                return 1;
        }
@@ -3177,13 +3178,13 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu)
        u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u)
                | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32);
 
-       trace_kvm_msr_write(ecx, data);
-
        if (vmx_set_msr(vcpu, ecx, data) != 0) {
+               trace_kvm_msr_write_ex(ecx, data);
                kvm_inject_gp(vcpu, 0);
                return 1;
        }
 
+       trace_kvm_msr_write(ecx, data);
        skip_emulated_instruction(vcpu);
        return 1;
 }