public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Laurent Vivier <Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
To: kvm-devel <kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Subject: [PATCH 5/5] svm.c uses x86_decode_prefix() instead of io_address() and io_get_override().
Date: Wed, 01 Aug 2007 11:22:47 +0200	[thread overview]
Message-ID: <46B050E7.7080908@bull.net> (raw)
In-Reply-To: <46B0501C.6060409-6ktuUTfB/bM@public.gmane.org>


[-- Attachment #1.1.1: Type: text/plain, Size: 374 bytes --]

svm.c uses x86_decode_prefix() instead of io_address() and io_get_override().

*** WARNING: the SVM part has not been tested because I don't have any AMD
system. ***

Signed-off-by: Laurent Vivier <Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
-- 
------------- Laurent.Vivier-6ktuUTfB/bM@public.gmane.org  --------------
          "Software is hard" - Donald Knuth

[-- Attachment #1.1.2: svm-decode_prefix --]
[-- Type: text/plain, Size: 6694 bytes --]

Index: kvm/drivers/kvm/svm.c
===================================================================
--- kvm.orig/drivers/kvm/svm.c	2007-08-01 10:10:24.000000000 +0200
+++ kvm/drivers/kvm/svm.c	2007-08-01 10:37:30.000000000 +0200
@@ -98,20 +98,6 @@
 	return svm_features & feat;
 }
 
-static unsigned get_addr_size(struct vcpu_svm *svm)
-{
-	struct vmcb_save_area *sa = &svm->vmcb->save;
-	u16 cs_attrib;
-
-	if (!(sa->cr0 & X86_CR0_PE) || (sa->rflags & X86_EFLAGS_VM))
-		return 2;
-
-	cs_attrib = sa->cs.attrib;
-
-	return (cs_attrib & SVM_SELECTOR_L_MASK) ? 8 :
-				(cs_attrib & SVM_SELECTOR_DB_MASK) ? 4 : 2;
-}
-
 static inline u8 pop_irq(struct kvm_vcpu *vcpu)
 {
 	int word_index = __ffs(vcpu->irq_summary);
@@ -996,112 +982,6 @@
 	return 0;
 }
 
-static int io_get_override(struct vcpu_svm *svm,
-			  struct vmcb_seg **seg,
-			  int *addr_override)
-{
-	u8 inst[MAX_INST_SIZE];
-	unsigned ins_length;
-	gva_t rip;
-	int i;
-
-	rip =  svm->vmcb->save.rip;
-	ins_length = svm->next_rip - rip;
-	rip += svm->vmcb->save.cs.base;
-
-	if (ins_length > MAX_INST_SIZE)
-		printk(KERN_DEBUG
-		       "%s: inst length err, cs base 0x%llx rip 0x%llx "
-		       "next rip 0x%llx ins_length %u\n",
-		       __FUNCTION__,
-		       svm->vmcb->save.cs.base,
-		       svm->vmcb->save.rip,
-		       svm->vmcb->control.exit_info_2,
-		       ins_length);
-
-	if (emulator_read_std(rip, inst, ins_length, &svm->vcpu)
-	    != X86EMUL_CONTINUE)
-		/* #PF */
-		return 0;
-
-	*addr_override = 0;
-	*seg = NULL;
-	for (i = 0; i < ins_length; i++)
-		switch (inst[i]) {
-		case 0xf0:
-		case 0xf2:
-		case 0xf3:
-		case 0x66:
-			continue;
-		case 0x67:
-			*addr_override = 1;
-			continue;
-		case 0x2e:
-			*seg = &svm->vmcb->save.cs;
-			continue;
-		case 0x36:
-			*seg = &svm->vmcb->save.ss;
-			continue;
-		case 0x3e:
-			*seg = &svm->vmcb->save.ds;
-			continue;
-		case 0x26:
-			*seg = &svm->vmcb->save.es;
-			continue;
-		case 0x64:
-			*seg = &svm->vmcb->save.fs;
-			continue;
-		case 0x65:
-			*seg = &svm->vmcb->save.gs;
-			continue;
-		default:
-			return 1;
-		}
-	printk(KERN_DEBUG "%s: unexpected\n", __FUNCTION__);
-	return 0;
-}
-
-static unsigned long io_address(struct vcpu_svm *svm, int ins, gva_t *address)
-{
-	unsigned long addr_mask;
-	unsigned long *reg;
-	struct vmcb_seg *seg;
-	int addr_override;
-	struct vmcb_save_area *save_area = &svm->vmcb->save;
-	u16 cs_attrib = save_area->cs.attrib;
-	unsigned addr_size = get_addr_size(svm);
-
-	if (!io_get_override(svm, &seg, &addr_override))
-		return 0;
-
-	if (addr_override)
-		addr_size = (addr_size == 2) ? 4: (addr_size >> 1);
-
-	if (ins) {
-		reg = &svm->vcpu.regs[VCPU_REGS_RDI];
-		seg = &svm->vmcb->save.es;
-	} else {
-		reg = &svm->vcpu.regs[VCPU_REGS_RSI];
-		seg = (seg) ? seg : &svm->vmcb->save.ds;
-	}
-
-	addr_mask = ~0ULL >> (64 - (addr_size * 8));
-
-	if ((cs_attrib & SVM_SELECTOR_L_MASK) &&
-	    !(svm->vmcb->save.rflags & X86_EFLAGS_VM)) {
-		*address = (*reg & addr_mask);
-		return addr_mask;
-	}
-
-	if (!(seg->attrib & SVM_SELECTOR_P_SHIFT)) {
-		svm_inject_gp(&svm->vcpu, 0);
-		return 0;
-	}
-
-	*address = (*reg & addr_mask) + seg->base;
-	return addr_mask;
-}
-
 static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 {
 	u32 io_info = svm->vmcb->control.exit_info_1; //address size bug?
@@ -1109,6 +989,7 @@
 	unsigned port;
 	unsigned long count;
 	gva_t address = 0;
+	struct vmcb_save_area *sa = &svm->vmcb->save;
 
 	++svm->vcpu.stat.io_exits;
 
@@ -1120,21 +1001,96 @@
 	string = (io_info & SVM_IOIO_STR_MASK) != 0;
 	rep = (io_info & SVM_IOIO_REP_MASK) != 0;
 	count = 1;
-	down = (svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0;
+	down = (sa->rflags & X86_EFLAGS_DF) != 0;
 
 	if (string) {
-		unsigned addr_mask;
+		int mode;
+		u8 inst[MAX_INST_SIZE];
+		unsigned ins_length;
+		gva_t rip;
+		struct x86_prefix prefix;
+		u16 cs_ar = sa->cs.attrib;
+		unsigned long addr_mask;
+
+		mode = (!(sa->cr0 & X86_CR0_PE) ||
+			(sa->rflags & X86_EFLAGS_VM)) ?
+			X86EMUL_MODE_REAL :  (cs_ar & SVM_SELECTOR_L_MASK)
+			? X86EMUL_MODE_PROT64 : (cs_ar & SVM_SELECTOR_DB_MASK)
+			? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+
+		rip =  svm->vmcb->save.rip;
+		ins_length = svm->vmcb->save.rip - rip;
+		if (mode != X86EMUL_MODE_PROT64)
+			rip += svm->vmcb->save.cs.base;
+
+		if (ins_length > MAX_INST_SIZE)
+			printk(KERN_DEBUG
+			       "%s: inst length err, cs base 0x%llx rip 0x%llx "
+			       "next rip 0x%llx ins_length %u\n",
+			       __FUNCTION__,
+			       svm->vmcb->save.cs.base,
+			       svm->vmcb->save.rip,
+			       svm->vmcb->control.exit_info_2,
+			       ins_length);
 
-		addr_mask = io_address(svm, in, &address);
-		if (!addr_mask) {
-			printk(KERN_DEBUG "%s: get io address failed\n",
-			       __FUNCTION__);
+		if (emulator_read_std(rip, inst, ins_length, &svm->vcpu)
+					!= X86EMUL_CONTINUE)
+			return 1;
+
+		prefix.override_base = -1;
+		if (x86_decode_prefix(mode, (u8*)&inst, &prefix) == -1)
 			return 1;
-		}
 
+		addr_mask = (~0ULL >> (64 - (prefix.ad_bytes <<3)));
 		if (rep)
 			count = svm->vcpu.regs[VCPU_REGS_RCX] & addr_mask;
+
+		if (in)
+			address = svm->vcpu.regs[VCPU_REGS_RDI];
+		else
+			address = svm->vcpu.regs[VCPU_REGS_RSI];
+
+		address &= addr_mask;
+
+		if (mode != X86EMUL_MODE_PROT64) {
+			struct vmcb_seg *seg;
+
+			if (in)
+				seg = &svm->vmcb->save.es;
+			else switch(prefix.override_base) {
+				case -1:
+				case X86EMUL_BASE_DS:
+					seg = &svm->vmcb->save.ds;
+					break;
+				case X86EMUL_BASE_CS:
+					seg = &svm->vmcb->save.cs;
+					break;
+				case X86EMUL_BASE_ES:
+					seg = &svm->vmcb->save.es;
+					break;
+				case X86EMUL_BASE_GS:
+					seg = &svm->vmcb->save.gs;
+					break;
+				case X86EMUL_BASE_SS:
+					seg = &svm->vmcb->save.ss;
+					break;
+				default:
+					printk(KERN_DEBUG "%s: unexpected\n",
+						__FUNCTION__);
+					return 1;
+			}
+
+			if (seg->attrib & SVM_SELECTOR_P_SHIFT) {
+				svm_inject_gp(&svm->vcpu, 0);
+				printk(KERN_DEBUG "%s: get io address failed\n",
+					__FUNCTION__);
+				return 1;
+			}
+
+			address += seg->base;
+		}
 	}
+
 	return kvm_setup_pio(&svm->vcpu, kvm_run, in, size, count, string,
 			     down, address, rep, port);
 }
Index: kvm/drivers/kvm/.svm.c.swp
===================================================================
Binary files kvm.orig/drivers/kvm/.svm.c.swp	2007-08-01 10:12:34.000000000 +0200 and /dev/null	1970-01-01 00:00:00.000000000 +0000 differ

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: 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 #3: 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-01  9:22 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-01  9:05 PATCH 0/5] Consolidate the insb/outsb emulation into x86_emulate.c Laurent Vivier
     [not found] ` <46B04CCA.2010503-6ktuUTfB/bM@public.gmane.org>
2007-08-01  9:09   ` [PATCH 1/5] change ctxt.*_base to an array ctxt.base[X86EMUL_BASE_*] Laurent Vivier
     [not found]     ` <46B04DD6.7010702-6ktuUTfB/bM@public.gmane.org>
2007-08-01  9:13       ` [PATCH 2/5] group all prefix decoding results in a structure called x86_prefix Laurent Vivier
     [not found]         ` <46B04EB9.5010103-6ktuUTfB/bM@public.gmane.org>
2007-08-01  9:16           ` [PATCH 3/5] extract prefix decoding part from x86_emulate_memop() to x86_decode_prefix() Laurent Vivier
     [not found]             ` <46B04F56.60607-6ktuUTfB/bM@public.gmane.org>
2007-08-01  9:19               ` [PATCH 4/5] vmx.c uses x86_decode_prefix() instead of get_io_count() Laurent Vivier
     [not found]                 ` <46B0501C.6060409-6ktuUTfB/bM@public.gmane.org>
2007-08-01  9:22                   ` Laurent Vivier [this message]
2007-08-02  8:48                   ` Avi Kivity
     [not found]                     ` <46B19A7B.2030109-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-08-02  9:34                       ` Laurent Vivier
     [not found]                         ` <46B1A51C.2040104-6ktuUTfB/bM@public.gmane.org>
2007-08-02  9:41                           ` Avi Kivity
     [not found]                             ` <46B1A6B8.7020404-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-08-02 16:46                               ` Laurent Vivier

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=46B050E7.7080908@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox