direct-io.hg

changeset 15214:5710c94e6539

Fix boot loader hangs with syslinux's 32-bit vesamenu module.

Syslinux can load 32-bit UI code for menu handling. But the core of
syslinux is still 16-bit. When it jumps to this 32-bit code, it
installs a set of 32-bit interrupt trap handlers which just bounce the
interrupts back to 16-bit mode.

But this plays badly with vmxassist. When running 16-bit boot loader
code, vmxassist installs its own trap handlers which bounce vPIC
interrupts back down to 16-bit mode. The trap handlers live at
int 0x20 to 0x2f, so when the 16-bit code tries to reprogram the vPIC,
vm86 rewrites the outb()s on the fly to set the irq_base vectors
accordingly.

So when syslinux enters 32-bit mode, the vPIC has still been
programmed to point to vmxassist's bounce traps, even though vmxassist
is no longer active once the guest is running 32-bit code. So the
wrong interrupts get delivered to the guest.

Fix this by restoring the rombios vPIC irq_base vectors when we leave
vmxassist mode, and returning the vmxassist traps when we reenter it.
These irq base values are hard-coded in this patch, but they are
already hard-coded in vmxassist so any boot code that relies on
changing them will already fail.

Signed-off-by: Stephen Tweedie <sct@redhat.com>
author kfraser@localhost.localdomain
date Mon Jun 04 15:32:11 2007 +0100 (2007-06-04)
parents d0dc12484bf2
children c09dbe98e4d6
files xen/arch/x86/hvm/vmx/vmx.c
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Mon Jun 04 15:21:12 2007 +0100
     1.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Mon Jun 04 15:32:11 2007 +0100
     1.3 @@ -2002,6 +2002,19 @@ static int vmx_assist(struct vcpu *v, in
     1.4              if ( vmx_world_restore(v, &c) != 0 )
     1.5                  goto error;
     1.6              v->arch.hvm_vmx.vmxassist_enabled = 1;
     1.7 +            /*
     1.8 +             * The 32-bit vmxassist vm86.c support code is hard-coded to
     1.9 +             * expect vPIC interrupts to arrive at interrupt traps 0x20-0x27
    1.10 +             * and 0x28-0x2f.  It bounces these to 16-bit boot code traps
    1.11 +             * 0x08-0x0f and 0x70-0x77.  But when the guest transitions
    1.12 +             * to true native 32-bit mode, vmxassist steps out of the
    1.13 +             * way and no such bouncing occurs; so we need to rewrite
    1.14 +             * the vPIC irq base to point directly to 0x08/0x70 (see
    1.15 +             * code just below).  So on re-entering 16-bit mode, we need
    1.16 +             * to reset the vPICs to go back to the 0x20/0x28 bounce traps.
    1.17 +             */
    1.18 +            v->domain->arch.hvm_domain.vpic[0].irq_base = 0x20;
    1.19 +            v->domain->arch.hvm_domain.vpic[1].irq_base = 0x28;
    1.20              return 1;
    1.21          }
    1.22          break;
    1.23 @@ -2020,6 +2033,12 @@ static int vmx_assist(struct vcpu *v, in
    1.24              if ( vmx_world_restore(v, &c) != 0 )
    1.25                  goto error;
    1.26              v->arch.hvm_vmx.vmxassist_enabled = 0;
    1.27 +            /*
    1.28 +             * See comment above about vmxassist 16/32-bit vPIC behaviour.
    1.29 +             * The irq_base values are hard-coded into vmxassist vm86.c.
    1.30 +             */
    1.31 +            v->domain->arch.hvm_domain.vpic[0].irq_base = 0x08;
    1.32 +            v->domain->arch.hvm_domain.vpic[1].irq_base = 0x70;
    1.33              return 1;
    1.34          }
    1.35          break;