All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Vivier <Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
To: Laurent Vivier <Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
Cc: kvm-devel <kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Subject: Re: [PATCH 5/5] Call x86_decode_insn() only when needed
Date: Wed, 29 Aug 2007 19:03:10 +0200	[thread overview]
Message-ID: <46D5A6CE.5090004@bull.net> (raw)
In-Reply-To: <46D5A2B0.7050802-6ktuUTfB/bM@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 642 bytes --]

Laurent Vivier wrote:
> Index: kvm/drivers/kvm/kvm.h
> @@ -1860,7 +1869,7 @@ static int kvm_vcpu_ioctl_run(struct kvm
>  		vcpu->mmio_read_completed = 1;
>  		vcpu->mmio_needed = 0;
>  		r = emulate_instruction(vcpu, kvm_run,
> -					vcpu->mmio_fault_cr2, 0);
> +					vcpu->mmio_fault_cr2, 0, 0);
>  		if (r == EMULATE_DO_MMIO) {
>  			/*
>  			 * Read-modify-write.  Back to userspace.

Sorry this one is wrong, we must have here:

+					vcpu->mmio_fault_cr2, 0, 1);

(good patch attached)
Laurent
-- 
------------- Laurent.Vivier-6ktuUTfB/bM@public.gmane.org  --------------
          "Software is hard" - Donald Knuth

[-- Attachment #2: x86_emulate-optimize --]
[-- Type: text/plain, Size: 9897 bytes --]

Index: kvm/drivers/kvm/kvm.h
===================================================================
--- kvm.orig/drivers/kvm/kvm.h	2007-08-29 18:27:21.000000000 +0200
+++ kvm/drivers/kvm/kvm.h	2007-08-29 18:27:26.000000000 +0200
@@ -206,6 +206,8 @@ enum {
 	VCPU_SREG_LDTR,
 };
 
+#include "x86_emulate.h"
+
 struct kvm_pio_request {
 	unsigned long count;
 	int cur_count;
@@ -372,6 +374,10 @@ struct kvm_vcpu {
 
 	int cpuid_nent;
 	struct kvm_cpuid_entry cpuid_entries[KVM_MAX_CPUID_ENTRIES];
+
+	/* emulate context */
+
+	struct x86_emulate_ctxt emulate_ctxt;
 };
 
 struct kvm_mem_alias {
@@ -525,7 +531,7 @@ enum emulation_result {
 };
 
 int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run,
-			unsigned long cr2, u16 error_code);
+			unsigned long cr2, u16 error_code, int no_decode);
 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_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
Index: kvm/drivers/kvm/kvm_main.c
===================================================================
--- kvm.orig/drivers/kvm/kvm_main.c	2007-08-29 18:27:26.000000000 +0200
+++ kvm/drivers/kvm/kvm_main.c	2007-08-29 18:55:58.000000000 +0200
@@ -1167,47 +1167,56 @@ struct x86_emulate_ops emulate_ops = {
 int emulate_instruction(struct kvm_vcpu *vcpu,
 			struct kvm_run *run,
 			unsigned long cr2,
-			u16 error_code)
+			u16 error_code,
+			int no_decode)
 {
-	struct x86_emulate_ctxt emulate_ctxt;
 	int r;
-	int cs_db, cs_l;
 
 	vcpu->mmio_fault_cr2 = cr2;
 	kvm_arch_ops->cache_regs(vcpu);
+	vcpu->emulate_ctxt.cr2 = cr2;
 
-	kvm_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
-
-	emulate_ctxt.vcpu = vcpu;
-	emulate_ctxt.eflags = kvm_arch_ops->get_rflags(vcpu);
-	emulate_ctxt.cr2 = cr2;
-	emulate_ctxt.mode = (emulate_ctxt.eflags & X86_EFLAGS_VM)
-		? X86EMUL_MODE_REAL : cs_l
-		? X86EMUL_MODE_PROT64 :	cs_db
-		? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
-
-	if (emulate_ctxt.mode == X86EMUL_MODE_PROT64) {
-		emulate_ctxt.cs_base = 0;
-		emulate_ctxt.ds_base = 0;
-		emulate_ctxt.es_base = 0;
-		emulate_ctxt.ss_base = 0;
-	} else {
-		emulate_ctxt.cs_base = get_segment_base(vcpu, VCPU_SREG_CS);
-		emulate_ctxt.ds_base = get_segment_base(vcpu, VCPU_SREG_DS);
-		emulate_ctxt.es_base = get_segment_base(vcpu, VCPU_SREG_ES);
-		emulate_ctxt.ss_base = get_segment_base(vcpu, VCPU_SREG_SS);
-	}
+	if (!no_decode) {
+		int cs_db, cs_l;
+		kvm_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
+
+		vcpu->emulate_ctxt.vcpu = vcpu;
+		vcpu->emulate_ctxt.eflags = kvm_arch_ops->get_rflags(vcpu);
+		vcpu->emulate_ctxt.mode =
+			(vcpu->emulate_ctxt.eflags & X86_EFLAGS_VM)
+			? X86EMUL_MODE_REAL : cs_l
+			? X86EMUL_MODE_PROT64 :	cs_db
+			? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+
+		if (vcpu->emulate_ctxt.mode == X86EMUL_MODE_PROT64) {
+			vcpu->emulate_ctxt.cs_base = 0;
+			vcpu->emulate_ctxt.ds_base = 0;
+			vcpu->emulate_ctxt.es_base = 0;
+			vcpu->emulate_ctxt.ss_base = 0;
+		} else {
+			vcpu->emulate_ctxt.cs_base =
+					get_segment_base(vcpu, VCPU_SREG_CS);
+			vcpu->emulate_ctxt.ds_base =
+					get_segment_base(vcpu, VCPU_SREG_DS);
+			vcpu->emulate_ctxt.es_base =
+					get_segment_base(vcpu, VCPU_SREG_ES);
+			vcpu->emulate_ctxt.ss_base =
+					get_segment_base(vcpu, VCPU_SREG_SS);
+		}
 
-	emulate_ctxt.gs_base = get_segment_base(vcpu, VCPU_SREG_GS);
-	emulate_ctxt.fs_base = get_segment_base(vcpu, VCPU_SREG_FS);
+		vcpu->emulate_ctxt.gs_base =
+					get_segment_base(vcpu, VCPU_SREG_GS);
+		vcpu->emulate_ctxt.fs_base =
+					get_segment_base(vcpu, VCPU_SREG_FS);
 
-	r = x86_decode_insn(&emulate_ctxt, &emulate_ops);
-	if (r)
-		return EMULATE_FAIL;
+		r = x86_decode_insn(&vcpu->emulate_ctxt, &emulate_ops);
+		if (r)
+			return EMULATE_FAIL;
+	}
 
 	vcpu->mmio_is_write = 0;
 	vcpu->pio.string = 0;
-	r = x86_emulate_insn(&emulate_ctxt, &emulate_ops);
+	r = x86_emulate_insn(&vcpu->emulate_ctxt, &emulate_ops);
 	if (vcpu->pio.string)
 		return EMULATE_DO_MMIO;
 
@@ -1223,14 +1232,14 @@ int emulate_instruction(struct kvm_vcpu 
 		if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
 			return EMULATE_DONE;
 		if (!vcpu->mmio_needed) {
-			report_emulation_failure(&emulate_ctxt);
+			report_emulation_failure(&vcpu->emulate_ctxt);
 			return EMULATE_FAIL;
 		}
 		return EMULATE_DO_MMIO;
 	}
 
 	kvm_arch_ops->decache_regs(vcpu);
-	kvm_arch_ops->set_rflags(vcpu, emulate_ctxt.eflags);
+	kvm_arch_ops->set_rflags(vcpu, vcpu->emulate_ctxt.eflags);
 
 	if (vcpu->mmio_is_write) {
 		vcpu->mmio_needed = 0;
@@ -1860,7 +1869,7 @@ static int kvm_vcpu_ioctl_run(struct kvm
 		vcpu->mmio_read_completed = 1;
 		vcpu->mmio_needed = 0;
 		r = emulate_instruction(vcpu, kvm_run,
-					vcpu->mmio_fault_cr2, 0);
+					vcpu->mmio_fault_cr2, 0, 1);
 		if (r == EMULATE_DO_MMIO) {
 			/*
 			 * Read-modify-write.  Back to userspace.
Index: kvm/drivers/kvm/svm.c
===================================================================
--- kvm.orig/drivers/kvm/svm.c	2007-08-29 18:27:21.000000000 +0200
+++ kvm/drivers/kvm/svm.c	2007-08-29 18:27:26.000000000 +0200
@@ -938,7 +938,7 @@ static int pf_interception(struct vcpu_s
 		return 1;
 	}
 	er = emulate_instruction(&svm->vcpu, kvm_run, fault_address,
-				 error_code);
+				 error_code, 0);
 	mutex_unlock(&kvm->lock);
 
 	switch (er) {
@@ -994,7 +994,8 @@ static int io_interception(struct vcpu_s
 	string = (io_info & SVM_IOIO_STR_MASK) != 0;
 
 	if (string) {
-		if (emulate_instruction(&svm->vcpu, kvm_run, 0, 0) == EMULATE_DO_MMIO)
+		if (emulate_instruction(&svm->vcpu,
+					kvm_run, 0, 0, 0) == EMULATE_DO_MMIO)
 			return 0;
 		return 1;
 	}
@@ -1052,7 +1053,7 @@ static int cpuid_interception(struct vcp
 static int emulate_on_interception(struct vcpu_svm *svm,
 				   struct kvm_run *kvm_run)
 {
-	if (emulate_instruction(&svm->vcpu, NULL, 0, 0) != EMULATE_DONE)
+	if (emulate_instruction(&svm->vcpu, NULL, 0, 0, 0) != EMULATE_DONE)
 		pr_unimpl(&svm->vcpu, "%s: failed\n", __FUNCTION__);
 	return 1;
 }
Index: kvm/drivers/kvm/vmx.c
===================================================================
--- kvm.orig/drivers/kvm/vmx.c	2007-08-29 18:27:21.000000000 +0200
+++ kvm/drivers/kvm/vmx.c	2007-08-29 18:27:26.000000000 +0200
@@ -1659,7 +1659,7 @@ static int handle_rmode_exception(struct
 	 * Cause the #SS fault with 0 error code in VM86 mode.
 	 */
 	if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0)
-		if (emulate_instruction(vcpu, NULL, 0, 0) == EMULATE_DONE)
+		if (emulate_instruction(vcpu, NULL, 0, 0, 0) == EMULATE_DONE)
 			return 1;
 	return 0;
 }
@@ -1715,7 +1715,7 @@ static int handle_exception(struct kvm_v
 			return 1;
 		}
 
-		er = emulate_instruction(vcpu, kvm_run, cr2, error_code);
+		er = emulate_instruction(vcpu, kvm_run, cr2, error_code, 0);
 		mutex_unlock(&vcpu->kvm->lock);
 
 		switch (er) {
@@ -1776,7 +1776,8 @@ static int handle_io(struct kvm_vcpu *vc
 	string = (exit_qualification & 16) != 0;
 
 	if (string) {
-		if (emulate_instruction(vcpu, kvm_run, 0, 0) == EMULATE_DO_MMIO)
+		if (emulate_instruction(vcpu,
+					kvm_run, 0, 0, 0) == EMULATE_DO_MMIO)
 			return 0;
 		return 1;
 	}
Index: kvm/drivers/kvm/x86_emulate.c
===================================================================
--- kvm.orig/drivers/kvm/x86_emulate.c	2007-08-29 18:27:26.000000000 +0200
+++ kvm/drivers/kvm/x86_emulate.c	2007-08-29 18:27:26.000000000 +0200
@@ -888,8 +888,12 @@ x86_emulate_insn(struct x86_emulate_ctxt
 	int mode = ctxt->mode;
 	int no_wb = 0;
 	u64 msr_data;
+	unsigned long saved_rcx = 0, saved_eip = 0;
 	unsigned long _eflags = ctxt->eflags;
 
+	if ((decode->d & ModRM) && (decode->modrm_mod != 3))
+		ctxt->cr2 = decode->modrm_ea;
+
 	if (decode->src.type == OP_MEM) {
 		decode->src.ptr = (unsigned long *)ctxt->cr2;
 		if ((rc = ops->read_emulated((unsigned long)decode->src.ptr,
@@ -1274,6 +1278,8 @@ special_insn:
 			ctxt->vcpu->rip = decode->eip;
 			goto done;
 		}
+		saved_rcx = ctxt->decode.regs[VCPU_REGS_RCX];
+		saved_eip = ctxt->decode.eip;
 		decode->regs[VCPU_REGS_RCX]--;
 		decode->eip = ctxt->vcpu->rip;
 	}
@@ -1289,8 +1295,13 @@ special_insn:
 					ctxt->ds_base,
 					decode->regs[VCPU_REGS_RSI]),
 					&decode->dst.val,
-					decode->dst.bytes, ctxt->vcpu)) != 0)
+					decode->dst.bytes, ctxt->vcpu)) != 0) {
+			if (ctxt->decode.rep_prefix) {
+				ctxt->decode.regs[VCPU_REGS_RCX] = saved_rcx;
+				ctxt->decode.eip = saved_eip;
+			}
 			goto done;
+		}
 		register_address_increment(decode->regs[VCPU_REGS_RSI],
 			     (_eflags & EFLG_DF) ? -decode->dst.bytes :
 						   decode->dst.bytes);
@@ -1316,8 +1327,13 @@ special_insn:
 		decode->dst.ptr = (unsigned long *)&decode->regs[VCPU_REGS_RAX];
 		if ((rc = ops->read_emulated(ctxt->cr2, &decode->dst.val,
 					     decode->dst.bytes,
-					     ctxt->vcpu)) != 0)
+					     ctxt->vcpu)) != 0) {
+			if (ctxt->decode.rep_prefix) {
+				ctxt->decode.regs[VCPU_REGS_RCX] = saved_rcx;
+				ctxt->decode.eip = saved_eip;
+			}
 			goto done;
+		}
 		register_address_increment(decode->regs[VCPU_REGS_RSI],
 			   (_eflags & EFLG_DF) ? -decode->dst.bytes :
 						 decode->dst.bytes);
@@ -1338,8 +1354,13 @@ special_insn:
 pop_instruction:
 		if ((rc = ops->read_std(register_address(ctxt->ss_base,
 			decode->regs[VCPU_REGS_RSP]), decode->dst.ptr,
-			decode->op_bytes, ctxt->vcpu)) != 0)
+			decode->op_bytes, ctxt->vcpu)) != 0) {
+			if (ctxt->decode.rep_prefix) {
+				ctxt->decode.regs[VCPU_REGS_RCX] = saved_rcx;
+				ctxt->decode.eip = saved_eip;
+			}
 			goto done;
+		}
 
 		register_address_increment(decode->regs[VCPU_REGS_RSP],
 					   decode->op_bytes);

[-- Attachment #3: Type: text/plain, Size: 315 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

[-- Attachment #4: Type: text/plain, Size: 186 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel

      parent reply	other threads:[~2007-08-29 17:03 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-29 16:45 [PATCH 5/5] Call x86_decode_insn() only when needed Laurent Vivier
     [not found] ` <46D5A2B0.7050802-6ktuUTfB/bM@public.gmane.org>
2007-08-29 17:03   ` Laurent Vivier [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46D5A6CE.5090004@bull.net \
    --to=laurent.vivier-6ktuutfb/bm@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.