WARNING - OLD ARCHIVES

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

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 09 Dec 2006 15:45:27 +0000
Delivery-date: Sat, 09 Dec 2006 07:48:55 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User 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

<Prev in Thread] Current Thread [Next in Thread>