WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [patch 2/2] Preserve correct PIC vectors across Xen vmxassis

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [patch 2/2] Preserve correct PIC vectors across Xen vmxassist 16/32-bit transitions
From: "Stephen C. Tweedie" <sct@xxxxxxxxxx>
Date: Tue, 22 May 2007 16:42:36 +0100
Delivery-date: Tue, 22 May 2007 08:41:28 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <1179848292.8438.40.camel@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Organization: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 03798903
References: <1179848292.8438.40.camel@xxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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