[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] hvm: Respect irqbase set by protected mode in mode switching with VMXAssist.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1181297995 -3600
# Node ID 656b8175f4f24b5bb3a761e62c496075510914ed
# Parent  345ae2e61ba0130cf4913fee13b378c4e21d24e7
hvm: Respect irqbase set by protected mode in mode switching with VMXAssist.

RHEL4U4 PAE SMP guest currently crashes, and we found changeset 15214
introduced it. This patch fixes it.

Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
---
 tools/firmware/vmxassist/vm86.c     |    6 ++++++
 tools/firmware/vmxassist/vm86.h     |    4 ----
 xen/arch/x86/hvm/vmx/vmx.c          |   34 +++++++++++++---------------------
 xen/arch/x86/hvm/vpic.c             |    8 +++++++-
 xen/include/asm-x86/hvm/vmx/vmcs.h  |    4 ++++
 xen/include/public/hvm/vmx_assist.h |    6 ++++++
 6 files changed, 36 insertions(+), 26 deletions(-)

diff -r 345ae2e61ba0 -r 656b8175f4f2 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Thu Jun 07 20:02:27 2007 +0100
+++ b/tools/firmware/vmxassist/vm86.c   Fri Jun 08 11:19:55 2007 +0100
@@ -927,6 +927,7 @@ load_or_clear_seg(unsigned long sel, uin
                load_seg(0, base, limit, arbytes);
 }
 
+static unsigned char rm_irqbase[2];
 
 /*
  * Transition to protected mode
@@ -935,6 +936,9 @@ protected_mode(struct regs *regs)
 protected_mode(struct regs *regs)
 {
        extern char stack_top[];
+
+       oldctx.rm_irqbase[0] = rm_irqbase[0];
+       oldctx.rm_irqbase[1] = rm_irqbase[1];
 
        regs->eflags &= ~(EFLAGS_TF|EFLAGS_VM);
 
@@ -1187,6 +1191,7 @@ outbyte(struct regs *regs, unsigned pref
                        icw2[0] = 0;
                        printf("Remapping master: ICW2 0x%x -> 0x%x\n",
                                al, NR_EXCEPTION_HANDLER);
+                       rm_irqbase[0] = al;
                        al = NR_EXCEPTION_HANDLER;
                }
                break;
@@ -1200,6 +1205,7 @@ outbyte(struct regs *regs, unsigned pref
                        icw2[1] = 0;
                        printf("Remapping slave: ICW2 0x%x -> 0x%x\n",
                                al, NR_EXCEPTION_HANDLER+8);
+                       rm_irqbase[1] = al;
                        al = NR_EXCEPTION_HANDLER+8;
                }
                break;
diff -r 345ae2e61ba0 -r 656b8175f4f2 tools/firmware/vmxassist/vm86.h
--- a/tools/firmware/vmxassist/vm86.h   Thu Jun 07 20:02:27 2007 +0100
+++ b/tools/firmware/vmxassist/vm86.h   Fri Jun 08 11:19:55 2007 +0100
@@ -25,10 +25,6 @@
 #endif
 
 #include <xen/hvm/vmx_assist.h>
-
-#define        NR_EXCEPTION_HANDLER    32
-#define        NR_INTERRUPT_HANDLERS   16
-#define        NR_TRAPS                
(NR_EXCEPTION_HANDLER+NR_INTERRUPT_HANDLERS)
 
 #ifndef __ASSEMBLY__
 
diff -r 345ae2e61ba0 -r 656b8175f4f2 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Jun 07 20:02:27 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Jun 08 11:19:55 2007 +0100
@@ -2039,8 +2039,8 @@ static int vmx_assist(struct vcpu *v, in
 static int vmx_assist(struct vcpu *v, int mode)
 {
     struct vmx_assist_context c;
-    u32 magic;
-    u32 cp;
+    struct hvm_hw_vpic *vpic = v->domain->arch.hvm_domain.vpic;
+    u32 magic, cp;
 
     /* make sure vmxassist exists (this is not an error) */
     if (hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
@@ -2074,20 +2074,11 @@ static int vmx_assist(struct vcpu *v, in
                 goto error;
             if ( vmx_world_restore(v, &c) != 0 )
                 goto error;
+            v->arch.hvm_vmx.pm_irqbase[0] = vpic[0].irq_base;
+            v->arch.hvm_vmx.pm_irqbase[1] = vpic[1].irq_base;
+            vpic[0].irq_base = NR_EXCEPTION_HANDLER;
+            vpic[1].irq_base = NR_EXCEPTION_HANDLER + 8;
             v->arch.hvm_vmx.vmxassist_enabled = 1;
-            /*
-             * The 32-bit vmxassist vm86.c support code is hard-coded to
-             * expect vPIC interrupts to arrive at interrupt traps 0x20-0x27
-             * and 0x28-0x2f.  It bounces these to 16-bit boot code traps
-             * 0x08-0x0f and 0x70-0x77.  But when the guest transitions
-             * to true native 32-bit mode, vmxassist steps out of the
-             * way and no such bouncing occurs; so we need to rewrite
-             * the vPIC irq base to point directly to 0x08/0x70 (see
-             * code just below).  So on re-entering 16-bit mode, we need
-             * to reset the vPICs to go back to the 0x20/0x28 bounce traps.
-             */
-            v->domain->arch.hvm_domain.vpic[0].irq_base = 0x20;
-            v->domain->arch.hvm_domain.vpic[1].irq_base = 0x28;
             return 1;
         }
         break;
@@ -2105,13 +2096,14 @@ static int vmx_assist(struct vcpu *v, in
                 goto error;
             if ( vmx_world_restore(v, &c) != 0 )
                 goto error;
+            if ( v->arch.hvm_vmx.irqbase_mode ) {
+                vpic[0].irq_base = c.rm_irqbase[0] & 0xf8;
+                vpic[1].irq_base = c.rm_irqbase[1] & 0xf8;
+            } else {
+                vpic[0].irq_base = v->arch.hvm_vmx.pm_irqbase[0];
+                vpic[1].irq_base = v->arch.hvm_vmx.pm_irqbase[1];
+            }
             v->arch.hvm_vmx.vmxassist_enabled = 0;
-            /*
-             * See comment above about vmxassist 16/32-bit vPIC behaviour.
-             * The irq_base values are hard-coded into vmxassist vm86.c.
-             */
-            v->domain->arch.hvm_domain.vpic[0].irq_base = 0x08;
-            v->domain->arch.hvm_domain.vpic[1].irq_base = 0x70;
             return 1;
         }
         break;
diff -r 345ae2e61ba0 -r 656b8175f4f2 xen/arch/x86/hvm/vpic.c
--- a/xen/arch/x86/hvm/vpic.c   Thu Jun 07 20:02:27 2007 +0100
+++ b/xen/arch/x86/hvm/vpic.c   Fri Jun 08 11:19:55 2007 +0100
@@ -174,7 +174,8 @@ static int vpic_intack(struct hvm_hw_vpi
     return irq;
 }
 
-static void vpic_ioport_write(struct hvm_hw_vpic *vpic, uint32_t addr, 
uint32_t val)
+static void vpic_ioport_write(
+    struct hvm_hw_vpic *vpic, uint32_t addr, uint32_t val)
 {
     int priority, cmd, irq;
     uint8_t mask;
@@ -265,6 +266,11 @@ static void vpic_ioport_write(struct hvm
             vpic->imr = val;
             break;
         case 1:
+#if 1 /* Delete me when vmxassist is retired. */
+            /* Which mode is irqbase programmed in? */
+            current->arch.hvm_vmx.irqbase_mode =
+                current->arch.hvm_vmx.vmxassist_enabled;
+#endif
             /* ICW2 */
             vpic->irq_base = val & 0xf8;
             vpic->init_state++;
diff -r 345ae2e61ba0 -r 656b8175f4f2 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Thu Jun 07 20:02:27 2007 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Fri Jun 08 11:19:55 2007 +0100
@@ -79,7 +79,11 @@ struct arch_vmx_struct {
     unsigned long        cstar;
 #endif
     unsigned long        efer;
+
+    /* Following fields are all specific to vmxassist. */
     unsigned long        vmxassist_enabled:1;
+    unsigned long        irqbase_mode:1;
+    unsigned char        pm_irqbase[2];
 };
 
 struct vmcs_struct *vmx_alloc_host_vmcs(void);
diff -r 345ae2e61ba0 -r 656b8175f4f2 xen/include/public/hvm/vmx_assist.h
--- a/xen/include/public/hvm/vmx_assist.h       Thu Jun 07 20:02:27 2007 +0100
+++ b/xen/include/public/hvm/vmx_assist.h       Fri Jun 08 11:19:55 2007 +0100
@@ -34,6 +34,10 @@
 #define VMXASSIST_OLD_CONTEXT (VMXASSIST_NEW_CONTEXT + 4)
 
 #ifndef __ASSEMBLY__
+
+#define NR_EXCEPTION_HANDLER    32
+#define NR_INTERRUPT_HANDLERS   16
+#define NR_TRAPS        (NR_EXCEPTION_HANDLER+NR_INTERRUPT_HANDLERS)
 
 union vmcs_arbytes {
     struct arbyte_fields {
@@ -98,6 +102,8 @@ struct vmx_assist_context {
     uint32_t  ldtr_limit;
     uint32_t  ldtr_base;
     union vmcs_arbytes ldtr_arbytes;
+
+    unsigned char rm_irqbase[2];
 };
 typedef struct vmx_assist_context vmx_assist_context_t;
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.