[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Use 32bit operand and address during VMXAssist protected to real.



# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1183332299 -3600
# Node ID 93b9161fc92095241b4566f510aeb34ffff27f55
# Parent  5d7160564381eedda0853cf003b3097da0173893
Use 32bit operand and address during VMXAssist protected to real.
Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
---
 tools/firmware/vmxassist/setup.c |    3 +
 tools/firmware/vmxassist/vm86.c  |   61 +++++++++++++++++++++++++++++++--------
 2 files changed, 52 insertions(+), 12 deletions(-)

diff -r 5d7160564381 -r 93b9161fc920 tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c  Sun Jul 01 22:25:27 2007 +0100
+++ b/tools/firmware/vmxassist/setup.c  Mon Jul 02 00:24:59 2007 +0100
@@ -198,9 +198,10 @@ enter_real_mode(struct regs *regs)
        }
 
        /* go from protected to real mode */
-       regs->eflags |= EFLAGS_VM;
        set_mode(regs, VM86_PROTECTED_TO_REAL);
        emulate(regs);
+       if (mode != VM86_REAL)
+               panic("failed to emulate between clear PE and long jump.\n");
 }
 
 /*
diff -r 5d7160564381 -r 93b9161fc920 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Sun Jul 01 22:25:27 2007 +0100
+++ b/tools/firmware/vmxassist/vm86.c   Mon Jul 02 00:24:59 2007 +0100
@@ -580,8 +580,13 @@ movr(struct regs *regs, unsigned prefix,
        unsigned addr = operand(prefix, regs, modrm);
        unsigned val, r = (modrm >> 3) & 7;
 
-       if ((modrm & 0xC0) == 0xC0) /* no registers */
-               return 0;
+       if ((modrm & 0xC0) == 0xC0) {
+               /*
+                * Emulate all guest instructions in protected to real mode.
+                */
+               if (mode != VM86_PROTECTED_TO_REAL)
+                       return 0;
+       }
 
        switch (opc) {
        case 0x88: /* addr32 mov r8, r/m8 */
@@ -806,8 +811,13 @@ mov_to_seg(struct regs *regs, unsigned p
 {
        unsigned modrm = fetch8(regs);
 
-       /* Only need to emulate segment loads in real->protected mode. */
-       if (mode != VM86_REAL_TO_PROTECTED)
+       /*
+        * Emulate segment loads in:
+        * 1) real->protected mode.
+        * 2) protected->real mode.
+        */
+       if ((mode != VM86_REAL_TO_PROTECTED) &&
+           (mode != VM86_PROTECTED_TO_REAL))
                return 0;
 
        /* Register source only. */
@@ -817,6 +827,8 @@ mov_to_seg(struct regs *regs, unsigned p
        switch ((modrm & 0x38) >> 3) {
        case 0: /* es */
                regs->ves = getreg16(regs, modrm);
+               if (mode == VM86_PROTECTED_TO_REAL)
+                       return 1;
                saved_rm_regs.ves = 0;
                oldctx.es_sel = regs->ves;
                return 1;
@@ -825,21 +837,29 @@ mov_to_seg(struct regs *regs, unsigned p
 
        case 2: /* ss */
                regs->uss = getreg16(regs, modrm);
+               if (mode == VM86_PROTECTED_TO_REAL)
+                       return 1;
                saved_rm_regs.uss = 0;
                oldctx.ss_sel = regs->uss;
                return 1;
        case 3: /* ds */
                regs->vds = getreg16(regs, modrm);
+               if (mode == VM86_PROTECTED_TO_REAL)
+                       return 1;
                saved_rm_regs.vds = 0;
                oldctx.ds_sel = regs->vds;
                return 1;
        case 4: /* fs */
                regs->vfs = getreg16(regs, modrm);
+               if (mode == VM86_PROTECTED_TO_REAL)
+                       return 1;
                saved_rm_regs.vfs = 0;
                oldctx.fs_sel = regs->vfs;
                return 1;
        case 5: /* gs */
                regs->vgs = getreg16(regs, modrm);
+               if (mode == VM86_PROTECTED_TO_REAL)
+                       return 1;
                saved_rm_regs.vgs = 0;
                oldctx.gs_sel = regs->vgs;
                return 1;
@@ -1055,7 +1075,8 @@ set_mode(struct regs *regs, enum vm86_mo
        }
 
        mode = newmode;
-       TRACE((regs, 0, states[mode]));
+       if (mode != VM86_PROTECTED)
+               TRACE((regs, 0, states[mode]));
 }
 
 static void
@@ -1268,6 +1289,12 @@ opcode(struct regs *regs)
        unsigned eip = regs->eip;
        unsigned opc, modrm, disp;
        unsigned prefix = 0;
+
+       if (mode == VM86_PROTECTED_TO_REAL &&
+               oldctx.cs_arbytes.fields.default_ops_size) {
+               prefix |= DATA32;
+               prefix |= ADDR32;
+       }
 
        for (;;) {
                switch ((opc = fetch8(regs))) {
@@ -1379,17 +1406,29 @@ opcode(struct regs *regs)
                        continue;
 
                case 0x66:
-                       TRACE((regs, regs->eip - eip, "data32"));
-                       prefix |= DATA32;
+                       if (mode == VM86_PROTECTED_TO_REAL &&
+                               oldctx.cs_arbytes.fields.default_ops_size) {
+                               TRACE((regs, regs->eip - eip, "data16"));
+                               prefix &= ~DATA32;
+                       } else {
+                               TRACE((regs, regs->eip - eip, "data32"));
+                               prefix |= DATA32;
+                       }
                        continue;
 
                case 0x67:
-                       TRACE((regs, regs->eip - eip, "addr32"));
-                       prefix |= ADDR32;
+                       if (mode == VM86_PROTECTED_TO_REAL &&
+                               oldctx.cs_arbytes.fields.default_ops_size) {
+                               TRACE((regs, regs->eip - eip, "addr16"));
+                               prefix &= ~ADDR32;
+                       } else {
+                               TRACE((regs, regs->eip - eip, "addr32"));
+                               prefix |= ADDR32;
+                       }
                        continue;
 
-               case 0x88: /* addr32 mov r8, r/m8 */
-               case 0x8A: /* addr32 mov r/m8, r8 */
+               case 0x88: /* mov r8, r/m8 */
+               case 0x8A: /* mov r/m8, r8 */
                        if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
                                goto invalid;
                        if ((prefix & ADDR32) == 0)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.