[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg



# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1178636957 21600
# Node ID d7303c4a9dabdc7b461e7915fb8cd9d03ff7570c
# Parent  d1ce60b8070f640408c702f1fbbef0f6ffda8586
# Parent  3ef0510e44d04eb837ae238203251b969fc45df9
merge with xen-unstable.hg
---
 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c                  |   12 
 patches/linux-2.6.18/git-5ee7737379b1d7f0c977c0f1661fbaf01a8d4721.patch |   21 
 patches/linux-2.6.18/series                                             |    1 
 tools/blktap/drivers/block-qcow.c                                       |    3 
 tools/ioemu/keymaps/modifiers                                           |    2 
 tools/ioemu/patches/acpi-poweroff-support                               |   10 
 tools/ioemu/patches/acpi-support                                        |  291 
----------
 tools/ioemu/patches/acpi-timer-support                                  |  116 
---
 tools/ioemu/patches/domain-destroy                                      |   10 
 tools/ioemu/patches/domain-reset                                        |   35 
-
 tools/ioemu/patches/domain-timeoffset                                   |   88 
++-
 tools/ioemu/patches/hypervisor-pit                                      |   10 
 tools/ioemu/patches/ide-cd-dma                                          |    6 
 tools/ioemu/patches/ide-error-reporting                                 |   14 
 tools/ioemu/patches/ide-hd-multithread                                  |   56 
+
 tools/ioemu/patches/ioemu-buffer-pio-ia64                               |   83 
++
 tools/ioemu/patches/ioemu-ia64                                          |   29 
 tools/ioemu/patches/ioemu-save-restore                                  |  119 
++++
 tools/ioemu/patches/ioemu-save-restore-acpi                             |   15 
 tools/ioemu/patches/ioemu-save-restore-ide                              |   17 
 tools/ioemu/patches/ioemu-save-restore-logdirty                         |   50 
+
 tools/ioemu/patches/ioemu-save-restore-ne2000                           |   27 
 tools/ioemu/patches/ioemu-save-restore-pcnet                            |   21 
 tools/ioemu/patches/ioemu-save-restore-rtl8139                          |   21 
 tools/ioemu/patches/ioemu-save-restore-timer                            |   14 
 tools/ioemu/patches/ioemu-save-restore-usb                              |   78 
++
 tools/ioemu/patches/nodelay-serial-over-tcp                             |    6 
 tools/ioemu/patches/qemu-64bit                                          |   12 
 tools/ioemu/patches/qemu-block-device-bounds-checks                     |   17 
 tools/ioemu/patches/qemu-bootorder                                      |   18 
 tools/ioemu/patches/qemu-cirrus-bounds-checks                           |  246 
++++++++
 tools/ioemu/patches/qemu-cleanup                                        |   10 
 tools/ioemu/patches/qemu-daemonize                                      |    4 
 tools/ioemu/patches/qemu-dm                                             |   38 
-
 tools/ioemu/patches/qemu-dma-null-pointer-check                         |   10 
 tools/ioemu/patches/qemu-logging                                        |    6 
 tools/ioemu/patches/qemu-pci                                            |   16 
 tools/ioemu/patches/qemu-pci-vendor-ids                                 |   32 
+
 tools/ioemu/patches/qemu-serial-fixes                                   |    6 
 tools/ioemu/patches/qemu-smp                                            |   12 
 tools/ioemu/patches/qemu-target-i386-dm                                 |   32 
-
 tools/ioemu/patches/qemu-timer                                          |   10 
 tools/ioemu/patches/qemu-tunable-ide-write-cache                        |   10 
 tools/ioemu/patches/scsi                                                |  153 
+++++
 tools/ioemu/patches/serial-non-block                                    |    4 
 tools/ioemu/patches/series                                              |   23 
 tools/ioemu/patches/shadow-vram                                         |   29 
 tools/ioemu/patches/shared-vram                                         |   39 
-
 tools/ioemu/patches/support-xm-console                                  |   42 
+
 tools/ioemu/patches/tpm-tis-device                                      |   15 
 tools/ioemu/patches/usb-mouse-tablet-status-check                       |   49 
-
 tools/ioemu/patches/vnc-altgr-keysym                                    |   20 
 tools/ioemu/patches/vnc-backoff-screen-scan                             |    8 
 tools/ioemu/patches/vnc-cleanup                                         |    6 
 tools/ioemu/patches/vnc-display-find-unused                             |   24 
 tools/ioemu/patches/vnc-fix-signedness                                  |  194 
++++++
 tools/ioemu/patches/vnc-fix-version-check                               |   11 
 tools/ioemu/patches/vnc-fixes                                           |    8 
 tools/ioemu/patches/vnc-listen-specific-interface                       |   26 
 tools/ioemu/patches/vnc-password                                        |   50 
-
 tools/ioemu/patches/vnc-start-vncviewer                                 |   27 
 tools/ioemu/patches/xen-build                                           |   21 
 tools/ioemu/patches/xen-domain-name                                     |    8 
 tools/ioemu/patches/xen-domid                                           |    4 
 tools/ioemu/patches/xen-mapcache                                        |  213 
++-----
 tools/ioemu/patches/xen-mm                                              |   41 
-
 tools/ioemu/patches/xen-network                                         |   19 
 tools/ioemu/patches/xen-platform-device                                 |   29 
 tools/ioemu/patches/xen-support-buffered-ioreqs                         |   50 
+
 tools/ioemu/patches/xenstore                                            |   41 
+
 tools/ioemu/patches/xenstore-block-device-config                        |  273 
++-------
 tools/ioemu/patches/xenstore-device-info-functions                      |   22 
 tools/ioemu/patches/xenstore-write-vnc-port                             |   25 
 tools/libxc/xc_hvm_build.c                                              |   62 
+-
 tools/python/xen/xend/XendAPI.py                                        |    2 
 tools/python/xen/xend/XendDomainInfo.py                                 |    5 
 tools/python/xen/xend/image.py                                          |    2 
 tools/xenstat/libxenstat/src/xenstat_linux.c                            |    6 
 78 files changed, 1964 insertions(+), 1221 deletions(-)

diff -r d1ce60b8070f -r d7303c4a9dab 
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Mon May 07 
13:24:37 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Tue May 08 
09:09:17 2007 -0600
@@ -113,10 +113,18 @@ static void post_suspend(int suspend_can
 
 #else /* !(defined(__i386__) || defined(__x86_64__)) */
 
+#ifndef HAVE_XEN_PRE_SUSPEND
+#define xen_pre_suspend()      ((void)0)
+#endif
+
+#ifndef HAVE_XEN_POST_SUSPEND
+#define xen_post_suspend(x)    ((void)0)
+#endif
+
 #define switch_idle_mm()       ((void)0)
 #define mm_pin_all()           ((void)0)
-#define pre_suspend()          ((void)0)
-#define post_suspend(x)                ((void)0)
+#define pre_suspend()          xen_pre_suspend()
+#define post_suspend(x)                xen_post_suspend(x)
 
 #endif
 
diff -r d1ce60b8070f -r d7303c4a9dab 
patches/linux-2.6.18/git-5ee7737379b1d7f0c977c0f1661fbaf01a8d4721.patch
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.18/git-5ee7737379b1d7f0c977c0f1661fbaf01a8d4721.patch   
Tue May 08 09:09:17 2007 -0600
@@ -0,0 +1,28 @@
+--- ./arch/ia64/kernel/smp.c.orig      2007-05-02 19:00:01.000000000 +0900
++++ ./arch/ia64/kernel/smp.c   2007-05-02 19:04:32.000000000 +0900
+@@ -328,10 +328,14 @@ int
+ smp_call_function (void (*func) (void *info), void *info, int nonatomic, int 
wait)
+ {
+       struct call_data_struct data;
+-      int cpus = num_online_cpus()-1;
++      int cpus;
+ 
+-      if (!cpus)
++      spin_lock(&call_lock);
++      cpus = num_online_cpus()-1;
++      if (!cpus) {
++              spin_unlock(&call_lock);
+               return 0;
++      }
+ 
+       /* Can deadlock when called with interrupts disabled */
+       WARN_ON(irqs_disabled());
+@@ -343,8 +347,6 @@ smp_call_function (void (*func) (void *i
+       if (wait)
+               atomic_set(&data.finished, 0);
+ 
+-      spin_lock(&call_lock);
+-
+       call_data = &data;
+       mb();   /* ensure store to call_data precedes setting of IPI_CALL_FUNC 
*/
+       send_IPI_allbutself(IPI_CALL_FUNC);
diff -r d1ce60b8070f -r d7303c4a9dab patches/linux-2.6.18/series
--- a/patches/linux-2.6.18/series       Mon May 07 13:24:37 2007 -0600
+++ b/patches/linux-2.6.18/series       Tue May 08 09:09:17 2007 -0600
@@ -21,3 +21,4 @@ softlockup-no-idle-hz.patch
 softlockup-no-idle-hz.patch
 allow-i386-crash-kernels-to-handle-x86_64-dumps.patch
 allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch
+git-5ee7737379b1d7f0c977c0f1661fbaf01a8d4721.patch
diff -r d1ce60b8070f -r d7303c4a9dab tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Mon May 07 13:24:37 2007 -0600
+++ b/tools/blktap/drivers/block-qcow.c Tue May 08 09:09:17 2007 -0600
@@ -199,7 +199,8 @@ static int init_aio_state(struct disk_dr
        }
 
         /* A segment (i.e. a page) can span multiple clusters */
-        s->max_aio_reqs = (getpagesize() / s->cluster_size) + 1;
+        s->max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) *
+            MAX_SEGMENTS_PER_REQ * MAX_REQUESTS;
 
         /* Initialize AIO */
         s->iocb_free_count = s->max_aio_reqs;
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/keymaps/modifiers
--- a/tools/ioemu/keymaps/modifiers     Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/keymaps/modifiers     Tue May 08 09:09:17 2007 -0600
@@ -3,7 +3,7 @@ Shift_L 0x2a
 
 Alt_R 0xb8
 Mode_switch 0xb8
-ISO_Level3_Switch 0xb8
+ISO_Level3_Shift 0xb8
 Alt_L 0x38
 
 Control_R 0x9d
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/acpi-poweroff-support
--- a/tools/ioemu/patches/acpi-poweroff-support Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/acpi-poweroff-support Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/hw/piix4acpi.c
 Index: ioemu/hw/piix4acpi.c
 ===================================================================
---- ioemu.orig/hw/piix4acpi.c  2006-08-17 19:50:05.060576667 +0100
-+++ ioemu/hw/piix4acpi.c       2006-08-17 19:50:07.563300039 +0100
+--- ioemu.orig/hw/piix4acpi.c  2007-05-02 15:59:27.000000000 +0100
++++ ioemu/hw/piix4acpi.c       2007-05-02 16:02:29.000000000 +0100
 @@ -45,6 +45,10 @@
  #define GBL_RLS           (1 << 2)
  #define SLP_EN            (1 << 13)
@@ -13,23 +13,22 @@ Index: ioemu/hw/piix4acpi.c
  typedef struct AcpiDeviceState AcpiDeviceState;
  AcpiDeviceState *acpi_device_table;
  
-@@ -190,7 +194,14 @@
-     s->pm1_control = (val<<8)||(s->pm1_control);
+@@ -81,7 +85,13 @@
+     s->pm1_control = (s->pm1_control & 0xff) | (val << 8);
  /*    printf("acpiPm1ControlP1_writeb \n addr %x val:%x\n", addr, val); */
  
 -} 
 +    // Check for power off request
-+
++    val <<= 8;
 +    if (((val & SLP_EN) != 0) &&
 +        ((val & SLP_TYP_MASK) == SLP_VAL)) {
-+        s->pm1_timer=0x0; //clear ACPI timer
 +        qemu_system_shutdown_request();
 +    }
 +}
  
  static uint32_t acpiPm1ControlP1_readb(void *opaque, uint32_t addr)
  {
-@@ -257,7 +268,14 @@
+@@ -105,7 +115,14 @@
      s->pm1_control = val;
  /*    printf("acpiPm1Control_writew \n addr %x val:%x\n", addr, val); */
  
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/acpi-support
--- a/tools/ioemu/patches/acpi-support  Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/acpi-support  Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-12-08 02:00:40.000000000 +0000
-+++ ioemu/Makefile.target      2006-12-08 02:00:40.000000000 +0000
+--- ioemu.orig/Makefile.target 2007-05-03 15:06:42.000000000 +0100
++++ ioemu/Makefile.target      2007-05-03 15:07:21.000000000 +0100
 @@ -358,6 +358,7 @@
  VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
  VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
@@ -12,11 +12,11 @@ Index: ioemu/Makefile.target
  ifeq ($(TARGET_BASE_ARCH), ppc)
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-12-08 02:00:40.000000000 +0000
-+++ ioemu/hw/pc.c      2006-12-08 02:00:40.000000000 +0000
-@@ -874,13 +874,19 @@
- 
-     cmos_init(ram_size, boot_device, bs_table, timeoffset);
+--- ioemu.orig/hw/pc.c 2007-05-03 15:06:42.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-03 15:07:21.000000000 +0100
+@@ -873,13 +873,19 @@
+ 
+     cmos_init(ram_size, boot_device, bs_table);
  
 +    /* using PIIX4 acpi model */
 +    if (pci_enabled && acpi_enabled)
@@ -35,7 +35,7 @@ Index: ioemu/hw/pc.c
  
  #if 0
      /* ??? Need to figure out some way for the user to
-@@ -903,8 +909,10 @@
+@@ -902,8 +908,10 @@
      /* XXX: should be done in the Bochs BIOS */
      if (pci_enabled) {
          pci_bios_init();
@@ -49,8 +49,8 @@ Index: ioemu/hw/piix4acpi.c
 Index: ioemu/hw/piix4acpi.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/hw/piix4acpi.c       2006-12-08 02:00:40.000000000 +0000
-@@ -0,0 +1,396 @@
++++ ioemu/hw/piix4acpi.c       2007-05-03 15:07:31.000000000 +0100
+@@ -0,0 +1,186 @@
 +/*
 + * PIIX4 ACPI controller emulation
 + *
@@ -101,22 +101,10 @@ Index: ioemu/hw/piix4acpi.c
 +typedef struct AcpiDeviceState AcpiDeviceState;
 +AcpiDeviceState *acpi_device_table;
 +
-+/* Bits of PM1a register define here  */
-+typedef struct PM1Event_BLK {
-+    uint16_t pm1_status; /* pm1a_EVT_BLK */
-+    uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */
-+}PM1Event_BLK;
-+
 +typedef struct PCIAcpiState {
 +    PCIDevice dev;
-+    uint16_t irq;
-+    uint16_t pm1_status; /* pm1a_EVT_BLK */
-+    uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */
 +    uint16_t pm1_control; /* pm1a_ECNT_BLK */
-+    uint32_t pm1_timer; /* pmtmr_BLK */
 +} PCIAcpiState;
-+
-+static PCIAcpiState *acpi_state;
 +
 +static inline void acpi_set_irq(PCIAcpiState *s)
 +{
@@ -125,189 +113,50 @@ Index: ioemu/hw/piix4acpi.c
 +    printf("acpi_set_irq: s->irq %x \n",s->irq);
 +}
 +
-+static void acpi_reset(PCIAcpiState *s)
-+{
-+    uint8_t *pci_conf;
-+    pci_conf = s->dev.config;
-+
-+    pci_conf[0x42] = 0x00;
-+    pci_conf[0x43] = 0x00;
-+    s->irq = 9;
-+    s->pm1_status = 0;
-+    s->pm1_enable = 0x00;    /* TMROF_EN should cleared */
-+    s->pm1_control = SCI_EN; /* SCI_EN */
-+    s->pm1_timer = 0;
-+}
-+
-+/*byte access  */
-+static void acpiPm1Status_writeb(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIAcpiState *s = opaque;
-+
-+    if ((val&TMROF_STS)==TMROF_STS)
-+        s->pm1_status = s->pm1_status&!TMROF_STS;
-+
-+    if ((val&GBL_STS)==GBL_STS)
-+        s->pm1_status = s->pm1_status&!GBL_STS;     
-+    
-+/*     printf("acpiPm1Status_writeb \n addr %x val:%x pm1_status:%x \n", 
addr, val,s->pm1_status); */
-+}
-+
-+static uint32_t acpiPm1Status_readb(void *opaque, uint32_t addr)
++static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
++{
++    PCIAcpiState *s = opaque;
++
++    s->pm1_control = (s->pm1_control & 0xff00) | (val & 0xff);
++/*  printf("acpiPm1Control_writeb \n addr %x val:%x\n", addr, val); */
++
++}
++
++static uint32_t acpiPm1Control_readb(void *opaque, uint32_t addr)
 +{
 +    PCIAcpiState *s = opaque;
 +    uint32_t val;
 +
-+    val = s->pm1_status;
-+/*         printf("acpiPm1Status_readb \n addr %x val:%x\n", addr, val); */
-+
-+   return val;
-+}
-+
-+static void acpiPm1StatusP1_writeb(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIAcpiState *s = opaque;
-+
-+     s->pm1_status = (val<<8)||(s->pm1_status);
-+/*     printf("acpiPm1StatusP1_writeb \n addr %x val:%x\n", addr, val); */
-+}
-+
-+static uint32_t acpiPm1StatusP1_readb(void *opaque, uint32_t addr)
++    /* Mask out the write-only bits */
++    val = s->pm1_control & ~(GBL_RLS|SLP_EN) & 0xff;
++/*    printf("acpiPm1Control_readb \n addr %x val:%x\n", addr, val); */
++
++    return val;
++}
++
++static void acpiPm1ControlP1_writeb(void *opaque, uint32_t addr, uint32_t val)
++{
++    PCIAcpiState *s = opaque;
++
++    s->pm1_control = (s->pm1_control & 0xff) | (val << 8);
++/*    printf("acpiPm1ControlP1_writeb \n addr %x val:%x\n", addr, val); */
++
++} 
++
++static uint32_t acpiPm1ControlP1_readb(void *opaque, uint32_t addr)
 +{
 +    PCIAcpiState *s = opaque;
 +    uint32_t val;
 +
-+    val = (s->pm1_status)>>8;
-+    printf("acpiPm1StatusP1_readb \n addr %x val:%x\n", addr, val);
++    /* Mask out the write-only bits */
++    val = (s->pm1_control & ~(GBL_RLS|SLP_EN)) >> 8;
++/*    printf("acpiPm1ControlP1_readb \n addr %x val:%x\n", addr, val); */
 +
 +    return val;
 +}
 +
-+static void acpiPm1Enable_writeb(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIAcpiState *s = opaque;
-+
-+    s->pm1_enable = val;
-+/*   printf("acpiPm1Enable_writeb \n addr %x val:%x\n", addr, val); */
-+}
-+
-+static uint32_t acpiPm1Enable_readb(void *opaque, uint32_t addr)
-+{
-+    PCIAcpiState *s = opaque;
-+    uint32_t val;
-+
-+    val = (s->pm1_enable)||0x1;
-+/*  printf("acpiPm1Enable_readb \n addr %x val:%x\n", addr, val); */
-+
-+    return val;
-+}
-+
-+static void acpiPm1EnableP1_writeb(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIAcpiState *s = opaque;
-+
-+    s->pm1_enable = (val<<8)||(s->pm1_enable);
-+/*    printf("acpiPm1EnableP1_writeb \n addr %x val:%x\n", addr, val); */
-+
-+}
-+
-+static uint32_t acpiPm1EnableP1_readb(void *opaque, uint32_t addr)
-+{
-+    PCIAcpiState *s = opaque;
-+    uint32_t val;
-+
-+    val = (s->pm1_enable)>>8;
-+/*  printf("acpiPm1EnableP1_readb \n addr %x val:%x\n", addr, val); */
-+
-+    return val;
-+}
-+
-+static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIAcpiState *s = opaque;
-+
-+    s->pm1_control = val;
-+/*  printf("acpiPm1Control_writeb \n addr %x val:%x\n", addr, val); */
-+
-+}
-+
-+static uint32_t acpiPm1Control_readb(void *opaque, uint32_t addr)
-+{
-+    PCIAcpiState *s = opaque;
-+    uint32_t val;
-+
-+    val = s->pm1_control;
-+/*    printf("acpiPm1Control_readb \n addr %x val:%x\n", addr, val); */
-+
-+    return val;
-+}
-+
-+static void acpiPm1ControlP1_writeb(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIAcpiState *s = opaque;
-+
-+    s->pm1_control = (val<<8)||(s->pm1_control);
-+/*    printf("acpiPm1ControlP1_writeb \n addr %x val:%x\n", addr, val); */
-+
-+} 
-+
-+static uint32_t acpiPm1ControlP1_readb(void *opaque, uint32_t addr)
-+{
-+    PCIAcpiState *s = opaque;
-+    uint32_t val;
-+
-+    val = (s->pm1_control)>>8;
-+/*    printf("acpiPm1ControlP1_readb \n addr %x val:%x\n", addr, val); */
-+
-+    return val;
-+}
-+
 +
 +/* word access   */
-+
-+static void acpiPm1Status_writew(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIAcpiState *s = opaque;
-+
-+    if ((val&TMROF_STS)==TMROF_STS)
-+        s->pm1_status = s->pm1_status&!TMROF_STS;
-+
-+    if ((val&GBL_STS)==GBL_STS)
-+        s->pm1_status = s->pm1_status&!GBL_STS;     
-+
-+/*    printf("acpiPm1Status_writew \n addr %x val:%x pm1_status:%x \n", addr, 
val,s->pm1_status); */
-+}
-+
-+static uint32_t acpiPm1Status_readw(void *opaque, uint32_t addr)
-+{
-+    PCIAcpiState *s = opaque;
-+    uint32_t val;
-+
-+    val = s->pm1_status;
-+/*    printf("acpiPm1Status_readw \n addr %x val:%x\n", addr, val); */
-+
-+    return val;
-+}
-+
-+static void acpiPm1Enable_writew(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIAcpiState *s = opaque;
-+
-+    s->pm1_enable = val;
-+/*    printf("acpiPm1Enable_writew \n addr %x val:%x\n", addr, val); */
-+
-+}
-+
-+static uint32_t acpiPm1Enable_readw(void *opaque, uint32_t addr)
-+{
-+    PCIAcpiState *s = opaque;
-+    uint32_t val;
-+
-+    val = s->pm1_enable;
-+/*    printf("acpiPm1Enable_readw \n addr %x val:%x\n", addr, val); */
-+
-+   return val;
-+}
 +
 +static void acpiPm1Control_writew(void *opaque, uint32_t addr, uint32_t val)
 +{
@@ -323,50 +172,13 @@ Index: ioemu/hw/piix4acpi.c
 +    PCIAcpiState *s = opaque;
 +    uint32_t val;
 +
-+    val = s->pm1_control;
++    /* Mask out the write-only bits */
++    val = s->pm1_control & ~(GBL_RLS|SLP_EN);
 +/*    printf("acpiPm1Control_readw \n addr %x val:%x\n", addr, val);  */
 +
 +    return val;
 +}
 +
-+/* dword access */
-+
-+static void acpiPm1Event_writel(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIAcpiState *s = opaque;
-+
-+    s->pm1_status = val;
-+    s->pm1_enable = val>>16;
-+/*     printf("acpiPm1Event_writel \n addr %x val:%x \n", addr, val); */
-+
-+}
-+
-+static void acpiPm1Event_readl(void *opaque, uint32_t addr)
-+{
-+    PCIAcpiState *s = opaque;
-+    uint32_t val;
-+
-+    val=s->pm1_status|(s->pm1_enable<<16);
-+/*    printf("acpiPm1Event_readl \n addr %x val:%x\n", addr, val);    */
-+}
-+
-+static void acpiPm1Timer_writel(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIAcpiState *s = opaque;
-+
-+    s->pm1_timer = val;
-+/*    printf("acpiPm1Timer_writel \n addr %x val:%x\n", addr, val); */
-+}
-+
-+static uint32_t acpiPm1Timer_readl(void *opaque, uint32_t addr)
-+{
-+    PCIAcpiState *s = opaque;
-+    uint32_t val;
-+
-+    val = s->pm1_timer;
-+/*    printf("acpiPm1Timer_readl \n addr %x val:%x\n", addr, val); */
-+    return val;
-+}
 +
 +static void acpi_map(PCIDevice *pci_dev, int region_num,
 +                    uint32_t addr, uint32_t size, int type)
@@ -376,39 +188,15 @@ Index: ioemu/hw/piix4acpi.c
 +    printf("register acpi io \n");
 +
 +    /* Byte access */
-+    register_ioport_write(addr, 1, 1, acpiPm1Status_writeb, d);
-+    register_ioport_read(addr, 1, 1, acpiPm1Status_readb, d);
-+    register_ioport_write(addr+1, 1, 1, acpiPm1StatusP1_writeb, d);
-+    register_ioport_read(addr+1, 1, 1, acpiPm1StatusP1_readb, d);
-+
-+    register_ioport_write(addr + 2, 1, 1, acpiPm1Enable_writeb, d);
-+    register_ioport_read(addr + 2, 1, 1, acpiPm1Enable_readb, d);
-+    register_ioport_write(addr + 2 +1, 1, 1, acpiPm1EnableP1_writeb, d);
-+    register_ioport_read(addr + 2 +1, 1, 1, acpiPm1EnableP1_readb, d);
-+
 +    register_ioport_write(addr + 4, 1, 1, acpiPm1Control_writeb, d);
 +    register_ioport_read(addr + 4, 1, 1, acpiPm1Control_readb, d);
 +    register_ioport_write(addr + 4 + 1, 1, 1, acpiPm1ControlP1_writeb, d);
-+    register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d);       
++    register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d);
 +
 +    /* Word access */
-+    register_ioport_write(addr, 2, 2, acpiPm1Status_writew, d);
-+    register_ioport_read(addr, 2, 2, acpiPm1Status_readw, d);
-+
-+    register_ioport_write(addr + 2, 2, 2, acpiPm1Enable_writew, d);
-+    register_ioport_read(addr + 2, 2, 2, acpiPm1Enable_readw, d); 
-+
 +    register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d);
 +    register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
-+
-+    /* DWord access */
-+    register_ioport_write(addr, 4, 4, acpiPm1Event_writel, d);
-+    register_ioport_read(addr, 4, 4, acpiPm1Event_readl, d);
-+              
-+    register_ioport_write(addr + 8, 4, 4, acpiPm1Timer_writel, d);
-+    register_ioport_read(addr + 8, 4, 4, acpiPm1Timer_readl, d);
-+}
-+                                                                              
                        
++}
 +
 +/* PIIX4 acpi pci configuration space, func 2 */
 +void pci_piix4_acpi_init(PCIBus *bus, int devfn)
@@ -421,7 +209,6 @@ Index: ioemu/hw/piix4acpi.c
 +        bus, "PIIX4 ACPI", sizeof(PCIAcpiState),
 +        devfn, NULL, NULL);
 +
-+    acpi_state = d;
 +    pci_conf = d->dev.config;
 +    pci_conf[0x00] = 0x86;  /* Intel */
 +    pci_conf[0x01] = 0x80;
@@ -444,14 +231,17 @@ Index: ioemu/hw/piix4acpi.c
 +     */
 +    pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */
 +    pci_conf[0x41] = 0x1f;
++    pci_conf[0x42] = 0x00;
++    pci_conf[0x43] = 0x00;
++    d->pm1_control = SCI_EN;
++
 +    acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
-+    acpi_reset(d);
 +}
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-08 02:00:40.000000000 +0000
-+++ ioemu/vl.c 2006-12-08 02:00:40.000000000 +0000
-@@ -156,7 +156,7 @@
+--- ioemu.orig/vl.c    2007-05-03 15:06:42.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:07:21.000000000 +0100
+@@ -157,7 +157,7 @@
  #else
  #define MAX_CPUS 1
  #endif
@@ -460,33 +250,33 @@ Index: ioemu/vl.c
  int fd_bootchk = 1;
  
  extern int vcpus;
-@@ -5341,6 +5341,7 @@
+@@ -5415,6 +5415,7 @@
+ #endif
             "-loadvm file    start right away with a saved state (loadvm in 
monitor)\n"
           "-vnc display    start a VNC server on display\n"
-            "-timeoffset     time offset (in seconds) from local time\n"
 +           "-acpi           disable or enable ACPI of HVM domain \n"
             "\n"
             "During emulation, the following keys are useful:\n"
             "ctrl-alt-f      toggle full screen\n"
-@@ -5426,6 +5427,7 @@
+@@ -5499,6 +5500,7 @@
+ 
      QEMU_OPTION_d,
      QEMU_OPTION_vcpus,
-     QEMU_OPTION_timeoffset,
 +    QEMU_OPTION_acpi,
  };
  
  typedef struct QEMUOption {
-@@ -5509,6 +5511,7 @@
+@@ -5581,6 +5583,7 @@
+     
      { "d", HAS_ARG, QEMU_OPTION_d },
      { "vcpus", 1, QEMU_OPTION_vcpus },
-     { "timeoffset", HAS_ARG, QEMU_OPTION_timeoffset },
 +    { "acpi", 0, QEMU_OPTION_acpi },
      { NULL },
  };
  
-@@ -6240,6 +6243,9 @@
-             case QEMU_OPTION_timeoffset:
-                 timeoffset = strtol(optarg, NULL, 0);
+@@ -6322,6 +6325,9 @@
+                 vcpus = atoi(optarg);
+                 fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
                  break;
 +            case QEMU_OPTION_acpi:
 +                acpi_enabled = 1;
@@ -496,8 +286,8 @@ Index: ioemu/vl.c
      }
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-08 02:00:40.000000000 +0000
-+++ ioemu/vl.h 2006-12-08 02:00:40.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 15:06:42.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:07:21.000000000 +0100
 @@ -168,6 +168,7 @@
  extern int kqemu_allowed;
  extern int win2k_install_hack;
@@ -506,7 +296,7 @@ Index: ioemu/vl.h
  extern int smp_cpus;
  
  /* XXX: make it dynamic */
-@@ -923,6 +924,9 @@
+@@ -924,6 +925,9 @@
  void piix4_pm_init(PCIBus *bus, int devfn);
  void acpi_bios_init(void);
  
@@ -518,8 +308,8 @@ Index: ioemu/vl.h
  extern QEMUMachine isapc_machine;
 Index: ioemu/hw/piix_pci.c
 ===================================================================
---- ioemu.orig/hw/piix_pci.c   2006-12-08 02:00:39.000000000 +0000
-+++ ioemu/hw/piix_pci.c        2006-12-08 02:00:40.000000000 +0000
+--- ioemu.orig/hw/piix_pci.c   2007-05-03 15:06:42.000000000 +0100
++++ ioemu/hw/piix_pci.c        2007-05-03 15:07:13.000000000 +0100
 @@ -241,7 +241,7 @@
  static uint32_t pci_bios_io_addr;
  static uint32_t pci_bios_mem_addr;
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/acpi-timer-support
--- a/tools/ioemu/patches/acpi-timer-support    Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/acpi-timer-support    Tue May 08 09:09:17 2007 -0600
@@ -1,8 +1,8 @@ Index: ioemu/hw/piix4acpi.c
 Index: ioemu/hw/piix4acpi.c
 ===================================================================
---- ioemu.orig/hw/piix4acpi.c  2006-12-08 01:35:52.000000000 +0000
-+++ ioemu/hw/piix4acpi.c       2006-12-08 01:35:59.000000000 +0000
-@@ -24,31 +24,30 @@
+--- ioemu.orig/hw/piix4acpi.c  2007-05-02 15:59:22.000000000 +0100
++++ ioemu/hw/piix4acpi.c       2007-05-02 15:59:27.000000000 +0100
+@@ -24,26 +24,26 @@
   */
  
  #include "vl.h"
@@ -41,19 +41,9 @@ Index: ioemu/hw/piix4acpi.c
  
  typedef struct AcpiDeviceState AcpiDeviceState;
  AcpiDeviceState *acpi_device_table;
- 
--/* Bits of PM1a register define here  */
- typedef struct PM1Event_BLK {
-     uint16_t pm1_status; /* pm1a_EVT_BLK */
-     uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */
-@@ -61,17 +60,11 @@
-     uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */
+@@ -53,13 +53,6 @@
      uint16_t pm1_control; /* pm1a_ECNT_BLK */
-     uint32_t pm1_timer; /* pmtmr_BLK */
-+    uint64_t old_vmck_ticks; /* using vm_clock counter */
  } PCIAcpiState;
- 
- static PCIAcpiState *acpi_state;
  
 -static inline void acpi_set_irq(PCIAcpiState *s)
 -{
@@ -62,92 +52,10 @@ Index: ioemu/hw/piix4acpi.c
 -    printf("acpi_set_irq: s->irq %x \n",s->irq);
 -}
 -
- static void acpi_reset(PCIAcpiState *s)
- {
-     uint8_t *pci_conf;
-@@ -84,6 +77,7 @@
-     s->pm1_enable = 0x00;    /* TMROF_EN should cleared */
-     s->pm1_control = SCI_EN; /* SCI_EN */
-     s->pm1_timer = 0;
-+    s->old_vmck_ticks = qemu_get_clock(vm_clock);
- }
- 
- /*byte access  */
-@@ -95,8 +89,8 @@
-         s->pm1_status = s->pm1_status&!TMROF_STS;
- 
-     if ((val&GBL_STS)==GBL_STS)
--        s->pm1_status = s->pm1_status&!GBL_STS;     
--    
-+        s->pm1_status = s->pm1_status&!GBL_STS;
-+
- /*     printf("acpiPm1Status_writeb \n addr %x val:%x pm1_status:%x \n", 
addr, val,s->pm1_status); */
- }
- 
-@@ -115,7 +109,7 @@
+ static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
  {
      PCIAcpiState *s = opaque;
- 
--     s->pm1_status = (val<<8)||(s->pm1_status);
-+    s->pm1_status = (val<<8)||(s->pm1_status);
- /*     printf("acpiPm1StatusP1_writeb \n addr %x val:%x\n", addr, val); */
- }
- 
-@@ -220,7 +214,7 @@
-         s->pm1_status = s->pm1_status&!TMROF_STS;
- 
-     if ((val&GBL_STS)==GBL_STS)
--        s->pm1_status = s->pm1_status&!GBL_STS;     
-+        s->pm1_status = s->pm1_status&!GBL_STS;
- 
- /*    printf("acpiPm1Status_writew \n addr %x val:%x pm1_status:%x \n", addr, 
val,s->pm1_status); */
- }
-@@ -288,13 +282,15 @@
- 
- }
- 
--static void acpiPm1Event_readl(void *opaque, uint32_t addr)
-+static uint32_t acpiPm1Event_readl(void *opaque, uint32_t addr)
- {
-     PCIAcpiState *s = opaque;
-     uint32_t val;
- 
--    val=s->pm1_status|(s->pm1_enable<<16);
-+    val = s->pm1_status|(s->pm1_enable<<16);
- /*    printf("acpiPm1Event_readl \n addr %x val:%x\n", addr, val);    */
-+
-+    return val;
- }
- 
- static void acpiPm1Timer_writel(void *opaque, uint32_t addr, uint32_t val)
-@@ -302,17 +298,21 @@
-     PCIAcpiState *s = opaque;
- 
-     s->pm1_timer = val;
--/*    printf("acpiPm1Timer_writel \n addr %x val:%x\n", addr, val); */
-+    s->old_vmck_ticks = qemu_get_clock(vm_clock) +
-+        muldiv64(val, FREQUENCE_PMTIMER, ticks_per_sec);
- }
- 
- static uint32_t acpiPm1Timer_readl(void *opaque, uint32_t addr)
- {
-     PCIAcpiState *s = opaque;
--    uint32_t val;
-+    int64_t current_vmck_ticks = qemu_get_clock(vm_clock);
-+    int64_t vmck_ticks_delta = current_vmck_ticks - s->old_vmck_ticks;
- 
--    val = s->pm1_timer;
--/*    printf("acpiPm1Timer_readl \n addr %x val:%x\n", addr, val); */
--    return val;
-+    if (s->old_vmck_ticks)
-+        s->pm1_timer += muldiv64(vmck_ticks_delta, FREQUENCE_PMTIMER,
-+                                 ticks_per_sec);
-+    s->old_vmck_ticks = current_vmck_ticks;
-+    return s->pm1_timer;
- }
- 
- static void acpi_map(PCIDevice *pci_dev, int region_num,
-@@ -320,7 +320,7 @@
+@@ -132,7 +125,7 @@
  {
      PCIAcpiState *d = (PCIAcpiState *)pci_dev;
  
@@ -155,34 +63,4 @@ Index: ioemu/hw/piix4acpi.c
 +    printf("register acpi io\n");
  
      /* Byte access */
-     register_ioport_write(addr, 1, 1, acpiPm1Status_writeb, d);
-@@ -336,14 +336,14 @@
      register_ioport_write(addr + 4, 1, 1, acpiPm1Control_writeb, d);
-     register_ioport_read(addr + 4, 1, 1, acpiPm1Control_readb, d);
-     register_ioport_write(addr + 4 + 1, 1, 1, acpiPm1ControlP1_writeb, d);
--    register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d);       
-+    register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d);
- 
-     /* Word access */
-     register_ioport_write(addr, 2, 2, acpiPm1Status_writew, d);
-     register_ioport_read(addr, 2, 2, acpiPm1Status_readw, d);
- 
-     register_ioport_write(addr + 2, 2, 2, acpiPm1Enable_writew, d);
--    register_ioport_read(addr + 2, 2, 2, acpiPm1Enable_readw, d); 
-+    register_ioport_read(addr + 2, 2, 2, acpiPm1Enable_readw, d);
- 
-     register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d);
-     register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
-@@ -351,11 +351,10 @@
-     /* DWord access */
-     register_ioport_write(addr, 4, 4, acpiPm1Event_writel, d);
-     register_ioport_read(addr, 4, 4, acpiPm1Event_readl, d);
--              
-+
-     register_ioport_write(addr + 8, 4, 4, acpiPm1Timer_writel, d);
-     register_ioport_read(addr + 8, 4, 4, acpiPm1Timer_readl, d);
- }
--                                                                              
                        
- 
- /* PIIX4 acpi pci configuration space, func 2 */
- void pci_piix4_acpi_init(PCIBus *bus, int devfn)
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/domain-destroy
--- a/tools/ioemu/patches/domain-destroy        Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/domain-destroy        Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/monitor.c
 Index: ioemu/monitor.c
 ===================================================================
---- ioemu.orig/monitor.c       2006-12-08 01:26:07.000000000 +0000
-+++ ioemu/monitor.c    2006-12-08 01:26:08.000000000 +0000
+--- ioemu.orig/monitor.c       2007-05-03 14:54:59.000000000 +0100
++++ ioemu/monitor.c    2007-05-03 14:55:01.000000000 +0100
 @@ -308,6 +308,7 @@
  
  static void do_quit(void)
@@ -12,13 +12,14 @@ Index: ioemu/monitor.c
  
 Index: ioemu/target-i386-dm/helper2.c
 ===================================================================
---- ioemu.orig/target-i386-dm/helper2.c        2006-12-08 01:26:08.000000000 
+0000
-+++ ioemu/target-i386-dm/helper2.c     2006-12-08 01:26:08.000000000 +0000
-@@ -507,5 +507,25 @@
+--- ioemu.orig/target-i386-dm/helper2.c        2007-05-03 14:55:00.000000000 
+0100
++++ ioemu/target-i386-dm/helper2.c     2007-05-03 14:55:01.000000000 +0100
+@@ -549,5 +549,26 @@
          /* Wait up to 10 msec. */
          main_loop_wait(10);
-     }
+ 
 +    destroy_hvm_domain();
++
      return 0;
  }
 +
@@ -42,8 +43,8 @@ Index: ioemu/target-i386-dm/helper2.c
 +}
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-08 01:26:08.000000000 +0000
-+++ ioemu/vl.h 2006-12-08 01:26:08.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 14:55:00.000000000 +0100
++++ ioemu/vl.h 2007-05-03 14:55:01.000000000 +0100
 @@ -1190,4 +1190,7 @@
  void kqemu_record_dump(void);
  
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/domain-reset
--- a/tools/ioemu/patches/domain-reset  Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/domain-reset  Tue May 08 09:09:17 2007 -0600
@@ -1,16 +1,13 @@ Index: ioemu/target-i386-dm/helper2.c
 Index: ioemu/target-i386-dm/helper2.c
 ===================================================================
---- ioemu.orig/target-i386-dm/helper2.c        2006-12-08 01:26:06.000000000 
+0000
-+++ ioemu/target-i386-dm/helper2.c     2006-12-08 01:26:08.000000000 +0000
-@@ -127,6 +127,25 @@
+--- ioemu.orig/target-i386-dm/helper2.c        2007-05-03 14:54:46.000000000 
+0100
++++ ioemu/target-i386-dm/helper2.c     2007-05-03 14:55:00.000000000 +0100
+@@ -127,6 +127,22 @@
  /* called from main_cpu_reset */
  void cpu_reset(CPUX86State *env)
  {
 +    int xcHandle;
 +    int sts;
-+
-+    /* pause domain first, to avoid repeated reboot request*/
-+    xc_domain_pause(xc_handle, domid);
 +
 +    xcHandle = xc_interface_open();
 +    if (xcHandle < 0)
@@ -28,22 +25,28 @@ Index: ioemu/target-i386-dm/helper2.c
  }
  
  void cpu_x86_close(CPUX86State *env)
-@@ -479,6 +498,10 @@
-         if (vm_running) {
-             if (shutdown_requested)
-                 break;
-+            if (reset_requested) {
-+                qemu_system_reset();
-+                reset_requested = 0;
-+            }
-         }
+@@ -529,14 +545,9 @@
  
+     qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
+ 
+-    while (1) {
+-        if (vm_running) {
+-            if (shutdown_requested)
+-                break;
+-        }
+-
++    while (!(vm_running && suspend_requested))
          /* Wait up to 10 msec. */
+         main_loop_wait(10);
+-    }
++
+     return 0;
+ }
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-08 01:26:08.000000000 +0000
-+++ ioemu/vl.c 2006-12-08 01:26:08.000000000 +0000
-@@ -4948,7 +4948,7 @@
+--- ioemu.orig/vl.c    2007-05-03 14:55:00.000000000 +0100
++++ ioemu/vl.c 2007-05-03 14:55:00.000000000 +0100
+@@ -4957,7 +4957,7 @@
  } QEMUResetEntry;
  
  static QEMUResetEntry *first_reset_entry;
@@ -54,8 +57,8 @@ Index: ioemu/vl.c
  
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-08 01:26:07.000000000 +0000
-+++ ioemu/vl.h 2006-12-08 01:26:08.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 14:55:00.000000000 +0100
++++ ioemu/vl.h 2007-05-03 14:55:00.000000000 +0100
 @@ -131,6 +131,7 @@
  
  void qemu_register_reset(QEMUResetHandler *func, void *opaque);
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/domain-timeoffset
--- a/tools/ioemu/patches/domain-timeoffset     Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/domain-timeoffset     Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/hw/mc146818rtc.c
 Index: ioemu/hw/mc146818rtc.c
 ===================================================================
---- ioemu.orig/hw/mc146818rtc.c        2006-12-20 15:21:33.000000000 +0000
-+++ ioemu/hw/mc146818rtc.c     2006-12-20 15:21:50.000000000 +0000
+--- ioemu.orig/hw/mc146818rtc.c        2007-05-03 15:38:35.000000000 +0100
++++ ioemu/hw/mc146818rtc.c     2007-05-03 15:38:45.000000000 +0100
 @@ -178,10 +178,27 @@
      }
  }
@@ -46,8 +46,8 @@ Index: ioemu/hw/mc146818rtc.c
  static void rtc_copy_date(RTCState *s)
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-12-20 15:21:49.000000000 +0000
-+++ ioemu/hw/pc.c      2006-12-20 15:21:50.000000000 +0000
+--- ioemu.orig/hw/pc.c 2007-05-03 15:38:44.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-03 15:38:45.000000000 +0100
 @@ -159,7 +159,7 @@
  }
  
@@ -81,9 +81,9 @@ Index: ioemu/hw/pc.c
 -    cmos_init(ram_size, boot_device, bs_table);
 +    cmos_init(ram_size, boot_device, bs_table, timeoffset);
  
-     if (pci_enabled && usb_enabled) {
-         usb_uhci_init(pci_bus, piix3_devfn + 2);
-@@ -912,12 +913,13 @@
+     /* using PIIX4 acpi model */
+     if (pci_enabled && acpi_enabled)
+@@ -920,12 +921,13 @@
                          int snapshot, 
                          const char *kernel_filename, 
                          const char *kernel_cmdline,
@@ -99,7 +99,7 @@ Index: ioemu/hw/pc.c
  }
  
  static void pc_init_isa(uint64_t ram_size, int vga_ram_size, int boot_device,
-@@ -925,12 +927,13 @@
+@@ -933,12 +935,13 @@
                          int snapshot, 
                          const char *kernel_filename, 
                          const char *kernel_cmdline,
@@ -117,9 +117,9 @@ Index: ioemu/hw/pc.c
  QEMUMachine pc_machine = {
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:21:49.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:50.000000000 +0000
-@@ -163,6 +163,8 @@
+--- ioemu.orig/vl.c    2007-05-03 15:38:45.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:38:45.000000000 +0100
+@@ -167,6 +167,8 @@
  
  int xc_handle;
  
@@ -128,41 +128,51 @@ Index: ioemu/vl.c
  char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
  extern int domid;
  
-@@ -5338,6 +5340,7 @@
- #endif
-            "-loadvm file    start right away with a saved state (loadvm in 
monitor)\n"
-          "-vnc display    start a VNC server on display\n"
+@@ -5435,6 +5437,7 @@
+            "-vncviewer      start a vncviewer process for this domain\n"
+            "-vncunused      bind the VNC server to an unused port\n"
+            "-vnclisten      bind the VNC server to this address\n"
 +           "-timeoffset     time offset (in seconds) from local time\n"
+            "-acpi           disable or enable ACPI of HVM domain \n"
             "\n"
             "During emulation, the following keys are useful:\n"
-            "ctrl-alt-f      toggle full screen\n"
-@@ -5422,6 +5425,7 @@
+@@ -5522,6 +5525,7 @@
  
      QEMU_OPTION_d,
      QEMU_OPTION_vcpus,
 +    QEMU_OPTION_timeoffset,
- };
- 
- typedef struct QEMUOption {
-@@ -5504,6 +5508,7 @@
+     QEMU_OPTION_acpi,
+     QEMU_OPTION_vncviewer,
+     QEMU_OPTION_vncunused,
+@@ -5613,6 +5617,7 @@
      
      { "d", HAS_ARG, QEMU_OPTION_d },
      { "vcpus", 1, QEMU_OPTION_vcpus },
 +    { "timeoffset", HAS_ARG, QEMU_OPTION_timeoffset },
+     { "acpi", 0, QEMU_OPTION_acpi },
      { NULL },
  };
- 
-@@ -6232,6 +6237,9 @@
+@@ -6377,6 +6382,9 @@
                  vcpus = atoi(optarg);
                  fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
                  break;
 +            case QEMU_OPTION_timeoffset:
 +                timeoffset = strtol(optarg, NULL, 0);
 +                break;
-             }
-         }
+             case QEMU_OPTION_acpi:
+                 acpi_enabled = 1;
+                 break;
+@@ -6531,6 +6539,9 @@
      }
-@@ -6484,7 +6492,8 @@
+     free(page_array);
+ #endif
++
++    timeoffset_get();
++
+ #else  /* !CONFIG_DM */
+ 
+     phys_ram_base = qemu_vmalloc(phys_ram_size);
+@@ -6662,7 +6673,8 @@
  
      machine->init(ram_size, vga_ram_size, boot_device,
                    ds, fd_filename, snapshot,
@@ -174,9 +184,9 @@ Index: ioemu/vl.c
      if (usb_enabled) {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:21:49.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:50.000000000 +0000
-@@ -576,7 +576,7 @@
+--- ioemu.orig/vl.h    2007-05-03 15:38:45.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:38:45.000000000 +0100
+@@ -581,7 +581,7 @@
                                   int boot_device,
               DisplayState *ds, const char **fd_filename, int snapshot,
               const char *kernel_filename, const char *kernel_cmdline,
@@ -185,3 +195,72 @@ Index: ioemu/vl.h
  
  typedef struct QEMUMachine {
      const char *name;
+@@ -1216,6 +1216,10 @@
+ int xenstore_vm_write(int domid, char *key, char *val);
+ char *xenstore_vm_read(int domid, char *key, int *len);
+ 
++/* helper2.c */
++extern long time_offset;
++void timeoffset_get(void);
++
+ void kqemu_record_dump(void);
+ 
+ extern char domain_name[];
+Index: ioemu/target-i386-dm/helper2.c
+===================================================================
+--- ioemu.orig/target-i386-dm/helper2.c        2007-05-03 15:38:44.000000000 
+0100
++++ ioemu/target-i386-dm/helper2.c     2007-05-03 15:38:45.000000000 +0100
+@@ -74,6 +74,8 @@
+ 
+ int xc_handle;
+ 
++long time_offset = 0;
++
+ shared_iopage_t *shared_page = NULL;
+ 
+ /* the evtchn fd for polling */
+@@ -447,6 +449,34 @@
+     req->data = tmp1;
+ }
+ 
++void timeoffset_get()
++{
++    char *p;
++
++    p = xenstore_vm_read(domid, "rtc/timeoffset", NULL);
++    if (!p)
++      return;
++
++    if (sscanf(p, "%ld", &time_offset) == 1)
++      fprintf(logfile, "Time offset set %ld\n", time_offset);
++    else
++      time_offset = 0;
++
++    xc_domain_set_time_offset(xc_handle, domid, time_offset);
++
++    free(p);
++}
++
++void cpu_ioreq_timeoffset(CPUState *env, ioreq_t *req)
++{
++    char b[64];
++
++    time_offset += (ulong)req->data;
++
++    sprintf(b, "%ld", time_offset);
++    xenstore_vm_write(domid, "rtc/timeoffset", b);
++}
++
+ void cpu_ioreq_xchg(CPUState *env, ioreq_t *req)
+ {
+     unsigned long tmp1;
+@@ -497,6 +527,9 @@
+         case IOREQ_TYPE_XCHG:
+             cpu_ioreq_xchg(env, req);
+             break;
++      case IOREQ_TYPE_TIMEOFFSET:
++            cpu_ioreq_timeoffset(env, req);
++            break;
+         default:
+             hw_error("Invalid ioreq type 0x%x\n", req->type);
+         }
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/hypervisor-pit
--- a/tools/ioemu/patches/hypervisor-pit        Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/hypervisor-pit        Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-12-08 01:41:12.000000000 +0000
-+++ ioemu/Makefile.target      2006-12-08 01:41:12.000000000 +0000
+--- ioemu.orig/Makefile.target 2007-05-03 10:07:52.000000000 +0100
++++ ioemu/Makefile.target      2007-05-03 10:07:53.000000000 +0100
 @@ -355,7 +355,7 @@
  ifeq ($(TARGET_BASE_ARCH), i386)
  # Hardware support
@@ -13,8 +13,8 @@ Index: ioemu/Makefile.target
  DEFINES += -DHAS_AUDIO
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-12-08 01:41:12.000000000 +0000
-+++ ioemu/hw/pc.c      2006-12-08 01:41:12.000000000 +0000
+--- ioemu.orig/hw/pc.c 2007-05-03 10:07:52.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-03 10:07:53.000000000 +0100
 @@ -38,7 +38,9 @@
  
  static fdctrl_t *floppy_controller;
@@ -38,9 +38,9 @@ Index: ioemu/hw/pc.c
          pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-08 01:41:12.000000000 +0000
-+++ ioemu/vl.c 2006-12-08 01:41:12.000000000 +0000
-@@ -5570,6 +5570,7 @@
+--- ioemu.orig/vl.c    2007-05-03 10:07:53.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:07:53.000000000 +0100
+@@ -5622,6 +5622,7 @@
  
  #ifdef HAS_AUDIO
  struct soundhw soundhw[] = {
@@ -48,7 +48,7 @@ Index: ioemu/vl.c
  #ifdef TARGET_I386
      {
          "pcspk",
-@@ -5579,6 +5580,7 @@
+@@ -5631,6 +5632,7 @@
          { .init_isa = pcspk_audio_init }
      },
  #endif
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/ide-cd-dma
--- a/tools/ioemu/patches/ide-cd-dma    Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/ide-cd-dma    Tue May 08 09:09:17 2007 -0600
@@ -5,9 +5,11 @@
 [HVM] Enable DMA mode for CD-ROM IDE ATAPI interface.
 Signed-off-by: Winston Wang <winston.l.wang@xxxxxxxxx
 
---- ioemu/hw/ide.c     Wed Oct 18 18:37:18 2006 +0100
-+++ ioemu/hw/ide.c     Wed Oct 18 18:41:47 2006 +0100
-@@ -557,9 +557,9 @@ static void ide_atapi_identify(IDEState 
+Index: ioemu/hw/ide.c
+===================================================================
+--- ioemu.orig/hw/ide.c        2007-05-03 15:07:16.000000000 +0100
++++ ioemu/hw/ide.c     2007-05-03 15:07:16.000000000 +0100
+@@ -713,9 +713,9 @@
      padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
      padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
      put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/ide-error-reporting
--- a/tools/ioemu/patches/ide-error-reporting   Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/ide-error-reporting   Tue May 08 09:09:17 2007 -0600
@@ -33,9 +33,9 @@ Signed-off-by: Keir Fraser <keir@xensour
 
 Index: ioemu/hw/ide.c
 ===================================================================
---- ioemu.orig/hw/ide.c        2006-12-08 18:21:36.000000000 +0000
-+++ ioemu/hw/ide.c     2006-12-08 18:23:18.000000000 +0000
-@@ -680,7 +680,7 @@
+--- ioemu.orig/hw/ide.c        2007-05-03 15:07:16.000000000 +0100
++++ ioemu/hw/ide.c     2007-05-03 15:07:17.000000000 +0100
+@@ -838,7 +838,7 @@
  static void ide_sector_read(IDEState *s)
  {
      int64_t sector_num;
@@ -44,7 +44,7 @@ Index: ioemu/hw/ide.c
  
      s->status = READY_STAT | SEEK_STAT;
      s->error = 0; /* not needed by IDE spec, but needed by Windows */
-@@ -695,7 +695,11 @@
+@@ -853,7 +853,11 @@
  #endif
          if (n > s->req_nb_sectors)
              n = s->req_nb_sectors;
@@ -57,7 +57,7 @@ Index: ioemu/hw/ide.c
          ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
          ide_set_irq(s);
          ide_set_sector(s, sector_num + n);
-@@ -721,7 +725,11 @@
+@@ -879,7 +883,11 @@
              if (n > MAX_MULT_SECTORS)
                  n = MAX_MULT_SECTORS;
              sector_num = ide_get_sector(s);
@@ -70,7 +70,7 @@ Index: ioemu/hw/ide.c
              s->io_buffer_index = 0;
              s->io_buffer_size = n * 512;
              len = s->io_buffer_size;
-@@ -767,7 +775,7 @@
+@@ -925,7 +933,7 @@
  static void ide_sector_write(IDEState *s)
  {
      int64_t sector_num;
@@ -79,7 +79,7 @@ Index: ioemu/hw/ide.c
  
      s->status = READY_STAT | SEEK_STAT;
      sector_num = ide_get_sector(s);
-@@ -777,7 +785,11 @@
+@@ -935,7 +943,11 @@
      n = s->nsector;
      if (n > s->req_nb_sectors)
          n = s->req_nb_sectors;
@@ -92,7 +92,7 @@ Index: ioemu/hw/ide.c
      s->nsector -= n;
      if (s->nsector == 0) {
          /* no more sector to write */
-@@ -823,8 +835,13 @@
+@@ -981,8 +993,13 @@
          if (len == 0) {
              n = s->io_buffer_size >> 9;
              sector_num = ide_get_sector(s);
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/ide-hd-multithread
--- a/tools/ioemu/patches/ide-hd-multithread    Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/ide-hd-multithread    Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/hw/ide.c
 Index: ioemu/hw/ide.c
 ===================================================================
---- ioemu.orig/hw/ide.c        2006-08-17 19:37:36.267534285 +0100
-+++ ioemu/hw/ide.c     2006-08-17 19:49:57.830375828 +0100
+--- ioemu.orig/hw/ide.c        2007-05-03 15:03:18.000000000 +0100
++++ ioemu/hw/ide.c     2007-05-03 15:06:48.000000000 +0100
 @@ -22,6 +22,7 @@
   * THE SOFTWARE.
   */
@@ -10,7 +10,7 @@ Index: ioemu/hw/ide.c
  
  /* debug IDE devices */
  //#define DEBUG_IDE
-@@ -390,6 +391,48 @@
+@@ -390,6 +391,89 @@
      int type; /* see IDE_TYPE_xxx */
  } PCIIDEState;
  
@@ -18,17 +18,41 @@ Index: ioemu/hw/ide.c
 +
 +#ifdef DMA_MULTI_THREAD
 +
++static pthread_t ide_dma_thread;
 +static int file_pipes[2];
 +
 +static void ide_dma_loop(BMDMAState *bm);
 +static void dma_thread_loop(BMDMAState *bm);
 +
++extern int suspend_requested;
 +static void *dma_thread_func(void* opaque)
 +{
 +    BMDMAState* req;
-+
-+    while (read(file_pipes[0], &req, sizeof(req))) {
-+        dma_thread_loop(req);
++    fd_set fds;
++    int rv, nfds = file_pipes[0] + 1;
++    struct timeval tm;
++
++    while (1) {
++
++        /* Wait at most a second for the pipe to become readable */
++        FD_ZERO(&fds);
++        FD_SET(file_pipes[0], &fds);
++        tm.tv_sec = 1;
++        tm.tv_usec = 0;
++        rv = select(nfds, &fds, NULL, NULL, &tm);
++        
++        if (rv != 0) {
++            if (read(file_pipes[0], &req, sizeof(req)) == 0)
++                return NULL;
++            dma_thread_loop(req);
++        } else {
++            if (suspend_requested)  {
++                /* Need to tidy up the DMA thread so that we don't end up 
++                 * finishing operations after the domain's ioreqs are 
++                 * drained and its state saved */
++                return NULL;
++            }
++        }
 +    }
 +
 +    return NULL;
@@ -36,30 +60,47 @@ Index: ioemu/hw/ide.c
 +
 +static void dma_create_thread(void)
 +{
-+    pthread_t tid;
 +    int rt;
++    pthread_attr_t a;
 +
 +    if (pipe(file_pipes) != 0) {
 +        fprintf(stderr, "create pipe failed\n");
 +        exit(1);
 +    }
 +
-+    if ((rt = pthread_create(&tid, NULL, dma_thread_func, NULL))) {
++    if ((rt = pthread_attr_init(&a))
++        || (rt = pthread_attr_setdetachstate(&a, PTHREAD_CREATE_JOINABLE))) {
++        fprintf(stderr, "Oops, dma thread attr setup failed, errno=%d\n", rt);
++        exit(1);
++    }    
++    
++    if ((rt = pthread_create(&ide_dma_thread, &a, dma_thread_func, NULL))) {
 +        fprintf(stderr, "Oops, dma thread creation failed, errno=%d\n", rt);
 +        exit(1);
 +    }
-+
-+    if ((rt = pthread_detach(tid))) {
-+        fprintf(stderr, "Oops, dma thread detachment failed, errno=%d\n", rt);
-+        exit(1);
-+    }
++}
++
++void ide_stop_dma_thread(void)
++{
++    int rc;
++    /* Make sure the IDE DMA thread is stopped */
++    if ( (rc = pthread_join(ide_dma_thread, NULL)) != 0 )
++    {
++        fprintf(stderr, "Oops, error collecting IDE DMA thread (%s)\n", 
++                strerror(rc));
++    }
++}
++
++#else
++void ide_stop_dma_thread(void)
++{
 +}
 +#endif /* DMA_MULTI_THREAD */
 +
  static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
  
  static void padstr(char *str, const char *src, int len)
-@@ -695,7 +738,9 @@
+@@ -695,7 +779,9 @@
      }
      if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
          s->status = READY_STAT | SEEK_STAT;
@@ -69,7 +110,7 @@ Index: ioemu/hw/ide.c
  #ifdef DEBUG_IDE_ATAPI
          printf("dma status=0x%x\n", s->status);
  #endif
-@@ -795,7 +840,11 @@
+@@ -795,7 +881,11 @@
                              qemu_get_clock(vm_clock) + (ticks_per_sec / 
1000));
                  } else 
  #endif
@@ -81,7 +122,7 @@ Index: ioemu/hw/ide.c
                  return 0;
              }
              if (n > MAX_MULT_SECTORS)
-@@ -1046,7 +1095,9 @@
+@@ -1046,7 +1136,9 @@
      if (s->packet_transfer_size <= 0) {
          s->status = READY_STAT;
          s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | 
ATAPI_INT_REASON_CD;
@@ -91,7 +132,7 @@ Index: ioemu/hw/ide.c
  #ifdef DEBUG_IDE_ATAPI
          printf("dma status=0x%x\n", s->status);
  #endif
-@@ -2103,9 +2154,30 @@
+@@ -2103,9 +2195,30 @@
      }
  }
  
@@ -122,7 +163,7 @@ Index: ioemu/hw/ide.c
  {
      struct {
          uint32_t addr;
-@@ -2141,10 +2213,7 @@
+@@ -2141,10 +2254,7 @@
      }
      /* end of transfer */
   the_end:
@@ -134,7 +175,7 @@ Index: ioemu/hw/ide.c
  }
  
  static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)
-@@ -2370,6 +2439,9 @@
+@@ -2370,6 +2480,9 @@
                cmd646_set_irq, d, 0);
      ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
                cmd646_set_irq, d, 1);
@@ -143,14 +184,41 @@ Index: ioemu/hw/ide.c
 +#endif /* DMA_MULTI_THREAD */
  }
  
- /* hd_table must contain 4 block drivers */
-@@ -2405,6 +2477,9 @@
-               pic_set_irq_new, isa_pic, 15);
-     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
-     ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+ static void pci_ide_save(QEMUFile* f, void *opaque)
+@@ -2522,6 +2635,10 @@
+ 
+     register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d);
+     register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
++
 +#ifdef DMA_MULTI_THREAD    
 +    dma_create_thread();
 +#endif //DMA_MULTI_THREAD    
  }
  
  /***********************************************************/
+Index: ioemu/target-i386-dm/helper2.c
+===================================================================
+--- ioemu.orig/target-i386-dm/helper2.c        2007-05-03 15:03:18.000000000 
+0100
++++ ioemu/target-i386-dm/helper2.c     2007-05-03 15:06:41.000000000 +0100
+@@ -556,6 +556,9 @@
+     handle_buffered_io(env);
+     main_loop_wait(1); /* For the select() on events */
+ 
++    /* Stop the IDE thread */
++    ide_stop_dma_thread();
++
+     /* Save the device state */
+     sprintf(qemu_file, "/tmp/xen.qemu-dm.%d", domid);
+     if (qemu_savevm(qemu_file) < 0)
+Index: ioemu/vl.h
+===================================================================
+--- ioemu.orig/vl.h    2007-05-03 15:03:18.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:06:42.000000000 +0100
+@@ -797,6 +797,7 @@
+ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn);
+ int pmac_ide_init (BlockDriverState **hd_table,
+                    SetIRQFunc *set_irq, void *irq_opaque, int irq);
++void ide_stop_dma_thread(void);
+ 
+ /* cdrom.c */
+ int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/ioemu-buffer-pio-ia64
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-buffer-pio-ia64 Tue May 08 09:09:17 2007 -0600
@@ -0,0 +1,215 @@
+Index: ioemu/vl.c
+===================================================================
+--- ioemu.orig/vl.c    2007-05-03 15:07:15.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:07:15.000000000 +0100
+@@ -5924,6 +5924,7 @@
+     unsigned long ioreq_pfn;
+     extern void *shared_page;
+     extern void *buffered_io_page;
++    extern void *buffered_pio_page;
+     unsigned long nr_pages;
+ 
+     char qemu_dm_logfilename[64];
+@@ -6530,6 +6531,10 @@
+                                        PROT_READ|PROT_WRITE,
+                                        BUFFER_IO_PAGE_START >> PAGE_SHIFT);
+ 
++    buffered_pio_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
++                                       PROT_READ|PROT_WRITE,
++                                       BUFFER_PIO_PAGE_START >> PAGE_SHIFT);
++
+     for (i = 0; i < nr_pages; i++)
+         page_array[i] = i;
+       
+Index: ioemu/hw/ide.c
+===================================================================
+--- ioemu.orig/hw/ide.c        2007-05-03 15:07:15.000000000 +0100
++++ ioemu/hw/ide.c     2007-05-03 15:07:15.000000000 +0100
+@@ -474,6 +474,121 @@
+ }
+ #endif /* DMA_MULTI_THREAD */
+ 
++#if defined(__ia64__)
++#include <xen/hvm/ioreq.h>
++
++struct buffered_piopage *buffered_pio_page;
++
++static inline struct pio_buffer *
++piobuf_by_addr(uint32_t addr)
++{
++    if (addr == 0x1F0)
++        return &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
++    if (addr == 0x170)
++        return &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
++    return NULL;
++}
++
++static void
++buffered_pio_init(void)
++{
++    struct pio_buffer *p1, *p2;
++    uint32_t off1, off2;
++
++    if (!buffered_pio_page)
++        return;
++
++    p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
++    p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
++    off1 = offsetof(struct buffered_piopage, buffer);
++    off2 = (off1 + TARGET_PAGE_SIZE)/2;
++
++    p1->buf_size = off2 - off1;
++    p1->page_offset = off1;
++
++    p2->buf_size = TARGET_PAGE_SIZE - off2;
++    p2->page_offset = off2;
++}
++
++static inline void
++buffered_pio_flush(struct pio_buffer *piobuf)
++{
++    IDEState *s = piobuf->opaque;
++    uint32_t pointer = piobuf->pointer;
++
++    if (s != NULL && pointer > 0) {
++        uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
++        memcpy(s->data_ptr, buf, pointer);
++        s->data_ptr += pointer;
++    }
++}
++
++static inline void
++buffered_pio_reset(IDEState *s)
++{
++    struct pio_buffer *piobuf;
++
++    if ((unsigned)s->drive_serial - 1 < 2)      /* 1,2 */
++        piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
++    else if ((unsigned)s->drive_serial - 3 < 2) /* 3,4 */
++        piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
++    else
++        return;
++    buffered_pio_flush(piobuf);
++    piobuf->pointer = 0;
++    piobuf->data_end = 0;
++    piobuf->opaque = NULL;
++}
++
++static inline void
++buffered_pio_write(IDEState *s, uint32_t addr, int size)
++{
++    struct pio_buffer *piobuf = piobuf_by_addr(addr);
++    int data_end;
++
++    if (!piobuf)
++        return;
++    buffered_pio_flush(piobuf);
++    data_end = s->data_end - s->data_ptr - size;
++    if (data_end <= 0)
++        data_end = 0;
++    else if (data_end > piobuf->buf_size)
++        data_end = piobuf->buf_size;
++    piobuf->pointer = 0;
++    piobuf->data_end = data_end;
++    piobuf->opaque = s;
++}
++
++static inline void
++buffered_pio_read(IDEState *s, uint32_t addr, int size)
++{
++    struct pio_buffer *piobuf = piobuf_by_addr(addr);
++    int data_end;
++
++    if (!piobuf)
++        return;
++    s->data_ptr += piobuf->pointer;
++    data_end = s->data_end - s->data_ptr - size;
++    if (data_end <= 0) {
++        data_end = 0;
++    } else {
++      uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
++        if (data_end > piobuf->buf_size)
++            data_end = piobuf->buf_size;
++        memcpy(buf, s->data_ptr + size, data_end);
++    }
++    piobuf->pointer = 0;
++    piobuf->data_end = data_end;
++    piobuf->opaque = NULL;
++}
++
++#else /* !__ia64__ */
++#define buffered_pio_init()         do {} while (0)
++#define buffered_pio_reset(I)       do {} while (0)
++#define buffered_pio_write(I,A,S)   do {} while (0)
++#define buffered_pio_read(I,A,S)    do {} while (0)
++#endif
++
+ static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
+ 
+ static void padstr(char *str, const char *src, int len)
+@@ -658,6 +773,7 @@
+     s->data_ptr = buf;
+     s->data_end = buf + size;
+     s->status |= DRQ_STAT;
++    buffered_pio_reset(s);
+ }
+ 
+ static void ide_transfer_stop(IDEState *s)
+@@ -666,6 +782,7 @@
+     s->data_ptr = s->io_buffer;
+     s->data_end = s->io_buffer;
+     s->status &= ~DRQ_STAT;
++    buffered_pio_reset(s);
+ }
+ 
+ static int64_t ide_get_sector(IDEState *s)
+@@ -1578,6 +1695,7 @@
+         ide_if[0].select = (val & ~0x10) | 0xa0;
+         ide_if[1].select = (val | 0x10) | 0xa0;
+         /* select drive */
++        buffered_pio_reset(ide_if->cur_drive);
+         unit = (val >> 4) & 1;
+         s = ide_if + unit;
+         ide_if->cur_drive = s;
+@@ -1936,6 +2054,7 @@
+     IDEState *s = ((IDEState *)opaque)->cur_drive;
+     uint8_t *p;
+ 
++    buffered_pio_write(s, addr, 2);
+     p = s->data_ptr;
+     *(uint16_t *)p = le16_to_cpu(val);
+     p += 2;
+@@ -1949,6 +2068,8 @@
+     IDEState *s = ((IDEState *)opaque)->cur_drive;
+     uint8_t *p;
+     int ret;
++    
++    buffered_pio_read(s, addr, 2);
+     p = s->data_ptr;
+     ret = cpu_to_le16(*(uint16_t *)p);
+     p += 2;
+@@ -1963,6 +2084,7 @@
+     IDEState *s = ((IDEState *)opaque)->cur_drive;
+     uint8_t *p;
+ 
++    buffered_pio_write(s, addr, 4);
+     p = s->data_ptr;
+     *(uint32_t *)p = le32_to_cpu(val);
+     p += 4;
+@@ -1977,6 +2099,7 @@
+     uint8_t *p;
+     int ret;
+     
++    buffered_pio_read(s, addr, 4);
+     p = s->data_ptr;
+     ret = cpu_to_le32(*(uint32_t *)p);
+     p += 4;
+@@ -2634,6 +2757,8 @@
+     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
+     ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+ 
++    buffered_pio_init();
++
+     register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d);
+     register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
+ 
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/ioemu-ia64
--- a/tools/ioemu/patches/ioemu-ia64    Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/ioemu-ia64    Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/hw/iommu.c
 Index: ioemu/hw/iommu.c
 ===================================================================
---- ioemu.orig/hw/iommu.c      2006-12-20 15:04:54.000000000 +0000
-+++ ioemu/hw/iommu.c   2006-12-20 15:04:54.000000000 +0000
+--- ioemu.orig/hw/iommu.c      2007-05-03 09:56:32.000000000 +0100
++++ ioemu/hw/iommu.c   2007-05-03 10:05:51.000000000 +0100
 @@ -82,7 +82,11 @@
  #define IOPTE_VALID         0x00000002 /* IOPTE is valid */
  #define IOPTE_WAZ           0x00000001 /* Write as zeros */
@@ -16,8 +16,8 @@ Index: ioemu/hw/iommu.c
  
 Index: ioemu/cpu-all.h
 ===================================================================
---- ioemu.orig/cpu-all.h       2006-12-20 15:04:54.000000000 +0000
-+++ ioemu/cpu-all.h    2006-12-20 15:04:54.000000000 +0000
+--- ioemu.orig/cpu-all.h       2007-05-03 09:56:32.000000000 +0100
++++ ioemu/cpu-all.h    2007-05-03 10:05:51.000000000 +0100
 @@ -835,6 +835,31 @@
                  :"=m" (*(volatile long *)addr)
                  :"dIr" (nr));
@@ -52,17 +52,13 @@ Index: ioemu/cpu-all.h
  /* memory API */
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:04:54.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:12:00.000000000 +0000
-@@ -6137,6 +6137,15 @@
+--- ioemu.orig/vl.c    2007-05-03 10:04:06.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:25:23.000000000 +0100
+@@ -6142,6 +6142,11 @@
              exit(1);
      }
  
 +#if defined (__ia64__)
-+    /* ram_size passed from xend has added on GFW memory,
-+       so we must subtract it here */
-+    ram_size -= 16 * MEM_M;
-+
 +    if (ram_size > MMIO_START)
 +        ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */
 +#endif
@@ -70,20 +66,20 @@ Index: ioemu/vl.c
      /* init the memory */
      phys_ram_size = ram_size + vga_ram_size + bios_size;
  
-@@ -6161,6 +6170,7 @@
-         exit(-1);
-     }
- 
-+#if defined(__i386__) || defined(__x86_64__)
-     for ( i = 0; i < tmp_nr_pages; i++)
-         page_array[i] = i;
- 
-@@ -6185,6 +6195,36 @@
+@@ -6182,6 +6187,44 @@
  
      free(page_array);
  
 +#elif defined(__ia64__)
-+  
++
++    nr_pages = ram_size/PAGE_SIZE;
++
++    page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
++    if (page_array == NULL) {
++        fprintf(logfile, "malloc returned error %d\n", errno);
++        exit(-1);
++    }
++
 +    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
 +                                       PROT_READ|PROT_WRITE,
 +                                       IO_PAGE_START >> PAGE_SHIFT);
@@ -92,7 +88,7 @@ Index: ioemu/vl.c
 +                                       PROT_READ|PROT_WRITE,
 +                                       BUFFER_IO_PAGE_START >> PAGE_SHIFT);
 +
-+    for (i = 0; i < tmp_nr_pages; i++)
++    for (i = 0; i < nr_pages; i++)
 +        page_array[i] = i;
 +      
 +    /* VTI will not use memory between 3G~4G, so we just pass a legal pfn
@@ -117,8 +113,8 @@ Index: ioemu/vl.c
      phys_ram_base = qemu_vmalloc(phys_ram_size);
 Index: ioemu/exec-all.h
 ===================================================================
---- ioemu.orig/exec-all.h      2006-12-20 15:04:54.000000000 +0000
-+++ ioemu/exec-all.h   2006-12-20 15:04:54.000000000 +0000
+--- ioemu.orig/exec-all.h      2007-05-03 09:56:32.000000000 +0100
++++ ioemu/exec-all.h   2007-05-03 10:05:51.000000000 +0100
 @@ -462,12 +462,13 @@
  }
  #endif
@@ -138,8 +134,8 @@ Index: ioemu/exec-all.h
  
 Index: ioemu/target-i386-dm/cpu.h
 ===================================================================
---- ioemu.orig/target-i386-dm/cpu.h    2006-12-20 15:04:54.000000000 +0000
-+++ ioemu/target-i386-dm/cpu.h 2006-12-20 15:10:13.000000000 +0000
+--- ioemu.orig/target-i386-dm/cpu.h    2007-05-03 09:56:32.000000000 +0100
++++ ioemu/target-i386-dm/cpu.h 2007-05-03 10:25:13.000000000 +0100
 @@ -78,7 +78,11 @@
  /* helper2.c */
  int main_loop(void);
@@ -155,7 +151,7 @@ Index: ioemu/ia64_intrinsic.h
 Index: ioemu/ia64_intrinsic.h
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/ia64_intrinsic.h     2006-12-20 15:04:54.000000000 +0000
++++ ioemu/ia64_intrinsic.h     2007-05-03 10:05:51.000000000 +0100
 @@ -0,0 +1,276 @@
 +#ifndef IA64_INTRINSIC_H
 +#define IA64_INTRINSIC_H
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/ioemu-save-restore
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-save-restore    Tue May 08 09:09:17 2007 -0600
@@ -0,0 +1,225 @@
+Index: ioemu/hw/cirrus_vga.c
+===================================================================
+--- ioemu.orig/hw/cirrus_vga.c 2007-05-03 15:03:18.000000000 +0100
++++ ioemu/hw/cirrus_vga.c      2007-05-03 15:08:02.000000000 +0100
+@@ -3011,11 +3011,42 @@
+     cirrus_mmio_writel,
+ };
+ 
++void cirrus_stop_acc(CirrusVGAState *s)
++{
++    if (s->map_addr){
++        int error;
++        s->map_addr = 0;
++        error = unset_vram_mapping(s->cirrus_lfb_addr,
++                s->cirrus_lfb_end, s->vram_ptr);
++        fprintf(stderr, "cirrus_stop_acc:unset_vram_mapping.\n");
++    }
++}
++
++void cirrus_restart_acc(CirrusVGAState *s)
++{
++    if (s->cirrus_lfb_addr && s->cirrus_lfb_end) {
++        void *vram_pointer, *old_vram;
++        fprintf(stderr, "cirrus_vga_load:re-enable vga acc.lfb_addr=0x%lx, 
lfb_end=0x%lx.\n",
++                s->cirrus_lfb_addr, s->cirrus_lfb_end);
++        vram_pointer = set_vram_mapping(s->cirrus_lfb_addr 
,s->cirrus_lfb_end);
++        if (!vram_pointer){
++            fprintf(stderr, "cirrus_vga_load:NULL vram_pointer\n");
++        } else {
++            old_vram = vga_update_vram((VGAState *)s, vram_pointer,
++                    VGA_RAM_SIZE);
++            qemu_free(old_vram);
++            s->map_addr = s->cirrus_lfb_addr;
++            s->map_end = s->cirrus_lfb_end;
++        }
++    }
++}
++
+ /* load/save state */
+ 
+ static void cirrus_vga_save(QEMUFile *f, void *opaque)
+ {
+     CirrusVGAState *s = opaque;
++    uint8_t vga_acc;
+ 
+     qemu_put_be32s(f, &s->latch);
+     qemu_put_8s(f, &s->sr_index);
+@@ -3050,11 +3081,20 @@
+     qemu_put_be32s(f, &s->hw_cursor_y);
+     /* XXX: we do not save the bitblt state - we assume we do not save
+        the state when the blitter is active */
++
++    vga_acc = (!!s->map_addr);
++    qemu_put_8s(f, &vga_acc);
++    qemu_put_be64s(f, (uint64_t*)&s->cirrus_lfb_addr);
++    qemu_put_be64s(f, (uint64_t*)&s->cirrus_lfb_end);
++    qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE); 
++    if (vga_acc)
++        cirrus_stop_acc(s);
+ }
+ 
+ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
+ {
+     CirrusVGAState *s = opaque;
++    uint8_t vga_acc = 0;
+ 
+     if (version_id != 1)
+         return -EINVAL;
+@@ -3093,6 +3133,14 @@
+     qemu_get_be32s(f, &s->hw_cursor_x);
+     qemu_get_be32s(f, &s->hw_cursor_y);
+ 
++    qemu_get_8s(f, &vga_acc);
++    qemu_get_be64s(f, (uint64_t*)&s->cirrus_lfb_addr);
++    qemu_get_be64s(f, (uint64_t*)&s->cirrus_lfb_end);
++    qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE); 
++    if (vga_acc){
++        cirrus_restart_acc(s);
++    }
++
+     /* force refresh */
+     s->graphic_mode = -1;
+     cirrus_update_bank_ptr(s, 0);
+@@ -3298,6 +3346,8 @@
+                     ds, vga_ram_base, vga_ram_offset, vga_ram_size);
+     cirrus_init_common(s, device_id, 1);
+ 
++    register_savevm("cirrus_vga_pci", 0, 1, generic_pci_save, 
generic_pci_load, d);
++
+     /* setup memory space */
+     /* memory #0 LFB */
+     /* memory #1 memory-mapped I/O */
+Index: ioemu/vl.c
+===================================================================
+--- ioemu.orig/vl.c    2007-05-03 15:03:18.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:08:04.000000000 +0100
+@@ -4470,6 +4470,11 @@
+         qemu_fseek(f, cur_pos + record_len, SEEK_SET);
+     }
+     fclose(f);
++
++    /* del tmp file */
++    if (unlink(filename) == -1)
++        fprintf(stderr, "delete tmp qemu state file failed.\n");
++
+     ret = 0;
+  the_end:
+     if (saved_vm_running)
+@@ -5056,6 +5061,7 @@
+ static QEMUResetEntry *first_reset_entry;
+ int reset_requested;
+ int shutdown_requested;
++int suspend_requested;
+ static int powerdown_requested;
+ 
+ void qemu_register_reset(QEMUResetHandler *func, void *opaque)
+@@ -5816,6 +5822,15 @@
+     return 0;
+ }
+ 
++void suspend(int sig)
++{
++    fprintf(logfile, "suspend sig handler called with requested=%d!\n",
++            suspend_requested);
++    if (sig != SIGUSR1)
++        fprintf(logfile, "suspend signal dismatch, get sig=%d!\n", sig);
++    suspend_requested = 1;
++}
++
+ int main(int argc, char **argv)
+ {
+ #ifdef CONFIG_GDBSTUB
+@@ -6581,6 +6596,26 @@
+             vm_start();
+         }
+     }
++
++    /* register signal for the suspend request when save */
++    {
++        struct sigaction act;
++        sigset_t set;
++        act.sa_handler = suspend;
++        act.sa_flags = SA_RESTART;
++        sigemptyset(&act.sa_mask);
++
++        sigaction(SIGUSR1, &act, NULL);
++
++        /* control panel mask some signals when spawn qemu, need unmask here*/
++        sigemptyset(&set);
++        sigaddset(&set, SIGUSR1);
++        sigaddset(&set, SIGTERM);
++        if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
++            fprintf(stderr, "unblock signal fail, possible issue for HVM 
save!\n");
++
++    }
++
+     main_loop();
+     quit_timers();
+     return 0;
+Index: ioemu/hw/pci.c
+===================================================================
+--- ioemu.orig/hw/pci.c        2007-05-03 15:03:12.000000000 +0100
++++ ioemu/hw/pci.c     2007-05-03 15:08:02.000000000 +0100
+@@ -40,6 +40,8 @@
+ static int pci_irq_index;
+ static PCIBus *first_bus;
+ 
++static void pci_update_mappings(PCIDevice *d);
++
+ PCIBus *pci_register_bus(pci_set_irq_fn set_irq, void *pic, int devfn_min)
+ {
+     PCIBus *bus;
+@@ -71,6 +73,7 @@
+         return -EINVAL;
+ 
+     qemu_get_buffer(f, s->config, 256);
++    pci_update_mappings(s);
+     return 0;
+ }
+ 
+Index: ioemu/hw/ide.c
+===================================================================
+--- ioemu.orig/hw/ide.c        2007-05-03 15:03:12.000000000 +0100
++++ ioemu/hw/ide.c     2007-05-03 15:08:04.000000000 +0100
+@@ -2405,6 +2405,8 @@
+               pic_set_irq_new, isa_pic, 15);
+     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
+     ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
++
++    register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d);
+ }
+ 
+ /***********************************************************/
+Index: ioemu/target-i386-dm/helper2.c
+===================================================================
+--- ioemu.orig/target-i386-dm/helper2.c        2007-05-03 15:03:18.000000000 
+0100
++++ ioemu/target-i386-dm/helper2.c     2007-05-03 15:09:10.000000000 +0100
+@@ -540,8 +540,10 @@
+ {
+     extern int vm_running;
+     extern int shutdown_requested;
++    extern int suspend_requested;
+     CPUState *env = cpu_single_env;
+     int evtchn_fd = xc_evtchn_fd(xce_handle);
++    char qemu_file[20];
+ 
+     qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
+ 
+@@ -549,7 +551,15 @@
+         /* Wait up to 10 msec. */
+         main_loop_wait(10);
+ 
+-    destroy_hvm_domain();
++    fprintf(logfile, "device model received suspend signal!\n");
++
++    /* Pull all outstanding ioreqs through the system */
++    main_loop_wait(1); /* For the select() on events */
++
++    /* Save the device state */
++    sprintf(qemu_file, "/tmp/xen.qemu-dm.%d", domid);
++    if (qemu_savevm(qemu_file) < 0)
++        fprintf(stderr, "qemu save fail.\n");
+ 
+     return 0;
+ }
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/ioemu-save-restore-acpi
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-save-restore-acpi       Tue May 08 09:09:17 
2007 -0600
@@ -0,0 +1,34 @@
+Index: ioemu/hw/piix4acpi.c
+===================================================================
+--- ioemu.orig/hw/piix4acpi.c  2007-05-03 15:07:43.000000000 +0100
++++ ioemu/hw/piix4acpi.c       2007-05-03 15:07:43.000000000 +0100
+@@ -57,6 +57,20 @@
+     uint16_t pm1_control; /* pm1a_ECNT_BLK */
+ } PCIAcpiState;
+ 
++static void piix4acpi_save(QEMUFile *f, void *opaque)
++{
++    PCIAcpiState *s = opaque;
++    qemu_put_be16s(f, &s->pm1_control);
++}
++
++static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id)
++{
++    PCIAcpiState *s = opaque;
++    if (version_id > 1) 
++        return -EINVAL;
++    qemu_get_be16s(f, &s->pm1_control);
++}
++
+ static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
+ {
+     PCIAcpiState *s = opaque;
+@@ -193,4 +207,8 @@
+     d->pm1_control = SCI_EN;
+ 
+     acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
++
++    register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d);    
++    register_savevm("piix4acpi_pci", 0, 1, generic_pci_save, 
generic_pci_load, 
++                    &d->dev);
+ }
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/ioemu-save-restore-ide
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-save-restore-ide        Tue May 08 09:09:17 
2007 -0600
@@ -0,0 +1,133 @@
+Index: ioemu/hw/ide.c
+===================================================================
+--- ioemu.orig/hw/ide.c        2007-05-02 14:12:00.000000000 +0100
++++ ioemu/hw/ide.c     2007-05-02 14:12:40.000000000 +0100
+@@ -2372,6 +2372,120 @@
+               cmd646_set_irq, d, 1);
+ }
+ 
++static void pci_ide_save(QEMUFile* f, void *opaque)
++{
++    PCIIDEState *d = opaque;
++    int i;
++
++    for(i = 0; i < 2; i++) {
++        BMDMAState *bm = &d->bmdma[i];
++        qemu_put_8s(f, &bm->cmd);
++        qemu_put_8s(f, &bm->status);
++        qemu_put_be32s(f, &bm->addr);
++        /* XXX: if a transfer is pending, we do not save it yet */
++    }
++
++    /* per IDE interface data */
++    for(i = 0; i < 2; i++) {
++        IDEState *s = &d->ide_if[i * 2];
++        uint8_t drive1_selected;
++        qemu_put_8s(f, &s->cmd);
++        drive1_selected = (s->cur_drive != s);
++        qemu_put_8s(f, &drive1_selected);
++    }
++
++    /* per IDE drive data */
++    for(i = 0; i < 4; i++) {
++        IDEState *s = &d->ide_if[i];
++        qemu_put_be32s(f, &s->mult_sectors);
++        qemu_put_be32s(f, &s->identify_set);
++        if (s->identify_set) {
++            qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
++        }
++        qemu_put_8s(f, &s->write_cache);
++        qemu_put_8s(f, &s->feature);
++        qemu_put_8s(f, &s->error);
++        qemu_put_be32s(f, &s->nsector);
++        qemu_put_8s(f, &s->sector);
++        qemu_put_8s(f, &s->lcyl);
++        qemu_put_8s(f, &s->hcyl);
++        qemu_put_8s(f, &s->hob_feature);
++        qemu_put_8s(f, &s->hob_nsector);
++        qemu_put_8s(f, &s->hob_sector);
++        qemu_put_8s(f, &s->hob_lcyl);
++        qemu_put_8s(f, &s->hob_hcyl);
++        qemu_put_8s(f, &s->select);
++        qemu_put_8s(f, &s->status);
++        qemu_put_8s(f, &s->lba48);
++
++        qemu_put_8s(f, &s->sense_key);
++        qemu_put_8s(f, &s->asc);
++        /* XXX: if a transfer is pending, we do not save it yet */
++    }
++}
++
++static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
++{
++    PCIIDEState *d = opaque;
++    int ret, i;
++
++    if (version_id != 1)
++        return -EINVAL;
++
++    for(i = 0; i < 2; i++) {
++        BMDMAState *bm = &d->bmdma[i];
++        qemu_get_8s(f, &bm->cmd);
++        qemu_get_8s(f, &bm->status);
++        qemu_get_be32s(f, &bm->addr);
++        /* XXX: if a transfer is pending, we do not save it yet */
++    }
++
++    /* per IDE interface data */
++    for(i = 0; i < 2; i++) {
++        IDEState *s = &d->ide_if[i * 2];
++        uint8_t drive1_selected;
++        qemu_get_8s(f, &s->cmd);
++        qemu_get_8s(f, &drive1_selected);
++        s->cur_drive = &d->ide_if[i * 2 + (drive1_selected != 0)];
++    }
++
++    /* per IDE drive data */
++    for(i = 0; i < 4; i++) {
++        IDEState *s = &d->ide_if[i];
++        qemu_get_be32s(f, &s->mult_sectors);
++        qemu_get_be32s(f, &s->identify_set);
++        if (s->identify_set) {
++            qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
++        }
++        qemu_get_8s(f, &s->write_cache);
++        qemu_get_8s(f, &s->feature);
++        qemu_get_8s(f, &s->error);
++        qemu_get_be32s(f, &s->nsector);
++        qemu_get_8s(f, &s->sector);
++        qemu_get_8s(f, &s->lcyl);
++        qemu_get_8s(f, &s->hcyl);
++        qemu_get_8s(f, &s->hob_feature);
++        qemu_get_8s(f, &s->hob_nsector);
++        qemu_get_8s(f, &s->hob_sector);
++        qemu_get_8s(f, &s->hob_lcyl);
++        qemu_get_8s(f, &s->hob_hcyl);
++        qemu_get_8s(f, &s->select);
++        qemu_get_8s(f, &s->status);
++        qemu_get_8s(f, &s->lba48);
++
++        qemu_get_8s(f, &s->sense_key);
++        qemu_get_8s(f, &s->asc);
++        /* XXX: if a transfer is pending, we do not save it yet */
++        if (s->status & (DRQ_STAT|BUSY_STAT)) {
++            /* Tell the guest that its transfer has gone away */
++            ide_abort_command(s);
++            ide_set_irq(s);
++        }
++    }
++    return 0;
++}
++
++
+ /* hd_table must contain 4 block drivers */
+ /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
+ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
+@@ -2407,6 +2521,7 @@
+     ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+ 
+     register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d);
++    register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
+ }
+ 
+ /***********************************************************/
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/ioemu-save-restore-logdirty
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-save-restore-logdirty   Tue May 08 09:09:17 
2007 -0600
@@ -0,0 +1,190 @@
+Index: ioemu/xenstore.c
+===================================================================
+--- ioemu.orig/xenstore.c      2007-05-03 10:42:11.000000000 +0100
++++ ioemu/xenstore.c   2007-05-03 14:17:13.000000000 +0100
+@@ -11,6 +11,11 @@
+ #include "vl.h"
+ #include "block_int.h"
+ #include <unistd.h>
++#include <sys/ipc.h>
++#include <sys/shm.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
+ 
+ static struct xs_handle *xsh = NULL;
+ static char *media_filename[MAX_DISKS];
+@@ -173,6 +178,13 @@
+       }
+     }
+ 
++    /* Set a watch for log-dirty requests from the migration tools */
++    if (pasprintf(&buf, "%s/logdirty/next-active", path) != -1) {
++        xs_watch(xsh, buf, "logdirty");
++        fprintf(logfile, "Watching %s\n", buf);
++    }
++
++
+  out:
+     free(type);
+     free(params);
+@@ -191,6 +203,112 @@
+     return -1;
+ }
+ 
++unsigned long *logdirty_bitmap = NULL;
++unsigned long logdirty_bitmap_size;
++extern int vga_ram_size, bios_size;
++
++void xenstore_process_logdirty_event(void)
++{
++    char *act;
++    static char *active_path = NULL;
++    static char *next_active_path = NULL;
++    static char *seg = NULL;
++    unsigned int len;
++    int i;
++
++    fprintf(logfile, "Triggered log-dirty buffer switch\n");
++
++    if (!seg) {
++        char *path, *p, *key_ascii, key_terminated[17] = {0,};
++        key_t key;
++        int shmid;
++
++        /* Find and map the shared memory segment for log-dirty bitmaps */
++        if (!(path = xs_get_domain_path(xsh, domid))) {            
++            fprintf(logfile, "Log-dirty: can't get domain path in store\n");
++            exit(1);
++        }
++        if (!(path = realloc(path, strlen(path) 
++                             + strlen("/logdirty/next-active") + 1))) {
++            fprintf(logfile, "Log-dirty: out of memory\n");
++            exit(1);
++        }
++        strcat(path, "/logdirty/");
++        p = path + strlen(path);
++        strcpy(p, "key");
++        
++        key_ascii = xs_read(xsh, XBT_NULL, path, &len);
++        if (!key_ascii) {
++            /* No key yet: wait for the next watch */
++            free(path);
++            return;
++        }
++        strncpy(key_terminated, key_ascii, 16);
++        free(key_ascii);
++        key = (key_t) strtoull(key_terminated, NULL, 16);
++
++        /* Figure out how bit the log-dirty bitmaps are */
++        logdirty_bitmap_size = xc_memory_op(xc_handle, 
++                                            XENMEM_maximum_gpfn, &domid) + 1;
++        logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1)
++                                / HOST_LONG_BITS); /* longs */
++        logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */
++
++        /* Map the shared-memory segment */
++        if ((shmid = shmget(key, 
++                            2 * logdirty_bitmap_size, 
++                            S_IRUSR|S_IWUSR)) == -1 
++            || (seg = shmat(shmid, NULL, 0)) == (void *)-1) {
++            fprintf(logfile, "Log-dirty: can't map segment %16.16llx (%s)\n",
++                    (unsigned long long) key, strerror(errno));
++            exit(1);
++        }
++
++        fprintf(logfile, "Log-dirty: mapped segment at %p\n", seg);
++
++        /* Double-check that the bitmaps are the size we expect */
++        if (logdirty_bitmap_size != *(uint32_t *)seg) {
++            fprintf(logfile, "Log-dirty: got %u, calc %lu\n", 
++                    *(uint32_t *)seg, logdirty_bitmap_size);
++            return;
++        }
++
++        /* Remember the paths for the next-active and active entries */
++        strcpy(p, "active");
++        if (!(active_path = strdup(path))) {
++            fprintf(logfile, "Log-dirty: out of memory\n");
++            exit(1);
++        }
++        strcpy(p, "next-active");
++        if (!(next_active_path = strdup(path))) {
++            fprintf(logfile, "Log-dirty: out of memory\n");
++            exit(1);
++        }
++        free(path);
++    }
++    
++    /* Read the required active buffer from the store */
++    act = xs_read(xsh, XBT_NULL, next_active_path, &len);
++    if (!act) {
++        fprintf(logfile, "Log-dirty: can't read next-active\n");
++        exit(1);
++    }
++
++    /* Switch buffers */
++    i = act[0] - '0';
++    if (i != 0 && i != 1) {
++        fprintf(logfile, "Log-dirty: bad next-active entry: %s\n", act);
++        exit(1);
++    }
++    logdirty_bitmap = (unsigned long *)(seg + i * logdirty_bitmap_size);
++
++    /* Ack that we've switched */
++    xs_write(xsh, XBT_NULL, active_path, act, len);
++    free(act);
++}
++
++
++
+ void xenstore_process_event(void *opaque)
+ {
+     char **vec, *image = NULL;
+@@ -200,6 +318,11 @@
+     if (!vec)
+       return;
+ 
++    if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
++        xenstore_process_logdirty_event();
++        goto out;
++    }
++
+     if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
+       strlen(vec[XS_WATCH_TOKEN]) != 3)
+       goto out;
+Index: ioemu/target-i386-dm/exec-dm.c
+===================================================================
+--- ioemu.orig/target-i386-dm/exec-dm.c        2007-05-03 14:13:38.000000000 
+0100
++++ ioemu/target-i386-dm/exec-dm.c     2007-05-03 14:18:14.000000000 +0100
+@@ -431,6 +431,9 @@
+ #define phys_ram_addr(x) ((addr < ram_size) ? (phys_ram_base + (x)) : NULL)
+ #endif
+ 
++extern unsigned long *logdirty_bitmap;
++extern unsigned long logdirty_bitmap_size;
++
+ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
+                             int len, int is_write)
+ {
+@@ -466,8 +469,19 @@
+                     l = 1;
+                 }
+             } else if ((ptr = phys_ram_addr(addr)) != NULL) {
+-                /* Reading from RAM */
++                /* Writing to RAM */
+                 memcpy(ptr, buf, l);
++                if (logdirty_bitmap != NULL) {
++                    /* Record that we have dirtied this frame */
++                    unsigned long pfn = addr >> TARGET_PAGE_BITS;
++                    if (pfn / 8 >= logdirty_bitmap_size) {
++                        fprintf(logfile, "dirtying pfn %lx >= bitmap "
++                                "size %lx\n", pfn, logdirty_bitmap_size * 8);
++                    } else {
++                        logdirty_bitmap[pfn / HOST_LONG_BITS]
++                            |= 1UL << pfn % HOST_LONG_BITS;
++                    }
++                }
+ #ifdef __ia64__
+                 sync_icache(ptr, l);
+ #endif 
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/ioemu-save-restore-ne2000
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-save-restore-ne2000     Tue May 08 09:09:17 
2007 -0600
@@ -0,0 +1,34 @@
+Index: ioemu/hw/ne2000.c
+===================================================================
+--- ioemu.orig/hw/ne2000.c     2007-05-02 16:09:35.000000000 +0100
++++ ioemu/hw/ne2000.c  2007-05-02 16:10:03.000000000 +0100
+@@ -739,7 +739,7 @@
+              s->macaddr[4],
+              s->macaddr[5]);
+              
+-    register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
++    register_savevm("ne2000", base, 2, ne2000_save, ne2000_load, s);
+ }
+ 
+ /***********************************************************/
+@@ -775,6 +775,7 @@
+     PCINE2000State *d;
+     NE2000State *s;
+     uint8_t *pci_conf;
++    int instance;
+     
+     d = (PCINE2000State *)pci_register_device(bus,
+                                               "NE2000", 
sizeof(PCINE2000State),
+@@ -809,8 +810,8 @@
+              s->macaddr[4],
+              s->macaddr[5]);
+              
+-    /* XXX: instance number ? */
+-    register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
+-    register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load, 
+-                    &d->dev);
++    instance = pci_bus_num(bus) << 8 | s->pci_dev->devfn;
++    register_savevm("ne2000", instance, 2, ne2000_save, ne2000_load, s);
++    register_savevm("ne2000_pci", instance, 1, generic_pci_save, 
++                    generic_pci_load, &d->dev);
+ }
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/ioemu-save-restore-pcnet
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-save-restore-pcnet      Tue May 08 09:09:17 
2007 -0600
@@ -0,0 +1,80 @@
+Index: ioemu/hw/pcnet.c
+===================================================================
+--- ioemu.orig/hw/pcnet.c      2007-05-02 16:09:36.000000000 +0100
++++ ioemu/hw/pcnet.c   2007-05-02 16:10:28.000000000 +0100
+@@ -1727,10 +1727,63 @@
+     cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_io_addr);
+ }
+ 
++
++static void pcnet_save(QEMUFile *f, void *opaque)
++{
++    PCNetState *s = opaque;
++    unsigned int i;
++
++    qemu_put_be32s(f, &s->rap);
++    qemu_put_be32s(f, &s->isr);
++    qemu_put_be32s(f, &s->lnkst);
++    qemu_put_be32s(f, &s->rdra);
++    qemu_put_be32s(f, &s->tdra);
++    qemu_put_buffer(f, s->prom, 16);
++    for (i = 0; i < 128; i++)
++        qemu_put_be16s(f, &s->csr[i]);
++    for (i = 0; i < 32; i++)
++        qemu_put_be16s(f, &s->bcr[i]);
++    qemu_put_be64s(f, &s->timer);
++    qemu_put_be32s(f, &s->xmit_pos);
++    qemu_put_be32s(f, &s->recv_pos);
++    qemu_put_buffer(f, s->buffer, 4096);
++    qemu_put_be32s(f, &s->tx_busy);
++    qemu_put_timer(f, s->poll_timer);
++}
++
++static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
++{
++    PCNetState *s = opaque;
++    int i, ret;
++
++    if (version_id != 1)
++        return -EINVAL;
++
++    qemu_get_be32s(f, &s->rap);
++    qemu_get_be32s(f, &s->isr);
++    qemu_get_be32s(f, &s->lnkst);
++    qemu_get_be32s(f, &s->rdra);
++    qemu_get_be32s(f, &s->tdra);
++    qemu_get_buffer(f, s->prom, 16);
++    for (i = 0; i < 128; i++)
++        qemu_get_be16s(f, &s->csr[i]);
++    for (i = 0; i < 32; i++)
++        qemu_get_be16s(f, &s->bcr[i]);
++    qemu_get_be64s(f, &s->timer);
++    qemu_get_be32s(f, &s->xmit_pos);
++    qemu_get_be32s(f, &s->recv_pos);
++    qemu_get_buffer(f, s->buffer, 4096);
++    qemu_get_be32s(f, &s->tx_busy);
++    qemu_get_timer(f, s->poll_timer);
++
++    return 0;
++}
++
+ void pci_pcnet_init(PCIBus *bus, NICInfo *nd)
+ {
+     PCNetState *d;
+     uint8_t *pci_conf;
++    int instance;
+ 
+ #if 0
+     printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", 
+@@ -1775,6 +1828,11 @@
+ 
+     d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive, 
+                                  pcnet_can_receive, d);
++
++    instance = pci_bus_num(bus) << 8 | d->dev.devfn;
++    register_savevm("pcnet", instance, 1, pcnet_save, pcnet_load, d);
++    register_savevm("pcnet_pci", instance, 1, generic_pci_save,
++                    generic_pci_load, &d->dev);
+     
+     snprintf(d->vc->info_str, sizeof(d->vc->info_str),
+              "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/ioemu-save-restore-rtl8139
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-save-restore-rtl8139    Tue May 08 09:09:17 
2007 -0600
@@ -0,0 +1,27 @@
+Index: ioemu/hw/rtl8139.c
+===================================================================
+--- ioemu.orig/hw/rtl8139.c    2007-05-02 16:09:35.000000000 +0100
++++ ioemu/hw/rtl8139.c 2007-05-02 16:10:56.000000000 +0100
+@@ -3406,6 +3406,7 @@
+     PCIRTL8139State *d;
+     RTL8139State *s;
+     uint8_t *pci_conf;
++    int instance;
+     
+     d = (PCIRTL8139State *)pci_register_device(bus,
+                                               "RTL8139", 
sizeof(PCIRTL8139State),
+@@ -3456,10 +3457,10 @@
+     s->cplus_txbuffer_len = 0;
+     s->cplus_txbuffer_offset = 0;
+              
+-    /* XXX: instance number ? */
+-    register_savevm("rtl8139", 0, 2, rtl8139_save, rtl8139_load, s);
+-    register_savevm("rtl8139_pci", 0, 1, generic_pci_save, generic_pci_load, 
+-                    &d->dev);
++    instance = pci_bus_num(bus) << 8 | s->pci_dev->devfn;
++    register_savevm("rtl8139", instance, 2, rtl8139_save, rtl8139_load, s);
++    register_savevm("rtl8139_pci", instance, 1, generic_pci_save, 
++                    generic_pci_load, &d->dev);
+ 
+ #if RTL8139_ONBOARD_TIMER
+     s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s);
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/ioemu-save-restore-timer
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-save-restore-timer      Tue May 08 09:09:17 
2007 -0600
@@ -0,0 +1,27 @@
+Index: ioemu/vl.c
+===================================================================
+--- ioemu.orig/vl.c    2007-05-03 10:07:54.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:07:54.000000000 +0100
+@@ -828,10 +828,22 @@
+ #ifdef CONFIG_DM
+ static void timer_save(QEMUFile *f, void *opaque)
+ {
++    /* need timer for save/restoe qemu_timer in usb_uhci */
++    if (cpu_ticks_enabled) {
++        hw_error("cannot save state if virtual timers are running");
++    }
++    qemu_put_be64s(f, &cpu_clock_offset);
+ }
+ 
+ static int timer_load(QEMUFile *f, void *opaque, int version_id)
+ {
++    if (version_id != 1)
++        return -EINVAL;
++    if (cpu_ticks_enabled) {
++        return -EINVAL;
++    }
++
++    qemu_get_be64s(f, &cpu_clock_offset);
+     return 0;
+ }
+ #else  /* !CONFIG_DM */
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/ioemu-save-restore-usb
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-save-restore-usb        Tue May 08 09:09:17 
2007 -0600
@@ -0,0 +1,235 @@
+Index: ioemu/hw/usb-hid.c
+===================================================================
+--- ioemu.orig/hw/usb-hid.c    2007-05-03 09:56:32.000000000 +0100
++++ ioemu/hw/usb-hid.c 2007-05-03 10:07:54.000000000 +0100
+@@ -508,6 +508,49 @@
+     qemu_free(s);
+ }
+ 
++void usb_mouse_save(QEMUFile *f, void *opaque)
++{
++    USBMouseState *s = (USBMouseState*)opaque;
++
++    qemu_put_be32s(f, &s->dx);
++    qemu_put_be32s(f, &s->dy);
++    qemu_put_be32s(f, &s->dz);
++    qemu_put_be32s(f, &s->buttons_state);
++    qemu_put_be32s(f, &s->x);
++    qemu_put_be32s(f, &s->y);
++    qemu_put_be32s(f, &s->kind);
++    qemu_put_be32s(f, &s->mouse_grabbed);
++    qemu_put_be32s(f, &s->status_changed);
++
++}
++
++int usb_mouse_load(QEMUFile *f, void *opaque, int version_id)
++{
++    USBMouseState *s = (USBMouseState*)opaque;
++
++    if (version_id != 1)
++        return -EINVAL;
++
++    qemu_get_be32s(f, &s->dx);
++    qemu_get_be32s(f, &s->dy);
++    qemu_get_be32s(f, &s->dz);
++    qemu_get_be32s(f, &s->buttons_state);
++    qemu_get_be32s(f, &s->x);
++    qemu_get_be32s(f, &s->y);
++    qemu_get_be32s(f, &s->kind);
++    qemu_get_be32s(f, &s->mouse_grabbed);
++    qemu_get_be32s(f, &s->status_changed);
++
++    if ( s->kind == USB_TABLET) {
++        fprintf(logfile, "usb_mouse_load:add usb_tablet_event.\n");
++        qemu_add_mouse_event_handler(usb_tablet_event, s, 1);
++    } else if ( s->kind == USB_MOUSE) {
++        fprintf(logfile, "usb_mouse_load:add usb_mouse_event.\n");
++        qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
++    }
++}
++
++
+ USBDevice *usb_tablet_init(void)
+ {
+     USBMouseState *s;
+@@ -526,6 +569,8 @@
+ 
+     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
+ 
++    register_savevm("USB tablet dev", 0, 1, usb_mouse_save, usb_mouse_load, 
s);
++
+     return (USBDevice *)s;
+ }
+ 
+@@ -547,5 +592,7 @@
+ 
+     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
+ 
++    register_savevm("USB mouse dev", 0, 1, usb_mouse_save, usb_mouse_load, s);
++
+     return (USBDevice *)s;
+ }
+Index: ioemu/vl.c
+===================================================================
+--- ioemu.orig/vl.c    2007-05-03 10:07:53.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:07:54.000000000 +0100
+@@ -3878,6 +3878,7 @@
+     const char *p;
+     USBDevice *dev;
+     USBPort *port;
++    char usb_name[256] = "USB ";
+ 
+     if (!free_usb_ports)
+         return -1;
+@@ -3914,6 +3915,12 @@
+     free_usb_ports = port->next;
+     port->next = used_usb_ports;
+     used_usb_ports = port;
++
++    pstrcpy(usb_name + strlen(usb_name), 
++            sizeof(usb_name) - strlen(usb_name), 
++            devname);
++    register_savevm(usb_name, 0, 1, generic_usb_save, generic_usb_load, dev);
++    
+     usb_attach(port, dev);
+     return 0;
+ }
+Index: ioemu/hw/usb.c
+===================================================================
+--- ioemu.orig/hw/usb.c        2007-05-03 09:56:32.000000000 +0100
++++ ioemu/hw/usb.c     2007-05-03 10:07:54.000000000 +0100
+@@ -191,3 +191,43 @@
+     }
+     return q - buf;
+ }
++
++void generic_usb_save(QEMUFile* f, void *opaque)
++{
++    USBDevice *s = (USBDevice*)opaque;
++
++    qemu_put_be32s(f, &s->speed);
++    qemu_put_8s(f, &s->addr);
++    qemu_put_be32s(f, &s->state);
++
++    qemu_put_buffer(f, s->setup_buf, 8);
++    qemu_put_buffer(f, s->data_buf, 1024);
++
++    qemu_put_be32s(f, &s->remote_wakeup);
++    qemu_put_be32s(f, &s->setup_state);
++    qemu_put_be32s(f, &s->setup_len);
++    qemu_put_be32s(f, &s->setup_index);
++
++}
++
++int generic_usb_load(QEMUFile* f, void *opaque, int version_id)
++{
++    USBDevice *s = (USBDevice*)opaque;
++
++    if (version_id != 1)
++        return -EINVAL;
++
++    qemu_get_be32s(f, &s->speed);
++    qemu_get_8s(f, &s->addr);
++    qemu_get_be32s(f, &s->state);
++
++    qemu_get_buffer(f, s->setup_buf, 8);
++    qemu_get_buffer(f, s->data_buf, 1024);
++
++    qemu_get_be32s(f, &s->remote_wakeup);
++    qemu_get_be32s(f, &s->setup_state);
++    qemu_get_be32s(f, &s->setup_len);
++    qemu_get_be32s(f, &s->setup_index);
++
++    return 0;
++}
+Index: ioemu/hw/usb-ohci.c
+===================================================================
+--- ioemu.orig/hw/usb-ohci.c   2007-05-03 09:56:32.000000000 +0100
++++ ioemu/hw/usb-ohci.c        2007-05-03 10:07:54.000000000 +0100
+@@ -1186,5 +1186,7 @@
+         qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
+     }
+ 
++    register_savevm("OHCI USB", 0, 1, generic_pci_save, generic_pci_load, 
ohci);
++
+     ohci_reset(ohci);
+ }
+Index: ioemu/hw/usb.h
+===================================================================
+--- ioemu.orig/hw/usb.h        2007-05-03 09:56:32.000000000 +0100
++++ ioemu/hw/usb.h     2007-05-03 10:07:54.000000000 +0100
+@@ -176,3 +176,9 @@
+ 
+ /* usb-msd.c */
+ USBDevice *usb_msd_init(const char *filename);
++
++/* usb.c */
++void generic_usb_save(QEMUFile* f, void *opaque);
++int generic_usb_load(QEMUFile* f, void *opaque, int version_id);
++
++
+Index: ioemu/hw/usb-uhci.c
+===================================================================
+--- ioemu.orig/hw/usb-uhci.c   2007-05-03 09:56:32.000000000 +0100
++++ ioemu/hw/usb-uhci.c        2007-05-03 10:07:54.000000000 +0100
+@@ -638,6 +638,51 @@
+     register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
+ }
+ 
++void uhci_usb_save(QEMUFile *f, void *opaque)
++{
++    int i;
++    UHCIState *s = (UHCIState*)opaque;
++
++    qemu_put_be16s(f, &s->cmd);
++    qemu_put_be16s(f, &s->status);
++    qemu_put_be16s(f, &s->intr);
++    qemu_put_be16s(f, &s->frnum);
++    qemu_put_be32s(f, &s->fl_base_addr);
++    qemu_put_8s(f, &s->sof_timing);
++    qemu_put_8s(f, &s->status2);
++
++    for(i = 0; i < NB_PORTS; i++) {
++        qemu_put_be16s(f, &s->ports[i].ctrl);
++    }
++
++    qemu_put_timer(f, s->frame_timer);
++}
++
++int uhci_usb_load(QEMUFile *f, void *opaque, int version_id)
++{
++    int i;
++    UHCIState *s = (UHCIState*)opaque;
++
++    if (version_id != 1)
++        return -EINVAL;
++
++    qemu_get_be16s(f, &s->cmd);
++    qemu_get_be16s(f, &s->status);
++    qemu_get_be16s(f, &s->intr);
++    qemu_get_be16s(f, &s->frnum);
++    qemu_get_be32s(f, &s->fl_base_addr);
++    qemu_get_8s(f, &s->sof_timing);
++    qemu_get_8s(f, &s->status2);
++
++    for(i = 0; i < NB_PORTS; i++) {
++        qemu_get_be16s(f, &s->ports[i].ctrl);
++    }
++
++    qemu_get_timer(f, s->frame_timer);
++
++    return 0;
++}
++
+ void usb_uhci_init(PCIBus *bus, int devfn)
+ {
+     UHCIState *s;
+@@ -671,4 +716,8 @@
+        to rely on this.  */
+     pci_register_io_region(&s->dev, 4, 0x20, 
+                            PCI_ADDRESS_SPACE_IO, uhci_map);
++
++    register_savevm("UHCI_usb_pci", 0, 1, generic_pci_save, generic_pci_load, 
s);
++
++    register_savevm("UHCI usb controller", 0, 1, uhci_usb_save, 
uhci_usb_load, s);
+ }
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/nodelay-serial-over-tcp
--- a/tools/ioemu/patches/nodelay-serial-over-tcp       Mon May 07 13:24:37 
2007 -0600
+++ b/tools/ioemu/patches/nodelay-serial-over-tcp       Tue May 08 09:09:17 
2007 -0600
@@ -8,9 +8,9 @@ Signed-off-by: Steven Smith <sos22@xxxxx
 
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-08 18:21:56.000000000 +0000
-+++ ioemu/vl.c 2006-12-08 18:22:42.000000000 +0000
-@@ -2530,6 +2530,7 @@
+--- ioemu.orig/vl.c    2007-05-03 10:09:02.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:09:03.000000000 +0100
+@@ -2586,6 +2586,7 @@
      int is_waitconnect = 1;
      const char *ptr;
      struct sockaddr_in saddr;
@@ -18,7 +18,7 @@ Index: ioemu/vl.c
  
      if (parse_host_port(&saddr, host_str) < 0)
          goto fail;
-@@ -2598,6 +2599,8 @@
+@@ -2654,6 +2655,8 @@
              }
          }
          s->fd = fd;
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-64bit
--- a/tools/ioemu/patches/qemu-64bit    Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-64bit    Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/cpu-all.h
 Index: ioemu/cpu-all.h
 ===================================================================
---- ioemu.orig/cpu-all.h       2006-08-06 02:14:09.796902750 +0100
-+++ ioemu/cpu-all.h    2006-08-06 02:15:39.707879423 +0100
+--- ioemu.orig/cpu-all.h       2007-05-02 16:04:46.000000000 +0100
++++ ioemu/cpu-all.h    2007-05-02 16:05:50.000000000 +0100
 @@ -822,7 +822,7 @@
  
  /* memory API */
@@ -13,8 +13,8 @@ Index: ioemu/cpu-all.h
  extern uint8_t *phys_ram_dirty;
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-08-06 02:14:09.797902638 +0100
-+++ ioemu/hw/pc.c      2006-08-06 02:15:39.708879311 +0100
+--- ioemu.orig/hw/pc.c 2007-05-02 16:04:46.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-02 16:05:50.000000000 +0100
 @@ -155,7 +155,7 @@
  }
  
@@ -53,8 +53,8 @@ Index: ioemu/hw/pc.c
                          const char *kernel_filename, 
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-06 02:15:31.040845624 +0100
-+++ ioemu/vl.c 2006-08-06 02:15:39.711878977 +0100
+--- ioemu.orig/vl.c    2007-05-02 16:05:50.000000000 +0100
++++ ioemu/vl.c 2007-05-02 16:05:50.000000000 +0100
 @@ -122,7 +122,7 @@
  const char* keyboard_layout = NULL;
  int64_t ticks_per_sec;
@@ -64,7 +64,7 @@ Index: ioemu/vl.c
  int pit_min_timer_count = 0;
  int nb_nics;
  NICInfo nd_table[MAX_NICS];
-@@ -5895,7 +5895,7 @@
+@@ -5899,7 +5899,7 @@
                  help();
                  break;
              case QEMU_OPTION_m:
@@ -75,8 +75,8 @@ Index: ioemu/vl.c
                  if (ram_size > PHYS_RAM_MAX_SIZE) {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-06 02:15:10.368150219 +0100
-+++ ioemu/vl.h 2006-08-06 02:15:39.711878977 +0100
+--- ioemu.orig/vl.h    2007-05-02 16:05:50.000000000 +0100
++++ ioemu/vl.h 2007-05-02 16:05:50.000000000 +0100
 @@ -146,7 +146,7 @@
  extern int xc_handle;
  extern int domid;
@@ -97,8 +97,8 @@ Index: ioemu/vl.h
               const char *kernel_filename, const char *kernel_cmdline,
 Index: ioemu/hw/vga.c
 ===================================================================
---- ioemu.orig/hw/vga.c        2006-08-06 02:15:10.364150665 +0100
-+++ ioemu/hw/vga.c     2006-08-06 02:15:39.712878866 +0100
+--- ioemu.orig/hw/vga.c        2007-05-02 16:05:50.000000000 +0100
++++ ioemu/hw/vga.c     2007-05-02 16:05:50.000000000 +0100
 @@ -1365,7 +1365,8 @@
  static void vga_draw_graphic(VGAState *s, int full_update)
  {
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/qemu-block-device-bounds-checks
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/qemu-block-device-bounds-checks       Tue May 08 
09:09:17 2007 -0600
@@ -0,0 +1,22 @@
+Index: ioemu/block.c
+===================================================================
+--- ioemu.orig/block.c 2007-05-03 14:55:04.000000000 +0100
++++ ioemu/block.c      2007-05-03 14:59:20.000000000 +0100
+@@ -420,6 +420,8 @@
+ 
+     if (!bs->inserted)
+         return -1;
++    if (sector_num < 0)
++      return -1;
+ 
+     while (nb_sectors > 0) {
+         if (sector_num == 0 && bs->boot_sector_enabled) {
+@@ -458,6 +460,8 @@
+         return -1;
+     if (bs->read_only)
+         return -1;
++    if (sector_num < 0)
++      return -1;
+     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+         memcpy(bs->boot_sector_data, buf, 512);   
+     }
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-bootorder
--- a/tools/ioemu/patches/qemu-bootorder        Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-bootorder        Tue May 08 09:09:17 2007 -0600
@@ -1,8 +1,8 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:12:08.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:19.000000000 +0000
-@@ -125,7 +125,7 @@
+--- ioemu.orig/vl.c    2007-05-03 15:20:35.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:20:43.000000000 +0100
+@@ -126,7 +126,7 @@
  struct sockaddr_in vnclisten_addr;
  const char* keyboard_layout = NULL;
  int64_t ticks_per_sec;
@@ -11,7 +11,7 @@ Index: ioemu/vl.c
  uint64_t ram_size;
  int pit_min_timer_count = 0;
  int nb_nics;
-@@ -6059,14 +6059,14 @@
+@@ -6150,14 +6150,14 @@
                  break;
  #endif /* !CONFIG_DM */
              case QEMU_OPTION_boot:
@@ -34,7 +34,7 @@ Index: ioemu/vl.c
                      exit(1);
                  }
                  break;
-@@ -6333,6 +6333,7 @@
+@@ -6424,6 +6424,7 @@
          fd_filename[0] == '\0')
          help();
      
@@ -42,7 +42,7 @@ Index: ioemu/vl.c
      /* boot to cd by default if no hard disk */
      if (hd_filename[0] == '\0' && boot_device == 'c') {
          if (fd_filename[0] != '\0')
-@@ -6340,6 +6341,7 @@
+@@ -6431,6 +6432,7 @@
          else
              boot_device = 'd';
      }
@@ -50,7 +50,7 @@ Index: ioemu/vl.c
  #endif /* !CONFIG_DM */
  
      setvbuf(stdout, NULL, _IOLBF, 0);
-@@ -6590,6 +6592,7 @@
+@@ -6692,6 +6694,7 @@
                    ds, fd_filename, snapshot,
                    kernel_filename, kernel_cmdline, initrd_filename,
                    timeoffset);
@@ -60,8 +60,8 @@ Index: ioemu/vl.c
      if (usb_enabled) {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:12:08.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:14.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 15:20:39.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:20:43.000000000 +0100
 @@ -578,7 +578,7 @@
  #ifndef QEMU_TOOL
  
@@ -71,7 +71,7 @@ Index: ioemu/vl.h
               DisplayState *ds, const char **fd_filename, int snapshot,
               const char *kernel_filename, const char *kernel_cmdline,
               const char *initrd_filename, time_t timeoffset);
-@@ -1023,7 +1023,7 @@
+@@ -1024,7 +1024,7 @@
                      uint32_t start, uint32_t count);
  int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
                            const unsigned char *arch,
@@ -82,8 +82,8 @@ Index: ioemu/vl.h
                            uint32_t initrd_image, uint32_t initrd_size,
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-12-20 15:12:08.000000000 +0000
-+++ ioemu/hw/pc.c      2006-12-20 15:21:19.000000000 +0000
+--- ioemu.orig/hw/pc.c 2007-05-03 15:20:35.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-03 15:20:43.000000000 +0100
 @@ -158,8 +158,25 @@
      rtc_set_memory(s, info_ofs + 8, sectors);
  }
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/qemu-cirrus-bounds-checks
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/qemu-cirrus-bounds-checks     Tue May 08 09:09:17 
2007 -0600
@@ -0,0 +1,350 @@
+Index: ioemu/hw/cirrus_vga.c
+===================================================================
+--- ioemu.orig/hw/cirrus_vga.c 2007-05-03 14:55:45.000000000 +0100
++++ ioemu/hw/cirrus_vga.c      2007-05-03 14:58:05.000000000 +0100
+@@ -601,7 +601,8 @@
+       off_cur_end = off_cur + bytesperline;
+       off_cur &= TARGET_PAGE_MASK;
+       while (off_cur < off_cur_end) {
+-          cpu_physical_memory_set_dirty(s->vram_offset + off_cur);
++          cpu_physical_memory_set_dirty(s->vram_offset +
++                                        (off_cur & s->cirrus_addr_mask));
+           off_cur += TARGET_PAGE_SIZE;
+       }
+       off_begin += off_pitch;
+Index: ioemu/hw/cirrus_vga_rop.h
+===================================================================
+--- ioemu.orig/hw/cirrus_vga_rop.h     2007-05-02 10:30:05.000000000 +0100
++++ ioemu/hw/cirrus_vga_rop.h  2007-05-03 14:58:22.000000000 +0100
+@@ -22,18 +22,36 @@
+  * THE SOFTWARE.
+  */
+ 
++#define get_base(p, s, b) do { \
++    if ((p) >= (s)->vram_ptr && (p) < (s)->vram_ptr + (s)->vram_size) \
++      (b) = (s)->vram_ptr; \
++    else if ((p) >= &(s)->cirrus_bltbuf[0] && \
++           (p) < &(s)->cirrus_bltbuf[CIRRUS_BLTBUFSIZE]) \
++      (b) = &(s)->cirrus_bltbuf[0]; \
++    else \
++      return; \
++} while(0)
++
++#define m(x) ((x) & s->cirrus_addr_mask)
++
+ static void
+ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
+-                             uint8_t *dst,const uint8_t *src,
++                             uint8_t *dst_,const uint8_t *src_,
+                              int dstpitch,int srcpitch,
+                              int bltwidth,int bltheight)
+ {
+     int x,y;
++    uint32_t dst, src;
++    uint8_t *dst_base, *src_base;
++    get_base(dst_, s, dst_base);
++    get_base(src_, s, src_base);
++    dst = dst_ - dst_base;
++    src = src_ - src_base;
+     dstpitch -= bltwidth;
+     srcpitch -= bltwidth;
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+-            ROP_OP(*dst, *src);
++            ROP_OP(*(dst_base + m(dst)), *(src_base + m(src)));
+             dst++;
+             src++;
+         }
+@@ -44,16 +62,22 @@
+ 
+ static void
+ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
+-                                        uint8_t *dst,const uint8_t *src,
++                                        uint8_t *dst_,const uint8_t *src_,
+                                         int dstpitch,int srcpitch,
+                                         int bltwidth,int bltheight)
+ {
+     int x,y;
++    uint32_t dst, src;
++    uint8_t *dst_base, *src_base;
++    get_base(dst_, s, dst_base);
++    get_base(src_, s, src_base);
++    dst = dst_ - dst_base;
++    src = src_ - src_base;
+     dstpitch += bltwidth;
+     srcpitch += bltwidth;
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+-            ROP_OP(*dst, *src);
++            ROP_OP(*(dst_base + m(dst)), *(src_base + m(src)));
+             dst--;
+             src--;
+         }
+@@ -76,3 +100,6 @@
+ 
+ #undef ROP_NAME
+ #undef ROP_OP
++
++#undef get_base
++#undef m
+Index: ioemu/hw/cirrus_vga_rop2.h
+===================================================================
+--- ioemu.orig/hw/cirrus_vga_rop2.h    2007-05-02 10:30:05.000000000 +0100
++++ ioemu/hw/cirrus_vga_rop2.h 2007-05-03 14:58:42.000000000 +0100
+@@ -23,36 +23,42 @@
+  */
+ 
+ #if DEPTH == 8
+-#define PUTPIXEL()    ROP_OP(d[0], col)
++#define PUTPIXEL()    ROP_OP((dst_base + m(d))[0], col)
+ #elif DEPTH == 16
+-#define PUTPIXEL()    ROP_OP(((uint16_t *)d)[0], col);
++#define PUTPIXEL()    ROP_OP(((uint16_t *)(dst_base + m(d)))[0], col);
+ #elif DEPTH == 24
+-#define PUTPIXEL()    ROP_OP(d[0], col); \
+-                      ROP_OP(d[1], (col >> 8)); \
+-                      ROP_OP(d[2], (col >> 16))
++#define PUTPIXEL()    ROP_OP((dst_base + m(d))[0], col); \
++                      ROP_OP((dst_base + m(d))[1], (col >> 8)); \
++                      ROP_OP((dst_base + m(d))[2], (col >> 16))
+ #elif DEPTH == 32
+-#define PUTPIXEL()    ROP_OP(((uint32_t *)d)[0], col)
++#define PUTPIXEL()    ROP_OP(((uint32_t *)(dst_base + m(d)))[0], col)
+ #else
+ #error unsupported DEPTH
+ #endif                
+ 
+ static void
+ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
+-     (CirrusVGAState * s, uint8_t * dst,
+-      const uint8_t * src, 
++     (CirrusVGAState * s, uint8_t * dst_,
++      const uint8_t * src_, 
+       int dstpitch, int srcpitch, 
+       int bltwidth, int bltheight)
+ {
+-    uint8_t *d;
++    uint8_t *dst_base, *src_base;
++    uint32_t src, dst;
++    uint32_t d;
+     int x, y, pattern_y, pattern_pitch, pattern_x;
+     unsigned int col;
+-    const uint8_t *src1;
++    uint32_t src1;
+ #if DEPTH == 24
+     int skipleft = s->gr[0x2f] & 0x1f;
+ #else
+     int skipleft = (s->gr[0x2f] & 0x07) * (DEPTH / 8);
+ #endif
+ 
++    get_base(dst_, s, dst_base);
++    get_base(src_, s, src_base);
++    dst = dst_ - dst_base;
++    src = src_ - src_base;
+ #if DEPTH == 8
+     pattern_pitch = 8;
+ #elif DEPTH == 16
+@@ -67,19 +73,19 @@
+         src1 = src + pattern_y * pattern_pitch;
+         for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
+ #if DEPTH == 8
+-            col = src1[pattern_x];
++            col = *(src_base + m(src1 + pattern_x));
+             pattern_x = (pattern_x + 1) & 7;
+ #elif DEPTH == 16
+-            col = ((uint16_t *)(src1 + pattern_x))[0];
++            col = *(uint16_t *)(src_base + m(src1 + pattern_x));
+             pattern_x = (pattern_x + 2) & 15;
+ #elif DEPTH == 24
+             {
+-                const uint8_t *src2 = src1 + pattern_x * 3;
++                const uint8_t *src2 = src_base + m(src1 + pattern_x * 3);
+                 col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
+                 pattern_x = (pattern_x + 1) & 7;
+             }
+ #else
+-            col = ((uint32_t *)(src1 + pattern_x))[0];
++            col = *(uint32_t *)(src_base + m(src1 + pattern_x));
+             pattern_x = (pattern_x + 4) & 31;
+ #endif
+             PUTPIXEL();
+@@ -93,12 +99,14 @@
+ /* NOTE: srcpitch is ignored */
+ static void
+ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
+-     (CirrusVGAState * s, uint8_t * dst,
+-      const uint8_t * src, 
++     (CirrusVGAState * s, uint8_t * dst_,
++      const uint8_t * src_, 
+       int dstpitch, int srcpitch, 
+       int bltwidth, int bltheight)
+ {
+-    uint8_t *d;
++    uint8_t *dst_base, *src_base;
++    uint32_t src, dst;
++    uint32_t d;
+     int x, y;
+     unsigned bits, bits_xor;
+     unsigned int col;
+@@ -112,6 +120,10 @@
+     int dstskipleft = srcskipleft * (DEPTH / 8);
+ #endif
+ 
++    get_base(dst_, s, dst_base);
++    get_base(src_, s, src_base);
++    dst = dst_ - dst_base;
++    src = src_ - src_base;
+     if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
+         bits_xor = 0xff;
+         col = s->cirrus_blt_bgcol;
+@@ -122,12 +134,12 @@
+ 
+     for(y = 0; y < bltheight; y++) {
+         bitmask = 0x80 >> srcskipleft;
+-        bits = *src++ ^ bits_xor;
++        bits = *(src_base + m(src++)) ^ bits_xor;
+         d = dst + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+             if ((bitmask & 0xff) == 0) {
+                 bitmask = 0x80;
+-                bits = *src++ ^ bits_xor;
++                bits = *(src_base + m(src++)) ^ bits_xor;
+             }
+             index = (bits & bitmask);
+             if (index) {
+@@ -142,13 +154,15 @@
+ 
+ static void
+ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
+-     (CirrusVGAState * s, uint8_t * dst,
+-      const uint8_t * src, 
++     (CirrusVGAState * s, uint8_t * dst_,
++      const uint8_t * src_, 
+       int dstpitch, int srcpitch, 
+       int bltwidth, int bltheight)
+ {
++    uint8_t *dst_base, *src_base;
++    uint32_t src, dst;
+     uint32_t colors[2];
+-    uint8_t *d;
++    uint32_t d;
+     int x, y;
+     unsigned bits;
+     unsigned int col;
+@@ -156,16 +170,20 @@
+     int srcskipleft = s->gr[0x2f] & 0x07;
+     int dstskipleft = srcskipleft * (DEPTH / 8);
+ 
++    get_base(dst_, s, dst_base);
++    get_base(src_, s, src_base);
++    dst = dst_ - dst_base;
++    src = src_ - src_base;
+     colors[0] = s->cirrus_blt_bgcol;
+     colors[1] = s->cirrus_blt_fgcol;
+     for(y = 0; y < bltheight; y++) {
+         bitmask = 0x80 >> srcskipleft;
+-        bits = *src++;
++        bits = *(src_base + m(src++));
+         d = dst + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+             if ((bitmask & 0xff) == 0) {
+                 bitmask = 0x80;
+-                bits = *src++;
++                bits = *(src_base + m(src++));
+             }
+             col = colors[!!(bits & bitmask)];
+             PUTPIXEL();
+@@ -178,12 +196,14 @@
+ 
+ static void
+ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
+-     (CirrusVGAState * s, uint8_t * dst,
+-      const uint8_t * src, 
++     (CirrusVGAState * s, uint8_t * dst_,
++      const uint8_t * src_, 
+       int dstpitch, int srcpitch, 
+       int bltwidth, int bltheight)
+ {
+-    uint8_t *d;
++    uint8_t *dst_base, *src_base;
++    uint32_t src, dst;
++    uint32_t d;
+     int x, y, bitpos, pattern_y;
+     unsigned int bits, bits_xor;
+     unsigned int col;
+@@ -195,6 +215,10 @@
+     int dstskipleft = srcskipleft * (DEPTH / 8);
+ #endif
+ 
++    get_base(dst_, s, dst_base);
++    get_base(src_, s, src_base);
++    dst = dst_ - dst_base;
++    src = src_ - src_base;
+     if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
+         bits_xor = 0xff;
+         col = s->cirrus_blt_bgcol;
+@@ -205,7 +229,7 @@
+     pattern_y = s->cirrus_blt_srcaddr & 7;
+ 
+     for(y = 0; y < bltheight; y++) {
+-        bits = src[pattern_y] ^ bits_xor;
++        bits = *(src_base + m(src + pattern_y)) ^ bits_xor;
+         bitpos = 7 - srcskipleft;
+         d = dst + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+@@ -222,25 +246,31 @@
+ 
+ static void
+ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
+-     (CirrusVGAState * s, uint8_t * dst,
+-      const uint8_t * src, 
++     (CirrusVGAState * s, uint8_t * dst_,
++      const uint8_t * src_, 
+       int dstpitch, int srcpitch, 
+       int bltwidth, int bltheight)
+ {
++    uint8_t *dst_base, *src_base;
++    uint32_t src, dst;
+     uint32_t colors[2];
+-    uint8_t *d;
++    uint32_t d;
+     int x, y, bitpos, pattern_y;
+     unsigned int bits;
+     unsigned int col;
+     int srcskipleft = s->gr[0x2f] & 0x07;
+     int dstskipleft = srcskipleft * (DEPTH / 8);
+ 
++    get_base(dst_, s, dst_base);
++    get_base(src_, s, src_base);
++    dst = dst_ - dst_base;
++    src = src_ - src_base;
+     colors[0] = s->cirrus_blt_bgcol;
+     colors[1] = s->cirrus_blt_fgcol;
+     pattern_y = s->cirrus_blt_srcaddr & 7;
+ 
+     for(y = 0; y < bltheight; y++) {
+-        bits = src[pattern_y];
++        bits = *(src_base + m(src + pattern_y));
+         bitpos = 7 - srcskipleft;
+         d = dst + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+@@ -257,13 +287,17 @@
+ static void 
+ glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
+      (CirrusVGAState *s,
+-      uint8_t *dst, int dst_pitch, 
++      uint8_t *dst_, int dst_pitch, 
+       int width, int height)
+ {
+-    uint8_t *d, *d1;
++    uint8_t *dst_base;
++    uint32_t dst;
++    uint32_t d, d1;
+     uint32_t col;
+     int x, y;
+ 
++    get_base(dst_, s, dst_base);
++    dst = dst_ - dst_base;
+     col = s->cirrus_blt_fgcol;
+ 
+     d1 = dst;
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-cleanup
--- a/tools/ioemu/patches/qemu-cleanup  Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-cleanup  Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/hw/vga.c
 Index: ioemu/hw/vga.c
 ===================================================================
---- ioemu.orig/hw/vga.c        2006-10-24 14:44:03.000000000 +0100
-+++ ioemu/hw/vga.c     2006-10-24 14:45:22.000000000 +0100
+--- ioemu.orig/hw/vga.c        2007-05-02 16:04:46.000000000 +0100
++++ ioemu/hw/vga.c     2007-05-02 16:05:50.000000000 +0100
 @@ -1622,7 +1622,9 @@
  static void vga_save(QEMUFile *f, void *opaque)
  {
@@ -26,8 +26,8 @@ Index: ioemu/hw/vga.c
          return -EINVAL;
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:44:08.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:45:29.000000000 +0100
+--- ioemu.orig/vl.c    2007-05-02 16:05:50.000000000 +0100
++++ ioemu/vl.c 2007-05-02 16:05:50.000000000 +0100
 @@ -39,6 +39,7 @@
  #include <sys/ioctl.h>
  #include <sys/socket.h>
@@ -74,7 +74,7 @@ Index: ioemu/vl.c
  #ifdef USE_KQEMU
      { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
      { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
-@@ -5849,9 +5854,11 @@
+@@ -5853,9 +5858,11 @@
                  fd_bootchk = 0;
                  break;
  #endif
@@ -88,8 +88,8 @@ Index: ioemu/vl.c
                      fprintf(stderr, "qemu: too many network clients\n");
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-10-24 14:44:08.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:45:22.000000000 +0100
+--- ioemu.orig/vl.h    2007-05-02 16:05:50.000000000 +0100
++++ ioemu/vl.h 2007-05-02 16:05:50.000000000 +0100
 @@ -957,7 +957,7 @@
               unsigned long vram_offset, int vram_size, int width, int height);
  
@@ -101,8 +101,8 @@ Index: ioemu/vl.h
  void slavio_irq_info(void *opaque);
 Index: ioemu/usb-linux.c
 ===================================================================
---- ioemu.orig/usb-linux.c     2006-10-24 14:44:03.000000000 +0100
-+++ ioemu/usb-linux.c  2006-10-24 14:44:08.000000000 +0100
+--- ioemu.orig/usb-linux.c     2007-05-02 16:04:46.000000000 +0100
++++ ioemu/usb-linux.c  2007-05-02 16:05:50.000000000 +0100
 @@ -26,7 +26,9 @@
  #if defined(__linux__)
  #include <dirent.h>
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-daemonize
--- a/tools/ioemu/patches/qemu-daemonize        Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-daemonize        Tue May 08 09:09:17 2007 -0600
@@ -2,9 +2,9 @@ Changes required because qemu-dm runs da
 
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-08 02:00:42.000000000 +0000
-+++ ioemu/vl.c 2006-12-08 02:00:42.000000000 +0000
-@@ -6038,10 +6038,11 @@
+--- ioemu.orig/vl.c    2007-05-03 10:11:05.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:11:05.000000000 +0100
+@@ -6129,10 +6129,11 @@
                  }
                  break;
              case QEMU_OPTION_nographic:
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-dm
--- a/tools/ioemu/patches/qemu-dm       Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-dm       Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-12-08 01:41:05.000000000 +0000
-+++ ioemu/Makefile.target      2006-12-08 01:41:10.000000000 +0000
+--- ioemu.orig/Makefile.target 2007-05-02 15:48:40.000000000 +0100
++++ ioemu/Makefile.target      2007-05-02 16:04:46.000000000 +0100
 @@ -303,7 +303,7 @@
  endif
  
@@ -13,8 +13,8 @@ Index: ioemu/Makefile.target
  VL_OBJS+=tap-win32.o
 Index: ioemu/configure
 ===================================================================
---- ioemu.orig/configure       2006-12-08 01:40:58.000000000 +0000
-+++ ioemu/configure    2006-12-08 01:41:10.000000000 +0000
+--- ioemu.orig/configure       2007-05-02 15:48:40.000000000 +0100
++++ ioemu/configure    2007-05-02 16:04:46.000000000 +0100
 @@ -75,8 +75,8 @@
  bigendian="no"
  mingw32="no"
@@ -37,8 +37,8 @@ Index: ioemu/configure
    target_user_only="yes"
 Index: ioemu/cpu-all.h
 ===================================================================
---- ioemu.orig/cpu-all.h       2006-12-08 01:40:58.000000000 +0000
-+++ ioemu/cpu-all.h    2006-12-08 01:41:10.000000000 +0000
+--- ioemu.orig/cpu-all.h       2007-05-02 15:48:36.000000000 +0100
++++ ioemu/cpu-all.h    2007-05-02 16:04:46.000000000 +0100
 @@ -690,7 +690,9 @@
  void page_set_flags(target_ulong start, target_ulong end, int flags);
  void page_unprotect_range(target_ulong data, target_ulong data_size);
@@ -64,8 +64,8 @@ Index: ioemu/cpu-all.h
  void cpu_dump_state(CPUState *env, FILE *f, 
 Index: ioemu/disas.h
 ===================================================================
---- ioemu.orig/disas.h 2006-12-08 01:40:58.000000000 +0000
-+++ ioemu/disas.h      2006-12-08 01:41:10.000000000 +0000
+--- ioemu.orig/disas.h 2007-05-02 15:48:36.000000000 +0100
++++ ioemu/disas.h      2007-05-02 15:48:40.000000000 +0100
 @@ -1,6 +1,7 @@
  #ifndef _QEMU_DISAS_H
  #define _QEMU_DISAS_H
@@ -83,8 +83,8 @@ Index: ioemu/disas.h
  #endif /* _QEMU_DISAS_H */
 Index: ioemu/exec-all.h
 ===================================================================
---- ioemu.orig/exec-all.h      2006-12-08 01:40:58.000000000 +0000
-+++ ioemu/exec-all.h   2006-12-08 01:41:10.000000000 +0000
+--- ioemu.orig/exec-all.h      2007-05-02 15:48:36.000000000 +0100
++++ ioemu/exec-all.h   2007-05-02 16:04:45.000000000 +0100
 @@ -509,7 +509,7 @@
  
  extern int tb_invalidated_flag;
@@ -105,8 +105,8 @@ Index: ioemu/exec-all.h
      return addr;
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-12-08 01:40:58.000000000 +0000
-+++ ioemu/hw/pc.c      2006-12-08 01:41:10.000000000 +0000
+--- ioemu.orig/hw/pc.c 2007-05-02 15:48:36.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-02 16:04:46.000000000 +0100
 @@ -73,6 +73,7 @@
      }
  }
@@ -184,8 +184,8 @@ Index: ioemu/hw/pc.c
          if (serial_hds[i]) {
 Index: ioemu/hw/vga_int.h
 ===================================================================
---- ioemu.orig/hw/vga_int.h    2006-12-08 01:40:58.000000000 +0000
-+++ ioemu/hw/vga_int.h 2006-12-08 01:41:10.000000000 +0000
+--- ioemu.orig/hw/vga_int.h    2007-05-02 15:48:36.000000000 +0100
++++ ioemu/hw/vga_int.h 2007-05-02 16:04:45.000000000 +0100
 @@ -28,7 +28,7 @@
  #define ST01_DISP_ENABLE    0x01
  
@@ -197,8 +197,8 @@ Index: ioemu/hw/vga_int.h
  #define VBE_DISPI_MAX_YRES              1200
 Index: ioemu/monitor.c
 ===================================================================
---- ioemu.orig/monitor.c       2006-12-08 01:40:58.000000000 +0000
-+++ ioemu/monitor.c    2006-12-08 01:41:10.000000000 +0000
+--- ioemu.orig/monitor.c       2007-05-02 15:48:36.000000000 +0100
++++ ioemu/monitor.c    2007-05-02 16:04:46.000000000 +0100
 @@ -68,6 +68,12 @@
  
  void term_flush(void)
@@ -429,8 +429,8 @@ Index: ioemu/monitor.c
  {
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-08 01:40:58.000000000 +0000
-+++ ioemu/vl.c 2006-12-08 01:41:10.000000000 +0000
+--- ioemu.orig/vl.c    2007-05-02 15:48:36.000000000 +0100
++++ ioemu/vl.c 2007-05-02 16:05:40.000000000 +0100
 @@ -422,12 +422,15 @@
  void hw_error(const char *fmt, ...)
  {
@@ -489,7 +489,31 @@ Index: ioemu/vl.c
  
  /***********************************************************/
  /* machine registration */
-@@ -6054,6 +6078,7 @@
+@@ -5664,15 +5688,19 @@
+ #endif
+     cyls = heads = secs = 0;
+     translation = BIOS_ATA_TRANSLATION_AUTO;
+-    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
++    pstrcpy(monitor_device, sizeof(monitor_device), "null");
+ 
+-    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
+-    for(i = 1; i < MAX_SERIAL_PORTS; i++)
++    for(i = 0; i < MAX_SERIAL_PORTS; i++)
+         serial_devices[i][0] = '\0';
+     serial_device_index = 0;
+-    
++
++#ifndef CONFIG_DM
+     pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
+     for(i = 1; i < MAX_PARALLEL_PORTS; i++)
++#else
++    /* Xen steals IRQ7 for PCI. Disable LPT1 by default. */
++    for(i = 0; i < MAX_PARALLEL_PORTS; i++)
++#endif
+         parallel_devices[i][0] = '\0';
+     parallel_device_index = 0;
+     
+@@ -6054,6 +6082,7 @@
      socket_init();
  #endif
  
@@ -497,7 +521,7 @@ Index: ioemu/vl.c
      /* init network clients */
      if (nb_net_clients == 0) {
          /* if no clients, we use a default config */
-@@ -6063,6 +6088,7 @@
+@@ -6063,6 +6092,7 @@
                  "user");
          nb_net_clients = 2;
      }
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/qemu-dma-null-pointer-check
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/qemu-dma-null-pointer-check   Tue May 08 09:09:17 
2007 -0600
@@ -0,0 +1,13 @@
+Index: ioemu/hw/dma.c
+===================================================================
+--- ioemu.orig/hw/dma.c        2007-05-02 10:30:05.000000000 +0100
++++ ioemu/hw/dma.c     2007-05-03 14:59:53.000000000 +0100
+@@ -340,6 +340,8 @@
+ #endif
+ 
+     r = dma_controllers[ncont].regs + ichan;
++    if (r->transfer_handler == NULL)
++      return;
+     n = r->transfer_handler (r->opaque, ichan + (ncont << 2),
+                              r->now[COUNT], (r->base[COUNT] + 1) << ncont);
+     r->now[COUNT] = n;
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-logging
--- a/tools/ioemu/patches/qemu-logging  Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-logging  Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:36:58.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:37:03.000000000 +0100
+--- ioemu.orig/vl.c    2007-05-02 16:05:51.000000000 +0100
++++ ioemu/vl.c 2007-05-02 16:05:51.000000000 +0100
 @@ -5234,7 +5234,7 @@
             "-S              freeze CPU at startup (use 'c' to start 
execution)\n"
             "-s              wait gdb connection to port %d\n"
@@ -38,7 +38,7 @@ Index: ioemu/vl.c
      LIST_INIT (&vm_change_state_head);
  #ifndef _WIN32
      {
-@@ -5715,6 +5717,11 @@
+@@ -5719,6 +5721,11 @@
      nb_nics = 0;
      /* default mac address of the first network interface */
      
@@ -50,7 +50,7 @@ Index: ioemu/vl.c
      optind = 1;
      for(;;) {
          if (optind >= argc)
-@@ -5905,7 +5912,7 @@
+@@ -5909,7 +5916,7 @@
                      exit(1);
                  }
                  break;
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-pci
--- a/tools/ioemu/patches/qemu-pci      Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-pci      Tue May 08 09:09:17 2007 -0600
@@ -1,8 +1,8 @@ Index: ioemu/hw/pci.c
 Index: ioemu/hw/pci.c
 ===================================================================
---- ioemu.orig/hw/pci.c        2006-12-08 02:02:05.000000000 +0000
-+++ ioemu/hw/pci.c     2006-12-08 18:16:55.000000000 +0000
-@@ -286,6 +286,7 @@
+--- ioemu.orig/hw/pci.c        2007-05-03 15:20:35.000000000 +0100
++++ ioemu/hw/pci.c     2007-05-03 15:20:43.000000000 +0100
+@@ -289,6 +289,7 @@
              case 0x0b:
              case 0x0e:
              case 0x10 ... 0x27: /* base */
@@ -10,7 +10,7 @@ Index: ioemu/hw/pci.c
              case 0x30 ... 0x33: /* rom */
              case 0x3d:
                  can_write = 0;
-@@ -318,6 +319,18 @@
+@@ -321,6 +322,18 @@
              break;
          }
          if (can_write) {
@@ -31,9 +31,9 @@ Index: ioemu/hw/pci.c
          addr++;
 Index: ioemu/hw/rtl8139.c
 ===================================================================
---- ioemu.orig/hw/rtl8139.c    2006-12-08 02:02:05.000000000 +0000
-+++ ioemu/hw/rtl8139.c 2006-12-08 18:16:47.000000000 +0000
-@@ -3423,6 +3423,8 @@
+--- ioemu.orig/hw/rtl8139.c    2007-05-03 15:20:35.000000000 +0100
++++ ioemu/hw/rtl8139.c 2007-05-03 15:20:43.000000000 +0100
+@@ -3424,6 +3424,8 @@
      pci_conf[0x0e] = 0x00; /* header_type */
      pci_conf[0x3d] = 1;    /* interrupt pin 0 */
      pci_conf[0x34] = 0xdc;
@@ -44,9 +44,9 @@ Index: ioemu/hw/rtl8139.c
  
 Index: ioemu/hw/usb-uhci.c
 ===================================================================
---- ioemu.orig/hw/usb-uhci.c   2006-12-08 02:02:05.000000000 +0000
-+++ ioemu/hw/usb-uhci.c        2006-12-08 02:02:38.000000000 +0000
-@@ -659,6 +659,8 @@
+--- ioemu.orig/hw/usb-uhci.c   2007-05-03 15:20:35.000000000 +0100
++++ ioemu/hw/usb-uhci.c        2007-05-03 15:20:43.000000000 +0100
+@@ -704,6 +704,8 @@
      pci_conf[0x0e] = 0x00; // header_type
      pci_conf[0x3d] = 4; // interrupt pin 3
      pci_conf[0x60] = 0x10; // release number
@@ -57,8 +57,8 @@ Index: ioemu/hw/usb-uhci.c
          qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-08 18:16:47.000000000 +0000
-+++ ioemu/vl.h 2006-12-08 18:16:55.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 15:20:43.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:20:43.000000000 +0100
 @@ -650,8 +650,11 @@
  #define PCI_MAX_LAT           0x3f    /* 8 bits */
  
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-pci-vendor-ids
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/qemu-pci-vendor-ids   Tue May 08 09:09:17 2007 -0600
@@ -0,0 +1,47 @@
+Index: ioemu/hw/cirrus_vga.c
+===================================================================
+--- ioemu.orig/hw/cirrus_vga.c 2007-05-03 15:06:41.000000000 +0100
++++ ioemu/hw/cirrus_vga.c      2007-05-03 15:07:16.000000000 +0100
+@@ -3339,6 +3339,10 @@
+     pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
+     pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
+     pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
++    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
++    pci_conf[0x2d] = 0x58;
++    pci_conf[0x2e] = 0x01; /* subsystem device */
++    pci_conf[0x2f] = 0x00;
+ 
+     /* setup VGA */
+     s = &d->cirrus_vga;
+Index: ioemu/hw/rtl8139.c
+===================================================================
+--- ioemu.orig/hw/rtl8139.c    2007-05-03 15:07:16.000000000 +0100
++++ ioemu/hw/rtl8139.c 2007-05-03 15:07:16.000000000 +0100
+@@ -3424,8 +3424,10 @@
+     pci_conf[0x0e] = 0x00; /* header_type */
+     pci_conf[0x3d] = 1;    /* interrupt pin 0 */
+     pci_conf[0x34] = 0xdc;
+-    pci_conf[0x2c] = pci_conf[0x00]; // same as Vendor ID
+-    pci_conf[0x2d] = pci_conf[0x01];
++    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
++    pci_conf[0x2d] = 0x58;
++    pci_conf[0x2e] = 0x01; /* subsystem device */
++    pci_conf[0x2f] = 0x00;
+ 
+     s = &d->rtl8139;
+ 
+Index: ioemu/hw/ide.c
+===================================================================
+--- ioemu.orig/hw/ide.c        2007-05-03 15:07:16.000000000 +0100
++++ ioemu/hw/ide.c     2007-05-03 15:07:16.000000000 +0100
+@@ -2763,6 +2763,10 @@
+     pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
+     pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
+     pci_conf[0x0e] = 0x00; // header_type
++    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
++    pci_conf[0x2d] = 0x58;
++    pci_conf[0x2e] = 0x01; /* subsystem device */
++    pci_conf[0x2f] = 0x00;
+ 
+     pci_register_io_region((PCIDevice *)d, 4, 0x10, 
+                            PCI_ADDRESS_SPACE_IO, bmdma_map);
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-serial-fixes
--- a/tools/ioemu/patches/qemu-serial-fixes     Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-serial-fixes     Tue May 08 09:09:17 2007 -0600
@@ -13,9 +13,9 @@ Signed-off-by: Keir Fraser <keir@xensour
 
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-08 01:28:59.000000000 +0000
-+++ ioemu/vl.c 2006-12-08 01:28:59.000000000 +0000
-@@ -1684,7 +1684,7 @@
+--- ioemu.orig/vl.c    2007-05-03 10:09:02.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:09:02.000000000 +0100
+@@ -1740,7 +1740,7 @@
  
      tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
                            |INLCR|IGNCR|ICRNL|IXON);
@@ -26,8 +26,8 @@ Index: ioemu/vl.c
      switch(data_bits) {
 Index: ioemu/hw/serial.c
 ===================================================================
---- ioemu.orig/hw/serial.c     2006-12-08 01:28:17.000000000 +0000
-+++ ioemu/hw/serial.c  2006-12-08 01:29:10.000000000 +0000
+--- ioemu.orig/hw/serial.c     2007-05-03 10:09:02.000000000 +0100
++++ ioemu/hw/serial.c  2007-05-03 10:09:02.000000000 +0100
 @@ -73,6 +73,11 @@
  #define UART_LSR_OE   0x02    /* Overrun error indicator */
  #define UART_LSR_DR   0x01    /* Receiver data ready */
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-smp
--- a/tools/ioemu/patches/qemu-smp      Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-smp      Tue May 08 09:09:17 2007 -0600
@@ -1,8 +1,8 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-06 02:18:54.847125593 +0100
-+++ ioemu/vl.c 2006-08-06 02:19:00.413505070 +0100
-@@ -158,6 +158,8 @@
+--- ioemu.orig/vl.c    2007-05-03 10:07:47.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:07:52.000000000 +0100
+@@ -159,6 +159,8 @@
  int acpi_enabled = 1;
  int fd_bootchk = 1;
  
@@ -11,7 +11,7 @@ Index: ioemu/vl.c
  int xc_handle;
  
  char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
-@@ -5172,6 +5174,7 @@
+@@ -5173,6 +5175,7 @@
             "-m megs         set virtual RAM size to megs MB [default=%d]\n"
             "-smp n          set the number of CPUs to 'n' [default=1]\n"
             "-nographic      disable graphical output and redirect serial I/Os 
to console\n"
@@ -19,7 +19,7 @@ Index: ioemu/vl.c
  #ifndef _WIN32
           "-k language     use keyboard layout (for example \"fr\" for 
French)\n"
  #endif
-@@ -5342,6 +5345,7 @@
+@@ -5343,6 +5346,7 @@
      QEMU_OPTION_no_acpi,
  
      QEMU_OPTION_d,
@@ -27,7 +27,7 @@ Index: ioemu/vl.c
  };
  
  typedef struct QEMUOption {
-@@ -5423,6 +5427,7 @@
+@@ -5424,6 +5428,7 @@
      { "no-acpi", 0, QEMU_OPTION_no_acpi },
      
      { "d", HAS_ARG, QEMU_OPTION_d },
@@ -35,7 +35,7 @@ Index: ioemu/vl.c
      { NULL },
  };
  
-@@ -6087,6 +6092,10 @@
+@@ -6092,6 +6097,10 @@
                  domid = atoi(optarg);
                  fprintf(logfile, "domid: %d\n", domid);
                  break;
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-target-i386-dm
--- a/tools/ioemu/patches/qemu-target-i386-dm   Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-target-i386-dm   Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-12-08 01:41:10.000000000 +0000
-+++ ioemu/Makefile.target      2006-12-08 01:41:11.000000000 +0000
+--- ioemu.orig/Makefile.target 2007-05-03 14:53:03.000000000 +0100
++++ ioemu/Makefile.target      2007-05-03 14:53:58.000000000 +0100
 @@ -62,6 +62,8 @@
  QEMU_SYSTEM=qemu-fast
  endif
@@ -32,8 +32,8 @@ Index: ioemu/Makefile.target
  DEFINES += -DHAS_AUDIO
 Index: ioemu/configure
 ===================================================================
---- ioemu.orig/configure       2006-12-08 01:41:10.000000000 +0000
-+++ ioemu/configure    2006-12-08 01:41:11.000000000 +0000
+--- ioemu.orig/configure       2007-05-03 14:53:03.000000000 +0100
++++ ioemu/configure    2007-05-03 14:53:57.000000000 +0100
 @@ -373,6 +373,8 @@
      if [ "$user" = "yes" ] ; then
          target_list="i386-user arm-user armeb-user sparc-user ppc-user 
mips-user mipsel-user $target_list"
@@ -45,8 +45,8 @@ Index: ioemu/configure
  fi
 Index: ioemu/monitor.c
 ===================================================================
---- ioemu.orig/monitor.c       2006-12-08 01:41:10.000000000 +0000
-+++ ioemu/monitor.c    2006-12-08 01:41:11.000000000 +0000
+--- ioemu.orig/monitor.c       2007-05-03 14:53:03.000000000 +0100
++++ ioemu/monitor.c    2007-05-03 14:53:58.000000000 +0100
 @@ -1262,6 +1262,10 @@
        "", "show profiling information", },
      { "capture", "", do_info_capture,
@@ -60,8 +60,8 @@ Index: ioemu/monitor.c
  
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-08 01:41:10.000000000 +0000
-+++ ioemu/vl.c 2006-12-08 01:41:11.000000000 +0000
+--- ioemu.orig/vl.c    2007-05-03 14:53:03.000000000 +0100
++++ ioemu/vl.c 2007-05-03 14:53:59.000000000 +0100
 @@ -87,7 +87,7 @@
  
  #include "exec-all.h"
@@ -98,8 +98,8 @@ Index: ioemu/vl.c
  {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-08 01:40:58.000000000 +0000
-+++ ioemu/vl.h 2006-12-08 01:41:11.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 14:52:58.000000000 +0100
++++ ioemu/vl.h 2007-05-03 14:53:59.000000000 +0100
 @@ -37,6 +37,8 @@
  #include <unistd.h>
  #include <fcntl.h>
@@ -132,7 +132,7 @@ Index: ioemu/target-i386-dm/cpu.h
 Index: ioemu/target-i386-dm/cpu.h
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/cpu.h 2006-12-08 01:41:11.000000000 +0000
++++ ioemu/target-i386-dm/cpu.h 2007-05-03 14:53:58.000000000 +0100
 @@ -0,0 +1,84 @@
 +/*
 + * i386 virtual CPU header
@@ -221,8 +221,8 @@ Index: ioemu/target-i386-dm/exec-dm.c
 Index: ioemu/target-i386-dm/exec-dm.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/exec-dm.c     2006-12-08 01:41:11.000000000 +0000
-@@ -0,0 +1,546 @@
++++ ioemu/target-i386-dm/exec-dm.c     2007-05-03 14:53:56.000000000 +0100
+@@ -0,0 +1,540 @@
 +/*
 + *  virtual page mapping and translated block handling
 + * 
@@ -638,14 +638,8 @@ Index: ioemu/target-i386-dm/exec-dm.c
 +{
 +    /* Is this guest physical address RAM-backed? */
 +#if defined(CONFIG_DM) && (defined(__i386__) || defined(__x86_64__))
-+    if (ram_size <= HVM_BELOW_4G_RAM_END)
-+        /* RAM is contiguous */
-+        return (addr < ram_size);
-+    else
-+        /* There is RAM below and above the MMIO hole */
-+        return ((addr < HVM_BELOW_4G_MMIO_START) ||
-+                ((addr >= HVM_BELOW_4G_MMIO_START + HVM_BELOW_4G_MMIO_LENGTH)
-+                 && (addr < ram_size + HVM_BELOW_4G_MMIO_LENGTH)));
++    return ((addr < HVM_BELOW_4G_MMIO_START) ||
++            (addr >= HVM_BELOW_4G_MMIO_START + HVM_BELOW_4G_MMIO_LENGTH));
 +#else
 +    return (addr < ram_size);
 +#endif
@@ -772,8 +766,8 @@ Index: ioemu/target-i386-dm/helper2.c
 Index: ioemu/target-i386-dm/helper2.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/helper2.c     2006-12-08 01:41:11.000000000 +0000
-@@ -0,0 +1,488 @@
++++ ioemu/target-i386-dm/helper2.c     2007-05-03 14:54:46.000000000 +0100
+@@ -0,0 +1,542 @@
 +/*
 + *  i386 helpers (without register variable usage)
 + *
@@ -1162,6 +1156,21 @@ Index: ioemu/target-i386-dm/helper2.c
 +    req->data = tmp1;
 +}
 +
++void cpu_ioreq_sub(CPUState *env, ioreq_t *req)
++{
++    unsigned long tmp1, tmp2;
++
++    if (req->data_is_ptr != 0)
++        hw_error("expected scalar value");
++
++    read_physical(req->addr, req->size, &tmp1);
++    if (req->dir == IOREQ_WRITE) {
++        tmp2 = tmp1 - (unsigned long) req->data;
++        write_physical(req->addr, req->size, &tmp2);
++    }
++    req->data = tmp1;
++}
++
 +void cpu_ioreq_or(CPUState *env, ioreq_t *req)
 +{
 +    unsigned long tmp1, tmp2;
@@ -1192,8 +1201,22 @@ Index: ioemu/target-i386-dm/helper2.c
 +    req->data = tmp1;
 +}
 +
++void cpu_ioreq_xchg(CPUState *env, ioreq_t *req)
++{
++    unsigned long tmp1;
++
++    if (req->data_is_ptr != 0)
++        hw_error("expected scalar value");
++
++    read_physical(req->addr, req->size, &tmp1);
++    write_physical(req->addr, req->size, &req->data);
++    req->data = tmp1;
++}
++
 +void cpu_handle_ioreq(void *opaque)
 +{
++    extern int vm_running;
++    extern int shutdown_requested;
 +    CPUState *env = opaque;
 +    ioreq_t *req = cpu_get_ioreq();
 +
@@ -1216,11 +1239,17 @@ Index: ioemu/target-i386-dm/helper2.c
 +        case IOREQ_TYPE_ADD:
 +            cpu_ioreq_add(env, req);
 +            break;
++        case IOREQ_TYPE_SUB:
++            cpu_ioreq_sub(env, req);
++            break;
 +        case IOREQ_TYPE_OR:
 +            cpu_ioreq_or(env, req);
 +            break;
 +        case IOREQ_TYPE_XOR:
 +            cpu_ioreq_xor(env, req);
++            break;
++        case IOREQ_TYPE_XCHG:
++            cpu_ioreq_xchg(env, req);
 +            break;
 +        default:
 +            hw_error("Invalid ioreq type 0x%x\n", req->type);
@@ -1237,6 +1266,25 @@ Index: ioemu/target-i386-dm/helper2.c
 +        }
 +
 +        wmb(); /* Update ioreq contents /then/ update state. */
++
++      /*
++         * We do this before we send the response so that the tools
++         * have the opportunity to pick up on the reset before the
++         * guest resumes and does a hlt with interrupts disabled which
++         * causes Xen to powerdown the domain.
++         */
++        if (vm_running) {
++            if (shutdown_requested) {
++              fprintf(logfile, "shutdown requested in cpu_handle_ioreq\n");
++              destroy_hvm_domain();
++          }
++          if (reset_requested) {
++              fprintf(logfile, "reset requested in cpu_handle_ioreq.\n");
++              qemu_system_reset();
++              reset_requested = 0;
++          }
++      }
++
 +        req->state = STATE_IORESP_READY;
 +        xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
 +    }
@@ -1265,7 +1313,7 @@ Index: ioemu/target-i386-dm/i8259-dm.c
 Index: ioemu/target-i386-dm/i8259-dm.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/i8259-dm.c    2006-12-08 01:41:11.000000000 +0000
++++ ioemu/target-i386-dm/i8259-dm.c    2007-05-03 14:53:57.000000000 +0100
 @@ -0,0 +1,67 @@
 +/* Xen 8259 stub for interrupt controller emulation
 + * 
@@ -1337,7 +1385,7 @@ Index: ioemu/target-i386-dm/qemu-dm.debu
 Index: ioemu/target-i386-dm/qemu-dm.debug
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/qemu-dm.debug 2006-12-08 01:41:11.000000000 +0000
++++ ioemu/target-i386-dm/qemu-dm.debug 2007-05-03 14:53:03.000000000 +0100
 @@ -0,0 +1,10 @@
 +#!/bin/sh
 +
@@ -1352,15 +1400,14 @@ Index: ioemu/target-i386-dm/qemu-ifup
 Index: ioemu/target-i386-dm/qemu-ifup
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/qemu-ifup     2006-12-08 01:41:11.000000000 +0000
-@@ -0,0 +1,10 @@
++++ ioemu/target-i386-dm/qemu-ifup     2007-05-03 14:53:03.000000000 +0100
+@@ -0,0 +1,9 @@
 +#!/bin/sh
 +
 +#. /etc/rc.d/init.d/functions
 +#ulimit -c unlimited
 +
-+echo -c 'config qemu network with xen bridge for '
-+echo $*
++echo 'config qemu network with xen bridge for ' $*
 +
 +ifconfig $1 0.0.0.0 up
 +brctl addif $2 $1
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/qemu-timer
--- a/tools/ioemu/patches/qemu-timer    Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/qemu-timer    Tue May 08 09:09:17 2007 -0600
@@ -1,8 +1,8 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-06 02:22:53.925474246 +0100
-+++ ioemu/vl.c 2006-08-06 02:22:56.618174081 +0100
-@@ -824,6 +824,16 @@
+--- ioemu.orig/vl.c    2007-05-03 10:07:52.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:07:52.000000000 +0100
+@@ -825,6 +825,16 @@
      }
  }
  
@@ -19,7 +19,7 @@ Index: ioemu/vl.c
  static void timer_save(QEMUFile *f, void *opaque)
  {
      if (cpu_ticks_enabled) {
-@@ -940,6 +950,8 @@
+@@ -941,6 +951,8 @@
  
  #endif /* !defined(_WIN32) */
  
@@ -28,7 +28,7 @@ Index: ioemu/vl.c
  static void init_timer_alarm(void)
  {
  #ifdef _WIN32
-@@ -971,12 +983,15 @@
+@@ -972,12 +984,15 @@
      pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
  #else
      {
@@ -44,7 +44,7 @@ Index: ioemu/vl.c
          /* timer signal */
          sigfillset(&act.sa_mask);
         act.sa_flags = 0;
-@@ -1022,6 +1037,7 @@
+@@ -1023,6 +1038,7 @@
              pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * 
                                     PIT_FREQ) / 1000000;
          }
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/qemu-tunable-ide-write-cache
--- a/tools/ioemu/patches/qemu-tunable-ide-write-cache  Mon May 07 13:24:37 
2007 -0600
+++ b/tools/ioemu/patches/qemu-tunable-ide-write-cache  Tue May 08 09:09:17 
2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/hw/ide.c
 Index: ioemu/hw/ide.c
 ===================================================================
---- ioemu.orig/hw/ide.c        2006-08-20 22:22:36.000000000 +0100
-+++ ioemu/hw/ide.c     2006-08-20 23:56:13.000000000 +0100
+--- ioemu.orig/hw/ide.c        2007-05-03 15:07:15.000000000 +0100
++++ ioemu/hw/ide.c     2007-05-03 15:07:16.000000000 +0100
 @@ -305,6 +305,7 @@
      PCIDevice *pci_dev;
      struct BMDMAState *bmdma;
@@ -10,7 +10,7 @@ Index: ioemu/hw/ide.c
      /* ide regs */
      uint8_t feature;
      uint8_t error;
-@@ -789,6 +790,9 @@
+@@ -947,6 +948,9 @@
      }
      ide_set_sector(s, sector_num + n);
      
@@ -20,7 +20,7 @@ Index: ioemu/hw/ide.c
  #ifdef TARGET_I386
      if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
          /* It seems there is a bug in the Windows 2000 installer HDD
-@@ -863,6 +867,10 @@
+@@ -1021,6 +1025,10 @@
          transfer_size -= len;
          phys_addr += len;
      }
@@ -31,7 +31,7 @@ Index: ioemu/hw/ide.c
      return transfer_size1 - transfer_size;
  }
  
-@@ -1672,7 +1680,15 @@
+@@ -1831,7 +1839,15 @@
              /* XXX: valid for CDROM ? */
              switch(s->feature) {
              case 0x02: /* write cache enable */
@@ -47,7 +47,7 @@ Index: ioemu/hw/ide.c
              case 0xaa: /* read look-ahead enable */
              case 0x55: /* read look-ahead disable */
                  s->status = READY_STAT | SEEK_STAT;
-@@ -2090,6 +2106,7 @@
+@@ -2254,6 +2270,7 @@
          s->irq = irq;
          s->sector_write_timer = qemu_new_timer(vm_clock, 
                                                 ide_sector_write_timer_cb, s);
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/scsi
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/scsi  Tue May 08 09:09:17 2007 -0600
@@ -0,0 +1,194 @@
+Index: ioemu/vl.c
+===================================================================
+--- ioemu.orig/vl.c    2007-05-03 15:20:45.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:20:45.000000000 +0100
+@@ -116,7 +116,7 @@
+ void *ioport_opaque[MAX_IOPORTS];
+ IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
+ IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
+-BlockDriverState *bs_table[MAX_DISKS], *fd_table[MAX_FD];
++BlockDriverState *bs_table[MAX_DISKS + MAX_SCSI_DISKS], *fd_table[MAX_FD];
+ int vga_ram_size;
+ int bios_size;
+ static DisplayState display_state;
+@@ -1396,7 +1396,7 @@
+         case 's': 
+             {
+                 int i;
+-                for (i = 0; i < MAX_DISKS; i++) {
++                for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
+                     if (bs_table[i])
+                         bdrv_commit(bs_table[i]);
+                 }
+@@ -6057,7 +6057,7 @@
+     int snapshot, linux_boot;
+     const char *initrd_filename;
+ #ifndef CONFIG_DM
+-    const char *hd_filename[MAX_DISKS];
++    const char *hd_filename[MAX_DISKS + MAX_SCSI_DISKS];
+ #endif /* !CONFIG_DM */
+     const char *fd_filename[MAX_FD];
+     const char *kernel_filename, *kernel_cmdline;
+@@ -6126,7 +6126,7 @@
+     for(i = 0; i < MAX_FD; i++)
+         fd_filename[i] = NULL;
+ #ifndef CONFIG_DM
+-    for(i = 0; i < MAX_DISKS; i++)
++    for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
+         hd_filename[i] = NULL;
+ #endif /* !CONFIG_DM */
+     ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
+@@ -6724,7 +6724,7 @@
+     }
+ 
+     /* open the virtual block devices */
+-    for(i = 0; i < MAX_DISKS; i++) {
++    for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
+         if (hd_filename[i]) {
+             if (!bs_table[i]) {
+                 char buf[64];
+Index: ioemu/vl.h
+===================================================================
+--- ioemu.orig/vl.h    2007-05-03 15:20:45.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:20:45.000000000 +0100
+@@ -818,8 +818,9 @@
+ 
+ /* ide.c */
+ #define MAX_DISKS 4
++#define MAX_SCSI_DISKS 7
+ 
+-extern BlockDriverState *bs_table[MAX_DISKS];
++extern BlockDriverState *bs_table[MAX_DISKS + MAX_SCSI_DISKS];
+ 
+ void isa_ide_init(int iobase, int iobase2, int irq,
+                   BlockDriverState *hd0, BlockDriverState *hd1);
+Index: ioemu/hw/pc.c
+===================================================================
+--- ioemu.orig/hw/pc.c 2007-05-03 15:20:44.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-03 15:20:45.000000000 +0100
+@@ -902,7 +902,6 @@
+     if (pci_enabled && acpi_enabled) {
+         piix4_pm_init(pci_bus, piix3_devfn + 3);
+     }
+-#endif /* !CONFIG_DM */
+ 
+ #if 0
+     /* ??? Need to figure out some way for the user to
+@@ -921,6 +920,18 @@
+         lsi_scsi_attach(scsi, bdrv, -1);
+     }
+ #endif
++#else
++    if (pci_enabled) {
++        void *scsi = NULL;
++        for (i = 0; i < MAX_SCSI_DISKS ; i++) {
++            if (!bs_table[i + MAX_DISKS])
++                continue;
++            if (!scsi)
++                scsi = lsi_scsi_init(pci_bus, -1);
++            lsi_scsi_attach(scsi, bs_table[i + MAX_DISKS], -1);
++        }
++    }
++#endif /* !CONFIG_DM */
+     /* must be done after all PCI devices are instanciated */
+     /* XXX: should be done in the Bochs BIOS */
+     if (pci_enabled) {
+Index: ioemu/xenstore.c
+===================================================================
+--- ioemu.orig/xenstore.c      2007-05-03 15:20:45.000000000 +0100
++++ ioemu/xenstore.c   2007-05-03 15:20:45.000000000 +0100
+@@ -18,7 +18,7 @@
+ #include <fcntl.h>
+ 
+ static struct xs_handle *xsh = NULL;
+-static char *media_filename[MAX_DISKS];
++static char *media_filename[MAX_DISKS + MAX_SCSI_DISKS];
+ static QEMUTimer *insert_timer = NULL;
+ 
+ #define UWAIT_MAX (30*1000000) /* thirty seconds */
+@@ -44,7 +44,7 @@
+ {
+     int i;
+ 
+-    for (i = 0; i < MAX_DISKS; i++) {
++    for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
+         if (media_filename[i] && bs_table[i]) {
+             do_change(bs_table[i]->device_name, media_filename[i]);
+             free(media_filename[i]);
+@@ -83,10 +83,10 @@
+     char *buf = NULL, *path;
+     char *fpath = NULL, *bpath = NULL,
+         *dev = NULL, *params = NULL, *type = NULL;
+-    int i;
++    int i, is_scsi;
+     unsigned int len, num, hd_index;
+ 
+-    for(i = 0; i < MAX_DISKS; i++)
++    for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
+         media_filename[i] = NULL;
+ 
+     xsh = xs_daemon_open();
+@@ -123,10 +123,11 @@
+         dev = xs_read(xsh, XBT_NULL, buf, &len);
+         if (dev == NULL)
+             continue;
+-        if (strncmp(dev, "hd", 2) || strlen(dev) != 3)
++        is_scsi = !strncmp(dev, "sd", 2);
++        if ((strncmp(dev, "hd", 2) && !is_scsi) || strlen(dev) != 3 )
+             continue;
+         hd_index = dev[2] - 'a';
+-        if (hd_index >= MAX_DISKS)
++        if (hd_index >= (is_scsi ? MAX_SCSI_DISKS : MAX_DISKS))
+             continue;
+         /* read the type of the device */
+         if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
+@@ -163,7 +164,7 @@
+             }
+         }
+ 
+-        bs_table[hd_index] = bdrv_new(dev);
++        bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)] = bdrv_new(dev);
+         /* check if it is a cdrom */
+         if (type && !strcmp(type, "cdrom")) {
+             bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
+@@ -172,7 +173,8 @@
+         }
+         /* open device now if media present */
+         if (params[0]) {
+-            if (bdrv_open(bs_table[hd_index], params, 0 /* snapshot */) < 0)
++            if (bdrv_open(bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)],
++                          params, 0 /* snapshot */) < 0)
+                 fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
+                         params);
+         }
+Index: ioemu/monitor.c
+===================================================================
+--- ioemu.orig/monitor.c       2007-05-03 15:18:43.000000000 +0100
++++ ioemu/monitor.c    2007-05-03 15:20:45.000000000 +0100
+@@ -180,7 +180,7 @@
+ {
+     int i;
+ 
+-    for (i = 0; i < MAX_DISKS; i++) {
++    for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
+         if (bs_table[i]) {
+             bdrv_commit(bs_table[i]);
+         }
+Index: ioemu/hw/lsi53c895a.c
+===================================================================
+--- ioemu.orig/hw/lsi53c895a.c 2007-05-03 15:18:43.000000000 +0100
++++ ioemu/hw/lsi53c895a.c      2007-05-03 15:20:45.000000000 +0100
+@@ -1071,8 +1071,13 @@
+         shift = (offset & 3) * 8;
+         return (s->scratch[n] >> shift) & 0xff;
+     }
++#ifndef CONFIG_DM
+     BADF("readb 0x%x\n", offset);
+     exit(1);
++#else
++    /* XEN: This path can be triggered (e.g. ASPI8DOS.SYS reads 0x8). */
++    return 0;
++#endif
+ #undef CASE_GET_REG32
+ }
+ 
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/serial-non-block
--- a/tools/ioemu/patches/serial-non-block      Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/serial-non-block      Tue May 08 09:09:17 2007 -0600
@@ -1,8 +1,8 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:49:52.162002356 +0100
-+++ ioemu/vl.c 2006-08-17 19:49:56.273547905 +0100
-@@ -1175,19 +1175,34 @@
+--- ioemu.orig/vl.c    2007-05-03 10:07:53.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:07:53.000000000 +0100
+@@ -1176,19 +1176,34 @@
  
  static int unix_write(int fd, const uint8_t *buf, int len1)
  {
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/series
--- a/tools/ioemu/patches/series        Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/series        Tue May 08 09:09:17 2007 -0600
@@ -24,11 +24,18 @@ shared-vram
 shared-vram
 shadow-vram
 serial-non-block
+ioemu-save-restore
+ioemu-save-restore-ide
+ioemu-save-restore-usb
+ioemu-save-restore-timer
+ioemu-save-restore-rtl8139
+ioemu-save-restore-pcnet
+ioemu-save-restore-ne2000
 ide-hd-multithread
-domain-timeoffset
 acpi-support
 acpi-timer-support
 acpi-poweroff-support
+ioemu-save-restore-acpi
 fix-vga-scanning-code-overflow
 vnc-cleanup
 vnc-fixes
@@ -39,16 +46,20 @@ vnc-display-find-unused
 vnc-display-find-unused
 vnc-listen-specific-interface
 vnc-backoff-screen-scan
+xenstore
 xenstore-block-device-config
 xenstore-write-vnc-port
+domain-timeoffset
 qemu-allow-disable-sdl
 qemu-fix-memset-args
 xen-support-buffered-ioreqs
+ioemu-buffer-pio-ia64
 qemu-daemonize
 xen-platform-device
 qemu-bootorder
 qemu-tunable-ide-write-cache
 qemu-pci 
+qemu-pci-vendor-ids
 serial-port-rate-limit
 hypervisor-rtc
 ide-cd-dma
@@ -67,5 +78,13 @@ vnc-monitor-shift-key-processing
 vnc-monitor-shift-key-processing
 ide-error-reporting
 vnc-numpad-handling
+vnc-altgr-keysym
 xen-mapcache
-usb-mouse-tablet-status-check -p3
+ioemu-save-restore-logdirty
+usb-mouse-tablet-status-check
+vnc-fix-signedness
+vnc-fix-version-check
+scsi
+qemu-cirrus-bounds-checks
+qemu-block-device-bounds-checks
+qemu-dma-null-pointer-check
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/shadow-vram
--- a/tools/ioemu/patches/shadow-vram   Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/shadow-vram   Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/hw/vga.c
 Index: ioemu/hw/vga.c
 ===================================================================
---- ioemu.orig/hw/vga.c        2006-08-17 19:49:52.159002688 +0100
-+++ ioemu/hw/vga.c     2006-08-17 19:49:54.575735565 +0100
+--- ioemu.orig/hw/vga.c        2007-05-02 10:32:35.000000000 +0100
++++ ioemu/hw/vga.c     2007-05-02 10:35:05.000000000 +0100
 @@ -1359,6 +1359,105 @@
      }
  }
@@ -120,10 +120,11 @@ Index: ioemu/hw/vga.c
      addr1 = (s->start_addr * 4);
      bwidth = width * 4;
      y_start = -1;
-@@ -1889,6 +1993,14 @@
+@@ -1889,7 +1993,18 @@
  
      vga_reset(s);
  
+-    s->vram_ptr = qemu_malloc(vga_ram_size);
 +    check_sse2();
 +    s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1);
 +    if (s->vram_shadow == NULL)
@@ -132,16 +133,43 @@ Index: ioemu/hw/vga.c
 +    s->vram_shadow = (uint8_t *)((long)(s->vram_shadow + TARGET_PAGE_SIZE - 1)
 +                                 & ~(TARGET_PAGE_SIZE - 1));
 +
-     s->vram_ptr = qemu_malloc(vga_ram_size);
++    /* Video RAM must be 128-bit aligned for SSE optimizations later */
++    s->vram_alloc = qemu_malloc(vga_ram_size + 15);
++    s->vram_ptr = (uint8_t *)((long)(s->vram_alloc + 15) & ~15L);
++
      s->vram_offset = vga_ram_offset;
      s->vram_size = vga_ram_size;
+     s->ds = ds;
+@@ -2013,7 +2128,7 @@
+     }
+ 
+     if (!vga_ram_base) {
+-        vga_ram_base = qemu_malloc(vga_ram_size);
++        vga_ram_base = qemu_malloc(vga_ram_size + TARGET_PAGE_SIZE + 1);
+         if (!vga_ram_base) {
+             fprintf(stderr, "reallocate error\n");
+             return NULL;
+@@ -2021,8 +2136,10 @@
+     }
+ 
+     /* XXX lock needed? */
++    old_pointer = s->vram_alloc;
++    s->vram_alloc = vga_ram_base;
++    vga_ram_base = (uint8_t *)((long)(vga_ram_base + 15) & ~15L);
+     memcpy(vga_ram_base, s->vram_ptr, vga_ram_size);
+-    old_pointer = s->vram_ptr;
+     s->vram_ptr = vga_ram_base;
+ 
+     return old_pointer;
 Index: ioemu/hw/vga_int.h
 ===================================================================
---- ioemu.orig/hw/vga_int.h    2006-08-17 19:49:52.159002688 +0100
-+++ ioemu/hw/vga_int.h 2006-08-17 19:49:54.575735565 +0100
-@@ -79,6 +79,7 @@
+--- ioemu.orig/hw/vga_int.h    2007-05-02 10:32:35.000000000 +0100
++++ ioemu/hw/vga_int.h 2007-05-02 10:35:10.000000000 +0100
+@@ -78,7 +78,9 @@
+ #define VGA_MAX_HEIGHT 2048
  
  #define VGA_STATE_COMMON                                                \
++    uint8_t *vram_alloc;                                                \
      uint8_t *vram_ptr;                                                  \
 +    uint8_t *vram_shadow;                                               \
      unsigned long vram_offset;                                          \
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/shared-vram
--- a/tools/ioemu/patches/shared-vram   Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/shared-vram   Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/hw/cirrus_vga.c
 Index: ioemu/hw/cirrus_vga.c
 ===================================================================
---- ioemu.orig/hw/cirrus_vga.c 2006-12-08 01:57:54.000000000 +0000
-+++ ioemu/hw/cirrus_vga.c      2006-12-08 02:00:04.000000000 +0000
+--- ioemu.orig/hw/cirrus_vga.c 2007-05-03 09:56:32.000000000 +0100
++++ ioemu/hw/cirrus_vga.c      2007-05-03 10:07:53.000000000 +0100
 @@ -28,6 +28,9 @@
   */
  #include "vl.h"
@@ -39,7 +39,7 @@ Index: ioemu/hw/cirrus_vga.c
  /***************************************
   *
   *  prototypes.
-@@ -2520,6 +2529,80 @@
+@@ -2520,6 +2529,83 @@
      cirrus_linear_bitblt_writel,
  };
  
@@ -85,7 +85,8 @@ Index: ioemu/hw/cirrus_vga.c
 +    return vram_pointer;
 +}
 +
-+static int unset_vram_mapping(unsigned long begin, unsigned long end)
++static int unset_vram_mapping(unsigned long begin, unsigned long end, 
++                              void *mapping)
 +{
 +    xen_pfn_t *extent_start = NULL;
 +    unsigned long nr_extents;
@@ -105,11 +106,13 @@ Index: ioemu/hw/cirrus_vga.c
 +        return -1;
 +    }
 +
++    /* Drop our own references to the vram pages */
++    munmap(mapping, nr_extents * TARGET_PAGE_SIZE);
++
++    /* Now drop the guest's mappings */
 +    memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
-+
 +    for (i = 0; i < nr_extents; i++)
 +        extent_start[i] = (begin + (i * TARGET_PAGE_SIZE)) >> 
TARGET_PAGE_BITS;
-+
 +    unset_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
 +
 +    free(extent_start);
@@ -120,7 +123,7 @@ Index: ioemu/hw/cirrus_vga.c
  /* Compute the memory access functions */
  static void cirrus_update_memory_access(CirrusVGAState *s)
  {
-@@ -2538,11 +2621,39 @@
+@@ -2538,11 +2624,37 @@
          
        mode = s->gr[0x05] & 0x7;
        if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
@@ -145,22 +148,20 @@ Index: ioemu/hw/cirrus_vga.c
          } else {
          generic_io:
 +            if (s->cirrus_lfb_addr && s->cirrus_lfb_end && s->map_addr) {
-+              int error;
-+                void *old_vram = NULL;
-+
-+              error = unset_vram_mapping(s->cirrus_lfb_addr,
-+                                         s->cirrus_lfb_end);
-+              if (!error)
-+                  old_vram = vga_update_vram((VGAState *)s, NULL,
-+                                               VGA_RAM_SIZE);
-+                if (old_vram)
-+                    munmap(old_vram, s->map_addr - s->map_end);
++                void *old_vram;
++
++                old_vram = vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
++
++                unset_vram_mapping(s->cirrus_lfb_addr,
++                                   s->cirrus_lfb_end, 
++                                   old_vram);
++
 +                s->map_addr = s->map_end = 0;
 +            }
              s->cirrus_linear_write[0] = cirrus_linear_writeb;
              s->cirrus_linear_write[1] = cirrus_linear_writew;
              s->cirrus_linear_write[2] = cirrus_linear_writel;
-@@ -3136,6 +3247,13 @@
+@@ -3136,6 +3248,13 @@
      /* XXX: add byte swapping apertures */
      cpu_register_physical_memory(addr, s->vram_size,
                                 s->cirrus_linear_io_addr);
@@ -176,8 +177,8 @@ Index: ioemu/hw/cirrus_vga.c
  }
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-12-08 02:00:04.000000000 +0000
-+++ ioemu/hw/pc.c      2006-12-08 02:00:04.000000000 +0000
+--- ioemu.orig/hw/pc.c 2007-05-03 10:07:53.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-03 10:07:53.000000000 +0100
 @@ -790,14 +790,14 @@
      if (cirrus_vga_enabled) {
          if (pci_enabled) {
@@ -198,8 +199,8 @@ Index: ioemu/hw/pc.c
  
 Index: ioemu/hw/vga.c
 ===================================================================
---- ioemu.orig/hw/vga.c        2006-12-08 02:00:04.000000000 +0000
-+++ ioemu/hw/vga.c     2006-12-08 02:00:04.000000000 +0000
+--- ioemu.orig/hw/vga.c        2007-05-03 10:07:52.000000000 +0100
++++ ioemu/hw/vga.c     2007-05-03 10:07:53.000000000 +0100
 @@ -1858,6 +1858,7 @@
      /* TODO: add vbe support if enabled */
  }
@@ -251,8 +252,8 @@ Index: ioemu/hw/vga.c
  
 Index: ioemu/hw/vga_int.h
 ===================================================================
---- ioemu.orig/hw/vga_int.h    2006-12-08 01:57:54.000000000 +0000
-+++ ioemu/hw/vga_int.h 2006-12-08 02:00:04.000000000 +0000
+--- ioemu.orig/hw/vga_int.h    2007-05-03 09:56:32.000000000 +0100
++++ ioemu/hw/vga_int.h 2007-05-03 10:07:53.000000000 +0100
 @@ -169,5 +169,6 @@
                               unsigned int color0, unsigned int color1,
                               unsigned int color_xor);
@@ -262,9 +263,9 @@ Index: ioemu/hw/vga_int.h
  extern const uint8_t gr_mask[16];
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-08 02:00:04.000000000 +0000
-+++ ioemu/vl.c 2006-12-08 02:00:27.000000000 +0000
-@@ -5693,6 +5693,62 @@
+--- ioemu.orig/vl.c    2007-05-03 10:07:53.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:07:53.000000000 +0100
+@@ -5745,6 +5745,62 @@
  
  #define MAX_NET_CLIENTS 32
  
@@ -278,17 +279,17 @@ Index: ioemu/vl.c
 +    int err = 0;
 +    xc_dominfo_t info;
 +
++    xc_domain_getinfo(xc_handle, domid, 1, &info);
++    if ((info.nr_pages - nr_pages) <= 0) {
++        fprintf(stderr, "unset_mm_mapping: error nr_pages\n");
++        err = -1;
++    }
++
 +    err = xc_domain_memory_decrease_reservation(xc_handle, domid,
 +                                                nr_pages, 0, extent_start);
 +    if (err)
 +        fprintf(stderr, "Failed to decrease physmap\n");
 +
-+    xc_domain_getinfo(xc_handle, domid, 1, &info);
-+
-+    if ((info.nr_pages - nr_pages) <= 0) {
-+        fprintf(stderr, "unset_mm_mapping: error nr_pages\n");
-+        err = -1;
-+    }
 +
 +    if (xc_domain_setmaxmem(xc_handle, domid, (info.nr_pages - nr_pages) *
 +                            PAGE_SIZE/1024) != 0) {
@@ -329,8 +330,8 @@ Index: ioemu/vl.c
  #ifdef CONFIG_GDBSTUB
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-08 02:00:04.000000000 +0000
-+++ ioemu/vl.h 2006-12-08 02:00:04.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 10:07:53.000000000 +0100
++++ ioemu/vl.h 2007-05-03 10:07:53.000000000 +0100
 @@ -145,6 +145,13 @@
  
  void main_loop_wait(int timeout);
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/support-xm-console
--- a/tools/ioemu/patches/support-xm-console    Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/support-xm-console    Tue May 08 09:09:17 2007 -0600
@@ -1,17 +1,56 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:49:40.119333436 +0100
-+++ ioemu/vl.c 2006-08-17 19:49:48.566399780 +0100
-@@ -1536,26 +1536,65 @@
+--- ioemu.orig/vl.c    2007-05-03 10:24:03.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:24:04.000000000 +0100
+@@ -1537,26 +1537,108 @@
      return chr;
  }
  
-+int store_console_dev(int domid, char *pts)
++/*
++ * Create a store entry for a device (e.g., monitor, serial/parallel lines).
++ * The entry is <domain-path><storeString>/tty and the value is the name
++ * of the pty associated with the device.
++ */
++static int store_dev_info(char *devName, int domid,
++                          CharDriverState *cState, char *storeString)
 +{
 +    int xc_handle;
 +    struct xs_handle *xs;
 +    char *path;
++    char *newpath;
++    FDCharDriver *s;
++    char *pts;
 +
++    /* Check for valid arguments (at least, prevent segfaults). */
++    if ((devName == NULL) || (cState == NULL) || (storeString == NULL)) {
++        fprintf(logfile, "%s - invalid arguments\n", __FUNCTION__);
++        return EINVAL;
++    }
++
++    /*
++     * Only continue if we're talking to a pty
++     * Actually, the following code works for any CharDriverState using
++     * FDCharDriver, but we really only care about pty's here
++     */
++    if (strcmp(devName, "pty"))
++        return 0;
++
++    s = cState->opaque;
++    if (s == NULL) {
++        fprintf(logfile, "%s - unable to retrieve fd for '%s'/'%s'\n",
++                __FUNCTION__, storeString, devName);
++        return EBADF;
++    }
++
++    pts = ptsname(s->fd_in);
++    if (pts == NULL) {
++        fprintf(logfile, "%s - unable to determine ptsname '%s'/'%s', "
++                "error %d (%s)\n",
++                __FUNCTION__, storeString, devName, errno, strerror(errno));
++        return errno;
++    }
++
++    /* We now have everything we need to set the xenstore entry. */
 +    xs = xs_daemon_open();
 +    if (xs == NULL) {
 +        fprintf(logfile, "Could not contact XenStore\n");
@@ -29,14 +68,19 @@ Index: ioemu/vl.c
 +        fprintf(logfile, "xs_get_domain_path() error\n");
 +        return -1;
 +    }
-+    path = realloc(path, strlen(path) + strlen("/console/tty") + 1);
-+    if (path == NULL) {
++    newpath = realloc(path, (strlen(path) + strlen(storeString) +
++                             strlen("/tty") + 1));
++    if (newpath == NULL) {
++        free(path); /* realloc errors leave old block */
 +        fprintf(logfile, "realloc error\n");
 +        return -1;
 +    }
-+    strcat(path, "/console/tty");
++    path = newpath;
++
++    strcat(path, storeString);
++    strcat(path, "/tty");
 +    if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
-+        fprintf(logfile, "xs_write for console fail");
++        fprintf(logfile, "xs_write for '%s' fail", storeString);
 +        return -1;
 +    }
 +
@@ -71,13 +115,12 @@ Index: ioemu/vl.c
 +    tcsetattr(slave_fd, TCSAFLUSH, &tty);
 +    
 +    fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
-+    store_console_dev(domid, ptsname(master_fd));
  
 -    fprintf(stderr, "char device redirected to %s\n", slave_name);
      return qemu_chr_open_fd(master_fd, master_fd);
  }
  
-@@ -5868,7 +5907,9 @@
+@@ -5881,7 +5963,9 @@
                  break;
              case QEMU_OPTION_nographic:
                  pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
@@ -88,3 +131,43 @@ Index: ioemu/vl.c
                  nographic = 1;
                  break;
              case QEMU_OPTION_kernel:
+@@ -6348,16 +6432,23 @@
+         fprintf(stderr, "qemu: could not open monitor device '%s'\n", 
monitor_device);
+         exit(1);
+     }
++    store_dev_info(monitor_device, domid, monitor_hd, "/monitor");
+     monitor_init(monitor_hd, !nographic);
+ 
+     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+         if (serial_devices[i][0] != '\0') {
++            char buf[16];
+             serial_hds[i] = qemu_chr_open(serial_devices[i]);
+             if (!serial_hds[i]) {
+                 fprintf(stderr, "qemu: could not open serial device '%s'\n", 
+                         serial_devices[i]);
+                 exit(1);
+             }
++            snprintf(buf, sizeof(buf), "/serial/%d", i);
++            store_dev_info(serial_devices[i], domid, serial_hds[i], buf);
++            if (i == 0) /* serial 0 is also called the console */
++                store_dev_info(serial_devices[i], domid,
++                               serial_hds[i], "/console");
+             if (!strcmp(serial_devices[i], "vc"))
+                 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
+         }
+@@ -6365,12 +6456,15 @@
+ 
+     for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
+         if (parallel_devices[i][0] != '\0') {
++            char buf[16];
+             parallel_hds[i] = qemu_chr_open(parallel_devices[i]);
+             if (!parallel_hds[i]) {
+                 fprintf(stderr, "qemu: could not open parallel device 
'%s'\n", 
+                         parallel_devices[i]);
+                 exit(1);
+             }
++            snprintf(buf, sizeof(buf), "/parallel/%d", i);
++            store_dev_info(parallel_devices[i], domid, parallel_hds[i], buf);
+             if (!strcmp(parallel_devices[i], "vc"))
+                 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
+         }
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/tpm-tis-device
--- a/tools/ioemu/patches/tpm-tis-device        Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/tpm-tis-device        Tue May 08 09:09:17 2007 -0600
@@ -22,8 +22,8 @@ Signed-off-by: Stefan Berger <stefanb@us
 
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-12-20 15:21:55.000000000 +0000
-+++ ioemu/Makefile.target      2006-12-20 15:21:55.000000000 +0000
+--- ioemu.orig/Makefile.target 2007-05-03 15:20:44.000000000 +0100
++++ ioemu/Makefile.target      2007-05-03 15:20:44.000000000 +0100
 @@ -369,6 +369,7 @@
  VL_OBJS+= piix4acpi.o
  VL_OBJS+= xenstore.o
@@ -34,8 +34,8 @@ Index: ioemu/Makefile.target
  ifeq ($(TARGET_BASE_ARCH), ppc)
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-12-20 15:21:54.000000000 +0000
-+++ ioemu/hw/pc.c      2006-12-20 15:21:55.000000000 +0000
+--- ioemu.orig/hw/pc.c 2007-05-03 15:20:43.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-03 15:20:44.000000000 +0100
 @@ -877,6 +877,9 @@
          }
      }
@@ -49,8 +49,8 @@ Index: ioemu/hw/tpm_tis.c
 Index: ioemu/hw/tpm_tis.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/hw/tpm_tis.c 2006-12-20 15:21:55.000000000 +0000
-@@ -0,0 +1,1120 @@
++++ ioemu/hw/tpm_tis.c 2007-05-03 15:20:44.000000000 +0100
+@@ -0,0 +1,1128 @@
 +/*
 + * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface
 + *
@@ -570,7 +570,7 @@ Index: ioemu/hw/tpm_tis.c
 +
 +#ifdef DEBUG_TPM
 +    fprintf(logfile," read(%08x) = %08x\n",
-+            addr,
++            (int)addr,
 +            val);
 +#endif
 +
@@ -591,7 +591,7 @@ Index: ioemu/hw/tpm_tis.c
 +
 +#ifdef DEBUG_TPM
 +    fprintf(logfile,"write(%08x) = %08x\n",
-+            addr,
++            (int)addr,
 +            val);
 +#endif
 +
@@ -810,10 +810,11 @@ Index: ioemu/hw/tpm_tis.c
 +static void tpm_save(QEMUFile* f,void* opaque)
 +{
 +    tpmState* s=(tpmState*)opaque;
++    uint8_t locty = s->active_loc;
 +    int c;
 +
 +    /* need to wait for outstanding requests to complete */
-+    if (IS_COMM_WITH_VTPM(s)) {
++    if (s->loc[locty].state == STATE_EXECUTION) {
 +        int repeats = 30; /* 30 seconds; really should be infty */
 +        while (repeats > 0 &&
 +               !(s->loc[s->active_loc].sts & STS_DATA_AVAILABLE)) {
@@ -821,6 +822,8 @@ Index: ioemu/hw/tpm_tis.c
 +            if (n > 0) {
 +                if (IS_VALID_LOC(s->active_loc)) {
 +                    s->loc[s->active_loc].sts = STS_VALID | 
STS_DATA_AVAILABLE;
++                    s->loc[s->active_loc].state = STATE_COMPLETION;
++                    tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);
 +                }
 +                /* close the connection with the vTPM for good */
 +                close_vtpm_channel(s, 1);
@@ -828,6 +831,10 @@ Index: ioemu/hw/tpm_tis.c
 +            }
 +            sleep(1);
 +        }
++    }
++
++    if (IS_COMM_WITH_VTPM(s)) {
++        close_vtpm_channel(s, 1);
 +    }
 +
 +    qemu_put_be32s(f,&s->offset);
@@ -929,6 +936,7 @@ Index: ioemu/hw/tpm_tis.c
 +    s->Transmitlayer = -1;
 +    s->tpmTx.fd[0] = -1;
 +    s->tpmTx.fd[1] = -1;
++    s->aborting_locty = NO_LOCALITY;
 +
 +    tpm_initialize_instance(s, s->vtpm_instance);
 +    memset(s->buffer.buf,0,sizeof(s->buffer.buf));
@@ -1046,7 +1054,7 @@ Index: ioemu/hw/tpm_tis.c
 +        uint32_t size = tpm_get_size_from_buffer(buffer->buf);
 +        if (size + sizeof(buffer->instance) != off) {
 +            fprintf(logfile,"TPM: Packet size is bad! %d != %d\n",
-+                    size + sizeof(buffer->instance),
++                    (int)(size + sizeof(buffer->instance)),
 +                    off);
 +        } else {
 +            uint32_t ret;
@@ -1173,9 +1181,9 @@ Index: ioemu/hw/tpm_tis.c
 +}
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:21:55.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:55.000000000 +0000
-@@ -932,6 +932,10 @@
+--- ioemu.orig/vl.h    2007-05-03 15:20:44.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:20:44.000000000 +0100
+@@ -933,6 +933,10 @@
  void piix4_pm_init(PCIBus *bus, int devfn);
  void acpi_bios_init(void);
  
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/usb-mouse-tablet-status-check
--- a/tools/ioemu/patches/usb-mouse-tablet-status-check Mon May 07 13:24:37 
2007 -0600
+++ b/tools/ioemu/patches/usb-mouse-tablet-status-check Tue May 08 09:09:17 
2007 -0600
@@ -16,10 +16,11 @@ This patch make UHC & USB mouse/tablet b
 
 Signed-off-by: Xinmei Huang <xinmei.huang@xxxxxxxxx>
 
-diff -r fb3cb6f52a29 -r 60bbcf799384 tools/ioemu/hw/usb-hid.c
---- a/tools/ioemu/hw/usb-hid.c Thu Dec 07 11:51:22 2006 +0000
-+++ b/tools/ioemu/hw/usb-hid.c Thu Dec 07 11:52:26 2006 +0000
-@@ -39,6 +39,7 @@ typedef struct USBMouseState {
+Index: ioemu/hw/usb-hid.c
+===================================================================
+--- ioemu.orig/hw/usb-hid.c    2007-05-02 14:21:51.000000000 +0100
++++ ioemu/hw/usb-hid.c 2007-05-02 14:23:54.000000000 +0100
+@@ -39,6 +39,7 @@
      int x, y;
      int kind;
      int mouse_grabbed;
@@ -27,7 +28,7 @@ diff -r fb3cb6f52a29 -r 60bbcf799384 too
  } USBMouseState;
  
  /* mostly the same values as the Bochs USB Mouse device */
-@@ -231,6 +232,7 @@ static void usb_mouse_event(void *opaque
+@@ -231,6 +232,7 @@
      s->dy += dy1;
      s->dz += dz1;
      s->buttons_state = buttons_state;
@@ -35,7 +36,7 @@ diff -r fb3cb6f52a29 -r 60bbcf799384 too
  }
  
  static void usb_tablet_event(void *opaque,
-@@ -242,6 +244,7 @@ static void usb_tablet_event(void *opaqu
+@@ -242,6 +244,7 @@
      s->y = y;
      s->dz += dz;
      s->buttons_state = buttons_state;
@@ -43,7 +44,7 @@ diff -r fb3cb6f52a29 -r 60bbcf799384 too
  }
  
  static inline int int_clamp(int val, int vmin, int vmax)
-@@ -483,10 +486,16 @@ static int usb_mouse_handle_data(USBDevi
+@@ -483,10 +486,16 @@
      switch(pid) {
      case USB_TOKEN_IN:
          if (devep == 1) {
@@ -64,7 +65,7 @@ diff -r fb3cb6f52a29 -r 60bbcf799384 too
          } else {
              goto fail;
          }
-@@ -523,6 +532,7 @@ USBDevice *usb_tablet_init(void)
+@@ -566,6 +575,7 @@
      s->dev.handle_data = usb_mouse_handle_data;
      s->dev.handle_destroy = usb_mouse_handle_destroy;
      s->kind = USB_TABLET;
@@ -72,7 +73,7 @@ diff -r fb3cb6f52a29 -r 60bbcf799384 too
  
      pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
  
-@@ -544,6 +554,7 @@ USBDevice *usb_mouse_init(void)
+@@ -589,6 +599,7 @@
      s->dev.handle_data = usb_mouse_handle_data;
      s->dev.handle_destroy = usb_mouse_handle_destroy;
      s->kind = USB_MOUSE;
@@ -80,27 +81,45 @@ diff -r fb3cb6f52a29 -r 60bbcf799384 too
  
      pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
  
-diff -r fb3cb6f52a29 -r 60bbcf799384 tools/ioemu/hw/usb-uhci.c
---- a/tools/ioemu/hw/usb-uhci.c        Thu Dec 07 11:51:22 2006 +0000
-+++ b/tools/ioemu/hw/usb-uhci.c        Thu Dec 07 11:52:26 2006 +0000
-@@ -424,12 +424,10 @@ static int uhci_handle_td(UHCIState *s, 
+Index: ioemu/hw/usb-uhci.c
+===================================================================
+--- ioemu.orig/hw/usb-uhci.c   2007-05-02 14:23:54.000000000 +0100
++++ ioemu/hw/usb-uhci.c        2007-05-02 14:23:54.000000000 +0100
+@@ -43,9 +43,15 @@
+ #define TD_CTRL_IOC     (1 << 24)
+ #define TD_CTRL_ACTIVE  (1 << 23)
+ #define TD_CTRL_STALL   (1 << 22)
++#define TD_CTRL_BUFFER  (1 << 21)
+ #define TD_CTRL_BABBLE  (1 << 20)
+ #define TD_CTRL_NAK     (1 << 19)
+ #define TD_CTRL_TIMEOUT (1 << 18)
++#define TD_CTRL_BITSTUFF                                 \
++                        (1 << 17)
++#define TD_CTRL_MASK                                     \
++    (TD_CTRL_BITSTUFF | TD_CTRL_TIMEOUT | TD_CTRL_NAK    \
++     | TD_CTRL_BABBLE | TD_CTRL_BUFFER | TD_CTRL_STALL)
+ 
+ #define UHCI_PORT_RESET (1 << 9)
+ #define UHCI_PORT_LSDA  (1 << 8)
+@@ -424,12 +430,12 @@
      uint8_t buf[2048];
      int len, max_len, err, ret;
  
 -    if (td->ctrl & TD_CTRL_IOC) {
 -        *int_mask |= 0x01;
--    }
++    if (!(td->ctrl & TD_CTRL_ACTIVE)){
++        ret = 1;
++        goto out;
+     }
 -    
 -    if (!(td->ctrl & TD_CTRL_ACTIVE))
 -        return 1;
-+    if (!(td->ctrl & TD_CTRL_ACTIVE)){
-+        ret = 1;
-+        goto out;
-+    }
++    /* Clear TD's status field explicitly */
++    td->ctrl = td->ctrl & (~TD_CTRL_MASK);
  
      /* TD is active */
      max_len = ((td->token >> 21) + 1) & 0x7ff;
-@@ -467,7 +465,8 @@ static int uhci_handle_td(UHCIState *s, 
+@@ -467,7 +473,8 @@
          /* invalid pid : frame interrupted */
          s->status |= UHCI_STS_HCPERR;
          uhci_update_irq(s);
@@ -110,7 +129,7 @@ diff -r fb3cb6f52a29 -r 60bbcf799384 too
      }
      if (td->ctrl & TD_CTRL_IOS)
          td->ctrl &= ~TD_CTRL_ACTIVE;
-@@ -479,10 +478,12 @@ static int uhci_handle_td(UHCIState *s, 
+@@ -479,10 +486,12 @@
              len < max_len) {
              *int_mask |= 0x02;
              /* short packet: do not update QH */
@@ -125,7 +144,7 @@ diff -r fb3cb6f52a29 -r 60bbcf799384 too
          }
      } else {
          switch(ret) {
-@@ -501,23 +502,34 @@ static int uhci_handle_td(UHCIState *s, 
+@@ -501,23 +510,34 @@
              }
              td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) | 
                  (err << TD_CTRL_ERROR_SHIFT);
@@ -150,12 +169,10 @@ diff -r fb3cb6f52a29 -r 60bbcf799384 too
              td->ctrl &= ~TD_CTRL_ACTIVE;
              /* frame interrupted */
 -            return -1;
--        }
--    }
 +            ret = -1;
 +            goto out;
-+        }
-+    }
+         }
+     }
 +   
 +out:
 +    /* If TD is inactive and IOC bit set to 1 then update int_mask */ 
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/vnc-altgr-keysym
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/vnc-altgr-keysym      Tue May 08 09:09:17 2007 -0600
@@ -0,0 +1,24 @@
+Index: ioemu/keymaps/modifiers
+===================================================================
+--- ioemu.orig/keymaps/modifiers       2007-05-02 10:30:05.000000000 +0100
++++ ioemu/keymaps/modifiers    2007-05-03 15:02:56.000000000 +0100
+@@ -3,6 +3,7 @@
+ 
+ Alt_R 0xb8
+ Mode_switch 0xb8
++ISO_Level3_Switch 0xb8
+ Alt_L 0x38
+ 
+ Control_R 0x9d
+Index: ioemu/vnc_keysym.h
+===================================================================
+--- ioemu.orig/vnc_keysym.h    2007-05-03 15:02:10.000000000 +0100
++++ ioemu/vnc_keysym.h 2007-05-03 15:03:03.000000000 +0100
+@@ -215,6 +215,7 @@
+ {"Shift_R", 0xffe2},   /* XK_Shift_R */
+ {"Super_L", 0xffeb},   /* XK_Super_L */
+ {"Super_R", 0xffec},   /* XK_Super_R */
++{"ISO_Level3_Shift", 0xfe03}, /* XK_ISO_Level3_Shift */
+ 
+     /* special keys */
+ {"BackSpace", 0xff08}, /* XK_BackSpace */
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/vnc-backoff-screen-scan
--- a/tools/ioemu/patches/vnc-backoff-screen-scan       Mon May 07 13:24:37 
2007 -0600
+++ b/tools/ioemu/patches/vnc-backoff-screen-scan       Tue May 08 09:09:17 
2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-12-06 23:46:12.000000000 +0000
-+++ ioemu/vnc.c        2006-12-06 23:46:12.000000000 +0000
+--- ioemu.orig/vnc.c   2007-05-03 10:07:56.000000000 +0100
++++ ioemu/vnc.c        2007-05-03 10:07:56.000000000 +0100
 @@ -28,7 +28,19 @@
  #include "qemu_socket.h"
  #include <assert.h>
@@ -356,9 +356,9 @@ Index: ioemu/vnc.c
      case 6:
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-06 23:46:12.000000000 +0000
-+++ ioemu/vl.c 2006-12-06 23:46:12.000000000 +0000
-@@ -726,6 +726,12 @@
+--- ioemu.orig/vl.c    2007-05-03 10:07:56.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:07:56.000000000 +0100
+@@ -725,6 +725,12 @@
      }
  }
  
@@ -373,8 +373,8 @@ Index: ioemu/vl.c
  void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-06 23:46:12.000000000 +0000
-+++ ioemu/vl.h 2006-12-06 23:46:12.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 10:07:56.000000000 +0100
++++ ioemu/vl.h 2007-05-03 10:07:56.000000000 +0100
 @@ -407,6 +407,7 @@
  void qemu_free_timer(QEMUTimer *ts);
  void qemu_del_timer(QEMUTimer *ts);
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/vnc-cleanup
--- a/tools/ioemu/patches/vnc-cleanup   Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/vnc-cleanup   Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-09-21 18:54:22.000000000 +0100
-+++ ioemu/vnc.c        2006-09-21 19:05:39.000000000 +0100
+--- ioemu.orig/vnc.c   2007-05-03 09:56:31.000000000 +0100
++++ ioemu/vnc.c        2007-05-03 10:07:55.000000000 +0100
 @@ -143,13 +143,16 @@
  static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
  {
@@ -90,9 +90,9 @@ Index: ioemu/vnc.c
  static void set_encodings(VncState *vs, int32_t *encodings, size_t 
n_encodings)
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-09-21 18:55:38.000000000 +0100
-+++ ioemu/vl.c 2006-09-21 19:00:48.000000000 +0100
-@@ -5120,10 +5120,10 @@
+--- ioemu.orig/vl.c    2007-05-03 10:07:54.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:07:55.000000000 +0100
+@@ -5195,10 +5195,10 @@
          /* XXX: better handling of removal */
          for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
              ioh_next = ioh->next;
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/vnc-display-find-unused
--- a/tools/ioemu/patches/vnc-display-find-unused       Mon May 07 13:24:37 
2007 -0600
+++ b/tools/ioemu/patches/vnc-display-find-unused       Tue May 08 09:09:17 
2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-12-20 15:21:52.000000000 +0000
-+++ ioemu/vnc.c        2006-12-20 15:21:52.000000000 +0000
+--- ioemu.orig/vnc.c   2007-05-03 10:24:06.000000000 +0100
++++ ioemu/vnc.c        2007-05-03 10:24:06.000000000 +0100
 @@ -1197,7 +1197,7 @@
      }
  }
@@ -50,9 +50,9 @@ Index: ioemu/vnc.c
  int vnc_start_viewer(int port)
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:21:51.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:52.000000000 +0000
-@@ -121,6 +121,7 @@
+--- ioemu.orig/vl.c    2007-05-03 10:24:06.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:24:06.000000000 +0100
+@@ -122,6 +122,7 @@
  static DisplayState display_state;
  int nographic;
  int vncviewer;
@@ -60,23 +60,23 @@ Index: ioemu/vl.c
  const char* keyboard_layout = NULL;
  int64_t ticks_per_sec;
  int boot_device = 'c';
-@@ -5342,6 +5343,7 @@
+@@ -5417,6 +5418,7 @@
             "-loadvm file    start right away with a saved state (loadvm in 
monitor)\n"
           "-vnc display    start a VNC server on display\n"
             "-vncviewer      start a vncviewer process for this domain\n"
 +           "-vncunused      bind the VNC server to an unused port\n"
-            "-timeoffset     time offset (in seconds) from local time\n"
             "-acpi           disable or enable ACPI of HVM domain \n"
             "\n"
-@@ -5431,6 +5433,7 @@
-     QEMU_OPTION_timeoffset,
+            "During emulation, the following keys are useful:\n"
+@@ -5504,6 +5506,7 @@
+     QEMU_OPTION_vcpus,
      QEMU_OPTION_acpi,
      QEMU_OPTION_vncviewer,
 +    QEMU_OPTION_vncunused,
  };
  
  typedef struct QEMUOption {
-@@ -5506,6 +5509,7 @@
+@@ -5579,6 +5582,7 @@
      { "smp", HAS_ARG, QEMU_OPTION_smp },
      { "vnc", HAS_ARG, QEMU_OPTION_vnc },
      { "vncviewer", 0, QEMU_OPTION_vncviewer },
@@ -84,7 +84,7 @@ Index: ioemu/vl.c
      
      /* temporary options */
      { "usb", 0, QEMU_OPTION_usb },
-@@ -5857,6 +5861,7 @@
+@@ -5938,6 +5942,7 @@
      snapshot = 0;
      nographic = 0;
      vncviewer = 0;
@@ -92,7 +92,7 @@ Index: ioemu/vl.c
      kernel_filename = NULL;
      kernel_cmdline = "";
  #ifdef TARGET_PPC
-@@ -6254,6 +6259,11 @@
+@@ -6336,6 +6341,11 @@
              case QEMU_OPTION_vncviewer:
                  vncviewer++;
                  break;
@@ -104,7 +104,7 @@ Index: ioemu/vl.c
              }
          }
      }
-@@ -6460,7 +6470,7 @@
+@@ -6537,7 +6547,7 @@
      if (nographic) {
          dumb_display_init(ds);
      } else if (vnc_display != -1) {
@@ -115,8 +115,8 @@ Index: ioemu/vl.c
      } else {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:21:51.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:52.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 10:24:06.000000000 +0100
++++ ioemu/vl.h 2007-05-03 10:24:06.000000000 +0100
 @@ -785,7 +785,7 @@
  void cocoa_display_init(DisplayState *ds, int full_screen);
  
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/vnc-fix-signedness
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/vnc-fix-signedness    Tue May 08 09:09:17 2007 -0600
@@ -0,0 +1,222 @@
+# HG changeset patch
+# User kaf24@xxxxxxxxxxxxxxxxxxxxx
+# Date 1167325891 0
+# Node ID ede2f5280810789c3cb37603cf2e6b34c60982b1
+# Parent  a138fabc2120376cfb4bf72596a334a1edf8adb0
+[QEMU] Fix a number of signedness issues plus a typo in the version checking 
in vnc.c.
+Signed-off-by:  Anthony Liguori <aliguori@xxxxxxxxxx>
+
+Index: ioemu/vnc.c
+===================================================================
+--- ioemu.orig/vnc.c   2007-05-02 14:03:41.000000000 +0100
++++ ioemu/vnc.c        2007-05-02 14:03:42.000000000 +0100
+@@ -54,12 +54,12 @@
+ {
+     size_t capacity;
+     size_t offset;
+-    char *buffer;
++    uint8_t *buffer;
+ } Buffer;
+ 
+ typedef struct VncState VncState;
+ 
+-typedef int VncReadEvent(VncState *vs, char *data, size_t len);
++typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
+ 
+ typedef void VncWritePixels(VncState *vs, void *data, int size);
+ 
+@@ -90,7 +90,7 @@
+     uint64_t *update_row;     /* outstanding updates */
+     int has_update;           /* there's outstanding updates in the
+                                * visible area */
+-    char *old_data;
++    uint8_t *old_data;
+     int depth; /* internal VNC frame buffer byte per pixel */
+     int has_resize;
+     int has_hextile;
+@@ -140,7 +140,7 @@
+ static void vnc_update_client(void *opaque);
+ static void vnc_client_read(void *opaque);
+ static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h);
+-static int make_challenge(char *random, int size);
++static int make_challenge(unsigned char *random, int size);
+ static void set_seed(unsigned int *seedp);
+ static void get_random(int len, unsigned char *buf);
+ 
+@@ -330,7 +330,7 @@
+ static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, 
int h)
+ {
+     int i;
+-    char *row;
++    uint8_t *row;
+ 
+     vnc_framebuffer_update(vs, x, y, w, h, 0);
+ 
+@@ -394,9 +394,9 @@
+ static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int 
dst_y, int w, int h)
+ {
+     int src, dst;
+-    char *src_row;
+-    char *dst_row;
+-    char *old_row;
++    uint8_t *src_row;
++    uint8_t *dst_row;
++    uint8_t *old_row;
+     int y = 0;
+     int pitch = ds->linesize;
+     VncState *vs = ds->opaque;
+@@ -465,8 +465,8 @@
+     VncState *vs = opaque;
+     int64_t now;
+     int y;
+-    char *row;
+-    char *old_row;
++    uint8_t *row;
++    uint8_t *old_row;
+     uint64_t width_mask;
+     int n_rectangles;
+     int saved_offset;
+@@ -491,7 +491,7 @@
+     for (y = 0; y < vs->ds->height; y++) {
+       if (vs->dirty_row[y] & width_mask) {
+           int x;
+-          char *ptr, *old_ptr;
++          uint8_t *ptr, *old_ptr;
+ 
+           ptr = row;
+           old_ptr = old_row;
+@@ -654,7 +654,7 @@
+     return buffer->offset == 0;
+ }
+ 
+-static char *buffer_end(Buffer *buffer)
++static uint8_t *buffer_end(Buffer *buffer)
+ {
+     return buffer->buffer + buffer->offset;
+ }
+@@ -778,7 +778,7 @@
+ 
+ static void vnc_write_u16(VncState *vs, uint16_t value)
+ {
+-    char buf[2];
++    uint8_t buf[2];
+ 
+     buf[0] = (value >> 8) & 0xFF;
+     buf[1] = value & 0xFF;
+@@ -788,7 +788,7 @@
+ 
+ static void vnc_write_u8(VncState *vs, uint8_t value)
+ {
+-    vnc_write(vs, (char *)&value, 1);
++    vnc_write(vs, &value, 1);
+ }
+ 
+ static void vnc_flush(VncState *vs)
+@@ -797,23 +797,23 @@
+       vnc_client_write(vs);
+ }
+ 
+-static uint8_t read_u8(char *data, size_t offset)
++static uint8_t read_u8(uint8_t *data, size_t offset)
+ {
+     return data[offset];
+ }
+ 
+-static uint16_t read_u16(char *data, size_t offset)
++static uint16_t read_u16(uint8_t *data, size_t offset)
+ {
+     return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
+ }
+ 
+-static int32_t read_s32(char *data, size_t offset)
++static int32_t read_s32(uint8_t *data, size_t offset)
+ {
+     return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
+                    (data[offset + 2] << 8) | data[offset + 3]);
+ }
+ 
+-static uint32_t read_u32(char *data, size_t offset)
++static uint32_t read_u32(uint8_t *data, size_t offset)
+ {
+     return ((data[offset] << 24) | (data[offset + 1] << 16) |
+           (data[offset + 2] << 8) | data[offset + 3]);
+@@ -1115,11 +1115,10 @@
+     vga_hw_update();
+ }
+ 
+-static int protocol_client_msg(VncState *vs, char *data, size_t len)
++static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
+ {
+     int i;
+     uint16_t limit;
+-    int64_t now;
+ 
+     switch (data[0]) {
+     case 0:
+@@ -1188,7 +1187,7 @@
+               return 8 + v;
+       }
+ 
+-      client_cut_text(vs, read_u32(data, 4), data + 8);
++      client_cut_text(vs, read_u32(data, 4), (char *)(data + 8));
+       break;
+     default:
+       printf("Msg: %d\n", data[0]);
+@@ -1200,7 +1199,7 @@
+     return 0;
+ }
+ 
+-static int protocol_client_init(VncState *vs, char *data, size_t len)
++static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
+ {
+     size_t l;
+     char pad[3] = { 0, 0, 0 };
+@@ -1261,7 +1260,7 @@
+     return 0;
+ }
+ 
+-static int protocol_response(VncState *vs, char *client_response, size_t len)
++static int protocol_response(VncState *vs, uint8_t *client_response, size_t 
len)
+ {
+     extern char vncpasswd[64];
+     extern unsigned char challenge[AUTHCHALLENGESIZE];
+@@ -1299,7 +1298,7 @@
+     return 0;
+ }
+ 
+-static int protocol_version(VncState *vs, char *version, size_t len)
++static int protocol_version(VncState *vs, uint8_t *version, size_t len)
+ {
+     extern char vncpasswd[64];
+     extern unsigned char challenge[AUTHCHALLENGESIZE];
+@@ -1474,7 +1473,7 @@
+ 
+ unsigned int seed;
+ 
+-static int make_challenge(char *random, int size)
++static int make_challenge(unsigned char *random, int size)
+ {
+  
+     set_seed(&seed);
+Index: ioemu/vnchextile.h
+===================================================================
+--- ioemu.orig/vnchextile.h    2007-05-02 14:03:13.000000000 +0100
++++ ioemu/vnchextile.h 2007-05-02 14:03:42.000000000 +0100
+@@ -13,7 +13,7 @@
+                                              uint32_t *last_fg32,
+                                              int *has_bg, int *has_fg)
+ {
+-    char *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
++    uint8_t *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
+     pixel_t *irow = (pixel_t *)row;
+     int j, i;
+     pixel_t *last_bg = (pixel_t *)last_bg32;
+@@ -119,7 +119,7 @@
+       for (j = 0; j < h; j++) {
+           int has_color = 0;
+           int min_x = -1;
+-          pixel_t color;
++          pixel_t color = 0;
+ 
+           for (i = 0; i < w; i++) {
+               if (!has_color) {
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/vnc-fix-version-check
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/vnc-fix-version-check Tue May 08 09:09:17 2007 -0600
@@ -0,0 +1,13 @@
+Index: ioemu/vnc.c
+===================================================================
+--- ioemu.orig/vnc.c   2007-05-02 10:47:41.000000000 +0100
++++ ioemu/vnc.c        2007-05-02 10:47:42.000000000 +0100
+@@ -1317,7 +1317,7 @@
+ 
+ 
+     support = 0;
+-    if (maj = 3) {
++    if (maj == 3) {
+       if (min == 3 || min ==4) {
+           support = 1;
+       }
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/vnc-fixes
--- a/tools/ioemu/patches/vnc-fixes     Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/vnc-fixes     Tue May 08 09:09:17 2007 -0600
@@ -1,8 +1,8 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:21:51.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:51.000000000 +0000
-@@ -6511,8 +6511,10 @@
+--- ioemu.orig/vl.c    2007-05-03 10:24:05.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:24:05.000000000 +0100
+@@ -6597,8 +6597,10 @@
          }
      }
  
@@ -17,8 +17,8 @@ Index: ioemu/vl.c
      if (use_gdbstub) {
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-12-20 15:21:51.000000000 +0000
-+++ ioemu/vnc.c        2006-12-20 15:21:51.000000000 +0000
+--- ioemu.orig/vnc.c   2007-05-03 10:24:05.000000000 +0100
++++ ioemu/vnc.c        2007-05-03 10:24:05.000000000 +0100
 @@ -3,6 +3,7 @@
   * 
   * Copyright (C) 2006 Anthony Liguori <anthony@xxxxxxxxxxxxx>
@@ -531,8 +531,8 @@ Index: ioemu/vnc.c
  }
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:21:51.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:51.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 10:24:05.000000000 +0100
++++ ioemu/vl.h 2007-05-03 10:24:05.000000000 +0100
 @@ -319,6 +319,7 @@
  int is_graphic_console(void);
  CharDriverState *text_console_init(DisplayState *ds);
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/vnc-listen-specific-interface
--- a/tools/ioemu/patches/vnc-listen-specific-interface Mon May 07 13:24:37 
2007 -0600
+++ b/tools/ioemu/patches/vnc-listen-specific-interface Tue May 08 09:09:17 
2007 -0600
@@ -20,9 +20,9 @@ Signed-off-by:  Daniel P. Berrange <berr
 
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:21:52.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:52.000000000 +0000
-@@ -122,6 +122,7 @@
+--- ioemu.orig/vl.c    2007-05-03 10:24:06.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:24:06.000000000 +0100
+@@ -123,6 +123,7 @@
  int nographic;
  int vncviewer;
  int vncunused;
@@ -30,7 +30,7 @@ Index: ioemu/vl.c
  const char* keyboard_layout = NULL;
  int64_t ticks_per_sec;
  int boot_device = 'c';
-@@ -2777,10 +2778,22 @@
+@@ -2831,10 +2832,22 @@
      return -1;
  }
  
@@ -54,7 +54,7 @@ Index: ioemu/vl.c
      const char *p, *r;
      int port;
  
-@@ -2791,14 +2804,8 @@
+@@ -2845,14 +2858,8 @@
      if (buf[0] == '\0') {
          saddr->sin_addr.s_addr = 0;
      } else {
@@ -71,15 +71,15 @@ Index: ioemu/vl.c
      }
      port = strtol(p, (char **)&r, 0);
      if (r == p)
-@@ -5344,6 +5351,7 @@
+@@ -5419,6 +5426,7 @@
           "-vnc display    start a VNC server on display\n"
             "-vncviewer      start a vncviewer process for this domain\n"
             "-vncunused      bind the VNC server to an unused port\n"
 +           "-vnclisten      bind the VNC server to this address\n"
-            "-timeoffset     time offset (in seconds) from local time\n"
             "-acpi           disable or enable ACPI of HVM domain \n"
             "\n"
-@@ -5434,6 +5442,7 @@
+            "During emulation, the following keys are useful:\n"
+@@ -5507,6 +5515,7 @@
      QEMU_OPTION_acpi,
      QEMU_OPTION_vncviewer,
      QEMU_OPTION_vncunused,
@@ -87,7 +87,7 @@ Index: ioemu/vl.c
  };
  
  typedef struct QEMUOption {
-@@ -5510,6 +5519,7 @@
+@@ -5583,6 +5592,7 @@
      { "vnc", HAS_ARG, QEMU_OPTION_vnc },
      { "vncviewer", 0, QEMU_OPTION_vncviewer },
      { "vncunused", 0, QEMU_OPTION_vncunused },
@@ -95,7 +95,7 @@ Index: ioemu/vl.c
      
      /* temporary options */
      { "usb", 0, QEMU_OPTION_usb },
-@@ -5889,6 +5899,8 @@
+@@ -5974,6 +5984,8 @@
  
      nb_nics = 0;
      /* default mac address of the first network interface */
@@ -104,7 +104,7 @@ Index: ioemu/vl.c
      
      /* init debug */
      sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%ld.log", 
(long)getpid());
-@@ -6264,6 +6276,9 @@
+@@ -6346,6 +6358,9 @@
                  if (vnc_display == -1)
                      vnc_display = 0;
                  break;
@@ -114,7 +114,7 @@ Index: ioemu/vl.c
              }
          }
      }
-@@ -6470,7 +6485,7 @@
+@@ -6547,7 +6562,7 @@
      if (nographic) {
          dumb_display_init(ds);
      } else if (vnc_display != -1) {
@@ -125,8 +125,8 @@ Index: ioemu/vl.c
      } else {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:21:52.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:52.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 10:24:06.000000000 +0100
++++ ioemu/vl.h 2007-05-03 10:24:06.000000000 +0100
 @@ -37,6 +37,8 @@
  #include <unistd.h>
  #include <fcntl.h>
@@ -147,8 +147,8 @@ Index: ioemu/vl.h
  /* ide.c */
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-12-20 15:21:52.000000000 +0000
-+++ ioemu/vnc.c        2006-12-20 15:21:52.000000000 +0000
+--- ioemu.orig/vnc.c   2007-05-03 10:24:06.000000000 +0100
++++ ioemu/vnc.c        2007-05-03 10:24:06.000000000 +0100
 @@ -1197,9 +1197,8 @@
      }
  }
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/vnc-password
--- a/tools/ioemu/patches/vnc-password  Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/vnc-password  Tue May 08 09:09:17 2007 -0600
@@ -17,8 +17,8 @@ Signed-off-by: Masami Watanabe <masami.w
 
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-12-20 15:21:55.000000000 +0000
-+++ ioemu/Makefile.target      2006-12-20 15:21:55.000000000 +0000
+--- ioemu.orig/Makefile.target 2007-05-03 15:23:43.000000000 +0100
++++ ioemu/Makefile.target      2007-05-03 15:23:43.000000000 +0100
 @@ -407,6 +407,7 @@
  VL_OBJS+=sdl.o
  endif
@@ -39,9 +39,9 @@ Index: ioemu/Makefile.target
  
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:21:54.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:55.000000000 +0000
-@@ -171,6 +171,9 @@
+--- ioemu.orig/vl.c    2007-05-03 15:23:43.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:23:43.000000000 +0100
+@@ -172,6 +172,9 @@
  char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
  extern int domid;
  
@@ -51,7 +51,7 @@ Index: ioemu/vl.c
  /***********************************************************/
  /* x86 ISA bus support */
  
-@@ -5895,6 +5898,7 @@
+@@ -5982,6 +5985,7 @@
      vncunused = 0;
      kernel_filename = NULL;
      kernel_cmdline = "";
@@ -59,7 +59,7 @@ Index: ioemu/vl.c
  #ifndef CONFIG_DM
  #ifdef TARGET_PPC
      cdrom_index = 1;
-@@ -6535,6 +6539,10 @@
+@@ -6627,6 +6631,10 @@
  
      init_ioports();
  
@@ -72,17 +72,17 @@ Index: ioemu/vl.c
          dumb_display_init(ds);
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:21:54.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:55.000000000 +0000
-@@ -1214,6 +1214,7 @@
+--- ioemu.orig/vl.h    2007-05-03 15:23:43.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:23:43.000000000 +0100
+@@ -1215,6 +1215,7 @@
  void xenstore_process_event(void *opaque);
  void xenstore_check_new_media_present(int timeout);
  void xenstore_write_vncport(int vnc_display);
 +int xenstore_read_vncpasswd(int domid);
  
- /* xen_platform.c */
- void pci_xen_platform_init(PCIBus *bus);
-@@ -1225,4 +1226,7 @@
+ int xenstore_vm_write(int domid, char *key, char *val);
+ char *xenstore_vm_read(int domid, char *key, int *len);
+@@ -1233,4 +1234,7 @@
  
  void destroy_hvm_domain(void);
  
@@ -92,8 +92,8 @@ Index: ioemu/vl.h
  #endif /* VL_H */
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-12-20 15:21:52.000000000 +0000
-+++ ioemu/vnc.c        2006-12-20 15:21:55.000000000 +0000
+--- ioemu.orig/vnc.c   2007-05-03 15:22:57.000000000 +0100
++++ ioemu/vnc.c        2007-05-03 15:23:43.000000000 +0100
 @@ -44,6 +44,7 @@
  
  #include "vnc_keysym.h"
@@ -209,7 +209,7 @@ Index: ioemu/vnc.c
  
      return 0;
  }
-@@ -1344,3 +1417,32 @@
+@@ -1350,3 +1423,32 @@
        return pid;
      }
  }
@@ -244,13 +244,12 @@ Index: ioemu/vnc.c
 +}
 Index: ioemu/xenstore.c
 ===================================================================
---- ioemu.orig/xenstore.c      2006-12-20 15:21:54.000000000 +0000
-+++ ioemu/xenstore.c   2006-12-20 15:21:55.000000000 +0000
-@@ -213,3 +213,54 @@
-     free(portstr);
+--- ioemu.orig/xenstore.c      2007-05-03 15:23:43.000000000 +0100
++++ ioemu/xenstore.c   2007-05-03 15:24:09.000000000 +0100
+@@ -253,6 +253,57 @@
      free(buf);
  }
-+
+ 
 +int xenstore_read_vncpasswd(int domid)
 +{
 +    extern char vncpasswd[64];
@@ -258,41 +257,41 @@ Index: ioemu/xenstore.c
 +    unsigned int i, len, rc = 0;
 +
 +    if (xsh == NULL) {
-+      return -1;
++        return -1;
 +    }
 +
 +    path = xs_get_domain_path(xsh, domid);
 +    if (path == NULL) {
-+      fprintf(logfile, "xs_get_domain_path() error. domid %d.\n", domid);
-+      return -1;
++        fprintf(logfile, "xs_get_domain_path() error. domid %d.\n", domid);
++        return -1;
 +    }
 +
 +    pasprintf(&buf, "%s/vm", path);
 +    uuid = xs_read(xsh, XBT_NULL, buf, &len);
 +    if (uuid == NULL) {
-+      fprintf(logfile, "xs_read(): uuid get error. %s.\n", buf);
-+      free(path);
-+      return -1;
++        fprintf(logfile, "xs_read(): uuid get error. %s.\n", buf);
++        free(path);
++        return -1;
 +    }
 +
 +    pasprintf(&buf, "%s/vncpasswd", uuid);
 +    passwd = xs_read(xsh, XBT_NULL, buf, &len);
 +    if (passwd == NULL) {
-+      fprintf(logfile, "xs_read(): vncpasswd get error. %s.\n", buf);
-+      free(uuid);
-+      free(path);
-+      return rc;
++        fprintf(logfile, "xs_read(): vncpasswd get error. %s.\n", buf);
++        free(uuid);
++        free(path);
++        return rc;
 +    }
 +
 +    for (i=0; i<len && i<63; i++) {
-+      vncpasswd[i] = passwd[i];
-+      passwd[i] = '\0';
++        vncpasswd[i] = passwd[i];
++        passwd[i] = '\0';
 +    }
 +    vncpasswd[len] = '\0';
 +    pasprintf(&buf, "%s/vncpasswd", uuid);
 +    if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) {
-+      fprintf(logfile, "xs_write() vncpasswd failed.\n");
-+      rc = -1;
++        fprintf(logfile, "xs_write() vncpasswd failed.\n");
++        rc = -1;
 +    }
 +
 +    free(passwd);
@@ -301,10 +300,14 @@ Index: ioemu/xenstore.c
 +
 +    return rc;
 +}
++
+ char *xenstore_vm_read(int domid, char *key, int *len)
+ {
+     char *buf = NULL, *path = NULL, *value = NULL;
 Index: ioemu/d3des.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/d3des.c      2006-12-20 15:21:55.000000000 +0000
++++ ioemu/d3des.c      2007-05-03 15:23:43.000000000 +0100
 @@ -0,0 +1,434 @@
 +/*
 + * This is D3DES (V5.09) by Richard Outerbridge with the double and
@@ -743,7 +746,7 @@ Index: ioemu/d3des.h
 Index: ioemu/d3des.h
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/d3des.h      2006-12-20 15:21:55.000000000 +0000
++++ ioemu/d3des.h      2007-05-03 15:23:43.000000000 +0100
 @@ -0,0 +1,51 @@
 +/*
 + * This is D3DES (V5.09) by Richard Outerbridge with the double and
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/vnc-start-vncviewer
--- a/tools/ioemu/patches/vnc-start-vncviewer   Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/vnc-start-vncviewer   Tue May 08 09:09:17 2007 -0600
@@ -1,15 +1,15 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-12-20 15:21:51.000000000 +0000
-+++ ioemu/vnc.c        2006-12-20 15:21:51.000000000 +0000
-@@ -1189,3 +1189,25 @@
+--- ioemu.orig/vnc.c   2007-05-03 10:24:06.000000000 +0100
++++ ioemu/vnc.c        2007-05-03 10:24:06.000000000 +0100
+@@ -1189,3 +1189,31 @@
  
      vnc_dpy_resize(vs->ds, 640, 400);
  }
 +
 +int vnc_start_viewer(int port)
 +{
-+    int pid;
++    int pid, i, open_max;
 +    char s[16];
 +
 +    sprintf(s, ":%d", port);
@@ -20,6 +20,12 @@ Index: ioemu/vnc.c
 +      exit(1);
 +
 +    case 0:   /* child */
++      open_max = sysconf(_SC_OPEN_MAX);
++      for (i = 0; i < open_max; i++)
++          if (i != STDIN_FILENO &&
++              i != STDOUT_FILENO &&
++              i != STDERR_FILENO)
++              close(i);
 +      execlp("vncviewer", "vncviewer", s, NULL);
 +      fprintf(stderr, "vncviewer execlp failed\n");
 +      exit(1);
@@ -30,9 +36,9 @@ Index: ioemu/vnc.c
 +}
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:21:51.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:51.000000000 +0000
-@@ -120,6 +120,7 @@
+--- ioemu.orig/vl.c    2007-05-03 10:24:05.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:24:06.000000000 +0100
+@@ -121,6 +121,7 @@
  int bios_size;
  static DisplayState display_state;
  int nographic;
@@ -40,23 +46,23 @@ Index: ioemu/vl.c
  const char* keyboard_layout = NULL;
  int64_t ticks_per_sec;
  int boot_device = 'c';
-@@ -5340,6 +5341,7 @@
+@@ -5415,6 +5416,7 @@
  #endif
             "-loadvm file    start right away with a saved state (loadvm in 
monitor)\n"
           "-vnc display    start a VNC server on display\n"
 +           "-vncviewer      start a vncviewer process for this domain\n"
-            "-timeoffset     time offset (in seconds) from local time\n"
             "-acpi           disable or enable ACPI of HVM domain \n"
             "\n"
-@@ -5428,6 +5430,7 @@
+            "During emulation, the following keys are useful:\n"
+@@ -5501,6 +5503,7 @@
+     QEMU_OPTION_d,
      QEMU_OPTION_vcpus,
-     QEMU_OPTION_timeoffset,
      QEMU_OPTION_acpi,
 +    QEMU_OPTION_vncviewer,
  };
  
  typedef struct QEMUOption {
-@@ -5502,6 +5505,7 @@
+@@ -5575,6 +5578,7 @@
      { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
      { "smp", HAS_ARG, QEMU_OPTION_smp },
      { "vnc", HAS_ARG, QEMU_OPTION_vnc },
@@ -64,7 +70,7 @@ Index: ioemu/vl.c
      
      /* temporary options */
      { "usb", 0, QEMU_OPTION_usb },
-@@ -5852,6 +5856,7 @@
+@@ -5933,6 +5937,7 @@
  #endif
      snapshot = 0;
      nographic = 0;
@@ -72,7 +78,7 @@ Index: ioemu/vl.c
      kernel_filename = NULL;
      kernel_cmdline = "";
  #ifdef TARGET_PPC
-@@ -6246,6 +6251,9 @@
+@@ -6328,6 +6333,9 @@
              case QEMU_OPTION_acpi:
                  acpi_enabled = 1;
                  break;
@@ -82,7 +88,7 @@ Index: ioemu/vl.c
              }
          }
      }
-@@ -6453,6 +6461,8 @@
+@@ -6530,6 +6538,8 @@
          dumb_display_init(ds);
      } else if (vnc_display != -1) {
        vnc_display_init(ds, vnc_display);
@@ -93,8 +99,8 @@ Index: ioemu/vl.c
          sdl_display_init(ds, full_screen);
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:21:51.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:51.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 10:24:05.000000000 +0100
++++ ioemu/vl.h 2007-05-03 10:24:06.000000000 +0100
 @@ -786,6 +786,7 @@
  
  /* vnc.c */
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/xen-build
--- a/tools/ioemu/patches/xen-build     Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/xen-build     Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/Makefile
 Index: ioemu/Makefile
 ===================================================================
---- ioemu.orig/Makefile        2006-12-08 01:26:04.000000000 +0000
-+++ ioemu/Makefile     2006-12-08 01:26:06.000000000 +0000
+--- ioemu.orig/Makefile        2007-05-03 15:38:37.000000000 +0100
++++ ioemu/Makefile     2007-05-03 15:38:39.000000000 +0100
 @@ -1,11 +1,14 @@
  # Makefile for QEMU.
  
@@ -41,7 +41,17 @@ Index: ioemu/Makefile
          done
  
  distclean: clean
-@@ -68,12 +73,12 @@
+@@ -60,24 +65,24 @@
+ 
+ install-doc: $(DOCS)
+       mkdir -p "$(DESTDIR)$(docdir)"
+-      $(INSTALL) -m 644 qemu-doc.html  qemu-tech.html "$(DESTDIR)$(docdir)"
++      $(INSTALL_DATA) qemu-doc.html  qemu-tech.html "$(DESTDIR)$(docdir)"
+ ifndef CONFIG_WIN32
+       mkdir -p "$(DESTDIR)$(mandir)/man1"
+-      $(INSTALL) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
++      $(INSTALL_DATA) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
+ endif
  
  install: all $(if $(BUILD_DOCS),install-doc)
        mkdir -p "$(DESTDIR)$(bindir)"
@@ -55,11 +65,16 @@ Index: ioemu/Makefile
 +#     mkdir -p "$(DESTDIR)$(datadir)"
 +#     for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
 +#                     video.x openbios-sparc32 linux_boot.bin; do \
-+#             $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x 
"$(DESTDIR)$(datadir)"; \
++#             $(INSTALL_DATA) $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; 
\
 +#     done
  ifndef CONFIG_WIN32
        mkdir -p "$(DESTDIR)$(datadir)/keymaps"
        for x in $(KEYMAPS); do \
+-              $(INSTALL) -m 644 $(SRC_PATH)/keymaps/$$x 
"$(DESTDIR)$(datadir)/keymaps"; \
++              $(INSTALL_DATA) $(SRC_PATH)/keymaps/$$x 
"$(DESTDIR)$(datadir)/keymaps"; \
+       done
+ endif
+       for d in $(TARGET_DIRS); do \
 @@ -89,7 +94,7 @@
        $(MAKE) -C tests $@
  
@@ -85,8 +100,8 @@ Index: ioemu/Makefile
  info: qemu-doc.info qemu-tech.info
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-12-08 01:26:04.000000000 +0000
-+++ ioemu/Makefile.target      2006-12-08 01:41:05.000000000 +0000
+--- ioemu.orig/Makefile.target 2007-05-03 15:38:37.000000000 +0100
++++ ioemu/Makefile.target      2007-05-03 15:38:39.000000000 +0100
 @@ -1,5 +1,8 @@
  include config.mak
  
@@ -163,8 +178,8 @@ Index: ioemu/Makefile.target
  include .depend
 Index: ioemu/configure
 ===================================================================
---- ioemu.orig/configure       2006-12-08 01:26:04.000000000 +0000
-+++ ioemu/configure    2006-12-08 01:40:58.000000000 +0000
+--- ioemu.orig/configure       2007-05-03 15:38:37.000000000 +0100
++++ ioemu/configure    2007-05-03 15:38:39.000000000 +0100
 @@ -18,8 +18,8 @@
  
  # default parameters
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/xen-domain-name
--- a/tools/ioemu/patches/xen-domain-name       Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/xen-domain-name       Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/sdl.c
 Index: ioemu/sdl.c
 ===================================================================
---- ioemu.orig/sdl.c   2006-08-06 02:03:48.563137711 +0100
-+++ ioemu/sdl.c        2006-08-06 02:17:16.063137816 +0100
+--- ioemu.orig/sdl.c   2007-05-02 16:04:45.000000000 +0100
++++ ioemu/sdl.c        2007-05-02 16:05:51.000000000 +0100
 @@ -273,14 +273,14 @@
  static void sdl_update_caption(void)
  {
@@ -21,8 +21,8 @@ Index: ioemu/sdl.c
  static void sdl_hide_cursor(void)
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-06 02:16:31.246133963 +0100
-+++ ioemu/vl.c 2006-08-06 02:17:31.428424918 +0100
+--- ioemu.orig/vl.c    2007-05-02 16:05:51.000000000 +0100
++++ ioemu/vl.c 2007-05-02 16:05:51.000000000 +0100
 @@ -158,6 +158,8 @@
  int acpi_enabled = 1;
  int fd_bootchk = 1;
@@ -56,7 +56,7 @@ Index: ioemu/vl.c
      { "serial", 1, QEMU_OPTION_serial },
      { "parallel", 1, QEMU_OPTION_parallel },
      { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
-@@ -6062,6 +6067,9 @@
+@@ -6066,6 +6071,9 @@
              case QEMU_OPTION_no_acpi:
                  acpi_enabled = 0;
                  break;
@@ -68,8 +68,8 @@ Index: ioemu/vl.c
      }
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-06 02:15:39.711878977 +0100
-+++ ioemu/vl.h 2006-08-06 02:17:16.068137258 +0100
+--- ioemu.orig/vl.h    2007-05-02 16:05:50.000000000 +0100
++++ ioemu/vl.h 2007-05-02 16:05:51.000000000 +0100
 @@ -1185,4 +1185,5 @@
  
  void kqemu_record_dump(void);
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/xen-domid
--- a/tools/ioemu/patches/xen-domid     Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/xen-domid     Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-06 02:17:31.428424918 +0100
-+++ ioemu/vl.c 2006-08-06 02:18:12.550840673 +0100
+--- ioemu.orig/vl.c    2007-05-02 16:05:51.000000000 +0100
++++ ioemu/vl.c 2007-05-02 16:05:51.000000000 +0100
 @@ -159,6 +159,7 @@
  int fd_bootchk = 1;
  
@@ -36,7 +36,7 @@ Index: ioemu/vl.c
      { NULL },
  };
  
-@@ -6070,6 +6076,10 @@
+@@ -6074,6 +6080,10 @@
              case QEMU_OPTION_domainname:
                  strncat(domain_name, optarg, sizeof(domain_name) - 20);
                  break;
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/xen-mapcache
--- a/tools/ioemu/patches/xen-mapcache  Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/xen-mapcache  Tue May 08 09:09:17 2007 -0600
@@ -17,44 +17,116 @@ Signed-off-by: Keir Fraser <keir@xensour
 
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:21:55.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:56.000000000 +0000
-@@ -5808,6 +5808,91 @@
+--- ioemu.orig/vl.c    2007-05-03 15:12:21.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:12:41.000000000 +0100
+@@ -286,7 +286,7 @@
+     for(i = start; i < start + length; i += size) {
+         ioport_write_table[bsize][i] = func;
+         if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
+-            hw_error("register_ioport_read: invalid opaque");
++            hw_error("register_ioport_write: invalid opaque");
+         ioport_opaque[i] = opaque;
+     }
      return 0;
+@@ -5894,6 +5894,157 @@
+     suspend_requested = 1;
  }
  
-+#if defined(__i386__) || defined(__x86_64__)
++#if defined(MAPCACHE)
++
++#if defined(__i386__) 
++#define MAX_MCACHE_SIZE    0x40000000 /* 1GB max for x86 */
++#define MCACHE_BUCKET_SHIFT 16
++#elif defined(__x86_64__)
++#define MAX_MCACHE_SIZE    0x1000000000 /* 64GB max for x86_64 */
++#define MCACHE_BUCKET_SHIFT 20
++#endif
++
++#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
++
++#define BITS_PER_LONG (sizeof(long)*8)
++#define BITS_TO_LONGS(bits) \
++    (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
++#define DECLARE_BITMAP(name,bits) \
++    unsigned long name[BITS_TO_LONGS(bits)]
++#define test_bit(bit,map) \
++    (!!((map)[(bit)/BITS_PER_LONG] & (1UL << ((bit)%BITS_PER_LONG))))
++
++struct map_cache {
++    unsigned long paddr_index;
++    uint8_t      *vaddr_base;
++    DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE>>PAGE_SHIFT);
++};
++
 +static struct map_cache *mapcache_entry;
 +static unsigned long nr_buckets;
 +
-+static int qemu_map_cache_init(unsigned long nr_pages)
++/* For most cases (>99.9%), the page address is the same. */
++static unsigned long last_address_index = ~0UL;
++static uint8_t      *last_address_vaddr;
++
++static int qemu_map_cache_init(void)
 +{
-+    unsigned long max_pages = MAX_MCACHE_SIZE >> PAGE_SHIFT;
-+    int i;
-+
-+    if (nr_pages < max_pages)
-+        max_pages = nr_pages;
-+
-+    nr_buckets   = max_pages + (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 
1;
-+    nr_buckets >>= (MCACHE_BUCKET_SHIFT - PAGE_SHIFT);
++    unsigned long size;
++
++    nr_buckets = (((MAX_MCACHE_SIZE >> PAGE_SHIFT) +
++                   (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1) >>
++                  (MCACHE_BUCKET_SHIFT - PAGE_SHIFT));
 +    fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets);
 +
-+    mapcache_entry = malloc(nr_buckets * sizeof(struct map_cache));
-+    if (mapcache_entry == NULL) {
++    /*
++     * Use mmap() directly: lets us allocate a big hash table with no up-front
++     * cost in storage space. The OS will allocate memory only for the buckets
++     * that we actually use. All others will contain all zeroes.
++     */
++    size = nr_buckets * sizeof(struct map_cache);
++    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
++    mapcache_entry = mmap(NULL, size, PROT_READ|PROT_WRITE,
++                          MAP_SHARED|MAP_ANONYMOUS, 0, 0);
++    if (mapcache_entry == MAP_FAILED) {
 +        errno = ENOMEM;
 +        return -1;
 +    }
 +
-+    memset(mapcache_entry, 0, nr_buckets * sizeof(struct map_cache));
-+
-+    /*
-+     * To avoid ENOMEM from xc_map_foreign_batch() at runtime, we
-+     * pre-fill all the map caches in advance.
-+     */
-+    for (i = 0; i < nr_buckets; i++)
-+       (void)qemu_map_cache(((target_phys_addr_t)i) << MCACHE_BUCKET_SHIFT);
-+
 +    return 0;
++}
++
++static void qemu_remap_bucket(struct map_cache *entry,
++                              unsigned long address_index)
++{
++    uint8_t *vaddr_base;
++    unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
++    unsigned int i, j;
++
++    if (entry->vaddr_base != NULL) {
++        errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
++        if (errno) {
++            fprintf(logfile, "unmap fails %d\n", errno);
++            exit(-1);
++        }
++    }
++
++    for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i++)
++        pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-PAGE_SHIFT)) + i;
++
++    vaddr_base = xc_map_foreign_batch(xc_handle, domid, PROT_READ|PROT_WRITE,
++                                      pfns, MCACHE_BUCKET_SIZE >> PAGE_SHIFT);
++    if (vaddr_base == NULL) {
++        fprintf(logfile, "xc_map_foreign_batch error %d\n", errno);
++        exit(-1);
++    }
++
++    entry->vaddr_base  = vaddr_base;
++    entry->paddr_index = address_index;
++
++    for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i += BITS_PER_LONG) {
++        unsigned long word = 0;
++        j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> PAGE_SHIFT)) ?
++            (MCACHE_BUCKET_SIZE >> PAGE_SHIFT) % BITS_PER_LONG : 
BITS_PER_LONG;
++        while (j > 0)
++            word = (word << 1) | !(pfns[i + --j] & 0xF0000000UL);
++        entry->valid_mapping[i / BITS_PER_LONG] = word;
++    }
 +}
 +
 +uint8_t *qemu_map_cache(target_phys_addr_t phys_addr)
@@ -63,55 +135,71 @@ Index: ioemu/vl.c
 +    unsigned long address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
 +    unsigned long address_offset = phys_addr & (MCACHE_BUCKET_SIZE-1);
 +
-+    /* For most cases (>99.9%), the page address is the same. */
-+    static unsigned long last_address_index = ~0UL;
-+    static uint8_t      *last_address_vaddr;
-+
 +    if (address_index == last_address_index)
 +        return last_address_vaddr + address_offset;
 +
 +    entry = &mapcache_entry[address_index % nr_buckets];
 +
-+    if (entry->vaddr_base == NULL || entry->paddr_index != address_index) {
-+        /* We need to remap a bucket. */
-+        uint8_t *vaddr_base;
-+        unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
-+        unsigned int i;
-+
-+        if (entry->vaddr_base != NULL) {
-+            errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
-+            if (errno) {
-+                fprintf(logfile, "unmap fails %d\n", errno);
-+                exit(-1);
-+            }
-+        }
-+
-+        for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i++)
-+            pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-PAGE_SHIFT)) + i;
-+
-+        vaddr_base = xc_map_foreign_batch(
-+            xc_handle, domid, PROT_READ|PROT_WRITE,
-+            pfns, MCACHE_BUCKET_SIZE >> PAGE_SHIFT);
-+        if (vaddr_base == NULL) {
-+            fprintf(logfile, "xc_map_foreign_batch error %d\n", errno);
++    if (entry->vaddr_base == NULL || entry->paddr_index != address_index ||
++        !test_bit(address_offset>>PAGE_SHIFT, entry->valid_mapping))
++        qemu_remap_bucket(entry, address_index);
++
++    if (!test_bit(address_offset>>PAGE_SHIFT, entry->valid_mapping))
++        return NULL;
++
++    last_address_index = address_index;
++    last_address_vaddr = entry->vaddr_base;
++
++    return last_address_vaddr + address_offset;
++}
++
++void qemu_invalidate_map_cache(void)
++{
++    unsigned long i;
++
++    mapcache_lock();
++
++    for (i = 0; i < nr_buckets; i++) {
++        struct map_cache *entry = &mapcache_entry[i];
++
++        if (entry->vaddr_base == NULL)
++            continue;
++
++        errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
++        if (errno) {
++            fprintf(logfile, "unmap fails %d\n", errno);
 +            exit(-1);
 +        }
 +
-+        entry->vaddr_base  = vaddr_base;
-+        entry->paddr_index = address_index;;
-+    }
-+
-+    last_address_index = address_index;
-+    last_address_vaddr = entry->vaddr_base;
-+
-+    return last_address_vaddr + address_offset;
++        entry->paddr_index = 0;
++        entry->vaddr_base  = NULL;
++    }
++
++    last_address_index =  ~0UL;
++    last_address_vaddr = NULL;
++
++    mapcache_unlock();
 +}
-+#endif
++
++#endif /* defined(MAPCACHE) */
 +
  int main(int argc, char **argv)
  {
  #ifdef CONFIG_GDBSTUB
-@@ -6130,6 +6215,7 @@
+@@ -5930,8 +6081,11 @@
+     unsigned long ioreq_pfn;
+     extern void *shared_page;
+     extern void *buffered_io_page;
+-    extern void *buffered_pio_page;
++#ifdef __ia64__
+     unsigned long nr_pages;
++    xen_pfn_t *page_array;
++    extern void *buffered_pio_page;
++#endif
+ 
+     char qemu_dm_logfilename[64];
+ 
+@@ -6221,6 +6375,7 @@
                  break;
              case QEMU_OPTION_m:
                  ram_size = atol(optarg) * 1024 * 1024;
@@ -119,75 +207,61 @@ Index: ioemu/vl.c
                  if (ram_size <= 0)
                      help();
  #ifndef CONFIG_DM
-@@ -6404,50 +6490,41 @@
-         shared_page_nr = nr_pages - 1;
- #endif
- 
--    page_array = (xen_pfn_t *)malloc(tmp_nr_pages * sizeof(xen_pfn_t));
+@@ -6482,30 +6637,15 @@
+ 
+ #if defined(__i386__) || defined(__x86_64__)
+ 
+-    nr_pages = ram_size/PAGE_SIZE;
+-
+-    page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
 -    if (page_array == NULL) {
 -        fprintf(logfile, "malloc returned error %d\n", errno);
 -        exit(-1);
 -    }
 -
- #if defined(__i386__) || defined(__x86_64__)
--    for ( i = 0; i < tmp_nr_pages; i++)
+-    for ( i = 0; i < nr_pages; i++)
 -        page_array[i] = i;
- 
+-
 -    phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
 -                                         PROT_READ|PROT_WRITE, page_array,
--                                         tmp_nr_pages);
+-                                         nr_pages);
 -    if (phys_ram_base == NULL) {
 -        fprintf(logfile, "batch map guest memory returned error %d\n", errno);
-+    if ( qemu_map_cache_init(tmp_nr_pages) )
-+    {
++    if (qemu_map_cache_init()) {
 +        fprintf(logfile, "qemu_map_cache_init returned: error %d\n", errno);
          exit(-1);
      }
  
+     xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
+     fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
      shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
 -                                       PROT_READ|PROT_WRITE,
--                                       page_array[shared_page_nr]);
-+                                       PROT_READ|PROT_WRITE, shared_page_nr);
+-                                       page_array[ioreq_pfn]);
++                                       PROT_READ|PROT_WRITE, ioreq_pfn);
      if (shared_page == NULL) {
          fprintf(logfile, "map shared IO page returned error %d\n", errno);
          exit(-1);
-     }
- 
--    fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n",
--            shared_page_nr, (uint64_t)(page_array[shared_page_nr]));
-+    fprintf(logfile, "shared page at pfn:%lx\n", shared_page_nr);
- 
+@@ -6514,15 +6654,12 @@
+     xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
+     fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
      buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-                                             PROT_READ|PROT_WRITE,
--                                            page_array[shared_page_nr - 2]);
-+                                            shared_page_nr - 2);
+-                                            PROT_READ|PROT_WRITE,
+-                                            page_array[ioreq_pfn]);
++                                            PROT_READ|PROT_WRITE, ioreq_pfn);
      if (buffered_io_page == NULL) {
          fprintf(logfile, "map buffered IO page returned error %d\n", errno);
          exit(-1);
      }
  
--    fprintf(logfile, "buffered io page at pfn:%lx, mfn: %"PRIx64"\n",
--            shared_page_nr - 2, (uint64_t)(page_array[shared_page_nr - 2]));
+-    free(page_array);
 -
--    free(page_array);
-+    fprintf(logfile, "buffered io page at pfn:%lx\n", shared_page_nr - 2);
- 
  #elif defined(__ia64__)
--  
-+
-+    page_array = (xen_pfn_t *)malloc(tmp_nr_pages * sizeof(xen_pfn_t));
-+    if (page_array == NULL) {
-+        fprintf(logfile, "malloc returned error %d\n", errno);
-+        exit(-1);
-+    }
-+
-     shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-                                        PROT_READ|PROT_WRITE,
-                                        IO_PAGE_START >> PAGE_SHIFT);
+ 
+     nr_pages = ram_size/PAGE_SIZE;
 Index: ioemu/target-i386-dm/exec-dm.c
 ===================================================================
---- ioemu.orig/target-i386-dm/exec-dm.c        2006-12-20 15:21:42.000000000 
+0000
-+++ ioemu/target-i386-dm/exec-dm.c     2006-12-21 11:32:29.000000000 +0000
+--- ioemu.orig/target-i386-dm/exec-dm.c        2007-05-03 15:10:22.000000000 
+0100
++++ ioemu/target-i386-dm/exec-dm.c     2007-05-03 15:12:34.000000000 +0100
 @@ -36,6 +36,7 @@
  
  #include "cpu.h"
@@ -196,25 +270,13 @@ Index: ioemu/target-i386-dm/exec-dm.c
  
  //#define DEBUG_TB_INVALIDATE
  //#define DEBUG_FLUSH
-@@ -127,10 +128,29 @@
+@@ -127,10 +128,17 @@
  FILE *logfile;
  int loglevel;
  
-+
-+#if defined(__i386__) || defined(__x86_64__)
-+#define MAPCACHE
-+#endif
-+
 +#ifdef MAPCACHE
-+#include <pthread.h>
-+static pthread_mutex_t mapcache_mutex;
-+#define mapcache_lock() pthread_mutex_lock(&mapcache_mutex)
-+#define mapcache_unlock() pthread_mutex_unlock(&mapcache_mutex)
-+#else 
-+#define mapcache_lock() ( (void)0 )
-+#define mapcache_unlock() ( (void)0 )
-+#endif
-+
++pthread_mutex_t mapcache_mutex;
++#endif
 +
  void cpu_exec_init(CPUState *env)
  {
@@ -226,7 +288,7 @@ Index: ioemu/target-i386-dm/exec-dm.c
  
      env->next_cpu = NULL;
      penv = &first_cpu;
-@@ -144,6 +164,14 @@
+@@ -144,6 +152,14 @@
  
      /* alloc dirty bits array */
      phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
@@ -241,19 +303,28 @@ Index: ioemu/target-i386-dm/exec-dm.c
  }
  
  /* enable or disable low levels log */
-@@ -426,19 +454,27 @@
- #endif
+@@ -409,16 +425,11 @@
+         return 0;
  }
  
+-static inline int paddr_is_ram(target_phys_addr_t addr)
+-{
+-    /* Is this guest physical address RAM-backed? */
+-#if defined(CONFIG_DM) && (defined(__i386__) || defined(__x86_64__))
+-    return ((addr < HVM_BELOW_4G_MMIO_START) ||
+-            (addr >= HVM_BELOW_4G_MMIO_START + HVM_BELOW_4G_MMIO_LENGTH));
+-#else
+-    return (addr < ram_size);
 +#if defined(__i386__) || defined(__x86_64__)
 +#define phys_ram_addr(x) (qemu_map_cache(x))
 +#elif defined(__ia64__)
-+#define phys_ram_addr(x) (phys_ram_base + (x))
-+#endif
-+
++#define phys_ram_addr(x) ((addr < ram_size) ? (phys_ram_base + (x)) : NULL)
+ #endif
+-}
+ 
  void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
                              int len, int is_write)
- {
+@@ -426,13 +437,15 @@
      int l, io_index;
      uint8_t *ptr;
      uint32_t val;
@@ -271,12 +342,14 @@ Index: ioemu/target-i386-dm/exec-dm.c
          io_index = iomem_index(addr);
          if (is_write) {
              if (io_index) {
-@@ -460,9 +496,10 @@
+@@ -452,11 +465,11 @@
+                     io_mem_write[io_index][0](io_mem_opaque[io_index], addr, 
val);
+                     l = 1;
                  }
-             } else if (paddr_is_ram(addr)) {
+-            } else if (paddr_is_ram(addr)) {
++            } else if ((ptr = phys_ram_addr(addr)) != NULL) {
                  /* Reading from RAM */
 -                memcpy(phys_ram_base + addr, buf, l);
-+                ptr = phys_ram_addr(addr);
 +                memcpy(ptr, buf, l);
  #ifdef __ia64__
 -                sync_icache((unsigned long)(phys_ram_base + addr), l);
@@ -284,17 +357,19 @@ Index: ioemu/target-i386-dm/exec-dm.c
  #endif 
              }
          } else {
-@@ -485,7 +522,8 @@
+@@ -477,9 +490,9 @@
+                     stb_raw(buf, val);
+                     l = 1;
                  }
-             } else if (paddr_is_ram(addr)) {
+-            } else if (paddr_is_ram(addr)) {
++            } else if ((ptr = phys_ram_addr(addr)) != NULL) {
                  /* Reading from RAM */
 -                memcpy(buf, phys_ram_base + addr, l);
-+                ptr = phys_ram_addr(addr);
 +                memcpy(buf, ptr, l);
              } else {
                  /* Neither RAM nor known MMIO space */
                  memset(buf, 0xff, len); 
-@@ -495,6 +533,8 @@
+@@ -489,6 +502,8 @@
          buf += l;
          addr += l;
      }
@@ -305,30 +380,32 @@ Index: ioemu/target-i386-dm/exec-dm.c
  
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:21:55.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:56.000000000 +0000
-@@ -156,6 +156,26 @@
+--- ioemu.orig/vl.h    2007-05-03 15:12:20.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:12:34.000000000 +0100
+@@ -156,6 +156,28 @@
  
  extern FILE *logfile;
  
 +
 +#if defined(__i386__) || defined(__x86_64__)
-+#if defined(__i386__) 
-+#define MAX_MCACHE_SIZE    0x40000000 /* 1GB max for x86 */
-+#define MCACHE_BUCKET_SHIFT 16
-+#elif defined(__x86_64__)
-+#define MAX_MCACHE_SIZE    0x1000000000 /* 64GB max for x86_64 */
-+#define MCACHE_BUCKET_SHIFT 20
-+#endif
-+
-+#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
-+
-+struct map_cache {
-+    unsigned long paddr_index;
-+    uint8_t      *vaddr_base;
-+};
++
++#define MAPCACHE
 +
 +uint8_t *qemu_map_cache(target_phys_addr_t phys_addr);
++void     qemu_invalidate_map_cache(void);
++
++#include <pthread.h>
++extern  pthread_mutex_t mapcache_mutex;
++#define mapcache_lock() pthread_mutex_lock(&mapcache_mutex)
++#define mapcache_unlock() pthread_mutex_unlock(&mapcache_mutex)
++
++#else 
++
++#define qemu_invalidate_map_cache() ((void)0)
++
++#define mapcache_lock()   ((void)0)
++#define mapcache_unlock() ((void)0)
++
 +#endif
 +
  extern int xc_handle;
@@ -336,8 +413,8 @@ Index: ioemu/vl.h
  
 Index: ioemu/target-i386-dm/cpu.h
 ===================================================================
---- ioemu.orig/target-i386-dm/cpu.h    2006-12-20 15:21:45.000000000 +0000
-+++ ioemu/target-i386-dm/cpu.h 2006-12-20 15:21:56.000000000 +0000
+--- ioemu.orig/target-i386-dm/cpu.h    2007-05-03 15:10:22.000000000 +0100
++++ ioemu/target-i386-dm/cpu.h 2007-05-03 15:12:21.000000000 +0100
 @@ -25,7 +25,8 @@
  #ifdef TARGET_X86_64
  #define TARGET_LONG_BITS 64
@@ -348,3 +425,17 @@ Index: ioemu/target-i386-dm/cpu.h
  #endif
  
  /* target supports implicit self modifying code */
+Index: ioemu/target-i386-dm/helper2.c
+===================================================================
+--- ioemu.orig/target-i386-dm/helper2.c        2007-05-03 15:12:19.000000000 
+0100
++++ ioemu/target-i386-dm/helper2.c     2007-05-03 15:12:21.000000000 +0100
+@@ -526,6 +526,9 @@
+     case IOREQ_TYPE_TIMEOFFSET:
+         cpu_ioreq_timeoffset(env, req);
+         break;
++    case IOREQ_TYPE_INVALIDATE:
++        qemu_invalidate_map_cache();
++        break;
+     default:
+         hw_error("Invalid ioreq type 0x%x\n", req->type);
+     }
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/xen-mm
--- a/tools/ioemu/patches/xen-mm        Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/xen-mm        Tue May 08 09:09:17 2007 -0600
@@ -1,7 +1,7 @@ Index: ioemu/hw/pc.c
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-12-08 02:00:38.000000000 +0000
-+++ ioemu/hw/pc.c      2006-12-08 02:02:07.000000000 +0000
+--- ioemu.orig/hw/pc.c 2007-05-03 09:54:24.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-03 09:56:32.000000000 +0100
 @@ -646,7 +646,9 @@
      }
  
@@ -25,9 +25,17 @@ Index: ioemu/hw/pc.c
      isa_bios_size = bios_size;
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-08 02:00:39.000000000 +0000
-+++ ioemu/vl.c 2006-12-08 02:02:28.000000000 +0000
-@@ -158,6 +158,8 @@
+--- ioemu.orig/vl.c    2007-05-03 09:54:24.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:04:06.000000000 +0100
+@@ -88,6 +88,7 @@
+ 
+ #include "exec-all.h"
+ 
++#include <xen/hvm/params.h>
+ #define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
+ 
+ //#define DEBUG_UNUSED_IOPORT
+@@ -158,6 +159,8 @@
  int acpi_enabled = 1;
  int fd_bootchk = 1;
  
@@ -36,17 +44,17 @@ Index: ioemu/vl.c
  char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
  extern int domid;
  
-@@ -5650,6 +5652,9 @@
+@@ -5650,6 +5653,9 @@
      QEMUMachine *machine;
      char usb_devices[MAX_USB_CMDLINE][128];
      int usb_devices_index;
-+    unsigned long nr_pages, tmp_nr_pages, shared_page_nr;
-+    xen_pfn_t *page_array;
++    unsigned long ioreq_pfn;
 +    extern void *shared_page;
++    unsigned long nr_pages;
  
      char qemu_dm_logfilename[64];
  
-@@ -5917,11 +5922,13 @@
+@@ -5921,11 +5927,13 @@
                  ram_size = atol(optarg) * 1024 * 1024;
                  if (ram_size <= 0)
                      help();
@@ -60,7 +68,7 @@ Index: ioemu/vl.c
                  break;
              case QEMU_OPTION_l:
                  {
-@@ -6133,12 +6140,61 @@
+@@ -6137,12 +6145,53 @@
      /* init the memory */
      phys_ram_size = ram_size + vga_ram_size + bios_size;
  
@@ -68,44 +76,36 @@ Index: ioemu/vl.c
 +
 +    xc_handle = xc_interface_open();
 +
++#if defined(__i386__) || defined(__x86_64__)
++
 +    nr_pages = ram_size/PAGE_SIZE;
-+    tmp_nr_pages = nr_pages;
 +
-+#if defined(__i386__) || defined(__x86_64__)
-+    if (ram_size > HVM_BELOW_4G_RAM_END) {
-+        tmp_nr_pages += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
-+        shared_page_nr = (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT) - 1;
-+    } else
-+        shared_page_nr = nr_pages - 1;
-+#endif
-+
-+    page_array = (xen_pfn_t *)malloc(tmp_nr_pages * sizeof(xen_pfn_t));
++    page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
 +    if (page_array == NULL) {
 +        fprintf(logfile, "malloc returned error %d\n", errno);
 +        exit(-1);
 +    }
 +
-+    for ( i = 0; i < tmp_nr_pages; i++)
++    for ( i = 0; i < nr_pages; i++)
 +        page_array[i] = i;
 +
 +    phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
 +                                         PROT_READ|PROT_WRITE, page_array,
-+                                         tmp_nr_pages);
++                                         nr_pages);
 +    if (phys_ram_base == NULL) {
 +        fprintf(logfile, "batch map guest memory returned error %d\n", errno);
 +        exit(-1);
 +    }
 +
++    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
++    fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
 +    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
 +                                       PROT_READ|PROT_WRITE,
-+                                       page_array[shared_page_nr]);
++                                       page_array[ioreq_pfn]);
 +    if (shared_page == NULL) {
 +        fprintf(logfile, "map shared IO page returned error %d\n", errno);
 +        exit(-1);
 +    }
-+
-+    fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n",
-+            shared_page_nr, (uint64_t)(page_array[shared_page_nr]));
 +
 +    free(page_array);
 +
@@ -124,8 +124,8 @@ Index: ioemu/vl.c
      if (cdrom_index >= 0) {
 Index: ioemu/hw/piix_pci.c
 ===================================================================
---- ioemu.orig/hw/piix_pci.c   2006-12-08 02:00:36.000000000 +0000
-+++ ioemu/hw/piix_pci.c        2006-12-08 02:02:06.000000000 +0000
+--- ioemu.orig/hw/piix_pci.c   2007-05-03 09:54:18.000000000 +0100
++++ ioemu/hw/piix_pci.c        2007-05-03 09:56:32.000000000 +0100
 @@ -399,7 +399,7 @@
      uint8_t elcr[2];
  
@@ -137,8 +137,8 @@ Index: ioemu/hw/piix_pci.c
      elcr[0] = 0x00;
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-08 02:00:39.000000000 +0000
-+++ ioemu/vl.h 2006-12-08 02:02:07.000000000 +0000
+--- ioemu.orig/vl.h    2007-05-03 09:54:24.000000000 +0100
++++ ioemu/vl.h 2007-05-03 09:56:32.000000000 +0100
 @@ -39,6 +39,7 @@
  #include <sys/stat.h>
  #include "xenctrl.h"
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/xen-network
--- a/tools/ioemu/patches/xen-network   Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/xen-network   Tue May 08 09:09:17 2007 -0600
@@ -1,16 +1,16 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-06 02:22:01.556312045 +0100
-+++ ioemu/vl.c 2006-08-06 02:22:53.925474246 +0100
-@@ -89,6 +89,7 @@
- #include "exec-all.h"
+--- ioemu.orig/vl.c    2007-05-03 10:07:52.000000000 +0100
++++ ioemu/vl.c 2007-05-03 10:07:52.000000000 +0100
+@@ -90,6 +90,7 @@
  
+ #include <xen/hvm/params.h>
  #define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
 +#define DEFAULT_BRIDGE "xenbr0"
  
  //#define DEBUG_UNUSED_IOPORT
  //#define DEBUG_IOPORT
-@@ -3090,11 +3091,11 @@
+@@ -3091,11 +3092,11 @@
  #endif
  
  static int net_tap_init(VLANState *vlan, const char *ifname1,
@@ -24,7 +24,18 @@ Index: ioemu/vl.c
      char **parg;
      char ifname[128];
  
-@@ -3116,6 +3117,7 @@
+@@ -3114,9 +3115,18 @@
+         pid = fork();
+         if (pid >= 0) {
+             if (pid == 0) {
++                int open_max = sysconf(_SC_OPEN_MAX), i;
++                for (i = 0; i < open_max; i++)
++                    if (i != STDIN_FILENO &&
++                        i != STDOUT_FILENO &&
++                        i != STDERR_FILENO &&
++                        i != fd)
++                        close(i);
++
                  parg = args;
                  *parg++ = (char *)setup_script;
                  *parg++ = ifname;
@@ -32,7 +43,7 @@ Index: ioemu/vl.c
                  *parg++ = NULL;
                  execv(setup_script, args);
                  _exit(1);
-@@ -3671,6 +3673,7 @@
+@@ -3672,6 +3682,7 @@
      if (!strcmp(device, "tap")) {
          char ifname[64];
          char setup_script[1024];
@@ -40,7 +51,7 @@ Index: ioemu/vl.c
          int fd;
          if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
              fd = strtol(buf, NULL, 0);
-@@ -3683,7 +3686,10 @@
+@@ -3684,7 +3695,10 @@
              if (get_param_value(setup_script, sizeof(setup_script), "script", 
p) == 0) {
                  pstrcpy(setup_script, sizeof(setup_script), 
DEFAULT_NETWORK_SCRIPT);
              }
@@ -52,7 +63,7 @@ Index: ioemu/vl.c
          }
      } else
  #endif
-@@ -5208,7 +5214,7 @@
+@@ -5209,7 +5223,7 @@
             "-net tap[,vlan=n],ifname=name\n"
             "                connect the host TAP network interface to VLAN 
'n'\n"
  #else
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/xen-platform-device
--- a/tools/ioemu/patches/xen-platform-device   Mon May 07 13:24:37 2007 -0600
+++ b/tools/ioemu/patches/xen-platform-device   Tue May 08 09:09:17 2007 -0600
@@ -3,8 +3,8 @@ will come later.
 
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-12-08 01:41:14.000000000 +0000
-+++ ioemu/Makefile.target      2006-12-08 01:41:15.000000000 +0000
+--- ioemu.orig/Makefile.target 2007-05-03 15:16:41.000000000 +0100
++++ ioemu/Makefile.target      2007-05-03 15:20:35.000000000 +0100
 @@ -360,6 +360,7 @@
  VL_OBJS+= usb-uhci.o
  VL_OBJS+= piix4acpi.o
@@ -15,8 +15,8 @@ Index: ioemu/Makefile.target
  ifeq ($(TARGET_BASE_ARCH), ppc)
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-12-08 01:41:13.000000000 +0000
-+++ ioemu/hw/pc.c      2006-12-08 01:41:15.000000000 +0000
+--- ioemu.orig/hw/pc.c 2007-05-03 15:18:17.000000000 +0100
++++ ioemu/hw/pc.c      2007-05-03 15:20:35.000000000 +0100
 @@ -823,6 +823,9 @@
      }
  #endif /* !CONFIG_DM */
@@ -30,8 +30,8 @@ Index: ioemu/hw/xen_platform.c
 Index: ioemu/hw/xen_platform.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/hw/xen_platform.c    2006-12-08 01:41:15.000000000 +0000
-@@ -0,0 +1,144 @@
++++ ioemu/hw/xen_platform.c    2007-05-03 15:18:17.000000000 +0100
+@@ -0,0 +1,133 @@
 +/*
 + * XEN platform fake pci device, formerly known as the event channel device
 + * 
@@ -63,21 +63,10 @@ Index: ioemu/hw/xen_platform.c
 +
 +extern FILE *logfile;
 +
-+static void platform_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    return;
-+}
-+
-+static uint32_t platform_ioport_read(void *opaque, uint32_t addr)
-+{
-+    return 0;
-+}
-+
 +static void platform_ioport_map(PCIDevice *pci_dev, int region_num,
 +                                uint32_t addr, uint32_t size, int type)
 +{
-+    register_ioport_write(addr, 16, 4, platform_ioport_write, NULL);
-+    register_ioport_read(addr, 16, 1, platform_ioport_read, NULL);
++    /* nothing yet */
 +}
 +
 +static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
@@ -178,15 +167,16 @@ Index: ioemu/hw/xen_platform.c
 +}
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-08 01:41:14.000000000 +0000
-+++ ioemu/vl.h 2006-12-08 01:41:15.000000000 +0000
-@@ -1212,6 +1212,9 @@
- void xenstore_check_new_media_present(int timeout);
- void xenstore_write_vncport(int vnc_display);
+--- ioemu.orig/vl.h    2007-05-03 15:18:17.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:20:39.000000000 +0100
+@@ -1220,6 +1220,10 @@
+ extern long time_offset;
+ void timeoffset_get(void);
  
 +/* xen_platform.c */
 +void pci_xen_platform_init(PCIBus *bus);
 +
- 
++
  void kqemu_record_dump(void);
  
+ extern char domain_name[];
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/xen-support-buffered-ioreqs
--- a/tools/ioemu/patches/xen-support-buffered-ioreqs   Mon May 07 13:24:37 
2007 -0600
+++ b/tools/ioemu/patches/xen-support-buffered-ioreqs   Tue May 08 09:09:17 
2007 -0600
@@ -1,38 +1,37 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:21:54.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:54.000000000 +0000
-@@ -5838,6 +5838,7 @@
-     unsigned long nr_pages, tmp_nr_pages, shared_page_nr;
-     xen_pfn_t *page_array;
+--- ioemu.orig/vl.c    2007-05-03 15:09:21.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:09:48.000000000 +0100
+@@ -5923,6 +5923,7 @@
+     int usb_devices_index;
+     unsigned long ioreq_pfn;
      extern void *shared_page;
 +    extern void *buffered_io_page;
+     unsigned long nr_pages;
  
      char qemu_dm_logfilename[64];
+@@ -6499,6 +6500,16 @@
+         exit(-1);
+     }
  
-@@ -6422,6 +6423,17 @@
-     fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n",
-             shared_page_nr, (uint64_t)(page_array[shared_page_nr]));
- 
++    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
++    fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
 +    buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
 +                                            PROT_READ|PROT_WRITE,
-+                                            page_array[shared_page_nr - 2]);
++                                            page_array[ioreq_pfn]);
 +    if (buffered_io_page == NULL) {
 +        fprintf(logfile, "map buffered IO page returned error %d\n", errno);
 +        exit(-1);
 +    }
-+
-+    fprintf(logfile, "buffered io page at pfn:%lx, mfn: %"PRIx64"\n",
-+            shared_page_nr - 2, (uint64_t)(page_array[shared_page_nr - 2]));
 +
      free(page_array);
  
  #elif defined(__ia64__)
 Index: ioemu/target-i386-dm/helper2.c
 ===================================================================
---- ioemu.orig/target-i386-dm/helper2.c        2006-12-20 15:21:47.000000000 
+0000
-+++ ioemu/target-i386-dm/helper2.c     2006-12-20 15:21:54.000000000 +0000
-@@ -76,6 +76,10 @@
+--- ioemu.orig/target-i386-dm/helper2.c        2007-05-03 15:09:21.000000000 
+0100
++++ ioemu/target-i386-dm/helper2.c     2007-05-03 15:10:03.000000000 +0100
+@@ -78,6 +78,10 @@
  
  shared_iopage_t *shared_page = NULL;
  
@@ -43,7 +42,7 @@ Index: ioemu/target-i386-dm/helper2.c
  /* the evtchn fd for polling */
  int xce_handle = -1;
  
-@@ -435,39 +439,71 @@
+@@ -489,6 +493,72 @@
      req->data = tmp1;
  }
  
@@ -65,11 +64,20 @@ Index: ioemu/target-i386-dm/helper2.c
 +    case IOREQ_TYPE_ADD:
 +        cpu_ioreq_add(env, req);
 +        break;
++    case IOREQ_TYPE_SUB:
++        cpu_ioreq_sub(env, req);
++        break;
 +    case IOREQ_TYPE_OR:
 +        cpu_ioreq_or(env, req);
 +        break;
 +    case IOREQ_TYPE_XOR:
 +        cpu_ioreq_xor(env, req);
++        break;
++    case IOREQ_TYPE_XCHG:
++        cpu_ioreq_xchg(env, req);
++        break;
++    case IOREQ_TYPE_TIMEOFFSET:
++        cpu_ioreq_timeoffset(env, req);
 +        break;
 +    default:
 +        hw_error("Invalid ioreq type 0x%x\n", req->type);
@@ -106,6 +114,8 @@ Index: ioemu/target-i386-dm/helper2.c
 +
  void cpu_handle_ioreq(void *opaque)
  {
+     extern int vm_running;
+@@ -496,43 +566,9 @@
      CPUState *env = opaque;
      ioreq_t *req = cpu_get_ioreq();
  
@@ -129,11 +139,20 @@ Index: ioemu/target-i386-dm/helper2.c
 -        case IOREQ_TYPE_ADD:
 -            cpu_ioreq_add(env, req);
 -            break;
+-        case IOREQ_TYPE_SUB:
+-            cpu_ioreq_sub(env, req);
+-            break;
 -        case IOREQ_TYPE_OR:
 -            cpu_ioreq_or(env, req);
 -            break;
 -        case IOREQ_TYPE_XOR:
 -            cpu_ioreq_xor(env, req);
+-            break;
+-        case IOREQ_TYPE_XCHG:
+-            cpu_ioreq_xchg(env, req);
+-            break;
+-      case IOREQ_TYPE_TIMEOFFSET:
+-            cpu_ioreq_timeoffset(env, req);
 -            break;
 -        default:
 -            hw_error("Invalid ioreq type 0x%x\n", req->type);
@@ -142,9 +161,9 @@ Index: ioemu/target-i386-dm/helper2.c
  
          if (req->state != STATE_IOREQ_INPROCESS) {
              fprintf(logfile, "Badness in I/O request ... not in service?!: "
-@@ -492,6 +528,10 @@
-     CPUState *env = cpu_single_env;
+@@ -578,6 +614,10 @@
      int evtchn_fd = xc_evtchn_fd(xce_handle);
+     char qemu_file[20];
  
 +    buffered_io_timer = qemu_new_timer(rt_clock, handle_buffered_io,
 +                                     cpu_single_env);
@@ -152,4 +171,12 @@ Index: ioemu/target-i386-dm/helper2.c
 +
      qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
  
-     while (1) {
+     while (!(vm_running && suspend_requested))
+@@ -587,6 +627,7 @@
+     fprintf(logfile, "device model received suspend signal!\n");
+ 
+     /* Pull all outstanding ioreqs through the system */
++    handle_buffered_io(env);
+     main_loop_wait(1); /* For the select() on events */
+ 
+     /* Stop the IDE thread */
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/xenstore
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/xenstore      Tue May 08 09:09:17 2007 -0600
@@ -0,0 +1,197 @@
+Index: ioemu/xenstore.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ ioemu/xenstore.c   2007-05-03 15:17:52.000000000 +0100
+@@ -0,0 +1,139 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General
++ * Public License.  See the file "COPYING" in the main directory of
++ * this archive for more details.
++ *
++ * Copyright (C) 2006 Christian Limpach
++ * Copyright (C) 2006 XenSource Ltd.
++ *
++ */
++
++#include "vl.h"
++
++static struct xs_handle *xsh = NULL;
++
++static int pasprintf(char **buf, const char *fmt, ...)
++{
++    va_list ap;
++    int ret = 0;
++
++    if (*buf)
++        free(*buf);
++    va_start(ap, fmt);
++    if (vasprintf(buf, fmt, ap) == -1) {
++        buf = NULL;
++        ret = -1;
++    }
++    va_end(ap);
++    return ret;
++}
++
++void xenstore_parse_domain_config(int domid)
++{
++    char *path;
++
++    xsh = xs_daemon_open();
++    if (xsh == NULL) {
++        fprintf(logfile, "Could not contact xenstore for domain config\n");
++        return;
++    }
++
++    path = xs_get_domain_path(xsh, domid);
++    if (path == NULL) {
++        fprintf(logfile, "xs_get_domain_path() error\n");
++        goto out;
++    }
++
++ out:
++    free(path);
++    return;
++}
++
++int xenstore_fd(void)
++{
++    if (xsh)
++        return xs_fileno(xsh);
++    return -1;
++}
++
++void xenstore_process_event(void *opaque)
++{
++    char **vec;
++    unsigned int num;
++
++    vec = xs_read_watch(xsh, &num);
++    if (!vec)
++        return;
++
++ out:
++    free(vec);
++}
++
++char *xenstore_vm_read(int domid, char *key, int *len)
++{
++    char *buf = NULL, *path = NULL, *value = NULL;
++
++    if (xsh == NULL)
++        goto out;
++
++    path = xs_get_domain_path(xsh, domid);
++    if (path == NULL) {
++        fprintf(logfile, "xs_get_domain_path(%d): error\n", domid);
++        goto out;
++    }
++
++    pasprintf(&buf, "%s/vm", path);
++    free(path);
++    path = xs_read(xsh, XBT_NULL, buf, NULL);
++    if (path == NULL) {
++        fprintf(logfile, "xs_read(%s): read error\n", buf);
++        goto out;
++    }
++
++    pasprintf(&buf, "%s/%s", path, key);
++    value = xs_read(xsh, XBT_NULL, buf, len);
++    if (value == NULL) {
++        fprintf(logfile, "xs_read(%s): read error\n", buf);
++        goto out;
++    }
++
++ out:
++    free(path);
++    free(buf);
++    return value;
++}
++
++int xenstore_vm_write(int domid, char *key, char *value)
++{
++    char *buf = NULL, *path = NULL;
++    int rc = -1;
++
++    if (xsh == NULL)
++        goto out;
++
++    path = xs_get_domain_path(xsh, domid);
++    if (path == NULL) {
++        fprintf(logfile, "xs_get_domain_path: error\n");
++        goto out;
++    }
++
++    pasprintf(&buf, "%s/vm", path);
++    free(path);
++    path = xs_read(xsh, XBT_NULL, buf, NULL);
++    if (path == NULL) {
++        fprintf(logfile, "xs_read(%s): read error\n", buf);
++        goto out;
++    }
++
++    pasprintf(&buf, "%s/%s", path, key);
++    rc = xs_write(xsh, XBT_NULL, buf, value, strlen(value));
++    if (rc) {
++        fprintf(logfile, "xs_write(%s, %s): write error\n", buf, key);
++        goto out;
++    }
++
++ out:
++    free(path);
++    free(buf);
++    return rc;
++}
+Index: ioemu/vl.h
+===================================================================
+--- ioemu.orig/vl.h    2007-05-03 15:15:40.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:18:00.000000000 +0100
+@@ -1204,6 +1204,12 @@
+ void readline_start(const char *prompt, int is_password,
+                     ReadLineFunc *readline_func, void *opaque);
+ 
++/* xenstore.c */
++void xenstore_parse_domain_config(int domid);
++
++int xenstore_vm_write(int domid, char *key, char *val);
++char *xenstore_vm_read(int domid, char *key, int *len);
++
+ void kqemu_record_dump(void);
+ 
+ extern char domain_name[];
+Index: ioemu/Makefile.target
+===================================================================
+--- ioemu.orig/Makefile.target 2007-05-03 15:15:39.000000000 +0100
++++ ioemu/Makefile.target      2007-05-03 15:16:41.000000000 +0100
+@@ -359,6 +359,7 @@
+ VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
+ VL_OBJS+= usb-uhci.o
+ VL_OBJS+= piix4acpi.o
++VL_OBJS+= xenstore.o
+ DEFINES += -DHAS_AUDIO
+ endif
+ ifeq ($(TARGET_BASE_ARCH), ppc)
+Index: ioemu/vl.c
+===================================================================
+--- ioemu.orig/vl.c    2007-05-03 15:15:40.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:17:52.000000000 +0100
+@@ -6371,6 +6371,10 @@
+         }
+     }
+ 
++#ifdef CONFIG_DM
++    xenstore_parse_domain_config(domid);
++#endif /* CONFIG_DM */
++
+ #ifdef USE_KQEMU
+     if (smp_cpus > 1)
+         kqemu_allowed = 0;
+@@ -6624,6 +6628,8 @@
+         }
+     }
+ 
++    qemu_set_fd_handler(xenstore_fd(), xenstore_process_event, NULL, NULL);
++
+     machine->init(ram_size, vga_ram_size, boot_device,
+                   ds, fd_filename, snapshot,
+                   kernel_filename, kernel_cmdline, initrd_filename);
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/xenstore-block-device-config
--- a/tools/ioemu/patches/xenstore-block-device-config  Mon May 07 13:24:37 
2007 -0600
+++ b/tools/ioemu/patches/xenstore-block-device-config  Tue May 08 09:09:17 
2007 -0600
@@ -1,63 +1,37 @@ Index: ioemu/Makefile.target
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2006-12-20 15:21:51.000000000 +0000
-+++ ioemu/Makefile.target      2006-12-20 15:21:53.000000000 +0000
-@@ -359,6 +359,7 @@
- VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
- VL_OBJS+= usb-uhci.o
- VL_OBJS+= piix4acpi.o
-+VL_OBJS+= xenstore.o
- DEFINES += -DHAS_AUDIO
- endif
- ifeq ($(TARGET_BASE_ARCH), ppc)
 Index: ioemu/xenstore.c
 ===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/xenstore.c   2006-12-20 15:21:53.000000000 +0000
-@@ -0,0 +1,187 @@
-+/*
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file "COPYING" in the main directory of
-+ * this archive for more details.
-+ *
-+ * Copyright (C) 2006 Christian Limpach
-+ * Copyright (C) 2006 XenSource Ltd.
-+ *
-+ */
-+
-+#include "vl.h"
+--- ioemu.orig/xenstore.c      2007-05-03 15:17:52.000000000 +0100
++++ ioemu/xenstore.c   2007-05-03 15:18:05.000000000 +0100
+@@ -9,8 +9,15 @@
+  */
+ 
+ #include "vl.h"
 +#include "block_int.h"
-+
-+static struct xs_handle *xsh = NULL;
-+static char *hd_filename[MAX_DISKS];
++#include <unistd.h>
+ 
+ static struct xs_handle *xsh = NULL;
++static char *media_filename[MAX_DISKS];
 +static QEMUTimer *insert_timer = NULL;
 +
-+static int pasprintf(char **buf, const char *fmt, ...)
-+{
-+    va_list ap;
-+    int ret = 0;
-+
-+    if (*buf)
-+      free(*buf);
-+    va_start(ap, fmt);
-+    if (vasprintf(buf, fmt, ap) == -1) {
-+      buf = NULL;
-+      ret = -1;
-+    }
-+    va_end(ap);
-+    return ret;
-+}
-+
++#define UWAIT_MAX (30*1000000) /* thirty seconds */
++#define UWAIT     (100000)     /* 1/10th second  */
+ 
+ static int pasprintf(char **buf, const char *fmt, ...)
+ {
+@@ -28,9 +35,54 @@
+     return ret;
+ }
+ 
 +static void insert_media(void *opaque)
 +{
 +    int i;
 +
 +    for (i = 0; i < MAX_DISKS; i++) {
-+      if (hd_filename[i]) {
-+          do_change(bs_table[i]->device_name, hd_filename[i]);
-+          free(hd_filename[i]);
-+          hd_filename[i] = NULL;
-+      }
++        if (media_filename[i] && bs_table[i]) {
++            do_change(bs_table[i]->device_name, media_filename[i]);
++            free(media_filename[i]);
++            media_filename[i] = NULL;
++        }
 +    }
 +}
 +
@@ -65,148 +39,176 @@ Index: ioemu/xenstore.c
 +{
 +
 +    if (insert_timer == NULL)
-+      insert_timer = qemu_new_timer(rt_clock, insert_media, NULL);
++        insert_timer = qemu_new_timer(rt_clock, insert_media, NULL);
 +    qemu_mod_timer(insert_timer, qemu_get_clock(rt_clock) + timeout);
 +}
 +
-+void xenstore_parse_domain_config(int domid)
-+{
++static void waitForDevice(char *fn)
++{ 
++    struct stat sbuf;
++    int status;
++    int uwait = UWAIT_MAX;
++
++    do {
++        status = stat(fn, &sbuf);
++        if (!status) break;
++        usleep(UWAIT);
++        uwait -= UWAIT;
++    } while (uwait > 0);
++
++    return;
++}
++
+ void xenstore_parse_domain_config(int domid)
+ {
+-    char *path;
 +    char **e = NULL;
 +    char *buf = NULL, *path;
-+    char *bpath = NULL, *dev = NULL, *params = NULL, *type = NULL;
++    char *fpath = NULL, *bpath = NULL,
++        *dev = NULL, *params = NULL, *type = NULL;
 +    int i;
 +    unsigned int len, num, hd_index;
 +
 +    for(i = 0; i < MAX_DISKS; i++)
-+        hd_filename[i] = NULL;
-+
-+    xsh = xs_daemon_open();
-+    if (xsh == NULL) {
-+      fprintf(logfile, "Could not contact xenstore for domain config\n");
-+      return;
-+    }
-+
-+    path = xs_get_domain_path(xsh, domid);
-+    if (path == NULL) {
-+        fprintf(logfile, "xs_get_domain_path() error\n");
++        media_filename[i] = NULL;
+ 
+     xsh = xs_daemon_open();
+     if (xsh == NULL) {
+@@ -44,8 +96,91 @@
+         goto out;
+     }
+ 
++    if (pasprintf(&buf, "%s/device/vbd", path) == -1)
 +        goto out;
-+    }
-+
-+    if (pasprintf(&buf, "%s/device/vbd", path) == -1)
-+      goto out;
 +
 +    e = xs_directory(xsh, XBT_NULL, buf, &num);
 +    if (e == NULL)
-+      goto out;
++        goto out;
 +
 +    for (i = 0; i < num; i++) {
-+      /* read the backend path */
-+      if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
-+          continue;
-+      free(bpath);
++        /* read the backend path */
++        if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
++            continue;
++        free(bpath);
 +        bpath = xs_read(xsh, XBT_NULL, buf, &len);
-+      if (bpath == NULL)
-+          continue;
-+      /* read the name of the device */
-+      if (pasprintf(&buf, "%s/dev", bpath) == -1)
-+          continue;
-+      free(dev);
-+      dev = xs_read(xsh, XBT_NULL, buf, &len);
-+      if (dev == NULL)
-+          continue;
-+      if (strncmp(dev, "hd", 2) || strlen(dev) != 3)
-+          continue;
-+      hd_index = dev[2] - 'a';
-+      if (hd_index >= MAX_DISKS)
-+          continue;
-+      /* read the type of the device */
-+      if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
-+          continue;
-+      free(type);
-+      type = xs_read(xsh, XBT_NULL, buf, &len);
-+      /* read params to get the patch of the image -- read it last
-+       * so that we have its path in buf when setting up the
-+       * watch */
-+      if (pasprintf(&buf, "%s/params", bpath) == -1)
-+          continue;
-+      free(params);
-+      params = xs_read(xsh, XBT_NULL, buf, &len);
-+      if (params == NULL)
-+          continue;
-+      if (params[0]) {
-+          hd_filename[hd_index] = params;     /* strdup() */
-+          params = NULL;              /* don't free params on re-use */
-+      }
-+      bs_table[hd_index] = bdrv_new(dev);
-+      /* check if it is a cdrom */
-+      if (type && !strcmp(type, "cdrom")) {
-+          bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
-+          xs_watch(xsh, buf, dev);
-+      }
-+      if (hd_filename[hd_index]) {
-+            if (bdrv_open(bs_table[hd_index], hd_filename[hd_index],
-+                        0 /* snapshot */) < 0)
++        if (bpath == NULL)
++            continue;
++        /* read the name of the device */
++        if (pasprintf(&buf, "%s/dev", bpath) == -1)
++            continue;
++        free(dev);
++        dev = xs_read(xsh, XBT_NULL, buf, &len);
++        if (dev == NULL)
++            continue;
++        if (strncmp(dev, "hd", 2) || strlen(dev) != 3)
++            continue;
++        hd_index = dev[2] - 'a';
++        if (hd_index >= MAX_DISKS)
++            continue;
++        /* read the type of the device */
++        if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
++            continue;
++        free(type);
++        type = xs_read(xsh, XBT_NULL, buf, &len);
++        if (pasprintf(&buf, "%s/params", bpath) == -1)
++            continue;
++        free(params);
++        params = xs_read(xsh, XBT_NULL, buf, &len);
++        if (params == NULL)
++            continue;
++        /* 
++         * check if device has a phantom vbd; the phantom is hooked
++         * to the frontend device (for ease of cleanup), so lookup 
++         * the frontend device, and see if there is a phantom_vbd
++         * if there is, we will use resolution as the filename
++         */
++        if (pasprintf(&buf, "%s/device/vbd/%s/phantom_vbd", path, e[i]) == -1)
++            continue;
++        free(fpath);
++        fpath = xs_read(xsh, XBT_NULL, buf, &len);
++        if (fpath) {
++            if (pasprintf(&buf, "%s/dev", fpath) == -1)
++                continue;
++            free(params);
++            params = xs_read(xsh, XBT_NULL, buf , &len);
++            if (params) {
++                /* 
++                 * wait for device, on timeout silently fail because we will 
++                 * fail to open below
++                 */
++                waitForDevice(params);
++            }
++        }
++
++        bs_table[hd_index] = bdrv_new(dev);
++        /* check if it is a cdrom */
++        if (type && !strcmp(type, "cdrom")) {
++            bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
++            if (pasprintf(&buf, "%s/params", bpath) != -1)
++                xs_watch(xsh, buf, dev);
++        }
++        /* open device now if media present */
++        if (params[0]) {
++            if (bdrv_open(bs_table[hd_index], params, 0 /* snapshot */) < 0)
 +                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
-+                        hd_filename[hd_index]);
-+      }
++                        params);
++        }
 +    }
 +
-+ out:
+  out:
 +    free(type);
 +    free(params);
 +    free(dev);
 +    free(bpath);
 +    free(buf);
-+    free(path);
+     free(path);
 +    free(e);
-+    return;
-+}
-+
-+int xenstore_fd(void)
-+{
-+    if (xsh)
-+      return xs_fileno(xsh);
-+    return -1;
-+}
-+
-+void xenstore_process_event(void *opaque)
-+{
+     return;
+ }
+ 
+@@ -58,14 +193,35 @@
+ 
+ void xenstore_process_event(void *opaque)
+ {
+-    char **vec;
+-    unsigned int num;
 +    char **vec, *image = NULL;
 +    unsigned int len, num, hd_index;
-+
-+    vec = xs_read_watch(xsh, &num);
-+    if (!vec)
-+      return;
-+
+ 
+     vec = xs_read_watch(xsh, &num);
+     if (!vec)
+         return;
+ 
 +    if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
-+      strlen(vec[XS_WATCH_TOKEN]) != 3)
-+      goto out;
++        strlen(vec[XS_WATCH_TOKEN]) != 3)
++        goto out;
 +    hd_index = vec[XS_WATCH_TOKEN][2] - 'a';
 +    image = xs_read(xsh, XBT_NULL, vec[XS_WATCH_PATH], &len);
 +    if (image == NULL || !strcmp(image, bs_table[hd_index]->filename))
-+      goto out;               /* gone or identical */
++        goto out;  /* gone or identical */
 +
 +    do_eject(0, vec[XS_WATCH_TOKEN]);
 +    bs_table[hd_index]->filename[0] = 0;
-+    if (hd_filename[hd_index]) {
-+      free(hd_filename[hd_index]);
-+      hd_filename[hd_index] = NULL;
++    if (media_filename[hd_index]) {
++        free(media_filename[hd_index]);
++        media_filename[hd_index] = NULL;
 +    }
 +
 +    if (image[0]) {
-+      hd_filename[hd_index] = strdup(image);
-+      xenstore_check_new_media_present(5000);
++        media_filename[hd_index] = strdup(image);
++        xenstore_check_new_media_present(5000);
 +    }
 +
-+ out:
+  out:
 +    free(image);
-+    free(vec);
-+}
+     free(vec);
+ }
+ 
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:21:52.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:53.000000000 +0000
-@@ -5256,9 +5256,11 @@
+--- ioemu.orig/vl.c    2007-05-03 15:17:52.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:18:05.000000000 +0100
+@@ -5331,9 +5331,11 @@
             "Standard options:\n"
             "-M machine      select emulated machine (-M ? for list)\n"
             "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
@@ -218,7 +220,7 @@ Index: ioemu/vl.c
             "-boot [a|c|d]   boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
           "-snapshot       write to temporary files instead of disk image 
files\n"
  #ifdef TARGET_I386
-@@ -5386,11 +5388,13 @@
+@@ -5460,11 +5462,13 @@
      QEMU_OPTION_M,
      QEMU_OPTION_fda,
      QEMU_OPTION_fdb,
@@ -232,7 +234,7 @@ Index: ioemu/vl.c
      QEMU_OPTION_boot,
      QEMU_OPTION_snapshot,
  #ifdef TARGET_I386
-@@ -5463,11 +5467,13 @@
+@@ -5536,11 +5540,13 @@
      { "M", HAS_ARG, QEMU_OPTION_M },
      { "fda", HAS_ARG, QEMU_OPTION_fda },
      { "fdb", HAS_ARG, QEMU_OPTION_fdb },
@@ -246,7 +248,7 @@ Index: ioemu/vl.c
      { "boot", HAS_ARG, QEMU_OPTION_boot },
      { "snapshot", 0, QEMU_OPTION_snapshot },
  #ifdef TARGET_I386
-@@ -5801,10 +5807,16 @@
+@@ -5882,10 +5888,16 @@
  #ifdef CONFIG_GDBSTUB
      int use_gdbstub, gdbstub_port;
  #endif
@@ -265,7 +267,7 @@ Index: ioemu/vl.c
      const char *kernel_filename, *kernel_cmdline;
      DisplayState *ds = &display_state;
      int cyls, heads, secs, translation;
-@@ -5865,8 +5877,10 @@
+@@ -5946,8 +5958,10 @@
      initrd_filename = NULL;
      for(i = 0; i < MAX_FD; i++)
          fd_filename[i] = NULL;
@@ -276,7 +278,7 @@ Index: ioemu/vl.c
      ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
      vga_ram_size = VGA_RAM_SIZE;
      bios_size = BIOS_SIZE;
-@@ -5880,11 +5894,13 @@
+@@ -5961,11 +5975,13 @@
      vncunused = 0;
      kernel_filename = NULL;
      kernel_cmdline = "";
@@ -289,8 +291,8 @@ Index: ioemu/vl.c
 +#endif /* !CONFIG_DM */
      cyls = heads = secs = 0;
      translation = BIOS_ATA_TRANSLATION_AUTO;
-     pstrcpy(monitor_device, sizeof(monitor_device), "vc");
-@@ -5919,7 +5935,11 @@
+     pstrcpy(monitor_device, sizeof(monitor_device), "null");
+@@ -6004,7 +6020,11 @@
              break;
          r = argv[optind];
          if (r[0] != '-') {
@@ -302,7 +304,7 @@ Index: ioemu/vl.c
          } else {
              const QEMUOption *popt;
  
-@@ -5963,6 +5983,7 @@
+@@ -6048,6 +6068,7 @@
              case QEMU_OPTION_initrd:
                  initrd_filename = optarg;
                  break;
@@ -310,7 +312,7 @@ Index: ioemu/vl.c
              case QEMU_OPTION_hda:
              case QEMU_OPTION_hdb:
              case QEMU_OPTION_hdc:
-@@ -5975,6 +5996,7 @@
+@@ -6060,6 +6081,7 @@
                          cdrom_index = -1;
                  }
                  break;
@@ -318,7 +320,7 @@ Index: ioemu/vl.c
              case QEMU_OPTION_snapshot:
                  snapshot = 1;
                  break;
-@@ -6027,11 +6049,13 @@
+@@ -6112,11 +6134,13 @@
              case QEMU_OPTION_append:
                  kernel_cmdline = optarg;
                  break;
@@ -332,18 +334,15 @@ Index: ioemu/vl.c
              case QEMU_OPTION_boot:
                  boot_device = optarg[0];
                  if (boot_device != 'a' && 
-@@ -6289,12 +6313,18 @@
-         }
+@@ -6372,6 +6396,7 @@
      }
  
-+#ifdef CONFIG_DM
+ #ifdef CONFIG_DM
 +    bdrv_init();
-+    xenstore_parse_domain_config(domid);
-+#endif /* CONFIG_DM */
-+
- #ifdef USE_KQEMU
-     if (smp_cpus > 1)
-         kqemu_allowed = 0;
+     xenstore_parse_domain_config(domid);
+ #endif /* CONFIG_DM */
+ 
+@@ -6381,6 +6406,7 @@
  #endif
      linux_boot = (kernel_filename != NULL);
          
@@ -351,7 +350,7 @@ Index: ioemu/vl.c
      if (!linux_boot && 
          hd_filename[0] == '\0' && 
          (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
-@@ -6308,6 +6338,7 @@
+@@ -6394,6 +6420,7 @@
          else
              boot_device = 'd';
      }
@@ -359,7 +358,7 @@ Index: ioemu/vl.c
  
      setvbuf(stdout, NULL, _IOLBF, 0);
      
-@@ -6433,6 +6464,7 @@
+@@ -6514,6 +6541,7 @@
  
  #endif /* !CONFIG_DM */
  
@@ -367,7 +366,7 @@ Index: ioemu/vl.c
      /* we always create the cdrom drive, even if no disk is there */
      bdrv_init();
      if (cdrom_index >= 0) {
-@@ -6459,6 +6491,7 @@
+@@ -6540,6 +6568,7 @@
              }
          }
      }
@@ -375,19 +374,10 @@ Index: ioemu/vl.c
  
      /* we always create at least one floppy disk */
      fd_table[0] = bdrv_new("fda");
-@@ -6537,6 +6570,8 @@
-         }
-     }
- 
-+    qemu_set_fd_handler(xenstore_fd(), xenstore_process_event, NULL, NULL);
-+
-     machine->init(ram_size, vga_ram_size, boot_device,
-                   ds, fd_filename, snapshot,
-                   kernel_filename, kernel_cmdline, initrd_filename,
 Index: ioemu/monitor.c
 ===================================================================
---- ioemu.orig/monitor.c       2006-12-20 15:21:47.000000000 +0000
-+++ ioemu/monitor.c    2006-12-20 15:21:53.000000000 +0000
+--- ioemu.orig/monitor.c       2007-05-03 15:17:52.000000000 +0100
++++ ioemu/monitor.c    2007-05-03 15:18:05.000000000 +0100
 @@ -24,6 +24,7 @@
  #include "vl.h"
  #include "disas.h"
@@ -416,8 +406,8 @@ Index: ioemu/monitor.c
      int i;
 Index: ioemu/block.c
 ===================================================================
---- ioemu.orig/block.c 2006-12-20 15:21:31.000000000 +0000
-+++ ioemu/block.c      2006-12-20 15:21:53.000000000 +0000
+--- ioemu.orig/block.c 2007-05-03 15:17:52.000000000 +0100
++++ ioemu/block.c      2007-05-03 15:18:05.000000000 +0100
 @@ -758,6 +758,7 @@
  static void raw_close(BlockDriverState *bs)
  {
@@ -428,9 +418,9 @@ Index: ioemu/block.c
  
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:21:52.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:53.000000000 +0000
-@@ -1191,6 +1191,8 @@
+--- ioemu.orig/vl.h    2007-05-03 15:18:00.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:18:05.000000000 +0100
+@@ -1192,6 +1192,8 @@
  void term_print_help(void);
  void monitor_readline(const char *prompt, int is_password,
                        char *buf, int buf_size);
@@ -439,25 +429,21 @@ Index: ioemu/vl.h
  
  /* readline.c */
  typedef void ReadLineFunc(void *opaque, const char *str);
-@@ -1203,6 +1205,13 @@
- void readline_start(const char *prompt, int is_password,
-                     ReadLineFunc *readline_func, void *opaque);
- 
-+/* xenstore.c */
-+void xenstore_parse_domain_config(int domid);
+@@ -1206,6 +1208,9 @@
+ 
+ /* xenstore.c */
+ void xenstore_parse_domain_config(int domid);
 +int xenstore_fd(void);
 +void xenstore_process_event(void *opaque);
 +void xenstore_check_new_media_present(int timeout);
-+
-+
- void kqemu_record_dump(void);
- 
- extern char domain_name[];
+ 
+ int xenstore_vm_write(int domid, char *key, char *val);
+ char *xenstore_vm_read(int domid, char *key, int *len);
 Index: ioemu/hw/ide.c
 ===================================================================
---- ioemu.orig/hw/ide.c        2006-12-20 15:21:49.000000000 +0000
-+++ ioemu/hw/ide.c     2006-12-20 15:21:53.000000000 +0000
-@@ -1158,6 +1158,7 @@
+--- ioemu.orig/hw/ide.c        2007-05-03 15:17:52.000000000 +0100
++++ ioemu/hw/ide.c     2007-05-03 15:18:05.000000000 +0100
+@@ -1199,6 +1199,7 @@
          } else {
              ide_atapi_cmd_error(s, SENSE_NOT_READY, 
                                  ASC_MEDIUM_NOT_PRESENT);
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/ioemu/patches/xenstore-device-info-functions
--- a/tools/ioemu/patches/xenstore-device-info-functions        Mon May 07 
13:24:37 2007 -0600
+++ b/tools/ioemu/patches/xenstore-device-info-functions        Tue May 08 
09:09:17 2007 -0600
@@ -15,13 +15,12 @@ Signed-off-by: Stefan Berger <stefanb@us
 
 Index: ioemu/xenstore.c
 ===================================================================
---- ioemu.orig/xenstore.c      2006-12-08 18:20:53.000000000 +0000
-+++ ioemu/xenstore.c   2006-12-08 18:20:53.000000000 +0000
-@@ -264,3 +264,140 @@
- 
+--- ioemu.orig/xenstore.c      2007-05-03 15:21:22.000000000 +0100
++++ ioemu/xenstore.c   2007-05-03 15:22:05.000000000 +0100
+@@ -304,6 +304,143 @@
      return rc;
  }
-+
+ 
 +
 +/*
 + * get all device instances of a certain type
@@ -38,7 +37,7 @@ Index: ioemu/xenstore.c
 +        goto out;
 +
 +    if (pasprintf(&buf, "%s/device/%s", path,devtype) == -1)
-+      goto out;
++        goto out;
 +
 +    e = xs_directory(handle, XBT_NULL, buf, num);
 +
@@ -91,13 +90,13 @@ Index: ioemu/xenstore.c
 +
 +    buf = get_device_variable_path(devtype, inst, var);
 +    if (NULL == buf)
-+      goto out;
++        goto out;
 +
 +    value = xs_read(handle, XBT_NULL, buf, &len);
 +
 +    free(buf);
 +
-+out:
++ out:
 +    return value;
 +}
 +
@@ -158,11 +157,15 @@ Index: ioemu/xenstore.c
 +
 +    return rc;
 +}
++
+ char *xenstore_vm_read(int domid, char *key, int *len)
+ {
+     char *buf = NULL, *path = NULL, *value = NULL;
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-08 18:20:53.000000000 +0000
-+++ ioemu/vl.h 2006-12-08 18:20:53.000000000 +0000
-@@ -1216,6 +1216,25 @@
+--- ioemu.orig/vl.h    2007-05-03 15:21:09.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:21:47.000000000 +0100
+@@ -1217,6 +1217,24 @@
  void xenstore_write_vncport(int vnc_display);
  int xenstore_read_vncpasswd(int domid);
  
@@ -184,7 +187,6 @@ Index: ioemu/vl.h
 +                                             const char *inst,
 +                                             const char *token);
 +
-+
- /* xen_platform.c */
- void pci_xen_platform_init(PCIBus *bus);
+ int xenstore_vm_write(int domid, char *key, char *val);
+ char *xenstore_vm_read(int domid, char *key, int *len);
  
diff -r d1ce60b8070f -r d7303c4a9dab tools/ioemu/patches/xenstore-write-vnc-port
--- a/tools/ioemu/patches/xenstore-write-vnc-port       Mon May 07 13:24:37 
2007 -0600
+++ b/tools/ioemu/patches/xenstore-write-vnc-port       Tue May 08 09:09:17 
2007 -0600
@@ -1,19 +1,18 @@ Index: ioemu/xenstore.c
 Index: ioemu/xenstore.c
 ===================================================================
---- ioemu.orig/xenstore.c      2006-12-20 15:21:53.000000000 +0000
-+++ ioemu/xenstore.c   2006-12-20 15:21:54.000000000 +0000
-@@ -185,3 +185,31 @@
-     free(image);
+--- ioemu.orig/xenstore.c      2007-05-03 15:18:05.000000000 +0100
++++ ioemu/xenstore.c   2007-05-03 15:18:17.000000000 +0100
+@@ -225,6 +225,34 @@
      free(vec);
  }
-+
+ 
 +void xenstore_write_vncport(int display)
 +{
 +    char *buf = NULL, *path;
 +    char *portstr = NULL;
 +
 +    if (xsh == NULL)
-+      return;
++        return;
 +
 +    path = xs_get_domain_path(xsh, domid);
 +    if (path == NULL) {
@@ -22,10 +21,10 @@ Index: ioemu/xenstore.c
 +    }
 +
 +    if (pasprintf(&buf, "%s/console/vnc-port", path) == -1)
-+      goto out;
++        goto out;
 +
 +    if (pasprintf(&portstr, "%d", 5900 + display) == -1)
-+      goto out;
++        goto out;
 +
 +    if (xs_write(xsh, XBT_NULL, buf, portstr, strlen(portstr)) == 0)
 +        fprintf(logfile, "xs_write() vncport failed\n");
@@ -34,11 +33,15 @@ Index: ioemu/xenstore.c
 +    free(portstr);
 +    free(buf);
 +}
++
+ char *xenstore_vm_read(int domid, char *key, int *len)
+ {
+     char *buf = NULL, *path = NULL, *value = NULL;
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-12-20 15:21:53.000000000 +0000
-+++ ioemu/vl.c 2006-12-20 15:21:54.000000000 +0000
-@@ -6527,6 +6527,7 @@
+--- ioemu.orig/vl.c    2007-05-03 15:18:05.000000000 +0100
++++ ioemu/vl.c 2007-05-03 15:18:17.000000000 +0100
+@@ -6604,6 +6604,7 @@
        vnc_display = vnc_display_init(ds, vnc_display, vncunused, 
&vnclisten_addr);
        if (vncviewer)
            vnc_start_viewer(vnc_display);
@@ -48,13 +51,13 @@ Index: ioemu/vl.c
          sdl_display_init(ds, full_screen);
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-12-20 15:21:53.000000000 +0000
-+++ ioemu/vl.h 2006-12-20 15:21:54.000000000 +0000
-@@ -1210,6 +1210,7 @@
+--- ioemu.orig/vl.h    2007-05-03 15:18:05.000000000 +0100
++++ ioemu/vl.h 2007-05-03 15:18:17.000000000 +0100
+@@ -1211,6 +1211,7 @@
  int xenstore_fd(void);
  void xenstore_process_event(void *opaque);
  void xenstore_check_new_media_present(int timeout);
 +void xenstore_write_vncport(int vnc_display);
  
- 
- void kqemu_record_dump(void);
+ int xenstore_vm_write(int domid, char *key, char *val);
+ char *xenstore_vm_read(int domid, char *key, int *len);
diff -r d1ce60b8070f -r d7303c4a9dab tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Mon May 07 13:24:37 2007 -0600
+++ b/tools/libxc/xc_hvm_build.c        Tue May 08 09:09:17 2007 -0600
@@ -108,43 +108,45 @@ static void build_e820map(void *e820_pag
     *(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map;
 }
 
-static int
-loadelfimage(struct elf_binary *elf, int xch, uint32_t dom, unsigned long 
*parray)
+static int loadelfimage(
+    struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray)
 {
     privcmd_mmap_entry_t *entries = NULL;
     int pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT;
     int i, rc = -1;
 
-    /* map hvmloader address space */
+    /* Map address space for initial elf image. */
     entries = malloc(pages * sizeof(privcmd_mmap_entry_t));
-    if (NULL == entries)
+    if ( entries == NULL )
         goto err;
     elf->dest = mmap(NULL, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE,
                      MAP_SHARED, xch, 0);
-    if (MAP_FAILED == elf->dest)
+    if ( elf->dest == MAP_FAILED )
         goto err;
 
-    for (i = 0; i < pages; i++)
+    for ( i = 0; i < pages; i++ )
     {
         entries[i].va = (uintptr_t)elf->dest + (i << PAGE_SHIFT);
         entries[i].mfn = parray[(elf->pstart >> PAGE_SHIFT) + i];
         entries[i].npages = 1;
     }
+
     rc = xc_map_foreign_ranges(xch, dom, entries, pages);
-    if (rc < 0)
+    if ( rc < 0 )
         goto err;
 
-    /* load hvmloader */
+    /* Load the initial elf image. */
     elf_load_binary(elf);
     rc = 0;
 
  err:
-    /* cleanup */
-    if (elf->dest) {
+    if ( elf->dest )
+    {
         munmap(elf->dest, pages << PAGE_SHIFT);
         elf->dest = NULL;
     }
-    if (entries)
+
+    if ( entries )
         free(entries);
 
     return rc;
@@ -166,13 +168,17 @@ static int setup_guest(int xc_handle,
     int rc;
     xen_capabilities_info_t caps;
 
-    if (0 != elf_init(&elf, image, image_size))
+    /* An HVM guest must be initialised with at least 2MB memory. */
+    if ( memsize < 2 )
+        goto error_out;
+
+    if ( elf_init(&elf, image, image_size) != 0 )
         goto error_out;
     elf_parse_binary(&elf);
     v_start = 0;
     v_end = (unsigned long long)memsize << 20;
 
-    if (xc_version(xc_handle, XENVER_capabilities, &caps) != 0)
+    if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 )
     {
         PERROR("Could not get Xen capabilities\n");
         goto error_out;
@@ -185,9 +191,9 @@ static int setup_guest(int xc_handle,
     }
 
     IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
-            "  Loaded HVM loader:    %016"PRIx64"->%016"PRIx64"\n"
-            "  TOTAL:                %016"PRIx64"->%016"PRIx64"\n"
-            "  ENTRY ADDRESS:        %016"PRIx64"\n",
+            "  Loader:        %016"PRIx64"->%016"PRIx64"\n"
+            "  TOTAL:         %016"PRIx64"->%016"PRIx64"\n"
+            "  ENTRY ADDRESS: %016"PRIx64"\n",
             elf.pstart, elf.pend,
             v_start, v_end,
             elf_uval(&elf, elf.ehdr, e_entry));
@@ -205,9 +211,8 @@ static int setup_guest(int xc_handle,
 
     /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */
     rc = xc_domain_memory_populate_physmap(
-        xc_handle, dom, (nr_pages > 0xa0) ? 0xa0 : nr_pages,
-        0, 0, &page_array[0x00]);
-    if ( (rc == 0) && (nr_pages > 0xc0) )
+        xc_handle, dom, 0xa0, 0, 0, &page_array[0x00]);
+    if ( rc == 0 )
         rc = xc_domain_memory_populate_physmap(
             xc_handle, dom, nr_pages - 0xc0, 0, 0, &page_array[0xc0]);
     if ( rc != 0 )
@@ -216,7 +221,8 @@ static int setup_guest(int xc_handle,
         goto error_out;
     }
 
-    loadelfimage(&elf, xc_handle, dom, page_array);
+    if ( loadelfimage(&elf, xc_handle, dom, page_array) != 0 )
+        goto error_out;
 
     if ( (e820_page = xc_map_foreign_range(
               xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
@@ -328,12 +334,9 @@ static inline int is_loadable_phdr(Elf32
             ((phdr->p_flags & (PF_W|PF_X)) != 0));
 }
 
-/* xc_hvm_build
- *
- * Create a domain for a virtualized Linux, using files/filenames
- *
+/* xc_hvm_build:
+ * Create a domain for a virtualized Linux, using files/filenames.
  */
-
 int xc_hvm_build(int xc_handle,
                  uint32_t domid,
                  int memsize,
@@ -354,12 +357,9 @@ int xc_hvm_build(int xc_handle,
     return sts;
 }
 
-/* xc_hvm_build_mem
- *
- * Create a domain for a virtualized Linux, using buffers
- *
+/* xc_hvm_build_mem:
+ * Create a domain for a virtualized Linux, using memory buffers.
  */
-
 int xc_hvm_build_mem(int xc_handle,
                      uint32_t domid,
                      int memsize,
@@ -379,7 +379,7 @@ int xc_hvm_build_mem(int xc_handle,
     }
 
     img = xc_inflate_buffer(image_buffer, image_size, &img_len);
-    if (img == NULL)
+    if ( img == NULL )
     {
         ERROR("unable to inflate ram disk buffer");
         return -1;
diff -r d1ce60b8070f -r d7303c4a9dab tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Mon May 07 13:24:37 2007 -0600
+++ b/tools/python/xen/xend/XendAPI.py  Tue May 08 09:09:17 2007 -0600
@@ -1009,7 +1009,7 @@ class XendAPI(object):
                   'cpu_configuration': node.get_cpu_configuration(),
                   'metrics': node.host_metrics_uuid,
                   'capabilities': node.get_capabilities(),
-                  'supported_bootloaders': 'pygrub',
+                  'supported_bootloaders': ['pygrub'],
                   'sched_policy': node.get_vcpus_policy()}
         return xen_api_success(record)
 
diff -r d1ce60b8070f -r d7303c4a9dab tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon May 07 13:24:37 2007 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue May 08 09:09:17 2007 -0600
@@ -867,7 +867,10 @@ class XendDomainInfo:
 
         # convert two lists into a python dictionary
         vm_details = dict(zip(cfg_vm, vm_details))
-        
+
+        if vm_details['rtc/timeoffset'] == None:
+            vm_details['rtc/timeoffset'] = "0"
+
         for arg, val in vm_details.items():
             if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
                 xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
diff -r d1ce60b8070f -r d7303c4a9dab tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Mon May 07 13:24:37 2007 -0600
+++ b/tools/python/xen/xend/image.py    Tue May 08 09:09:17 2007 -0600
@@ -418,7 +418,7 @@ class HVMImageHandler(ImageHandler):
             ret.append('-nographic')
 
         if int(vmConfig['platform'].get('monitor', 0)) != 0:
-            ret.append('-monitor vc')
+            ret = ret + ['-monitor', 'vc']
         return ret
 
     def createDeviceModel(self, restore = False):
diff -r d1ce60b8070f -r d7303c4a9dab 
tools/xenstat/libxenstat/src/xenstat_linux.c
--- a/tools/xenstat/libxenstat/src/xenstat_linux.c      Mon May 07 13:24:37 
2007 -0600
+++ b/tools/xenstat/libxenstat/src/xenstat_linux.c      Tue May 08 09:09:17 
2007 -0600
@@ -206,10 +206,8 @@ int xenstat_collect_vbds(xenstat_node * 
 
 
                ret = sscanf(dp->d_name, "vbd-%u-%u", &domid, &vbd.dev);
-               if (ret != 2) {
-                       continue;
-               }
-               printf("%s is VBD.\n",dp->d_name);
+               if (ret != 2)
+                       continue;
 
                domain = xenstat_node_domain(node, domid);
                if (domain == NULL) {

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.