[RHEL7,COMMIT] kvm/x86: add log printing on emulation failure

Submitted by Konstantin Khorenko on June 24, 2019, 3:25 p.m.

Details

Message ID 201906241525.x5OFP67u012085@finist-ce7.sw.ru
State New
Series "kvm/x86: add log printing on emulation failure"
Headers show

Commit Message

Konstantin Khorenko June 24, 2019, 3:25 p.m.
The commit is pushed to "branch-rh7-3.10.0-957.12.2.vz7.96.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-957.12.2.vz7.96.17
------>
commit 366859f048cbe002f8096cc5e0073d1525f08d60
Author: Denis Plotnikov <dplotnikov@virtuozzo.com>
Date:   Mon Jun 24 18:25:06 2019 +0300

    kvm/x86: add log printing on emulation failure
    
    This is a temporary patch serving to increase the amount of data
    available for analysis in the cases of kvm "emulation failure" for
    bugs like the following:
    
    https://jira.sw.ru/browse/PSBM-95474
    https://jira.sw.ru/browse/PSBM-68018
    
    Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
---
 arch/x86/kvm/x86.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Patch hide | download patch | download mbox

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index fa5ba1994c46..29a07d335551 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -55,6 +55,7 @@ 
 #include <linux/irqbypass.h>
 #include <linux/mem_encrypt.h>
 #include <trace/events/kvm.h>
+#include <linux/kvm_host.h>
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
@@ -5335,6 +5336,34 @@  int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip)
 }
 EXPORT_SYMBOL_GPL(kvm_inject_realmode_interrupt);
 
+static void printk_emulation_data(struct kvm_vcpu *vcpu, int emulation_type)
+{
+	struct x86_emulate_ctxt *ctx = &vcpu->arch.emulate_ctxt;
+	int i;
+
+	vcpu_err(vcpu, "=== emulation failure ===\n");
+
+	dump_stack();
+
+	vcpu_err(vcpu, "emulation context data (emulation_type: 0x%x)\n",
+		emulation_type);
+	vcpu_err(vcpu, "eflags: 0x%lx start_eip: 0x%lx mode: %d\n",
+		ctx->eflags, ctx->eip, ctx->mode);
+	vcpu_err(vcpu, "opcode_len: %u b: 0x%x op_bytes: %u ad_bytes: %u\n",
+		ctx->opcode_len, ctx->b, ctx->op_bytes, ctx->ad_bytes);
+	vcpu_err(vcpu, "d: 0x%llx current_eip: 0x%lx\n ", ctx->d, ctx->_eip);
+	vcpu_err(vcpu, "fetch data: data: %p ptr %p pos %p\n",
+		ctx->fetch.data, ctx->fetch.ptr, ctx->fetch.end);
+	vcpu_err(vcpu, "fetch data content: ");
+
+	for (i = 0; i < ARRAY_SIZE(ctx->fetch.data); i++) {
+		printk("0x%02x ", ctx->fetch.data[i]);
+	}
+	printk("\n");
+
+	vcpu_err(vcpu, "=== end of emulation failure ===\n");
+}
+
 static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
 {
 	int r = EMULATE_DONE;
@@ -5350,6 +5379,7 @@  static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
 		vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
 		vcpu->run->internal.ndata = 0;
 		r = EMULATE_FAIL;
+		printk_emulation_data(vcpu, emulation_type);
 	}
 
 	kvm_queue_exception(vcpu, UD_VECTOR);