aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-09-12 06:21:09 -0400
committerAvi Kivity <avi@qumranet.com>2007-10-13 04:18:28 -0400
commit054b1369679fb97582fc77f25a700d4290ff3e89 (patch)
treefc06afd41830c263f6c068d1bd743ef7fcf9637d
parentfd2a76086527cbe074b08a8820253228cd919ece (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.h1
-rw-r--r--drivers/kvm/kvm_main.c16
-rw-r--r--drivers/kvm/svm.c2
-rw-r--r--drivers/kvm/vmx.c2
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
559int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run, 559int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run,
560 unsigned long cr2, u16 error_code); 560 unsigned long cr2, u16 error_code);
561void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context);
561void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); 562void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
562void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); 563void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
563void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, 564void 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
1243static void report_emulation_failure(struct x86_emulate_ctxt *ctxt) 1243void 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}
1261EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
1262 1262
1263struct x86_emulate_ops emulate_ops = { 1263struct 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();