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] merge

# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID c4ac21dc3f16d7be84d480f8795e1902da99c230
# Parent  ede16886f979dde3991f2a13c7eef71820a60cca
# Parent  e8fb817c4c1530b9f763b8a726aa00d805173a56
merge

diff -r ede16886f979 -r c4ac21dc3f16 .hgignore
--- a/.hgignore Mon Mar  6 16:09:18 2006
+++ b/.hgignore Mon Mar  6 17:21:35 2006
@@ -166,6 +166,7 @@
 ^tools/xenstore/xenstore-read$
 ^tools/xenstore/xenstore-rm$
 ^tools/xenstore/xenstore-write$
+^tools/xenstore/xenstore-control$
 ^tools/xenstore/xenstore-ls$
 ^tools/xenstore/xenstored$
 ^tools/xenstore/xenstored_test$
diff -r ede16886f979 -r c4ac21dc3f16 docs/src/interface.tex
--- a/docs/src/interface.tex    Mon Mar  6 16:09:18 2006
+++ b/docs/src/interface.tex    Mon Mar  6 17:21:35 2006
@@ -1059,6 +1059,21 @@
       \item[domain] the name of the frontend
       \end{description}
     \end{description}
+
+  \item[vtpm/] a directory containin vtpm backends
+    \begin{description}
+    \item[$<$domid$>$/] a directory containing vtpm's for domid
+      \begin{description}
+      \item[$<$vtpm number$>$/] a directory for each vtpm
+      \item[frontend-id] the domain id of the frontend
+      \item[frontend] the path to the frontend
+      \item[instance] the instance of the virtual TPM that is used
+      \item[pref{\textunderscore}instance] the instance number as given in the 
VM configuration file;
+           may be different from {\bf instance}
+      \item[domain] the name of the domain of the frontend
+      \end{description}
+    \end{description}
+
   \end{description}
 
   \item[device/] a directory containing the frontend devices for the
@@ -1094,6 +1109,18 @@
          \item[event-channel] the event channel used for the two ring queues 
          \end{description}
        \end{description}
+
+      \item[vtpm/] a directory containing the vtpm frontend device for the
+        domain
+        \begin{description}
+        \item[$<$id$>$] a directory for vtpm id frontend device for the domain
+          \begin{description}
+         \item[backend-id] the backend domain id
+          \item[backend] a path to the backend's store entry
+          \item[ring-ref] the grant table reference for the tx/rx ring
+          \item[event-channel] the event channel used for the ring
+          \end{description}
+        \end{description}
        
       \item[device-misc/] miscellanous information for devices 
        \begin{description}
@@ -1450,6 +1477,76 @@
   value of {\tt first\_sect}.
 \end{description}
 
+\section{Virtual TPM}
+
+Virtual TPM (VTPM) support provides TPM functionality to each virtual
+machine that requests this functionality in its configuration file.
+The interface enables domains to access therr own private TPM like it
+was a hardware TPM built into the machine.
+
+The virtual TPM interface is implemented as a split driver,
+similar to the network and block interfaces described above.
+The user domain hosting the frontend exports a character device /dev/tpm0
+to user-level applications for communicating with the virtual TPM.
+This is the same device interface that is also offered if a hardware TPM
+is available in the system. The backend provides a single interface
+/dev/vtpm where the virtual TPM is waiting for commands from all domains
+that have located their backend in a given domain.
+
+\subsection{Data Transfer}
+
+A single shared memory ring is used between the frontend and backend
+drivers. TPM requests and responses are sent in pages where a pointer
+to those pages and other information is placed into the ring such that
+the backend can map the pages into its memory space using the grant
+table mechanism.
+
+The backend driver has been implemented to only accept well-formed
+TPM requests. To meet this requirement, the length inidicator in the
+TPM request must correctly indicate the length of the request.
+Otherwise an error message is automatically sent back by the device driver.
+
+The virtual TPM implementation listenes for TPM request on /dev/vtpm. Since
+it must be able to apply the TPM request packet to the virtual TPM instance
+associated with the virtual machine, a 4-byte virtual TPM instance
+identifier is prepended to each packet by the backend driver (in network
+byte order) for internal routing of the request.
+
+\subsection{Virtual TPM ring interface}
+
+The TPM protocol is a strict request/response protocol and therefore
+only one ring is used to send requests from the frontend to the backend
+and responses on the reverse path.
+
+The request/response structure is defined as follows:
+
+\scriptsize
+\begin{verbatim}
+typedef struct {
+    unsigned long addr;     /* Machine address of packet.     */
+    grant_ref_t ref;        /* grant table access reference.  */
+    uint16_t unused;        /* unused                         */
+    uint16_t size;          /* Packet size in bytes.          */
+} tpmif_tx_request_t;
+\end{verbatim}
+\normalsize
+
+The fields are as follows:
+
+\begin{description}
+\item[addr] The machine address of the page asscoiated with the TPM
+            request/response; a request/response may span multiple
+            pages
+\item[ref]  The grant table reference associated with the address.
+\item[size] The size of the remaining packet; up to
+            PAGE{\textunderscore}SIZE bytes can be found in the
+            page referenced by 'addr'
+\end{description}
+
+The frontend initially allocates several pages whose addresses
+are stored in the ring. Only these pages are used for exchange of
+requests and responses.
+
 
 \chapter{Further Information}
 
diff -r ede16886f979 -r c4ac21dc3f16 install.sh
--- a/install.sh        Mon Mar  6 16:09:18 2006
+++ b/install.sh        Mon Mar  6 17:21:35 2006
@@ -22,19 +22,29 @@
   exit 1
 fi
 
+tmp="`mktemp -d`"
+
 echo "Installing Xen from '$src' to '$dst'..."
-(cd $src; tar -cf - --exclude etc/init.d --exclude etc/hotplug --exclude 
etc/udev * ) | tar -C $dst -xf -
-cp -fdRL $src/etc/init.d/* $dst/etc/init.d/
-echo "All done."
+(cd $src; tar -cf - * ) | tar -C "$tmp" -xf -
 
 [ -x "$(which udevinfo)" ] && \
   UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]* 
\([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
 
 if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -ge 059 ]; then
-  cp -f $src/etc/udev/rules.d/*.rules $dst/etc/udev/rules.d/
+  echo " - installing for udev-based system"
+  rm -rf "$tmp/etc/hotplug"
 else
-  cp -f $src/etc/hotplug/*.agent $dst/etc/hotplug/
+  echo " - installing for hotplug-based system"
+  rm -rf "$tmp/etc/udev"
 fi
+
+echo " - modifying permissions"
+chmod -R a+rX "$tmp"
+
+(cd $tmp; tar -cf - *) | tar --no-same-owner -C "$dst" -xf -
+rm -rf "$tmp"
+
+echo "All done."
 
 echo "Checking to see whether prerequisite tools are installed..."
 cd $src/../check
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c       Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c       Mon Mar  6 
17:21:35 2006
@@ -61,8 +61,8 @@
        int ret;
 
        op.cmd = PHYSDEVOP_APIC_READ;
-       op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
-       op.u.apic_op.offset = reg;
+       op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+       op.u.apic_op.reg = reg;
        ret = HYPERVISOR_physdev_op(&op);
        if (ret)
                return ret;
@@ -74,8 +74,8 @@
        physdev_op_t op;
 
        op.cmd = PHYSDEVOP_APIC_WRITE;
-       op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
-       op.u.apic_op.offset = reg;
+       op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+       op.u.apic_op.reg = reg;
        op.u.apic_op.value = value;
        HYPERVISOR_physdev_op(&op);
 }
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c     Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c     Mon Mar  6 
17:21:35 2006
@@ -108,8 +108,8 @@
        int ret;
 
        op.cmd = PHYSDEVOP_APIC_READ;
-       op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
-       op.u.apic_op.offset = reg;
+       op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+       op.u.apic_op.reg = reg;
        ret = HYPERVISOR_physdev_op(&op);
        if (ret)
                return ret;
@@ -121,8 +121,8 @@
        physdev_op_t op;
 
        op.cmd = PHYSDEVOP_APIC_WRITE;
-       op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
-       op.u.apic_op.offset = reg;
+       op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+       op.u.apic_op.reg = reg;
        op.u.apic_op.value = value;
        HYPERVISOR_physdev_op(&op);
 }
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Mon Mar  6 
17:21:35 2006
@@ -82,6 +82,8 @@
 extern unsigned long start_pfn;
 extern struct edid_info edid_info;
 
+extern void machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c);
+
 shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
 EXPORT_SYMBOL(HYPERVISOR_shared_info);
 
@@ -1405,6 +1407,8 @@
        select_idle_routine(c);
        detect_ht(c); 
 
+       machine_specific_modify_cpu_capabilities(c);
+
        /*
         * On SMP, boot_cpu_data holds the common feature set between
         * all CPUs; so make sure that we indicate which features are
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/arch/x86_64/kernel/x8664_ksyms-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/x8664_ksyms-xen.c Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/x8664_ksyms-xen.c Mon Mar  6 
17:21:35 2006
@@ -32,8 +32,6 @@
 #include <asm/tlbflush.h>
 #include <asm/kdebug.h>
 
-extern spinlock_t rtc_lock;
-
 #ifdef CONFIG_SMP
 extern void __write_lock_failed(rwlock_t *rw);
 extern void __read_lock_failed(rwlock_t *rw);
@@ -42,9 +40,6 @@
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
 //EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(__ioremap);
-EXPORT_SYMBOL(ioremap_nocache);
-EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(pm_idle);
 EXPORT_SYMBOL(pm_power_off);
@@ -101,8 +96,6 @@
 #endif
 
 EXPORT_SYMBOL(get_wchan);
-
-EXPORT_SYMBOL(rtc_lock);
 
 #ifdef CONFIG_X86_LOCAL_APIC
 EXPORT_SYMBOL_GPL(set_nmi_callback);
@@ -166,7 +159,5 @@
 EXPORT_SYMBOL(flush_tlb_page);
 #endif
 
-EXPORT_SYMBOL(cpu_khz);
-
 EXPORT_SYMBOL(load_gs_index);
 
diff -r ede16886f979 -r c4ac21dc3f16 linux-2.6-xen-sparse/drivers/xen/char/mem.c
--- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c       Mon Mar  6 16:09:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c       Mon Mar  6 17:21:35 2006
@@ -43,49 +43,85 @@
 static ssize_t read_mem(struct file * file, char __user * buf,
                        size_t count, loff_t *ppos)
 {
-       unsigned long i, p = *ppos;
-       ssize_t read = -EFAULT;
+       unsigned long p = *ppos, ignored;
+       ssize_t read = 0, sz;
        void __iomem *v;
 
-       if ((v = ioremap(p, count)) == NULL) {
+       while (count > 0) {
                /*
-                * Some programs (e.g., dmidecode) groove off into weird RAM
-                * areas where no table scan possibly exist (because Xen will
-                * have stomped on them!). These programs get rather upset if
-                 * we let them know that Xen failed their access, so we fake
-                 * out a read of all zeroes. :-)
+                * Handle first page in case it's not aligned
                 */
-               for (i = 0; i < count; i++)
-                       if (put_user(0, buf+i))
+               if (-p & (PAGE_SIZE - 1))
+                       sz = -p & (PAGE_SIZE - 1);
+               else
+                       sz = PAGE_SIZE;
+
+               sz = min_t(unsigned long, sz, count);
+
+               if ((v = ioremap(p, sz)) == NULL) {
+                       /*
+                        * Some programs (e.g., dmidecode) groove off into 
weird RAM
+                        * areas where no tables can possibly exist (because 
Xen will
+                        * have stomped on them!). These programs get rather 
upset if
+                        * we let them know that Xen failed their access, so we 
fake
+                        * out a read of all zeroes. :-)
+                        */
+                       if (clear_user(buf, count))
                                return -EFAULT;
-               return count;
+                       read += count;
+                       break;
+               }
+
+               ignored = copy_to_user(buf, v, sz);
+               iounmap(v);
+               if (ignored)
+                       return -EFAULT;
+               buf += sz;
+               p += sz;
+               count -= sz;
+               read += sz;
        }
-       if (copy_to_user(buf, v, count))
-               goto out;
 
-       read = count;
        *ppos += read;
-out:
-       iounmap(v);
        return read;
 }
 
 static ssize_t write_mem(struct file * file, const char __user * buf, 
                         size_t count, loff_t *ppos)
 {
-       unsigned long p = *ppos;
-       ssize_t written = -EFAULT;
+       unsigned long p = *ppos, ignored;
+       ssize_t written = 0, sz;
        void __iomem *v;
 
-       if ((v = ioremap(p, count)) == NULL)
-               return -EFAULT;
-       if (copy_from_user(v, buf, count))
-               goto out;
+       while (count > 0) {
+               /*
+                * Handle first page in case it's not aligned
+                */
+               if (-p & (PAGE_SIZE - 1))
+                       sz = -p & (PAGE_SIZE - 1);
+               else
+                       sz = PAGE_SIZE;
 
-       written = count;
+               sz = min_t(unsigned long, sz, count);
+
+               if ((v = ioremap(p, sz)) == NULL)
+                       break;
+
+               ignored = copy_from_user(v, buf, sz);
+               iounmap(v);
+               if (ignored) {
+                       written += sz - ignored;
+                       if (written)
+                               break;
+                       return -EFAULT;
+               }
+               buf += sz;
+               p += sz;
+               count -= sz;
+               written += sz;
+       }
+
        *ppos += written;
-out:
-       iounmap(v);
        return written;
 }
 
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Mon Mar  6 16:09:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Mon Mar  6 17:21:35 2006
@@ -35,7 +35,6 @@
 #include <xen/interface/xen.h>
 #include <asm/fixmap.h>
 #include <asm/uaccess.h>
-#include <xen/public/privcmd.h>
 #include <xen/gnttab.h>
 #include <asm/synch_bitops.h>
 
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Mon Mar  6 
17:21:35 2006
@@ -19,8 +19,7 @@
 
 LIST_HEAD(tpmif_list);
 
-tpmif_t *
-alloc_tpmif(domid_t domid, long int instance)
+static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
 {
        struct page *page;
        tpmif_t *tpmif;
@@ -45,16 +44,14 @@
        return tpmif;
 }
 
-void
-free_tpmif(tpmif_t * tpmif)
+static void free_tpmif(tpmif_t * tpmif)
 {
        num_frontends--;
        list_del(&tpmif->tpmif_list);
        kmem_cache_free(tpmif_cachep, tpmif);
 }
 
-tpmif_t *
-tpmif_find(domid_t domid, long int instance)
+tpmif_t *tpmif_find(domid_t domid, long int instance)
 {
        tpmif_t *tpmif;
 
@@ -72,8 +69,7 @@
        return alloc_tpmif(domid, instance);
 }
 
-static int
-map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
+static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
 {
        int ret;
        struct gnttab_map_grant_ref op = {
@@ -99,8 +95,7 @@
        return 0;
 }
 
-static void
-unmap_frontend_page(tpmif_t *tpmif)
+static void unmap_frontend_page(tpmif_t *tpmif)
 {
        struct gnttab_unmap_grant_ref op;
        int ret;
@@ -115,14 +110,14 @@
        BUG_ON(ret);
 }
 
-int
-tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
+int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
 {
        int err;
        evtchn_op_t op = {
                .cmd = EVTCHNOP_bind_interdomain,
                .u.bind_interdomain.remote_dom = tpmif->domid,
-               .u.bind_interdomain.remote_port = evtchn };
+               .u.bind_interdomain.remote_port = evtchn,
+        };
 
         if (tpmif->irq) {
                 return 0;
@@ -156,8 +151,7 @@
        return 0;
 }
 
-static void
-__tpmif_disconnect_complete(void *arg)
+static void __tpmif_disconnect_complete(void *arg)
 {
        tpmif_t *tpmif = (tpmif_t *) arg;
 
@@ -172,22 +166,19 @@
        free_tpmif(tpmif);
 }
 
-void
-tpmif_disconnect_complete(tpmif_t * tpmif)
+void tpmif_disconnect_complete(tpmif_t * tpmif)
 {
        INIT_WORK(&tpmif->work, __tpmif_disconnect_complete, (void *)tpmif);
        schedule_work(&tpmif->work);
 }
 
-void __init
-tpmif_interface_init(void)
+void __init tpmif_interface_init(void)
 {
        tpmif_cachep = kmem_cache_create("tpmif_cache", sizeof (tpmif_t),
                                         0, 0, NULL, NULL);
 }
 
-void __init
-tpmif_interface_exit(void)
+void __init tpmif_interface_exit(void)
 {
        kmem_cache_destroy(tpmif_cachep);
 }
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Mon Mar  6 
17:21:35 2006
@@ -22,16 +22,22 @@
 #include <xen/xenbus.h>
 #include <xen/interface/grant_table.h>
 
-
 /* local data structures */
 struct data_exchange {
        struct list_head pending_pak;
        struct list_head current_pak;
        unsigned int copied_so_far;
        u8 has_opener;
-       rwlock_t pak_lock;  // protects all of the previous fields
+       rwlock_t pak_lock;      // protects all of the previous fields
        wait_queue_head_t wait_queue;
 };
+
+struct vtpm_resp_hdr {
+       uint32_t instance_no;
+       uint16_t tag_no;
+       uint32_t len_no;
+       uint32_t ordinal_no;
+} __attribute__ ((packed));
 
 struct packet {
        struct list_head next;
@@ -50,36 +56,30 @@
        PACKET_FLAG_CHECK_RESPONSESTATUS = 2,
 };
 
+/* local variables */
 static struct data_exchange dataex;
 
 /* local function prototypes */
+static int _packet_write(struct packet *pak,
+                        const char *data, size_t size, int userbuffer);
+static void processing_timeout(unsigned long ptr);
+static int packet_read_shmem(struct packet *pak,
+                            tpmif_t * tpmif,
+                            u32 offset,
+                            char *buffer, int isuserbuffer, u32 left);
 static int vtpm_queue_packet(struct packet *pak);
-static int _packet_write(struct packet *pak,
-                         const char *data, size_t size,
-                         int userbuffer);
-static void processing_timeout(unsigned long ptr);
-static int  packet_read_shmem(struct packet *pak,
-                              tpmif_t *tpmif,
-                              u32 offset,
-                              char *buffer,
-                              int isuserbuffer,
-                              u32 left);
-
 
 #define MIN(x,y)  (x) < (y) ? (x) : (y)
 
-
 /***************************************************************
- Buffer copying
+ Buffer copying fo user and kernel space buffes.
 ***************************************************************/
-static inline int
-copy_from_buffer(void *to,
-                 const void *from,
-                 unsigned long size,
-                 int userbuffer)
-{
-       if (userbuffer) {
-               if (copy_from_user(to, from, size))
+static inline int copy_from_buffer(void *to,
+                                  const void *from, unsigned long size,
+                                  int isuserbuffer)
+{
+       if (isuserbuffer) {
+               if (copy_from_user(to, (void __user *)from, size))
                        return -EFAULT;
        } else {
                memcpy(to, from, size);
@@ -87,21 +87,36 @@
        return 0;
 }
 
+static inline int copy_to_buffer(void *to,
+                                const void *from, unsigned long size,
+                                int isuserbuffer)
+{
+       if (isuserbuffer) {
+               if (copy_to_user((void __user *)to, from, size))
+                       return -EFAULT;
+       } else {
+               memcpy(to, from, size);
+       }
+       return 0;
+}
+
 /***************************************************************
  Packet-related functions
 ***************************************************************/
 
-static struct packet *
-packet_find_instance(struct list_head *head, u32 tpm_instance)
+static struct packet *packet_find_instance(struct list_head *head,
+                                          u32 tpm_instance)
 {
        struct packet *pak;
        struct list_head *p;
+
        /*
         * traverse the list of packets and return the first
         * one with the given instance number
         */
        list_for_each(p, head) {
                pak = list_entry(p, struct packet, next);
+
                if (pak->tpm_instance == tpm_instance) {
                        return pak;
                }
@@ -109,17 +124,18 @@
        return NULL;
 }
 
-static struct packet *
-packet_find_packet(struct list_head *head, void *packet)
+static struct packet *packet_find_packet(struct list_head *head, void *packet)
 {
        struct packet *pak;
        struct list_head *p;
+
        /*
         * traverse the list of packets and return the first
         * one with the given instance number
         */
        list_for_each(p, head) {
                pak = list_entry(p, struct packet, next);
+
                if (pak == packet) {
                        return pak;
                }
@@ -127,22 +143,20 @@
        return NULL;
 }
 
-static struct packet *
-packet_alloc(tpmif_t *tpmif, u32 size, u8 req_tag, u8 flags)
+static struct packet *packet_alloc(tpmif_t * tpmif,
+                                  u32 size, u8 req_tag, u8 flags)
 {
        struct packet *pak = NULL;
-       pak = kmalloc(sizeof(struct packet),
-                      GFP_KERNEL);
+       pak = kzalloc(sizeof (struct packet), GFP_KERNEL);
        if (NULL != pak) {
-               memset(pak, 0x0, sizeof(*pak));
                if (tpmif) {
                        pak->tpmif = tpmif;
                        pak->tpm_instance = tpmif->tpm_instance;
                }
-               pak->data_len  = size;
-               pak->req_tag   = req_tag;
+               pak->data_len = size;
+               pak->req_tag = req_tag;
                pak->last_read = 0;
-               pak->flags     = flags;
+               pak->flags = flags;
 
                /*
                 * cannot do tpmif_get(tpmif); bad things happen
@@ -155,16 +169,16 @@
        return pak;
 }
 
-static void inline
-packet_reset(struct packet *pak)
+static void inline packet_reset(struct packet *pak)
 {
        pak->last_read = 0;
 }
 
-static void inline
-packet_free(struct packet *pak)
-{
-       del_singleshot_timer_sync(&pak->processing_timer);
+static void packet_free(struct packet *pak)
+{
+       if (timer_pending(&pak->processing_timer)) {
+               BUG();
+       }
        kfree(pak->data_buffer);
        /*
         * cannot do tpmif_put(pak->tpmif); bad things happen
@@ -173,13 +187,13 @@
        kfree(pak);
 }
 
-static int
-packet_set(struct packet *pak,
-           const unsigned char *buffer, u32 size)
+static int packet_set(struct packet *pak,
+                     const unsigned char *buffer, u32 size)
 {
        int rc = 0;
        unsigned char *buf = kmalloc(size, GFP_KERNEL);
-       if (NULL != buf) {
+
+       if (buf) {
                pak->data_buffer = buf;
                memcpy(buf, buffer, size);
                pak->data_len = size;
@@ -189,27 +203,21 @@
        return rc;
 }
 
-
 /*
  * Write data to the shared memory and send it to the FE.
  */
-static int
-packet_write(struct packet *pak,
-             const char *data, size_t size,
-             int userbuffer)
+static int packet_write(struct packet *pak,
+                       const char *data, size_t size, int isuserbuffer)
 {
        int rc = 0;
 
-       DPRINTK("Supposed to send %d bytes to front-end!\n",
-               size);
-
-       if (0 != (pak->flags & PACKET_FLAG_CHECK_RESPONSESTATUS)) {
+       if ((pak->flags & PACKET_FLAG_CHECK_RESPONSESTATUS)) {
 #ifdef CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
                u32 res;
+
                if (copy_from_buffer(&res,
-                                    &data[2+4],
-                                    sizeof(res),
-                                    userbuffer)) {
+                                    &data[2 + 4], sizeof (res),
+                                    isuserbuffer)) {
                        return -EFAULT;
                }
 
@@ -230,17 +238,14 @@
                /* Don't send a respone to this packet. Just acknowledge it. */
                rc = size;
        } else {
-               rc = _packet_write(pak, data, size, userbuffer);
+               rc = _packet_write(pak, data, size, isuserbuffer);
        }
 
        return rc;
 }
 
-
-static int
-_packet_write(struct packet *pak,
-              const char *data, size_t size,
-              int userbuffer)
+int _packet_write(struct packet *pak,
+                 const char *data, size_t size, int isuserbuffer)
 {
        /*
         * Write into the shared memory pages directly
@@ -254,7 +259,7 @@
 
        if (tpmif == NULL) {
                return -EFAULT;
-        }
+       }
 
        if (tpmif->status == DISCONNECTED) {
                return size;
@@ -273,16 +278,13 @@
                        return 0;
                }
 
-               map_op.host_addr  = MMAP_VADDR(tpmif, i);
-               map_op.flags      = GNTMAP_host_map;
-               map_op.ref        = tx->ref;
-               map_op.dom        = tpmif->domid;
-
-               if(unlikely(
-                   HYPERVISOR_grant_table_op(
-                       GNTTABOP_map_grant_ref,
-                       &map_op,
-                       1))) {
+               map_op.host_addr = MMAP_VADDR(tpmif, i);
+               map_op.flags = GNTMAP_host_map;
+               map_op.ref = tx->ref;
+               map_op.dom = tpmif->domid;
+
+               if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
+                                                      &map_op, 1))) {
                        BUG();
                }
 
@@ -292,28 +294,27 @@
                        DPRINTK(" Grant table operation failure !\n");
                        return 0;
                }
-               set_phys_to_machine(__pa(MMAP_VADDR(tpmif,i)) >> PAGE_SHIFT,
-                       FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT));
+               set_phys_to_machine(__pa(MMAP_VADDR(tpmif, i)) >> PAGE_SHIFT,
+                                   FOREIGN_FRAME(map_op.
+                                                 dev_bus_addr >> PAGE_SHIFT));
 
                tocopy = MIN(size - offset, PAGE_SIZE);
 
-               if (copy_from_buffer((void *)(MMAP_VADDR(tpmif,i)|
-                                    (tx->addr & ~PAGE_MASK)),
-                                    &data[offset],
-                                    tocopy,
-                                    userbuffer)) {
+               if (copy_from_buffer((void *)(MMAP_VADDR(tpmif, i) |
+                                             (tx->addr & ~PAGE_MASK)),
+                                    &data[offset], tocopy, isuserbuffer)) {
                        tpmif_put(tpmif);
                        return -EFAULT;
                }
                tx->size = tocopy;
 
-               unmap_op.host_addr    = MMAP_VADDR(tpmif, i);
-               unmap_op.handle       = handle;
+               unmap_op.host_addr = MMAP_VADDR(tpmif, i);
+               unmap_op.handle = handle;
                unmap_op.dev_bus_addr = 0;
 
-               if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
-                                                     &unmap_op,
-                                                     1))) {
+               if (unlikely
+                   (HYPERVISOR_grant_table_op
+                    (GNTTABOP_unmap_grant_ref, &unmap_op, 1))) {
                        BUG();
                }
 
@@ -322,8 +323,7 @@
        }
 
        rc = offset;
-       DPRINTK("Notifying frontend via irq %d\n",
-               tpmif->irq);
+       DPRINTK("Notifying frontend via irq %d\n", tpmif->irq);
        notify_remote_via_irq(tpmif->irq);
 
        return rc;
@@ -334,26 +334,19 @@
  * provided buffer. Advance the read_last indicator which tells
  * how many bytes have already been read.
  */
-static int
-packet_read(struct packet *pak, size_t numbytes,
-            char *buffer, size_t buffersize,
-            int userbuffer)
+static int packet_read(struct packet *pak, size_t numbytes,
+                      char *buffer, size_t buffersize, int isuserbuffer)
 {
        tpmif_t *tpmif = pak->tpmif;
-       /*
-        * I am supposed to read 'numbytes' of data from the
-        * buffer.
-        * The first 4 bytes that are read are the instance number in
-        * network byte order, after that comes the data from the
-        * shared memory buffer.
+
+       /*
+        * Read 'numbytes' of data from the buffer. The first 4
+        * bytes are the instance number in network byte order,
+        * after that come the data from the shared memory buffer.
         */
        u32 to_copy;
        u32 offset = 0;
        u32 room_left = buffersize;
-       /*
-        * Ensure that we see the request when we copy it.
-        */
-       mb();
 
        if (pak->last_read < 4) {
                /*
@@ -361,18 +354,13 @@
                 */
                u32 instance_no = htonl(pak->tpm_instance);
                u32 last_read = pak->last_read;
+
                to_copy = MIN(4 - last_read, numbytes);
 
-               if (userbuffer) {
-                       if (copy_to_user(&buffer[0],
-                                        &(((u8 *)&instance_no)[last_read]),
-                                        to_copy)) {
-                               return -EFAULT;
-                       }
-               } else {
-                       memcpy(&buffer[0],
-                              &(((u8 *)&instance_no)[last_read]),
-                              to_copy);
+               if (copy_to_buffer(&buffer[0],
+                                  &(((u8 *) & instance_no)[last_read]),
+                                  to_copy, isuserbuffer)) {
+                       return -EFAULT;
                }
 
                pak->last_read += to_copy;
@@ -388,39 +376,30 @@
                if (pak->data_buffer) {
                        u32 to_copy = MIN(pak->data_len - offset, room_left);
                        u32 last_read = pak->last_read - 4;
-                       if (userbuffer) {
-                               if (copy_to_user(&buffer[offset],
-                                                &pak->data_buffer[last_read],
-                                                to_copy)) {
-                                       return -EFAULT;
-                               }
-                       } else {
-                               memcpy(&buffer[offset],
-                                      &pak->data_buffer[last_read],
-                                      to_copy);
+
+                       if (copy_to_buffer(&buffer[offset],
+                                          &pak->data_buffer[last_read],
+                                          to_copy, isuserbuffer)) {
+                               return -EFAULT;
                        }
                        pak->last_read += to_copy;
                        offset += to_copy;
                } else {
                        offset = packet_read_shmem(pak,
-                                                  tpmif,
-                                                  offset,
-                                                  buffer,
-                                                  userbuffer,
-                                                  room_left);
+                                                  tpmif,
+                                                  offset,
+                                                  buffer,
+                                                  isuserbuffer, room_left);
                }
        }
        return offset;
 }
 
-
-static int
-packet_read_shmem(struct packet *pak,
-                  tpmif_t *tpmif,
-                  u32 offset,
-                  char *buffer,
-                  int isuserbuffer,
-                  u32 room_left) {
+static int packet_read_shmem(struct packet *pak,
+                            tpmif_t * tpmif,
+                            u32 offset, char *buffer, int isuserbuffer,
+                            u32 room_left)
+{
        u32 last_read = pak->last_read - 4;
        u32 i = (last_read / PAGE_SIZE);
        u32 pg_offset = last_read & (PAGE_SIZE - 1);
@@ -428,6 +407,7 @@
        grant_handle_t handle;
 
        tpmif_tx_request_t *tx;
+
        tx = &tpmif->tx->ring[0].req;
        /*
         * Start copying data at the page with index 'index'
@@ -443,13 +423,12 @@
                tx = &tpmif->tx->ring[i].req;
 
                map_op.host_addr = MMAP_VADDR(tpmif, i);
-               map_op.flags     = GNTMAP_host_map;
-               map_op.ref       = tx->ref;
-               map_op.dom       = tpmif->domid;
-
-               if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
-                                                     &map_op,
-                                                     1))) {
+               map_op.flags = GNTMAP_host_map;
+               map_op.ref = tx->ref;
+               map_op.dom = tpmif->domid;
+
+               if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
+                                                      &map_op, 1))) {
                        BUG();
                }
 
@@ -462,41 +441,33 @@
 
                if (to_copy > tx->size) {
                        /*
-                        * This is the case when the user wants to read more
-                        * than what we have. So we just give him what we
-                        * have.
+                        * User requests more than what's available
                         */
                        to_copy = MIN(tx->size, to_copy);
                }
 
                DPRINTK("Copying from mapped memory at %08lx\n",
-                       (unsigned long)(MMAP_VADDR(tpmif,i) |
-                       (tx->addr & ~PAGE_MASK)));
-
-               src = (void *)(MMAP_VADDR(tpmif,i) | ((tx->addr & ~PAGE_MASK) + 
pg_offset));
-               if (isuserbuffer) {
-                       if (copy_to_user(&buffer[offset],
-                                        src,
-                                        to_copy)) {
-                               return -EFAULT;
-                       }
-               } else {
-                       memcpy(&buffer[offset],
-                              src,
-                              to_copy);
-               }
-
+                       (unsigned long)(MMAP_VADDR(tpmif, i) |
+                                       (tx->addr & ~PAGE_MASK)));
+
+               src = (void *)(MMAP_VADDR(tpmif, i) |
+                              ((tx->addr & ~PAGE_MASK) + pg_offset));
+               if (copy_to_buffer(&buffer[offset],
+                                  src, to_copy, isuserbuffer)) {
+                       return -EFAULT;
+               }
 
                DPRINTK("Data from TPM-FE of domain %d are %d %d %d %d\n",
-                       tpmif->domid, buffer[offset], 
buffer[offset+1],buffer[offset+2],buffer[offset+3]);
-
-               unmap_op.host_addr    = MMAP_VADDR(tpmif, i);
-               unmap_op.handle       = handle;
+                       tpmif->domid, buffer[offset], buffer[offset + 1],
+                       buffer[offset + 2], buffer[offset + 3]);
+
+               unmap_op.host_addr = MMAP_VADDR(tpmif, i);
+               unmap_op.handle = handle;
                unmap_op.dev_bus_addr = 0;
 
-               if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
-                                                     &unmap_op,
-                                                     1))) {
+               if (unlikely
+                   (HYPERVISOR_grant_table_op
+                    (GNTTABOP_unmap_grant_ref, &unmap_op, 1))) {
                        BUG();
                }
 
@@ -507,21 +478,19 @@
 
                to_copy = MIN(PAGE_SIZE, room_left);
                i++;
-       } /* while (to_copy > 0) */
+       }                       /* while (to_copy > 0) */
        /*
         * Adjust the last_read pointer
         */
        pak->last_read = last_read + 4;
        return offset;
 }
-
 
 /* ============================================================
  * The file layer for reading data from this device
  * ============================================================
  */
-static int
-vtpm_op_open(struct inode *inode, struct file *f)
+static int vtpm_op_open(struct inode *inode, struct file *f)
 {
        int rc = 0;
        unsigned long flags;
@@ -536,9 +505,8 @@
        return rc;
 }
 
-static ssize_t
-vtpm_op_read(struct file *file,
-            char __user * data, size_t size, loff_t * offset)
+static ssize_t vtpm_op_read(struct file *file,
+                           char __user * data, size_t size, loff_t * offset)
 {
        int ret_size = -ENODATA;
        struct packet *pak = NULL;
@@ -549,7 +517,7 @@
        if (list_empty(&dataex.pending_pak)) {
                write_unlock_irqrestore(&dataex.pak_lock, flags);
                wait_event_interruptible(dataex.wait_queue,
-                                        !list_empty(&dataex.pending_pak));
+                                        !list_empty(&dataex.pending_pak));
                write_lock_irqsave(&dataex.pak_lock, flags);
        }
 
@@ -561,7 +529,7 @@
 
                DPRINTK("size given by app: %d, available: %d\n", size, left);
 
-               ret_size = MIN(size,left);
+               ret_size = MIN(size, left);
 
                ret_size = packet_read(pak, ret_size, data, size, 1);
                if (ret_size < 0) {
@@ -574,7 +542,8 @@
                                DPRINTK("All data from this packet given to 
app.\n");
                                /* All data given to app */
 
-                               
del_singleshot_timer_sync(&pak->processing_timer);
+                               del_singleshot_timer_sync(&pak->
+                                                         processing_timer);
                                list_del(&pak->next);
                                list_add_tail(&pak->next, &dataex.current_pak);
                                /*
@@ -582,7 +551,7 @@
                                 * the more time we give the TPM to process the 
request.
                                 */
                                mod_timer(&pak->processing_timer,
-                                         jiffies + (num_frontends * 60 * HZ));
+                                         jiffies + (num_frontends * 60 * HZ));
                                dataex.copied_so_far = 0;
                        }
                }
@@ -597,16 +566,15 @@
 /*
  * Write operation - only works after a previous read operation!
  */
-static ssize_t
-vtpm_op_write(struct file *file, const char __user * data, size_t size,
-             loff_t * offset)
+static ssize_t vtpm_op_write(struct file *file,
+                            const char __user * data, size_t size,
+                            loff_t * offset)
 {
        struct packet *pak;
        int rc = 0;
        unsigned int off = 4;
        unsigned long flags;
-       u32 instance_no = 0;
-       u32 len_no = 0;
+       struct vtpm_resp_hdr vrh;
 
        /*
         * Minimum required packet size is:
@@ -616,45 +584,38 @@
         * 4 bytes for the ordinal
         * sum: 14 bytes
         */
-       if ( size < off + 10 ) {
+       if (size < sizeof (vrh))
                return -EFAULT;
-       }
-
-       if (copy_from_user(&instance_no,
-                          (void __user *)&data[0],
-                          4)) {
+
+       if (copy_from_user(&vrh, data, sizeof (vrh)))
                return -EFAULT;
-       }
-
-       if (copy_from_user(&len_no,
-                          (void __user *)&data[off+2],
-                          4) ||
-           (off + ntohl(len_no) != size)) {
+
+       /* malformed packet? */
+       if ((off + ntohl(vrh.len_no)) != size)
                return -EFAULT;
-       }
 
        write_lock_irqsave(&dataex.pak_lock, flags);
-       pak = packet_find_instance(&dataex.current_pak, ntohl(instance_no));
+       pak = packet_find_instance(&dataex.current_pak,
+                                  ntohl(vrh.instance_no));
 
        if (pak == NULL) {
                write_unlock_irqrestore(&dataex.pak_lock, flags);
-               printk(KERN_ALERT "No associated packet!\n");
+               printk(KERN_ALERT "No associated packet! (inst=%d)\n",
+                      ntohl(vrh.instance_no));
                return -EFAULT;
-       } else {
-               del_singleshot_timer_sync(&pak->processing_timer);
-               list_del(&pak->next);
-       }
+       }
+
+       del_singleshot_timer_sync(&pak->processing_timer);
+       list_del(&pak->next);
 
        write_unlock_irqrestore(&dataex.pak_lock, flags);
 
        /*
-        * The first 'offset' bytes must be the instance number.
-        * I will just pull that from the packet.
+        * The first 'offset' bytes must be the instance number - skip them.
         */
        size -= off;
-       data = &data[off];
-
-       rc = packet_write(pak, data, size, 1);
+
+       rc = packet_write(pak, &data[off], size, 1);
 
        if (rc > 0) {
                /* I neglected the first 4 bytes */
@@ -664,10 +625,10 @@
        return rc;
 }
 
-static int
-vtpm_op_release(struct inode *inode, struct file *file)
+static int vtpm_op_release(struct inode *inode, struct file *file)
 {
        unsigned long flags;
+
        vtpm_release_packets(NULL, 1);
        write_lock_irqsave(&dataex.pak_lock, flags);
        dataex.has_opener = 0;
@@ -675,10 +636,11 @@
        return 0;
 }
 
-static unsigned int
-vtpm_op_poll(struct file *file, struct poll_table_struct *pts)
+static unsigned int vtpm_op_poll(struct file *file,
+                                struct poll_table_struct *pts)
 {
        unsigned int flags = POLLOUT | POLLWRNORM;
+
        poll_wait(file, &dataex.wait_queue, pts);
        if (!list_empty(&dataex.pending_pak)) {
                flags |= POLLIN | POLLRDNORM;
@@ -696,54 +658,47 @@
        .poll = vtpm_op_poll,
 };
 
-static struct miscdevice ibmvtpms_miscdevice = {
+static struct miscdevice vtpms_miscdevice = {
        .minor = 225,
        .name = "vtpm",
        .fops = &vtpm_ops,
 };
 
-
 /***************************************************************
  Virtual TPM functions and data stuctures
 ***************************************************************/
 
 static u8 create_cmd[] = {
-        1,193,         /* 0: TPM_TAG_RQU_COMMAMD */
-        0,0,0,19,      /* 2: length */
-        0,0,0,0x1,     /* 6: VTPM_ORD_OPEN */
-        0,             /* 10: VTPM type */
-        0,0,0,0,       /* 11: domain id */
-        0,0,0,0                /* 15: instance id */
+       1, 193,                 /* 0: TPM_TAG_RQU_COMMAMD */
+       0, 0, 0, 19,            /* 2: length */
+       0, 0, 0, 0x1,           /* 6: VTPM_ORD_OPEN */
+       0,                      /* 10: VTPM type */
+       0, 0, 0, 0,             /* 11: domain id */
+       0, 0, 0, 0              /* 15: instance id */
 };
 
-static u8 destroy_cmd[] = {
-        1,193,         /* 0: TPM_TAG_RQU_COMMAMD */
-        0,0,0,14,      /* 2: length */
-        0,0,0,0x2,     /* 6: VTPM_ORD_CLOSE */
-        0,0,0,0                /* 10: instance id */
-};
-
-int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domid, u32 instance)
+int tpmif_vtpm_open(tpmif_t * tpmif, domid_t domid, u32 instance)
 {
        int rc = 0;
        struct packet *pak;
 
        pak = packet_alloc(tpmif,
-                          sizeof(create_cmd),
-                          create_cmd[0],
-                          PACKET_FLAG_DISCARD_RESPONSE|
-                          PACKET_FLAG_CHECK_RESPONSESTATUS);
+                          sizeof (create_cmd),
+                          create_cmd[1],
+                          PACKET_FLAG_DISCARD_RESPONSE |
+                          PACKET_FLAG_CHECK_RESPONSESTATUS);
        if (pak) {
-               u8 buf[sizeof(create_cmd)];
-               u32 domid_no = htonl((u32)domid);
+               u8 buf[sizeof (create_cmd)];
+               u32 domid_no = htonl((u32) domid);
                u32 instance_no = htonl(instance);
-               memcpy(buf, create_cmd, sizeof(create_cmd));
-
-               memcpy(&buf[11], &domid_no, sizeof(u32));
-               memcpy(&buf[15], &instance_no, sizeof(u32));
+
+               memcpy(buf, create_cmd, sizeof (create_cmd));
+
+               memcpy(&buf[11], &domid_no, sizeof (u32));
+               memcpy(&buf[15], &instance_no, sizeof (u32));
 
                /* copy the buffer into the packet */
-               rc = packet_set(pak, buf, sizeof(buf));
+               rc = packet_set(pak, buf, sizeof (buf));
 
                if (rc == 0) {
                        pak->tpm_instance = 0;
@@ -759,23 +714,30 @@
        return rc;
 }
 
+static u8 destroy_cmd[] = {
+       1, 193,                 /* 0: TPM_TAG_RQU_COMMAMD */
+       0, 0, 0, 14,            /* 2: length */
+       0, 0, 0, 0x2,           /* 6: VTPM_ORD_CLOSE */
+       0, 0, 0, 0              /* 10: instance id */
+};
+
 int tpmif_vtpm_close(u32 instid)
 {
        int rc = 0;
        struct packet *pak;
 
        pak = packet_alloc(NULL,
-                          sizeof(create_cmd),
-                          create_cmd[0],
-                          PACKET_FLAG_DISCARD_RESPONSE);
+                          sizeof (destroy_cmd),
+                          destroy_cmd[1], PACKET_FLAG_DISCARD_RESPONSE);
        if (pak) {
-               u8 buf[sizeof(destroy_cmd)];
+               u8 buf[sizeof (destroy_cmd)];
                u32 instid_no = htonl(instid);
-               memcpy(buf, destroy_cmd, sizeof(destroy_cmd));
-               memcpy(&buf[10], &instid_no, sizeof(u32));
+
+               memcpy(buf, destroy_cmd, sizeof (destroy_cmd));
+               memcpy(&buf[10], &instid_no, sizeof (u32));
 
                /* copy the buffer into the packet */
-               rc = packet_set(pak, buf, sizeof(buf));
+               rc = packet_set(pak, buf, sizeof (buf));
 
                if (rc == 0) {
                        pak->tpm_instance = 0;
@@ -791,23 +753,22 @@
        return rc;
 }
 
-
 /***************************************************************
  Utility functions
 ***************************************************************/
 
-static int
-tpm_send_fail_message(struct packet *pak, u8 req_tag)
+static int tpm_send_fail_message(struct packet *pak, u8 req_tag)
 {
        int rc;
        static const unsigned char tpm_error_message_fail[] = {
                0x00, 0x00,
                0x00, 0x00, 0x00, 0x0a,
-               0x00, 0x00, 0x00, 0x09 /* TPM_FAIL */
+               0x00, 0x00, 0x00, 0x09  /* TPM_FAIL */
        };
-       unsigned char buffer[sizeof(tpm_error_message_fail)];
-
-       memcpy(buffer, tpm_error_message_fail, sizeof(tpm_error_message_fail));
+       unsigned char buffer[sizeof (tpm_error_message_fail)];
+
+       memcpy(buffer, tpm_error_message_fail,
+              sizeof (tpm_error_message_fail));
        /*
         * Insert the right response tag depending on the given tag
         * All response tags are '+3' to the request tag.
@@ -817,23 +778,24 @@
        /*
         * Write the data to shared memory and notify the front-end
         */
-       rc = packet_write(pak, buffer, sizeof(buffer), 0);
+       rc = packet_write(pak, buffer, sizeof (buffer), 0);
 
        return rc;
 }
 
-
-static void
-_vtpm_release_packets(struct list_head *head, tpmif_t *tpmif,
-                      int send_msgs)
+static void _vtpm_release_packets(struct list_head *head,
+                                 tpmif_t * tpmif, int send_msgs)
 {
        struct packet *pak;
-       struct list_head *pos, *tmp;
+       struct list_head *pos,
+                *tmp;
 
        list_for_each_safe(pos, tmp, head) {
                pak = list_entry(pos, struct packet, next);
+
                if (tpmif == NULL || pak->tpmif == tpmif) {
                        int can_send = 0;
+
                        del_singleshot_timer_sync(&pak->processing_timer);
                        list_del(&pak->next);
 
@@ -849,9 +811,7 @@
        }
 }
 
-
-int
-vtpm_release_packets(tpmif_t *tpmif, int send_msgs)
+int vtpm_release_packets(tpmif_t * tpmif, int send_msgs)
 {
        unsigned long flags;
 
@@ -860,23 +820,22 @@
        _vtpm_release_packets(&dataex.pending_pak, tpmif, send_msgs);
        _vtpm_release_packets(&dataex.current_pak, tpmif, send_msgs);
 
-       write_unlock_irqrestore(&dataex.pak_lock,
-                               flags);
+       write_unlock_irqrestore(&dataex.pak_lock, flags);
        return 0;
 }
 
-
 static int vtpm_queue_packet(struct packet *pak)
 {
        int rc = 0;
+
        if (dataex.has_opener) {
                unsigned long flags;
+
                write_lock_irqsave(&dataex.pak_lock, flags);
                list_add_tail(&pak->next, &dataex.pending_pak);
                /* give the TPM some time to pick up the request */
                mod_timer(&pak->processing_timer, jiffies + (30 * HZ));
-               write_unlock_irqrestore(&dataex.pak_lock,
-                                       flags);
+               write_unlock_irqrestore(&dataex.pak_lock, flags);
 
                wake_up_interruptible(&dataex.wait_queue);
        } else {
@@ -885,24 +844,22 @@
        return rc;
 }
 
-
-static int vtpm_receive(tpmif_t *tpmif, u32 size)
+static int vtpm_receive(tpmif_t * tpmif, u32 size)
 {
        int rc = 0;
        unsigned char buffer[10];
        __be32 *native_size;
-
-       struct packet *pak = packet_alloc(tpmif, size, buffer[4], 0);
-       if (NULL == pak) {
+       struct packet *pak = packet_alloc(tpmif, size, 0, 0);
+
+       if (!pak)
                return -ENOMEM;
-       }
        /*
         * Read 10 bytes from the received buffer to test its
         * content for validity.
         */
-       if (sizeof(buffer) != packet_read(pak,
-                                         sizeof(buffer), buffer,
-                                         sizeof(buffer), 0)) {
+       if (sizeof (buffer) != packet_read(pak,
+                                          sizeof (buffer), buffer,
+                                          sizeof (buffer), 0)) {
                goto failexit;
        }
        /*
@@ -911,7 +868,7 @@
         */
        packet_reset(pak);
 
-       native_size = (__force __be32 *)(&buffer[4+2]);
+       native_size = (__force __be32 *) (&buffer[4 + 2]);
        /*
         * Verify that the size of the packet is correct
         * as indicated and that there's actually someone reading packets.
@@ -920,25 +877,23 @@
         */
        if (size < 10 ||
            be32_to_cpu(*native_size) != size ||
-           0 == dataex.has_opener ||
-           tpmif->status != CONNECTED) {
-               rc = -EINVAL;
-               goto failexit;
+           0 == dataex.has_opener || tpmif->status != CONNECTED) {
+               rc = -EINVAL;
+               goto failexit;
        } else {
-               if ((rc = vtpm_queue_packet(pak)) < 0) {
+               rc = vtpm_queue_packet(pak);
+               if (rc < 0)
                        goto failexit;
-               }
        }
        return 0;
 
-failexit:
+      failexit:
        if (pak) {
-               tpm_send_fail_message(pak, buffer[4+1]);
+               tpm_send_fail_message(pak, buffer[4 + 1]);
                packet_free(pak);
        }
        return rc;
 }
-
 
 /*
  * Timeout function that gets invoked when a packet has not been processed
@@ -951,22 +906,23 @@
 {
        struct packet *pak = (struct packet *)ptr;
        unsigned long flags;
+
        write_lock_irqsave(&dataex.pak_lock, flags);
        /*
         * The packet needs to be searched whether it
         * is still on the list.
         */
        if (pak == packet_find_packet(&dataex.pending_pak, pak) ||
-           pak == packet_find_packet(&dataex.current_pak, pak) ) {
+           pak == packet_find_packet(&dataex.current_pak, pak)) {
                list_del(&pak->next);
-               tpm_send_fail_message(pak, pak->req_tag);
+               if ((pak->flags & PACKET_FLAG_DISCARD_RESPONSE) == 0) {
+                       tpm_send_fail_message(pak, pak->req_tag);
+               }
                packet_free(pak);
        }
 
        write_unlock_irqrestore(&dataex.pak_lock, flags);
 }
-
-
 
 static void tpm_tx_action(unsigned long unused);
 static DECLARE_TASKLET(tpm_tx_tasklet, tpm_tx_action, 0);
@@ -974,21 +930,18 @@
 static struct list_head tpm_schedule_list;
 static spinlock_t tpm_schedule_list_lock;
 
-static inline void
-maybe_schedule_tx_action(void)
+static inline void maybe_schedule_tx_action(void)
 {
        smp_mb();
        tasklet_schedule(&tpm_tx_tasklet);
 }
 
-static inline int
-__on_tpm_schedule_list(tpmif_t * tpmif)
+static inline int __on_tpm_schedule_list(tpmif_t * tpmif)
 {
        return tpmif->list.next != NULL;
 }
 
-static void
-remove_from_tpm_schedule_list(tpmif_t * tpmif)
+static void remove_from_tpm_schedule_list(tpmif_t * tpmif)
 {
        spin_lock_irq(&tpm_schedule_list_lock);
        if (likely(__on_tpm_schedule_list(tpmif))) {
@@ -999,8 +952,7 @@
        spin_unlock_irq(&tpm_schedule_list_lock);
 }
 
-static void
-add_to_tpm_schedule_list_tail(tpmif_t * tpmif)
+static void add_to_tpm_schedule_list_tail(tpmif_t * tpmif)
 {
        if (__on_tpm_schedule_list(tpmif))
                return;
@@ -1013,22 +965,18 @@
        spin_unlock_irq(&tpm_schedule_list_lock);
 }
 
-void
-tpmif_schedule_work(tpmif_t * tpmif)
+void tpmif_schedule_work(tpmif_t * tpmif)
 {
        add_to_tpm_schedule_list_tail(tpmif);
        maybe_schedule_tx_action();
 }
 
-void
-tpmif_deschedule_work(tpmif_t * tpmif)
+void tpmif_deschedule_work(tpmif_t * tpmif)
 {
        remove_from_tpm_schedule_list(tpmif);
 }
 
-
-static void
-tpm_tx_action(unsigned long unused)
+static void tpm_tx_action(unsigned long unused)
 {
        struct list_head *ent;
        tpmif_t *tpmif;
@@ -1042,10 +990,6 @@
                tpmif = list_entry(ent, tpmif_t, list);
                tpmif_get(tpmif);
                remove_from_tpm_schedule_list(tpmif);
-               /*
-                * Ensure that we see the request when we read from it.
-                */
-               mb();
 
                tx = &tpmif->tx->ring[0].req;
 
@@ -1056,22 +1000,22 @@
        }
 }
 
-irqreturn_t
-tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs)
-{
-       tpmif_t *tpmif = dev_id;
+irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+       tpmif_t *tpmif = (tpmif_t *) dev_id;
+
        add_to_tpm_schedule_list_tail(tpmif);
        maybe_schedule_tx_action();
        return IRQ_HANDLED;
 }
 
-static int __init
-tpmback_init(void)
+static int __init tpmback_init(void)
 {
        int rc;
 
-       if ((rc = misc_register(&ibmvtpms_miscdevice)) != 0) {
-               printk(KERN_ALERT "Could not register misc device for TPM 
BE.\n");
+       if ((rc = misc_register(&vtpms_miscdevice)) != 0) {
+               printk(KERN_ALERT
+                      "Could not register misc device for TPM BE.\n");
                return rc;
        }
 
@@ -1094,13 +1038,11 @@
 
 module_init(tpmback_init);
 
-static void __exit
-tpmback_exit(void)
-{
-
+static void __exit tpmback_exit(void)
+{
        tpmif_xenbus_exit();
        tpmif_interface_exit();
-       misc_deregister(&ibmvtpms_miscdevice);
+       misc_deregister(&vtpms_miscdevice);
 }
 
 module_exit(tpmback_exit);
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Mon Mar  6 
17:21:35 2006
@@ -602,7 +602,6 @@
 
                tx = &tp->tx->ring[i].req;
 
-               tx->id = i;
                tx->addr = virt_to_machine(txb->data);
                tx->size = txb->len;
 
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c   Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c   Mon Mar  6 
17:21:35 2006
@@ -95,18 +95,25 @@
         */
 
        int current_state;
-
-       int err = xenbus_scanf(xbt, dev->nodename, "state", "%d",
+       int err;
+
+       if (state == dev->state)
+               return 0;
+
+       err = xenbus_scanf(xbt, dev->nodename, "state", "%d",
                               &current_state);
-       if ((err == 1 && (XenbusState)current_state == state) ||
-           err == -ENOENT)
+       if (err != 1)
                return 0;
 
        err = xenbus_printf(xbt, dev->nodename, "state", "%d", state);
        if (err) {
-               xenbus_dev_fatal(dev, err, "writing new state");
+               if (state != XenbusStateClosing) /* Avoid looping */
+                       xenbus_dev_fatal(dev, err, "writing new state");
                return err;
        }
+
+       dev->state = state;
+
        return 0;
 }
 EXPORT_SYMBOL(xenbus_switch_state);
@@ -138,7 +145,6 @@
        ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
 
        BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
-       dev->has_error = 1;
 
        dev_err(&dev->dev, "%s\n", printf_buffer);
 
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Mon Mar  6 
17:21:35 2006
@@ -89,14 +89,18 @@
 {
        struct xenstore_domain_interface *intf = xenstore_domain_interface();
        XENSTORE_RING_IDX cons, prod;
+       int rc;
 
        while (len != 0) {
                void *dst;
                unsigned int avail;
 
-               wait_event_interruptible(xb_waitq,
-                                        (intf->req_prod - intf->req_cons) !=
-                                        XENSTORE_RING_SIZE);
+               rc = wait_event_interruptible(
+                       xb_waitq,
+                       (intf->req_prod - intf->req_cons) !=
+                       XENSTORE_RING_SIZE);
+               if (rc < 0)
+                       return rc;
 
                /* Read indexes, then verify. */
                cons = intf->req_cons;
@@ -130,13 +134,17 @@
 {
        struct xenstore_domain_interface *intf = xenstore_domain_interface();
        XENSTORE_RING_IDX cons, prod;
+       int rc;
 
        while (len != 0) {
                unsigned int avail;
                const char *src;
 
-               wait_event_interruptible(xb_waitq,
-                                        intf->rsp_cons != intf->rsp_prod);
+               rc = wait_event_interruptible(
+                       xb_waitq,
+                       intf->rsp_cons != intf->rsp_prod);
+               if (rc < 0)
+                       return rc;
 
                /* Read indexes, then verify. */
                cons = intf->rsp_cons;
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Mon Mar  6 
17:21:35 2006
@@ -45,9 +45,7 @@
 #include <asm/hypervisor.h>
 #include <xen/xenbus.h>
 #include <xen/xen_proc.h>
-#include <xen/balloon.h>
 #include <xen/evtchn.h>
-#include <xen/public/evtchn.h>
 
 #include "xenbus_comms.h"
 
@@ -886,9 +884,33 @@
 EXPORT_SYMBOL(unregister_xenstore_notifier);
 
 
+static int all_devices_ready_(struct device *dev, void *data)
+{
+       struct xenbus_device *xendev = to_xenbus_device(dev);
+       int *result = data;
+
+       if (xendev->state != XenbusStateConnected) {
+               result = 0;
+               return 1;
+       }
+
+       return 0;
+}
+
+
+static int all_devices_ready(void)
+{
+       int ready = 1;
+       bus_for_each_dev(&xenbus_frontend.bus, NULL, &ready,
+                        all_devices_ready_);
+       return ready;
+}
+
 
 void xenbus_probe(void *unused)
 {
+       int i;
+
        BUG_ON((xenstored_ready <= 0));
 
        /* Enumerate devices in xenstore. */
@@ -901,12 +923,50 @@
 
        /* Notify others that xenstore is up */
        notifier_call_chain(&xenstore_chain, 0, NULL);
-}
-
-
+
+       /* On a 10 second timeout, waiting for all devices currently
+          configured.  We need to do this to guarantee that the filesystems
+          and / or network devices needed for boot are available, before we
+          can allow the boot to proceed.
+
+          A possible improvement here would be to have the tools add a
+          per-device flag to the store entry, indicating whether it is needed
+          at boot time.  This would allow people who knew what they were
+          doing to accelerate their boot slightly, but of course needs tools
+          or manual intervention to set up those flags correctly.
+        */
+       for (i = 0; i < 10 * HZ; i++) {
+               if (all_devices_ready())
+                       return;
+
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(1);
+       }
+
+       printk(KERN_WARNING
+              "XENBUS: Timeout connecting to devices!\n");
+}
+
+
+static struct file_operations xsd_kva_fops;
 static struct proc_dir_entry *xsd_kva_intf;
 static struct proc_dir_entry *xsd_port_intf;
 
+static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       size_t size = vma->vm_end - vma->vm_start;
+
+       if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0))
+               return -EINVAL;
+
+       vma->vm_pgoff = mfn_to_pfn(xen_start_info->store_mfn);
+
+       if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+                           size, vma->vm_page_prot))
+               return -EAGAIN;
+
+       return 0;
+}
 
 static int xsd_kva_read(char *page, char **start, off_t off,
                         int count, int *eof, void *data)
@@ -980,9 +1040,14 @@
                xen_start_info->store_evtchn = op.u.alloc_unbound.port;
 
                /* And finally publish the above info in /proc/xen */
-               if((xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0400)))
+               if ((xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0400))) {
+                       memcpy(&xsd_kva_fops, xsd_kva_intf->proc_fops,
+                              sizeof(xsd_kva_fops));
+                       xsd_kva_fops.mmap = xsd_kva_mmap;
+                       xsd_kva_intf->proc_fops = &xsd_kva_fops;
                        xsd_kva_intf->read_proc = xsd_kva_read;
-               if((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400)))
+               }
+               if ((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400)))
                        xsd_port_intf->read_proc = xsd_port_read;
        }
 
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Mon Mar  6 
16:09:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Mon Mar  6 
17:21:35 2006
@@ -123,8 +123,9 @@
 
        while (list_empty(&xs_state.reply_list)) {
                spin_unlock(&xs_state.reply_lock);
-               wait_event_interruptible(xs_state.reply_waitq,
-                                        !list_empty(&xs_state.reply_list));
+               /* XXX FIXME: Avoid synchronous wait for response here. */
+               wait_event(xs_state.reply_waitq,
+                          !list_empty(&xs_state.reply_list));
                spin_lock(&xs_state.reply_lock);
        }
 
@@ -685,6 +686,9 @@
                wait_event_interruptible(watch_events_waitq,
                                         !list_empty(&watch_events));
 
+               if (kthread_should_stop())
+                       break;
+
                down(&xenwatch_mutex);
 
                spin_lock(&watch_events_lock);
@@ -705,6 +709,8 @@
 
                up(&xenwatch_mutex);
        }
+
+       return 0;
 }
 
 static int process_msg(void)
@@ -778,7 +784,11 @@
                if (err)
                        printk(KERN_WARNING "XENBUS error %d while reading "
                               "message\n", err);
-       }
+               if (kthread_should_stop())
+                       break;
+       }
+
+       return 0;
 }
 
 int xs_init(void)
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h  Mon Mar 
 6 16:09:18 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h  Mon Mar 
 6 17:21:35 2006
@@ -16,7 +16,7 @@
        return "Xen";
 }
 
-void __init machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
+void __devinit machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
 {
        clear_bit(X86_FEATURE_VME, c->x86_capability);
        clear_bit(X86_FEATURE_DE, c->x86_capability);
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h        
Mon Mar  6 16:09:18 2006
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h        
Mon Mar  6 17:21:35 2006
@@ -1,28 +1,12 @@
 /**
- * machine_specific_memory_setup - Hook for machine specific memory setup.
+ * machine_specific_* - Hooks for machine specific setup.
  *
  * Description:
  *     This is included late in kernel/setup.c so that it can make
  *     use of all of the static functions.
  **/
 
-static char * __init machine_specific_memory_setup(void)
-{
-       char *who;
-       unsigned long start_pfn, max_pfn;
-
-       who = "Xen";
-
-       start_pfn = 0;
-       max_pfn = xen_start_info->nr_pages;
-
-       e820.nr_map = 0;
-       add_memory_region(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn) - 
PFN_PHYS(start_pfn), E820_RAM);
-
-       return who;
-}
-
-void __init machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
+void __cpuinit machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
 {
        clear_bit(X86_FEATURE_VME, c->x86_capability);
        clear_bit(X86_FEATURE_DE, c->x86_capability);
diff -r ede16886f979 -r c4ac21dc3f16 linux-2.6-xen-sparse/include/xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h Mon Mar  6 16:09:18 2006
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Mon Mar  6 17:21:35 2006
@@ -63,7 +63,7 @@
        int otherend_id;
        struct xenbus_watch otherend_watch;
        struct device dev;
-       int has_error;
+       XenbusState state;
        void *data;
 };
 
diff -r ede16886f979 -r c4ac21dc3f16 
tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c     
Mon Mar  6 16:09:18 2006
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c     
Mon Mar  6 17:21:35 2006
@@ -41,8 +41,6 @@
 
 #define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
 
-long (*myptrace)(int xc_handle, enum __ptrace_request, uint32_t, long, long);
-int (*myxcwait)(int xc_handle, int domain, int *status, int options) ;
 static int xc_handle;
 
 static inline int
@@ -170,7 +168,7 @@
     add_thread (0, new_process);
     new_process->stop_expected = 0;
 
-    if (myptrace (xc_handle, PTRACE_ATTACH, domid, 0, 0) != 0) {
+    if (xc_ptrace (xc_handle, PTRACE_ATTACH, domid, 0, isfile) != 0) {
        fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domid,
                 strerror (errno), errno);
        fflush (stderr);
@@ -188,7 +186,7 @@
 {
   struct thread_info *thread = (struct thread_info *) entry;
   struct process_info *process = get_thread_process (thread);
-  myptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0);
+  xc_ptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0);
 }
 
 
@@ -202,7 +200,7 @@
 linux_detach_one_process (struct inferior_list_entry *entry)
 {
 
-  myptrace (xc_handle, PTRACE_DETACH, current_domid, 0, 0);
+  xc_ptrace (xc_handle, PTRACE_DETACH, current_domid, 0, 0);
 }
 
 
@@ -228,7 +226,7 @@
 linux_wait (char *status)
 {
   int w;
-  if (myxcwait(xc_handle, current_domid, &w, 0))
+  if (xc_waitdomain(xc_handle, current_domid, &w, 0))
       return -1;
   
   linux_set_inferior();
@@ -250,7 +248,7 @@
   for_each_inferior(&all_threads, regcache_invalidate_one);
   if (debug_threads)
     fprintf(stderr, "step: %d\n", step);
-  myptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT, 
+  xc_ptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT, 
            resume_info->thread, 0, 0);
 
 }
@@ -275,7 +273,7 @@
        }
 
       buf = malloc (regset->size);
-      res = myptrace (xc_handle, regset->get_request, 
+      res = xc_ptrace (xc_handle, regset->get_request, 
                      curvcpuid(),
                      0, (PTRACE_XFER_TYPE)buf);
       if (res < 0)
@@ -329,7 +327,7 @@
 
       buf = malloc (regset->size);
       regset->fill_function (buf);
-      res = myptrace (xc_handle, regset->set_request, curvcpuid(), 0, 
(PTRACE_XFER_TYPE)buf);
+      res = xc_ptrace (xc_handle, regset->set_request, curvcpuid(), 0, 
(PTRACE_XFER_TYPE)buf);
       if (res < 0)
        {
          if (errno == EIO)
@@ -407,7 +405,7 @@
   for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
     {
       errno = 0;
-      buffer[i] = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(), 
(PTRACE_ARG3_TYPE) addr, 0);
+      buffer[i] = xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(), 
(PTRACE_ARG3_TYPE) addr, 0);
       if (errno)
        return errno;
     }
@@ -440,13 +438,13 @@
 
   /* Fill start and end extra bytes of buffer with existing memory data.  */
 
-  buffer[0] = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
+  buffer[0] = xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
                      (PTRACE_ARG3_TYPE) addr, 0);
 
   if (count > 1)
     {
       buffer[count - 1]
-       = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
+       = xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
                  (PTRACE_ARG3_TYPE) (addr + (count - 1)
                                      * sizeof (PTRACE_XFER_TYPE)),
                  0);
@@ -460,7 +458,7 @@
   for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
     {
       errno = 0;
-      myptrace (xc_handle, PTRACE_POKETEXT, curvcpuid(), 
+      xc_ptrace (xc_handle, PTRACE_POKETEXT, curvcpuid(), 
                (PTRACE_ARG3_TYPE) addr, buffer[i]);
       if (errno)
        return errno;
@@ -561,13 +559,6 @@
                       the_low_target.breakpoint_len);
   init_registers ();
   linux_init_signals ();
-  if (isfile) {
-      myptrace = xc_ptrace_core;
-      myxcwait = xc_waitdomain_core;
-  } else {
-      myptrace = xc_ptrace;
-      myxcwait = xc_waitdomain;
-  }
   using_threads = thread_db_init ();
 
 }
diff -r ede16886f979 -r c4ac21dc3f16 tools/debugger/gdb/gdbbuild
--- a/tools/debugger/gdb/gdbbuild       Mon Mar  6 16:09:18 2006
+++ b/tools/debugger/gdb/gdbbuild       Mon Mar  6 17:21:35 2006
@@ -1,7 +1,9 @@
 #!/bin/sh
 
+[ "$GDB_MIRROR" ] || GDB_MIRROR="ftp://ftp.gnu.org/gnu/gdb/";
+
 rm -rf gdb-6.2.1 gdb-6.2.1-linux-i386-xen
-[ -a gdb-6.2.1.tar.bz2 ] || wget -c ftp://ftp.gnu.org/gnu/gdb/gdb-6.2.1.tar.bz2
+[ -a gdb-6.2.1.tar.bz2 ] || wget -c "$GDB_MIRROR/gdb-6.2.1.tar.bz2"
 tar xjf gdb-6.2.1.tar.bz2
 
 cd gdb-6.2.1-xen-sparse
@@ -12,8 +14,10 @@
 cd gdb-6.2.1-linux-i386-xen
 ../gdb-6.2.1/configure
 
-# some people don't have gmake
-if which gmake ; then
+# Use $MAKE if set, else use gmake if present, otherwise use make
+if [ "$MAKE" ]; then
+    $MAKE
+elif which gmake ; then
     gmake -j4
 else
     make -j4
diff -r ede16886f979 -r c4ac21dc3f16 tools/examples/block
--- a/tools/examples/block      Mon Mar  6 16:09:18 2006
+++ b/tools/examples/block      Mon Mar  6 17:21:35 2006
@@ -129,7 +129,14 @@
 same_vm()
 {
   local otherdom="$1"
-  local othervm=$(xenstore-read "/local/domain/$otherdom/vm")
+  # Note that othervm can be MISSING here, because Xend will be racing with
+  # the hotplug scripts -- the entries in /local/domain can be removed by
+  # Xend before the hotplug scripts have removed the entry in
+  # /local/domain/0/backend/.  In this case, we want to pretend that the
+  # VM is the same as FRONTEND_UUID, because that way the 'sharing' will be
+  # allowed.
+  local othervm=$(xenstore_read_default "/local/domain/$otherdom/vm"         \
+                  "$FRONTEND_UUID")
 
   [ "$FRONTEND_UUID" == "$othervm" ]
 }
@@ -314,7 +321,28 @@
               fi
             fi
 
-            f=$(readlink -f "$f")
+            # Canonicalise the filename for the comparison.
+
+            # I have seen this readlink fails because the filename given by
+            # losetup is only the basename.  This cannot happen when the loop
+            # device is set up through this script, because file is
+            # canonicalised above, but it may happen when loop devices are set
+            # up some other way.  This readlink may also conceivably fail if
+            # the file backing this loop device has been removed.
+
+            # For maximum safety, in the case that $f does not resolve, we
+            # assume that $file and $f are in the same directory.
+
+            # If you create a loopback filesystem, remove it and continue to
+            # run on it, and then create another file with the same name, then
+            # this check will block that -- don't do that.
+
+            # If you create loop devices through some other mechanism, use
+            # relative filenames, and then use the same filename through this
+            # script, then this check will block that -- don't do that either.
+
+            f=$(readlink -f "$f" || echo $(dirname "$file")/$(basename "$f"))
+
 
             if [ "$f" == "$file" ]
             then
diff -r ede16886f979 -r c4ac21dc3f16 tools/examples/xen-hotplug-cleanup
--- a/tools/examples/xen-hotplug-cleanup        Mon Mar  6 16:09:18 2006
+++ b/tools/examples/xen-hotplug-cleanup        Mon Mar  6 17:21:35 2006
@@ -12,10 +12,11 @@
 claim_lock "block"
 
 # remove device frontend store entries
-xenstore-rm -t $(xenstore-read "$XENBUS_PATH/frontend") || true
+xenstore-rm -t \
+  $(xenstore-read "$XENBUS_PATH/frontend" 2>/dev/null) 2>/dev/null || true
 
 # remove device backend store entries
-xenstore-rm -t "$XENBUS_PATH"       || true
-xenstore-rm -t "error/$XENBUS_PATH" || true
+xenstore-rm -t "$XENBUS_PATH"        2>/dev/null || true
+xenstore-rm -t "error/$XENBUS_PATH"  2>/dev/null || true
 
 release_lock "block"
diff -r ede16886f979 -r c4ac21dc3f16 tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Mon Mar  6 16:09:18 2006
+++ b/tools/firmware/hvmloader/Makefile Mon Mar  6 17:21:35 2006
@@ -17,6 +17,9 @@
 # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 # Place - Suite 330, Boston, MA 02111-1307 USA.
 #
+
+# External CFLAGS can do more harm than good.
+CFLAGS :=
 
 XEN_ROOT = ../../..
 include $(XEN_ROOT)/Config.mk
diff -r ede16886f979 -r c4ac21dc3f16 tools/firmware/vmxassist/Makefile
--- a/tools/firmware/vmxassist/Makefile Mon Mar  6 16:09:18 2006
+++ b/tools/firmware/vmxassist/Makefile Mon Mar  6 17:21:35 2006
@@ -17,6 +17,9 @@
 # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 # Place - Suite 330, Boston, MA 02111-1307 USA.
 #
+
+# External CFLAGS can do more harm than good.
+CFLAGS :=
 
 XEN_ROOT = ../../..
 include $(XEN_ROOT)/Config.mk
diff -r ede16886f979 -r c4ac21dc3f16 tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c  Mon Mar  6 16:09:18 2006
+++ b/tools/firmware/vmxassist/setup.c  Mon Mar  6 17:21:35 2006
@@ -123,6 +123,8 @@
 void
 setup_gdt(void)
 {
+       unsigned long long addr = (unsigned long long) &tss;
+
        /* setup task state segment */
        memset(&tss, 0, sizeof(tss));
        tss.ss0 = DATA_SELECTOR;
@@ -130,8 +132,7 @@
        tss.iomap_base = offsetof(struct tss, iomap);
 
        /* initialize gdt's tss selector */
-       unsigned long long addr = (unsigned long long) &tss;
-        gdt[TSS_SELECTOR / sizeof(gdt[0])] |=
+       gdt[TSS_SELECTOR / sizeof(gdt[0])] |=
                ((addr & 0xFF000000) << (56-24)) |
                ((addr & 0x00FF0000) << (32-16)) |
                ((addr & 0x0000FFFF) << (16)) |
diff -r ede16886f979 -r c4ac21dc3f16 tools/ioemu/audio/audio.c
--- a/tools/ioemu/audio/audio.c Mon Mar  6 16:09:18 2006
+++ b/tools/ioemu/audio/audio.c Mon Mar  6 17:21:35 2006
@@ -713,7 +713,7 @@
     delta = now - sw->old_ticks;
     bytes = (delta * sw->bytes_per_second) / ticks_per_sec;
     if (delta < 0) {
-        dolog ("whoops delta(<0)=%lld\n", delta);
+        dolog ("whoops delta(<0)=%"PRId64"\n", delta);
         return 0;
     }
 
diff -r ede16886f979 -r c4ac21dc3f16 tools/ioemu/hw/i8254.c
--- a/tools/ioemu/hw/i8254.c    Mon Mar  6 16:09:18 2006
+++ b/tools/ioemu/hw/i8254.c    Mon Mar  6 17:21:35 2006
@@ -249,7 +249,7 @@
     req->u.data |= (irq << 16);
     req->u.data |= (hvm_channel << 24);
     req->u.data |= ((s->rw_mode) << 26);
-    fprintf(logfile, "HVM_PIT:pass info 0x%llx to HV!\n", req->u.data);
+    fprintf(logfile, "HVM_PIT:pass info 0x%"PRIx64" to HV!\n", req->u.data);
 }
 
 static inline void pit_load_count(PITChannelState *s, int val)
diff -r ede16886f979 -r c4ac21dc3f16 tools/ioemu/monitor.c
--- a/tools/ioemu/monitor.c     Mon Mar  6 16:09:18 2006
+++ b/tools/ioemu/monitor.c     Mon Mar  6 17:21:35 2006
@@ -676,19 +676,19 @@
             break;
         case '-':
             {
-                int has_option;
+                long has_option;
                 /* option */
-                
+
                 c = *typestr++;
                 if (c == '\0')
                     goto bad_type;
-                while (isspace(*p)) 
+                while (isspace(*p))
                     p++;
                 has_option = 0;
                 if (*p == '-') {
                     p++;
                     if (*p != c) {
-                        term_printf("%s: unsupported option -%c\n", 
+                        term_printf("%s: unsupported option -%c\n",
                                     cmdname, *p);
                         goto fail;
                     }
diff -r ede16886f979 -r c4ac21dc3f16 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Mon Mar  6 16:09:18 2006
+++ b/tools/ioemu/target-i386-dm/helper2.c      Mon Mar  6 17:21:35 2006
@@ -138,11 +138,11 @@
         req = &(shared_page->vcpu_iodata[i].vp_ioreq);
         term_printf("vcpu %d: event port %d\n",
                     i, shared_page->vcpu_iodata[i].vp_eport);
-        term_printf("  req state: %x, pvalid: %x, addr: %llx, "
-                    "data: %llx, count: %llx, size: %llx\n",
+        term_printf("  req state: %x, pvalid: %x, addr: %"PRIx64", "
+                    "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
                     req->state, req->pdata_valid, req->addr,
                     req->u.data, req->count, req->size);
-        term_printf("  IO totally occurred on this vcpu: %llx\n",
+        term_printf("  IO totally occurred on this vcpu: %"PRIx64"\n",
                     req->io_count);
     }
 }
@@ -158,8 +158,8 @@
         return req;
 
     fprintf(logfile, "False I/O request ... in-service already: "
-                     "%x, pvalid: %x, port: %llx, "
-                     "data: %llx, count: %llx, size: %llx\n",
+                     "%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;
@@ -460,12 +460,6 @@
         FD_ZERO(&wakeup_rfds);
         FD_SET(evtchn_fd, &wakeup_rfds);
 
-#if __WORDSIZE == 32
-#define ULONGLONG_MAX   0xffffffffffffffffULL
-#else
-#define ULONGLONG_MAX   ULONG_MAX
-#endif
-
         tun_receive_handler(&rfds);
         if ( FD_ISSET(evtchn_fd, &rfds) ) {
             cpu_handle_ioreq(env);
diff -r ede16886f979 -r c4ac21dc3f16 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Mon Mar  6 16:09:18 2006
+++ b/tools/ioemu/vl.c  Mon Mar  6 17:21:35 2006
@@ -2672,6 +2672,7 @@
     char qemu_dm_logfilename[64];
     const char *loadvm = NULL;
     unsigned long nr_pages, extra_pages, ram_pages, *page_array;
+    xc_dominfo_t info;
     extern void *shared_page;
     extern void *shared_vram;
 
@@ -3132,7 +3133,7 @@
 
     ram_pages = ram_size/PAGE_SIZE;
 #if defined(__i386__) || defined(__x86_64__)
-    vgaram_pages =  (vga_ram_size -1)/PAGE_SIZE + 1;
+    vgaram_pages =  (vga_ram_size -1) / PAGE_SIZE + 1;
     free_pages = vgaram_pages / L1_PAGETABLE_ENTRIES;
     extra_pages = vgaram_pages + free_pages;
 #else
@@ -3142,7 +3143,6 @@
 
     xc_handle = xc_interface_open();
 
-    xc_dominfo_t info;
     xc_domain_getinfo(xc_handle, domid, 1, &info);
 
     nr_pages = info.nr_pages + extra_pages;
diff -r ede16886f979 -r c4ac21dc3f16 tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c     Mon Mar  6 16:09:18 2006
+++ b/tools/libxc/xc_core.c     Mon Mar  6 17:21:35 2006
@@ -61,7 +61,7 @@
  
     nr_pages = info.nr_pages;
 
-    header.xch_magic = 0xF00FEBED; 
+    header.xch_magic = XC_CORE_MAGIC;
     header.xch_nr_vcpus = nr_vcpus;
     header.xch_nr_pages = nr_pages;
     header.xch_ctxt_offset = sizeof(struct xc_core_header);
@@ -71,8 +71,12 @@
                                          (sizeof(vcpu_guest_context_t) * 
nr_vcpus) +
                                          (nr_pages * sizeof(unsigned long)));
 
-    write(dump_fd, &header, sizeof(struct xc_core_header));
-    write(dump_fd, &ctxt, sizeof(ctxt[0]) * nr_vcpus);
+    if (write(dump_fd, &header, sizeof(struct xc_core_header)) < 0 ||
+        write(dump_fd, &ctxt, sizeof(ctxt[0]) * nr_vcpus) < 0)
+    {
+        PERROR("write failed");
+        goto error_out;
+    }
 
     if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
         printf("Could not allocate memory\n");
@@ -82,7 +86,11 @@
         printf("Could not get the page frame list\n");
         goto error_out;
     }
-    write(dump_fd, page_array, nr_pages * sizeof(unsigned long));
+    if (write(dump_fd, page_array, nr_pages * sizeof(unsigned long)) < 0)
+    {
+        PERROR("write failed");
+        goto error_out;
+    }
     lseek(dump_fd, header.xch_pages_offset, SEEK_SET);
     for (dump_mem = dump_mem_start, i = 0; i < nr_pages; i++) {
         copy_from_domain_page(xc_handle, domid, page_array, i, dump_mem);
diff -r ede16886f979 -r c4ac21dc3f16 tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Mon Mar  6 16:09:18 2006
+++ b/tools/libxc/xc_ptrace.c   Mon Mar  6 17:21:35 2006
@@ -7,14 +7,13 @@
 
 #include "xc_private.h"
 #include "xg_private.h"
-#include <thread_db.h>
 #include "xc_ptrace.h"
-
 
 /* XXX application state */
 static long                     nr_pages = 0;
 static unsigned long           *page_array = NULL;
 static int                      current_domid = -1;
+static int                      current_isfile;
 
 static cpumap_t                 online_cpumap;
 static cpumap_t                 regs_valid;
@@ -32,7 +31,8 @@
 
     if (online)
         *online = 0;
-    if ( !(regs_valid & (1 << cpu)) ) { 
+    if ( !(regs_valid & (1 << cpu)) )
+    { 
         retval = xc_vcpu_getcontext(xc_handle, current_domid, 
                                                cpu, &ctxt[cpu]);
         if ( retval ) 
@@ -50,9 +50,6 @@
     return retval;    
 }
 
-#define FETCH_REGS(cpu) if (fetch_regs(xc_handle, cpu, NULL)) goto error_out;
-
-
 static struct thr_ev_handlers {
     thr_ev_handler_t td_create;
     thr_ev_handler_t td_death;
@@ -95,14 +92,12 @@
     *cpumap = 0;
     for (i = 0; i <= d->max_vcpu_id; i++) {
         if ((retval = fetch_regs(xc_handle, i, &online)))
-            goto error_out;        
+            return retval;
         if (online)
             *cpumap |= (1 << i);            
     }
     
     return 0;
- error_out:
-    return retval;
 }
 
 /* 
@@ -118,7 +113,8 @@
     int index;
     
     while ( (index = ffsll(changed_cpumap)) ) {
-        if ( cpumap & (1 << (index - 1)) ) {
+        if ( cpumap & (1 << (index - 1)) )
+        {
             if (handlers.td_create) handlers.td_create(index - 1);
         } else {
             printf("thread death: %d\n", index - 1);
@@ -143,34 +139,32 @@
     uint64_t *l3, *l2, *l1;
     static void *v;
 
-    FETCH_REGS(cpu);
+    if (fetch_regs(xc_handle, cpu, NULL))
+        return NULL;
 
     l3 = xc_map_foreign_range(
         xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
     if ( l3 == NULL )
-        goto error_out;
+        return NULL;
 
     l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
     l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l2p);
     if ( l2 == NULL )
-        goto error_out;
+        return NULL;
 
     l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
     l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
     if ( l1 == NULL )
-        goto error_out;
+        return NULL;
 
     p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
     if ( v != NULL )
         munmap(v, PAGE_SIZE);
     v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
     if ( v == NULL )
-        goto error_out;
+        return NULL;
 
     return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
-
- error_out:
-    return NULL;
 }
 
 static void *
@@ -215,17 +209,18 @@
         if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
         {
             printf("Could not allocate memory\n");
-            goto error_out;
+            return NULL;
         }
         if ( xc_get_pfn_list(xc_handle, current_domid,
                              page_array, nr_pages) != nr_pages )
         {
             printf("Could not get the page frame list\n");
-            goto error_out;
+            return NULL;
         }
     }
 
-    FETCH_REGS(cpu);
+    if (fetch_regs(xc_handle, cpu, NULL))
+        return NULL;
 
     if ( ctxt[cpu].ctrlreg[3] != cr3_phys[cpu] )
     {
@@ -236,10 +231,10 @@
             xc_handle, current_domid, PAGE_SIZE, PROT_READ,
             cr3_phys[cpu] >> PAGE_SHIFT);
         if ( cr3_virt[cpu] == NULL )
-            goto error_out;
+            return NULL;
     }
     if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 )
-        goto error_out;
+        return NULL;
     if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
         pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
     if ( pde != pde_phys[cpu] )
@@ -251,10 +246,10 @@
             xc_handle, current_domid, PAGE_SIZE, PROT_READ,
             pde_phys[cpu] >> PAGE_SHIFT);
         if ( pde_virt[cpu] == NULL )
-            goto error_out;
+            return NULL;
     }
     if ( (page = pde_virt[cpu][vtopti(va)]) == 0 )
-        goto error_out;
+        return NULL;
     if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
         page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
     if ( (page != page_phys[cpu]) || (perm != prev_perm[cpu]) )
@@ -268,19 +263,16 @@
         if ( page_virt[cpu] == NULL )
         {
             page_phys[cpu] = 0;
-            goto error_out;
+            return NULL;
         }
         prev_perm[cpu] = perm;
     } 
 
     return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
-
- error_out:
-    return NULL;
-}
-
-int 
-xc_waitdomain(
+}
+
+static int 
+__xc_waitdomain(
     int xc_handle,
     int domain,
     int *status,
@@ -335,7 +327,6 @@
     long edata)
 {
     DECLARE_DOM0_OP;
-    int             status = 0;
     struct gdb_regs pt;
     long            retval = 0;
     unsigned long  *guest_va;
@@ -350,84 +341,83 @@
     { 
     case PTRACE_PEEKTEXT:
     case PTRACE_PEEKDATA:
-        guest_va = (unsigned long *)map_domain_va(
-            xc_handle, cpu, addr, PROT_READ);
+        if (current_isfile)
+            guest_va = (unsigned long *)map_domain_va_core(current_domid, 
+                                cpu, addr, ctxt);
+        else
+            guest_va = (unsigned long *)map_domain_va(xc_handle, 
+                                cpu, addr, PROT_READ);
         if ( guest_va == NULL )
-        {
-            status = EFAULT;
-            goto error_out;
-        }
+            goto out_error;
         retval = *guest_va;
         break;
 
     case PTRACE_POKETEXT:
     case PTRACE_POKEDATA:
         /* XXX assume that all CPUs have the same address space */
-        guest_va = (unsigned long *)map_domain_va(
-                            xc_handle, cpu, addr, PROT_READ|PROT_WRITE);
-        if ( guest_va == NULL ) {
-            status = EFAULT;
-            goto error_out;
-        }
+        if (current_isfile)
+            guest_va = (unsigned long *)map_domain_va_core(current_domid, 
+                                cpu, addr, ctxt);
+        else
+            guest_va = (unsigned long *)map_domain_va(xc_handle, 
+                                cpu, addr, PROT_READ|PROT_WRITE);
+        if ( guest_va == NULL ) 
+            goto out_error;
         *guest_va = (unsigned long)data;
         break;
 
     case PTRACE_GETREGS:
+        if (!current_isfile && fetch_regs(xc_handle, cpu, NULL)) 
+            goto out_error;
+        SET_PT_REGS(pt, ctxt[cpu].user_regs); 
+        memcpy(data, &pt, sizeof(struct gdb_regs));
+        break;
+
     case PTRACE_GETFPREGS:
     case PTRACE_GETFPXREGS:
-        
-        FETCH_REGS(cpu);
-        if ( request == PTRACE_GETREGS )
-        {
-            SET_PT_REGS(pt, ctxt[cpu].user_regs); 
-            memcpy(data, &pt, sizeof(struct gdb_regs));
-        }
-        else if (request == PTRACE_GETFPREGS)
-        {
-            memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
-        }
-        else /*if (request == PTRACE_GETFPXREGS)*/
-        {
-            memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
-        }
+        if (!current_isfile && fetch_regs(xc_handle, cpu, NULL)) 
+                goto out_error;
+        memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
         break;
 
     case PTRACE_SETREGS:
+        if (!current_isfile)
+                goto out_unspported; /* XXX not yet supported */
         SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
-        retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]);
-        if (retval)
-            goto error_out;
+        if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, 
+                                &ctxt[cpu])))
+            goto out_error_dom0;
         break;
 
     case PTRACE_SINGLESTEP:
+        if (!current_isfile)
+              goto out_unspported; /* XXX not yet supported */
         /*  XXX we can still have problems if the user switches threads
          *  during single-stepping - but that just seems retarded
          */
         ctxt[cpu].user_regs.eflags |= PSL_T; 
-        retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]);
-        if ( retval )
-        {
-            perror("dom0 op failed");
-            goto error_out;
-        }
+        if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, 
+                                &ctxt[cpu])))
+            goto out_error_dom0;
         /* FALLTHROUGH */
 
     case PTRACE_CONT:
     case PTRACE_DETACH:
+        if (!current_isfile)
+            goto out_unspported; /* XXX not yet supported */
         if ( request != PTRACE_SINGLESTEP )
         {
             FOREACH_CPU(cpumap, index) {
                 cpu = index - 1;
-                FETCH_REGS(cpu);
+                if (fetch_regs(xc_handle, cpu, NULL)) 
+                    goto out_error;
                 /* Clear trace flag */
-                if ( ctxt[cpu].user_regs.eflags & PSL_T ) {
+                if ( ctxt[cpu].user_regs.eflags & PSL_T ) 
+                {
                     ctxt[cpu].user_regs.eflags &= ~PSL_T;
-                    retval = xc_vcpu_setcontext(xc_handle, current_domid, 
-                                                cpu, &ctxt[cpu]);
-                    if ( retval ) {
-                        perror("dom0 op failed");
-                        goto error_out;
-                    }
+                    if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, 
+                                                cpu, &ctxt[cpu])))
+                        goto out_error_dom0;
                 }
             }
         }
@@ -436,31 +426,34 @@
             op.cmd = DOM0_SETDEBUGGING;
             op.u.setdebugging.domain = current_domid;
             op.u.setdebugging.enable = 0;
-            retval = do_dom0_op(xc_handle, &op);
+            if ((retval = do_dom0_op(xc_handle, &op)))
+                goto out_error_dom0;
         }
         regs_valid = 0;
-        xc_domain_unpause(xc_handle, current_domid > 0 ? current_domid : 
-current_domid);
+        if ((retval = xc_domain_unpause(xc_handle, current_domid > 0 ? 
+                                current_domid : -current_domid)))
+            goto out_error_dom0;
         break;
 
     case PTRACE_ATTACH:
         current_domid = domid_tid;
+        current_isfile = (int)edata;
+        if (current_isfile)
+            break;
         op.cmd = DOM0_GETDOMAININFO;
         op.u.getdomaininfo.domain = current_domid;
         retval = do_dom0_op(xc_handle, &op);
         if ( retval || (op.u.getdomaininfo.domain != current_domid) )
-        {
-            perror("dom0 op failed");
-            goto error_out;
-        }
+            goto out_error_dom0;
         if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
-        {
             printf("domain currently paused\n");
-        } else
-            retval = xc_domain_pause(xc_handle, current_domid);
+        else if ((retval = xc_domain_pause(xc_handle, current_domid)))
+            goto out_error_dom0;
         op.cmd = DOM0_SETDEBUGGING;
         op.u.setdebugging.domain = current_domid;
         op.u.setdebugging.enable = 1;
-        retval = do_dom0_op(xc_handle, &op);
+        if ((retval = do_dom0_op(xc_handle, &op)))
+            goto out_error_dom0;
 
         if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap))
             printf("get_online_cpumap failed\n");
@@ -474,26 +467,40 @@
     case PTRACE_POKEUSER:
     case PTRACE_SYSCALL:
     case PTRACE_KILL:
-#ifdef DEBUG
-        printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
-#endif
-        /* XXX not yet supported */
-        status = ENOSYS;
-        break;
+        goto out_unspported; /* XXX not yet supported */
 
     case PTRACE_TRACEME:
         printf("PTRACE_TRACEME is an invalid request under Xen\n");
-        status = EINVAL;
-    }
-    
-    if ( status )
-    {
-        errno = status;
-        retval = -1;
-    }
-
- error_out:
+        goto out_error;
+    }
+
     return retval;
+
+ out_error_dom0:
+    perror("dom0 op failed");
+ out_error:
+    errno = EINVAL;
+    return retval;
+
+ out_unspported:
+#ifdef DEBUG
+    printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
+#endif
+    errno = ENOSYS;
+    return -1;
+
+}
+
+int 
+xc_waitdomain(
+    int xc_handle,
+    int domain,
+    int *status,
+    int options)
+{
+    if (current_isfile)
+        return xc_waitdomain_core(xc_handle, domain, status, options, ctxt);
+    return __xc_waitdomain(xc_handle, domain, status, options);
 }
 
 /*
diff -r ede16886f979 -r c4ac21dc3f16 tools/libxc/xc_ptrace.h
--- a/tools/libxc/xc_ptrace.h   Mon Mar  6 16:09:18 2006
+++ b/tools/libxc/xc_ptrace.h   Mon Mar  6 17:21:35 2006
@@ -1,5 +1,7 @@
 #ifndef XC_PTRACE_
 #define XC_PTRACE_
+
+#include <thread_db.h>
 
 #ifdef XC_PTRACE_PRIVATE
 #define X86_CR0_PE              0x00000001 /* Enable Protected Mode    (RW) */
@@ -8,33 +10,7 @@
 #define PDRSHIFT        22
 #define PSL_T  0x00000100 /* trace enable bit */
 
-char * ptrace_names[] = {
-    "PTRACE_TRACEME",
-    "PTRACE_PEEKTEXT",
-    "PTRACE_PEEKDATA",
-    "PTRACE_PEEKUSER",
-    "PTRACE_POKETEXT",
-    "PTRACE_POKEDATA",
-    "PTRACE_POKEUSER",
-    "PTRACE_CONT",
-    "PTRACE_KILL",
-    "PTRACE_SINGLESTEP",
-    "PTRACE_INVALID",
-    "PTRACE_INVALID",
-    "PTRACE_GETREGS",
-    "PTRACE_SETREGS",
-    "PTRACE_GETFPREGS",
-    "PTRACE_SETFPREGS",
-    "PTRACE_ATTACH",
-    "PTRACE_DETACH",
-    "PTRACE_GETFPXREGS",
-    "PTRACE_SETFPXREGS",
-    "PTRACE_INVALID",
-    "PTRACE_INVALID",
-    "PTRACE_INVALID",
-    "PTRACE_INVALID",
-    "PTRACE_SYSCALL",
-};
+extern const char const * ptrace_names[];
 
 struct gdb_regs {
     long ebx; /* 0 */
diff -r ede16886f979 -r c4ac21dc3f16 tools/libxc/xc_ptrace_core.c
--- a/tools/libxc/xc_ptrace_core.c      Mon Mar  6 16:09:18 2006
+++ b/tools/libxc/xc_ptrace_core.c      Mon Mar  6 17:21:35 2006
@@ -1,81 +1,10 @@
+#define XC_PTRACE_PRIVATE
+
 #include <sys/ptrace.h>
 #include <sys/wait.h>
 #include "xc_private.h"
+#include "xc_ptrace.h"
 #include <time.h>
-
-#define BSD_PAGE_MASK (PAGE_SIZE-1)
-#define PDRSHIFT        22
-#define VCPU            0               /* XXX */
-
-/*
- * long  
- * ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
- */
-
-struct gdb_regs {
-    long ebx; /* 0 */
-    long ecx; /* 4 */
-    long edx; /* 8 */
-    long esi; /* 12 */
-    long edi; /* 16 */
-    long ebp; /* 20 */
-    long eax; /* 24 */ 
-    int  xds; /* 28 */
-    int  xes; /* 32 */
-    int  xfs; /* 36 */
-    int  xgs; /* 40 */
-    long orig_eax; /* 44 */
-    long eip;    /* 48 */
-    int  xcs;    /* 52 */
-    long eflags; /* 56 */
-    long esp;    /* 60 */     
-    int  xss;    /* 64 */
-};
-
-#define printval(x) printf("%s = %lx\n", #x, (long)x);
-#define SET_PT_REGS(pt, xc)                     \
-{                                               \
-    pt.ebx = xc.ebx;                            \
-    pt.ecx = xc.ecx;                            \
-    pt.edx = xc.edx;                            \
-    pt.esi = xc.esi;                            \
-    pt.edi = xc.edi;                            \
-    pt.ebp = xc.ebp;                            \
-    pt.eax = xc.eax;                            \
-    pt.eip = xc.eip;                            \
-    pt.xcs = xc.cs;                             \
-    pt.eflags = xc.eflags;                      \
-    pt.esp = xc.esp;                            \
-    pt.xss = xc.ss;                             \
-    pt.xes = xc.es;                             \
-    pt.xds = xc.ds;                             \
-    pt.xfs = xc.fs;                             \
-    pt.xgs = xc.gs;                             \
-}
-
-#define SET_XC_REGS(pt, xc)                     \
-{                                               \
-    xc.ebx = pt->ebx;                           \
-    xc.ecx = pt->ecx;                           \
-    xc.edx = pt->edx;                           \
-    xc.esi = pt->esi;                           \
-    xc.edi = pt->edi;                           \
-    xc.ebp = pt->ebp;                           \
-    xc.eax = pt->eax;                           \
-    xc.eip = pt->eip;                           \
-    xc.cs = pt->xcs;                            \
-    xc.eflags = pt->eflags;                     \
-    xc.esp = pt->esp;                           \
-    xc.ss = pt->xss;                            \
-    xc.es = pt->xes;                            \
-    xc.ds = pt->xds;                            \
-    xc.fs = pt->xfs;                            \
-    xc.gs = pt->xgs;                            \
-}
-
-
-#define vtopdi(va) ((va) >> PDRSHIFT)
-#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
 
 /* XXX application state */
 
@@ -84,7 +13,6 @@
 static unsigned long  *m2p_array = NULL;
 static unsigned long            pages_offset;
 static unsigned long            cr3[MAX_VIRT_CPUS];
-static vcpu_guest_context_t     ctxt[MAX_VIRT_CPUS];
 
 /* --------------------- */
 
@@ -92,11 +20,13 @@
 map_mtop_offset(unsigned long ma)
 {
     return pages_offset + (m2p_array[ma >> PAGE_SHIFT] << PAGE_SHIFT);
+    return 0;
 }
 
 
-static void *
-map_domain_va(unsigned long domfd, int cpu, void * guest_va)
+void *
+map_domain_va_core(unsigned long domfd, int cpu, void * guest_va,
+                        vcpu_guest_context_t *ctxt)
 {
     unsigned long pde, page;
     unsigned long va = (unsigned long)guest_va;
@@ -120,12 +50,12 @@
         if (v == MAP_FAILED)
         {
             perror("mmap failed");
-            goto error_out;
+            return NULL;
         }
         cr3_virt[cpu] = v;
     } 
     if ((pde = cr3_virt[cpu][vtopdi(va)]) == 0) /* logical address */
-        goto error_out;
+        return NULL;
     if (ctxt[cpu].flags & VGCF_HVM_GUEST)
         pde = p2m_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
     if (pde != pde_phys[cpu]) 
@@ -137,11 +67,11 @@
             NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd,
             map_mtop_offset(pde_phys[cpu]));
         if (v == MAP_FAILED)
-            goto error_out;
+            return NULL;
         pde_virt[cpu] = v;
     }
     if ((page = pde_virt[cpu][vtopti(va)]) == 0) /* logical address */
-        goto error_out;
+        return NULL;
     if (ctxt[cpu].flags & VGCF_HVM_GUEST)
         page = p2m_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
     if (page != page_phys[cpu]) 
@@ -152,17 +82,15 @@
         v = mmap(
             NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd,
             map_mtop_offset(page_phys[cpu]));
-        if (v == MAP_FAILED) {
+        if (v == MAP_FAILED)
+        {
             printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, 
vtopti(va));
             page_phys[cpu] = 0;
-            goto error_out;
+            return NULL;
         }
         page_virt[cpu] = v;
     } 
     return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
-
- error_out:
-    return 0;
 }
 
 int 
@@ -170,17 +98,25 @@
     int xc_handle,
     int domfd,
     int *status,
-    int options)
+    int options,
+    vcpu_guest_context_t *ctxt)
 {
-    int retval = -1;
     int nr_vcpus;
     int i;
     xc_core_header_t header;
 
-    if (nr_pages == 0) {
+    if (nr_pages == 0)
+    {
 
         if (read(domfd, &header, sizeof(header)) != sizeof(header))
             return -1;
+
+        if (header.xch_magic != XC_CORE_MAGIC) {
+                printf("Magic number missmatch: 0x%08x (file) != "
+                                        " 0x%08x (code)\n", header.xch_magic,
+                                        XC_CORE_MAGIC);
+                return -1;
+        }
 
         nr_pages = header.xch_nr_pages;
         nr_vcpus = header.xch_nr_vcpus;
@@ -193,17 +129,19 @@
         for (i = 0; i < nr_vcpus; i++) {
             cr3[i] = ctxt[i].ctrlreg[3];
         }
-        if ((p2m_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
+        if ((p2m_array = malloc(nr_pages * sizeof(unsigned long))) == NULL)
+        {
             printf("Could not allocate p2m_array\n");
-            goto error_out;
+            return -1;
         }
         if (read(domfd, p2m_array, sizeof(unsigned long)*nr_pages) != 
             sizeof(unsigned long)*nr_pages)
             return -1;
 
-        if ((m2p_array = malloc((1<<20) * sizeof(unsigned long))) == NULL) {
+        if ((m2p_array = malloc((1<<20) * sizeof(unsigned long))) == NULL)
+        {
             printf("Could not allocate m2p array\n");
-            goto error_out;
+            return -1;
         }
         bzero(m2p_array, sizeof(unsigned long)* 1 << 20);
 
@@ -212,89 +150,7 @@
         }
 
     }
-    retval = 0;
- error_out:
-    return retval;
-
-}
-
-long
-xc_ptrace_core(
-    int xc_handle,
-    enum __ptrace_request request,
-    uint32_t domfd,
-    long eaddr,
-    long edata)
-{
-    int             status = 0;
-    struct gdb_regs pt;
-    long            retval = 0;
-    unsigned long  *guest_va;
-    int             cpu = VCPU;
-    void           *addr = (char *)eaddr;
-    void           *data = (char *)edata;
-
-#if 0
-    printf("%20s %d, %p, %p \n", ptrace_names[request], domid, addr, data);
-#endif
-    switch (request) { 
-    case PTRACE_PEEKTEXT:
-    case PTRACE_PEEKDATA:
-        if ((guest_va = (unsigned long *)map_domain_va(domfd, cpu, addr)) == 
NULL) {
-            status = EFAULT;
-            goto error_out;
-        }
-
-        retval = *guest_va;
-        break;
-    case PTRACE_POKETEXT:
-    case PTRACE_POKEDATA:
-        if ((guest_va = (unsigned long *)map_domain_va(domfd, cpu, addr)) == 
NULL) {
-            status = EFAULT;
-            goto error_out;
-        }
-        *guest_va = (unsigned long)data;
-        break;
-    case PTRACE_GETREGS:
-    case PTRACE_GETFPREGS:
-    case PTRACE_GETFPXREGS:
-        if (request == PTRACE_GETREGS) {
-            SET_PT_REGS(pt, ctxt[cpu].user_regs); 
-            memcpy(data, &pt, sizeof(struct gdb_regs));
-        } else if (request == PTRACE_GETFPREGS)
-            memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
-        else /*if (request == PTRACE_GETFPXREGS)*/
-            memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
-        break;
-    case PTRACE_ATTACH:
-        retval = 0;
-        break;
-    case PTRACE_SETREGS:
-    case PTRACE_SINGLESTEP:
-    case PTRACE_CONT:
-    case PTRACE_DETACH:
-    case PTRACE_SETFPREGS:
-    case PTRACE_SETFPXREGS:
-    case PTRACE_PEEKUSER:
-    case PTRACE_POKEUSER:
-    case PTRACE_SYSCALL:
-    case PTRACE_KILL:
-#ifdef DEBUG
-        printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
-#endif
-        status = ENOSYS;
-        break;
-    case PTRACE_TRACEME:
-        printf("PTRACE_TRACEME is an invalid request under Xen\n");
-        status = EINVAL;
-    }
-    
-    if (status) {
-        errno = status;
-        retval = -1;
-    }
- error_out:
-    return retval;
+    return 0;
 }
 
 /*
diff -r ede16886f979 -r c4ac21dc3f16 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Mon Mar  6 16:09:18 2006
+++ b/tools/libxc/xenctrl.h     Mon Mar  6 17:21:35 2006
@@ -92,19 +92,26 @@
     unsigned int xch_pages_offset;
 } xc_core_header_t;
 
+#define XC_CORE_MAGIC 0xF00FEBED
 
 long xc_ptrace_core(
     int xc_handle,
     enum __ptrace_request request, 
     uint32_t domid, 
     long addr, 
-    long data);
-
+    long data,
+    vcpu_guest_context_t *ctxt);
+void * map_domain_va_core(
+    unsigned long domfd, 
+    int cpu, 
+    void *guest_va,
+    vcpu_guest_context_t *ctxt);
 int xc_waitdomain_core(
     int xc_handle,
     int domain, 
     int *status, 
-    int options);
+    int options,
+    vcpu_guest_context_t *ctxt);
 
 /*
  * DOMAIN MANAGEMENT FUNCTIONS
diff -r ede16886f979 -r c4ac21dc3f16 tools/misc/lomount/lomount.c
--- a/tools/misc/lomount/lomount.c      Mon Mar  6 16:09:18 2006
+++ b/tools/misc/lomount/lomount.c      Mon Mar  6 17:21:35 2006
@@ -24,16 +24,33 @@
  * THE SOFTWARE.
  */
 
+/*
+ *  Return code:
+ *
+ *  bit 7 set:         lomount wrapper failed
+ *  bit 7 clear:       lomount wrapper ok; mount's return code in low 7 bits
+ *  0                  success
+ */
+
+enum
+{
+       ERR_USAGE = 0x80,       // Incorrect usage
+       ERR_PART_PARSE,         // Failed to parse partition table
+       ERR_NO_PART,            // No such partition
+       ERR_NO_EPART,           // No such extended partition
+       ERR_MOUNT               // Other failure of mount command
+};
+
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
+#include <sys/wait.h>
 #include <errno.h>
 
 #define BUF 4096
 
-//#define SECSIZE 4096    /* arbitrarilly large (it's probably just 512) */
 #define SECSIZE 512
 
 struct pentry 
@@ -50,30 +67,32 @@
        unsigned long no_of_sectors_abs;
 };
 
-char * progname;
-
-int loadptable(const char *argv, struct pentry parttbl[], struct pentry 
**exttbl)
-{
-       FILE *fd; 
-       int i, valid, total_known_sectors = 0;
+int loadptable(const char *diskimage, struct pentry parttbl[], struct pentry 
**exttbl, int * valid)
+{
+       FILE *fd;
+       size_t size;
+       int fail = 1;
+       int i, total_known_sectors = 0;
        unsigned char *pi; 
        unsigned char data [SECSIZE]; 
        unsigned long extent = 0, old_extent = 0, e_count = 1;
        struct pentry exttbls[4];
 
-       fd = fopen(argv, "r");
+       *valid = 0;
+
+       fd = fopen(diskimage, "r");
        if (fd == NULL)
        {
-               perror ("lomount"); 
-               return 1;
-       }
-       i = fread (&data, 1, sizeof (data), fd); 
-       if (i < SECSIZE)
-       {
-               fprintf (stderr, "%s: could not read the entire first 
sector\n", progname); 
-               return 1;
-       }
-       for (i = 0;i < 4;i++)
+               perror(diskimage);
+               goto done;
+       }
+       size = fread (&data, 1, sizeof(data), fd);
+       if (size < (size_t)sizeof(data))
+       {
+               fprintf(stderr, "Could not read the entire first sector of 
%s.\n", diskimage);
+               goto done;
+       }
+       for (i = 0; i < 4; i++)
        {
                pi = &data [446 + 16 * i];
                parttbl [i].bootable = *pi; 
@@ -95,7 +114,7 @@
                        old_extent = extent;
                }
        }
-       valid = (data [510] == 0x55 && data [511] == 0xaa) ? 1 : 0;
+       *valid = (data [510] == 0x55 && data [511] == 0xaa) ? 1 : 0;
        for (i = 0; i < 4; i++)
        {
                total_known_sectors += parttbl[i].no_of_sectors_abs;
@@ -105,7 +124,7 @@
 #ifdef DEBUG
        if (extent != 0)
        {
-               printf("extended partition detected at offset %d\n", extent);
+               printf("extended partition detected at offset %ld\n", extent);
        }
 #endif
        while (extent != 0)
@@ -113,14 +132,14 @@
 /* according to realloc(3) passing NULL as pointer is same as calling malloc() 
*/
                exttbl[0] = realloc(exttbl[0], e_count * sizeof(struct pentry));
                fseek(fd, extent, SEEK_SET);
-               i = fread (&data, 1, sizeof (data), fd); 
-               if (i < SECSIZE)
-               {
-                       fprintf (stderr, "%s: could not read the entire first 
sector\n", progname); 
-                       return 1;
+               size = fread (&data, 1, sizeof(data), fd);
+               if (size < (size_t)sizeof(data))
+               {
+                       fprintf(stderr, "Could not read extended partition of 
%s.", diskimage);
+                       goto done;
                }
        /* only first 2 entrys are used in extented partition tables */
-               for (i = 0;i < 2;i++)
+               for (i = 0; i < 2; i++)
                {
                        pi = &data [446 + 16 * i];
                        exttbls [i].bootable = *pi; 
@@ -152,7 +171,7 @@
                        /* adjust for start of image instead of start of ext 
partition */
                                exttbl[0][e_count-1].start_sector_abs += 
(extent/SECSIZE);
 #ifdef DEBUG
-                               printf("extent %d start_sector_abs %d\n", 
extent, exttbl[0][e_count-1].start_sector_abs);
+                               printf("extent %ld start_sector_abs %ld\n", 
extent, exttbl[0][e_count-1].start_sector_abs);
 #endif
                        //else if (parttbl[i].system == 0x5)
                        }
@@ -165,53 +184,71 @@
                }
                e_count ++;
        }
-       //fclose (fd);
-       //the above segfaults (?!!!)
-#ifdef DEBUG
-       printf("e_count = %d\n", e_count);
-#endif
-       return valid;
+#ifdef DEBUG
+       printf("e_count = %ld\n", e_count);
+#endif
+       fail = 0;
+
+done:
+       if (fd)
+               fclose(fd);
+       return fail;
 }
 
+void usage()
+{
+       fprintf(stderr, "You must specify at least -diskimage and 
-partition.\n");
+       fprintf(stderr, "All other arguments are passed through to 'mount'.\n");
+       fprintf(stderr, "ex. lomount -t fs-type -diskimage hda.img -partition 1 
/mnt\n");
+       exit(ERR_USAGE);
+}
+
 int main(int argc, char ** argv)
 {
+       int status;
        struct pentry perttbl [4];
        struct pentry *exttbl[1], *parttbl;
-       char buf[BUF], argv2[BUF], diskimage[BUF];
-       int partition = 1, sec, num = 0, pnum = 0, len = BUF, i, f = 0, valid;
-       progname = argv[0];
+       char buf[BUF], argv2[BUF];
+       const char * diskimage = 0;
+       int partition = 0, sec, num = 0, pnum = 0, i, valid;
+       size_t argv2_len = sizeof(argv2);
+       argv2[0] = '\0';
        exttbl[0] = NULL;
+
        for (i = 1; i < argc; i ++)
        {
-               if (strncmp(argv[i], "-diskimage", BUF)==0)
-               {
-                       strncpy(diskimage, argv[i+1], BUF);
-                       i++; f = 1;
-               }
-               else if (strncmp(argv[i], "-partition", BUF)==0)
-               {
-                       partition = atoi(argv[i+1]);
+               if (strcmp(argv[i], "-diskimage")==0)
+               {
+                       if (i == argc-1)
+                               usage();
                        i++;
-                       if (partition < 1) partition = 1;
+                       diskimage = argv[i];
+               }
+               else if (strcmp(argv[i], "-partition")==0)
+               {
+                       if (i == argc-1)
+                               usage();
+                       i++;
+                       partition = atoi(argv[i]);
                }
                else
                {
-                       strncat(argv2, argv[i], len);
-                       strncat(argv2, " ", len-1);
-                       len -= strlen(argv[i]);
-                       len--;
-               }
-       }
-       if (!f)
-       {
-               printf("You must specify -diskimage and -partition\n");
-               printf("ex. lomount -t fs-type -diskimage hda.img -partition 1 
/mnt\n");
-               return 0;
-       }
-       valid = loadptable(diskimage, perttbl, exttbl);
+                       size_t len = strlen(argv[i]);
+                       if (len >= argv2_len-1)
+                               usage();
+                       strcat(argv2, argv[i]);
+                       strcat(argv2, " ");
+                       len -= (len+1);
+               }
+       }
+       if (! diskimage || partition < 1)
+               usage();
+
+       if (loadptable(diskimage, perttbl, exttbl, &valid))
+               return ERR_PART_PARSE;
        if (!valid)
        {
-               printf("Warning: disk image does not appear to describe a valid 
partition table.\n");
+               fprintf(stderr, "Warning: disk image does not appear to 
describe a valid partition table.\n");
        }
        /* NOTE: need to make sure this always rounds down */
        //sec = total_known_sectors / sizeof_diskimage;
@@ -228,14 +265,14 @@
        {
                if (exttbl[0] == NULL)
                {
-                   printf("No extended partitions were found in %s.\n", 
diskimage);
-                   return 2;
+                   fprintf(stderr, "No extended partitions were found in 
%s.\n", diskimage);
+                   return ERR_NO_EPART;
                }
                parttbl = exttbl[0];
                if (parttbl[partition-5].no_of_sectors_abs == 0)
                {
-                       printf("Partition %d was not found in %s.\n", 
partition, diskimage);
-                       return 3;
+                       fprintf(stderr, "Partition %d was not found in %s.\n", 
partition, diskimage);
+                       return ERR_NO_PART;
                }
                partition -= 4;
        }
@@ -244,8 +281,8 @@
                parttbl = perttbl;
                if (parttbl[partition-1].no_of_sectors_abs == 0)
                {
-                       printf("Partition %d was not found in %s.\n", 
partition, diskimage);
-                       return 3;
+                       fprintf(stderr, "Partition %d was not found in %s.\n", 
partition, diskimage);
+                       return ERR_NO_PART;
                }
        }
        num = parttbl[partition-1].start_sector_abs;
@@ -253,10 +290,14 @@
 #ifdef DEBUG
        printf("offset = %d\n", pnum);
 #endif
-       snprintf(buf, BUF, "mount -oloop,offset=%d %s %s", pnum, diskimage, 
argv2);
+       snprintf(buf, sizeof(buf), "mount -oloop,offset=%d %s %s", pnum, 
diskimage, argv2);
 #ifdef DEBUG
        printf("%s\n", buf);
 #endif
-       system(buf);
-       return 0;
+       status = system(buf);
+       if (WIFEXITED(status))
+               status = WEXITSTATUS(status);
+       else
+               status = ERR_MOUNT;
+       return status;
 }
diff -r ede16886f979 -r c4ac21dc3f16 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py       Mon Mar  6 16:09:18 2006
+++ b/tools/python/xen/xend/XendClient.py       Mon Mar  6 17:21:35 2006
@@ -196,8 +196,9 @@
     def xend_domains(self):
         return self.xendGet(self.domainurl())
 
-    def xend_list_domains(self):
-        return self.xendGet(self.domainurl(), {'detail': '1'})
+    def xend_list_domains(self, detail = True):
+        return self.xendGet(self.domainurl(),
+                            {'detail': detail and '1' or '0'})
 
     def xend_domain_vcpuinfo(self, dom):
         return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'})
diff -r ede16886f979 -r c4ac21dc3f16 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Mar  6 16:09:18 2006
+++ b/tools/python/xen/xend/XendDomainInfo.py   Mon Mar  6 17:21:35 2006
@@ -13,7 +13,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
-# Copyright (C) 2005 XenSource Ltd
+# Copyright (C) 2005, 2006 XenSource Ltd
 #============================================================================
 
 """Representation of a single domain.
@@ -82,7 +82,7 @@
 STATE_DOM_OK       = 1
 STATE_DOM_SHUTDOWN = 2
 
-SHUTDOWN_TIMEOUT = 30
+SHUTDOWN_TIMEOUT = 30.0
 
 ZOMBIE_PREFIX = 'Zombie-'
 
@@ -182,7 +182,7 @@
         vm.initDomain()
         vm.storeVmDetails()
         vm.storeDomDetails()
-        vm.registerWatch()
+        vm.registerWatches()
         vm.refreshShutdown()
         return vm
     except:
@@ -238,7 +238,7 @@
         vm.storeVmDetails()
         vm.storeDomDetails()
 
-    vm.registerWatch()
+    vm.registerWatches()
     vm.refreshShutdown(xeninfo)
     return vm
 
@@ -443,7 +443,10 @@
         self.console_mfn = None
 
         self.vmWatch = None
-
+        self.shutdownWatch = None
+
+        self.shutdownStartTime = None
+        
         self.state = STATE_DOM_OK
         self.state_updated = threading.Condition()
         self.refresh_shutdown_lock = threading.Condition()
@@ -648,7 +651,7 @@
 
         self.introduceDomain()
         self.storeDomDetails()
-        self.registerWatch()
+        self.registerWatches()
         self.refreshShutdown()
 
         log.debug("XendDomainInfo.completeRestore done")
@@ -711,13 +714,15 @@
 
     ## public:
 
-    def registerWatch(self):
-        """Register a watch on this VM's entries in the store, so that
-        when they are changed externally, we keep up to date.  This should
-        only be called by {@link #create}, {@link #recreate}, or {@link
-        #restore}, once the domain's details have been written, but before the
-        new instance is returned."""
+    def registerWatches(self):
+        """Register a watch on this VM's entries in the store, and the
+        domain's control/shutdown node, so that when they are changed
+        externally, we keep up to date.  This should only be called by {@link
+        #create}, {@link #recreate}, or {@link #restore}, once the domain's
+        details have been written, but before the new instance is returned."""
         self.vmWatch = xswatch(self.vmpath, self.storeChanged)
+        self.shutdownWatch = xswatch(self.dompath + '/control/shutdown',
+                                     self.handleShutdownWatch)
 
 
     def getDomid(self):
@@ -852,33 +857,49 @@
                 # Domain is alive.  If we are shutting it down, then check
                 # the timeout on that, and destroy it if necessary.
 
-                sst = self.readDom('xend/shutdown_start_time')
-                if sst:
-                    sst = float(sst)
-                    timeout = SHUTDOWN_TIMEOUT - time.time() + sst
+                if self.shutdownStartTime:
+                    timeout = (SHUTDOWN_TIMEOUT - time.time() +
+                               self.shutdownStartTime)
                     if timeout < 0:
                         log.info(
                             "Domain shutdown timeout expired: name=%s id=%s",
                             self.info['name'], self.domid)
                         self.destroy()
-                    else:
-                        log.debug(
-                            "Scheduling refreshShutdown on domain %d in %ds.",
-                            self.domid, timeout)
-                        threading.Timer(timeout, self.refreshShutdown).start()
         finally:
             self.refresh_shutdown_lock.release()
 
         if restart_reason:
             self.maybeRestart(restart_reason)
+
+
+    def handleShutdownWatch(self, _):
+        log.debug('XendDomainInfo.handleShutdownWatch')
+        
+        reason = self.readDom('control/shutdown')
+
+        if reason and reason != 'suspend':
+            sst = self.readDom('xend/shutdown_start_time')
+            now = time.time()
+            if sst:
+                self.shutdownStartTime = float(sst)
+                timeout = float(sst) + SHUTDOWN_TIMEOUT - now
+            else:
+                self.shutdownStartTime = now
+                self.storeDom('xend/shutdown_start_time', now)
+                timeout = SHUTDOWN_TIMEOUT
+
+            log.trace(
+                "Scheduling refreshShutdown on domain %d in %ds.",
+                self.domid, timeout)
+            threading.Timer(timeout, self.refreshShutdown).start()
+
+        return 1
 
 
     def shutdown(self, reason):
         if not reason in shutdown_reasons.values():
             raise XendError('Invalid reason: %s' % reason)
         self.storeDom("control/shutdown", reason)
-        if reason != 'suspend':
-            self.storeDom('xend/shutdown_start_time', time.time())
 
 
     ## private:
@@ -1225,6 +1246,8 @@
         """Cleanup domain resources; release devices.  Idempotent.  Nothrow
         guarantee."""
 
+        self.unwatchShutdown()
+
         self.release_devices()
 
         if self.image:
@@ -1274,6 +1297,20 @@
                 self.vmWatch = None
         except:
             log.exception("Unwatching VM path failed.")
+
+
+    def unwatchShutdown(self):
+        """Remove the watch on the domain's control/shutdown node, if any.
+        Idempotent.  Nothrow guarantee."""
+
+        try:
+            try:
+                if self.shutdownWatch:
+                    self.shutdownWatch.unwatch()
+            finally:
+                self.shutdownWatch = None
+        except:
+            log.exception("Unwatching control/shutdown failed.")
 
 
     ## public:
diff -r ede16886f979 -r c4ac21dc3f16 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Mon Mar  6 16:09:18 2006
+++ b/tools/python/xen/xend/image.py    Mon Mar  6 17:21:35 2006
@@ -274,6 +274,10 @@
                 uname = sxp.child_value(info, 'uname')
                 typedev = sxp.child_value(info, 'dev')
                 (_, vbdparam) = string.split(uname, ':', 1)
+
+                if 'file:' in uname and not os.path.isfile(vbdparam):
+                   raise VmError('Disk image does not exist: %s' % vbdparam)
+
                 if 'ioemu:' in typedev:
                     (emtype, vbddev) = string.split(typedev, ':', 1)
                 else:
diff -r ede16886f979 -r c4ac21dc3f16 tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py     Mon Mar  6 16:09:18 2006
+++ b/tools/python/xen/xend/server/blkif.py     Mon Mar  6 17:21:35 2006
@@ -42,10 +42,6 @@
         """@see DevController.getDeviceDetails"""
 
         dev = sxp.child_value(config, 'dev')
-        if 'ioemu:' in dev:
-            return (None,{},{})
-
-        devid = blkif.blkdev_name_to_number(dev)
 
         (typ, params) = string.split(sxp.child_value(config, 'uname'), ':', 1)
         back = { 'dev'    : dev,
@@ -54,7 +50,13 @@
                  'mode'   : sxp.child_value(config, 'mode', 'r')
                  }
 
-        front = { 'virtual-device' : "%i" % devid }
+        if 'ioemu:' in dev:
+            (dummy, dev1) = string.split(dev, ':', 1)
+            devid = blkif.blkdev_name_to_number(dev1)
+            front = {}
+        else:
+            devid = blkif.blkdev_name_to_number(dev)
+            front = { 'virtual-device' : "%i" % devid }
 
         return (devid, back, front)
 
diff -r ede16886f979 -r c4ac21dc3f16 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Mon Mar  6 16:09:18 2006
+++ b/tools/python/xen/xm/main.py       Mon Mar  6 17:21:35 2006
@@ -396,10 +396,8 @@
     if args:
         dominfo = map(server.xend_domain_vcpuinfo, args)
     else:
-        doms = server.xend_list_domains()
-        dominfo = map(
-            lambda x: server.xend_domain_vcpuinfo(sxp.child_value(x, 'name')),
-            doms)
+        doms = server.xend_list_domains(False)
+        dominfo = map(server.xend_domain_vcpuinfo, doms)
 
     print 'Name                              ID  VCPU  CPU  State  Time(s)  
CPU Affinity'
 
diff -r ede16886f979 -r c4ac21dc3f16 tools/vtpm_manager/manager/dmictl.c
--- a/tools/vtpm_manager/manager/dmictl.c       Mon Mar  6 16:09:18 2006
+++ b/tools/vtpm_manager/manager/dmictl.c       Mon Mar  6 17:21:35 2006
@@ -74,7 +74,13 @@
          
   close(dmi_res->guest_tx_fh); dmi_res->guest_tx_fh = -1;
   close(dmi_res->vtpm_tx_fh);  dmi_res->vtpm_tx_fh = -1; 
-               
+  vtpm_globals->connected_dmis--;
+
+  if (vtpm_globals->connected_dmis == 0) {
+    // No more DMI's connected. Close fifo to prevent a broken pipe.
+    close(vtpm_globals->guest_rx_fh);
+    vtpm_globals->guest_rx_fh = -1;
+  }
  #ifndef MANUAL_DM_LAUNCH
   if (dmi_res->dmi_id != VTPM_CTL_DM) {
     if (dmi_res->dmi_pid != 0) {
@@ -118,6 +124,7 @@
     status = TPM_BAD_PARAMETER;
     goto abort_egress;
   } else {
+    vtpm_globals->connected_dmis++; // Put this here so we don't count Dom0
     BSG_UnpackList( param_buf->bytes, 3,
                    BSG_TYPE_BYTE, &type,
                    BSG_TYPE_UINT32, &domain_id,
diff -r ede16886f979 -r c4ac21dc3f16 tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c        Mon Mar  6 16:09:18 2006
+++ b/tools/vtpm_manager/manager/securestorage.c        Mon Mar  6 17:21:35 2006
@@ -307,8 +307,8 @@
   TPM_RESULT status=TPM_SUCCESS;
   int fh, dmis=-1;
 
-  BYTE *flat_boot_key, *flat_dmis, *flat_enc;
-  buffer_t clear_flat_global, enc_flat_global;
+  BYTE *flat_boot_key=NULL, *flat_dmis=NULL, *flat_enc=NULL;
+  buffer_t clear_flat_global=NULL_BUF, enc_flat_global=NULL_BUF;
   UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
   UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
   struct pack_buf_t storage_key_pack = {storageKeySize, 
vtpm_globals->storageKeyWrap.bytes};
@@ -328,12 +328,9 @@
                                               sizeof(UINT32) +// storagekeysize
                                               storageKeySize, NULL) ); // 
storage key
 
-  flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS 
(-1 for Dom0)
-                   (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
 
   flat_boot_key = (BYTE *) malloc( boot_key_size );
   flat_enc = (BYTE *) malloc( sizeof(UINT32) );
-  flat_dmis = (BYTE *) malloc( flat_dmis_size );
 
   boot_key_size = BSG_PackList(flat_boot_key, 1,
                                BSG_TPM_SIZE32_DATA, &boot_key_pack);
@@ -349,8 +346,12 @@
 
   BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc);
 
-  // Per DMI values to be saved
+  // Per DMI values to be saved (if any exit)
   if (hashtable_count(vtpm_globals->dmi_map) > 0) {
+
+    flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num 
DMIS (-1 for Dom0)
+                     (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
+    flat_dmis = (BYTE *) malloc( flat_dmis_size );
 
     dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
     do {
diff -r ede16886f979 -r c4ac21dc3f16 tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Mon Mar  6 16:09:18 2006
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Mon Mar  6 17:21:35 2006
@@ -754,6 +754,7 @@
 #ifndef VTPM_MULTI_VM
   vtpm_globals->vtpm_rx_fh = -1;
   vtpm_globals->guest_rx_fh = -1;
+  vtpm_globals->connected_dmis = 0;
 #endif
   if ((vtpm_globals->dmi_map = create_hashtable(10, hashfunc32, equals32)) == 
NULL){
     status = TPM_FAIL;
diff -r ede16886f979 -r c4ac21dc3f16 tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h     Mon Mar  6 16:09:18 2006
+++ b/tools/vtpm_manager/manager/vtpmpriv.h     Mon Mar  6 17:21:35 2006
@@ -98,6 +98,7 @@
 #ifndef VTPM_MULTI_VM
   int                 vtpm_rx_fh;
   int                 guest_rx_fh;
+  int                 connected_dmis;     // Used to close guest_rx when no 
dmis are connected
   
   pid_t               master_pid;
 #endif
diff -r ede16886f979 -r c4ac21dc3f16 tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Mon Mar  6 16:09:18 2006
+++ b/tools/xenstore/Makefile   Mon Mar  6 17:21:35 2006
@@ -27,21 +27,27 @@
 CLIENTS += xenstore-write
 CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS))
 
-all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump xenstore-ls
+all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump xenstore-control 
xenstore-ls
+
+test_interleaved_transactions: test_interleaved_transactions.o
+       $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -L. -lxenstore -o $@
 
 testcode: xs_test xenstored_test xs_random
 
-xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o 
xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o
+xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o 
xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o hashtable.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@
 
 $(CLIENTS): xenstore-%: xenstore_%.o libxenstore.so
-       $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@
+       $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -L. -lxenstore -o $@
 
 $(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c
        $(COMPILE.c) -DCLIENT_$(*F) -o $@ $<
 
+xenstore-control: xenstore_control.o libxenstore.so
+       $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -L. -lxenstore -o $@
+
 xenstore-ls: xsls.o libxenstore.so
-       $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@
+       $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -L. -lxenstore -o $@
 
 xenstored_test: xenstored_core_test.o xenstored_watch_test.o 
xenstored_domain_test.o xenstored_transaction_test.o xs_lib.o talloc_test.o 
fake_libxc.o utils.o tdb.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
@@ -77,7 +83,8 @@
 clean: testsuite-clean
        rm -f *.o *.opic *.so
        rm -f xenstored xs_random xs_stress xs_crashme
-       rm -f xs_test xenstored_test xs_tdb_dump xenstore-ls $(CLIENTS)
+       rm -f xs_test xenstored_test xs_tdb_dump xenstore-control xenstore-ls
+       rm -f $(CLIENTS)
        $(RM) $(PROG_DEP)
 
 print-dir:
@@ -129,7 +136,7 @@
 tarball: clean
        cd .. && tar -c -j -v -h -f xenstore.tar.bz2 xenstore/
 
-install: libxenstore.so xenstored xenstore-ls $(CLIENTS)
+install: all
        $(INSTALL_DIR) -p $(DESTDIR)/var/run/xenstored
        $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xenstored
        $(INSTALL_DIR) -p $(DESTDIR)/usr/bin
@@ -137,6 +144,7 @@
        $(INSTALL_DIR) -p $(DESTDIR)/usr/include
        $(INSTALL_PROG) xenstored $(DESTDIR)/usr/sbin
        $(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/bin
+       $(INSTALL_PROG) xenstore-control $(DESTDIR)/usr/bin
        $(INSTALL_PROG) xenstore-ls $(DESTDIR)/usr/bin
        $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
        $(INSTALL_DATA) libxenstore.so $(DESTDIR)/usr/$(LIBDIR)
diff -r ede16886f979 -r c4ac21dc3f16 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Mon Mar  6 16:09:18 2006
+++ b/tools/xenstore/xenstored_core.c   Mon Mar  6 17:21:35 2006
@@ -51,14 +51,31 @@
 #include "xenctrl.h"
 #include "tdb.h"
 
+#include "hashtable.h"
+
+
 extern int eventchn_fd; /* in xenstored_domain.c */
 
-static bool verbose;
+static bool verbose = false;
 LIST_HEAD(connections);
 static int tracefd = -1;
+static bool recovery = true;
+static bool remove_local = true;
 static int reopen_log_pipe[2];
 static char *tracefile = NULL;
 static TDB_CONTEXT *tdb_ctx;
+
+static void corrupt(struct connection *conn, const char *fmt, ...);
+static void check_store();
+
+#define log(...)                                                       \
+       do {                                                            \
+               char *s = talloc_asprintf(NULL, __VA_ARGS__);           \
+               trace("%s\n", s);                                       \
+               syslog(LOG_ERR, "%s",  s);                              \
+               talloc_free(s);                                         \
+       } while (0)
+
 
 #ifdef TESTING
 static bool failtest = false;
@@ -103,33 +120,6 @@
 #endif /* TESTING */
 
 #include "xenstored_test.h"
-
-/* FIXME: Ideally, this should never be called.  Some can be eliminated. */
-/* Something is horribly wrong: shutdown immediately. */
-void __attribute__((noreturn)) corrupt(struct connection *conn,
-                                      const char *fmt, ...)
-{
-       va_list arglist;
-       char *str;
-       int saved_errno = errno;
-
-       va_start(arglist, fmt);
-       str = talloc_vasprintf(NULL, fmt, arglist);
-       va_end(arglist);
-
-       trace("xenstored corruption: connection id %i: err %s: %s",
-               conn ? (int)conn->id : -1, strerror(saved_errno), str);
-       eprintf("xenstored corruption: connection id %i: err %s: %s",
-               conn ? (int)conn->id : -1, strerror(saved_errno), str);
-#ifdef TESTING
-       /* Allow them to attach debugger. */
-       sleep(30);
-#endif
-       syslog(LOG_DAEMON,
-              "xenstored corruption: connection id %i: err %s: %s",
-              conn ? (int)conn->id : -1, strerror(saved_errno), str);
-       _exit(2);
-}
 
 TDB_CONTEXT *tdb_context(struct connection *conn)
 {
@@ -216,8 +206,9 @@
        now = time(NULL);
        tm = localtime(&now);
 
-       trace("%s %p %02d:%02d:%02d %s (", prefix, conn,
-             tm->tm_hour, tm->tm_min, tm->tm_sec,
+       trace("%s %p %04d%02d%02d %02d:%02d:%02d %s (", prefix, conn,
+             tm->tm_year + 1900, tm->tm_mon + 1,
+             tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
              sockmsg_string(data->hdr.msg.type));
        
        for (i = 0; i < data->hdr.msg.len; i++)
@@ -415,16 +406,19 @@
        TDB_DATA key, data;
        uint32_t *p;
        struct node *node;
+       TDB_CONTEXT * context = tdb_context(conn);
 
        key.dptr = (void *)name;
        key.dsize = strlen(name);
-       data = tdb_fetch(tdb_context(conn), key);
+       data = tdb_fetch(context, key);
 
        if (data.dptr == NULL) {
-               if (tdb_error(tdb_context(conn)) == TDB_ERR_NOEXIST)
+               if (tdb_error(context) == TDB_ERR_NOEXIST)
                        errno = ENOENT;
-               else
+               else {
+                       log("TDB error on read: %s", tdb_errorstr(context));
                        errno = EIO;
+               }
                return NULL;
        }
 
@@ -837,8 +831,6 @@
        return 0;
 }
 
-/* Be careful: create heirarchy, put entry in existing parent *last*.
- * This helps fsck if we die during this. */
 static struct node *create_node(struct connection *conn, 
                                const char *name,
                                void *data, unsigned int datalen)
@@ -939,8 +931,9 @@
 {
        unsigned int i;
 
-       /* Delete self, then delete children.  If something goes wrong,
-        * consistency check will clean up this way. */
+       /* Delete self, then delete children.  If we crash, then the worst
+          that can happen is the children will continue to take up space, but
+          will otherwise be unreachable. */
        delete_node_single(conn, node);
 
        /* Delete children, too. */
@@ -950,11 +943,17 @@
                child = read_node(conn, 
                                  talloc_asprintf(node, "%s/%s", node->name,
                                                  node->children + i));
-               if (!child)
-                       corrupt(conn, "No child '%s' found", child);
-               delete_node(conn, child);
-       }
-}
+               if (child) {
+                       delete_node(conn, child);
+               }
+               else {
+                       trace("delete_node: No child '%s/%s' found!\n",
+                             node->name, node->children + i);
+                       /* Skip it, we've already deleted the parent. */
+               }
+       }
+}
+
 
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
@@ -962,6 +961,17 @@
        memmove(mem + off, mem + off + len, total - off - len);
 }
 
+
+static bool remove_child_entry(struct connection *conn, struct node *node,
+                              size_t offset)
+{
+       size_t childlen = strlen(node->children + offset);
+       memdel(node->children, offset, childlen + 1, node->childlen);
+       node->childlen -= childlen + 1;
+       return write_node(conn, node);
+}
+
+
 static bool delete_child(struct connection *conn,
                         struct node *node, const char *childname)
 {
@@ -969,19 +979,19 @@
 
        for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
                if (streq(node->children+i, childname)) {
-                       memdel(node->children, i, strlen(childname) + 1,
-                              node->childlen);
-                       node->childlen -= strlen(childname) + 1;
-                       return write_node(conn, node);
+                       return remove_child_entry(conn, node, i);
                }
        }
        corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
+       return false;
 }
 
 
 static int _rm(struct connection *conn, struct node *node, const char *name)
 {
-       /* Delete from parent first, then if something explodes fsck cleans. */
+       /* Delete from parent first, then if we crash, the worst that can
+          happen is the child will continue to take up space, but will
+          otherwise be unreachable. */
        struct node *parent = read_node(conn, get_parent(name));
        if (!parent) {
                send_error(conn, EINVAL);
@@ -1000,10 +1010,12 @@
 
 static void internal_rm(const char *name)
 {
-       char *tname = talloc_strdup(talloc_autofree_context(), name);
+       char *tname = talloc_strdup(NULL, name);
        struct node *node = read_node(NULL, tname);
        if (node)
                _rm(NULL, node, tname);
+       talloc_free(node);
+       talloc_free(tname);
 }
 
 
@@ -1149,18 +1161,19 @@
        case XS_DEBUG:
                if (streq(in->buffer, "print"))
                        xprintf("debug: %s", in->buffer + get_string(in, 0));
+               if (streq(in->buffer, "check"))
+                       check_store();
 #ifdef TESTING
                /* For testing, we allow them to set id. */
                if (streq(in->buffer, "setid")) {
                        conn->id = atoi(in->buffer + get_string(in, 0));
-                       send_ack(conn, XS_DEBUG);
                } else if (streq(in->buffer, "failtest")) {
                        if (get_string(in, 0) < in->used)
                                srandom(atoi(in->buffer + get_string(in, 0)));
-                       send_ack(conn, XS_DEBUG);
                        failtest = true;
                }
 #endif /* TESTING */
+               send_ack(conn, XS_DEBUG);
                break;
 
        case XS_WATCH:
@@ -1258,7 +1271,7 @@
 
                if (in->hdr.msg.len > PATH_MAX) {
 #ifndef TESTING
-                       syslog(LOG_DAEMON, "Client tried to feed us %i",
+                       syslog(LOG_ERR, "Client tried to feed us %i",
                               in->hdr.msg.len);
 #endif
                        goto bad_client;
@@ -1425,10 +1438,18 @@
                   balloon driver will pick up stale entries.  In the case of
                   the balloon driver, this can be fatal.
                */
-               char *tlocal = talloc_strdup(talloc_autofree_context(),
-                                            "/local");
-               internal_rm("/local");
-               create_node(NULL, tlocal, NULL, 0);
+               char *tlocal = talloc_strdup(NULL, "/local");
+
+               check_store();
+
+               if (remove_local) {
+                       internal_rm("/local");
+                       create_node(NULL, tlocal, NULL, 0);
+
+                       check_store();
+               }
+
+               talloc_free(tlocal);
        }
        else {
                tdb_ctx = tdb_open(tdbname, 7919, TDB_FLAGS, O_RDWR|O_CREAT,
@@ -1439,10 +1460,196 @@
                manual_node("/", "tool");
                manual_node("/tool", "xenstored");
                manual_node("/tool/xenstored", NULL);
-       }
-
-       /* FIXME: Fsck */
-}
+
+               check_store();
+       }
+}
+
+
+static unsigned int hash_from_key_fn(void *k)
+{
+       char *str = k;
+        unsigned int hash = 5381;
+        char c;
+
+        while ((c = *str++))
+               hash = ((hash << 5) + hash) + (unsigned int)c;
+
+        return hash;
+}
+
+
+static int keys_equal_fn(void *key1, void *key2)
+{
+       return 0 == strcmp((char *)key1, (char *)key2);
+}
+
+
+static char *child_name(const char *s1, const char *s2)
+{
+       if (strcmp(s1, "/")) {
+               return talloc_asprintf(NULL, "%s/%s", s1, s2);
+       }
+       else {
+               return talloc_asprintf(NULL, "/%s", s2);
+       }
+}
+
+
+static void remember_string(struct hashtable *hash, const char *str)
+{
+       char *k = malloc(strlen(str) + 1);
+       strcpy(k, str);
+       hashtable_insert(hash, k, (void *)1);
+}
+
+
+/**
+ * A node has a children field that names the children of the node, separated
+ * by NULs.  We check whether there are entries in there that are duplicated
+ * (and if so, delete the second one), and whether there are any that do not
+ * have a corresponding child node (and if so, delete them).  Each valid child
+ * is then recursively checked.
+ *
+ * No deleting is performed if the recovery flag is cleared (i.e. -R was
+ * passed on the command line).
+ *
+ * As we go, we record each node in the given reachable hashtable.  These
+ * entries will be used later in clean_store.
+ */
+static void check_store_(const char *name, struct hashtable *reachable)
+{
+       struct node *node = read_node(NULL, name);
+
+       if (node) {
+               size_t i = 0;
+
+               struct hashtable * children =
+                       create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+
+               remember_string(reachable, name);
+
+               while (i < node->childlen) {
+                       size_t childlen = strlen(node->children + i);
+                       char * childname = child_name(node->name,
+                                                     node->children + i);
+                       struct node *childnode = read_node(NULL, childname);
+                       
+                       if (childnode) {
+                               if (hashtable_search(children, childname)) {
+                                       log("check_store: '%s' is duplicated!",
+                                           childname);
+
+                                       if (recovery) {
+                                               remove_child_entry(NULL, node,
+                                                                  i);
+                                               i -= childlen + 1;
+                                       }
+                               }
+                               else {
+                                       remember_string(children, childname);
+                                       check_store_(childname, reachable);
+                               }
+                       }
+                       else {
+                               log("check_store: No child '%s' found!\n",
+                                   childname);
+
+                               if (recovery) {
+                                       remove_child_entry(NULL, node, i);
+                                       i -= childlen + 1;
+                               }
+                       }
+
+                       talloc_free(childnode);
+                       talloc_free(childname);
+                       i += childlen + 1;
+               }
+
+               hashtable_destroy(children, 0 /* Don't free values (they are
+                                                all (void *)1) */);
+               talloc_free(node);
+       }
+       else {
+               /* Impossible, because no database should ever be without the
+                  root, and otherwise, we've just checked in our caller
+                  (which made a recursive call to get here). */
+                  
+               log("check_store: No child '%s' found: impossible!", name);
+       }
+}
+
+
+/**
+ * Helper to clean_store below.
+ */
+static int clean_store_(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA val,
+                       void *private)
+{
+       struct hashtable *reachable = private;
+       char * name = talloc_strndup(NULL, key.dptr, key.dsize);
+
+       if (!hashtable_search(reachable, name)) {
+               log("clean_store: '%s' is orphaned!", name);
+               if (recovery) {
+                       tdb_delete(tdb, key);
+               }
+       }
+
+       talloc_free(name);
+
+       return 0;
+}
+
+
+/**
+ * Given the list of reachable nodes, iterate over the whole store, and
+ * remove any that were not reached.
+ */
+static void clean_store(struct hashtable *reachable)
+{
+       tdb_traverse(tdb_ctx, &clean_store_, reachable);
+}
+
+
+static void check_store()
+{
+       char * root = talloc_strdup(NULL, "/");
+       struct hashtable * reachable =
+               create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+ 
+       log("Checking store ...");
+       check_store_(root, reachable);
+       clean_store(reachable);
+       log("Checking store complete.");
+
+       hashtable_destroy(reachable, 0 /* Don't free values (they are all
+                                         (void *)1) */);
+       talloc_free(root);
+}
+
+
+/* Something is horribly wrong: check the store. */
+static void corrupt(struct connection *conn, const char *fmt, ...)
+{
+       va_list arglist;
+       char *str;
+       int saved_errno = errno;
+
+       va_start(arglist, fmt);
+       str = talloc_vasprintf(NULL, fmt, arglist);
+       va_end(arglist);
+
+       log("corruption detected by connection %i: err %s: %s",
+           conn ? (int)conn->id : -1, strerror(saved_errno), str);
+
+#ifdef TESTING
+       /* Allow them to attach debugger. */
+       sleep(30);
+#endif
+       check_store();
+}
+
 
 static void write_pidfile(const char *pidfile)
 {
@@ -1506,6 +1713,9 @@
 "  --no-fork           to request that the daemon does not fork,\n"
 "  --output-pid        to request that the pid of the daemon is output,\n"
 "  --trace-file <file> giving the file for logging, and\n"
+"  --no-recovery       to request that no recovery should be attempted when\n"
+"                      the store is corrupted (debug only),\n"
+"  --preserve-local    to request that /local is preserved on start-up,\n"
 "  --verbose           to request verbose execution.\n");
 }
 
@@ -1517,6 +1727,8 @@
        { "no-fork", 0, NULL, 'N' },
        { "output-pid", 0, NULL, 'P' },
        { "trace-file", 1, NULL, 'T' },
+       { "no-recovery", 0, NULL, 'R' },
+       { "preserve-local", 0, NULL, 'L' },
        { "verbose", 0, NULL, 'V' },
        { NULL, 0, NULL, 0 } };
 
@@ -1532,7 +1744,7 @@
        bool no_domain_init = false;
        const char *pidfile = NULL;
 
-       while ((opt = getopt_long(argc, argv, "DF:HNPT:V", options,
+       while ((opt = getopt_long(argc, argv, "DF:HNPT:RLV", options,
                                  NULL)) != -1) {
                switch (opt) {
                case 'D':
@@ -1550,6 +1762,12 @@
                case 'P':
                        outputpid = true;
                        break;
+               case 'R':
+                       recovery = false;
+                       break;
+               case 'L':
+                       remove_local = false;
+                       break;
                case 'T':
                        tracefile = optarg;
                        break;
diff -r ede16886f979 -r c4ac21dc3f16 tools/xenstore/xenstored_core.h
--- a/tools/xenstore/xenstored_core.h   Mon Mar  6 16:09:18 2006
+++ b/tools/xenstore/xenstored_core.h   Mon Mar  6 17:21:35 2006
@@ -148,10 +148,6 @@
 /* Replace the tdb: required for transaction code */
 bool replace_tdb(const char *newname, TDB_CONTEXT *newtdb);
 
-/* Fail due to excessive corruption, capitalist pigdogs! */
-void __attribute__((noreturn)) corrupt(struct connection *conn,
-                                      const char *fmt, ...);
-
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 
 
diff -r ede16886f979 -r c4ac21dc3f16 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Mon Mar  6 16:09:18 2006
+++ b/tools/xenstore/xenstored_domain.c Mon Mar  6 17:21:35 2006
@@ -27,7 +27,6 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <paths.h>
 
 //#define DEBUG
 #include "utils.h"
@@ -466,21 +465,8 @@
 { 
        int rc, fd;
        evtchn_port_t port; 
-       unsigned long kva; 
        char str[20]; 
        struct domain *dom0; 
-
-       fd = open(XENSTORED_PROC_KVA, O_RDONLY); 
-       if (fd == -1)
-               return -1;
-
-       rc = read(fd, str, sizeof(str)); 
-       if (rc == -1)
-               goto outfd;
-       str[rc] = '\0'; 
-       kva = strtoul(str, NULL, 0); 
-
-       close(fd); 
 
        fd = open(XENSTORED_PROC_PORT, O_RDONLY); 
        if (fd == -1)
@@ -496,12 +482,12 @@
 
        dom0 = new_domain(NULL, 0, port); 
 
-       fd = open(_PATH_KMEM, O_RDWR);
+       fd = open(XENSTORED_PROC_KVA, O_RDWR);
        if (fd == -1)
                return -1;
 
        dom0->interface = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE,
-                              MAP_SHARED, fd, kva);
+                              MAP_SHARED, fd, 0);
        if (dom0->interface == MAP_FAILED)
                goto outfd;
 
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Mon Mar  6 16:09:18 2006
+++ b/xen/arch/ia64/xen/dom0_ops.c      Mon Mar  6 17:21:35 2006
@@ -16,10 +16,11 @@
 #include <asm/pdb.h>
 #include <xen/trace.h>
 #include <xen/console.h>
+#include <xen/guest_access.h>
 #include <public/sched_ctl.h>
 #include <asm/vmx.h>
 
-long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
+long arch_do_dom0_op(dom0_op_t *op, GUEST_HANDLE(dom0_op_t) u_dom0_op)
 {
     long ret = 0;
 
@@ -64,7 +65,7 @@
 
         put_domain(d);
 
-        copy_to_user(u_dom0_op, op, sizeof(*op));
+        copy_to_guest(u_dom0_op, op, 1);
     }
     break;
 
@@ -74,7 +75,6 @@
         int n,j;
         int num = op->u.getpageframeinfo2.num;
         domid_t dom = op->u.getpageframeinfo2.domain;
-        unsigned long *s_ptr = (unsigned long*) op->u.getpageframeinfo2.array;
         struct domain *d;
         unsigned long *l_arr;
         ret = -ESRCH;
@@ -95,7 +95,8 @@
         {
             int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n);
 
-            if ( copy_from_user(l_arr, &s_ptr[n], k*sizeof(unsigned long)) )
+            if ( copy_from_guest_offset(l_arr, op->u.getpageframeinfo2.array,
+                                        n, k) )
             {
                 ret = -EINVAL;
                 break;
@@ -135,7 +136,8 @@
 
             }
 
-            if ( copy_to_user(&s_ptr[n], l_arr, k*sizeof(unsigned long)) )
+            if ( copy_to_guest_offset(op->u.getpageframeinfo2.array,
+                                      n, l_arr, k) )
             {
                 ret = -EINVAL;
                 break;
@@ -160,7 +162,6 @@
         unsigned long start_page = op->u.getmemlist.max_pfns >> 32;
         unsigned long nr_pages = op->u.getmemlist.max_pfns & 0xffffffff;
         unsigned long mfn;
-        unsigned long *buffer = op->u.getmemlist.buffer;
 
         ret = -EINVAL;
         if ( d != NULL )
@@ -180,16 +181,16 @@
             {
                 mfn = gmfn_to_mfn_foreign(d, i);
 
-                if ( put_user(mfn, buffer) )
+                if ( copy_to_guest_offset(op->u.getmemlist.buffer,
+                                          i - start_page, &mfn, 1) )
                 {
                     ret = -EFAULT;
                     break;
                 }
-                buffer++;
             }
 
             op->u.getmemlist.num_pfns = i - start_page;
-            copy_to_user(u_dom0_op, op, sizeof(*op));
+            copy_to_guest(u_dom0_op, op, 1);
             
             put_domain(d);
         }
@@ -211,7 +212,7 @@
         memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
         //memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
         ret = 0;
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
     }
     break;
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Mon Mar  6 16:09:18 2006
+++ b/xen/arch/ia64/xen/xensetup.c      Mon Mar  6 17:21:35 2006
@@ -12,7 +12,7 @@
 #include <xen/sched.h>
 #include <xen/mm.h>
 #include <public/version.h>
-//#include <xen/delay.h>
+#include <xen/gdbstub.h>
 #include <xen/compile.h>
 #include <xen/console.h>
 #include <xen/serial.h>
@@ -341,6 +341,8 @@
     printk("Brought up %ld CPUs\n", (long)num_online_cpus());
     smp_cpus_done(max_cpus);
 #endif
+
+    initialise_gdb(); /* could be moved earlier */
 
     do_initcalls();
 printk("About to call sort_main_extable()\n");
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/boot/mkelf32.c
--- a/xen/arch/x86/boot/mkelf32.c       Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/boot/mkelf32.c       Mon Mar  6 17:21:35 2006
@@ -244,8 +244,8 @@
 
     inimage  = argv[1];
     outimage = argv[2];
-    loadbase = strtoull(argv[3], NULL, 16);
-    final_exec_addr = strtoul(argv[4], NULL, 16);
+    loadbase = strtoul(argv[3], NULL, 16);
+    final_exec_addr = strtoull(argv[4], NULL, 16);
 
     infd = open(inimage, O_RDONLY);
     if ( infd == -1 )
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/dom0_ops.c   Mon Mar  6 17:21:35 2006
@@ -10,6 +10,7 @@
 #include <xen/types.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/guest_access.h>
 #include <public/dom0_ops.h>
 #include <xen/sched.h>
 #include <xen/event.h>
@@ -48,7 +49,7 @@
         (void)rdmsr_safe(msr_addr, msr_lo, msr_hi);
 }
 
-long arch_do_dom0_op(struct dom0_op *op, struct dom0_op *u_dom0_op)
+long arch_do_dom0_op(struct dom0_op *op, GUEST_HANDLE(dom0_op_t) u_dom0_op)
 {
     long ret = 0;
 
@@ -75,7 +76,7 @@
 
             op->u.msr.out1 = msr_lo;
             op->u.msr.out2 = msr_hi;
-            copy_to_user(u_dom0_op, op, sizeof(*op));
+            copy_to_guest(u_dom0_op, op, 1);
         }
         ret = 0;
     }
@@ -90,7 +91,7 @@
         {
             ret = shadow_mode_control(d, &op->u.shadow_control);
             put_domain(d);
-            copy_to_user(u_dom0_op, op, sizeof(*op));
+            copy_to_guest(u_dom0_op, op, 1);
         } 
     }
     break;
@@ -102,10 +103,11 @@
             op->u.add_memtype.nr_mfns,
             op->u.add_memtype.type,
             1);
-        if (ret > 0)
-        {
-            (void)__put_user(0, &u_dom0_op->u.add_memtype.handle);
-            (void)__put_user(ret, &u_dom0_op->u.add_memtype.reg);
+        if ( ret > 0 )
+        {
+            op->u.add_memtype.handle = 0;
+            op->u.add_memtype.reg    = ret;
+            (void)copy_to_guest(u_dom0_op, op, 1);
             ret = 0;
         }
     }
@@ -136,9 +138,10 @@
         if ( op->u.read_memtype.reg < num_var_ranges )
         {
             mtrr_if->get(op->u.read_memtype.reg, &mfn, &nr_mfns, &type);
-            (void)__put_user(mfn, &u_dom0_op->u.read_memtype.mfn);
-            (void)__put_user(nr_mfns, &u_dom0_op->u.read_memtype.nr_mfns);
-            (void)__put_user(type, &u_dom0_op->u.read_memtype.type);
+            op->u.read_memtype.mfn     = mfn;
+            op->u.read_memtype.nr_mfns = nr_mfns;
+            op->u.read_memtype.type    = type;
+            (void)copy_to_guest(u_dom0_op, op, 1);
             ret = 0;
         }
     }
@@ -147,7 +150,7 @@
     case DOM0_MICROCODE:
     {
         extern int microcode_update(void *buf, unsigned long len);
-        ret = microcode_update(op->u.microcode.data, op->u.microcode.length);
+        ret = microcode_update(op->u.microcode.data.p, op->u.microcode.length);
     }
     break;
 
@@ -195,7 +198,7 @@
         memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
         memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
         ret = 0;
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
     }
     break;
@@ -245,7 +248,7 @@
 
         put_domain(d);
 
-        copy_to_user(u_dom0_op, op, sizeof(*op));
+        copy_to_guest(u_dom0_op, op, 1);
     }
     break;
 
@@ -255,7 +258,6 @@
         int n,j;
         int num = op->u.getpageframeinfo2.num;
         domid_t dom = op->u.getpageframeinfo2.domain;
-        unsigned long *s_ptr = (unsigned long*) op->u.getpageframeinfo2.array;
         struct domain *d;
         unsigned long *l_arr;
         ret = -ESRCH;
@@ -277,7 +279,8 @@
         {
             int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n);
 
-            if ( copy_from_user(l_arr, &s_ptr[n], k*sizeof(unsigned long)) )
+            if ( copy_from_guest_offset(l_arr, op->u.getpageframeinfo2.array,
+                                        n, k) )
             {
                 ret = -EINVAL;
                 break;
@@ -320,7 +323,8 @@
 
             }
 
-            if ( copy_to_user(&s_ptr[n], l_arr, k*sizeof(unsigned long)) )
+            if ( copy_to_guest_offset(op->u.getpageframeinfo2.array,
+                                      n, l_arr, k) )
             {
                 ret = -EINVAL;
                 break;
@@ -341,7 +345,6 @@
         struct domain *d = find_domain_by_id(op->u.getmemlist.domain);
         unsigned long max_pfns = op->u.getmemlist.max_pfns;
         unsigned long mfn;
-        unsigned long *buffer = op->u.getmemlist.buffer;
         struct list_head *list_ent;
 
         ret = -EINVAL;
@@ -353,19 +356,20 @@
             list_ent = d->page_list.next;
             for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ )
             {
-                mfn = page_to_mfn(list_entry(list_ent, struct page_info, 
list));
-                if ( put_user(mfn, buffer) )
+                mfn = page_to_mfn(list_entry(
+                    list_ent, struct page_info, list));
+                if ( copy_to_guest_offset(op->u.getmemlist.buffer,
+                                          i, &mfn, 1) )
                 {
                     ret = -EFAULT;
                     break;
                 }
-                buffer++;
                 list_ent = mfn_to_page(mfn)->list.next;
             }
             spin_unlock(&d->page_alloc_lock);
 
             op->u.getmemlist.num_pfns = i;
-            copy_to_user(u_dom0_op, op, sizeof(*op));
+            copy_to_guest(u_dom0_op, op, 1);
             
             put_domain(d);
         }
@@ -401,13 +405,12 @@
             entry.start  = e820.map[i].addr;
             entry.end    = e820.map[i].addr + e820.map[i].size;
             entry.is_ram = (e820.map[i].type == E820_RAM);
-            (void)copy_to_user(
-                &op->u.physical_memory_map.memory_map[i],
-                &entry, sizeof(entry));
+            (void)copy_to_guest_offset(
+                op->u.physical_memory_map.memory_map, i, &entry, 1);
         }
 
         op->u.physical_memory_map.nr_map_entries = i;
-        (void)copy_to_user(u_dom0_op, op, sizeof(*op));
+        (void)copy_to_guest(u_dom0_op, op, 1);
     }
     break;
 
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/hvm/svm/svm.c        Mon Mar  6 17:21:35 2006
@@ -247,6 +247,7 @@
 void svm_restore_msrs(struct vcpu *v)
 {
 }
+#endif
 
 #define IS_CANO_ADDRESS(add) 1
 
@@ -297,7 +298,7 @@
         return 0;
     }
 
-    HVM_DBG_LOG(DBG_LEVEL_2, "mode_do_msr_read: msr_content: %lx\n", 
+    HVM_DBG_LOG(DBG_LEVEL_2, "mode_do_msr_read: msr_content: %"PRIx64"\n", 
             msr_content);
 
     regs->eax = msr_content & 0xffffffff;
@@ -311,12 +312,14 @@
     struct vcpu *vc = current;
     struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
 
-    HVM_DBG_LOG(DBG_LEVEL_1, "mode_do_msr_write msr %lx msr_content %lx\n", 
-                regs->ecx, msr_content);
+    HVM_DBG_LOG(DBG_LEVEL_1, "mode_do_msr_write msr %lx "
+                "msr_content %"PRIx64"\n", 
+                (unsigned long)regs->ecx, msr_content);
 
     switch (regs->ecx)
     {
     case MSR_EFER:
+#ifdef __x86_64__
         if ((msr_content & EFER_LME) ^ test_bit(SVM_CPU_STATE_LME_ENABLED,
                                                 &vc->arch.hvm_svm.cpu_state))
         {
@@ -337,6 +340,7 @@
         if ((msr_content ^ vmcb->efer) & EFER_LME)
             msr_content &= ~EFER_LME;  
         /* No update for LME/LMA since it have no effect */
+#endif
         vmcb->efer = msr_content | EFER_SVME;
         break;
 
@@ -382,18 +386,6 @@
     }
     return 1;
 }
-
-#else
-static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
-{
-    return 0;
-}
-
-static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
-{
-    return 0;
-}
-#endif
 
 void svm_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
 {
@@ -752,7 +744,8 @@
         /* unmap IO shared page */
         struct domain *d = v->domain;
         if ( d->arch.hvm_domain.shared_page_va )
-            unmap_domain_page((void *)d->arch.hvm_domain.shared_page_va);
+            unmap_domain_page_global(
+                (void *)d->arch.hvm_domain.shared_page_va);
         shadow_direct_map_clean(d);
     }
 
@@ -937,10 +930,8 @@
 
     if (input == 1)
     {
-#ifndef __x86_64__
         if ( hvm_apic_support(v->domain) &&
                 !vlapic_global_enabled((VLAPIC(v))) )
-#endif
             clear_bit(X86_FEATURE_APIC, &edx);
            
 #if CONFIG_PAGING_LEVELS < 3
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/hvm/svm/x86_32/exits.S
--- a/xen/arch/x86/hvm/svm/x86_32/exits.S       Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/hvm/svm/x86_32/exits.S       Mon Mar  6 17:21:35 2006
@@ -88,9 +88,6 @@
 #define STGI   .byte 0x0F,0x01,0xDC
 #define CLGI   .byte 0x0F,0x01,0xDD
 
-#define DO_TSC_OFFSET 0
-#define DO_FPUSAVE    0
-        
 ENTRY(svm_asm_do_launch)
         sti
         CLGI                
@@ -100,36 +97,6 @@
         movl %eax, VMCB_rax(%ecx)
         movl VCPU_svm_hsa_pa(%ebx), %eax
         VMSAVE
-
-#if DO_FPUSAVE
-        mov      %cr0, %eax     
-        push %eax
-        clts
-        lea     VCPU_arch_guest_fpu_ctxt(%ebx), %eax
-        fxrstor (%eax)
-        pop      %eax
-        mov      %eax, %cr0
-#endif
-
-#if (DO_TSC_OFFSET)
-        pushl %edx /* eax and edx get trashed by rdtsc */
-        pushl %eax
-        rdtsc
-        subl VCPU_svm_vmexit_tsc(%ebx),%eax   /* tsc's from    */
-        sbbl VCPU_svm_vmexit_tsc+4(%ebx),%edx /* last #VMEXIT? */
-        subl %eax,VMCB_tsc_offset(%ecx)  /* subtract from running TSC_OFFSET */
-        sbbl %edx,VMCB_tsc_offset+4(%ecx)
-        subl $20000,VMCB_tsc_offset(%ecx)  /* fudge factor for VMXXX calls  */
-        sbbl $0,VMCB_tsc_offset+4(%ecx)
-
-        /* 
-         * TODO: may need to add a kludge factor to account for all the cycles 
-         * burned in VMLOAD, VMSAVE, VMRUN...
-         */
-
-        popl %eax
-        popl %edx
-        #endif
 
         movl VCPU_svm_vmcb_pa(%ebx), %eax
         popl %ebx
@@ -150,31 +117,7 @@
         VMSAVE
         /* eax is the only register we're allowed to touch here... */
 
-#if DO_FPUSAVE
-        mov  %cr0, %eax
-        push %eax
-        clts
         GET_CURRENT(%eax)
-        lea     VCPU_arch_guest_fpu_ctxt(%eax), %eax
-        fxsave (%eax)
-        fnclex
-        pop  %eax
-        mov  %eax, %cr0
-#endif
-        
-        GET_CURRENT(%eax)
-
-#if (DO_TSC_OFFSET)
-        pushl %edx
-        pushl %ebx
-        movl %eax,%ebx
-        rdtsc
-        movl %eax,VCPU_svm_vmexit_tsc(%ebx)
-        movl %edx,VCPU_svm_vmexit_tsc+4(%ebx)
-        movl %ebx,%eax
-        popl %ebx
-        popl %edx
-#endif
 
         movl VCPU_svm_hsa_pa(%eax), %eax
         VMLOAD
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/hvm/vioapic.c        Mon Mar  6 17:21:35 2006
@@ -52,20 +52,6 @@
         s->flags &= ~IOAPIC_ENABLE_FLAG;
 }
 
-static void ioapic_dump_redir(hvm_vioapic_t *s, uint8_t entry)
-{
-    RedirStatus redir = s->redirtbl[entry];
-
-    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_dump_redir "
-      "entry %x vector %x deliver_mod %x destmode %x delivestatus %x "
-      "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
-      entry, redir.RedirForm.vector, redir.RedirForm.deliver_mode,
-      redir.RedirForm.destmode, redir.RedirForm.delivestatus,
-      redir.RedirForm.polarity, redir.RedirForm.remoteirr,
-      redir.RedirForm.trigmod, redir.RedirForm.mask,
-      redir.RedirForm.dest_id);
-}
-
 #ifdef HVM_DOMAIN_SAVE_RESTORE
 void ioapic_save(QEMUFile* f, void* opaque)
 {
@@ -534,7 +520,19 @@
     if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask)
         return;
 
-    ioapic_dump_redir(s, irq);
+    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_set_irq entry %x "
+      "vector %x deliver_mod %x destmode %x delivestatus %x "
+      "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
+      irq,
+      s->redirtbl[irq].RedirForm.vector,
+      s->redirtbl[irq].RedirForm.deliver_mode,
+      s->redirtbl[irq].RedirForm.destmode,
+      s->redirtbl[irq].RedirForm.delivestatus,
+      s->redirtbl[irq].RedirForm.polarity,
+      s->redirtbl[irq].RedirForm.remoteirr,
+      s->redirtbl[irq].RedirForm.trigmod,
+      s->redirtbl[irq].RedirForm.mask,
+      s->redirtbl[irq].RedirForm.dest_id);
 
     if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
         uint32_t bit = 1 << irq;
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Mon Mar  6 17:21:35 2006
@@ -172,7 +172,7 @@
     switch(regs->ecx){
     case MSR_EFER:
         msr_content = msr->msr_items[VMX_INDEX_MSR_EFER];
-        HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content %llx\n", (unsigned long 
long)msr_content);
+        HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content %"PRIx64"\n", msr_content);
         if (test_bit(VMX_CPU_STATE_LME_ENABLED,
                      &vc->arch.hvm_vmx.cpu_state))
             msr_content |= 1 << _EFER_LME;
@@ -202,7 +202,8 @@
     default:
         return 0;
     }
-    HVM_DBG_LOG(DBG_LEVEL_2, "mode_do_msr_read: msr_content: %lx\n", 
msr_content);
+    HVM_DBG_LOG(DBG_LEVEL_2, "mode_do_msr_read: msr_content: %"PRIx64"\n",
+                msr_content);
     regs->eax = msr_content & 0xffffffff;
     regs->edx = msr_content >> 32;
     return 1;
@@ -216,8 +217,9 @@
     struct vmx_msr_state * host_state =
         &percpu_msr[smp_processor_id()];
 
-    HVM_DBG_LOG(DBG_LEVEL_1, " mode_do_msr_write msr %lx msr_content %lx\n",
-                regs->ecx, msr_content);
+    HVM_DBG_LOG(DBG_LEVEL_1, " mode_do_msr_write msr %lx "
+                "msr_content %"PRIx64"\n",
+                (unsigned long)regs->ecx, msr_content);
 
     switch (regs->ecx){
     case MSR_EFER:
@@ -882,7 +884,7 @@
     __vmread(GUEST_RFLAGS, &eflags);
     vm86 = eflags & X86_EFLAGS_VM ? 1 : 0;
 
-    HVM_DBG_LOG(DBG_LEVEL_1,
+    HVM_DBG_LOG(DBG_LEVEL_IO,
                 "vmx_io_instruction: vm86 %d, eip=%lx:%lx, "
                 "exit_qualification = %lx",
                 vm86, cs, eip, exit_qualification);
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/io_apic.c    Mon Mar  6 17:21:35 2006
@@ -1548,8 +1548,9 @@
      */
     apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
     init_8259A(1);
-    timer_ack = 1;
-    enable_8259A_irq(0);
+    /* XEN: Ripped out the legacy missed-tick logic, so below is not needed. */
+    /*timer_ack = 1;*/
+    /*enable_8259A_irq(0);*/
 
     pin1  = find_isa_irq_pin(0, mp_INT);
     apic1 = find_isa_irq_apic(0, mp_INT);
@@ -1617,7 +1618,7 @@
 
     printk(KERN_INFO "...trying to set up timer as ExtINT IRQ...");
 
-    timer_ack = 0;
+    /*timer_ack = 0;*/
     init_8259A(0);
     make_8259A_irq(0);
     apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
@@ -1631,16 +1632,6 @@
     printk(" failed :(.\n");
     panic("IO-APIC + timer doesn't work!  Boot with apic=debug and send a "
           "report.  Then try booting with the 'noapic' option");
-}
-
-#define NR_IOAPIC_BIOSIDS 256
-static u8 ioapic_biosid_to_apic_enum[NR_IOAPIC_BIOSIDS];
-static void store_ioapic_biosid_mapping(void)
-{
-    u8 apic;
-    memset(ioapic_biosid_to_apic_enum, ~0, NR_IOAPIC_BIOSIDS);
-    for ( apic = 0; apic < nr_ioapics; apic++ )
-        ioapic_biosid_to_apic_enum[mp_ioapics[apic].mpc_apicid] = apic;
 }
 
 /*
@@ -1654,8 +1645,6 @@
 
 void __init setup_IO_APIC(void)
 {
-    store_ioapic_biosid_mapping();
-
     enable_IO_APIC();
 
     if (acpi_ioapic)
@@ -1839,50 +1828,45 @@
 
 #endif /*CONFIG_ACPI_BOOT*/
 
-
-int ioapic_guest_read(int apicid, int address, u32 *pval)
-{
-    u32 val;
-    int apicenum;
-    union IO_APIC_reg_00 reg_00;
+static int ioapic_physbase_to_id(unsigned long physbase)
+{
+    int apic;
+    for ( apic = 0; apic < nr_ioapics; apic++ )
+        if ( mp_ioapics[apic].mpc_apicaddr == physbase )
+            return apic;
+    return -EINVAL;
+}
+
+int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval)
+{
+    int apic;
     unsigned long flags;
 
-    if ( (apicid >= NR_IOAPIC_BIOSIDS) ||
-         ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) )
-        return -EINVAL;
+    if ( (apic = ioapic_physbase_to_id(physbase)) < 0 )
+        return apic;
 
     spin_lock_irqsave(&ioapic_lock, flags);
-    val = io_apic_read(apicenum, address);
+    *pval = io_apic_read(apic, reg);
     spin_unlock_irqrestore(&ioapic_lock, flags);
 
-    /* Rewrite APIC ID to what the BIOS originally specified. */
-    if ( address == 0 )
-    {
-        reg_00.raw = val;
-        reg_00.bits.ID = apicid;
-        val = reg_00.raw;
-    }
-
-    *pval = val;
     return 0;
 }
 
-int ioapic_guest_write(int apicid, int address, u32 val)
-{
-    int apicenum, pin, irq;
+int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
+{
+    int apic, pin, irq;
     struct IO_APIC_route_entry rte = { 0 };
     struct irq_pin_list *entry;
     unsigned long flags;
 
-    if ( (apicid >= NR_IOAPIC_BIOSIDS) ||
-         ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) )
-        return -EINVAL;
+    if ( (apic = ioapic_physbase_to_id(physbase)) < 0 )
+        return apic;
 
     /* Only write to the first half of a route entry. */
-    if ( (address < 0x10) || (address & 1) )
+    if ( (reg < 0x10) || (reg & 1) )
         return 0;
     
-    pin = (address - 0x10) >> 1;
+    pin = (reg - 0x10) >> 1;
 
     *(u32 *)&rte = val;
     rte.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
@@ -1898,7 +1882,7 @@
     if ( rte.delivery_mode > dest_LowestPrio )
     {
         printk("ERROR: Attempt to write weird IOAPIC destination mode!\n");
-        printk("       APIC=%d/%d, lo-reg=%x\n", apicid, pin, val);
+        printk("       APIC=%d/%d, lo-reg=%x\n", apic, pin, val);
         return -EINVAL;
     }
 
@@ -1923,19 +1907,19 @@
         /* Record the pin<->irq mapping. */
         for ( entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next] )
         {
-            if ( (entry->apic == apicenum) && (entry->pin == pin) )
+            if ( (entry->apic == apic) && (entry->pin == pin) )
                 break;
             if ( !entry->next )
             {
-                add_pin_to_irq(irq, apicenum, pin);
+                add_pin_to_irq(irq, apic, pin);
                 break;
             }
         }
     }
 
     spin_lock_irqsave(&ioapic_lock, flags);
-    io_apic_write(apicenum, 0x10 + 2 * pin, *(((int *)&rte) + 0));
-    io_apic_write(apicenum, 0x11 + 2 * pin, *(((int *)&rte) + 1));
+    io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&rte) + 0));
+    io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&rte) + 1));
     spin_unlock_irqrestore(&ioapic_lock, flags);
 
     return 0;
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/microcode.c
--- a/xen/arch/x86/microcode.c  Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/microcode.c  Mon Mar  6 17:21:35 2006
@@ -116,7 +116,7 @@
 #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)
 
 /* serialize access to the physical write to MSR 0x79 */
-static spinlock_t microcode_update_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(microcode_update_lock);
 
 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
 static DECLARE_MUTEX(microcode_sem);
@@ -166,7 +166,8 @@
        }
 
        wrmsr(MSR_IA32_UCODE_REV, 0, 0);
-       __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
+       /* see notes above for revision 1.07.  Apparent chip bug */
+       sync_core();
        /* get the current revision from MSR 0x8B */
        rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev);
        pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n",
@@ -366,7 +367,7 @@
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
 
        if (uci->mc == NULL) {
-               printk(KERN_INFO "microcode: No suitable data for CPU%d\n", 
cpu_num);
+               printk(KERN_INFO "microcode: No new microcode data for 
CPU%d\n", cpu_num);
                return;
        }
 
@@ -379,7 +380,9 @@
                (unsigned long) uci->mc->bits >> 16 >> 16);
        wrmsr(MSR_IA32_UCODE_REV, 0, 0);
 
-       __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
+       /* see notes above for revision 1.07.  Apparent chip bug */
+       sync_core();
+
        /* get the current revision from MSR 0x8B */
        rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
 
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/mm.c Mon Mar  6 17:21:35 2006
@@ -506,7 +506,6 @@
     vaddr <<= PGT_va_shift;
     rc = get_page_and_type_from_pagenr(
         l2e_get_pfn(l2e), PGT_l1_page_table | vaddr, d);
-
 #if CONFIG_PAGING_LEVELS == 2
     if ( unlikely(!rc) )
         rc = get_linear_pagetable(l2e, pfn, d);
@@ -3187,8 +3186,8 @@
         ptwr_flush(d, PTWR_PT_INACTIVE);
 
     /* Read the PTE that maps the page being updated. */
-    if (__copy_from_user(&pte, &linear_pg_table[l1_linear_offset(addr)],
-                         sizeof(pte)))
+    if ( __copy_from_user(&pte, &linear_pg_table[l1_linear_offset(addr)],
+                          sizeof(pte)) )
     {
         MEM_LOG("ptwr_emulate: Cannot read thru linear_pg_table");
         return X86EMUL_UNHANDLEABLE;
@@ -3198,15 +3197,10 @@
     page = mfn_to_page(pfn);
 
     /* We are looking only for read-only mappings of p.t. pages. */
-    if ( ((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) != _PAGE_PRESENT) ||
-         ((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) ||
-         (page_get_owner(page) != d) )
-    {
-        MEM_LOG("ptwr_emulate: Page is mistyped or bad pte "
-                "(%lx, %" PRtype_info ")",
-                l1e_get_pfn(pte), page->u.inuse.type_info);
-        return X86EMUL_UNHANDLEABLE;
-    }
+    ASSERT((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) == _PAGE_PRESENT);
+    ASSERT((page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table);
+    ASSERT((page->u.inuse.type_info & PGT_count_mask) != 0);
+    ASSERT(page_get_owner(page) == d);
 
     /* Check the new PTE. */
     nl1e = l1e_from_intpte(val);
@@ -3266,8 +3260,11 @@
     unsigned long new,
     unsigned long new_hi)
 {
-    return ptwr_emulated_update(
-        addr, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1);
+    if ( CONFIG_PAGING_LEVELS == 2 )
+        return X86EMUL_UNHANDLEABLE;
+    else
+        return ptwr_emulated_update(
+            addr, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1);
 }
 
 static struct x86_mem_emulator ptwr_mem_emulator = {
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/nmi.c
--- a/xen/arch/x86/nmi.c        Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/nmi.c        Mon Mar  6 17:21:35 2006
@@ -322,15 +322,9 @@
     case X86_VENDOR_INTEL:
         switch (boot_cpu_data.x86) {
         case 6:
-            if (boot_cpu_data.x86_model > 0xd)
-                return;
-
             setup_p6_watchdog();
             break;
         case 15:
-            if (boot_cpu_data.x86_model > 0x4)
-                return;
-
             if (!setup_p4_watchdog())
                 return;
             break;
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/physdev.c    Mon Mar  6 17:21:35 2006
@@ -11,8 +11,12 @@
 #include <public/xen.h>
 #include <public/physdev.h>
 
-extern int ioapic_guest_read(int apicid, int address, u32 *pval);
-extern int ioapic_guest_write(int apicid, int address, u32 pval);
+extern int
+ioapic_guest_read(
+    unsigned long physbase, unsigned int reg, u32 *pval);
+extern int
+ioapic_guest_write(
+    unsigned long physbase, unsigned int reg, u32 pval);
 
 /*
  * Demuxing hypercall.
@@ -49,7 +53,9 @@
         if ( !IS_PRIV(current->domain) )
             break;
         ret = ioapic_guest_read(
-            op.u.apic_op.apic, op.u.apic_op.offset, &op.u.apic_op.value);
+            op.u.apic_op.apic_physbase,
+            op.u.apic_op.reg,
+            &op.u.apic_op.value);
         break;
 
     case PHYSDEVOP_APIC_WRITE:
@@ -57,7 +63,9 @@
         if ( !IS_PRIV(current->domain) )
             break;
         ret = ioapic_guest_write(
-            op.u.apic_op.apic, op.u.apic_op.offset, op.u.apic_op.value);
+            op.u.apic_op.apic_physbase,
+            op.u.apic_op.reg,
+            op.u.apic_op.value);
         break;
 
     case PHYSDEVOP_ASSIGN_VECTOR:
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/setup.c      Mon Mar  6 17:21:35 2006
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/domain_page.h>
 #include <xen/compile.h>
+#include <xen/gdbstub.h>
 #include <public/version.h>
 #include <asm/bitops.h>
 #include <asm/smp.h>
@@ -479,6 +480,8 @@
     printk("Brought up %ld CPUs\n", (long)num_online_cpus());
     smp_cpus_done(max_cpus);
 
+    initialise_gdb(); /* could be moved earlier */
+
     do_initcalls();
 
     schedulers_start();
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/shadow.c     Mon Mar  6 17:21:35 2006
@@ -279,8 +279,8 @@
              psh_type == PGT_l4_shadow )      /* allocated for PAE PDP page */
             page = alloc_domheap_pages(NULL, 0, ALLOC_DOM_DMA);
         else if ( d->arch.ops->guest_paging_levels == PAGING_L3 &&
-                  psh_type == PGT_l3_shadow ) /* allocated for PAE PDP page */
-            page = alloc_domheap_pages(NULL, 0, ALLOC_DOM_DMA);
+                  (psh_type == PGT_l3_shadow || psh_type == PGT_l4_shadow) )
+            page = alloc_domheap_pages(NULL, 0, ALLOC_DOM_DMA); /* allocated 
for PAE PDP page */
         else
             page = alloc_domheap_page(NULL);
 #endif
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/shadow32.c   Mon Mar  6 17:21:35 2006
@@ -29,6 +29,7 @@
 #include <xen/event.h>
 #include <xen/sched.h>
 #include <xen/trace.h>
+#include <xen/guest_access.h>
 
 #define MFN_PINNED(_x) (mfn_to_page(_x)->u.inuse.type_info & PGT_pinned)
 #define va_to_l1mfn(_ed, _va) \
@@ -1508,14 +1509,14 @@
         d->arch.shadow_fault_count       = 0;
         d->arch.shadow_dirty_count       = 0;
  
-        if ( (sc->dirty_bitmap == NULL) || 
+        if ( guest_handle_is_null(sc->dirty_bitmap) ||
              (d->arch.shadow_dirty_bitmap == NULL) )
         {
             rc = -EINVAL;
             break;
         }
 
-        if(sc->pages > d->arch.shadow_dirty_bitmap_size)
+        if ( sc->pages > d->arch.shadow_dirty_bitmap_size )
             sc->pages = d->arch.shadow_dirty_bitmap_size; 
 
 #define chunk (8*1024) /* Transfer and clear in 1kB chunks for L1 cache. */
@@ -1524,10 +1525,10 @@
             int bytes = ((((sc->pages - i) > chunk) ?
                           chunk : (sc->pages - i)) + 7) / 8;
      
-            if (copy_to_user(
-                    sc->dirty_bitmap + (i/(8*sizeof(unsigned long))),
-                    d->arch.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
-                    bytes))
+            if ( copy_to_guest_offset(
+                sc->dirty_bitmap, i/(8*sizeof(unsigned long)),
+                d->arch.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
+                (bytes+sizeof(unsigned long)-1) / sizeof(unsigned long)) )
             {
                 rc = -EINVAL;
                 break;
@@ -1544,18 +1545,20 @@
         sc->stats.fault_count       = d->arch.shadow_fault_count;
         sc->stats.dirty_count       = d->arch.shadow_dirty_count;
 
-        if ( (sc->dirty_bitmap == NULL) || 
+        if ( guest_handle_is_null(sc->dirty_bitmap) ||
              (d->arch.shadow_dirty_bitmap == NULL) )
         {
             rc = -EINVAL;
             break;
         }
  
-        if(sc->pages > d->arch.shadow_dirty_bitmap_size)
+        if ( sc->pages > d->arch.shadow_dirty_bitmap_size )
             sc->pages = d->arch.shadow_dirty_bitmap_size; 
 
-        if (copy_to_user(sc->dirty_bitmap, 
-                         d->arch.shadow_dirty_bitmap, (sc->pages+7)/8))
+        if ( copy_to_guest(sc->dirty_bitmap, 
+                           d->arch.shadow_dirty_bitmap,
+                           (((sc->pages+7)/8)+sizeof(unsigned long)-1) /
+                           sizeof(unsigned long)) )
         {
             rc = -EINVAL;
             break;
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c      Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/shadow_public.c      Mon Mar  6 17:21:35 2006
@@ -29,6 +29,7 @@
 #include <xen/event.h>
 #include <xen/sched.h>
 #include <xen/trace.h>
+#include <xen/guest_access.h>
 #include <asm/shadow_64.h>
 
 static int alloc_p2m_table(struct domain *d);
@@ -413,7 +414,8 @@
             (l3e_get_flags(mpl3e[i]) & _PAGE_PRESENT) ?
             l2e_from_pfn(l3e_get_pfn(mpl3e[i]), __PAGE_HYPERVISOR) :
             l2e_empty();
-    mpl2e[l2_table_offset(RO_MPT_VIRT_START)] = l2e_empty();
+    for ( i = 0; i < (MACHPHYS_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
+        mpl2e[l2_table_offset(RO_MPT_VIRT_START) + i] = l2e_empty();
 
     v->arch.monitor_table = mk_pagetable(m3mfn << PAGE_SHIFT); /* < 4GB */
     v->arch.monitor_vtable = (l2_pgentry_t *) mpl3e;
@@ -1266,14 +1268,14 @@
         d->arch.shadow_fault_count       = 0;
         d->arch.shadow_dirty_count       = 0;
  
-        if ( (sc->dirty_bitmap == NULL) || 
+        if ( guest_handle_is_null(sc->dirty_bitmap) ||
              (d->arch.shadow_dirty_bitmap == NULL) )
         {
             rc = -EINVAL;
             break;
         }
 
-        if(sc->pages > d->arch.shadow_dirty_bitmap_size)
+        if ( sc->pages > d->arch.shadow_dirty_bitmap_size )
             sc->pages = d->arch.shadow_dirty_bitmap_size; 
 
 #define chunk (8*1024) /* Transfer and clear in 1kB chunks for L1 cache. */
@@ -1282,10 +1284,10 @@
             int bytes = ((((sc->pages - i) > chunk) ?
                           chunk : (sc->pages - i)) + 7) / 8;
 
-            if (copy_to_user(
-                sc->dirty_bitmap + (i/(8*sizeof(unsigned long))),
+            if ( copy_to_guest_offset(
+                sc->dirty_bitmap, i/(8*sizeof(unsigned long)),
                 d->arch.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
-                bytes))
+                (bytes+sizeof(unsigned long)-1) / sizeof(unsigned long)) )
             {
                 rc = -EINVAL;
                 break;
@@ -1301,18 +1303,20 @@
         sc->stats.fault_count       = d->arch.shadow_fault_count;
         sc->stats.dirty_count       = d->arch.shadow_dirty_count;
  
-        if ( (sc->dirty_bitmap == NULL) || 
+        if ( guest_handle_is_null(sc->dirty_bitmap) ||
              (d->arch.shadow_dirty_bitmap == NULL) )
         {
             rc = -EINVAL;
             break;
         }
  
-        if(sc->pages > d->arch.shadow_dirty_bitmap_size)
+        if ( sc->pages > d->arch.shadow_dirty_bitmap_size )
             sc->pages = d->arch.shadow_dirty_bitmap_size; 
 
-        if (copy_to_user(sc->dirty_bitmap, 
-                         d->arch.shadow_dirty_bitmap, (sc->pages+7)/8))
+        if ( copy_to_guest(sc->dirty_bitmap, 
+                           d->arch.shadow_dirty_bitmap,
+                           (((sc->pages+7)/8)+sizeof(unsigned long)-1) /
+                           sizeof(unsigned long)) )
         {
             rc = -EINVAL;
             break;
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/time.c       Mon Mar  6 17:21:35 2006
@@ -41,7 +41,6 @@
 unsigned long cpu_khz;  /* CPU clock frequency in kHz. */
 unsigned long hpet_address;
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
-int timer_ack = 0;
 unsigned long volatile jiffies;
 static u32 wc_sec, wc_nsec; /* UTC time at last 'time update'. */
 static spinlock_t wc_lock = SPIN_LOCK_UNLOCKED;
@@ -148,16 +147,6 @@
 {
     ASSERT(local_irq_is_enabled());
 
-    if ( timer_ack ) 
-    {
-        extern spinlock_t i8259A_lock;
-        spin_lock_irq(&i8259A_lock);
-        outb(0x0c, 0x20);
-        /* Ack the IRQ; AEOI will end it automatically. */
-        inb(0x20);
-        spin_unlock_irq(&i8259A_lock);
-    }
-    
     /* Update jiffies counter. */
     (*(unsigned long *)&jiffies)++;
 
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/traps.c      Mon Mar  6 17:21:35 2006
@@ -1410,7 +1410,13 @@
     struct trap_info *dst = current->arch.guest_context.trap_ctxt;
     long rc = 0;
 
-    LOCK_BIGLOCK(current->domain);
+    /* If no table is presented then clear the entire virtual IDT. */
+    if ( traps == NULL )
+    {
+        memset(dst, 0, 256 * sizeof(*dst));
+        init_int80_direct_trap(current);
+        return 0;
+    }
 
     for ( ; ; )
     {
@@ -1439,8 +1445,6 @@
 
         traps++;
     }
-
-    UNLOCK_BIGLOCK(current->domain);
 
     return rc;
 }
diff -r ede16886f979 -r c4ac21dc3f16 xen/arch/x86/x86_32/domain_page.c
--- a/xen/arch/x86/x86_32/domain_page.c Mon Mar  6 16:09:18 2006
+++ b/xen/arch/x86/x86_32/domain_page.c Mon Mar  6 17:21:35 2006
@@ -11,15 +11,40 @@
 #include <xen/mm.h>
 #include <xen/perfc.h>
 #include <xen/domain_page.h>
+#include <xen/shadow.h>
 #include <asm/current.h>
 #include <asm/flushtlb.h>
 #include <asm/hardirq.h>
 
+static inline struct vcpu *mapcache_current_vcpu(void)
+{
+    struct vcpu *v;
+
+    /* In the common case we use the mapcache of the running VCPU. */
+    v = current;
+
+    /*
+     * If guest_table is NULL, and we are running a paravirtualised guest,
+     * then it means we are running on the idle domain's page table and must
+     * therefore use its mapcache.
+     */
+    if ( unlikely(!pagetable_get_pfn(v->arch.guest_table)) && !HVM_DOMAIN(v) )
+    {
+        /* If we really are idling, perform lazy context switch now. */
+        if ( (v = idle_vcpu[smp_processor_id()]) == current )
+            __sync_lazy_execstate();
+        /* We must now be running on the idle page table. */
+        ASSERT(read_cr3() == __pa(idle_pg_table));
+    }
+
+    return v;
+}
+
 void *map_domain_page(unsigned long pfn)
 {
     unsigned long va;
-    unsigned int idx, i, vcpu = current->vcpu_id;
-    struct domain *d;
+    unsigned int idx, i, vcpu;
+    struct vcpu *v;
     struct mapcache *cache;
     struct vcpu_maphash_entry *hashent;
 
@@ -27,12 +52,10 @@
 
     perfc_incrc(map_domain_page_count);
 
-    /* If we are the idle domain, ensure that we run on our own page tables. */
-    d = current->domain;
-    if ( unlikely(is_idle_domain(d)) )
-        __sync_lazy_execstate();
-
-    cache = &d->arch.mapcache;
+    v = mapcache_current_vcpu();
+
+    vcpu  = v->vcpu_id;
+    cache = &v->domain->arch.mapcache;
 
     hashent = &cache->vcpu_maphash[vcpu].hash[MAPHASH_HASHFN(pfn)];
     if ( hashent->pfn == pfn )
@@ -93,7 +116,8 @@
 void unmap_domain_page(void *va)
 {
     unsigned int idx;
-    struct mapcache *cache = &current->domain->arch.mapcache;
+    struct vcpu *v;
+    struct mapcache *cache;
     unsigned long pfn;
     struct vcpu_maphash_entry *hashent;
 
@@ -102,9 +126,13 @@
     ASSERT((void *)MAPCACHE_VIRT_START <= va);
     ASSERT(va < (void *)MAPCACHE_VIRT_END);
 
+    v = mapcache_current_vcpu();
+
+    cache = &v->domain->arch.mapcache;
+
     idx = ((unsigned long)va - MAPCACHE_VIRT_START) >> PAGE_SHIFT;
     pfn = l1e_get_pfn(cache->l1tab[idx]);
-    hashent = &cache->vcpu_maphash[current->vcpu_id].hash[MAPHASH_HASHFN(pfn)];
+    hashent = &cache->vcpu_maphash[v->vcpu_id].hash[MAPHASH_HASHFN(pfn)];
 
     if ( hashent->idx == idx )
     {
diff -r ede16886f979 -r c4ac21dc3f16 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c     Mon Mar  6 16:09:18 2006
+++ b/xen/common/dom0_ops.c     Mon Mar  6 17:21:35 2006
@@ -17,13 +17,14 @@
 #include <xen/trace.h>
 #include <xen/console.h>
 #include <xen/iocap.h>
+#include <xen/guest_access.h>
 #include <asm/current.h>
 #include <public/dom0_ops.h>
 #include <public/sched_ctl.h>
 #include <acm/acm_hooks.h>
 
 extern long arch_do_dom0_op(
-    struct dom0_op *op, struct dom0_op *u_dom0_op);
+    struct dom0_op *op, GUEST_HANDLE(dom0_op_t) u_dom0_op);
 extern void arch_getdomaininfo_ctxt(
     struct vcpu *, struct vcpu_guest_context *);
 
@@ -89,7 +90,7 @@
     memcpy(info->handle, d->handle, sizeof(xen_domain_handle_t));
 }
 
-long do_dom0_op(struct dom0_op *u_dom0_op)
+long do_dom0_op(GUEST_HANDLE(dom0_op_t) u_dom0_op)
 {
     long ret = 0;
     struct dom0_op curop, *op = &curop;
@@ -99,7 +100,7 @@
     if ( !IS_PRIV(current->domain) )
         return -EPERM;
 
-    if ( copy_from_user(op, u_dom0_op, sizeof(*op)) )
+    if ( copy_from_guest(op, u_dom0_op, 1) )
         return -EFAULT;
 
     if ( op->interface_version != DOM0_INTERFACE_VERSION )
@@ -239,7 +240,7 @@
         ret = 0;
 
         op->u.createdomain.domain = d->domain_id;
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
     }
     break;
@@ -357,7 +358,7 @@
     case DOM0_SCHEDCTL:
     {
         ret = sched_ctl(&op->u.schedctl);
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
     }
     break;
@@ -365,7 +366,7 @@
     case DOM0_ADJUSTDOM:
     {
         ret = sched_adjdom(&op->u.adjustdom);
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
     }
     break;
@@ -398,20 +399,17 @@
 
         getdomaininfo(d, &op->u.getdomaininfo);
 
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )     
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
 
         put_domain(d);
     }
     break;
-
-
 
     case DOM0_GETDOMAININFOLIST:
     { 
         struct domain *d;
         dom0_getdomaininfo_t info;
-        dom0_getdomaininfo_t *buffer = op->u.getdomaininfolist.buffer;
         u32 num_domains = 0;
 
         read_lock(&domlist_lock);
@@ -432,13 +430,13 @@
 
             put_domain(d);
 
-            if ( copy_to_user(buffer, &info, sizeof(dom0_getdomaininfo_t)) )
+            if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer,
+                                      num_domains, &info, 1) )
             {
                 ret = -EFAULT;
                 break;
             }
             
-            buffer++;
             num_domains++;
         }
         
@@ -449,7 +447,7 @@
         
         op->u.getdomaininfolist.num_domains = num_domains;
 
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
     }
     break;
@@ -489,12 +487,12 @@
         if ( v != current )
             vcpu_unpause(v);
 
-        if ( copy_to_user(op->u.getvcpucontext.ctxt, c, sizeof(*c)) )
+        if ( copy_to_guest(op->u.getvcpucontext.ctxt, c, 1) )
             ret = -EFAULT;
 
         xfree(c);
 
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )     
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
 
     getvcpucontext_out:
@@ -534,7 +532,7 @@
                    (int)sizeof(op->u.getvcpuinfo.cpumap)));
         ret = 0;
 
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )     
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
 
     getvcpuinfo_out:
@@ -554,7 +552,7 @@
     case DOM0_TBUFCONTROL:
     {
         ret = tb_control(&op->u.tbufcontrol);
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
     }
     break;
@@ -562,10 +560,10 @@
     case DOM0_READCONSOLE:
     {
         ret = read_console_ring(
-            &op->u.readconsole.buffer, 
+            op->u.readconsole.buffer, 
             &op->u.readconsole.count,
             op->u.readconsole.clear); 
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
     }
     break;
@@ -573,7 +571,7 @@
     case DOM0_SCHED_ID:
     {
         op->u.sched_id.sched_id = sched_id();
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
         else
             ret = 0;
@@ -678,15 +676,15 @@
     {
         extern int perfc_control(dom0_perfccontrol_t *);
         ret = perfc_control(&op->u.perfccontrol);
-        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+        if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
     }
     break;
 #endif
 
     default:
-        ret = arch_do_dom0_op(op,u_dom0_op);
-
+        ret = arch_do_dom0_op(op, u_dom0_op);
+        break;
     }
 
     spin_unlock(&dom0_lock);
diff -r ede16886f979 -r c4ac21dc3f16 xen/common/domain.c
--- a/xen/common/domain.c       Mon Mar  6 16:09:18 2006
+++ b/xen/common/domain.c       Mon Mar  6 17:21:35 2006
@@ -17,6 +17,7 @@
 #include <xen/softirq.h>
 #include <xen/domain_page.h>
 #include <xen/rangeset.h>
+#include <xen/guest_access.h>
 #include <asm/debugger.h>
 #include <public/dom0_ops.h>
 #include <public/sched.h>
@@ -380,7 +381,7 @@
     domain_pause(d);
 
     rc = -EFAULT;
-    if ( copy_from_user(c, setvcpucontext->ctxt, sizeof(*c)) == 0 )
+    if ( copy_from_guest(c, setvcpucontext->ctxt, 1) == 0 )
         rc = arch_set_info_guest(v, c);
 
     domain_unpause(d);
diff -r ede16886f979 -r c4ac21dc3f16 xen/common/gdbstub.c
--- a/xen/common/gdbstub.c      Mon Mar  6 16:09:18 2006
+++ b/xen/common/gdbstub.c      Mon Mar  6 17:21:35 2006
@@ -376,7 +376,6 @@
         break;
     case 'g': /* Read registers */
         gdb_arch_read_reg_array(regs, ctx);
-        ASSERT(!local_irq_is_enabled());
         break;
     case 'G': /* Write registers */
         gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
@@ -395,7 +394,6 @@
             return 0;
         }
         gdb_cmd_read_mem(addr, length, ctx);
-        ASSERT(!local_irq_is_enabled());
         break;
     case 'M': /* Write memory */
         addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
@@ -477,7 +475,7 @@
 {
     int resume = 0;
     int r;
-    unsigned flags;
+    unsigned long flags;
 
     if ( gdb_ctx->serhnd < 0 )
     {
@@ -506,7 +504,7 @@
 
     if ( !gdb_ctx->connected )
     {
-        printk("GDB connection activated\n");
+        printk("GDB connection activated.\n");
         gdb_arch_print_state(regs);
         gdb_ctx->connected = 1;
     }
@@ -522,7 +520,7 @@
 
     /* Shouldn't really do this, but otherwise we stop for no
        obvious reason, which is Bad */
-    printk("Waiting for GDB to attach to Gdb\n");
+    printk("Waiting for GDB to attach...\n");
 
     gdb_arch_enter(regs);
     gdb_ctx->signum = gdb_arch_signal_num(regs, cookie);
@@ -535,9 +533,7 @@
 
     while ( resume == 0 )
     {
-        ASSERT(!local_irq_is_enabled());
         r = receive_command(gdb_ctx);
-        ASSERT(!local_irq_is_enabled());
         if ( r < 0 )
         {
             dbg_printk("GDB disappeared, trying to resume Xen...\n");
@@ -545,9 +541,7 @@
         }
         else
         {
-            ASSERT(!local_irq_is_enabled());
             resume = process_command(regs, gdb_ctx);
-            ASSERT(!local_irq_is_enabled());
         }
     }
 
@@ -561,27 +555,13 @@
     return 0;
 }
 
-/*
- * initialization
- * XXX TODO
- *     This should be an explicit call from architecture code.               
- *     initcall is far too late for some early debugging, and only the 
- *     architecture code knows when this call can be made.          
- */
-static int
-initialize_gdb(void)
-{
-    if ( !strcmp(opt_gdb, "none") )
-        return 0;
+void
+initialise_gdb(void)
+{
     gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
-    if ( gdb_ctx->serhnd == -1 )
-        panic("Can't parse %s as GDB serial info.\n", opt_gdb);
-
-    printk("Gdb initialised.\n");
-    return 0;
-}
-
-__initcall(initialize_gdb);
+    if ( gdb_ctx->serhnd != -1 )
+        printk("GDB stub initialised.\n");
+}
 
 /*
  * Local variables:
diff -r ede16886f979 -r c4ac21dc3f16 xen/common/memory.c
--- a/xen/common/memory.c       Mon Mar  6 16:09:18 2006
+++ b/xen/common/memory.c       Mon Mar  6 17:21:35 2006
@@ -31,7 +31,7 @@
 static long
 increase_reservation(
     struct domain *d, 
-    GUEST_HANDLE(xen_ulong) extent_list,
+    GUEST_HANDLE(ulong) extent_list,
     unsigned int   nr_extents,
     unsigned int   extent_order,
     unsigned int   flags,
@@ -80,7 +80,7 @@
 static long
 populate_physmap(
     struct domain *d, 
-    GUEST_HANDLE(xen_ulong) extent_list,
+    GUEST_HANDLE(ulong) extent_list,
     unsigned int  nr_extents,
     unsigned int  extent_order,
     unsigned int  flags,
@@ -141,7 +141,7 @@
 static long
 decrease_reservation(
     struct domain *d,
-    GUEST_HANDLE(xen_ulong) extent_list,
+    GUEST_HANDLE(ulong) extent_list,
     unsigned int   nr_extents,
     unsigned int   extent_order,
     unsigned int   flags,
diff -r ede16886f979 -r c4ac21dc3f16 xen/common/perfc.c
--- a/xen/common/perfc.c        Mon Mar  6 16:09:18 2006
+++ b/xen/common/perfc.c        Mon Mar  6 17:21:35 2006
@@ -5,9 +5,10 @@
 #include <xen/perfc.h>
 #include <xen/keyhandler.h> 
 #include <xen/spinlock.h>
+#include <xen/mm.h>
+#include <xen/guest_access.h>
 #include <public/dom0_ops.h>
 #include <asm/uaccess.h>
-#include <xen/mm.h>
 
 #undef  PERFCOUNTER
 #undef  PERFCOUNTER_CPU
@@ -131,12 +132,12 @@
 
 static dom0_perfc_desc_t perfc_d[NR_PERFCTRS];
 static int               perfc_init = 0;
-static int perfc_copy_info(dom0_perfc_desc_t *desc)
+static int perfc_copy_info(GUEST_HANDLE(dom0_perfc_desc_t) desc)
 {
     unsigned int i, j;
     atomic_t *counters = (atomic_t *)&perfcounters;
 
-    if ( desc == NULL )
+    if ( guest_handle_is_null(desc) )
         return 0;
 
     /* We only copy the name and array-size information once. */
@@ -196,7 +197,7 @@
         }
     }
 
-    return (copy_to_user(desc, perfc_d, NR_PERFCTRS * sizeof(*desc)) ?
+    return (copy_to_guest(desc, (dom0_perfc_desc_t *)perfc_d, NR_PERFCTRS) ?
             -EFAULT : 0);
 }
 
diff -r ede16886f979 -r c4ac21dc3f16 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Mon Mar  6 16:09:18 2006
+++ b/xen/drivers/char/console.c        Mon Mar  6 17:21:35 2006
@@ -20,6 +20,7 @@
 #include <xen/keyhandler.h>
 #include <xen/mm.h>
 #include <xen/delay.h>
+#include <xen/guest_access.h>
 #include <asm/current.h>
 #include <asm/uaccess.h>
 #include <asm/debugger.h>
@@ -221,9 +222,8 @@
         conringc = conringp - CONRING_SIZE;
 }
 
-long read_console_ring(char **pstr, u32 *pcount, int clear)
-{
-    char *str = *pstr;
+long read_console_ring(GUEST_HANDLE(char) str, u32 *pcount, int clear)
+{
     unsigned int idx, len, max, sofar, c;
     unsigned long flags;
 
@@ -239,7 +239,7 @@
             len = CONRING_SIZE - idx;
         if ( (sofar + len) > max )
             len = max - sofar;
-        if ( copy_to_user(str + sofar, &conring[idx], len) )
+        if ( copy_to_guest_offset(str, sofar, &conring[idx], len) )
             return -EFAULT;
         sofar += len;
         c += len;
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Mon Mar  6 16:09:18 2006
+++ b/xen/include/asm-x86/hvm/support.h Mon Mar  6 17:21:35 2006
@@ -26,7 +26,11 @@
 #include <asm/regs.h>
 #include <asm/processor.h>
 
+#ifndef NDEBUG
 #define HVM_DEBUG 1
+#else
+#define HVM_DEBUG 0
+#endif
 
 #define        HVM_DOMAIN(v)   ((v)->arch.guest_context.flags & VGCF_HVM_GUEST)
 
@@ -113,7 +117,7 @@
 #define DBG_LEVEL_VMMU              (1 << 5)
 #define DBG_LEVEL_VLAPIC            (1 << 6)
 #define DBG_LEVEL_VLAPIC_TIMER      (1 << 7)
-#define DBG_LEVEL_VLAPIC_INTERRUPT  (1 << 7)
+#define DBG_LEVEL_VLAPIC_INTERRUPT  (1 << 8)
 #define DBG_LEVEL_IOAPIC            (1 << 9)
 
 extern unsigned int opt_hvm_debug_level;
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Mon Mar  6 16:09:18 2006
+++ b/xen/include/asm-x86/processor.h   Mon Mar  6 17:21:35 2006
@@ -352,6 +352,13 @@
        outb((reg), 0x22); \
        outb((data), 0x23); \
 } while (0)
+
+/* Stop speculative execution */
+static inline void sync_core(void)
+{
+    int tmp;
+    asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
+}
 
 static always_inline void __monitor(const void *eax, unsigned long ecx,
                unsigned long edx)
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/asm-x86/time.h
--- a/xen/include/asm-x86/time.h        Mon Mar  6 16:09:18 2006
+++ b/xen/include/asm-x86/time.h        Mon Mar  6 17:21:35 2006
@@ -3,8 +3,6 @@
 #define __X86_TIME_H__
 
 #include <asm/msr.h>
-
-extern int timer_ack;
 
 extern void calibrate_tsc_bp(void);
 extern void calibrate_tsc_ap(void);
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Mon Mar  6 16:09:18 2006
+++ b/xen/include/public/arch-ia64.h    Mon Mar  6 17:21:35 2006
@@ -6,6 +6,28 @@
 
 #ifndef __HYPERVISOR_IF_IA64_H__
 #define __HYPERVISOR_IF_IA64_H__
+
+#ifdef __XEN__
+#define __DEFINE_GUEST_HANDLE(name, type) \
+    typedef struct { type *p; } __guest_handle_ ## name
+#else
+#define __DEFINE_GUEST_HANDLE(name, type) \
+    typedef type * __guest_handle_ ## name
+#endif
+
+#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
+#define GUEST_HANDLE(name)        __guest_handle_ ## name
+
+#ifndef __ASSEMBLY__
+/* Guest handles for primitive C types. */
+__DEFINE_GUEST_HANDLE(uchar, unsigned char);
+__DEFINE_GUEST_HANDLE(uint,  unsigned int);
+__DEFINE_GUEST_HANDLE(ulong, unsigned long);
+DEFINE_GUEST_HANDLE(char);
+DEFINE_GUEST_HANDLE(int);
+DEFINE_GUEST_HANDLE(long);
+DEFINE_GUEST_HANDLE(void);
+#endif
 
 /* Maximum number of virtual CPUs in multi-processor guests. */
 /* WARNING: before changing this, check that shared_info fits on a page */
@@ -298,6 +320,7 @@
     arch_initrd_info_t initrd;
     char cmdline[IA64_COMMAND_LINE_SIZE];
 } vcpu_guest_context_t;
+DEFINE_GUEST_HANDLE(vcpu_guest_context_t);
 
 #endif /* !__ASSEMBLY__ */
 
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h  Mon Mar  6 16:09:18 2006
+++ b/xen/include/public/arch-x86_32.h  Mon Mar  6 17:21:35 2006
@@ -8,6 +8,28 @@
 
 #ifndef __XEN_PUBLIC_ARCH_X86_32_H__
 #define __XEN_PUBLIC_ARCH_X86_32_H__
+
+#ifdef __XEN__
+#define __DEFINE_GUEST_HANDLE(name, type) \
+    typedef struct { type *p; } __guest_handle_ ## name
+#else
+#define __DEFINE_GUEST_HANDLE(name, type) \
+    typedef type * __guest_handle_ ## name
+#endif
+
+#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
+#define GUEST_HANDLE(name)        __guest_handle_ ## name
+
+#ifndef __ASSEMBLY__
+/* Guest handles for primitive C types. */
+__DEFINE_GUEST_HANDLE(uchar, unsigned char);
+__DEFINE_GUEST_HANDLE(uint,  unsigned int);
+__DEFINE_GUEST_HANDLE(ulong, unsigned long);
+DEFINE_GUEST_HANDLE(char);
+DEFINE_GUEST_HANDLE(int);
+DEFINE_GUEST_HANDLE(long);
+DEFINE_GUEST_HANDLE(void);
+#endif
 
 /*
  * SEGMENT DESCRIPTOR TABLES
@@ -130,6 +152,7 @@
     unsigned long failsafe_callback_eip;
     unsigned long vm_assist;                /* VMASST_TYPE_* bitmap */
 } vcpu_guest_context_t;
+DEFINE_GUEST_HANDLE(vcpu_guest_context_t);
 
 typedef struct arch_shared_info {
     unsigned long max_pfn;                  /* max pfn that appears in table */
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h  Mon Mar  6 16:09:18 2006
+++ b/xen/include/public/arch-x86_64.h  Mon Mar  6 17:21:35 2006
@@ -8,6 +8,28 @@
 
 #ifndef __XEN_PUBLIC_ARCH_X86_64_H__
 #define __XEN_PUBLIC_ARCH_X86_64_H__
+
+#ifdef __XEN__
+#define __DEFINE_GUEST_HANDLE(name, type) \
+    typedef struct { type *p; } __guest_handle_ ## name
+#else
+#define __DEFINE_GUEST_HANDLE(name, type) \
+    typedef type * __guest_handle_ ## name
+#endif
+
+#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
+#define GUEST_HANDLE(name)        __guest_handle_ ## name
+
+#ifndef __ASSEMBLY__
+/* Guest handles for primitive C types. */
+__DEFINE_GUEST_HANDLE(uchar, unsigned char);
+__DEFINE_GUEST_HANDLE(uint,  unsigned int);
+__DEFINE_GUEST_HANDLE(ulong, unsigned long);
+DEFINE_GUEST_HANDLE(char);
+DEFINE_GUEST_HANDLE(int);
+DEFINE_GUEST_HANDLE(long);
+DEFINE_GUEST_HANDLE(void);
+#endif
 
 /*
  * SEGMENT DESCRIPTOR TABLES
@@ -215,6 +237,7 @@
     uint64_t      gs_base_kernel;
     uint64_t      gs_base_user;
 } vcpu_guest_context_t;
+DEFINE_GUEST_HANDLE(vcpu_guest_context_t);
 
 typedef struct arch_shared_info {
     unsigned long max_pfn;                  /* max pfn that appears in table */
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Mon Mar  6 16:09:18 2006
+++ b/xen/include/public/dom0_ops.h     Mon Mar  6 17:21:35 2006
@@ -28,18 +28,21 @@
     /* IN variables. */
     domid_t       domain;
     unsigned long max_pfns;
-    void         *buffer;
+    GUEST_HANDLE(ulong) buffer;
     /* OUT variables. */
     unsigned long num_pfns;
 } dom0_getmemlist_t;
+DEFINE_GUEST_HANDLE(dom0_getmemlist_t);
 
 #define DOM0_SCHEDCTL          6
  /* struct sched_ctl_cmd is from sched-ctl.h   */
 typedef struct sched_ctl_cmd dom0_schedctl_t;
+DEFINE_GUEST_HANDLE(dom0_schedctl_t);
 
 #define DOM0_ADJUSTDOM         7
 /* struct sched_adjdom_cmd is from sched-ctl.h */
 typedef struct sched_adjdom_cmd dom0_adjustdom_t;
+DEFINE_GUEST_HANDLE(dom0_adjustdom_t);
 
 #define DOM0_CREATEDOMAIN      8
 typedef struct dom0_createdomain {
@@ -50,24 +53,28 @@
     /* Identifier for new domain (auto-allocate if zero is specified). */
     domid_t domain;
 } dom0_createdomain_t;
+DEFINE_GUEST_HANDLE(dom0_createdomain_t);
 
 #define DOM0_DESTROYDOMAIN     9
 typedef struct dom0_destroydomain {
     /* IN variables. */
     domid_t domain;
 } dom0_destroydomain_t;
+DEFINE_GUEST_HANDLE(dom0_destroydomain_t);
 
 #define DOM0_PAUSEDOMAIN      10
 typedef struct dom0_pausedomain {
     /* IN parameters. */
     domid_t domain;
 } dom0_pausedomain_t;
+DEFINE_GUEST_HANDLE(dom0_pausedomain_t);
 
 #define DOM0_UNPAUSEDOMAIN    11
 typedef struct dom0_unpausedomain {
     /* IN parameters. */
     domid_t domain;
 } dom0_unpausedomain_t;
+DEFINE_GUEST_HANDLE(dom0_unpausedomain_t);
 
 #define DOM0_GETDOMAININFO    12
 typedef struct dom0_getdomaininfo {
@@ -93,6 +100,7 @@
     uint32_t ssidref;
     xen_domain_handle_t handle;
 } dom0_getdomaininfo_t;
+DEFINE_GUEST_HANDLE(dom0_getdomaininfo_t);
 
 #define DOM0_SETVCPUCONTEXT   13
 typedef struct dom0_setvcpucontext {
@@ -100,8 +108,9 @@
     domid_t               domain;
     uint32_t              vcpu;
     /* IN/OUT parameters */
-    vcpu_guest_context_t *ctxt;
+    GUEST_HANDLE(vcpu_guest_context_t) ctxt;
 } dom0_setvcpucontext_t;
+DEFINE_GUEST_HANDLE(dom0_setvcpucontext_t);
 
 #define DOM0_MSR              15
 typedef struct dom0_msr {
@@ -115,6 +124,7 @@
     uint32_t out1;
     uint32_t out2;
 } dom0_msr_t;
+DEFINE_GUEST_HANDLE(dom0_msr_t);
 
 /*
  * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC,
@@ -127,6 +137,7 @@
     uint32_t nsecs;
     uint64_t system_time;
 } dom0_settime_t;
+DEFINE_GUEST_HANDLE(dom0_settime_t);
 
 #define DOM0_GETPAGEFRAMEINFO 18
 #define NOTAB 0         /* normal page */
@@ -147,6 +158,7 @@
     /* Is the page PINNED to a type? */
     uint32_t type;         /* see above type defs */
 } dom0_getpageframeinfo_t;
+DEFINE_GUEST_HANDLE(dom0_getpageframeinfo_t);
 
 /*
  * Read console content from Xen buffer ring.
@@ -154,11 +166,12 @@
 #define DOM0_READCONSOLE      19
 typedef struct dom0_readconsole {
     /* IN variables. */
-    uint32_t clear;        /* Non-zero -> clear after reading. */
+    uint32_t clear;            /* Non-zero -> clear after reading. */
     /* IN/OUT variables. */
-    char    *buffer;       /* In: Buffer start; Out: Used buffer start */
-    uint32_t count;        /* In: Buffer size;  Out: Used buffer size  */
+    GUEST_HANDLE(char) buffer; /* In: Buffer start; Out: Used buffer start */
+    uint32_t count;            /* In: Buffer size;  Out: Used buffer size  */
 } dom0_readconsole_t;
+DEFINE_GUEST_HANDLE(dom0_readconsole_t);
 
 /* 
  * Set which physical cpus a vcpu can execute on.
@@ -170,6 +183,7 @@
     uint32_t  vcpu;
     cpumap_t  cpumap;
 } dom0_setvcpuaffinity_t;
+DEFINE_GUEST_HANDLE(dom0_setvcpuaffinity_t);
 
 /* Get trace buffers machine base address */
 #define DOM0_TBUFCONTROL       21
@@ -189,6 +203,7 @@
     unsigned long buffer_mfn;
     uint32_t size;
 } dom0_tbufcontrol_t;
+DEFINE_GUEST_HANDLE(dom0_tbufcontrol_t);
 
 /*
  * Get physical information about the host machine
@@ -204,6 +219,7 @@
     unsigned long free_pages;
     uint32_t hw_cap[8];
 } dom0_physinfo_t;
+DEFINE_GUEST_HANDLE(dom0_physinfo_t);
 
 /*
  * Get the ID of the current scheduler.
@@ -213,6 +229,7 @@
     /* OUT variable */
     uint32_t sched_id;
 } dom0_sched_id_t;
+DEFINE_GUEST_HANDLE(dom0_sched_id_t);
 
 /* 
  * Control shadow pagetables operation
@@ -234,17 +251,19 @@
     uint32_t dirty_net_count;     
     uint32_t dirty_block_count;     
 } dom0_shadow_control_stats_t;
+DEFINE_GUEST_HANDLE(dom0_shadow_control_stats_t);
 
 typedef struct dom0_shadow_control {
     /* IN variables. */
     domid_t        domain;
     uint32_t       op;
-    unsigned long *dirty_bitmap; /* pointer to locked buffer */
+    GUEST_HANDLE(ulong) dirty_bitmap;
     /* IN/OUT variables. */
     unsigned long  pages;        /* size of buffer, updated with actual size */
     /* OUT variables. */
     dom0_shadow_control_stats_t stats;
 } dom0_shadow_control_t;
+DEFINE_GUEST_HANDLE(dom0_shadow_control_t);
 
 #define DOM0_SETDOMAINMAXMEM   28
 typedef struct dom0_setdomainmaxmem {
@@ -252,6 +271,7 @@
     domid_t       domain;
     unsigned long max_memkb;
 } dom0_setdomainmaxmem_t;
+DEFINE_GUEST_HANDLE(dom0_setdomainmaxmem_t);
 
 #define DOM0_GETPAGEFRAMEINFO2 29   /* batched interface */
 typedef struct dom0_getpageframeinfo2 {
@@ -259,8 +279,9 @@
     domid_t        domain;
     unsigned long  num;
     /* IN/OUT variables. */
-    unsigned long *array;
+    GUEST_HANDLE(ulong) array;
 } dom0_getpageframeinfo2_t;
+DEFINE_GUEST_HANDLE(dom0_getpageframeinfo2_t);
 
 /*
  * Request memory range (@mfn, @mfn+@nr_mfns-1) to have type @type.
@@ -279,6 +300,7 @@
     uint32_t      handle;
     uint32_t      reg;
 } dom0_add_memtype_t;
+DEFINE_GUEST_HANDLE(dom0_add_memtype_t);
 
 /*
  * Tear down an existing memory-range type. If @handle is remembered then it
@@ -293,6 +315,7 @@
     uint32_t handle;
     uint32_t reg;
 } dom0_del_memtype_t;
+DEFINE_GUEST_HANDLE(dom0_del_memtype_t);
 
 /* Read current type of an MTRR (x86-specific). */
 #define DOM0_READ_MEMTYPE        33
@@ -304,6 +327,7 @@
     unsigned long nr_mfns;
     uint32_t type;
 } dom0_read_memtype_t;
+DEFINE_GUEST_HANDLE(dom0_read_memtype_t);
 
 /* Interface for controlling Xen software performance counters. */
 #define DOM0_PERFCCONTROL        34
@@ -315,20 +339,23 @@
     uint32_t     nr_vals;              /* number of values for this counter */
     uint32_t     vals[64];             /* array of values */
 } dom0_perfc_desc_t;
+DEFINE_GUEST_HANDLE(dom0_perfc_desc_t);
 typedef struct dom0_perfccontrol {
     /* IN variables. */
     uint32_t       op;                /*  DOM0_PERFCCONTROL_OP_??? */
     /* OUT variables. */
     uint32_t       nr_counters;       /*  number of counters */
-    dom0_perfc_desc_t *desc;          /*  counter information (or NULL) */
+    GUEST_HANDLE(dom0_perfc_desc_t) desc; /*  counter information (or NULL) */
 } dom0_perfccontrol_t;
+DEFINE_GUEST_HANDLE(dom0_perfccontrol_t);
 
 #define DOM0_MICROCODE           35
 typedef struct dom0_microcode {
     /* IN variables. */
-    void    *data;                    /* Pointer to microcode data */
+    GUEST_HANDLE(void) data;          /* Pointer to microcode data */
     uint32_t length;                  /* Length of microcode data. */
 } dom0_microcode_t;
+DEFINE_GUEST_HANDLE(dom0_microcode_t);
 
 #define DOM0_IOPORT_PERMISSION   36
 typedef struct dom0_ioport_permission {
@@ -337,6 +364,7 @@
     uint32_t nr_ports;                /* size of port range */
     uint8_t  allow_access;            /* allow or deny access to range? */
 } dom0_ioport_permission_t;
+DEFINE_GUEST_HANDLE(dom0_ioport_permission_t);
 
 #define DOM0_GETVCPUCONTEXT      37
 typedef struct dom0_getvcpucontext {
@@ -344,8 +372,9 @@
     domid_t  domain;                  /* domain to be affected */
     uint32_t vcpu;                    /* vcpu # */
     /* OUT variables. */
-    vcpu_guest_context_t *ctxt;
+    GUEST_HANDLE(vcpu_guest_context_t) ctxt;
 } dom0_getvcpucontext_t;
+DEFINE_GUEST_HANDLE(dom0_getvcpucontext_t);
 
 #define DOM0_GETVCPUINFO         43
 typedef struct dom0_getvcpuinfo {
@@ -360,16 +389,18 @@
     uint32_t cpu;                     /* current mapping   */
     cpumap_t cpumap;                  /* allowable mapping */
 } dom0_getvcpuinfo_t;
+DEFINE_GUEST_HANDLE(dom0_getvcpuinfo_t);
 
 #define DOM0_GETDOMAININFOLIST   38
 typedef struct dom0_getdomaininfolist {
     /* IN variables. */
     domid_t               first_domain;
     uint32_t              max_domains;
-    dom0_getdomaininfo_t *buffer;
+    GUEST_HANDLE(dom0_getdomaininfo_t) buffer;
     /* OUT variables. */
     uint32_t              num_domains;
 } dom0_getdomaininfolist_t;
+DEFINE_GUEST_HANDLE(dom0_getdomaininfolist_t);
 
 #define DOM0_PLATFORM_QUIRK      39  
 #define QUIRK_NOIRQBALANCING  1
@@ -377,37 +408,44 @@
     /* IN variables. */
     uint32_t quirk_id;
 } dom0_platform_quirk_t;
+DEFINE_GUEST_HANDLE(dom0_platform_quirk_t);
 
 #define DOM0_PHYSICAL_MEMORY_MAP 40
+typedef struct dom0_memory_map_entry {
+    uint64_t start, end;
+    uint32_t flags; /* reserved */
+    uint8_t  is_ram;
+} dom0_memory_map_entry_t;
+DEFINE_GUEST_HANDLE(dom0_memory_map_entry_t);
 typedef struct dom0_physical_memory_map {
     /* IN variables. */
     uint32_t max_map_entries;
     /* OUT variables. */
     uint32_t nr_map_entries;
-    struct dom0_memory_map_entry {
-        uint64_t start, end;
-        uint32_t flags; /* reserved */
-        uint8_t  is_ram;
-    } *memory_map;
+    GUEST_HANDLE(dom0_memory_map_entry_t) memory_map;
 } dom0_physical_memory_map_t;
+DEFINE_GUEST_HANDLE(dom0_physical_memory_map_t);
 
 #define DOM0_MAX_VCPUS 41
 typedef struct dom0_max_vcpus {
     domid_t  domain;        /* domain to be affected */
     uint32_t max;           /* maximum number of vcpus */
 } dom0_max_vcpus_t;
+DEFINE_GUEST_HANDLE(dom0_max_vcpus_t);
 
 #define DOM0_SETDOMAINHANDLE 44
 typedef struct dom0_setdomainhandle {
     domid_t domain;
     xen_domain_handle_t handle;
 } dom0_setdomainhandle_t;
+DEFINE_GUEST_HANDLE(dom0_setdomainhandle_t);
 
 #define DOM0_SETDEBUGGING 45
 typedef struct dom0_setdebugging {
     domid_t domain;
     uint8_t enable;
 } dom0_setdebugging_t;
+DEFINE_GUEST_HANDLE(dom0_setdebugging_t);
 
 #define DOM0_IRQ_PERMISSION 46
 typedef struct dom0_irq_permission {
@@ -415,6 +453,7 @@
     uint8_t pirq;
     uint8_t allow_access;    /* flag to specify enable/disable of IRQ access */
 } dom0_irq_permission_t;
+DEFINE_GUEST_HANDLE(dom0_irq_permission_t);
 
 #define DOM0_IOMEM_PERMISSION 47
 typedef struct dom0_iomem_permission {
@@ -423,12 +462,14 @@
     unsigned long nr_mfns;    /* number of pages in range (>0) */
     uint8_t allow_access;     /* allow (!0) or deny (0) access to range? */
 } dom0_iomem_permission_t;
+DEFINE_GUEST_HANDLE(dom0_iomem_permission_t);
  
 #define DOM0_HYPERCALL_INIT   48
 typedef struct dom0_hypercall_init {
     domid_t  domain;          /* domain to be affected */
     unsigned long mfn;        /* machine frame to be initialised */
 } dom0_hypercall_init_t;
+DEFINE_GUEST_HANDLE(dom0_hypercall_init_t);
  
 typedef struct dom0_op {
     uint32_t cmd;
@@ -471,9 +512,10 @@
         struct dom0_irq_permission    irq_permission;
         struct dom0_iomem_permission  iomem_permission;
         struct dom0_hypercall_init    hypercall_init;
-        uint8_t                  pad[128];
+        uint8_t                       pad[128];
     } u;
 } dom0_op_t;
+DEFINE_GUEST_HANDLE(dom0_op_t);
 
 #endif /* __XEN_PUBLIC_DOM0_OPS_H__ */
 
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h    Mon Mar  6 16:09:18 2006
+++ b/xen/include/public/hvm/ioreq.h    Mon Mar  6 17:21:35 2006
@@ -71,8 +71,8 @@
 typedef struct {
     ioreq_t         vp_ioreq;
     /* Event channel port */
-    unsigned long   vp_eport;   /* VMX vcpu uses this to notify DM */
-    unsigned long   dm_eport;   /* DM uses this to notify VMX vcpu */
+    unsigned int    vp_eport;   /* VMX vcpu uses this to notify DM */
+    unsigned int    dm_eport;   /* DM uses this to notify VMX vcpu */
 } vcpu_iodata_t;
 
 typedef struct {
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/public/io/tpmif.h
--- a/xen/include/public/io/tpmif.h     Mon Mar  6 16:09:18 2006
+++ b/xen/include/public/io/tpmif.h     Mon Mar  6 17:21:35 2006
@@ -21,7 +21,7 @@
 typedef struct {
     unsigned long addr;   /* Machine address of packet.   */
     grant_ref_t ref;      /* grant table access reference */
-    uint16_t id;          /* Echoed in response message.  */
+    uint16_t unused;
     uint16_t size;        /* Packet size in bytes.        */
 } tpmif_tx_request_t;
 
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/public/memory.h
--- a/xen/include/public/memory.h       Mon Mar  6 16:09:18 2006
+++ b/xen/include/public/memory.h       Mon Mar  6 17:21:35 2006
@@ -29,7 +29,7 @@
      *   OUT: GMFN bases of extents that were allocated
      *   (NB. This command also updates the mach_to_phys translation table)
      */
-    GUEST_HANDLE(xen_ulong) extent_start;
+    GUEST_HANDLE(ulong) extent_start;
 
     /* Number of extents, and size/alignment of each (2^extent_order pages). */
     unsigned long  nr_extents;
@@ -86,7 +86,7 @@
      * any large discontiguities in the machine address space, 2MB gaps in
      * the machphys table will be represented by an MFN base of zero.
      */
-    GUEST_HANDLE(xen_ulong) extent_start;
+    GUEST_HANDLE(ulong) extent_start;
 
     /*
      * Number of extents written to the above array. This will be smaller
@@ -130,13 +130,13 @@
     unsigned long nr_gpfns;
 
     /* List of GPFNs to translate. */
-    GUEST_HANDLE(xen_ulong) gpfn_list;
+    GUEST_HANDLE(ulong) gpfn_list;
 
     /*
      * Output list to contain MFN translations. May be the same as the input
      * list (in which case each input GPFN is overwritten with the output MFN).
      */
-    GUEST_HANDLE(xen_ulong) mfn_list;
+    GUEST_HANDLE(ulong) mfn_list;
 } xen_translate_gpfn_list_t;
 DEFINE_GUEST_HANDLE(xen_translate_gpfn_list_t);
 
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/public/physdev.h
--- a/xen/include/public/physdev.h      Mon Mar  6 16:09:18 2006
+++ b/xen/include/public/physdev.h      Mon Mar  6 17:21:35 2006
@@ -33,8 +33,8 @@
 
 typedef struct physdevop_apic {
     /* IN */
-    uint32_t apic;
-    uint32_t offset;
+    unsigned long apic_physbase;
+    uint32_t reg;
     /* IN or OUT */
     uint32_t value;
 } physdevop_apic_t; 
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Mon Mar  6 16:09:18 2006
+++ b/xen/include/public/xen.h  Mon Mar  6 17:21:35 2006
@@ -8,22 +8,6 @@
 
 #ifndef __XEN_PUBLIC_XEN_H__
 #define __XEN_PUBLIC_XEN_H__
-
-#ifdef __XEN__
-#define DEFINE_GUEST_HANDLE(type) struct __guest_handle_ ## type { type *p; }
-#define GUEST_HANDLE(type)        struct __guest_handle_ ## type
-#else
-#define DEFINE_GUEST_HANDLE(type)
-#define GUEST_HANDLE(type)        type *
-#endif
-
-#ifndef __ASSEMBLY__
-/* Guest handle for unsigned long pointer. Define a name with no whitespace. */
-typedef unsigned long xen_ulong;
-DEFINE_GUEST_HANDLE(xen_ulong);
-/* Guest handle for arbitrary-type pointer (void *). */
-DEFINE_GUEST_HANDLE(void);
-#endif
 
 #if defined(__i386__)
 #include "arch-x86_32.h"
@@ -396,8 +380,8 @@
  *      a. relocated kernel image
  *      b. initial ram disk              [mod_start, mod_len]
  *      c. list of allocated page frames [mfn_list, nr_pages]
- *      d. bootstrap page tables         [pt_base, CR3 (x86)]
- *      e. start_info_t structure        [register ESI (x86)]
+ *      d. start_info_t structure        [register ESI (x86)]
+ *      e. bootstrap page tables         [pt_base, CR3 (x86)]
  *      f. bootstrap stack               [register ESP (x86)]
  *  5. Bootstrap elements are packed together, but each is 4kB-aligned.
  *  6. The initial ram disk may be omitted.
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/xen/console.h
--- a/xen/include/xen/console.h Mon Mar  6 16:09:18 2006
+++ b/xen/include/xen/console.h Mon Mar  6 17:21:35 2006
@@ -8,12 +8,13 @@
 #define __CONSOLE_H__
 
 #include <xen/spinlock.h>
+#include <xen/guest_access.h>
 
 extern spinlock_t console_lock;
 
 void set_printk_prefix(const char *prefix);
 
-long read_console_ring(char **, u32 *, int);
+long read_console_ring(GUEST_HANDLE(char), u32 *, int);
 
 void init_console(void);
 void console_endboot(int disable_vga);
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/xen/gdbstub.h
--- a/xen/include/xen/gdbstub.h Mon Mar  6 16:09:18 2006
+++ b/xen/include/xen/gdbstub.h Mon Mar  6 17:21:35 2006
@@ -20,6 +20,8 @@
 
 #ifndef __XEN_GDBSTUB_H__
 #define __XEN_GDBSTUB_H__
+
+#ifdef CRASH_DEBUG
 
 /* value <-> char (de)serialzers for arch specific gdb backends */
 char hex2char(unsigned long x); 
@@ -84,6 +86,14 @@
 #define SIGALRM         14
 #define SIGTERM         15
 
+void initialise_gdb(void);
+
+#else
+
+#define initialise_gdb() ((void)0)
+
+#endif
+
 #endif /* __XEN_GDBSTUB_H__ */
 
 /*
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/xen/guest_access.h
--- a/xen/include/xen/guest_access.h    Mon Mar  6 16:09:18 2006
+++ b/xen/include/xen/guest_access.h    Mon Mar  6 17:21:35 2006
@@ -7,64 +7,17 @@
 #ifndef __XEN_GUEST_ACCESS_H__
 #define __XEN_GUEST_ACCESS_H__
 
-#include <asm/uaccess.h>
+#include <asm/guest_access.h>
 
-/* Is the guest handle a NULL reference? */
-#define guest_handle_is_null(hnd)        ((hnd).p == NULL)
-
-/* Offset the given guest handle into the array it refers to. */
-#define guest_handle_add_offset(hnd, nr) ((hnd).p += (nr))
-
-/* Cast a guest handle to the specified type of handle. */
-#define guest_handle_cast(hnd, type) ({         \
-    type *_x = (hnd).p;                         \
-    (GUEST_HANDLE(type)) { _x };                \
-})
-
-/*
- * Copy an array of objects to guest context via a guest handle.
- * Optionally specify an offset into the guest array.
- */
-#define copy_to_guest_offset(hnd, off, ptr, nr) ({      \
-    const typeof(ptr) _x = (hnd).p;                     \
-    const typeof(ptr) _y = (ptr);                       \
-    copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));       \
-})
 #define copy_to_guest(hnd, ptr, nr)                     \
     copy_to_guest_offset(hnd, 0, ptr, nr)
 
-/*
- * Copy an array of objects from guest context via a guest handle.
- * Optionally specify an offset into the guest array.
- */
-#define copy_from_guest_offset(ptr, hnd, off, nr) ({    \
-    const typeof(ptr) _x = (hnd).p;                     \
-    const typeof(ptr) _y = (ptr);                       \
-    copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));     \
-})
 #define copy_from_guest(ptr, hnd, nr)                   \
     copy_from_guest_offset(ptr, hnd, 0, nr)
 
-/*
- * Pre-validate a guest handle.
- * Allows use of faster __copy_* functions.
- */
-#define guest_handle_okay(hnd, nr)                      \
-    array_access_ok((hnd).p, (nr), sizeof(*(hnd).p))
-
-#define __copy_to_guest_offset(hnd, off, ptr, nr) ({    \
-    const typeof(ptr) _x = (hnd).p;                     \
-    const typeof(ptr) _y = (ptr);                       \
-    __copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));     \
-})
 #define __copy_to_guest(hnd, ptr, nr)                   \
     __copy_to_guest_offset(hnd, 0, ptr, nr)
 
-#define __copy_from_guest_offset(ptr, hnd, off, nr) ({  \
-    const typeof(ptr) _x = (hnd).p;                     \
-    const typeof(ptr) _y = (ptr);                       \
-    __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));   \
-})
 #define __copy_from_guest(ptr, hnd, nr)                 \
     __copy_from_guest_offset(ptr, hnd, 0, nr)
 
diff -r ede16886f979 -r c4ac21dc3f16 tools/xenstore/hashtable.c
--- /dev/null   Mon Mar  6 16:09:18 2006
+++ b/tools/xenstore/hashtable.c        Mon Mar  6 17:21:35 2006
@@ -0,0 +1,276 @@
+/* Copyright (C) 2004 Christopher Clark <firstname.lastname@xxxxxxxxxxxx> */
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <stdint.h>
+
+/*
+Credit for primes table: Aaron Krowne
+ http://br.endernet.org/~akrowne/
+ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
+*/
+static const unsigned int primes[] = {
+53, 97, 193, 389,
+769, 1543, 3079, 6151,
+12289, 24593, 49157, 98317,
+196613, 393241, 786433, 1572869,
+3145739, 6291469, 12582917, 25165843,
+50331653, 100663319, 201326611, 402653189,
+805306457, 1610612741
+};
+const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
+const unsigned int max_load_factor = 65; /* percentage */
+
+/*****************************************************************************/
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashf) (void*),
+                 int (*eqf) (void*,void*))
+{
+    struct hashtable *h;
+    unsigned int pindex, size = primes[0];
+    /* Check requested hashtable isn't too large */
+    if (minsize > (1u << 30)) return NULL;
+    /* Enforce size as prime */
+    for (pindex=0; pindex < prime_table_length; pindex++) {
+        if (primes[pindex] > minsize) { size = primes[pindex]; break; }
+    }
+    h = (struct hashtable *)malloc(sizeof(struct hashtable));
+    if (NULL == h) return NULL; /*oom*/
+    h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
+    if (NULL == h->table) { free(h); return NULL; } /*oom*/
+    memset(h->table, 0, size * sizeof(struct entry *));
+    h->tablelength  = size;
+    h->primeindex   = pindex;
+    h->entrycount   = 0;
+    h->hashfn       = hashf;
+    h->eqfn         = eqf;
+    h->loadlimit    = (unsigned int)(((uint64_t)size * max_load_factor) / 100);
+    return h;
+}
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k)
+{
+    /* Aim to protect against poor hash functions by adding logic here
+     * - logic taken from java 1.4 hashtable source */
+    unsigned int i = h->hashfn(k);
+    i += ~(i << 9);
+    i ^=  ((i >> 14) | (i << 18)); /* >>> */
+    i +=  (i << 4);
+    i ^=  ((i >> 10) | (i << 22)); /* >>> */
+    return i;
+}
+
+/*****************************************************************************/
+static int
+hashtable_expand(struct hashtable *h)
+{
+    /* Double the size of the table to accomodate more entries */
+    struct entry **newtable;
+    struct entry *e;
+    struct entry **pE;
+    unsigned int newsize, i, index;
+    /* Check we're not hitting max capacity */
+    if (h->primeindex == (prime_table_length - 1)) return 0;
+    newsize = primes[++(h->primeindex)];
+
+    newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
+    if (NULL != newtable)
+    {
+        memset(newtable, 0, newsize * sizeof(struct entry *));
+        /* This algorithm is not 'stable'. ie. it reverses the list
+         * when it transfers entries between the tables */
+        for (i = 0; i < h->tablelength; i++) {
+            while (NULL != (e = h->table[i])) {
+                h->table[i] = e->next;
+                index = indexFor(newsize,e->h);
+                e->next = newtable[index];
+                newtable[index] = e;
+            }
+        }
+        free(h->table);
+        h->table = newtable;
+    }
+    /* Plan B: realloc instead */
+    else 
+    {
+        newtable = (struct entry **)
+                   realloc(h->table, newsize * sizeof(struct entry *));
+        if (NULL == newtable) { (h->primeindex)--; return 0; }
+        h->table = newtable;
+        memset(newtable[h->tablelength], 0, newsize - h->tablelength);
+        for (i = 0; i < h->tablelength; i++) {
+            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+                index = indexFor(newsize,e->h);
+                if (index == i)
+                {
+                    pE = &(e->next);
+                }
+                else
+                {
+                    *pE = e->next;
+                    e->next = newtable[index];
+                    newtable[index] = e;
+                }
+            }
+        }
+    }
+    h->tablelength = newsize;
+    h->loadlimit   = (unsigned int)
+        (((uint64_t)newsize * max_load_factor) / 100);
+    return -1;
+}
+
+/*****************************************************************************/
+unsigned int
+hashtable_count(struct hashtable *h)
+{
+    return h->entrycount;
+}
+
+/*****************************************************************************/
+int
+hashtable_insert(struct hashtable *h, void *k, void *v)
+{
+    /* This method allows duplicate keys - but they shouldn't be used */
+    unsigned int index;
+    struct entry *e;
+    if (++(h->entrycount) > h->loadlimit)
+    {
+        /* Ignore the return value. If expand fails, we should
+         * still try cramming just this value into the existing table
+         * -- we may not have memory for a larger table, but one more
+         * element may be ok. Next time we insert, we'll try expanding again.*/
+        hashtable_expand(h);
+    }
+    e = (struct entry *)malloc(sizeof(struct entry));
+    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
+    e->h = hash(h,k);
+    index = indexFor(h->tablelength,e->h);
+    e->k = k;
+    e->v = v;
+    e->next = h->table[index];
+    h->table[index] = e;
+    return -1;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_search(struct hashtable *h, void *k)
+{
+    struct entry *e;
+    unsigned int hashvalue, index;
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+    e = h->table[index];
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_remove(struct hashtable *h, void *k)
+{
+    /* TODO: consider compacting the table when the load factor drops enough,
+     *       or provide a 'compact' method. */
+
+    struct entry *e;
+    struct entry **pE;
+    void *v;
+    unsigned int hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hash(h,k));
+    pE = &(h->table[index]);
+    e = *pE;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            *pE = e->next;
+            h->entrycount--;
+            v = e->v;
+            freekey(e->k);
+            free(e);
+            return v;
+        }
+        pE = &(e->next);
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+/* destroy */
+void
+hashtable_destroy(struct hashtable *h, int free_values)
+{
+    unsigned int i;
+    struct entry *e, *f;
+    struct entry **table = h->table;
+    if (free_values)
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
+        }
+    }
+    else
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f); }
+        }
+    }
+    free(h->table);
+    free(h);
+}
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff -r ede16886f979 -r c4ac21dc3f16 tools/xenstore/hashtable.h
--- /dev/null   Mon Mar  6 16:09:18 2006
+++ b/tools/xenstore/hashtable.h        Mon Mar  6 17:21:35 2006
@@ -0,0 +1,199 @@
+/* Copyright (C) 2002 Christopher Clark <firstname.lastname@xxxxxxxxxxxx> */
+
+#ifndef __HASHTABLE_CWC22_H__
+#define __HASHTABLE_CWC22_H__
+
+struct hashtable;
+
+/* Example of use:
+ *
+ *      struct hashtable  *h;
+ *      struct some_key   *k;
+ *      struct some_value *v;
+ *
+ *      static unsigned int         hash_from_key_fn( void *k );
+ *      static int                  keys_equal_fn ( void *key1, void *key2 );
+ *
+ *      h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+ *      k = (struct some_key *)     malloc(sizeof(struct some_key));
+ *      v = (struct some_value *)   malloc(sizeof(struct some_value));
+ *
+ *      (initialise k and v to suitable values)
+ * 
+ *      if (! hashtable_insert(h,k,v) )
+ *      {     exit(-1);               }
+ *
+ *      if (NULL == (found = hashtable_search(h,k) ))
+ *      {    printf("not found!");                  }
+ *
+ *      if (NULL == (found = hashtable_remove(h,k) ))
+ *      {    printf("Not found\n");                 }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ * 
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+/*****************************************************************************
+ * create_hashtable
+   
+ * @name                    create_hashtable
+ * @param   minsize         minimum initial size of hashtable
+ * @param   hashfunction    function for hashing keys
+ * @param   key_eq_fn       function for determining key equality
+ * @return                  newly created hashtable or NULL on failure
+ */
+
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashfunction) (void*),
+                 int (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+   
+ * @name        hashtable_insert
+ * @param   h   the hashtable to insert into
+ * @param   k   the key - hashtable claims ownership and will free on removal
+ * @param   v   the value - does not claim ownership
+ * @return      non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+int 
+hashtable_insert(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+    return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+   
+ * @name        hashtable_search
+ * @param   h   the hashtable to search
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+   
+ * @name        hashtable_remove
+ * @param   h   the hashtable to remove the item from
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+   
+ * @name        hashtable_count
+ * @param   h   the hashtable
+ * @return      the number of items stored in the hashtable
+ */
+unsigned int
+hashtable_count(struct hashtable *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+   
+ * @name        hashtable_destroy
+ * @param   h   the hashtable
+ * @param       free_values     whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(struct hashtable *h, int free_values);
+
+#endif /* __HASHTABLE_CWC22_H__ */
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff -r ede16886f979 -r c4ac21dc3f16 tools/xenstore/hashtable_private.h
--- /dev/null   Mon Mar  6 16:09:18 2006
+++ b/tools/xenstore/hashtable_private.h        Mon Mar  6 17:21:35 2006
@@ -0,0 +1,85 @@
+/* Copyright (C) 2002, 2004 Christopher Clark 
<firstname.lastname@xxxxxxxxxxxx> */
+
+#ifndef __HASHTABLE_PRIVATE_CWC22_H__
+#define __HASHTABLE_PRIVATE_CWC22_H__
+
+#include "hashtable.h"
+
+/*****************************************************************************/
+struct entry
+{
+    void *k, *v;
+    unsigned int h;
+    struct entry *next;
+};
+
+struct hashtable {
+    unsigned int tablelength;
+    struct entry **table;
+    unsigned int entrycount;
+    unsigned int loadlimit;
+    unsigned int primeindex;
+    unsigned int (*hashfn) (void *k);
+    int (*eqfn) (void *k1, void *k2);
+};
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k);
+
+/*****************************************************************************/
+/* indexFor */
+static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue) {
+    return (hashvalue % tablelength);
+};
+
+/* Only works if tablelength == 2^N */
+/*static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue)
+{
+    return (hashvalue & (tablelength - 1u));
+}
+*/
+
+/*****************************************************************************/
+#define freekey(X) free(X)
+/*define freekey(X) ; */
+
+
+/*****************************************************************************/
+
+#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff -r ede16886f979 -r c4ac21dc3f16 tools/xenstore/xenstore_control.c
--- /dev/null   Mon Mar  6 16:09:18 2006
+++ b/tools/xenstore/xenstore_control.c Mon Mar  6 17:21:35 2006
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "xs.h"
+
+
+int main(int argc, char **argv)
+{
+  struct xs_handle * xsh;
+
+  if (argc < 2 ||
+      strcmp(argv[1], "check"))
+  {
+    fprintf(stderr,
+            "Usage:\n"
+            "\n"
+            "       %s check\n"
+            "\n", argv[0]);
+    return 2;
+  }
+
+  xsh = xs_daemon_open();
+
+  if (xsh == NULL) {
+    fprintf(stderr, "Failed to contact Xenstored.\n");
+    return 1;
+  }
+
+  xs_debug_command(xsh, argv[1], NULL, 0);
+
+  xs_daemon_close(xsh);
+
+  return 0;
+}
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/asm-ia64/guest_access.h
--- /dev/null   Mon Mar  6 16:09:18 2006
+++ b/xen/include/asm-ia64/guest_access.h       Mon Mar  6 17:21:35 2006
@@ -0,0 +1,63 @@
+/******************************************************************************
+ * guest_access.h
+ * 
+ * Copyright (c) 2006, K A Fraser
+ */
+
+#ifndef __ASM_IA64_GUEST_ACCESS_H__
+#define __ASM_IA64_GUEST_ACCESS_H__
+
+#include <asm/uaccess.h>
+
+/* Is the guest handle a NULL reference? */
+#define guest_handle_is_null(hnd)        ((hnd).p == NULL)
+
+/* Offset the given guest handle into the array it refers to. */
+#define guest_handle_add_offset(hnd, nr) ((hnd).p += (nr))
+
+/* Cast a guest handle to the specified type of handle. */
+#define guest_handle_cast(hnd, type) ({         \
+    type *_x = (hnd).p;                         \
+    (GUEST_HANDLE(type)) { _x };                \
+})
+
+/*
+ * Copy an array of objects to guest context via a guest handle,
+ * specifying an offset into the guest array.
+ */
+#define copy_to_guest_offset(hnd, off, ptr, nr) ({      \
+    const typeof(ptr) _x = (hnd).p;                     \
+    const typeof(ptr) _y = (ptr);                       \
+    copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));       \
+})
+
+/*
+ * Copy an array of objects from guest context via a guest handle,
+ * specifying an offset into the guest array.
+ */
+#define copy_from_guest_offset(ptr, hnd, off, nr) ({    \
+    const typeof(ptr) _x = (hnd).p;                     \
+    const typeof(ptr) _y = (ptr);                       \
+    copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));     \
+})
+
+/*
+ * Pre-validate a guest handle.
+ * Allows use of faster __copy_* functions.
+ */
+#define guest_handle_okay(hnd, nr)                      \
+    array_access_ok((hnd).p, (nr), sizeof(*(hnd).p))
+
+#define __copy_to_guest_offset(hnd, off, ptr, nr) ({    \
+    const typeof(ptr) _x = (hnd).p;                     \
+    const typeof(ptr) _y = (ptr);                       \
+    __copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));     \
+})
+
+#define __copy_from_guest_offset(ptr, hnd, off, nr) ({  \
+    const typeof(ptr) _x = (hnd).p;                     \
+    const typeof(ptr) _y = (ptr);                       \
+    __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));   \
+})
+
+#endif /* __ASM_IA64_GUEST_ACCESS_H__ */
diff -r ede16886f979 -r c4ac21dc3f16 xen/include/asm-x86/guest_access.h
--- /dev/null   Mon Mar  6 16:09:18 2006
+++ b/xen/include/asm-x86/guest_access.h        Mon Mar  6 17:21:35 2006
@@ -0,0 +1,63 @@
+/******************************************************************************
+ * guest_access.h
+ * 
+ * Copyright (c) 2006, K A Fraser
+ */
+
+#ifndef __ASM_X86_GUEST_ACCESS_H__
+#define __ASM_X86_GUEST_ACCESS_H__
+
+#include <asm/uaccess.h>
+
+/* Is the guest handle a NULL reference? */
+#define guest_handle_is_null(hnd)        ((hnd).p == NULL)
+
+/* Offset the given guest handle into the array it refers to. */
+#define guest_handle_add_offset(hnd, nr) ((hnd).p += (nr))
+
+/* Cast a guest handle to the specified type of handle. */
+#define guest_handle_cast(hnd, type) ({         \
+    type *_x = (hnd).p;                         \
+    (GUEST_HANDLE(type)) { _x };                \
+})
+
+/*
+ * Copy an array of objects to guest context via a guest handle,
+ * specifying an offset into the guest array.
+ */
+#define copy_to_guest_offset(hnd, off, ptr, nr) ({      \
+    const typeof(ptr) _x = (hnd).p;                     \
+    const typeof(ptr) _y = (ptr);                       \
+    copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));       \
+})
+
+/*
+ * Copy an array of objects from guest context via a guest handle,
+ * specifying an offset into the guest array.
+ */
+#define copy_from_guest_offset(ptr, hnd, off, nr) ({    \
+    const typeof(ptr) _x = (hnd).p;                     \
+    const typeof(ptr) _y = (ptr);                       \
+    copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));     \
+})
+
+/*
+ * Pre-validate a guest handle.
+ * Allows use of faster __copy_* functions.
+ */
+#define guest_handle_okay(hnd, nr)                      \
+    array_access_ok((hnd).p, (nr), sizeof(*(hnd).p))
+
+#define __copy_to_guest_offset(hnd, off, ptr, nr) ({    \
+    const typeof(ptr) _x = (hnd).p;                     \
+    const typeof(ptr) _y = (ptr);                       \
+    __copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));     \
+})
+
+#define __copy_from_guest_offset(ptr, hnd, off, nr) ({  \
+    const typeof(ptr) _x = (hnd).p;                     \
+    const typeof(ptr) _y = (ptr);                       \
+    __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));   \
+})
+
+#endif /* __ASM_X86_GUEST_ACCESS_H__ */
diff -r ede16886f979 -r c4ac21dc3f16 
linux-2.6-xen-sparse/include/xen/public/xenstored.h
--- a/linux-2.6-xen-sparse/include/xen/public/xenstored.h       Mon Mar  6 
16:09:18 2006
+++ /dev/null   Mon Mar  6 17:21:35 2006
@@ -1,89 +0,0 @@
-/*
- * Simple prototyle Xen Store Daemon providing simple tree-like database.
- * Copyright (C) 2005 Rusty Russell IBM Corporation
- *
- * This file may be distributed separately from the Linux kernel, or
- * incorporated into other software packages, subject to the following license:
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (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.
- */
-
-#ifndef _XENSTORED_H
-#define _XENSTORED_H
-
-enum xsd_sockmsg_type
-{
-       XS_DEBUG,
-       XS_SHUTDOWN,
-       XS_DIRECTORY,
-       XS_READ,
-       XS_GET_PERMS,
-       XS_WATCH,
-       XS_WATCH_ACK,
-       XS_UNWATCH,
-       XS_TRANSACTION_START,
-       XS_TRANSACTION_END,
-       XS_OP_READ_ONLY = XS_TRANSACTION_END,
-       XS_INTRODUCE,
-       XS_RELEASE,
-       XS_GET_DOMAIN_PATH,
-       XS_WRITE,
-       XS_MKDIR,
-       XS_RM,
-       XS_SET_PERMS,
-       XS_WATCH_EVENT,
-       XS_ERROR,
-};
-
-#define XS_WRITE_NONE "NONE"
-#define XS_WRITE_CREATE "CREATE"
-#define XS_WRITE_CREATE_EXCL "CREATE|EXCL"
-
-/* We hand errors as strings, for portability. */
-struct xsd_errors
-{
-       int errnum;
-       const char *errstring;
-};
-#define XSD_ERROR(x) { x, #x }
-static struct xsd_errors xsd_errors[] __attribute__((unused)) = {
-       XSD_ERROR(EINVAL),
-       XSD_ERROR(EACCES),
-       XSD_ERROR(EEXIST),
-       XSD_ERROR(EISDIR),
-       XSD_ERROR(ENOENT),
-       XSD_ERROR(ENOMEM),
-       XSD_ERROR(ENOSPC),
-       XSD_ERROR(EIO),
-       XSD_ERROR(ENOTEMPTY),
-       XSD_ERROR(ENOSYS),
-       XSD_ERROR(EROFS),
-       XSD_ERROR(EBUSY),
-       XSD_ERROR(EAGAIN),
-       XSD_ERROR(EISCONN),
-};
-struct xsd_sockmsg
-{
-       u32 type;
-       u32 len;                /* Length of data following this. */
-
-       /* Generally followed by nul-terminated string(s). */
-};
-
-#endif /* _XENSTORED_H */

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

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