diff options
author | Avi Kivity <avi@qumranet.com> | 2007-09-12 06:21:09 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-10-13 04:18:28 -0400 |
commit | 054b1369679fb97582fc77f25a700d4290ff3e89 (patch) | |
tree | fc06afd41830c263f6c068d1bd743ef7fcf9637d | |
parent | fd2a76086527cbe074b08a8820253228cd919ece (diff) |
KVM: Improve emulation failure reporting
Report failed opcodes from all locations.
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r-- | drivers/kvm/kvm.h | 1 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 16 | ||||
-rw-r--r-- | drivers/kvm/svm.c | 2 | ||||
-rw-r--r-- | drivers/kvm/vmx.c | 2 |
4 files changed, 11 insertions, 10 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index d93ab48424c6..ad0813843adc 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h | |||
@@ -558,6 +558,7 @@ enum emulation_result { | |||
558 | 558 | ||
559 | int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run, | 559 | int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run, |
560 | unsigned long cr2, u16 error_code); | 560 | unsigned long cr2, u16 error_code); |
561 | void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context); | ||
561 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); | 562 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); |
562 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); | 563 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); |
563 | void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, | 564 | void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, |
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index e17b433152cb..3b046507ebc6 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -1240,25 +1240,25 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) | |||
1240 | return X86EMUL_CONTINUE; | 1240 | return X86EMUL_CONTINUE; |
1241 | } | 1241 | } |
1242 | 1242 | ||
1243 | static void report_emulation_failure(struct x86_emulate_ctxt *ctxt) | 1243 | void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) |
1244 | { | 1244 | { |
1245 | static int reported; | 1245 | static int reported; |
1246 | u8 opcodes[4]; | 1246 | u8 opcodes[4]; |
1247 | unsigned long rip = ctxt->vcpu->rip; | 1247 | unsigned long rip = vcpu->rip; |
1248 | unsigned long rip_linear; | 1248 | unsigned long rip_linear; |
1249 | 1249 | ||
1250 | rip_linear = rip + get_segment_base(ctxt->vcpu, VCPU_SREG_CS); | 1250 | rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS); |
1251 | 1251 | ||
1252 | if (reported) | 1252 | if (reported) |
1253 | return; | 1253 | return; |
1254 | 1254 | ||
1255 | emulator_read_std(rip_linear, (void *)opcodes, 4, ctxt->vcpu); | 1255 | emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu); |
1256 | 1256 | ||
1257 | printk(KERN_ERR "emulation failed but !mmio_needed?" | 1257 | printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n", |
1258 | " rip %lx %02x %02x %02x %02x\n", | 1258 | context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]); |
1259 | rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]); | ||
1260 | reported = 1; | 1259 | reported = 1; |
1261 | } | 1260 | } |
1261 | EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); | ||
1262 | 1262 | ||
1263 | struct x86_emulate_ops emulate_ops = { | 1263 | struct x86_emulate_ops emulate_ops = { |
1264 | .read_std = emulator_read_std, | 1264 | .read_std = emulator_read_std, |
@@ -1323,7 +1323,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
1323 | if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) | 1323 | if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) |
1324 | return EMULATE_DONE; | 1324 | return EMULATE_DONE; |
1325 | if (!vcpu->mmio_needed) { | 1325 | if (!vcpu->mmio_needed) { |
1326 | report_emulation_failure(&emulate_ctxt); | 1326 | kvm_report_emulation_failure(vcpu, "mmio"); |
1327 | return EMULATE_FAIL; | 1327 | return EMULATE_FAIL; |
1328 | } | 1328 | } |
1329 | return EMULATE_DO_MMIO; | 1329 | return EMULATE_DO_MMIO; |
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 95681ea16382..729f1cd93606 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c | |||
@@ -960,7 +960,7 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
960 | ++svm->vcpu.stat.mmio_exits; | 960 | ++svm->vcpu.stat.mmio_exits; |
961 | return 0; | 961 | return 0; |
962 | case EMULATE_FAIL: | 962 | case EMULATE_FAIL: |
963 | vcpu_printf(&svm->vcpu, "%s: emulate fail\n", __FUNCTION__); | 963 | kvm_report_emulation_failure(&svm->vcpu, "pagetable"); |
964 | break; | 964 | break; |
965 | default: | 965 | default: |
966 | BUG(); | 966 | BUG(); |
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index c44c9ac79ca5..4f115a8e45ef 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -1798,7 +1798,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
1798 | ++vcpu->stat.mmio_exits; | 1798 | ++vcpu->stat.mmio_exits; |
1799 | return 0; | 1799 | return 0; |
1800 | case EMULATE_FAIL: | 1800 | case EMULATE_FAIL: |
1801 | vcpu_printf(vcpu, "%s: emulate fail\n", __FUNCTION__); | 1801 | kvm_report_emulation_failure(vcpu, "pagetable"); |
1802 | break; | 1802 | break; |
1803 | default: | 1803 | default: |
1804 | BUG(); | 1804 | BUG(); |