Extract prefix decoding part from x86_emulate_memop() to x86_decode_prefix().

Signed-off-by: Laurent Vivier <[EMAIL PROTECTED]>
-- 
------------- [EMAIL PROTECTED]  --------------
          "Software is hard" - Donald Knuth
Index: kvm/drivers/kvm/x86_emulate.c
===================================================================
--- kvm.orig/drivers/kvm/x86_emulate.c  2007-07-31 17:44:35.000000000 +0200
+++ kvm/drivers/kvm/x86_emulate.c       2007-07-31 18:23:39.000000000 +0200
@@ -480,43 +480,24 @@
 }
 
 int
-x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+x86_decode_prefix(int mode, u8 *inst, struct x86_prefix *prefix)
 {
-       unsigned d;
-       u8 b, sib, twobyte = 0;
-       u8 modrm, modrm_mod = 0;
-       unsigned int i;
-       int rc = 0;
-       struct operand src, dst;
-       unsigned long cr2 = ctxt->cr2;
-       int mode = ctxt->mode;
-       unsigned long modrm_ea;
-       int use_modrm_ea, scale, rip_relative = 0;
-       int no_wb = 0;
-       u64 msr_data;
-       struct x86_prefix prefix;
-
-       /* Shadow copy of register state. Committed on successful emulation. */
-       unsigned long _regs[NR_VCPU_REGS];
-       unsigned long _eip = ctxt->vcpu->rip, _eflags = ctxt->eflags;
-       unsigned long modrm_val = 0;
-
-       memcpy(_regs, ctxt->vcpu->regs, sizeof _regs);
-       memset(&prefix, 0, sizeof(prefix));
-       prefix.override_base = -1;
+       unsigned int op_bytes, ad_bytes;
+       int i;
+       u8 b;
 
        switch (mode) {
        case X86EMUL_MODE_REAL:
        case X86EMUL_MODE_PROT16:
-               prefix.op_bytes = prefix.ad_bytes = 2;
+               op_bytes = ad_bytes = 2;
                break;
        case X86EMUL_MODE_PROT32:
-               prefix.op_bytes = prefix.ad_bytes = 4;
+               op_bytes = ad_bytes = 4;
                break;
 #ifdef CONFIG_X86_64
        case X86EMUL_MODE_PROT64:
-               prefix.op_bytes = 4;
-               prefix.ad_bytes = 8;
+               op_bytes = 4;
+               ad_bytes = 8;
                break;
 #endif
        default:
@@ -525,39 +506,39 @@
 
        /* Legacy prefixes. */
        for (i = 0; i < 8; i++) {
-               switch (b = insn_fetch(u8, 1, _eip)) {
+               switch (b = inst[i]) {
                case 0x66:      /* operand-size override */
-                       prefix.op_bytes ^= 6;   /* switch between 2/4 bytes */
+                       op_bytes ^= 6;  /* switch between 2/4 bytes */
                        break;
                case 0x67:      /* address-size override */
                        if (mode == X86EMUL_MODE_PROT64)
-                               prefix.ad_bytes ^= 12;  /* switch between 4/8 
bytes */
+                               ad_bytes ^= 12; /* switch between 4/8 bytes */
                        else
-                               prefix.ad_bytes ^= 6;   /* switch between 2/4 
bytes */
+                               ad_bytes ^= 6;  /* switch between 2/4 bytes */
                        break;
                case 0x2e:      /* CS override */
-                       prefix.override_base = X86EMUL_BASE_CS;
+                       prefix->override_base = X86EMUL_BASE_CS;
                        break;
                case 0x3e:      /* DS override */
-                       prefix.override_base = X86EMUL_BASE_DS;
+                       prefix->override_base = X86EMUL_BASE_DS;
                        break;
                case 0x26:      /* ES override */
-                       prefix.override_base = X86EMUL_BASE_ES;
+                       prefix->override_base = X86EMUL_BASE_ES;
                        break;
                case 0x64:      /* FS override */
-                       prefix.override_base = X86EMUL_BASE_FS;
+                       prefix->override_base = X86EMUL_BASE_FS;
                        break;
                case 0x65:      /* GS override */
-                       prefix.override_base = X86EMUL_BASE_GS;
+                       prefix->override_base = X86EMUL_BASE_GS;
                        break;
                case 0x36:      /* SS override */
-                       prefix.override_base = X86EMUL_BASE_SS;
+                       prefix->override_base = X86EMUL_BASE_SS;
                        break;
                case 0xf0:      /* LOCK */
-                       prefix.lock = 1;
+                       prefix->lock = 1;
                        break;
                case 0xf3:      /* REP/REPE/REPZ */
-                       prefix.rep = 1;
+                       prefix->rep = 1;
                        break;
                case 0xf2:      /* REPNE/REPNZ */
                        break;
@@ -570,15 +551,62 @@
 
        /* REX prefix. */
        if ((mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40)) {
-               prefix.rex = b;
+               prefix->rex = b;
                if (b & 8)
-                       prefix.op_bytes = 8;    /* REX.W */
-               prefix.modrm_reg = (b & 4) << 1;        /* REX.R */
-               prefix.index_reg = (b & 2) << 2; /* REX.X */
-               prefix.modrm_rm = prefix.base_reg = (b & 1) << 3; /* REG.B */
-               b = insn_fetch(u8, 1, _eip);
+                       op_bytes = 8;   /* REX.W */
+               prefix->modrm_reg = (b & 4) << 1;       /* REX.R */
+               prefix->index_reg = (b & 2) << 2; /* REX.X */
+               prefix->modrm_rm = prefix->base_reg = (b & 1) << 3; /* REG.B */
+               i++;
        }
 
+       prefix->op_bytes = op_bytes;
+       prefix->ad_bytes = ad_bytes;
+
+       return i;
+}
+EXPORT_SYMBOL_GPL(x86_decode_prefix);
+
+int
+x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+{
+       unsigned d;
+       u8 b, sib, twobyte = 0;
+       u8 modrm, modrm_mod = 0;
+       int rc = 0;
+       struct operand src, dst;
+       unsigned long cr2 = ctxt->cr2;
+       int mode = ctxt->mode;
+       unsigned long modrm_ea;
+       int use_modrm_ea, scale, rip_relative = 0;
+       int no_wb = 0;
+       u64 msr_data, inst;
+       struct x86_prefix prefix;
+       int count;
+
+       /* Shadow copy of register state. Committed on successful emulation. */
+       unsigned long _regs[NR_VCPU_REGS];
+       unsigned long _eip = ctxt->vcpu->rip, _eflags = ctxt->eflags;
+       unsigned long modrm_val = 0;
+
+       memcpy(_regs, ctxt->vcpu->regs, sizeof _regs);
+
+       /* decode prefixes */
+
+       rc = ops->read_std(_eip + ctxt->base[X86EMUL_BASE_CS],
+                          &inst, sizeof(inst), ctxt->vcpu);
+       if ( rc != 0 )
+               goto done;
+
+       memset(&prefix, 0, sizeof(prefix));
+       prefix.override_base = -1;
+
+       count = x86_decode_prefix(mode, (u8*)&inst, &prefix);
+       if (count == -1)
+               return -1;
+       _eip += count;
+       b = insn_fetch(u8, 1, _eip);
+
        /* Opcode byte(s). */
        d = opcode_table[b];
        if (d == 0) {
Index: kvm/drivers/kvm/x86_emulate.h
===================================================================
--- kvm.orig/drivers/kvm/x86_emulate.h  2007-07-31 18:00:51.000000000 +0200
+++ kvm/drivers/kvm/x86_emulate.h       2007-07-31 18:01:53.000000000 +0200
@@ -164,6 +164,13 @@
 #endif
 
 /*
+ * x86_decode_prefix: Decode instruction prefixes
+ * Returns -1 on failure, 0 on success.
+ */
+int
+x86_decode_prefix(int mode, u8 *inst, struct x86_prefix *prefix);
+
+/*
  * x86_emulate_memop: Emulate an instruction that faulted attempting to
  *                    read/write a 'special' memory area.
  * Returns -1 on failure, 0 on success.

Attachment: signature.asc
Description: OpenPGP digital signature

-------------------------------------------------------------------------
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/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to