Hi,
On Tue, 2007-05-22 at 14:54 +0100, Stephen C. Tweedie wrote:
> The following two patches --- one to the HV, one to the tools --- allow
> rawhide isos to boot under Xen full virtualisation.
And this is the userland tools side of the fix.
> So the fix here is ... secondly to have vmxassist use that sequence to reset
> the PIC
> vectors appropriately whenever we transition between 16 and 32-bit mode.
This code teaches vmxassist:
1) to remember how the guest has set up the virtual PIC interrupt
vectors; and
2) to reprogram the vPIC to point to the true guest vector when entering
32-bit mode, and to point back to the vmxassist bounce-irq traps when
reentering 16-bit mode.
--Stephen
--- xen-3.1.0-testing.hg-rc7.irq/tools/firmware/vmxassist/vm86.c.~1~
2007-05-03 17:49:28.000000000 +0100
+++ xen-3.1.0-testing.hg-rc7.irq/tools/firmware/vmxassist/vm86.c
2007-05-22 14:03:59.000000000 +0100
@@ -1020,6 +1020,7 @@ real_mode(struct regs *regs)
* when we transitioned to protected mode and we should abandon the
* emulator. No instructions are emulated when in VM86_PROTECTED mode.
*/
+static void reset_PIC_translation(int mode);
void
set_mode(struct regs *regs, enum vm86_mode newmode)
{
@@ -1028,6 +1029,7 @@ set_mode(struct regs *regs, enum vm86_mo
if ((mode == VM86_PROTECTED_TO_REAL) ||
(mode == VM86_REAL_TO_PROTECTED)) {
regs->eflags &= ~EFLAGS_TF;
+ reset_PIC_translation(newmode);
real_mode(regs);
} else if (mode != VM86_REAL)
panic("unexpected real mode transition");
@@ -1058,6 +1060,7 @@ set_mode(struct regs *regs, enum vm86_mo
case VM86_PROTECTED:
if (mode != VM86_REAL_TO_PROTECTED)
panic("unexpected protected mode transition");
+ reset_PIC_translation(newmode);
protected_mode(regs);
break;
}
@@ -1157,25 +1160,16 @@ interrupt(struct regs *regs, int n)
* careful and make sure the emulated program isn't remapping the
* interrupt vectors. The following simple state machine catches
* these attempts and rewrites them.
+ *
+ * We also have to be careful to record the intended vector, so that we
+ * can restore it on transition to 32-bit mode.
*/
-static int
-outbyte(struct regs *regs, unsigned prefix, unsigned opc)
+
+static int PIC_vector[2] = {0};
+
+static int translate_PIC_vector(int port, int al)
{
static char icw2[2] = { 0 };
- int al, port;
-
- switch (opc) {
- case 0xE6: /* outb port, al */
- port = fetch8(regs);
- break;
- case 0xEE: /* outb (%dx), al */
- port = MASK16(regs->edx);
- break;
- default:
- return 0;
- }
-
- al = regs->eax & 0xFF;
switch (port) {
case PIC_MASTER + PIC_CMD:
@@ -1187,6 +1181,7 @@ outbyte(struct regs *regs, unsigned pref
icw2[0] = 0;
printf("Remapping master: ICW2 0x%x -> 0x%x\n",
al, NR_EXCEPTION_HANDLER);
+ PIC_vector[0] = al & 0xf8;
al = NR_EXCEPTION_HANDLER;
}
break;
@@ -1200,11 +1195,58 @@ outbyte(struct regs *regs, unsigned pref
icw2[1] = 0;
printf("Remapping slave: ICW2 0x%x -> 0x%x\n",
al, NR_EXCEPTION_HANDLER+8);
+ PIC_vector[1] = al & 0xf8;
al = NR_EXCEPTION_HANDLER+8;
}
break;
+ default:
+ return 0;
+ }
+
+ outb(port, al);
+ return 1;
+}
+
+static void reset_PIC_translation(int mode)
+{
+ int vec0, vec1;
+
+ if (mode == VM86_PROTECTED)
+ vec0 = PIC_vector[0], vec1 = PIC_vector[1];
+ else if (mode == VM86_REAL)
+ vec0 = NR_EXCEPTION_HANDLER, vec1 = NR_EXCEPTION_HANDLER+8;
+ else
+ panic("reset_PIC_translation");
+ /* Use a non-standard, modified PIC initialisation sequence
+ * (supported by the HV vpic.c) to rewrite the icw2 irq vector
+ * without fully reinitialising the entire PIC state */
+ outb(0x20, 0xff);
+ outb(0x21, vec0);
+ outb(0xa0, 0xff);
+ outb(0xa1, vec1);
+}
+
+static int
+outbyte(struct regs *regs, unsigned prefix, unsigned opc)
+{
+ int al, port;
+
+ switch (opc) {
+ case 0xE6: /* outb port, al */
+ port = fetch8(regs);
+ break;
+ case 0xEE: /* outb (%dx), al */
+ port = MASK16(regs->edx);
+ break;
+ default:
+ return 0;
}
+ al = regs->eax & 0xFF;
+
+ if (translate_PIC_vector(port, al))
+ return 1;
+
outb(port, al);
return 1;
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|