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
next prev 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 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.