diff options
author | Avi Kivity <avi@redhat.com> | 2010-01-25 12:47:02 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2010-03-01 10:36:06 -0500 |
commit | 59200273c4d07ddf99dd3c8d91b90bb170457fc3 (patch) | |
tree | bd0ecc72152d19f272248c8186b2f412df56bcf2 /arch/x86/kvm | |
parent | 6e7d15296773f7a479072ec7f3248f51d01e1fad (diff) |
KVM: Trace failed msr reads and writes
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>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/svm.c | 13 | ||||
-rw-r--r-- | arch/x86/kvm/trace.h | 17 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 5 |
3 files changed, 22 insertions, 13 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 9596cc86d6dd..52f78dd03010 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -2177,9 +2177,10 @@ static int rdmsr_interception(struct vcpu_svm *svm) | |||
2177 | u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; | 2177 | u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; |
2178 | u64 data; | 2178 | u64 data; |
2179 | 2179 | ||
2180 | if (svm_get_msr(&svm->vcpu, ecx, &data)) | 2180 | if (svm_get_msr(&svm->vcpu, ecx, &data)) { |
2181 | trace_kvm_msr_read_ex(ecx); | ||
2181 | kvm_inject_gp(&svm->vcpu, 0); | 2182 | kvm_inject_gp(&svm->vcpu, 0); |
2182 | else { | 2183 | } else { |
2183 | trace_kvm_msr_read(ecx, data); | 2184 | trace_kvm_msr_read(ecx, data); |
2184 | 2185 | ||
2185 | svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff; | 2186 | svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff; |
@@ -2271,13 +2272,15 @@ static int wrmsr_interception(struct vcpu_svm *svm) | |||
2271 | u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) | 2272 | u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) |
2272 | | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); | 2273 | | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); |
2273 | 2274 | ||
2274 | trace_kvm_msr_write(ecx, data); | ||
2275 | 2275 | ||
2276 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; | 2276 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; |
2277 | if (svm_set_msr(&svm->vcpu, ecx, data)) | 2277 | if (svm_set_msr(&svm->vcpu, ecx, data)) { |
2278 | trace_kvm_msr_write_ex(ecx, data); | ||
2278 | kvm_inject_gp(&svm->vcpu, 0); | 2279 | kvm_inject_gp(&svm->vcpu, 0); |
2279 | else | 2280 | } else { |
2281 | trace_kvm_msr_write(ecx, data); | ||
2280 | skip_emulated_instruction(&svm->vcpu); | 2282 | skip_emulated_instruction(&svm->vcpu); |
2283 | } | ||
2281 | return 1; | 2284 | return 1; |
2282 | } | 2285 | } |
2283 | 2286 | ||
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 45903a926372..6ad30a29f044 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h | |||
@@ -246,28 +246,33 @@ TRACE_EVENT(kvm_page_fault, | |||
246 | * Tracepoint for guest MSR access. | 246 | * Tracepoint for guest MSR access. |
247 | */ | 247 | */ |
248 | TRACE_EVENT(kvm_msr, | 248 | TRACE_EVENT(kvm_msr, |
249 | TP_PROTO(unsigned write, u32 ecx, u64 data), | 249 | TP_PROTO(unsigned write, u32 ecx, u64 data, bool exception), |
250 | TP_ARGS(write, ecx, data), | 250 | TP_ARGS(write, ecx, data, exception), |
251 | 251 | ||
252 | TP_STRUCT__entry( | 252 | TP_STRUCT__entry( |
253 | __field( unsigned, write ) | 253 | __field( unsigned, write ) |
254 | __field( u32, ecx ) | 254 | __field( u32, ecx ) |
255 | __field( u64, data ) | 255 | __field( u64, data ) |
256 | __field( u8, exception ) | ||
256 | ), | 257 | ), |
257 | 258 | ||
258 | TP_fast_assign( | 259 | TP_fast_assign( |
259 | __entry->write = write; | 260 | __entry->write = write; |
260 | __entry->ecx = ecx; | 261 | __entry->ecx = ecx; |
261 | __entry->data = data; | 262 | __entry->data = data; |
263 | __entry->exception = exception; | ||
262 | ), | 264 | ), |
263 | 265 | ||
264 | TP_printk("msr_%s %x = 0x%llx", | 266 | TP_printk("msr_%s %x = 0x%llx%s", |
265 | __entry->write ? "write" : "read", | 267 | __entry->write ? "write" : "read", |
266 | __entry->ecx, __entry->data) | 268 | __entry->ecx, __entry->data, |
269 | __entry->exception ? " (#GP)" : "") | ||
267 | ); | 270 | ); |
268 | 271 | ||
269 | #define trace_kvm_msr_read(ecx, data) trace_kvm_msr(0, ecx, data) | 272 | #define trace_kvm_msr_read(ecx, data) trace_kvm_msr(0, ecx, data, false) |
270 | #define trace_kvm_msr_write(ecx, data) trace_kvm_msr(1, ecx, data) | 273 | #define trace_kvm_msr_write(ecx, data) trace_kvm_msr(1, ecx, data, false) |
274 | #define trace_kvm_msr_read_ex(ecx) trace_kvm_msr(0, ecx, 0, true) | ||
275 | #define trace_kvm_msr_write_ex(ecx, data) trace_kvm_msr(1, ecx, data, true) | ||
271 | 276 | ||
272 | /* | 277 | /* |
273 | * Tracepoint for guest CR access. | 278 | * Tracepoint for guest CR access. |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 7a56879a058c..334b016267a9 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -3158,6 +3158,7 @@ static int handle_rdmsr(struct kvm_vcpu *vcpu) | |||
3158 | u64 data; | 3158 | u64 data; |
3159 | 3159 | ||
3160 | if (vmx_get_msr(vcpu, ecx, &data)) { | 3160 | if (vmx_get_msr(vcpu, ecx, &data)) { |
3161 | trace_kvm_msr_read_ex(ecx); | ||
3161 | kvm_inject_gp(vcpu, 0); | 3162 | kvm_inject_gp(vcpu, 0); |
3162 | return 1; | 3163 | return 1; |
3163 | } | 3164 | } |
@@ -3177,13 +3178,13 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu) | |||
3177 | u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u) | 3178 | u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u) |
3178 | | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32); | 3179 | | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32); |
3179 | 3180 | ||
3180 | trace_kvm_msr_write(ecx, data); | ||
3181 | |||
3182 | if (vmx_set_msr(vcpu, ecx, data) != 0) { | 3181 | if (vmx_set_msr(vcpu, ecx, data) != 0) { |
3182 | trace_kvm_msr_write_ex(ecx, data); | ||
3183 | kvm_inject_gp(vcpu, 0); | 3183 | kvm_inject_gp(vcpu, 0); |
3184 | return 1; | 3184 | return 1; |
3185 | } | 3185 | } |
3186 | 3186 | ||
3187 | trace_kvm_msr_write(ecx, data); | ||
3187 | skip_emulated_instruction(vcpu); | 3188 | skip_emulated_instruction(vcpu); |
3188 | return 1; | 3189 | return 1; |
3189 | } | 3190 | } |