Commit 054b1369 authored by Avi Kivity's avatar Avi Kivity

KVM: Improve emulation failure reporting

Report failed opcodes from all locations.
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent fd2a7608
...@@ -558,6 +558,7 @@ enum emulation_result { ...@@ -558,6 +558,7 @@ enum emulation_result {
int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run, int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run,
unsigned long cr2, u16 error_code); unsigned long cr2, u16 error_code);
void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context);
void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
......
...@@ -1240,25 +1240,25 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) ...@@ -1240,25 +1240,25 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value)
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
} }
static void report_emulation_failure(struct x86_emulate_ctxt *ctxt) void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
{ {
static int reported; static int reported;
u8 opcodes[4]; u8 opcodes[4];
unsigned long rip = ctxt->vcpu->rip; unsigned long rip = vcpu->rip;
unsigned long rip_linear; unsigned long rip_linear;
rip_linear = rip + get_segment_base(ctxt->vcpu, VCPU_SREG_CS); rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
if (reported) if (reported)
return; return;
emulator_read_std(rip_linear, (void *)opcodes, 4, ctxt->vcpu); emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu);
printk(KERN_ERR "emulation failed but !mmio_needed?" printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
" rip %lx %02x %02x %02x %02x\n", context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
reported = 1; reported = 1;
} }
EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
struct x86_emulate_ops emulate_ops = { struct x86_emulate_ops emulate_ops = {
.read_std = emulator_read_std, .read_std = emulator_read_std,
...@@ -1323,7 +1323,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, ...@@ -1323,7 +1323,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
return EMULATE_DONE; return EMULATE_DONE;
if (!vcpu->mmio_needed) { if (!vcpu->mmio_needed) {
report_emulation_failure(&emulate_ctxt); kvm_report_emulation_failure(vcpu, "mmio");
return EMULATE_FAIL; return EMULATE_FAIL;
} }
return EMULATE_DO_MMIO; return EMULATE_DO_MMIO;
......
...@@ -960,7 +960,7 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) ...@@ -960,7 +960,7 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
++svm->vcpu.stat.mmio_exits; ++svm->vcpu.stat.mmio_exits;
return 0; return 0;
case EMULATE_FAIL: case EMULATE_FAIL:
vcpu_printf(&svm->vcpu, "%s: emulate fail\n", __FUNCTION__); kvm_report_emulation_failure(&svm->vcpu, "pagetable");
break; break;
default: default:
BUG(); BUG();
......
...@@ -1798,7 +1798,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) ...@@ -1798,7 +1798,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
++vcpu->stat.mmio_exits; ++vcpu->stat.mmio_exits;
return 0; return 0;
case EMULATE_FAIL: case EMULATE_FAIL:
vcpu_printf(vcpu, "%s: emulate fail\n", __FUNCTION__); kvm_report_emulation_failure(vcpu, "pagetable");
break; break;
default: default:
BUG(); BUG();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment