WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [qemu patches] Update patches upto change

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [qemu patches] Update patches upto changeset 14986:1ddaf2650633.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 03 May 2007 14:20:06 -0700
Delivery-date: Thu, 03 May 2007 14:18:52 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Christian Limpach <Christian.Limpach@xxxxxxxxxxxxx>
# Date 1178203185 -3600
# Node ID 623a07dda15cd5ef4aae403ad18a9ecc9bda8ec6
# Parent  c857bf38f0157cb31fe9bdf8f0161047063c0fd1
[qemu patches] Update patches upto changeset 14986:1ddaf2650633.

Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxxx>
---
 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 -
 68 files changed, 1890 insertions(+), 1179 deletions(-)

diff -r c857bf38f015 -r 623a07dda15c tools/ioemu/patches/acpi-poweroff-support
--- a/tools/ioemu/patches/acpi-poweroff-support Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/acpi-poweroff-support Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/acpi-support
--- a/tools/ioemu/patches/acpi-support  Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/acpi-support  Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/acpi-timer-support
--- a/tools/ioemu/patches/acpi-timer-support    Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/acpi-timer-support    Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/domain-destroy
--- a/tools/ioemu/patches/domain-destroy        Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/domain-destroy        Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/domain-reset
--- a/tools/ioemu/patches/domain-reset  Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/domain-reset  Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/domain-timeoffset
--- a/tools/ioemu/patches/domain-timeoffset     Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/domain-timeoffset     Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/hypervisor-pit
--- a/tools/ioemu/patches/hypervisor-pit        Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/hypervisor-pit        Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/ide-cd-dma
--- a/tools/ioemu/patches/ide-cd-dma    Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/ide-cd-dma    Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/ide-error-reporting
--- a/tools/ioemu/patches/ide-error-reporting   Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/ide-error-reporting   Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/ide-hd-multithread
--- a/tools/ioemu/patches/ide-hd-multithread    Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/ide-hd-multithread    Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 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 Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/ioemu-ia64
--- a/tools/ioemu/patches/ioemu-ia64    Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/ioemu-ia64    Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/ioemu-save-restore
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ioemu-save-restore    Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 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       Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 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        Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
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   Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
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     Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
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      Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
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    Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
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      Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 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        Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/nodelay-serial-over-tcp
--- a/tools/ioemu/patches/nodelay-serial-over-tcp       Thu May 03 11:22:58 
2007 +0100
+++ b/tools/ioemu/patches/nodelay-serial-over-tcp       Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-64bit
--- a/tools/ioemu/patches/qemu-64bit    Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-64bit    Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
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       Thu May 03 
15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-bootorder
--- a/tools/ioemu/patches/qemu-bootorder        Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-bootorder        Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
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     Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-cleanup
--- a/tools/ioemu/patches/qemu-cleanup  Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-cleanup  Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-daemonize
--- a/tools/ioemu/patches/qemu-daemonize        Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-daemonize        Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-dm
--- a/tools/ioemu/patches/qemu-dm       Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-dm       Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
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   Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-logging
--- a/tools/ioemu/patches/qemu-logging  Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-logging  Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-pci
--- a/tools/ioemu/patches/qemu-pci      Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-pci      Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 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   Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-serial-fixes
--- a/tools/ioemu/patches/qemu-serial-fixes     Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-serial-fixes     Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-smp
--- a/tools/ioemu/patches/qemu-smp      Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-smp      Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-target-i386-dm
--- a/tools/ioemu/patches/qemu-target-i386-dm   Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-target-i386-dm   Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/qemu-timer
--- a/tools/ioemu/patches/qemu-timer    Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/qemu-timer    Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
tools/ioemu/patches/qemu-tunable-ide-write-cache
--- a/tools/ioemu/patches/qemu-tunable-ide-write-cache  Thu May 03 11:22:58 
2007 +0100
+++ b/tools/ioemu/patches/qemu-tunable-ide-write-cache  Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/scsi
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/scsi  Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/serial-non-block
--- a/tools/ioemu/patches/serial-non-block      Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/serial-non-block      Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/series
--- a/tools/ioemu/patches/series        Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/series        Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/shadow-vram
--- a/tools/ioemu/patches/shadow-vram   Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/shadow-vram   Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/shared-vram
--- a/tools/ioemu/patches/shared-vram   Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/shared-vram   Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/support-xm-console
--- a/tools/ioemu/patches/support-xm-console    Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/support-xm-console    Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/tpm-tis-device
--- a/tools/ioemu/patches/tpm-tis-device        Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/tpm-tis-device        Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
tools/ioemu/patches/usb-mouse-tablet-status-check
--- a/tools/ioemu/patches/usb-mouse-tablet-status-check Thu May 03 11:22:58 
2007 +0100
+++ b/tools/ioemu/patches/usb-mouse-tablet-status-check Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/vnc-altgr-keysym
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/vnc-altgr-keysym      Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/vnc-backoff-screen-scan
--- a/tools/ioemu/patches/vnc-backoff-screen-scan       Thu May 03 11:22:58 
2007 +0100
+++ b/tools/ioemu/patches/vnc-backoff-screen-scan       Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/vnc-cleanup
--- a/tools/ioemu/patches/vnc-cleanup   Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/vnc-cleanup   Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/vnc-display-find-unused
--- a/tools/ioemu/patches/vnc-display-find-unused       Thu May 03 11:22:58 
2007 +0100
+++ b/tools/ioemu/patches/vnc-display-find-unused       Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/vnc-fix-signedness
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/vnc-fix-signedness    Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 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 Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/vnc-fixes
--- a/tools/ioemu/patches/vnc-fixes     Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/vnc-fixes     Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
tools/ioemu/patches/vnc-listen-specific-interface
--- a/tools/ioemu/patches/vnc-listen-specific-interface Thu May 03 11:22:58 
2007 +0100
+++ b/tools/ioemu/patches/vnc-listen-specific-interface Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/vnc-password
--- a/tools/ioemu/patches/vnc-password  Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/vnc-password  Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/vnc-start-vncviewer
--- a/tools/ioemu/patches/vnc-start-vncviewer   Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/vnc-start-vncviewer   Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/xen-build
--- a/tools/ioemu/patches/xen-build     Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/xen-build     Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/xen-domain-name
--- a/tools/ioemu/patches/xen-domain-name       Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/xen-domain-name       Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/xen-domid
--- a/tools/ioemu/patches/xen-domid     Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/xen-domid     Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/xen-mapcache
--- a/tools/ioemu/patches/xen-mapcache  Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/xen-mapcache  Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/xen-mm
--- a/tools/ioemu/patches/xen-mm        Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/xen-mm        Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/xen-network
--- a/tools/ioemu/patches/xen-network   Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/xen-network   Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/xen-platform-device
--- a/tools/ioemu/patches/xen-platform-device   Thu May 03 11:22:58 2007 +0100
+++ b/tools/ioemu/patches/xen-platform-device   Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
tools/ioemu/patches/xen-support-buffered-ioreqs
--- a/tools/ioemu/patches/xen-support-buffered-ioreqs   Thu May 03 11:22:58 
2007 +0100
+++ b/tools/ioemu/patches/xen-support-buffered-ioreqs   Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/xenstore
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/xenstore      Thu May 03 15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
tools/ioemu/patches/xenstore-block-device-config
--- a/tools/ioemu/patches/xenstore-block-device-config  Thu May 03 11:22:58 
2007 +0100
+++ b/tools/ioemu/patches/xenstore-block-device-config  Thu May 03 15:39:45 
2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c 
tools/ioemu/patches/xenstore-device-info-functions
--- a/tools/ioemu/patches/xenstore-device-info-functions        Thu May 03 
11:22:58 2007 +0100
+++ b/tools/ioemu/patches/xenstore-device-info-functions        Thu May 03 
15:39:45 2007 +0100
@@ -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 c857bf38f015 -r 623a07dda15c tools/ioemu/patches/xenstore-write-vnc-port
--- a/tools/ioemu/patches/xenstore-write-vnc-port       Thu May 03 11:22:58 
2007 +0100
+++ b/tools/ioemu/patches/xenstore-write-vnc-port       Thu May 03 15:39:45 
2007 +0100
@@ -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);

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [qemu patches] Update patches upto changeset 14986:1ddaf2650633., Xen patchbot-unstable <=