Skip to contentSkip to conversation

Add more vmxassist opcodes for Ubuntu 7.0.4 support

PATCH In review Ben Guthro 2 participants 4 messages Oct 24, 2007 – Oct 25, 2007

lore
Share & tools
lore

Ben Guthro

author
#0 lore raw

PATCH 1/1 Add more vmxassist opcodes for Ubuntu 7.0.4 support

Add more opcodes to the vmxassist emulation sufficient to boot Ubuntu 7.04.

Add more opcodes to the vmxassist emulation sufficient to boot Ubuntu 7.04.

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

author
#1 lore raw

Attached description instead of patch. please find patch attached.

Quoted 11 lines · Ben Guthro

Add more opcodes to the vmxassist emulation sufficient to boot Ubuntu 7.04.

------------------------------------------------------------------------

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

tools/firmware/vmxassist/machine.h +5 -0
diff -r 30d246cbc009 tools/firmware/vmxassist/machine.h
@@ -38,10 +38,15 @@
 #define CR4_PSE		(1 << 4)
 #define CR4_PAE		(1 << 5)
 
+#define EFLAGS_CF	(1 << 0)
+#define EFLAGS_PF	(1 << 2)
+#define EFLAGS_AF	(1 << 4)
 #define EFLAGS_ZF	(1 << 6)
+#define EFLAGS_SF	(1 << 7)
 #define EFLAGS_TF	(1 << 8)
 #define EFLAGS_IF	(1 << 9)
 #define EFLAGS_DF	(1 << 10)
+#define EFLAGS_OF	(1 << 11)
 #define EFLAGS_IOPL	(3 << 12)
 #define EFLAGS_VM	((1 << 17) | EFLAGS_IOPL)
 #define EFLAGS_VIF	(1 << 19)
tools/firmware/vmxassist/vm86.c +267 -0

321 lines not on this page · raw message

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

#2 lore raw

RE: [PATCH] Add more vmxassist opcodes for Ubuntu 7.0.4support

This patch does not follow VMX Assist coding style, we use tab instead of spaces.

-Xin

________________________________

From: [email protected] [mailto:[email protected]] On Behalf Of Ben Guthro
Sent: 2007年10月25日 6:22
To: xen-devel
Cc: Gary Grebus
Subject: Re: [Xen-devel] [PATCH] Add more vmxassist opcodes for Ubuntu 7.0.4support

Attached description instead of patch. please find patch attached.

Ben Guthro wrote:

Add more opcodes to the vmxassist emulation sufficient to boot Ubuntu 7.04.

________________________________

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

author
#3 lore raw

Re: [PATCH] Add more vmxassist opcodes for Ubuntu 7.0.4support

I have reformatted the patch to use tabs instead of spaces. Please find the revised version of this patch attached.

Please note that I have only changed formatting of this patch, and no contents have changed.

Ben

Quoted 31 lines · Xin B

This patch does not follow VMX Assist coding style, we use tab instead of spaces.

-Xin

------------------------------------------------------------------------

*From:* [email protected] [mailto:[email protected]] *On Behalf Of *Ben Guthro *Sent:* 2007年10月25日 6:22
*To:* xen-devel
*Cc:* Gary Grebus
*Subject:* Re: [Xen-devel] [PATCH] Add more vmxassist opcodes for Ubuntu 7.0.4support

Attached description instead of patch. please find patch attached.

Ben Guthro wrote:

Add more opcodes to the vmxassist emulation sufficient to boot Ubuntu 7.04.

<mailto:[email protected]>

<mailto:[email protected]>

Quoted 8 lines

------------------------------------------------------------------------

_______________________________________________
Xen-devel mailing list
[email protected] <mailto:[email protected]>
http://lists.xensource.com/xen-devel

tools/firmware/vmxassist/machine.h +5 -0
diff -r 30d246cbc009 tools/firmware/vmxassist/machine.h
@@ -38,10 +38,15 @@
 #define CR4_PSE		(1 << 4)
 #define CR4_PAE		(1 << 5)
 
+#define EFLAGS_CF	(1 << 0)
+#define EFLAGS_PF	(1 << 2)
+#define EFLAGS_AF	(1 << 4)
 #define EFLAGS_ZF	(1 << 6)
+#define EFLAGS_SF	(1 << 7)
 #define EFLAGS_TF	(1 << 8)
 #define EFLAGS_IF	(1 << 9)
 #define EFLAGS_DF	(1 << 10)
+#define EFLAGS_OF	(1 << 11)
 #define EFLAGS_IOPL	(3 << 12)
 #define EFLAGS_VM	((1 << 17) | EFLAGS_IOPL)
 #define EFLAGS_VIF	(1 << 19)
tools/firmware/vmxassist/vm86.c +103 -0

115 lines not on this page · raw message

		regs->eflags &= ~EFLAGS_ZF;

}

+static void set_eflags_add(unsigned hi_bit_mask, unsigned v1, unsigned v2,
+ unsigned result, struct regs *regs)
+{
+ int bit_count;
+ unsigned tmp;
+ unsigned full_mask;
+ unsigned nonsign_mask;
+
+ /* Carry out of high order bit? */
+ if ( v1 & v2 & hi_bit_mask )
+ regs->eflags |= EFLAGS_CF;
+ else
+ regs->eflags &= ~EFLAGS_CF;
+
+ /* Even parity in least significant byte? */
+ tmp = result & 0xff;
+ for (bit_count = 0; tmp != 0; bit_count++)
+ tmp &= (tmp - 1);
+
+ if (bit_count & 1)
+ regs->eflags &= ~EFLAGS_PF;
+ else
+ regs->eflags |= EFLAGS_PF;
+
+ /* Carry out of least significant BCD digit? */
+ if ( v1 & v2 & (1<<3) )
+ regs->eflags |= EFLAGS_AF;
+ else
+ regs->eflags &= ~EFLAGS_AF;
+
+ /* Result is zero? */
+ full_mask = (hi_bit_mask - 1) | hi_bit_mask;
+ set_eflags_ZF(full_mask, result, regs);
+
+ /* Sign of result? */
+ if ( result & hi_bit_mask )
+ regs->eflags |= EFLAGS_SF;
+ else
+ regs->eflags &= ~EFLAGS_SF;
+
+ /* Carry out of highest non-sign bit? */
+ nonsign_mask = (hi_bit_mask >> 1) & ~hi_bit_mask;
+ if ( v1 & v2 & hi_bit_mask )
+ regs->eflags |= EFLAGS_OF;
+ else
+ regs->eflags &= ~EFLAGS_OF;
+
+}
+
/*
* We need to handle cmp opcodes that address memory beyond the 64KB
* segment limit that VM8086 mode enforces.
@@ -787,6 +939,82 @@ test(struct regs *regs, unsigned prefix,

	/* other test opcodes ... */
	}

+
+ return 1;
+}
+
+/*
+ * We need to handle add opcodes that address memory beyond the 64KB
+ * segment limit that VM8086 mode enforces.
+ */
+static int
+add(struct regs *regs, unsigned prefix, unsigned opc)
+{
+ unsigned eip = regs->eip - 1;
+ unsigned modrm = fetch8(regs);
+ unsigned addr = operand(prefix, regs, modrm);
+ unsigned r = (modrm >> 3) & 7;
+
+ unsigned val1 = 0;
+ unsigned val2 = 0;
+ unsigned result = 0;
+ unsigned hi_bit;
+
+ if ((modrm & 0xC0) == 0xC0) /* no registers */
+ return 0;
+
+ switch (opc) {
+ case 0x00: /* addr32 add r8, r/m8 */
+ val1 = getreg8(regs, r);
+ val2 = read8(addr);
+ result = val1 + val2;
+ write8(addr, result);
+ TRACE((regs, regs->eip - eip,
+ "addb %%e%s, *0x%x", rnames[r], addr));
+ break;
+
+ case 0x01: /* addr32 add r16, r/m16 */
+ if (prefix & DATA32) {
+ val1 = getreg32(regs, r);
+ val2 = read32(addr);
+ result = val1 + val2;
+ write32(addr, result);
+ TRACE((regs, regs->eip - eip,
+ "addl %%e%s, *0x%x", rnames[r], addr));
+ } else {
+ val1 = getreg16(regs, r);
+ val2 = read16(addr);
+ result = val1 + val2;
+ write16(addr, result);
+ TRACE((regs, regs->eip - eip,
+ "addw %%e%s, *0x%x", rnames[r], addr));
+ }
+ break;
+
+ case 0x03: /* addr32 add r/m16, r16 */
+ if (prefix & DATA32) {
+ val1 = getreg32(regs, r);
+ val2 = read32(addr);
+ result = val1 + val2;
+ setreg32(regs, r, result);
+ TRACE((regs, regs->eip - eip,
+ "addl *0x%x, %%e%s", addr, rnames[r]));
+ } else {
+ val1 = getreg16(regs, r);
+ val2 = read16(addr);
+ result = val1 + val2;
+ setreg16(regs, r, result);
+ TRACE((regs, regs->eip - eip,
+ "addw *0x%x, %%%s", addr, rnames[r]));
+ }
+ break;
+ }
+
+ if (opc == 0x00)
+ hi_bit = (1<<7);
+ else
+ hi_bit = (prefix & DATA32) ? (1<<31) : (1<<15);
+ set_eflags_add(hi_bit, val1, val2, result, regs);

	return 1;

}
@@ -1314,6 +1542,18 @@ opcode(struct regs *regs)

	for (;;) {
		switch ((opc = fetch8(regs))) {

+
+ case 0x00: /* addr32 add r8, r/m8 */
+ case 0x01: /* addr32 add r16, r/m16 */
+ case 0x03: /* addr32 add r/m16, r16 */
+ if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
+ goto invalid;
+ if ((prefix & ADDR32) == 0)
+ goto invalid;
+ if (!add(regs, prefix, opc))
+ goto invalid;
+ return OPC_EMULATED;
+

		case 0x07: /* pop %es */
			regs->ves = (prefix & DATA32) ?
				pop32(regs) : pop16(regs);
@@ -1510,6 +1750,21 @@ opcode(struct regs *regs)
			return OPC_EMULATED;
		}

+ case 0xA4: /* movsb */
+ case 0xA5: /* movsw */
+ if ((prefix & ADDR32) == 0)
+ goto invalid;
+ if (!movs(regs, prefix, opc))
+ goto invalid;
+ return OPC_EMULATED;
+
+ case 0xAD: /* lodsw */
+ if ((prefix & ADDR32) == 0)
+ goto invalid;
+ if (!lods(regs, prefix, opc))
+ goto invalid;
+ return OPC_EMULATED;
+

		case 0xBB: /* mov bx, imm16 */
		{
			int data;
@@ -1627,6 +1882,11 @@ opcode(struct regs *regs)
			/* Do something power-saving here! */
			return OPC_EMULATED;

+ case 0xF3: /* rep/repe/repz */
+ TRACE((regs, regs->eip - eip, "rep"));
+ prefix |= REP;
+ continue;
+

		case 0xF6: /* addr32 testb $imm, r/m8 */
			if (!(prefix & ADDR32))
				goto invalid;
@@ -1660,6 +1920,7 @@ emulate(struct regs *regs)
 {
	unsigned flteip;
	int nemul = 0;

+ unsigned ip;

	/* emulate as many instructions as possible */
	while (opcode(regs) != OPC_INVALID)
@@ -1668,6 +1929,12 @@ emulate(struct regs *regs)
	/* detect the case where we are not making progress */
	if (nemul == 0 && prev_eip == regs->eip) {
		flteip = address(regs, MASK16(regs->cs), regs->eip);

+
+ printf("Undecoded sequence: \n");
+ for (ip=flteip; ip < flteip+16; ip++)
+ printf("0x%02x ", read8(ip));
+ printf("\n");
+

		panic("Unknown opcode at %04x:%04x=0x%x",
			MASK16(regs->cs), regs->eip, flteip);
	} else

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel