# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 38765166ad7a788dfac3ffde9a50b4964039cac2
# Parent e5d29225a8d12aa3855339cbbef81dbb75dcaa78
[XEN] Fix the emulation of instructions in vm86 mode. It fetches
them using cs and eip instead of only eip. This makes it at least
possible to use the i945GM vesa bios from the running system.
Signed-off-by: Bastian Blank <waldi@xxxxxxxxxx>
---
xen/arch/x86/traps.c | 28 +++++++++++++++-------------
1 files changed, 15 insertions(+), 13 deletions(-)
diff -r e5d29225a8d1 -r 38765166ad7a xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Tue Sep 19 11:08:11 2006 +0100
+++ b/xen/arch/x86/traps.c Tue Sep 19 11:13:10 2006 +0100
@@ -1028,9 +1028,11 @@ static inline unsigned char inb_user(
(admin_io_okay(_p, 4, _d, _r) ? outl(_v, _p) : ((void)0))
/* Instruction fetch with error handling. */
-#define insn_fetch(_type, _size, _ptr) \
-({ unsigned long _rc, _x; \
- if ( (_rc = copy_from_user(&_x, (_type *)eip, sizeof(_type))) != 0 ) \
+#define insn_fetch(_type, _size, cs, eip) \
+({ unsigned long _rc, _x, _ptr = eip; \
+ if ( vm86_mode(regs) ) \
+ _ptr += cs << 4; \
+ if ( (_rc = copy_from_user(&_x, (_type *)_ptr, sizeof(_type))) != 0 ) \
{ \
propagate_page_fault(eip + sizeof(_type) - _rc, 0); \
return EXCRET_fault_fixed; \
@@ -1040,7 +1042,7 @@ static int emulate_privileged_op(struct
static int emulate_privileged_op(struct cpu_user_regs *regs)
{
struct vcpu *v = current;
- unsigned long *reg, eip = regs->eip, res;
+ unsigned long *reg, eip = regs->eip, cs = regs->cs, res;
u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0;
unsigned int port, i, op_bytes = 4, data, rc;
u32 l, h;
@@ -1048,7 +1050,7 @@ static int emulate_privileged_op(struct
/* Legacy prefixes. */
for ( i = 0; i < 8; i++ )
{
- switch ( opcode = insn_fetch(u8, 1, eip) )
+ switch ( opcode = insn_fetch(u8, 1, cs, eip) )
{
case 0x66: /* operand-size override */
op_bytes ^= 6; /* switch between 2/4 bytes */
@@ -1080,7 +1082,7 @@ static int emulate_privileged_op(struct
modrm_rm = (opcode & 1) << 3; /* REX.B */
/* REX.W and REX.X do not need to be decoded. */
- opcode = insn_fetch(u8, 1, eip);
+ opcode = insn_fetch(u8, 1, cs, eip);
}
#endif
@@ -1162,7 +1164,7 @@ static int emulate_privileged_op(struct
case 0xe4: /* IN imm8,%al */
op_bytes = 1;
case 0xe5: /* IN imm8,%eax */
- port = insn_fetch(u8, 1, eip);
+ port = insn_fetch(u8, 1, cs, eip);
exec_in:
if ( !guest_io_okay(port, op_bytes, v, regs) )
goto fail;
@@ -1191,7 +1193,7 @@ static int emulate_privileged_op(struct
case 0xe6: /* OUT %al,imm8 */
op_bytes = 1;
case 0xe7: /* OUT %eax,imm8 */
- port = insn_fetch(u8, 1, eip);
+ port = insn_fetch(u8, 1, cs, eip);
exec_out:
if ( !guest_io_okay(port, op_bytes, v, regs) )
goto fail;
@@ -1240,7 +1242,7 @@ static int emulate_privileged_op(struct
goto fail;
/* Privileged (ring 0) instructions. */
- opcode = insn_fetch(u8, 1, eip);
+ opcode = insn_fetch(u8, 1, cs, eip);
switch ( opcode )
{
case 0x06: /* CLTS */
@@ -1258,7 +1260,7 @@ static int emulate_privileged_op(struct
break;
case 0x20: /* MOV CR?,<reg> */
- opcode = insn_fetch(u8, 1, eip);
+ opcode = insn_fetch(u8, 1, cs, eip);
modrm_reg |= (opcode >> 3) & 7;
modrm_rm |= (opcode >> 0) & 7;
reg = decode_register(modrm_rm, regs, 0);
@@ -1292,7 +1294,7 @@ static int emulate_privileged_op(struct
break;
case 0x21: /* MOV DR?,<reg> */
- opcode = insn_fetch(u8, 1, eip);
+ opcode = insn_fetch(u8, 1, cs, eip);
modrm_reg |= (opcode >> 3) & 7;
modrm_rm |= (opcode >> 0) & 7;
reg = decode_register(modrm_rm, regs, 0);
@@ -1302,7 +1304,7 @@ static int emulate_privileged_op(struct
break;
case 0x22: /* MOV <reg>,CR? */
- opcode = insn_fetch(u8, 1, eip);
+ opcode = insn_fetch(u8, 1, cs, eip);
modrm_reg |= (opcode >> 3) & 7;
modrm_rm |= (opcode >> 0) & 7;
reg = decode_register(modrm_rm, regs, 0);
@@ -1342,7 +1344,7 @@ static int emulate_privileged_op(struct
break;
case 0x23: /* MOV <reg>,DR? */
- opcode = insn_fetch(u8, 1, eip);
+ opcode = insn_fetch(u8, 1, cs, eip);
modrm_reg |= (opcode >> 3) & 7;
modrm_rm |= (opcode >> 0) & 7;
reg = decode_register(modrm_rm, regs, 0);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|