# 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
|