xen/15444-vmxassist-p2r.patch

159 lines
4.5 KiB
Diff

# HG changeset 15444 patch
# User Keir Fraser <keir@xensource.com>
# 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@intel.com>
Index: 2007-05-14/tools/firmware/vmxassist/setup.c
===================================================================
--- 2007-05-14.orig/tools/firmware/vmxassist/setup.c 2007-04-23 10:01:14.000000000 +0200
+++ 2007-05-14/tools/firmware/vmxassist/setup.c 2007-07-02 10:51:33.000000000 +0200
@@ -241,9 +241,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");
}
/*
Index: 2007-05-14/tools/firmware/vmxassist/vm86.c
===================================================================
--- 2007-05-14.orig/tools/firmware/vmxassist/vm86.c 2007-04-23 10:01:14.000000000 +0200
+++ 2007-05-14/tools/firmware/vmxassist/vm86.c 2007-07-02 10:51:33.000000000 +0200
@@ -584,8 +584,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 */
@@ -818,8 +823,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. */
@@ -829,6 +839,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;
@@ -837,21 +849,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;
@@ -1063,7 +1083,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
@@ -1275,6 +1296,12 @@ opcode(struct regs *regs)
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))) {
case 0x07: /* pop %es */
@@ -1385,17 +1412,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)