ia64/xen-unstable

changeset 17005:9203ee23e724

merge with xen-unstable.hg
author Alex Williamson <alex.williamson@hp.com>
date Thu Feb 07 11:08:49 2008 -0700 (2008-02-07)
parents e3e8bdb5d52d e6cf98edf0c5
children 390707dd4c2f
files tools/firmware/README tools/firmware/vmxassist/Makefile tools/firmware/vmxassist/gen.c tools/firmware/vmxassist/head.S tools/firmware/vmxassist/machine.h tools/firmware/vmxassist/setup.c tools/firmware/vmxassist/trap.S tools/firmware/vmxassist/util.c tools/firmware/vmxassist/util.h tools/firmware/vmxassist/vm86.c tools/firmware/vmxassist/vm86.h tools/firmware/vmxassist/vmxassist.ld xen/include/asm-x86/hvm/vmx/cpu.h xen/include/public/hvm/vmx_assist.h
line diff
     1.1 --- a/docs/man/xmdomain.cfg.pod.5	Thu Feb 07 09:23:26 2008 -0700
     1.2 +++ b/docs/man/xmdomain.cfg.pod.5	Thu Feb 07 11:08:49 2008 -0700
     1.3 @@ -298,6 +298,22 @@ it holds, so that the new one may take t
     1.4  
     1.5  =back
     1.6  
     1.7 +=over 4
     1.8 +
     1.9 +Additionally, the "on_crash" event can also take:
    1.10 +
    1.11 +=item B<coredump-destroy>
    1.12 +
    1.13 +Dump the crashed domain's core and then destroy it.
    1.14 +
    1.15 +=back
    1.16 +
    1.17 +=item B<coredump-restart>
    1.18 +
    1.19 +Dump the crashed domain's core and then restart it.
    1.20 +
    1.21 +=back
    1.22 +
    1.23  =head1 EXAMPLES
    1.24  
    1.25  The following are quick examples of ways that domains might be
     2.1 --- a/extras/mini-os/blkfront.c	Thu Feb 07 09:23:26 2008 -0700
     2.2 +++ b/extras/mini-os/blkfront.c	Thu Feb 07 11:08:49 2008 -0700
     2.3 @@ -35,6 +35,8 @@ struct blk_buffer {
     2.4  };
     2.5  
     2.6  struct blkfront_dev {
     2.7 +    domid_t dom;
     2.8 +
     2.9      struct blkif_front_ring ring;
    2.10      grant_ref_t ring_ref;
    2.11      evtchn_port_t evtchn, local_port;
    2.12 @@ -81,6 +83,15 @@ struct blkfront_dev *init_blkfront(char 
    2.13      dev = malloc(sizeof(*dev));
    2.14      dev->nodename = strdup(nodename);
    2.15  
    2.16 +    evtchn_alloc_unbound_t op;
    2.17 +    op.dom = DOMID_SELF;
    2.18 +    snprintf(path, sizeof(path), "%s/backend-id", nodename);
    2.19 +    dev->dom = op.remote_dom = xenbus_read_integer(path); 
    2.20 +    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
    2.21 +    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
    2.22 +    dev->local_port = bind_evtchn(op.port, blkfront_handler, dev);
    2.23 +    dev->evtchn=op.port;
    2.24 +
    2.25      s = (struct blkif_sring*) alloc_page();
    2.26      memset(s,0,PAGE_SIZE);
    2.27  
    2.28 @@ -88,16 +99,7 @@ struct blkfront_dev *init_blkfront(char 
    2.29      SHARED_RING_INIT(s);
    2.30      FRONT_RING_INIT(&dev->ring, s, PAGE_SIZE);
    2.31  
    2.32 -    dev->ring_ref = gnttab_grant_access(0,virt_to_mfn(s),0);
    2.33 -
    2.34 -    evtchn_alloc_unbound_t op;
    2.35 -    op.dom = DOMID_SELF;
    2.36 -    snprintf(path, sizeof(path), "%s/backend-id", nodename);
    2.37 -    op.remote_dom = xenbus_read_integer(path); 
    2.38 -    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
    2.39 -    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
    2.40 -    dev->local_port = bind_evtchn(op.port, blkfront_handler, dev);
    2.41 -    dev->evtchn=op.port;
    2.42 +    dev->ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(s),0);
    2.43  
    2.44      // FIXME: proper frees on failures
    2.45  again:
    2.46 @@ -256,7 +258,7 @@ void blkfront_aio(struct blkfront_aiocb 
    2.47  
    2.48      start = (uintptr_t)aiocbp->aio_buf & PAGE_MASK;
    2.49      end = ((uintptr_t)aiocbp->aio_buf + aiocbp->aio_nbytes + PAGE_SIZE - 1) & PAGE_MASK;
    2.50 -    n = (end - start) / PAGE_SIZE;
    2.51 +    aiocbp->n = n = (end - start) / PAGE_SIZE;
    2.52  
    2.53      /* qemu's IDE max multsect is 16 (8KB) and SCSI max DMA was set to 32KB,
    2.54       * so max 44KB can't happen */
    2.55 @@ -280,7 +282,7 @@ void blkfront_aio(struct blkfront_aiocb 
    2.56              barrier();
    2.57          }
    2.58  	aiocbp->gref[j] = req->seg[j].gref =
    2.59 -            gnttab_grant_access(0, virtual_to_mfn(data), write);
    2.60 +            gnttab_grant_access(dev->dom, virtual_to_mfn(data), write);
    2.61  	req->seg[j].first_sect = 0;
    2.62  	req->seg[j].last_sect = PAGE_SIZE / dev->sector_size - 1;
    2.63      }
    2.64 @@ -325,8 +327,8 @@ moretodo:
    2.65          case BLKIF_OP_WRITE:
    2.66          {
    2.67              struct blkfront_aiocb *aiocbp = (void*) (uintptr_t) rsp->id;
    2.68 -            int n = (aiocbp->aio_nbytes + PAGE_SIZE - 1) / PAGE_SIZE, j;
    2.69 -            for (j = 0; j < n; j++)
    2.70 +            int j;
    2.71 +            for (j = 0; j < aiocbp->n; j++)
    2.72                  gnttab_end_access(aiocbp->gref[j]);
    2.73  
    2.74              /* Nota: callback frees aiocbp itself */
     3.1 --- a/extras/mini-os/include/blkfront.h	Thu Feb 07 09:23:26 2008 -0700
     3.2 +++ b/extras/mini-os/include/blkfront.h	Thu Feb 07 11:08:49 2008 -0700
     3.3 @@ -11,6 +11,7 @@ struct blkfront_aiocb
     3.4      void *data;
     3.5  
     3.6      grant_ref_t gref[BLKIF_MAX_SEGMENTS_PER_REQUEST];
     3.7 +    int n;
     3.8  
     3.9      void (*aio_cb)(struct blkfront_aiocb *aiocb, int ret);
    3.10  };
     4.1 --- a/extras/mini-os/netfront.c	Thu Feb 07 09:23:26 2008 -0700
     4.2 +++ b/extras/mini-os/netfront.c	Thu Feb 07 11:08:49 2008 -0700
     4.3 @@ -33,6 +33,8 @@ struct net_buffer {
     4.4  };
     4.5  
     4.6  struct netfront_dev {
     4.7 +    domid_t dom;
     4.8 +
     4.9      unsigned short tx_freelist[NET_TX_RING_SIZE];
    4.10      struct semaphore tx_sem;
    4.11  
    4.12 @@ -141,7 +143,7 @@ moretodo:
    4.13  
    4.14          /* We are sure to have free gnttab entries since they got released above */
    4.15          buf->gref = req->gref = 
    4.16 -            gnttab_grant_access(0,virt_to_mfn(page),0);
    4.17 +            gnttab_grant_access(dev->dom,virt_to_mfn(page),0);
    4.18  
    4.19          req->id = id;
    4.20      }
    4.21 @@ -258,6 +260,15 @@ struct netfront_dev *init_netfront(char 
    4.22          dev->rx_buffers[i].page = (char*)alloc_page();
    4.23      }
    4.24  
    4.25 +    evtchn_alloc_unbound_t op;
    4.26 +    op.dom = DOMID_SELF;
    4.27 +    snprintf(path, sizeof(path), "%s/backend-id", nodename);
    4.28 +    dev->dom = op.remote_dom = xenbus_read_integer(path);
    4.29 +    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
    4.30 +    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
    4.31 +    dev->local_port = bind_evtchn(op.port, netfront_handler, dev);
    4.32 +    dev->evtchn=op.port;
    4.33 +
    4.34      txs = (struct netif_tx_sring*) alloc_page();
    4.35      rxs = (struct netif_rx_sring *) alloc_page();
    4.36      memset(txs,0,PAGE_SIZE);
    4.37 @@ -269,17 +280,8 @@ struct netfront_dev *init_netfront(char 
    4.38      FRONT_RING_INIT(&dev->tx, txs, PAGE_SIZE);
    4.39      FRONT_RING_INIT(&dev->rx, rxs, PAGE_SIZE);
    4.40  
    4.41 -    dev->tx_ring_ref = gnttab_grant_access(0,virt_to_mfn(txs),0);
    4.42 -    dev->rx_ring_ref = gnttab_grant_access(0,virt_to_mfn(rxs),0);
    4.43 -
    4.44 -    evtchn_alloc_unbound_t op;
    4.45 -    op.dom = DOMID_SELF;
    4.46 -    snprintf(path, sizeof(path), "%s/backend-id", nodename);
    4.47 -    op.remote_dom = xenbus_read_integer(path);
    4.48 -    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
    4.49 -    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
    4.50 -    dev->local_port = bind_evtchn(op.port, netfront_handler, dev);
    4.51 -    dev->evtchn=op.port;
    4.52 +    dev->tx_ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(txs),0);
    4.53 +    dev->rx_ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(rxs),0);
    4.54  
    4.55      dev->netif_rx = thenetif_rx;
    4.56  
    4.57 @@ -416,7 +418,7 @@ void init_rx_buffers(struct netfront_dev
    4.58          req = RING_GET_REQUEST(&dev->rx, requeue_idx);
    4.59  
    4.60          buf->gref = req->gref = 
    4.61 -            gnttab_grant_access(0,virt_to_mfn(buf->page),0);
    4.62 +            gnttab_grant_access(dev->dom,virt_to_mfn(buf->page),0);
    4.63  
    4.64          req->id = requeue_idx;
    4.65  
    4.66 @@ -461,7 +463,7 @@ void netfront_xmit(struct netfront_dev *
    4.67      memcpy(page,data,len);
    4.68  
    4.69      buf->gref = 
    4.70 -        tx->gref = gnttab_grant_access(0,virt_to_mfn(page),0);
    4.71 +        tx->gref = gnttab_grant_access(dev->dom,virt_to_mfn(page),1);
    4.72  
    4.73      tx->offset=0;
    4.74      tx->size = len;
     5.1 --- a/tools/examples/xmexample.hvm	Thu Feb 07 09:23:26 2008 -0700
     5.2 +++ b/tools/examples/xmexample.hvm	Thu Feb 07 11:08:49 2008 -0700
     5.3 @@ -87,6 +87,11 @@ disk = [ 'file:/var/images/min-el3-i386.
     5.4  #   "rename-restart", meaning that the old domain is not cleaned up, but is
     5.5  #                     renamed and a new domain started in its place.
     5.6  #
     5.7 +# In the event a domain stops due to a crash, you have the additional options:
     5.8 +#
     5.9 +#   "coredump-destroy", meaning dump the crashed domain's core and then destroy;
    5.10 +#   "coredump-restart', meaning dump the crashed domain's core and the restart.
    5.11 +#
    5.12  # The default is
    5.13  #
    5.14  #   on_poweroff = 'destroy'
     6.1 --- a/tools/examples/xmexample1	Thu Feb 07 09:23:26 2008 -0700
     6.2 +++ b/tools/examples/xmexample1	Thu Feb 07 11:08:49 2008 -0700
     6.3 @@ -155,6 +155,11 @@ extra = "4"
     6.4  #   "rename-restart", meaning that the old domain is not cleaned up, but is
     6.5  #                     renamed and a new domain started in its place.
     6.6  #
     6.7 +# In the event a domain stops due to a crash, you have the additional options:
     6.8 +#
     6.9 +#   "coredump-destroy", meaning dump the crashed domain's core and then destroy;
    6.10 +#   "coredump-restart', meaning dump the crashed domain's core and the restart.
    6.11 +#
    6.12  # The default is
    6.13  #
    6.14  #   on_poweroff = 'destroy'
     7.1 --- a/tools/examples/xmexample2	Thu Feb 07 09:23:26 2008 -0700
     7.2 +++ b/tools/examples/xmexample2	Thu Feb 07 11:08:49 2008 -0700
     7.3 @@ -191,6 +191,11 @@ extra = "4 VMID=%d usr=/dev/sda6" % vmid
     7.4  #   "rename-restart", meaning that the old domain is not cleaned up, but is
     7.5  #                     renamed and a new domain started in its place.
     7.6  #
     7.7 +# In the event a domain stops due to a crash, you have the additional options:
     7.8 +#
     7.9 +#   "coredump-destroy", meaning dump the crashed domain's core and then destroy;
    7.10 +#   "coredump-restart', meaning dump the crashed domain's core and the restart.
    7.11 +#
    7.12  # The default is
    7.13  #
    7.14  #   on_poweroff = 'destroy'
     8.1 --- a/tools/examples/xmexample3	Thu Feb 07 09:23:26 2008 -0700
     8.2 +++ b/tools/examples/xmexample3	Thu Feb 07 11:08:49 2008 -0700
     8.3 @@ -177,6 +177,11 @@ extra = "4 VMID=%d" % vmid
     8.4  #   "rename-restart", meaning that the old domain is not cleaned up, but is
     8.5  #                     renamed and a new domain started in its place.
     8.6  #
     8.7 +# In the event a domain stops due to a crash, you have the additional options:
     8.8 +#
     8.9 +#   "coredump-destroy", meaning dump the crashed domain's core and then destroy;
    8.10 +#   "coredump-restart', meaning dump the crashed domain's core and the restart.
    8.11 +#
    8.12  # The default is
    8.13  #
    8.14  #   on_poweroff = 'destroy'
     9.1 --- a/tools/firmware/Makefile	Thu Feb 07 09:23:26 2008 -0700
     9.2 +++ b/tools/firmware/Makefile	Thu Feb 07 11:08:49 2008 -0700
     9.3 @@ -9,7 +9,6 @@ INST_DIR := $(DESTDIR)/usr/lib/xen/boot
     9.4  SUBDIRS :=
     9.5  SUBDIRS += rombios rombios/32bit
     9.6  SUBDIRS += vgabios
     9.7 -SUBDIRS += vmxassist
     9.8  SUBDIRS += extboot
     9.9  #SUBDIRS += etherboot
    9.10  SUBDIRS += hvmloader
    10.1 --- a/tools/firmware/README	Thu Feb 07 09:23:26 2008 -0700
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,88 +0,0 @@
    10.4 -Domain firmware support
    10.5 ------------------------
    10.6 -
    10.7 -One of the key advantages of full virtualization hardware support (such
    10.8 -as Intel's VT or AMD's SVM extensions) is the ability to run unmodified
    10.9 -guest operating systems.  However, since most OSes rely on BIOS support
   10.10 -during their early bringup, we need to provide a surrogate ROMBIOS and
   10.11 -VGABIOS firmware layer.
   10.12 -
   10.13 -What's more, we need to support real-mode which is required by
   10.14 -the firmware and bootstrap loaders. Real-mode support is especially
   10.15 -challenging for Intel's VMX (VT) enabled CPUs where there is no real-mode
   10.16 -support for VMX guest partitions. In this case you either have to do full
   10.17 -emulation (full real-mode emulator; more complete but potentially slower)
   10.18 -or partial emulation (use the VM8086 extensions, emulate only those
   10.19 -instructions that are missing; faster, but potentially incomplete). The
   10.20 -vmxassist code in this subdirectory uses the later approach because it
   10.21 -is smaller and faster.
   10.22 -
   10.23 -The approach is relatively straight forward. Vmxloader contains three
   10.24 -payloads (rombios, vgabios and vmxassist) and it is bootstrapped as any
   10.25 -other 32-bit OS. Vmxloader copies its payloads to the addresses below
   10.26 -and transfers control to vmxassist.
   10.27 -
   10.28 -	vgabios		VGABIOS (standard and Cirrus).
   10.29 -			Resides at C000:0000.
   10.30 -
   10.31 -	vmxassist	VMXAssist VM86 realmode emulator for VMX.
   10.32 -			Resides at D000:0000.
   10.33 -
   10.34 -	rombios		ROMBIOS code. Derived from Bochs.
   10.35 -			Resides at F000:0000
   10.36 -
   10.37 -Vmxassist first sets up it own world (GDT, IDT, TR, etc), enables
   10.38 -VM8086 and then transfers control to F000:FFF0 and executes 16-bit
   10.39 -code. Unsupported instructions cause a general protection failure at
   10.40 -which point vmxassist kicks in and emulates the offending instruction.
   10.41 -Whever the emulated code transitions to 32-bit protected mode, vmxassist
   10.42 -will go away. Whenever 32-bit protected code transitions to real-mode,
   10.43 -Xen/VMX will detect this and transfer control to vmxassist.
   10.44 -
   10.45 -Most of the vmxassist complexity comes from properly handling the
   10.46 -real to protected mode and protected to real mode transitions and
   10.47 -the proper emulation of the segment registers. Even though the Intel
   10.48 -manual clearly states that you should immediately perform a jmp far
   10.49 -after a mode transition, many operating systems execute additional
   10.50 -instructions and some even refer to segment selectors and pop data
   10.51 -from the stack. Vmxassist contains a number of work arounds for these
   10.52 -OSes.
   10.53 -
   10.54 -
   10.55 -Acknowledgements
   10.56 -----------------
   10.57 -
   10.58 -The rombios was taken (largely unmodified) from Bochs, which was written
   10.59 -by Kevin Lawton. The VGABIOS was written by Christophe Bothamy. Arun Sharma,
   10.60 -Asit Mallick and Nitin Kamble (Intel) provided the E820 patches and lots
   10.61 -of useful feedback.
   10.62 -
   10.63 -
   10.64 -Contact
   10.65 --------
   10.66 -
   10.67 -Leendert van Doorn
   10.68 -IBM T.J. Watson Research Center
   10.69 -19 Skyline Drive
   10.70 -Hawthorne, NY 10532
   10.71 -leendert@watson.ibm.com
   10.72 -
   10.73 -
   10.74 -Tested Operating Systems
   10.75 -------------------------
   10.76 -
   10.77 -Since vmxassist uses partial emulation, it may always miss opcodes
   10.78 -that are required by a particular OS. The table below lists the OSes
   10.79 -I have tried.  The Install column indicates a full CD/DVD install into
   10.80 -a VMX partition. The Disk column indicates booting from prefabricated
   10.81 -disk image.
   10.82 -
   10.83 -Operating System			Install		Disk
   10.84 -------------------------------------------------------------
   10.85 -RedHat Enterprise Linux (RHEL3_U5)	Yes		Yes
   10.86 -Fedora Code (FC3)			(-)		Yes
   10.87 -FreeBSD 5.3				(-)		Yes
   10.88 -MS-DOS 5.0				(-)		Yes
   10.89 -
   10.90 -(-) not tried yet
   10.91 -
    11.1 --- a/tools/firmware/hvmloader/Makefile	Thu Feb 07 09:23:26 2008 -0700
    11.2 +++ b/tools/firmware/hvmloader/Makefile	Thu Feb 07 11:08:49 2008 -0700
    11.3 @@ -50,11 +50,10 @@ hvmloader: roms.h acpi/acpi.a $(SRCS)
    11.4  acpi/acpi.a:
    11.5  	$(MAKE) -C acpi
    11.6  
    11.7 -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
    11.8 +roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../etherboot/eb-roms.h ../extboot/extboot.bin
    11.9  	sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
   11.10  	sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
   11.11  	sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
   11.12 -	sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
   11.13  	cat ../etherboot/eb-roms.h >> roms.h
   11.14  	sh ./mkhex extboot ../extboot/extboot.bin >> roms.h
   11.15  
    12.1 --- a/tools/firmware/hvmloader/config.h	Thu Feb 07 09:23:26 2008 -0700
    12.2 +++ b/tools/firmware/hvmloader/config.h	Thu Feb 07 11:08:49 2008 -0700
    12.3 @@ -21,7 +21,6 @@
    12.4  #define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
    12.5  #define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
    12.6  #define ETHERBOOT_PHYSICAL_ADDRESS    0x000C8000
    12.7 -#define VMXASSIST_PHYSICAL_ADDRESS    0x000D0000
    12.8  #define EXTBOOT_PHYSICAL_ADDRESS      0x000DF800
    12.9  #define SMBIOS_PHYSICAL_ADDRESS       0x000E9000
   12.10  #define SMBIOS_MAXIMUM_SIZE           0x00001000
    13.1 --- a/tools/firmware/hvmloader/hvmloader.c	Thu Feb 07 09:23:26 2008 -0700
    13.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Thu Feb 07 11:08:49 2008 -0700
    13.3 @@ -1,5 +1,5 @@
    13.4  /*
    13.5 - * hvmloader.c: HVM ROMBIOS/VGABIOS/ACPI/VMXAssist image loader.
    13.6 + * hvmloader.c: HVM bootloader.
    13.7   *
    13.8   * Leendert van Doorn, leendert@watson.ibm.com
    13.9   * Copyright (c) 2005, International Business Machines Corporation.
   13.10 @@ -40,7 +40,6 @@ asm(
   13.11      "    cli                         \n"
   13.12      "    movl $stack_top,%esp        \n"
   13.13      "    movl %esp,%ebp              \n"
   13.14 -    "    movl %eax,initial_eax       \n"
   13.15      "    call main                   \n"
   13.16      /* Relocate real-mode trampoline to 0x0. */
   13.17      "    mov  $trampoline_start,%esi \n"
   13.18 @@ -98,8 +97,6 @@ asm(
   13.19      "stack_top:                      \n"
   13.20      );
   13.21  
   13.22 -static unsigned int initial_eax;
   13.23 -
   13.24  void create_mp_tables(void);
   13.25  int hvm_write_smbios_tables(void);
   13.26  
   13.27 @@ -110,26 +107,6 @@ cirrus_check(void)
   13.28      return inb(0x3C5) == 0x12;
   13.29  }
   13.30  
   13.31 -static int
   13.32 -check_amd(void)
   13.33 -{
   13.34 -    char id[12];
   13.35 -
   13.36 -    __asm__ __volatile__ (
   13.37 -        "cpuid" 
   13.38 -        : "=b" (*(int *)(&id[0])),
   13.39 -        "=c" (*(int *)(&id[8])),
   13.40 -        "=d" (*(int *)(&id[4]))
   13.41 -        : "a" (0) );
   13.42 -    return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
   13.43 -}
   13.44 -
   13.45 -static int
   13.46 -use_vmxassist(void)
   13.47 -{
   13.48 -    return !check_amd() && !initial_eax;
   13.49 -}
   13.50 -
   13.51  static void
   13.52  wrmsr(uint32_t idx, uint64_t v)
   13.53  {
   13.54 @@ -506,10 +483,6 @@ int main(void)
   13.55          printf(" %05x-%05x: Extboot ROM\n",
   13.56                 EXTBOOT_PHYSICAL_ADDRESS,
   13.57                 EXTBOOT_PHYSICAL_ADDRESS + extboot_sz - 1);
   13.58 -    if ( use_vmxassist() )
   13.59 -        printf(" %05x-%05x: VMXAssist\n",
   13.60 -               VMXASSIST_PHYSICAL_ADDRESS,
   13.61 -               VMXASSIST_PHYSICAL_ADDRESS + sizeof(vmxassist) - 1);
   13.62      if ( smbios_sz )
   13.63          printf(" %05x-%05x: SMBIOS tables\n",
   13.64                 SMBIOS_PHYSICAL_ADDRESS,
   13.65 @@ -523,19 +496,6 @@ int main(void)
   13.66                 ROMBIOS_PHYSICAL_ADDRESS,
   13.67                 ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1);
   13.68  
   13.69 -    if ( use_vmxassist() )
   13.70 -    {
   13.71 -        printf("Loading VMXAssist ...\n");
   13.72 -        memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
   13.73 -               vmxassist, sizeof(vmxassist));
   13.74 -
   13.75 -        printf("VMX go ...\n");
   13.76 -        __asm__ __volatile__(
   13.77 -            "jmp *%%eax"
   13.78 -            : : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0)
   13.79 -            );
   13.80 -    }
   13.81 -
   13.82      printf("Invoking ROMBIOS ...\n");
   13.83      return 0;
   13.84  }
    14.1 --- a/tools/firmware/vmxassist/Makefile	Thu Feb 07 09:23:26 2008 -0700
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,81 +0,0 @@
    14.4 -#
    14.5 -# Makefile
    14.6 -#
    14.7 -# Leendert van Doorn, leendert@watson.ibm.com
    14.8 -# Copyright (c) 2005, International Business Machines Corporation.
    14.9 -#
   14.10 -# This program is free software; you can redistribute it and/or modify it
   14.11 -# under the terms and conditions of the GNU General Public License,
   14.12 -# version 2, as published by the Free Software Foundation.
   14.13 -#
   14.14 -# This program is distributed in the hope it will be useful, but WITHOUT
   14.15 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.16 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   14.17 -# more details.
   14.18 -#
   14.19 -# You should have received a copy of the GNU General Public License along with
   14.20 -# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   14.21 -# Place - Suite 330, Boston, MA 02111-1307 USA.
   14.22 -#
   14.23 -
   14.24 -# External CFLAGS can do more harm than good.
   14.25 -CFLAGS :=
   14.26 -
   14.27 -override XEN_TARGET_ARCH = x86_32
   14.28 -XEN_ROOT = ../../..
   14.29 -include $(XEN_ROOT)/tools/Rules.mk
   14.30 -
   14.31 -# The emulator code lives in ROM space
   14.32 -TEXTADDR=0x000D0000
   14.33 -
   14.34 -DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR)
   14.35 -XENINC=$(CFLAGS_include)
   14.36 -
   14.37 -# Disable PIE/SSP if GCC supports them. They can break us.
   14.38 -CFLAGS  += $(call cc-option,$(CC),-nopie,)
   14.39 -CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector,)
   14.40 -CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector-all,)
   14.41 -
   14.42 -CPP      = cpp -P
   14.43 -CFLAGS  += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float
   14.44 -
   14.45 -OBJECTS = head.o trap.o vm86.o setup.o util.o
   14.46 -
   14.47 -.PHONY: all
   14.48 -all: vmxassist.bin
   14.49 -
   14.50 -vmxassist.bin: vmxassist.ld $(OBJECTS)
   14.51 -	$(CPP) $(DEFINES) vmxassist.ld > vmxassist.tmp
   14.52 -	$(LD) -o vmxassist $(LDFLAGS_DIRECT) --fatal-warnings -N -T vmxassist.tmp $(OBJECTS)
   14.53 -	nm -n vmxassist > vmxassist.sym
   14.54 -	$(OBJCOPY) -p -O binary -R .note -R .comment -R .bss -S --gap-fill=0 vmxassist vmxassist.tmp
   14.55 -	dd if=vmxassist.tmp of=vmxassist.bin ibs=512 conv=sync
   14.56 -	rm -f vmxassist.tmp
   14.57 -
   14.58 -head.o: machine.h vm86.h head.S
   14.59 -	$(CC) $(CFLAGS) -D__ASSEMBLY__ $(DEFINES) -c head.S
   14.60 -
   14.61 -trap.o: machine.h vm86.h offsets.h trap.S
   14.62 -	$(CC) $(CFLAGS) -D__ASSEMBLY__ $(DEFINES) -c trap.S
   14.63 -
   14.64 -vm86.o: machine.h vm86.h vm86.c
   14.65 -	$(CC) $(CFLAGS) -c vm86.c
   14.66 -
   14.67 -setup.o: machine.h vm86.h setup.c
   14.68 -	$(CC) $(CFLAGS) -c setup.c
   14.69 -
   14.70 -util.o: machine.h vm86.h util.c
   14.71 -	$(CC) $(CFLAGS) -c util.c
   14.72 -
   14.73 -offsets.h: gen
   14.74 -	./gen > offsets.h
   14.75 -
   14.76 -gen:	vm86.h gen.c
   14.77 -	$(HOSTCC) $(HOSTCFLAGS) -I. $(XENINC) -o gen gen.c
   14.78 -
   14.79 -.PHONY: clean
   14.80 -clean:
   14.81 -	rm -f vmxassist vmxassist.tmp vmxassist.bin vmxassist.run vmxassist.sym head.s
   14.82 -	rm -f $(OBJECTS)
   14.83 -	rm -f gen gen.o offsets.h
   14.84 -
    15.1 --- a/tools/firmware/vmxassist/gen.c	Thu Feb 07 09:23:26 2008 -0700
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,52 +0,0 @@
    15.4 -/*
    15.5 - * gen.c: Generate assembler symbols.
    15.6 - *
    15.7 - * Leendert van Doorn, leendert@watson.ibm.com
    15.8 - * Copyright (c) 2005, International Business Machines Corporation.
    15.9 - *
   15.10 - * This program is free software; you can redistribute it and/or modify it
   15.11 - * under the terms and conditions of the GNU General Public License,
   15.12 - * version 2, as published by the Free Software Foundation.
   15.13 - *
   15.14 - * This program is distributed in the hope it will be useful, but WITHOUT
   15.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   15.17 - * more details.
   15.18 - *
   15.19 - * You should have received a copy of the GNU General Public License along with
   15.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   15.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   15.22 - */
   15.23 -#include <stdio.h>
   15.24 -#include <stddef.h>
   15.25 -#include <stdlib.h>
   15.26 -#include <vm86.h>
   15.27 -
   15.28 -int
   15.29 -main(void)
   15.30 -{
   15.31 -	printf("/* MACHINE GENERATED; DO NOT EDIT */\n");
   15.32 -	printf("#define VMX_ASSIST_CTX_GS_SEL	0x%x\n",
   15.33 -		(unsigned int)offsetof(struct vmx_assist_context, gs_sel));
   15.34 -	printf("#define VMX_ASSIST_CTX_FS_SEL	0x%x\n",
   15.35 -		(unsigned int)offsetof(struct vmx_assist_context, fs_sel));
   15.36 -	printf("#define VMX_ASSIST_CTX_DS_SEL	0x%x\n",
   15.37 -		(unsigned int)offsetof(struct vmx_assist_context, ds_sel));
   15.38 -	printf("#define VMX_ASSIST_CTX_ES_SEL	0x%x\n",
   15.39 -		(unsigned int)offsetof(struct vmx_assist_context, es_sel));
   15.40 -	printf("#define VMX_ASSIST_CTX_SS_SEL	0x%x\n",
   15.41 -		(unsigned int)offsetof(struct vmx_assist_context, ss_sel));
   15.42 -	printf("#define VMX_ASSIST_CTX_ESP	0x%x\n",
   15.43 -		(unsigned int)offsetof(struct vmx_assist_context, esp));
   15.44 -	printf("#define VMX_ASSIST_CTX_EFLAGS	0x%x\n",
   15.45 -		(unsigned int)offsetof(struct vmx_assist_context, eflags));
   15.46 -	printf("#define VMX_ASSIST_CTX_CS_SEL	0x%x\n",
   15.47 -		(unsigned int)offsetof(struct vmx_assist_context, cs_sel));
   15.48 -	printf("#define VMX_ASSIST_CTX_EIP	0x%x\n",
   15.49 -		(unsigned int)offsetof(struct vmx_assist_context, eip));
   15.50 -
   15.51 -	printf("#define VMX_ASSIST_CTX_CR0	0x%x\n",
   15.52 -		(unsigned int)offsetof(struct vmx_assist_context, cr0));
   15.53 -
   15.54 -	return 0;
   15.55 -}
    16.1 --- a/tools/firmware/vmxassist/head.S	Thu Feb 07 09:23:26 2008 -0700
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,94 +0,0 @@
    16.4 -/*
    16.5 - * head.S: VMXAssist runtime start off.
    16.6 - *
    16.7 - * Leendert van Doorn, leendert@watson.ibm.com
    16.8 - * Copyright (c) 2005, International Business Machines Corporation.
    16.9 - *
   16.10 - * This program is free software; you can redistribute it and/or modify it
   16.11 - * under the terms and conditions of the GNU General Public License,
   16.12 - * version 2, as published by the Free Software Foundation.
   16.13 - *
   16.14 - * This program is distributed in the hope it will be useful, but WITHOUT
   16.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   16.17 - * more details.
   16.18 - *
   16.19 - * You should have received a copy of the GNU General Public License along with
   16.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   16.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   16.22 - */
   16.23 -#include "vm86.h"
   16.24 -#include "machine.h"
   16.25 -
   16.26 -/*
   16.27 - * When a partition tries to mask off the CR0_PE bit a world
   16.28 - * switch happens to the environment below. The magic indicates
   16.29 - * that this is a valid context.
   16.30 - */
   16.31 -	jmp	_start
   16.32 -
   16.33 -	.align	8
   16.34 -	.long	VMXASSIST_MAGIC
   16.35 -	.long	newctx			/* new context */
   16.36 -	.long	oldctx			/* old context */
   16.37 -
   16.38 -/*
   16.39 - * This is the real start. Control was transfered to this point
   16.40 - * with CR0_PE set and executing in some 32-bit segment. We call
   16.41 - * main and setup our own environment.
   16.42 - */
   16.43 -	.globl	_start
   16.44 -	.code32
   16.45 -_start:
   16.46 -	cli
   16.47 -
   16.48 -	/* save register parameters to C land */
   16.49 -
   16.50 -	/* clear bss */
   16.51 -	cld
   16.52 -	xorb	%al, %al
   16.53 -	movl	$_bbss, %edi
   16.54 -	movl	$_ebss, %ecx
   16.55 -	subl	%edi, %ecx
   16.56 -	rep	stosb
   16.57 -
   16.58 -	movl	%edx, booting_cpu
   16.59 -	movl	%ebx, booting_vector
   16.60 -
   16.61 -	/* make sure we are in a sane world */
   16.62 -	clts
   16.63 -
   16.64 -	/* setup my own stack */
   16.65 -	movl	$stack_top, %esp
   16.66 -	movl	%esp, %ebp
   16.67 -
   16.68 -	/* go ... */
   16.69 -	call    main
   16.70 -	jmp	halt
   16.71 -
   16.72 -/*
   16.73 - * Something bad happened, print invoking %eip and loop forever
   16.74 - */
   16.75 -	.align	4
   16.76 -	.globl	halt
   16.77 -halt:
   16.78 -	push	$halt_msg
   16.79 -	call	printf
   16.80 -	cli
   16.81 -	jmp	.
   16.82 -
   16.83 -	.data
   16.84 -halt_msg:
   16.85 -	.asciz	"Halt called from %%eip 0x%x\n"
   16.86 -
   16.87 -
   16.88 -/*
   16.89 - * Our stack
   16.90 - */
   16.91 -	.bss
   16.92 -	.align	8
   16.93 -	.globl	stack, stack_top
   16.94 -stack:
   16.95 -	.skip	STACK_SIZE
   16.96 -stack_top:
   16.97 -
    17.1 --- a/tools/firmware/vmxassist/machine.h	Thu Feb 07 09:23:26 2008 -0700
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,199 +0,0 @@
    17.4 -/*
    17.5 - * machine.h: Intel CPU specific definitions
    17.6 - *
    17.7 - * Leendert van Doorn, leendert@watson.ibm.com
    17.8 - * Copyright (c) 2005, International Business Machines Corporation.
    17.9 - *
   17.10 - * This program is free software; you can redistribute it and/or modify it
   17.11 - * under the terms and conditions of the GNU General Public License,
   17.12 - * version 2, as published by the Free Software Foundation.
   17.13 - *
   17.14 - * This program is distributed in the hope it will be useful, but WITHOUT
   17.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   17.17 - * more details.
   17.18 - *
   17.19 - * You should have received a copy of the GNU General Public License along with
   17.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   17.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   17.22 - */
   17.23 -#ifndef __MACHINE_H__
   17.24 -#define __MACHINE_H__
   17.25 -
   17.26 -/* the size of our stack (4KB) */
   17.27 -#define STACK_SIZE	8192
   17.28 -
   17.29 -#define TSS_SELECTOR	0x08
   17.30 -#define CODE_SELECTOR	0x10
   17.31 -#define DATA_SELECTOR	0x18
   17.32 -
   17.33 -#define CR0_PE		(1 << 0)
   17.34 -#define CR0_EM		(1 << 2)
   17.35 -#define	CR0_TS		(1 << 3)
   17.36 -#define CR0_NE		(1 << 5)
   17.37 -#define CR0_PG		(1 << 31)
   17.38 -
   17.39 -#define CR4_VME		(1 << 0)
   17.40 -#define CR4_PVI		(1 << 1)
   17.41 -#define CR4_PSE		(1 << 4)
   17.42 -#define CR4_PAE		(1 << 5)
   17.43 -
   17.44 -#define EFLAGS_CF	(1 << 0)
   17.45 -#define EFLAGS_PF	(1 << 2)
   17.46 -#define EFLAGS_AF	(1 << 4)
   17.47 -#define EFLAGS_ZF	(1 << 6)
   17.48 -#define EFLAGS_SF	(1 << 7)
   17.49 -#define EFLAGS_TF	(1 << 8)
   17.50 -#define EFLAGS_IF	(1 << 9)
   17.51 -#define EFLAGS_DF	(1 << 10)
   17.52 -#define EFLAGS_OF	(1 << 11)
   17.53 -#define EFLAGS_IOPL	(3 << 12)
   17.54 -#define EFLAGS_VM	((1 << 17) | EFLAGS_IOPL)
   17.55 -#define EFLAGS_VIF	(1 << 19)
   17.56 -#define EFLAGS_VIP	(1 << 20)
   17.57 -
   17.58 -#define	LOG_PGSIZE	12	/* log2(page size) */
   17.59 -#define	LOG_PDSIZE	22	/* log2(page directory size) */
   17.60 -
   17.61 -/* Derived constants */
   17.62 -#define	PGSIZE		(1 << LOG_PGSIZE)	/* page size */
   17.63 -#define	PGMASK		(~(PGSIZE - 1))		/* page mask */
   17.64 -#define	LPGSIZE		(1 << LOG_PDSIZE)	/* large page size */
   17.65 -#define	LPGMASK		(~(LPGSIZE - 1))	/* large page mask */
   17.66 -
   17.67 -/* Programmable Interrupt Contoller (PIC) defines */
   17.68 -#define	PIC_MASTER	0x20
   17.69 -#define	PIC_SLAVE	0xA0
   17.70 -
   17.71 -#define	PIC_CMD		0	/* command */
   17.72 -#define	PIC_ISR		0	/* interrupt status */
   17.73 -#define	PIC_IMR		1	/* interrupt mask */
   17.74 -
   17.75 -
   17.76 -#ifndef __ASSEMBLY__
   17.77 -
   17.78 -struct dtr {
   17.79 -	unsigned short	size;
   17.80 -	unsigned long	base __attribute__ ((packed));
   17.81 -};
   17.82 -
   17.83 -struct tss {
   17.84 -	unsigned short	prev_link;
   17.85 -	unsigned short	_1;
   17.86 -	unsigned long	esp0;
   17.87 -	unsigned short	ss0;
   17.88 -	unsigned short	_2;
   17.89 -	unsigned long	esp1;
   17.90 -	unsigned short	ss1;
   17.91 -	unsigned short	_3;
   17.92 -	unsigned long	esp2;
   17.93 -	unsigned short	ss2;
   17.94 -	unsigned short	_4;
   17.95 -	unsigned long	cr3;
   17.96 -	unsigned long	eip;
   17.97 -	unsigned long	eflags;
   17.98 -	unsigned long	eax;
   17.99 -	unsigned long	ecx;
  17.100 -	unsigned long	edx;
  17.101 -	unsigned long	ebx;
  17.102 -	unsigned long	esi;
  17.103 -	unsigned long	edi;
  17.104 -	unsigned long	esp;
  17.105 -	unsigned long	ebp;
  17.106 -	unsigned long	es;
  17.107 -	unsigned long	cs;
  17.108 -	unsigned long	ss;
  17.109 -	unsigned long	ds;
  17.110 -	unsigned long	fs;
  17.111 -	unsigned long	gs;
  17.112 -	unsigned short	ldt_segment;
  17.113 -	unsigned short	_5;
  17.114 -	unsigned short	_6;
  17.115 -	unsigned short	iomap_base;
  17.116 -#ifdef	ENABLE_VME
  17.117 -	unsigned long	int_redir[8];
  17.118 -#endif
  17.119 -	unsigned char	iomap[8193];
  17.120 -};
  17.121 -
  17.122 -static inline void
  17.123 -outw(unsigned short addr, unsigned short val)
  17.124 -{
  17.125 -	__asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val));
  17.126 -}
  17.127 -
  17.128 -static inline void
  17.129 -outb(unsigned short addr, unsigned char val)
  17.130 -{
  17.131 -	__asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val));
  17.132 -}
  17.133 -
  17.134 -static inline unsigned char
  17.135 -inb(unsigned short addr)
  17.136 -{
  17.137 -	unsigned char val;
  17.138 -
  17.139 -	__asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr));
  17.140 -	return val;
  17.141 -}
  17.142 -
  17.143 -static inline unsigned
  17.144 -get_cmos(int reg)
  17.145 -{
  17.146 -	outb(0x70, reg);
  17.147 -	return inb(0x71);
  17.148 -}
  17.149 -
  17.150 -static inline unsigned
  17.151 -get_cr0(void)
  17.152 -{
  17.153 -        unsigned rv;
  17.154 -        __asm__ __volatile__("movl %%cr0, %0" : "=r"(rv));
  17.155 -        return rv;
  17.156 -}
  17.157 -
  17.158 -static inline void
  17.159 -set_cr0(unsigned value)
  17.160 -{
  17.161 -	__asm__ __volatile__(
  17.162 -		"movl	%0, %%cr0\n"
  17.163 -		"jmp	1f\n"
  17.164 -		"1: 	nop\n"
  17.165 -		: /* no outputs */
  17.166 -		: "r"(value)
  17.167 -	);
  17.168 -}
  17.169 -
  17.170 -static inline unsigned
  17.171 -get_cr2(void)
  17.172 -{
  17.173 -	unsigned rv;
  17.174 -
  17.175 -	__asm__ __volatile__("movl %%cr2, %0" : "=r"(rv));
  17.176 -	return rv;
  17.177 -}
  17.178 -
  17.179 -static inline unsigned
  17.180 -get_cr4(void)
  17.181 -{
  17.182 -        unsigned rv;
  17.183 -        __asm__ __volatile__("movl %%cr4, %0" : "=r"(rv));
  17.184 -        return rv;
  17.185 -}
  17.186 -
  17.187 -static inline void
  17.188 -set_cr3(unsigned addr)
  17.189 -{
  17.190 -        __asm__ __volatile__("movl %0, %%cr3" : /* no outputs */ : "r"(addr));
  17.191 -}
  17.192 -
  17.193 -static inline void
  17.194 -set_cr4(unsigned value)
  17.195 -{
  17.196 -	__asm__ __volatile__("movl %0, %%cr4" : /* no outputs */ : "r"(value));
  17.197 -}
  17.198 -
  17.199 -#endif /* __ASSEMBLY__ */
  17.200 -
  17.201 -#endif /* __MACHINE_H__ */
  17.202 -
    18.1 --- a/tools/firmware/vmxassist/setup.c	Thu Feb 07 09:23:26 2008 -0700
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,337 +0,0 @@
    18.4 -/*
    18.5 - * setup.c: Setup the world for vmxassist.
    18.6 - *
    18.7 - * Leendert van Doorn, leendert@watson.ibm.com
    18.8 - * Copyright (c) 2005, International Business Machines Corporation.
    18.9 - *
   18.10 - * This program is free software; you can redistribute it and/or modify it
   18.11 - * under the terms and conditions of the GNU General Public License,
   18.12 - * version 2, as published by the Free Software Foundation.
   18.13 - *
   18.14 - * This program is distributed in the hope it will be useful, but WITHOUT
   18.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   18.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   18.17 - * more details.
   18.18 - *
   18.19 - * You should have received a copy of the GNU General Public License along with
   18.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   18.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   18.22 - */
   18.23 -#include "vm86.h"
   18.24 -#include "util.h"
   18.25 -#include "machine.h"
   18.26 -
   18.27 -#if (VMXASSIST_BASE != TEXTADDR)
   18.28 -#error VMXAssist base mismatch
   18.29 -#endif
   18.30 -
   18.31 -#define	NR_PGD		(PGSIZE / sizeof(unsigned))
   18.32 -
   18.33 -#define	min(a, b)	((a) > (b) ? (b) : (a))
   18.34 -
   18.35 -/* Which CPU are we booting, and what is the initial CS segment? */
   18.36 -int booting_cpu, booting_vector;
   18.37 -
   18.38 -unsigned long long gdt[] __attribute__ ((aligned(32))) = {
   18.39 -	0x0000000000000000ULL,		/* 0x00: reserved */
   18.40 -	0x0000890000000000ULL,		/* 0x08: 32-bit TSS */
   18.41 -	0x00CF9A000000FFFFULL,		/* 0x10: CS 32-bit */
   18.42 -	0x00CF92000000FFFFULL,		/* 0x18: DS 32-bit */
   18.43 -};
   18.44 -
   18.45 -struct dtr gdtr = { sizeof(gdt)-1, (unsigned long) &gdt };
   18.46 -
   18.47 -struct tss tss __attribute__ ((aligned(4)));
   18.48 -
   18.49 -unsigned long long idt[NR_TRAPS] __attribute__ ((aligned(32)));
   18.50 -
   18.51 -struct dtr idtr = { sizeof(idt)-1, (unsigned long) &idt };
   18.52 -
   18.53 -struct vmx_assist_context oldctx;
   18.54 -struct vmx_assist_context newctx;
   18.55 -
   18.56 -unsigned long memory_size;
   18.57 -int initialize_real_mode;
   18.58 -
   18.59 -extern char stack_top[];
   18.60 -extern unsigned trap_handlers[];
   18.61 -
   18.62 -void
   18.63 -banner(void)
   18.64 -{
   18.65 -	printf("VMXAssist (%s)\n", __DATE__);
   18.66 -
   18.67 -	/* Bochs its way to convey memory size */
   18.68 -	memory_size = ((get_cmos(0x35) << 8) | get_cmos(0x34)) << 6;
   18.69 -	if (memory_size > 0x3bc000)
   18.70 -		memory_size = 0x3bc000;
   18.71 -	memory_size = (memory_size << 10) + 0xF00000;
   18.72 -	if (memory_size <= 0xF00000)
   18.73 -		memory_size =
   18.74 -		    (((get_cmos(0x31) << 8) | get_cmos(0x30)) + 0x400) << 10;
   18.75 -	memory_size += 0x400 << 10; /* + 1MB */
   18.76 -
   18.77 -	printf("Memory size %ld MB\n", memory_size >> 20);
   18.78 -	printf("E820 map:\n");
   18.79 -	print_e820_map(HVM_E820, *HVM_E820_NR);
   18.80 -	printf("\n");
   18.81 -}
   18.82 -
   18.83 -void
   18.84 -setup_gdt(void)
   18.85 -{
   18.86 -	unsigned long long addr = (unsigned long long) &tss;
   18.87 -
   18.88 -	/* setup task state segment */
   18.89 -	memset(&tss, 0, sizeof(tss));
   18.90 -	tss.ss0 = DATA_SELECTOR;
   18.91 -	tss.esp0 = (unsigned) stack_top;
   18.92 -	tss.iomap_base = offsetof(struct tss, iomap);
   18.93 -	tss.iomap[sizeof(tss.iomap)-1] = 0xff;
   18.94 -
   18.95 -	/* initialize gdt's tss selector */
   18.96 -	gdt[TSS_SELECTOR / sizeof(gdt[0])] |=
   18.97 -		((addr & 0xFF000000) << (56-24)) |
   18.98 -		((addr & 0x00FF0000) << (32-16)) |
   18.99 -		((addr & 0x0000FFFF) << (16)) |
  18.100 -		(sizeof(tss) - 1);
  18.101 -
  18.102 -	/* switch to our own gdt and set current tss */
  18.103 -	__asm__ __volatile__ ("lgdt %0" : : "m" (gdtr));
  18.104 -	__asm__ __volatile__ ("movl %%eax,%%ds;"
  18.105 -			      "movl %%eax,%%es;"
  18.106 -			      "movl %%eax,%%fs;"
  18.107 -			      "movl %%eax,%%gs;"
  18.108 -			      "movl %%eax,%%ss" : : "a" (DATA_SELECTOR));
  18.109 -
  18.110 -	__asm__ __volatile__ ("ljmp %0,$1f; 1:" : : "i" (CODE_SELECTOR));
  18.111 -
  18.112 -	__asm__ __volatile__ ("ltr %%ax" : : "a" (TSS_SELECTOR));
  18.113 -}
  18.114 -
  18.115 -void
  18.116 -set_intr_gate(int i, unsigned handler)
  18.117 -{
  18.118 -	unsigned long long addr = handler;
  18.119 -
  18.120 -	idt[i] = ((addr & 0xFFFF0000ULL) << 32) | (0x8E00ULL << 32) |
  18.121 -		(addr & 0xFFFFULL) | (CODE_SELECTOR << 16);
  18.122 -}
  18.123 -
  18.124 -void
  18.125 -setup_idt(void)
  18.126 -{
  18.127 -	int i;
  18.128 -
  18.129 -	for (i = 0; i < NR_TRAPS; i++)
  18.130 -		set_intr_gate(i, trap_handlers[i]);
  18.131 -	__asm__ __volatile__ ("lidt %0" : : "m" (idtr));
  18.132 -}
  18.133 -
  18.134 -void
  18.135 -setup_pic(void)
  18.136 -{
  18.137 -	/* mask all interrupts */
  18.138 -	outb(PIC_MASTER + PIC_IMR, 0xFF);
  18.139 -	outb(PIC_SLAVE + PIC_IMR, 0xFF);
  18.140 -
  18.141 -	/* setup master PIC */
  18.142 -	outb(PIC_MASTER + PIC_CMD, 0x11); /* edge triggered, cascade, ICW4 */
  18.143 -	outb(PIC_MASTER + PIC_IMR, NR_EXCEPTION_HANDLER);
  18.144 -	outb(PIC_MASTER + PIC_IMR, 1 << 2); /* slave on channel 2 */
  18.145 -	outb(PIC_MASTER + PIC_IMR, 0x01);
  18.146 -
  18.147 -	/* setup slave PIC */
  18.148 -	outb(PIC_SLAVE + PIC_CMD, 0x11); /* edge triggered, cascade, ICW4 */
  18.149 -	outb(PIC_SLAVE + PIC_IMR, NR_EXCEPTION_HANDLER + 8);
  18.150 -	outb(PIC_SLAVE + PIC_IMR, 0x02); /* slave identity is 2 */
  18.151 -	outb(PIC_SLAVE + PIC_IMR, 0x01);
  18.152 -
  18.153 -	/* enable all interrupts */
  18.154 -	outb(PIC_MASTER + PIC_IMR, 0);
  18.155 -	outb(PIC_SLAVE + PIC_IMR, 0);
  18.156 -}
  18.157 -
  18.158 -void
  18.159 -setiomap(int port)
  18.160 -{
  18.161 -	tss.iomap[port >> 3] |= 1 << (port & 7);
  18.162 -}
  18.163 -
  18.164 -void
  18.165 -enter_real_mode(struct regs *regs)
  18.166 -{
  18.167 -	/* mask off TSS busy bit */
  18.168 -	gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL;
  18.169 -
  18.170 -	/* start 8086 emulation of BIOS */
  18.171 -	if (initialize_real_mode) {
  18.172 -		initialize_real_mode = 0;
  18.173 -		regs->eflags |= EFLAGS_VM | 0x02;
  18.174 -		regs->ves = regs->vds = regs->vfs = regs->vgs = 0xF000;
  18.175 -		if (booting_cpu == 0) {
  18.176 -			regs->cs = 0xF000; /* ROM BIOS POST entry point */
  18.177 -			regs->eip = 0xFFF0;
  18.178 -		} else {
  18.179 -			regs->cs = booting_vector << 8; /* AP entry point */
  18.180 -			regs->eip = 0;
  18.181 -		}
  18.182 -
  18.183 -		regs->uesp = regs->uss = 0;
  18.184 -		regs->eax = regs->ecx = regs->edx = regs->ebx = 0;
  18.185 -		regs->esp = regs->ebp = regs->esi = regs->edi = 0;
  18.186 -
  18.187 -		/* intercept accesses to the PIC */
  18.188 -		setiomap(PIC_MASTER+PIC_CMD);
  18.189 -		setiomap(PIC_MASTER+PIC_IMR);
  18.190 -		setiomap(PIC_SLAVE+PIC_CMD);
  18.191 -		setiomap(PIC_SLAVE+PIC_IMR);
  18.192 -
  18.193 -		printf("Starting emulated 16-bit real-mode: ip=%04x:%04x\n",
  18.194 -			regs->cs, regs->eip);
  18.195 -
  18.196 -		mode = VM86_REAL; /* becomes previous mode */
  18.197 -		set_mode(regs, VM86_REAL);
  18.198 -
  18.199 -		/* this should get us into 16-bit mode */
  18.200 -		return;
  18.201 -	}
  18.202 -
  18.203 -	/* go from protected to real mode */
  18.204 -	set_mode(regs, VM86_PROTECTED_TO_REAL);
  18.205 -	emulate(regs);
  18.206 -	if (mode != VM86_REAL)
  18.207 -		panic("failed to emulate between clear PE and long jump.\n");
  18.208 -}
  18.209 -
  18.210 -/*
  18.211 - * Setup the environment for VMX assist.
  18.212 - * This environment consists of flat segments (code and data),
  18.213 - * its own gdt, idt, and tr.
  18.214 - */
  18.215 -void
  18.216 -setup_ctx(void)
  18.217 -{
  18.218 -	struct vmx_assist_context *c = &newctx;
  18.219 -
  18.220 -	memset(c, 0, sizeof(*c));
  18.221 -	c->eip = (unsigned long) switch_to_real_mode;
  18.222 -	c->esp = (unsigned) stack_top;
  18.223 -	c->eflags = 0x2; /* no interrupts, please */
  18.224 -
  18.225 -	/*
  18.226 -	 * Obviously, vmx assist is not running with CR0_PE disabled.
  18.227 -	 * The reason why the vmx assist cr0 has CR0.PE disabled is
  18.228 -	 * that a transtion to CR0.PE causes a world switch. It seems
  18.229 -	 * more natural to enable CR0.PE to cause a world switch to
  18.230 -	 * protected mode rather than disabling it.
  18.231 -	 */
  18.232 -	c->cr0 = (get_cr0() | CR0_NE) & ~CR0_PE;
  18.233 -	c->cr3 = 0;
  18.234 -	c->cr4 = get_cr4();
  18.235 -
  18.236 -	c->idtr_limit = sizeof(idt)-1;
  18.237 -	c->idtr_base = (unsigned long) &idt;
  18.238 -
  18.239 -	c->gdtr_limit = sizeof(gdt)-1;
  18.240 -	c->gdtr_base = (unsigned long) &gdt;
  18.241 -
  18.242 -	c->cs_sel = CODE_SELECTOR;
  18.243 -	c->cs_limit = 0xFFFFFFFF;
  18.244 -	c->cs_base = 0;
  18.245 -	c->cs_arbytes.fields.seg_type = 0xb;
  18.246 -	c->cs_arbytes.fields.s = 1;
  18.247 -	c->cs_arbytes.fields.dpl = 0;
  18.248 -	c->cs_arbytes.fields.p = 1;
  18.249 -	c->cs_arbytes.fields.avl = 0;
  18.250 -	c->cs_arbytes.fields.default_ops_size = 1;
  18.251 -	c->cs_arbytes.fields.g = 1;
  18.252 -
  18.253 -	c->ds_sel = DATA_SELECTOR;
  18.254 -	c->ds_limit = 0xFFFFFFFF;
  18.255 -	c->ds_base = 0;
  18.256 -	c->ds_arbytes = c->cs_arbytes;
  18.257 -	c->ds_arbytes.fields.seg_type = 0x3;
  18.258 -
  18.259 -	c->es_sel = DATA_SELECTOR;
  18.260 -	c->es_limit = 0xFFFFFFFF;
  18.261 -	c->es_base = 0;
  18.262 -	c->es_arbytes = c->ds_arbytes;
  18.263 -
  18.264 -	c->ss_sel = DATA_SELECTOR;
  18.265 -	c->ss_limit = 0xFFFFFFFF;
  18.266 -	c->ss_base = 0;
  18.267 -	c->ss_arbytes = c->ds_arbytes;
  18.268 -
  18.269 -	c->fs_sel = DATA_SELECTOR;
  18.270 -	c->fs_limit = 0xFFFFFFFF;
  18.271 -	c->fs_base = 0;
  18.272 -	c->fs_arbytes = c->ds_arbytes;
  18.273 -
  18.274 -	c->gs_sel = DATA_SELECTOR;
  18.275 -	c->gs_limit = 0xFFFFFFFF;
  18.276 -	c->gs_base = 0;
  18.277 -	c->gs_arbytes = c->ds_arbytes;
  18.278 -
  18.279 -	c->tr_sel = TSS_SELECTOR;
  18.280 -	c->tr_limit = sizeof(tss) - 1;
  18.281 -	c->tr_base = (unsigned long) &tss;
  18.282 -	c->tr_arbytes.fields.seg_type = 0xb; /* 0x9 | 0x2 (busy) */
  18.283 -	c->tr_arbytes.fields.s = 0;
  18.284 -	c->tr_arbytes.fields.dpl = 0;
  18.285 -	c->tr_arbytes.fields.p = 1;
  18.286 -	c->tr_arbytes.fields.avl = 0;
  18.287 -	c->tr_arbytes.fields.default_ops_size = 0;
  18.288 -	c->tr_arbytes.fields.g = 0;
  18.289 -
  18.290 -	c->ldtr_sel = 0;
  18.291 -	c->ldtr_limit = 0;
  18.292 -	c->ldtr_base = 0;
  18.293 -	c->ldtr_arbytes = c->ds_arbytes;
  18.294 -	c->ldtr_arbytes.fields.seg_type = 0x2;
  18.295 -	c->ldtr_arbytes.fields.s = 0;
  18.296 -	c->ldtr_arbytes.fields.dpl = 0;
  18.297 -	c->ldtr_arbytes.fields.p = 1;
  18.298 -	c->ldtr_arbytes.fields.avl = 0;
  18.299 -	c->ldtr_arbytes.fields.default_ops_size = 0;
  18.300 -	c->ldtr_arbytes.fields.g = 0;
  18.301 -}
  18.302 -
  18.303 -/*
  18.304 - * Start BIOS by causing a world switch to vmxassist, which causes
  18.305 - * VM8086 to be enabled and control is transfered to F000:FFF0.
  18.306 - */
  18.307 -void
  18.308 -start_bios(void)
  18.309 -{
  18.310 -	if (booting_cpu == 0)
  18.311 -		printf("Start BIOS ...\n");
  18.312 -	else
  18.313 -		printf("Start AP %d from %08x ...\n",
  18.314 -		       booting_cpu, booting_vector << 12);
  18.315 -
  18.316 -	initialize_real_mode = 1;
  18.317 -	set_cr0(get_cr0() & ~CR0_PE);
  18.318 -	panic("vmxassist returned"); /* "cannot happen" */
  18.319 -}
  18.320 -
  18.321 -int
  18.322 -main(void)
  18.323 -{
  18.324 -	if (booting_cpu == 0)
  18.325 -		banner();
  18.326 -
  18.327 -	setup_gdt();
  18.328 -	setup_idt();
  18.329 -
  18.330 -	set_cr4(get_cr4() | CR4_VME);
  18.331 -
  18.332 -	setup_ctx();
  18.333 -
  18.334 -	if (booting_cpu == 0)
  18.335 -		setup_pic();
  18.336 -
  18.337 -	start_bios();
  18.338 -
  18.339 -	return 0;
  18.340 -}
    19.1 --- a/tools/firmware/vmxassist/trap.S	Thu Feb 07 09:23:26 2008 -0700
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,179 +0,0 @@
    19.4 -/*
    19.5 - * trap.S: Trap and world switch handlers
    19.6 - *
    19.7 - * Leendert van Doorn, leendert@watson.ibm.com
    19.8 - * Copyright (c) 2005, International Business Machines Corporation.
    19.9 - *
   19.10 - * This program is free software; you can redistribute it and/or modify it
   19.11 - * under the terms and conditions of the GNU General Public License,
   19.12 - * version 2, as published by the Free Software Foundation.
   19.13 - *
   19.14 - * This program is distributed in the hope it will be useful, but WITHOUT
   19.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   19.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   19.17 - * more details.
   19.18 - *
   19.19 - * You should have received a copy of the GNU General Public License along with
   19.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   19.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   19.22 - */
   19.23 -#include "machine.h"
   19.24 -#include "vm86.h"
   19.25 -#include "offsets.h"
   19.26 -
   19.27 -/*
   19.28 - * All processor exception/faults/interrupts end up here.
   19.29 - *
   19.30 - * On an exception/fault, the processor pushes CS:EIP, SS, ESP and an
   19.31 - * optional error code onto the stack. The common_trap routine
   19.32 - * below saves the processor context and transfers control to trap()
   19.33 - * whose job it is to virtualize and pass on the trap.
   19.34 - */
   19.35 -	.macro	TRAP_HANDLER trapno error
   19.36 -	.text
   19.37 -	.align	16
   19.38 -1:	.if	\error == 0
   19.39 -	pushl	$0			/* dummy error code */
   19.40 -	.endif
   19.41 -	pushl	$\trapno
   19.42 -	jmp	common_trap
   19.43 -	.section .rodata
   19.44 -	.long	1b
   19.45 -	.text
   19.46 -	.endm
   19.47 -
   19.48 -	.section .rodata
   19.49 -	.code32
   19.50 -	.align	4
   19.51 -	.global	trap_handlers
   19.52 -trap_handlers:
   19.53 -	TRAP_HANDLER	0, 0	/* divide error */
   19.54 -	TRAP_HANDLER	1, 0	/* debug */
   19.55 -	TRAP_HANDLER	2, 0	/* NMI interrupt */
   19.56 -	TRAP_HANDLER	3, 0	/* breakpoint */
   19.57 -	TRAP_HANDLER	4, 0	/* overflow */
   19.58 -	TRAP_HANDLER	5, 0	/* BOUND range exceeded */
   19.59 -	TRAP_HANDLER	6, 0	/* invalid opcode */
   19.60 -	TRAP_HANDLER	7, 0	/* device not available */
   19.61 -	TRAP_HANDLER	8, 1	/* double fault */
   19.62 -	TRAP_HANDLER	9, 0	/* coprocessor segment overrun */
   19.63 -	TRAP_HANDLER	10, 1	/* invalid TSS */
   19.64 -	TRAP_HANDLER	11, 1	/* segment not present */
   19.65 -	TRAP_HANDLER	12, 1	/* stack-segment fault */
   19.66 -	TRAP_HANDLER	13, 1	/* general protection */
   19.67 -	TRAP_HANDLER	14, 1	/* page fault */
   19.68 -	TRAP_HANDLER	15, 0	/* reserved */
   19.69 -	TRAP_HANDLER	16, 0	/* FPU floating-point error */
   19.70 -	TRAP_HANDLER	17, 1	/* alignment check */
   19.71 -	TRAP_HANDLER	18, 0	/* machine check */
   19.72 -	TRAP_HANDLER	19, 0	/* SIMD floating-point error */
   19.73 -	TRAP_HANDLER	20, 0	/* reserved */
   19.74 -	TRAP_HANDLER	21, 0	/* reserved */
   19.75 -	TRAP_HANDLER	22, 0	/* reserved */
   19.76 -	TRAP_HANDLER	23, 0	/* reserved */
   19.77 -	TRAP_HANDLER	24, 0	/* reserved */
   19.78 -	TRAP_HANDLER	25, 0	/* reserved */
   19.79 -	TRAP_HANDLER	26, 0	/* reserved */
   19.80 -	TRAP_HANDLER	27, 0	/* reserved */
   19.81 -	TRAP_HANDLER	28, 0	/* reserved */
   19.82 -	TRAP_HANDLER	29, 0	/* reserved */
   19.83 -	TRAP_HANDLER	30, 0	/* reserved */
   19.84 -	TRAP_HANDLER	31, 0	/* reserved */
   19.85 -	TRAP_HANDLER	32, 0	/* irq 0 */
   19.86 -	TRAP_HANDLER	33, 0	/* irq 1 */
   19.87 -	TRAP_HANDLER	34, 0	/* irq 2 */
   19.88 -	TRAP_HANDLER	35, 0	/* irq 3 */
   19.89 -	TRAP_HANDLER	36, 0	/* irq 4 */
   19.90 -	TRAP_HANDLER	37, 0	/* irq 5 */
   19.91 -	TRAP_HANDLER	38, 0	/* irq 6 */
   19.92 -	TRAP_HANDLER	39, 0	/* irq 7 */
   19.93 -	TRAP_HANDLER	40, 0	/* irq 8 */
   19.94 -	TRAP_HANDLER	41, 0	/* irq 9 */
   19.95 -	TRAP_HANDLER	42, 0	/* irq 10 */
   19.96 -	TRAP_HANDLER	43, 0	/* irq 11 */
   19.97 -	TRAP_HANDLER	44, 0	/* irq 12 */
   19.98 -	TRAP_HANDLER	45, 0	/* irq 13 */
   19.99 -	TRAP_HANDLER	46, 0	/* irq 14 */
  19.100 -	TRAP_HANDLER	47, 0	/* irq 15 */
  19.101 -
  19.102 -	.text
  19.103 -	.code32
  19.104 -	.align	16
  19.105 -common_trap:				/* common trap handler */
  19.106 -	pushal
  19.107 -
  19.108 -	movl	$(DATA_SELECTOR), %eax	/* make sure these are sane */
  19.109 -	movl	%eax, %ds
  19.110 -	movl	%eax, %es
  19.111 -	movl	%eax, %fs
  19.112 -	movl	%eax, %gs
  19.113 -	movl	%esp, %ebp
  19.114 -
  19.115 -	pushl	%ebp
  19.116 -	pushl	36(%ebp)
  19.117 -	pushl	32(%ebp)
  19.118 -	call	trap			/* trap(trapno, errno, regs) */
  19.119 -	addl	$12, %esp
  19.120 -
  19.121 -trap_return:
  19.122 -	popal
  19.123 -	addl	$8, %esp		/* skip trapno, errno */
  19.124 -	iret
  19.125 -	/* NOT REACHED */
  19.126 -
  19.127 -
  19.128 -/*
  19.129 - * A world switch to real mode occured. The hypervisor saved the
  19.130 - * executing context into "oldctx" and instantiated "newctx", which
  19.131 - * gets us here. Here we push a stack frame that is compatible with
  19.132 - * a trap frame (see above) so that we can handle this event as a
  19.133 - * regular trap.
  19.134 - */
  19.135 -	.text
  19.136 -	.align	16
  19.137 -	.globl	switch_to_real_mode
  19.138 -switch_to_real_mode:
  19.139 -	pushl	oldctx+VMX_ASSIST_CTX_GS_SEL /* 16 to 32-bit transition */
  19.140 -	pushl	oldctx+VMX_ASSIST_CTX_FS_SEL
  19.141 -	pushl	oldctx+VMX_ASSIST_CTX_DS_SEL
  19.142 -	pushl	oldctx+VMX_ASSIST_CTX_ES_SEL
  19.143 -	pushl	oldctx+VMX_ASSIST_CTX_SS_SEL
  19.144 -	pushl	oldctx+VMX_ASSIST_CTX_ESP
  19.145 -	pushl	oldctx+VMX_ASSIST_CTX_EFLAGS
  19.146 -	pushl	oldctx+VMX_ASSIST_CTX_CS_SEL
  19.147 -	pushl	oldctx+VMX_ASSIST_CTX_EIP
  19.148 -	pushl	$-1			/* trapno, errno */
  19.149 -	pushl	$-1
  19.150 -	pushal
  19.151 -
  19.152 -	movl	%esp, %ebp
  19.153 -	pushl	%ebp
  19.154 -	call	enter_real_mode
  19.155 -	addl	$4, %esp
  19.156 -
  19.157 -	jmp	trap_return
  19.158 -	/* NOT REACHED */
  19.159 -
  19.160 -
  19.161 -/*
  19.162 - * Switch to protected mode. At this point all the registers have
  19.163 - * been reloaded by trap_return and all we have to do is cause a
  19.164 - * world switch by turning on CR0.PE.
  19.165 - */
  19.166 -	.text
  19.167 -	.align	16
  19.168 -	.globl	switch_to_protected_mode
  19.169 -switch_to_protected_mode:
  19.170 -	movl	oldctx+VMX_ASSIST_CTX_CR0, %esp
  19.171 -	movl	%esp, %cr0		/* actual world switch ! */
  19.172 -
  19.173 -	/* NOT REACHED */
  19.174 -	pushl	$switch_failed
  19.175 -	call	panic
  19.176 -	jmp	.
  19.177 -
  19.178 -	.data
  19.179 -	.align	4
  19.180 -switch_failed:
  19.181 -	.asciz	"World switch to protected mode failed\n"
  19.182 -
    20.1 --- a/tools/firmware/vmxassist/util.c	Thu Feb 07 09:23:26 2008 -0700
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,430 +0,0 @@
    20.4 -/*
    20.5 - * util.c: Commonly used utility functions.
    20.6 - *
    20.7 - * Leendert van Doorn, leendert@watson.ibm.com
    20.8 - * Copyright (c) 2005, International Business Machines Corporation.
    20.9 - *
   20.10 - * This program is free software; you can redistribute it and/or modify it
   20.11 - * under the terms and conditions of the GNU General Public License,
   20.12 - * version 2, as published by the Free Software Foundation.
   20.13 - *
   20.14 - * This program is distributed in the hope it will be useful, but WITHOUT
   20.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   20.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   20.17 - * more details.
   20.18 - *
   20.19 - * You should have received a copy of the GNU General Public License along with
   20.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   20.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   20.22 - */
   20.23 -#include <stdarg.h>
   20.24 -
   20.25 -#include "util.h"
   20.26 -#include "machine.h"
   20.27 -
   20.28 -#define	isdigit(c)	((c) >= '0' && (c) <= '9')
   20.29 -#define	min(a, b)	((a) < (b) ? (a) : (b))
   20.30 -
   20.31 -static void putchar(int);
   20.32 -static char *printnum(char *, unsigned long, int);
   20.33 -static void _doprint(void (*)(int), const char *, va_list);
   20.34 -
   20.35 -void
   20.36 -cpuid_addr_value(uint64_t addr, uint64_t *value)
   20.37 -{
   20.38 -	uint32_t addr_low   = (uint32_t)addr;
   20.39 -	uint32_t addr_high  = (uint32_t)(addr >> 32);
   20.40 -	uint32_t value_low, value_high;
   20.41 -	static unsigned int addr_leaf;
   20.42 -
   20.43 -	if (!addr_leaf) {
   20.44 -		unsigned int eax, ebx, ecx, edx;
   20.45 -		__asm__ __volatile__(
   20.46 -			"cpuid"
   20.47 -			: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
   20.48 -			: "0" (0x40000000));
   20.49 -		addr_leaf = eax + 1;
   20.50 -	}
   20.51 -
   20.52 -	__asm__ __volatile__(
   20.53 -		"cpuid"
   20.54 -		: "=c" (value_low), "=d" (value_high)
   20.55 -		: "a" (addr_leaf), "0" (addr_low), "1" (addr_high)
   20.56 -		: "ebx");
   20.57 -
   20.58 -	*value = (uint64_t)value_high << 32 | value_low;
   20.59 -}
   20.60 -
   20.61 -void
   20.62 -dump_regs(struct regs *regs)
   20.63 -{
   20.64 -	printf("eax    %8x ecx    %8x edx    %8x ebx    %8x\n",
   20.65 -		regs->eax, regs->ecx, regs->edx, regs->ebx);
   20.66 -	printf("esp    %8x ebp    %8x esi    %8x edi    %8x\n",
   20.67 -		regs->esp, regs->ebp, regs->esi, regs->edi);
   20.68 -	printf("trapno %8x errno  %8x\n", regs->trapno, regs->errno);
   20.69 -	printf("eip    %8x cs     %8x eflags %8x\n",
   20.70 -		regs->eip, regs->cs, regs->eflags);
   20.71 -	printf("uesp   %8x uss    %8x\n",
   20.72 -		regs->uesp, regs->uss);
   20.73 -	printf("ves    %8x vds    %8x vfs    %8x vgs    %8x\n",
   20.74 -		regs->ves, regs->vds, regs->vfs, regs->vgs);
   20.75 -
   20.76 -	printf("cr0    %8lx cr2    %8x cr3    %8lx cr4    %8lx\n\n",
   20.77 -		(long)oldctx.cr0, get_cr2(),
   20.78 -		(long)oldctx.cr3, (long)oldctx.cr4);
   20.79 -}
   20.80 -
   20.81 -#ifdef DEBUG
   20.82 -void
   20.83 -hexdump(unsigned char *data, int sz)
   20.84 -{
   20.85 -	unsigned char *d;
   20.86 -	int i;
   20.87 -
   20.88 -	for (d = data; sz > 0; d += 16, sz -= 16) {
   20.89 -		int n = sz > 16 ? 16 : sz;
   20.90 -
   20.91 -		printf("%08x: ", (unsigned)d);
   20.92 -		for (i = 0; i < n; i++)
   20.93 -			printf("%02x%c", d[i], i == 7 ? '-' : ' ');
   20.94 -		for (; i < 16; i++)
   20.95 -			printf("  %c", i == 7 ? '-' : ' ');
   20.96 -		printf("   ");
   20.97 -		for (i = 0; i < n; i++)
   20.98 -			printf("%c", d[i] >= ' ' && d[i] <= '~' ? d[i] : '.');
   20.99 -		printf("\n");
  20.100 -	}
  20.101 -}
  20.102 -
  20.103 -void
  20.104 -print_e820_map(struct e820entry *map, int entries)
  20.105 -{
  20.106 -	struct e820entry *m;
  20.107 -
  20.108 -	if (entries > 32)
  20.109 -		entries = 32;
  20.110 -
  20.111 -	for (m = map; m < &map[entries]; m++) {
  20.112 -		printf("%08lx%08lx - %08lx%08lx ",
  20.113 -			(unsigned long) (m->addr >> 32),
  20.114 -			(unsigned long) (m->addr),
  20.115 -			(unsigned long) ((m->addr+m->size) >> 32),
  20.116 -			(unsigned long) ((m->addr+m->size)));
  20.117 -
  20.118 -		switch (m->type) {
  20.119 -		case E820_RAM:
  20.120 -			printf("(RAM)\n"); break;
  20.121 -		case E820_RESERVED:
  20.122 -			printf("(Reserved)\n"); break;
  20.123 -		case E820_ACPI:
  20.124 -			printf("(ACPI Data)\n"); break;
  20.125 -		case E820_NVS:
  20.126 -			printf("(ACPI NVS)\n"); break;
  20.127 -		default:
  20.128 -			printf("(Type %ld)\n", m->type); break;
  20.129 -		}
  20.130 -	}
  20.131 -}
  20.132 -
  20.133 -void
  20.134 -dump_dtr(unsigned long addr, unsigned long size)
  20.135 -{
  20.136 -	unsigned long long entry;
  20.137 -	unsigned long base, limit;
  20.138 -	int i;
  20.139 -
  20.140 -	for (i = 0; i < size; i += 8) {
  20.141 -		entry = ((unsigned long long *) addr)[i >> 3];
  20.142 -		base = (((entry >> (56-24)) & 0xFF000000) |
  20.143 -			((entry >> (32-16)) & 0x00FF0000) |
  20.144 -			((entry >> (   16)) & 0x0000FFFF));
  20.145 -		limit = (((entry >> (48-16)) & 0x000F0000) |
  20.146 -		         ((entry           ) & 0x0000FFFF));
  20.147 -		if (entry & (1ULL << (23+32))) /* G */
  20.148 -			limit = (limit << 12) | 0xFFF;
  20.149 -
  20.150 -		printf("[0x%x] = 0x%08x%08x, base 0x%lx, limit 0x%lx\n", i,
  20.151 -			(unsigned)(entry >> 32), (unsigned)(entry),
  20.152 -			base, limit);
  20.153 -	}
  20.154 -}
  20.155 -
  20.156 -void
  20.157 -dump_vmx_context(struct vmx_assist_context *c)
  20.158 -{
  20.159 -	printf("eip 0x%lx, esp 0x%lx, eflags 0x%lx\n",
  20.160 -		(long) c->eip, (long) c->esp, (long) c->eflags);
  20.161 -
  20.162 -	printf("cr0 0x%lx, cr3 0x%lx, cr4 0x%lx\n",
  20.163 -		(long)c->cr0, (long)c->cr3, (long)c->cr4);
  20.164 -
  20.165 -	printf("idtr: limit 0x%lx, base 0x%lx\n",
  20.166 -		(long)c->idtr_limit, (long)c->idtr_base);
  20.167 -
  20.168 -	printf("gdtr: limit 0x%lx, base 0x%lx\n",
  20.169 -		(long)c->gdtr_limit, (long)c->gdtr_base);
  20.170 -
  20.171 -	printf("cs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
  20.172 -		(long)c->cs_sel, (long)c->cs_limit, (long)c->cs_base);
  20.173 -	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
  20.174 -		c->cs_arbytes.fields.seg_type,
  20.175 -		c->cs_arbytes.fields.s,
  20.176 -		c->cs_arbytes.fields.dpl,
  20.177 -		c->cs_arbytes.fields.p,
  20.178 -		c->cs_arbytes.fields.avl,
  20.179 -		c->cs_arbytes.fields.default_ops_size,
  20.180 -		c->cs_arbytes.fields.g,
  20.181 -		c->cs_arbytes.fields.null_bit);
  20.182 -
  20.183 -	printf("ds: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
  20.184 -		(long)c->ds_sel, (long)c->ds_limit, (long)c->ds_base);
  20.185 -	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
  20.186 -		c->ds_arbytes.fields.seg_type,
  20.187 -		c->ds_arbytes.fields.s,
  20.188 -		c->ds_arbytes.fields.dpl,
  20.189 -		c->ds_arbytes.fields.p,
  20.190 -		c->ds_arbytes.fields.avl,
  20.191 -		c->ds_arbytes.fields.default_ops_size,
  20.192 -		c->ds_arbytes.fields.g,
  20.193 -		c->ds_arbytes.fields.null_bit);
  20.194 -
  20.195 -	printf("es: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
  20.196 -		(long)c->es_sel, (long)c->es_limit, (long)c->es_base);
  20.197 -	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
  20.198 -		c->es_arbytes.fields.seg_type,
  20.199 -		c->es_arbytes.fields.s,
  20.200 -		c->es_arbytes.fields.dpl,
  20.201 -		c->es_arbytes.fields.p,
  20.202 -		c->es_arbytes.fields.avl,
  20.203 -		c->es_arbytes.fields.default_ops_size,
  20.204 -		c->es_arbytes.fields.g,
  20.205 -		c->es_arbytes.fields.null_bit);
  20.206 -
  20.207 -	printf("ss: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
  20.208 -		(long)c->ss_sel, (long)c->ss_limit, (long)c->ss_base);
  20.209 -	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
  20.210 -		c->ss_arbytes.fields.seg_type,
  20.211 -		c->ss_arbytes.fields.s,
  20.212 -		c->ss_arbytes.fields.dpl,
  20.213 -		c->ss_arbytes.fields.p,
  20.214 -		c->ss_arbytes.fields.avl,
  20.215 -		c->ss_arbytes.fields.default_ops_size,
  20.216 -		c->ss_arbytes.fields.g,
  20.217 -		c->ss_arbytes.fields.null_bit);
  20.218 -
  20.219 -	printf("fs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
  20.220 -		(long)c->fs_sel, (long)c->fs_limit, (long)c->fs_base);
  20.221 -	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
  20.222 -		c->fs_arbytes.fields.seg_type,
  20.223 -		c->fs_arbytes.fields.s,
  20.224 -		c->fs_arbytes.fields.dpl,
  20.225 -		c->fs_arbytes.fields.p,
  20.226 -		c->fs_arbytes.fields.avl,
  20.227 -		c->fs_arbytes.fields.default_ops_size,
  20.228 -		c->fs_arbytes.fields.g,
  20.229 -		c->fs_arbytes.fields.null_bit);
  20.230 -
  20.231 -	printf("gs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
  20.232 -		(long)c->gs_sel, (long)c->gs_limit, (long)c->gs_base);
  20.233 -	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
  20.234 -		c->gs_arbytes.fields.seg_type,
  20.235 -		c->gs_arbytes.fields.s,
  20.236 -		c->gs_arbytes.fields.dpl,
  20.237 -		c->gs_arbytes.fields.p,
  20.238 -		c->gs_arbytes.fields.avl,
  20.239 -		c->gs_arbytes.fields.default_ops_size,
  20.240 -		c->gs_arbytes.fields.g,
  20.241 -		c->gs_arbytes.fields.null_bit);
  20.242 -
  20.243 -	printf("tr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
  20.244 -		(long)c->tr_sel, (long)c->tr_limit, (long)c->tr_base);
  20.245 -	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
  20.246 -		c->tr_arbytes.fields.seg_type,
  20.247 -		c->tr_arbytes.fields.s,
  20.248 -		c->tr_arbytes.fields.dpl,
  20.249 -		c->tr_arbytes.fields.p,
  20.250 -		c->tr_arbytes.fields.avl,
  20.251 -		c->tr_arbytes.fields.default_ops_size,
  20.252 -		c->tr_arbytes.fields.g,
  20.253 -		c->tr_arbytes.fields.null_bit);
  20.254 -
  20.255 -	printf("ldtr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
  20.256 -		(long)c->ldtr_sel, (long)c->ldtr_limit, (long)c->ldtr_base);
  20.257 -	printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
  20.258 -		c->ldtr_arbytes.fields.seg_type,
  20.259 -		c->ldtr_arbytes.fields.s,
  20.260 -		c->ldtr_arbytes.fields.dpl,
  20.261 -		c->ldtr_arbytes.fields.p,
  20.262 -		c->ldtr_arbytes.fields.avl,
  20.263 -		c->ldtr_arbytes.fields.default_ops_size,
  20.264 -		c->ldtr_arbytes.fields.g,
  20.265 -		c->ldtr_arbytes.fields.null_bit);
  20.266 -
  20.267 -	printf("GDTR <0x%lx,0x%lx>:\n",
  20.268 -		(long)c->gdtr_base, (long)c->gdtr_limit);
  20.269 -	dump_dtr(c->gdtr_base, c->gdtr_limit);
  20.270 -}
  20.271 -#endif /* DEBUG */
  20.272 -
  20.273 -/*
  20.274 - * Lightweight printf that doesn't drag in everything under the sun.
  20.275 - */
  20.276 -int
  20.277 -printf(const char *fmt, ...)
  20.278 -{
  20.279 -	va_list ap;
  20.280 -
  20.281 -	va_start(ap, fmt);
  20.282 -	_doprint(putchar, fmt, ap);
  20.283 -	va_end(ap);
  20.284 -	return 0; /* for gcc compat */
  20.285 -}
  20.286 -
  20.287 -int
  20.288 -vprintf(const char *fmt, va_list ap)
  20.289 -{
  20.290 -	_doprint(putchar, fmt, ap);
  20.291 -	return 0; /* for gcc compat */
  20.292 -}
  20.293 -
  20.294 -void
  20.295 -panic(const char *fmt, ...)
  20.296 -{
  20.297 -	va_list ap;
  20.298 -
  20.299 -	va_start(ap, fmt);
  20.300 -	_doprint(putchar, fmt, ap);
  20.301 -	putchar('\n');
  20.302 -	va_end(ap);
  20.303 -	halt();
  20.304 -}
  20.305 -
  20.306 -unsigned
  20.307 -strlen(const char *s)
  20.308 -{
  20.309 -	const char *q = s;
  20.310 -
  20.311 -	while (*s++)
  20.312 -		/* void */;
  20.313 -	return s - q - 1;
  20.314 -}
  20.315 -
  20.316 -static void
  20.317 -putchar(int ch)
  20.318 -{
  20.319 -	outb(0xE9, ch);
  20.320 -}
  20.321 -
  20.322 -/*
  20.323 - * A stripped down version of doprint,
  20.324 - * but still powerful enough for most tasks.
  20.325 - */
  20.326 -static void
  20.327 -_doprint(void (*put)(int), const char *fmt, va_list ap)
  20.328 -{
  20.329 -	register char *str, c;
  20.330 -	int lflag, zflag, nflag;
  20.331 -	char buffer[17];
  20.332 -	unsigned value;
  20.333 -	int i, slen, pad;
  20.334 -
  20.335 -	for ( ; *fmt != '\0'; fmt++) {
  20.336 -		pad = zflag = nflag = lflag = 0;
  20.337 -		if (*fmt == '%') {
  20.338 -			c = *++fmt;
  20.339 -			if (c == '-' || isdigit(c)) {
  20.340 -				if (c == '-') {
  20.341 -					nflag = 1;
  20.342 -					c = *++fmt;
  20.343 -				}
  20.344 -				zflag = c == '0';
  20.345 -				for (pad = 0; isdigit(c); c = *++fmt)
  20.346 -					pad = (pad * 10) + c - '0';
  20.347 -			}
  20.348 -			if (c == 'l') { /* long extension */
  20.349 -				lflag = 1;
  20.350 -				c = *++fmt;
  20.351 -			}
  20.352 -			if (c == 'd' || c == 'u' || c == 'o' || c == 'x') {
  20.353 -				if (lflag)
  20.354 -					value = va_arg(ap, unsigned);
  20.355 -				else
  20.356 -					value = (unsigned) va_arg(ap, unsigned int);
  20.357 -				str = buffer;
  20.358 -				printnum(str, value,
  20.359 -					c == 'o' ? 8 : (c == 'x' ? 16 : 10));
  20.360 -				goto printn;
  20.361 -			} else if (c == 'O' || c == 'D' || c == 'X') {
  20.362 -				value = va_arg(ap, unsigned);
  20.363 -				str = buffer;
  20.364 -				printnum(str, value,
  20.365 -					c == 'O' ? 8 : (c == 'X' ? 16 : 10));
  20.366 -			printn:
  20.367 -				slen = strlen(str);
  20.368 -				for (i = pad - slen; i > 0; i--)
  20.369 -					put(zflag ? '0' : ' ');
  20.370 -				while (*str) put(*str++);
  20.371 -			} else if (c == 's') {
  20.372 -				str = va_arg(ap, char *);
  20.373 -				slen = strlen(str);
  20.374 -				if (nflag == 0)
  20.375 -					for (i = pad - slen; i > 0; i--) put(' ');
  20.376 -				while (*str) put(*str++);
  20.377 -				if (nflag)
  20.378 -					for (i = pad - slen; i > 0; i--) put(' ');
  20.379 -			} else if (c == 'c')
  20.380 -				put(va_arg(ap, int));
  20.381 -			else
  20.382 -				put(*fmt);
  20.383 -		} else
  20.384 -			put(*fmt);
  20.385 -	}
  20.386 -}
  20.387 -
  20.388 -static char *
  20.389 -printnum(char *p, unsigned long num, int base)
  20.390 -{
  20.391 -	unsigned long n;
  20.392 -
  20.393 -	if ((n = num/base) > 0)
  20.394 -		p = printnum(p, n, base);
  20.395 -	*p++ = "0123456789ABCDEF"[(int)(num % base)];
  20.396 -	*p = '\0';
  20.397 -	return p;
  20.398 -}
  20.399 -
  20.400 -void *
  20.401 -memset(void *s, int c, unsigned n)
  20.402 -{
  20.403 -        int t0, t1;
  20.404 -
  20.405 -        __asm__ __volatile__ ("cld; rep; stosb"
  20.406 -                : "=&c" (t0), "=&D" (t1)
  20.407 -                : "a" (c), "1" (s), "0" (n)
  20.408 -                : "memory");
  20.409 -        return s;
  20.410 -}
  20.411 -
  20.412 -void *
  20.413 -memcpy(void *dest, const void *src, unsigned n)
  20.414 -{
  20.415 -	int t0, t1, t2;
  20.416 -
  20.417 -	__asm__ __volatile__(
  20.418 -		"cld\n"
  20.419 -		"rep; movsl\n"
  20.420 -		"testb $2,%b4\n"
  20.421 -		"je 1f\n"
  20.422 -		"movsw\n"
  20.423 -		"1: testb $1,%b4\n"
  20.424 -		"je 2f\n"
  20.425 -		"movsb\n"
  20.426 -		"2:"
  20.427 -		: "=&c" (t0), "=&D" (t1), "=&S" (t2)
  20.428 -		: "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
  20.429 -		: "memory"
  20.430 -	);
  20.431 -	return dest;
  20.432 -}
  20.433 -
    21.1 --- a/tools/firmware/vmxassist/util.h	Thu Feb 07 09:23:26 2008 -0700
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,45 +0,0 @@
    21.4 -/*
    21.5 - * util.h: Useful utility functions.
    21.6 - *
    21.7 - * Leendert van Doorn, leendert@watson.ibm.com
    21.8 - * Copyright (c) 2005, International Business Machines Corporation.
    21.9 - *
   21.10 - * This program is free software; you can redistribute it and/or modify it
   21.11 - * under the terms and conditions of the GNU General Public License,
   21.12 - * version 2, as published by the Free Software Foundation.
   21.13 - *
   21.14 - * This program is distributed in the hope it will be useful, but WITHOUT
   21.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   21.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   21.17 - * more details.
   21.18 - *
   21.19 - * You should have received a copy of the GNU General Public License along with
   21.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   21.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   21.22 - */
   21.23 -#ifndef __UTIL_H__
   21.24 -#define __UTIL_H__
   21.25 -
   21.26 -#include <stdarg.h>
   21.27 -#include <vm86.h>
   21.28 -
   21.29 -#define	offsetof(type, member)	((unsigned) &((type *)0)->member)
   21.30 -
   21.31 -struct vmx_assist_context;
   21.32 -
   21.33 -#include "../hvmloader/e820.h"
   21.34 -
   21.35 -extern void cpuid_addr_value(uint64_t addr, uint64_t *value);
   21.36 -extern void hexdump(unsigned char *, int);
   21.37 -extern void dump_regs(struct regs *);
   21.38 -extern void dump_vmx_context(struct vmx_assist_context *);
   21.39 -extern void print_e820_map(struct e820entry *, int);
   21.40 -extern void dump_dtr(unsigned long, unsigned long);
   21.41 -extern void *memcpy(void *, const void *, unsigned);
   21.42 -extern void *memset(void *, int, unsigned);
   21.43 -extern int printf(const char *fmt, ...);
   21.44 -extern int vprintf(const char *fmt, va_list ap);
   21.45 -extern void panic(const char *format, ...);
   21.46 -extern void halt(void);
   21.47 -
   21.48 -#endif /* __UTIL_H__ */
    22.1 --- a/tools/firmware/vmxassist/vm86.c	Thu Feb 07 09:23:26 2008 -0700
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,1992 +0,0 @@
    22.4 -/*
    22.5 - * vm86.c: A vm86 emulator. The main purpose of this emulator is to do as
    22.6 - * little work as possible.
    22.7 - *
    22.8 - * Leendert van Doorn, leendert@watson.ibm.com
    22.9 - * Copyright (c) 2005-2006, International Business Machines Corporation.
   22.10 - *
   22.11 - * This program is free software; you can redistribute it and/or modify it
   22.12 - * under the terms and conditions of the GNU General Public License,
   22.13 - * version 2, as published by the Free Software Foundation.
   22.14 - *
   22.15 - * This program is distributed in the hope it will be useful, but WITHOUT
   22.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   22.17 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   22.18 - * more details.
   22.19 - *
   22.20 - * You should have received a copy of the GNU General Public License along with
   22.21 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   22.22 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   22.23 - */
   22.24 -#include "vm86.h"
   22.25 -#include "util.h"
   22.26 -#include "machine.h"
   22.27 -
   22.28 -#define	HIGHMEM		(1 << 20)		/* 1MB */
   22.29 -#define	MASK16(v)	((v) & 0xFFFF)
   22.30 -
   22.31 -#define	DATA32		0x0001
   22.32 -#define	ADDR32		0x0002
   22.33 -#define	SEG_CS		0x0004
   22.34 -#define	SEG_DS		0x0008
   22.35 -#define	SEG_ES		0x0010
   22.36 -#define	SEG_SS		0x0020
   22.37 -#define	SEG_FS		0x0040
   22.38 -#define	SEG_GS		0x0080
   22.39 -#define REP		0x0100
   22.40 -
   22.41 -static unsigned prev_eip = 0;
   22.42 -enum vm86_mode mode = 0;
   22.43 -
   22.44 -static struct regs saved_rm_regs;
   22.45 -
   22.46 -#ifdef DEBUG
   22.47 -int traceset = 0;
   22.48 -
   22.49 -char *states[] = {
   22.50 -	"<VM86_REAL>",
   22.51 -	"<VM86_REAL_TO_PROTECTED>",
   22.52 -	"<VM86_PROTECTED_TO_REAL>",
   22.53 -	"<VM86_PROTECTED>"
   22.54 -};
   22.55 -
   22.56 -static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
   22.57 -#endif /* DEBUG */
   22.58 -
   22.59 -#define PDE_PS				(1 << 7)
   22.60 -#define PT_ENTRY_PRESENT	0x1
   22.61 -
   22.62 -/* We only support access to <=4G physical memory due to 1:1 mapping */
   22.63 -static uint64_t
   22.64 -guest_linear_to_phys(uint32_t base)
   22.65 -{
   22.66 -	uint32_t gcr3 = oldctx.cr3;
   22.67 -	uint64_t l2_mfn;
   22.68 -	uint64_t l1_mfn;
   22.69 -	uint64_t l0_mfn;
   22.70 -
   22.71 -	if (!(oldctx.cr0 & CR0_PG))
   22.72 -		return base;
   22.73 -
   22.74 -	if (!(oldctx.cr4 & CR4_PAE)) {
   22.75 -		l1_mfn = ((uint32_t *)(long)gcr3)[(base >> 22) & 0x3ff];
   22.76 -		if (!(l1_mfn & PT_ENTRY_PRESENT))
   22.77 -			panic("l2 entry not present\n");
   22.78 -
   22.79 -		if ((oldctx.cr4 & CR4_PSE) && (l1_mfn & PDE_PS)) {
   22.80 -			l0_mfn = l1_mfn & 0xffc00000;
   22.81 -			return l0_mfn + (base & 0x3fffff);
   22.82 -		}
   22.83 -
   22.84 -		l1_mfn &= 0xfffff000;
   22.85 -
   22.86 -		l0_mfn = ((uint32_t *)(long)l1_mfn)[(base >> 12) & 0x3ff];
   22.87 -		if (!(l0_mfn & PT_ENTRY_PRESENT))
   22.88 -			panic("l1 entry not present\n");
   22.89 -		l0_mfn &= 0xfffff000;
   22.90 -
   22.91 -		return l0_mfn + (base & 0xfff);
   22.92 -	} else {
   22.93 -		l2_mfn = ((uint64_t *)(long)gcr3)[(base >> 30) & 0x3];
   22.94 -		if (!(l2_mfn & PT_ENTRY_PRESENT))
   22.95 -			panic("l3 entry not present\n");
   22.96 -		l2_mfn &= 0xffffff000ULL;
   22.97 -
   22.98 -		if (l2_mfn & 0xf00000000ULL) {
   22.99 -			printf("l2 page above 4G\n");
  22.100 -			cpuid_addr_value(l2_mfn + 8 * ((base >> 21) & 0x1ff), &l1_mfn);
  22.101 -		} else
  22.102 -			l1_mfn = ((uint64_t *)(long)l2_mfn)[(base >> 21) & 0x1ff];
  22.103 -		if (!(l1_mfn & PT_ENTRY_PRESENT))
  22.104 -			panic("l2 entry not present\n");
  22.105 -
  22.106 -		if (l1_mfn & PDE_PS) { /* CR4.PSE is ignored in PAE mode */
  22.107 -			l0_mfn = l1_mfn & 0xfffe00000ULL;
  22.108 -			return l0_mfn + (base & 0x1fffff);
  22.109 -		}
  22.110 -
  22.111 -		l1_mfn &= 0xffffff000ULL;
  22.112 -
  22.113 -		if (l1_mfn & 0xf00000000ULL) {
  22.114 -			printf("l1 page above 4G\n");
  22.115 -			cpuid_addr_value(l1_mfn + 8 * ((base >> 12) & 0x1ff), &l0_mfn);
  22.116 -		} else
  22.117 -			l0_mfn = ((uint64_t *)(long)l1_mfn)[(base >> 12) & 0x1ff];
  22.118 -		if (!(l0_mfn & PT_ENTRY_PRESENT))
  22.119 -			panic("l1 entry not present\n");
  22.120 -
  22.121 -		l0_mfn &= 0xffffff000ULL;
  22.122 -
  22.123 -		return l0_mfn + (base & 0xfff);
  22.124 -	}
  22.125 -}
  22.126 -
  22.127 -static unsigned
  22.128 -address(struct regs *regs, unsigned seg, unsigned off)
  22.129 -{
  22.130 -	uint64_t gdt_phys_base;
  22.131 -	unsigned long long entry;
  22.132 -	unsigned seg_base, seg_limit;
  22.133 -	unsigned entry_low, entry_high;
  22.134 -
  22.135 -	if (seg == 0) {
  22.136 -		if (mode == VM86_REAL || mode == VM86_REAL_TO_PROTECTED)
  22.137 -			return off;
  22.138 -		else
  22.139 -			panic("segment is zero, but not in real mode!\n");
  22.140 -	}
  22.141 -
  22.142 -	if (mode == VM86_REAL || seg > oldctx.gdtr_limit ||
  22.143 -		(mode == VM86_REAL_TO_PROTECTED && regs->cs == seg))
  22.144 -		return ((seg & 0xFFFF) << 4) + off;
  22.145 -
  22.146 -	gdt_phys_base = guest_linear_to_phys(oldctx.gdtr_base);
  22.147 -	if (gdt_phys_base != (uint32_t)gdt_phys_base) {
  22.148 -		printf("gdt base address above 4G\n");
  22.149 -		cpuid_addr_value(gdt_phys_base + 8 * (seg >> 3), &entry);
  22.150 -	} else
  22.151 -		entry = ((unsigned long long *)(long)gdt_phys_base)[seg >> 3];
  22.152 -
  22.153 -	entry_high = entry >> 32;
  22.154 -	entry_low = entry & 0xFFFFFFFF;
  22.155 -
  22.156 -	seg_base  = (entry_high & 0xFF000000) | ((entry >> 16) & 0xFFFFFF);
  22.157 -	seg_limit = (entry_high & 0xF0000) | (entry_low & 0xFFFF);
  22.158 -
  22.159 -	if (entry_high & 0x8000 &&
  22.160 -		((entry_high & 0x800000 && off >> 12 <= seg_limit) ||
  22.161 -		(!(entry_high & 0x800000) && off <= seg_limit)))
  22.162 -		return seg_base + off;
  22.163 -
  22.164 -	panic("should never reach here in function address():\n\t"
  22.165 -		  "entry=0x%08x%08x, mode=%d, seg=0x%08x, offset=0x%08x\n",
  22.166 -		  entry_high, entry_low, mode, seg, off);
  22.167 -
  22.168 -	return 0;
  22.169 -}
  22.170 -
  22.171 -#ifdef DEBUG
  22.172 -void
  22.173 -trace(struct regs *regs, int adjust, char *fmt, ...)
  22.174 -{
  22.175 -	unsigned off = regs->eip - adjust;
  22.176 -	va_list ap;
  22.177 -
  22.178 -	if ((traceset & (1 << mode)) &&
  22.179 -		(mode == VM86_REAL_TO_PROTECTED || mode == VM86_REAL)) {
  22.180 -		/* 16-bit, seg:off addressing */
  22.181 -		unsigned addr = address(regs, regs->cs, off);
  22.182 -		printf("0x%08x: 0x%x:0x%04x ", addr, regs->cs, off);
  22.183 -		printf("(%d) ", mode);
  22.184 -		va_start(ap, fmt);
  22.185 -		vprintf(fmt, ap);
  22.186 -		va_end(ap);
  22.187 -		printf("\n");
  22.188 -	}
  22.189 -	if ((traceset & (1 << mode)) &&
  22.190 -		(mode == VM86_PROTECTED_TO_REAL || mode == VM86_PROTECTED)) {
  22.191 -		/* 16-bit, gdt addressing */
  22.192 -		unsigned addr = address(regs, regs->cs, off);
  22.193 -		printf("0x%08x: 0x%x:0x%08x ", addr, regs->cs, off);
  22.194 -		printf("(%d) ", mode);
  22.195 -		va_start(ap, fmt);
  22.196 -		vprintf(fmt, ap);
  22.197 -		va_end(ap);
  22.198 -		printf("\n");
  22.199 -	}
  22.200 -}
  22.201 -#endif /* DEBUG */
  22.202 -
  22.203 -static inline unsigned
  22.204 -read32(unsigned addr)
  22.205 -{
  22.206 -	return *(unsigned long *) addr;
  22.207 -}
  22.208 -
  22.209 -static inline unsigned
  22.210 -read16(unsigned addr)
  22.211 -{
  22.212 -	return *(unsigned short *) addr;
  22.213 -}
  22.214 -
  22.215 -static inline unsigned
  22.216 -read8(unsigned addr)
  22.217 -{
  22.218 -	return *(unsigned char *) addr;
  22.219 -}
  22.220 -
  22.221 -static inline void
  22.222 -write32(unsigned addr, unsigned value)
  22.223 -{
  22.224 -	*(unsigned long *) addr = value;
  22.225 -}
  22.226 -
  22.227 -static inline void
  22.228 -write16(unsigned addr, unsigned value)
  22.229 -{
  22.230 -	*(unsigned short *) addr = value;
  22.231 -}
  22.232 -
  22.233 -static inline void
  22.234 -write8(unsigned addr, unsigned value)
  22.235 -{
  22.236 -	*(unsigned char *) addr = value;
  22.237 -}
  22.238 -
  22.239 -static inline void
  22.240 -push32(struct regs *regs, unsigned value)
  22.241 -{
  22.242 -	regs->uesp -= 4;
  22.243 -	write32(address(regs, regs->uss, MASK16(regs->uesp)), value);
  22.244 -}
  22.245 -
  22.246 -static inline void
  22.247 -push16(struct regs *regs, unsigned value)
  22.248 -{
  22.249 -	regs->uesp -= 2;
  22.250 -	write16(address(regs, regs->uss, MASK16(regs->uesp)), value);
  22.251 -}
  22.252 -
  22.253 -static inline unsigned
  22.254 -pop32(struct regs *regs)
  22.255 -{
  22.256 -	unsigned value = read32(address(regs, regs->uss, MASK16(regs->uesp)));
  22.257 -	regs->uesp += 4;
  22.258 -	return value;
  22.259 -}
  22.260 -
  22.261 -static inline unsigned
  22.262 -pop16(struct regs *regs)
  22.263 -{
  22.264 -	unsigned value = read16(address(regs, regs->uss, MASK16(regs->uesp)));
  22.265 -	regs->uesp += 2;
  22.266 -	return value;
  22.267 -}
  22.268 -
  22.269 -static inline unsigned
  22.270 -fetch32(struct regs *regs)
  22.271 -{
  22.272 -	unsigned addr = address(regs, regs->cs, MASK16(regs->eip));
  22.273 -
  22.274 -	regs->eip += 4;
  22.275 -	return read32(addr);
  22.276 -}
  22.277 -
  22.278 -static inline unsigned
  22.279 -fetch16(struct regs *regs)
  22.280 -{
  22.281 -	unsigned addr = address(regs, regs->cs, MASK16(regs->eip));
  22.282 -
  22.283 -	regs->eip += 2;
  22.284 -	return read16(addr);
  22.285 -}
  22.286 -
  22.287 -static inline unsigned
  22.288 -fetch8(struct regs *regs)
  22.289 -{
  22.290 -	unsigned addr = address(regs, regs->cs, MASK16(regs->eip));
  22.291 -
  22.292 -	regs->eip++;
  22.293 -	return read8(addr);
  22.294 -}
  22.295 -
  22.296 -static unsigned
  22.297 -getreg32(struct regs *regs, int r)
  22.298 -{
  22.299 -	switch (r & 7) {
  22.300 -	case 0: return regs->eax;
  22.301 -	case 1: return regs->ecx;
  22.302 -	case 2: return regs->edx;
  22.303 -	case 3: return regs->ebx;
  22.304 -	case 4: return regs->uesp;
  22.305 -	case 5: return regs->ebp;
  22.306 -	case 6: return regs->esi;
  22.307 -	case 7: return regs->edi;
  22.308 -	}
  22.309 -	return ~0;
  22.310 -}
  22.311 -
  22.312 -static unsigned
  22.313 -getreg16(struct regs *regs, int r)
  22.314 -{
  22.315 -	return MASK16(getreg32(regs, r));
  22.316 -}
  22.317 -
  22.318 -static unsigned
  22.319 -getreg8(struct regs *regs, int r)
  22.320 -{
  22.321 -	switch (r & 7) {
  22.322 -	case 0: return regs->eax & 0xFF; /* al */
  22.323 -	case 1: return regs->ecx & 0xFF; /* cl */
  22.324 -	case 2: return regs->edx & 0xFF; /* dl */
  22.325 -	case 3: return regs->ebx & 0xFF; /* bl */
  22.326 -	case 4: return (regs->eax >> 8) & 0xFF; /* ah */
  22.327 -	case 5: return (regs->ecx >> 8) & 0xFF; /* ch */
  22.328 -	case 6: return (regs->edx >> 8) & 0xFF; /* dh */
  22.329 -	case 7: return (regs->ebx >> 8) & 0xFF; /* bh */
  22.330 -	}
  22.331 -	return ~0;
  22.332 -}
  22.333 -
  22.334 -static void
  22.335 -setreg32(struct regs *regs, int r, unsigned v)
  22.336 -{
  22.337 -	switch (r & 7) {
  22.338 -	case 0: regs->eax = v; break;
  22.339 -	case 1: regs->ecx = v; break;
  22.340 -	case 2: regs->edx = v; break;
  22.341 -	case 3: regs->ebx = v; break;
  22.342 -	case 4: regs->uesp = v; break;
  22.343 -	case 5: regs->ebp = v; break;
  22.344 -	case 6: regs->esi = v; break;
  22.345 -	case 7: regs->edi = v; break;
  22.346 -	}
  22.347 -}
  22.348 -
  22.349 -static void
  22.350 -setreg16(struct regs *regs, int r, unsigned v)
  22.351 -{
  22.352 -	setreg32(regs, r, (getreg32(regs, r) & ~0xFFFF) | MASK16(v));
  22.353 -}
  22.354 -
  22.355 -static void
  22.356 -setreg8(struct regs *regs, int r, unsigned v)
  22.357 -{
  22.358 -	v &= 0xFF;
  22.359 -	switch (r & 7) {
  22.360 -	case 0: regs->eax = (regs->eax & ~0xFF) | v; break;
  22.361 -	case 1: regs->ecx = (regs->ecx & ~0xFF) | v; break;
  22.362 -	case 2: regs->edx = (regs->edx & ~0xFF) | v; break;
  22.363 -	case 3: regs->ebx = (regs->ebx & ~0xFF) | v; break;
  22.364 -	case 4: regs->eax = (regs->eax & ~0xFF00) | (v << 8); break;
  22.365 -	case 5: regs->ecx = (regs->ecx & ~0xFF00) | (v << 8); break;
  22.366 -	case 6: regs->edx = (regs->edx & ~0xFF00) | (v << 8); break;
  22.367 -	case 7: regs->ebx = (regs->ebx & ~0xFF00) | (v << 8); break;
  22.368 -	}
  22.369 -}
  22.370 -
  22.371 -static unsigned
  22.372 -segment(unsigned prefix, struct regs *regs, unsigned seg)
  22.373 -{
  22.374 -	if (prefix & SEG_ES)
  22.375 -		seg = regs->ves;
  22.376 -	if (prefix & SEG_DS)
  22.377 -		seg = regs->vds;
  22.378 -	if (prefix & SEG_CS)
  22.379 -		seg = regs->cs;
  22.380 -	if (prefix & SEG_SS)
  22.381 -		seg = regs->uss;
  22.382 -	if (prefix & SEG_FS)
  22.383 -		seg = regs->vfs;
  22.384 -	if (prefix & SEG_GS)
  22.385 -		seg = regs->vgs;
  22.386 -	return seg;
  22.387 -}
  22.388 -
  22.389 -static unsigned
  22.390 -sib(struct regs *regs, int mod, unsigned byte)
  22.391 -{
  22.392 -	unsigned scale = (byte >> 6) & 3;
  22.393 -	int index = (byte >> 3) & 7;
  22.394 -	int base = byte & 7;
  22.395 -	unsigned addr = 0;
  22.396 -
  22.397 -	switch (mod) {
  22.398 -	case 0:
  22.399 -		if (base == 5)
  22.400 -			addr = fetch32(regs);
  22.401 -		else
  22.402 -			addr = getreg32(regs, base);
  22.403 -		break;
  22.404 -	case 1:
  22.405 -		addr = getreg32(regs, base) + (char) fetch8(regs);
  22.406 -		break;
  22.407 -	case 2:
  22.408 -		addr = getreg32(regs, base) + fetch32(regs);
  22.409 -		break;
  22.410 -	}
  22.411 -
  22.412 -	if (index != 4)
  22.413 -		addr += getreg32(regs, index) << scale;
  22.414 -
  22.415 -	return addr;
  22.416 -}
  22.417 -
  22.418 -/*
  22.419 - * Operand (modrm) decode
  22.420 - */
  22.421 -static unsigned
  22.422 -operand(unsigned prefix, struct regs *regs, unsigned modrm)
  22.423 -{
  22.424 -	int mod, disp = 0, seg;
  22.425 -
  22.426 -	seg = segment(prefix, regs, regs->vds);
  22.427 -
  22.428 -	if (prefix & ADDR32) { /* 32-bit addressing */
  22.429 -		switch ((mod = (modrm >> 6) & 3)) {
  22.430 -		case 0:
  22.431 -			switch (modrm & 7) {
  22.432 -			case 0: return address(regs, seg, regs->eax);
  22.433 -			case 1: return address(regs, seg, regs->ecx);
  22.434 -			case 2: return address(regs, seg, regs->edx);
  22.435 -			case 3: return address(regs, seg, regs->ebx);
  22.436 -			case 4: return address(regs, seg,
  22.437 -						   sib(regs, mod, fetch8(regs)));
  22.438 -			case 5: return address(regs, seg, fetch32(regs));
  22.439 -			case 6: return address(regs, seg, regs->esi);
  22.440 -			case 7: return address(regs, seg, regs->edi);
  22.441 -			}
  22.442 -			break;
  22.443 -		case 1:
  22.444 -		case 2:
  22.445 -			if ((modrm & 7) != 4) {
  22.446 -				if (mod == 1)
  22.447 -					disp = (char) fetch8(regs);
  22.448 -				else
  22.449 -					disp = (int) fetch32(regs);
  22.450 -			}
  22.451 -			switch (modrm & 7) {
  22.452 -			case 0: return address(regs, seg, regs->eax + disp);
  22.453 -			case 1: return address(regs, seg, regs->ecx + disp);
  22.454 -			case 2: return address(regs, seg, regs->edx + disp);
  22.455 -			case 3: return address(regs, seg, regs->ebx + disp);
  22.456 -			case 4: return address(regs, seg,
  22.457 -						   sib(regs, mod, fetch8(regs)));
  22.458 -			case 5: return address(regs, seg, regs->ebp + disp);
  22.459 -			case 6: return address(regs, seg, regs->esi + disp);
  22.460 -			case 7: return address(regs, seg, regs->edi + disp);
  22.461 -			}
  22.462 -			break;
  22.463 -		case 3:
  22.464 -			return getreg32(regs, modrm);
  22.465 -		}
  22.466 -	} else { /* 16-bit addressing */
  22.467 -		switch ((mod = (modrm >> 6) & 3)) {
  22.468 -		case 0:
  22.469 -			switch (modrm & 7) {
  22.470 -			case 0: return address(regs, seg, MASK16(regs->ebx) +
  22.471 -					MASK16(regs->esi));
  22.472 -			case 1: return address(regs, seg, MASK16(regs->ebx) +
  22.473 -					MASK16(regs->edi));
  22.474 -			case 2: return address(regs, seg, MASK16(regs->ebp) +
  22.475 -					MASK16(regs->esi));
  22.476 -			case 3: return address(regs, seg, MASK16(regs->ebp) +
  22.477 -					MASK16(regs->edi));
  22.478 -			case 4: return address(regs, seg, MASK16(regs->esi));
  22.479 -			case 5: return address(regs, seg, MASK16(regs->edi));
  22.480 -			case 6: return address(regs, seg, fetch16(regs));
  22.481 -			case 7: return address(regs, seg, MASK16(regs->ebx));
  22.482 -			}
  22.483 -			break;
  22.484 -		case 1:
  22.485 -		case 2:
  22.486 -			if (mod == 1)
  22.487 -				disp = (char) fetch8(regs);
  22.488 -			else
  22.489 -				disp = (int) fetch16(regs);
  22.490 -			switch (modrm & 7) {
  22.491 -			case 0: return address(regs, seg, MASK16(regs->ebx) +
  22.492 -					MASK16(regs->esi) + disp);
  22.493 -			case 1: return address(regs, seg, MASK16(regs->ebx) +
  22.494 -					MASK16(regs->edi) + disp);
  22.495 -			case 2: return address(regs, seg, MASK16(regs->ebp) +
  22.496 -					MASK16(regs->esi) + disp);
  22.497 -			case 3: return address(regs, seg, MASK16(regs->ebp) +
  22.498 -					MASK16(regs->edi) + disp);
  22.499 -			case 4: return address(regs, seg,
  22.500 -					MASK16(regs->esi) + disp);
  22.501 -			case 5: return address(regs, seg,
  22.502 -					MASK16(regs->edi) + disp);
  22.503 -			case 6: return address(regs, seg,
  22.504 -					MASK16(regs->ebp) + disp);
  22.505 -			case 7: return address(regs, seg,
  22.506 -					MASK16(regs->ebx) + disp);
  22.507 -			}
  22.508 -			break;
  22.509 -		case 3:
  22.510 -			return getreg16(regs, modrm);
  22.511 -		}
  22.512 -	}
  22.513 -
  22.514 -	return 0;
  22.515 -}
  22.516 -
  22.517 -/*
  22.518 - * Load new IDT
  22.519 - */
  22.520 -static int
  22.521 -lidt(struct regs *regs, unsigned prefix, unsigned modrm)
  22.522 -{
  22.523 -	unsigned eip = regs->eip - 3;
  22.524 -	unsigned addr = operand(prefix, regs, modrm);
  22.525 -
  22.526 -	oldctx.idtr_limit = ((struct dtr *) addr)->size;
  22.527 -	if ((prefix & DATA32) == 0)
  22.528 -		oldctx.idtr_base = ((struct dtr *) addr)->base & 0xFFFFFF;
  22.529 -	else
  22.530 -		oldctx.idtr_base = ((struct dtr *) addr)->base;
  22.531 -	TRACE((regs, regs->eip - eip, "lidt 0x%x <%d, 0x%x>",
  22.532 -		addr, oldctx.idtr_limit, oldctx.idtr_base));
  22.533 -
  22.534 -	return 1;
  22.535 -}
  22.536 -
  22.537 -/*
  22.538 - * Load new GDT
  22.539 - */
  22.540 -static int
  22.541 -lgdt(struct regs *regs, unsigned prefix, unsigned modrm)
  22.542 -{
  22.543 -	unsigned eip = regs->eip - 3;
  22.544 -	unsigned addr = operand(prefix, regs, modrm);
  22.545 -
  22.546 -	oldctx.gdtr_limit = ((struct dtr *) addr)->size;
  22.547 -	if ((prefix & DATA32) == 0)
  22.548 -		oldctx.gdtr_base = ((struct dtr *) addr)->base & 0xFFFFFF;
  22.549 -	else
  22.550 -		oldctx.gdtr_base = ((struct dtr *) addr)->base;
  22.551 -	TRACE((regs, regs->eip - eip, "lgdt 0x%x <%d, 0x%x>",
  22.552 -		addr, oldctx.gdtr_limit, oldctx.gdtr_base));
  22.553 -
  22.554 -	return 1;
  22.555 -}
  22.556 -
  22.557 -/*
  22.558 - * Modify CR0 either through an lmsw instruction.
  22.559 - */
  22.560 -static int
  22.561 -lmsw(struct regs *regs, unsigned prefix, unsigned modrm)
  22.562 -{
  22.563 -	unsigned eip = regs->eip - 3;
  22.564 -	unsigned ax = operand(prefix, regs, modrm) & 0xF;
  22.565 -	unsigned cr0 = (oldctx.cr0 & 0xFFFFFFF0) | ax;
  22.566 -
  22.567 -	TRACE((regs, regs->eip - eip, "lmsw 0x%x", ax));
  22.568 -	oldctx.cr0 = cr0 | CR0_PE | CR0_NE;
  22.569 -	if (cr0 & CR0_PE)
  22.570 -		set_mode(regs, VM86_REAL_TO_PROTECTED);
  22.571 -
  22.572 -	return 1;
  22.573 -}
  22.574 -
  22.575 -/*
  22.576 - * We need to handle moves that address memory beyond the 64KB segment
  22.577 - * limit that VM8086 mode enforces.
  22.578 - */
  22.579 -static int
  22.580 -movr(struct regs *regs, unsigned prefix, unsigned opc)
  22.581 -{
  22.582 -	unsigned eip = regs->eip - 1;
  22.583 -	unsigned modrm = fetch8(regs);
  22.584 -	unsigned addr = operand(prefix, regs, modrm);
  22.585 -	unsigned val, r = (modrm >> 3) & 7;
  22.586 -
  22.587 -	if ((modrm & 0xC0) == 0xC0) {
  22.588 -		/*
  22.589 -		 * Emulate all guest instructions in protected to real mode.
  22.590 -		 */
  22.591 -		if (mode != VM86_PROTECTED_TO_REAL)
  22.592 -			return 0;
  22.593 -	}
  22.594 -
  22.595 -	switch (opc) {
  22.596 -	case 0x88: /* addr32 mov r8, r/m8 */
  22.597 -		val = getreg8(regs, r);
  22.598 -		TRACE((regs, regs->eip - eip,
  22.599 -			"movb %%e%s, *0x%x", rnames[r], addr));
  22.600 -		write8(addr, val);
  22.601 -		return 1;
  22.602 -
  22.603 -	case 0x8A: /* addr32 mov r/m8, r8 */
  22.604 -		TRACE((regs, regs->eip - eip,
  22.605 -			"movb *0x%x, %%%s", addr, rnames[r]));
  22.606 -		setreg8(regs, r, read8(addr));
  22.607 -		return 1;
  22.608 -
  22.609 -	case 0x89: /* addr32 mov r16, r/m16 */
  22.610 -		val = getreg32(regs, r);
  22.611 -		if ((modrm & 0xC0) == 0xC0) {
  22.612 -			if (prefix & DATA32)
  22.613 -				setreg32(regs, modrm & 7, val);
  22.614 -			else
  22.615 -				setreg16(regs, modrm & 7, MASK16(val));
  22.616 -			return 1;
  22.617 -		}
  22.618 -
  22.619 -		if (prefix & DATA32) {
  22.620 -			TRACE((regs, regs->eip - eip,
  22.621 -				"movl %%e%s, *0x%x", rnames[r], addr));
  22.622 -			write32(addr, val);
  22.623 -		} else {
  22.624 -			TRACE((regs, regs->eip - eip,
  22.625 -				"movw %%%s, *0x%x", rnames[r], addr));
  22.626 -			write16(addr, MASK16(val));
  22.627 -		}
  22.628 -		return 1;
  22.629 -
  22.630 -	case 0x8B: /* mov r/m16, r16 */
  22.631 -		if ((modrm & 0xC0) == 0xC0) {
  22.632 -			if (prefix & DATA32)
  22.633 -				setreg32(regs, r, addr);
  22.634 -			else
  22.635 -				setreg16(regs, r, MASK16(addr));
  22.636 -			return 1;
  22.637 -		}
  22.638 -
  22.639 -		if (prefix & DATA32) {
  22.640 -			TRACE((regs, regs->eip - eip,
  22.641 -				"movl *0x%x, %%e%s", addr, rnames[r]));
  22.642 -			setreg32(regs, r, read32(addr));
  22.643 -		} else {
  22.644 -			TRACE((regs, regs->eip - eip,
  22.645 -				"movw *0x%x, %%%s", addr, rnames[r]));
  22.646 -			setreg16(regs, r, read16(addr));
  22.647 -		}
  22.648 -		return 1;
  22.649 -
  22.650 -	case 0xC6: /* addr32 movb $imm, r/m8 */
  22.651 -		if ((modrm >> 3) & 7)
  22.652 -			return 0;
  22.653 -		val = fetch8(regs);
  22.654 -		write8(addr, val);
  22.655 -		TRACE((regs, regs->eip - eip, "movb $0x%x, *0x%x",
  22.656 -							val, addr));
  22.657 -		return 1;
  22.658 -	}
  22.659 -	return 0;
  22.660 -}
  22.661 -
  22.662 -/*
  22.663 - * We need to handle string moves that address memory beyond the 64KB segment
  22.664 - * limit that VM8086 mode enforces.
  22.665 - */
  22.666 -static inline int
  22.667 -movs(struct regs *regs, unsigned prefix, unsigned opc)
  22.668 -{
  22.669 -	unsigned eip = regs->eip - 1;
  22.670 -	unsigned sseg = segment(prefix, regs, regs->vds);
  22.671 -	unsigned dseg = regs->ves;
  22.672 -	unsigned saddr, daddr;
  22.673 -	unsigned count = 1;
  22.674 -	int incr = ((regs->eflags & EFLAGS_DF) == 0) ? 1 : -1;
  22.675 -
  22.676 -	saddr = address(regs, sseg, regs->esi);
  22.677 -	daddr = address(regs, dseg, regs->edi);
  22.678 -
  22.679 -	if ((prefix & REP) != 0) {
  22.680 -		count = regs->ecx;
  22.681 -		regs->ecx = 0;
  22.682 -	}
  22.683 -
  22.684 -	switch (opc) {
  22.685 -	case 0xA4: /* movsb */
  22.686 -		regs->esi += (incr * count);
  22.687 -		regs->edi += (incr * count);
  22.688 -
  22.689 -		while (count-- != 0) {
  22.690 -			write8(daddr, read8(saddr));
  22.691 -			daddr += incr;
  22.692 -			saddr += incr;
  22.693 -		}
  22.694 -		TRACE((regs, regs->eip - eip, "movsb (%%esi),%%es:(%%edi)"));
  22.695 -		break;
  22.696 -
  22.697 -	case 0xA5: /* movsw */
  22.698 -		if ((prefix & DATA32) == 0) {
  22.699 -			incr = 2 * incr;
  22.700 -			regs->esi += (incr * count);
  22.701 -			regs->edi += (incr * count);
  22.702 -
  22.703 -			while (count-- != 0) {
  22.704 -				write16(daddr, read16(saddr));
  22.705 -				daddr += incr;
  22.706 -				saddr += incr;
  22.707 -			}
  22.708 -		} else {
  22.709 -			incr = 4 * incr;
  22.710 -			regs->esi += (incr * count);
  22.711 -			regs->edi += (incr * count);
  22.712 -
  22.713 -			while (count-- != 0) {
  22.714 -				write32(daddr, read32(saddr));
  22.715 -				daddr += incr;
  22.716 -				saddr += incr;
  22.717 -			}
  22.718 -		}			
  22.719 -		TRACE((regs, regs->eip - eip, "movsw %s(%%esi),%%es:(%%edi)"));
  22.720 -		break;
  22.721 -	}
  22.722 -
  22.723 -	return 1;
  22.724 -}
  22.725 -
  22.726 -static inline int
  22.727 -lods(struct regs *regs, unsigned prefix, unsigned opc)
  22.728 -{
  22.729 -	unsigned eip = regs->eip - 1;
  22.730 -	unsigned seg = segment(prefix, regs, regs->vds);
  22.731 -	unsigned addr = address(regs, seg, regs->esi);
  22.732 -	unsigned count = 1;
  22.733 -	int incr = ((regs->eflags & EFLAGS_DF) == 0) ? 1 : -1;
  22.734 -
  22.735 -	if ((prefix & REP) != 0) {
  22.736 -		count = regs->ecx;
  22.737 -		regs->ecx = 0;
  22.738 -	}
  22.739 -
  22.740 -	switch (opc) {
  22.741 -	case 0xAD: /* lodsw */
  22.742 -		if ((prefix & DATA32) == 0) {
  22.743 -			incr = 2 * incr;
  22.744 -			regs->esi += (incr * count);
  22.745 -			while (count-- != 0) {
  22.746 -				setreg16(regs, 0, read16(addr));
  22.747 -				addr += incr;
  22.748 -			}
  22.749 -
  22.750 -			TRACE((regs, regs->eip - eip, "lodsw (%%esi),%%ax"));
  22.751 -		} else {
  22.752 -			incr = 4 * incr;
  22.753 -			regs->esi += (incr * count);
  22.754 -			while (count-- != 0) {
  22.755 -				setreg32(regs, 0, read32(addr));
  22.756 -				addr += incr;
  22.757 -			}
  22.758 -			TRACE((regs, regs->eip - eip, "lodsw (%%esi),%%eax"));
  22.759 -		}
  22.760 -		break;
  22.761 -	}
  22.762 -	return 1;
  22.763 -}
  22.764 -/*
  22.765 - * Move to and from a control register.
  22.766 - */
  22.767 -static int
  22.768 -movcr(struct regs *regs, unsigned prefix, unsigned opc)
  22.769 -{
  22.770 -	unsigned eip = regs->eip - 2;
  22.771 -	unsigned modrm = fetch8(regs);
  22.772 -	unsigned cr = (modrm >> 3) & 7;
  22.773 -
  22.774 -	if ((modrm & 0xC0) != 0xC0) /* only registers */
  22.775 -		return 0;
  22.776 -
  22.777 -	switch (opc) {
  22.778 -	case 0x20: /* mov Rd, Cd */
  22.779 -		TRACE((regs, regs->eip - eip, "movl %%cr%d, %%eax", cr));
  22.780 -		switch (cr) {
  22.781 -		case 0:
  22.782 -			setreg32(regs, modrm,
  22.783 -				oldctx.cr0 & ~(CR0_PE | CR0_NE));
  22.784 -			break;
  22.785 -		case 2:
  22.786 -			setreg32(regs, modrm, get_cr2());
  22.787 -			break;
  22.788 -		case 3:
  22.789 -			setreg32(regs, modrm, oldctx.cr3);
  22.790 -			break;
  22.791 -		case 4:
  22.792 -			setreg32(regs, modrm, oldctx.cr4);
  22.793 -			break;
  22.794 -		}
  22.795 -		break;
  22.796 -	case 0x22: /* mov Cd, Rd */
  22.797 -		TRACE((regs, regs->eip - eip, "movl %%eax, %%cr%d", cr));
  22.798 -		switch (cr) {
  22.799 -		case 0:
  22.800 -			oldctx.cr0 = getreg32(regs, modrm) | (CR0_PE | CR0_NE);
  22.801 -			if (getreg32(regs, modrm) & CR0_PE)
  22.802 -				set_mode(regs, VM86_REAL_TO_PROTECTED);
  22.803 -			else
  22.804 -				set_mode(regs, VM86_REAL);
  22.805 -			break;
  22.806 -		case 3:
  22.807 -			oldctx.cr3 = getreg32(regs, modrm);
  22.808 -			break;
  22.809 -		case 4:
  22.810 -			oldctx.cr4 = getreg32(regs, modrm);
  22.811 -			break;
  22.812 -		}
  22.813 -		break;
  22.814 -	}
  22.815 -
  22.816 -	return 1;
  22.817 -}
  22.818 -
  22.819 -static inline void set_eflags_ZF(unsigned mask, unsigned v1, struct regs *regs)
  22.820 -{
  22.821 -	if ((v1 & mask) == 0)
  22.822 -		regs->eflags |= EFLAGS_ZF;
  22.823 -	else
  22.824 -		regs->eflags &= ~EFLAGS_ZF;
  22.825 -}
  22.826 -
  22.827 -static void set_eflags_add(unsigned hi_bit_mask, unsigned v1, unsigned v2,
  22.828 -				unsigned result, struct regs *regs)
  22.829 -{
  22.830 -	int bit_count;
  22.831 -	unsigned tmp;
  22.832 -	unsigned full_mask;
  22.833 -	unsigned nonsign_mask;
  22.834 -
  22.835 -	/* Carry out of high order bit? */
  22.836 -	if ( v1 & v2 & hi_bit_mask )
  22.837 -		regs->eflags |= EFLAGS_CF;
  22.838 -	else
  22.839 -		regs->eflags &= ~EFLAGS_CF;
  22.840 -
  22.841 -	/* Even parity in least significant byte? */
  22.842 -	tmp = result & 0xff;
  22.843 -	for (bit_count = 0; tmp != 0; bit_count++)
  22.844 -		tmp &= (tmp - 1);
  22.845 -
  22.846 -	if (bit_count & 1)
  22.847 -		regs->eflags &= ~EFLAGS_PF;
  22.848 -	else
  22.849 -		regs->eflags |= EFLAGS_PF;
  22.850 -
  22.851 -	/* Carry out of least significant BCD digit? */
  22.852 -	if ( v1 & v2 & (1<<3) )
  22.853 -		regs->eflags |= EFLAGS_AF;
  22.854 -	else
  22.855 -		regs->eflags &= ~EFLAGS_AF;
  22.856 -
  22.857 -	/* Result is zero? */
  22.858 -	full_mask = (hi_bit_mask - 1) | hi_bit_mask;
  22.859 -	set_eflags_ZF(full_mask, result, regs);
  22.860 -
  22.861 -	/* Sign of result? */
  22.862 -	if ( result & hi_bit_mask )
  22.863 -		regs->eflags |= EFLAGS_SF;
  22.864 -	else
  22.865 -		regs->eflags &= ~EFLAGS_SF;
  22.866 -
  22.867 -	/* Carry out of highest non-sign bit? */
  22.868 -	nonsign_mask = (hi_bit_mask >> 1) & ~hi_bit_mask;
  22.869 -	if ( v1 & v2 & hi_bit_mask )
  22.870 -		regs->eflags |= EFLAGS_OF;
  22.871 -	else
  22.872 -		regs->eflags &= ~EFLAGS_OF;
  22.873 -
  22.874 -}
  22.875 -
  22.876 -/*
  22.877 - * We need to handle cmp opcodes that address memory beyond the 64KB
  22.878 - * segment limit that VM8086 mode enforces.
  22.879 - */
  22.880 -static int
  22.881 -cmp(struct regs *regs, unsigned prefix, unsigned opc)
  22.882 -{
  22.883 -	unsigned eip = regs->eip - 1;
  22.884 -	unsigned modrm = fetch8(regs);
  22.885 -	unsigned addr = operand(prefix, regs, modrm);
  22.886 -	unsigned diff, val, r = (modrm >> 3) & 7;
  22.887 -
  22.888 -	if ((modrm & 0xC0) == 0xC0) /* no registers */
  22.889 -		return 0;
  22.890 -
  22.891 -	switch (opc) {
  22.892 -	case 0x39: /* addr32 cmp r16, r/m16 */
  22.893 -		val = getreg32(regs, r);
  22.894 -		if (prefix & DATA32) {
  22.895 -			diff = read32(addr) - val;
  22.896 -			set_eflags_ZF(~0, diff, regs);
  22.897 -
  22.898 -			TRACE((regs, regs->eip - eip,
  22.899 -				"cmp %%e%s, *0x%x (0x%x)",
  22.900 -				rnames[r], addr, diff));
  22.901 -		} else {
  22.902 -			diff = read16(addr) - val;
  22.903 -			set_eflags_ZF(0xFFFF, diff, regs);
  22.904 -
  22.905 -			TRACE((regs, regs->eip - eip,
  22.906 -				"cmp %%%s, *0x%x (0x%x)",
  22.907 -				rnames[r], addr, diff));
  22.908 -		}
  22.909 -		break;
  22.910 -
  22.911 -	/* other cmp opcodes ... */
  22.912 -	}
  22.913 -	return 1;
  22.914 -}
  22.915 -
  22.916 -/*
  22.917 - * We need to handle test opcodes that address memory beyond the 64KB
  22.918 - * segment limit that VM8086 mode enforces.
  22.919 - */
  22.920 -static int
  22.921 -test(struct regs *regs, unsigned prefix, unsigned opc)
  22.922 -{
  22.923 -	unsigned eip = regs->eip - 1;
  22.924 -	unsigned modrm = fetch8(regs);
  22.925 -	unsigned addr = operand(prefix, regs, modrm);
  22.926 -	unsigned val, diff;
  22.927 -
  22.928 -	if ((modrm & 0xC0) == 0xC0) /* no registers */
  22.929 -		return 0;
  22.930 -
  22.931 -	switch (opc) {
  22.932 -	case 0xF6: /* testb $imm, r/m8 */
  22.933 -		if ((modrm >> 3) & 7)
  22.934 -			return 0;
  22.935 -		val = fetch8(regs);
  22.936 -		diff = read8(addr) & val;
  22.937 -		set_eflags_ZF(0xFF, diff, regs);
  22.938 -
  22.939 -		TRACE((regs, regs->eip - eip, "testb $0x%x, *0x%x (0x%x)",
  22.940 -							val, addr, diff));
  22.941 -		break;
  22.942 -
  22.943 -	/* other test opcodes ... */
  22.944 -	}
  22.945 -
  22.946 -	return 1;
  22.947 -}
  22.948 -
  22.949 -/*
  22.950 - * We need to handle add opcodes that address memory beyond the 64KB
  22.951 - * segment limit that VM8086 mode enforces.
  22.952 - */
  22.953 -static int
  22.954 -add(struct regs *regs, unsigned prefix, unsigned opc)
  22.955 -{
  22.956 -	unsigned eip = regs->eip - 1;
  22.957 -	unsigned modrm = fetch8(regs);
  22.958 -	unsigned addr = operand(prefix, regs, modrm);
  22.959 -	unsigned r = (modrm >> 3) & 7;
  22.960 -
  22.961 -	unsigned val1 = 0;
  22.962 -	unsigned val2 = 0;
  22.963 -	unsigned result = 0;
  22.964 -	unsigned hi_bit;
  22.965 -
  22.966 -	if ((modrm & 0xC0) == 0xC0) /* no registers */
  22.967 -		return 0;
  22.968 -
  22.969 -	switch (opc) {
  22.970 -	case 0x00: /* addr32 add r8, r/m8 */
  22.971 -		val1 = getreg8(regs, r);
  22.972 -		val2 = read8(addr);
  22.973 -		result = val1 + val2;
  22.974 -		write8(addr, result);
  22.975 -		TRACE((regs, regs->eip - eip,
  22.976 -			"addb %%e%s, *0x%x", rnames[r], addr));
  22.977 -		break;
  22.978 -		
  22.979 -	case 0x01: /* addr32 add r16, r/m16 */
  22.980 -		if (prefix & DATA32) {
  22.981 -			val1 = getreg32(regs, r);
  22.982 -			val2 = read32(addr);
  22.983 -			result = val1 + val2;
  22.984 -			write32(addr, result);
  22.985 -			TRACE((regs, regs->eip - eip,
  22.986 -				"addl %%e%s, *0x%x", rnames[r], addr));
  22.987 -		} else {
  22.988 -			val1 = getreg16(regs, r);
  22.989 -			val2 = read16(addr);
  22.990 -			result = val1 + val2;
  22.991 -			write16(addr, result);
  22.992 -			TRACE((regs, regs->eip - eip,
  22.993 -				"addw %%e%s, *0x%x", rnames[r], addr));
  22.994 -		}
  22.995 -		break;
  22.996 -		
  22.997 -	case 0x03: /* addr32 add r/m16, r16 */
  22.998 -		if (prefix & DATA32) {
  22.999 -			val1 = getreg32(regs, r);
 22.1000 -			val2 = read32(addr);
 22.1001 -			result = val1 + val2;
 22.1002 -			setreg32(regs, r, result);
 22.1003 -			TRACE((regs, regs->eip - eip,
 22.1004 -				"addl *0x%x, %%e%s", addr, rnames[r]));
 22.1005 -		} else {
 22.1006 -			val1 = getreg16(regs, r);
 22.1007 -			val2 = read16(addr);
 22.1008 -			result = val1 + val2;
 22.1009 -			setreg16(regs, r, result);
 22.1010 -			TRACE((regs, regs->eip - eip,
 22.1011 -				"addw *0x%x, %%%s", addr, rnames[r]));
 22.1012 -		}
 22.1013 -		break;
 22.1014 -	}
 22.1015 -
 22.1016 -	if (opc == 0x00)
 22.1017 -		hi_bit = (1<<7);
 22.1018 -	else
 22.1019 -		hi_bit = (prefix & DATA32) ? (1<<31) : (1<<15);
 22.1020 -	set_eflags_add(hi_bit, val1, val2, result, regs);
 22.1021 -
 22.1022 -	return 1;
 22.1023 -}
 22.1024 -
 22.1025 -/*
 22.1026 - * We need to handle pop opcodes that address memory beyond the 64KB
 22.1027 - * segment limit that VM8086 mode enforces.
 22.1028 - */
 22.1029 -static int
 22.1030 -pop(struct regs *regs, unsigned prefix, unsigned opc)
 22.1031 -{
 22.1032 -	unsigned eip = regs->eip - 1;
 22.1033 -	unsigned modrm = fetch8(regs);
 22.1034 -	unsigned addr = operand(prefix, regs, modrm);
 22.1035 -
 22.1036 -	if ((modrm & 0xC0) == 0xC0) /* no registers */
 22.1037 -		return 0;
 22.1038 -
 22.1039 -	switch (opc) {
 22.1040 -	case 0x8F: /* pop r/m16 */
 22.1041 -		if ((modrm >> 3) & 7)
 22.1042 -			return 0;
 22.1043 -		if (prefix & DATA32)
 22.1044 -			write32(addr, pop32(regs));
 22.1045 -		else
 22.1046 -			write16(addr, pop16(regs));
 22.1047 -		TRACE((regs, regs->eip - eip, "pop *0x%x", addr));
 22.1048 -		break;
 22.1049 -
 22.1050 -	/* other pop opcodes ... */
 22.1051 -	}
 22.1052 -
 22.1053 -	return 1;
 22.1054 -}
 22.1055 -
 22.1056 -static int
 22.1057 -mov_to_seg(struct regs *regs, unsigned prefix, unsigned opc)
 22.1058 -{
 22.1059 -	unsigned modrm = fetch8(regs);
 22.1060 -
 22.1061 -	/*
 22.1062 -	 * Emulate segment loads in:
 22.1063 -	 * 1) real->protected mode.
 22.1064 -	 * 2) protected->real mode.
 22.1065 -	 */
 22.1066 -	if (mode != VM86_REAL_TO_PROTECTED &&
 22.1067 -	    mode != VM86_PROTECTED_TO_REAL)
 22.1068 -		return 0;
 22.1069 -
 22.1070 -	/* Register source only. */
 22.1071 -	if ((modrm & 0xC0) != 0xC0)
 22.1072 -		goto fail;
 22.1073 -
 22.1074 -	switch ((modrm & 0x38) >> 3) {
 22.1075 -	case 0: /* es */
 22.1076 -		regs->ves = getreg16(regs, modrm);
 22.1077 -		if (mode == VM86_PROTECTED_TO_REAL)
 22.1078 -			return 1;
 22.1079 -		saved_rm_regs.ves = 0;
 22.1080 -		oldctx.es_sel = regs->ves;
 22.1081 -		return 1;
 22.1082 -
 22.1083 -	/* case 1: cs */
 22.1084 -
 22.1085 -	case 2: /* ss */
 22.1086 -		regs->uss = getreg16(regs, modrm);
 22.1087 -		if (mode == VM86_PROTECTED_TO_REAL)
 22.1088 -			return 1;
 22.1089 -		saved_rm_regs.uss = 0;
 22.1090 -		oldctx.ss_sel = regs->uss;
 22.1091 -		return 1;
 22.1092 -	case 3: /* ds */
 22.1093 -		regs->vds = getreg16(regs, modrm);
 22.1094 -		if (mode == VM86_PROTECTED_TO_REAL)
 22.1095 -			return 1;
 22.1096 -		saved_rm_regs.vds = 0;
 22.1097 -		oldctx.ds_sel = regs->vds;
 22.1098 -		return 1;
 22.1099 -	case 4: /* fs */
 22.1100 -		regs->vfs = getreg16(regs, modrm);
 22.1101 -		if (mode == VM86_PROTECTED_TO_REAL)
 22.1102 -			return 1;
 22.1103 -		saved_rm_regs.vfs = 0;
 22.1104 -		oldctx.fs_sel = regs->vfs;
 22.1105 -		return 1;
 22.1106 -	case 5: /* gs */
 22.1107 -		regs->vgs = getreg16(regs, modrm);
 22.1108 -		if (mode == VM86_PROTECTED_TO_REAL)
 22.1109 -			return 1;
 22.1110 -		saved_rm_regs.vgs = 0;
 22.1111 -		oldctx.gs_sel = regs->vgs;
 22.1112 -		return 1;
 22.1113 -	}
 22.1114 -
 22.1115 - fail:
 22.1116 -	printf("%s:%d: missed opcode %02x %02x\n",
 22.1117 -		   __FUNCTION__, __LINE__, opc, modrm);
 22.1118 -	return 0;
 22.1119 -}
 22.1120 -
 22.1121 -/*
 22.1122 - * Emulate a segment load in protected mode
 22.1123 - */
 22.1124 -static int
 22.1125 -load_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union vmcs_arbytes *arbytes)
 22.1126 -{
 22.1127 -	uint64_t gdt_phys_base;
 22.1128 -	unsigned long long entry;
 22.1129 -
 22.1130 -	/* protected mode: use seg as index into gdt */
 22.1131 -	if (sel > oldctx.gdtr_limit)
 22.1132 -		return 0;
 22.1133 -
 22.1134 -	if (sel == 0) {
 22.1135 -		arbytes->fields.null_bit = 1;
 22.1136 -		return 1;
 22.1137 -	}
 22.1138 -
 22.1139 -	gdt_phys_base = guest_linear_to_phys(oldctx.gdtr_base);
 22.1140 -	if (gdt_phys_base != (uint32_t)gdt_phys_base) {
 22.1141 -		printf("gdt base address above 4G\n");
 22.1142 -		cpuid_addr_value(gdt_phys_base + 8 * (sel >> 3), &entry);
 22.1143 -	} else
 22.1144 -		entry = ((unsigned long long *)(long)gdt_phys_base)[sel >> 3];
 22.1145 -
 22.1146 -	/* Check the P bit first */
 22.1147 -	if (!((entry >> (15+32)) & 0x1) && sel != 0)
 22.1148 -		return 0;
 22.1149 -
 22.1150 -	*base =  (((entry >> (56-24)) & 0xFF000000) |
 22.1151 -		  ((entry >> (32-16)) & 0x00FF0000) |
 22.1152 -		  ((entry >> (   16)) & 0x0000FFFF));
 22.1153 -	*limit = (((entry >> (48-16)) & 0x000F0000) |
 22.1154 -		  (entry & 0x0000FFFF));
 22.1155 -
 22.1156 -	arbytes->bytes = 0;
 22.1157 -	arbytes->fields.seg_type = (entry >> (8+32)) & 0xF; /* TYPE */
 22.1158 -	arbytes->fields.s = (entry >> (12+32)) & 0x1; /* S */
 22.1159 -	if (arbytes->fields.s)
 22.1160 -		arbytes->fields.seg_type |= 1; /* accessed */
 22.1161 -	arbytes->fields.dpl = (entry >> (13+32)) & 0x3; /* DPL */
 22.1162 -	arbytes->fields.p = (entry >> (15+32)) & 0x1; /* P */
 22.1163 -	arbytes->fields.avl = (entry >> (20+32)) & 0x1; /* AVL */
 22.1164 -	arbytes->fields.default_ops_size = (entry >> (22+32)) & 0x1; /* D */
 22.1165 -
 22.1166 -	if (entry & (1ULL << (23+32))) { /* G */
 22.1167 -		arbytes->fields.g = 1;
 22.1168 -		*limit = (*limit << 12) | 0xFFF;
 22.1169 -	}
 22.1170 -
 22.1171 -	return 1;
 22.1172 -}
 22.1173 -
 22.1174 -/*
 22.1175 - * Emulate a protected mode segment load, falling back to clearing it if
 22.1176 - * the descriptor was invalid.
 22.1177 - */
 22.1178 -static void
 22.1179 -load_or_clear_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union vmcs_arbytes *arbytes)
 22.1180 -{
 22.1181 -	if (!load_seg(sel, base, limit, arbytes))
 22.1182 -		load_seg(0, base, limit, arbytes);
 22.1183 -}
 22.1184 -
 22.1185 -static unsigned char rm_irqbase[2];
 22.1186 -
 22.1187 -/*
 22.1188 - * Transition to protected mode
 22.1189 - */
 22.1190 -static void
 22.1191 -protected_mode(struct regs *regs)
 22.1192 -{
 22.1193 -	extern char stack_top[];
 22.1194 -
 22.1195 -	oldctx.rm_irqbase[0] = rm_irqbase[0];
 22.1196 -	oldctx.rm_irqbase[1] = rm_irqbase[1];
 22.1197 -
 22.1198 -	regs->eflags &= ~(EFLAGS_TF|EFLAGS_VM);
 22.1199 -
 22.1200 -	oldctx.eip = regs->eip;
 22.1201 -	oldctx.esp = regs->uesp;
 22.1202 -	oldctx.eflags = regs->eflags;
 22.1203 -
 22.1204 -	/* reload all segment registers */
 22.1205 -	if (!load_seg(regs->cs, &oldctx.cs_base,
 22.1206 -				&oldctx.cs_limit, &oldctx.cs_arbytes))
 22.1207 -		panic("Invalid %%cs=0x%x for protected mode\n", regs->cs);
 22.1208 -	oldctx.cs_sel = regs->cs;
 22.1209 -
 22.1210 -	load_or_clear_seg(oldctx.es_sel, &oldctx.es_base,
 22.1211 -			  &oldctx.es_limit, &oldctx.es_arbytes);
 22.1212 -	load_or_clear_seg(oldctx.ss_sel, &oldctx.ss_base,
 22.1213 -			  &oldctx.ss_limit, &oldctx.ss_arbytes);
 22.1214 -	load_or_clear_seg(oldctx.ds_sel, &oldctx.ds_base,
 22.1215 -			  &oldctx.ds_limit, &oldctx.ds_arbytes);
 22.1216 -	load_or_clear_seg(oldctx.fs_sel, &oldctx.fs_base,
 22.1217 -			  &oldctx.fs_limit, &oldctx.fs_arbytes);
 22.1218 -	load_or_clear_seg(oldctx.gs_sel, &oldctx.gs_base,
 22.1219 -			  &oldctx.gs_limit, &oldctx.gs_arbytes);
 22.1220 -
 22.1221 -	/* initialize jump environment to warp back to protected mode */
 22.1222 -	regs->uss = DATA_SELECTOR;
 22.1223 -	regs->uesp = (unsigned long)stack_top;
 22.1224 -	regs->cs = CODE_SELECTOR;
 22.1225 -	regs->eip = (unsigned long)switch_to_protected_mode;
 22.1226 -
 22.1227 -	/* this should get us into 32-bit mode */
 22.1228 -}
 22.1229 -
 22.1230 -/*
 22.1231 - * Start real-mode emulation
 22.1232 - */
 22.1233 -static void
 22.1234 -real_mode(struct regs *regs)
 22.1235 -{
 22.1236 -	regs->eflags |= EFLAGS_VM | 0x02;
 22.1237 -
 22.1238 -	/*
 22.1239 -	 * When we transition from protected to real-mode and we
 22.1240 -	 * have not reloaded the segment descriptors yet, they are
 22.1241 -	 * interpreted as if they were in protect mode.
 22.1242 -	 * We emulate this behavior by assuming that these memory
 22.1243 -	 * reference are below 1MB and set %ss, %ds, %es accordingly.
 22.1244 -	 */
 22.1245 -	if (regs->uss != 0) {
 22.1246 -		if (regs->uss >= HIGHMEM)
 22.1247 -			panic("%%ss 0x%lx higher than 1MB", regs->uss);
 22.1248 -		regs->uss = address(regs, regs->uss, 0) >> 4;
 22.1249 -	} else {
 22.1250 -		regs->uss = saved_rm_regs.uss;
 22.1251 -	}
 22.1252 -	if (regs->vds != 0) {
 22.1253 -		if (regs->vds >= HIGHMEM)
 22.1254 -			panic("%%ds 0x%lx higher than 1MB", regs->vds);
 22.1255 -		regs->vds = address(regs, regs->vds, 0) >> 4;
 22.1256 -	} else {
 22.1257 -		regs->vds = saved_rm_regs.vds;
 22.1258 -	}
 22.1259 -	if (regs->ves != 0) {
 22.1260 -		if (regs->ves >= HIGHMEM)
 22.1261 -			panic("%%es 0x%lx higher than 1MB", regs->ves);
 22.1262 -		regs->ves = address(regs, regs->ves, 0) >> 4;
 22.1263 -	} else {
 22.1264 -		regs->ves = saved_rm_regs.ves;
 22.1265 -	}
 22.1266 -
 22.1267 -	/* this should get us into 16-bit mode */
 22.1268 -}
 22.1269 -
 22.1270 -/*
 22.1271 - * This is the smarts of the emulator and handles the mode transitions. The
 22.1272 - * emulator handles 4 different modes. 1) VM86_REAL: emulated real-mode,
 22.1273 - * Just handle those instructions that are not supported under VM8086.
 22.1274 - * 2) VM86_REAL_TO_PROTECTED: going from real-mode to protected mode. In
 22.1275 - * this we single step through the instructions until we reload the
 22.1276 - * new %cs (some OSes do a lot of computations before reloading %cs). 2)
 22.1277 - * VM86_PROTECTED_TO_REAL when we are going from protected to real mode. In
 22.1278 - * this case we emulate the instructions by hand. Finally, 4) VM86_PROTECTED
 22.1279 - * when we transitioned to protected mode and we should abandon the
 22.1280 - * emulator. No instructions are emulated when in VM86_PROTECTED mode.
 22.1281 - */
 22.1282 -void
 22.1283 -set_mode(struct regs *regs, enum vm86_mode newmode)
 22.1284 -{
 22.1285 -	switch (newmode) {
 22.1286 -	case VM86_REAL:
 22.1287 -		if (mode == VM86_PROTECTED_TO_REAL ||
 22.1288 -		    mode == VM86_REAL_TO_PROTECTED) {
 22.1289 -			regs->eflags &= ~EFLAGS_TF;
 22.1290 -			real_mode(regs);
 22.1291 -		} else if (mode != VM86_REAL)
 22.1292 -			panic("unexpected real mode transition");
 22.1293 -		break;
 22.1294 -
 22.1295 -	case VM86_REAL_TO_PROTECTED:
 22.1296 -		if (mode == VM86_REAL) {
 22.1297 -			regs->eflags |= EFLAGS_TF;
 22.1298 -			saved_rm_regs.vds = regs->vds;
 22.1299 -			saved_rm_regs.ves = regs->ves;
 22.1300 -			saved_rm_regs.vfs = regs->vfs;
 22.1301 -			saved_rm_regs.vgs = regs->vgs;
 22.1302 -			saved_rm_regs.uss = regs->uss;
 22.1303 -			oldctx.ds_sel = 0;
 22.1304 -			oldctx.es_sel = 0;
 22.1305 -			oldctx.fs_sel = 0;
 22.1306 -			oldctx.gs_sel = 0;
 22.1307 -			oldctx.ss_sel = 0;
 22.1308 -		} else if (mode != VM86_REAL_TO_PROTECTED)
 22.1309 -			panic("unexpected real-to-protected mode transition");
 22.1310 -		break;
 22.1311 -
 22.1312 -	case VM86_PROTECTED_TO_REAL:
 22.1313 -		if (mode != VM86_PROTECTED)
 22.1314 -			panic("unexpected protected-to-real mode transition");
 22.1315 -		break;
 22.1316 -
 22.1317 -	case VM86_PROTECTED:
 22.1318 -		if (mode != VM86_REAL_TO_PROTECTED)
 22.1319 -			panic("unexpected protected mode transition");
 22.1320 -		protected_mode(regs);
 22.1321 -		break;
 22.1322 -	}
 22.1323 -
 22.1324 -	mode = newmode;
 22.1325 -	if (mode != VM86_PROTECTED)
 22.1326 -		TRACE((regs, 0, states[mode]));
 22.1327 -}
 22.1328 -
 22.1329 -static void
 22.1330 -jmpl(struct regs *regs, int prefix)
 22.1331 -{
 22.1332 -	unsigned n = regs->eip;
 22.1333 -	unsigned cs, eip;
 22.1334 -
 22.1335 -	eip = (prefix & DATA32) ? fetch32(regs) : fetch16(regs);
 22.1336 -	cs = fetch16(regs);
 22.1337 -
 22.1338 -	TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
 22.1339 -
 22.1340 -	regs->cs = cs;
 22.1341 -	regs->eip = eip;
 22.1342 -
 22.1343 -	if (mode == VM86_REAL_TO_PROTECTED)		/* jump to protected mode */
 22.1344 -		set_mode(regs, VM86_PROTECTED);
 22.1345 -	else if (mode == VM86_PROTECTED_TO_REAL)	/* jump to real mode */
 22.1346 -		set_mode(regs, VM86_REAL);
 22.1347 -	else
 22.1348 -		panic("jmpl");
 22.1349 -}
 22.1350 -
 22.1351 -static void
 22.1352 -jmpl_indirect(struct regs *regs, int prefix, unsigned modrm)
 22.1353 -{
 22.1354 -	unsigned n = regs->eip;
 22.1355 -	unsigned cs, eip;
 22.1356 -	unsigned addr;
 22.1357 -
 22.1358 -	addr = operand(prefix, regs, modrm);
 22.1359 -
 22.1360 -	eip = (prefix & DATA32) ? read32(addr) : read16(addr);
 22.1361 -	addr += (prefix & DATA32) ? 4 : 2;
 22.1362 -	cs = read16(addr);
 22.1363 -
 22.1364 -	TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
 22.1365 -
 22.1366 -	regs->cs = cs;
 22.1367 -	regs->eip = eip;
 22.1368 -
 22.1369 -	if (mode == VM86_REAL_TO_PROTECTED)		/* jump to protected mode */
 22.1370 -		set_mode(regs, VM86_PROTECTED);
 22.1371 -	else if (mode == VM86_PROTECTED_TO_REAL)	/* jump to real mode */
 22.1372 -		set_mode(regs, VM86_REAL);
 22.1373 -	else
 22.1374 -		panic("jmpl");
 22.1375 -}
 22.1376 -
 22.1377 -static void
 22.1378 -retl(struct regs *regs, int prefix)
 22.1379 -{
 22.1380 -	unsigned cs, eip;
 22.1381 -
 22.1382 -	if (prefix & DATA32) {
 22.1383 -		eip = pop32(regs);
 22.1384 -		cs = MASK16(pop32(regs));
 22.1385 -	} else {
 22.1386 -		eip = pop16(regs);
 22.1387 -		cs = pop16(regs);
 22.1388 -	}
 22.1389 -
 22.1390 -	TRACE((regs, 1, "retl (to 0x%x:0x%x)", cs, eip));
 22.1391 -
 22.1392 -	regs->cs = cs;
 22.1393 -	regs->eip = eip;
 22.1394 -
 22.1395 -	if (mode == VM86_REAL_TO_PROTECTED)		/* jump to protected mode */
 22.1396 -		set_mode(regs, VM86_PROTECTED);
 22.1397 -	else if (mode == VM86_PROTECTED_TO_REAL)	/* jump to real mode */
 22.1398 -		set_mode(regs, VM86_REAL);
 22.1399 -	else
 22.1400 -		panic("retl");
 22.1401 -}
 22.1402 -
 22.1403 -static void
 22.1404 -interrupt(struct regs *regs, int n)
 22.1405 -{
 22.1406 -	TRACE((regs, 0, "external interrupt %d", n));
 22.1407 -	push16(regs, regs->eflags);
 22.1408 -	push16(regs, regs->cs);
 22.1409 -	push16(regs, regs->eip);
 22.1410 -	regs->eflags &= ~EFLAGS_IF;
 22.1411 -	regs->eip = read16(address(regs, 0, n * 4));
 22.1412 -	regs->cs = read16(address(regs, 0, n * 4 + 2));
 22.1413 -}
 22.1414 -
 22.1415 -/*
 22.1416 - * Most port I/O operations are passed unmodified. We do have to be
 22.1417 - * careful and make sure the emulated program isn't remapping the
 22.1418 - * interrupt vectors. The following simple state machine catches
 22.1419 - * these attempts and rewrites them.
 22.1420 - */
 22.1421 -static int
 22.1422 -outbyte(struct regs *regs, unsigned prefix, unsigned opc)
 22.1423 -{
 22.1424 -	static char icw2[2] = { 0 };
 22.1425 -	int al, port;
 22.1426 -
 22.1427 -	switch (opc) {
 22.1428 -	case 0xE6: /* outb port, al */
 22.1429 -		port = fetch8(regs);
 22.1430 -		break;
 22.1431 -	case 0xEE: /* outb (%dx), al */
 22.1432 -		port = MASK16(regs->edx);
 22.1433 -		break;
 22.1434 -	default:
 22.1435 -		return 0;
 22.1436 -	}
 22.1437 -
 22.1438 -	al = regs->eax & 0xFF;
 22.1439 -
 22.1440 -	switch (port) {
 22.1441 -	case PIC_MASTER + PIC_CMD:
 22.1442 -		if (al & (1 << 4)) /* A0=0,D4=1 -> ICW1 */
 22.1443 -			icw2[0] = 1;
 22.1444 -		break;
 22.1445 -	case PIC_MASTER + PIC_IMR:
 22.1446 -		if (icw2[0]) {
 22.1447 -			icw2[0] = 0;
 22.1448 -			printf("Remapping master: ICW2 0x%x -> 0x%x\n",
 22.1449 -				al, NR_EXCEPTION_HANDLER);
 22.1450 -			rm_irqbase[0] = al;
 22.1451 -			al = NR_EXCEPTION_HANDLER;
 22.1452 -		}
 22.1453 -		break;
 22.1454 -
 22.1455 -	case PIC_SLAVE  + PIC_CMD:
 22.1456 -		if (al & (1 << 4)) /* A0=0,D4=1 -> ICW1 */
 22.1457 -			icw2[1] = 1;
 22.1458 -		break;
 22.1459 -	case PIC_SLAVE  + PIC_IMR:
 22.1460 -		if (icw2[1]) {
 22.1461 -			icw2[1] = 0;
 22.1462 -			printf("Remapping slave: ICW2 0x%x -> 0x%x\n",
 22.1463 -				al, NR_EXCEPTION_HANDLER+8);
 22.1464 -			rm_irqbase[1] = al;
 22.1465 -			al = NR_EXCEPTION_HANDLER+8;
 22.1466 -		}
 22.1467 -		break;
 22.1468 -	}
 22.1469 -
 22.1470 -	outb(port, al);
 22.1471 -	return 1;
 22.1472 -}
 22.1473 -
 22.1474 -static int
 22.1475 -inbyte(struct regs *regs, unsigned prefix, unsigned opc)
 22.1476 -{
 22.1477 -	int port;
 22.1478 -
 22.1479 -	switch (opc) {
 22.1480 -	case 0xE4: /* inb al, port */
 22.1481 -		port = fetch8(regs);
 22.1482 -		break;
 22.1483 -	case 0xEC: /* inb al, (%dx) */
 22.1484 -		port = MASK16(regs->edx);
 22.1485 -		break;
 22.1486 -	default:
 22.1487 -		return 0;
 22.1488 -	}
 22.1489 -
 22.1490 -	regs->eax = (regs->eax & ~0xFF) | inb(port);
 22.1491 -	return 1;
 22.1492 -}
 22.1493 -
 22.1494 -static void
 22.1495 -pushrm(struct regs *regs, int prefix, unsigned modrm)
 22.1496 -{
 22.1497 -	unsigned n = regs->eip;
 22.1498 -	unsigned addr;
 22.1499 -	unsigned data;
 22.1500 -
 22.1501 -	addr = operand(prefix, regs, modrm);
 22.1502 -
 22.1503 -	if (prefix & DATA32) {
 22.1504 -		data = read32(addr);
 22.1505 -		push32(regs, data);
 22.1506 -	} else {
 22.1507 -		data = read16(addr);
 22.1508 -		push16(regs, data);
 22.1509 -	}
 22.1510 -
 22.1511 -	TRACE((regs, (regs->eip - n) + 1, "push *0x%x", addr));
 22.1512 -}
 22.1513 -
 22.1514 -enum { OPC_INVALID, OPC_EMULATED };
 22.1515 -
 22.1516 -#define rdmsr(msr,val1,val2)				\
 22.1517 -	__asm__ __volatile__(				\
 22.1518 -		"rdmsr"					\
 22.1519 -		: "=a" (val1), "=d" (val2)		\
 22.1520 -		: "c" (msr))
 22.1521 -
 22.1522 -#define wrmsr(msr,val1,val2)				\
 22.1523 -	__asm__ __volatile__(				\
 22.1524 -		"wrmsr"					\
 22.1525 -		: /* no outputs */			\
 22.1526 -		: "c" (msr), "a" (val1), "d" (val2))
 22.1527 -
 22.1528 -/*
 22.1529 - * Emulate a single instruction, including all its prefixes. We only implement
 22.1530 - * a small subset of the opcodes, and not all opcodes are implemented for each
 22.1531 - * of the four modes we can operate in.
 22.1532 - */
 22.1533 -static int
 22.1534 -opcode(struct regs *regs)
 22.1535 -{
 22.1536 -	unsigned eip = regs->eip;
 22.1537 -	unsigned opc, modrm, disp;
 22.1538 -	unsigned prefix = 0;
 22.1539 -
 22.1540 -	if (mode == VM86_PROTECTED_TO_REAL &&
 22.1541 -		oldctx.cs_arbytes.fields.default_ops_size) {
 22.1542 -		prefix |= DATA32;
 22.1543 -		prefix |= ADDR32;
 22.1544 -	}
 22.1545 -
 22.1546 -	for (;;) {
 22.1547 -		switch ((opc = fetch8(regs))) {
 22.1548 -
 22.1549 -		case 0x00: /* addr32 add r8, r/m8 */
 22.1550 -		case 0x01: /* addr32 add r16, r/m16 */
 22.1551 -		case 0x03: /* addr32 add r/m16, r16 */
 22.1552 -			if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
 22.1553 -				goto invalid;
 22.1554 -			if ((prefix & ADDR32) == 0)
 22.1555 -				goto invalid;
 22.1556 -			if (!add(regs, prefix, opc))
 22.1557 -				goto invalid;
 22.1558 -			return OPC_EMULATED;
 22.1559 -			
 22.1560 -		case 0x07: /* pop %es */
 22.1561 -			regs->ves = (prefix & DATA32) ?
 22.1562 -				pop32(regs) : pop16(regs);
 22.1563 -			TRACE((regs, regs->eip - eip, "pop %%es"));
 22.1564 -			if (mode == VM86_REAL_TO_PROTECTED) {
 22.1565 -				saved_rm_regs.ves = 0;
 22.1566 -				oldctx.es_sel = regs->ves;
 22.1567 -			}
 22.1568 -			return OPC_EMULATED;
 22.1569 -
 22.1570 -		case 0x0F: /* two byte opcode */
 22.1571 -			if (mode == VM86_PROTECTED)
 22.1572 -				goto invalid;
 22.1573 -			switch ((opc = fetch8(regs))) {
 22.1574 -			case 0x01:
 22.1575 -				switch (((modrm = fetch8(regs)) >> 3) & 7) {
 22.1576 -				case 0: /* sgdt */
 22.1577 -				case 1: /* sidt */
 22.1578 -					goto invalid;
 22.1579 -				case 2: /* lgdt */
 22.1580 -					if (!lgdt(regs, prefix, modrm))
 22.1581 -						goto invalid;
 22.1582 -					return OPC_EMULATED;
 22.1583 -				case 3: /* lidt */
 22.1584 -					if (!lidt(regs, prefix, modrm))
 22.1585 -						goto invalid;
 22.1586 -					return OPC_EMULATED;
 22.1587 -				case 4: /* smsw */
 22.1588 -					goto invalid;
 22.1589 -				case 5:
 22.1590 -					goto invalid;
 22.1591 -				case 6: /* lmsw */
 22.1592 -					if (!lmsw(regs, prefix, modrm))
 22.1593 -						goto invalid;
 22.1594 -					return OPC_EMULATED;
 22.1595 -				case 7: /* invlpg */
 22.1596 -					goto invalid;
 22.1597 -				}
 22.1598 -				break;
 22.1599 -			case 0x06: /* clts */
 22.1600 -				oldctx.cr0 &= ~CR0_TS;
 22.1601 -				return OPC_EMULATED;
 22.1602 -			case 0x09: /* wbinvd */
 22.1603 -				return OPC_EMULATED;
 22.1604 -			case 0x20: /* mov Rd, Cd (1h) */
 22.1605 -			case 0x22:
 22.1606 -				if (!movcr(regs, prefix, opc))
 22.1607 -					goto invalid;
 22.1608 -				return OPC_EMULATED;
 22.1609 -			case 0x30: /* WRMSR */
 22.1610 -				wrmsr(regs->ecx, regs->eax, regs->edx);
 22.1611 -				return OPC_EMULATED;
 22.1612 -			case 0x32: /* RDMSR */
 22.1613 -				rdmsr(regs->ecx, regs->eax, regs->edx);
 22.1614 -				return OPC_EMULATED;
 22.1615 -			default:
 22.1616 -				goto invalid;
 22.1617 -			}
 22.1618 -			goto invalid;
 22.1619 -
 22.1620 -		case 0x1F: /* pop %ds */
 22.1621 -			regs->vds = (prefix & DATA32) ?
 22.1622 -				pop32(regs) : pop16(regs);
 22.1623 -			TRACE((regs, regs->eip - eip, "pop %%ds"));
 22.1624 -			if (mode == VM86_REAL_TO_PROTECTED) {
 22.1625 -				saved_rm_regs.vds = 0;
 22.1626 -				oldctx.ds_sel = regs->vds;
 22.1627 -			}
 22.1628 -			return OPC_EMULATED;
 22.1629 -
 22.1630 -		case 0x26:
 22.1631 -			TRACE((regs, regs->eip - eip, "%%es:"));
 22.1632 -			prefix |= SEG_ES;
 22.1633 -			continue;
 22.1634 -
 22.1635 -		case 0x2E:
 22.1636 -			TRACE((regs, regs->eip - eip, "%%cs:"));
 22.1637 -			prefix |= SEG_CS;
 22.1638 -			continue;
 22.1639 -
 22.1640 -		case 0x36:
 22.1641 -			TRACE((regs, regs->eip - eip, "%%ss:"));
 22.1642 -			prefix |= SEG_SS;
 22.1643 -			continue;
 22.1644 -
 22.1645 -		case 0x39: /* addr32 cmp r16, r/m16 */
 22.1646 -		case 0x3B: /* addr32 cmp r/m16, r16 */
 22.1647 -			if (mode == VM86_PROTECTED_TO_REAL || !(prefix & ADDR32))
 22.1648 -				goto invalid;
 22.1649 -			if (!cmp(regs, prefix, opc))
 22.1650 -				goto invalid;
 22.1651 -			return OPC_EMULATED;
 22.1652 -
 22.1653 -		case 0x3E:
 22.1654 -			TRACE((regs, regs->eip - eip, "%%ds:"));
 22.1655 -			prefix |= SEG_DS;
 22.1656 -			continue;
 22.1657 -
 22.1658 -		case 0x64:
 22.1659 -			TRACE((regs, regs->eip - eip, "%%fs:"));
 22.1660 -			prefix |= SEG_FS;
 22.1661 -			continue;
 22.1662 -
 22.1663 -		case 0x65:
 22.1664 -			TRACE((regs, regs->eip - eip, "%%gs:"));
 22.1665 -			prefix |= SEG_GS;
 22.1666 -			continue;
 22.1667 -
 22.1668 -		case 0x66:
 22.1669 -			if (mode == VM86_PROTECTED_TO_REAL &&
 22.1670 -				oldctx.cs_arbytes.fields.default_ops_size) {
 22.1671 -				TRACE((regs, regs->eip - eip, "data16"));
 22.1672 -				prefix &= ~DATA32;
 22.1673 -			} else {
 22.1674 -				TRACE((regs, regs->eip - eip, "data32"));
 22.1675 -				prefix |= DATA32;
 22.1676 -			}
 22.1677 -			continue;
 22.1678 -
 22.1679 -		case 0x67:
 22.1680 -			if (mode == VM86_PROTECTED_TO_REAL &&
 22.1681 -				oldctx.cs_arbytes.fields.default_ops_size) {
 22.1682 -				TRACE((regs, regs->eip - eip, "addr16"));
 22.1683 -				prefix &= ~ADDR32;
 22.1684 -			} else {
 22.1685 -				TRACE((regs, regs->eip - eip, "addr32"));
 22.1686 -				prefix |= ADDR32;
 22.1687 -			}
 22.1688 -			continue;
 22.1689 -
 22.1690 -		case 0x88: /* addr32 mov r8, r/m8 */
 22.1691 -		case 0x8A: /* addr32 mov r/m8, r8 */
 22.1692 -			if (mode == VM86_PROTECTED_TO_REAL || !(prefix & ADDR32))
 22.1693 -				goto invalid;
 22.1694 -			if (!movr(regs, prefix, opc))
 22.1695 -				goto invalid;
 22.1696 -			return OPC_EMULATED;
 22.1697 -
 22.1698 -		case 0x89: /* mov r16, r/m16 */
 22.1699 -		case 0x8B: /* mov r/m16, r16 */
 22.1700 -			if (mode != VM86_PROTECTED_TO_REAL && !(prefix & ADDR32))
 22.1701 -				goto invalid;
 22.1702 -			if (!movr(regs, prefix, opc))
 22.1703 -				goto invalid;
 22.1704 -			return OPC_EMULATED;
 22.1705 -
 22.1706 -		case 0x8E: /* mov r16, sreg */
 22.1707 -			if (!mov_to_seg(regs, prefix, opc))
 22.1708 -				goto invalid;
 22.1709 -			return OPC_EMULATED;
 22.1710 -
 22.1711 -		case 0x8F: /* addr32 pop r/m16 */
 22.1712 -			if (!(prefix & ADDR32))
 22.1713 -				goto invalid;
 22.1714 -			if (!pop(regs, prefix, opc))
 22.1715 -				goto invalid;
 22.1716 -			return OPC_EMULATED;
 22.1717 -
 22.1718 -		case 0x90: /* nop */
 22.1719 -			TRACE((regs, regs->eip - eip, "nop"));
 22.1720 -			return OPC_EMULATED;
 22.1721 -
 22.1722 -		case 0x9C: /* pushf */
 22.1723 -			TRACE((regs, regs->eip - eip, "pushf"));
 22.1724 -			if (prefix & DATA32)
 22.1725 -				push32(regs, regs->eflags & ~EFLAGS_VM);
 22.1726 -			else
 22.1727 -				push16(regs, regs->eflags & ~EFLAGS_VM);
 22.1728 -			return OPC_EMULATED;
 22.1729 -
 22.1730 -		case 0x9D: /* popf */
 22.1731 -			TRACE((regs, regs->eip - eip, "popf"));
 22.1732 -			if (prefix & DATA32)
 22.1733 -				regs->eflags = pop32(regs);
 22.1734 -			else
 22.1735 -				regs->eflags = (regs->eflags & 0xFFFF0000L) |
 22.1736 -								pop16(regs);
 22.1737 -			regs->eflags |= EFLAGS_VM;
 22.1738 -			return OPC_EMULATED;
 22.1739 -
 22.1740 -		case 0xA1: /* mov ax, r/m16 */
 22.1741 -		{
 22.1742 -			int addr, data;
 22.1743 -			int seg = segment(prefix, regs, regs->vds);
 22.1744 -			int offset = prefix & ADDR32 ? fetch32(regs) : fetch16(regs);
 22.1745 -
 22.1746 -			if (prefix & DATA32) {
 22.1747 -				addr = address(regs, seg, offset);
 22.1748 -				data = read32(addr);
 22.1749 -				setreg32(regs, 0, data);
 22.1750 -			} else {
 22.1751 -				addr = address(regs, seg, offset);
 22.1752 -				data = read16(addr);
 22.1753 -				setreg16(regs, 0, data);
 22.1754 -			}
 22.1755 -			TRACE((regs, regs->eip - eip, "mov *0x%x, %%ax", addr));
 22.1756 -			return OPC_EMULATED;
 22.1757 -		}
 22.1758 -
 22.1759 -		case 0xA4: /* movsb */
 22.1760 -		case 0xA5: /* movsw */
 22.1761 -			if ((prefix & ADDR32) == 0)
 22.1762 -				goto invalid;
 22.1763 -			if (!movs(regs, prefix, opc))
 22.1764 -				goto invalid;
 22.1765 -			return OPC_EMULATED;
 22.1766 -
 22.1767 -		case 0xAD: /* lodsw */
 22.1768 -			if ((prefix & ADDR32) == 0)
 22.1769 -				goto invalid;
 22.1770 -			if (!lods(regs, prefix, opc))
 22.1771 -				goto invalid;
 22.1772 -			return OPC_EMULATED;
 22.1773 -			
 22.1774 -		case 0xBB: /* mov bx, imm16 */
 22.1775 -		{
 22.1776 -			int data;
 22.1777 -			if (prefix & DATA32) {
 22.1778 -				data = fetch32(regs);
 22.1779 -				setreg32(regs, 3, data);
 22.1780 -			} else {
 22.1781 -				data = fetch16(regs);
 22.1782 -				setreg16(regs, 3, data);
 22.1783 -			}
 22.1784 -			TRACE((regs, regs->eip - eip, "mov $0x%x, %%bx", data));
 22.1785 -			return OPC_EMULATED;
 22.1786 -		}
 22.1787 -
 22.1788 -		case 0xC6: /* addr32 movb $imm, r/m8 */
 22.1789 -			if (!(prefix & ADDR32))
 22.1790 -				goto invalid;
 22.1791 -			if (!movr(regs, prefix, opc))
 22.1792 -				goto invalid;
 22.1793 -			return OPC_EMULATED;
 22.1794 -
 22.1795 -		case 0xCB: /* retl */
 22.1796 -			if (mode == VM86_REAL_TO_PROTECTED ||
 22.1797 -				mode == VM86_PROTECTED_TO_REAL) {
 22.1798 -				retl(regs, prefix);
 22.1799 -				return OPC_INVALID;
 22.1800 -			}
 22.1801 -			goto invalid;
 22.1802 -
 22.1803 -		case 0xCD: /* int $n */
 22.1804 -			TRACE((regs, regs->eip - eip, "int"));
 22.1805 -			interrupt(regs, fetch8(regs));
 22.1806 -			return OPC_EMULATED;
 22.1807 -
 22.1808 -		case 0xCF: /* iret */
 22.1809 -			if (prefix & DATA32) {
 22.1810 -				TRACE((regs, regs->eip - eip, "data32 iretd"));
 22.1811 -				regs->eip = pop32(regs);
 22.1812 -				regs->cs = pop32(regs);
 22.1813 -				regs->eflags = pop32(regs);
 22.1814 -			} else {
 22.1815 -				TRACE((regs, regs->eip - eip, "iret"));
 22.1816 -				regs->eip = pop16(regs);
 22.1817 -				regs->cs = pop16(regs);
 22.1818 -				regs->eflags = (regs->eflags & 0xFFFF0000L) |
 22.1819 -								pop16(regs);
 22.1820 -			}
 22.1821 -			return OPC_EMULATED;
 22.1822 -
 22.1823 -		case 0xE4: /* inb al, port */
 22.1824 -			if (!inbyte(regs, prefix, opc))
 22.1825 -				goto invalid;
 22.1826 -			return OPC_EMULATED;
 22.1827 -
 22.1828 -		case 0xE6: /* outb port, al */
 22.1829 -			if (!outbyte(regs, prefix, opc))
 22.1830 -				goto invalid;
 22.1831 -			return OPC_EMULATED;
 22.1832 -
 22.1833 -		case 0xEA: /* jmpl */
 22.1834 -			if (mode == VM86_REAL_TO_PROTECTED ||
 22.1835 -				mode == VM86_PROTECTED_TO_REAL) {
 22.1836 -				jmpl(regs, prefix);
 22.1837 -				return OPC_INVALID;
 22.1838 -			}
 22.1839 -			goto invalid;
 22.1840 -
 22.1841 -		case 0xFF:
 22.1842 -		{
 22.1843 -			unsigned modrm = fetch8(regs);
 22.1844 -			switch((modrm >> 3) & 7) {
 22.1845 -			case 5: /* jmpl (indirect) */
 22.1846 -				if (mode == VM86_REAL_TO_PROTECTED ||
 22.1847 -					mode == VM86_PROTECTED_TO_REAL) {
 22.1848 -					jmpl_indirect(regs, prefix, modrm);
 22.1849 -					return OPC_INVALID;
 22.1850 -				}
 22.1851 -				goto invalid;
 22.1852 -
 22.1853 -			case 6: /* push r/m16 */
 22.1854 -				pushrm(regs, prefix, modrm);
 22.1855 -				return OPC_EMULATED;
 22.1856 -
 22.1857 -			default:
 22.1858 -				goto invalid;
 22.1859 -			}
 22.1860 -		}
 22.1861 -
 22.1862 -		case 0xEB: /* short jump */
 22.1863 -			if (mode == VM86_REAL_TO_PROTECTED ||
 22.1864 -				mode == VM86_PROTECTED_TO_REAL) {
 22.1865 -				disp = (char) fetch8(regs);
 22.1866 -				TRACE((regs, 2, "jmp 0x%x", regs->eip + disp));
 22.1867 -				regs->eip += disp;
 22.1868 -				return OPC_EMULATED;
 22.1869 -			}
 22.1870 -			goto invalid;
 22.1871 -
 22.1872 -		case 0xEC: /* inb al, (%dx) */
 22.1873 -			if (!inbyte(regs, prefix, opc))
 22.1874 -				goto invalid;
 22.1875 -			return OPC_EMULATED;
 22.1876 -
 22.1877 -		case 0xEE: /* outb (%dx), al */
 22.1878 -			if (!outbyte(regs, prefix, opc))
 22.1879 -				goto invalid;
 22.1880 -			return OPC_EMULATED;
 22.1881 -
 22.1882 -		case 0xF0: /* lock */
 22.1883 -			TRACE((regs, regs->eip - eip, "lock"));
 22.1884 -			continue;
 22.1885 -
 22.1886 -		case 0xF4: /* hlt */
 22.1887 -			TRACE((regs, regs->eip - eip, "hlt"));
 22.1888 -			/* Do something power-saving here! */
 22.1889 -			return OPC_EMULATED;
 22.1890 -
 22.1891 -		case 0xF3: /* rep/repe/repz */
 22.1892 -			TRACE((regs, regs->eip - eip, "rep"));
 22.1893 -			prefix |= REP;
 22.1894 -			continue;
 22.1895 -
 22.1896 -		case 0xF6: /* addr32 testb $imm, r/m8 */
 22.1897 -			if (!(prefix & ADDR32))
 22.1898 -				goto invalid;
 22.1899 -			if (!test(regs, prefix, opc))
 22.1900 -				goto invalid;
 22.1901 -			return OPC_EMULATED;
 22.1902 -
 22.1903 -		case 0xFA: /* cli */
 22.1904 -			TRACE((regs, regs->eip - eip, "cli"));
 22.1905 -			regs->eflags &= ~EFLAGS_IF;
 22.1906 -			return OPC_EMULATED;
 22.1907 -
 22.1908 -		case 0xFB: /* sti */
 22.1909 -			TRACE((regs, regs->eip - eip, "sti"));
 22.1910 -			regs->eflags |= EFLAGS_IF;
 22.1911 -			return OPC_EMULATED;
 22.1912 -
 22.1913 -		default:
 22.1914 -			goto invalid;
 22.1915 -		}
 22.1916 -	}
 22.1917 -
 22.1918 -invalid:
 22.1919 -	regs->eip = eip;
 22.1920 -	TRACE((regs, regs->eip - eip, "opc 0x%x", opc));
 22.1921 -	return OPC_INVALID;
 22.1922 -}
 22.1923 -
 22.1924 -void
 22.1925 -emulate(struct regs *regs)
 22.1926 -{
 22.1927 -	unsigned flteip;
 22.1928 -	int nemul = 0;
 22.1929 -	unsigned ip;
 22.1930 -
 22.1931 -	/* emulate as many instructions as possible */
 22.1932 -	while (opcode(regs) != OPC_INVALID)
 22.1933 -		nemul++;
 22.1934 -
 22.1935 -	/* detect the case where we are not making progress */
 22.1936 -	if (nemul == 0 && prev_eip == regs->eip) {
 22.1937 -		flteip = address(regs, MASK16(regs->cs), regs->eip);
 22.1938 -
 22.1939 -		printf("Undecoded sequence: \n");
 22.1940 -		for (ip=flteip; ip < flteip+16; ip++)
 22.1941 -			printf("0x%02x ", read8(ip));
 22.1942 -		printf("\n");
 22.1943 -
 22.1944 -		panic("Unknown opcode at %04x:%04x=0x%x",
 22.1945 -			MASK16(regs->cs), regs->eip, flteip);
 22.1946 -	} else
 22.1947 -		prev_eip = regs->eip;
 22.1948 -}
 22.1949 -
 22.1950 -void
 22.1951 -trap(int trapno, int errno, struct regs *regs)
 22.1952 -{
 22.1953 -	/* emulate device interrupts */
 22.1954 -	if (trapno >= NR_EXCEPTION_HANDLER) {
 22.1955 -		int irq = trapno - NR_EXCEPTION_HANDLER;
 22.1956 -		if (irq < 8) 
 22.1957 -			interrupt(regs, irq + 8);
 22.1958 -		else
 22.1959 -			interrupt(regs, 0x70 + (irq - 8));
 22.1960 -		return;
 22.1961 -	}
 22.1962 -
 22.1963 -	switch (trapno) {
 22.1964 -	case 1: /* Debug */
 22.1965 -		if (regs->eflags & EFLAGS_VM) {
 22.1966 -			/* emulate any 8086 instructions  */
 22.1967 -			if (mode == VM86_REAL)
 22.1968 -				return;
 22.1969 -			if (mode != VM86_REAL_TO_PROTECTED)
 22.1970 -				panic("not in real-to-protected mode");
 22.1971 -			emulate(regs);
 22.1972 -			return;
 22.1973 -		}
 22.1974 -		goto invalid;
 22.1975 -
 22.1976 -	case 13: /* GPF */
 22.1977 -		if (regs->eflags & EFLAGS_VM) {
 22.1978 -			/* emulate any 8086 instructions  */
 22.1979 -			if (mode == VM86_PROTECTED)
 22.1980 -				panic("unexpected protected mode");
 22.1981 -			emulate(regs);
 22.1982 -			return;
 22.1983 -		}
 22.1984 -		goto invalid;
 22.1985 -
 22.1986 -	default:
 22.1987 -	invalid:
 22.1988 -		printf("Trap (0x%x) while in %s mode\n",
 22.1989 -			trapno, regs->eflags & EFLAGS_VM ? "real" : "protected");
 22.1990 -		if (trapno == 14)
 22.1991 -			printf("Page fault address 0x%x\n", get_cr2());
 22.1992 -		dump_regs(regs);
 22.1993 -		halt();
 22.1994 -	}
 22.1995 -}
    23.1 --- a/tools/firmware/vmxassist/vm86.h	Thu Feb 07 09:23:26 2008 -0700
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,64 +0,0 @@
    23.4 -/*
    23.5 - * vm86.h: vm86 emulator definitions.
    23.6 - *
    23.7 - * Leendert van Doorn, leendert@watson.ibm.com
    23.8 - * Copyright (c) 2005, International Business Machines Corporation.
    23.9 - *
   23.10 - * This program is free software; you can redistribute it and/or modify it
   23.11 - * under the terms and conditions of the GNU General Public License,
   23.12 - * version 2, as published by the Free Software Foundation.
   23.13 - *
   23.14 - * This program is distributed in the hope it will be useful, but WITHOUT
   23.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   23.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   23.17 - * more details.
   23.18 - *
   23.19 - * You should have received a copy of the GNU General Public License along with
   23.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   23.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   23.22 - */
   23.23 -#ifndef __VM86_H__
   23.24 -#define __VM86_H__
   23.25 -
   23.26 -#ifndef __ASSEMBLY__
   23.27 -#include <stdint.h>
   23.28 -#endif
   23.29 -
   23.30 -#include <xen/hvm/vmx_assist.h>
   23.31 -
   23.32 -#ifndef __ASSEMBLY__
   23.33 -
   23.34 -struct regs {
   23.35 -	unsigned	edi, esi, ebp, esp, ebx, edx, ecx, eax;
   23.36 -	unsigned	trapno, errno;
   23.37 -	unsigned	eip, cs, eflags, uesp, uss;
   23.38 -	unsigned	ves, vds, vfs, vgs;
   23.39 -};
   23.40 -
   23.41 -enum vm86_mode {
   23.42 -	VM86_REAL = 0,
   23.43 -	VM86_REAL_TO_PROTECTED,
   23.44 -	VM86_PROTECTED_TO_REAL,
   23.45 -	VM86_PROTECTED
   23.46 -};
   23.47 -
   23.48 -#ifdef DEBUG
   23.49 -#define TRACE(a)        trace a
   23.50 -#else
   23.51 -#define TRACE(a)
   23.52 -#endif
   23.53 -
   23.54 -extern enum vm86_mode prevmode, mode;
   23.55 -extern struct vmx_assist_context oldctx;
   23.56 -
   23.57 -extern void emulate(struct regs *);
   23.58 -extern void dump_regs(struct regs *);
   23.59 -extern void trace(struct regs *, int, char *, ...);
   23.60 -
   23.61 -extern void set_mode(struct regs *, enum vm86_mode);
   23.62 -extern void switch_to_real_mode(void);
   23.63 -extern void switch_to_protected_mode(void);
   23.64 -
   23.65 -#endif /* __ASSEMBLY__ */
   23.66 -
   23.67 -#endif /* __VM86_H__ */
    24.1 --- a/tools/firmware/vmxassist/vmxassist.ld	Thu Feb 07 09:23:26 2008 -0700
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,32 +0,0 @@
    24.4 -/*
    24.5 - * vmxassist.ld
    24.6 - */
    24.7 -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
    24.8 -ENTRY(_start)
    24.9 -
   24.10 -SECTIONS
   24.11 -{
   24.12 -	_btext = .;
   24.13 -	.text TEXTADDR : 
   24.14 -	{
   24.15 -		*(.text)
   24.16 -		*(.rodata)
   24.17 -		*(.rodata.*)
   24.18 -	}
   24.19 -	_etext = .;
   24.20 -
   24.21 -	_bdata = .;
   24.22 -	.data :
   24.23 -	{
   24.24 -		*(.data)
   24.25 -	}
   24.26 -	_edata = .;
   24.27 -
   24.28 -	_bbss = .;
   24.29 -	.bss :
   24.30 -	{
   24.31 -		*(.bss)
   24.32 -	}
   24.33 -	_ebss = .;
   24.34 -}
   24.35 -
    25.1 --- a/tools/ioemu/audio/audio.c	Thu Feb 07 09:23:26 2008 -0700
    25.2 +++ b/tools/ioemu/audio/audio.c	Thu Feb 07 11:08:49 2008 -0700
    25.3 @@ -707,8 +707,8 @@ static void audio_detach_capture (HWVoic
    25.4              sw->rate = NULL;
    25.5          }
    25.6  
    25.7 -        LIST_REMOVE (sw, entries);
    25.8 -        LIST_REMOVE (sc, entries);
    25.9 +        QEMU_LIST_REMOVE (sw, entries);
   25.10 +        QEMU_LIST_REMOVE (sc, entries);
   25.11          qemu_free (sc);
   25.12          if (was_active) {
   25.13              /* We have removed soft voice from the capture:
   25.14 @@ -751,8 +751,8 @@ static int audio_attach_capture (AudioSt
   25.15              qemu_free (sw);
   25.16              return -1;
   25.17          }
   25.18 -        LIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
   25.19 -        LIST_INSERT_HEAD (&hw->cap_head, sc, entries);
   25.20 +        QEMU_LIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
   25.21 +        QEMU_LIST_INSERT_HEAD (&hw->cap_head, sc, entries);
   25.22  #ifdef DEBUG_CAPTURE
   25.23          asprintf (&sw->name, "for %p %d,%d,%d",
   25.24                    hw, sw->info.freq, sw->info.bits, sw->info.nchannels);
   25.25 @@ -1620,12 +1620,12 @@ void AUD_register_card (AudioState *s, c
   25.26      card->audio = s;
   25.27      card->name = qemu_strdup (name);
   25.28      memset (&card->entries, 0, sizeof (card->entries));
   25.29 -    LIST_INSERT_HEAD (&s->card_head, card, entries);
   25.30 +    QEMU_LIST_INSERT_HEAD (&s->card_head, card, entries);
   25.31  }
   25.32  
   25.33  void AUD_remove_card (QEMUSoundCard *card)
   25.34  {
   25.35 -    LIST_REMOVE (card, entries);
   25.36 +    QEMU_LIST_REMOVE (card, entries);
   25.37      card->audio = NULL;
   25.38      qemu_free (card->name);
   25.39  }
   25.40 @@ -1637,9 +1637,9 @@ AudioState *AUD_init (void)
   25.41      const char *drvname;
   25.42      AudioState *s = &glob_audio_state;
   25.43  
   25.44 -    LIST_INIT (&s->hw_head_out);
   25.45 -    LIST_INIT (&s->hw_head_in);
   25.46 -    LIST_INIT (&s->cap_head);
   25.47 +    QEMU_LIST_INIT (&s->hw_head_out);
   25.48 +    QEMU_LIST_INIT (&s->hw_head_in);
   25.49 +    QEMU_LIST_INIT (&s->cap_head);
   25.50      atexit (audio_atexit);
   25.51  
   25.52      s->ts = qemu_new_timer (vm_clock, audio_timer, s);
   25.53 @@ -1731,7 +1731,7 @@ AudioState *AUD_init (void)
   25.54          return NULL;
   25.55      }
   25.56  
   25.57 -    LIST_INIT (&s->card_head);
   25.58 +    QEMU_LIST_INIT (&s->card_head);
   25.59      register_savevm ("audio", 0, 1, audio_save, audio_load, s);
   25.60      qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
   25.61      return s;
   25.62 @@ -1769,7 +1769,7 @@ CaptureVoiceOut *AUD_add_capture (
   25.63  
   25.64      cap = audio_pcm_capture_find_specific (s, as);
   25.65      if (cap) {
   25.66 -        LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
   25.67 +        QEMU_LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
   25.68          return cap;
   25.69      }
   25.70      else {
   25.71 @@ -1784,8 +1784,8 @@ CaptureVoiceOut *AUD_add_capture (
   25.72          }
   25.73  
   25.74          hw = &cap->hw;
   25.75 -        LIST_INIT (&hw->sw_head);
   25.76 -        LIST_INIT (&cap->cb_head);
   25.77 +        QEMU_LIST_INIT (&hw->sw_head);
   25.78 +        QEMU_LIST_INIT (&cap->cb_head);
   25.79  
   25.80          /* XXX find a more elegant way */
   25.81          hw->samples = 4096 * 4;
   25.82 @@ -1813,8 +1813,8 @@ CaptureVoiceOut *AUD_add_capture (
   25.83              [hw->info.swap_endianness]
   25.84              [hw->info.bits == 16];
   25.85  
   25.86 -        LIST_INSERT_HEAD (&s->cap_head, cap, entries);
   25.87 -        LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
   25.88 +        QEMU_LIST_INSERT_HEAD (&s->cap_head, cap, entries);
   25.89 +        QEMU_LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
   25.90  
   25.91          hw = NULL;
   25.92          while ((hw = audio_pcm_hw_find_any_out (s, hw))) {
   25.93 @@ -1840,7 +1840,7 @@ void AUD_del_capture (CaptureVoiceOut *c
   25.94      for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
   25.95          if (cb->opaque == cb_opaque) {
   25.96              cb->ops.destroy (cb_opaque);
   25.97 -            LIST_REMOVE (cb, entries);
   25.98 +            QEMU_LIST_REMOVE (cb, entries);
   25.99              qemu_free (cb);
  25.100  
  25.101              if (!cap->cb_head.lh_first) {
  25.102 @@ -1857,12 +1857,12 @@ void AUD_del_capture (CaptureVoiceOut *c
  25.103                          st_rate_stop (sw->rate);
  25.104                          sw->rate = NULL;
  25.105                      }
  25.106 -                    LIST_REMOVE (sw, entries);
  25.107 -                    LIST_REMOVE (sc, entries);
  25.108 +                    QEMU_LIST_REMOVE (sw, entries);
  25.109 +                    QEMU_LIST_REMOVE (sc, entries);
  25.110                      qemu_free (sc);
  25.111                      sw = sw1;
  25.112                  }
  25.113 -                LIST_REMOVE (cap, entries);
  25.114 +                QEMU_LIST_REMOVE (cap, entries);
  25.115                  qemu_free (cap);
  25.116              }
  25.117              return;
    26.1 --- a/tools/ioemu/audio/audio.h	Thu Feb 07 09:23:26 2008 -0700
    26.2 +++ b/tools/ioemu/audio/audio.h	Thu Feb 07 11:08:49 2008 -0700
    26.3 @@ -68,7 +68,7 @@ struct capture_ops {
    26.4  typedef struct CaptureState {
    26.5      void *opaque;
    26.6      struct capture_ops ops;
    26.7 -    LIST_ENTRY (CaptureState) entries;
    26.8 +    QEMU_LIST_ENTRY (CaptureState) entries;
    26.9  } CaptureState;
   26.10  
   26.11  typedef struct AudioState AudioState;
   26.12 @@ -79,7 +79,7 @@ typedef struct SWVoiceIn SWVoiceIn;
   26.13  typedef struct QEMUSoundCard {
   26.14      AudioState *audio;
   26.15      char *name;
   26.16 -    LIST_ENTRY (QEMUSoundCard) entries;
   26.17 +    QEMU_LIST_ENTRY (QEMUSoundCard) entries;
   26.18  } QEMUSoundCard;
   26.19  
   26.20  typedef struct QEMUAudioTimeStamp {
    27.1 --- a/tools/ioemu/audio/audio_int.h	Thu Feb 07 09:23:26 2008 -0700
    27.2 +++ b/tools/ioemu/audio/audio_int.h	Thu Feb 07 11:08:49 2008 -0700
    27.3 @@ -79,10 +79,10 @@ typedef struct HWVoiceOut {
    27.4      st_sample_t *mix_buf;
    27.5  
    27.6      int samples;
    27.7 -    LIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
    27.8 -    LIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
    27.9 +    QEMU_LIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
   27.10 +    QEMU_LIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
   27.11      struct audio_pcm_ops *pcm_ops;
   27.12 -    LIST_ENTRY (HWVoiceOut) entries;
   27.13 +    QEMU_LIST_ENTRY (HWVoiceOut) entries;
   27.14  } HWVoiceOut;
   27.15  
   27.16  typedef struct HWVoiceIn {
   27.17 @@ -98,9 +98,9 @@ typedef struct HWVoiceIn {
   27.18      st_sample_t *conv_buf;
   27.19  
   27.20      int samples;
   27.21 -    LIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
   27.22 +    QEMU_LIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
   27.23      struct audio_pcm_ops *pcm_ops;
   27.24 -    LIST_ENTRY (HWVoiceIn) entries;
   27.25 +    QEMU_LIST_ENTRY (HWVoiceIn) entries;
   27.26  } HWVoiceIn;
   27.27  
   27.28  struct SWVoiceOut {
   27.29 @@ -116,7 +116,7 @@ struct SWVoiceOut {
   27.30      char *name;
   27.31      volume_t vol;
   27.32      struct audio_callback callback;
   27.33 -    LIST_ENTRY (SWVoiceOut) entries;
   27.34 +    QEMU_LIST_ENTRY (SWVoiceOut) entries;
   27.35  };
   27.36  
   27.37  struct SWVoiceIn {
   27.38 @@ -131,7 +131,7 @@ struct SWVoiceIn {
   27.39      char *name;
   27.40      volume_t vol;
   27.41      struct audio_callback callback;
   27.42 -    LIST_ENTRY (SWVoiceIn) entries;
   27.43 +    QEMU_LIST_ENTRY (SWVoiceIn) entries;
   27.44  };
   27.45  
   27.46  struct audio_driver {
   27.47 @@ -165,20 +165,20 @@ struct audio_pcm_ops {
   27.48  struct capture_callback {
   27.49      struct audio_capture_ops ops;
   27.50      void *opaque;
   27.51 -    LIST_ENTRY (capture_callback) entries;
   27.52 +    QEMU_LIST_ENTRY (capture_callback) entries;
   27.53  };
   27.54  
   27.55  struct CaptureVoiceOut {
   27.56      HWVoiceOut hw;
   27.57      void *buf;
   27.58 -    LIST_HEAD (cb_listhead, capture_callback) cb_head;
   27.59 -    LIST_ENTRY (CaptureVoiceOut) entries;
   27.60 +    QEMU_LIST_HEAD (cb_listhead, capture_callback) cb_head;
   27.61 +    QEMU_LIST_ENTRY (CaptureVoiceOut) entries;
   27.62  };
   27.63  
   27.64  struct SWVoiceCap {
   27.65      SWVoiceOut sw;
   27.66      CaptureVoiceOut *cap;
   27.67 -    LIST_ENTRY (SWVoiceCap) entries;
   27.68 +    QEMU_LIST_ENTRY (SWVoiceCap) entries;
   27.69  };
   27.70  
   27.71  struct AudioState {
   27.72 @@ -186,10 +186,10 @@ struct AudioState {
   27.73      void *drv_opaque;
   27.74  
   27.75      QEMUTimer *ts;
   27.76 -    LIST_HEAD (card_listhead, QEMUSoundCard) card_head;
   27.77 -    LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
   27.78 -    LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
   27.79 -    LIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
   27.80 +    QEMU_LIST_HEAD (card_listhead, QEMUSoundCard) card_head;
   27.81 +    QEMU_LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
   27.82 +    QEMU_LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
   27.83 +    QEMU_LIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
   27.84      int nb_hw_voices_out;
   27.85      int nb_hw_voices_in;
   27.86  };
    28.1 --- a/tools/ioemu/audio/audio_template.h	Thu Feb 07 09:23:26 2008 -0700
    28.2 +++ b/tools/ioemu/audio/audio_template.h	Thu Feb 07 11:08:49 2008 -0700
    28.3 @@ -186,12 +186,12 @@ static void glue (audio_pcm_sw_fini_, TY
    28.4  
    28.5  static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
    28.6  {
    28.7 -    LIST_INSERT_HEAD (&hw->sw_head, sw, entries);
    28.8 +    QEMU_LIST_INSERT_HEAD (&hw->sw_head, sw, entries);
    28.9  }
   28.10  
   28.11  static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
   28.12  {
   28.13 -    LIST_REMOVE (sw, entries);
   28.14 +    QEMU_LIST_REMOVE (sw, entries);
   28.15  }
   28.16  
   28.17  static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp)
   28.18 @@ -202,7 +202,7 @@ static void glue (audio_pcm_hw_gc_, TYPE
   28.19  #ifdef DAC
   28.20          audio_detach_capture (hw);
   28.21  #endif
   28.22 -        LIST_REMOVE (hw, entries);
   28.23 +        QEMU_LIST_REMOVE (hw, entries);
   28.24          glue (s->nb_hw_voices_, TYPE) += 1;
   28.25          glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
   28.26          glue (hw->pcm_ops->fini_, TYPE) (hw);
   28.27 @@ -267,9 +267,9 @@ static HW *glue (audio_pcm_hw_add_new_, 
   28.28      }
   28.29  
   28.30      hw->pcm_ops = drv->pcm_ops;
   28.31 -    LIST_INIT (&hw->sw_head);
   28.32 +    QEMU_LIST_INIT (&hw->sw_head);
   28.33  #ifdef DAC
   28.34 -    LIST_INIT (&hw->cap_head);
   28.35 +    QEMU_LIST_INIT (&hw->cap_head);
   28.36  #endif
   28.37      if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
   28.38          goto err0;
   28.39 @@ -294,7 +294,7 @@ static HW *glue (audio_pcm_hw_add_new_, 
   28.40          goto err1;
   28.41      }
   28.42  
   28.43 -    LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
   28.44 +    QEMU_LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
   28.45      glue (s->nb_hw_voices_, TYPE) -= 1;
   28.46  #ifdef DAC
   28.47      audio_attach_capture (s, hw);
    29.1 --- a/tools/ioemu/audio/sys-queue.h	Thu Feb 07 09:23:26 2008 -0700
    29.2 +++ b/tools/ioemu/audio/sys-queue.h	Thu Feb 07 11:08:49 2008 -0700
    29.3 @@ -64,12 +64,12 @@
    29.4  /*
    29.5   * List definitions.
    29.6   */
    29.7 -#define LIST_HEAD(name, type)						\
    29.8 +#define QEMU_LIST_HEAD(name, type)					\
    29.9  struct name {								\
   29.10  	struct type *lh_first;	/* first element */			\
   29.11  }
   29.12  
   29.13 -#define LIST_ENTRY(type)						\
   29.14 +#define QEMU_LIST_ENTRY(type)						\
   29.15  struct {								\
   29.16  	struct type *le_next;	/* next element */			\
   29.17  	struct type **le_prev;	/* address of previous next element */	\
   29.18 @@ -78,11 +78,11 @@ struct {								\
   29.19  /*
   29.20   * List functions.
   29.21   */
   29.22 -#define	LIST_INIT(head) {						\
   29.23 +#define	QEMU_LIST_INIT(head) {						\
   29.24  	(head)->lh_first = NULL;					\
   29.25  }
   29.26  
   29.27 -#define LIST_INSERT_AFTER(listelm, elm, field) {			\
   29.28 +#define QEMU_LIST_INSERT_AFTER(listelm, elm, field) {			\
   29.29  	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
   29.30  		(listelm)->field.le_next->field.le_prev =		\
   29.31  		    &(elm)->field.le_next;				\
   29.32 @@ -90,14 +90,14 @@ struct {								\
   29.33  	(elm)->field.le_prev = &(listelm)->field.le_next;		\
   29.34  }
   29.35  
   29.36 -#define LIST_INSERT_HEAD(head, elm, field) {				\
   29.37 +#define QEMU_LIST_INSERT_HEAD(head, elm, field) {			\
   29.38  	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
   29.39  		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
   29.40  	(head)->lh_first = (elm);					\
   29.41  	(elm)->field.le_prev = &(head)->lh_first;			\
   29.42  }
   29.43  
   29.44 -#define LIST_REMOVE(elm, field) {					\
   29.45 +#define QEMU_LIST_REMOVE(elm, field) {					\
   29.46  	if ((elm)->field.le_next != NULL)				\
   29.47  		(elm)->field.le_next->field.le_prev = 			\
   29.48  		    (elm)->field.le_prev;				\
    30.1 --- a/tools/ioemu/hw/rtl8139.c	Thu Feb 07 09:23:26 2008 -0700
    30.2 +++ b/tools/ioemu/hw/rtl8139.c	Thu Feb 07 11:08:49 2008 -0700
    30.3 @@ -1468,7 +1468,7 @@ static void rtl8139_BasicModeCtrl_write(
    30.4      DEBUG_PRINT(("RTL8139: BasicModeCtrl register write(w) val=0x%04x\n", val));
    30.5  
    30.6      /* mask unwriteable bits */
    30.7 -    uint32 mask = 0x4cff;
    30.8 +    uint32_t mask = 0x4cff;
    30.9  
   30.10      if (1 || !rtl8139_config_writeable(s))
   30.11      {
    31.1 --- a/tools/ioemu/monitor.c	Thu Feb 07 09:23:26 2008 -0700
    31.2 +++ b/tools/ioemu/monitor.c	Thu Feb 07 11:08:49 2008 -0700
    31.3 @@ -1167,7 +1167,7 @@ static void do_info_profile(void)
    31.4  #endif
    31.5  
    31.6  /* Capture support */
    31.7 -static LIST_HEAD (capture_list_head, CaptureState) capture_head;
    31.8 +static QEMU_LIST_HEAD (capture_list_head, CaptureState) capture_head;
    31.9  
   31.10  static void do_info_capture (void)
   31.11  {
   31.12 @@ -1188,7 +1188,7 @@ static void do_stop_capture (int n)
   31.13      for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
   31.14          if (i == n) {
   31.15              s->ops.destroy (s->opaque);
   31.16 -            LIST_REMOVE (s, entries);
   31.17 +            QEMU_LIST_REMOVE (s, entries);
   31.18              qemu_free (s);
   31.19              return;
   31.20          }
   31.21 @@ -1220,7 +1220,7 @@ static void do_wav_capture (const char *
   31.22          term_printf ("Faied to add wave capture\n");
   31.23          qemu_free (s);
   31.24      }
   31.25 -    LIST_INSERT_HEAD (&capture_head, s, entries);
   31.26 +    QEMU_LIST_INSERT_HEAD (&capture_head, s, entries);
   31.27  }
   31.28  #endif
   31.29  
    32.1 --- a/tools/ioemu/qemu_socket.h	Thu Feb 07 09:23:26 2008 -0700
    32.2 +++ b/tools/ioemu/qemu_socket.h	Thu Feb 07 11:08:49 2008 -0700
    32.3 @@ -14,12 +14,19 @@
    32.4  #define EINTR       WSAEINTR
    32.5  #define EINPROGRESS WSAEINPROGRESS
    32.6  
    32.7 +#ifndef NO_UNIX_SOCKETS
    32.8 +#define NO_UNIX_SOCKETS 1
    32.9 +#endif
   32.10 +
   32.11  #else
   32.12  
   32.13  #include <sys/socket.h>
   32.14  #include <netinet/in.h>
   32.15  #include <netinet/tcp.h>
   32.16 +
   32.17 +#ifndef NO_UNIX_SOCKETS
   32.18  #include <sys/un.h>
   32.19 +#endif
   32.20  
   32.21  #define socket_error() errno
   32.22  #define closesocket(s) close(s)
    33.1 --- a/tools/ioemu/vl.c	Thu Feb 07 09:23:26 2008 -0700
    33.2 +++ b/tools/ioemu/vl.c	Thu Feb 07 11:08:49 2008 -0700
    33.3 @@ -3127,7 +3127,7 @@ int parse_host_port(struct sockaddr_in *
    33.4      return 0;
    33.5  }
    33.6  
    33.7 -#ifndef _WIN32
    33.8 +#ifndef NO_UNIX_SOCKETS
    33.9  static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
   33.10  {
   33.11      const char *p;
   33.12 @@ -6065,10 +6065,10 @@ void gui_update(void *opaque)
   33.13  struct vm_change_state_entry {
   33.14      VMChangeStateHandler *cb;
   33.15      void *opaque;
   33.16 -    LIST_ENTRY (vm_change_state_entry) entries;
   33.17 +    QEMU_LIST_ENTRY (vm_change_state_entry) entries;
   33.18  };
   33.19  
   33.20 -static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
   33.21 +static QEMU_LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
   33.22  
   33.23  VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
   33.24                                                       void *opaque)
   33.25 @@ -6081,13 +6081,13 @@ VMChangeStateEntry *qemu_add_vm_change_s
   33.26  
   33.27      e->cb = cb;
   33.28      e->opaque = opaque;
   33.29 -    LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
   33.30 +    QEMU_LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
   33.31      return e;
   33.32  }
   33.33  
   33.34  void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
   33.35  {
   33.36 -    LIST_REMOVE (e, entries);
   33.37 +    QEMU_LIST_REMOVE (e, entries);
   33.38      qemu_free (e);
   33.39  }
   33.40  
   33.41 @@ -7052,7 +7052,7 @@ int main(int argc, char **argv)
   33.42          sigprocmask(SIG_BLOCK, &set, NULL);
   33.43      }
   33.44  
   33.45 -    LIST_INIT (&vm_change_state_head);
   33.46 +    QEMU_LIST_INIT (&vm_change_state_head);
   33.47  #ifndef _WIN32
   33.48      {
   33.49          struct sigaction act;
    34.1 --- a/tools/ioemu/vnc.c	Thu Feb 07 09:23:26 2008 -0700
    34.2 +++ b/tools/ioemu/vnc.c	Thu Feb 07 11:08:49 2008 -0700
    34.3 @@ -2401,7 +2401,7 @@ int vnc_display_open(DisplayState *ds, c
    34.4  	}
    34.5  #endif
    34.6      }
    34.7 -#ifndef _WIN32
    34.8 +#ifndef NO_UNIX_SOCKETS
    34.9      if (strstart(display, "unix:", &p)) {
   34.10  	addr = (struct sockaddr *)&uaddr;
   34.11  	addrlen = sizeof(uaddr);
    35.1 --- a/tools/python/xen/xend/XendAPIConstants.py	Thu Feb 07 09:23:26 2008 -0700
    35.2 +++ b/tools/python/xen/xend/XendAPIConstants.py	Thu Feb 07 11:08:49 2008 -0700
    35.3 @@ -51,6 +51,18 @@ XEN_API_ON_CRASH_BEHAVIOUR = [
    35.4      'rename_restart'
    35.5  ]
    35.6  
    35.7 +XEN_API_ON_CRASH_BEHAVIOUR_FILTER = {
    35.8 +    'destroy' : 'destroy',
    35.9 +    'coredump-destroy' : 'coredump_and_destroy',
   35.10 +    'coredump_and_destroy' : 'coredump_and_destroy',
   35.11 +    'restart' : 'restart',
   35.12 +    'coredump-restart' : 'coredump_and_restart',
   35.13 +    'coredump_and_restart' : 'coredump_and_restart',
   35.14 +    'preserve' : 'preserve',
   35.15 +    'rename-restart' : 'rename_restart',
   35.16 +    'rename_restart' : 'rename_restart',
   35.17 +}
   35.18 +
   35.19  XEN_API_VBD_MODE = ['RO', 'RW']
   35.20  XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral']
   35.21  XEN_API_VBD_TYPE = ['CD', 'Disk']
    36.1 --- a/tools/python/xen/xend/XendConfig.py	Thu Feb 07 09:23:26 2008 -0700
    36.2 +++ b/tools/python/xen/xend/XendConfig.py	Thu Feb 07 11:08:49 2008 -0700
    36.3 @@ -242,7 +242,8 @@ LEGACY_XENSTORE_VM_PARAMS = [
    36.4  ## Config Choices
    36.5  ##
    36.6  
    36.7 -CONFIG_RESTART_MODES = ('restart', 'destroy', 'preserve', 'rename-restart')
    36.8 +CONFIG_RESTART_MODES = ('restart', 'destroy', 'preserve', 'rename-restart',
    36.9 +                        'coredump-destroy', 'coredump-restart')
   36.10  CONFIG_OLD_DOM_STATES = ('running', 'blocked', 'paused', 'shutdown',
   36.11                           'crashed', 'dying')
   36.12  
    37.1 --- a/tools/python/xen/xend/XendConstants.py	Thu Feb 07 09:23:26 2008 -0700
    37.2 +++ b/tools/python/xen/xend/XendConstants.py	Thu Feb 07 11:08:49 2008 -0700
    37.3 @@ -52,7 +52,9 @@ restart_modes = [
    37.4      "restart",
    37.5      "destroy",
    37.6      "preserve",
    37.7 -    "rename-restart"
    37.8 +    "rename-restart",
    37.9 +    "coredump-destroy",
   37.10 +    "coredump-restart"
   37.11      ]
   37.12  
   37.13  DOM_STATES = [
    38.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Feb 07 09:23:26 2008 -0700
    38.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Feb 07 11:08:49 2008 -0700
    38.3 @@ -879,6 +879,9 @@ class XendDomainInfo:
    38.4      def _gatherVm(self, *args):
    38.5          return xstransact.Gather(self.vmpath, *args)
    38.6  
    38.7 +    def _listRecursiveVm(self, *args):
    38.8 +        return xstransact.ListRecursive(self.vmpath, *args)
    38.9 +
   38.10      def storeVm(self, *args):
   38.11          return xstransact.Store(self.vmpath, *args)
   38.12  
   38.13 @@ -1260,14 +1263,6 @@ class XendDomainInfo:
   38.14                           self.info['name_label'], self.domid)
   38.15                  self._writeVm(LAST_SHUTDOWN_REASON, 'crash')
   38.16  
   38.17 -                if xoptions.get_enable_dump():
   38.18 -                    try:
   38.19 -                        self.dumpCore()
   38.20 -                    except XendError:
   38.21 -                        # This error has been logged -- there's nothing more
   38.22 -                        # we can do in this context.
   38.23 -                        pass
   38.24 -
   38.25                  restart_reason = 'crash'
   38.26                  self._stateSet(DOM_STATE_HALTED)
   38.27  
   38.28 @@ -1335,14 +1330,30 @@ class XendDomainInfo:
   38.29      def _clearRestart(self):
   38.30          self._removeDom("xend/shutdown_start_time")
   38.31  
   38.32 +    def _maybeDumpCore(self, reason):
   38.33 +        if reason == 'crash':
   38.34 +            if xoptions.get_enable_dump() or self.get_on_crash() \
   38.35 +                   in ['coredump_and_destroy', 'coredump_and_restart']:
   38.36 +                try:
   38.37 +                    self.dumpCore()
   38.38 +                except XendError:
   38.39 +                    # This error has been logged -- there's nothing more
   38.40 +                    # we can do in this context.
   38.41 +                    pass
   38.42  
   38.43      def _maybeRestart(self, reason):
   38.44 +        # Before taking configured action, dump core if configured to do so.
   38.45 +        #
   38.46 +        self._maybeDumpCore(reason)
   38.47 +
   38.48          # Dispatch to the correct method based upon the configured on_{reason}
   38.49          # behaviour.
   38.50          actions =  {"destroy"        : self.destroy,
   38.51                      "restart"        : self._restart,
   38.52                      "preserve"       : self._preserve,
   38.53 -                    "rename-restart" : self._renameRestart}
   38.54 +                    "rename-restart" : self._renameRestart,
   38.55 +                    "coredump-destroy" : self.destroy,
   38.56 +                    "coredump-restart" : self._restart}
   38.57  
   38.58          action_conf = {
   38.59              'poweroff': 'actions_after_shutdown',
   38.60 @@ -1393,6 +1404,7 @@ class XendDomainInfo:
   38.61  
   38.62          self._writeVm('xend/previous_restart_time', str(now))
   38.63  
   38.64 +        prev_vm_xend = self._listRecursiveVm('xend')
   38.65          new_dom_info = self.info
   38.66          try:
   38.67              if rename:
   38.68 @@ -1411,8 +1423,13 @@ class XendDomainInfo:
   38.69              try:
   38.70                  new_dom = XendDomain.instance().domain_create_from_dict(
   38.71                      new_dom_info)
   38.72 +                for x in prev_vm_xend[0][1]:
   38.73 +                    new_dom._writeVm('xend/%s' % x[0], x[1])
   38.74                  new_dom.waitForDevices()
   38.75                  new_dom.unpause()
   38.76 +                rst_cnt = new_dom._readVm('xend/restart_count')
   38.77 +                rst_cnt = int(rst_cnt) + 1
   38.78 +                new_dom._writeVm('xend/restart_count', str(rst_cnt))
   38.79                  new_dom._removeVm(RESTART_IN_PROGRESS)
   38.80              except:
   38.81                  if new_dom:
   38.82 @@ -1448,9 +1465,6 @@ class XendDomainInfo:
   38.83          self.vmpath = XS_VMROOT + new_uuid
   38.84          # Write out new vm node to xenstore
   38.85          self._storeVmDetails()
   38.86 -        rst_cnt = self._readVm('xend/restart_count')
   38.87 -        rst_cnt = int(rst_cnt) + 1
   38.88 -        self._writeVm('xend/restart_count', str(rst_cnt))
   38.89          self._preserve()
   38.90          return new_dom_info
   38.91  
   38.92 @@ -2566,9 +2580,10 @@ class XendDomainInfo:
   38.93  
   38.94      def get_on_crash(self):
   38.95          after_crash = self.info.get('actions_after_crash')
   38.96 -        if not after_crash or after_crash not in XEN_API_ON_CRASH_BEHAVIOUR:
   38.97 +        if not after_crash or after_crash not in \
   38.98 +               XEN_API_ON_CRASH_BEHAVIOUR + restart_modes:
   38.99              return XEN_API_ON_CRASH_BEHAVIOUR[0]
  38.100 -        return after_crash
  38.101 +        return XEN_API_ON_CRASH_BEHAVIOUR_FILTER[after_crash]
  38.102  
  38.103      def get_dev_config_by_uuid(self, dev_class, dev_uuid):
  38.104          """ Get's a device configuration either from XendConfig or
    39.1 --- a/tools/python/xen/xend/image.py	Thu Feb 07 09:23:26 2008 -0700
    39.2 +++ b/tools/python/xen/xend/image.py	Thu Feb 07 11:08:49 2008 -0700
    39.3 @@ -329,7 +329,7 @@ class ImageHandler:
    39.4              return
    39.5          if self.pid:
    39.6              try:
    39.7 -                os.kill(self.pid, signal.SIGHUP)
    39.8 +                os.kill(self.pid, signal.SIGKILL)
    39.9              except OSError, exn:
   39.10                  log.exception(exn)
   39.11              try:
    40.1 --- a/tools/python/xen/xend/server/DevController.py	Thu Feb 07 09:23:26 2008 -0700
    40.2 +++ b/tools/python/xen/xend/server/DevController.py	Thu Feb 07 11:08:49 2008 -0700
    40.3 @@ -22,6 +22,7 @@ import types
    40.4  from xen.xend import sxp, XendOptions
    40.5  from xen.xend.XendError import VmError
    40.6  from xen.xend.XendLogging import log
    40.7 +import xen.xend.XendConfig
    40.8  
    40.9  from xen.xend.xenstore.xstransact import xstransact, complete
   40.10  from xen.xend.xenstore.xswatch import xswatch
   40.11 @@ -113,10 +114,10 @@ class DevController:
   40.12                      raise VmError("Device %s is already connected." % dev_str)
   40.13  
   40.14                  if count == 0:
   40.15 -                    log.debug('DevController: writing %s to %s.', str(front),
   40.16 -                              frontpath)
   40.17 -                    log.debug('DevController: writing %s to %s.', str(back),
   40.18 -                              backpath)
   40.19 +                    log.debug('DevController: writing %s to %s.',
   40.20 +                              str(front), frontpath)
   40.21 +                    log.debug('DevController: writing %s to %s.',
   40.22 +                              str(xen.xend.XendConfig.scrub_password(back)), backpath)
   40.23                  elif count % 50 == 0:
   40.24                      log.debug(
   40.25                        'DevController: still waiting to write device entries.')
    41.1 --- a/tools/python/xen/xm/create.py	Thu Feb 07 09:23:26 2008 -0700
    41.2 +++ b/tools/python/xen/xm/create.py	Thu Feb 07 11:08:49 2008 -0700
    41.3 @@ -264,15 +264,17 @@ gopts.var('on_reboot', val='destroy|rest
    41.4                              renamed and a new domain started in its place.
    41.5            """)
    41.6  
    41.7 -gopts.var('on_crash', val='destroy|restart|preserve|rename-restart',
    41.8 +gopts.var('on_crash', val='destroy|restart|preserve|rename-restart|coredump-destroy|ciredump-restart',
    41.9            fn=set_value, default=None,
   41.10 -          use="""Behaviour  when a domain exits with reason 'crash'.
   41.11 -          - destroy:        the domain is cleaned up as normal;
   41.12 -          - restart:        a new domain is started in place of the old one;
   41.13 -          - preserve:       no clean-up is done until the domain is manually
   41.14 -                            destroyed (using xm destroy, for example);
   41.15 -          - rename-restart: the old domain is not cleaned up, but is
   41.16 -                            renamed and a new domain started in its place.
   41.17 +          use="""Behaviour when a domain exits with reason 'crash'.
   41.18 +          - destroy:          the domain is cleaned up as normal;
   41.19 +          - restart:          a new domain is started in place of the old one;
   41.20 +          - preserve:         no clean-up is done until the domain is manually
   41.21 +                              destroyed (using xm destroy, for example);
   41.22 +          - rename-restart:   the old domain is not cleaned up, but is
   41.23 +                              renamed and a new domain started in its place.
   41.24 +          - coredump-destroy: dump the domain's core, followed by destroy
   41.25 +          - coredump-restart: dump the domain's core, followed by restart
   41.26            """)
   41.27  
   41.28  gopts.var('blkif', val='no|yes',
    42.1 --- a/tools/python/xen/xm/shutdown.py	Thu Feb 07 09:23:26 2008 -0700
    42.2 +++ b/tools/python/xen/xm/shutdown.py	Thu Feb 07 11:08:49 2008 -0700
    42.3 @@ -24,6 +24,8 @@ from opts import *
    42.4  from main import server, serverType, SERVER_XEN_API, get_single_vm
    42.5  from xen.xend.XendAPIConstants import *
    42.6  
    42.7 +RECREATING_TIMEOUT = 30
    42.8 +
    42.9  gopts = Opts(use="""[options] [DOM]
   42.10  
   42.11  Shutdown one or more domains gracefully.
   42.12 @@ -53,6 +55,7 @@ def wait_reboot(opts, doms, rcs):
   42.13      if serverType == SERVER_XEN_API:
   42.14          opts.err("Cannot wait for reboot w/ XenAPI (yet)")
   42.15  
   42.16 +    recreating = {}
   42.17      while doms:
   42.18          alive = server.xend.domains(0)
   42.19          reboot = []
   42.20 @@ -61,9 +64,17 @@ def wait_reboot(opts, doms, rcs):
   42.21                  rc = server.xend.domain.getRestartCount(d)
   42.22                  if rc == rcs[d]: continue
   42.23                  reboot.append(d)
   42.24 +
   42.25 +            # Probably the domain is being recreated now.
   42.26 +            # We have to wait just a bit for recreating the domain.
   42.27 +            elif not recreating.has_key(d):
   42.28 +                recreating[d] = 0
   42.29              else:
   42.30 -                opts.info("Domain %s destroyed for failed in rebooting" % d)
   42.31 -                doms.remove(d)
   42.32 +                recreating[d] += 1
   42.33 +                if recreating[d] > RECREATING_TIMEOUT:
   42.34 +                    opts.info("Domain %s destroyed for failing to reboot" % d)
   42.35 +                    doms.remove(d)
   42.36 +
   42.37          for d in reboot:
   42.38              opts.info("Domain %s rebooted" % d)
   42.39              doms.remove(d)
    43.1 --- a/xen/arch/x86/Rules.mk	Thu Feb 07 09:23:26 2008 -0700
    43.2 +++ b/xen/arch/x86/Rules.mk	Thu Feb 07 11:08:49 2008 -0700
    43.3 @@ -11,11 +11,6 @@ xenoprof := y
    43.4  #
    43.5  pae ?= n
    43.6  supervisor_mode_kernel ?= n
    43.7 -vmxassist ?= n
    43.8 -
    43.9 -ifeq ($(vmxassist),y)
   43.10 -CFLAGS += -DVMXASSIST
   43.11 -endif
   43.12  
   43.13  # Solaris grabs stdarg.h and friends from the system include directory.
   43.14  ifneq ($(XEN_OS),SunOS)
    44.1 --- a/xen/arch/x86/domain_build.c	Thu Feb 07 09:23:26 2008 -0700
    44.2 +++ b/xen/arch/x86/domain_build.c	Thu Feb 07 11:08:49 2008 -0700
    44.3 @@ -292,9 +292,6 @@ int __init construct_dom0(
    44.4              compatible = 1;
    44.5          break;
    44.6      case 4: /* x86_64 */
    44.7 -#ifndef CONFIG_COMPAT
    44.8 -        printk(" Xen  kernel: 64-bit, lsb\n");
    44.9 -#else
   44.10          printk(" Xen  kernel: 64-bit, lsb, compat32\n");
   44.11          if (elf_32bit(&elf) && parms.pae == PAEKERN_bimodal)
   44.12              parms.pae = PAEKERN_extended_cr3;
   44.13 @@ -303,7 +300,6 @@ int __init construct_dom0(
   44.14              compat32 = 1;
   44.15              compatible = 1;
   44.16          }
   44.17 -#endif
   44.18          if (elf_64bit(&elf) && machine == EM_X86_64)
   44.19              compatible = 1;
   44.20          break;
   44.21 @@ -323,7 +319,7 @@ int __init construct_dom0(
   44.22          return -EINVAL;
   44.23      }
   44.24  
   44.25 -#ifdef CONFIG_COMPAT
   44.26 +#if defined(__x86_64__)
   44.27      if ( compat32 )
   44.28      {
   44.29          l1_pgentry_t gdt_l1e;
   44.30 @@ -346,34 +342,32 @@ int __init construct_dom0(
   44.31          flush_tlb_one_local(GDT_LDT_VIRT_START + FIRST_RESERVED_GDT_BYTE);
   44.32      }
   44.33  #endif
   44.34 +
   44.35      if ( parms.pae == PAEKERN_extended_cr3 )
   44.36              set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
   44.37  
   44.38 -    if ( UNSET_ADDR != parms.virt_hv_start_low && elf_32bit(&elf) )
   44.39 +    if ( (parms.virt_hv_start_low != UNSET_ADDR) && elf_32bit(&elf) )
   44.40      {
   44.41 -#if CONFIG_PAGING_LEVELS < 4
   44.42          unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1;
   44.43 +        value = (parms.virt_hv_start_low + mask) & ~mask;
   44.44 +        BUG_ON(!is_pv_32bit_domain(d));
   44.45 +#if defined(__i386__)
   44.46 +        if ( value > HYPERVISOR_VIRT_START )
   44.47 +            panic("Domain 0 expects too high a hypervisor start address.\n");
   44.48  #else
   44.49 -        unsigned long mask = is_pv_32bit_domain(d)
   44.50 -                             ? (1UL << L2_PAGETABLE_SHIFT) - 1
   44.51 -                             : (1UL << L4_PAGETABLE_SHIFT) - 1;
   44.52 -#endif
   44.53 -
   44.54 -        value = (parms.virt_hv_start_low + mask) & ~mask;
   44.55 -#ifdef CONFIG_COMPAT
   44.56 +        if ( value > __HYPERVISOR_COMPAT_VIRT_START )
   44.57 +            panic("Domain 0 expects too high a hypervisor start address.\n");
   44.58          HYPERVISOR_COMPAT_VIRT_START(d) =
   44.59              max_t(unsigned int, m2p_compat_vstart, value);
   44.60 +#endif
   44.61 +    }
   44.62 +
   44.63 +#if defined(__x86_64__)
   44.64 +    if ( is_pv_32on64_domain(d) )
   44.65          d->arch.physaddr_bitsize =
   44.66              fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 1
   44.67              + (PAGE_SIZE - 2);
   44.68 -        if ( value > (!is_pv_32on64_domain(d) ?
   44.69 -                      HYPERVISOR_VIRT_START :
   44.70 -                      __HYPERVISOR_COMPAT_VIRT_START) )
   44.71 -#else
   44.72 -        if ( value > HYPERVISOR_VIRT_START )
   44.73  #endif
   44.74 -            panic("Domain 0 expects too high a hypervisor start address.\n");
   44.75 -    }
   44.76  
   44.77      /*
   44.78       * Why do we need this? The number of page-table frames depends on the 
   44.79 @@ -702,7 +696,6 @@ int __init construct_dom0(
   44.80          mfn++;
   44.81      }
   44.82  
   44.83 -#ifdef CONFIG_COMPAT
   44.84      if ( is_pv_32on64_domain(d) )
   44.85      {
   44.86          /* Ensure the first four L3 entries are all populated. */
   44.87 @@ -724,7 +717,6 @@ int __init construct_dom0(
   44.88                 &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)],
   44.89                 COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*l2tab));
   44.90      }
   44.91 -#endif
   44.92  
   44.93      /* Pages that are part of page tables must be read only. */
   44.94      l4tab = l4start + l4_table_offset(vpt_start);
   44.95 @@ -885,7 +877,7 @@ int __init construct_dom0(
   44.96          si->console.dom0.info_size = sizeof(struct dom0_vga_console_info);
   44.97      }
   44.98  
   44.99 -#ifdef CONFIG_COMPAT
  44.100 +#if defined(__x86_64__)
  44.101      if ( is_pv_32on64_domain(d) )
  44.102          xlat_start_info(si, XLAT_start_info_console_dom0);
  44.103  #endif
    45.1 --- a/xen/arch/x86/hvm/hvm.c	Thu Feb 07 09:23:26 2008 -0700
    45.2 +++ b/xen/arch/x86/hvm/hvm.c	Thu Feb 07 11:08:49 2008 -0700
    45.3 @@ -1400,6 +1400,7 @@ void hvm_print_line(struct vcpu *v, cons
    45.4      spin_unlock(&hd->pbuf_lock);
    45.5  }
    45.6  
    45.7 +#define bitmaskof(idx)  (1U << ((idx) & 31))
    45.8  void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
    45.9                                     unsigned int *ecx, unsigned int *edx)
   45.10  {
   45.11 @@ -1413,16 +1414,44 @@ void hvm_cpuid(unsigned int input, unsig
   45.12      switch ( input )
   45.13      {
   45.14      case 0x00000001:
   45.15 -        __clear_bit(X86_FEATURE_MWAIT & 31, ecx);
   45.16 +        /* Clear #threads count and poke initial VLAPIC ID. */
   45.17 +        *ebx &= 0x0000FFFFu;
   45.18 +        *ebx |= (current->vcpu_id * 2) << 24;
   45.19  
   45.20 +        *ecx &= (bitmaskof(X86_FEATURE_XMM3) |
   45.21 +                 bitmaskof(X86_FEATURE_SSSE3) |
   45.22 +                 bitmaskof(X86_FEATURE_CX16) |
   45.23 +                 bitmaskof(X86_FEATURE_SSE4_1) |
   45.24 +                 bitmaskof(X86_FEATURE_SSE4_2) |
   45.25 +                 bitmaskof(X86_FEATURE_POPCNT));
   45.26 +
   45.27 +        *edx &= (bitmaskof(X86_FEATURE_FPU) |
   45.28 +                 bitmaskof(X86_FEATURE_VME) |
   45.29 +                 bitmaskof(X86_FEATURE_DE) |
   45.30 +                 bitmaskof(X86_FEATURE_PSE) |
   45.31 +                 bitmaskof(X86_FEATURE_TSC) |
   45.32 +                 bitmaskof(X86_FEATURE_MSR) |
   45.33 +                 bitmaskof(X86_FEATURE_PAE) |
   45.34 +                 bitmaskof(X86_FEATURE_MCE) |
   45.35 +                 bitmaskof(X86_FEATURE_CX8) |
   45.36 +                 bitmaskof(X86_FEATURE_APIC) |
   45.37 +                 bitmaskof(X86_FEATURE_SEP) |
   45.38 +                 bitmaskof(X86_FEATURE_MTRR) |
   45.39 +                 bitmaskof(X86_FEATURE_PGE) |
   45.40 +                 bitmaskof(X86_FEATURE_MCA) |
   45.41 +                 bitmaskof(X86_FEATURE_CMOV) |
   45.42 +                 bitmaskof(X86_FEATURE_PAT) |
   45.43 +                 bitmaskof(X86_FEATURE_CLFLSH) |
   45.44 +                 bitmaskof(X86_FEATURE_MMX) |
   45.45 +                 bitmaskof(X86_FEATURE_FXSR) |
   45.46 +                 bitmaskof(X86_FEATURE_XMM) |
   45.47 +                 bitmaskof(X86_FEATURE_XMM2));
   45.48          if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
   45.49              __clear_bit(X86_FEATURE_APIC & 31, edx);
   45.50 -
   45.51  #if CONFIG_PAGING_LEVELS >= 3
   45.52          if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
   45.53  #endif
   45.54              __clear_bit(X86_FEATURE_PAE & 31, edx);
   45.55 -        __clear_bit(X86_FEATURE_PSE36 & 31, edx);
   45.56          break;
   45.57  
   45.58      case 0x80000001:
   45.59 @@ -1671,16 +1700,6 @@ int hvm_bringup_ap(int vcpuid, int tramp
   45.60      ctxt->flags = VGCF_online;
   45.61      ctxt->user_regs.eflags = 2;
   45.62  
   45.63 -#ifdef VMXASSIST
   45.64 -    if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
   45.65 -    {
   45.66 -        ctxt->user_regs.eip = VMXASSIST_BASE;
   45.67 -        ctxt->user_regs.edx = vcpuid;
   45.68 -        ctxt->user_regs.ebx = trampoline_vector;
   45.69 -        goto done;
   45.70 -    }
   45.71 -#endif
   45.72 -
   45.73      v->arch.hvm_vcpu.guest_cr[0] = X86_CR0_ET;
   45.74      hvm_update_guest_cr(v, 0);
   45.75  
   45.76 @@ -1721,9 +1740,6 @@ int hvm_bringup_ap(int vcpuid, int tramp
   45.77      hvm_set_segment_register(v, x86_seg_gdtr, &reg);
   45.78      hvm_set_segment_register(v, x86_seg_idtr, &reg);
   45.79  
   45.80 -#ifdef VMXASSIST
   45.81 - done:
   45.82 -#endif
   45.83      /* Sync AP's TSC with BSP's. */
   45.84      v->arch.hvm_vcpu.cache_tsc_offset =
   45.85          v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset;
    46.1 --- a/xen/arch/x86/hvm/svm/svm.c	Thu Feb 07 09:23:26 2008 -0700
    46.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Thu Feb 07 11:08:49 2008 -0700
    46.3 @@ -578,8 +578,8 @@ static unsigned long svm_get_segment_bas
    46.4      case x86_seg_gdtr: return vmcb->gdtr.base;
    46.5      case x86_seg_idtr: return vmcb->idtr.base;
    46.6      case x86_seg_ldtr: svm_sync_vmcb(v); return vmcb->ldtr.base;
    46.7 +    default: BUG();
    46.8      }
    46.9 -    BUG();
   46.10      return 0;
   46.11  }
   46.12  
   46.13 @@ -986,11 +986,6 @@ static void svm_do_no_device_fault(struc
   46.14          vmcb->cr0 &= ~X86_CR0_TS;
   46.15  }
   46.16  
   46.17 -/* Reserved bits ECX: [31:14], [12:4], [2:1]*/
   46.18 -#define SVM_VCPU_CPUID_L1_ECX_RESERVED 0xffffdff6
   46.19 -/* Reserved bits EDX: [31:29], [27], [22:20], [18], [10] */
   46.20 -#define SVM_VCPU_CPUID_L1_EDX_RESERVED 0xe8740400
   46.21 -
   46.22  #define bitmaskof(idx)  (1U << ((idx) & 31))
   46.23  static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb,
   46.24                                  struct cpu_user_regs *regs)
   46.25 @@ -1005,16 +1000,10 @@ static void svm_vmexit_do_cpuid(struct v
   46.26      switch ( input )
   46.27      {
   46.28      case 0x00000001:
   46.29 -        /* Clear out reserved bits. */
   46.30 -        ecx &= ~SVM_VCPU_CPUID_L1_ECX_RESERVED;
   46.31 -        edx &= ~SVM_VCPU_CPUID_L1_EDX_RESERVED;
   46.32 -
   46.33 -        /* Guest should only see one logical processor.
   46.34 -         * See details on page 23 of AMD CPUID Specification.
   46.35 -         */
   46.36 -        __clear_bit(X86_FEATURE_HT & 31, &edx);
   46.37 -        ebx &= 0xFF00FFFF;  /* clear the logical processor count when HTT=0 */
   46.38 -        ebx |= 0x00010000;  /* set to 1 just for precaution */
   46.39 +        /* Mask Intel-only features. */
   46.40 +        ecx &= ~(bitmaskof(X86_FEATURE_SSSE3) |
   46.41 +                 bitmaskof(X86_FEATURE_SSE4_1) |
   46.42 +                 bitmaskof(X86_FEATURE_SSE4_2));
   46.43          break;
   46.44  
   46.45      case 0x80000001:
    47.1 --- a/xen/arch/x86/hvm/vmx/Makefile	Thu Feb 07 09:23:26 2008 -0700
    47.2 +++ b/xen/arch/x86/hvm/vmx/Makefile	Thu Feb 07 11:08:49 2008 -0700
    47.3 @@ -4,9 +4,7 @@ subdir-$(x86_32) += x86_32
    47.4  subdir-$(x86_64) += x86_64
    47.5  
    47.6  obj-y += intr.o
    47.7 -ifneq ($(vmxassist),y)
    47.8  obj-y += realmode.o
    47.9 -endif
   47.10  obj-y += vmcs.o
   47.11  obj-y += vmx.o
   47.12  obj-y += vpmu.o
    48.1 --- a/xen/arch/x86/hvm/vmx/realmode.c	Thu Feb 07 09:23:26 2008 -0700
    48.2 +++ b/xen/arch/x86/hvm/vmx/realmode.c	Thu Feb 07 11:08:49 2008 -0700
    48.3 @@ -18,7 +18,6 @@
    48.4  #include <asm/hvm/support.h>
    48.5  #include <asm/hvm/vmx/vmx.h>
    48.6  #include <asm/hvm/vmx/vmcs.h>
    48.7 -#include <asm/hvm/vmx/cpu.h>
    48.8  #include <asm/x86_emulate.h>
    48.9  
   48.10  struct realmode_emulate_ctxt {
   48.11 @@ -118,6 +117,18 @@ static void realmode_deliver_exception(
   48.12      }
   48.13  }
   48.14  
   48.15 +static uint32_t virtual_to_linear(
   48.16 +    enum x86_segment seg,
   48.17 +    uint32_t offset,
   48.18 +    struct realmode_emulate_ctxt *rm_ctxt)
   48.19 +{
   48.20 +    uint32_t addr = offset;
   48.21 +    if ( seg == x86_seg_none )
   48.22 +        return addr;
   48.23 +    ASSERT(is_x86_user_segment(seg));
   48.24 +    return addr + rm_ctxt->seg_reg[seg].base;
   48.25 +}
   48.26 +
   48.27  static int
   48.28  realmode_read(
   48.29      enum x86_segment seg,
   48.30 @@ -127,14 +138,17 @@ realmode_read(
   48.31      enum hvm_access_type access_type,
   48.32      struct realmode_emulate_ctxt *rm_ctxt)
   48.33  {
   48.34 -    uint32_t addr = rm_ctxt->seg_reg[seg].base + offset;
   48.35 +    uint32_t addr = virtual_to_linear(seg, offset, rm_ctxt);
   48.36  
   48.37      *val = 0;
   48.38  
   48.39 -    if ( hvm_copy_from_guest_phys(val, addr, bytes) )
   48.40 +    if ( hvm_copy_from_guest_virt_nofault(val, addr, bytes) )
   48.41      {
   48.42          struct vcpu *curr = current;
   48.43  
   48.44 +        if ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
   48.45 +            return X86EMUL_UNHANDLEABLE;
   48.46 +
   48.47          if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
   48.48              return X86EMUL_UNHANDLEABLE;
   48.49  
   48.50 @@ -202,12 +216,15 @@ realmode_emulate_write(
   48.51  {
   48.52      struct realmode_emulate_ctxt *rm_ctxt =
   48.53          container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
   48.54 -    uint32_t addr = rm_ctxt->seg_reg[seg].base + offset;
   48.55 +    uint32_t addr = virtual_to_linear(seg, offset, rm_ctxt);
   48.56  
   48.57 -    if ( hvm_copy_to_guest_phys(addr, &val, bytes) )
   48.58 +    if ( hvm_copy_to_guest_virt_nofault(addr, &val, bytes) )
   48.59      {
   48.60          struct vcpu *curr = current;
   48.61  
   48.62 +        if ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
   48.63 +            return X86EMUL_UNHANDLEABLE;
   48.64 +
   48.65          if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
   48.66              return X86EMUL_UNHANDLEABLE;
   48.67  
   48.68 @@ -244,7 +261,10 @@ realmode_rep_ins(
   48.69      struct realmode_emulate_ctxt *rm_ctxt =
   48.70          container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
   48.71      struct vcpu *curr = current;
   48.72 -    uint32_t paddr = rm_ctxt->seg_reg[dst_seg].base + dst_offset;
   48.73 +    uint32_t paddr = virtual_to_linear(dst_seg, dst_offset, rm_ctxt);
   48.74 +
   48.75 +    if ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
   48.76 +        return X86EMUL_UNHANDLEABLE;
   48.77  
   48.78      if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
   48.79          return X86EMUL_UNHANDLEABLE;
   48.80 @@ -277,7 +297,10 @@ realmode_rep_outs(
   48.81      struct realmode_emulate_ctxt *rm_ctxt =
   48.82          container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
   48.83      struct vcpu *curr = current;
   48.84 -    uint32_t paddr = rm_ctxt->seg_reg[src_seg].base + src_offset;
   48.85 +    uint32_t paddr = virtual_to_linear(src_seg, src_offset, rm_ctxt);
   48.86 +
   48.87 +    if ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
   48.88 +        return X86EMUL_UNHANDLEABLE;
   48.89  
   48.90      if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
   48.91          return X86EMUL_UNHANDLEABLE;
   48.92 @@ -310,9 +333,29 @@ realmode_write_segment(
   48.93  {
   48.94      struct realmode_emulate_ctxt *rm_ctxt =
   48.95          container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
   48.96 +    struct vcpu *curr = current;
   48.97 +
   48.98 +    if ( seg == x86_seg_cs )
   48.99 +    {
  48.100 +        if ( reg->attr.fields.dpl != 0 )
  48.101 +            return X86EMUL_UNHANDLEABLE;
  48.102 +        curr->arch.hvm_vmx.vmxemul &= ~VMXEMUL_BAD_CS;
  48.103 +        if ( reg->sel & 3 )
  48.104 +            curr->arch.hvm_vmx.vmxemul |= VMXEMUL_BAD_CS;
  48.105 +    }
  48.106 +
  48.107 +    if ( seg == x86_seg_ss )
  48.108 +    {
  48.109 +        if ( reg->attr.fields.dpl != 0 )
  48.110 +            return X86EMUL_UNHANDLEABLE;
  48.111 +        curr->arch.hvm_vmx.vmxemul &= ~VMXEMUL_BAD_SS;
  48.112 +        if ( reg->sel & 3 )
  48.113 +            curr->arch.hvm_vmx.vmxemul |= VMXEMUL_BAD_SS;
  48.114 +        rm_ctxt->flags.mov_ss = 1;
  48.115 +    }
  48.116 +
  48.117      memcpy(&rm_ctxt->seg_reg[seg], reg, sizeof(struct segment_register));
  48.118 -    if ( seg == x86_seg_ss )
  48.119 -        rm_ctxt->flags.mov_ss = 1;
  48.120 +
  48.121      return X86EMUL_OKAY;
  48.122  }
  48.123  
  48.124 @@ -336,7 +379,7 @@ realmode_read_io(
  48.125  
  48.126      if ( !curr->arch.hvm_vmx.real_mode_io_completed )
  48.127          return X86EMUL_RETRY;
  48.128 -    
  48.129 +
  48.130      *val = curr->arch.hvm_vmx.real_mode_io_data;
  48.131      curr->arch.hvm_vmx.real_mode_io_completed = 0;
  48.132  
  48.133 @@ -506,11 +549,19 @@ static int realmode_hlt(
  48.134  
  48.135  static int realmode_inject_hw_exception(
  48.136      uint8_t vector,
  48.137 +    uint16_t error_code,
  48.138      struct x86_emulate_ctxt *ctxt)
  48.139  {
  48.140      struct realmode_emulate_ctxt *rm_ctxt =
  48.141          container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
  48.142  
  48.143 +    /* We don't emulate protected-mode exception delivery. */
  48.144 +    if ( current->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
  48.145 +        return X86EMUL_UNHANDLEABLE;
  48.146 +
  48.147 +    if ( error_code != 0 )
  48.148 +        return X86EMUL_UNHANDLEABLE;
  48.149 +
  48.150      rm_ctxt->exn_vector = vector;
  48.151      rm_ctxt->exn_insn_len = 0;
  48.152  
  48.153 @@ -525,6 +576,10 @@ static int realmode_inject_sw_interrupt(
  48.154      struct realmode_emulate_ctxt *rm_ctxt =
  48.155          container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
  48.156  
  48.157 +    /* We don't emulate protected-mode exception delivery. */
  48.158 +    if ( current->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
  48.159 +        return X86EMUL_UNHANDLEABLE;
  48.160 +
  48.161      rm_ctxt->exn_vector = vector;
  48.162      rm_ctxt->exn_insn_len = insn_len;
  48.163  
  48.164 @@ -568,12 +623,22 @@ static void realmode_emulate_one(struct 
  48.165      struct vcpu *curr = current;
  48.166      u32 new_intr_shadow;
  48.167      int rc, io_completed;
  48.168 +    unsigned long addr;
  48.169  
  48.170 -    rm_ctxt->insn_buf_eip = regs->eip;
  48.171 -    (void)hvm_copy_from_guest_phys(
  48.172 -        rm_ctxt->insn_buf,
  48.173 -        (uint32_t)(rm_ctxt->seg_reg[x86_seg_cs].base + regs->eip),
  48.174 -        sizeof(rm_ctxt->insn_buf));
  48.175 +    rm_ctxt->ctxt.addr_size =
  48.176 +        rm_ctxt->seg_reg[x86_seg_cs].attr.fields.db ? 32 : 16;
  48.177 +    rm_ctxt->ctxt.sp_size =
  48.178 +        rm_ctxt->seg_reg[x86_seg_ss].attr.fields.db ? 32 : 16;
  48.179 +
  48.180 +    rm_ctxt->insn_buf_eip = (uint32_t)regs->eip;
  48.181 +    addr = virtual_to_linear(x86_seg_cs, regs->eip, rm_ctxt);
  48.182 +    if ( hvm_fetch_from_guest_virt_nofault(rm_ctxt->insn_buf, addr,
  48.183 +                                           sizeof(rm_ctxt->insn_buf))
  48.184 +         != HVMCOPY_okay )
  48.185 +    {
  48.186 +        gdprintk(XENLOG_ERR, "Failed to pre-fetch instruction bytes.\n");
  48.187 +        goto fail;
  48.188 +    }
  48.189  
  48.190      rm_ctxt->flag_word = 0;
  48.191  
  48.192 @@ -670,39 +735,35 @@ void vmx_realmode(struct cpu_user_regs *
  48.193      for ( i = 0; i < 10; i++ )
  48.194          hvm_get_segment_register(curr, i, &rm_ctxt.seg_reg[i]);
  48.195  
  48.196 -    rm_ctxt.ctxt.addr_size =
  48.197 -        rm_ctxt.seg_reg[x86_seg_cs].attr.fields.db ? 32 : 16;
  48.198 -    rm_ctxt.ctxt.sp_size =
  48.199 -        rm_ctxt.seg_reg[x86_seg_ss].attr.fields.db ? 32 : 16;
  48.200 -
  48.201      rm_ctxt.intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
  48.202  
  48.203      if ( curr->arch.hvm_vmx.real_mode_io_in_progress ||
  48.204           curr->arch.hvm_vmx.real_mode_io_completed )
  48.205          realmode_emulate_one(&rm_ctxt);
  48.206  
  48.207 -    if ( intr_info & INTR_INFO_VALID_MASK )
  48.208 +    /* Only deliver interrupts into emulated real mode. */
  48.209 +    if ( !(curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) &&
  48.210 +         (intr_info & INTR_INFO_VALID_MASK) )
  48.211      {
  48.212          realmode_deliver_exception((uint8_t)intr_info, 0, &rm_ctxt);
  48.213          __vmwrite(VM_ENTRY_INTR_INFO, 0);
  48.214      }
  48.215  
  48.216 -    while ( !(curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) &&
  48.217 +    while ( curr->arch.hvm_vmx.vmxemul &&
  48.218              !softirq_pending(smp_processor_id()) &&
  48.219 -            !hvm_local_events_need_delivery(curr) &&
  48.220 -            !curr->arch.hvm_vmx.real_mode_io_in_progress )
  48.221 +            !curr->arch.hvm_vmx.real_mode_io_in_progress &&
  48.222 +            /* Check for pending interrupts only in proper real mode. */
  48.223 +            ((curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) ||
  48.224 +             !hvm_local_events_need_delivery(curr)) )
  48.225          realmode_emulate_one(&rm_ctxt);
  48.226  
  48.227 -    /*
  48.228 -     * Cannot enter protected mode with bogus selector RPLs and DPLs. Hence we
  48.229 -     * fix up as best we can, even though this deviates from native execution
  48.230 -     */
  48.231 -    if  ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
  48.232 +    if ( !curr->arch.hvm_vmx.vmxemul )
  48.233      {
  48.234 -        /* CS.RPL == SS.RPL == SS.DPL == 0. */
  48.235 -        rm_ctxt.seg_reg[x86_seg_cs].sel &= ~3;
  48.236 -        rm_ctxt.seg_reg[x86_seg_ss].sel &= ~3;
  48.237 -        /* DS,ES,FS,GS: The most uninvasive trick is to set DPL == RPL. */
  48.238 +        /*
  48.239 +         * Cannot enter protected mode with bogus selector RPLs and DPLs.
  48.240 +         * At this point CS.RPL == SS.RPL == CS.DPL == SS.DPL == 0. For
  48.241 +         * DS, ES, FS and GS the most uninvasive trick is to set DPL == RPL.
  48.242 +         */
  48.243          rm_ctxt.seg_reg[x86_seg_ds].attr.fields.dpl =
  48.244              rm_ctxt.seg_reg[x86_seg_ds].sel & 3;
  48.245          rm_ctxt.seg_reg[x86_seg_es].attr.fields.dpl =
    49.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Feb 07 09:23:26 2008 -0700
    49.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Feb 07 11:08:49 2008 -0700
    49.3 @@ -41,7 +41,6 @@
    49.4  #include <asm/hvm/support.h>
    49.5  #include <asm/hvm/vmx/vmx.h>
    49.6  #include <asm/hvm/vmx/vmcs.h>
    49.7 -#include <asm/hvm/vmx/cpu.h>
    49.8  #include <public/sched.h>
    49.9  #include <public/hvm/ioreq.h>
   49.10  #include <asm/hvm/vpic.h>
   49.11 @@ -94,11 +93,10 @@ static int vmx_vcpu_initialise(struct vc
   49.12  
   49.13      vmx_install_vlapic_mapping(v);
   49.14  
   49.15 -#ifndef VMXASSIST
   49.16 +    /* %eax == 1 signals full real-mode support to the guest loader. */
   49.17      if ( v->vcpu_id == 0 )
   49.18          v->arch.guest_context.user_regs.eax = 1;
   49.19      v->arch.hvm_vcpu.io_complete = vmx_realmode_io_complete;
   49.20 -#endif
   49.21  
   49.22      return 0;
   49.23  }
   49.24 @@ -710,10 +708,6 @@ static void vmx_load_cpu_state(struct vc
   49.25      v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
   49.26  #endif
   49.27  
   49.28 -#ifdef VMXASSIST
   49.29 -    v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE);
   49.30 -#endif
   49.31 -
   49.32      hvm_set_guest_time(v, data->tsc);
   49.33  
   49.34      dump_msr_state(guest_state);
   49.35 @@ -1061,6 +1055,10 @@ static void vmx_update_guest_cr(struct v
   49.36                  vmx_fpu_enter(v);
   49.37          }
   49.38  
   49.39 +        v->arch.hvm_vmx.vmxemul &= ~VMXEMUL_REALMODE;
   49.40 +        if ( !(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) )
   49.41 +            v->arch.hvm_vmx.vmxemul |= VMXEMUL_REALMODE;
   49.42 +
   49.43          v->arch.hvm_vcpu.hw_cr[0] =
   49.44              v->arch.hvm_vcpu.guest_cr[0] | hw_cr0_mask;
   49.45          __vmwrite(GUEST_CR0, v->arch.hvm_vcpu.hw_cr[0]);
   49.46 @@ -1263,65 +1261,18 @@ void vmx_cpuid_intercept(
   49.47      unsigned int input = *eax;
   49.48      unsigned int count = *ecx;
   49.49  
   49.50 -#ifdef VMXASSIST
   49.51 -    if ( input == 0x40000003 )
   49.52 -    {
   49.53 -        /*
   49.54 -         * NB. Unsupported interface for private use of VMXASSIST only.
   49.55 -         * Note that this leaf lives at <max-hypervisor-leaf> + 1.
   49.56 -         */
   49.57 -        u64 value = ((u64)*edx << 32) | (u32)*ecx;
   49.58 -        p2m_type_t p2mt;
   49.59 -        unsigned long mfn;
   49.60 -        struct vcpu *v = current;
   49.61 -        char *p;
   49.62 -
   49.63 -        mfn = mfn_x(gfn_to_mfn_current(value >> PAGE_SHIFT, &p2mt));
   49.64 -
   49.65 -        gdprintk(XENLOG_INFO, "Input address is 0x%"PRIx64".\n", value);
   49.66 -
   49.67 -        /* 8-byte aligned valid pseudophys address from vmxassist, please. */
   49.68 -        if ( (value & 7) || !p2m_is_ram(p2mt) ||
   49.69 -             !v->arch.hvm_vmx.vmxassist_enabled )
   49.70 -        {
   49.71 -            domain_crash(v->domain);
   49.72 -            return;
   49.73 -        }
   49.74 -        ASSERT(mfn_valid(mfn));
   49.75 -
   49.76 -        p = map_domain_page(mfn);
   49.77 -        value = *((uint64_t *)(p + (value & (PAGE_SIZE - 1))));
   49.78 -        unmap_domain_page(p);
   49.79 -
   49.80 -        gdprintk(XENLOG_INFO, "Output value is 0x%"PRIx64".\n", value);
   49.81 -        *ecx = (u32)value;
   49.82 -        *edx = (u32)(value >> 32);
   49.83 -        return;
   49.84 -    }
   49.85 -#endif
   49.86 -
   49.87      hvm_cpuid(input, eax, ebx, ecx, edx);
   49.88  
   49.89      switch ( input )
   49.90      {
   49.91      case 0x00000001:
   49.92 -        *ecx &= ~VMX_VCPU_CPUID_L1_ECX_RESERVED;
   49.93 -        *ebx &= NUM_THREADS_RESET_MASK;
   49.94 -        *ecx &= ~(bitmaskof(X86_FEATURE_VMXE) |
   49.95 -                  bitmaskof(X86_FEATURE_EST)  |
   49.96 -                  bitmaskof(X86_FEATURE_TM2)  |
   49.97 -                  bitmaskof(X86_FEATURE_CID)  |
   49.98 -                  bitmaskof(X86_FEATURE_PDCM) |
   49.99 -                  bitmaskof(X86_FEATURE_DSCPL));
  49.100 -        *edx &= ~(bitmaskof(X86_FEATURE_HT)   |
  49.101 -                  bitmaskof(X86_FEATURE_ACPI) |
  49.102 -                  bitmaskof(X86_FEATURE_ACC)  |
  49.103 -                  bitmaskof(X86_FEATURE_DS));
  49.104 +        /* Mask AMD-only features. */
  49.105 +        *ecx &= ~(bitmaskof(X86_FEATURE_POPCNT));
  49.106          break;
  49.107  
  49.108      case 0x00000004:
  49.109          cpuid_count(input, count, eax, ebx, ecx, edx);
  49.110 -        *eax &= NUM_CORES_RESET_MASK;
  49.111 +        *eax &= 0x3FFF; /* one core */
  49.112          break;
  49.113  
  49.114      case 0x00000006:
  49.115 @@ -1839,256 +1790,6 @@ static void vmx_io_instruction(unsigned 
  49.116      }
  49.117  }
  49.118  
  49.119 -#ifdef VMXASSIST
  49.120 -
  49.121 -static void vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
  49.122 -{
  49.123 -    struct cpu_user_regs *regs = guest_cpu_user_regs();
  49.124 -
  49.125 -    c->eip  = regs->eip;
  49.126 -    c->eip += __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
  49.127 -    c->esp = regs->esp;
  49.128 -    c->eflags = regs->eflags & ~X86_EFLAGS_RF;
  49.129 -
  49.130 -    c->cr0 = v->arch.hvm_vcpu.guest_cr[0];
  49.131 -    c->cr3 = v->arch.hvm_vcpu.guest_cr[3];
  49.132 -    c->cr4 = v->arch.hvm_vcpu.guest_cr[4];
  49.133 -
  49.134 -    c->idtr_limit = __vmread(GUEST_IDTR_LIMIT);
  49.135 -    c->idtr_base = __vmread(GUEST_IDTR_BASE);
  49.136 -
  49.137 -    c->gdtr_limit = __vmread(GUEST_GDTR_LIMIT);
  49.138 -    c->gdtr_base = __vmread(GUEST_GDTR_BASE);
  49.139 -
  49.140 -    c->cs_sel = __vmread(GUEST_CS_SELECTOR);
  49.141 -    c->cs_limit = __vmread(GUEST_CS_LIMIT);
  49.142 -    c->cs_base = __vmread(GUEST_CS_BASE);
  49.143 -    c->cs_arbytes.bytes = __vmread(GUEST_CS_AR_BYTES);
  49.144 -
  49.145 -    c->ds_sel = __vmread(GUEST_DS_SELECTOR);
  49.146 -    c->ds_limit = __vmread(GUEST_DS_LIMIT);
  49.147 -    c->ds_base = __vmread(GUEST_DS_BASE);
  49.148 -    c->ds_arbytes.bytes = __vmread(GUEST_DS_AR_BYTES);
  49.149 -
  49.150 -    c->es_sel = __vmread(GUEST_ES_SELECTOR);
  49.151 -    c->es_limit = __vmread(GUEST_ES_LIMIT);
  49.152 -    c->es_base = __vmread(GUEST_ES_BASE);
  49.153 -    c->es_arbytes.bytes = __vmread(GUEST_ES_AR_BYTES);
  49.154 -
  49.155 -    c->ss_sel = __vmread(GUEST_SS_SELECTOR);
  49.156 -    c->ss_limit = __vmread(GUEST_SS_LIMIT);
  49.157 -    c->ss_base = __vmread(GUEST_SS_BASE);
  49.158 -    c->ss_arbytes.bytes = __vmread(GUEST_SS_AR_BYTES);
  49.159 -
  49.160 -    c->fs_sel = __vmread(GUEST_FS_SELECTOR);
  49.161 -    c->fs_limit = __vmread(GUEST_FS_LIMIT);
  49.162 -    c->fs_base = __vmread(GUEST_FS_BASE);
  49.163 -    c->fs_arbytes.bytes = __vmread(GUEST_FS_AR_BYTES);
  49.164 -
  49.165 -    c->gs_sel = __vmread(GUEST_GS_SELECTOR);
  49.166 -    c->gs_limit = __vmread(GUEST_GS_LIMIT);
  49.167 -    c->gs_base = __vmread(GUEST_GS_BASE);
  49.168 -    c->gs_arbytes.bytes = __vmread(GUEST_GS_AR_BYTES);
  49.169 -
  49.170 -    c->tr_sel = __vmread(GUEST_TR_SELECTOR);
  49.171 -    c->tr_limit = __vmread(GUEST_TR_LIMIT);
  49.172 -    c->tr_base = __vmread(GUEST_TR_BASE);
  49.173 -    c->tr_arbytes.bytes = __vmread(GUEST_TR_AR_BYTES);
  49.174 -
  49.175 -    c->ldtr_sel = __vmread(GUEST_LDTR_SELECTOR);
  49.176 -    c->ldtr_limit = __vmread(GUEST_LDTR_LIMIT);
  49.177 -    c->ldtr_base = __vmread(GUEST_LDTR_BASE);
  49.178 -    c->ldtr_arbytes.bytes = __vmread(GUEST_LDTR_AR_BYTES);
  49.179 -}
  49.180 -
  49.181 -static int vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
  49.182 -{
  49.183 -    struct cpu_user_regs *regs = guest_cpu_user_regs();
  49.184 -    int rc;
  49.185 -
  49.186 -    rc = vmx_restore_cr0_cr3(v, c->cr0, c->cr3);
  49.187 -    if ( rc )
  49.188 -        return rc;
  49.189 -
  49.190 -    regs->eip = c->eip;
  49.191 -    regs->esp = c->esp;
  49.192 -    regs->eflags = c->eflags | 2;
  49.193 -
  49.194 -    v->arch.hvm_vcpu.guest_cr[4] = c->cr4;
  49.195 -    vmx_update_guest_cr(v, 0);
  49.196 -    vmx_update_guest_cr(v, 4);
  49.197 -
  49.198 -    __vmwrite(GUEST_IDTR_LIMIT, c->idtr_limit);
  49.199 -    __vmwrite(GUEST_IDTR_BASE, c->idtr_base);
  49.200 -
  49.201 -    __vmwrite(GUEST_GDTR_LIMIT, c->gdtr_limit);
  49.202 -    __vmwrite(GUEST_GDTR_BASE, c->gdtr_base);
  49.203 -
  49.204 -    __vmwrite(GUEST_CS_SELECTOR, c->cs_sel);
  49.205 -    __vmwrite(GUEST_CS_LIMIT, c->cs_limit);
  49.206 -    __vmwrite(GUEST_CS_BASE, c->cs_base);
  49.207 -    __vmwrite(GUEST_CS_AR_BYTES, c->cs_arbytes.bytes);
  49.208 -
  49.209 -    __vmwrite(GUEST_DS_SELECTOR, c->ds_sel);
  49.210 -    __vmwrite(GUEST_DS_LIMIT, c->ds_limit);
  49.211 -    __vmwrite(GUEST_DS_BASE, c->ds_base);
  49.212 -    __vmwrite(GUEST_DS_AR_BYTES, c->ds_arbytes.bytes);
  49.213 -
  49.214 -    __vmwrite(GUEST_ES_SELECTOR, c->es_sel);
  49.215 -    __vmwrite(GUEST_ES_LIMIT, c->es_limit);
  49.216 -    __vmwrite(GUEST_ES_BASE, c->es_base);
  49.217 -    __vmwrite(GUEST_ES_AR_BYTES, c->es_arbytes.bytes);
  49.218 -
  49.219 -    __vmwrite(GUEST_SS_SELECTOR, c->ss_sel);
  49.220 -    __vmwrite(GUEST_SS_LIMIT, c->ss_limit);
  49.221 -    __vmwrite(GUEST_SS_BASE, c->ss_base);
  49.222 -    __vmwrite(GUEST_SS_AR_BYTES, c->ss_arbytes.bytes);
  49.223 -
  49.224 -    __vmwrite(GUEST_FS_SELECTOR, c->fs_sel);
  49.225 -    __vmwrite(GUEST_FS_LIMIT, c->fs_limit);
  49.226 -    __vmwrite(GUEST_FS_BASE, c->fs_base);
  49.227 -    __vmwrite(GUEST_FS_AR_BYTES, c->fs_arbytes.bytes);
  49.228 -
  49.229 -    __vmwrite(GUEST_GS_SELECTOR, c->gs_sel);
  49.230 -    __vmwrite(GUEST_GS_LIMIT, c->gs_limit);
  49.231 -    __vmwrite(GUEST_GS_BASE, c->gs_base);
  49.232 -    __vmwrite(GUEST_GS_AR_BYTES, c->gs_arbytes.bytes);
  49.233 -
  49.234 -    __vmwrite(GUEST_TR_SELECTOR, c->tr_sel);
  49.235 -    __vmwrite(GUEST_TR_LIMIT, c->tr_limit);
  49.236 -    __vmwrite(GUEST_TR_BASE, c->tr_base);
  49.237 -    __vmwrite(GUEST_TR_AR_BYTES, c->tr_arbytes.bytes);
  49.238 -
  49.239 -    __vmwrite(GUEST_LDTR_SELECTOR, c->ldtr_sel);
  49.240 -    __vmwrite(GUEST_LDTR_LIMIT, c->ldtr_limit);
  49.241 -    __vmwrite(GUEST_LDTR_BASE, c->ldtr_base);
  49.242 -    __vmwrite(GUEST_LDTR_AR_BYTES, c->ldtr_arbytes.bytes);
  49.243 -
  49.244 -    paging_update_paging_modes(v);
  49.245 -    return 0;
  49.246 -}
  49.247 -
  49.248 -enum { VMX_ASSIST_INVOKE = 0, VMX_ASSIST_RESTORE };
  49.249 -
  49.250 -static int vmx_assist(struct vcpu *v, int mode)
  49.251 -{
  49.252 -    struct vmx_assist_context c;
  49.253 -    struct hvm_hw_vpic *vpic = v->domain->arch.hvm_domain.vpic;
  49.254 -    u32 magic, cp;
  49.255 -
  49.256 -    if ( hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
  49.257 -                                  sizeof(magic)) )
  49.258 -    {
  49.259 -        gdprintk(XENLOG_ERR, "No vmxassist: can't execute real mode code\n");
  49.260 -        domain_crash(v->domain);
  49.261 -        return 0;
  49.262 -    }
  49.263 -
  49.264 -    if ( magic != VMXASSIST_MAGIC )
  49.265 -    {
  49.266 -        gdprintk(XENLOG_ERR, "vmxassist magic number not match\n");
  49.267 -        domain_crash(v->domain);
  49.268 -        return 0;
  49.269 -    }
  49.270 -
  49.271 -    switch ( mode ) {
  49.272 -        /*
  49.273 -         * Transfer control to vmxassist.
  49.274 -         * Store the current context in VMXASSIST_OLD_CONTEXT and load
  49.275 -         * the new VMXASSIST_NEW_CONTEXT context. This context was created
  49.276 -         * by vmxassist and will transfer control to it.
  49.277 -         */
  49.278 -    case VMX_ASSIST_INVOKE:
  49.279 -        /* save the old context */
  49.280 -        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)) )
  49.281 -            goto error;
  49.282 -        if ( cp != 0 ) {
  49.283 -            vmx_world_save(v, &c);
  49.284 -            if ( hvm_copy_to_guest_phys(cp, &c, sizeof(c)) )
  49.285 -                goto error;
  49.286 -        }
  49.287 -
  49.288 -        /* restore the new context, this should activate vmxassist */
  49.289 -        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp)) )
  49.290 -            goto error;
  49.291 -        if ( cp != 0 ) {
  49.292 -            if ( hvm_copy_from_guest_phys(&c, cp, sizeof(c)) )
  49.293 -                goto error;
  49.294 -            if ( vmx_world_restore(v, &c) != 0 )
  49.295 -                goto error;
  49.296 -            v->arch.hvm_vmx.pm_irqbase[0] = vpic[0].irq_base;
  49.297 -            v->arch.hvm_vmx.pm_irqbase[1] = vpic[1].irq_base;
  49.298 -            vpic[0].irq_base = NR_EXCEPTION_HANDLER;
  49.299 -            vpic[1].irq_base = NR_EXCEPTION_HANDLER + 8;
  49.300 -            v->arch.hvm_vmx.vmxassist_enabled = 1;
  49.301 -            return 1;
  49.302 -        }
  49.303 -        break;
  49.304 -
  49.305 -        /*
  49.306 -         * Restore the VMXASSIST_OLD_CONTEXT that was saved by
  49.307 -         * VMX_ASSIST_INVOKE above.
  49.308 -         */
  49.309 -    case VMX_ASSIST_RESTORE:
  49.310 -        /* save the old context */
  49.311 -        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)) )
  49.312 -            goto error;
  49.313 -        if ( cp != 0 ) {
  49.314 -            if ( hvm_copy_from_guest_phys(&c, cp, sizeof(c)) )
  49.315 -                goto error;
  49.316 -            if ( vmx_world_restore(v, &c) != 0 )
  49.317 -                goto error;
  49.318 -            if ( v->arch.hvm_vmx.irqbase_mode ) {
  49.319 -                vpic[0].irq_base = c.rm_irqbase[0] & 0xf8;
  49.320 -                vpic[1].irq_base = c.rm_irqbase[1] & 0xf8;
  49.321 -            } else {
  49.322 -                vpic[0].irq_base = v->arch.hvm_vmx.pm_irqbase[0];
  49.323 -                vpic[1].irq_base = v->arch.hvm_vmx.pm_irqbase[1];
  49.324 -            }
  49.325 -            v->arch.hvm_vmx.vmxassist_enabled = 0;
  49.326 -            return 1;
  49.327 -        }
  49.328 -        break;
  49.329 -    }
  49.330 -
  49.331 - error:
  49.332 -    gdprintk(XENLOG_ERR, "Failed to transfer to vmxassist\n");
  49.333 -    domain_crash(v->domain);
  49.334 -    return 0;
  49.335 -}
  49.336 -
  49.337 -static int vmx_set_cr0(unsigned long value)
  49.338 -{
  49.339 -    struct vcpu *v = current;
  49.340 -
  49.341 -    if ( hvm_set_cr0(value) == 0 )
  49.342 -        return 0;
  49.343 -
  49.344 -    /*
  49.345 -     * VMX does not implement real-mode virtualization. We emulate
  49.346 -     * real-mode by performing a world switch to VMXAssist whenever
  49.347 -     * a partition disables the CR0.PE bit.
  49.348 -     */
  49.349 -    if ( !(value & X86_CR0_PE) )
  49.350 -    {
  49.351 -        if ( vmx_assist(v, VMX_ASSIST_INVOKE) )
  49.352 -            return 0; /* do not update eip! */
  49.353 -    }
  49.354 -    else if ( v->arch.hvm_vmx.vmxassist_enabled )
  49.355 -    {
  49.356 -        if ( vmx_assist(v, VMX_ASSIST_RESTORE) )
  49.357 -            return 0; /* do not update eip! */
  49.358 -    }
  49.359 -
  49.360 -    return 1;
  49.361 -}
  49.362 -
  49.363 -#else /* !defined(VMXASSIST) */
  49.364 -
  49.365 -#define vmx_set_cr0(v) hvm_set_cr0(v)
  49.366 -
  49.367 -#endif
  49.368 -
  49.369  #define CASE_SET_REG(REG, reg)      \
  49.370      case REG_ ## REG: regs->reg = value; break
  49.371  #define CASE_GET_REG(REG, reg)      \
  49.372 @@ -2142,7 +1843,7 @@ static int mov_to_cr(int gp, int cr, str
  49.373      switch ( cr )
  49.374      {
  49.375      case 0:
  49.376 -        return vmx_set_cr0(value);
  49.377 +        return hvm_set_cr0(value);
  49.378  
  49.379      case 3:
  49.380          return hvm_set_cr3(value);
  49.381 @@ -2239,7 +1940,7 @@ static int vmx_cr_access(unsigned long e
  49.382          value = (value & ~0xF) |
  49.383              (((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
  49.384          HVMTRACE_1D(LMSW, current, value);
  49.385 -        return vmx_set_cr0(value);
  49.386 +        return hvm_set_cr0(value);
  49.387      default:
  49.388          BUG();
  49.389      }
    50.1 --- a/xen/arch/x86/hvm/vmx/vpmu.c	Thu Feb 07 09:23:26 2008 -0700
    50.2 +++ b/xen/arch/x86/hvm/vmx/vpmu.c	Thu Feb 07 11:08:49 2008 -0700
    50.3 @@ -89,8 +89,6 @@ void vpmu_initialise(struct vcpu *v)
    50.4          case 15:
    50.5          case 23:
    50.6              vpmu->arch_vpmu_ops = &core2_vpmu_ops;
    50.7 -            dprintk(XENLOG_INFO,
    50.8 -                   "Core 2 duo CPU detected for guest PMU usage.\n");
    50.9              break;
   50.10          }
   50.11      }
    51.1 --- a/xen/arch/x86/hvm/vmx/vpmu_core2.c	Thu Feb 07 09:23:26 2008 -0700
    51.2 +++ b/xen/arch/x86/hvm/vmx/vpmu_core2.c	Thu Feb 07 11:08:49 2008 -0700
    51.3 @@ -35,60 +35,69 @@
    51.4  #include <asm/hvm/vmx/vpmu.h>
    51.5  #include <asm/hvm/vmx/vpmu_core2.h>
    51.6  
    51.7 -static int arch_pmc_cnt = 0;
    51.8 +static int arch_pmc_cnt;
    51.9  
   51.10  static int core2_get_pmc_count(void)
   51.11  {
   51.12      u32 eax, ebx, ecx, edx;
   51.13  
   51.14 -    if ( arch_pmc_cnt )
   51.15 -        return arch_pmc_cnt;
   51.16 +    if ( arch_pmc_cnt == 0 )
   51.17 +    {
   51.18 +        cpuid(0xa, &eax, &ebx, &ecx, &edx);
   51.19 +        arch_pmc_cnt = (eax & 0xff00) >> 8;
   51.20 +    }
   51.21  
   51.22 -    cpuid(0xa, &eax, &ebx, &ecx, &edx);
   51.23 -    return arch_pmc_cnt = (eax & 0xff00) >> 8;
   51.24 +    return arch_pmc_cnt;
   51.25  }
   51.26  
   51.27  static int is_core2_vpmu_msr(u32 msr_index, int *type, int *index)
   51.28  {
   51.29      int i;
   51.30  
   51.31 -    for ( i=0; i < core2_counters.num; i++ )
   51.32 +    for ( i = 0; i < core2_counters.num; i++ )
   51.33 +    {
   51.34          if ( core2_counters.msr[i] == msr_index )
   51.35          {
   51.36              *type = MSR_TYPE_COUNTER;
   51.37              *index = i;
   51.38              return 1;
   51.39          }
   51.40 -    for ( i=0; i < core2_ctrls.num; i++ )
   51.41 +    }
   51.42 +    
   51.43 +    for ( i = 0; i < core2_ctrls.num; i++ )
   51.44 +    {
   51.45          if ( core2_ctrls.msr[i] == msr_index )
   51.46          {
   51.47              *type = MSR_TYPE_CTRL;
   51.48              *index = i;
   51.49              return 1;
   51.50          }
   51.51 +    }
   51.52  
   51.53 -    if ( msr_index == MSR_CORE_PERF_GLOBAL_CTRL ||
   51.54 -         msr_index == MSR_CORE_PERF_GLOBAL_STATUS ||
   51.55 -         msr_index == MSR_CORE_PERF_GLOBAL_OVF_CTRL )
   51.56 +    if ( (msr_index == MSR_CORE_PERF_GLOBAL_CTRL) ||
   51.57 +         (msr_index == MSR_CORE_PERF_GLOBAL_STATUS) ||
   51.58 +         (msr_index == MSR_CORE_PERF_GLOBAL_OVF_CTRL) )
   51.59      {
   51.60          *type = MSR_TYPE_GLOBAL;
   51.61          return 1;
   51.62      }
   51.63  
   51.64 -    if ( msr_index >= MSR_IA32_PERFCTR0 &&
   51.65 -         msr_index < MSR_IA32_PERFCTR0 + core2_get_pmc_count() )
   51.66 +    if ( (msr_index >= MSR_IA32_PERFCTR0) &&
   51.67 +         (msr_index < (MSR_IA32_PERFCTR0 + core2_get_pmc_count())) )
   51.68      {
   51.69          *type = MSR_TYPE_ARCH_COUNTER;
   51.70          *index = msr_index - MSR_IA32_PERFCTR0;
   51.71          return 1;
   51.72      }
   51.73 -    if ( msr_index >= MSR_P6_EVNTSEL0 &&
   51.74 -         msr_index < MSR_P6_EVNTSEL0 + core2_get_pmc_count() )
   51.75 +
   51.76 +    if ( (msr_index >= MSR_P6_EVNTSEL0) &&
   51.77 +         (msr_index < (MSR_P6_EVNTSEL0 + core2_get_pmc_count())) )
   51.78      {
   51.79          *type = MSR_TYPE_ARCH_CTRL;
   51.80          *index = msr_index - MSR_P6_EVNTSEL0;
   51.81          return 1;
   51.82      }
   51.83 +
   51.84      return 0;
   51.85  }
   51.86  
   51.87 @@ -97,20 +106,21 @@ static void core2_vpmu_set_msr_bitmap(ch
   51.88      int i;
   51.89  
   51.90      /* Allow Read/Write PMU Counters MSR Directly. */
   51.91 -    for ( i=0; i < core2_counters.num; i++ )
   51.92 +    for ( i = 0; i < core2_counters.num; i++ )
   51.93      {
   51.94          clear_bit(msraddr_to_bitpos(core2_counters.msr[i]), msr_bitmap);
   51.95 -        clear_bit(msraddr_to_bitpos(core2_counters.msr[i]), msr_bitmap + 0x800);
   51.96 +        clear_bit(msraddr_to_bitpos(core2_counters.msr[i]), msr_bitmap+0x800);
   51.97      }
   51.98 -    for ( i=0; i < core2_get_pmc_count(); i++ )
   51.99 +    for ( i = 0; i < core2_get_pmc_count(); i++ )
  51.100      {
  51.101          clear_bit(msraddr_to_bitpos(MSR_IA32_PERFCTR0+i), msr_bitmap);
  51.102 -        clear_bit(msraddr_to_bitpos(MSR_IA32_PERFCTR0+i), msr_bitmap + 0x800);
  51.103 +        clear_bit(msraddr_to_bitpos(MSR_IA32_PERFCTR0+i), msr_bitmap+0x800);
  51.104      }
  51.105 +
  51.106      /* Allow Read PMU Non-global Controls Directly. */
  51.107 -    for ( i=0; i < core2_ctrls.num; i++ )
  51.108 +    for ( i = 0; i < core2_ctrls.num; i++ )
  51.109          clear_bit(msraddr_to_bitpos(core2_ctrls.msr[i]), msr_bitmap);
  51.110 -    for ( i=0; i < core2_get_pmc_count(); i++ )
  51.111 +    for ( i = 0; i < core2_get_pmc_count(); i++ )
  51.112          clear_bit(msraddr_to_bitpos(MSR_P6_EVNTSEL0+i), msr_bitmap);
  51.113  }
  51.114  
  51.115 @@ -118,20 +128,19 @@ static void core2_vpmu_unset_msr_bitmap(
  51.116  {
  51.117      int i;
  51.118  
  51.119 -    /* Undo all the changes to msr bitmap. */
  51.120 -    for ( i=0; i < core2_counters.num; i++ )
  51.121 +    for ( i = 0; i < core2_counters.num; i++ )
  51.122      {
  51.123          set_bit(msraddr_to_bitpos(core2_counters.msr[i]), msr_bitmap);
  51.124 -        set_bit(msraddr_to_bitpos(core2_counters.msr[i]), msr_bitmap + 0x800);
  51.125 +        set_bit(msraddr_to_bitpos(core2_counters.msr[i]), msr_bitmap+0x800);
  51.126      }
  51.127 -    for ( i=0; i < core2_get_pmc_count(); i++ )
  51.128 +    for ( i = 0; i < core2_get_pmc_count(); i++ )
  51.129      {
  51.130          set_bit(msraddr_to_bitpos(MSR_IA32_PERFCTR0+i), msr_bitmap);
  51.131 -        set_bit(msraddr_to_bitpos(MSR_IA32_PERFCTR0+i), msr_bitmap + 0x800);
  51.132 +        set_bit(msraddr_to_bitpos(MSR_IA32_PERFCTR0+i), msr_bitmap+0x800);
  51.133      }
  51.134 -    for ( i=0; i < core2_ctrls.num; i++ )
  51.135 +    for ( i = 0; i < core2_ctrls.num; i++ )
  51.136          set_bit(msraddr_to_bitpos(core2_ctrls.msr[i]), msr_bitmap);
  51.137 -    for ( i=0; i < core2_get_pmc_count(); i++ )
  51.138 +    for ( i = 0; i < core2_get_pmc_count(); i++ )
  51.139          set_bit(msraddr_to_bitpos(MSR_P6_EVNTSEL0+i), msr_bitmap);
  51.140  }
  51.141  
  51.142 @@ -140,9 +149,9 @@ static inline void __core2_vpmu_save(str
  51.143      int i;
  51.144      struct core2_vpmu_context *core2_vpmu_cxt = vcpu_vpmu(v)->context;
  51.145  
  51.146 -    for ( i=0; i < core2_counters.num; i++ )
  51.147 +    for ( i = 0; i < core2_counters.num; i++ )
  51.148          rdmsrl(core2_counters.msr[i], core2_vpmu_cxt->counters[i]);
  51.149 -    for ( i=0; i < core2_get_pmc_count(); i++ )
  51.150 +    for ( i = 0; i < core2_get_pmc_count(); i++ )
  51.151          rdmsrl(MSR_IA32_PERFCTR0+i, core2_vpmu_cxt->arch_msr_pair[i].counter);
  51.152      core2_vpmu_cxt->hw_lapic_lvtpc = apic_read(APIC_LVTPC);
  51.153      apic_write(APIC_LVTPC, LVTPC_HVM_PMU | APIC_LVT_MASKED);
  51.154 @@ -171,14 +180,14 @@ static inline void __core2_vpmu_load(str
  51.155      int i;
  51.156      struct core2_vpmu_context *core2_vpmu_cxt = vcpu_vpmu(v)->context;
  51.157  
  51.158 -    for ( i=0; i < core2_counters.num; i++ )
  51.159 +    for ( i = 0; i < core2_counters.num; i++ )
  51.160          wrmsrl(core2_counters.msr[i], core2_vpmu_cxt->counters[i]);
  51.161 -    for ( i=0; i < core2_get_pmc_count(); i++ )
  51.162 +    for ( i = 0; i < core2_get_pmc_count(); i++ )
  51.163          wrmsrl(MSR_IA32_PERFCTR0+i, core2_vpmu_cxt->arch_msr_pair[i].counter);
  51.164  
  51.165 -    for ( i=0; i < core2_ctrls.num; i++ )
  51.166 +    for ( i = 0; i < core2_ctrls.num; i++ )
  51.167          wrmsrl(core2_ctrls.msr[i], core2_vpmu_cxt->ctrls[i]);
  51.168 -    for ( i=0; i < core2_get_pmc_count(); i++ )
  51.169 +    for ( i = 0; i < core2_get_pmc_count(); i++ )
  51.170          wrmsrl(MSR_P6_EVNTSEL0+i, core2_vpmu_cxt->arch_msr_pair[i].control);
  51.171  
  51.172      apic_write_around(APIC_LVTPC, core2_vpmu_cxt->hw_lapic_lvtpc);
  51.173 @@ -233,9 +242,9 @@ static int core2_vpmu_alloc_resource(str
  51.174   out2:
  51.175      xfree(pmu_enable);
  51.176   out1:
  51.177 -    dprintk(XENLOG_WARNING, "Insufficient memory for PMU, PMU feature is \
  51.178 -            unavailable on domain %d vcpu %d.\n",
  51.179 -            v->vcpu_id, v->domain->domain_id);
  51.180 +    gdprintk(XENLOG_WARNING, "Insufficient memory for PMU, PMU feature is "
  51.181 +             "unavailable on domain %d vcpu %d.\n",
  51.182 +             v->vcpu_id, v->domain->domain_id);
  51.183      return 0;
  51.184  }
  51.185  
  51.186 @@ -300,17 +309,17 @@ static int core2_vpmu_do_wrmsr(struct cp
  51.187          core2_vpmu_cxt->global_ovf_status &= ~msr_content;
  51.188          return 1;
  51.189      case MSR_CORE_PERF_GLOBAL_STATUS:
  51.190 -        dprintk(XENLOG_INFO, "Can not write readonly MSR: \
  51.191 -                            MSR_PERF_GLOBAL_STATUS(0x38E)!\n");
  51.192 +        gdprintk(XENLOG_INFO, "Can not write readonly MSR: "
  51.193 +                 "MSR_PERF_GLOBAL_STATUS(0x38E)!\n");
  51.194          vmx_inject_hw_exception(current, TRAP_gp_fault, 0);
  51.195          return 1;
  51.196      case MSR_IA32_PEBS_ENABLE:
  51.197          if ( msr_content & 1 )
  51.198 -            dprintk(XENLOG_WARNING, "Guest is trying to enable PEBS, \
  51.199 -                    which is not supported.\n");
  51.200 +            gdprintk(XENLOG_WARNING, "Guest is trying to enable PEBS, "
  51.201 +                     "which is not supported.\n");
  51.202          return 1;
  51.203      case MSR_IA32_DS_AREA:
  51.204 -        dprintk(XENLOG_WARNING, "Guest setting of DTS is ignored.\n");
  51.205 +        gdprintk(XENLOG_WARNING, "Guest setting of DTS is ignored.\n");
  51.206          return 1;
  51.207      case MSR_CORE_PERF_GLOBAL_CTRL:
  51.208          global_ctrl = msr_content;
  51.209 @@ -466,4 +475,3 @@ struct arch_vpmu_ops core2_vpmu_ops = {
  51.210      .arch_vpmu_save = core2_vpmu_save,
  51.211      .arch_vpmu_load = core2_vpmu_load
  51.212  };
  51.213 -
    52.1 --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S	Thu Feb 07 09:23:26 2008 -0700
    52.2 +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S	Thu Feb 07 11:08:49 2008 -0700
    52.3 @@ -115,10 +115,8 @@ ENTRY(vmx_asm_do_vmentry)
    52.4          movl $GUEST_RFLAGS,%eax
    52.5          VMWRITE(UREGS_eflags)
    52.6  
    52.7 -#ifndef VMXASSIST
    52.8 -        testb $X86_CR0_PE,VCPU_hvm_guest_cr0(%ebx)
    52.9 -        jz   vmx_goto_realmode
   52.10 -#endif
   52.11 +        testb $0xff,VCPU_vmx_emul(%ebx)
   52.12 +        jnz  vmx_goto_realmode
   52.13  
   52.14          cmpb $0,VCPU_vmx_launched(%ebx)
   52.15          je   vmx_launch
   52.16 @@ -138,7 +136,6 @@ vmx_launch:
   52.17          call vm_launch_fail
   52.18          ud2
   52.19  
   52.20 -#ifndef VMXASSIST
   52.21  vmx_goto_realmode:
   52.22          sti
   52.23          movl %esp,%eax
   52.24 @@ -146,4 +143,3 @@ vmx_goto_realmode:
   52.25          call vmx_realmode
   52.26          addl $4,%esp
   52.27          jmp vmx_asm_do_vmentry
   52.28 -#endif
    53.1 --- a/xen/arch/x86/hvm/vmx/x86_64/exits.S	Thu Feb 07 09:23:26 2008 -0700
    53.2 +++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S	Thu Feb 07 11:08:49 2008 -0700
    53.3 @@ -134,10 +134,8 @@ ENTRY(vmx_asm_do_vmentry)
    53.4          movl $GUEST_RFLAGS,%eax
    53.5          VMWRITE(UREGS_eflags)
    53.6  
    53.7 -#ifndef VMXASSIST
    53.8 -        testb $X86_CR0_PE,VCPU_hvm_guest_cr0(%rbx)
    53.9 -        jz   vmx_goto_realmode
   53.10 -#endif
   53.11 +        testb $0xff,VCPU_vmx_emul(%rbx)
   53.12 +        jnz  vmx_goto_realmode
   53.13  
   53.14          cmpb $0,VCPU_vmx_launched(%rbx)
   53.15          je   vmx_launch
   53.16 @@ -157,10 +155,8 @@ vmx_launch:
   53.17          call vm_launch_fail
   53.18          ud2
   53.19  
   53.20 -#ifndef VMXASSIST
   53.21  vmx_goto_realmode:
   53.22          sti
   53.23          movq %rsp,%rdi
   53.24          call vmx_realmode
   53.25          jmp vmx_asm_do_vmentry
   53.26 -#endif
    54.1 --- a/xen/arch/x86/hvm/vpic.c	Thu Feb 07 09:23:26 2008 -0700
    54.2 +++ b/xen/arch/x86/hvm/vpic.c	Thu Feb 07 11:08:49 2008 -0700
    54.3 @@ -271,11 +271,6 @@ static void vpic_ioport_write(
    54.4              vpic->imr = val;
    54.5              break;
    54.6          case 1:
    54.7 -#ifdef VMXASSIST
    54.8 -            /* Which mode is irqbase programmed in? */
    54.9 -            current->arch.hvm_vmx.irqbase_mode =
   54.10 -                current->arch.hvm_vmx.vmxassist_enabled;
   54.11 -#endif
   54.12              /* ICW2 */
   54.13              vpic->irq_base = val & 0xf8;
   54.14              vpic->init_state++;
    55.1 --- a/xen/arch/x86/mm/shadow/common.c	Thu Feb 07 09:23:26 2008 -0700
    55.2 +++ b/xen/arch/x86/mm/shadow/common.c	Thu Feb 07 11:08:49 2008 -0700
    55.3 @@ -176,6 +176,8 @@ hvm_emulate_read(enum x86_segment seg,
    55.4                   unsigned int bytes,
    55.5                   struct x86_emulate_ctxt *ctxt)
    55.6  {
    55.7 +    if ( !is_x86_user_segment(seg) )
    55.8 +        return X86EMUL_UNHANDLEABLE;
    55.9      return hvm_read(seg, offset, val, bytes, hvm_access_read,
   55.10                      container_of(ctxt, struct sh_emulate_ctxt, ctxt));
   55.11  }
   55.12 @@ -191,6 +193,8 @@ hvm_emulate_insn_fetch(enum x86_segment 
   55.13          container_of(ctxt, struct sh_emulate_ctxt, ctxt);
   55.14      unsigned int insn_off = offset - sh_ctxt->insn_buf_eip;
   55.15  
   55.16 +    ASSERT(seg == x86_seg_cs);
   55.17 +
   55.18      /* Fall back if requested bytes are not in the prefetch cache. */
   55.19      if ( unlikely((insn_off + bytes) > sh_ctxt->insn_buf_bytes) )
   55.20          return hvm_read(seg, offset, val, bytes,
   55.21 @@ -215,6 +219,9 @@ hvm_emulate_write(enum x86_segment seg,
   55.22      unsigned long addr;
   55.23      int rc;
   55.24  
   55.25 +    if ( !is_x86_user_segment(seg) )
   55.26 +        return X86EMUL_UNHANDLEABLE;
   55.27 +
   55.28      /* How many emulations could we save if we unshadowed on stack writes? */
   55.29      if ( seg == x86_seg_ss )
   55.30          perfc_incr(shadow_fault_emulate_stack);
   55.31 @@ -242,6 +249,9 @@ hvm_emulate_cmpxchg(enum x86_segment seg
   55.32      unsigned long addr;
   55.33      int rc;
   55.34  
   55.35 +    if ( !is_x86_user_segment(seg) )
   55.36 +        return X86EMUL_UNHANDLEABLE;
   55.37 +
   55.38      rc = hvm_translate_linear_addr(
   55.39          seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
   55.40      if ( rc )
   55.41 @@ -266,6 +276,9 @@ hvm_emulate_cmpxchg8b(enum x86_segment s
   55.42      unsigned long addr;
   55.43      int rc;
   55.44  
   55.45 +    if ( !is_x86_user_segment(seg) )
   55.46 +        return X86EMUL_UNHANDLEABLE;
   55.47 +
   55.48      rc = hvm_translate_linear_addr(
   55.49          seg, offset, 8, hvm_access_write, sh_ctxt, &addr);
   55.50      if ( rc )
   55.51 @@ -292,6 +305,9 @@ pv_emulate_read(enum x86_segment seg,
   55.52  {
   55.53      unsigned int rc;
   55.54  
   55.55 +    if ( !is_x86_user_segment(seg) )
   55.56 +        return X86EMUL_UNHANDLEABLE;
   55.57 +
   55.58      *val = 0;
   55.59      if ( (rc = copy_from_user((void *)val, (void *)offset, bytes)) != 0 )
   55.60      {
   55.61 @@ -312,6 +328,8 @@ pv_emulate_write(enum x86_segment seg,
   55.62      struct sh_emulate_ctxt *sh_ctxt =
   55.63          container_of(ctxt, struct sh_emulate_ctxt, ctxt);
   55.64      struct vcpu *v = current;
   55.65 +    if ( !is_x86_user_segment(seg) )
   55.66 +        return X86EMUL_UNHANDLEABLE;
   55.67      return v->arch.paging.mode->shadow.x86_emulate_write(
   55.68          v, offset, &val, bytes, sh_ctxt);
   55.69  }
   55.70 @@ -327,6 +345,8 @@ pv_emulate_cmpxchg(enum x86_segment seg,
   55.71      struct sh_emulate_ctxt *sh_ctxt =
   55.72          container_of(ctxt, struct sh_emulate_ctxt, ctxt);
   55.73      struct vcpu *v = current;
   55.74 +    if ( !is_x86_user_segment(seg) )
   55.75 +        return X86EMUL_UNHANDLEABLE;
   55.76      return v->arch.paging.mode->shadow.x86_emulate_cmpxchg(
   55.77          v, offset, old, new, bytes, sh_ctxt);
   55.78  }
   55.79 @@ -343,6 +363,8 @@ pv_emulate_cmpxchg8b(enum x86_segment se
   55.80      struct sh_emulate_ctxt *sh_ctxt =
   55.81          container_of(ctxt, struct sh_emulate_ctxt, ctxt);
   55.82      struct vcpu *v = current;
   55.83 +    if ( !is_x86_user_segment(seg) )
   55.84 +        return X86EMUL_UNHANDLEABLE;
   55.85      return v->arch.paging.mode->shadow.x86_emulate_cmpxchg8b(
   55.86          v, offset, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
   55.87  }
    56.1 --- a/xen/arch/x86/x86_32/asm-offsets.c	Thu Feb 07 09:23:26 2008 -0700
    56.2 +++ b/xen/arch/x86/x86_32/asm-offsets.c	Thu Feb 07 11:08:49 2008 -0700
    56.3 @@ -84,7 +84,7 @@ void __dummy__(void)
    56.4      BLANK();
    56.5  
    56.6      OFFSET(VCPU_vmx_launched, struct vcpu, arch.hvm_vmx.launched);
    56.7 -    OFFSET(VCPU_hvm_guest_cr0, struct vcpu, arch.hvm_vcpu.guest_cr[0]);
    56.8 +    OFFSET(VCPU_vmx_emul, struct vcpu, arch.hvm_vmx.vmxemul);
    56.9      OFFSET(VCPU_hvm_guest_cr2, struct vcpu, arch.hvm_vcpu.guest_cr[2]);
   56.10      BLANK();
   56.11  
    57.1 --- a/xen/arch/x86/x86_64/asm-offsets.c	Thu Feb 07 09:23:26 2008 -0700
    57.2 +++ b/xen/arch/x86/x86_64/asm-offsets.c	Thu Feb 07 11:08:49 2008 -0700
    57.3 @@ -103,7 +103,7 @@ void __dummy__(void)
    57.4      BLANK();
    57.5  
    57.6      OFFSET(VCPU_vmx_launched, struct vcpu, arch.hvm_vmx.launched);
    57.7 -    OFFSET(VCPU_hvm_guest_cr0, struct vcpu, arch.hvm_vcpu.guest_cr[0]);
    57.8 +    OFFSET(VCPU_vmx_emul, struct vcpu, arch.hvm_vmx.vmxemul);
    57.9      OFFSET(VCPU_hvm_guest_cr2, struct vcpu, arch.hvm_vcpu.guest_cr[2]);
   57.10      BLANK();
   57.11  
    58.1 --- a/xen/arch/x86/x86_emulate.c	Thu Feb 07 09:23:26 2008 -0700
    58.2 +++ b/xen/arch/x86/x86_emulate.c	Thu Feb 07 11:08:49 2008 -0700
    58.3 @@ -303,7 +303,11 @@ struct operand {
    58.4  #define EXC_OF  4
    58.5  #define EXC_BR  5
    58.6  #define EXC_UD  6
    58.7 +#define EXC_TS 10
    58.8 +#define EXC_NP 11
    58.9 +#define EXC_SS 12
   58.10  #define EXC_GP 13
   58.11 +#define EXC_PF 14
   58.12  
   58.13  /*
   58.14   * Instruction emulation:
   58.15 @@ -500,12 +504,12 @@ do {                                    
   58.16      if ( rc ) goto done;                                \
   58.17  } while (0)
   58.18  
   58.19 -#define generate_exception_if(p, e)                                     \
   58.20 -({  if ( (p) ) {                                                        \
   58.21 -        fail_if(ops->inject_hw_exception == NULL);                      \
   58.22 -        rc = ops->inject_hw_exception(e, ctxt) ? : X86EMUL_EXCEPTION;   \
   58.23 -        goto done;                                                      \
   58.24 -    }                                                                   \
   58.25 +#define generate_exception_if(p, e)                                      \
   58.26 +({  if ( (p) ) {                                                         \
   58.27 +        fail_if(ops->inject_hw_exception == NULL);                       \
   58.28 +        rc = ops->inject_hw_exception(e, 0, ctxt) ? : X86EMUL_EXCEPTION; \
   58.29 +        goto done;                                                       \
   58.30 +    }                                                                    \
   58.31  })
   58.32  
   58.33  /*
   58.34 @@ -546,7 +550,8 @@ do {                                    
   58.35  
   58.36  #define jmp_rel(rel)                                                    \
   58.37  do {                                                                    \
   58.38 -    _regs.eip += (int)(rel);                                            \
   58.39 +    int _rel = (int)(rel);                                              \
   58.40 +    _regs.eip += _rel;                                                  \
   58.41      if ( !mode_64bit() )                                                \
   58.42          _regs.eip = ((op_bytes == 2)                                    \
   58.43                       ? (uint16_t)_regs.eip : (uint32_t)_regs.eip);      \
   58.44 @@ -774,7 +779,7 @@ in_realmode(
   58.45  }
   58.46  
   58.47  static int
   58.48 -load_seg(
   58.49 +realmode_load_seg(
   58.50      enum x86_segment seg,
   58.51      uint16_t sel,
   58.52      struct x86_emulate_ctxt *ctxt,
   58.53 @@ -783,11 +788,6 @@ load_seg(
   58.54      struct segment_register reg;
   58.55      int rc;
   58.56  
   58.57 -    if ( !in_realmode(ctxt, ops) ||
   58.58 -         (ops->read_segment == NULL) ||
   58.59 -         (ops->write_segment == NULL) )
   58.60 -        return X86EMUL_UNHANDLEABLE;
   58.61 -
   58.62      if ( (rc = ops->read_segment(seg, &reg, ctxt)) != 0 )
   58.63          return rc;
   58.64  
   58.65 @@ -797,6 +797,148 @@ load_seg(
   58.66      return ops->write_segment(seg, &reg, ctxt);
   58.67  }
   58.68  
   58.69 +static int
   58.70 +protmode_load_seg(
   58.71 +    enum x86_segment seg,
   58.72 +    uint16_t sel,
   58.73 +    struct x86_emulate_ctxt *ctxt,
   58.74 +    struct x86_emulate_ops *ops)
   58.75 +{
   58.76 +    struct segment_register desctab, cs, segr;
   58.77 +    struct { uint32_t a, b; } desc;
   58.78 +    unsigned long val;
   58.79 +    uint8_t dpl, rpl, cpl;
   58.80 +    int rc, fault_type = EXC_TS;
   58.81 +
   58.82 +    /* NULL selector? */
   58.83 +    if ( (sel & 0xfffc) == 0 )
   58.84 +    {
   58.85 +        if ( (seg == x86_seg_cs) || (seg == x86_seg_ss) )
   58.86 +            goto raise_exn;
   58.87 +        memset(&segr, 0, sizeof(segr));
   58.88 +        return ops->write_segment(seg, &segr, ctxt);
   58.89 +    }
   58.90 +
   58.91 +    /* LDT descriptor must be in the GDT. */
   58.92 +    if ( (seg == x86_seg_ldtr) && (sel & 4) )
   58.93 +        goto raise_exn;
   58.94 +
   58.95 +    if ( (rc = ops->read_segment(x86_seg_cs, &cs, ctxt)) ||
   58.96 +         (rc = ops->read_segment((sel & 4) ? x86_seg_ldtr : x86_seg_gdtr,
   58.97 +                                 &desctab, ctxt)) )
   58.98 +        return rc;
   58.99 +
  58.100 +    /* Check against descriptor table limit. */
  58.101 +    if ( ((sel & 0xfff8) + 7) > desctab.limit )
  58.102 +        goto raise_exn;
  58.103 +
  58.104 +    do {
  58.105 +        if ( (rc = ops->read(x86_seg_none, desctab.base + (sel & 0xfff8),
  58.106 +                             &val, 4, ctxt)) )
  58.107 +            return rc;
  58.108 +        desc.a = val;
  58.109 +        if ( (rc = ops->read(x86_seg_none, desctab.base + (sel & 0xfff8) + 4,
  58.110 +                             &val, 4, ctxt)) )
  58.111 +            return rc;
  58.112 +        desc.b = val;
  58.113 +
  58.114 +        /* Segment present in memory? */
  58.115 +        if ( !(desc.b & (1u<<15)) )
  58.116 +        {
  58.117 +            fault_type = EXC_NP;
  58.118 +            goto raise_exn;
  58.119 +        }
  58.120 +
  58.121 +        /* LDT descriptor is a system segment. All others are code/data. */
  58.122 +        if ( (desc.b & (1u<<12)) == ((seg == x86_seg_ldtr) << 12) )
  58.123 +            goto raise_exn;
  58.124 +
  58.125 +        dpl = (desc.b >> 13) & 3;
  58.126 +        rpl = sel & 3;
  58.127 +        cpl = cs.sel & 3;
  58.128 +
  58.129 +        switch ( seg )
  58.130 +        {
  58.131 +        case x86_seg_cs:
  58.132 +            /* Code segment? */
  58.133 +            if ( !(desc.b & (1u<<11)) )
  58.134 +                goto raise_exn;
  58.135 +            /* Non-conforming segment: check DPL against RPL. */
  58.136 +            if ( ((desc.b & (6u<<9)) != 6) && (dpl != rpl) )
  58.137 +                goto raise_exn;
  58.138 +            break;
  58.139 +        case x86_seg_ss:
  58.140 +            /* Writable data segment? */
  58.141 +            if ( (desc.b & (5u<<9)) != (1u<<9) )
  58.142 +                goto raise_exn;
  58.143 +            if ( (dpl != cpl) || (dpl != rpl) )
  58.144 +                goto raise_exn;
  58.145 +            break;
  58.146 +        case x86_seg_ldtr:
  58.147 +            /* LDT system segment? */
  58.148 +            if ( (desc.b & (15u<<8)) != (2u<<8) )
  58.149 +                goto raise_exn;
  58.150 +            goto skip_accessed_flag;
  58.151 +        default:
  58.152 +            /* Readable code or data segment? */
  58.153 +            if ( (desc.b & (5u<<9)) == (4u<<9) )
  58.154 +                goto raise_exn;
  58.155 +            /* Non-conforming segment: check DPL against RPL and CPL. */
  58.156 +            if ( ((desc.b & (6u<<9)) != 6) && ((dpl < cpl) || (dpl < rpl)) )
  58.157 +                goto raise_exn;
  58.158 +            break;
  58.159 +        }
  58.160 +
  58.161 +        /* Ensure Accessed flag is set. */
  58.162 +        rc = ((desc.b & 0x100) ? X86EMUL_OKAY : 
  58.163 +              ops->cmpxchg(
  58.164 +                  x86_seg_none, desctab.base + (sel & 0xfff8) + 4, desc.b,
  58.165 +                  desc.b | 0x100, 4, ctxt));
  58.166 +    } while ( rc == X86EMUL_CMPXCHG_FAILED );
  58.167 +
  58.168 +    if ( rc )
  58.169 +        return rc;
  58.170 +
  58.171 +    /* Force the Accessed flag in our local copy. */
  58.172 +    desc.b |= 0x100;
  58.173 +
  58.174 + skip_accessed_flag:
  58.175 +    segr.base = (((desc.b <<  0) & 0xff000000u) |
  58.176 +                 ((desc.b << 16) & 0x00ff0000u) |
  58.177 +                 ((desc.a >> 16) & 0x0000ffffu));
  58.178 +    segr.attr.bytes = (((desc.b >>  8) & 0x00ffu) |
  58.179 +                       ((desc.b >> 12) & 0x0f00u));
  58.180 +    segr.limit = (desc.b & 0x000f0000u) | (desc.a & 0x0000ffffu);
  58.181 +    if ( segr.attr.fields.g )
  58.182 +        segr.limit = (segr.limit << 12) | 0xfffu;
  58.183 +    segr.sel = sel;
  58.184 +    return ops->write_segment(seg, &segr, ctxt);
  58.185 +
  58.186 + raise_exn:
  58.187 +    if ( ops->inject_hw_exception == NULL )
  58.188 +        return X86EMUL_UNHANDLEABLE;
  58.189 +    if ( (rc = ops->inject_hw_exception(fault_type, sel & 0xfffc, ctxt)) )
  58.190 +        return rc;
  58.191 +    return X86EMUL_EXCEPTION;
  58.192 +}
  58.193 +
  58.194 +static int
  58.195 +load_seg(
  58.196 +    enum x86_segment seg,
  58.197 +    uint16_t sel,
  58.198 +    struct x86_emulate_ctxt *ctxt,
  58.199 +    struct x86_emulate_ops *ops)
  58.200 +{
  58.201 +    if ( (ops->read_segment == NULL) ||
  58.202 +         (ops->write_segment == NULL) )
  58.203 +        return X86EMUL_UNHANDLEABLE;
  58.204 +
  58.205 +    if ( in_realmode(ctxt, ops) )
  58.206 +        return realmode_load_seg(seg, sel, ctxt, ops);
  58.207 +
  58.208 +    return protmode_load_seg(seg, sel, ctxt, ops);
  58.209 +}
  58.210 +
  58.211  void *
  58.212  decode_register(
  58.213      uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs)
  58.214 @@ -1858,7 +2000,7 @@ x86_emulate(
  58.215      if ( (_regs.eflags & EFLG_TF) &&
  58.216           (rc == X86EMUL_OKAY) &&
  58.217           (ops->inject_hw_exception != NULL) )
  58.218 -        rc = ops->inject_hw_exception(EXC_DB, ctxt) ? : X86EMUL_EXCEPTION;
  58.219 +        rc = ops->inject_hw_exception(EXC_DB, 0, ctxt) ? : X86EMUL_EXCEPTION;
  58.220  
  58.221   done:
  58.222      return rc;
  58.223 @@ -2226,7 +2368,7 @@ x86_emulate(
  58.224      }
  58.225  
  58.226      case 0x9e: /* sahf */
  58.227 -        *(uint8_t *)_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02;
  58.228 +        *(uint8_t *)&_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02;
  58.229          break;
  58.230  
  58.231      case 0x9f: /* lahf */
  58.232 @@ -2644,9 +2786,11 @@ x86_emulate(
  58.233          break;
  58.234      }
  58.235  
  58.236 -    case 0xeb: /* jmp (short) */
  58.237 -        jmp_rel(insn_fetch_type(int8_t));
  58.238 +    case 0xeb: /* jmp (short) */ {
  58.239 +        int rel = insn_fetch_type(int8_t);
  58.240 +        jmp_rel(rel);
  58.241          break;
  58.242 +    }
  58.243  
  58.244      case 0xf1: /* int1 (icebp) */
  58.245          src.val = EXC_DB;
    59.1 --- a/xen/include/asm-x86/hvm/vmx/cpu.h	Thu Feb 07 09:23:26 2008 -0700
    59.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.3 @@ -1,32 +0,0 @@
    59.4 -/*
    59.5 - * cpu.h: Virtual CPU state
    59.6 - * Copyright (c) 2004, Intel Corporation.
    59.7 - *
    59.8 - * This program is free software; you can redistribute it and/or modify it
    59.9 - * under the terms and conditions of the GNU General Public License,
   59.10 - * version 2, as published by the Free Software Foundation.
   59.11 - *
   59.12 - * This program is distributed in the hope it will be useful, but WITHOUT
   59.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   59.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   59.15 - * more details.
   59.16 - *
   59.17 - * You should have received a copy of the GNU General Public License along with
   59.18 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   59.19 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   59.20 - *
   59.21 - */
   59.22 -#ifndef __ASM_X86_HVM_VMX_CPU_H__
   59.23 -#define __ASM_X86_HVM_VMX_CPU_H__
   59.24 -
   59.25 -#define NUM_CORES_RESET_MASK                 0x00003FFF
   59.26 -#define NUM_THREADS_RESET_MASK               0xFF00FFFF
   59.27 -
   59.28 -#define VMX_VCPU_CPUID_L1_ECX_RESERVED_18    0x00040000
   59.29 -#define VMX_VCPU_CPUID_L1_ECX_RESERVED_6     0x00000040
   59.30 -
   59.31 -#define VMX_VCPU_CPUID_L1_ECX_RESERVED              \
   59.32 -            ( VMX_VCPU_CPUID_L1_ECX_RESERVED_18 |   \
   59.33 -              VMX_VCPU_CPUID_L1_ECX_RESERVED_6 )
   59.34 -
   59.35 -#endif /* __ASM_X86_HVM_VMX_CPU_H__ */
    60.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu Feb 07 09:23:26 2008 -0700
    60.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu Feb 07 11:08:49 2008 -0700
    60.3 @@ -21,13 +21,8 @@
    60.4  
    60.5  #include <asm/config.h>
    60.6  #include <asm/hvm/io.h>
    60.7 -#include <asm/hvm/vmx/cpu.h>
    60.8  #include <asm/hvm/vmx/vpmu.h>
    60.9  
   60.10 -#ifdef VMXASSIST
   60.11 -#include <public/hvm/vmx_assist.h>
   60.12 -#endif
   60.13 -
   60.14  extern void start_vmx(void);
   60.15  extern void vmcs_dump_vcpu(struct vcpu *v);
   60.16  extern void setup_vmcs_dump(void);
   60.17 @@ -94,15 +89,16 @@ struct arch_vmx_struct {
   60.18  
   60.19      unsigned long        host_cr0;
   60.20  
   60.21 -#ifdef VMXASSIST
   60.22 -    unsigned long        vmxassist_enabled:1;
   60.23 -    unsigned long        irqbase_mode:1;
   60.24 -    unsigned char        pm_irqbase[2];
   60.25 -#else
   60.26 +    /* Are we emulating rather than VMENTERing? */
   60.27 +#define VMXEMUL_REALMODE 1  /* Yes, because CR0.PE == 0   */
   60.28 +#define VMXEMUL_BAD_CS   2  /* Yes, because CS.RPL != CPL */
   60.29 +#define VMXEMUL_BAD_SS   4  /* Yes, because SS.RPL != CPL */
   60.30 +    uint8_t              vmxemul;
   60.31 +
   60.32 +    /* I/O request in flight to device model. */
   60.33      bool_t               real_mode_io_in_progress;
   60.34      bool_t               real_mode_io_completed;
   60.35      unsigned long        real_mode_io_data;
   60.36 -#endif
   60.37  };
   60.38  
   60.39  int vmx_create_vmcs(struct vcpu *v);
    61.1 --- a/xen/include/asm-x86/x86_emulate.h	Thu Feb 07 09:23:26 2008 -0700
    61.2 +++ b/xen/include/asm-x86/x86_emulate.h	Thu Feb 07 11:08:49 2008 -0700
    61.3 @@ -39,9 +39,18 @@ enum x86_segment {
    61.4      x86_seg_tr,
    61.5      x86_seg_ldtr,
    61.6      x86_seg_gdtr,
    61.7 -    x86_seg_idtr
    61.8 +    x86_seg_idtr,
    61.9 +    /*
   61.10 +     * Dummy: used to emulate direct processor accesses to management
   61.11 +     * structures (TSS, GDT, LDT, IDT, etc.) which use linear addressing
   61.12 +     * (no segment component) and bypass usual segment- and page-level
   61.13 +     * protection checks.
   61.14 +     */
   61.15 +    x86_seg_none
   61.16  };
   61.17  
   61.18 +#define is_x86_user_segment(seg) ((unsigned)(seg) <= x86_seg_gs)
   61.19 +
   61.20  /* 
   61.21   * Attribute for segment selector. This is a copy of bit 40:47 & 52:55 of the
   61.22   * segment descriptor. It happens to match the format of an AMD SVM VMCB.
   61.23 @@ -333,6 +342,7 @@ struct x86_emulate_ops
   61.24      /* inject_hw_exception */
   61.25      int (*inject_hw_exception)(
   61.26          uint8_t vector,
   61.27 +        uint16_t error_code,
   61.28          struct x86_emulate_ctxt *ctxt);
   61.29  
   61.30      /* inject_sw_interrupt */
    62.1 --- a/xen/include/public/hvm/vmx_assist.h	Thu Feb 07 09:23:26 2008 -0700
    62.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.3 @@ -1,122 +0,0 @@
    62.4 -/*
    62.5 - * vmx_assist.h: Context definitions for the VMXASSIST world switch.
    62.6 - *
    62.7 - * Permission is hereby granted, free of charge, to any person obtaining a copy
    62.8 - * of this software and associated documentation files (the "Software"), to
    62.9 - * deal in the Software without restriction, including without limitation the
   62.10 - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   62.11 - * sell copies of the Software, and to permit persons to whom the Software is
   62.12 - * furnished to do so, subject to the following conditions:
   62.13 - *
   62.14 - * The above copyright notice and this permission notice shall be included in
   62.15 - * all copies or substantial portions of the Software.
   62.16 - *
   62.17 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   62.18 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   62.19 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   62.20 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   62.21 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   62.22 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   62.23 - * DEALINGS IN THE SOFTWARE.
   62.24 - *
   62.25 - * Leendert van Doorn, leendert@watson.ibm.com
   62.26 - * Copyright (c) 2005, International Business Machines Corporation.
   62.27 - */
   62.28 -
   62.29 -#ifndef _VMX_ASSIST_H_
   62.30 -#define _VMX_ASSIST_H_
   62.31 -
   62.32 -#define VMXASSIST_BASE         0xD0000
   62.33 -#define VMXASSIST_MAGIC        0x17101966
   62.34 -#define VMXASSIST_MAGIC_OFFSET (VMXASSIST_BASE+8)
   62.35 -
   62.36 -#define VMXASSIST_NEW_CONTEXT (VMXASSIST_BASE + 12)
   62.37 -#define VMXASSIST_OLD_CONTEXT (VMXASSIST_NEW_CONTEXT + 4)
   62.38 -
   62.39 -#ifndef __ASSEMBLY__
   62.40 -
   62.41 -#define NR_EXCEPTION_HANDLER    32
   62.42 -#define NR_INTERRUPT_HANDLERS   16
   62.43 -#define NR_TRAPS        (NR_EXCEPTION_HANDLER+NR_INTERRUPT_HANDLERS)
   62.44 -
   62.45 -union vmcs_arbytes {
   62.46 -    struct arbyte_fields {
   62.47 -        unsigned int seg_type : 4,
   62.48 -            s         : 1,
   62.49 -            dpl       : 2,
   62.50 -            p         : 1,
   62.51 -            reserved0 : 4,
   62.52 -            avl       : 1,
   62.53 -            reserved1 : 1,
   62.54 -            default_ops_size: 1,
   62.55 -            g         : 1,
   62.56 -            null_bit  : 1,
   62.57 -            reserved2 : 15;
   62.58 -    } fields;
   62.59 -    unsigned int bytes;
   62.60 -};
   62.61 -
   62.62 -/*
   62.63 - * World switch state
   62.64 - */
   62.65 -struct vmx_assist_context {
   62.66 -    uint32_t  eip;        /* execution pointer */
   62.67 -    uint32_t  esp;        /* stack pointer */
   62.68 -    uint32_t  eflags;     /* flags register */
   62.69 -    uint32_t  cr0;
   62.70 -    uint32_t  cr3;        /* page table directory */
   62.71 -    uint32_t  cr4;
   62.72 -    uint32_t  idtr_limit; /* idt */
   62.73 -    uint32_t  idtr_base;
   62.74 -    uint32_t  gdtr_limit; /* gdt */
   62.75 -    uint32_t  gdtr_base;
   62.76 -    uint32_t  cs_sel;     /* cs selector */
   62.77 -    uint32_t  cs_limit;
   62.78 -    uint32_t  cs_base;
   62.79 -    union vmcs_arbytes cs_arbytes;
   62.80 -    uint32_t  ds_sel;     /* ds selector */
   62.81 -    uint32_t  ds_limit;
   62.82 -    uint32_t  ds_base;
   62.83 -    union vmcs_arbytes ds_arbytes;
   62.84 -    uint32_t  es_sel;     /* es selector */
   62.85 -    uint32_t  es_limit;
   62.86 -    uint32_t  es_base;
   62.87 -    union vmcs_arbytes es_arbytes;
   62.88 -    uint32_t  ss_sel;     /* ss selector */
   62.89 -    uint32_t  ss_limit;
   62.90 -    uint32_t  ss_base;
   62.91 -    union vmcs_arbytes ss_arbytes;
   62.92 -    uint32_t  fs_sel;     /* fs selector */
   62.93 -    uint32_t  fs_limit;
   62.94 -    uint32_t  fs_base;
   62.95 -    union vmcs_arbytes fs_arbytes;
   62.96 -    uint32_t  gs_sel;     /* gs selector */
   62.97 -    uint32_t  gs_limit;
   62.98 -    uint32_t  gs_base;
   62.99 -    union vmcs_arbytes gs_arbytes;
  62.100 -    uint32_t  tr_sel;     /* task selector */
  62.101 -    uint32_t  tr_limit;
  62.102 -    uint32_t  tr_base;
  62.103 -    union vmcs_arbytes tr_arbytes;
  62.104 -    uint32_t  ldtr_sel;   /* ldtr selector */
  62.105 -    uint32_t  ldtr_limit;
  62.106 -    uint32_t  ldtr_base;
  62.107 -    union vmcs_arbytes ldtr_arbytes;
  62.108 -
  62.109 -    unsigned char rm_irqbase[2];
  62.110 -};
  62.111 -typedef struct vmx_assist_context vmx_assist_context_t;
  62.112 -
  62.113 -#endif /* __ASSEMBLY__ */
  62.114 -
  62.115 -#endif /* _VMX_ASSIST_H_ */
  62.116 -
  62.117 -/*
  62.118 - * Local variables:
  62.119 - * mode: C
  62.120 - * c-set-style: "BSD"
  62.121 - * c-basic-offset: 4
  62.122 - * tab-width: 4
  62.123 - * indent-tabs-mode: nil
  62.124 - * End:
  62.125 - */