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

[Xen-changelog] [xen-unstable] x86 vmx: Remove vmxassist.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86 vmx: Remove vmxassist.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 06 Feb 2008 10:40:07 -0800
Delivery-date: Wed, 06 Feb 2008 10:40:14 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1202299675 0
# Node ID 9d0e86d8c1d1360be64921928ae98b3693adfc73
# Parent  f8db1c6baad90b038e1cf4f91c3a829793344798
x86 vmx: Remove vmxassist.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 tools/firmware/README                 |   83 -
 tools/firmware/vmxassist/Makefile     |   81 -
 tools/firmware/vmxassist/gen.c        |   52 
 tools/firmware/vmxassist/head.S       |   94 -
 tools/firmware/vmxassist/machine.h    |  199 ---
 tools/firmware/vmxassist/setup.c      |  337 -----
 tools/firmware/vmxassist/trap.S       |  179 ---
 tools/firmware/vmxassist/util.c       |  430 -------
 tools/firmware/vmxassist/util.h       |   45 
 tools/firmware/vmxassist/vm86.c       | 1992 ----------------------------------
 tools/firmware/vmxassist/vm86.h       |   64 -
 tools/firmware/vmxassist/vmxassist.ld |   32 
 xen/include/public/hvm/vmx_assist.h   |  122 --
 tools/firmware/Makefile               |    1 
 tools/firmware/hvmloader/Makefile     |    3 
 tools/firmware/hvmloader/config.h     |    1 
 tools/firmware/hvmloader/hvmloader.c  |   28 
 xen/arch/x86/Rules.mk                 |    5 
 xen/arch/x86/hvm/hvm.c                |   13 
 xen/arch/x86/hvm/vmx/Makefile         |    2 
 xen/arch/x86/hvm/vmx/vmx.c            |  298 -----
 xen/arch/x86/hvm/vmx/x86_32/exits.S   |    4 
 xen/arch/x86/hvm/vmx/x86_64/exits.S   |    4 
 xen/arch/x86/hvm/vpic.c               |    5 
 xen/include/asm-x86/hvm/vmx/vmcs.h    |   13 
 25 files changed, 5 insertions(+), 4082 deletions(-)

diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/Makefile
--- a/tools/firmware/Makefile   Tue Feb 05 23:27:12 2008 +0000
+++ b/tools/firmware/Makefile   Wed Feb 06 12:07:55 2008 +0000
@@ -9,7 +9,6 @@ SUBDIRS :=
 SUBDIRS :=
 SUBDIRS += rombios rombios/32bit
 SUBDIRS += vgabios
-SUBDIRS += vmxassist
 SUBDIRS += extboot
 #SUBDIRS += etherboot
 SUBDIRS += hvmloader
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/README
--- a/tools/firmware/README     Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-Domain firmware support
------------------------
-
-One of the key advantages of full virtualization hardware support (such
-as Intel's VT or AMD's SVM extensions) is the ability to run unmodified
-guest operating systems.  However, since most OSes rely on BIOS support
-during their early bringup, we need to provide a surrogate ROMBIOS and
-VGABIOS firmware layer.
-
-What's more, we need to support real-mode which is required by
-the firmware and bootstrap loaders. Real-mode support is especially
-challenging for Intel's VMX (VT) enabled CPUs where there is no real-mode
-support for VMX guest partitions. In this case you either have to do full
-emulation (full real-mode emulator; more complete but potentially slower)
-or partial emulation (use the VM8086 extensions, emulate only those
-instructions that are missing; faster, but potentially incomplete). The
-vmxassist code in this subdirectory uses the later approach because it
-is smaller and faster.
-
-The approach is relatively straight forward. Vmxloader contains three
-payloads (rombios, vgabios and vmxassist) and it is bootstrapped as any
-other 32-bit OS. Vmxloader copies its payloads to the addresses below
-and transfers control to vmxassist.
-
-       vgabios         VGABIOS (standard and Cirrus).
-                       Resides at C000:0000.
-
-       vmxassist       VMXAssist VM86 realmode emulator for VMX.
-                       Resides at D000:0000.
-
-       rombios         ROMBIOS code. Derived from Bochs.
-                       Resides at F000:0000
-
-Vmxassist first sets up it own world (GDT, IDT, TR, etc), enables
-VM8086 and then transfers control to F000:FFF0 and executes 16-bit
-code. Unsupported instructions cause a general protection failure at
-which point vmxassist kicks in and emulates the offending instruction.
-Whever the emulated code transitions to 32-bit protected mode, vmxassist
-will go away. Whenever 32-bit protected code transitions to real-mode,
-Xen/VMX will detect this and transfer control to vmxassist.
-
-Most of the vmxassist complexity comes from properly handling the
-real to protected mode and protected to real mode transitions and
-the proper emulation of the segment registers. Even though the Intel
-manual clearly states that you should immediately perform a jmp far
-after a mode transition, many operating systems execute additional
-instructions and some even refer to segment selectors and pop data
-from the stack. Vmxassist contains a number of work arounds for these
-OSes.
-
-
-Acknowledgements
-----------------
-
-The rombios was taken (largely unmodified) from Bochs, which was written
-by Kevin Lawton. The VGABIOS was written by Christophe Bothamy. Arun Sharma,
-Asit Mallick and Nitin Kamble (Intel) provided the E820 patches and lots
-of useful feedback.
-
-
-Contact
--------
-
-Leendert van Doorn
-IBM T.J. Watson Research Center
-19 Skyline Drive
-Hawthorne, NY 10532
-leendert@xxxxxxxxxxxxxx
-
-
-Tested Operating Systems
-------------------------
-
-Since vmxassist uses partial emulation, it may always miss opcodes
-that are required by a particular OS. The table below lists the OSes
-I have tried.  The Install column indicates a full CD/DVD install into
-a VMX partition. The Disk column indicates booting from prefabricated
-disk image.
-
-Operating System                       Install         Disk
-------------------------------------------------------------
-RedHat Enterprise Linux (RHEL3_U5)     Yes             Yes
-Fedora Code (FC3)                      (-)             Yes
-FreeBSD 5.3                            (-)             Yes
-MS-DOS 5.0                             (-)             Yes
-
-(-) not tried yet
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Tue Feb 05 23:27:12 2008 +0000
+++ b/tools/firmware/hvmloader/Makefile Wed Feb 06 12:07:55 2008 +0000
@@ -50,11 +50,10 @@ acpi/acpi.a:
 acpi/acpi.a:
        $(MAKE) -C acpi
 
-roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin 
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin 
../etherboot/eb-roms.h ../extboot/extboot.bin
+roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin 
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../etherboot/eb-roms.h 
../extboot/extboot.bin
        sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
        sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
        sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin 
>> roms.h
-       sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
        cat ../etherboot/eb-roms.h >> roms.h
        sh ./mkhex extboot ../extboot/extboot.bin >> roms.h
 
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Tue Feb 05 23:27:12 2008 +0000
+++ b/tools/firmware/hvmloader/config.h Wed Feb 06 12:07:55 2008 +0000
@@ -21,7 +21,6 @@
 #define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
 #define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
 #define ETHERBOOT_PHYSICAL_ADDRESS    0x000C8000
-#define VMXASSIST_PHYSICAL_ADDRESS    0x000D0000
 #define EXTBOOT_PHYSICAL_ADDRESS      0x000DF800
 #define SMBIOS_PHYSICAL_ADDRESS       0x000E9000
 #define SMBIOS_MAXIMUM_SIZE           0x00001000
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Tue Feb 05 23:27:12 2008 +0000
+++ b/tools/firmware/hvmloader/hvmloader.c      Wed Feb 06 12:07:55 2008 +0000
@@ -1,5 +1,5 @@
 /*
- * hvmloader.c: HVM ROMBIOS/VGABIOS/ACPI/VMXAssist image loader.
+ * hvmloader.c: HVM bootloader.
  *
  * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
  * Copyright (c) 2005, International Business Machines Corporation.
@@ -40,7 +40,6 @@ asm(
     "    cli                         \n"
     "    movl $stack_top,%esp        \n"
     "    movl %esp,%ebp              \n"
-    "    movl %eax,initial_eax       \n"
     "    call main                   \n"
     /* Relocate real-mode trampoline to 0x0. */
     "    mov  $trampoline_start,%esi \n"
@@ -98,8 +97,6 @@ asm(
     "stack_top:                      \n"
     );
 
-static unsigned int initial_eax;
-
 void create_mp_tables(void);
 int hvm_write_smbios_tables(void);
 
@@ -122,12 +119,6 @@ check_amd(void)
         "=d" (*(int *)(&id[4]))
         : "a" (0) );
     return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
-}
-
-static int
-use_vmxassist(void)
-{
-    return !check_amd() && !initial_eax;
 }
 
 static void
@@ -506,10 +497,6 @@ int main(void)
         printf(" %05x-%05x: Extboot ROM\n",
                EXTBOOT_PHYSICAL_ADDRESS,
                EXTBOOT_PHYSICAL_ADDRESS + extboot_sz - 1);
-    if ( use_vmxassist() )
-        printf(" %05x-%05x: VMXAssist\n",
-               VMXASSIST_PHYSICAL_ADDRESS,
-               VMXASSIST_PHYSICAL_ADDRESS + sizeof(vmxassist) - 1);
     if ( smbios_sz )
         printf(" %05x-%05x: SMBIOS tables\n",
                SMBIOS_PHYSICAL_ADDRESS,
@@ -523,19 +510,6 @@ int main(void)
                ROMBIOS_PHYSICAL_ADDRESS,
                ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1);
 
-    if ( use_vmxassist() )
-    {
-        printf("Loading VMXAssist ...\n");
-        memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
-               vmxassist, sizeof(vmxassist));
-
-        printf("VMX go ...\n");
-        __asm__ __volatile__(
-            "jmp *%%eax"
-            : : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0)
-            );
-    }
-
     printf("Invoking ROMBIOS ...\n");
     return 0;
 }
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/Makefile
--- a/tools/firmware/vmxassist/Makefile Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-#
-# Makefile
-#
-# Leendert van Doorn, leendert@xxxxxxxxxxxxxx
-# Copyright (c) 2005, International Business Machines Corporation.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms and conditions of the GNU General Public License,
-# version 2, as published by the Free Software Foundation.
-#
-# This program is distributed in the hope it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-# Place - Suite 330, Boston, MA 02111-1307 USA.
-#
-
-# External CFLAGS can do more harm than good.
-CFLAGS :=
-
-override XEN_TARGET_ARCH = x86_32
-XEN_ROOT = ../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-# The emulator code lives in ROM space
-TEXTADDR=0x000D0000
-
-DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR)
-XENINC=$(CFLAGS_include)
-
-# Disable PIE/SSP if GCC supports them. They can break us.
-CFLAGS  += $(call cc-option,$(CC),-nopie,)
-CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector,)
-CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector-all,)
-
-CPP      = cpp -P
-CFLAGS  += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float
-
-OBJECTS = head.o trap.o vm86.o setup.o util.o
-
-.PHONY: all
-all: vmxassist.bin
-
-vmxassist.bin: vmxassist.ld $(OBJECTS)
-       $(CPP) $(DEFINES) vmxassist.ld > vmxassist.tmp
-       $(LD) -o vmxassist $(LDFLAGS_DIRECT) --fatal-warnings -N -T 
vmxassist.tmp $(OBJECTS)
-       nm -n vmxassist > vmxassist.sym
-       $(OBJCOPY) -p -O binary -R .note -R .comment -R .bss -S --gap-fill=0 
vmxassist vmxassist.tmp
-       dd if=vmxassist.tmp of=vmxassist.bin ibs=512 conv=sync
-       rm -f vmxassist.tmp
-
-head.o: machine.h vm86.h head.S
-       $(CC) $(CFLAGS) -D__ASSEMBLY__ $(DEFINES) -c head.S
-
-trap.o: machine.h vm86.h offsets.h trap.S
-       $(CC) $(CFLAGS) -D__ASSEMBLY__ $(DEFINES) -c trap.S
-
-vm86.o: machine.h vm86.h vm86.c
-       $(CC) $(CFLAGS) -c vm86.c
-
-setup.o: machine.h vm86.h setup.c
-       $(CC) $(CFLAGS) -c setup.c
-
-util.o: machine.h vm86.h util.c
-       $(CC) $(CFLAGS) -c util.c
-
-offsets.h: gen
-       ./gen > offsets.h
-
-gen:   vm86.h gen.c
-       $(HOSTCC) $(HOSTCFLAGS) -I. $(XENINC) -o gen gen.c
-
-.PHONY: clean
-clean:
-       rm -f vmxassist vmxassist.tmp vmxassist.bin vmxassist.run vmxassist.sym 
head.s
-       rm -f $(OBJECTS)
-       rm -f gen gen.o offsets.h
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/gen.c
--- a/tools/firmware/vmxassist/gen.c    Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * gen.c: Generate assembler symbols.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <vm86.h>
-
-int
-main(void)
-{
-       printf("/* MACHINE GENERATED; DO NOT EDIT */\n");
-       printf("#define VMX_ASSIST_CTX_GS_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, gs_sel));
-       printf("#define VMX_ASSIST_CTX_FS_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, fs_sel));
-       printf("#define VMX_ASSIST_CTX_DS_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, ds_sel));
-       printf("#define VMX_ASSIST_CTX_ES_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, es_sel));
-       printf("#define VMX_ASSIST_CTX_SS_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, ss_sel));
-       printf("#define VMX_ASSIST_CTX_ESP      0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, esp));
-       printf("#define VMX_ASSIST_CTX_EFLAGS   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, eflags));
-       printf("#define VMX_ASSIST_CTX_CS_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, cs_sel));
-       printf("#define VMX_ASSIST_CTX_EIP      0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, eip));
-
-       printf("#define VMX_ASSIST_CTX_CR0      0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, cr0));
-
-       return 0;
-}
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/head.S
--- a/tools/firmware/vmxassist/head.S   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * head.S: VMXAssist runtime start off.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "vm86.h"
-#include "machine.h"
-
-/*
- * When a partition tries to mask off the CR0_PE bit a world
- * switch happens to the environment below. The magic indicates
- * that this is a valid context.
- */
-       jmp     _start
-
-       .align  8
-       .long   VMXASSIST_MAGIC
-       .long   newctx                  /* new context */
-       .long   oldctx                  /* old context */
-
-/*
- * This is the real start. Control was transfered to this point
- * with CR0_PE set and executing in some 32-bit segment. We call
- * main and setup our own environment.
- */
-       .globl  _start
-       .code32
-_start:
-       cli
-
-       /* save register parameters to C land */
-
-       /* clear bss */
-       cld
-       xorb    %al, %al
-       movl    $_bbss, %edi
-       movl    $_ebss, %ecx
-       subl    %edi, %ecx
-       rep     stosb
-
-       movl    %edx, booting_cpu
-       movl    %ebx, booting_vector
-
-       /* make sure we are in a sane world */
-       clts
-
-       /* setup my own stack */
-       movl    $stack_top, %esp
-       movl    %esp, %ebp
-
-       /* go ... */
-       call    main
-       jmp     halt
-
-/*
- * Something bad happened, print invoking %eip and loop forever
- */
-       .align  4
-       .globl  halt
-halt:
-       push    $halt_msg
-       call    printf
-       cli
-       jmp     .
-
-       .data
-halt_msg:
-       .asciz  "Halt called from %%eip 0x%x\n"
-
-
-/*
- * Our stack
- */
-       .bss
-       .align  8
-       .globl  stack, stack_top
-stack:
-       .skip   STACK_SIZE
-stack_top:
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/machine.h
--- a/tools/firmware/vmxassist/machine.h        Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +0,0 @@
-/*
- * machine.h: Intel CPU specific definitions
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __MACHINE_H__
-#define __MACHINE_H__
-
-/* the size of our stack (4KB) */
-#define STACK_SIZE     8192
-
-#define TSS_SELECTOR   0x08
-#define CODE_SELECTOR  0x10
-#define DATA_SELECTOR  0x18
-
-#define CR0_PE         (1 << 0)
-#define CR0_EM         (1 << 2)
-#define        CR0_TS          (1 << 3)
-#define CR0_NE         (1 << 5)
-#define CR0_PG         (1 << 31)
-
-#define CR4_VME                (1 << 0)
-#define CR4_PVI                (1 << 1)
-#define CR4_PSE                (1 << 4)
-#define CR4_PAE                (1 << 5)
-
-#define EFLAGS_CF      (1 << 0)
-#define EFLAGS_PF      (1 << 2)
-#define EFLAGS_AF      (1 << 4)
-#define EFLAGS_ZF      (1 << 6)
-#define EFLAGS_SF      (1 << 7)
-#define EFLAGS_TF      (1 << 8)
-#define EFLAGS_IF      (1 << 9)
-#define EFLAGS_DF      (1 << 10)
-#define EFLAGS_OF      (1 << 11)
-#define EFLAGS_IOPL    (3 << 12)
-#define EFLAGS_VM      ((1 << 17) | EFLAGS_IOPL)
-#define EFLAGS_VIF     (1 << 19)
-#define EFLAGS_VIP     (1 << 20)
-
-#define        LOG_PGSIZE      12      /* log2(page size) */
-#define        LOG_PDSIZE      22      /* log2(page directory size) */
-
-/* Derived constants */
-#define        PGSIZE          (1 << LOG_PGSIZE)       /* page size */
-#define        PGMASK          (~(PGSIZE - 1))         /* page mask */
-#define        LPGSIZE         (1 << LOG_PDSIZE)       /* large page size */
-#define        LPGMASK         (~(LPGSIZE - 1))        /* large page mask */
-
-/* Programmable Interrupt Contoller (PIC) defines */
-#define        PIC_MASTER      0x20
-#define        PIC_SLAVE       0xA0
-
-#define        PIC_CMD         0       /* command */
-#define        PIC_ISR         0       /* interrupt status */
-#define        PIC_IMR         1       /* interrupt mask */
-
-
-#ifndef __ASSEMBLY__
-
-struct dtr {
-       unsigned short  size;
-       unsigned long   base __attribute__ ((packed));
-};
-
-struct tss {
-       unsigned short  prev_link;
-       unsigned short  _1;
-       unsigned long   esp0;
-       unsigned short  ss0;
-       unsigned short  _2;
-       unsigned long   esp1;
-       unsigned short  ss1;
-       unsigned short  _3;
-       unsigned long   esp2;
-       unsigned short  ss2;
-       unsigned short  _4;
-       unsigned long   cr3;
-       unsigned long   eip;
-       unsigned long   eflags;
-       unsigned long   eax;
-       unsigned long   ecx;
-       unsigned long   edx;
-       unsigned long   ebx;
-       unsigned long   esi;
-       unsigned long   edi;
-       unsigned long   esp;
-       unsigned long   ebp;
-       unsigned long   es;
-       unsigned long   cs;
-       unsigned long   ss;
-       unsigned long   ds;
-       unsigned long   fs;
-       unsigned long   gs;
-       unsigned short  ldt_segment;
-       unsigned short  _5;
-       unsigned short  _6;
-       unsigned short  iomap_base;
-#ifdef ENABLE_VME
-       unsigned long   int_redir[8];
-#endif
-       unsigned char   iomap[8193];
-};
-
-static inline void
-outw(unsigned short addr, unsigned short val)
-{
-       __asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val));
-}
-
-static inline void
-outb(unsigned short addr, unsigned char val)
-{
-       __asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val));
-}
-
-static inline unsigned char
-inb(unsigned short addr)
-{
-       unsigned char val;
-
-       __asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr));
-       return val;
-}
-
-static inline unsigned
-get_cmos(int reg)
-{
-       outb(0x70, reg);
-       return inb(0x71);
-}
-
-static inline unsigned
-get_cr0(void)
-{
-        unsigned rv;
-        __asm__ __volatile__("movl %%cr0, %0" : "=r"(rv));
-        return rv;
-}
-
-static inline void
-set_cr0(unsigned value)
-{
-       __asm__ __volatile__(
-               "movl   %0, %%cr0\n"
-               "jmp    1f\n"
-               "1:     nop\n"
-               : /* no outputs */
-               : "r"(value)
-       );
-}
-
-static inline unsigned
-get_cr2(void)
-{
-       unsigned rv;
-
-       __asm__ __volatile__("movl %%cr2, %0" : "=r"(rv));
-       return rv;
-}
-
-static inline unsigned
-get_cr4(void)
-{
-        unsigned rv;
-        __asm__ __volatile__("movl %%cr4, %0" : "=r"(rv));
-        return rv;
-}
-
-static inline void
-set_cr3(unsigned addr)
-{
-        __asm__ __volatile__("movl %0, %%cr3" : /* no outputs */ : "r"(addr));
-}
-
-static inline void
-set_cr4(unsigned value)
-{
-       __asm__ __volatile__("movl %0, %%cr4" : /* no outputs */ : "r"(value));
-}
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __MACHINE_H__ */
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c  Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,337 +0,0 @@
-/*
- * setup.c: Setup the world for vmxassist.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "vm86.h"
-#include "util.h"
-#include "machine.h"
-
-#if (VMXASSIST_BASE != TEXTADDR)
-#error VMXAssist base mismatch
-#endif
-
-#define        NR_PGD          (PGSIZE / sizeof(unsigned))
-
-#define        min(a, b)       ((a) > (b) ? (b) : (a))
-
-/* Which CPU are we booting, and what is the initial CS segment? */
-int booting_cpu, booting_vector;
-
-unsigned long long gdt[] __attribute__ ((aligned(32))) = {
-       0x0000000000000000ULL,          /* 0x00: reserved */
-       0x0000890000000000ULL,          /* 0x08: 32-bit TSS */
-       0x00CF9A000000FFFFULL,          /* 0x10: CS 32-bit */
-       0x00CF92000000FFFFULL,          /* 0x18: DS 32-bit */
-};
-
-struct dtr gdtr = { sizeof(gdt)-1, (unsigned long) &gdt };
-
-struct tss tss __attribute__ ((aligned(4)));
-
-unsigned long long idt[NR_TRAPS] __attribute__ ((aligned(32)));
-
-struct dtr idtr = { sizeof(idt)-1, (unsigned long) &idt };
-
-struct vmx_assist_context oldctx;
-struct vmx_assist_context newctx;
-
-unsigned long memory_size;
-int initialize_real_mode;
-
-extern char stack_top[];
-extern unsigned trap_handlers[];
-
-void
-banner(void)
-{
-       printf("VMXAssist (%s)\n", __DATE__);
-
-       /* Bochs its way to convey memory size */
-       memory_size = ((get_cmos(0x35) << 8) | get_cmos(0x34)) << 6;
-       if (memory_size > 0x3bc000)
-               memory_size = 0x3bc000;
-       memory_size = (memory_size << 10) + 0xF00000;
-       if (memory_size <= 0xF00000)
-               memory_size =
-                   (((get_cmos(0x31) << 8) | get_cmos(0x30)) + 0x400) << 10;
-       memory_size += 0x400 << 10; /* + 1MB */
-
-       printf("Memory size %ld MB\n", memory_size >> 20);
-       printf("E820 map:\n");
-       print_e820_map(HVM_E820, *HVM_E820_NR);
-       printf("\n");
-}
-
-void
-setup_gdt(void)
-{
-       unsigned long long addr = (unsigned long long) &tss;
-
-       /* setup task state segment */
-       memset(&tss, 0, sizeof(tss));
-       tss.ss0 = DATA_SELECTOR;
-       tss.esp0 = (unsigned) stack_top;
-       tss.iomap_base = offsetof(struct tss, iomap);
-       tss.iomap[sizeof(tss.iomap)-1] = 0xff;
-
-       /* initialize gdt's tss selector */
-       gdt[TSS_SELECTOR / sizeof(gdt[0])] |=
-               ((addr & 0xFF000000) << (56-24)) |
-               ((addr & 0x00FF0000) << (32-16)) |
-               ((addr & 0x0000FFFF) << (16)) |
-               (sizeof(tss) - 1);
-
-       /* switch to our own gdt and set current tss */
-       __asm__ __volatile__ ("lgdt %0" : : "m" (gdtr));
-       __asm__ __volatile__ ("movl %%eax,%%ds;"
-                             "movl %%eax,%%es;"
-                             "movl %%eax,%%fs;"
-                             "movl %%eax,%%gs;"
-                             "movl %%eax,%%ss" : : "a" (DATA_SELECTOR));
-
-       __asm__ __volatile__ ("ljmp %0,$1f; 1:" : : "i" (CODE_SELECTOR));
-
-       __asm__ __volatile__ ("ltr %%ax" : : "a" (TSS_SELECTOR));
-}
-
-void
-set_intr_gate(int i, unsigned handler)
-{
-       unsigned long long addr = handler;
-
-       idt[i] = ((addr & 0xFFFF0000ULL) << 32) | (0x8E00ULL << 32) |
-               (addr & 0xFFFFULL) | (CODE_SELECTOR << 16);
-}
-
-void
-setup_idt(void)
-{
-       int i;
-
-       for (i = 0; i < NR_TRAPS; i++)
-               set_intr_gate(i, trap_handlers[i]);
-       __asm__ __volatile__ ("lidt %0" : : "m" (idtr));
-}
-
-void
-setup_pic(void)
-{
-       /* mask all interrupts */
-       outb(PIC_MASTER + PIC_IMR, 0xFF);
-       outb(PIC_SLAVE + PIC_IMR, 0xFF);
-
-       /* setup master PIC */
-       outb(PIC_MASTER + PIC_CMD, 0x11); /* edge triggered, cascade, ICW4 */
-       outb(PIC_MASTER + PIC_IMR, NR_EXCEPTION_HANDLER);
-       outb(PIC_MASTER + PIC_IMR, 1 << 2); /* slave on channel 2 */
-       outb(PIC_MASTER + PIC_IMR, 0x01);
-
-       /* setup slave PIC */
-       outb(PIC_SLAVE + PIC_CMD, 0x11); /* edge triggered, cascade, ICW4 */
-       outb(PIC_SLAVE + PIC_IMR, NR_EXCEPTION_HANDLER + 8);
-       outb(PIC_SLAVE + PIC_IMR, 0x02); /* slave identity is 2 */
-       outb(PIC_SLAVE + PIC_IMR, 0x01);
-
-       /* enable all interrupts */
-       outb(PIC_MASTER + PIC_IMR, 0);
-       outb(PIC_SLAVE + PIC_IMR, 0);
-}
-
-void
-setiomap(int port)
-{
-       tss.iomap[port >> 3] |= 1 << (port & 7);
-}
-
-void
-enter_real_mode(struct regs *regs)
-{
-       /* mask off TSS busy bit */
-       gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL;
-
-       /* start 8086 emulation of BIOS */
-       if (initialize_real_mode) {
-               initialize_real_mode = 0;
-               regs->eflags |= EFLAGS_VM | 0x02;
-               regs->ves = regs->vds = regs->vfs = regs->vgs = 0xF000;
-               if (booting_cpu == 0) {
-                       regs->cs = 0xF000; /* ROM BIOS POST entry point */
-                       regs->eip = 0xFFF0;
-               } else {
-                       regs->cs = booting_vector << 8; /* AP entry point */
-                       regs->eip = 0;
-               }
-
-               regs->uesp = regs->uss = 0;
-               regs->eax = regs->ecx = regs->edx = regs->ebx = 0;
-               regs->esp = regs->ebp = regs->esi = regs->edi = 0;
-
-               /* intercept accesses to the PIC */
-               setiomap(PIC_MASTER+PIC_CMD);
-               setiomap(PIC_MASTER+PIC_IMR);
-               setiomap(PIC_SLAVE+PIC_CMD);
-               setiomap(PIC_SLAVE+PIC_IMR);
-
-               printf("Starting emulated 16-bit real-mode: ip=%04x:%04x\n",
-                       regs->cs, regs->eip);
-
-               mode = VM86_REAL; /* becomes previous mode */
-               set_mode(regs, VM86_REAL);
-
-               /* this should get us into 16-bit mode */
-               return;
-       }
-
-       /* go from protected to real mode */
-       set_mode(regs, VM86_PROTECTED_TO_REAL);
-       emulate(regs);
-       if (mode != VM86_REAL)
-               panic("failed to emulate between clear PE and long jump.\n");
-}
-
-/*
- * Setup the environment for VMX assist.
- * This environment consists of flat segments (code and data),
- * its own gdt, idt, and tr.
- */
-void
-setup_ctx(void)
-{
-       struct vmx_assist_context *c = &newctx;
-
-       memset(c, 0, sizeof(*c));
-       c->eip = (unsigned long) switch_to_real_mode;
-       c->esp = (unsigned) stack_top;
-       c->eflags = 0x2; /* no interrupts, please */
-
-       /*
-        * Obviously, vmx assist is not running with CR0_PE disabled.
-        * The reason why the vmx assist cr0 has CR0.PE disabled is
-        * that a transtion to CR0.PE causes a world switch. It seems
-        * more natural to enable CR0.PE to cause a world switch to
-        * protected mode rather than disabling it.
-        */
-       c->cr0 = (get_cr0() | CR0_NE) & ~CR0_PE;
-       c->cr3 = 0;
-       c->cr4 = get_cr4();
-
-       c->idtr_limit = sizeof(idt)-1;
-       c->idtr_base = (unsigned long) &idt;
-
-       c->gdtr_limit = sizeof(gdt)-1;
-       c->gdtr_base = (unsigned long) &gdt;
-
-       c->cs_sel = CODE_SELECTOR;
-       c->cs_limit = 0xFFFFFFFF;
-       c->cs_base = 0;
-       c->cs_arbytes.fields.seg_type = 0xb;
-       c->cs_arbytes.fields.s = 1;
-       c->cs_arbytes.fields.dpl = 0;
-       c->cs_arbytes.fields.p = 1;
-       c->cs_arbytes.fields.avl = 0;
-       c->cs_arbytes.fields.default_ops_size = 1;
-       c->cs_arbytes.fields.g = 1;
-
-       c->ds_sel = DATA_SELECTOR;
-       c->ds_limit = 0xFFFFFFFF;
-       c->ds_base = 0;
-       c->ds_arbytes = c->cs_arbytes;
-       c->ds_arbytes.fields.seg_type = 0x3;
-
-       c->es_sel = DATA_SELECTOR;
-       c->es_limit = 0xFFFFFFFF;
-       c->es_base = 0;
-       c->es_arbytes = c->ds_arbytes;
-
-       c->ss_sel = DATA_SELECTOR;
-       c->ss_limit = 0xFFFFFFFF;
-       c->ss_base = 0;
-       c->ss_arbytes = c->ds_arbytes;
-
-       c->fs_sel = DATA_SELECTOR;
-       c->fs_limit = 0xFFFFFFFF;
-       c->fs_base = 0;
-       c->fs_arbytes = c->ds_arbytes;
-
-       c->gs_sel = DATA_SELECTOR;
-       c->gs_limit = 0xFFFFFFFF;
-       c->gs_base = 0;
-       c->gs_arbytes = c->ds_arbytes;
-
-       c->tr_sel = TSS_SELECTOR;
-       c->tr_limit = sizeof(tss) - 1;
-       c->tr_base = (unsigned long) &tss;
-       c->tr_arbytes.fields.seg_type = 0xb; /* 0x9 | 0x2 (busy) */
-       c->tr_arbytes.fields.s = 0;
-       c->tr_arbytes.fields.dpl = 0;
-       c->tr_arbytes.fields.p = 1;
-       c->tr_arbytes.fields.avl = 0;
-       c->tr_arbytes.fields.default_ops_size = 0;
-       c->tr_arbytes.fields.g = 0;
-
-       c->ldtr_sel = 0;
-       c->ldtr_limit = 0;
-       c->ldtr_base = 0;
-       c->ldtr_arbytes = c->ds_arbytes;
-       c->ldtr_arbytes.fields.seg_type = 0x2;
-       c->ldtr_arbytes.fields.s = 0;
-       c->ldtr_arbytes.fields.dpl = 0;
-       c->ldtr_arbytes.fields.p = 1;
-       c->ldtr_arbytes.fields.avl = 0;
-       c->ldtr_arbytes.fields.default_ops_size = 0;
-       c->ldtr_arbytes.fields.g = 0;
-}
-
-/*
- * Start BIOS by causing a world switch to vmxassist, which causes
- * VM8086 to be enabled and control is transfered to F000:FFF0.
- */
-void
-start_bios(void)
-{
-       if (booting_cpu == 0)
-               printf("Start BIOS ...\n");
-       else
-               printf("Start AP %d from %08x ...\n",
-                      booting_cpu, booting_vector << 12);
-
-       initialize_real_mode = 1;
-       set_cr0(get_cr0() & ~CR0_PE);
-       panic("vmxassist returned"); /* "cannot happen" */
-}
-
-int
-main(void)
-{
-       if (booting_cpu == 0)
-               banner();
-
-       setup_gdt();
-       setup_idt();
-
-       set_cr4(get_cr4() | CR4_VME);
-
-       setup_ctx();
-
-       if (booting_cpu == 0)
-               setup_pic();
-
-       start_bios();
-
-       return 0;
-}
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/trap.S
--- a/tools/firmware/vmxassist/trap.S   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/*
- * trap.S: Trap and world switch handlers
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "machine.h"
-#include "vm86.h"
-#include "offsets.h"
-
-/*
- * All processor exception/faults/interrupts end up here.
- *
- * On an exception/fault, the processor pushes CS:EIP, SS, ESP and an
- * optional error code onto the stack. The common_trap routine
- * below saves the processor context and transfers control to trap()
- * whose job it is to virtualize and pass on the trap.
- */
-       .macro  TRAP_HANDLER trapno error
-       .text
-       .align  16
-1:     .if     \error == 0
-       pushl   $0                      /* dummy error code */
-       .endif
-       pushl   $\trapno
-       jmp     common_trap
-       .section .rodata
-       .long   1b
-       .text
-       .endm
-
-       .section .rodata
-       .code32
-       .align  4
-       .global trap_handlers
-trap_handlers:
-       TRAP_HANDLER    0, 0    /* divide error */
-       TRAP_HANDLER    1, 0    /* debug */
-       TRAP_HANDLER    2, 0    /* NMI interrupt */
-       TRAP_HANDLER    3, 0    /* breakpoint */
-       TRAP_HANDLER    4, 0    /* overflow */
-       TRAP_HANDLER    5, 0    /* BOUND range exceeded */
-       TRAP_HANDLER    6, 0    /* invalid opcode */
-       TRAP_HANDLER    7, 0    /* device not available */
-       TRAP_HANDLER    8, 1    /* double fault */
-       TRAP_HANDLER    9, 0    /* coprocessor segment overrun */
-       TRAP_HANDLER    10, 1   /* invalid TSS */
-       TRAP_HANDLER    11, 1   /* segment not present */
-       TRAP_HANDLER    12, 1   /* stack-segment fault */
-       TRAP_HANDLER    13, 1   /* general protection */
-       TRAP_HANDLER    14, 1   /* page fault */
-       TRAP_HANDLER    15, 0   /* reserved */
-       TRAP_HANDLER    16, 0   /* FPU floating-point error */
-       TRAP_HANDLER    17, 1   /* alignment check */
-       TRAP_HANDLER    18, 0   /* machine check */
-       TRAP_HANDLER    19, 0   /* SIMD floating-point error */
-       TRAP_HANDLER    20, 0   /* reserved */
-       TRAP_HANDLER    21, 0   /* reserved */
-       TRAP_HANDLER    22, 0   /* reserved */
-       TRAP_HANDLER    23, 0   /* reserved */
-       TRAP_HANDLER    24, 0   /* reserved */
-       TRAP_HANDLER    25, 0   /* reserved */
-       TRAP_HANDLER    26, 0   /* reserved */
-       TRAP_HANDLER    27, 0   /* reserved */
-       TRAP_HANDLER    28, 0   /* reserved */
-       TRAP_HANDLER    29, 0   /* reserved */
-       TRAP_HANDLER    30, 0   /* reserved */
-       TRAP_HANDLER    31, 0   /* reserved */
-       TRAP_HANDLER    32, 0   /* irq 0 */
-       TRAP_HANDLER    33, 0   /* irq 1 */
-       TRAP_HANDLER    34, 0   /* irq 2 */
-       TRAP_HANDLER    35, 0   /* irq 3 */
-       TRAP_HANDLER    36, 0   /* irq 4 */
-       TRAP_HANDLER    37, 0   /* irq 5 */
-       TRAP_HANDLER    38, 0   /* irq 6 */
-       TRAP_HANDLER    39, 0   /* irq 7 */
-       TRAP_HANDLER    40, 0   /* irq 8 */
-       TRAP_HANDLER    41, 0   /* irq 9 */
-       TRAP_HANDLER    42, 0   /* irq 10 */
-       TRAP_HANDLER    43, 0   /* irq 11 */
-       TRAP_HANDLER    44, 0   /* irq 12 */
-       TRAP_HANDLER    45, 0   /* irq 13 */
-       TRAP_HANDLER    46, 0   /* irq 14 */
-       TRAP_HANDLER    47, 0   /* irq 15 */
-
-       .text
-       .code32
-       .align  16
-common_trap:                           /* common trap handler */
-       pushal
-
-       movl    $(DATA_SELECTOR), %eax  /* make sure these are sane */
-       movl    %eax, %ds
-       movl    %eax, %es
-       movl    %eax, %fs
-       movl    %eax, %gs
-       movl    %esp, %ebp
-
-       pushl   %ebp
-       pushl   36(%ebp)
-       pushl   32(%ebp)
-       call    trap                    /* trap(trapno, errno, regs) */
-       addl    $12, %esp
-
-trap_return:
-       popal
-       addl    $8, %esp                /* skip trapno, errno */
-       iret
-       /* NOT REACHED */
-
-
-/*
- * A world switch to real mode occured. The hypervisor saved the
- * executing context into "oldctx" and instantiated "newctx", which
- * gets us here. Here we push a stack frame that is compatible with
- * a trap frame (see above) so that we can handle this event as a
- * regular trap.
- */
-       .text
-       .align  16
-       .globl  switch_to_real_mode
-switch_to_real_mode:
-       pushl   oldctx+VMX_ASSIST_CTX_GS_SEL /* 16 to 32-bit transition */
-       pushl   oldctx+VMX_ASSIST_CTX_FS_SEL
-       pushl   oldctx+VMX_ASSIST_CTX_DS_SEL
-       pushl   oldctx+VMX_ASSIST_CTX_ES_SEL
-       pushl   oldctx+VMX_ASSIST_CTX_SS_SEL
-       pushl   oldctx+VMX_ASSIST_CTX_ESP
-       pushl   oldctx+VMX_ASSIST_CTX_EFLAGS
-       pushl   oldctx+VMX_ASSIST_CTX_CS_SEL
-       pushl   oldctx+VMX_ASSIST_CTX_EIP
-       pushl   $-1                     /* trapno, errno */
-       pushl   $-1
-       pushal
-
-       movl    %esp, %ebp
-       pushl   %ebp
-       call    enter_real_mode
-       addl    $4, %esp
-
-       jmp     trap_return
-       /* NOT REACHED */
-
-
-/*
- * Switch to protected mode. At this point all the registers have
- * been reloaded by trap_return and all we have to do is cause a
- * world switch by turning on CR0.PE.
- */
-       .text
-       .align  16
-       .globl  switch_to_protected_mode
-switch_to_protected_mode:
-       movl    oldctx+VMX_ASSIST_CTX_CR0, %esp
-       movl    %esp, %cr0              /* actual world switch ! */
-
-       /* NOT REACHED */
-       pushl   $switch_failed
-       call    panic
-       jmp     .
-
-       .data
-       .align  4
-switch_failed:
-       .asciz  "World switch to protected mode failed\n"
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/util.c
--- a/tools/firmware/vmxassist/util.c   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,430 +0,0 @@
-/*
- * util.c: Commonly used utility functions.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include <stdarg.h>
-
-#include "util.h"
-#include "machine.h"
-
-#define        isdigit(c)      ((c) >= '0' && (c) <= '9')
-#define        min(a, b)       ((a) < (b) ? (a) : (b))
-
-static void putchar(int);
-static char *printnum(char *, unsigned long, int);
-static void _doprint(void (*)(int), const char *, va_list);
-
-void
-cpuid_addr_value(uint64_t addr, uint64_t *value)
-{
-       uint32_t addr_low   = (uint32_t)addr;
-       uint32_t addr_high  = (uint32_t)(addr >> 32);
-       uint32_t value_low, value_high;
-       static unsigned int addr_leaf;
-
-       if (!addr_leaf) {
-               unsigned int eax, ebx, ecx, edx;
-               __asm__ __volatile__(
-                       "cpuid"
-                       : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
-                       : "0" (0x40000000));
-               addr_leaf = eax + 1;
-       }
-
-       __asm__ __volatile__(
-               "cpuid"
-               : "=c" (value_low), "=d" (value_high)
-               : "a" (addr_leaf), "0" (addr_low), "1" (addr_high)
-               : "ebx");
-
-       *value = (uint64_t)value_high << 32 | value_low;
-}
-
-void
-dump_regs(struct regs *regs)
-{
-       printf("eax    %8x ecx    %8x edx    %8x ebx    %8x\n",
-               regs->eax, regs->ecx, regs->edx, regs->ebx);
-       printf("esp    %8x ebp    %8x esi    %8x edi    %8x\n",
-               regs->esp, regs->ebp, regs->esi, regs->edi);
-       printf("trapno %8x errno  %8x\n", regs->trapno, regs->errno);
-       printf("eip    %8x cs     %8x eflags %8x\n",
-               regs->eip, regs->cs, regs->eflags);
-       printf("uesp   %8x uss    %8x\n",
-               regs->uesp, regs->uss);
-       printf("ves    %8x vds    %8x vfs    %8x vgs    %8x\n",
-               regs->ves, regs->vds, regs->vfs, regs->vgs);
-
-       printf("cr0    %8lx cr2    %8x cr3    %8lx cr4    %8lx\n\n",
-               (long)oldctx.cr0, get_cr2(),
-               (long)oldctx.cr3, (long)oldctx.cr4);
-}
-
-#ifdef DEBUG
-void
-hexdump(unsigned char *data, int sz)
-{
-       unsigned char *d;
-       int i;
-
-       for (d = data; sz > 0; d += 16, sz -= 16) {
-               int n = sz > 16 ? 16 : sz;
-
-               printf("%08x: ", (unsigned)d);
-               for (i = 0; i < n; i++)
-                       printf("%02x%c", d[i], i == 7 ? '-' : ' ');
-               for (; i < 16; i++)
-                       printf("  %c", i == 7 ? '-' : ' ');
-               printf("   ");
-               for (i = 0; i < n; i++)
-                       printf("%c", d[i] >= ' ' && d[i] <= '~' ? d[i] : '.');
-               printf("\n");
-       }
-}
-
-void
-print_e820_map(struct e820entry *map, int entries)
-{
-       struct e820entry *m;
-
-       if (entries > 32)
-               entries = 32;
-
-       for (m = map; m < &map[entries]; m++) {
-               printf("%08lx%08lx - %08lx%08lx ",
-                       (unsigned long) (m->addr >> 32),
-                       (unsigned long) (m->addr),
-                       (unsigned long) ((m->addr+m->size) >> 32),
-                       (unsigned long) ((m->addr+m->size)));
-
-               switch (m->type) {
-               case E820_RAM:
-                       printf("(RAM)\n"); break;
-               case E820_RESERVED:
-                       printf("(Reserved)\n"); break;
-               case E820_ACPI:
-                       printf("(ACPI Data)\n"); break;
-               case E820_NVS:
-                       printf("(ACPI NVS)\n"); break;
-               default:
-                       printf("(Type %ld)\n", m->type); break;
-               }
-       }
-}
-
-void
-dump_dtr(unsigned long addr, unsigned long size)
-{
-       unsigned long long entry;
-       unsigned long base, limit;
-       int i;
-
-       for (i = 0; i < size; i += 8) {
-               entry = ((unsigned long long *) addr)[i >> 3];
-               base = (((entry >> (56-24)) & 0xFF000000) |
-                       ((entry >> (32-16)) & 0x00FF0000) |
-                       ((entry >> (   16)) & 0x0000FFFF));
-               limit = (((entry >> (48-16)) & 0x000F0000) |
-                        ((entry           ) & 0x0000FFFF));
-               if (entry & (1ULL << (23+32))) /* G */
-                       limit = (limit << 12) | 0xFFF;
-
-               printf("[0x%x] = 0x%08x%08x, base 0x%lx, limit 0x%lx\n", i,
-                       (unsigned)(entry >> 32), (unsigned)(entry),
-                       base, limit);
-       }
-}
-
-void
-dump_vmx_context(struct vmx_assist_context *c)
-{
-       printf("eip 0x%lx, esp 0x%lx, eflags 0x%lx\n",
-               (long) c->eip, (long) c->esp, (long) c->eflags);
-
-       printf("cr0 0x%lx, cr3 0x%lx, cr4 0x%lx\n",
-               (long)c->cr0, (long)c->cr3, (long)c->cr4);
-
-       printf("idtr: limit 0x%lx, base 0x%lx\n",
-               (long)c->idtr_limit, (long)c->idtr_base);
-
-       printf("gdtr: limit 0x%lx, base 0x%lx\n",
-               (long)c->gdtr_limit, (long)c->gdtr_base);
-
-       printf("cs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->cs_sel, (long)c->cs_limit, (long)c->cs_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->cs_arbytes.fields.seg_type,
-               c->cs_arbytes.fields.s,
-               c->cs_arbytes.fields.dpl,
-               c->cs_arbytes.fields.p,
-               c->cs_arbytes.fields.avl,
-               c->cs_arbytes.fields.default_ops_size,
-               c->cs_arbytes.fields.g,
-               c->cs_arbytes.fields.null_bit);
-
-       printf("ds: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->ds_sel, (long)c->ds_limit, (long)c->ds_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->ds_arbytes.fields.seg_type,
-               c->ds_arbytes.fields.s,
-               c->ds_arbytes.fields.dpl,
-               c->ds_arbytes.fields.p,
-               c->ds_arbytes.fields.avl,
-               c->ds_arbytes.fields.default_ops_size,
-               c->ds_arbytes.fields.g,
-               c->ds_arbytes.fields.null_bit);
-
-       printf("es: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->es_sel, (long)c->es_limit, (long)c->es_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->es_arbytes.fields.seg_type,
-               c->es_arbytes.fields.s,
-               c->es_arbytes.fields.dpl,
-               c->es_arbytes.fields.p,
-               c->es_arbytes.fields.avl,
-               c->es_arbytes.fields.default_ops_size,
-               c->es_arbytes.fields.g,
-               c->es_arbytes.fields.null_bit);
-
-       printf("ss: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->ss_sel, (long)c->ss_limit, (long)c->ss_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->ss_arbytes.fields.seg_type,
-               c->ss_arbytes.fields.s,
-               c->ss_arbytes.fields.dpl,
-               c->ss_arbytes.fields.p,
-               c->ss_arbytes.fields.avl,
-               c->ss_arbytes.fields.default_ops_size,
-               c->ss_arbytes.fields.g,
-               c->ss_arbytes.fields.null_bit);
-
-       printf("fs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->fs_sel, (long)c->fs_limit, (long)c->fs_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->fs_arbytes.fields.seg_type,
-               c->fs_arbytes.fields.s,
-               c->fs_arbytes.fields.dpl,
-               c->fs_arbytes.fields.p,
-               c->fs_arbytes.fields.avl,
-               c->fs_arbytes.fields.default_ops_size,
-               c->fs_arbytes.fields.g,
-               c->fs_arbytes.fields.null_bit);
-
-       printf("gs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->gs_sel, (long)c->gs_limit, (long)c->gs_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->gs_arbytes.fields.seg_type,
-               c->gs_arbytes.fields.s,
-               c->gs_arbytes.fields.dpl,
-               c->gs_arbytes.fields.p,
-               c->gs_arbytes.fields.avl,
-               c->gs_arbytes.fields.default_ops_size,
-               c->gs_arbytes.fields.g,
-               c->gs_arbytes.fields.null_bit);
-
-       printf("tr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->tr_sel, (long)c->tr_limit, (long)c->tr_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->tr_arbytes.fields.seg_type,
-               c->tr_arbytes.fields.s,
-               c->tr_arbytes.fields.dpl,
-               c->tr_arbytes.fields.p,
-               c->tr_arbytes.fields.avl,
-               c->tr_arbytes.fields.default_ops_size,
-               c->tr_arbytes.fields.g,
-               c->tr_arbytes.fields.null_bit);
-
-       printf("ldtr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->ldtr_sel, (long)c->ldtr_limit, (long)c->ldtr_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->ldtr_arbytes.fields.seg_type,
-               c->ldtr_arbytes.fields.s,
-               c->ldtr_arbytes.fields.dpl,
-               c->ldtr_arbytes.fields.p,
-               c->ldtr_arbytes.fields.avl,
-               c->ldtr_arbytes.fields.default_ops_size,
-               c->ldtr_arbytes.fields.g,
-               c->ldtr_arbytes.fields.null_bit);
-
-       printf("GDTR <0x%lx,0x%lx>:\n",
-               (long)c->gdtr_base, (long)c->gdtr_limit);
-       dump_dtr(c->gdtr_base, c->gdtr_limit);
-}
-#endif /* DEBUG */
-
-/*
- * Lightweight printf that doesn't drag in everything under the sun.
- */
-int
-printf(const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       _doprint(putchar, fmt, ap);
-       va_end(ap);
-       return 0; /* for gcc compat */
-}
-
-int
-vprintf(const char *fmt, va_list ap)
-{
-       _doprint(putchar, fmt, ap);
-       return 0; /* for gcc compat */
-}
-
-void
-panic(const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       _doprint(putchar, fmt, ap);
-       putchar('\n');
-       va_end(ap);
-       halt();
-}
-
-unsigned
-strlen(const char *s)
-{
-       const char *q = s;
-
-       while (*s++)
-               /* void */;
-       return s - q - 1;
-}
-
-static void
-putchar(int ch)
-{
-       outb(0xE9, ch);
-}
-
-/*
- * A stripped down version of doprint,
- * but still powerful enough for most tasks.
- */
-static void
-_doprint(void (*put)(int), const char *fmt, va_list ap)
-{
-       register char *str, c;
-       int lflag, zflag, nflag;
-       char buffer[17];
-       unsigned value;
-       int i, slen, pad;
-
-       for ( ; *fmt != '\0'; fmt++) {
-               pad = zflag = nflag = lflag = 0;
-               if (*fmt == '%') {
-                       c = *++fmt;
-                       if (c == '-' || isdigit(c)) {
-                               if (c == '-') {
-                                       nflag = 1;
-                                       c = *++fmt;
-                               }
-                               zflag = c == '0';
-                               for (pad = 0; isdigit(c); c = *++fmt)
-                                       pad = (pad * 10) + c - '0';
-                       }
-                       if (c == 'l') { /* long extension */
-                               lflag = 1;
-                               c = *++fmt;
-                       }
-                       if (c == 'd' || c == 'u' || c == 'o' || c == 'x') {
-                               if (lflag)
-                                       value = va_arg(ap, unsigned);
-                               else
-                                       value = (unsigned) va_arg(ap, unsigned 
int);
-                               str = buffer;
-                               printnum(str, value,
-                                       c == 'o' ? 8 : (c == 'x' ? 16 : 10));
-                               goto printn;
-                       } else if (c == 'O' || c == 'D' || c == 'X') {
-                               value = va_arg(ap, unsigned);
-                               str = buffer;
-                               printnum(str, value,
-                                       c == 'O' ? 8 : (c == 'X' ? 16 : 10));
-                       printn:
-                               slen = strlen(str);
-                               for (i = pad - slen; i > 0; i--)
-                                       put(zflag ? '0' : ' ');
-                               while (*str) put(*str++);
-                       } else if (c == 's') {
-                               str = va_arg(ap, char *);
-                               slen = strlen(str);
-                               if (nflag == 0)
-                                       for (i = pad - slen; i > 0; i--) put(' 
');
-                               while (*str) put(*str++);
-                               if (nflag)
-                                       for (i = pad - slen; i > 0; i--) put(' 
');
-                       } else if (c == 'c')
-                               put(va_arg(ap, int));
-                       else
-                               put(*fmt);
-               } else
-                       put(*fmt);
-       }
-}
-
-static char *
-printnum(char *p, unsigned long num, int base)
-{
-       unsigned long n;
-
-       if ((n = num/base) > 0)
-               p = printnum(p, n, base);
-       *p++ = "0123456789ABCDEF"[(int)(num % base)];
-       *p = '\0';
-       return p;
-}
-
-void *
-memset(void *s, int c, unsigned n)
-{
-        int t0, t1;
-
-        __asm__ __volatile__ ("cld; rep; stosb"
-                : "=&c" (t0), "=&D" (t1)
-                : "a" (c), "1" (s), "0" (n)
-                : "memory");
-        return s;
-}
-
-void *
-memcpy(void *dest, const void *src, unsigned n)
-{
-       int t0, t1, t2;
-
-       __asm__ __volatile__(
-               "cld\n"
-               "rep; movsl\n"
-               "testb $2,%b4\n"
-               "je 1f\n"
-               "movsw\n"
-               "1: testb $1,%b4\n"
-               "je 2f\n"
-               "movsb\n"
-               "2:"
-               : "=&c" (t0), "=&D" (t1), "=&S" (t2)
-               : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
-               : "memory"
-       );
-       return dest;
-}
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/util.h
--- a/tools/firmware/vmxassist/util.h   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * util.h: Useful utility functions.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __UTIL_H__
-#define __UTIL_H__
-
-#include <stdarg.h>
-#include <vm86.h>
-
-#define        offsetof(type, member)  ((unsigned) &((type *)0)->member)
-
-struct vmx_assist_context;
-
-#include "../hvmloader/e820.h"
-
-extern void cpuid_addr_value(uint64_t addr, uint64_t *value);
-extern void hexdump(unsigned char *, int);
-extern void dump_regs(struct regs *);
-extern void dump_vmx_context(struct vmx_assist_context *);
-extern void print_e820_map(struct e820entry *, int);
-extern void dump_dtr(unsigned long, unsigned long);
-extern void *memcpy(void *, const void *, unsigned);
-extern void *memset(void *, int, unsigned);
-extern int printf(const char *fmt, ...);
-extern int vprintf(const char *fmt, va_list ap);
-extern void panic(const char *format, ...);
-extern void halt(void);
-
-#endif /* __UTIL_H__ */
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1992 +0,0 @@
-/*
- * vm86.c: A vm86 emulator. The main purpose of this emulator is to do as
- * little work as possible.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005-2006, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "vm86.h"
-#include "util.h"
-#include "machine.h"
-
-#define        HIGHMEM         (1 << 20)               /* 1MB */
-#define        MASK16(v)       ((v) & 0xFFFF)
-
-#define        DATA32          0x0001
-#define        ADDR32          0x0002
-#define        SEG_CS          0x0004
-#define        SEG_DS          0x0008
-#define        SEG_ES          0x0010
-#define        SEG_SS          0x0020
-#define        SEG_FS          0x0040
-#define        SEG_GS          0x0080
-#define REP            0x0100
-
-static unsigned prev_eip = 0;
-enum vm86_mode mode = 0;
-
-static struct regs saved_rm_regs;
-
-#ifdef DEBUG
-int traceset = 0;
-
-char *states[] = {
-       "<VM86_REAL>",
-       "<VM86_REAL_TO_PROTECTED>",
-       "<VM86_PROTECTED_TO_REAL>",
-       "<VM86_PROTECTED>"
-};
-
-static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
-#endif /* DEBUG */
-
-#define PDE_PS                         (1 << 7)
-#define PT_ENTRY_PRESENT       0x1
-
-/* We only support access to <=4G physical memory due to 1:1 mapping */
-static uint64_t
-guest_linear_to_phys(uint32_t base)
-{
-       uint32_t gcr3 = oldctx.cr3;
-       uint64_t l2_mfn;
-       uint64_t l1_mfn;
-       uint64_t l0_mfn;
-
-       if (!(oldctx.cr0 & CR0_PG))
-               return base;
-
-       if (!(oldctx.cr4 & CR4_PAE)) {
-               l1_mfn = ((uint32_t *)(long)gcr3)[(base >> 22) & 0x3ff];
-               if (!(l1_mfn & PT_ENTRY_PRESENT))
-                       panic("l2 entry not present\n");
-
-               if ((oldctx.cr4 & CR4_PSE) && (l1_mfn & PDE_PS)) {
-                       l0_mfn = l1_mfn & 0xffc00000;
-                       return l0_mfn + (base & 0x3fffff);
-               }
-
-               l1_mfn &= 0xfffff000;
-
-               l0_mfn = ((uint32_t *)(long)l1_mfn)[(base >> 12) & 0x3ff];
-               if (!(l0_mfn & PT_ENTRY_PRESENT))
-                       panic("l1 entry not present\n");
-               l0_mfn &= 0xfffff000;
-
-               return l0_mfn + (base & 0xfff);
-       } else {
-               l2_mfn = ((uint64_t *)(long)gcr3)[(base >> 30) & 0x3];
-               if (!(l2_mfn & PT_ENTRY_PRESENT))
-                       panic("l3 entry not present\n");
-               l2_mfn &= 0xffffff000ULL;
-
-               if (l2_mfn & 0xf00000000ULL) {
-                       printf("l2 page above 4G\n");
-                       cpuid_addr_value(l2_mfn + 8 * ((base >> 21) & 0x1ff), 
&l1_mfn);
-               } else
-                       l1_mfn = ((uint64_t *)(long)l2_mfn)[(base >> 21) & 
0x1ff];
-               if (!(l1_mfn & PT_ENTRY_PRESENT))
-                       panic("l2 entry not present\n");
-
-               if (l1_mfn & PDE_PS) { /* CR4.PSE is ignored in PAE mode */
-                       l0_mfn = l1_mfn & 0xfffe00000ULL;
-                       return l0_mfn + (base & 0x1fffff);
-               }
-
-               l1_mfn &= 0xffffff000ULL;
-
-               if (l1_mfn & 0xf00000000ULL) {
-                       printf("l1 page above 4G\n");
-                       cpuid_addr_value(l1_mfn + 8 * ((base >> 12) & 0x1ff), 
&l0_mfn);
-               } else
-                       l0_mfn = ((uint64_t *)(long)l1_mfn)[(base >> 12) & 
0x1ff];
-               if (!(l0_mfn & PT_ENTRY_PRESENT))
-                       panic("l1 entry not present\n");
-
-               l0_mfn &= 0xffffff000ULL;
-
-               return l0_mfn + (base & 0xfff);
-       }
-}
-
-static unsigned
-address(struct regs *regs, unsigned seg, unsigned off)
-{
-       uint64_t gdt_phys_base;
-       unsigned long long entry;
-       unsigned seg_base, seg_limit;
-       unsigned entry_low, entry_high;
-
-       if (seg == 0) {
-               if (mode == VM86_REAL || mode == VM86_REAL_TO_PROTECTED)
-                       return off;
-               else
-                       panic("segment is zero, but not in real mode!\n");
-       }
-
-       if (mode == VM86_REAL || seg > oldctx.gdtr_limit ||
-               (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg))
-               return ((seg & 0xFFFF) << 4) + off;
-
-       gdt_phys_base = guest_linear_to_phys(oldctx.gdtr_base);
-       if (gdt_phys_base != (uint32_t)gdt_phys_base) {
-               printf("gdt base address above 4G\n");
-               cpuid_addr_value(gdt_phys_base + 8 * (seg >> 3), &entry);
-       } else
-               entry = ((unsigned long long *)(long)gdt_phys_base)[seg >> 3];
-
-       entry_high = entry >> 32;
-       entry_low = entry & 0xFFFFFFFF;
-
-       seg_base  = (entry_high & 0xFF000000) | ((entry >> 16) & 0xFFFFFF);
-       seg_limit = (entry_high & 0xF0000) | (entry_low & 0xFFFF);
-
-       if (entry_high & 0x8000 &&
-               ((entry_high & 0x800000 && off >> 12 <= seg_limit) ||
-               (!(entry_high & 0x800000) && off <= seg_limit)))
-               return seg_base + off;
-
-       panic("should never reach here in function address():\n\t"
-                 "entry=0x%08x%08x, mode=%d, seg=0x%08x, offset=0x%08x\n",
-                 entry_high, entry_low, mode, seg, off);
-
-       return 0;
-}
-
-#ifdef DEBUG
-void
-trace(struct regs *regs, int adjust, char *fmt, ...)
-{
-       unsigned off = regs->eip - adjust;
-       va_list ap;
-
-       if ((traceset & (1 << mode)) &&
-               (mode == VM86_REAL_TO_PROTECTED || mode == VM86_REAL)) {
-               /* 16-bit, seg:off addressing */
-               unsigned addr = address(regs, regs->cs, off);
-               printf("0x%08x: 0x%x:0x%04x ", addr, regs->cs, off);
-               printf("(%d) ", mode);
-               va_start(ap, fmt);
-               vprintf(fmt, ap);
-               va_end(ap);
-               printf("\n");
-       }
-       if ((traceset & (1 << mode)) &&
-               (mode == VM86_PROTECTED_TO_REAL || mode == VM86_PROTECTED)) {
-               /* 16-bit, gdt addressing */
-               unsigned addr = address(regs, regs->cs, off);
-               printf("0x%08x: 0x%x:0x%08x ", addr, regs->cs, off);
-               printf("(%d) ", mode);
-               va_start(ap, fmt);
-               vprintf(fmt, ap);
-               va_end(ap);
-               printf("\n");
-       }
-}
-#endif /* DEBUG */
-
-static inline unsigned
-read32(unsigned addr)
-{
-       return *(unsigned long *) addr;
-}
-
-static inline unsigned
-read16(unsigned addr)
-{
-       return *(unsigned short *) addr;
-}
-
-static inline unsigned
-read8(unsigned addr)
-{
-       return *(unsigned char *) addr;
-}
-
-static inline void
-write32(unsigned addr, unsigned value)
-{
-       *(unsigned long *) addr = value;
-}
-
-static inline void
-write16(unsigned addr, unsigned value)
-{
-       *(unsigned short *) addr = value;
-}
-
-static inline void
-write8(unsigned addr, unsigned value)
-{
-       *(unsigned char *) addr = value;
-}
-
-static inline void
-push32(struct regs *regs, unsigned value)
-{
-       regs->uesp -= 4;
-       write32(address(regs, regs->uss, MASK16(regs->uesp)), value);
-}
-
-static inline void
-push16(struct regs *regs, unsigned value)
-{
-       regs->uesp -= 2;
-       write16(address(regs, regs->uss, MASK16(regs->uesp)), value);
-}
-
-static inline unsigned
-pop32(struct regs *regs)
-{
-       unsigned value = read32(address(regs, regs->uss, MASK16(regs->uesp)));
-       regs->uesp += 4;
-       return value;
-}
-
-static inline unsigned
-pop16(struct regs *regs)
-{
-       unsigned value = read16(address(regs, regs->uss, MASK16(regs->uesp)));
-       regs->uesp += 2;
-       return value;
-}
-
-static inline unsigned
-fetch32(struct regs *regs)
-{
-       unsigned addr = address(regs, regs->cs, MASK16(regs->eip));
-
-       regs->eip += 4;
-       return read32(addr);
-}
-
-static inline unsigned
-fetch16(struct regs *regs)
-{
-       unsigned addr = address(regs, regs->cs, MASK16(regs->eip));
-
-       regs->eip += 2;
-       return read16(addr);
-}
-
-static inline unsigned
-fetch8(struct regs *regs)
-{
-       unsigned addr = address(regs, regs->cs, MASK16(regs->eip));
-
-       regs->eip++;
-       return read8(addr);
-}
-
-static unsigned
-getreg32(struct regs *regs, int r)
-{
-       switch (r & 7) {
-       case 0: return regs->eax;
-       case 1: return regs->ecx;
-       case 2: return regs->edx;
-       case 3: return regs->ebx;
-       case 4: return regs->uesp;
-       case 5: return regs->ebp;
-       case 6: return regs->esi;
-       case 7: return regs->edi;
-       }
-       return ~0;
-}
-
-static unsigned
-getreg16(struct regs *regs, int r)
-{
-       return MASK16(getreg32(regs, r));
-}
-
-static unsigned
-getreg8(struct regs *regs, int r)
-{
-       switch (r & 7) {
-       case 0: return regs->eax & 0xFF; /* al */
-       case 1: return regs->ecx & 0xFF; /* cl */
-       case 2: return regs->edx & 0xFF; /* dl */
-       case 3: return regs->ebx & 0xFF; /* bl */
-       case 4: return (regs->eax >> 8) & 0xFF; /* ah */
-       case 5: return (regs->ecx >> 8) & 0xFF; /* ch */
-       case 6: return (regs->edx >> 8) & 0xFF; /* dh */
-       case 7: return (regs->ebx >> 8) & 0xFF; /* bh */
-       }
-       return ~0;
-}
-
-static void
-setreg32(struct regs *regs, int r, unsigned v)
-{
-       switch (r & 7) {
-       case 0: regs->eax = v; break;
-       case 1: regs->ecx = v; break;
-       case 2: regs->edx = v; break;
-       case 3: regs->ebx = v; break;
-       case 4: regs->uesp = v; break;
-       case 5: regs->ebp = v; break;
-       case 6: regs->esi = v; break;
-       case 7: regs->edi = v; break;
-       }
-}
-
-static void
-setreg16(struct regs *regs, int r, unsigned v)
-{
-       setreg32(regs, r, (getreg32(regs, r) & ~0xFFFF) | MASK16(v));
-}
-
-static void
-setreg8(struct regs *regs, int r, unsigned v)
-{
-       v &= 0xFF;
-       switch (r & 7) {
-       case 0: regs->eax = (regs->eax & ~0xFF) | v; break;
-       case 1: regs->ecx = (regs->ecx & ~0xFF) | v; break;
-       case 2: regs->edx = (regs->edx & ~0xFF) | v; break;
-       case 3: regs->ebx = (regs->ebx & ~0xFF) | v; break;
-       case 4: regs->eax = (regs->eax & ~0xFF00) | (v << 8); break;
-       case 5: regs->ecx = (regs->ecx & ~0xFF00) | (v << 8); break;
-       case 6: regs->edx = (regs->edx & ~0xFF00) | (v << 8); break;
-       case 7: regs->ebx = (regs->ebx & ~0xFF00) | (v << 8); break;
-       }
-}
-
-static unsigned
-segment(unsigned prefix, struct regs *regs, unsigned seg)
-{
-       if (prefix & SEG_ES)
-               seg = regs->ves;
-       if (prefix & SEG_DS)
-               seg = regs->vds;
-       if (prefix & SEG_CS)
-               seg = regs->cs;
-       if (prefix & SEG_SS)
-               seg = regs->uss;
-       if (prefix & SEG_FS)
-               seg = regs->vfs;
-       if (prefix & SEG_GS)
-               seg = regs->vgs;
-       return seg;
-}
-
-static unsigned
-sib(struct regs *regs, int mod, unsigned byte)
-{
-       unsigned scale = (byte >> 6) & 3;
-       int index = (byte >> 3) & 7;
-       int base = byte & 7;
-       unsigned addr = 0;
-
-       switch (mod) {
-       case 0:
-               if (base == 5)
-                       addr = fetch32(regs);
-               else
-                       addr = getreg32(regs, base);
-               break;
-       case 1:
-               addr = getreg32(regs, base) + (char) fetch8(regs);
-               break;
-       case 2:
-               addr = getreg32(regs, base) + fetch32(regs);
-               break;
-       }
-
-       if (index != 4)
-               addr += getreg32(regs, index) << scale;
-
-       return addr;
-}
-
-/*
- * Operand (modrm) decode
- */
-static unsigned
-operand(unsigned prefix, struct regs *regs, unsigned modrm)
-{
-       int mod, disp = 0, seg;
-
-       seg = segment(prefix, regs, regs->vds);
-
-       if (prefix & ADDR32) { /* 32-bit addressing */
-               switch ((mod = (modrm >> 6) & 3)) {
-               case 0:
-                       switch (modrm & 7) {
-                       case 0: return address(regs, seg, regs->eax);
-                       case 1: return address(regs, seg, regs->ecx);
-                       case 2: return address(regs, seg, regs->edx);
-                       case 3: return address(regs, seg, regs->ebx);
-                       case 4: return address(regs, seg,
-                                                  sib(regs, mod, 
fetch8(regs)));
-                       case 5: return address(regs, seg, fetch32(regs));
-                       case 6: return address(regs, seg, regs->esi);
-                       case 7: return address(regs, seg, regs->edi);
-                       }
-                       break;
-               case 1:
-               case 2:
-                       if ((modrm & 7) != 4) {
-                               if (mod == 1)
-                                       disp = (char) fetch8(regs);
-                               else
-                                       disp = (int) fetch32(regs);
-                       }
-                       switch (modrm & 7) {
-                       case 0: return address(regs, seg, regs->eax + disp);
-                       case 1: return address(regs, seg, regs->ecx + disp);
-                       case 2: return address(regs, seg, regs->edx + disp);
-                       case 3: return address(regs, seg, regs->ebx + disp);
-                       case 4: return address(regs, seg,
-                                                  sib(regs, mod, 
fetch8(regs)));
-                       case 5: return address(regs, seg, regs->ebp + disp);
-                       case 6: return address(regs, seg, regs->esi + disp);
-                       case 7: return address(regs, seg, regs->edi + disp);
-                       }
-                       break;
-               case 3:
-                       return getreg32(regs, modrm);
-               }
-       } else { /* 16-bit addressing */
-               switch ((mod = (modrm >> 6) & 3)) {
-               case 0:
-                       switch (modrm & 7) {
-                       case 0: return address(regs, seg, MASK16(regs->ebx) +
-                                       MASK16(regs->esi));
-                       case 1: return address(regs, seg, MASK16(regs->ebx) +
-                                       MASK16(regs->edi));
-                       case 2: return address(regs, seg, MASK16(regs->ebp) +
-                                       MASK16(regs->esi));
-                       case 3: return address(regs, seg, MASK16(regs->ebp) +
-                                       MASK16(regs->edi));
-                       case 4: return address(regs, seg, MASK16(regs->esi));
-                       case 5: return address(regs, seg, MASK16(regs->edi));
-                       case 6: return address(regs, seg, fetch16(regs));
-                       case 7: return address(regs, seg, MASK16(regs->ebx));
-                       }
-                       break;
-               case 1:
-               case 2:
-                       if (mod == 1)
-                               disp = (char) fetch8(regs);
-                       else
-                               disp = (int) fetch16(regs);
-                       switch (modrm & 7) {
-                       case 0: return address(regs, seg, MASK16(regs->ebx) +
-                                       MASK16(regs->esi) + disp);
-                       case 1: return address(regs, seg, MASK16(regs->ebx) +
-                                       MASK16(regs->edi) + disp);
-                       case 2: return address(regs, seg, MASK16(regs->ebp) +
-                                       MASK16(regs->esi) + disp);
-                       case 3: return address(regs, seg, MASK16(regs->ebp) +
-                                       MASK16(regs->edi) + disp);
-                       case 4: return address(regs, seg,
-                                       MASK16(regs->esi) + disp);
-                       case 5: return address(regs, seg,
-                                       MASK16(regs->edi) + disp);
-                       case 6: return address(regs, seg,
-                                       MASK16(regs->ebp) + disp);
-                       case 7: return address(regs, seg,
-                                       MASK16(regs->ebx) + disp);
-                       }
-                       break;
-               case 3:
-                       return getreg16(regs, modrm);
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Load new IDT
- */
-static int
-lidt(struct regs *regs, unsigned prefix, unsigned modrm)
-{
-       unsigned eip = regs->eip - 3;
-       unsigned addr = operand(prefix, regs, modrm);
-
-       oldctx.idtr_limit = ((struct dtr *) addr)->size;
-       if ((prefix & DATA32) == 0)
-               oldctx.idtr_base = ((struct dtr *) addr)->base & 0xFFFFFF;
-       else
-               oldctx.idtr_base = ((struct dtr *) addr)->base;
-       TRACE((regs, regs->eip - eip, "lidt 0x%x <%d, 0x%x>",
-               addr, oldctx.idtr_limit, oldctx.idtr_base));
-
-       return 1;
-}
-
-/*
- * Load new GDT
- */
-static int
-lgdt(struct regs *regs, unsigned prefix, unsigned modrm)
-{
-       unsigned eip = regs->eip - 3;
-       unsigned addr = operand(prefix, regs, modrm);
-
-       oldctx.gdtr_limit = ((struct dtr *) addr)->size;
-       if ((prefix & DATA32) == 0)
-               oldctx.gdtr_base = ((struct dtr *) addr)->base & 0xFFFFFF;
-       else
-               oldctx.gdtr_base = ((struct dtr *) addr)->base;
-       TRACE((regs, regs->eip - eip, "lgdt 0x%x <%d, 0x%x>",
-               addr, oldctx.gdtr_limit, oldctx.gdtr_base));
-
-       return 1;
-}
-
-/*
- * Modify CR0 either through an lmsw instruction.
- */
-static int
-lmsw(struct regs *regs, unsigned prefix, unsigned modrm)
-{
-       unsigned eip = regs->eip - 3;
-       unsigned ax = operand(prefix, regs, modrm) & 0xF;
-       unsigned cr0 = (oldctx.cr0 & 0xFFFFFFF0) | ax;
-
-       TRACE((regs, regs->eip - eip, "lmsw 0x%x", ax));
-       oldctx.cr0 = cr0 | CR0_PE | CR0_NE;
-       if (cr0 & CR0_PE)
-               set_mode(regs, VM86_REAL_TO_PROTECTED);
-
-       return 1;
-}
-
-/*
- * We need to handle moves that address memory beyond the 64KB segment
- * limit that VM8086 mode enforces.
- */
-static int
-movr(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned modrm = fetch8(regs);
-       unsigned addr = operand(prefix, regs, modrm);
-       unsigned val, r = (modrm >> 3) & 7;
-
-       if ((modrm & 0xC0) == 0xC0) {
-               /*
-                * Emulate all guest instructions in protected to real mode.
-                */
-               if (mode != VM86_PROTECTED_TO_REAL)
-                       return 0;
-       }
-
-       switch (opc) {
-       case 0x88: /* addr32 mov r8, r/m8 */
-               val = getreg8(regs, r);
-               TRACE((regs, regs->eip - eip,
-                       "movb %%e%s, *0x%x", rnames[r], addr));
-               write8(addr, val);
-               return 1;
-
-       case 0x8A: /* addr32 mov r/m8, r8 */
-               TRACE((regs, regs->eip - eip,
-                       "movb *0x%x, %%%s", addr, rnames[r]));
-               setreg8(regs, r, read8(addr));
-               return 1;
-
-       case 0x89: /* addr32 mov r16, r/m16 */
-               val = getreg32(regs, r);
-               if ((modrm & 0xC0) == 0xC0) {
-                       if (prefix & DATA32)
-                               setreg32(regs, modrm & 7, val);
-                       else
-                               setreg16(regs, modrm & 7, MASK16(val));
-                       return 1;
-               }
-
-               if (prefix & DATA32) {
-                       TRACE((regs, regs->eip - eip,
-                               "movl %%e%s, *0x%x", rnames[r], addr));
-                       write32(addr, val);
-               } else {
-                       TRACE((regs, regs->eip - eip,
-                               "movw %%%s, *0x%x", rnames[r], addr));
-                       write16(addr, MASK16(val));
-               }
-               return 1;
-
-       case 0x8B: /* mov r/m16, r16 */
-               if ((modrm & 0xC0) == 0xC0) {
-                       if (prefix & DATA32)
-                               setreg32(regs, r, addr);
-                       else
-                               setreg16(regs, r, MASK16(addr));
-                       return 1;
-               }
-
-               if (prefix & DATA32) {
-                       TRACE((regs, regs->eip - eip,
-                               "movl *0x%x, %%e%s", addr, rnames[r]));
-                       setreg32(regs, r, read32(addr));
-               } else {
-                       TRACE((regs, regs->eip - eip,
-                               "movw *0x%x, %%%s", addr, rnames[r]));
-                       setreg16(regs, r, read16(addr));
-               }
-               return 1;
-
-       case 0xC6: /* addr32 movb $imm, r/m8 */
-               if ((modrm >> 3) & 7)
-                       return 0;
-               val = fetch8(regs);
-               write8(addr, val);
-               TRACE((regs, regs->eip - eip, "movb $0x%x, *0x%x",
-                                                       val, addr));
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * We need to handle string moves that address memory beyond the 64KB segment
- * limit that VM8086 mode enforces.
- */
-static inline int
-movs(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned sseg = segment(prefix, regs, regs->vds);
-       unsigned dseg = regs->ves;
-       unsigned saddr, daddr;
-       unsigned count = 1;
-       int incr = ((regs->eflags & EFLAGS_DF) == 0) ? 1 : -1;
-
-       saddr = address(regs, sseg, regs->esi);
-       daddr = address(regs, dseg, regs->edi);
-
-       if ((prefix & REP) != 0) {
-               count = regs->ecx;
-               regs->ecx = 0;
-       }
-
-       switch (opc) {
-       case 0xA4: /* movsb */
-               regs->esi += (incr * count);
-               regs->edi += (incr * count);
-
-               while (count-- != 0) {
-                       write8(daddr, read8(saddr));
-                       daddr += incr;
-                       saddr += incr;
-               }
-               TRACE((regs, regs->eip - eip, "movsb (%%esi),%%es:(%%edi)"));
-               break;
-
-       case 0xA5: /* movsw */
-               if ((prefix & DATA32) == 0) {
-                       incr = 2 * incr;
-                       regs->esi += (incr * count);
-                       regs->edi += (incr * count);
-
-                       while (count-- != 0) {
-                               write16(daddr, read16(saddr));
-                               daddr += incr;
-                               saddr += incr;
-                       }
-               } else {
-                       incr = 4 * incr;
-                       regs->esi += (incr * count);
-                       regs->edi += (incr * count);
-
-                       while (count-- != 0) {
-                               write32(daddr, read32(saddr));
-                               daddr += incr;
-                               saddr += incr;
-                       }
-               }                       
-               TRACE((regs, regs->eip - eip, "movsw %s(%%esi),%%es:(%%edi)"));
-               break;
-       }
-
-       return 1;
-}
-
-static inline int
-lods(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned seg = segment(prefix, regs, regs->vds);
-       unsigned addr = address(regs, seg, regs->esi);
-       unsigned count = 1;
-       int incr = ((regs->eflags & EFLAGS_DF) == 0) ? 1 : -1;
-
-       if ((prefix & REP) != 0) {
-               count = regs->ecx;
-               regs->ecx = 0;
-       }
-
-       switch (opc) {
-       case 0xAD: /* lodsw */
-               if ((prefix & DATA32) == 0) {
-                       incr = 2 * incr;
-                       regs->esi += (incr * count);
-                       while (count-- != 0) {
-                               setreg16(regs, 0, read16(addr));
-                               addr += incr;
-                       }
-
-                       TRACE((regs, regs->eip - eip, "lodsw (%%esi),%%ax"));
-               } else {
-                       incr = 4 * incr;
-                       regs->esi += (incr * count);
-                       while (count-- != 0) {
-                               setreg32(regs, 0, read32(addr));
-                               addr += incr;
-                       }
-                       TRACE((regs, regs->eip - eip, "lodsw (%%esi),%%eax"));
-               }
-               break;
-       }
-       return 1;
-}
-/*
- * Move to and from a control register.
- */
-static int
-movcr(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 2;
-       unsigned modrm = fetch8(regs);
-       unsigned cr = (modrm >> 3) & 7;
-
-       if ((modrm & 0xC0) != 0xC0) /* only registers */
-               return 0;
-
-       switch (opc) {
-       case 0x20: /* mov Rd, Cd */
-               TRACE((regs, regs->eip - eip, "movl %%cr%d, %%eax", cr));
-               switch (cr) {
-               case 0:
-                       setreg32(regs, modrm,
-                               oldctx.cr0 & ~(CR0_PE | CR0_NE));
-                       break;
-               case 2:
-                       setreg32(regs, modrm, get_cr2());
-                       break;
-               case 3:
-                       setreg32(regs, modrm, oldctx.cr3);
-                       break;
-               case 4:
-                       setreg32(regs, modrm, oldctx.cr4);
-                       break;
-               }
-               break;
-       case 0x22: /* mov Cd, Rd */
-               TRACE((regs, regs->eip - eip, "movl %%eax, %%cr%d", cr));
-               switch (cr) {
-               case 0:
-                       oldctx.cr0 = getreg32(regs, modrm) | (CR0_PE | CR0_NE);
-                       if (getreg32(regs, modrm) & CR0_PE)
-                               set_mode(regs, VM86_REAL_TO_PROTECTED);
-                       else
-                               set_mode(regs, VM86_REAL);
-                       break;
-               case 3:
-                       oldctx.cr3 = getreg32(regs, modrm);
-                       break;
-               case 4:
-                       oldctx.cr4 = getreg32(regs, modrm);
-                       break;
-               }
-               break;
-       }
-
-       return 1;
-}
-
-static inline void set_eflags_ZF(unsigned mask, unsigned v1, struct regs *regs)
-{
-       if ((v1 & mask) == 0)
-               regs->eflags |= EFLAGS_ZF;
-       else
-               regs->eflags &= ~EFLAGS_ZF;
-}
-
-static void set_eflags_add(unsigned hi_bit_mask, unsigned v1, unsigned v2,
-                               unsigned result, struct regs *regs)
-{
-       int bit_count;
-       unsigned tmp;
-       unsigned full_mask;
-       unsigned nonsign_mask;
-
-       /* Carry out of high order bit? */
-       if ( v1 & v2 & hi_bit_mask )
-               regs->eflags |= EFLAGS_CF;
-       else
-               regs->eflags &= ~EFLAGS_CF;
-
-       /* Even parity in least significant byte? */
-       tmp = result & 0xff;
-       for (bit_count = 0; tmp != 0; bit_count++)
-               tmp &= (tmp - 1);
-
-       if (bit_count & 1)
-               regs->eflags &= ~EFLAGS_PF;
-       else
-               regs->eflags |= EFLAGS_PF;
-
-       /* Carry out of least significant BCD digit? */
-       if ( v1 & v2 & (1<<3) )
-               regs->eflags |= EFLAGS_AF;
-       else
-               regs->eflags &= ~EFLAGS_AF;
-
-       /* Result is zero? */
-       full_mask = (hi_bit_mask - 1) | hi_bit_mask;
-       set_eflags_ZF(full_mask, result, regs);
-
-       /* Sign of result? */
-       if ( result & hi_bit_mask )
-               regs->eflags |= EFLAGS_SF;
-       else
-               regs->eflags &= ~EFLAGS_SF;
-
-       /* Carry out of highest non-sign bit? */
-       nonsign_mask = (hi_bit_mask >> 1) & ~hi_bit_mask;
-       if ( v1 & v2 & hi_bit_mask )
-               regs->eflags |= EFLAGS_OF;
-       else
-               regs->eflags &= ~EFLAGS_OF;
-
-}
-
-/*
- * We need to handle cmp opcodes that address memory beyond the 64KB
- * segment limit that VM8086 mode enforces.
- */
-static int
-cmp(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned modrm = fetch8(regs);
-       unsigned addr = operand(prefix, regs, modrm);
-       unsigned diff, val, r = (modrm >> 3) & 7;
-
-       if ((modrm & 0xC0) == 0xC0) /* no registers */
-               return 0;
-
-       switch (opc) {
-       case 0x39: /* addr32 cmp r16, r/m16 */
-               val = getreg32(regs, r);
-               if (prefix & DATA32) {
-                       diff = read32(addr) - val;
-                       set_eflags_ZF(~0, diff, regs);
-
-                       TRACE((regs, regs->eip - eip,
-                               "cmp %%e%s, *0x%x (0x%x)",
-                               rnames[r], addr, diff));
-               } else {
-                       diff = read16(addr) - val;
-                       set_eflags_ZF(0xFFFF, diff, regs);
-
-                       TRACE((regs, regs->eip - eip,
-                               "cmp %%%s, *0x%x (0x%x)",
-                               rnames[r], addr, diff));
-               }
-               break;
-
-       /* other cmp opcodes ... */
-       }
-       return 1;
-}
-
-/*
- * We need to handle test opcodes that address memory beyond the 64KB
- * segment limit that VM8086 mode enforces.
- */
-static int
-test(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned modrm = fetch8(regs);
-       unsigned addr = operand(prefix, regs, modrm);
-       unsigned val, diff;
-
-       if ((modrm & 0xC0) == 0xC0) /* no registers */
-               return 0;
-
-       switch (opc) {
-       case 0xF6: /* testb $imm, r/m8 */
-               if ((modrm >> 3) & 7)
-                       return 0;
-               val = fetch8(regs);
-               diff = read8(addr) & val;
-               set_eflags_ZF(0xFF, diff, regs);
-
-               TRACE((regs, regs->eip - eip, "testb $0x%x, *0x%x (0x%x)",
-                                                       val, addr, diff));
-               break;
-
-       /* other test opcodes ... */
-       }
-
-       return 1;
-}
-
-/*
- * We need to handle add opcodes that address memory beyond the 64KB
- * segment limit that VM8086 mode enforces.
- */
-static int
-add(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned modrm = fetch8(regs);
-       unsigned addr = operand(prefix, regs, modrm);
-       unsigned r = (modrm >> 3) & 7;
-
-       unsigned val1 = 0;
-       unsigned val2 = 0;
-       unsigned result = 0;
-       unsigned hi_bit;
-
-       if ((modrm & 0xC0) == 0xC0) /* no registers */
-               return 0;
-
-       switch (opc) {
-       case 0x00: /* addr32 add r8, r/m8 */
-               val1 = getreg8(regs, r);
-               val2 = read8(addr);
-               result = val1 + val2;
-               write8(addr, result);
-               TRACE((regs, regs->eip - eip,
-                       "addb %%e%s, *0x%x", rnames[r], addr));
-               break;
-               
-       case 0x01: /* addr32 add r16, r/m16 */
-               if (prefix & DATA32) {
-                       val1 = getreg32(regs, r);
-                       val2 = read32(addr);
-                       result = val1 + val2;
-                       write32(addr, result);
-                       TRACE((regs, regs->eip - eip,
-                               "addl %%e%s, *0x%x", rnames[r], addr));
-               } else {
-                       val1 = getreg16(regs, r);
-                       val2 = read16(addr);
-                       result = val1 + val2;
-                       write16(addr, result);
-                       TRACE((regs, regs->eip - eip,
-                               "addw %%e%s, *0x%x", rnames[r], addr));
-               }
-               break;
-               
-       case 0x03: /* addr32 add r/m16, r16 */
-               if (prefix & DATA32) {
-                       val1 = getreg32(regs, r);
-                       val2 = read32(addr);
-                       result = val1 + val2;
-                       setreg32(regs, r, result);
-                       TRACE((regs, regs->eip - eip,
-                               "addl *0x%x, %%e%s", addr, rnames[r]));
-               } else {
-                       val1 = getreg16(regs, r);
-                       val2 = read16(addr);
-                       result = val1 + val2;
-                       setreg16(regs, r, result);
-                       TRACE((regs, regs->eip - eip,
-                               "addw *0x%x, %%%s", addr, rnames[r]));
-               }
-               break;
-       }
-
-       if (opc == 0x00)
-               hi_bit = (1<<7);
-       else
-               hi_bit = (prefix & DATA32) ? (1<<31) : (1<<15);
-       set_eflags_add(hi_bit, val1, val2, result, regs);
-
-       return 1;
-}
-
-/*
- * We need to handle pop opcodes that address memory beyond the 64KB
- * segment limit that VM8086 mode enforces.
- */
-static int
-pop(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned modrm = fetch8(regs);
-       unsigned addr = operand(prefix, regs, modrm);
-
-       if ((modrm & 0xC0) == 0xC0) /* no registers */
-               return 0;
-
-       switch (opc) {
-       case 0x8F: /* pop r/m16 */
-               if ((modrm >> 3) & 7)
-                       return 0;
-               if (prefix & DATA32)
-                       write32(addr, pop32(regs));
-               else
-                       write16(addr, pop16(regs));
-               TRACE((regs, regs->eip - eip, "pop *0x%x", addr));
-               break;
-
-       /* other pop opcodes ... */
-       }
-
-       return 1;
-}
-
-static int
-mov_to_seg(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned modrm = fetch8(regs);
-
-       /*
-        * Emulate segment loads in:
-        * 1) real->protected mode.
-        * 2) protected->real mode.
-        */
-       if (mode != VM86_REAL_TO_PROTECTED &&
-           mode != VM86_PROTECTED_TO_REAL)
-               return 0;
-
-       /* Register source only. */
-       if ((modrm & 0xC0) != 0xC0)
-               goto fail;
-
-       switch ((modrm & 0x38) >> 3) {
-       case 0: /* es */
-               regs->ves = getreg16(regs, modrm);
-               if (mode == VM86_PROTECTED_TO_REAL)
-                       return 1;
-               saved_rm_regs.ves = 0;
-               oldctx.es_sel = regs->ves;
-               return 1;
-
-       /* case 1: cs */
-
-       case 2: /* ss */
-               regs->uss = getreg16(regs, modrm);
-               if (mode == VM86_PROTECTED_TO_REAL)
-                       return 1;
-               saved_rm_regs.uss = 0;
-               oldctx.ss_sel = regs->uss;
-               return 1;
-       case 3: /* ds */
-               regs->vds = getreg16(regs, modrm);
-               if (mode == VM86_PROTECTED_TO_REAL)
-                       return 1;
-               saved_rm_regs.vds = 0;
-               oldctx.ds_sel = regs->vds;
-               return 1;
-       case 4: /* fs */
-               regs->vfs = getreg16(regs, modrm);
-               if (mode == VM86_PROTECTED_TO_REAL)
-                       return 1;
-               saved_rm_regs.vfs = 0;
-               oldctx.fs_sel = regs->vfs;
-               return 1;
-       case 5: /* gs */
-               regs->vgs = getreg16(regs, modrm);
-               if (mode == VM86_PROTECTED_TO_REAL)
-                       return 1;
-               saved_rm_regs.vgs = 0;
-               oldctx.gs_sel = regs->vgs;
-               return 1;
-       }
-
- fail:
-       printf("%s:%d: missed opcode %02x %02x\n",
-                  __FUNCTION__, __LINE__, opc, modrm);
-       return 0;
-}
-
-/*
- * Emulate a segment load in protected mode
- */
-static int
-load_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union 
vmcs_arbytes *arbytes)
-{
-       uint64_t gdt_phys_base;
-       unsigned long long entry;
-
-       /* protected mode: use seg as index into gdt */
-       if (sel > oldctx.gdtr_limit)
-               return 0;
-
-       if (sel == 0) {
-               arbytes->fields.null_bit = 1;
-               return 1;
-       }
-
-       gdt_phys_base = guest_linear_to_phys(oldctx.gdtr_base);
-       if (gdt_phys_base != (uint32_t)gdt_phys_base) {
-               printf("gdt base address above 4G\n");
-               cpuid_addr_value(gdt_phys_base + 8 * (sel >> 3), &entry);
-       } else
-               entry = ((unsigned long long *)(long)gdt_phys_base)[sel >> 3];
-
-       /* Check the P bit first */
-       if (!((entry >> (15+32)) & 0x1) && sel != 0)
-               return 0;
-
-       *base =  (((entry >> (56-24)) & 0xFF000000) |
-                 ((entry >> (32-16)) & 0x00FF0000) |
-                 ((entry >> (   16)) & 0x0000FFFF));
-       *limit = (((entry >> (48-16)) & 0x000F0000) |
-                 (entry & 0x0000FFFF));
-
-       arbytes->bytes = 0;
-       arbytes->fields.seg_type = (entry >> (8+32)) & 0xF; /* TYPE */
-       arbytes->fields.s = (entry >> (12+32)) & 0x1; /* S */
-       if (arbytes->fields.s)
-               arbytes->fields.seg_type |= 1; /* accessed */
-       arbytes->fields.dpl = (entry >> (13+32)) & 0x3; /* DPL */
-       arbytes->fields.p = (entry >> (15+32)) & 0x1; /* P */
-       arbytes->fields.avl = (entry >> (20+32)) & 0x1; /* AVL */
-       arbytes->fields.default_ops_size = (entry >> (22+32)) & 0x1; /* D */
-
-       if (entry & (1ULL << (23+32))) { /* G */
-               arbytes->fields.g = 1;
-               *limit = (*limit << 12) | 0xFFF;
-       }
-
-       return 1;
-}
-
-/*
- * Emulate a protected mode segment load, falling back to clearing it if
- * the descriptor was invalid.
- */
-static void
-load_or_clear_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union 
vmcs_arbytes *arbytes)
-{
-       if (!load_seg(sel, base, limit, arbytes))
-               load_seg(0, base, limit, arbytes);
-}
-
-static unsigned char rm_irqbase[2];
-
-/*
- * Transition to protected mode
- */
-static void
-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);
-
-       oldctx.eip = regs->eip;
-       oldctx.esp = regs->uesp;
-       oldctx.eflags = regs->eflags;
-
-       /* reload all segment registers */
-       if (!load_seg(regs->cs, &oldctx.cs_base,
-                               &oldctx.cs_limit, &oldctx.cs_arbytes))
-               panic("Invalid %%cs=0x%x for protected mode\n", regs->cs);
-       oldctx.cs_sel = regs->cs;
-
-       load_or_clear_seg(oldctx.es_sel, &oldctx.es_base,
-                         &oldctx.es_limit, &oldctx.es_arbytes);
-       load_or_clear_seg(oldctx.ss_sel, &oldctx.ss_base,
-                         &oldctx.ss_limit, &oldctx.ss_arbytes);
-       load_or_clear_seg(oldctx.ds_sel, &oldctx.ds_base,
-                         &oldctx.ds_limit, &oldctx.ds_arbytes);
-       load_or_clear_seg(oldctx.fs_sel, &oldctx.fs_base,
-                         &oldctx.fs_limit, &oldctx.fs_arbytes);
-       load_or_clear_seg(oldctx.gs_sel, &oldctx.gs_base,
-                         &oldctx.gs_limit, &oldctx.gs_arbytes);
-
-       /* initialize jump environment to warp back to protected mode */
-       regs->uss = DATA_SELECTOR;
-       regs->uesp = (unsigned long)stack_top;
-       regs->cs = CODE_SELECTOR;
-       regs->eip = (unsigned long)switch_to_protected_mode;
-
-       /* this should get us into 32-bit mode */
-}
-
-/*
- * Start real-mode emulation
- */
-static void
-real_mode(struct regs *regs)
-{
-       regs->eflags |= EFLAGS_VM | 0x02;
-
-       /*
-        * When we transition from protected to real-mode and we
-        * have not reloaded the segment descriptors yet, they are
-        * interpreted as if they were in protect mode.
-        * We emulate this behavior by assuming that these memory
-        * reference are below 1MB and set %ss, %ds, %es accordingly.
-        */
-       if (regs->uss != 0) {
-               if (regs->uss >= HIGHMEM)
-                       panic("%%ss 0x%lx higher than 1MB", regs->uss);
-               regs->uss = address(regs, regs->uss, 0) >> 4;
-       } else {
-               regs->uss = saved_rm_regs.uss;
-       }
-       if (regs->vds != 0) {
-               if (regs->vds >= HIGHMEM)
-                       panic("%%ds 0x%lx higher than 1MB", regs->vds);
-               regs->vds = address(regs, regs->vds, 0) >> 4;
-       } else {
-               regs->vds = saved_rm_regs.vds;
-       }
-       if (regs->ves != 0) {
-               if (regs->ves >= HIGHMEM)
-                       panic("%%es 0x%lx higher than 1MB", regs->ves);
-               regs->ves = address(regs, regs->ves, 0) >> 4;
-       } else {
-               regs->ves = saved_rm_regs.ves;
-       }
-
-       /* this should get us into 16-bit mode */
-}
-
-/*
- * This is the smarts of the emulator and handles the mode transitions. The
- * emulator handles 4 different modes. 1) VM86_REAL: emulated real-mode,
- * Just handle those instructions that are not supported under VM8086.
- * 2) VM86_REAL_TO_PROTECTED: going from real-mode to protected mode. In
- * this we single step through the instructions until we reload the
- * new %cs (some OSes do a lot of computations before reloading %cs). 2)
- * VM86_PROTECTED_TO_REAL when we are going from protected to real mode. In
- * this case we emulate the instructions by hand. Finally, 4) VM86_PROTECTED
- * when we transitioned to protected mode and we should abandon the
- * emulator. No instructions are emulated when in VM86_PROTECTED mode.
- */
-void
-set_mode(struct regs *regs, enum vm86_mode newmode)
-{
-       switch (newmode) {
-       case VM86_REAL:
-               if (mode == VM86_PROTECTED_TO_REAL ||
-                   mode == VM86_REAL_TO_PROTECTED) {
-                       regs->eflags &= ~EFLAGS_TF;
-                       real_mode(regs);
-               } else if (mode != VM86_REAL)
-                       panic("unexpected real mode transition");
-               break;
-
-       case VM86_REAL_TO_PROTECTED:
-               if (mode == VM86_REAL) {
-                       regs->eflags |= EFLAGS_TF;
-                       saved_rm_regs.vds = regs->vds;
-                       saved_rm_regs.ves = regs->ves;
-                       saved_rm_regs.vfs = regs->vfs;
-                       saved_rm_regs.vgs = regs->vgs;
-                       saved_rm_regs.uss = regs->uss;
-                       oldctx.ds_sel = 0;
-                       oldctx.es_sel = 0;
-                       oldctx.fs_sel = 0;
-                       oldctx.gs_sel = 0;
-                       oldctx.ss_sel = 0;
-               } else if (mode != VM86_REAL_TO_PROTECTED)
-                       panic("unexpected real-to-protected mode transition");
-               break;
-
-       case VM86_PROTECTED_TO_REAL:
-               if (mode != VM86_PROTECTED)
-                       panic("unexpected protected-to-real mode transition");
-               break;
-
-       case VM86_PROTECTED:
-               if (mode != VM86_REAL_TO_PROTECTED)
-                       panic("unexpected protected mode transition");
-               protected_mode(regs);
-               break;
-       }
-
-       mode = newmode;
-       if (mode != VM86_PROTECTED)
-               TRACE((regs, 0, states[mode]));
-}
-
-static void
-jmpl(struct regs *regs, int prefix)
-{
-       unsigned n = regs->eip;
-       unsigned cs, eip;
-
-       eip = (prefix & DATA32) ? fetch32(regs) : fetch16(regs);
-       cs = fetch16(regs);
-
-       TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
-
-       regs->cs = cs;
-       regs->eip = eip;
-
-       if (mode == VM86_REAL_TO_PROTECTED)             /* jump to protected 
mode */
-               set_mode(regs, VM86_PROTECTED);
-       else if (mode == VM86_PROTECTED_TO_REAL)        /* jump to real mode */
-               set_mode(regs, VM86_REAL);
-       else
-               panic("jmpl");
-}
-
-static void
-jmpl_indirect(struct regs *regs, int prefix, unsigned modrm)
-{
-       unsigned n = regs->eip;
-       unsigned cs, eip;
-       unsigned addr;
-
-       addr = operand(prefix, regs, modrm);
-
-       eip = (prefix & DATA32) ? read32(addr) : read16(addr);
-       addr += (prefix & DATA32) ? 4 : 2;
-       cs = read16(addr);
-
-       TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
-
-       regs->cs = cs;
-       regs->eip = eip;
-
-       if (mode == VM86_REAL_TO_PROTECTED)             /* jump to protected 
mode */
-               set_mode(regs, VM86_PROTECTED);
-       else if (mode == VM86_PROTECTED_TO_REAL)        /* jump to real mode */
-               set_mode(regs, VM86_REAL);
-       else
-               panic("jmpl");
-}
-
-static void
-retl(struct regs *regs, int prefix)
-{
-       unsigned cs, eip;
-
-       if (prefix & DATA32) {
-               eip = pop32(regs);
-               cs = MASK16(pop32(regs));
-       } else {
-               eip = pop16(regs);
-               cs = pop16(regs);
-       }
-
-       TRACE((regs, 1, "retl (to 0x%x:0x%x)", cs, eip));
-
-       regs->cs = cs;
-       regs->eip = eip;
-
-       if (mode == VM86_REAL_TO_PROTECTED)             /* jump to protected 
mode */
-               set_mode(regs, VM86_PROTECTED);
-       else if (mode == VM86_PROTECTED_TO_REAL)        /* jump to real mode */
-               set_mode(regs, VM86_REAL);
-       else
-               panic("retl");
-}
-
-static void
-interrupt(struct regs *regs, int n)
-{
-       TRACE((regs, 0, "external interrupt %d", n));
-       push16(regs, regs->eflags);
-       push16(regs, regs->cs);
-       push16(regs, regs->eip);
-       regs->eflags &= ~EFLAGS_IF;
-       regs->eip = read16(address(regs, 0, n * 4));
-       regs->cs = read16(address(regs, 0, n * 4 + 2));
-}
-
-/*
- * Most port I/O operations are passed unmodified. We do have to be
- * careful and make sure the emulated program isn't remapping the
- * interrupt vectors. The following simple state machine catches
- * these attempts and rewrites them.
- */
-static int
-outbyte(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       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:
-               if (al & (1 << 4)) /* A0=0,D4=1 -> ICW1 */
-                       icw2[0] = 1;
-               break;
-       case PIC_MASTER + PIC_IMR:
-               if (icw2[0]) {
-                       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;
-
-       case PIC_SLAVE  + PIC_CMD:
-               if (al & (1 << 4)) /* A0=0,D4=1 -> ICW1 */
-                       icw2[1] = 1;
-               break;
-       case PIC_SLAVE  + PIC_IMR:
-               if (icw2[1]) {
-                       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;
-       }
-
-       outb(port, al);
-       return 1;
-}
-
-static int
-inbyte(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       int port;
-
-       switch (opc) {
-       case 0xE4: /* inb al, port */
-               port = fetch8(regs);
-               break;
-       case 0xEC: /* inb al, (%dx) */
-               port = MASK16(regs->edx);
-               break;
-       default:
-               return 0;
-       }
-
-       regs->eax = (regs->eax & ~0xFF) | inb(port);
-       return 1;
-}
-
-static void
-pushrm(struct regs *regs, int prefix, unsigned modrm)
-{
-       unsigned n = regs->eip;
-       unsigned addr;
-       unsigned data;
-
-       addr = operand(prefix, regs, modrm);
-
-       if (prefix & DATA32) {
-               data = read32(addr);
-               push32(regs, data);
-       } else {
-               data = read16(addr);
-               push16(regs, data);
-       }
-
-       TRACE((regs, (regs->eip - n) + 1, "push *0x%x", addr));
-}
-
-enum { OPC_INVALID, OPC_EMULATED };
-
-#define rdmsr(msr,val1,val2)                           \
-       __asm__ __volatile__(                           \
-               "rdmsr"                                 \
-               : "=a" (val1), "=d" (val2)              \
-               : "c" (msr))
-
-#define wrmsr(msr,val1,val2)                           \
-       __asm__ __volatile__(                           \
-               "wrmsr"                                 \
-               : /* no outputs */                      \
-               : "c" (msr), "a" (val1), "d" (val2))
-
-/*
- * Emulate a single instruction, including all its prefixes. We only implement
- * a small subset of the opcodes, and not all opcodes are implemented for each
- * of the four modes we can operate in.
- */
-static int
-opcode(struct regs *regs)
-{
-       unsigned eip = regs->eip;
-       unsigned opc, modrm, disp;
-       unsigned prefix = 0;
-
-       if (mode == VM86_PROTECTED_TO_REAL &&
-               oldctx.cs_arbytes.fields.default_ops_size) {
-               prefix |= DATA32;
-               prefix |= ADDR32;
-       }
-
-       for (;;) {
-               switch ((opc = fetch8(regs))) {
-
-               case 0x00: /* addr32 add r8, r/m8 */
-               case 0x01: /* addr32 add r16, r/m16 */
-               case 0x03: /* addr32 add r/m16, r16 */
-                       if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
-                               goto invalid;
-                       if ((prefix & ADDR32) == 0)
-                               goto invalid;
-                       if (!add(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-                       
-               case 0x07: /* pop %es */
-                       regs->ves = (prefix & DATA32) ?
-                               pop32(regs) : pop16(regs);
-                       TRACE((regs, regs->eip - eip, "pop %%es"));
-                       if (mode == VM86_REAL_TO_PROTECTED) {
-                               saved_rm_regs.ves = 0;
-                               oldctx.es_sel = regs->ves;
-                       }
-                       return OPC_EMULATED;
-
-               case 0x0F: /* two byte opcode */
-                       if (mode == VM86_PROTECTED)
-                               goto invalid;
-                       switch ((opc = fetch8(regs))) {
-                       case 0x01:
-                               switch (((modrm = fetch8(regs)) >> 3) & 7) {
-                               case 0: /* sgdt */
-                               case 1: /* sidt */
-                                       goto invalid;
-                               case 2: /* lgdt */
-                                       if (!lgdt(regs, prefix, modrm))
-                                               goto invalid;
-                                       return OPC_EMULATED;
-                               case 3: /* lidt */
-                                       if (!lidt(regs, prefix, modrm))
-                                               goto invalid;
-                                       return OPC_EMULATED;
-                               case 4: /* smsw */
-                                       goto invalid;
-                               case 5:
-                                       goto invalid;
-                               case 6: /* lmsw */
-                                       if (!lmsw(regs, prefix, modrm))
-                                               goto invalid;
-                                       return OPC_EMULATED;
-                               case 7: /* invlpg */
-                                       goto invalid;
-                               }
-                               break;
-                       case 0x06: /* clts */
-                               oldctx.cr0 &= ~CR0_TS;
-                               return OPC_EMULATED;
-                       case 0x09: /* wbinvd */
-                               return OPC_EMULATED;
-                       case 0x20: /* mov Rd, Cd (1h) */
-                       case 0x22:
-                               if (!movcr(regs, prefix, opc))
-                                       goto invalid;
-                               return OPC_EMULATED;
-                       case 0x30: /* WRMSR */
-                               wrmsr(regs->ecx, regs->eax, regs->edx);
-                               return OPC_EMULATED;
-                       case 0x32: /* RDMSR */
-                               rdmsr(regs->ecx, regs->eax, regs->edx);
-                               return OPC_EMULATED;
-                       default:
-                               goto invalid;
-                       }
-                       goto invalid;
-
-               case 0x1F: /* pop %ds */
-                       regs->vds = (prefix & DATA32) ?
-                               pop32(regs) : pop16(regs);
-                       TRACE((regs, regs->eip - eip, "pop %%ds"));
-                       if (mode == VM86_REAL_TO_PROTECTED) {
-                               saved_rm_regs.vds = 0;
-                               oldctx.ds_sel = regs->vds;
-                       }
-                       return OPC_EMULATED;
-
-               case 0x26:
-                       TRACE((regs, regs->eip - eip, "%%es:"));
-                       prefix |= SEG_ES;
-                       continue;
-
-               case 0x2E:
-                       TRACE((regs, regs->eip - eip, "%%cs:"));
-                       prefix |= SEG_CS;
-                       continue;
-
-               case 0x36:
-                       TRACE((regs, regs->eip - eip, "%%ss:"));
-                       prefix |= SEG_SS;
-                       continue;
-
-               case 0x39: /* addr32 cmp r16, r/m16 */
-               case 0x3B: /* addr32 cmp r/m16, r16 */
-                       if (mode == VM86_PROTECTED_TO_REAL || !(prefix & 
ADDR32))
-                               goto invalid;
-                       if (!cmp(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0x3E:
-                       TRACE((regs, regs->eip - eip, "%%ds:"));
-                       prefix |= SEG_DS;
-                       continue;
-
-               case 0x64:
-                       TRACE((regs, regs->eip - eip, "%%fs:"));
-                       prefix |= SEG_FS;
-                       continue;
-
-               case 0x65:
-                       TRACE((regs, regs->eip - eip, "%%gs:"));
-                       prefix |= SEG_GS;
-                       continue;
-
-               case 0x66:
-                       if (mode == VM86_PROTECTED_TO_REAL &&
-                               oldctx.cs_arbytes.fields.default_ops_size) {
-                               TRACE((regs, regs->eip - eip, "data16"));
-                               prefix &= ~DATA32;
-                       } else {
-                               TRACE((regs, regs->eip - eip, "data32"));
-                               prefix |= DATA32;
-                       }
-                       continue;
-
-               case 0x67:
-                       if (mode == VM86_PROTECTED_TO_REAL &&
-                               oldctx.cs_arbytes.fields.default_ops_size) {
-                               TRACE((regs, regs->eip - eip, "addr16"));
-                               prefix &= ~ADDR32;
-                       } else {
-                               TRACE((regs, regs->eip - eip, "addr32"));
-                               prefix |= ADDR32;
-                       }
-                       continue;
-
-               case 0x88: /* addr32 mov r8, r/m8 */
-               case 0x8A: /* addr32 mov r/m8, r8 */
-                       if (mode == VM86_PROTECTED_TO_REAL || !(prefix & 
ADDR32))
-                               goto invalid;
-                       if (!movr(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0x89: /* mov r16, r/m16 */
-               case 0x8B: /* mov r/m16, r16 */
-                       if (mode != VM86_PROTECTED_TO_REAL && !(prefix & 
ADDR32))
-                               goto invalid;
-                       if (!movr(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0x8E: /* mov r16, sreg */
-                       if (!mov_to_seg(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0x8F: /* addr32 pop r/m16 */
-                       if (!(prefix & ADDR32))
-                               goto invalid;
-                       if (!pop(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0x90: /* nop */
-                       TRACE((regs, regs->eip - eip, "nop"));
-                       return OPC_EMULATED;
-
-               case 0x9C: /* pushf */
-                       TRACE((regs, regs->eip - eip, "pushf"));
-                       if (prefix & DATA32)
-                               push32(regs, regs->eflags & ~EFLAGS_VM);
-                       else
-                               push16(regs, regs->eflags & ~EFLAGS_VM);
-                       return OPC_EMULATED;
-
-               case 0x9D: /* popf */
-                       TRACE((regs, regs->eip - eip, "popf"));
-                       if (prefix & DATA32)
-                               regs->eflags = pop32(regs);
-                       else
-                               regs->eflags = (regs->eflags & 0xFFFF0000L) |
-                                                               pop16(regs);
-                       regs->eflags |= EFLAGS_VM;
-                       return OPC_EMULATED;
-
-               case 0xA1: /* mov ax, r/m16 */
-               {
-                       int addr, data;
-                       int seg = segment(prefix, regs, regs->vds);
-                       int offset = prefix & ADDR32 ? fetch32(regs) : 
fetch16(regs);
-
-                       if (prefix & DATA32) {
-                               addr = address(regs, seg, offset);
-                               data = read32(addr);
-                               setreg32(regs, 0, data);
-                       } else {
-                               addr = address(regs, seg, offset);
-                               data = read16(addr);
-                               setreg16(regs, 0, data);
-                       }
-                       TRACE((regs, regs->eip - eip, "mov *0x%x, %%ax", addr));
-                       return OPC_EMULATED;
-               }
-
-               case 0xA4: /* movsb */
-               case 0xA5: /* movsw */
-                       if ((prefix & ADDR32) == 0)
-                               goto invalid;
-                       if (!movs(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xAD: /* lodsw */
-                       if ((prefix & ADDR32) == 0)
-                               goto invalid;
-                       if (!lods(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-                       
-               case 0xBB: /* mov bx, imm16 */
-               {
-                       int data;
-                       if (prefix & DATA32) {
-                               data = fetch32(regs);
-                               setreg32(regs, 3, data);
-                       } else {
-                               data = fetch16(regs);
-                               setreg16(regs, 3, data);
-                       }
-                       TRACE((regs, regs->eip - eip, "mov $0x%x, %%bx", data));
-                       return OPC_EMULATED;
-               }
-
-               case 0xC6: /* addr32 movb $imm, r/m8 */
-                       if (!(prefix & ADDR32))
-                               goto invalid;
-                       if (!movr(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xCB: /* retl */
-                       if (mode == VM86_REAL_TO_PROTECTED ||
-                               mode == VM86_PROTECTED_TO_REAL) {
-                               retl(regs, prefix);
-                               return OPC_INVALID;
-                       }
-                       goto invalid;
-
-               case 0xCD: /* int $n */
-                       TRACE((regs, regs->eip - eip, "int"));
-                       interrupt(regs, fetch8(regs));
-                       return OPC_EMULATED;
-
-               case 0xCF: /* iret */
-                       if (prefix & DATA32) {
-                               TRACE((regs, regs->eip - eip, "data32 iretd"));
-                               regs->eip = pop32(regs);
-                               regs->cs = pop32(regs);
-                               regs->eflags = pop32(regs);
-                       } else {
-                               TRACE((regs, regs->eip - eip, "iret"));
-                               regs->eip = pop16(regs);
-                               regs->cs = pop16(regs);
-                               regs->eflags = (regs->eflags & 0xFFFF0000L) |
-                                                               pop16(regs);
-                       }
-                       return OPC_EMULATED;
-
-               case 0xE4: /* inb al, port */
-                       if (!inbyte(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xE6: /* outb port, al */
-                       if (!outbyte(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xEA: /* jmpl */
-                       if (mode == VM86_REAL_TO_PROTECTED ||
-                               mode == VM86_PROTECTED_TO_REAL) {
-                               jmpl(regs, prefix);
-                               return OPC_INVALID;
-                       }
-                       goto invalid;
-
-               case 0xFF:
-               {
-                       unsigned modrm = fetch8(regs);
-                       switch((modrm >> 3) & 7) {
-                       case 5: /* jmpl (indirect) */
-                               if (mode == VM86_REAL_TO_PROTECTED ||
-                                       mode == VM86_PROTECTED_TO_REAL) {
-                                       jmpl_indirect(regs, prefix, modrm);
-                                       return OPC_INVALID;
-                               }
-                               goto invalid;
-
-                       case 6: /* push r/m16 */
-                               pushrm(regs, prefix, modrm);
-                               return OPC_EMULATED;
-
-                       default:
-                               goto invalid;
-                       }
-               }
-
-               case 0xEB: /* short jump */
-                       if (mode == VM86_REAL_TO_PROTECTED ||
-                               mode == VM86_PROTECTED_TO_REAL) {
-                               disp = (char) fetch8(regs);
-                               TRACE((regs, 2, "jmp 0x%x", regs->eip + disp));
-                               regs->eip += disp;
-                               return OPC_EMULATED;
-                       }
-                       goto invalid;
-
-               case 0xEC: /* inb al, (%dx) */
-                       if (!inbyte(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xEE: /* outb (%dx), al */
-                       if (!outbyte(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xF0: /* lock */
-                       TRACE((regs, regs->eip - eip, "lock"));
-                       continue;
-
-               case 0xF4: /* hlt */
-                       TRACE((regs, regs->eip - eip, "hlt"));
-                       /* Do something power-saving here! */
-                       return OPC_EMULATED;
-
-               case 0xF3: /* rep/repe/repz */
-                       TRACE((regs, regs->eip - eip, "rep"));
-                       prefix |= REP;
-                       continue;
-
-               case 0xF6: /* addr32 testb $imm, r/m8 */
-                       if (!(prefix & ADDR32))
-                               goto invalid;
-                       if (!test(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xFA: /* cli */
-                       TRACE((regs, regs->eip - eip, "cli"));
-                       regs->eflags &= ~EFLAGS_IF;
-                       return OPC_EMULATED;
-
-               case 0xFB: /* sti */
-                       TRACE((regs, regs->eip - eip, "sti"));
-                       regs->eflags |= EFLAGS_IF;
-                       return OPC_EMULATED;
-
-               default:
-                       goto invalid;
-               }
-       }
-
-invalid:
-       regs->eip = eip;
-       TRACE((regs, regs->eip - eip, "opc 0x%x", opc));
-       return OPC_INVALID;
-}
-
-void
-emulate(struct regs *regs)
-{
-       unsigned flteip;
-       int nemul = 0;
-       unsigned ip;
-
-       /* emulate as many instructions as possible */
-       while (opcode(regs) != OPC_INVALID)
-               nemul++;
-
-       /* detect the case where we are not making progress */
-       if (nemul == 0 && prev_eip == regs->eip) {
-               flteip = address(regs, MASK16(regs->cs), regs->eip);
-
-               printf("Undecoded sequence: \n");
-               for (ip=flteip; ip < flteip+16; ip++)
-                       printf("0x%02x ", read8(ip));
-               printf("\n");
-
-               panic("Unknown opcode at %04x:%04x=0x%x",
-                       MASK16(regs->cs), regs->eip, flteip);
-       } else
-               prev_eip = regs->eip;
-}
-
-void
-trap(int trapno, int errno, struct regs *regs)
-{
-       /* emulate device interrupts */
-       if (trapno >= NR_EXCEPTION_HANDLER) {
-               int irq = trapno - NR_EXCEPTION_HANDLER;
-               if (irq < 8) 
-                       interrupt(regs, irq + 8);
-               else
-                       interrupt(regs, 0x70 + (irq - 8));
-               return;
-       }
-
-       switch (trapno) {
-       case 1: /* Debug */
-               if (regs->eflags & EFLAGS_VM) {
-                       /* emulate any 8086 instructions  */
-                       if (mode == VM86_REAL)
-                               return;
-                       if (mode != VM86_REAL_TO_PROTECTED)
-                               panic("not in real-to-protected mode");
-                       emulate(regs);
-                       return;
-               }
-               goto invalid;
-
-       case 13: /* GPF */
-               if (regs->eflags & EFLAGS_VM) {
-                       /* emulate any 8086 instructions  */
-                       if (mode == VM86_PROTECTED)
-                               panic("unexpected protected mode");
-                       emulate(regs);
-                       return;
-               }
-               goto invalid;
-
-       default:
-       invalid:
-               printf("Trap (0x%x) while in %s mode\n",
-                       trapno, regs->eflags & EFLAGS_VM ? "real" : 
"protected");
-               if (trapno == 14)
-                       printf("Page fault address 0x%x\n", get_cr2());
-               dump_regs(regs);
-               halt();
-       }
-}
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/vm86.h
--- a/tools/firmware/vmxassist/vm86.h   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * vm86.h: vm86 emulator definitions.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __VM86_H__
-#define __VM86_H__
-
-#ifndef __ASSEMBLY__
-#include <stdint.h>
-#endif
-
-#include <xen/hvm/vmx_assist.h>
-
-#ifndef __ASSEMBLY__
-
-struct regs {
-       unsigned        edi, esi, ebp, esp, ebx, edx, ecx, eax;
-       unsigned        trapno, errno;
-       unsigned        eip, cs, eflags, uesp, uss;
-       unsigned        ves, vds, vfs, vgs;
-};
-
-enum vm86_mode {
-       VM86_REAL = 0,
-       VM86_REAL_TO_PROTECTED,
-       VM86_PROTECTED_TO_REAL,
-       VM86_PROTECTED
-};
-
-#ifdef DEBUG
-#define TRACE(a)        trace a
-#else
-#define TRACE(a)
-#endif
-
-extern enum vm86_mode prevmode, mode;
-extern struct vmx_assist_context oldctx;
-
-extern void emulate(struct regs *);
-extern void dump_regs(struct regs *);
-extern void trace(struct regs *, int, char *, ...);
-
-extern void set_mode(struct regs *, enum vm86_mode);
-extern void switch_to_real_mode(void);
-extern void switch_to_protected_mode(void);
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __VM86_H__ */
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/vmxassist.ld
--- a/tools/firmware/vmxassist/vmxassist.ld     Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * vmxassist.ld
- */
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-ENTRY(_start)
-
-SECTIONS
-{
-       _btext = .;
-       .text TEXTADDR : 
-       {
-               *(.text)
-               *(.rodata)
-               *(.rodata.*)
-       }
-       _etext = .;
-
-       _bdata = .;
-       .data :
-       {
-               *(.data)
-       }
-       _edata = .;
-
-       _bbss = .;
-       .bss :
-       {
-               *(.bss)
-       }
-       _ebss = .;
-}
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/Rules.mk
--- a/xen/arch/x86/Rules.mk     Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/Rules.mk     Wed Feb 06 12:07:55 2008 +0000
@@ -11,11 +11,6 @@ xenoprof := y
 #
 pae ?= n
 supervisor_mode_kernel ?= n
-vmxassist ?= n
-
-ifeq ($(vmxassist),y)
-CFLAGS += -DVMXASSIST
-endif
 
 # Solaris grabs stdarg.h and friends from the system include directory.
 ifneq ($(XEN_OS),SunOS)
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Wed Feb 06 12:07:55 2008 +0000
@@ -1671,16 +1671,6 @@ int hvm_bringup_ap(int vcpuid, int tramp
     ctxt->flags = VGCF_online;
     ctxt->user_regs.eflags = 2;
 
-#ifdef VMXASSIST
-    if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
-    {
-        ctxt->user_regs.eip = VMXASSIST_BASE;
-        ctxt->user_regs.edx = vcpuid;
-        ctxt->user_regs.ebx = trampoline_vector;
-        goto done;
-    }
-#endif
-
     v->arch.hvm_vcpu.guest_cr[0] = X86_CR0_ET;
     hvm_update_guest_cr(v, 0);
 
@@ -1721,9 +1711,6 @@ int hvm_bringup_ap(int vcpuid, int tramp
     hvm_set_segment_register(v, x86_seg_gdtr, &reg);
     hvm_set_segment_register(v, x86_seg_idtr, &reg);
 
-#ifdef VMXASSIST
- done:
-#endif
     /* Sync AP's TSC with BSP's. */
     v->arch.hvm_vcpu.cache_tsc_offset =
         v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset;
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/vmx/Makefile
--- a/xen/arch/x86/hvm/vmx/Makefile     Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/Makefile     Wed Feb 06 12:07:55 2008 +0000
@@ -4,9 +4,7 @@ subdir-$(x86_64) += x86_64
 subdir-$(x86_64) += x86_64
 
 obj-y += intr.o
-ifneq ($(vmxassist),y)
 obj-y += realmode.o
-endif
 obj-y += vmcs.o
 obj-y += vmx.o
 obj-y += vpmu.o
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed Feb 06 12:07:55 2008 +0000
@@ -94,11 +94,10 @@ static int vmx_vcpu_initialise(struct vc
 
     vmx_install_vlapic_mapping(v);
 
-#ifndef VMXASSIST
+    /* %eax == 1 signals full real-mode support to the guest loader. */
     if ( v->vcpu_id == 0 )
         v->arch.guest_context.user_regs.eax = 1;
     v->arch.hvm_vcpu.io_complete = vmx_realmode_io_complete;
-#endif
 
     return 0;
 }
@@ -708,10 +707,6 @@ static void vmx_load_cpu_state(struct vc
 
     v->arch.hvm_vmx.cstar     = data->msr_cstar;
     v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
-#endif
-
-#ifdef VMXASSIST
-    v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE);
 #endif
 
     hvm_set_guest_time(v, data->tsc);
@@ -1266,43 +1261,6 @@ void vmx_cpuid_intercept(
 {
     unsigned int input = *eax;
     unsigned int count = *ecx;
-
-#ifdef VMXASSIST
-    if ( input == 0x40000003 )
-    {
-        /*
-         * NB. Unsupported interface for private use of VMXASSIST only.
-         * Note that this leaf lives at <max-hypervisor-leaf> + 1.
-         */
-        u64 value = ((u64)*edx << 32) | (u32)*ecx;
-        p2m_type_t p2mt;
-        unsigned long mfn;
-        struct vcpu *v = current;
-        char *p;
-
-        mfn = mfn_x(gfn_to_mfn_current(value >> PAGE_SHIFT, &p2mt));
-
-        gdprintk(XENLOG_INFO, "Input address is 0x%"PRIx64".\n", value);
-
-        /* 8-byte aligned valid pseudophys address from vmxassist, please. */
-        if ( (value & 7) || !p2m_is_ram(p2mt) ||
-             !v->arch.hvm_vmx.vmxassist_enabled )
-        {
-            domain_crash(v->domain);
-            return;
-        }
-        ASSERT(mfn_valid(mfn));
-
-        p = map_domain_page(mfn);
-        value = *((uint64_t *)(p + (value & (PAGE_SIZE - 1))));
-        unmap_domain_page(p);
-
-        gdprintk(XENLOG_INFO, "Output value is 0x%"PRIx64".\n", value);
-        *ecx = (u32)value;
-        *edx = (u32)(value >> 32);
-        return;
-    }
-#endif
 
     hvm_cpuid(input, eax, ebx, ecx, edx);
 
@@ -1843,256 +1801,6 @@ static void vmx_io_instruction(unsigned 
     }
 }
 
-#ifdef VMXASSIST
-
-static void vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
-{
-    struct cpu_user_regs *regs = guest_cpu_user_regs();
-
-    c->eip  = regs->eip;
-    c->eip += __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
-    c->esp = regs->esp;
-    c->eflags = regs->eflags & ~X86_EFLAGS_RF;
-
-    c->cr0 = v->arch.hvm_vcpu.guest_cr[0];
-    c->cr3 = v->arch.hvm_vcpu.guest_cr[3];
-    c->cr4 = v->arch.hvm_vcpu.guest_cr[4];
-
-    c->idtr_limit = __vmread(GUEST_IDTR_LIMIT);
-    c->idtr_base = __vmread(GUEST_IDTR_BASE);
-
-    c->gdtr_limit = __vmread(GUEST_GDTR_LIMIT);
-    c->gdtr_base = __vmread(GUEST_GDTR_BASE);
-
-    c->cs_sel = __vmread(GUEST_CS_SELECTOR);
-    c->cs_limit = __vmread(GUEST_CS_LIMIT);
-    c->cs_base = __vmread(GUEST_CS_BASE);
-    c->cs_arbytes.bytes = __vmread(GUEST_CS_AR_BYTES);
-
-    c->ds_sel = __vmread(GUEST_DS_SELECTOR);
-    c->ds_limit = __vmread(GUEST_DS_LIMIT);
-    c->ds_base = __vmread(GUEST_DS_BASE);
-    c->ds_arbytes.bytes = __vmread(GUEST_DS_AR_BYTES);
-
-    c->es_sel = __vmread(GUEST_ES_SELECTOR);
-    c->es_limit = __vmread(GUEST_ES_LIMIT);
-    c->es_base = __vmread(GUEST_ES_BASE);
-    c->es_arbytes.bytes = __vmread(GUEST_ES_AR_BYTES);
-
-    c->ss_sel = __vmread(GUEST_SS_SELECTOR);
-    c->ss_limit = __vmread(GUEST_SS_LIMIT);
-    c->ss_base = __vmread(GUEST_SS_BASE);
-    c->ss_arbytes.bytes = __vmread(GUEST_SS_AR_BYTES);
-
-    c->fs_sel = __vmread(GUEST_FS_SELECTOR);
-    c->fs_limit = __vmread(GUEST_FS_LIMIT);
-    c->fs_base = __vmread(GUEST_FS_BASE);
-    c->fs_arbytes.bytes = __vmread(GUEST_FS_AR_BYTES);
-
-    c->gs_sel = __vmread(GUEST_GS_SELECTOR);
-    c->gs_limit = __vmread(GUEST_GS_LIMIT);
-    c->gs_base = __vmread(GUEST_GS_BASE);
-    c->gs_arbytes.bytes = __vmread(GUEST_GS_AR_BYTES);
-
-    c->tr_sel = __vmread(GUEST_TR_SELECTOR);
-    c->tr_limit = __vmread(GUEST_TR_LIMIT);
-    c->tr_base = __vmread(GUEST_TR_BASE);
-    c->tr_arbytes.bytes = __vmread(GUEST_TR_AR_BYTES);
-
-    c->ldtr_sel = __vmread(GUEST_LDTR_SELECTOR);
-    c->ldtr_limit = __vmread(GUEST_LDTR_LIMIT);
-    c->ldtr_base = __vmread(GUEST_LDTR_BASE);
-    c->ldtr_arbytes.bytes = __vmread(GUEST_LDTR_AR_BYTES);
-}
-
-static int vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
-{
-    struct cpu_user_regs *regs = guest_cpu_user_regs();
-    int rc;
-
-    rc = vmx_restore_cr0_cr3(v, c->cr0, c->cr3);
-    if ( rc )
-        return rc;
-
-    regs->eip = c->eip;
-    regs->esp = c->esp;
-    regs->eflags = c->eflags | 2;
-
-    v->arch.hvm_vcpu.guest_cr[4] = c->cr4;
-    vmx_update_guest_cr(v, 0);
-    vmx_update_guest_cr(v, 4);
-
-    __vmwrite(GUEST_IDTR_LIMIT, c->idtr_limit);
-    __vmwrite(GUEST_IDTR_BASE, c->idtr_base);
-
-    __vmwrite(GUEST_GDTR_LIMIT, c->gdtr_limit);
-    __vmwrite(GUEST_GDTR_BASE, c->gdtr_base);
-
-    __vmwrite(GUEST_CS_SELECTOR, c->cs_sel);
-    __vmwrite(GUEST_CS_LIMIT, c->cs_limit);
-    __vmwrite(GUEST_CS_BASE, c->cs_base);
-    __vmwrite(GUEST_CS_AR_BYTES, c->cs_arbytes.bytes);
-
-    __vmwrite(GUEST_DS_SELECTOR, c->ds_sel);
-    __vmwrite(GUEST_DS_LIMIT, c->ds_limit);
-    __vmwrite(GUEST_DS_BASE, c->ds_base);
-    __vmwrite(GUEST_DS_AR_BYTES, c->ds_arbytes.bytes);
-
-    __vmwrite(GUEST_ES_SELECTOR, c->es_sel);
-    __vmwrite(GUEST_ES_LIMIT, c->es_limit);
-    __vmwrite(GUEST_ES_BASE, c->es_base);
-    __vmwrite(GUEST_ES_AR_BYTES, c->es_arbytes.bytes);
-
-    __vmwrite(GUEST_SS_SELECTOR, c->ss_sel);
-    __vmwrite(GUEST_SS_LIMIT, c->ss_limit);
-    __vmwrite(GUEST_SS_BASE, c->ss_base);
-    __vmwrite(GUEST_SS_AR_BYTES, c->ss_arbytes.bytes);
-
-    __vmwrite(GUEST_FS_SELECTOR, c->fs_sel);
-    __vmwrite(GUEST_FS_LIMIT, c->fs_limit);
-    __vmwrite(GUEST_FS_BASE, c->fs_base);
-    __vmwrite(GUEST_FS_AR_BYTES, c->fs_arbytes.bytes);
-
-    __vmwrite(GUEST_GS_SELECTOR, c->gs_sel);
-    __vmwrite(GUEST_GS_LIMIT, c->gs_limit);
-    __vmwrite(GUEST_GS_BASE, c->gs_base);
-    __vmwrite(GUEST_GS_AR_BYTES, c->gs_arbytes.bytes);
-
-    __vmwrite(GUEST_TR_SELECTOR, c->tr_sel);
-    __vmwrite(GUEST_TR_LIMIT, c->tr_limit);
-    __vmwrite(GUEST_TR_BASE, c->tr_base);
-    __vmwrite(GUEST_TR_AR_BYTES, c->tr_arbytes.bytes);
-
-    __vmwrite(GUEST_LDTR_SELECTOR, c->ldtr_sel);
-    __vmwrite(GUEST_LDTR_LIMIT, c->ldtr_limit);
-    __vmwrite(GUEST_LDTR_BASE, c->ldtr_base);
-    __vmwrite(GUEST_LDTR_AR_BYTES, c->ldtr_arbytes.bytes);
-
-    paging_update_paging_modes(v);
-    return 0;
-}
-
-enum { VMX_ASSIST_INVOKE = 0, VMX_ASSIST_RESTORE };
-
-static int vmx_assist(struct vcpu *v, int mode)
-{
-    struct vmx_assist_context c;
-    struct hvm_hw_vpic *vpic = v->domain->arch.hvm_domain.vpic;
-    u32 magic, cp;
-
-    if ( hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
-                                  sizeof(magic)) )
-    {
-        gdprintk(XENLOG_ERR, "No vmxassist: can't execute real mode code\n");
-        domain_crash(v->domain);
-        return 0;
-    }
-
-    if ( magic != VMXASSIST_MAGIC )
-    {
-        gdprintk(XENLOG_ERR, "vmxassist magic number not match\n");
-        domain_crash(v->domain);
-        return 0;
-    }
-
-    switch ( mode ) {
-        /*
-         * Transfer control to vmxassist.
-         * Store the current context in VMXASSIST_OLD_CONTEXT and load
-         * the new VMXASSIST_NEW_CONTEXT context. This context was created
-         * by vmxassist and will transfer control to it.
-         */
-    case VMX_ASSIST_INVOKE:
-        /* save the old context */
-        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)) )
-            goto error;
-        if ( cp != 0 ) {
-            vmx_world_save(v, &c);
-            if ( hvm_copy_to_guest_phys(cp, &c, sizeof(c)) )
-                goto error;
-        }
-
-        /* restore the new context, this should activate vmxassist */
-        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp)) )
-            goto error;
-        if ( cp != 0 ) {
-            if ( hvm_copy_from_guest_phys(&c, cp, sizeof(c)) )
-                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;
-            return 1;
-        }
-        break;
-
-        /*
-         * Restore the VMXASSIST_OLD_CONTEXT that was saved by
-         * VMX_ASSIST_INVOKE above.
-         */
-    case VMX_ASSIST_RESTORE:
-        /* save the old context */
-        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)) )
-            goto error;
-        if ( cp != 0 ) {
-            if ( hvm_copy_from_guest_phys(&c, cp, sizeof(c)) )
-                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;
-            return 1;
-        }
-        break;
-    }
-
- error:
-    gdprintk(XENLOG_ERR, "Failed to transfer to vmxassist\n");
-    domain_crash(v->domain);
-    return 0;
-}
-
-static int vmx_set_cr0(unsigned long value)
-{
-    struct vcpu *v = current;
-
-    if ( hvm_set_cr0(value) == 0 )
-        return 0;
-
-    /*
-     * VMX does not implement real-mode virtualization. We emulate
-     * real-mode by performing a world switch to VMXAssist whenever
-     * a partition disables the CR0.PE bit.
-     */
-    if ( !(value & X86_CR0_PE) )
-    {
-        if ( vmx_assist(v, VMX_ASSIST_INVOKE) )
-            return 0; /* do not update eip! */
-    }
-    else if ( v->arch.hvm_vmx.vmxassist_enabled )
-    {
-        if ( vmx_assist(v, VMX_ASSIST_RESTORE) )
-            return 0; /* do not update eip! */
-    }
-
-    return 1;
-}
-
-#else /* !defined(VMXASSIST) */
-
-#define vmx_set_cr0(v) hvm_set_cr0(v)
-
-#endif
-
 #define CASE_SET_REG(REG, reg)      \
     case REG_ ## REG: regs->reg = value; break
 #define CASE_GET_REG(REG, reg)      \
@@ -2146,7 +1854,7 @@ static int mov_to_cr(int gp, int cr, str
     switch ( cr )
     {
     case 0:
-        return vmx_set_cr0(value);
+        return hvm_set_cr0(value);
 
     case 3:
         return hvm_set_cr3(value);
@@ -2243,7 +1951,7 @@ static int vmx_cr_access(unsigned long e
         value = (value & ~0xF) |
             (((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
         HVMTRACE_1D(LMSW, current, value);
-        return vmx_set_cr0(value);
+        return hvm_set_cr0(value);
     default:
         BUG();
     }
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/vmx/x86_32/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_32/exits.S       Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S       Wed Feb 06 12:07:55 2008 +0000
@@ -115,10 +115,8 @@ ENTRY(vmx_asm_do_vmentry)
         movl $GUEST_RFLAGS,%eax
         VMWRITE(UREGS_eflags)
 
-#ifndef VMXASSIST
         testb $0xff,VCPU_vmx_emul(%ebx)
         jnz  vmx_goto_realmode
-#endif
 
         cmpb $0,VCPU_vmx_launched(%ebx)
         je   vmx_launch
@@ -138,7 +136,6 @@ vmx_launch:
         call vm_launch_fail
         ud2
 
-#ifndef VMXASSIST
 vmx_goto_realmode:
         sti
         movl %esp,%eax
@@ -146,4 +143,3 @@ vmx_goto_realmode:
         call vmx_realmode
         addl $4,%esp
         jmp vmx_asm_do_vmentry
-#endif
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/vmx/x86_64/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_64/exits.S       Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S       Wed Feb 06 12:07:55 2008 +0000
@@ -134,10 +134,8 @@ ENTRY(vmx_asm_do_vmentry)
         movl $GUEST_RFLAGS,%eax
         VMWRITE(UREGS_eflags)
 
-#ifndef VMXASSIST
         testb $0xff,VCPU_vmx_emul(%rbx)
         jnz  vmx_goto_realmode
-#endif
 
         cmpb $0,VCPU_vmx_launched(%rbx)
         je   vmx_launch
@@ -157,10 +155,8 @@ vmx_launch:
         call vm_launch_fail
         ud2
 
-#ifndef VMXASSIST
 vmx_goto_realmode:
         sti
         movq %rsp,%rdi
         call vmx_realmode
         jmp vmx_asm_do_vmentry
-#endif
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/vpic.c
--- a/xen/arch/x86/hvm/vpic.c   Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/vpic.c   Wed Feb 06 12:07:55 2008 +0000
@@ -271,11 +271,6 @@ static void vpic_ioport_write(
             vpic->imr = val;
             break;
         case 1:
-#ifdef VMXASSIST
-            /* 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 f8db1c6baad9 -r 9d0e86d8c1d1 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Wed Feb 06 12:07:55 2008 +0000
@@ -23,10 +23,6 @@
 #include <asm/hvm/io.h>
 #include <asm/hvm/vmx/cpu.h>
 #include <asm/hvm/vmx/vpmu.h>
-
-#ifdef VMXASSIST
-#include <public/hvm/vmx_assist.h>
-#endif
 
 extern void start_vmx(void);
 extern void vmcs_dump_vcpu(struct vcpu *v);
@@ -94,14 +90,6 @@ struct arch_vmx_struct {
 
     unsigned long        host_cr0;
 
-#ifdef VMXASSIST
-
-    unsigned long        vmxassist_enabled:1;
-    unsigned long        irqbase_mode:1;
-    unsigned char        pm_irqbase[2];
-
-#else
-
     /* Are we emulating rather than VMENTERing? */
 #define VMXEMUL_REALMODE 1  /* Yes, because CR0.PE == 0   */
 #define VMXEMUL_BAD_CS   2  /* Yes, because CS.RPL != CPL */
@@ -112,7 +100,6 @@ struct arch_vmx_struct {
     bool_t               real_mode_io_in_progress;
     bool_t               real_mode_io_completed;
     unsigned long        real_mode_io_data;
-#endif
 };
 
 int vmx_create_vmcs(struct vcpu *v);
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/include/public/hvm/vmx_assist.h
--- a/xen/include/public/hvm/vmx_assist.h       Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * vmx_assist.h: Context definitions for the VMXASSIST world switch.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- */
-
-#ifndef _VMX_ASSIST_H_
-#define _VMX_ASSIST_H_
-
-#define VMXASSIST_BASE         0xD0000
-#define VMXASSIST_MAGIC        0x17101966
-#define VMXASSIST_MAGIC_OFFSET (VMXASSIST_BASE+8)
-
-#define VMXASSIST_NEW_CONTEXT (VMXASSIST_BASE + 12)
-#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 {
-        unsigned int seg_type : 4,
-            s         : 1,
-            dpl       : 2,
-            p         : 1,
-            reserved0 : 4,
-            avl       : 1,
-            reserved1 : 1,
-            default_ops_size: 1,
-            g         : 1,
-            null_bit  : 1,
-            reserved2 : 15;
-    } fields;
-    unsigned int bytes;
-};
-
-/*
- * World switch state
- */
-struct vmx_assist_context {
-    uint32_t  eip;        /* execution pointer */
-    uint32_t  esp;        /* stack pointer */
-    uint32_t  eflags;     /* flags register */
-    uint32_t  cr0;
-    uint32_t  cr3;        /* page table directory */
-    uint32_t  cr4;
-    uint32_t  idtr_limit; /* idt */
-    uint32_t  idtr_base;
-    uint32_t  gdtr_limit; /* gdt */
-    uint32_t  gdtr_base;
-    uint32_t  cs_sel;     /* cs selector */
-    uint32_t  cs_limit;
-    uint32_t  cs_base;
-    union vmcs_arbytes cs_arbytes;
-    uint32_t  ds_sel;     /* ds selector */
-    uint32_t  ds_limit;
-    uint32_t  ds_base;
-    union vmcs_arbytes ds_arbytes;
-    uint32_t  es_sel;     /* es selector */
-    uint32_t  es_limit;
-    uint32_t  es_base;
-    union vmcs_arbytes es_arbytes;
-    uint32_t  ss_sel;     /* ss selector */
-    uint32_t  ss_limit;
-    uint32_t  ss_base;
-    union vmcs_arbytes ss_arbytes;
-    uint32_t  fs_sel;     /* fs selector */
-    uint32_t  fs_limit;
-    uint32_t  fs_base;
-    union vmcs_arbytes fs_arbytes;
-    uint32_t  gs_sel;     /* gs selector */
-    uint32_t  gs_limit;
-    uint32_t  gs_base;
-    union vmcs_arbytes gs_arbytes;
-    uint32_t  tr_sel;     /* task selector */
-    uint32_t  tr_limit;
-    uint32_t  tr_base;
-    union vmcs_arbytes tr_arbytes;
-    uint32_t  ldtr_sel;   /* ldtr selector */
-    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;
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _VMX_ASSIST_H_ */
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86 vmx: Remove vmxassist., Xen patchbot-unstable <=