[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [patch 2/2] Preserve correct PIC vectors across Xen vmxassist 16/32-bit transitions
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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |