direct-io.hg

changeset 15239:656b8175f4f2

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@intel.com>
Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
author kfraser@localhost.localdomain
date Fri Jun 08 11:19:55 2007 +0100 (2007-06-08)
parents 345ae2e61ba0
children 55230846b2f4
files tools/firmware/vmxassist/vm86.c tools/firmware/vmxassist/vm86.h xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/hvm/vpic.c xen/include/asm-x86/hvm/vmx/vmcs.h xen/include/public/hvm/vmx_assist.h
line diff
     1.1 --- a/tools/firmware/vmxassist/vm86.c	Thu Jun 07 20:02:27 2007 +0100
     1.2 +++ b/tools/firmware/vmxassist/vm86.c	Fri Jun 08 11:19:55 2007 +0100
     1.3 @@ -927,6 +927,7 @@ load_or_clear_seg(unsigned long sel, uin
     1.4  		load_seg(0, base, limit, arbytes);
     1.5  }
     1.6  
     1.7 +static unsigned char rm_irqbase[2];
     1.8  
     1.9  /*
    1.10   * Transition to protected mode
    1.11 @@ -936,6 +937,9 @@ protected_mode(struct regs *regs)
    1.12  {
    1.13  	extern char stack_top[];
    1.14  
    1.15 +	oldctx.rm_irqbase[0] = rm_irqbase[0];
    1.16 +	oldctx.rm_irqbase[1] = rm_irqbase[1];
    1.17 +
    1.18  	regs->eflags &= ~(EFLAGS_TF|EFLAGS_VM);
    1.19  
    1.20  	oldctx.eip = regs->eip;
    1.21 @@ -1187,6 +1191,7 @@ outbyte(struct regs *regs, unsigned pref
    1.22  			icw2[0] = 0;
    1.23  			printf("Remapping master: ICW2 0x%x -> 0x%x\n",
    1.24  				al, NR_EXCEPTION_HANDLER);
    1.25 +			rm_irqbase[0] = al;
    1.26  			al = NR_EXCEPTION_HANDLER;
    1.27  		}
    1.28  		break;
    1.29 @@ -1200,6 +1205,7 @@ outbyte(struct regs *regs, unsigned pref
    1.30  			icw2[1] = 0;
    1.31  			printf("Remapping slave: ICW2 0x%x -> 0x%x\n",
    1.32  				al, NR_EXCEPTION_HANDLER+8);
    1.33 +			rm_irqbase[1] = al;
    1.34  			al = NR_EXCEPTION_HANDLER+8;
    1.35  		}
    1.36  		break;
     2.1 --- a/tools/firmware/vmxassist/vm86.h	Thu Jun 07 20:02:27 2007 +0100
     2.2 +++ b/tools/firmware/vmxassist/vm86.h	Fri Jun 08 11:19:55 2007 +0100
     2.3 @@ -26,10 +26,6 @@
     2.4  
     2.5  #include <xen/hvm/vmx_assist.h>
     2.6  
     2.7 -#define	NR_EXCEPTION_HANDLER	32
     2.8 -#define	NR_INTERRUPT_HANDLERS	16
     2.9 -#define	NR_TRAPS		(NR_EXCEPTION_HANDLER+NR_INTERRUPT_HANDLERS)
    2.10 -
    2.11  #ifndef __ASSEMBLY__
    2.12  
    2.13  struct regs {
     3.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Jun 07 20:02:27 2007 +0100
     3.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Jun 08 11:19:55 2007 +0100
     3.3 @@ -2039,8 +2039,8 @@ enum { VMX_ASSIST_INVOKE = 0, VMX_ASSIST
     3.4  static int vmx_assist(struct vcpu *v, int mode)
     3.5  {
     3.6      struct vmx_assist_context c;
     3.7 -    u32 magic;
     3.8 -    u32 cp;
     3.9 +    struct hvm_hw_vpic *vpic = v->domain->arch.hvm_domain.vpic;
    3.10 +    u32 magic, cp;
    3.11  
    3.12      /* make sure vmxassist exists (this is not an error) */
    3.13      if (hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
    3.14 @@ -2074,20 +2074,11 @@ static int vmx_assist(struct vcpu *v, in
    3.15                  goto error;
    3.16              if ( vmx_world_restore(v, &c) != 0 )
    3.17                  goto error;
    3.18 +            v->arch.hvm_vmx.pm_irqbase[0] = vpic[0].irq_base;
    3.19 +            v->arch.hvm_vmx.pm_irqbase[1] = vpic[1].irq_base;
    3.20 +            vpic[0].irq_base = NR_EXCEPTION_HANDLER;
    3.21 +            vpic[1].irq_base = NR_EXCEPTION_HANDLER + 8;
    3.22              v->arch.hvm_vmx.vmxassist_enabled = 1;
    3.23 -            /*
    3.24 -             * The 32-bit vmxassist vm86.c support code is hard-coded to
    3.25 -             * expect vPIC interrupts to arrive at interrupt traps 0x20-0x27
    3.26 -             * and 0x28-0x2f.  It bounces these to 16-bit boot code traps
    3.27 -             * 0x08-0x0f and 0x70-0x77.  But when the guest transitions
    3.28 -             * to true native 32-bit mode, vmxassist steps out of the
    3.29 -             * way and no such bouncing occurs; so we need to rewrite
    3.30 -             * the vPIC irq base to point directly to 0x08/0x70 (see
    3.31 -             * code just below).  So on re-entering 16-bit mode, we need
    3.32 -             * to reset the vPICs to go back to the 0x20/0x28 bounce traps.
    3.33 -             */
    3.34 -            v->domain->arch.hvm_domain.vpic[0].irq_base = 0x20;
    3.35 -            v->domain->arch.hvm_domain.vpic[1].irq_base = 0x28;
    3.36              return 1;
    3.37          }
    3.38          break;
    3.39 @@ -2105,13 +2096,14 @@ static int vmx_assist(struct vcpu *v, in
    3.40                  goto error;
    3.41              if ( vmx_world_restore(v, &c) != 0 )
    3.42                  goto error;
    3.43 +            if ( v->arch.hvm_vmx.irqbase_mode ) {
    3.44 +                vpic[0].irq_base = c.rm_irqbase[0] & 0xf8;
    3.45 +                vpic[1].irq_base = c.rm_irqbase[1] & 0xf8;
    3.46 +            } else {
    3.47 +                vpic[0].irq_base = v->arch.hvm_vmx.pm_irqbase[0];
    3.48 +                vpic[1].irq_base = v->arch.hvm_vmx.pm_irqbase[1];
    3.49 +            }
    3.50              v->arch.hvm_vmx.vmxassist_enabled = 0;
    3.51 -            /*
    3.52 -             * See comment above about vmxassist 16/32-bit vPIC behaviour.
    3.53 -             * The irq_base values are hard-coded into vmxassist vm86.c.
    3.54 -             */
    3.55 -            v->domain->arch.hvm_domain.vpic[0].irq_base = 0x08;
    3.56 -            v->domain->arch.hvm_domain.vpic[1].irq_base = 0x70;
    3.57              return 1;
    3.58          }
    3.59          break;
     4.1 --- a/xen/arch/x86/hvm/vpic.c	Thu Jun 07 20:02:27 2007 +0100
     4.2 +++ b/xen/arch/x86/hvm/vpic.c	Fri Jun 08 11:19:55 2007 +0100
     4.3 @@ -174,7 +174,8 @@ static int vpic_intack(struct hvm_hw_vpi
     4.4      return irq;
     4.5  }
     4.6  
     4.7 -static void vpic_ioport_write(struct hvm_hw_vpic *vpic, uint32_t addr, uint32_t val)
     4.8 +static void vpic_ioport_write(
     4.9 +    struct hvm_hw_vpic *vpic, uint32_t addr, uint32_t val)
    4.10  {
    4.11      int priority, cmd, irq;
    4.12      uint8_t mask;
    4.13 @@ -265,6 +266,11 @@ static void vpic_ioport_write(struct hvm
    4.14              vpic->imr = val;
    4.15              break;
    4.16          case 1:
    4.17 +#if 1 /* Delete me when vmxassist is retired. */
    4.18 +            /* Which mode is irqbase programmed in? */
    4.19 +            current->arch.hvm_vmx.irqbase_mode =
    4.20 +                current->arch.hvm_vmx.vmxassist_enabled;
    4.21 +#endif
    4.22              /* ICW2 */
    4.23              vpic->irq_base = val & 0xf8;
    4.24              vpic->init_state++;
     5.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu Jun 07 20:02:27 2007 +0100
     5.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Jun 08 11:19:55 2007 +0100
     5.3 @@ -79,7 +79,11 @@ struct arch_vmx_struct {
     5.4      unsigned long        cstar;
     5.5  #endif
     5.6      unsigned long        efer;
     5.7 +
     5.8 +    /* Following fields are all specific to vmxassist. */
     5.9      unsigned long        vmxassist_enabled:1;
    5.10 +    unsigned long        irqbase_mode:1;
    5.11 +    unsigned char        pm_irqbase[2];
    5.12  };
    5.13  
    5.14  struct vmcs_struct *vmx_alloc_host_vmcs(void);
     6.1 --- a/xen/include/public/hvm/vmx_assist.h	Thu Jun 07 20:02:27 2007 +0100
     6.2 +++ b/xen/include/public/hvm/vmx_assist.h	Fri Jun 08 11:19:55 2007 +0100
     6.3 @@ -35,6 +35,10 @@
     6.4  
     6.5  #ifndef __ASSEMBLY__
     6.6  
     6.7 +#define NR_EXCEPTION_HANDLER    32
     6.8 +#define NR_INTERRUPT_HANDLERS   16
     6.9 +#define NR_TRAPS        (NR_EXCEPTION_HANDLER+NR_INTERRUPT_HANDLERS)
    6.10 +
    6.11  union vmcs_arbytes {
    6.12      struct arbyte_fields {
    6.13          unsigned int seg_type : 4,
    6.14 @@ -98,6 +102,8 @@ struct vmx_assist_context {
    6.15      uint32_t  ldtr_limit;
    6.16      uint32_t  ldtr_base;
    6.17      union vmcs_arbytes ldtr_arbytes;
    6.18 +
    6.19 +    unsigned char rm_irqbase[2];
    6.20  };
    6.21  typedef struct vmx_assist_context vmx_assist_context_t;
    6.22