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

[Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxxx
# Node ID 8cddaee4a51cb0c905a87e2ef85d1a8c54e4d963
# Parent  1cfd862e5254fa7c9614035035586a3f182a530f
# Parent  1ad7dff99968ae1d801900854e1a418630f06c21
Merge with xen-ia64-unstable.hg
---
 tools/ioemu/patches/acpi-support                     |   41 --
 tools/ioemu/patches/acpi-timer-support               |    8 
 tools/ioemu/patches/domain-destroy                   |   12 
 tools/ioemu/patches/domain-reset                     |    8 
 tools/ioemu/patches/domain-timeoffset                |   12 
 tools/ioemu/patches/fix-interrupt-routing            |   55 +++
 tools/ioemu/patches/hypervisor-pit                   |    8 
 tools/ioemu/patches/hypervisor-rtc                   |   12 
 tools/ioemu/patches/ide-error-reporting              |   85 +++++
 tools/ioemu/patches/ioemu-ia64                       |   72 ----
 tools/ioemu/patches/limit-fdc-sector-size-to-16K     |   30 +
 tools/ioemu/patches/ne2000-bounds-checks             |   79 +++++
 tools/ioemu/patches/nodelay-serial-over-tcp          |   25 +
 tools/ioemu/patches/qemu-bootorder                   |   14 
 tools/ioemu/patches/qemu-daemonize                   |    4 
 tools/ioemu/patches/qemu-dm                          |   20 -
 tools/ioemu/patches/qemu-no-apic                     |    6 
 tools/ioemu/patches/qemu-pci                         |   18 -
 tools/ioemu/patches/qemu-serial-fixes                |   79 +++++
 tools/ioemu/patches/qemu-target-i386-dm              |  149 ---------
 tools/ioemu/patches/remove-pci-bridge-setup          |  287 +++++++++++++++++++
 tools/ioemu/patches/rtl8139-bound-chaining           |   31 ++
 tools/ioemu/patches/series                           |   16 +
 tools/ioemu/patches/shared-vram                      |   30 -
 tools/ioemu/patches/tpm-tis-device                   |   56 +++
 tools/ioemu/patches/usb-mouse-tablet-status-check    |  124 ++++++++
 tools/ioemu/patches/usb-uhci-buffer-size             |   23 +
 tools/ioemu/patches/vnc-access-monitor-vt            |    4 
 tools/ioemu/patches/vnc-backoff-screen-scan          |   22 -
 tools/ioemu/patches/vnc-display-find-unused          |   20 -
 tools/ioemu/patches/vnc-fixes                        |   46 +--
 tools/ioemu/patches/vnc-japan-keymap                 |   24 +
 tools/ioemu/patches/vnc-listen-specific-interface    |   18 -
 tools/ioemu/patches/vnc-monitor-shift-key-processing |   41 ++
 tools/ioemu/patches/vnc-numpad-handling              |  126 ++++++++
 tools/ioemu/patches/vnc-password                     |   68 ++--
 tools/ioemu/patches/vnc-protocol-fixes               |    8 
 tools/ioemu/patches/vnc-start-vncviewer              |   14 
 tools/ioemu/patches/vnc-title-domain-name            |    6 
 tools/ioemu/patches/xen-build                        |   18 -
 tools/ioemu/patches/xen-mapcache                     |  145 +++++++++
 tools/ioemu/patches/xen-mm                           |   18 -
 tools/ioemu/patches/xen-platform-device              |    9 
 tools/ioemu/patches/xen-support-buffered-ioreqs      |   28 -
 tools/ioemu/patches/xenstore-block-device-config     |   40 +-
 tools/ioemu/patches/xenstore-device-info-functions   |   32 ++
 tools/ioemu/patches/xenstore-write-vnc-port          |    8 
 tools/libxc/Makefile                                 |    4 
 tools/libxc/xc_private.c                             |   22 -
 tools/python/xen/xend/XendConfig.py                  |   18 -
 tools/python/xen/xend/server/netif.py                |    4 
 tools/python/xen/xm/main.py                          |    4 
 52 files changed, 1557 insertions(+), 494 deletions(-)

diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/acpi-support
--- a/tools/ioemu/patches/acpi-support  Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/acpi-support  Sat Dec 09 14:34:53 2006 +0000
@@ -1,8 +1,8 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-08-17 19:49:50.228216099 +0100
-+++ ioemu/Makefile.target      2006-08-17 19:50:02.405870095 +0100
-@@ -357,6 +357,7 @@
+--- ioemu.orig/Makefile.target 2006-12-08 02:00:40.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 02:00:40.000000000 +0000
+@@ -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
  VL_OBJS+= usb-uhci.o
@@ -12,8 +12,8 @@ Index: ioemu/Makefile.target
  ifeq ($(TARGET_BASE_ARCH), ppc)
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-08-17 19:49:59.312212039 +0100
-+++ ioemu/hw/pc.c      2006-08-17 19:50:02.406869984 +0100
+--- 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);
@@ -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-08-17 19:50:02.407869874 +0100
-@@ -0,0 +1,388 @@
++++ ioemu/hw/piix4acpi.c       2006-12-08 02:00:40.000000000 +0000
+@@ -0,0 +1,396 @@
 +/*
 + * PIIX4 ACPI controller emulation
 + *
@@ -434,15 +434,23 @@ Index: ioemu/hw/piix4acpi.c
 +    pci_conf[0x0e] = 0x00;
 +    pci_conf[0x3d] = 0x01;  /* Hardwired to PIRQA is used */
 +
-+    pci_register_io_region((PCIDevice *)d, 4, 0x10,
-+                           PCI_ADDRESS_SPACE_IO, acpi_map);
-+
-+    acpi_reset (d);
++
++    /* PMBA POWER MANAGEMENT BASE ADDRESS, hardcoded to 0x1f40 
++     * to make shutdown work for IPF, due to IPF Guest Firmware 
++     * will enumerate pci devices. 
++     *
++     * TODO:  if Guest Firmware or Guest OS will change this PMBA,
++     * More logic will be added.
++     */
++    pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */
++    pci_conf[0x41] = 0x1f;
++    acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
++    acpi_reset(d);
 +}
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:49:59.315211708 +0100
-+++ ioemu/vl.c 2006-08-17 19:50:02.410869542 +0100
+--- 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 @@
  #else
  #define MAX_CPUS 1
@@ -476,7 +484,7 @@ Index: ioemu/vl.c
      { NULL },
  };
  
-@@ -6256,6 +6259,9 @@
+@@ -6240,6 +6243,9 @@
              case QEMU_OPTION_timeoffset:
                  timeoffset = strtol(optarg, NULL, 0);
                  break;
@@ -488,8 +496,8 @@ Index: ioemu/vl.c
      }
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:49:59.316211597 +0100
-+++ ioemu/vl.h 2006-08-17 19:50:02.411869432 +0100
+--- ioemu.orig/vl.h    2006-12-08 02:00:40.000000000 +0000
++++ ioemu/vl.h 2006-12-08 02:00:40.000000000 +0000
 @@ -168,6 +168,7 @@
  extern int kqemu_allowed;
  extern int win2k_install_hack;
@@ -510,8 +518,8 @@ Index: ioemu/vl.h
  extern QEMUMachine isapc_machine;
 Index: ioemu/hw/piix_pci.c
 ===================================================================
---- ioemu.orig/hw/piix_pci.c   2006-08-17 19:38:05.806252180 +0100
-+++ ioemu/hw/piix_pci.c        2006-08-17 19:50:02.411869432 +0100
+--- 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
 @@ -241,7 +241,7 @@
  static uint32_t pci_bios_io_addr;
  static uint32_t pci_bios_mem_addr;
@@ -521,33 +529,22 @@ Index: ioemu/hw/piix_pci.c
  
  static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
  {
-@@ -336,6 +336,14 @@
+@@ -336,6 +336,18 @@
              pci_set_io_region_addr(d, 3, 0x374);
          }
          break;
 +    case 0x0680:
 +        if (vendor_id == 0x8086 && device_id == 0x7113) {
-+            /* PIIX4 ACPI PM */
-+            pci_config_writew(d, 0x20, 0x0000); /* NO smb bus IO enable in 
PIIX4 */
++            /*
++             * PIIX4 ACPI PM.
++             * Special device with special PCI config space. No ordinary BARs.
++             */
++            pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
 +            pci_config_writew(d, 0x22, 0x0000);
-+            goto default_map;
++            pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
++            pci_config_writew(d, 0x3d, 0x0001);
 +        }
 +        break;
      case 0x0300:
          if (vendor_id != 0x1234)
              goto default_map;
-@@ -386,6 +394,14 @@
-         pic_irq = pci_irqs[pin];
-         pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
-     }
-+
-+    if (class== 0x0680&& vendor_id == 0x8086 && device_id == 0x7113) {
-+         // PIIX4 ACPI PM
-+       pci_config_writew(d, 0x20, 0x0000); // NO smb bus IO enable in PIIX4
-+       pci_config_writew(d, 0x22, 0x0000);
-+       pci_config_writew(d, 0x3c, 0x0009); // Hardcodeed IRQ9
-+       pci_config_writew(d, 0x3d, 0x0001);
-+    }
- }
- 
- /*
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/acpi-timer-support
--- a/tools/ioemu/patches/acpi-timer-support    Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/acpi-timer-support    Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/hw/piix4acpi.c
 Index: ioemu/hw/piix4acpi.c
 ===================================================================
---- ioemu.orig/hw/piix4acpi.c  2006-08-17 19:50:02.407869874 +0100
-+++ ioemu/hw/piix4acpi.c       2006-08-17 19:50:05.060576667 +0100
+--- 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 @@
   */
  
@@ -186,10 +186,3 @@ Index: ioemu/hw/piix4acpi.c
  
  /* PIIX4 acpi pci configuration space, func 2 */
  void pci_piix4_acpi_init(PCIBus *bus, int devfn)
-@@ -384,5 +383,5 @@
-     pci_register_io_region((PCIDevice *)d, 4, 0x10,
-                            PCI_ADDRESS_SPACE_IO, acpi_map);
- 
--    acpi_reset (d);
-+    acpi_reset(d);
- }
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/domain-destroy
--- a/tools/ioemu/patches/domain-destroy        Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/domain-destroy        Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/monitor.c
 Index: ioemu/monitor.c
 ===================================================================
---- ioemu.orig/monitor.c       2006-08-17 19:37:36.489509621 +0100
-+++ ioemu/monitor.c    2006-08-17 19:49:44.491850141 +0100
+--- ioemu.orig/monitor.c       2006-12-08 01:26:07.000000000 +0000
++++ ioemu/monitor.c    2006-12-08 01:26:08.000000000 +0000
 @@ -308,6 +308,7 @@
  
  static void do_quit(void)
@@ -12,11 +12,11 @@ Index: ioemu/monitor.c
  
 Index: ioemu/target-i386-dm/helper2.c
 ===================================================================
---- ioemu.orig/target-i386-dm/helper2.c        2006-08-17 19:49:40.116333768 
+0100
-+++ ioemu/target-i386-dm/helper2.c     2006-08-17 19:49:44.491850141 +0100
-@@ -488,5 +488,25 @@
-             xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
-         }
+--- 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 @@
+         /* Wait up to 10 msec. */
+         main_loop_wait(10);
      }
 +    destroy_hvm_domain();
      return 0;
@@ -42,8 +42,8 @@ Index: ioemu/target-i386-dm/helper2.c
 +}
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:49:40.120333326 +0100
-+++ ioemu/vl.h 2006-08-17 19:49:44.492850031 +0100
+--- ioemu.orig/vl.h    2006-12-08 01:26:08.000000000 +0000
++++ ioemu/vl.h 2006-12-08 01:26:08.000000000 +0000
 @@ -1190,4 +1190,7 @@
  void kqemu_record_dump(void);
  
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/domain-reset
--- a/tools/ioemu/patches/domain-reset  Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/domain-reset  Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/target-i386-dm/helper2.c
 Index: ioemu/target-i386-dm/helper2.c
 ===================================================================
---- ioemu.orig/target-i386-dm/helper2.c        2006-08-17 19:37:36.530505066 
+0100
-+++ ioemu/target-i386-dm/helper2.c     2006-08-17 19:49:40.116333768 +0100
+--- 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 @@
  /* called from main_cpu_reset */
  void cpu_reset(CPUX86State *env)
@@ -28,7 +28,7 @@ Index: ioemu/target-i386-dm/helper2.c
  }
  
  void cpu_x86_close(CPUX86State *env)
-@@ -455,6 +474,10 @@
+@@ -479,6 +498,10 @@
          if (vm_running) {
              if (shutdown_requested)
                  break;
@@ -41,8 +41,8 @@ Index: ioemu/target-i386-dm/helper2.c
          /* Wait up to 10 msec. */
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:49:39.442408257 +0100
-+++ ioemu/vl.c 2006-08-17 19:49:40.119333436 +0100
+--- 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 @@
  } QEMUResetEntry;
  
@@ -54,8 +54,8 @@ Index: ioemu/vl.c
  
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:47:32.680418959 +0100
-+++ ioemu/vl.h 2006-08-17 19:49:40.120333326 +0100
+--- ioemu.orig/vl.h    2006-12-08 01:26:07.000000000 +0000
++++ ioemu/vl.h 2006-12-08 01:26:08.000000000 +0000
 @@ -131,6 +131,7 @@
  
  void qemu_register_reset(QEMUResetHandler *func, void *opaque);
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/domain-timeoffset
--- a/tools/ioemu/patches/domain-timeoffset     Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/domain-timeoffset     Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/hw/mc146818rtc.c
 Index: ioemu/hw/mc146818rtc.c
 ===================================================================
---- ioemu.orig/hw/mc146818rtc.c        2006-10-24 14:45:21.000000000 +0100
-+++ ioemu/hw/mc146818rtc.c     2006-10-24 14:45:39.000000000 +0100
+--- ioemu.orig/hw/mc146818rtc.c        2006-12-08 18:36:31.000000000 +0000
++++ ioemu/hw/mc146818rtc.c     2006-12-08 18:36:36.000000000 +0000
 @@ -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-10-24 14:45:38.000000000 +0100
-+++ ioemu/hw/pc.c      2006-10-24 14:45:39.000000000 +0100
+--- ioemu.orig/hw/pc.c 2006-12-08 18:36:35.000000000 +0000
++++ ioemu/hw/pc.c      2006-12-08 18:36:36.000000000 +0000
 @@ -159,7 +159,7 @@
  }
  
@@ -117,8 +117,8 @@ Index: ioemu/hw/pc.c
  QEMUMachine pc_machine = {
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:45:38.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:45:39.000000000 +0100
+--- ioemu.orig/vl.c    2006-12-08 18:36:35.000000000 +0000
++++ ioemu/vl.c 2006-12-08 18:36:36.000000000 +0000
 @@ -163,6 +163,8 @@
  
  int xc_handle;
@@ -152,7 +152,7 @@ Index: ioemu/vl.c
      { NULL },
  };
  
-@@ -6248,6 +6253,9 @@
+@@ -6232,6 +6237,9 @@
                  vcpus = atoi(optarg);
                  fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
                  break;
@@ -162,7 +162,7 @@ Index: ioemu/vl.c
              }
          }
      }
-@@ -6507,7 +6515,8 @@
+@@ -6492,7 +6500,8 @@
  
      machine->init(ram_size, vga_ram_size, boot_device,
                    ds, fd_filename, snapshot,
@@ -174,8 +174,8 @@ Index: ioemu/vl.c
      if (usb_enabled) {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-10-24 14:45:38.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:45:39.000000000 +0100
+--- ioemu.orig/vl.h    2006-12-08 18:36:35.000000000 +0000
++++ ioemu/vl.h 2006-12-08 18:36:36.000000000 +0000
 @@ -576,7 +576,7 @@
                                   int boot_device,
               DisplayState *ds, const char **fd_filename, int snapshot,
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/hypervisor-pit
--- a/tools/ioemu/patches/hypervisor-pit        Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/hypervisor-pit        Sat Dec 09 14:34:53 2006 +0000
@@ -1,8 +1,8 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-08-17 19:49:33.813030472 +0100
-+++ ioemu/Makefile.target      2006-08-17 19:49:50.228216099 +0100
-@@ -354,7 +354,7 @@
+--- ioemu.orig/Makefile.target 2006-12-08 01:41:12.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 01:41:12.000000000 +0000
+@@ -355,7 +355,7 @@
  ifeq ($(TARGET_BASE_ARCH), i386)
  # Hardware support
  VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
@@ -13,8 +13,8 @@ Index: ioemu/Makefile.target
  DEFINES += -DHAS_AUDIO
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-08-17 19:49:35.507843144 +0100
-+++ ioemu/hw/pc.c      2006-08-17 19:49:50.229215988 +0100
+--- 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
 @@ -38,7 +38,9 @@
  
  static fdctrl_t *floppy_controller;
@@ -38,8 +38,8 @@ 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-08-17 19:49:48.566399780 +0100
-+++ ioemu/vl.c 2006-08-17 19:49:50.231215767 +0100
+--- 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 @@
  
  #ifdef HAS_AUDIO
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/hypervisor-rtc
--- a/tools/ioemu/patches/hypervisor-rtc        Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/hypervisor-rtc        Sat Dec 09 14:34:53 2006 +0000
@@ -5,9 +5,11 @@
 [HVM] Move RTC emulation into the hypervisor.
 Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx>
 
---- ioemu/Makefile.target      Wed Oct 18 18:13:57 2006 +0100
-+++ ioemu/Makefile.target      Wed Oct 18 18:35:21 2006 +0100
-@@ -294,7 +294,11 @@ endif
+Index: ioemu/Makefile.target
+===================================================================
+--- ioemu.orig/Makefile.target 2006-12-08 01:41:15.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 01:41:15.000000000 +0000
+@@ -295,7 +295,11 @@
  endif
  
  # qemu-dm objects
@@ -19,7 +21,7 @@ Signed-off-by: Xiaowei Yang <xiaowei.yan
  
  all: $(PROGS)
  
-@@ -354,7 +358,11 @@ ifeq ($(TARGET_BASE_ARCH), i386)
+@@ -355,7 +359,11 @@
  ifeq ($(TARGET_BASE_ARCH), i386)
  # Hardware support
  VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
@@ -31,8 +33,10 @@ Signed-off-by: Xiaowei Yang <xiaowei.yan
  VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
  VL_OBJS+= usb-uhci.o
  VL_OBJS+= piix4acpi.o
---- /dev/null  Thu Jan 01 00:00:00 1970 +0000
-+++ ioemu/target-i386-dm/rtc-dm.c      Wed Oct 18 18:35:21 2006 +0100
+Index: ioemu/target-i386-dm/rtc-dm.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ ioemu/target-i386-dm/rtc-dm.c      2006-12-08 01:41:15.000000000 +0000
 @@ -0,0 +1,107 @@
 +/*
 + * QEMU MC146818 RTC emulation
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/ioemu-ia64
--- a/tools/ioemu/patches/ioemu-ia64    Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/ioemu-ia64    Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/hw/iommu.c
 Index: ioemu/hw/iommu.c
 ===================================================================
---- ioemu.orig/hw/iommu.c      2006-08-17 19:37:36.791476068 +0100
-+++ ioemu/hw/iommu.c   2006-08-17 19:48:27.357375720 +0100
+--- ioemu.orig/hw/iommu.c      2006-12-08 02:02:07.000000000 +0000
++++ ioemu/hw/iommu.c   2006-12-08 02:02:34.000000000 +0000
 @@ -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-08-17 19:37:36.791476068 +0100
-+++ ioemu/cpu-all.h    2006-08-17 19:48:27.358375609 +0100
+--- ioemu.orig/cpu-all.h       2006-12-08 02:02:07.000000000 +0000
++++ ioemu/cpu-all.h    2006-12-08 02:02:34.000000000 +0000
 @@ -835,6 +835,31 @@
                  :"=m" (*(volatile long *)addr)
                  :"dIr" (nr));
@@ -52,36 +52,36 @@ Index: ioemu/cpu-all.h
  /* memory API */
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:47:08.538087284 +0100
-+++ ioemu/vl.c 2006-08-17 19:57:50.666108706 +0100
-@@ -6144,6 +6144,11 @@
- 
-     xc_handle = xc_interface_open();
+--- ioemu.orig/vl.c    2006-12-08 02:02:28.000000000 +0000
++++ ioemu/vl.c 2006-12-08 02:02:34.000000000 +0000
+@@ -6137,6 +6137,11 @@
+             exit(1);
+     }
  
 +#if defined (__ia64__)
 +    if (ram_size > MMIO_START)
 +        ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */
 +#endif
 +
-     nr_pages = ram_size/PAGE_SIZE;
-     tmp_nr_pages = nr_pages;
+     /* init the memory */
+     phys_ram_size = ram_size + vga_ram_size + bios_size;
  
 @@ -6161,6 +6166,7 @@
          exit(-1);
      }
  
 +#if defined(__i386__) || defined(__x86_64__)
-     if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
-         fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
-         exit(-1);
-@@ -6191,6 +6197,41 @@
+     for ( i = 0; i < tmp_nr_pages; i++)
+         page_array[i] = i;
+ 
+@@ -6185,6 +6191,48 @@
  
      free(page_array);
  
 +#elif defined(__ia64__)
 +  
 +    if (xc_ia64_get_pfn_list(xc_handle, domid, page_array,
-+                             IO_PAGE_START >> PAGE_SHIFT, 1) != 1) {
++                             IO_PAGE_START >> PAGE_SHIFT, 3) != 3) {
 +        fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
 +        exit(-1);
 +    }
@@ -92,6 +92,12 @@ Index: ioemu/vl.c
 +
 +    fprintf(logfile, "shared page at pfn:%lx, mfn: %016lx\n",
 +            IO_PAGE_START >> PAGE_SHIFT, page_array[0]);
++
++    buffered_io_page =xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
++                                       PROT_READ|PROT_WRITE,
++                                       page_array[2]);
++    fprintf(logfile, "Buffered IO page at pfn:%lx, mfn: %016lx\n",
++            BUFFER_IO_PAGE_START >> PAGE_SHIFT, page_array[2]);
 +
 +    if (xc_ia64_get_pfn_list(xc_handle, domid,
 +                             page_array, 0, nr_pages) != nr_pages) {
@@ -100,9 +106,9 @@ Index: ioemu/vl.c
 +    }
 +
 +    if (ram_size > MMIO_START) {      
-+        for (i = 0 ; i < MEM_G >> PAGE_SHIFT; i++)
-+            page_array[MMIO_START >> PAGE_SHIFT + i] =
-+                page_array[IO_PAGE_START >> PAGE_SHIFT + 1];
++        for (i = 0 ; i < (MEM_G >> PAGE_SHIFT); i++)
++            page_array[(MMIO_START >> PAGE_SHIFT) + i] =
++                page_array[(IO_PAGE_START >> PAGE_SHIFT) + 1];
 +    }
 +
 +    phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
@@ -112,52 +118,15 @@ Index: ioemu/vl.c
 +        fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
 +        exit(-1);
 +    }
++    free(page_array);
 +#endif
  #else  /* !CONFIG_DM */
  
      phys_ram_base = qemu_vmalloc(phys_ram_size);
-Index: ioemu/target-i386-dm/exec-dm.c
-===================================================================
---- ioemu.orig/target-i386-dm/exec-dm.c        2006-08-17 19:37:36.792475957 
+0100
-+++ ioemu/target-i386-dm/exec-dm.c     2006-08-17 19:48:27.361375278 +0100
-@@ -341,6 +341,23 @@
-     return io_mem_read[io_index >> IO_MEM_SHIFT];
- }
- 
-+#ifdef __ia64__
-+/* IA64 has seperate I/D cache, with coherence maintained by DMA controller.
-+ * So to emulate right behavior that guest OS is assumed, we need to flush
-+ * I/D cache here.
-+ */
-+static void sync_icache(unsigned long address, int len)
-+{
-+    int l;
-+
-+    for(l = 0; l < (len + 32); l += 32)
-+        __ia64_fc(address + l);
-+
-+    ia64_sync_i();
-+    ia64_srlz_i();
-+}
-+#endif 
-+
- /* physical memory access (slow version, mainly for debug) */
- #if defined(CONFIG_USER_ONLY)
- void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
-@@ -432,6 +449,9 @@
-                 /* RAM case */
-                 ptr = phys_ram_base + addr1;
-                 memcpy(ptr, buf, l);
-+#ifdef __ia64__
-+                sync_icache((unsigned long)ptr, l);
-+#endif 
-             }
-         } else {
-             if (io_index) {
 Index: ioemu/exec-all.h
 ===================================================================
---- ioemu.orig/exec-all.h      2006-08-17 19:37:36.791476068 +0100
-+++ ioemu/exec-all.h   2006-08-17 19:48:27.362375167 +0100
+--- ioemu.orig/exec-all.h      2006-12-08 02:02:07.000000000 +0000
++++ ioemu/exec-all.h   2006-12-08 02:02:34.000000000 +0000
 @@ -462,12 +462,13 @@
  }
  #endif
@@ -177,9 +146,9 @@ Index: ioemu/exec-all.h
  
 Index: ioemu/target-i386-dm/cpu.h
 ===================================================================
---- ioemu.orig/target-i386-dm/cpu.h    2006-08-17 19:37:36.792475957 +0100
-+++ ioemu/target-i386-dm/cpu.h 2006-08-17 19:48:27.362375167 +0100
-@@ -80,7 +80,11 @@
+--- ioemu.orig/target-i386-dm/cpu.h    2006-12-08 02:02:07.000000000 +0000
++++ ioemu/target-i386-dm/cpu.h 2006-12-08 02:02:34.000000000 +0000
+@@ -78,7 +78,11 @@
  /* helper2.c */
  int main_loop(void);
  
@@ -194,7 +163,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-08-17 19:48:27.363375057 +0100
++++ ioemu/ia64_intrinsic.h     2006-12-08 02:02:34.000000000 +0000
 @@ -0,0 +1,276 @@
 +#ifndef IA64_INTRINSIC_H
 +#define IA64_INTRINSIC_H
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-bootorder
--- a/tools/ioemu/patches/qemu-bootorder        Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/qemu-bootorder        Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:33:47.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:33:47.000000000 +0100
+--- ioemu.orig/vl.c    2006-12-08 02:02:38.000000000 +0000
++++ ioemu/vl.c 2006-12-08 02:02:38.000000000 +0000
 @@ -125,7 +125,7 @@
  struct sockaddr_in vnclisten_addr;
  const char* keyboard_layout = NULL;
@@ -11,7 +11,7 @@ Index: ioemu/vl.c
  uint64_t ram_size;
  int pit_min_timer_count = 0;
  int nb_nics;
-@@ -6075,14 +6075,14 @@
+@@ -6059,14 +6059,14 @@
                  break;
  #endif /* !CONFIG_DM */
              case QEMU_OPTION_boot:
@@ -32,7 +32,7 @@ Index: ioemu/vl.c
                      exit(1);
                  }
                  break;
-@@ -6349,6 +6349,7 @@
+@@ -6333,6 +6333,7 @@
          fd_filename[0] == '\0')
          help();
      
@@ -40,7 +40,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')
-@@ -6356,6 +6357,7 @@
+@@ -6340,6 +6341,7 @@
          else
              boot_device = 'd';
      }
@@ -48,7 +48,7 @@ Index: ioemu/vl.c
  #endif /* !CONFIG_DM */
  
      setvbuf(stdout, NULL, _IOLBF, 0);
-@@ -6614,6 +6616,7 @@
+@@ -6598,6 +6600,7 @@
                    ds, fd_filename, snapshot,
                    kernel_filename, kernel_cmdline, initrd_filename,
                    timeoffset);
@@ -58,8 +58,8 @@ Index: ioemu/vl.c
      if (usb_enabled) {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-10-24 14:33:47.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:33:47.000000000 +0100
+--- ioemu.orig/vl.h    2006-12-08 02:02:38.000000000 +0000
++++ ioemu/vl.h 2006-12-08 02:02:38.000000000 +0000
 @@ -578,7 +578,7 @@
  #ifndef QEMU_TOOL
  
@@ -80,8 +80,8 @@ Index: ioemu/vl.h
                            uint32_t initrd_image, uint32_t initrd_size,
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-10-24 14:33:47.000000000 +0100
-+++ ioemu/hw/pc.c      2006-10-24 14:33:47.000000000 +0100
+--- ioemu.orig/hw/pc.c 2006-12-08 02:02:38.000000000 +0000
++++ ioemu/hw/pc.c      2006-12-08 02:02:38.000000000 +0000
 @@ -158,8 +158,23 @@
      rtc_set_memory(s, info_ofs + 8, sectors);
  }
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-daemonize
--- a/tools/ioemu/patches/qemu-daemonize        Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/qemu-daemonize        Sat Dec 09 14:34:53 2006 +0000
@@ -2,9 +2,9 @@ Changes required because qemu-dm runs da
 
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:33:47.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:33:47.000000000 +0100
-@@ -6054,10 +6054,11 @@
+--- 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 @@
                  }
                  break;
              case QEMU_OPTION_nographic:
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-dm
--- a/tools/ioemu/patches/qemu-dm       Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/qemu-dm       Sat Dec 09 14:34:53 2006 +0000
@@ -1,8 +1,8 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-08-06 02:14:04.797460093 +0100
-+++ ioemu/Makefile.target      2006-08-06 02:14:09.794902973 +0100
-@@ -302,7 +302,7 @@
+--- ioemu.orig/Makefile.target 2006-12-08 01:41:05.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 01:41:10.000000000 +0000
+@@ -303,7 +303,7 @@
  endif
  
  # must use static linking to avoid leaving stuff in virtual address space
@@ -13,8 +13,8 @@ Index: ioemu/Makefile.target
  VL_OBJS+=tap-win32.o
 Index: ioemu/configure
 ===================================================================
---- ioemu.orig/configure       2006-08-06 02:14:04.797460093 +0100
-+++ ioemu/configure    2006-08-06 02:14:09.795902861 +0100
+--- ioemu.orig/configure       2006-12-08 01:40:58.000000000 +0000
++++ ioemu/configure    2006-12-08 01:41:10.000000000 +0000
 @@ -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-08-06 02:14:04.797460093 +0100
-+++ ioemu/cpu-all.h    2006-08-06 02:14:09.796902750 +0100
+--- 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
 @@ -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-08-06 02:14:04.797460093 +0100
-+++ ioemu/disas.h      2006-08-06 02:14:09.796902750 +0100
+--- ioemu.orig/disas.h 2006-12-08 01:40:58.000000000 +0000
++++ ioemu/disas.h      2006-12-08 01:41:10.000000000 +0000
 @@ -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-08-06 02:14:04.798459982 +0100
-+++ ioemu/exec-all.h   2006-08-06 02:14:09.796902750 +0100
+--- 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
 @@ -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-08-06 02:14:04.797460093 +0100
-+++ ioemu/hw/pc.c      2006-08-06 02:14:09.797902638 +0100
+--- 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
 @@ -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-08-06 02:14:04.797460093 +0100
-+++ ioemu/hw/vga_int.h 2006-08-06 02:14:09.797902638 +0100
+--- 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
 @@ -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-08-06 02:14:04.798459982 +0100
-+++ ioemu/monitor.c    2006-08-06 02:14:49.574468309 +0100
+--- ioemu.orig/monitor.c       2006-12-08 01:40:58.000000000 +0000
++++ ioemu/monitor.c    2006-12-08 01:41:10.000000000 +0000
 @@ -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-08-06 02:14:04.797460093 +0100
-+++ ioemu/vl.c 2006-08-06 02:14:09.802902081 +0100
+--- ioemu.orig/vl.c    2006-12-08 01:40:58.000000000 +0000
++++ ioemu/vl.c 2006-12-08 01:41:10.000000000 +0000
 @@ -422,12 +422,15 @@
  void hw_error(const char *fmt, ...)
  {
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-no-apic
--- a/tools/ioemu/patches/qemu-no-apic  Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/qemu-no-apic  Sat Dec 09 14:34:53 2006 +0000
@@ -1,8 +1,8 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-08-06 02:21:42.270461924 +0100
-+++ ioemu/Makefile.target      2006-08-06 02:22:26.380544784 +0100
-@@ -355,7 +355,7 @@
+--- ioemu.orig/Makefile.target 2006-12-08 01:41:11.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 01:41:12.000000000 +0000
+@@ -356,7 +356,7 @@
  # Hardware support
  VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
  VL_OBJS+= fdc.o mc146818rtc.o serial.o i8254.o pcspk.o pc.o
@@ -13,8 +13,8 @@ Index: ioemu/Makefile.target
  endif
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-08-06 02:22:01.524315611 +0100
-+++ ioemu/hw/pc.c      2006-08-06 02:22:11.875161758 +0100
+--- 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
 @@ -39,7 +39,9 @@
  static fdctrl_t *floppy_controller;
  static RTCState *rtc_state;
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-pci
--- a/tools/ioemu/patches/qemu-pci      Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/qemu-pci      Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/hw/pci.c
 Index: ioemu/hw/pci.c
 ===================================================================
---- ioemu.orig/hw/pci.c        2006-09-21 11:31:14.000000000 +0100
-+++ ioemu/hw/pci.c     2006-09-21 11:31:32.000000000 +0100
+--- 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 @@
              case 0x0b:
              case 0x0e:
@@ -31,8 +31,8 @@ Index: ioemu/hw/pci.c
          addr++;
 Index: ioemu/hw/rtl8139.c
 ===================================================================
---- ioemu.orig/hw/rtl8139.c    2006-09-21 11:31:14.000000000 +0100
-+++ ioemu/hw/rtl8139.c 2006-09-21 11:31:32.000000000 +0100
+--- 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 @@
      pci_conf[0x0e] = 0x00; /* header_type */
      pci_conf[0x3d] = 1;    /* interrupt pin 0 */
@@ -44,8 +44,8 @@ Index: ioemu/hw/rtl8139.c
  
 Index: ioemu/hw/usb-uhci.c
 ===================================================================
---- ioemu.orig/hw/usb-uhci.c   2006-09-21 11:31:14.000000000 +0100
-+++ ioemu/hw/usb-uhci.c        2006-09-21 11:31:32.000000000 +0100
+--- 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 @@
      pci_conf[0x0e] = 0x00; // header_type
      pci_conf[0x3d] = 4; // interrupt pin 3
@@ -55,3 +55,21 @@ Index: ioemu/hw/usb-uhci.c
      
      for(i = 0; i < NB_PORTS; i++) {
          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
+@@ -650,8 +650,11 @@
+ #define PCI_MAX_LAT           0x3f    /* 8 bits */
+ 
+ struct PCIDevice {
+-    /* PCI config space */
+-    uint8_t config[256];
++    /*
++     * PCI config space. The 4 extra bytes are a safety buffer for guest
++     * word/dword writes that can extend past byte 0xff.
++     */
++    uint8_t config[256+4];
+ 
+     /* the following fields are read only */
+     PCIBus *bus;
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-target-i386-dm
--- a/tools/ioemu/patches/qemu-target-i386-dm   Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/qemu-target-i386-dm   Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-10-24 13:47:23.000000000 +0100
-+++ ioemu/Makefile.target      2006-10-24 14:30:56.000000000 +0100
+--- ioemu.orig/Makefile.target 2006-12-08 01:41:10.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 01:41:11.000000000 +0000
 @@ -62,6 +62,8 @@
  QEMU_SYSTEM=qemu-fast
  endif
@@ -11,7 +11,7 @@ Index: ioemu/Makefile.target
  ifdef CONFIG_USER_ONLY
  PROGS=$(QEMU_USER)
  else
-@@ -291,6 +293,9 @@
+@@ -292,6 +294,9 @@
  OBJS+=gdbstub.o
  endif
  
@@ -21,7 +21,7 @@ Index: ioemu/Makefile.target
  all: $(PROGS)
  
  $(QEMU_USER): $(OBJS)
-@@ -349,7 +354,7 @@
+@@ -350,7 +355,7 @@
  ifeq ($(TARGET_BASE_ARCH), i386)
  # Hardware support
  VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
@@ -32,8 +32,8 @@ Index: ioemu/Makefile.target
  DEFINES += -DHAS_AUDIO
 Index: ioemu/configure
 ===================================================================
---- ioemu.orig/configure       2006-10-24 13:47:23.000000000 +0100
-+++ ioemu/configure    2006-10-24 14:29:34.000000000 +0100
+--- ioemu.orig/configure       2006-12-08 01:41:10.000000000 +0000
++++ ioemu/configure    2006-12-08 01:41:11.000000000 +0000
 @@ -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-10-24 13:47:23.000000000 +0100
-+++ ioemu/monitor.c    2006-10-24 14:30:56.000000000 +0100
+--- ioemu.orig/monitor.c       2006-12-08 01:41:10.000000000 +0000
++++ ioemu/monitor.c    2006-12-08 01:41:11.000000000 +0000
 @@ -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-10-24 13:47:23.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:30:56.000000000 +0100
+--- ioemu.orig/vl.c    2006-12-08 01:41:10.000000000 +0000
++++ ioemu/vl.c 2006-12-08 01:41:11.000000000 +0000
 @@ -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-10-24 13:47:23.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:30:56.000000000 +0100
+--- ioemu.orig/vl.h    2006-12-08 01:40:58.000000000 +0000
++++ ioemu/vl.h 2006-12-08 01:41:11.000000000 +0000
 @@ -37,6 +37,8 @@
  #include <unistd.h>
  #include <fcntl.h>
@@ -132,8 +132,8 @@ 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-10-24 14:30:56.000000000 +0100
-@@ -0,0 +1,86 @@
++++ ioemu/target-i386-dm/cpu.h 2006-12-08 01:41:11.000000000 +0000
+@@ -0,0 +1,84 @@
 +/*
 + * i386 virtual CPU header
 + * 
@@ -191,8 +191,6 @@ Index: ioemu/target-i386-dm/cpu.h
 +    int interrupt_request;
 +
 +    CPU_COMMON
-+
-+    int send_event;
 +} CPUX86State;
 +
 +CPUX86State *cpu_x86_init(void);
@@ -223,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-10-24 14:30:56.000000000 +0100
-@@ -0,0 +1,516 @@
++++ ioemu/target-i386-dm/exec-dm.c     2006-12-08 01:41:11.000000000 +0000
+@@ -0,0 +1,546 @@
 +/*
 + *  virtual page mapping and translated block handling
 + * 
@@ -258,6 +256,8 @@ Index: ioemu/target-i386-dm/exec-dm.c
 +#include <errno.h>
 +#include <unistd.h>
 +#include <inttypes.h>
++
++#include <xen/hvm/e820.h>
 +
 +#include "cpu.h"
 +#include "exec-all.h"
@@ -567,6 +567,23 @@ Index: ioemu/target-i386-dm/exec-dm.c
 +{
 +    return io_mem_read[io_index >> IO_MEM_SHIFT];
 +}
++
++#ifdef __ia64__
++/* IA64 has seperate I/D cache, with coherence maintained by DMA controller.
++ * So to emulate right behavior that guest OS is assumed, we need to flush
++ * I/D cache here.
++ */
++static void sync_icache(unsigned long address, int len)
++{
++    int l;
++
++    for(l = 0; l < (len + 32); l += 32)
++        __ia64_fc(address + l);
++
++    ia64_sync_i();
++    ia64_srlz_i();
++}
++#endif 
 +
 +/* physical memory access (slow version, mainly for debug) */
 +#if defined(CONFIG_USER_ONLY)
@@ -617,22 +634,36 @@ Index: ioemu/target-i386-dm/exec-dm.c
 +        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__))
++    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)));
++#else
++    return (addr < ram_size);
++#endif
++}
++
 +void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
 +                            int len, int is_write)
 +{
 +    int l, io_index;
 +    uint8_t *ptr;
 +    uint32_t val;
-+    target_phys_addr_t page;
-+    unsigned long pd;
 +    
 +    while (len > 0) {
-+        page = addr & TARGET_PAGE_MASK;
-+        l = (page + TARGET_PAGE_SIZE) - addr;
++        /* How much can we copy before the next page boundary? */
++        l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK); 
 +        if (l > len)
 +            l = len;
 +      
-+        pd = page;
 +        io_index = iomem_index(addr);
 +        if (is_write) {
 +            if (io_index) {
@@ -652,13 +683,12 @@ Index: ioemu/target-i386-dm/exec-dm.c
 +                    io_mem_write[io_index][0](io_mem_opaque[io_index], addr, 
val);
 +                    l = 1;
 +                }
-+            } else {
-+                unsigned long addr1;
-+
-+                addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
-+                /* RAM case */
-+                ptr = phys_ram_base + addr1;
-+                memcpy(ptr, buf, l);
++            } else if (paddr_is_ram(addr)) {
++                /* Reading from RAM */
++                memcpy(phys_ram_base + addr, buf, l);
++#ifdef __ia64__
++                sync_icache((unsigned long)(phys_ram_base + addr), l);
++#endif 
 +            }
 +        } else {
 +            if (io_index) {
@@ -678,14 +708,12 @@ Index: ioemu/target-i386-dm/exec-dm.c
 +                    stb_raw(buf, val);
 +                    l = 1;
 +                }
-+            } else if (addr < ram_size) {
-+                /* RAM case */
-+                ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + 
-+                    (addr & ~TARGET_PAGE_MASK);
-+                memcpy(buf, ptr, l);
++            } else if (paddr_is_ram(addr)) {
++                /* Reading from RAM */
++                memcpy(buf, phys_ram_base + addr, l);
 +            } else {
-+                /* unreported MMIO space */
-+                memset(buf, 0xff, len);
++                /* Neither RAM nor known MMIO space */
++                memset(buf, 0xff, len); 
 +            }
 +        }
 +        len -= l;
@@ -744,8 +772,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-10-24 14:31:01.000000000 +0100
-@@ -0,0 +1,469 @@
++++ ioemu/target-i386-dm/helper2.c     2006-12-08 01:41:11.000000000 +0000
+@@ -0,0 +1,488 @@
 +/*
 + *  i386 helpers (without register variable usage)
 + *
@@ -918,10 +946,10 @@ Index: ioemu/target-i386-dm/helper2.c
 +    for (i = 0; i < vcpus; i++) {
 +        req = &(shared_page->vcpu_iodata[i].vp_ioreq);
 +        term_printf("vcpu %d: event port %d\n", i, ioreq_local_port[i]);
-+        term_printf("  req state: %x, pvalid: %x, addr: %"PRIx64", "
++        term_printf("  req state: %x, ptr: %x, addr: %"PRIx64", "
 +                    "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
-+                    req->state, req->pdata_valid, req->addr,
-+                    req->u.data, req->count, req->size);
++                    req->state, req->data_is_ptr, req->addr,
++                    req->data, req->count, req->size);
 +        term_printf("  IO totally occurred on this vcpu: %"PRIx64"\n",
 +                    req->io_count);
 +    }
@@ -934,18 +962,19 @@ Index: ioemu/target-i386-dm/helper2.c
 +
 +    req = &(shared_page->vcpu_iodata[vcpu].vp_ioreq);
 +
-+    if (req->state == STATE_IOREQ_READY) {
-+        req->state = STATE_IOREQ_INPROCESS;
-+        rmb();
-+        return req;
-+    }
-+
-+    fprintf(logfile, "False I/O request ... in-service already: "
-+            "%x, pvalid: %x, port: %"PRIx64", "
-+            "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
-+            req->state, req->pdata_valid, req->addr,
-+            req->u.data, req->count, req->size);
-+    return NULL;
++    if (req->state != STATE_IOREQ_READY) {
++        fprintf(logfile, "I/O request not ready: "
++                "%x, ptr: %x, port: %"PRIx64", "
++                "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
++                req->state, req->data_is_ptr, req->addr,
++                req->data, req->count, req->size);
++        return NULL;
++    }
++
++    rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
++
++    req->state = STATE_IOREQ_INPROCESS;
++    return req;
 +}
 +
 +//use poll to get the port notification
@@ -1030,26 +1059,26 @@ Index: ioemu/target-i386-dm/helper2.c
 +    sign = req->df ? -1 : 1;
 +
 +    if (req->dir == IOREQ_READ) {
-+        if (!req->pdata_valid) {
-+            req->u.data = do_inp(env, req->addr, req->size);
++        if (!req->data_is_ptr) {
++            req->data = do_inp(env, req->addr, req->size);
 +        } else {
 +            unsigned long tmp;
 +
 +            for (i = 0; i < req->count; i++) {
 +                tmp = do_inp(env, req->addr, req->size);
-+                write_physical((target_phys_addr_t) req->u.pdata
++                write_physical((target_phys_addr_t) req->data
 +                  + (sign * i * req->size),
 +                  req->size, &tmp);
 +            }
 +        }
 +    } else if (req->dir == IOREQ_WRITE) {
-+        if (!req->pdata_valid) {
-+            do_outp(env, req->addr, req->size, req->u.data);
++        if (!req->data_is_ptr) {
++            do_outp(env, req->addr, req->size, req->data);
 +        } else {
 +            for (i = 0; i < req->count; i++) {
 +                unsigned long tmp;
 +
-+                read_physical((target_phys_addr_t) req->u.pdata
++                read_physical((target_phys_addr_t) req->data
 +                  + (sign * i * req->size),
 +                  req->size, &tmp);
 +                do_outp(env, req->addr, req->size, tmp);
@@ -1064,18 +1093,18 @@ Index: ioemu/target-i386-dm/helper2.c
 +
 +    sign = req->df ? -1 : 1;
 +
-+    if (!req->pdata_valid) {
++    if (!req->data_is_ptr) {
 +        if (req->dir == IOREQ_READ) {
 +            for (i = 0; i < req->count; i++) {
 +                read_physical(req->addr
 +                  + (sign * i * req->size),
-+                  req->size, &req->u.data);
++                  req->size, &req->data);
 +            }
 +        } else if (req->dir == IOREQ_WRITE) {
 +            for (i = 0; i < req->count; i++) {
 +                write_physical(req->addr
 +                  + (sign * i * req->size),
-+                  req->size, &req->u.data);
++                  req->size, &req->data);
 +            }
 +        }
 +    } else {
@@ -1086,13 +1115,13 @@ Index: ioemu/target-i386-dm/helper2.c
 +                read_physical(req->addr
 +                  + (sign * i * req->size),
 +                  req->size, &tmp);
-+                write_physical((target_phys_addr_t )req->u.pdata
++                write_physical((target_phys_addr_t )req->data
 +                  + (sign * i * req->size),
 +                  req->size, &tmp);
 +            }
 +        } else if (req->dir == IOREQ_WRITE) {
 +            for (i = 0; i < req->count; i++) {
-+                read_physical((target_phys_addr_t) req->u.pdata
++                read_physical((target_phys_addr_t) req->data
 +                  + (sign * i * req->size),
 +                  req->size, &tmp);
 +                write_physical(req->addr
@@ -1107,45 +1136,60 @@ Index: ioemu/target-i386-dm/helper2.c
 +{
 +    unsigned long tmp1, tmp2;
 +
-+    if (req->pdata_valid != 0)
++    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->u.data;
++        tmp2 = tmp1 & (unsigned long) req->data;
 +        write_physical(req->addr, req->size, &tmp2);
 +    }
-+    req->u.data = tmp1;
-+}
-+
-+void cpu_ioreq_or(CPUState *env, ioreq_t *req)
++    req->data = tmp1;
++}
++
++void cpu_ioreq_add(CPUState *env, ioreq_t *req)
 +{
 +    unsigned long tmp1, tmp2;
 +
-+    if (req->pdata_valid != 0)
++    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->u.data;
++        tmp2 = tmp1 + (unsigned long) req->data;
 +        write_physical(req->addr, req->size, &tmp2);
 +    }
-+    req->u.data = tmp1;
-+}
-+
-+void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
++    req->data = tmp1;
++}
++
++void cpu_ioreq_or(CPUState *env, ioreq_t *req)
 +{
 +    unsigned long tmp1, tmp2;
 +
-+    if (req->pdata_valid != 0)
++    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->u.data;
++        tmp2 = tmp1 | (unsigned long) req->data;
 +        write_physical(req->addr, req->size, &tmp2);
 +    }
-+    req->u.data = tmp1;
++    req->data = tmp1;
++}
++
++void cpu_ioreq_xor(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_handle_ioreq(void *opaque)
@@ -1154,9 +1198,9 @@ Index: ioemu/target-i386-dm/helper2.c
 +    ioreq_t *req = cpu_get_ioreq();
 +
 +    if (req) {
-+        if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
++        if ((!req->data_is_ptr) && (req->dir == IOREQ_WRITE)) {
 +            if (req->size != 4)
-+                req->u.data &= (1UL << (8 * req->size))-1;
++                req->data &= (1UL << (8 * req->size))-1;
 +        }
 +
 +        switch (req->type) {
@@ -1169,6 +1213,9 @@ Index: ioemu/target-i386-dm/helper2.c
 +        case IOREQ_TYPE_AND:
 +            cpu_ioreq_and(env, req);
 +            break;
++        case IOREQ_TYPE_ADD:
++            cpu_ioreq_add(env, req);
++            break;
 +        case IOREQ_TYPE_OR:
 +            cpu_ioreq_or(env, req);
 +            break;
@@ -1179,12 +1226,19 @@ Index: ioemu/target-i386-dm/helper2.c
 +            hw_error("Invalid ioreq type 0x%x\n", req->type);
 +        }
 +
-+        /* No state change if state = STATE_IORESP_HOOK */
-+        if (req->state == STATE_IOREQ_INPROCESS) {
-+            mb();
-+            req->state = STATE_IORESP_READY;
-+        }
-+        env->send_event = 1;
++        if (req->state != STATE_IOREQ_INPROCESS) {
++            fprintf(logfile, "Badness in I/O request ... not in service?!: "
++                    "%x, ptr: %x, port: %"PRIx64", "
++                    "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
++                    req->state, req->data_is_ptr, req->addr,
++                    req->data, req->count, req->size);
++            destroy_hvm_domain();
++            return;
++        }
++
++        wmb(); /* Update ioreq contents /then/ update state. */
++        req->state = STATE_IORESP_READY;
++        xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
 +    }
 +}
 +
@@ -1197,8 +1251,6 @@ Index: ioemu/target-i386-dm/helper2.c
 +
 +    qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
 +
-+    env->send_event = 0;
-+
 +    while (1) {
 +        if (vm_running) {
 +            if (shutdown_requested)
@@ -1207,19 +1259,14 @@ Index: ioemu/target-i386-dm/helper2.c
 +
 +        /* Wait up to 10 msec. */
 +        main_loop_wait(10);
-+
-+        if (env->send_event) {
-+            env->send_event = 0;
-+            xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
-+        }
 +    }
 +    return 0;
 +}
 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-10-24 13:47:23.000000000 +0100
-@@ -0,0 +1,107 @@
++++ ioemu/target-i386-dm/i8259-dm.c    2006-12-08 01:41:11.000000000 +0000
+@@ -0,0 +1,67 @@
 +/* Xen 8259 stub for interrupt controller emulation
 + * 
 + * Copyright (c) 2003-2004 Fabrice Bellard
@@ -1244,58 +1291,18 @@ Index: ioemu/target-i386-dm/i8259-dm.c
 + * THE SOFTWARE.
 + */
 +#include "vl.h"
-+
-+/* debug PIC */
-+//#define DEBUG_PIC
-+
-+//#define DEBUG_IRQ_LATENCY
-+//#define DEBUG_IRQ_COUNT
-+
 +#include "xenctrl.h"
 +#include <xen/hvm/ioreq.h>
 +#include <stdio.h>
 +#include "cpu.h"
 +#include "cpu-all.h"
 +
-+extern shared_iopage_t *shared_page;
-+
 +struct PicState2 {
 +};
 +
 +void pic_set_irq_new(void *opaque, int irq, int level)
 +{
-+    /* PicState2 *s = opaque; */
-+    global_iodata_t  *gio;
-+    int  mask;
-+
-+    gio = &shared_page->sp_global;
-+    mask = 1 << irq;
-+    if ( gio->pic_elcr & mask ) {
-+        /* level */
-+       if ( level ) {
-+           atomic_clear_bit(irq, &gio->pic_clear_irr);
-+           atomic_set_bit(irq, &gio->pic_irr);
-+           cpu_single_env->send_event = 1;
-+       }
-+       else {
-+           atomic_clear_bit(irq, &gio->pic_irr);
-+           atomic_set_bit(irq, &gio->pic_clear_irr);
-+           cpu_single_env->send_event = 1;
-+       }
-+    }
-+    else {
-+       /* edge */
-+       if ( level ) {
-+           if ( (mask & gio->pic_last_irr) == 0 ) { 
-+               atomic_set_bit(irq, &gio->pic_irr);
-+               atomic_set_bit(irq, &gio->pic_last_irr);
-+               cpu_single_env->send_event = 1;
-+           }
-+       }
-+       else {
-+           atomic_clear_bit(irq, &gio->pic_last_irr);
-+       }
-+    }
++    xc_hvm_set_irq_level(xc_handle, domid, irq, level);
 +}
 +
 +/* obsolete function */
@@ -1330,17 +1337,22 @@ 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-10-24 13:47:23.000000000 +0100
-@@ -0,0 +1,5 @@
++++ ioemu/target-i386-dm/qemu-dm.debug 2006-12-08 01:41:11.000000000 +0000
+@@ -0,0 +1,10 @@
 +#!/bin/sh
 +
++if [ "`arch`" = "x86_64" ]; then
++    LIBDIR="lib64"
++else
++    LIBDIR="lib"
++fi
 +echo $* > /tmp/args
 +echo $DISPLAY >> /tmp/args
-+exec /usr/lib/xen/bin/qemu-dm $*
++exec /usr/$LIBDIR/xen/bin/qemu-dm $*
 Index: ioemu/target-i386-dm/qemu-ifup
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/qemu-ifup     2006-10-24 13:47:23.000000000 +0100
++++ ioemu/target-i386-dm/qemu-ifup     2006-12-08 01:41:11.000000000 +0000
 @@ -0,0 +1,10 @@
 +#!/bin/sh
 +
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/series
--- a/tools/ioemu/patches/series        Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/series        Sat Dec 09 14:34:53 2006 +0000
@@ -53,3 +53,19 @@ hypervisor-rtc
 hypervisor-rtc
 ide-cd-dma
 vnc-password
+ne2000-bounds-checks
+xenstore-device-info-functions
+tpm-tis-device
+qemu-serial-fixes
+vnc-japan-keymap
+rtl8139-bound-chaining
+fix-interrupt-routing
+nodelay-serial-over-tcp
+remove-pci-bridge-setup
+limit-fdc-sector-size-to-16K
+usb-uhci-buffer-size
+vnc-monitor-shift-key-processing
+ide-error-reporting
+vnc-numpad-handling
+xen-mapcache -p3
+usb-mouse-tablet-status-check -p3
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/shared-vram
--- a/tools/ioemu/patches/shared-vram   Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/shared-vram   Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/hw/cirrus_vga.c
 Index: ioemu/hw/cirrus_vga.c
 ===================================================================
---- ioemu.orig/hw/cirrus_vga.c 2006-08-17 19:37:36.372522620 +0100
-+++ ioemu/hw/cirrus_vga.c      2006-08-17 19:49:52.157002909 +0100
+--- 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
 @@ -28,6 +28,9 @@
   */
  #include "vl.h"
@@ -176,8 +176,8 @@ Index: ioemu/hw/cirrus_vga.c
  }
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-08-17 19:49:50.229215988 +0100
-+++ ioemu/hw/pc.c      2006-08-17 19:49:52.158002799 +0100
+--- 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
 @@ -790,14 +790,14 @@
      if (cirrus_vga_enabled) {
          if (pci_enabled) {
@@ -198,8 +198,8 @@ Index: ioemu/hw/pc.c
  
 Index: ioemu/hw/vga.c
 ===================================================================
---- ioemu.orig/hw/vga.c        2006-08-17 19:49:37.764593706 +0100
-+++ ioemu/hw/vga.c     2006-08-17 19:49:52.159002688 +0100
+--- 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
 @@ -1858,6 +1858,7 @@
      /* TODO: add vbe support if enabled */
  }
@@ -251,8 +251,8 @@ Index: ioemu/hw/vga.c
  
 Index: ioemu/hw/vga_int.h
 ===================================================================
---- ioemu.orig/hw/vga_int.h    2006-08-17 19:37:36.372522620 +0100
-+++ ioemu/hw/vga_int.h 2006-08-17 19:49:52.159002688 +0100
+--- 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
 @@ -169,5 +169,6 @@
                               unsigned int color0, unsigned int color1,
                               unsigned int color_xor);
@@ -262,9 +262,9 @@ Index: ioemu/hw/vga_int.h
  extern const uint8_t gr_mask[16];
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:49:50.231215767 +0100
-+++ ioemu/vl.c 2006-08-17 19:49:52.162002356 +0100
-@@ -5693,6 +5693,78 @@
+--- 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 @@
  
  #define MAX_NET_CLIENTS 32
  
@@ -303,9 +303,6 @@ Index: ioemu/vl.c
 +                   unsigned long nr_pages, unsigned int address_bits,
 +                   xen_pfn_t *extent_start)
 +{
-+#if 0
-+    int i;
-+#endif
 +    xc_dominfo_t info;
 +    int err = 0;
 +
@@ -324,19 +321,6 @@ Index: ioemu/vl.c
 +        return -1;
 +    }
 +
-+    err = xc_domain_translate_gpfn_list(xc_handle, domid, nr_pages,
-+                                        extent_start, extent_start);
-+    if (err) {
-+        fprintf(stderr, "Failed to translate gpfn list\n");
-+        return -1;
-+    }
-+
-+#if 0 /* Generates lots of log file output - turn on for debugging */
-+    for (i = 0; i < nr_pages; i++)
-+        fprintf(stderr, "set_map result i %x result %lx\n", i,
-+                extent_start[i]);
-+#endif
-+
 +    return 0;
 +}
 +
@@ -345,8 +329,8 @@ Index: ioemu/vl.c
  #ifdef CONFIG_GDBSTUB
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:49:44.492850031 +0100
-+++ ioemu/vl.h 2006-08-17 19:49:52.163002246 +0100
+--- ioemu.orig/vl.h    2006-12-08 02:00:04.000000000 +0000
++++ ioemu/vl.h 2006-12-08 02:00:04.000000000 +0000
 @@ -145,6 +145,13 @@
  
  void main_loop_wait(int timeout);
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-access-monitor-vt
--- a/tools/ioemu/patches/vnc-access-monitor-vt Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/vnc-access-monitor-vt Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-10-24 14:33:46.000000000 +0100
-+++ ioemu/vnc.c        2006-10-24 14:33:46.000000000 +0100
+--- ioemu.orig/vnc.c   2006-12-06 23:46:11.000000000 +0000
++++ ioemu/vnc.c        2006-12-06 23:46:11.000000000 +0000
 @@ -33,6 +33,10 @@
  #include "vnc_keysym.h"
  #include "keymaps.c"
@@ -22,7 +22,7 @@ Index: ioemu/vnc.c
  };
  
  #define DIRTY_PIXEL_BITS 64
-@@ -794,16 +800,80 @@
+@@ -796,16 +802,80 @@
  
  static void do_key_event(VncState *vs, int down, uint32_t sym)
  {
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-backoff-screen-scan
--- a/tools/ioemu/patches/vnc-backoff-screen-scan       Fri Dec 08 11:31:29 
2006 -0700
+++ b/tools/ioemu/patches/vnc-backoff-screen-scan       Sat Dec 09 14:34:53 
2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-10-24 14:33:17.000000000 +0100
-+++ ioemu/vnc.c        2006-10-24 14:33:24.000000000 +0100
+--- ioemu.orig/vnc.c   2006-12-06 23:46:12.000000000 +0000
++++ ioemu/vnc.c        2006-12-06 23:46:12.000000000 +0000
 @@ -28,7 +28,19 @@
  #include "qemu_socket.h"
  #include <assert.h>
@@ -45,7 +45,7 @@ Index: ioemu/vnc.c
      int ctl_keys;               /* Ctrl+Alt starts calibration */
  };
  
-@@ -381,7 +392,7 @@
+@@ -383,7 +394,7 @@
      int y = 0;
      int pitch = ds->linesize;
      VncState *vs = ds->opaque;
@@ -54,7 +54,7 @@ Index: ioemu/vnc.c
  
      if (src_x < vs->visible_x || src_y < vs->visible_y ||
        dst_x < vs->visible_x || dst_y < vs->visible_y ||
-@@ -391,10 +402,8 @@
+@@ -393,10 +404,8 @@
        (dst_y + h) > (vs->visible_y + vs->visible_h))
        updating_client = 0;
  
@@ -66,7 +66,7 @@ Index: ioemu/vnc.c
  
      if (dst_y > src_y) {
        y = h - 1;
-@@ -446,110 +455,149 @@
+@@ -448,110 +457,149 @@
  static void _vnc_update_client(void *opaque)
  {
      VncState *vs = opaque;
@@ -299,7 +299,7 @@ Index: ioemu/vnc.c
  }
  
  static void vnc_update_client(void *opaque)
-@@ -562,8 +610,10 @@
+@@ -564,8 +612,10 @@
  
  static void vnc_timer_init(VncState *vs)
  {
@@ -311,7 +311,7 @@ Index: ioemu/vnc.c
  }
  
  static void vnc_dpy_refresh(DisplayState *ds)
-@@ -623,7 +673,6 @@
+@@ -625,7 +675,6 @@
        vs->csock = -1;
        buffer_reset(&vs->input);
        buffer_reset(&vs->output);
@@ -319,7 +319,7 @@ Index: ioemu/vnc.c
        return 0;
      }
      return ret;
-@@ -895,7 +944,6 @@
+@@ -897,7 +946,6 @@
                                       int x_position, int y_position,
                                       int w, int h)
  {
@@ -327,7 +327,7 @@ Index: ioemu/vnc.c
      if (!incremental)
        framebuffer_set_updated(vs, x_position, y_position, w, h);
      vs->visible_x = x_position;
-@@ -1018,6 +1066,7 @@
+@@ -1020,6 +1068,7 @@
  {
      int i;
      uint16_t limit;
@@ -335,7 +335,7 @@ Index: ioemu/vnc.c
  
      switch (data[0]) {
      case 0:
-@@ -1061,12 +1110,18 @@
+@@ -1063,12 +1112,18 @@
        if (len == 1)
            return 8;
  
@@ -356,8 +356,8 @@ Index: ioemu/vnc.c
      case 6:
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:33:17.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:33:24.000000000 +0100
+--- 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 @@
      }
  }
@@ -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-10-24 14:33:17.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:33:24.000000000 +0100
+--- ioemu.orig/vl.h    2006-12-06 23:46:12.000000000 +0000
++++ ioemu/vl.h 2006-12-06 23:46:12.000000000 +0000
 @@ -407,6 +407,7 @@
  void qemu_free_timer(QEMUTimer *ts);
  void qemu_del_timer(QEMUTimer *ts);
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-display-find-unused
--- a/tools/ioemu/patches/vnc-display-find-unused       Fri Dec 08 11:31:29 
2006 -0700
+++ b/tools/ioemu/patches/vnc-display-find-unused       Sat Dec 09 14:34:53 
2006 +0000
@@ -1,8 +1,8 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-10-24 14:31:09.000000000 +0100
-+++ ioemu/vnc.c        2006-10-24 14:31:36.000000000 +0100
-@@ -1195,7 +1195,7 @@
+--- ioemu.orig/vnc.c   2006-12-08 02:02:36.000000000 +0000
++++ ioemu/vnc.c        2006-12-08 02:02:37.000000000 +0000
+@@ -1197,7 +1197,7 @@
      }
  }
  
@@ -11,7 +11,7 @@ Index: ioemu/vnc.c
  {
      struct sockaddr_in addr;
      int reuse_addr, ret;
-@@ -1226,10 +1226,6 @@
+@@ -1228,10 +1228,6 @@
        exit(1);
      }
  
@@ -22,7 +22,7 @@ Index: ioemu/vnc.c
      reuse_addr = 1;
      ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
                     (const char *)&reuse_addr, sizeof(reuse_addr));
-@@ -1238,7 +1234,16 @@
+@@ -1240,7 +1236,16 @@
        exit(1);
      }
  
@@ -39,7 +39,7 @@ Index: ioemu/vnc.c
        fprintf(stderr, "bind() failed\n");
        exit(1);
      }
-@@ -1259,6 +1264,8 @@
+@@ -1261,6 +1266,8 @@
      vs->ds->dpy_refresh = vnc_dpy_refresh;
  
      vnc_dpy_resize(vs->ds, 640, 400);
@@ -50,8 +50,8 @@ Index: ioemu/vnc.c
  int vnc_start_viewer(int port)
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:31:09.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:31:41.000000000 +0100
+--- ioemu.orig/vl.c    2006-12-08 02:02:36.000000000 +0000
++++ ioemu/vl.c 2006-12-08 02:02:37.000000000 +0000
 @@ -121,6 +121,7 @@
  static DisplayState display_state;
  int nographic;
@@ -84,7 +84,7 @@ Index: ioemu/vl.c
      
      /* temporary options */
      { "usb", 0, QEMU_OPTION_usb },
-@@ -5873,6 +5877,7 @@
+@@ -5857,6 +5861,7 @@
      snapshot = 0;
      nographic = 0;
      vncviewer = 0;
@@ -92,7 +92,7 @@ Index: ioemu/vl.c
      kernel_filename = NULL;
      kernel_cmdline = "";
  #ifdef TARGET_PPC
-@@ -6270,6 +6275,11 @@
+@@ -6254,6 +6259,11 @@
              case QEMU_OPTION_vncviewer:
                  vncviewer++;
                  break;
@@ -104,7 +104,7 @@ Index: ioemu/vl.c
              }
          }
      }
-@@ -6483,7 +6493,7 @@
+@@ -6468,7 +6478,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-10-24 14:31:09.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:31:36.000000000 +0100
+--- ioemu.orig/vl.h    2006-12-08 02:02:36.000000000 +0000
++++ ioemu/vl.h 2006-12-08 02:02:37.000000000 +0000
 @@ -785,7 +785,7 @@
  void cocoa_display_init(DisplayState *ds, int full_screen);
  
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-fixes
--- a/tools/ioemu/patches/vnc-fixes     Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/vnc-fixes     Sat Dec 09 14:34:53 2006 +0000
@@ -1,8 +1,8 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 13:47:23.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:19:36.000000000 +0100
-@@ -6534,8 +6534,10 @@
+--- ioemu.orig/vl.c    2006-12-08 02:02:36.000000000 +0000
++++ ioemu/vl.c 2006-12-08 02:02:36.000000000 +0000
+@@ -6519,8 +6519,10 @@
          }
      }
  
@@ -17,8 +17,8 @@ Index: ioemu/vl.c
      if (use_gdbstub) {
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-10-24 13:47:23.000000000 +0100
-+++ ioemu/vnc.c        2006-10-24 14:20:00.000000000 +0100
+--- ioemu.orig/vnc.c   2006-12-08 02:02:36.000000000 +0000
++++ ioemu/vnc.c        2006-12-08 02:02:36.000000000 +0000
 @@ -3,6 +3,7 @@
   * 
   * Copyright (C) 2006 Anthony Liguori <anthony@xxxxxxxxxxxxx>
@@ -92,7 +92,7 @@ Index: ioemu/vnc.c
  static inline void vnc_set_bit(uint32_t *d, int k)
  {
      d[k >> 5] |= 1 << (k & 0x1f);
-@@ -139,20 +161,35 @@
+@@ -139,20 +161,37 @@
      }
      return 0;
  }
@@ -121,6 +121,8 @@ Index: ioemu/vnc.c
        mask = ~(0ULL);
  
 +    h += y;
++    if (h > vs->ds->height)
++        h = vs->ds->height;
      for (; y < h; y++)
 -      vs->dirty_row[y] |= mask;
 +      row[y] |= mask;
@@ -134,7 +136,7 @@ Index: ioemu/vnc.c
  }
  
  static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
-@@ -169,16 +206,23 @@
+@@ -169,16 +208,23 @@
  static void vnc_dpy_resize(DisplayState *ds, int w, int h)
  {
      VncState *vs = ds->opaque;
@@ -160,7 +162,7 @@ Index: ioemu/vnc.c
      ds->width = w;
      ds->height = h;
      ds->linesize = w * vs->depth;
-@@ -191,6 +235,10 @@
+@@ -191,6 +237,10 @@
        vs->width = ds->width;
        vs->height = ds->height;
      }
@@ -171,7 +173,7 @@ Index: ioemu/vnc.c
  }
  
  /* fastest code */
-@@ -326,8 +374,20 @@
+@@ -326,8 +376,20 @@
      int y = 0;
      int pitch = ds->linesize;
      VncState *vs = ds->opaque;
@@ -193,7 +195,7 @@ Index: ioemu/vnc.c
  
      if (dst_y > src_y) {
        y = h - 1;
-@@ -349,31 +409,34 @@
+@@ -349,31 +411,34 @@
        old_row += pitch;
      }
  
@@ -240,7 +242,7 @@ Index: ioemu/vnc.c
  {
      VncState *vs = opaque;
      int64_t now = qemu_get_clock(rt_clock);
-@@ -382,14 +445,18 @@
+@@ -382,14 +447,18 @@
        int y;
        char *row;
        char *old_row;
@@ -262,7 +264,7 @@ Index: ioemu/vnc.c
  
        /* Walk through the dirty map and eliminate tiles that
           really aren't dirty */
-@@ -397,23 +464,25 @@
+@@ -397,23 +466,25 @@
        old_row = vs->old_data;
  
        for (y = 0; y < vs->ds->height; y++) {
@@ -297,7 +299,7 @@ Index: ioemu/vnc.c
                }
            }
  
-@@ -421,7 +490,8 @@
+@@ -421,7 +492,8 @@
            old_row += vs->ds->linesize;
        }
  
@@ -307,7 +309,7 @@ Index: ioemu/vnc.c
            return;
  
        /* Count rectangles */
-@@ -431,34 +501,56 @@
+@@ -431,34 +503,56 @@
        saved_offset = vs->output.offset;
        vnc_write_u16(vs, 0);
  
@@ -375,7 +377,7 @@ Index: ioemu/vnc.c
  }
  
  static void vnc_timer_init(VncState *vs)
-@@ -469,8 +561,6 @@
+@@ -469,8 +563,6 @@
  
  static void vnc_dpy_refresh(DisplayState *ds)
  {
@@ -384,7 +386,7 @@ Index: ioemu/vnc.c
      vga_hw_update();
  }
  
-@@ -506,7 +596,7 @@
+@@ -506,7 +598,7 @@
  
  static void buffer_reset(Buffer *buffer)
  {
@@ -393,7 +395,7 @@ Index: ioemu/vnc.c
  }
  
  static void buffer_append(Buffer *buffer, const void *data, size_t len)
-@@ -547,12 +637,12 @@
+@@ -547,12 +639,12 @@
      if (!ret)
        return;
  
@@ -409,7 +411,7 @@ Index: ioemu/vnc.c
  }
  
  static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
-@@ -584,11 +674,11 @@
+@@ -584,11 +676,11 @@
            return;
  
        if (!ret) {
@@ -424,7 +426,7 @@ Index: ioemu/vnc.c
      }
  }
  
-@@ -596,9 +686,9 @@
+@@ -596,9 +688,9 @@
  {
      buffer_reserve(&vs->output, len);
  
@@ -437,7 +439,7 @@ Index: ioemu/vnc.c
  
      buffer_append(&vs->output, data, len);
  }
-@@ -720,22 +810,25 @@
+@@ -720,22 +812,25 @@
      do_key_event(vs, down, sym);
  }
  
@@ -474,7 +476,7 @@ Index: ioemu/vnc.c
  
      qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
  }
-@@ -843,8 +936,6 @@
+@@ -843,8 +938,6 @@
      }
  
      vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
@@ -483,7 +485,7 @@ Index: ioemu/vnc.c
  
      vga_hw_invalidate();
      vga_hw_update();
-@@ -924,6 +1015,8 @@
+@@ -924,6 +1017,8 @@
  {
      char pad[3] = { 0, 0, 0 };
  
@@ -492,7 +494,7 @@ Index: ioemu/vnc.c
      vs->width = vs->ds->width;
      vs->height = vs->ds->height;
      vnc_write_u16(vs, vs->ds->width);
-@@ -1010,11 +1103,11 @@
+@@ -1010,11 +1105,11 @@
        vnc_write(vs, "RFB 003.003\n", 12);
        vnc_flush(vs);
        vnc_read_when(vs, protocol_version, 12);
@@ -506,7 +508,7 @@ Index: ioemu/vnc.c
      }
  }
  
-@@ -1071,17 +1164,15 @@
+@@ -1071,17 +1166,15 @@
        exit(1);
      }
  
@@ -529,8 +531,8 @@ Index: ioemu/vnc.c
  }
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-10-24 13:47:23.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:19:36.000000000 +0100
+--- ioemu.orig/vl.h    2006-12-08 02:02:36.000000000 +0000
++++ ioemu/vl.h 2006-12-08 02:02:36.000000000 +0000
 @@ -319,6 +319,7 @@
  int is_graphic_console(void);
  CharDriverState *text_console_init(DisplayState *ds);
diff -r 1cfd862e5254 -r 8cddaee4a51c 
tools/ioemu/patches/vnc-listen-specific-interface
--- a/tools/ioemu/patches/vnc-listen-specific-interface Fri Dec 08 11:31:29 
2006 -0700
+++ b/tools/ioemu/patches/vnc-listen-specific-interface Sat Dec 09 14:34:53 
2006 +0000
@@ -20,8 +20,8 @@ Signed-off-by:  Daniel P. Berrange <berr
 
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:33:46.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:34:28.000000000 +0100
+--- ioemu.orig/vl.c    2006-12-08 02:02:37.000000000 +0000
++++ ioemu/vl.c 2006-12-08 02:02:37.000000000 +0000
 @@ -122,6 +122,7 @@
  int nographic;
  int vncviewer;
@@ -95,7 +95,7 @@ Index: ioemu/vl.c
      
      /* temporary options */
      { "usb", 0, QEMU_OPTION_usb },
-@@ -5905,6 +5915,8 @@
+@@ -5889,6 +5899,8 @@
  
      nb_nics = 0;
      /* default mac address of the first network interface */
@@ -103,8 +103,8 @@ Index: ioemu/vl.c
 +    memset(&vnclisten_addr.sin_addr, 0, sizeof(vnclisten_addr.sin_addr));
      
      /* init debug */
-     sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%d.log", getpid());
-@@ -6280,6 +6292,9 @@
+     sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%ld.log", 
(long)getpid());
+@@ -6264,6 +6276,9 @@
                  if (vnc_display == -1)
                      vnc_display = 0;
                  break;
@@ -114,7 +114,7 @@ Index: ioemu/vl.c
              }
          }
      }
-@@ -6493,7 +6508,7 @@
+@@ -6478,7 +6493,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-10-24 14:33:46.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:34:22.000000000 +0100
+--- ioemu.orig/vl.h    2006-12-08 02:02:37.000000000 +0000
++++ ioemu/vl.h 2006-12-08 02:02:37.000000000 +0000
 @@ -37,6 +37,8 @@
  #include <unistd.h>
  #include <fcntl.h>
@@ -147,9 +147,9 @@ Index: ioemu/vl.h
  /* ide.c */
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-10-24 14:33:46.000000000 +0100
-+++ ioemu/vnc.c        2006-10-24 14:34:22.000000000 +0100
-@@ -1195,9 +1195,8 @@
+--- ioemu.orig/vnc.c   2006-12-08 02:02:37.000000000 +0000
++++ ioemu/vnc.c        2006-12-08 02:02:37.000000000 +0000
+@@ -1197,9 +1197,8 @@
      }
  }
  
@@ -160,7 +160,7 @@ Index: ioemu/vnc.c
      int reuse_addr, ret;
      VncState *vs;
  
-@@ -1235,11 +1234,10 @@
+@@ -1237,11 +1236,10 @@
      }
  
   retry:
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-password
--- a/tools/ioemu/patches/vnc-password  Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/vnc-password  Sat Dec 09 14:34:53 2006 +0000
@@ -15,9 +15,11 @@ The difference is follows.
 
 Signed-off-by: Masami Watanabe <masami.watanabe@xxxxxxxxxxxxxx>
 
---- ioemu/Makefile.target      Fri Oct 20 09:32:16 2006 +0100
-+++ ioemu/Makefile.target      Fri Oct 20 09:50:09 2006 +0100
-@@ -406,6 +406,7 @@ VL_OBJS+=sdl.o
+Index: ioemu/Makefile.target
+===================================================================
+--- ioemu.orig/Makefile.target 2006-12-08 18:20:53.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 18:20:53.000000000 +0000
+@@ -407,6 +407,7 @@
  VL_OBJS+=sdl.o
  endif
  VL_OBJS+=vnc.o
@@ -25,29 +27,31 @@ Signed-off-by: Masami Watanabe <masami.w
  ifdef CONFIG_COCOA
  VL_OBJS+=cocoa.o
  COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit
-@@ -464,6 +465,9 @@ sdl.o: sdl.c keymaps.c sdl_keysym.h
+@@ -467,6 +468,9 @@
+ vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h
+       $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
+ 
++d3des.o: d3des.c d3des.h
++      $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
++
+ sdlaudio.o: sdlaudio.c
        $(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
  
- vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h
-+      $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
-+
-+d3des.o: d3des.c d3des.h
-       $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
- 
- sdlaudio.o: sdlaudio.c
---- ioemu/vl.c Fri Oct 20 09:32:16 2006 +0100
-+++ ioemu/vl.c Fri Oct 20 09:50:09 2006 +0100
-@@ -170,6 +170,9 @@ time_t timeoffset = 0;
- 
+Index: ioemu/vl.c
+===================================================================
+--- ioemu.orig/vl.c    2006-12-08 18:20:52.000000000 +0000
++++ ioemu/vl.c 2006-12-08 18:20:53.000000000 +0000
+@@ -171,6 +171,9 @@
  char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
  extern int domid;
-+
+ 
 +char vncpasswd[64];
 +unsigned char challenge[AUTHCHALLENGESIZE];
- 
++
  /***********************************************************/
  /* x86 ISA bus support */
-@@ -5911,6 +5914,7 @@ int main(int argc, char **argv)
+ 
+@@ -5895,6 +5898,7 @@
      vncunused = 0;
      kernel_filename = NULL;
      kernel_cmdline = "";
@@ -55,7 +59,7 @@ Signed-off-by: Masami Watanabe <masami.w
  #ifndef CONFIG_DM
  #ifdef TARGET_PPC
      cdrom_index = 1;
-@@ -6559,6 +6563,10 @@ int main(int argc, char **argv)
+@@ -6543,6 +6547,10 @@
  
      init_ioports();
  
@@ -66,9 +70,11 @@ Signed-off-by: Masami Watanabe <masami.w
      /* terminal init */
      if (nographic) {
          dumb_display_init(ds);
---- ioemu/vl.h Fri Oct 20 09:32:16 2006 +0100
-+++ ioemu/vl.h Fri Oct 20 09:50:09 2006 +0100
-@@ -1211,6 +1211,7 @@ void xenstore_process_event(void *opaque
+Index: ioemu/vl.h
+===================================================================
+--- ioemu.orig/vl.h    2006-12-08 18:20:52.000000000 +0000
++++ ioemu/vl.h 2006-12-08 18:20:53.000000000 +0000
+@@ -1214,6 +1214,7 @@
  void xenstore_process_event(void *opaque);
  void xenstore_check_new_media_present(int timeout);
  void xenstore_write_vncport(int vnc_display);
@@ -76,7 +82,7 @@ Signed-off-by: Masami Watanabe <masami.w
  
  /* xen_platform.c */
  void pci_xen_platform_init(PCIBus *bus);
-@@ -1222,4 +1223,7 @@ extern char domain_name[];
+@@ -1225,4 +1226,7 @@
  
  void destroy_hvm_domain(void);
  
@@ -84,8 +90,10 @@ Signed-off-by: Masami Watanabe <masami.w
 +#define AUTHCHALLENGESIZE 16
 +
  #endif /* VL_H */
---- ioemu/vnc.c        Fri Oct 20 09:32:16 2006 +0100
-+++ ioemu/vnc.c        Fri Oct 20 09:50:09 2006 +0100
+Index: ioemu/vnc.c
+===================================================================
+--- ioemu.orig/vnc.c   2006-12-08 18:20:52.000000000 +0000
++++ ioemu/vnc.c        2006-12-08 18:20:53.000000000 +0000
 @@ -44,6 +44,7 @@
  
  #include "vnc_keysym.h"
@@ -94,7 +102,7 @@ Signed-off-by: Masami Watanabe <masami.w
  
  #define XK_MISCELLANY
  #define XK_LATIN1
-@@ -137,6 +138,9 @@ static void vnc_update_client(void *opaq
+@@ -137,6 +138,9 @@
  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);
@@ -104,7 +112,7 @@ Signed-off-by: Masami Watanabe <masami.w
  
  #if 0
  static inline void vnc_set_bit(uint32_t *d, int k)
-@@ -1208,23 +1212,92 @@ static int protocol_client_init(VncState
+@@ -1210,23 +1214,92 @@
      return 0;
  }
  
@@ -166,9 +174,8 @@ Signed-off-by: Masami Watanabe <masami.w
  
 -    vnc_write_u32(vs, 1); /* None */
 -    vnc_flush(vs);
--
+ 
 -    vnc_read_when(vs, protocol_client_init, 1);
-+
 +    support = 0;
 +    if (maj = 3) {
 +      if (min == 3 || min ==4) {
@@ -202,7 +209,7 @@ Signed-off-by: Masami Watanabe <masami.w
  
      return 0;
  }
-@@ -1342,3 +1415,32 @@ int vnc_start_viewer(int port)
+@@ -1344,3 +1417,32 @@
        return pid;
      }
  }
@@ -235,9 +242,11 @@ Signed-off-by: Masami Watanabe <masami.w
 +
 +    return;
 +}
---- ioemu/xenstore.c   Fri Oct 20 09:32:16 2006 +0100
-+++ ioemu/xenstore.c   Fri Oct 20 09:50:09 2006 +0100
-@@ -213,3 +213,54 @@ void xenstore_write_vncport(int display)
+Index: ioemu/xenstore.c
+===================================================================
+--- ioemu.orig/xenstore.c      2006-12-08 18:20:52.000000000 +0000
++++ ioemu/xenstore.c   2006-12-08 18:20:53.000000000 +0000
+@@ -213,3 +213,54 @@
      free(portstr);
      free(buf);
  }
@@ -292,8 +301,10 @@ Signed-off-by: Masami Watanabe <masami.w
 +
 +    return rc;
 +}
---- /dev/null  Thu Jan 01 00:00:00 1970 +0000
-+++ ioemu/d3des.c      Fri Oct 20 09:50:09 2006 +0100
+Index: ioemu/d3des.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ ioemu/d3des.c      2006-12-08 18:20:53.000000000 +0000
 @@ -0,0 +1,434 @@
 +/*
 + * This is D3DES (V5.09) by Richard Outerbridge with the double and
@@ -729,8 +740,10 @@ Signed-off-by: Masami Watanabe <masami.w
 + *
 + * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
 + **********************************************************************/
---- /dev/null  Thu Jan 01 00:00:00 1970 +0000
-+++ ioemu/d3des.h      Fri Oct 20 09:50:09 2006 +0100
+Index: ioemu/d3des.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ ioemu/d3des.h      2006-12-08 18:20:53.000000000 +0000
 @@ -0,0 +1,51 @@
 +/*
 + * This is D3DES (V5.09) by Richard Outerbridge with the double and
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-protocol-fixes
--- a/tools/ioemu/patches/vnc-protocol-fixes    Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/vnc-protocol-fixes    Sat Dec 09 14:34:53 2006 +0000
@@ -9,8 +9,8 @@ Signed-off-by: Steven Smith <sos22@xxxxx
 
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-10-24 14:28:05.000000000 +0100
-+++ ioemu/vnc.c        2006-10-24 14:30:11.000000000 +0100
+--- ioemu.orig/vnc.c   2006-12-06 23:46:11.000000000 +0000
++++ ioemu/vnc.c        2006-12-06 23:46:11.000000000 +0000
 @@ -26,6 +26,7 @@
  
  #include "vl.h"
@@ -19,7 +19,7 @@ Index: ioemu/vnc.c
  
  #define VNC_REFRESH_INTERVAL (1000 / 30)
  
-@@ -677,8 +678,10 @@
+@@ -679,8 +680,10 @@
            memmove(vs->input.buffer, vs->input.buffer + len,
                    vs->input.offset - len);
            vs->input.offset -= len;
@@ -31,7 +31,7 @@ Index: ioemu/vnc.c
      }
  }
  
-@@ -961,8 +964,12 @@
+@@ -963,8 +966,12 @@
        if (len == 1)
            return 4;
  
@@ -46,7 +46,7 @@ Index: ioemu/vnc.c
  
        limit = read_u16(data, 2);
        for (i = 0; i < limit; i++) {
-@@ -996,8 +1003,12 @@
+@@ -998,8 +1005,12 @@
        if (len == 1)
            return 8;
  
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-start-vncviewer
--- a/tools/ioemu/patches/vnc-start-vncviewer   Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/vnc-start-vncviewer   Sat Dec 09 14:34:53 2006 +0000
@@ -1,8 +1,8 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-10-24 14:33:46.000000000 +0100
-+++ ioemu/vnc.c        2006-10-24 14:33:46.000000000 +0100
-@@ -1187,3 +1187,25 @@
+--- ioemu.orig/vnc.c   2006-12-08 02:02:36.000000000 +0000
++++ ioemu/vnc.c        2006-12-08 02:02:36.000000000 +0000
+@@ -1189,3 +1189,25 @@
  
      vnc_dpy_resize(vs->ds, 640, 400);
  }
@@ -30,8 +30,8 @@ Index: ioemu/vnc.c
 +}
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:33:46.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:33:46.000000000 +0100
+--- ioemu.orig/vl.c    2006-12-08 02:02:36.000000000 +0000
++++ ioemu/vl.c 2006-12-08 02:02:36.000000000 +0000
 @@ -120,6 +120,7 @@
  int bios_size;
  static DisplayState display_state;
@@ -64,7 +64,7 @@ Index: ioemu/vl.c
      
      /* temporary options */
      { "usb", 0, QEMU_OPTION_usb },
-@@ -5868,6 +5872,7 @@
+@@ -5852,6 +5856,7 @@
  #endif
      snapshot = 0;
      nographic = 0;
@@ -72,7 +72,7 @@ Index: ioemu/vl.c
      kernel_filename = NULL;
      kernel_cmdline = "";
  #ifdef TARGET_PPC
-@@ -6262,6 +6267,9 @@
+@@ -6246,6 +6251,9 @@
              case QEMU_OPTION_acpi:
                  acpi_enabled = 1;
                  break;
@@ -82,7 +82,7 @@ Index: ioemu/vl.c
              }
          }
      }
-@@ -6476,6 +6484,8 @@
+@@ -6461,6 +6469,8 @@
          dumb_display_init(ds);
      } else if (vnc_display != -1) {
        vnc_display_init(ds, vnc_display);
@@ -93,8 +93,8 @@ Index: ioemu/vl.c
          sdl_display_init(ds, full_screen);
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-10-24 14:33:46.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:33:46.000000000 +0100
+--- ioemu.orig/vl.h    2006-12-08 02:02:36.000000000 +0000
++++ ioemu/vl.h 2006-12-08 02:02:36.000000000 +0000
 @@ -786,6 +786,7 @@
  
  /* vnc.c */
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-title-domain-name
--- a/tools/ioemu/patches/vnc-title-domain-name Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/vnc-title-domain-name Sat Dec 09 14:34:53 2006 +0000
@@ -1,8 +1,8 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-10-24 14:33:46.000000000 +0100
-+++ ioemu/vnc.c        2006-10-24 14:33:46.000000000 +0100
-@@ -1024,6 +1024,7 @@
+--- ioemu.orig/vnc.c   2006-12-06 23:46:11.000000000 +0000
++++ ioemu/vnc.c        2006-12-06 23:46:11.000000000 +0000
+@@ -1026,6 +1026,7 @@
  
  static int protocol_client_init(VncState *vs, char *data, size_t len)
  {
@@ -10,7 +10,7 @@ Index: ioemu/vnc.c
      char pad[3] = { 0, 0, 0 };
  
      vga_hw_update();
-@@ -1071,8 +1072,10 @@
+@@ -1073,8 +1074,10 @@
        
      vnc_write(vs, pad, 3);           /* padding */
  
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xen-build
--- a/tools/ioemu/patches/xen-build     Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/xen-build     Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/Makefile
 Index: ioemu/Makefile
 ===================================================================
---- ioemu.orig/Makefile        2006-10-24 14:37:25.000000000 +0100
-+++ ioemu/Makefile     2006-10-24 14:37:28.000000000 +0100
+--- ioemu.orig/Makefile        2006-12-08 01:26:04.000000000 +0000
++++ ioemu/Makefile     2006-12-08 01:26:06.000000000 +0000
 @@ -1,11 +1,14 @@
  # Makefile for QEMU.
  
@@ -85,8 +85,8 @@ Index: ioemu/Makefile
  info: qemu-doc.info qemu-tech.info
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-10-24 14:37:25.000000000 +0100
-+++ ioemu/Makefile.target      2006-10-24 14:40:25.000000000 +0100
+--- ioemu.orig/Makefile.target 2006-12-08 01:26:04.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 01:41:05.000000000 +0000
 @@ -1,5 +1,8 @@
  include config.mak
  
@@ -120,9 +120,13 @@ Index: ioemu/Makefile.target
  #CFLAGS+=-Werror
  LDFLAGS=-g
  LIBS=
-@@ -167,6 +177,9 @@
- 
- DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+@@ -165,8 +175,12 @@
+ 
+ #########################################################
+ 
+-DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
++DEFINES+=-D_GNU_SOURCE
++#-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
  LIBS+=-lm
 +LIBS+=-L../../libxc -lxenctrl -lxenguest
 +LIBS+=-L../../xenstore -lxenstore
@@ -130,7 +134,7 @@ Index: ioemu/Makefile.target
  ifndef CONFIG_USER_ONLY
  LIBS+=-lz
  endif
-@@ -281,7 +294,7 @@
+@@ -281,7 +295,7 @@
  all: $(PROGS)
  
  $(QEMU_USER): $(OBJS)
@@ -139,7 +143,7 @@ Index: ioemu/Makefile.target
  ifeq ($(ARCH),alpha)
  # Mark as 32 bit binary, i. e. it will be mapped into the low 31 bit of
  # the address space (31 bit so sign extending doesn't matter)
-@@ -528,10 +541,16 @@
+@@ -528,10 +542,16 @@
  clean:
        rm -f *.o  *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o slirp/*.o 
fpu/*.o
  
@@ -159,8 +163,8 @@ Index: ioemu/Makefile.target
  include .depend
 Index: ioemu/configure
 ===================================================================
---- ioemu.orig/configure       2006-10-24 14:37:25.000000000 +0100
-+++ ioemu/configure    2006-10-24 14:40:20.000000000 +0100
+--- ioemu.orig/configure       2006-12-08 01:26:04.000000000 +0000
++++ ioemu/configure    2006-12-08 01:40:58.000000000 +0000
 @@ -18,8 +18,8 @@
  
  # default parameters
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xen-mm
--- a/tools/ioemu/patches/xen-mm        Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/xen-mm        Sat Dec 09 14:34:53 2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/hw/pc.c
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-08-17 19:36:00.588166019 +0100
-+++ ioemu/hw/pc.c      2006-08-17 19:37:36.704485734 +0100
+--- 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
 @@ -646,7 +646,9 @@
      }
  
@@ -25,8 +25,8 @@ Index: ioemu/hw/pc.c
      isa_bios_size = bios_size;
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:36:00.667157242 +0100
-+++ ioemu/vl.c 2006-08-17 19:47:08.538087284 +0100
+--- 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 @@
  int acpi_enabled = 1;
  int fd_bootchk = 1;
@@ -60,7 +60,7 @@ Index: ioemu/vl.c
                  break;
              case QEMU_OPTION_l:
                  {
-@@ -6133,12 +6140,67 @@
+@@ -6133,12 +6140,61 @@
      /* init the memory */
      phys_ram_size = ram_size + vga_ram_size + bios_size;
  
@@ -85,14 +85,8 @@ Index: ioemu/vl.c
 +        exit(-1);
 +    }
 +
-+    if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
-+        fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
-+        exit(-1);
-+    }
-+
-+    if (ram_size > HVM_BELOW_4G_RAM_END)
-+        for (i = 0; i < nr_pages - (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT); i++)
-+            page_array[tmp_nr_pages - 1 - i] = page_array[nr_pages - 1 - i];
++    for ( i = 0; i < tmp_nr_pages; i++)
++        page_array[i] = i;
 +
 +    phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
 +                                         PROT_READ|PROT_WRITE, page_array,
@@ -130,8 +124,8 @@ Index: ioemu/vl.c
      if (cdrom_index >= 0) {
 Index: ioemu/hw/piix_pci.c
 ===================================================================
---- ioemu.orig/hw/piix_pci.c   2006-08-17 19:37:36.189542951 +0100
-+++ ioemu/hw/piix_pci.c        2006-08-17 19:38:05.806252180 +0100
+--- 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
 @@ -399,7 +399,7 @@
      uint8_t elcr[2];
  
@@ -143,8 +137,8 @@ Index: ioemu/hw/piix_pci.c
      elcr[0] = 0x00;
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:37:36.529505177 +0100
-+++ ioemu/vl.h 2006-08-17 19:47:32.680418959 +0100
+--- ioemu.orig/vl.h    2006-12-08 02:00:39.000000000 +0000
++++ ioemu/vl.h 2006-12-08 02:02:07.000000000 +0000
 @@ -39,6 +39,7 @@
  #include <sys/stat.h>
  #include "xenctrl.h"
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xen-platform-device
--- a/tools/ioemu/patches/xen-platform-device   Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/ioemu/patches/xen-platform-device   Sat Dec 09 14:34:53 2006 +0000
@@ -3,9 +3,9 @@ will come later.
 
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-10-24 14:41:01.000000000 +0100
-+++ ioemu/Makefile.target      2006-10-24 14:41:01.000000000 +0100
-@@ -359,6 +359,7 @@
+--- ioemu.orig/Makefile.target 2006-12-08 01:41:14.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 01:41:15.000000000 +0000
+@@ -360,6 +360,7 @@
  VL_OBJS+= usb-uhci.o
  VL_OBJS+= piix4acpi.o
  VL_OBJS+= xenstore.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-10-24 14:41:00.000000000 +0100
-+++ ioemu/hw/pc.c      2006-10-24 14:41:01.000000000 +0100
+--- 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
 @@ -823,6 +823,9 @@
      }
  #endif /* !CONFIG_DM */
@@ -30,7 +30,7 @@ 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-10-24 14:41:04.000000000 +0100
++++ ioemu/hw/xen_platform.c    2006-12-08 01:41:15.000000000 +0000
 @@ -0,0 +1,144 @@
 +/*
 + * XEN platform fake pci device, formerly known as the event channel device
@@ -178,8 +178,8 @@ Index: ioemu/hw/xen_platform.c
 +}
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-10-24 14:41:01.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:41:01.000000000 +0100
+--- 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);
diff -r 1cfd862e5254 -r 8cddaee4a51c 
tools/ioemu/patches/xen-support-buffered-ioreqs
--- a/tools/ioemu/patches/xen-support-buffered-ioreqs   Fri Dec 08 11:31:29 
2006 -0700
+++ b/tools/ioemu/patches/xen-support-buffered-ioreqs   Sat Dec 09 14:34:53 
2006 +0000
@@ -1,8 +1,8 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:33:47.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:33:47.000000000 +0100
-@@ -5854,6 +5854,7 @@
+--- ioemu.orig/vl.c    2006-12-08 02:02:37.000000000 +0000
++++ ioemu/vl.c 2006-12-08 02:02:37.000000000 +0000
+@@ -5838,6 +5838,7 @@
      unsigned long nr_pages, tmp_nr_pages, shared_page_nr;
      xen_pfn_t *page_array;
      extern void *shared_page;
@@ -10,11 +10,10 @@ Index: ioemu/vl.c
  
      char qemu_dm_logfilename[64];
  
-@@ -6440,6 +6441,18 @@
+@@ -6418,6 +6419,17 @@
      fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n",
              shared_page_nr, (uint64_t)(page_array[shared_page_nr]));
  
-+    /* not yet add for IA64 */
 +    buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
 +                                            PROT_READ|PROT_WRITE,
 +                                            page_array[shared_page_nr - 2]);
@@ -31,8 +30,8 @@ Index: ioemu/vl.c
  #elif defined(__ia64__)
 Index: ioemu/target-i386-dm/helper2.c
 ===================================================================
---- ioemu.orig/target-i386-dm/helper2.c        2006-10-24 14:33:45.000000000 
+0100
-+++ ioemu/target-i386-dm/helper2.c     2006-10-24 14:33:47.000000000 +0100
+--- ioemu.orig/target-i386-dm/helper2.c        2006-12-08 02:02:35.000000000 
+0000
++++ ioemu/target-i386-dm/helper2.c     2006-12-08 02:02:37.000000000 +0000
 @@ -76,6 +76,10 @@
  
  shared_iopage_t *shared_page = NULL;
@@ -44,14 +43,14 @@ Index: ioemu/target-i386-dm/helper2.c
  /* the evtchn fd for polling */
  int xce_handle = -1;
  
-@@ -419,36 +423,68 @@
-     req->u.data = tmp1;
+@@ -435,39 +439,71 @@
+     req->data = tmp1;
  }
  
 +void __handle_ioreq(CPUState *env, ioreq_t *req)
 +{
-+    if (!req->pdata_valid && req->dir == IOREQ_WRITE && req->size != 4)
-+      req->u.data &= (1UL << (8 * req->size)) - 1;
++    if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4)
++      req->data &= (1UL << (8 * req->size)) - 1;
 +
 +    switch (req->type) {
 +    case IOREQ_TYPE_PIO:
@@ -62,6 +61,9 @@ Index: ioemu/target-i386-dm/helper2.c
 +        break;
 +    case IOREQ_TYPE_AND:
 +        cpu_ioreq_and(env, req);
++        break;
++    case IOREQ_TYPE_ADD:
++        cpu_ioreq_add(env, req);
 +        break;
 +    case IOREQ_TYPE_OR:
 +        cpu_ioreq_or(env, req);
@@ -109,9 +111,9 @@ Index: ioemu/target-i386-dm/helper2.c
  
 +    handle_buffered_io(env);
      if (req) {
--        if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
+-        if ((!req->data_is_ptr) && (req->dir == IOREQ_WRITE)) {
 -            if (req->size != 4)
--                req->u.data &= (1UL << (8 * req->size))-1;
+-                req->data &= (1UL << (8 * req->size))-1;
 -        }
 -
 -        switch (req->type) {
@@ -124,6 +126,9 @@ Index: ioemu/target-i386-dm/helper2.c
 -        case IOREQ_TYPE_AND:
 -            cpu_ioreq_and(env, req);
 -            break;
+-        case IOREQ_TYPE_ADD:
+-            cpu_ioreq_add(env, req);
+-            break;
 -        case IOREQ_TYPE_OR:
 -            cpu_ioreq_or(env, req);
 -            break;
@@ -135,9 +140,9 @@ Index: ioemu/target-i386-dm/helper2.c
 -        }
 +        __handle_ioreq(env, req);
  
-         /* No state change if state = STATE_IORESP_HOOK */
-         if (req->state == STATE_IOREQ_INPROCESS) {
-@@ -466,6 +502,10 @@
+         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;
      int evtchn_fd = xc_evtchn_fd(xce_handle);
  
@@ -147,4 +152,4 @@ Index: ioemu/target-i386-dm/helper2.c
 +
      qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
  
-     env->send_event = 0;
+     while (1) {
diff -r 1cfd862e5254 -r 8cddaee4a51c 
tools/ioemu/patches/xenstore-block-device-config
--- a/tools/ioemu/patches/xenstore-block-device-config  Fri Dec 08 11:31:29 
2006 -0700
+++ b/tools/ioemu/patches/xenstore-block-device-config  Sat Dec 09 14:34:53 
2006 +0000
@@ -1,8 +1,8 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-10-24 14:31:36.000000000 +0100
-+++ ioemu/Makefile.target      2006-10-24 14:33:28.000000000 +0100
-@@ -358,6 +358,7 @@
+--- ioemu.orig/Makefile.target 2006-12-08 02:02:36.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 02:02:37.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
@@ -13,7 +13,7 @@ Index: ioemu/xenstore.c
 Index: ioemu/xenstore.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/xenstore.c   2006-10-24 14:33:28.000000000 +0100
++++ ioemu/xenstore.c   2006-12-08 02:02:37.000000000 +0000
 @@ -0,0 +1,187 @@
 +/*
 + * This file is subject to the terms and conditions of the GNU General
@@ -117,7 +117,7 @@ Index: ioemu/xenstore.c
 +      if (strncmp(dev, "hd", 2) || strlen(dev) != 3)
 +          continue;
 +      hd_index = dev[2] - 'a';
-+      if (hd_index > MAX_DISKS)
++      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)
@@ -204,8 +204,8 @@ Index: ioemu/xenstore.c
 +}
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:33:24.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:33:28.000000000 +0100
+--- ioemu.orig/vl.c    2006-12-08 02:02:37.000000000 +0000
++++ ioemu/vl.c 2006-12-08 02:02:37.000000000 +0000
 @@ -5256,9 +5256,11 @@
             "Standard options:\n"
             "-M machine      select emulated machine (-M ? for list)\n"
@@ -246,7 +246,7 @@ Index: ioemu/vl.c
      { "boot", HAS_ARG, QEMU_OPTION_boot },
      { "snapshot", 0, QEMU_OPTION_snapshot },
  #ifdef TARGET_I386
-@@ -5817,10 +5823,16 @@
+@@ -5801,10 +5807,16 @@
  #ifdef CONFIG_GDBSTUB
      int use_gdbstub, gdbstub_port;
  #endif
@@ -265,7 +265,7 @@ Index: ioemu/vl.c
      const char *kernel_filename, *kernel_cmdline;
      DisplayState *ds = &display_state;
      int cyls, heads, secs, translation;
-@@ -5881,8 +5893,10 @@
+@@ -5865,8 +5877,10 @@
      initrd_filename = NULL;
      for(i = 0; i < MAX_FD; i++)
          fd_filename[i] = NULL;
@@ -276,7 +276,7 @@ Index: ioemu/vl.c
      ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
      vga_ram_size = VGA_RAM_SIZE;
      bios_size = BIOS_SIZE;
-@@ -5896,11 +5910,13 @@
+@@ -5880,11 +5894,13 @@
      vncunused = 0;
      kernel_filename = NULL;
      kernel_cmdline = "";
@@ -290,7 +290,7 @@ Index: ioemu/vl.c
      cyls = heads = secs = 0;
      translation = BIOS_ATA_TRANSLATION_AUTO;
      pstrcpy(monitor_device, sizeof(monitor_device), "vc");
-@@ -5935,7 +5951,11 @@
+@@ -5919,7 +5935,11 @@
              break;
          r = argv[optind];
          if (r[0] != '-') {
@@ -302,7 +302,7 @@ Index: ioemu/vl.c
          } else {
              const QEMUOption *popt;
  
-@@ -5979,6 +5999,7 @@
+@@ -5963,6 +5983,7 @@
              case QEMU_OPTION_initrd:
                  initrd_filename = optarg;
                  break;
@@ -310,7 +310,7 @@ Index: ioemu/vl.c
              case QEMU_OPTION_hda:
              case QEMU_OPTION_hdb:
              case QEMU_OPTION_hdc:
-@@ -5991,6 +6012,7 @@
+@@ -5975,6 +5996,7 @@
                          cdrom_index = -1;
                  }
                  break;
@@ -318,7 +318,7 @@ Index: ioemu/vl.c
              case QEMU_OPTION_snapshot:
                  snapshot = 1;
                  break;
-@@ -6043,11 +6065,13 @@
+@@ -6027,11 +6049,13 @@
              case QEMU_OPTION_append:
                  kernel_cmdline = optarg;
                  break;
@@ -332,7 +332,7 @@ Index: ioemu/vl.c
              case QEMU_OPTION_boot:
                  boot_device = optarg[0];
                  if (boot_device != 'a' && 
-@@ -6305,12 +6329,18 @@
+@@ -6289,12 +6313,18 @@
          }
      }
  
@@ -351,7 +351,7 @@ Index: ioemu/vl.c
      if (!linux_boot && 
          hd_filename[0] == '\0' && 
          (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
-@@ -6324,6 +6354,7 @@
+@@ -6308,6 +6338,7 @@
          else
              boot_device = 'd';
      }
@@ -359,7 +359,7 @@ Index: ioemu/vl.c
  
      setvbuf(stdout, NULL, _IOLBF, 0);
      
-@@ -6456,6 +6487,7 @@
+@@ -6441,6 +6472,7 @@
  
  #endif /* !CONFIG_DM */
  
@@ -367,7 +367,7 @@ Index: ioemu/vl.c
      /* we always create the cdrom drive, even if no disk is there */
      bdrv_init();
      if (cdrom_index >= 0) {
-@@ -6482,6 +6514,7 @@
+@@ -6467,6 +6499,7 @@
              }
          }
      }
@@ -375,7 +375,7 @@ Index: ioemu/vl.c
  
      /* we always create at least one floppy disk */
      fd_table[0] = bdrv_new("fda");
-@@ -6560,6 +6593,8 @@
+@@ -6545,6 +6578,8 @@
          }
      }
  
@@ -386,8 +386,8 @@ Index: ioemu/vl.c
                    kernel_filename, kernel_cmdline, initrd_filename,
 Index: ioemu/monitor.c
 ===================================================================
---- ioemu.orig/monitor.c       2006-10-24 14:31:36.000000000 +0100
-+++ ioemu/monitor.c    2006-10-24 14:33:28.000000000 +0100
+--- ioemu.orig/monitor.c       2006-12-08 02:02:35.000000000 +0000
++++ ioemu/monitor.c    2006-12-08 02:02:37.000000000 +0000
 @@ -24,6 +24,7 @@
  #include "vl.h"
  #include "disas.h"
@@ -416,8 +416,8 @@ Index: ioemu/monitor.c
      int i;
 Index: ioemu/block.c
 ===================================================================
---- ioemu.orig/block.c 2006-10-24 14:31:36.000000000 +0100
-+++ ioemu/block.c      2006-10-24 14:33:28.000000000 +0100
+--- ioemu.orig/block.c 2006-12-08 02:02:06.000000000 +0000
++++ ioemu/block.c      2006-12-08 02:02:37.000000000 +0000
 @@ -758,6 +758,7 @@
  static void raw_close(BlockDriverState *bs)
  {
@@ -428,8 +428,8 @@ Index: ioemu/block.c
  
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-10-24 14:33:24.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:33:28.000000000 +0100
+--- ioemu.orig/vl.h    2006-12-08 02:02:37.000000000 +0000
++++ ioemu/vl.h 2006-12-08 02:02:37.000000000 +0000
 @@ -1191,6 +1191,8 @@
  void term_print_help(void);
  void monitor_readline(const char *prompt, int is_password,
@@ -455,8 +455,8 @@ Index: ioemu/vl.h
  extern char domain_name[];
 Index: ioemu/hw/ide.c
 ===================================================================
---- ioemu.orig/hw/ide.c        2006-10-24 14:31:36.000000000 +0100
-+++ ioemu/hw/ide.c     2006-10-24 14:33:28.000000000 +0100
+--- ioemu.orig/hw/ide.c        2006-12-08 02:02:35.000000000 +0000
++++ ioemu/hw/ide.c     2006-12-08 02:02:37.000000000 +0000
 @@ -1158,6 +1158,7 @@
          } else {
              ide_atapi_cmd_error(s, SENSE_NOT_READY, 
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xenstore-write-vnc-port
--- a/tools/ioemu/patches/xenstore-write-vnc-port       Fri Dec 08 11:31:29 
2006 -0700
+++ b/tools/ioemu/patches/xenstore-write-vnc-port       Sat Dec 09 14:34:53 
2006 +0000
@@ -1,7 +1,7 @@ Index: ioemu/xenstore.c
 Index: ioemu/xenstore.c
 ===================================================================
---- ioemu.orig/xenstore.c      2006-10-24 14:33:47.000000000 +0100
-+++ ioemu/xenstore.c   2006-10-24 14:33:47.000000000 +0100
+--- ioemu.orig/xenstore.c      2006-12-08 02:02:37.000000000 +0000
++++ ioemu/xenstore.c   2006-12-08 02:02:37.000000000 +0000
 @@ -185,3 +185,31 @@
      free(image);
      free(vec);
@@ -36,9 +36,9 @@ Index: ioemu/xenstore.c
 +}
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-10-24 14:33:47.000000000 +0100
-+++ ioemu/vl.c 2006-10-24 14:33:47.000000000 +0100
-@@ -6550,6 +6550,7 @@
+--- ioemu.orig/vl.c    2006-12-08 02:02:37.000000000 +0000
++++ ioemu/vl.c 2006-12-08 02:02:37.000000000 +0000
+@@ -6535,6 +6535,7 @@
        vnc_display = vnc_display_init(ds, vnc_display, vncunused, 
&vnclisten_addr);
        if (vncviewer)
            vnc_start_viewer(vnc_display);
@@ -48,8 +48,8 @@ Index: ioemu/vl.c
          sdl_display_init(ds, full_screen);
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-10-24 14:33:47.000000000 +0100
-+++ ioemu/vl.h 2006-10-24 14:33:47.000000000 +0100
+--- ioemu.orig/vl.h    2006-12-08 02:02:37.000000000 +0000
++++ ioemu/vl.h 2006-12-08 02:02:37.000000000 +0000
 @@ -1210,6 +1210,7 @@
  int xenstore_fd(void);
  void xenstore_process_event(void *opaque);
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/libxc/Makefile
--- a/tools/libxc/Makefile      Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/libxc/Makefile      Sat Dec 09 14:34:53 2006 +0000
@@ -119,7 +119,7 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$(
        ln -sf $< $@
 
 libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS)
-       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) 
-Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^
+       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) 
-Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ -lpthread
 
 # libxenguest
 
@@ -132,7 +132,7 @@ libxenguest.so.$(MAJOR): libxenguest.so.
        ln -sf $< $@
 
 libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so
-       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) 
-Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz 
-lxenctrl
+       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) 
-Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz 
-lxenctrl -lpthread
 
 -include $(DEPS)
 
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/libxc/xc_private.c  Sat Dec 09 14:34:53 2006 +0000
@@ -7,8 +7,8 @@
 #include <inttypes.h>
 #include "xc_private.h"
 #include "xg_private.h"
-
 #include <stdarg.h>
+#include <pthread.h>
 
 static __thread xc_error last_error = { XC_ERROR_NONE, ""};
 #if DEBUG
@@ -486,14 +486,20 @@ char *safe_strerror(int errcode)
 char *safe_strerror(int errcode)
 {
     static __thread char errbuf[32];
-#ifdef __GLIBC__
-    /* Broken GNU definition of strerror_r may not use our supplied buffer. */
-    return strerror_r(errcode, errbuf, sizeof(errbuf));
-#else
-    /* Assume we have the POSIX definition of strerror_r. */
-    strerror_r(errcode, errbuf, sizeof(errbuf));
+    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+    char *strerror_str;
+
+    /*
+     * Thread-unsafe strerror() is protected by a local mutex. We copy
+     * the string to a thread-private buffer before releasing the mutex.
+     */
+    pthread_mutex_lock(&mutex);
+    strerror_str = strerror(errcode);
+    strncpy(errbuf, strerror_str, sizeof(errbuf));
+    errbuf[sizeof(errbuf)-1] = '\0';
+    pthread_mutex_unlock(&mutex);
+
     return errbuf;
-#endif
 }
 
 /*
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/python/xen/xend/XendConfig.py       Sat Dec 09 14:34:53 2006 +0000
@@ -390,11 +390,16 @@ class XendConfig(dict):
         if self.get('vcpus_number') != None:
             self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
 
+    def _uuid_sanity_check(self):
+        """Make sure UUID is in proper string format with hyphens."""
+        self['uuid'] = uuid.toString(uuid.fromString(self['uuid']))
+
     def validate(self):
         self._memory_sanity_check()
         self._actions_sanity_check()
         self._builder_sanity_check()
         self._vcpus_sanity_check()
+        self._uuid_sanity_check()
 
     def _dominfo_to_xapi(self, dominfo):
         self['domid'] = dominfo['domid']
@@ -917,24 +922,11 @@ class XendConfig(dict):
             except ValueError:
                 pass # SXP has no options for this device
 
-
-            # Special handling for certain device parameters.
-
-            def _get_config_ipaddr(cfg):
-                val = []
-                for ipaddr in sxp.children(cfg, elt='ip'):
-                    val.append(sxp.child0(ipaddr))
-                return val
-
-            if dev_type == 'vif' and 'ip' in dev_info:
-                dev_info['ip'] = _get_config_ipaddr(config)
-
             if dev_type == 'vbd':
                 if dev_info.get('dev', '').startswith('ioemu:'):
                     dev_info['driver'] = 'ioemu'
                 else:
                     dev_info['driver'] = 'paravirtualised'
-                    
 
             # create uuid if it doesn't exist
             dev_uuid = dev_info.get('uuid', uuid.createString())
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/python/xen/xend/server/netif.py
--- a/tools/python/xen/xend/server/netif.py     Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/python/xen/xend/server/netif.py     Sat Dec 09 14:34:53 2006 +0000
@@ -164,7 +164,7 @@ class NetifController(DevController):
             front = { 'handle' : "%i" % devid,
                       'mac'    : mac }
         if ipaddr:
-            back['ip'] = ' '.join(ipaddr)
+            back['ip'] = ipaddr
         if bridge:
             back['bridge'] = bridge
         if vifname:
@@ -189,7 +189,7 @@ class NetifController(DevController):
             network_script_dir = xroot.network_script_dir + os.sep
             result['script'] = script.replace(network_script_dir, "")
         if ip:
-            result['ip'] = ip.split(" ")
+            result['ip'] = ip
         if bridge:
             result['bridge'] = bridge
         if mac:
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Fri Dec 08 11:31:29 2006 -0700
+++ b/tools/python/xen/xm/main.py       Sat Dec 09 14:34:53 2006 +0000
@@ -138,9 +138,9 @@ SUBCOMMAND_HELP = {
 
     # device commands
 
-    'block-attach'  :  ('<Domain> <BackDev> <FrontDev> <Mode>',
+    'block-attach'  :  ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]',
                         'Create a new virtual block device.'),
-    'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomId]',
+    'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]',
                         'Change block device configuration'),
     'block-detach'  :  ('<Domain> <DevId>',
                         'Destroy a domain\'s virtual block device.'),
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/fix-interrupt-routing
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/fix-interrupt-routing Sat Dec 09 14:34:53 2006 +0000
@@ -0,0 +1,459 @@
+# HG changeset patch
+# User kfraser@xxxxxxxxxxxxxxxxxxxxx
+# Node ID f555a90bcc373a7379bc18f875eac5e7c7122ae9
+# Parent  b80f00215bbaf2050765e557f1a017a71e1e8529
+[HVM] Reworked interrupt distribution logic.
+
+TODO:
+ 1. Fix IO-APIC ID to not conflict with LAPIC IDS.
+ 2. Fix i8259 device model (seems to work already though!).
+ 3. Add INTSRC overrides in MPBIOS and ACPI tables so
+    that PCI legacy IRQ routing always ends up at an
+    IO-APIC input with level trigger. Restricting link
+    routing to {5,6,10,11} and setting overrides for all
+    four of those would work.
+
+Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
+
+Index: ioemu/Makefile.target
+===================================================================
+--- ioemu.orig/Makefile.target 2006-12-08 18:21:56.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 18:22:35.000000000 +0000
+@@ -298,7 +298,7 @@
+ ifeq ($(ARCH),ia64)
+ LIBOBJS=helper2.o exec-dm.o i8259-dm.o
+ else
+-LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o
++LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o piix_pci-dm.o
+ endif
+ 
+ all: $(PROGS)
+@@ -360,11 +360,11 @@
+ # Hardware support
+ VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
+ ifeq ($(ARCH),ia64)
+-VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
++VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o piix_pci.o
+ else
+ VL_OBJS+= fdc.o serial.o pc.o
+ endif
+-VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
++VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o
+ VL_OBJS+= usb-uhci.o
+ VL_OBJS+= piix4acpi.o
+ VL_OBJS+= xenstore.o
+Index: ioemu/target-i386-dm/i8259-dm.c
+===================================================================
+--- ioemu.orig/target-i386-dm/i8259-dm.c       2006-12-08 18:21:36.000000000 
+0000
++++ ioemu/target-i386-dm/i8259-dm.c    2006-12-08 18:22:35.000000000 +0000
+@@ -33,7 +33,7 @@
+ 
+ void pic_set_irq_new(void *opaque, int irq, int level)
+ {
+-    xc_hvm_set_irq_level(xc_handle, domid, irq, level);
++    xc_hvm_set_isa_irq_level(xc_handle, domid, irq, level);
+ }
+ 
+ /* obsolete function */
+Index: ioemu/target-i386-dm/piix_pci-dm.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ ioemu/target-i386-dm/piix_pci-dm.c 2006-12-08 18:22:35.000000000 +0000
+@@ -0,0 +1,397 @@
++/*
++ * QEMU i440FX/PIIX3 PCI Bridge Emulation
++ *
++ * Copyright (c) 2006 Fabrice Bellard
++ * 
++ * Permission is hereby granted, free of charge, to any person obtaining a 
copy
++ * of this software and associated documentation files (the "Software"), to 
deal
++ * in the Software without restriction, including without limitation the 
rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++ * THE SOFTWARE.
++ */
++
++#include "vl.h"
++typedef uint32_t pci_addr_t;
++#include "hw/pci_host.h"
++
++typedef PCIHostState I440FXState;
++
++static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val)
++{
++    I440FXState *s = opaque;
++    s->config_reg = val;
++}
++
++static uint32_t i440fx_addr_readl(void* opaque, uint32_t addr)
++{
++    I440FXState *s = opaque;
++    return s->config_reg;
++}
++
++static void i440fx_set_irq(PCIDevice *pci_dev, void *pic, int intx, int level)
++{
++    xc_hvm_set_pci_intx_level(xc_handle, domid, 0, 0, pci_dev->devfn >> 3,
++                              intx, level);
++}
++
++PCIBus *i440fx_init(void)
++{
++    PCIBus *b;
++    PCIDevice *d;
++    I440FXState *s;
++
++    s = qemu_mallocz(sizeof(I440FXState));
++    b = pci_register_bus(i440fx_set_irq, NULL, 0);
++    s->bus = b;
++
++    register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
++    register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s);
++
++    register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
++    register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);
++    register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);
++    register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
++    register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
++    register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
++
++    d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0, 
++                            NULL, NULL);
++
++    d->config[0x00] = 0x86; // vendor_id
++    d->config[0x01] = 0x80;
++    d->config[0x02] = 0x37; // device_id
++    d->config[0x03] = 0x12;
++    d->config[0x08] = 0x02; // revision
++    d->config[0x0a] = 0x00; // class_sub = host2pci
++    d->config[0x0b] = 0x06; // class_base = PCI_bridge
++    d->config[0x0e] = 0x00; // header_type
++    return b;
++}
++
++/* PIIX3 PCI to ISA bridge */
++
++static PCIDevice *piix3_dev;
++
++static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
++{
++    /* This is the barber's pole mapping used by Xen. */
++    return (irq_num + (pci_dev->devfn >> 3)) & 3;
++}
++
++static void piix3_write_config(PCIDevice *d, 
++                               uint32_t address, uint32_t val, int len)
++{
++    int i;
++
++    /* Scan for updates to PCI link routes (0x60-0x63). */
++    for (i = 0; i < len; i++) {
++        uint8_t v = (val >> (8*i)) & 0xff;
++        if (v & 0x80)
++            v = 0;
++        v &= 0xf;
++        if (((address+i) >= 0x60) && ((address+i) <= 0x63))
++            xc_hvm_set_pci_link_route(xc_handle, domid, address + i - 0x60, 
v);
++    }
++
++    /* Hand off to default logic. */
++    pci_default_write_config(d, address, val, len);
++}
++
++static void piix3_reset(PCIDevice *d)
++{
++    uint8_t *pci_conf = d->config;
++
++    pci_conf[0x04] = 0x07; // master, memory and I/O
++    pci_conf[0x05] = 0x00;
++    pci_conf[0x06] = 0x00;
++    pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
++    pci_conf[0x4c] = 0x4d;
++    pci_conf[0x4e] = 0x03;
++    pci_conf[0x4f] = 0x00;
++    pci_conf[0x60] = 0x80;
++    pci_conf[0x61] = 0x80;
++    pci_conf[0x62] = 0x80;
++    pci_conf[0x63] = 0x80;
++    pci_conf[0x69] = 0x02;
++    pci_conf[0x70] = 0x80;
++    pci_conf[0x76] = 0x0c;
++    pci_conf[0x77] = 0x0c;
++    pci_conf[0x78] = 0x02;
++    pci_conf[0x79] = 0x00;
++    pci_conf[0x80] = 0x00;
++    pci_conf[0x82] = 0x00;
++    pci_conf[0xa0] = 0x08;
++    pci_conf[0xa0] = 0x08;
++    pci_conf[0xa2] = 0x00;
++    pci_conf[0xa3] = 0x00;
++    pci_conf[0xa4] = 0x00;
++    pci_conf[0xa5] = 0x00;
++    pci_conf[0xa6] = 0x00;
++    pci_conf[0xa7] = 0x00;
++    pci_conf[0xa8] = 0x0f;
++    pci_conf[0xaa] = 0x00;
++    pci_conf[0xab] = 0x00;
++    pci_conf[0xac] = 0x00;
++    pci_conf[0xae] = 0x00;
++}
++
++int piix3_init(PCIBus *bus)
++{
++    PCIDevice *d;
++    uint8_t *pci_conf;
++
++    d = pci_register_device(bus, "PIIX3", sizeof(PCIDevice),
++                                    -1, NULL, piix3_write_config);
++    register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d);
++
++    piix3_dev = d;
++    pci_conf = d->config;
++
++    pci_conf[0x00] = 0x86; // Intel
++    pci_conf[0x01] = 0x80;
++    pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
++    pci_conf[0x03] = 0x70;
++    pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
++    pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
++    pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
++
++    piix3_reset(d);
++    return d->devfn;
++}
++
++/***********************************************************/
++/* XXX: the following should be moved to the PC BIOS */
++
++static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
++{
++    return cpu_inb(NULL, addr);
++}
++
++static void isa_outb(uint32_t val, uint32_t addr)
++{
++    cpu_outb(NULL, addr, val);
++}
++
++static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
++{
++    return cpu_inw(NULL, addr);
++}
++
++static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
++{
++    cpu_outw(NULL, addr, val);
++}
++
++static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
++{
++    return cpu_inl(NULL, addr);
++}
++
++static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
++{
++    cpu_outl(NULL, addr, val);
++}
++
++static uint32_t pci_bios_io_addr;
++static uint32_t pci_bios_mem_addr;
++/* host irqs corresponding to PCI irqs A-D */
++static uint8_t pci_irqs[4] = { 10, 11, 10, 11 };
++
++static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
++{
++    PCIBus *s = d->bus;
++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
++    pci_data_write(s, addr, val, 4);
++}
++
++static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
++{
++    PCIBus *s = d->bus;
++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
++    pci_data_write(s, addr, val, 2);
++}
++
++static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
++{
++    PCIBus *s = d->bus;
++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
++    pci_data_write(s, addr, val, 1);
++}
++
++static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, 
uint32_t addr)
++{
++    PCIBus *s = d->bus;
++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
++    return pci_data_read(s, addr, 4);
++}
++
++static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
++{
++    PCIBus *s = d->bus;
++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
++    return pci_data_read(s, addr, 2);
++}
++
++static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
++{
++    PCIBus *s = d->bus;
++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
++    return pci_data_read(s, addr, 1);
++}
++
++static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t 
addr)
++{
++    PCIIORegion *r;
++    uint16_t cmd;
++    uint32_t ofs;
++
++    if ( region_num == PCI_ROM_SLOT ) {
++        ofs = 0x30;
++    }else{
++        ofs = 0x10 + region_num * 4;
++    }
++
++    pci_config_writel(d, ofs, addr);
++    r = &d->io_regions[region_num];
++
++    /* enable memory mappings */
++    cmd = pci_config_readw(d, PCI_COMMAND);
++    if ( region_num == PCI_ROM_SLOT )
++        cmd |= 2;
++    else if (r->type & PCI_ADDRESS_SPACE_IO)
++        cmd |= 1;
++    else
++        cmd |= 2;
++    pci_config_writew(d, PCI_COMMAND, cmd);
++}
++
++static void pci_bios_init_device(PCIDevice *d)
++{
++    int class;
++    PCIIORegion *r;
++    uint32_t *paddr;
++    int i, pin, pic_irq, vendor_id, device_id;
++
++    class = pci_config_readw(d, PCI_CLASS_DEVICE);
++    vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
++    device_id = pci_config_readw(d, PCI_DEVICE_ID);
++    switch(class) {
++    case 0x0101:
++        if (vendor_id == 0x8086 && device_id == 0x7010) {
++            /* PIIX3 IDE */
++            pci_config_writew(d, 0x40, 0x8000); // enable IDE0
++            pci_config_writew(d, 0x42, 0x8000); // enable IDE1
++            goto default_map;
++        } else {
++            /* IDE: we map it as in ISA mode */
++            pci_set_io_region_addr(d, 0, 0x1f0);
++            pci_set_io_region_addr(d, 1, 0x3f4);
++            pci_set_io_region_addr(d, 2, 0x170);
++            pci_set_io_region_addr(d, 3, 0x374);
++        }
++        break;
++    case 0x0680:
++        if (vendor_id == 0x8086 && device_id == 0x7113) {
++            /*
++             * PIIX4 ACPI PM.
++             * Special device with special PCI config space. No ordinary BARs.
++             */
++            pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
++            pci_config_writew(d, 0x22, 0x0000);
++            pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
++            pci_config_writew(d, 0x3d, 0x0001);
++        }
++        break;
++    case 0x0300:
++        if (vendor_id != 0x1234)
++            goto default_map;
++        /* VGA: map frame buffer to default Bochs VBE address */
++        pci_set_io_region_addr(d, 0, 0xE0000000);
++        break;
++    case 0x0800:
++        /* PIC */
++        vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
++        device_id = pci_config_readw(d, PCI_DEVICE_ID);
++        if (vendor_id == 0x1014) {
++            /* IBM */
++            if (device_id == 0x0046 || device_id == 0xFFFF) {
++                /* MPIC & MPIC2 */
++                pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
++            }
++        }
++        break;
++    case 0xff00:
++        if (vendor_id == 0x0106b &&
++            (device_id == 0x0017 || device_id == 0x0022)) {
++            /* macio bridge */
++            pci_set_io_region_addr(d, 0, 0x80800000);
++        }
++        break;
++    default:
++    default_map:
++        /* default memory mappings */
++        for(i = 0; i < PCI_NUM_REGIONS; i++) {
++            r = &d->io_regions[i];
++            if (r->size) {
++                if (r->type & PCI_ADDRESS_SPACE_IO)
++                    paddr = &pci_bios_io_addr;
++                else
++                    paddr = &pci_bios_mem_addr;
++                *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
++                pci_set_io_region_addr(d, i, *paddr);
++                *paddr += r->size;
++            }
++        }
++        break;
++    }
++
++    /* map the interrupt */
++    pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
++    if (pin != 0) {
++        pin = pci_slot_get_pirq(d, pin - 1);
++        pic_irq = pci_irqs[pin];
++        pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
++    }
++}
++
++/*
++ * This function initializes the PCI devices as a normal PCI BIOS
++ * would do. It is provided just in case the BIOS has no support for
++ * PCI.
++ */
++void pci_bios_init(void)
++{
++    int i, irq;
++    uint8_t elcr[2];
++
++    pci_bios_io_addr = 0xc000;
++    pci_bios_mem_addr = HVM_BELOW_4G_MMIO_START;
++
++    /* activate IRQ mappings */
++    elcr[0] = 0x00;
++    elcr[1] = 0x00;
++    for(i = 0; i < 4; i++) {
++        irq = pci_irqs[i];
++        /* set to trigger level */
++        elcr[irq >> 3] |= (1 << (irq & 7));
++        /* activate irq remapping in PIIX */
++        pci_config_writeb(piix3_dev, 0x60 + i, irq);
++    }
++    isa_outb(elcr[0], 0x4d0);
++    isa_outb(elcr[1], 0x4d1);
++
++    pci_for_each_device(pci_bios_init_device);
++}
++
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/ide-error-reporting
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ide-error-reporting   Sat Dec 09 14:34:53 2006 +0000
@@ -0,0 +1,110 @@
+# HG changeset patch
+# User kfraser@xxxxxxxxxxxxxxxxxxxxx
+# Node ID fd28a1b139dea91b8bfcf06dd233dbdda8f51ff1
+# Parent  d8befb109c394c2c2d3e1870a500107d461724ef
+[QEMU] Error reporting in IDE device model.
+
+Following on from my patch to make blktap report I/O errors back to
+guest OS, a similar problem exists in the QEMU codebase. The IDE
+driver never reports I/O errors during read/write operations back to
+the guest OS. Instead all I/O operations are reported as
+succesfull. If, for example, the host FS holding the disk image fills
+up, then writes may fail due to lack of space. Since the guest OS
+never sees these failures, it assumes all is well & will continue
+writing. Eventually this can lead to severe & unrecoverable filesystem
+corruption.
+
+The attached patch fixes QEMU ide driver such that any failure of a
+read or write operation sets the appropriate IDE status/error
+registers. Having read the ATA-6 spec I think the most compliant
+behaviour is to set the status register to 'READY_STAT | ERR_STAT',
+and the error register to ABRT_ERR. There is already a convenience
+function ide_abort_command() in the QEMU codebase which does just
+this, so the attached patch simply calls that function.
+
+With this patch the guest OS sees the I/O failure & the kernel logs
+IDE errors and then retries the operation. This at least ensures that
+the guest can be shutdown the out of space issue in the host corrected
+and the guest restarted, without any serious filesystem damage having
+occurred.
+
+From: Daniel Berrange <berrange@xxxxxxxxxx>
+Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
+
+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 @@
+ static void ide_sector_read(IDEState *s)
+ {
+     int64_t sector_num;
+-    int ret, n;
++    int n;
+ 
+     s->status = READY_STAT | SEEK_STAT;
+     s->error = 0; /* not needed by IDE spec, but needed by Windows */
+@@ -695,7 +695,11 @@
+ #endif
+         if (n > s->req_nb_sectors)
+             n = s->req_nb_sectors;
+-        ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
++        if (bdrv_read(s->bs, sector_num, s->io_buffer, n) != 0) {
++            ide_abort_command(s);
++            ide_set_irq(s);
++            return;
++        }
+         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 @@
+             if (n > MAX_MULT_SECTORS)
+                 n = MAX_MULT_SECTORS;
+             sector_num = ide_get_sector(s);
+-            bdrv_read(s->bs, sector_num, s->io_buffer, n);
++            if (bdrv_read(s->bs, sector_num, s->io_buffer, n) != 0) {
++                ide_abort_command(s);
++                ide_set_irq(s);
++                return 0;
++            }
+             s->io_buffer_index = 0;
+             s->io_buffer_size = n * 512;
+             len = s->io_buffer_size;
+@@ -767,7 +775,7 @@
+ static void ide_sector_write(IDEState *s)
+ {
+     int64_t sector_num;
+-    int ret, n, n1;
++    int n, n1;
+ 
+     s->status = READY_STAT | SEEK_STAT;
+     sector_num = ide_get_sector(s);
+@@ -777,7 +785,11 @@
+     n = s->nsector;
+     if (n > s->req_nb_sectors)
+         n = s->req_nb_sectors;
+-    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
++    if (bdrv_write(s->bs, sector_num, s->io_buffer, n) != 0) {
++        ide_abort_command(s);
++        ide_set_irq(s);
++        return;
++    }
+     s->nsector -= n;
+     if (s->nsector == 0) {
+         /* no more sector to write */
+@@ -823,8 +835,13 @@
+         if (len == 0) {
+             n = s->io_buffer_size >> 9;
+             sector_num = ide_get_sector(s);
+-            bdrv_write(s->bs, sector_num, s->io_buffer, 
+-                       s->io_buffer_size >> 9);
++            if (bdrv_write(s->bs, sector_num, s->io_buffer, 
++                         s->io_buffer_size >> 9) != 0) {
++                ide_abort_command(s);
++                ide_set_irq(s);
++                return 0;
++            }
++
+             sector_num += n;
+             ide_set_sector(s, sector_num);
+             s->nsector -= n;
diff -r 1cfd862e5254 -r 8cddaee4a51c 
tools/ioemu/patches/limit-fdc-sector-size-to-16K
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/limit-fdc-sector-size-to-16K  Sat Dec 09 14:34:53 
2006 +0000
@@ -0,0 +1,32 @@
+# HG changeset patch
+# User kfraser@xxxxxxxxxxxxxxxxxxxxx
+# Node ID f711b87ba951e608287abd0de028c6f0d83400a9
+# Parent  f3ee62b7fb5299c89d442845e0883bcfab78c067
+[QEMU] fdc: Limit sector size to 16K
+
+In fdctrl_start_transfer the sector size field (fifo[5]) is not
+checked for overflows.  This allows an arbitrarily large sector size
+to be used, which can in turn result in a negative data_len field that
+is then used for DMA transfers.
+
+This can lead to the corrpuption of qemu state because some subsequent
+checks on the transfer length is conducted using signed integers.
+
+This patch limits the value fifo[5] to 7 which is the standard limit
+on floppy sector size.
+
+Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
+
+Index: ioemu/hw/fdc.c
+===================================================================
+--- ioemu.orig/hw/fdc.c        2006-12-08 18:21:36.000000000 +0000
++++ ioemu/hw/fdc.c     2006-12-08 18:22:57.000000000 +0000
+@@ -898,7 +898,7 @@
+         fdctrl->data_len = fdctrl->fifo[8];
+     } else {
+       int tmp;
+-        fdctrl->data_len = 128 << fdctrl->fifo[5];
++        fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
+         tmp = (cur_drv->last_sect - ks + 1);
+         if (fdctrl->fifo[0] & 0x80)
+             tmp += cur_drv->last_sect;
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/ne2000-bounds-checks
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/ne2000-bounds-checks  Sat Dec 09 14:34:53 2006 +0000
@@ -0,0 +1,113 @@
+# HG changeset patch
+# User kaf24@xxxxxxxxxxxxxxxxxxxxx
+# Node ID 66fe61db9e69e03e12d0c4086683bebfb4a67780
+# Parent  1940ee13f9d6ab1be2c614a0fbf7769536a056d2
+[QEMU] ne2000: Stop memory access beyond buffer
+
+As a program that runs in dom0 which serves users from guests,
+the qemu drivers need to be vigilant to the input that comes
+from the guests since they may be malicious.
+
+As it is there are multiple ways to get ne2000 to read/write
+memory beyond the 48K buffer that it has allocated for each
+adapter.
+
+This patch checks the addresses and prevents this from occuring.
+
+The boundary is checked each time since it's changed for every
+packet received while the other parameters are only changed
+(by the guest) during setup.
+
+Signed-off: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
+
+Index: ioemu/hw/ne2000.c
+===================================================================
+--- ioemu.orig/hw/ne2000.c     2006-12-08 18:20:45.000000000 +0000
++++ ioemu/hw/ne2000.c  2006-12-08 18:20:53.000000000 +0000
+@@ -137,6 +137,7 @@
+     uint8_t curpag;
+     uint8_t mult[8]; /* multicast mask array */
+     int irq;
++    int tainted;
+     PCIDevice *pci_dev;
+     VLANClientState *vc;
+     uint8_t macaddr[6];
+@@ -226,6 +227,27 @@
+ 
+ #define MIN_BUF_SIZE 60
+ 
++static inline int ne2000_valid_ring_addr(NE2000State *s, unsigned int addr)
++{
++    addr <<= 8;
++    return addr < s->stop && addr >= s->start;
++}
++
++static inline int ne2000_check_state(NE2000State *s)
++{
++    if (!s->tainted)
++        return 0;
++
++    if (s->start >= s->stop || s->stop > NE2000_MEM_SIZE)
++        return -EINVAL;
++
++    if (!ne2000_valid_ring_addr(s, s->curpag))
++        return -EINVAL;
++
++    s->tainted = 0;
++    return 0;
++}
++
+ static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
+ {
+     NE2000State *s = opaque;
+@@ -239,6 +261,12 @@
+     printf("NE2000: received len=%d\n", size);
+ #endif
+ 
++    if (ne2000_check_state(s))
++        return;
++
++    if (!ne2000_valid_ring_addr(s, s->boundary))
++        return;
++
+     if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
+         return;
+     
+@@ -359,9 +387,11 @@
+         switch(offset) {
+         case EN0_STARTPG:
+             s->start = val << 8;
++            s->tainted = 1;
+             break;
+         case EN0_STOPPG:
+             s->stop = val << 8;
++            s->tainted = 1;
+             break;
+         case EN0_BOUNDARY:
+             s->boundary = val;
+@@ -406,6 +436,7 @@
+             break;
+         case EN1_CURPAG:
+             s->curpag = val;
++            s->tainted = 1;
+             break;
+         case EN1_MULT ... EN1_MULT + 7:
+             s->mult[offset - EN1_MULT] = val;
+@@ -509,7 +540,7 @@
+ {
+     addr &= ~1; /* XXX: check exact behaviour if not even */
+     if (addr < 32 || 
+-        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
++        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
+         cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
+     }
+ }
+@@ -539,7 +570,7 @@
+ {
+     addr &= ~1; /* XXX: check exact behaviour if not even */
+     if (addr < 32 || 
+-        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
++        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
+         return le32_to_cpupu((uint32_t *)(s->mem + addr));
+     } else {
+         return 0xffffffff;
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/nodelay-serial-over-tcp
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/nodelay-serial-over-tcp       Sat Dec 09 14:34:53 
2006 +0000
@@ -0,0 +1,29 @@
+# HG changeset patch
+# User PeterJohnston <peter.johnston@xxxxxxxxxxxxx>
+# Node ID b8cc9ffda0a3dc449b026c72c97f78dea2e6f114
+# Parent  a8d2b1393b769048c7b62822e45bef27eef80fb6
+[QEMU] Add TCP_NODELAY to tcp connections exporting serial ports.
+
+Signed-off-by: Steven Smith <sos22@xxxxxxxxx>
+
+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 @@
+     int is_waitconnect = 1;
+     const char *ptr;
+     struct sockaddr_in saddr;
++    int opt;
+ 
+     if (parse_host_port(&saddr, host_str) < 0)
+         goto fail;
+@@ -2598,6 +2599,8 @@
+             }
+         }
+         s->fd = fd;
++      opt = 1;
++      setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
+         if (s->connected)
+             tcp_chr_connect(chr);
+         else
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-serial-fixes
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/qemu-serial-fixes     Sat Dec 09 14:34:53 2006 +0000
@@ -0,0 +1,133 @@
+# HG changeset patch
+# User kfraser@xxxxxxxxxxxxxxxxxxxxx
+# Node ID c33272c2571c7bab7056d8228490700d1df405f9
+# Parent  b3d94f4ddffefed8a5cb8dd65a60da9491d460e7
+[HVM] Fix Qemu-dm serial issues:
+ 1. Retry transmit via a polling timer if a byte cannot be written
+    immediately to its destination.
+ 2. Turn off output processing of raw serial lines.
+
+Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx>
+Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx>
+Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
+
+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 @@
+ 
+     tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+                           |INLCR|IGNCR|ICRNL|IXON);
+-    tty.c_oflag |= OPOST;
++    tty.c_oflag &= ~OPOST; /* no output mangling of raw serial stream */
+     tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
+     tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS);
+     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
+@@ -73,6 +73,11 @@
+ #define UART_LSR_OE   0x02    /* Overrun error indicator */
+ #define UART_LSR_DR   0x01    /* Receiver data ready */
+ 
++/* Maximum retries for a single byte transmit. */
++#define WRITE_MAX_SINGLE_RETRIES 3
++/* Maximum retries for a sequence of back-to-back unsuccessful transmits. */
++#define WRITE_MAX_TOTAL_RETRIES 10
++
+ struct SerialState {
+     uint8_t divider;
+     uint8_t rbr; /* receive register */
+@@ -93,6 +98,19 @@
+     int last_break_enable;
+     target_ulong base;
+     int it_shift;
++
++    /*
++     * If a character transmitted via UART cannot be written to its
++     * destination immediately we remember it here and retry a few times via
++     * a polling timer.
++     *  - write_single_retries: Number of write retries for current byte.
++     *  - write_total_retries:  Number of write retries for back-to-back
++     *                          unsuccessful transmits.
++     */
++    int write_single_retries;
++    int write_total_retries;
++    char write_chr;
++    QEMUTimer *write_retry_timer;
+ };
+ 
+ static void serial_update_irq(SerialState *s)
+@@ -204,10 +222,37 @@
+     tokens_avail--;
+ }
+ 
++static void serial_chr_write(void *opaque)
++{
++    SerialState *s = opaque;
++
++    /* Cancel any outstanding retry if this is a new byte. */
++    qemu_del_timer(s->write_retry_timer);
++
++    /* Retry every 100ms for 300ms total. */
++    if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) {
++        s->write_total_retries++; 
++        if (s->write_single_retries++ >= WRITE_MAX_SINGLE_RETRIES)
++            fprintf(stderr, "serial: write error\n");
++        else if (s->write_total_retries <= WRITE_MAX_TOTAL_RETRIES) {
++            qemu_mod_timer(s->write_retry_timer,
++                           qemu_get_clock(vm_clock) + ticks_per_sec / 10);
++            return;
++        }
++    } else {
++        s->write_total_retries = 0;  /* if successful then reset counter */
++    }
++
++    /* Success: Notify guest that THR is empty. */
++    s->thr_ipending = 1;
++    s->lsr |= UART_LSR_THRE;
++    s->lsr |= UART_LSR_TEMT;
++    serial_update_irq(s);
++}
++
+ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+ {
+     SerialState *s = opaque;
+-    unsigned char ch;
+     
+     addr &= 7;
+ #ifdef DEBUG_SERIAL
+@@ -223,12 +268,9 @@
+             s->thr_ipending = 0;
+             s->lsr &= ~UART_LSR_THRE;
+             serial_update_irq(s);
+-            ch = val;
+-            qemu_chr_write(s->chr, &ch, 1);
+-            s->thr_ipending = 1;
+-            s->lsr |= UART_LSR_THRE;
+-            s->lsr |= UART_LSR_TEMT;
+-            serial_update_irq(s);
++            s->write_chr = val;
++            s->write_single_retries = 0;
++            serial_chr_write(s);
+         }
+         break;
+     case 1:
+@@ -424,6 +466,7 @@
+     s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
+     s->iir = UART_IIR_NO_INT;
+     s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
++    s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
+ 
+     register_savevm("serial", base, 1, serial_save, serial_load, s);
+ 
+@@ -511,6 +554,7 @@
+     s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
+     s->base = base;
+     s->it_shift = it_shift;
++    s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
+ 
+     register_savevm("serial", base, 1, serial_save, serial_load, s);
+ 
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/remove-pci-bridge-setup
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/remove-pci-bridge-setup       Sat Dec 09 14:34:53 
2006 +0000
@@ -0,0 +1,289 @@
+# HG changeset patch
+# User kfraser@xxxxxxxxxxxxxxxxxxxxx
+# Node ID a8d31d5ce2589762c3226185deeca3afca47a698
+# Parent  b8cc9ffda0a3dc449b026c72c97f78dea2e6f114
+[HVM] Move PCI and PCI-ISA bridge setup to hvmloader.
+Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
+
+Index: ioemu/target-i386-dm/piix_pci-dm.c
+===================================================================
+--- ioemu.orig/target-i386-dm/piix_pci-dm.c    2006-12-08 18:22:35.000000000 
+0000
++++ ioemu/target-i386-dm/piix_pci-dm.c 2006-12-08 18:22:50.000000000 +0000
+@@ -84,12 +84,6 @@
+ 
+ static PCIDevice *piix3_dev;
+ 
+-static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+-{
+-    /* This is the barber's pole mapping used by Xen. */
+-    return (irq_num + (pci_dev->devfn >> 3)) & 3;
+-}
+-
+ static void piix3_write_config(PCIDevice *d, 
+                                uint32_t address, uint32_t val, int len)
+ {
+@@ -114,12 +108,9 @@
+     uint8_t *pci_conf = d->config;
+ 
+     pci_conf[0x04] = 0x07; // master, memory and I/O
+-    pci_conf[0x05] = 0x00;
+-    pci_conf[0x06] = 0x00;
+     pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
+     pci_conf[0x4c] = 0x4d;
+     pci_conf[0x4e] = 0x03;
+-    pci_conf[0x4f] = 0x00;
+     pci_conf[0x60] = 0x80;
+     pci_conf[0x61] = 0x80;
+     pci_conf[0x62] = 0x80;
+@@ -129,22 +120,9 @@
+     pci_conf[0x76] = 0x0c;
+     pci_conf[0x77] = 0x0c;
+     pci_conf[0x78] = 0x02;
+-    pci_conf[0x79] = 0x00;
+-    pci_conf[0x80] = 0x00;
+-    pci_conf[0x82] = 0x00;
+     pci_conf[0xa0] = 0x08;
+     pci_conf[0xa0] = 0x08;
+-    pci_conf[0xa2] = 0x00;
+-    pci_conf[0xa3] = 0x00;
+-    pci_conf[0xa4] = 0x00;
+-    pci_conf[0xa5] = 0x00;
+-    pci_conf[0xa6] = 0x00;
+-    pci_conf[0xa7] = 0x00;
+     pci_conf[0xa8] = 0x0f;
+-    pci_conf[0xaa] = 0x00;
+-    pci_conf[0xab] = 0x00;
+-    pci_conf[0xac] = 0x00;
+-    pci_conf[0xae] = 0x00;
+ }
+ 
+ int piix3_init(PCIBus *bus)
+@@ -171,227 +149,4 @@
+     return d->devfn;
+ }
+ 
+-/***********************************************************/
+-/* XXX: the following should be moved to the PC BIOS */
+-
+-static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
+-{
+-    return cpu_inb(NULL, addr);
+-}
+-
+-static void isa_outb(uint32_t val, uint32_t addr)
+-{
+-    cpu_outb(NULL, addr, val);
+-}
+-
+-static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
+-{
+-    return cpu_inw(NULL, addr);
+-}
+-
+-static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
+-{
+-    cpu_outw(NULL, addr, val);
+-}
+-
+-static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
+-{
+-    return cpu_inl(NULL, addr);
+-}
+-
+-static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
+-{
+-    cpu_outl(NULL, addr, val);
+-}
+-
+-static uint32_t pci_bios_io_addr;
+-static uint32_t pci_bios_mem_addr;
+-/* host irqs corresponding to PCI irqs A-D */
+-static uint8_t pci_irqs[4] = { 10, 11, 10, 11 };
+-
+-static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
+-{
+-    PCIBus *s = d->bus;
+-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
+-    pci_data_write(s, addr, val, 4);
+-}
+-
+-static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
+-{
+-    PCIBus *s = d->bus;
+-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
+-    pci_data_write(s, addr, val, 2);
+-}
+-
+-static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
+-{
+-    PCIBus *s = d->bus;
+-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
+-    pci_data_write(s, addr, val, 1);
+-}
+-
+-static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, 
uint32_t addr)
+-{
+-    PCIBus *s = d->bus;
+-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
+-    return pci_data_read(s, addr, 4);
+-}
+-
+-static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
+-{
+-    PCIBus *s = d->bus;
+-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
+-    return pci_data_read(s, addr, 2);
+-}
+-
+-static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
+-{
+-    PCIBus *s = d->bus;
+-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
+-    return pci_data_read(s, addr, 1);
+-}
+-
+-static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t 
addr)
+-{
+-    PCIIORegion *r;
+-    uint16_t cmd;
+-    uint32_t ofs;
+-
+-    if ( region_num == PCI_ROM_SLOT ) {
+-        ofs = 0x30;
+-    }else{
+-        ofs = 0x10 + region_num * 4;
+-    }
+-
+-    pci_config_writel(d, ofs, addr);
+-    r = &d->io_regions[region_num];
+-
+-    /* enable memory mappings */
+-    cmd = pci_config_readw(d, PCI_COMMAND);
+-    if ( region_num == PCI_ROM_SLOT )
+-        cmd |= 2;
+-    else if (r->type & PCI_ADDRESS_SPACE_IO)
+-        cmd |= 1;
+-    else
+-        cmd |= 2;
+-    pci_config_writew(d, PCI_COMMAND, cmd);
+-}
+-
+-static void pci_bios_init_device(PCIDevice *d)
+-{
+-    int class;
+-    PCIIORegion *r;
+-    uint32_t *paddr;
+-    int i, pin, pic_irq, vendor_id, device_id;
+-
+-    class = pci_config_readw(d, PCI_CLASS_DEVICE);
+-    vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
+-    device_id = pci_config_readw(d, PCI_DEVICE_ID);
+-    switch(class) {
+-    case 0x0101:
+-        if (vendor_id == 0x8086 && device_id == 0x7010) {
+-            /* PIIX3 IDE */
+-            pci_config_writew(d, 0x40, 0x8000); // enable IDE0
+-            pci_config_writew(d, 0x42, 0x8000); // enable IDE1
+-            goto default_map;
+-        } else {
+-            /* IDE: we map it as in ISA mode */
+-            pci_set_io_region_addr(d, 0, 0x1f0);
+-            pci_set_io_region_addr(d, 1, 0x3f4);
+-            pci_set_io_region_addr(d, 2, 0x170);
+-            pci_set_io_region_addr(d, 3, 0x374);
+-        }
+-        break;
+-    case 0x0680:
+-        if (vendor_id == 0x8086 && device_id == 0x7113) {
+-            /*
+-             * PIIX4 ACPI PM.
+-             * Special device with special PCI config space. No ordinary BARs.
+-             */
+-            pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
+-            pci_config_writew(d, 0x22, 0x0000);
+-            pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
+-            pci_config_writew(d, 0x3d, 0x0001);
+-        }
+-        break;
+-    case 0x0300:
+-        if (vendor_id != 0x1234)
+-            goto default_map;
+-        /* VGA: map frame buffer to default Bochs VBE address */
+-        pci_set_io_region_addr(d, 0, 0xE0000000);
+-        break;
+-    case 0x0800:
+-        /* PIC */
+-        vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
+-        device_id = pci_config_readw(d, PCI_DEVICE_ID);
+-        if (vendor_id == 0x1014) {
+-            /* IBM */
+-            if (device_id == 0x0046 || device_id == 0xFFFF) {
+-                /* MPIC & MPIC2 */
+-                pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
+-            }
+-        }
+-        break;
+-    case 0xff00:
+-        if (vendor_id == 0x0106b &&
+-            (device_id == 0x0017 || device_id == 0x0022)) {
+-            /* macio bridge */
+-            pci_set_io_region_addr(d, 0, 0x80800000);
+-        }
+-        break;
+-    default:
+-    default_map:
+-        /* default memory mappings */
+-        for(i = 0; i < PCI_NUM_REGIONS; i++) {
+-            r = &d->io_regions[i];
+-            if (r->size) {
+-                if (r->type & PCI_ADDRESS_SPACE_IO)
+-                    paddr = &pci_bios_io_addr;
+-                else
+-                    paddr = &pci_bios_mem_addr;
+-                *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
+-                pci_set_io_region_addr(d, i, *paddr);
+-                *paddr += r->size;
+-            }
+-        }
+-        break;
+-    }
+-
+-    /* map the interrupt */
+-    pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
+-    if (pin != 0) {
+-        pin = pci_slot_get_pirq(d, pin - 1);
+-        pic_irq = pci_irqs[pin];
+-        pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
+-    }
+-}
+-
+-/*
+- * This function initializes the PCI devices as a normal PCI BIOS
+- * would do. It is provided just in case the BIOS has no support for
+- * PCI.
+- */
+-void pci_bios_init(void)
+-{
+-    int i, irq;
+-    uint8_t elcr[2];
+-
+-    pci_bios_io_addr = 0xc000;
+-    pci_bios_mem_addr = HVM_BELOW_4G_MMIO_START;
+-
+-    /* activate IRQ mappings */
+-    elcr[0] = 0x00;
+-    elcr[1] = 0x00;
+-    for(i = 0; i < 4; i++) {
+-        irq = pci_irqs[i];
+-        /* set to trigger level */
+-        elcr[irq >> 3] |= (1 << (irq & 7));
+-        /* activate irq remapping in PIIX */
+-        pci_config_writeb(piix3_dev, 0x60 + i, irq);
+-    }
+-    isa_outb(elcr[0], 0x4d0);
+-    isa_outb(elcr[1], 0x4d1);
+-
+-    pci_for_each_device(pci_bios_init_device);
+-}
+-
++void pci_bios_init(void) {}
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/rtl8139-bound-chaining
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/rtl8139-bound-chaining        Sat Dec 09 14:34:53 
2006 +0000
@@ -0,0 +1,36 @@
+# HG changeset patch
+# User kfraser@xxxxxxxxxxxxxxxxxxxxx
+# Node ID 075f4ffdbbce5527ba525a515abe320703d17a0e
+# Parent  51edd3c6a4d861db6ce1c9a02251ed49213c3002
+[QEMU] rtl8139: Disallow chaining above 64K
+
+As it stands the 8139C+ TX chaining is only bounded by realloc failure.
+This is contrary to how the real hardware operates.  It also has DoS
+potential when ioemu runs in dom0.
+
+This patch makes any attempt to chain a frame beyond 64K fail
+immediately.
+
+Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
+
+Index: ioemu/hw/rtl8139.c
+===================================================================
+--- ioemu.orig/hw/rtl8139.c    2006-12-08 18:21:36.000000000 +0000
++++ ioemu/hw/rtl8139.c 2006-12-08 18:22:22.000000000 +0000
+@@ -1999,12 +1999,12 @@
+         DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated 
space %d\n", s->cplus_txbuffer_len));
+     }
+ 
+-    while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= 
s->cplus_txbuffer_len)
++    if (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= 
s->cplus_txbuffer_len)
+     {
+-        s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE;
+-        s->cplus_txbuffer = realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);
++      free(s->cplus_txbuffer);
++      s->cplus_txbuffer = NULL;
+ 
+-        DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space changed 
to %d\n", s->cplus_txbuffer_len));
++      DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space exceeded: 
%d\n", s->cplus_txbuffer_offset + txsize));
+     }
+ 
+     if (!s->cplus_txbuffer)
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/tpm-tis-device
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/tpm-tis-device        Sat Dec 09 14:34:53 2006 +0000
@@ -0,0 +1,1188 @@
+# HG changeset patch
+# User kaf24@xxxxxxxxxxxxxxxxxxxxx
+# Node ID d60b709724f48397b95da3d56299213cae391789
+# Parent  bbcac2aea0e8196cd75a3bf6dbe57bebf8c1e5b2
+[QEMU] Add a TIS device model compliant to the 1.2 TPM specification.
+It implements all registers necessary to make the Linux TIS driver
+work (tpm_tis.c). All of the basic registers supported by this type of
+device are implemented. Also the locality selection has been
+implemented, but has not been tested. The legacy registers as
+described in the specification are not supported.
+
+Current caveat: The device has so far not yet been integrated with the
+virtual TPM available in the repository. It will require changes to
+the virtual TPM spawned by the vTPM manager to offer an additional message
+interface. The TIS interface itself then needs to have an additional
+transport implemented. (see vTPMTransmit array).
+
+The relevant specification for the device model can be found here:
+https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf
+
+Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
+
+Index: ioemu/Makefile.target
+===================================================================
+--- ioemu.orig/Makefile.target 2006-12-08 18:33:48.000000000 +0000
++++ ioemu/Makefile.target      2006-12-08 18:35:14.000000000 +0000
+@@ -369,6 +369,7 @@
+ VL_OBJS+= piix4acpi.o
+ VL_OBJS+= xenstore.o
+ VL_OBJS+= xen_platform.o
++VL_OBJS+= tpm_tis.o
+ DEFINES += -DHAS_AUDIO
+ endif
+ ifeq ($(TARGET_BASE_ARCH), ppc)
+Index: ioemu/hw/pc.c
+===================================================================
+--- ioemu.orig/hw/pc.c 2006-12-08 18:33:47.000000000 +0000
++++ ioemu/hw/pc.c      2006-12-08 18:33:48.000000000 +0000
+@@ -875,6 +875,9 @@
+         }
+     }
+ 
++    if (has_tpm_device())
++        tpm_tis_init(&pic_set_irq_new, isa_pic, 11);
++
+     kbd_init();
+     DMA_init(0);
+ #ifdef HAS_AUDIO
+Index: ioemu/hw/tpm_tis.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ ioemu/hw/tpm_tis.c 2006-12-08 18:35:25.000000000 +0000
+@@ -0,0 +1,1120 @@
++/*
++ * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface
++ *
++ * Copyright (C) 2006 IBM Corporation
++ *
++ * Author: Stefan Berger <stefanb@xxxxxxxxxx>
++ *         David Safford <safford@xxxxxxxxxx>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation, version 2 of the
++ * License.
++ *
++ *
++ * Implementation of the TIS interface according to specs at
++ * 
https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf
++ *
++ */
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/socket.h>
++#include <sys/un.h>
++#include <fcntl.h>
++#include <errno.h>
++#include "vl.h"
++
++//#define DEBUG_TPM
++
++#define TPM_MAX_PKT                 4096
++
++#define VTPM_BAD_INSTANCE             (uint32_t)0xffffffff
++
++#define TIS_ADDR_BASE                 0xFED40000
++
++/* tis registers */
++#define TPM_REG_ACCESS                0x00
++#define TPM_REG_INT_ENABLE            0x08
++#define TPM_REG_INT_VECTOR            0x0c
++#define TPM_REG_INT_STATUS            0x10
++#define TPM_REG_INTF_CAPABILITY       0x14
++#define TPM_REG_STS                   0x18
++#define TPM_REG_DATA_FIFO             0x24
++#define TPM_REG_DID_VID               0xf00
++#define TPM_REG_RID                   0xf04
++
++#define STS_VALID                    (1 << 7)
++#define STS_COMMAND_READY            (1 << 6)
++#define STS_TPM_GO                   (1 << 5)
++#define STS_DATA_AVAILABLE           (1 << 4)
++#define STS_EXPECT                   (1 << 3)
++#define STS_RESPONSE_RETRY           (1 << 1)
++
++#define ACCESS_TPM_REG_VALID_STS     (1 << 7)
++#define ACCESS_ACTIVE_LOCALITY       (1 << 5)
++#define ACCESS_BEEN_SEIZED           (1 << 4)
++#define ACCESS_SEIZE                 (1 << 3)
++#define ACCESS_PENDING_REQUEST       (1 << 2)
++#define ACCESS_REQUEST_USE           (1 << 1)
++#define ACCESS_TPM_ESTABLISHMENT     (1 << 0)
++
++#define INT_ENABLED                  (1 << 31)
++#define INT_DATA_AVAILABLE           (1 << 0)
++#define INT_LOCALITY_CHANGED         (1 << 2)
++#define INT_COMMAND_READY            (1 << 7)
++
++#define INTERRUPTS_SUPPORTED         (INT_LOCALITY_CHANGED | \
++                                      INT_DATA_AVAILABLE   | \
++                                      INT_COMMAND_READY)
++#define CAPABILITIES_SUPPORTED       ((1 << 4) |            \
++                                      INTERRUPTS_SUPPORTED)
++
++enum {
++  STATE_IDLE = 0,
++  STATE_READY,
++  STATE_COMPLETION,
++  STATE_EXECUTION,
++  STATE_RECEPTION
++};
++
++#define NUM_LOCALITIES   5
++#define NO_LOCALITY      0xff
++
++#define IS_VALID_LOC(x) ((x) < NUM_LOCALITIES)
++
++#define TPM_DID          0x0001
++#define TPM_VID          0x0001
++#define TPM_RID          0x0001
++
++/* if the connection to the vTPM should be closed after a successfully
++   received response; set to '0' to allow keeping the connection */
++#define FORCE_CLOSE      0
++
++/* local data structures */
++
++typedef struct TPMTx {
++    int fd[2];
++} tpmTx;
++
++typedef struct TPMBuffer {
++    uint8_t instance[4];      /* instance number in network byte order */
++    uint8_t buf[TPM_MAX_PKT];
++} __attribute__((packed)) tpmBuffer;
++
++/* locality data */
++typedef struct TPMLocal {
++    uint32_t state;
++    uint8_t access;
++    uint8_t sts;
++    uint32_t inte;
++    uint32_t ints;
++} tpmLoc;
++
++/* overall state of the TPM interface; 's' marks as save upon suspension */
++typedef struct TPMState {
++    uint32_t offset;            /* s */
++    tpmBuffer buffer;           /* s */
++    uint8_t active_loc;         /* s */
++    uint8_t aborting_locty;
++    uint8_t next_locty;
++    uint8_t irq_pending;        /* s */
++    tpmLoc loc[NUM_LOCALITIES]; /* s */
++    QEMUTimer *poll_timer;
++    SetIRQFunc *set_irq;
++    void *irq_opaque;
++    int irq;
++    int poll_attempts;
++    uint32_t vtpm_instance;  /* vtpm inst. number; determined from xenstore*/
++    int Transmitlayer;
++    tpmTx tpmTx;
++} tpmState;
++
++
++/* local prototypes */
++static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg);
++static int TPM_Receive(tpmState *s, tpmBuffer *buffer);
++static uint32_t vtpm_instance_from_xenstore(void);
++static void tis_poll_timer(void *opaque);
++static void tis_prep_next_interrupt(tpmState *s);
++static void tis_raise_irq(tpmState *s, uint8_t locty, uint32_t irqmask);
++static void close_vtpm_channel(tpmState *s, int force);
++static void open_vtpm_channel(tpmState *s);
++static void tis_attempt_receive(tpmState *s, uint8_t locty);
++
++/* transport layer functions: local sockets */
++static int create_local_socket(tpmState *s, uint32_t vtpm_instance);
++static int write_local_socket(tpmState *s, const tpmBuffer *);
++static int read_local_socket(tpmState *s, tpmBuffer *);
++static int close_local_socket(tpmState *s, int force);
++static int has_channel_local_socket(tpmState *s);
++#define LOCAL_SOCKET_PATH      "/var/vtpm/vtpm_all.socket"
++
++
++#define NUM_TRANSPORTS 1
++
++struct vTPM_transmit {
++    int (*open) (tpmState *s, uint32_t vtpm_instance);
++    int (*write) (tpmState *s, const tpmBuffer *);
++    int (*read) (tpmState *s, tpmBuffer *);
++    int (*close) (tpmState *s, int);
++    int (*has_channel) (tpmState *s);
++} vTPMTransmit[NUM_TRANSPORTS] = {
++    { .open = create_local_socket,
++      .write = write_local_socket,
++      .read = read_local_socket,
++      .close = close_local_socket,
++      .has_channel = has_channel_local_socket,
++    }
++};
++
++
++#define IS_COMM_WITH_VTPM(s)                            \
++     ((s)->Transmitlayer >= 0 &&                        \
++      vTPMTransmit[(s)->Transmitlayer].has_channel(s))
++
++
++/**********************************************************************
++ helper functions
++ *********************************************************************/
++
++static inline uint32_t tpm_get_size_from_buffer(const uint8_t *buffer)
++{
++    uint32_t len = (buffer[4] << 8) + buffer[5];
++    return len;
++}
++
++static inline void tpm_initialize_instance(tpmState *s, uint32_t instance)
++{
++    s->buffer.instance[0] = (instance >> 24) & 0xff;
++    s->buffer.instance[1] = (instance >> 16) & 0xff;
++    s->buffer.instance[2] = (instance >>  8) & 0xff;
++    s->buffer.instance[3] = (instance >>  0) & 0xff;
++}
++
++/*
++ * open communication channel with a vTPM
++ */
++static void open_vtpm_channel(tpmState *s)
++{
++    int idx;
++    /* search a usable transmit layer */
++    for (idx = 0; idx < NUM_TRANSPORTS; idx++) {
++        if (1 == vTPMTransmit[idx].open(s, s->vtpm_instance)) {
++            /* found one */
++            s->Transmitlayer = idx;
++            break;
++        }
++    }
++}
++
++/*
++ * close the communication channel with the vTPM
++ */
++static inline void close_vtpm_channel(tpmState *s, int force)
++{
++    if (1 == vTPMTransmit[s->Transmitlayer].close(s, force)) {
++        s->Transmitlayer = -1;
++    }
++}
++
++static inline uint8_t locality_from_addr(target_phys_addr_t addr)
++{
++    return (uint8_t)((addr >> 12) & 0x7);
++}
++
++
++/**********************************************************************
++    low-level transmission layer methods
++ *********************************************************************/
++
++/*
++ * the 'open' method that creates the filedescriptor for communicating
++ * only one is needed for reading and writing
++ */
++static int create_local_socket(tpmState *s, uint32_t vtpm_instance)
++{
++    int success = 1;
++    if (s->tpmTx.fd[0] < 0) {
++        s->tpmTx.fd[0] = socket(PF_LOCAL, SOCK_STREAM, 0);
++
++        if (has_channel_local_socket(s)) {
++            struct sockaddr_un addr;
++            memset(&addr, 0x0, sizeof(addr));
++            addr.sun_family = AF_LOCAL;
++            strcpy(addr.sun_path, LOCAL_SOCKET_PATH);
++            if (connect(s->tpmTx.fd[0],
++                        (struct sockaddr *)&addr,
++                        sizeof(addr)) != 0) {
++                close_local_socket(s, 1);
++                success = 0;
++            } else {
++                /* put filedescriptor in non-blocking mode for polling */
++                int flags = fcntl(s->tpmTx.fd[0], F_GETFL);
++                fcntl(s->tpmTx.fd[0], F_SETFL, flags | O_NONBLOCK);
++            }
++#ifdef DEBUG_TPM
++            if (success)
++                fprintf(logfile,"Successfully connected using local socket "
++                                LOCAL_SOCKET_PATH ".\n");
++            else
++                fprintf(logfile,"Could not connect to local socket "
++                                LOCAL_SOCKET_PATH ".\n");
++#endif
++        } else {
++            success = 0;
++        }
++    }
++    return success;
++}
++
++/*
++ * the 'write' method for sending requests to the vTPM
++ * four bytes with the vTPM instance number are prepended to each request
++ * the locality in which the command was sent is transmitted in the
++ * highest 3 bits
++ */
++static int write_local_socket(tpmState *s, const tpmBuffer *buffer)
++{
++    uint32_t size = tpm_get_size_from_buffer(buffer->buf);
++    int len;
++
++    len = write(s->tpmTx.fd[0],
++                buffer->instance,
++                sizeof(buffer->instance) + size);
++    if (len == sizeof(buffer->instance) + size) {
++        return len;
++    } else {
++        return -1;
++    }
++}
++
++/*
++ * the 'read' method for receiving of responses from the TPM
++ * this function expects that four bytes with the instance number
++ * are received from the vTPM
++ */
++static int read_local_socket(tpmState *s, tpmBuffer *buffer)
++{
++    int off;
++#ifdef DEBUG_TPM
++    fprintf(logfile, "Reading from fd %d\n", s->tpmTx.fd[0]);
++#endif
++    off = read(s->tpmTx.fd[0],
++               buffer->instance,
++               sizeof(buffer->instance)+TPM_MAX_PKT);
++#ifdef DEBUG_TPM
++    fprintf(logfile, "Read %d bytes\n", off);
++#endif
++    return off;
++}
++
++/*
++ * the 'close' method
++ * shut down communication with the vTPM
++ * 'force' = 1 indicates that the socket *must* be closed
++ * 'force' = 0 indicates that a connection may be maintained
++ */
++static int close_local_socket(tpmState *s, int force)
++{
++    if (force) {
++        close(s->tpmTx.fd[0]);
++#ifdef DEBUG_TPM
++        fprintf(logfile,"Closed connection with fd %d\n",s->tpmTx.fd[0]);
++#endif
++        s->tpmTx.fd[0] = -1;
++        return 1; /* socket was closed */
++    }
++#ifdef DEBUG_TPM
++    fprintf(logfile,"Keeping connection with fd %d\n",s->tpmTx.fd[0]);
++#endif
++    return 0;
++}
++
++/*
++ * the 'has_channel' method that checks whether there's a communication
++ * channel with the vTPM
++ */
++static int has_channel_local_socket(tpmState *s)
++{
++    return (s->tpmTx.fd[0] > 0);
++}
++
++/**********************************************************************/
++
++/*
++ * read a byte of response data
++ */
++static uint32_t tpm_data_read(tpmState *s, uint8_t locty)
++{
++    uint32_t ret, len;
++
++    /* try to receive data, if none are there it is ok */
++    tis_attempt_receive(s, locty);
++
++    if (s->loc[locty].state != STATE_COMPLETION) {
++        return 0xff;
++    }
++
++    len = tpm_get_size_from_buffer(s->buffer.buf);
++    ret = s->buffer.buf[s->offset++];
++    if (s->offset >= len) {
++        s->loc[locty].sts = STS_VALID ;
++        s->offset = 0;
++    }
++#ifdef DEBUG_TPM
++    fprintf(logfile,"tpm_data_read byte x%02x   [%d]\n",ret,s->offset-1);
++#endif
++    return ret;
++}
++
++
++
++/* raise an interrupt if allowed */
++static void tis_raise_irq(tpmState *s, uint8_t locty, uint32_t irqmask)
++{
++    if (!s->irq_pending &&
++        (s->loc[locty].inte & INT_ENABLED) &&
++        (s->loc[locty].inte & irqmask)) {
++        if ((irqmask & s->loc[locty].ints) == 0) {
++#ifdef DEBUG_TPM
++            fprintf(logfile,"Raising IRQ for flag %08x\n",irqmask);
++#endif
++            s->set_irq(s->irq_opaque, s->irq, 1);
++            s->irq_pending = 1;
++            s->loc[locty].ints |= irqmask;
++        }
++    }
++}
++
++/* abort execution of command */
++static void tis_abort(tpmState *s)
++{
++    s->offset = 0;
++    s->active_loc = s->next_locty;
++
++    /*
++     * Need to react differently depending on who's aborting now and
++     * which locality will become active afterwards.
++     */
++    if (s->aborting_locty == s->next_locty) {
++        s->loc[s->aborting_locty].state = STATE_READY;
++        s->loc[s->aborting_locty].sts   = STS_COMMAND_READY;
++        tis_raise_irq(s, s->aborting_locty, INT_COMMAND_READY);
++    }
++
++    /* locality after abort is another one than the current one */
++    if (s->aborting_locty != s->next_locty && s->next_locty != NO_LOCALITY) {
++        s->loc[s->aborting_locty].access &= ~ACCESS_ACTIVE_LOCALITY;
++        s->loc[s->next_locty].access     |=  ACCESS_ACTIVE_LOCALITY;
++        tis_raise_irq(s, s->next_locty, INT_LOCALITY_CHANGED);
++    }
++
++    s->aborting_locty = NO_LOCALITY; /* nobody's aborting a command anymore */
++
++    qemu_del_timer(s->poll_timer);
++}
++
++/* abort current command */
++static void tis_prep_abort(tpmState *s, uint8_t locty, uint8_t newlocty)
++{
++    s->aborting_locty = locty; /* current locality */
++    s->next_locty = newlocty;  /* locality after successful abort */
++
++    /*
++     * only abort a command using an interrupt if currently executing
++     * a command AND if there's a valid connection to the vTPM.
++     */
++    if (s->loc[locty].state == STATE_EXECUTION &&
++        IS_COMM_WITH_VTPM(s)) {
++        /* start timer and inside the timer wait for the result */
++        s->poll_attempts = 0;
++        tis_prep_next_interrupt(s);
++    } else {
++        tis_abort(s);
++    }
++}
++
++
++/*
++ * Try to receive a response from the vTPM
++ */
++static void tis_attempt_receive(tpmState *s, uint8_t locty)
++{
++    /*
++     * Attempt to read from the vTPM here if
++     * - not aborting a command
++     * - command has been sent and state is 'EXECUTION' now
++     * - no data are already available (data have already been read)
++     * - there's a communication path to the vTPM established
++     */
++    if (!IS_VALID_LOC(s->aborting_locty)) {
++        if (s->loc[locty].state == STATE_EXECUTION) {
++            if (0 == (s->loc[locty].sts & STS_DATA_AVAILABLE)){
++                if (IS_COMM_WITH_VTPM(s)) {
++                    int n = TPM_Receive(s, &s->buffer);
++                    if (n > 0) {
++                        s->loc[locty].sts = STS_VALID | STS_DATA_AVAILABLE;
++                        s->loc[locty].state = STATE_COMPLETION;
++                        close_vtpm_channel(s, FORCE_CLOSE);
++                        tis_raise_irq(s, locty, INT_DATA_AVAILABLE);
++                    }
++                }
++            }
++        }
++    }
++}
++
++/*
++ * Read a register of the TIS interface
++ * See specs pages 33-63 for description of the registers
++ */
++static uint32_t tis_mem_readl(void *opaque, target_phys_addr_t addr)
++{
++    tpmState *s = (tpmState *)opaque;
++    uint16_t offset = addr & 0xffc;
++    uint8_t shift = (addr & 0x3) * 8;
++    uint32_t val = 0;
++    uint8_t locty = locality_from_addr(addr);
++
++    if (offset == TPM_REG_ACCESS) {
++        if (s->active_loc == locty) {
++            s->loc[locty].access |= (1 << 5);
++         } else {
++            s->loc[locty].access &= ~(1 << 5);
++        }
++        val = s->loc[locty].access;
++    } else
++    if (offset == TPM_REG_INT_ENABLE) {
++        val = s->loc[locty].inte;
++    } else
++    if (offset == TPM_REG_INT_VECTOR) {
++        val = s->irq;
++    } else
++    if (offset == TPM_REG_INT_STATUS) {
++        tis_attempt_receive(s, locty);
++        val = s->loc[locty].ints;
++    } else
++    if (offset == TPM_REG_INTF_CAPABILITY) {
++        val = CAPABILITIES_SUPPORTED;
++    } else
++    if (offset == TPM_REG_STS) { /* status register */
++        tis_attempt_receive(s, locty);
++        val = (sizeof(s->buffer.buf) - s->offset) << 8 | s->loc[locty].sts;
++    } else
++    if (offset == TPM_REG_DATA_FIFO) {
++      val = tpm_data_read(s, locty);
++    } else
++    if (offset == TPM_REG_DID_VID) {
++        val = (TPM_DID << 16) | TPM_VID;
++    } else
++    if (offset == TPM_REG_RID) {
++         val = TPM_RID;
++    }
++
++    if (shift)
++        val >>= shift;
++
++#ifdef DEBUG_TPM
++    fprintf(logfile," read(%08x) = %08x\n",
++            addr,
++            val);
++#endif
++
++    return val;
++}
++
++/*
++ * Write a value to a register of the TIS interface
++ * See specs pages 33-63 for description of the registers
++ */
++static void tis_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t 
val)
++{
++    tpmState* s=(tpmState*)opaque;
++    uint16_t off = addr & 0xfff;
++    uint8_t locty = locality_from_addr(addr);
++    int n, c;
++    uint32_t len;
++
++#ifdef DEBUG_TPM
++    fprintf(logfile,"write(%08x) = %08x\n",
++            addr,
++            val);
++#endif
++
++    if (off == TPM_REG_ACCESS) {
++        if (val & ACCESS_ACTIVE_LOCALITY) {
++            /* give up locality if currently owned */
++            if (s->active_loc == locty) {
++                uint8_t newlocty = NO_LOCALITY;
++                s->loc[locty].access &= ~(ACCESS_PENDING_REQUEST);
++                /* anybody wants the locality ? */
++                for (c = NUM_LOCALITIES - 1; c >= 0; c--) {
++                    if (s->loc[c].access & ACCESS_REQUEST_USE) {
++                        s->loc[c].access |= ACCESS_TPM_REG_VALID_STS;
++                        s->loc[c].access &= ~ACCESS_REQUEST_USE;
++                        newlocty = c;
++                        break;
++                    }
++                }
++                tis_prep_abort(s, locty, newlocty);
++            }
++        }
++        if (val & ACCESS_BEEN_SEIZED) {
++            /* clear the flag */
++            s->loc[locty].access &= ~ACCESS_BEEN_SEIZED;
++        }
++        if (val & ACCESS_SEIZE) {
++            if (locty > s->active_loc && IS_VALID_LOC(s->active_loc)) {
++                s->loc[s->active_loc].access |= ACCESS_BEEN_SEIZED;
++                s->loc[locty].access = ACCESS_TPM_REG_VALID_STS;
++                tis_prep_abort(s, s->active_loc, locty);
++            }
++        }
++        if (val & ACCESS_REQUEST_USE) {
++            if (IS_VALID_LOC(s->active_loc)) {
++                /* locality election */
++                s->loc[s->active_loc].access |= ACCESS_PENDING_REQUEST;
++            } else {
++                /* no locality active -> make this one active now */
++                s->loc[locty].access |= ACCESS_ACTIVE_LOCALITY;
++                s->active_loc = locty;
++                tis_raise_irq(s, locty, INT_LOCALITY_CHANGED);
++            }
++        }
++    } else
++    if (off == TPM_REG_INT_ENABLE) {
++        s->loc[locty].inte = (val & (INT_ENABLED | (0x3 << 3) |
++                                     INTERRUPTS_SUPPORTED));
++    } else
++    if (off == TPM_REG_INT_STATUS) {
++        /* clearing of interrupt flags */
++        if ((val & INTERRUPTS_SUPPORTED) &&
++            (s->loc[locty].ints & INTERRUPTS_SUPPORTED)) {
++            s->set_irq(s->irq_opaque, s->irq, 0);
++            s->irq_pending = 0;
++        }
++        s->loc[locty].ints &= ~(val & INTERRUPTS_SUPPORTED);
++    } else
++    if (off == TPM_REG_STS) {
++        if (val & STS_COMMAND_READY) {
++            if (s->loc[locty].state == STATE_IDLE) {
++                s->loc[locty].sts   = STS_COMMAND_READY;
++                s->loc[locty].state = STATE_READY;
++                tis_raise_irq(s, locty, INT_COMMAND_READY);
++            } else if (s->loc[locty].state == STATE_COMPLETION ||
++                       s->loc[locty].state == STATE_EXECUTION  ||
++                       s->loc[locty].state == STATE_RECEPTION) {
++                /* abort currently running command */
++                tis_prep_abort(s, locty, locty);
++            }
++        }
++        if (val & STS_TPM_GO) {
++            n = TPM_Send(s, &s->buffer, locty, "tpm_data_write");
++            if (n > 0) {
++                /* sending of data was successful */
++                s->offset = 0;
++                s->loc[locty].state = STATE_EXECUTION;
++                if (s->loc[locty].inte & (INT_ENABLED | INT_DATA_AVAILABLE)) {
++                    s->poll_attempts = 0;
++                    tis_prep_next_interrupt(s);
++                }
++            }
++        }
++        if (val & STS_RESPONSE_RETRY) {
++            s->offset = 0;
++        }
++    } else if (off == TPM_REG_DATA_FIFO) {
++        /* data fifo */
++        if (s->loc[locty].state == STATE_IDLE ||
++            s->loc[locty].state == STATE_EXECUTION ||
++            s->loc[locty].state == STATE_COMPLETION) {
++            /* drop the byte */
++        } else {
++#ifdef TPM_DEBUG
++        fprintf(logfile,"Byte to send to TPM: %02x\n", val);
++#endif
++            s->loc[locty].state = STATE_RECEPTION;
++
++            if (s->offset < sizeof(s->buffer.buf))
++                s->buffer.buf[s->offset++] = (uint8_t)val;
++
++            if (s->offset > 5) {
++                /* we have a packet length - see if we have all of it */
++                len = tpm_get_size_from_buffer(s->buffer.buf);
++                if (len > s->offset) {
++                    s->loc[locty].sts = STS_EXPECT | STS_VALID;
++                } else {
++                    s->loc[locty].sts = STS_VALID;
++                }
++            }
++        }
++    }
++}
++
++/*
++ * Prepare the next interrupt for example after a command has
++ * been sent out for the purpose of receiving the response.
++ * Depending on how many interrupts (used for polling on the fd) have
++ * already been schedule, this function determines the delta in time
++ * to the next interrupt. This accomodates for commands that finish
++ * quickly.
++ */
++static void tis_prep_next_interrupt(tpmState *s)
++{
++    int64_t expiration;
++    int rate = 5; /* 5 times per second */
++
++    /*
++       poll often at the beginning for quickly finished commands,
++       then back off
++     */
++    if (s->poll_attempts < 5) {
++        rate = 20;
++    } else if (s->poll_attempts < 10) {
++        rate = 10;
++    }
++
++    expiration = qemu_get_clock(vm_clock) + (ticks_per_sec / rate);
++    qemu_mod_timer(s->poll_timer, expiration);
++    s->poll_attempts++;
++}
++
++
++/*
++ * The polling routine called when the 'timer interrupt' fires.
++ * Tries to receive a command from the vTPM.
++ */
++static void tis_poll_timer(void *opaque)
++{
++    tpmState* s=(tpmState*)opaque;
++    uint8_t locty = s->active_loc;
++
++    if (!IS_VALID_LOC(locty) ||
++        (!(s->loc[locty].inte & INT_ENABLED) &&
++          (s->aborting_locty != NO_LOCALITY)) ||
++        !IS_COMM_WITH_VTPM(s)) {
++        /* no more interrupts requested, so no more polling needed */
++        qemu_del_timer(s->poll_timer);
++    }
++
++    if (!IS_COMM_WITH_VTPM(s)) {
++        if (s->aborting_locty != NO_LOCALITY) {
++            tis_abort(s);
++        }
++        return;
++    }
++
++    if (s->aborting_locty != NO_LOCALITY) {
++        int n = TPM_Receive(s, &s->buffer);
++#ifdef DEBUG_TPM
++        fprintf(logfile,"Receiving for abort.\n");
++#endif
++        if (n > 0) {
++            close_vtpm_channel(s, FORCE_CLOSE);
++            tis_abort(s);
++#ifdef DEBUG_TPM
++            fprintf(logfile,"Abort is complete.\n");
++#endif
++        } else {
++            tis_prep_next_interrupt(s);
++        }
++    } else if (IS_VALID_LOC(locty)) {
++        if (s->loc[locty].state == STATE_EXECUTION) {
++           /* poll for result */
++            int n = TPM_Receive(s, &s->buffer);
++            if (n > 0) {
++                s->loc[locty].sts = STS_VALID | STS_DATA_AVAILABLE;
++                s->loc[locty].state = STATE_COMPLETION;
++                close_vtpm_channel(s, FORCE_CLOSE);
++                tis_raise_irq(s, locty, INT_DATA_AVAILABLE);
++            } else {
++                /* nothing received */
++                tis_prep_next_interrupt(s);
++            }
++        }
++    }
++}
++
++
++static CPUReadMemoryFunc *tis_readfn[3]={
++    tis_mem_readl,
++    tis_mem_readl,
++    tis_mem_readl
++};
++
++static CPUWriteMemoryFunc *tis_writefn[3]={
++    tis_mem_writel,
++    tis_mem_writel,
++    tis_mem_writel
++};
++
++/*
++ * Save the internal state of this interface for later resumption.
++ * Need to get any outstanding responses from the vTPM back, so
++ * this might delay the suspend for a while.
++ */
++static void tpm_save(QEMUFile* f,void* opaque)
++{
++    tpmState* s=(tpmState*)opaque;
++    int c;
++
++    /* need to wait for outstanding requests to complete */
++    if (IS_COMM_WITH_VTPM(s)) {
++        int repeats = 30; /* 30 seconds; really should be infty */
++        while (repeats > 0 &&
++               !(s->loc[s->active_loc].sts & STS_DATA_AVAILABLE)) {
++            int n = TPM_Receive(s, &s->buffer);
++            if (n > 0) {
++                if (IS_VALID_LOC(s->active_loc)) {
++                    s->loc[s->active_loc].sts = STS_VALID | 
STS_DATA_AVAILABLE;
++                }
++                /* close the connection with the vTPM for good */
++                close_vtpm_channel(s, 1);
++                break;
++            }
++            sleep(1);
++        }
++    }
++
++    qemu_put_be32s(f,&s->offset);
++    qemu_put_buffer(f, s->buffer.buf, TPM_MAX_PKT);
++    qemu_put_8s(f, &s->active_loc);
++    qemu_put_8s(f, &s->irq_pending);
++    for (c = 0; c < NUM_LOCALITIES; c++) {
++        qemu_put_be32s(f, &s->loc[c].state);
++        qemu_put_8s(f, &s->loc[c].access);
++        qemu_put_8s(f, &s->loc[c].sts);
++        qemu_put_be32s(f, &s->loc[c].inte);
++        qemu_put_be32s(f, &s->loc[c].ints);
++    }
++}
++
++/*
++ * load TIS interface state
++ */
++static int tpm_load(QEMUFile* f,void* opaque,int version_id)
++{
++    tpmState* s=(tpmState*)opaque;
++    int c;
++
++    if (version_id != 1)
++        return -EINVAL;
++
++    qemu_get_be32s(f,&s->offset);
++    qemu_get_buffer(f, s->buffer.buf, TPM_MAX_PKT);
++    qemu_get_8s(f, &s->active_loc);
++    qemu_get_8s(f, &s->irq_pending);
++    for (c = 0; c < NUM_LOCALITIES; c++) {
++        qemu_get_be32s(f, &s->loc[c].state);
++        qemu_get_8s(f, &s->loc[c].access);
++        qemu_get_8s(f, &s->loc[c].sts);
++        qemu_get_be32s(f, &s->loc[c].inte);
++        qemu_get_be32s(f, &s->loc[c].ints);
++    }
++
++    /* need to be able to get the instance number from the xenstore */
++    s->vtpm_instance = vtpm_instance_from_xenstore();
++    if (s->vtpm_instance == VTPM_BAD_INSTANCE)
++        return -EINVAL;
++    tpm_initialize_instance(s, s->vtpm_instance);
++
++    return 0;
++}
++
++
++typedef struct LPCtpmState {
++    tpmState tpm;
++    int mem;
++} LPCtpmState;
++
++
++/*
++ * initialize TIS interface
++ */
++void tpm_tis_init(SetIRQFunc *set_irq, void *opaque, int irq)
++{
++    LPCtpmState *d;
++    tpmState *s;
++    int c = 0;
++    uint32_t vtpm_in;
++
++    vtpm_in = vtpm_instance_from_xenstore();
++    /* no valid vtpm instance -> no device */
++    if (vtpm_in == VTPM_BAD_INSTANCE)
++        return;
++
++    d = qemu_mallocz(sizeof(LPCtpmState));
++    d->mem = cpu_register_io_memory(0, tis_readfn, tis_writefn, d);
++
++    if (d->mem == -1) {
++       return;
++    }
++
++    cpu_register_physical_memory(TIS_ADDR_BASE,
++                                 0x1000 * NUM_LOCALITIES, d->mem);
++
++    /* initialize tpmState */
++    s = &d->tpm;
++
++    s->offset = 0;
++    s->active_loc = NO_LOCALITY;
++
++    while (c < NUM_LOCALITIES) {
++        s->loc[c].access = (1 << 7);
++        s->loc[c].sts = 0;
++        s->loc[c].inte = (1 << 3);
++        s->loc[c].ints = 0;
++        s->loc[c].state = STATE_IDLE;
++        c++;
++    }
++    s->poll_timer = qemu_new_timer(vm_clock, tis_poll_timer, s);
++    s->set_irq = set_irq;
++    s->irq_opaque = opaque;
++    s->irq = irq;
++    s->vtpm_instance = vtpm_in;
++    s->Transmitlayer = -1;
++    s->tpmTx.fd[0] = -1;
++    s->tpmTx.fd[1] = -1;
++
++    tpm_initialize_instance(s, s->vtpm_instance);
++    memset(s->buffer.buf,0,sizeof(s->buffer.buf));
++
++    register_savevm("tpm-tis", 0, 1, tpm_save, tpm_load, s);
++}
++
++/****************************************************************************/
++/*  optional verbose logging of data to/from vtpm                           */
++/****************************************************************************/
++#ifdef DEBUG_TPM
++static void showBuff(unsigned char *buff, char *string)
++{
++    uint32_t i, len;
++
++    len = tpm_get_size_from_buffer(buff);
++    fprintf(logfile,"%s length = %d\n", string, len);
++    for (i = 0; i < len; i++) {
++        if (i && !(i % 16)) {
++            fprintf(logfile,"\n");
++        }
++        fprintf(logfile,"%.2X ", buff[i]);
++    }
++    fprintf(logfile,"\n");
++}
++#endif
++
++/****************************************************************************/
++/* Transmit request to TPM and read Response                                */
++/****************************************************************************/
++
++const static unsigned char tpm_failure[] = {
++    0x00, 0x00,
++    0x00, 0x00, 0x00, 0x0a,
++    0x00, 0x00, 0x00, 0x09
++};
++
++
++/*
++ * Send a TPM request.
++ */
++static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg)
++{
++    int len;
++    uint32_t size = tpm_get_size_from_buffer(buffer->buf);
++
++    /* try to establish a connection to the vTPM */
++    if ( !IS_COMM_WITH_VTPM(s)) {
++        open_vtpm_channel(s);
++    }
++
++    if ( !IS_COMM_WITH_VTPM(s)) {
++        unsigned char tag = buffer->buf[1];
++
++        /* there's a failure response from the TPM */
++        memcpy(buffer->buf, tpm_failure, sizeof(tpm_failure));
++        buffer->buf[1] = tag + 3;
++        if (IS_VALID_LOC(s->active_loc)) {
++            s->loc[s->active_loc].sts = STS_DATA_AVAILABLE | STS_VALID;
++        }
++#ifdef DEBUG_TPM
++        fprintf(logfile,"No TPM running!\n");
++#endif
++        /* the request went out ok. */
++        return sizeof(buffer->instance) + size;
++    }
++
++#ifdef DEBUG_TPM
++    showBuff(buffer->buf, "To TPM");
++#endif
++
++    /* transmit the locality in the highest 3 bits */
++    buffer->instance[0] &= 0x1f;
++    buffer->instance[0] |= (locty << 5);
++
++    len = vTPMTransmit[s->Transmitlayer].write(s, buffer);
++    if (len < 0) {
++        s->Transmitlayer = -1;
++    }
++    return len;
++}
++
++/*
++ * Try to receive data from the file descriptor. Since it is in
++ * non-blocking mode it is possible that no data are actually received -
++ * whatever calls this function needs to try again later.
++ */
++static int TPM_Receive(tpmState *s, tpmBuffer *buffer)
++{
++    int off;
++
++    off = vTPMTransmit[s->Transmitlayer].read(s, buffer);
++
++    if (off < 0) {
++        /* EAGAIN is set in errno due to non-blocking mode */
++        return -1;
++    }
++
++    if (off == 0) {
++#ifdef DEBUG_TPM
++        fprintf(logfile,"TPM GONE? errno=%d\n",errno);
++#endif
++        close_vtpm_channel(s, 1);
++        /* pretend that data are available */
++        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);
++        }
++        return -1;
++    }
++
++#ifdef DEBUG_TPM
++    if (off > sizeof(buffer->instance ) + 6) {
++        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),
++                    off);
++        } else {
++            uint32_t ret;
++            showBuff(buffer->buf, "From TPM");
++            ret = (buffer->buf[8])*256 + buffer->buf[9];
++            if (ret)
++                fprintf(logfile,"Receive failed with error %d\n", ret);
++            else
++                fprintf(logfile,"Receive succeeded. Got response of length %d 
(=%d)\n",
++                       size, off);
++        }
++    }
++#endif
++
++    /* assuming reading in one chunk for now */
++    return off;
++}
++
++
++/****************************************************************************
++   Helper functions for reading data from the xenstore such as
++   reading virtual TPM instance information
++ ****************************************************************************/
++int has_tpm_device(void)
++{
++    int ret = 0;
++    struct xs_handle *handle = xs_daemon_open();
++    if (handle) {
++        ret = xenstore_domain_has_devtype(handle, "vtpm");
++        xs_daemon_close(handle);
++    }
++    return ret;
++}
++
++
++/*
++ * Wait until hotplug scripts have finished then read the vTPM instance
++ * number from the xenstore.
++ */
++static uint32_t vtpm_instance_from_xenstore(void)
++{
++    unsigned int num;
++    uint32_t number = VTPM_BAD_INSTANCE;
++    int end = 0;
++    char *token = "tok";
++    int subscribed = 0;
++    int ctr = 0;
++    fd_set readfds;
++
++    struct xs_handle *handle = xs_daemon_open();
++
++    FD_ZERO(&readfds);
++
++    if (handle) {
++        char **e = xenstore_domain_get_devices(handle, "vtpm", &num);
++        int fd = xs_fileno(handle);
++        FD_SET(fd, &readfds);
++        if (e) {
++            do {
++                struct timeval tv = {
++                    .tv_sec  = 30,
++                    .tv_usec = 0,
++                };
++                /* need to make sure that the hotplug scripts have finished */
++                char *status = xenstore_read_hotplug_status(handle,
++                                                            "vtpm",
++                                                            e[0]);
++                if (status) {
++                    if (!strcmp(status, "connected")) {
++                        char *inst = xenstore_backend_read_variable(handle,
++                                                                    "vtpm",
++                                                                    e[0],
++                                                                   
"instance");
++                        if (1 != (sscanf(inst,"%d",&number)))
++                            number = VTPM_BAD_INSTANCE;
++                        free(inst);
++                    } else {
++                        fprintf(logfile,
++                                "bad status '%s' from vtpm hotplug\n",
++                                status);
++                    }
++                    free(status);
++                    end = 1;
++                } else {
++                    /* no status, yet */
++                    int rc;
++                    unsigned int nr;
++                    char **f;
++
++                    if (!subscribed) {
++                        rc = xenstore_subscribe_to_hotplug_status(handle,
++                                                                  "vtpm",
++                                                                  e[0],
++                                                                  token);
++                        if (rc != 0)
++                            break;
++                        subscribed = 1;
++                    }
++                    rc = select(fd+1, &readfds, NULL, NULL, &tv);
++                    /* get what's available -- drain the fd */
++                    f = xs_read_watch(handle, &nr);
++                    ctr++;
++                    free(f);
++                    if (ctr > 2)
++                        end = 1;
++                }
++            } while (end == 0);
++            free(e);
++        }
++        if (subscribed) {
++            /* clean up */
++            xenstore_unsubscribe_from_hotplug_status(handle,
++                                                     "vtpm",
++                                                     e[0],
++                                                     token);
++        }
++        xs_daemon_close(handle);
++    }
++    if (number == VTPM_BAD_INSTANCE)
++        fprintf(logfile, "no valid vtpm instance");
++    else
++        fprintf(logfile,"vtpm instance:%d\n",number);
++    return number;
++}
+Index: ioemu/vl.h
+===================================================================
+--- ioemu.orig/vl.h    2006-12-08 18:33:48.000000000 +0000
++++ ioemu/vl.h 2006-12-08 18:35:14.000000000 +0000
+@@ -932,6 +932,10 @@
+ void piix4_pm_init(PCIBus *bus, int devfn);
+ void acpi_bios_init(void);
+ 
++/* tpm_tis.c */
++int has_tpm_device(void);
++void tpm_tis_init(SetIRQFunc *set_irq, void *irq_opaque, int irq);
++
+ /* piix4acpi.c */
+ extern void pci_piix4_acpi_init(PCIBus *bus, int devfn);
+ 
diff -r 1cfd862e5254 -r 8cddaee4a51c 
tools/ioemu/patches/usb-mouse-tablet-status-check
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/usb-mouse-tablet-status-check Sat Dec 09 14:34:53 
2006 +0000
@@ -0,0 +1,168 @@
+# HG changeset patch
+# User kfraser@xxxxxxxxxxxxxxxxxxxxx
+# Node ID 60bbcf799384d779c2a561b9d9ba30f28e31d970
+# Parent  fb3cb6f52a2905be938559529ae43b6ba990c878
+[HVM] qemu mouse: Adds support for USB mouse/tablet status check and
+restricts Universal Host Controller interrupt generating when received
+NAK in interrupt transfer.
+
+According to usb spec, USB mouse/tablet device returns NAK to host
+controller if its status does not alter in interrupt transfer.
+And UHC should leave a TD active when receiving NAK and execute this
+incompleted TD in a subseqent frame. UHC only generates an interrupt
+on complete after the TD with ICO bit is completed.
+
+This patch make UHC & USB mouse/tablet behave consistently with spec.
+
+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 {
+     int x, y;
+     int kind;
+     int mouse_grabbed;
++    int status_changed;
+ } USBMouseState;
+ 
+ /* mostly the same values as the Bochs USB Mouse device */
+@@ -231,6 +232,7 @@ static void usb_mouse_event(void *opaque
+     s->dy += dy1;
+     s->dz += dz1;
+     s->buttons_state = buttons_state;
++    s->status_changed = 1;
+ }
+ 
+ static void usb_tablet_event(void *opaque,
+@@ -242,6 +244,7 @@ static void usb_tablet_event(void *opaqu
+     s->y = y;
+     s->dz += dz;
+     s->buttons_state = buttons_state;
++    s->status_changed = 1;
+ }
+ 
+ static inline int int_clamp(int val, int vmin, int vmax)
+@@ -483,10 +486,16 @@ static int usb_mouse_handle_data(USBDevi
+     switch(pid) {
+     case USB_TOKEN_IN:
+         if (devep == 1) {
+-          if (s->kind == USB_MOUSE)
+-              ret = usb_mouse_poll(s, data, len);
+-          else if (s->kind == USB_TABLET)
+-              ret = usb_tablet_poll(s, data, len);
++            if (s->kind == USB_MOUSE)
++                ret = usb_mouse_poll(s, data, len);
++            else if (s->kind == USB_TABLET)
++                ret = usb_tablet_poll(s, data, len);
++
++            if (!s->status_changed)
++                ret = USB_RET_NAK;
++            else
++                s->status_changed = 0;
++
+         } else {
+             goto fail;
+         }
+@@ -523,6 +532,7 @@ USBDevice *usb_tablet_init(void)
+     s->dev.handle_data = usb_mouse_handle_data;
+     s->dev.handle_destroy = usb_mouse_handle_destroy;
+     s->kind = USB_TABLET;
++    s->status_changed = 0;
+ 
+     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
+ 
+@@ -544,6 +554,7 @@ USBDevice *usb_mouse_init(void)
+     s->dev.handle_data = usb_mouse_handle_data;
+     s->dev.handle_destroy = usb_mouse_handle_destroy;
+     s->kind = USB_MOUSE;
++    s->status_changed = 0;
+ 
+     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, 
+     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))
+-        return 1;
++    if (!(td->ctrl & TD_CTRL_ACTIVE)){
++        ret = 1;
++        goto out;
++    }
+ 
+     /* TD is active */
+     max_len = ((td->token >> 21) + 1) & 0x7ff;
+@@ -467,7 +465,8 @@ static int uhci_handle_td(UHCIState *s, 
+         /* invalid pid : frame interrupted */
+         s->status |= UHCI_STS_HCPERR;
+         uhci_update_irq(s);
+-        return -1;
++        ret = -1;
++        goto out;
+     }
+     if (td->ctrl & TD_CTRL_IOS)
+         td->ctrl &= ~TD_CTRL_ACTIVE;
+@@ -479,10 +478,12 @@ static int uhci_handle_td(UHCIState *s, 
+             len < max_len) {
+             *int_mask |= 0x02;
+             /* short packet: do not update QH */
+-            return 1;
++            ret = 1;
++            goto out;
+         } else {
+             /* success */
+-            return 0;
++            ret = 0;
++            goto out;
+         }
+     } else {
+         switch(ret) {
+@@ -501,23 +502,34 @@ static int uhci_handle_td(UHCIState *s, 
+             }
+             td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) | 
+                 (err << TD_CTRL_ERROR_SHIFT);
+-            return 1;
++            ret = 1;
++            goto out;
+         case USB_RET_NAK:
+             td->ctrl |= TD_CTRL_NAK;
+             if (pid == USB_TOKEN_SETUP)
+                 goto do_timeout;
+-            return 1;
++            ret = 1;
++            goto out;
+         case USB_RET_STALL:
+             td->ctrl |= TD_CTRL_STALL;
+             td->ctrl &= ~TD_CTRL_ACTIVE;
+-            return 1;
++            ret = 1;
++            goto out;
+         case USB_RET_BABBLE:
+             td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
+             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 */ 
++    if ((td->ctrl & TD_CTRL_IOC) && (!(td->ctrl & TD_CTRL_ACTIVE))) {
++        *int_mask |= 0x01;
++    }
++    return ret;
+ }
+ 
+ static void uhci_frame_timer(void *opaque)
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/usb-uhci-buffer-size
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/usb-uhci-buffer-size  Sat Dec 09 14:34:53 2006 +0000
@@ -0,0 +1,25 @@
+# HG changeset patch
+# User kfraser@xxxxxxxxxxxxxxxxxxxxx
+# Node ID f19ddc0ee3e68d5d8a250ba0a20ab7d90ae9a36a
+# Parent  f66f7c3a82a7420d80714b0d349ee9a24b50ec28
+[QEMU] usb-uhci: Data buffer is too small
+
+The data buffer is only 1280 bytes long but the user-supplied length
+can be as large as 0x7ff.  This patch extends the buffer to 2048
+bytes.
+
+Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
+
+Index: ioemu/hw/usb-uhci.c
+===================================================================
+--- ioemu.orig/hw/usb-uhci.c   2006-12-08 18:21:36.000000000 +0000
++++ ioemu/hw/usb-uhci.c        2006-12-08 18:23:06.000000000 +0000
+@@ -421,7 +421,7 @@
+ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
+ {
+     uint8_t pid;
+-    uint8_t buf[1280];
++    uint8_t buf[2048];
+     int len, max_len, err, ret;
+ 
+     if (td->ctrl & TD_CTRL_IOC) {
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-japan-keymap
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/vnc-japan-keymap      Sat Dec 09 14:34:53 2006 +0000
@@ -0,0 +1,39 @@
+# HG changeset patch
+# User kasai.takanori@xxxxxxxxxxxxxx
+# Node ID ea1ffa51b4121d36cffdc90276378a6ed334c2cc
+# Parent  edd592c823a520d4072a95ac39beb2012c05321e
+Add the Japanese keymap for VNC Server.
+
+Signed-off-by: Takanori Kasai < kasai.takanori@xxxxxxxxxxxxxx >
+
+Index: ioemu/keymaps/ja
+===================================================================
+--- ioemu.orig/keymaps/ja      2006-12-08 18:21:36.000000000 +0000
++++ ioemu/keymaps/ja   2006-12-08 18:21:56.000000000 +0000
+@@ -102,3 +102,6 @@
+ Henkan_Mode 0x79
+ Katakana 0x70
+ Muhenkan 0x7b
++Henkan_Mode_Real 0x79
++Henkan_Mode_Ultra 0x79
++backslash_ja 0x73
+Index: ioemu/vnc_keysym.h
+===================================================================
+--- ioemu.orig/vnc_keysym.h    2006-12-08 18:21:36.000000000 +0000
++++ ioemu/vnc_keysym.h 2006-12-08 18:21:56.000000000 +0000
+@@ -271,5 +271,15 @@
+ {"Num_Lock", 0xff7f},    /* XK_Num_Lock */
+ {"Pause", 0xff13},       /* XK_Pause */
+ {"Escape", 0xff1b},      /* XK_Escape */
++
++    /* localized keys */
++{"BackApostrophe", 0xff21},
++{"Muhenkan", 0xff22},
++{"Katakana", 0xff25},
++{"Zenkaku_Hankaku", 0xff29},
++{"Henkan_Mode_Real", 0xff23},
++{"Henkan_Mode_Ultra", 0xff3e},
++{"backslash_ja", 0xffa5},
++
+ {0,0},
+ };
diff -r 1cfd862e5254 -r 8cddaee4a51c 
tools/ioemu/patches/vnc-monitor-shift-key-processing
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/vnc-monitor-shift-key-processing      Sat Dec 09 
14:34:53 2006 +0000
@@ -0,0 +1,60 @@
+# HG changeset patch
+# User kfraser@xxxxxxxxxxxxxxxxxxxxx
+# Node ID 582d21e2d3cd12a13ad4debee9af8bb0f1be413a
+# Parent  b7095209e31ae1f52cd4b196225a360543e37a80
+[QEMU] Do shift-key processing in QEMU monitor terminal when connected via VNC.
+Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx>
+
+Index: ioemu/vnc.c
+===================================================================
+--- ioemu.orig/vnc.c   2006-12-08 18:21:36.000000000 +0000
++++ ioemu/vnc.c        2006-12-08 18:23:12.000000000 +0000
+@@ -114,6 +114,7 @@
+     int visible_h;
+ 
+     int ctl_keys;               /* Ctrl+Alt starts calibration */
++    int shift_keys;             /* Shift / CapsLock keys */
+ };
+ 
+ #define DIRTY_PIXEL_BITS 64
+@@ -870,9 +871,12 @@
+     } else if (down) {
+       int qemu_keysym = 0;
+ 
+-      if (sym <= 128) /* normal ascii */
++      if (sym <= 128) { /* normal ascii */
++          int shifted = vs->shift_keys == 1 || vs->shift_keys == 2;
+           qemu_keysym = sym;
+-      else {
++          if (sym >= 'a' && sym <= 'z' && shifted)
++              qemu_keysym -= 'a' - 'A';
++      } else {
+           switch (sym) {
+           case XK_Up: qemu_keysym = QEMU_KEY_UP; break;
+           case XK_Down: qemu_keysym = QEMU_KEY_DOWN; break;
+@@ -903,6 +907,10 @@
+           vs->ctl_keys |= 2;
+           break;
+ 
++      case XK_Shift_L:
++          vs->shift_keys |= 1;
++          break;
++
+       default:
+           break;
+       }
+@@ -916,6 +924,14 @@
+           vs->ctl_keys &= ~2;
+           break;
+ 
++      case XK_Shift_L:
++          vs->shift_keys &= ~1;
++          break;
++
++      case XK_Caps_Lock:
++          vs->shift_keys ^= 2;
++          break;
++
+       case XK_1 ... XK_9:
+           if ((vs->ctl_keys & 3) != 3)
+               break;
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-numpad-handling
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/vnc-numpad-handling   Sat Dec 09 14:34:53 2006 +0000
@@ -0,0 +1,236 @@
+# HG changeset patch
+# User Ewan Mellor <ewan@xxxxxxxxxxxxx>
+# Node ID c7f4a89eb054a1ad411da1e4cdc8aeda1a98c4fa
+# Parent  565cd8f32c70da8ae7dbaaeb9dff28aa8b6307e1
+Fix numpad handling in QEMU's VNC server.  The keymaps that we have include
+information on which keys change depending upon the numlock setting, but
+this isn't being used.  By forcing numlock on and off as necessary, when
+receiving these keysyms through the VNC connection, we ensure that the
+server's numlock status is the same as the client's.
+
+Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
+
+Index: ioemu/keymaps.c
+===================================================================
+--- ioemu.orig/keymaps.c       2006-12-06 23:41:30.000000000 +0000
++++ ioemu/keymaps.c    2006-12-08 18:20:27.000000000 +0000
+@@ -36,8 +36,10 @@
+ #define MAX_EXTRA_COUNT 256
+ typedef struct {
+     uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
++    int keysym2numlock[MAX_NORMAL_KEYCODE];
+     struct {
+       int keysym;
++      int numlock;
+       uint16_t keycode;
+     } keysym2keycode_extra[MAX_EXTRA_COUNT];
+     int extra_count;
+@@ -50,6 +52,8 @@
+     char file_name[1024];
+     char line[1024];
+     int len;
++    int *keycode2numlock;
++    int i;
+ 
+     snprintf(file_name, sizeof(file_name),
+              "%s/keymaps/%s", bios_dir, language);
+@@ -63,6 +67,15 @@
+               "Could not read keymap file: '%s'\n", file_name);
+       return 0;
+     }
++
++    /* Allocate a temporary map tracking which keycodes change when numlock is
++       set.  Keycodes are 16 bit, so 65536 is safe. */
++    keycode2numlock = malloc(65536 * sizeof(int));
++    if (!keycode2numlock) {
++        perror("Could not read keymap file");
++      return 0;
++    }
++
+     for(;;) {
+       if (fgets(line, 1024, f) == NULL)
+             break;
+@@ -86,13 +99,19 @@
+               if (keysym == 0) {
+                     //                    fprintf(stderr, "Warning: unknown 
keysym %s\n", line);
+               } else {
+-                  const char *rest = end_of_keysym + 1;
+-                  int keycode = strtol(rest, NULL, 0);
++                  char *rest = end_of_keysym + 1;
++                  int keycode = strtol(rest, &rest, 0);
++                  int numlock = (rest != NULL &&
++                                 strstr(rest, "numlock") != NULL);
++
++                    keycode2numlock[keycode] = numlock;
++
+                   /* if(keycode&0x80)
+                      keycode=(keycode<<8)^0x80e0; */
+                   if (keysym < MAX_NORMAL_KEYCODE) {
+                       //fprintf(stderr,"Setting keysym %s (%d) to 
%d\n",line,keysym,keycode);
+                       k->keysym2keycode[keysym] = keycode;
++                      k->keysym2numlock[keysym] = numlock;
+                   } else {
+                       if (k->extra_count >= MAX_EXTRA_COUNT) {
+                           fprintf(stderr,
+@@ -107,6 +126,8 @@
+                               keysym = keysym;
+                           k->keysym2keycode_extra[k->extra_count].
+                               keycode = keycode;
++                          k->keysym2keycode_extra[k->extra_count].
++                              numlock = numlock;
+                           k->extra_count++;
+                       }
+                   }
+@@ -115,6 +136,22 @@
+       }
+     }
+     fclose(f);
++
++    for (i = 0; i < MAX_NORMAL_KEYCODE; i++) {
++        if (k->keysym2numlock[i] != 1) {
++            k->keysym2numlock[i] = -keycode2numlock[k->keysym2keycode[i]];
++        }
++    }
++
++    for (i = 0; i < k->extra_count; i++) {
++        if (k->keysym2keycode_extra[i].numlock != 1) {
++            k->keysym2keycode_extra[i].numlock =
++                -keycode2numlock[k->keysym2keycode_extra[i].keycode];
++        }
++    }
++
++    free(keycode2numlock);
++
+     return k;
+ }
+ 
+@@ -143,3 +180,25 @@
+     }
+     return 0;
+ }
++
++/**
++ * Returns 1 if the given keysym requires numlock to be pressed, -1 if it
++ * requires it to be cleared, and 0 otherwise.
++ */
++static int keysym2numlock(void *kbd_layout, int keysym)
++{
++    kbd_layout_t *k = kbd_layout;
++    if (keysym < MAX_NORMAL_KEYCODE) {
++      return k->keysym2numlock[keysym];
++    } else {
++      int i;
++#ifdef XK_ISO_Left_Tab
++      if (keysym == XK_ISO_Left_Tab)
++          keysym = XK_Tab;
++#endif
++      for (i = 0; i < k->extra_count; i++)
++          if (k->keysym2keycode_extra[i].keysym == keysym)
++              return k->keysym2keycode_extra[i].numlock;
++    }
++    return 0;
++}
+Index: ioemu/vnc.c
+===================================================================
+--- ioemu.orig/vnc.c   2006-12-08 18:18:26.000000000 +0000
++++ ioemu/vnc.c        2006-12-08 18:19:43.000000000 +0000
+@@ -115,6 +115,7 @@
+ 
+     int ctl_keys;               /* Ctrl+Alt starts calibration */
+     int shift_keys;             /* Shift / CapsLock keys */
++    int numlock;
+ };
+ 
+ #define DIRTY_PIXEL_BITS 64
+@@ -854,14 +855,40 @@
+     }
+ }
+ 
++static void press_key(VncState *vs, int keycode)
++{
++    kbd_put_keycode(keysym2scancode(vs->kbd_layout, keycode) & 0x7f);
++    kbd_put_keycode(keysym2scancode(vs->kbd_layout, keycode) | 0x80);
++}
++
+ static void do_key_event(VncState *vs, int down, uint32_t sym)
+ {
+     sym &= 0xFFFF;
+ 
+     if (is_graphic_console()) {
+       int keycode;
++      int numlock;
+ 
+       keycode = keysym2scancode(vs->kbd_layout, sym);
++      numlock = keysym2numlock(vs->kbd_layout, sym);
++
++        /* If the numlock state needs to change then simulate an additional
++           keypress before sending this one.  This will happen if the user
++           toggles numlock away from the VNC window.
++        */
++      if (numlock == 1) {
++          if (!vs->numlock) {
++              vs->numlock = 1;
++              press_key(vs, XK_Num_Lock);
++          }
++      }
++      else if (numlock == -1) {
++          if (vs->numlock) {
++              vs->numlock = 0;
++              press_key(vs, XK_Num_Lock);
++          }
++        }
++
+       if (keycode & 0x80)
+           kbd_put_keycode(0xe0);
+       if (down)
+@@ -932,6 +959,10 @@
+           vs->shift_keys ^= 2;
+           break;
+ 
++      case XK_Num_Lock:
++          vs->numlock = !vs->numlock;
++          break;
++
+       case XK_1 ... XK_9:
+           if ((vs->ctl_keys & 3) != 3)
+               break;
+@@ -1355,6 +1386,7 @@
+     vs->lsock = -1;
+     vs->csock = -1;
+     vs->depth = 4;
++    vs->numlock = 0;
+ 
+     vs->ds = ds;
+ 
+Index: ioemu/vnc_keysym.h
+===================================================================
+--- ioemu.orig/vnc_keysym.h    2006-12-08 18:17:01.000000000 +0000
++++ ioemu/vnc_keysym.h 2006-12-08 18:19:43.000000000 +0000
+@@ -231,6 +231,19 @@
+ {"Home", 0xff50},      /* XK_Home */
+ {"End", 0xff57},       /* XK_End */
+ {"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */
++{"KP_Home", 0xff95},
++{"KP_Left", 0xff96},
++{"KP_Up", 0xff97},
++{"KP_Right", 0xff98},
++{"KP_Down", 0xff99},
++{"KP_Prior", 0xff9a},
++{"KP_Page_Up", 0xff9a},
++{"KP_Next", 0xff9b},
++{"KP_Page_Down", 0xff9b},
++{"KP_End", 0xff9c},
++{"KP_Begin", 0xff9d},
++{"KP_Insert", 0xff9e},
++{"KP_Delete", 0xff9f},
+ {"F1", 0xffbe},        /* XK_F1 */
+ {"F2", 0xffbf},        /* XK_F2 */
+ {"F3", 0xffc0},        /* XK_F3 */
+@@ -258,6 +271,7 @@
+ {"KP_8", 0xffb8},      /* XK_KP_8 */
+ {"KP_9", 0xffb9},      /* XK_KP_9 */
+ {"KP_Add", 0xffab},    /* XK_KP_Add */
++{"KP_Separator", 0xffac},/* XK_KP_Separator */
+ {"KP_Decimal", 0xffae},  /* XK_KP_Decimal */
+ {"KP_Divide", 0xffaf},   /* XK_KP_Divide */
+ {"KP_Enter", 0xff8d},    /* XK_KP_Enter */
diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xen-mapcache
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/xen-mapcache  Sat Dec 09 14:34:53 2006 +0000
@@ -0,0 +1,300 @@
+# HG changeset patch
+# User kfraser@xxxxxxxxxxxxxxxxxxxxx
+# Node ID 67a06a9b7b1dca707e1cd3b08ae0a341d6e97b3d
+# Parent  3f0ca90351e268084fbdb733d70fc596cb46537d
+[HVM] qemu: Add guest address-space mapping cache.
+
+On IA32 host or IA32 PAE host, at present, generally, we can't create
+an HVM guest with more than 2G memory, because generally it's almost
+impossible for Qemu to find a large enough and consecutive virtual
+address space to map an HVM guest's whole physical address space.
+The attached patch fixes this issue using dynamic mapping based on
+little blocks of memory.
+
+Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx>
+Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
+Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
+
+diff -r 3f0ca90351e2 -r 67a06a9b7b1d tools/ioemu/target-i386-dm/cpu.h
+--- a/tools/ioemu/target-i386-dm/cpu.h Thu Dec 07 10:54:43 2006 +0000
++++ b/tools/ioemu/target-i386-dm/cpu.h Thu Dec 07 11:12:52 2006 +0000
+@@ -25,7 +25,8 @@
+ #ifdef TARGET_X86_64
+ #define TARGET_LONG_BITS 64
+ #else
+-#define TARGET_LONG_BITS 32
++/* #define TARGET_LONG_BITS 32 */
++#define TARGET_LONG_BITS 64 /* for Qemu map cache */
+ #endif
+ 
+ /* target supports implicit self modifying code */
+diff -r 3f0ca90351e2 -r 67a06a9b7b1d tools/ioemu/target-i386-dm/exec-dm.c
+--- a/tools/ioemu/target-i386-dm/exec-dm.c     Thu Dec 07 10:54:43 2006 +0000
++++ b/tools/ioemu/target-i386-dm/exec-dm.c     Thu Dec 07 11:12:52 2006 +0000
+@@ -36,6 +36,7 @@
+ 
+ #include "cpu.h"
+ #include "exec-all.h"
++#include "vl.h"
+ 
+ //#define DEBUG_TB_INVALIDATE
+ //#define DEBUG_FLUSH
+@@ -426,6 +427,12 @@ static inline int paddr_is_ram(target_ph
+ #endif
+ }
+ 
++#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
++
+ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
+                             int len, int is_write)
+ {
+@@ -438,7 +445,7 @@ void cpu_physical_memory_rw(target_phys_
+         l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK); 
+         if (l > len)
+             l = len;
+-      
++
+         io_index = iomem_index(addr);
+         if (is_write) {
+             if (io_index) {
+@@ -460,9 +467,10 @@ void cpu_physical_memory_rw(target_phys_
+                 }
+             } else if (paddr_is_ram(addr)) {
+                 /* 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);
++                sync_icache(ptr, l);
+ #endif 
+             }
+         } else {
+@@ -485,7 +493,8 @@ void cpu_physical_memory_rw(target_phys_
+                 }
+             } else if (paddr_is_ram(addr)) {
+                 /* 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); 
+diff -r 3f0ca90351e2 -r 67a06a9b7b1d tools/ioemu/vl.c
+--- a/tools/ioemu/vl.c Thu Dec 07 10:54:43 2006 +0000
++++ b/tools/ioemu/vl.c Thu Dec 07 11:12:52 2006 +0000
+@@ -5807,6 +5807,92 @@ int set_mm_mapping(int xc_handle, uint32
+ 
+     return 0;
+ }
++
++#if defined(__i386__) || defined(__x86_64__)
++static struct map_cache *mapcache_entry;
++static unsigned long nr_buckets;
++
++static int qemu_map_cache_init(unsigned long nr_pages)
++{
++    unsigned long max_pages = MAX_MCACHE_SIZE >> PAGE_SHIFT;
++    int i;
++
++    if (nr_pages < max_pages)
++        max_pages = nr_pages;
++
++    nr_buckets = (max_pages << PAGE_SHIFT) >> MCACHE_BUCKET_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) {
++        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;
++}
++
++uint8_t *qemu_map_cache(target_phys_addr_t phys_addr)
++{
++    struct map_cache *entry;
++    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);
++            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;
++}
++#endif
+ 
+ int main(int argc, char **argv)
+ {
+@@ -6130,6 +6216,7 @@ int main(int argc, char **argv)
+                 break;
+             case QEMU_OPTION_m:
+                 ram_size = atol(optarg) * 1024 * 1024;
++                ram_size = (uint64_t)atol(optarg) * 1024 * 1024;
+                 if (ram_size <= 0)
+                     help();
+ #ifndef CONFIG_DM
+@@ -6400,50 +6487,41 @@ int main(int argc, char **argv)
+         shared_page_nr = nr_pages - 1;
+ #endif
+ 
++#if defined(__i386__) || defined(__x86_64__)
++
++    if ( qemu_map_cache_init(tmp_nr_pages) )
++    {
++        fprintf(logfile, "qemu_map_cache_init returned: error %d\n", errno);
++        exit(-1);
++    }
++
++    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
++                                       PROT_READ|PROT_WRITE, shared_page_nr);
++    if (shared_page == NULL) {
++        fprintf(logfile, "map shared IO page returned error %d\n", errno);
++        exit(-1);
++    }
++
++    fprintf(logfile, "shared page at pfn:%lx\n", shared_page_nr);
++
++    buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
++                                            PROT_READ|PROT_WRITE,
++                                            shared_page_nr - 2);
++    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\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);
+     }
+ 
+-#if defined(__i386__) || defined(__x86_64__)
+-    for ( i = 0; i < tmp_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);
+-    if (phys_ram_base == NULL) {
+-        fprintf(logfile, "batch map guest memory returned error %d\n", errno);
+-        exit(-1);
+-    }
+-
+-    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+-                                       PROT_READ|PROT_WRITE,
+-                                       page_array[shared_page_nr]);
+-    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]));
+-
+-    buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+-                                            PROT_READ|PROT_WRITE,
+-                                            page_array[shared_page_nr - 2]);
+-    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__)
+-  
+     if (xc_ia64_get_pfn_list(xc_handle, domid, page_array,
+                              IO_PAGE_START >> PAGE_SHIFT, 3) != 3) {
+         fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
+diff -r 3f0ca90351e2 -r 67a06a9b7b1d tools/ioemu/vl.h
+--- a/tools/ioemu/vl.h Thu Dec 07 10:54:43 2006 +0000
++++ b/tools/ioemu/vl.h Thu Dec 07 11:12:52 2006 +0000
+@@ -156,6 +156,26 @@ extern void *shared_vram;
+ 
+ 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;
++};
++
++uint8_t *qemu_map_cache(target_phys_addr_t phys_addr);
++#endif
++
+ extern int xc_handle;
+ extern int domid;
+ 
diff -r 1cfd862e5254 -r 8cddaee4a51c 
tools/ioemu/patches/xenstore-device-info-functions
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/xenstore-device-info-functions        Sat Dec 09 
14:34:53 2006 +0000
@@ -0,0 +1,190 @@
+# HG changeset patch
+# User kaf24@xxxxxxxxxxxxxxxxxxxxx
+# Node ID bbcac2aea0e8196cd75a3bf6dbe57bebf8c1e5b2
+# Parent  dc973fe5633386547ce5bc8fd4cf5f2bb5b55174
+[QEMU] Helper functions to interface with the xenstore and read device 
information from it.
+
+ - detect what types of devices a domain has or whether a domain has a
+   device of a certain type
+ - read the content of a variable related to a device, i.e.,
+   hotplug-status
+ - subscribe to changes of the hotplug status of a device for not
+   having to poll the status
+
+Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
+
+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 @@
+ 
+     return rc;
+ }
++
++
++/*
++ * get all device instances of a certain type
++ */
++char **xenstore_domain_get_devices(struct xs_handle *handle,
++                                   const char *devtype, unsigned int *num)
++{
++    char *path;
++    char *buf = NULL;
++    char **e  = NULL;
++
++    path = xs_get_domain_path(handle, domid);
++    if (path == NULL)
++        goto out;
++
++    if (pasprintf(&buf, "%s/device/%s", path,devtype) == -1)
++      goto out;
++
++    e = xs_directory(handle, XBT_NULL, buf, num);
++
++ out:
++    free(path);
++    free(buf);
++    return e;
++}
++
++/*
++ * Check whether a domain has devices of the given type
++ */
++int xenstore_domain_has_devtype(struct xs_handle *handle, const char *devtype)
++{
++    int rc = 0;
++    unsigned int num;
++    char **e = xenstore_domain_get_devices(handle, devtype, &num);
++    if (e)
++        rc = 1;
++    free(e);
++    return rc;
++}
++
++/*
++ * Function that creates a path to a variable of an instance of a
++ * certain device
++ */
++static char *get_device_variable_path(const char *devtype, const char *inst,
++                                      const char *var)
++{
++    char *buf = NULL;
++    if (pasprintf(&buf, "/local/domain/0/backend/%s/%d/%s/%s",
++                  devtype,
++                  domid,
++                  inst,
++                  var) == -1) {
++        free(buf);
++        buf = NULL;
++    }
++    return buf;
++}
++
++char *xenstore_backend_read_variable(struct xs_handle *handle,
++                                     const char *devtype, const char *inst,
++                                     const char *var)
++{
++    char *value = NULL;
++    char *buf = NULL;
++    unsigned int len;
++
++    buf = get_device_variable_path(devtype, inst, var);
++    if (NULL == buf)
++      goto out;
++
++    value = xs_read(handle, XBT_NULL, buf, &len);
++
++    free(buf);
++
++out:
++    return value;
++}
++
++/*
++  Read the hotplug status variable from the backend given the type
++  of device and its instance.
++*/
++char *xenstore_read_hotplug_status(struct xs_handle *handle,
++                                   const char *devtype, const char *inst)
++{
++    return xenstore_backend_read_variable(handle, devtype, inst,
++                                          "hotplug-status");
++}
++
++/*
++   Subscribe to the hotplug status of a device given the type of device and
++   its instance.
++   In case an error occurrs, a negative number is returned.
++ */
++int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
++                                         const char *devtype,
++                                         const char *inst,
++                                         const char *token)
++{
++    int rc = 0;
++    char *path = get_device_variable_path(devtype, inst, "hotplug-status");
++
++    if (path == NULL)
++        return -1;
++
++    if (0 == xs_watch(handle, path, token))
++        rc = -2;
++
++    free(path);
++
++    return rc;
++}
++
++/*
++ * Unsubscribe from a subscription to the status of a hotplug variable of
++ * a device.
++ */
++int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
++                                             const char *devtype,
++                                             const char *inst,
++                                             const char *token)
++{
++    int rc = 0;
++    char *path;
++    path = get_device_variable_path(devtype, inst, "hotplug-status");
++    if (path == NULL)
++        return -1;
++
++    if (0 == xs_unwatch(handle, path, token))
++        rc = -2;
++
++    free(path);
++
++    return rc;
++}
+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 @@
+ void xenstore_write_vncport(int vnc_display);
+ int xenstore_read_vncpasswd(int domid);
+ 
++int xenstore_domain_has_devtype(struct xs_handle *handle,
++                                const char *devtype);
++char **xenstore_domain_get_devices(struct xs_handle *handle,
++                                   const char *devtype, unsigned int *num);
++char *xenstore_read_hotplug_status(struct xs_handle *handle,
++                                   const char *devtype, const char *inst);
++char *xenstore_backend_read_variable(struct xs_handle *,
++                                     const char *devtype, const char *inst,
++                                     const char *var);
++int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
++                                         const char *devtype,
++                                         const char *inst,
++                                         const char *token);
++int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
++                                             const char *devtype,
++                                             const char *inst,
++                                             const char *token);
++
++
+ /* xen_platform.c */
+ void pci_xen_platform_init(PCIBus *bus);
+ 

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


 


Rackspace

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