Xen 
 
Home About Xen.org Xen Xen Summit Wiki Mailing List Bug Tracker Xen Downloads
 
   
 

xen-changelog

[Xen-changelog] Merge latest xen-unstable into xen-ia64-unstable

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Merge latest xen-unstable into xen-ia64-unstable
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 28 Sep 2005 20:16:13 +0000
Delivery-date: Wed, 28 Sep 2005 20:14:14 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID ef9591d03fdd96c4d290280fd3620e00f8a5ff2b
# Parent  eaedc6b4ec0fdbb5b14ac62f0854477f50fa55b2
# Parent  811559fb02ab1e1c5a7731895bd57ca7f9d6dbfe
Merge latest xen-unstable into xen-ia64-unstable

diff -r eaedc6b4ec0f -r ef9591d03fdd Makefile
--- a/Makefile  Fri Sep 23 21:41:28 2005
+++ b/Makefile  Mon Sep 26 17:07:49 2005
@@ -164,7 +164,7 @@
 uninstall: DESTDIR=
 uninstall: D=$(DESTDIR)
 uninstall:
-       [ -d $(D)/etc/xen ] && mv -f $(D)/etc/xen $(D)/etc/xen.old-`date +%s`
+       [ -d $(D)/etc/xen ] && mv -f $(D)/etc/xen $(D)/etc/xen.old-`date +%s` 
|| true
        rm -rf $(D)/etc/init.d/xend*
        rm -rf $(D)/etc/hotplug/xen-backend.agent
        rm -rf $(D)/var/run/xen* $(D)/var/lib/xen*
diff -r eaedc6b4ec0f -r ef9591d03fdd docs/src/user/installation.tex
--- a/docs/src/user/installation.tex    Fri Sep 23 21:41:28 2005
+++ b/docs/src/user/installation.tex    Mon Sep 26 17:07:49 2005
@@ -21,6 +21,9 @@
 \item [$\dag$] The \path{iproute2} package.
 \item [$\dag$] The Linux bridge-utils\footnote{Available from {\tt
       http://bridge.sourceforge.net}} (e.g., \path{/sbin/brctl})
+\item [$\dag$] The Linux hotplug system\footnote{Available from {\tt
+      http://linux-hotplug.sourceforge.net/}} (e.g., \path{/sbin/hotplug}
+      and related scripts)
 \item [$\dag$] An installation of Twisted~v1.3 or
   above\footnote{Available from {\tt http://www.twistedmatrix.com}}.
   There may be a binary package available for your distribution;
diff -r eaedc6b4ec0f -r ef9591d03fdd 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Fri Sep 23 
21:41:28 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Mon Sep 26 
17:07:49 2005
@@ -1394,9 +1394,7 @@
                        return;
 
                /* get the state value */
-               xenbus_transaction_start("cpu");
                err = xenbus_scanf(dir, "availability", "%s", state);
-               xenbus_transaction_end(0);
 
                if (err != 1) {
                        printk(KERN_ERR
diff -r eaedc6b4ec0f -r ef9591d03fdd 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Fri Sep 23 21:41:28 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Mon Sep 26 17:07:49 2005
@@ -324,7 +324,7 @@
     int err;
 
  again:
-    err = xenbus_transaction_start("control");
+    err = xenbus_transaction_start();
     if (err)
        return;
     str = (char *)xenbus_read("control", "shutdown", NULL);
@@ -337,7 +337,7 @@
     xenbus_write("control", "shutdown", "");
 
     err = xenbus_transaction_end(0);
-    if (err == -ETIMEDOUT) {
+    if (err == -EAGAIN) {
        kfree(str);
        goto again;
     }
@@ -366,7 +366,7 @@
     int err;
 
  again:
-    err = xenbus_transaction_start("control");
+    err = xenbus_transaction_start();
     if (err)
        return;
     if (!xenbus_scanf("control", "sysrq", "%c", &sysrq_key)) {
@@ -379,7 +379,7 @@
        xenbus_printf("control", "sysrq", "%c", '\0');
 
     err = xenbus_transaction_end(0);
-    if (err == -ETIMEDOUT)
+    if (err == -EAGAIN)
        goto again;
 
     if (sysrq_key != '\0') {
diff -r eaedc6b4ec0f -r ef9591d03fdd 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Sep 23 21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Mon Sep 26 17:07:49 2005
@@ -80,8 +80,9 @@
                return;
        }
 
+again:
        /* Supply the information about the device the frontend needs */
-       err = xenbus_transaction_start(be->dev->nodename);
+       err = xenbus_transaction_start();
        if (err) {
                xenbus_dev_error(be->dev, err, "starting transaction");
                return;
@@ -119,7 +120,15 @@
                goto abort;
        }
 
-       xenbus_transaction_end(0);
+       err = xenbus_transaction_end(0);
+       if (err == -EAGAIN)
+               goto again;
+       if (err) {
+               xenbus_dev_error(be->dev, err, "ending transaction",
+                                ring_ref, evtchn);
+               goto abort;
+       }
+
        xenbus_dev_ok(be->dev);
 
        return;
diff -r eaedc6b4ec0f -r ef9591d03fdd 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Fri Sep 23 
21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Mon Sep 26 
17:07:49 2005
@@ -572,7 +572,8 @@
                goto out;
        }
 
-       err = xenbus_transaction_start(dev->nodename);
+again:
+       err = xenbus_transaction_start();
        if (err) {
                xenbus_dev_error(dev, err, "starting transaction");
                goto destroy_blkring;
@@ -603,6 +604,8 @@
 
        err = xenbus_transaction_end(0);
        if (err) {
+               if (err == -EAGAIN)
+                       goto again;
                xenbus_dev_error(dev, err, "completing transaction");
                goto destroy_blkring;
        }
diff -r eaedc6b4ec0f -r ef9591d03fdd 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Sep 23 
21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Mon Sep 26 
17:07:49 2005
@@ -1122,7 +1122,8 @@
                goto out;
        }
 
-       err = xenbus_transaction_start(dev->nodename);
+again:
+       err = xenbus_transaction_start();
        if (err) {
                xenbus_dev_error(dev, err, "starting transaction");
                goto destroy_ring;
@@ -1160,6 +1161,8 @@
 
        err = xenbus_transaction_end(0);
        if (err) {
+               if (err == -EAGAIN)
+                       goto again;
                xenbus_dev_error(dev, err, "completing transaction");
                goto destroy_ring;
        }
diff -r eaedc6b4ec0f -r ef9591d03fdd 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Fri Sep 23 21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Mon Sep 26 17:07:49 2005
@@ -93,7 +93,8 @@
         * Tell the front-end that we are ready to go -
         * unless something bad happens
         */
-       err = xenbus_transaction_start(be->dev->nodename);
+again:
+       err = xenbus_transaction_start();
        if (err) {
                xenbus_dev_error(be->dev, err, "starting transaction");
                return;
@@ -127,7 +128,14 @@
                goto abort;
        }
 
-       xenbus_transaction_end(0);
+       err = xenbus_transaction_end(0);
+       if (err == -EAGAIN)
+               goto again;
+       if (err) {
+               xenbus_dev_error(be->dev, err, "end of transaction");
+               goto abort;
+       }
+
        xenbus_dev_ok(be->dev);
        return;
 abort:
diff -r eaedc6b4ec0f -r ef9591d03fdd 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Fri Sep 23 
21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Mon Sep 26 
17:07:49 2005
@@ -331,7 +331,8 @@
                goto out;
        }
 
-       err = xenbus_transaction_start(dev->nodename);
+again:
+       err = xenbus_transaction_start();
        if (err) {
                xenbus_dev_error(dev, err, "starting transaction");
                goto destroy_tpmring;
@@ -363,6 +364,8 @@
        }
 
        err = xenbus_transaction_end(0);
+       if (err == -EAGAIN)
+               goto again;
        if (err) {
                xenbus_dev_error(dev, err, "completing transaction");
                goto destroy_tpmring;
diff -r eaedc6b4ec0f -r ef9591d03fdd 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Fri Sep 23 
21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Mon Sep 26 
17:07:49 2005
@@ -287,12 +287,11 @@
 
 /* Start a transaction: changes by others will not be seen during this
  * transaction, and changes will not be visible to others until end.
- * Transaction only applies to the given subtree.
  * You can only have one transaction at any time.
  */
-int xenbus_transaction_start(const char *subtree)
-{
-       return xs_error(xs_single(XS_TRANSACTION_START, subtree, NULL));
+int xenbus_transaction_start(void)
+{
+       return xs_error(xs_single(XS_TRANSACTION_START, "", NULL));
 }
 EXPORT_SYMBOL(xenbus_transaction_start);
 
diff -r eaedc6b4ec0f -r ef9591d03fdd 
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Fri Sep 23 21:41:28 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Mon Sep 26 17:07:49 2005
@@ -87,7 +87,7 @@
 int xenbus_mkdir(const char *dir, const char *node);
 int xenbus_exists(const char *dir, const char *node);
 int xenbus_rm(const char *dir, const char *node);
-int xenbus_transaction_start(const char *subtree);
+int xenbus_transaction_start(void);
 int xenbus_transaction_end(int abort);
 
 /* Single read and scanf: returns -errno or num scanned if > 0. */
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/examples/Makefile
--- a/tools/examples/Makefile   Fri Sep 23 21:41:28 2005
+++ b/tools/examples/Makefile   Mon Sep 26 17:07:49 2005
@@ -25,19 +25,13 @@
 XEN_SCRIPTS += block-file
 XEN_SCRIPTS += block-enbd
 
-# no 64-bit specifics in mem-map.sxp
-# so place in /usr/lib, not /usr/lib64
-XEN_BOOT_DIR = /usr/lib/xen/boot
-XEN_BOOT = mem-map.sxp
-
 XEN_HOTPLUG_DIR = /etc/hotplug
 XEN_HOTPLUG_SCRIPTS = xen-backend.agent
 
 all:
 build:
 
-install: all install-initd install-configs install-scripts install-boot \
-        install-hotplug
+install: all install-initd install-configs install-scripts install-hotplug
 
 install-initd:
        [ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d
@@ -62,14 +56,6 @@
            $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
        done
 
-install-boot:
-       [ -d $(DESTDIR)$(XEN_BOOT_DIR) ] || \
-               $(INSTALL_DIR) $(DESTDIR)$(XEN_BOOT_DIR)
-       for i in $(XEN_BOOT); \
-           do [ -a $(DESTDIR)$(XEN_BOOT_DIR)/$$i ] || \
-           $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_BOOT_DIR); \
-       done
-
 install-hotplug:
        [ -d $(DESTDIR)$(XEN_HOTPLUG_DIR) ] || \
                $(INSTALL_DIR) $(DESTDIR)$(XEN_HOTPLUG_DIR)
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/examples/xmexample.vmx
--- a/tools/examples/xmexample.vmx      Fri Sep 23 21:41:28 2005
+++ b/tools/examples/xmexample.vmx      Mon Sep 26 17:07:49 2005
@@ -60,9 +60,6 @@
 # New stuff
 device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
 
-# Advanced users only. Don't touch if you don't know what you're doing
-memmap = '/usr/lib/xen/boot/mem-map.sxp'
-
 #-----------------------------------------------------------------------------
 # Disk image for 
 #cdrom=
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/firmware/vmxassist/Makefile
--- a/tools/firmware/vmxassist/Makefile Fri Sep 23 21:41:28 2005
+++ b/tools/firmware/vmxassist/Makefile Mon Sep 26 17:07:49 2005
@@ -44,7 +44,7 @@
 vmxloader: roms.h vmxloader.c acpi.h acpi_madt.c
        ${CC} ${CFLAGS} ${DEFINES} -c vmxloader.c -c acpi_madt.c
        $(CC) -o vmxloader.tmp -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,0x100000 
vmxloader.o acpi_madt.o
-       objcopy --change-addresses=0xC0000000 vmxloader.tmp vmxloader
+       objcopy vmxloader.tmp vmxloader
        rm -f vmxloader.tmp
 
 vmxassist.bin: vmxassist.ld ${OBJECTS}
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/firmware/vmxassist/vmxloader.c
--- a/tools/firmware/vmxassist/vmxloader.c      Fri Sep 23 21:41:28 2005
+++ b/tools/firmware/vmxassist/vmxloader.c      Mon Sep 26 17:07:49 2005
@@ -34,28 +34,39 @@
 /*
  * C runtime start off
  */
-asm("                                  \n\
-       .text                           \n\
-       .globl  _start                  \n\
-_start:                                        \n\
-       cli                             \n\
-       movl    $stack_top, %esp        \n\
-       movl    %esp, %ebp              \n\
-       call    main                    \n\
-       jmp     halt                    \n\
-                                       \n\
-       .globl  halt                    \n\
-halt:                                  \n\
-       sti                             \n\
-       jmp     .                       \n\
-                                       \n\
-       .bss                            \n\
-       .align  8                       \n\
-       .globl  stack, stack_top        \n\
-stack:                                 \n\
-       .skip   0x4000                  \n\
-stack_top:                             \n\
-");
+asm(
+"      .text                           \n"
+"      .globl  _start                  \n"
+"_start:                               \n"
+"      cld                             \n"
+"      cli                             \n"
+"      lgdt    gdt_desr                \n"
+"      movl    $stack_top, %esp        \n"
+"      movl    %esp, %ebp              \n"
+"      call    main                    \n"
+"      jmp     halt                    \n"
+"                                      \n"
+"gdt_desr:                             \n"
+"      .word   gdt_end - gdt - 1       \n"
+"      .long   gdt                     \n"
+"                                      \n"
+"      .align  8                       \n"
+"gdt:                                  \n"
+"      .quad   0x0000000000000000      \n"
+"      .quad   0x00CF92000000FFFF      \n"
+"      .quad   0x00CF9A000000FFFF      \n"
+"gdt_end:                              \n"
+"                                      \n"
+"halt:                                 \n"
+"      sti                             \n"
+"      jmp     .                       \n"
+"                                      \n"
+"      .bss                            \n"
+"      .align  8                       \n"
+"stack:                                        \n"
+"      .skip   0x4000                  \n"
+"stack_top:                            \n"
+);
 
 void *
 memcpy(void *dest, const void *src, unsigned n)
@@ -95,7 +106,7 @@
 }
 
 int
-main()
+main(void)
 {
        puts("VMXAssist Loader\n");
        puts("Loading ROMBIOS ...\n");
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c       Fri Sep 23 21:41:28 2005
+++ b/tools/ioemu/hw/cirrus_vga.c       Mon Sep 26 17:07:49 2005
@@ -231,6 +231,8 @@
     int cirrus_linear_io_addr;
     int cirrus_linear_bitblt_io_addr;
     int cirrus_mmio_io_addr;
+    unsigned long cirrus_lfb_addr;
+    unsigned long cirrus_lfb_end;
     uint32_t cirrus_addr_mask;
     uint32_t linear_mmio_mask;
     uint8_t cirrus_shadow_gr0;
@@ -2447,6 +2449,10 @@
 {
     unsigned mode;
 
+    extern void unset_vram_mapping(unsigned long addr, unsigned long end);
+    extern void set_vram_mapping(unsigned long addr, unsigned long end);
+    extern int vga_accelerate;
+
     if ((s->sr[0x17] & 0x44) == 0x44) {
         goto generic_io;
     } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
@@ -2454,17 +2460,21 @@
     } else {
        if ((s->gr[0x0B] & 0x14) == 0x14) {
             goto generic_io;
-       } else if (s->gr[0x0B] & 0x02) {
-            goto generic_io;
-        }
-        
-       mode = s->gr[0x05] & 0x7;
-       if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
+    } else if (s->gr[0x0B] & 0x02) {
+        goto generic_io;
+    }
+
+    mode = s->gr[0x05] & 0x7;
+    if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
+            if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end)
+                set_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end);
             s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
             s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
             s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
         } else {
         generic_io:
+            if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end)
+                 unset_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end);
             s->cirrus_linear_write[0] = cirrus_linear_writeb;
             s->cirrus_linear_write[1] = cirrus_linear_writew;
             s->cirrus_linear_write[2] = cirrus_linear_writel;
@@ -3058,6 +3068,8 @@
     /* XXX: add byte swapping apertures */
     cpu_register_physical_memory(addr, s->vram_size,
                                 s->cirrus_linear_io_addr);
+    s->cirrus_lfb_addr = addr;
+    s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
     cpu_register_physical_memory(addr + 0x1000000, 0x400000,
                                 s->cirrus_linear_bitblt_io_addr);
 }
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Fri Sep 23 21:41:28 2005
+++ b/tools/ioemu/hw/pc.c       Mon Sep 26 17:07:49 2005
@@ -385,6 +385,7 @@
     unsigned long bios_offset, vga_bios_offset;
     int bios_size, isa_bios_size;
     PCIBus *pci_bus;
+    extern void * shared_vram;
     
     linux_boot = (kernel_filename != NULL);
 
@@ -511,14 +512,14 @@
     if (cirrus_vga_enabled) {
         if (pci_enabled) {
             pci_cirrus_vga_init(pci_bus, 
-                                ds, phys_ram_base + ram_size, ram_size, 
+                                ds, shared_vram, ram_size, 
                                 vga_ram_size);
         } else {
-            isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size, 
+            isa_cirrus_vga_init(ds, shared_vram, ram_size, 
                                 vga_ram_size);
         }
     } else {
-        vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, 
+        vga_initialize(pci_bus, ds, shared_vram, ram_size, 
                        vga_ram_size);
     }
 
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Fri Sep 23 21:41:28 2005
+++ b/tools/ioemu/hw/vga.c      Mon Sep 26 17:07:49 2005
@@ -1568,6 +1568,8 @@
             s->graphic_mode = graphic_mode;
             full_update = 1;
         }
+
+        full_update = 1;
         switch(graphic_mode) {
         case GMODE_TEXT:
             vga_draw_text(s, full_update);
@@ -1848,6 +1850,7 @@
                      unsigned long vga_ram_offset, int vga_ram_size)
 {
     int i, j, v, b;
+    extern void* shared_vram;
 
     for(i = 0;i < 256; i++) {
         v = 0;
@@ -1876,7 +1879,7 @@
 
     /* qemu's vga mem is not detached from phys_ram_base and can cause DM abort
      * when guest write vga mem, so allocate a new one */
-    s->vram_ptr = qemu_mallocz(vga_ram_size);
+    s->vram_ptr = shared_vram;
 
     s->vram_offset = vga_ram_offset;
     s->vram_size = vga_ram_size;
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Fri Sep 23 21:41:28 2005
+++ b/tools/ioemu/target-i386-dm/helper2.c      Mon Sep 26 17:07:49 2005
@@ -54,6 +54,8 @@
 #include "exec-all.h"
 #include "vl.h"
 
+void *shared_vram;
+
 shared_iopage_t *shared_page = NULL;
 extern int reset_requested;
 
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Fri Sep 23 21:41:28 2005
+++ b/tools/ioemu/vl.c  Mon Sep 26 17:07:49 2005
@@ -134,6 +134,7 @@
 int prep_enabled = 0;
 int rtc_utc = 1;
 int cirrus_vga_enabled = 1;
+int vga_accelerate = 1;
 int graphic_width = 800;
 int graphic_height = 600;
 int graphic_depth = 15;
@@ -141,6 +142,12 @@
 TextConsole *vga_console;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 int xc_handle;
+unsigned long *vgapage_array;
+unsigned long *freepage_array;
+unsigned long free_pages;
+void *vtop_table;
+unsigned long toptab;
+unsigned long vgaram_pages;
 
 /***********************************************************/
 /* x86 ISA bus support */
@@ -2162,6 +2169,7 @@
            "-isa            simulate an ISA-only system (default is PCI 
system)\n"
            "-std-vga        simulate a standard VGA card with VESA Bochs 
Extensions\n"
            "                (default is CL-GD5446 PCI VGA)\n"
+           "-vgaacc [0|1]   1 to accelerate CL-GD5446 speed, default is 1\n"
 #endif
            "-loadvm file    start right away with a saved state (loadvm in 
monitor)\n"
            "\n"
@@ -2251,6 +2259,7 @@
     QEMU_OPTION_serial,
     QEMU_OPTION_loadvm,
     QEMU_OPTION_full_screen,
+    QEMU_OPTION_vgaacc,
 };
 
 typedef struct QEMUOption {
@@ -2327,6 +2336,7 @@
     { "pci", 0, QEMU_OPTION_pci },
     { "nic-pcnet", 0, QEMU_OPTION_nic_pcnet },
     { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
+    { "vgaacc", HAS_ARG, QEMU_OPTION_vgaacc },
     { NULL },
 };
 
@@ -2342,6 +2352,177 @@
 #define NET_IF_TUN   0
 #define NET_IF_USER  1
 #define NET_IF_DUMMY 2
+
+#include <xg_private.h>
+
+#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
+#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
+
+#ifdef __i386__
+#define _LEVEL_3_ 0
+#else
+#define _LEVEL_3_ 1
+#endif
+
+#if _LEVEL_3_
+#define L3_PROT (_PAGE_PRESENT)
+#define L1_PAGETABLE_ENTRIES    512
+#else
+#define L1_PAGETABLE_ENTRIES    1024
+#endif
+
+inline int
+get_vl2_table(unsigned long count, unsigned long start)
+{
+#if _LEVEL_3_
+    return ((start + (count << PAGE_SHIFT)) >> L3_PAGETABLE_SHIFT) & 0x3;
+#else
+    return 0;
+#endif
+}
+
+int
+setup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long  
*mem_page_array, unsigned long *page_table_array, unsigned long v_start, 
unsigned long v_end)
+{
+    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
+    l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
+    unsigned long l1tab;
+    unsigned long ppt_alloc = 0;
+    unsigned long count;
+    int i = 0;
+#if _LEVEL_3_
+    l3_pgentry_t *vl3tab = NULL;
+    unsigned long l2tab;
+    if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
+                                        PROT_READ|PROT_WRITE, 
+                                        toptab >> PAGE_SHIFT)) == NULL )
+        goto error_out;
+    for (i = 0; i < 4 ; i++) {
+        l2tab = vl3tab[i] & PAGE_MASK;
+        vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+          PROT_READ|PROT_WRITE,
+          l2tab >> PAGE_SHIFT);
+        if(vl2tab[i] == NULL)
+            goto error_out;
+    }
+    munmap(vl3tab, PAGE_SIZE);
+    vl3tab = NULL;
+#else
+    if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
+                                           PROT_READ|PROT_WRITE, 
+                                           toptab >> PAGE_SHIFT)) == NULL )
+        goto error_out;
+#endif
+
+    for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ )
+    {
+        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
+        {
+            vl2_table = vl2tab[get_vl2_table(count, v_start)];
+            vl2e = &vl2_table[l2_table_offset(
+                v_start + (count << PAGE_SHIFT))];
+
+            l1tab = page_table_array[ppt_alloc++] << PAGE_SHIFT;
+            if ( vl1tab != NULL )
+                munmap(vl1tab, PAGE_SIZE);
+
+            if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                                                PROT_READ|PROT_WRITE,
+                                                l1tab >> PAGE_SHIFT)) == NULL )
+            {
+                goto error_out;
+            }
+            memset(vl1tab, 0, PAGE_SIZE);
+            vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))];
+            *vl2e = l1tab | L2_PROT;
+        }
+
+        *vl1e = (mem_page_array[count] << PAGE_SHIFT) | L1_PROT;
+        vl1e++;
+    }
+error_out:
+    if(vl1tab)  munmap(vl1tab, PAGE_SIZE);
+    for(i = 0; i < 4; i++)
+        if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE);
+    return ppt_alloc;
+}
+
+void
+unsetup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long 
v_start, unsigned long v_end)
+{
+    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
+    l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
+    unsigned long l1tab;
+    unsigned long count;
+    int i = 0;
+#if _LEVEL_3_
+    l3_pgentry_t *vl3tab = NULL;
+    unsigned long l2tab;
+    if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
+                                        PROT_READ|PROT_WRITE, 
+                                        toptab >> PAGE_SHIFT)) == NULL )
+        goto error_out;
+    for (i = 0; i < 4 ; i ++){
+        l2tab = vl3tab[i] & PAGE_MASK;
+        vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+          PROT_READ|PROT_WRITE,
+          l2tab >> PAGE_SHIFT);
+        if(vl2tab[i] == NULL)
+            goto error_out;
+    }
+    munmap(vl3tab, PAGE_SIZE);
+    vl3tab = NULL;
+#else
+    if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
+                                        PROT_READ|PROT_WRITE, 
+                                        toptab >> PAGE_SHIFT)) == NULL )
+        goto error_out;
+#endif
+
+    for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ){
+        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
+        {
+            vl2_table = vl2tab[get_vl2_table(count, v_start)];
+            vl2e = &vl2_table[l2_table_offset(v_start + (count << 
PAGE_SHIFT))];
+            l1tab = *vl2e & PAGE_MASK;
+
+            if(l1tab == 0)
+                continue;
+            if ( vl1tab != NULL )
+                munmap(vl1tab, PAGE_SIZE);
+
+            if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                      PROT_READ|PROT_WRITE,
+                      l1tab >> PAGE_SHIFT)) == NULL )
+            {
+                goto error_out;
+            }
+            vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))];
+            *vl2e = 0;
+        }
+
+        *vl1e = 0;
+        vl1e++;
+    }
+error_out:
+    if(vl1tab)  munmap(vl1tab, PAGE_SIZE);
+    for(i = 0; i < 4; i++)
+        if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE);
+}
+
+void set_vram_mapping(unsigned long addr, unsigned long end)
+{
+    end = addr + VGA_RAM_SIZE;
+    setup_mapping(xc_handle, domid, toptab,
+      vgapage_array, freepage_array, addr, end);
+}
+
+void unset_vram_mapping(unsigned long addr, unsigned long end)
+{
+    end = addr + VGA_RAM_SIZE;
+    /* FIXME Flush the shadow page */
+    unsetup_mapping(xc_handle, domid, toptab, addr, end);
+}
 
 int main(int argc, char **argv)
 {
@@ -2366,8 +2547,9 @@
     char serial_devices[MAX_SERIAL_PORTS][128];
     int serial_device_index;
     const char *loadvm = NULL;
-    unsigned long nr_pages, *page_array;
+    unsigned long nr_pages, extra_pages, ram_pages, *page_array;
     extern void *shared_page;
+    extern void *shared_vram;
     /* change the qemu-dm to daemon, just like bochs dm */
 //    daemon(0, 0);
     
@@ -2674,6 +2856,17 @@
             case QEMU_OPTION_cirrusvga:
                 cirrus_vga_enabled = 1;
                 break;
+            case QEMU_OPTION_vgaacc:
+                {
+                    const char *p;
+                    p = optarg;
+                    vga_accelerate = strtol(p, (char **)&p, 0);
+                    if (*p != '\0') {
+                        fprintf(stderr, "qemu: invalid vgaacc option\n");
+                        exit(1);
+                    }
+                    break;
+                }
             case QEMU_OPTION_std_vga:
                 cirrus_vga_enabled = 0;
                 break;
@@ -2803,12 +2996,25 @@
     /* init the memory */
     phys_ram_size = ram_size + vga_ram_size + bios_size;
 
-    #define PAGE_SHIFT 12
-    #define PAGE_SIZE  (1 << PAGE_SHIFT)
-
-    nr_pages = ram_size/PAGE_SIZE;
+    ram_pages = ram_size/PAGE_SIZE;
+    vgaram_pages =  (vga_ram_size -1)/PAGE_SIZE + 1;
+    free_pages = vgaram_pages / L1_PAGETABLE_ENTRIES;
+    extra_pages = vgaram_pages + free_pages;
+
     xc_handle = xc_interface_open();
-    
+
+    xc_dominfo_t info;
+    xc_domain_getinfo(xc_handle, domid, 1, &info);
+
+    nr_pages = info.nr_pages + extra_pages;
+
+    if ( xc_domain_setmaxmem(xc_handle, domid,
+            (nr_pages) * PAGE_SIZE/1024 ) != 0)
+    {
+        perror("set maxmem");
+        exit(-1);
+    }
+   
     if ( (page_array = (unsigned long *)
          malloc(nr_pages * sizeof(unsigned long))) == NULL)
     {
@@ -2816,6 +3022,12 @@
            exit(-1);
     }
 
+    if (xc_domain_memory_increase_reservation(xc_handle, domid, 
+          extra_pages , 0, 0, NULL) != 0) {
+        perror("increase reservation");
+        exit(-1);
+    }
+
     if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
     {
            perror("xc_get_pfn_list");
@@ -2825,15 +3037,36 @@
     if ((phys_ram_base =  xc_map_foreign_batch(xc_handle, domid,
                                                 PROT_READ|PROT_WRITE,
                                                 page_array,
-                                                nr_pages - 1)) == 0) {
+                                                ram_pages - 1)) == 0) {
            perror("xc_map_foreign_batch");
            exit(-1);
     }
 
     shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
                                       PROT_READ|PROT_WRITE,
-                                      page_array[nr_pages - 1]);
-
+                                      page_array[ram_pages - 1]);
+
+    vgapage_array = &page_array[nr_pages - vgaram_pages];
+
+    if ((shared_vram =  xc_map_foreign_batch(xc_handle, domid,
+                                                PROT_READ|PROT_WRITE,
+                                                vgapage_array,
+                                                vgaram_pages)) == 0) {
+           perror("xc_map_foreign_batch vgaram ");
+           exit(-1);
+     }
+
+
+
+    memset(shared_vram, 0, vgaram_pages * PAGE_SIZE);
+    toptab = page_array[ram_pages] << PAGE_SHIFT;
+
+    vtop_table = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                      PROT_READ|PROT_WRITE,
+                                      page_array[ram_pages]);
+
+    freepage_array = &page_array[nr_pages - extra_pages];
+ 
 
     fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1), 
            (page_array[nr_pages - 1]));
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c        Fri Sep 23 21:41:28 2005
+++ b/tools/libxc/xc_vmx_build.c        Mon Sep 26 17:07:49 2005
@@ -10,7 +10,8 @@
 #include <unistd.h>
 #include <zlib.h>
 #include <xen/io/ioreq.h>
-#include "linux_boot_params.h"
+
+#define VMX_LOADER_ENTR_ADDR  0x00100000
 
 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
 #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
@@ -18,12 +19,28 @@
 #define L3_PROT (_PAGE_PRESENT)
 #endif
 
+#define E820MAX        128
+
+#define E820_RAM          1
+#define E820_RESERVED     2
+#define E820_ACPI         3
+#define E820_NVS          4
+#define E820_IO          16
+#define E820_SHARED_PAGE 17
+#define E820_XENSTORE    18
+
+#define E820_MAP_PAGE        0x00090000
+#define E820_MAP_NR_OFFSET   0x000001E8
+#define E820_MAP_OFFSET      0x000002D0
+
+struct e820entry {
+    u64 addr;
+    u64 size;
+    u32 type;
+} __attribute__((packed));
+
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
 #define round_pgdown(_p)  ((_p)&PAGE_MASK)
-
-#define LINUX_BOOT_PARAMS_ADDR   0x00090000
-#define LINUX_KERNEL_ENTR_ADDR   0x00100000
-#define LINUX_PAGE_OFFSET        0xC0000000
 
 static int
 parseelfimage(
@@ -33,78 +50,70 @@
     char *elfbase, int xch, u32 dom, unsigned long *parray,
     struct domain_setup_info *dsi);
 
-static void build_e820map(struct mem_map *mem_mapp, unsigned long mem_size)
-{
-    int nr_map = 0;
+static unsigned char build_e820map(void *e820_page, unsigned long mem_size)
+{
+    struct e820entry *e820entry =
+        (struct e820entry *)(((unsigned char *)e820_page) + E820_MAP_OFFSET);
+    unsigned char nr_map = 0;
 
     /* XXX: Doesn't work for > 4GB yet */
-    mem_mapp->map[nr_map].addr = 0x0;
-    mem_mapp->map[nr_map].size = 0x9F800;
-    mem_mapp->map[nr_map].type = E820_RAM;
-    mem_mapp->map[nr_map].caching_attr = MEMMAP_WB;
-    nr_map++;
-
-    mem_mapp->map[nr_map].addr = 0x9F800;
-    mem_mapp->map[nr_map].size = 0x800;
-    mem_mapp->map[nr_map].type = E820_RESERVED;
-    mem_mapp->map[nr_map].caching_attr = MEMMAP_UC;
-    nr_map++;
-
-    mem_mapp->map[nr_map].addr = 0xA0000;
-    mem_mapp->map[nr_map].size = 0x20000;
-    mem_mapp->map[nr_map].type = E820_IO;
-    mem_mapp->map[nr_map].caching_attr = MEMMAP_UC;
-    nr_map++;
-
-    mem_mapp->map[nr_map].addr = 0xF0000;
-    mem_mapp->map[nr_map].size = 0x10000;
-    mem_mapp->map[nr_map].type = E820_RESERVED;
-    mem_mapp->map[nr_map].caching_attr = MEMMAP_UC;
+    e820entry[nr_map].addr = 0x0;
+    e820entry[nr_map].size = 0x9F800;
+    e820entry[nr_map].type = E820_RAM;
+    nr_map++;
+
+    e820entry[nr_map].addr = 0x9F800;
+    e820entry[nr_map].size = 0x800;
+    e820entry[nr_map].type = E820_RESERVED;
+    nr_map++;
+
+    e820entry[nr_map].addr = 0xA0000;
+    e820entry[nr_map].size = 0x20000;
+    e820entry[nr_map].type = E820_IO;
+    nr_map++;
+
+    e820entry[nr_map].addr = 0xF0000;
+    e820entry[nr_map].size = 0x10000;
+    e820entry[nr_map].type = E820_RESERVED;
     nr_map++;
 
 #define STATIC_PAGES    2       /* for ioreq_t and store_mfn */
     /* Most of the ram goes here */
-    mem_mapp->map[nr_map].addr = 0x100000;
-    mem_mapp->map[nr_map].size = mem_size - 0x100000 - STATIC_PAGES*PAGE_SIZE;
-    mem_mapp->map[nr_map].type = E820_RAM;
-    mem_mapp->map[nr_map].caching_attr = MEMMAP_WB;
+    e820entry[nr_map].addr = 0x100000;
+    e820entry[nr_map].size = mem_size - 0x100000 - STATIC_PAGES*PAGE_SIZE;
+    e820entry[nr_map].type = E820_RAM;
     nr_map++;
 
     /* Statically allocated special pages */
 
     /* Shared ioreq_t page */
-    mem_mapp->map[nr_map].addr = mem_size - PAGE_SIZE;
-    mem_mapp->map[nr_map].size = PAGE_SIZE;
-    mem_mapp->map[nr_map].type = E820_SHARED;
-    mem_mapp->map[nr_map].caching_attr = MEMMAP_WB;
+    e820entry[nr_map].addr = mem_size - PAGE_SIZE;
+    e820entry[nr_map].size = PAGE_SIZE;
+    e820entry[nr_map].type = E820_SHARED_PAGE;
     nr_map++;
 
     /* For xenstore */
-    mem_mapp->map[nr_map].addr = mem_size - 2*PAGE_SIZE;
-    mem_mapp->map[nr_map].size = PAGE_SIZE;
-    mem_mapp->map[nr_map].type = E820_XENSTORE;
-    mem_mapp->map[nr_map].caching_attr = MEMMAP_WB;
-    nr_map++;
-
-    mem_mapp->map[nr_map].addr = mem_size;
-    mem_mapp->map[nr_map].size = 0x3 * PAGE_SIZE;
-    mem_mapp->map[nr_map].type = E820_NVS;
-    mem_mapp->map[nr_map].caching_attr = MEMMAP_UC;
-    nr_map++;
-
-    mem_mapp->map[nr_map].addr = mem_size + 0x3 * PAGE_SIZE;
-    mem_mapp->map[nr_map].size = 0xA * PAGE_SIZE;
-    mem_mapp->map[nr_map].type = E820_ACPI;
-    mem_mapp->map[nr_map].caching_attr = MEMMAP_WB;
-    nr_map++;
-
-    mem_mapp->map[nr_map].addr = 0xFEC00000;
-    mem_mapp->map[nr_map].size = 0x1400000;
-    mem_mapp->map[nr_map].type = E820_IO;
-    mem_mapp->map[nr_map].caching_attr = MEMMAP_UC;
-    nr_map++;
-
-    mem_mapp->nr_map = nr_map;
+    e820entry[nr_map].addr = mem_size - 2*PAGE_SIZE;
+    e820entry[nr_map].size = PAGE_SIZE;
+    e820entry[nr_map].type = E820_XENSTORE;
+    nr_map++;
+
+    e820entry[nr_map].addr = mem_size;
+    e820entry[nr_map].size = 0x3 * PAGE_SIZE;
+    e820entry[nr_map].type = E820_NVS;
+    nr_map++;
+
+    e820entry[nr_map].addr = mem_size + 0x3 * PAGE_SIZE;
+    e820entry[nr_map].size = 0xA * PAGE_SIZE;
+    e820entry[nr_map].type = E820_ACPI;
+    nr_map++;
+
+    e820entry[nr_map].addr = 0xFEC00000;
+    e820entry[nr_map].size = 0x1400000;
+    e820entry[nr_map].type = E820_IO;
+    nr_map++;
+
+    return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
 }
 
 /*
@@ -112,19 +121,19 @@
  * vmxloader will use it to config ACPI MADT table
  */
 #define VCPU_MAGIC 0x76637075 /* "vcpu" */
-static int 
-set_nr_vcpus(int xc_handle, u32 dom, unsigned long *pfn_list, 
+static int
+set_nr_vcpus(int xc_handle, u32 dom, unsigned long *pfn_list,
              struct domain_setup_info *dsi, unsigned long vcpus)
 {
     char          *va_map;
     unsigned long *va_vcpus;
-    
+
     va_map = xc_map_foreign_range(
         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
-        pfn_list[(0x9F000 - dsi->v_start) >> PAGE_SHIFT]);    
+        pfn_list[(0x9F000 - dsi->v_start) >> PAGE_SHIFT]);
     if ( va_map == NULL )
         return -1;
-    
+
     va_vcpus = (unsigned long *)(va_map + 0x800);
     *va_vcpus++ = VCPU_MAGIC;
     *va_vcpus++ = vcpus;
@@ -164,24 +173,23 @@
     return 0;
 }
 
-static int zap_mmio_ranges(int xc_handle, u32 dom,
-                           unsigned long l2tab,
-                           struct mem_map *mem_mapp)
-{
-    int i;
+static int zap_mmio_ranges(int xc_handle, u32 dom, unsigned long l2tab,
+                           unsigned char e820_map_nr, unsigned char *e820map)
+{
+    unsigned int i;
+    struct e820entry *e820entry = (struct e820entry *)e820map;
+
     l2_pgentry_32_t *vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
                                                    PROT_READ|PROT_WRITE,
                                                    l2tab >> PAGE_SHIFT);
     if ( vl2tab == 0 )
         return -1;
 
-    for ( i = 0; i < mem_mapp->nr_map; i++ )
-    {
-        if ( (mem_mapp->map[i].type == E820_IO) &&
-             (mem_mapp->map[i].caching_attr == MEMMAP_UC) &&
+    for ( i = 0; i < e820_map_nr; i++ )
+    {
+        if ( (e820entry[i].type == E820_IO) &&
              (zap_mmio_range(xc_handle, dom, vl2tab,
-                             mem_mapp->map[i].addr,
-                             mem_mapp->map[i].size) == -1) )
+                             e820entry[i].addr, e820entry[i].size) == -1))
             return -1;
     }
 
@@ -200,7 +208,7 @@
     unsigned long vl3e;
     l1_pgentry_t *vl1tab;
     l2_pgentry_t *vl2tab;
- 
+
     mmio_addr = mmio_range_start & PAGE_MASK;
     for ( ; mmio_addr < mmio_range_end; mmio_addr += PAGE_SIZE )
     {
@@ -239,22 +247,22 @@
     return 0;
 }
 
-static int zap_mmio_ranges(int xc_handle, u32 dom,
-                           unsigned long l3tab,
-                           struct mem_map *mem_mapp)
-{
-    int i;
+static int zap_mmio_ranges(int xc_handle, u32 dom, unsigned long l3tab,
+                           unsigned char e820_map_nr, unsigned char *e820map)
+{
+    unsigned int i;
+    struct e820entry *e820entry = (struct e820entry *)e820map;
+
     l3_pgentry_t *vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
                                                 PROT_READ|PROT_WRITE,
                                                 l3tab >> PAGE_SHIFT);
     if (vl3tab == 0)
         return -1;
-    for (i = 0; i < mem_mapp->nr_map; i++) {
-        if ((mem_mapp->map[i].type == E820_IO)
-            && (mem_mapp->map[i].caching_attr == MEMMAP_UC))
-            if (zap_mmio_range(xc_handle, dom, vl3tab,
-                               mem_mapp->map[i].addr, mem_mapp->map[i].size) 
== -1)
-                return -1;
+    for ( i = 0; i < e820_map_nr; i++ ) {
+        if ( (e820entry[i].type == E820_IO) &&
+             (zap_mmio_range(xc_handle, dom, vl3tab,
+                             e820entry[i].addr, e820entry[i].size) == -1) )
+            return -1;
     }
     munmap(vl3tab, PAGE_SIZE);
     return 0;
@@ -265,18 +273,14 @@
 static int setup_guest(int xc_handle,
                        u32 dom, int memsize,
                        char *image, unsigned long image_size,
-                       gzFile initrd_gfd, unsigned long initrd_len,
                        unsigned long nr_pages,
                        vcpu_guest_context_t *ctxt,
-                       const char *cmdline,
                        unsigned long shared_info_frame,
                        unsigned int control_evtchn,
                        unsigned long flags,
                        unsigned int vcpus,
                        unsigned int store_evtchn,
-                       unsigned long *store_mfn,
-                       struct mem_map *mem_mapp
-    )
+                       unsigned long *store_mfn)
 {
     l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
     l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
@@ -289,8 +293,8 @@
     unsigned long l1tab;
     unsigned long count, i;
     shared_info_t *shared_info;
-    struct linux_boot_params * boot_paramsp;
-    __u16 * boot_gdtp;
+    void *e820_page;
+    unsigned char e820_map_nr;
     xc_mmu_t *mmu = NULL;
     int rc;
 
@@ -298,12 +302,6 @@
     unsigned long ppt_alloc;
 
     struct domain_setup_info dsi;
-    unsigned long vinitrd_start;
-    unsigned long vinitrd_end;
-    unsigned long vboot_params_start;
-    unsigned long vboot_params_end;
-    unsigned long vboot_gdt_start;
-    unsigned long vboot_gdt_end;
     unsigned long vpt_start;
     unsigned long vpt_end;
     unsigned long v_end;
@@ -322,27 +320,8 @@
         goto error_out;
     }
 
-    /*
-     * Why do we need this? The number of page-table frames depends on the 
-     * size of the bootstrap address space. But the size of the address space 
-     * depends on the number of page-table frames (since each one is mapped 
-     * read-only). We have a pair of simultaneous equations in two unknowns, 
-     * which we solve by exhaustive search.
-     */
-    vboot_params_start = LINUX_BOOT_PARAMS_ADDR;
-    vboot_params_end   = vboot_params_start + PAGE_SIZE;
-    vboot_gdt_start    = vboot_params_end;
-    vboot_gdt_end      = vboot_gdt_start + PAGE_SIZE;
-
     /* memsize is in megabytes */
     v_end              = memsize << 20;
-    /* leaving the top 4k untouched for IO requests page use */
-    vinitrd_end        = v_end - PAGE_SIZE;
-    vinitrd_start      = vinitrd_end - initrd_len;
-    vinitrd_start      = vinitrd_start & (~(PAGE_SIZE - 1));
-
-    if(initrd_len == 0)
-        vinitrd_start = vinitrd_end = 0;
 
 #ifdef __i386__
     nr_pt_pages = 1 + ((memsize + 3) >> 2);
@@ -353,24 +332,17 @@
     vpt_end     = vpt_start + (nr_pt_pages * PAGE_SIZE);
 
     printf("VIRTUAL MEMORY ARRANGEMENT:\n"
-           " Boot_params:   %08lx->%08lx\n"
-           " boot_gdt:      %08lx->%08lx\n"
-           " Loaded kernel: %08lx->%08lx\n"
-           " Init. ramdisk: %08lx->%08lx\n"
+           " Loaded VMX loader: %08lx->%08lx\n"
            " Page tables:   %08lx->%08lx\n"
            " TOTAL:         %08lx->%08lx\n",
-           vboot_params_start, vboot_params_end,
-           vboot_gdt_start, vboot_gdt_end,
-           dsi.v_kernstart, dsi.v_kernend, 
-           vinitrd_start, vinitrd_end,
+           dsi.v_kernstart, dsi.v_kernend,
            vpt_start, vpt_end,
            dsi.v_start, v_end);
     printf(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
-    printf(" INITRD LENGTH: %08lx\n", initrd_len);
 
     if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
     {
-        printf("Initial guest OS requires too much space\n"
+        ERROR("Initial guest OS requires too much space\n"
                "(%luMB is greater than %luMB limit)\n",
                (v_end-dsi.v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
         goto error_out;
@@ -389,23 +361,6 @@
     }
 
     loadelfimage(image, xc_handle, dom, page_array, &dsi);
-
-    /* Load the initial ramdisk image. */
-    if ( initrd_len != 0 )
-    {
-        for ( i = (vinitrd_start - dsi.v_start); 
-              i < (vinitrd_end - dsi.v_start); i += PAGE_SIZE )
-        {
-            char page[PAGE_SIZE];
-            if ( gzread(initrd_gfd, page, PAGE_SIZE) == -1 )
-            {
-                PERROR("Error reading initrd image, could not");
-                goto error_out;
-            }
-            xc_copy_to_domain_page(xc_handle, dom,
-                                   page_array[i>>PAGE_SHIFT], page);
-        }
-    }
 
     if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
         goto error_out;
@@ -428,15 +383,14 @@
     l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
     ctxt->ctrlreg[3] = l2tab;
 
-    /* Initialise the page tables. */
-    if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
-                                        PROT_READ|PROT_WRITE, 
+    if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                                        PROT_READ|PROT_WRITE,
                                         l2tab >> PAGE_SHIFT)) == NULL )
         goto error_out;
     memset(vl2tab, 0, PAGE_SIZE);
     vl2e = &vl2tab[l2_table_offset(dsi.v_start)];
     for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
-    {    
+    {
         if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
         {
             l1tab = page_array[ppt_alloc++] << PAGE_SHIFT;
@@ -460,23 +414,35 @@
     munmap(vl1tab, PAGE_SIZE);
     munmap(vl2tab, PAGE_SIZE);
 #else
-    /* here l3tab means pdpt, only 4 entry is used */
     l3tab = page_array[ppt_alloc++] << PAGE_SHIFT;
     ctxt->ctrlreg[3] = l3tab;
 
-    /* Initialise the page tables. */
-    if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
-                                        PROT_READ|PROT_WRITE, 
+    if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                                        PROT_READ|PROT_WRITE,
                                         l3tab >> PAGE_SHIFT)) == NULL )
         goto error_out;
     memset(vl3tab, 0, PAGE_SIZE);
 
+    /* Fill in every PDPT entry. */
+    for ( i = 0; i < L3_PAGETABLE_ENTRIES_PAE; i++ )
+    {
+        l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
+        if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                                            PROT_READ|PROT_WRITE,
+                                            l2tab >> PAGE_SHIFT)) == NULL )
+            goto error_out;
+        memset(vl2tab, 0, PAGE_SIZE);
+        munmap(vl2tab, PAGE_SIZE);
+        vl3tab[i] = l2tab | L3_PROT;
+    }
+
     vl3e = &vl3tab[l3_table_offset(dsi.v_start)];
 
     for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
     {
-        if (!(count % (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){
-            l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
+        if (!(count & (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){
+            l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]
+                & PAGE_MASK;
 
             if (vl2tab != NULL)
                 munmap(vl2tab, PAGE_SIZE);
@@ -486,8 +452,6 @@
                                                 l2tab >> PAGE_SHIFT)) == NULL )
                 goto error_out;
 
-            memset(vl2tab, 0, PAGE_SIZE);
-            *vl3e++ = l2tab | L3_PROT;
             vl2e = &vl2tab[l2_table_offset(dsi.v_start + (count << 
PAGE_SHIFT))];
         }
         if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
@@ -519,103 +483,31 @@
     for ( count = 0; count < nr_pages; count++ )
     {
         if ( xc_add_mmu_update(xc_handle, mmu,
-                               (page_array[count] << PAGE_SHIFT) | 
+                               (page_array[count] << PAGE_SHIFT) |
                                MMU_MACHPHYS_UPDATE, count) )
             goto error_out;
     }
 
     set_nr_vcpus(xc_handle, dom, page_array, &dsi, vcpus);
 
-    if ((boot_paramsp = xc_map_foreign_range(
+    *store_mfn = page_array[(v_end-2) >> PAGE_SHIFT];
+    shared_page_frame = (v_end - PAGE_SIZE) >> PAGE_SHIFT;
+
+    if ((e820_page = xc_map_foreign_range(
         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
-        page_array[(vboot_params_start-dsi.v_start)>>PAGE_SHIFT])) == 0)
-        goto error_out;
-
-    memset(boot_paramsp, 0, sizeof(*boot_paramsp));
-
-    strncpy((char *)boot_paramsp->cmd_line, cmdline, 0x800);
-    boot_paramsp->cmd_line[0x800-1] = '\0';
-    boot_paramsp->cmd_line_ptr = ((unsigned long) vboot_params_start) + 
offsetof(struct linux_boot_params, cmd_line);
-
-    boot_paramsp->setup_sects = 0;
-    boot_paramsp->mount_root_rdonly = 1;
-    boot_paramsp->swapdev = 0x0; 
-    boot_paramsp->ramdisk_flags = 0x0; 
-    boot_paramsp->root_dev = 0x0; /* We must tell kernel root dev by kernel 
command line. */
-
-    /* we don't have a ps/2 mouse now.
-     * 0xAA means a aux mouse is there.
-     * See detect_auxiliary_port() in pc_keyb.c.
-     */
-    boot_paramsp->aux_device_info = 0x0; 
-
-    boot_paramsp->header_magic[0] = 0x48; /* "H" */
-    boot_paramsp->header_magic[1] = 0x64; /* "d" */
-    boot_paramsp->header_magic[2] = 0x72; /* "r" */
-    boot_paramsp->header_magic[3] = 0x53; /* "S" */
-
-    boot_paramsp->protocol_version = 0x0203; /* 2.03 */
-    boot_paramsp->loader_type = 0x71; /* GRUB */
-    boot_paramsp->loader_flags = 0x1; /* loaded high */
-    boot_paramsp->code32_start = LINUX_KERNEL_ENTR_ADDR; /* 1MB */
-    boot_paramsp->initrd_start = vinitrd_start;
-    boot_paramsp->initrd_size = initrd_len;
-
-    i = ((memsize - 1) << 10) - 4;
-    boot_paramsp->alt_mem_k = i; /* alt_mem_k */
-    boot_paramsp->screen.overlap.ext_mem_k = i & 0xFFFF; /* ext_mem_k */
-
-    /*
-     * Stuff SCREAN_INFO
-     */
-    boot_paramsp->screen.info.orig_x = 0;
-    boot_paramsp->screen.info.orig_y = 0;
-    boot_paramsp->screen.info.orig_video_page = 8;
-    boot_paramsp->screen.info.orig_video_mode = 3;
-    boot_paramsp->screen.info.orig_video_cols = 80;
-    boot_paramsp->screen.info.orig_video_ega_bx = 0;
-    boot_paramsp->screen.info.orig_video_lines = 25;
-    boot_paramsp->screen.info.orig_video_isVGA = 1;
-    boot_paramsp->screen.info.orig_video_points = 0x0010;
-
-    /* seems we may NOT stuff boot_paramsp->apm_bios_info */
-    /* seems we may NOT stuff boot_paramsp->drive_info */
-    /* seems we may NOT stuff boot_paramsp->sys_desc_table */
-    *((unsigned short *) &boot_paramsp->drive_info.dummy[0]) = 800;
-    boot_paramsp->drive_info.dummy[2] = 4;
-    boot_paramsp->drive_info.dummy[14] = 32;
-
-    /* memsize is in megabytes */
-    /* If you need to create a special e820map, comment this line
-       and use mem-map.sxp */
-    build_e820map(mem_mapp, memsize << 20);
-    *store_mfn = page_array[(v_end-2) >> PAGE_SHIFT];
+        page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0)
+        goto error_out;
+    memset(e820_page, 0, PAGE_SIZE);
+    e820_map_nr = build_e820map(e820_page, v_end);
 #if defined (__i386__)
-    if (zap_mmio_ranges(xc_handle, dom, l2tab, mem_mapp) == -1)
+    if (zap_mmio_ranges(xc_handle, dom, l2tab, e820_map_nr,
+                        ((unsigned char *)e820_page) + E820_MAP_OFFSET) == -1)
 #else
-        if (zap_mmio_ranges(xc_handle, dom, l3tab, mem_mapp) == -1)
+    if (zap_mmio_ranges(xc_handle, dom, l3tab, e820_map_nr,
+                        ((unsigned char *)e820_page) + E820_MAP_OFFSET) == -1)
 #endif
-            goto error_out;
-    boot_paramsp->e820_map_nr = mem_mapp->nr_map;
-    for (i=0; i<mem_mapp->nr_map; i++) {
-        boot_paramsp->e820_map[i].addr = mem_mapp->map[i].addr; 
-        boot_paramsp->e820_map[i].size = mem_mapp->map[i].size; 
-        boot_paramsp->e820_map[i].type = mem_mapp->map[i].type; 
-        if (mem_mapp->map[i].type == E820_SHARED)
-            shared_page_frame = (mem_mapp->map[i].addr >> PAGE_SHIFT);
-    }
-    munmap(boot_paramsp, PAGE_SIZE); 
-
-    if ((boot_gdtp = xc_map_foreign_range(
-        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
-        page_array[(vboot_gdt_start-dsi.v_start)>>PAGE_SHIFT])) == 0)
-        goto error_out;
-    memset(boot_gdtp, 0, PAGE_SIZE);
-    boot_gdtp[12*4 + 0] = boot_gdtp[13*4 + 0] = 0xffff; /* limit */
-    boot_gdtp[12*4 + 1] = boot_gdtp[13*4 + 1] = 0x0000; /* base */
-    boot_gdtp[12*4 + 2] = 0x9a00; boot_gdtp[13*4 + 2] = 0x9200; /* perms */
-    boot_gdtp[12*4 + 3] = boot_gdtp[13*4 + 3] = 0x00cf; /* granu + top of 
limit */
-    munmap(boot_gdtp, PAGE_SIZE);
+        goto error_out;
+    munmap(e820_page, PAGE_SIZE);
 
     /* shared_info page starts its life empty. */
     if ((shared_info = xc_map_foreign_range(
@@ -651,20 +543,21 @@
     /*
      * Initial register values:
      */
-    ctxt->user_regs.ds = 0x68;
-    ctxt->user_regs.es = 0x0;
-    ctxt->user_regs.fs = 0x0;
-    ctxt->user_regs.gs = 0x0;
-    ctxt->user_regs.ss = 0x68;
-    ctxt->user_regs.cs = 0x60;
+    ctxt->user_regs.ds = 0;
+    ctxt->user_regs.es = 0;
+    ctxt->user_regs.fs = 0;
+    ctxt->user_regs.gs = 0;
+    ctxt->user_regs.ss = 0;
+    ctxt->user_regs.cs = 0;
     ctxt->user_regs.eip = dsi.v_kernentry;
-    ctxt->user_regs.edx = vboot_gdt_start;
-    ctxt->user_regs.eax = 0x800;
-    ctxt->user_regs.esp = vboot_gdt_end;
+    ctxt->user_regs.edx = 0;
+    ctxt->user_regs.eax = 0;
+    ctxt->user_regs.esp = 0;
     ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot 
cpu */
-    ctxt->user_regs.ecx = mem_mapp->nr_map;
-    ctxt->user_regs.esi = vboot_params_start;
-    ctxt->user_regs.edi = vboot_params_start + 0x2d0;
+    ctxt->user_regs.ecx = 0;
+    ctxt->user_regs.esi = 0;
+    ctxt->user_regs.edi = 0;
+    ctxt->user_regs.ebp = 0;
 
     ctxt->user_regs.eflags = 0;
 
@@ -684,9 +577,9 @@
     int eax, ecx;
 
 #ifdef __i386__
-    __asm__ __volatile__ ("pushl %%ebx; cpuid; popl %%ebx" 
-                          : "=a" (eax), "=c" (ecx) 
-                          : "0" (1) 
+    __asm__ __volatile__ ("pushl %%ebx; cpuid; popl %%ebx"
+                          : "=a" (eax), "=c" (ecx)
+                          : "0" (1)
                           : "dx");
 #elif defined __x86_64__
     __asm__ __volatile__ ("pushq %%rbx; cpuid; popq %%rbx"
@@ -705,9 +598,6 @@
                  u32 domid,
                  int memsize,
                  const char *image_name,
-                 struct mem_map *mem_mapp,
-                 const char *ramdisk_name,
-                 const char *cmdline,
                  unsigned int control_evtchn,
                  unsigned long flags,
                  unsigned int vcpus,
@@ -715,20 +605,18 @@
                  unsigned long *store_mfn)
 {
     dom0_op_t launch_op, op;
-    int initrd_fd = -1;
-    gzFile initrd_gfd = NULL;
     int rc, i;
     vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
     unsigned long nr_pages;
     char         *image = NULL;
-    unsigned long image_size, initrd_size=0;
+    unsigned long image_size;
 
     if ( vmx_identify() < 0 )
     {
         PERROR("CPU doesn't support VMX Extensions");
         goto error_out;
     }
-    
+
     if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 )
     {
         PERROR("Could not find total pages for domain");
@@ -738,32 +626,15 @@
     if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL )
         goto error_out;
 
-    if ( (ramdisk_name != NULL) && (strlen(ramdisk_name) != 0) )
-    {
-        if ( (initrd_fd = open(ramdisk_name, O_RDONLY)) < 0 )
-        {
-            PERROR("Could not open the initial ramdisk image");
-            goto error_out;
-        }
-
-        initrd_size = xc_get_filesz(initrd_fd);
-
-        if ( (initrd_gfd = gzdopen(initrd_fd, "rb")) == NULL )
-        {
-            PERROR("Could not allocate decompression state for initrd");
-            goto error_out;
-        }
-    }
-
     if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
-    {   
+    {
         PERROR("xc_vmx_build: ctxt mlock failed");
         return 1;
     }
 
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = (domid_t)domid;
-    if ( (xc_dom0_op(xc_handle, &op) < 0) || 
+    if ( (xc_dom0_op(xc_handle, &op) < 0) ||
          ((u16)op.u.getdomaininfo.domain != domid) )
     {
         PERROR("Could not get info on domain");
@@ -783,21 +654,14 @@
         goto error_out;
     }
 
-    if ( setup_guest(xc_handle, domid, memsize, image, image_size, 
-                     initrd_gfd, initrd_size, nr_pages, 
-                     ctxt, cmdline,
-                     op.u.getdomaininfo.shared_info_frame,
-                     control_evtchn, flags, vcpus, store_evtchn, store_mfn,
-                     mem_mapp) < 0 )
+    if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
+                     ctxt, op.u.getdomaininfo.shared_info_frame, 
control_evtchn,
+                     flags, vcpus, store_evtchn, store_mfn) < 0)
     {
         ERROR("Error constructing guest OS");
         goto error_out;
     }
 
-    if ( initrd_fd >= 0 )
-        close(initrd_fd);
-    if ( initrd_gfd )
-        gzclose(initrd_gfd);
     free(image);
 
     ctxt->flags = VGCF_VMX_GUEST;
@@ -813,15 +677,10 @@
 
     /* No LDT. */
     ctxt->ldt_ents = 0;
-    
+
     /* Use the default Xen-provided GDT. */
     ctxt->gdt_ents = 0;
 
-    /* Ring 1 stack is the initial stack. */
-/*
-  ctxt->kernel_ss = FLAT_KERNEL_DS;
-  ctxt->kernel_sp = vstartinfo_start;
-*/
     /* No debugging. */
     memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
 
@@ -845,14 +704,10 @@
 
     launch_op.cmd = DOM0_SETDOMAININFO;
     rc = xc_dom0_op(xc_handle, &launch_op);
-    
+
     return rc;
 
  error_out:
-    if ( initrd_gfd != NULL )
-        gzclose(initrd_gfd);
-    else if ( initrd_fd >= 0 )
-        close(initrd_fd);
     free(image);
 
     return -1;
@@ -864,7 +719,7 @@
             ((phdr->p_flags & (PF_W|PF_X)) != 0));
 }
 
-static int parseelfimage(char *elfbase, 
+static int parseelfimage(char *elfbase,
                          unsigned long elfsize,
                          struct domain_setup_info *dsi)
 {
@@ -899,11 +754,11 @@
         ERROR("ELF image has no section-header strings table (shstrtab).");
         return -EINVAL;
     }
-    shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff + 
+    shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
                           (ehdr->e_shstrndx*ehdr->e_shentsize));
     shstrtab = elfbase + shdr->sh_offset;
-    
-    for ( h = 0; h < ehdr->e_phnum; h++ ) 
+
+    for ( h = 0; h < ehdr->e_phnum; h++ )
     {
         phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
         if ( !is_loadable_phdr(phdr) )
@@ -914,8 +769,8 @@
             kernend = phdr->p_paddr + phdr->p_memsz;
     }
 
-    if ( (kernstart > kernend) || 
-         (ehdr->e_entry < kernstart) || 
+    if ( (kernstart > kernend) ||
+         (ehdr->e_entry < kernstart) ||
          (ehdr->e_entry > kernend) )
     {
         ERROR("Malformed ELF image.");
@@ -924,9 +779,9 @@
 
     dsi->v_start = 0x00000000;
 
-    dsi->v_kernstart = kernstart - LINUX_PAGE_OFFSET;
-    dsi->v_kernend   = kernend - LINUX_PAGE_OFFSET;
-    dsi->v_kernentry = LINUX_KERNEL_ENTR_ADDR;
+    dsi->v_kernstart = kernstart;
+    dsi->v_kernend   = kernend;
+    dsi->v_kernentry = VMX_LOADER_ENTR_ADDR;
 
     dsi->v_end       = dsi->v_kernend;
 
@@ -945,18 +800,18 @@
     char         *va;
     unsigned long pa, done, chunksz;
 
-    for ( h = 0; h < ehdr->e_phnum; h++ ) 
+    for ( h = 0; h < ehdr->e_phnum; h++ )
     {
         phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
         if ( !is_loadable_phdr(phdr) )
             continue;
-        
+
         for ( done = 0; done < phdr->p_filesz; done += chunksz )
         {
-            pa = (phdr->p_paddr + done) - dsi->v_start - LINUX_PAGE_OFFSET;
+            pa = (phdr->p_paddr + done) - dsi->v_start;
             if ((va = xc_map_foreign_range(
                 xch, dom, PAGE_SIZE, PROT_WRITE,
-                parray[pa>>PAGE_SHIFT])) == 0)
+                parray[pa >> PAGE_SHIFT])) == 0)
                 return -1;
             chunksz = phdr->p_filesz - done;
             if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
@@ -968,10 +823,10 @@
 
         for ( ; done < phdr->p_memsz; done += chunksz )
         {
-            pa = (phdr->p_paddr + done) - dsi->v_start - LINUX_PAGE_OFFSET;
+            pa = (phdr->p_paddr + done) - dsi->v_start;
             if ((va = xc_map_foreign_range(
                 xch, dom, PAGE_SIZE, PROT_WRITE,
-                parray[pa>>PAGE_SHIFT])) == 0)
+                parray[pa >> PAGE_SHIFT])) == 0)
                 return -1;
             chunksz = phdr->p_memsz - done;
             if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Fri Sep 23 21:41:28 2005
+++ b/tools/libxc/xenguest.h    Mon Sep 26 17:07:49 2005
@@ -57,9 +57,6 @@
                  uint32_t domid,
                  int memsize,
                  const char *image_name,
-                 struct mem_map *memmap,
-                 const char *ramdisk_name,
-                 const char *cmdline,
                  unsigned int control_evtchn,
                  unsigned long flags,
                  unsigned int vcpus,
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Fri Sep 23 21:41:28 2005
+++ b/tools/libxc/xg_private.h  Mon Sep 26 17:07:49 2005
@@ -28,25 +28,27 @@
 #define _PAGE_PSE       0x080
 #define _PAGE_GLOBAL    0x100
 
+#define L1_PAGETABLE_SHIFT_PAE   12
+#define L2_PAGETABLE_SHIFT_PAE   21
+#define L3_PAGETABLE_SHIFT_PAE   30
+
 #if defined(__i386__)
 #define L1_PAGETABLE_SHIFT       12
 #define L2_PAGETABLE_SHIFT       22
-#define L1_PAGETABLE_SHIFT_PAE   12
-#define L2_PAGETABLE_SHIFT_PAE   21
-#define L3_PAGETABLE_SHIFT_PAE   30
 #elif defined(__x86_64__)
-#define L1_PAGETABLE_SHIFT      12
-#define L2_PAGETABLE_SHIFT      21
-#define L3_PAGETABLE_SHIFT      30
-#define L4_PAGETABLE_SHIFT      39
+#define L1_PAGETABLE_SHIFT       12
+#define L2_PAGETABLE_SHIFT       21
+#define L3_PAGETABLE_SHIFT       30
+#define L4_PAGETABLE_SHIFT       39
 #endif
 
-#if defined(__i386__) 
-#define ENTRIES_PER_L1_PAGETABLE 1024
-#define ENTRIES_PER_L2_PAGETABLE 1024
 #define L1_PAGETABLE_ENTRIES_PAE  512
 #define L2_PAGETABLE_ENTRIES_PAE  512
 #define L3_PAGETABLE_ENTRIES_PAE    4
+
+#if defined(__i386__) 
+#define L1_PAGETABLE_ENTRIES   1024
+#define L2_PAGETABLE_ENTRIES   1024
 #elif defined(__x86_64__)
 #define L1_PAGETABLE_ENTRIES    512
 #define L2_PAGETABLE_ENTRIES    512
@@ -70,17 +72,18 @@
 typedef unsigned long l4_pgentry_t;
 #endif
 
-#if defined(__i386__)
-#define l1_table_offset(_a) \
-          (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1))
-#define l2_table_offset(_a) \
-          ((_a) >> L2_PAGETABLE_SHIFT)
 #define l1_table_offset_pae(_a) \
   (((_a) >> L1_PAGETABLE_SHIFT_PAE) & (L1_PAGETABLE_ENTRIES_PAE - 1))
 #define l2_table_offset_pae(_a) \
   (((_a) >> L2_PAGETABLE_SHIFT_PAE) & (L2_PAGETABLE_ENTRIES_PAE - 1))
 #define l3_table_offset_pae(_a) \
        (((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))
+
+#if defined(__i386__)
+#define l1_table_offset(_a) \
+          (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
+#define l2_table_offset(_a) \
+          ((_a) >> L2_PAGETABLE_SHIFT)
 #elif defined(__x86_64__)
 #define l1_table_offset(_a) \
   (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon Sep 26 17:07:49 2005
@@ -17,7 +17,6 @@
 #include <arpa/inet.h>
 
 #include "xc_private.h"
-#include "linux_boot_params.h"
 
 /* Needed for Python versions earlier than 2.3. */
 #ifndef PyMODINIT_FUNC
@@ -310,80 +309,24 @@
     XcObject *xc = (XcObject *)self;
 
     u32   dom;
-    char *image, *ramdisk = NULL, *cmdline = "";
-    PyObject *memmap;
+    char *image;
     int   control_evtchn, store_evtchn;
     int flags = 0, vcpus = 1;
-    int numItems, i;
     int memsize;
-    struct mem_map mem_map;
     unsigned long store_mfn = 0;
 
     static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
-                                "memsize", "image", "memmap",
-                               "ramdisk", "cmdline", "flags",
-                               "vcpus", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisO!|ssii", kwd_list, 
+                                "memsize", "image", "flags", "vcpus", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list,
                                       &dom, &control_evtchn, &store_evtchn,
-                                      &memsize,
-                                      &image, &PyList_Type, &memmap,
-                                     &ramdisk, &cmdline, &flags, &vcpus) )
-        return NULL;
-
-    memset(&mem_map, 0, sizeof(mem_map));
-    /* Parse memmap */
-
-    /* get the number of lines passed to us */
-    numItems = PyList_Size(memmap) - 1;        /* removing the line 
-                                          containing "memmap" */
-    mem_map.nr_map = numItems;
-   
-    /* should raise an error here. */
-    if (numItems < 0) return NULL; /* Not a list */
-
-    /* iterate over items of the list, grabbing ranges and parsing them */
-    for (i = 1; i <= numItems; i++) {  // skip over "memmap"
-           PyObject *item, *f1, *f2, *f3, *f4;
-           int numFields;
-           unsigned long lf1, lf2, lf3, lf4;
-           char *sf1, *sf2;
-           
-           /* grab the string object from the next element of the list */
-           item = PyList_GetItem(memmap, i); /* Can't fail */
-
-           /* get the number of lines passed to us */
-           numFields = PyList_Size(item);
-
-           if (numFields != 4)
-                   return NULL;
-
-           f1 = PyList_GetItem(item, 0);
-           f2 = PyList_GetItem(item, 1);
-           f3 = PyList_GetItem(item, 2);
-           f4 = PyList_GetItem(item, 3);
-
-           /* Convert objects to strings/longs */
-           sf1 = PyString_AsString(f1);
-           sf2 = PyString_AsString(f2);
-           lf3 = PyLong_AsLong(f3);
-           lf4 = PyLong_AsLong(f4);
-           if ( sscanf(sf1, "%lx", &lf1) != 1 )
-                return NULL;
-           if ( sscanf(sf2, "%lx", &lf2) != 1 )
-                return NULL;
-
-            mem_map.map[i-1].addr = lf1;
-            mem_map.map[i-1].size = lf2 - lf1;
-            mem_map.map[i-1].type = lf3;
-            mem_map.map[i-1].caching_attr = lf4;
-    }
-
-    if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, &mem_map,
-                        ramdisk, cmdline, control_evtchn, flags,
-                        vcpus, store_evtchn, &store_mfn) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
+                                      &memsize, &image, &flags, &vcpus) )
+        return NULL;
+
+    if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, control_evtchn,
+                      flags, vcpus, store_evtchn, &store_mfn) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
     return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
 }
 
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/lowlevel/xs/xs.c Mon Sep 26 17:07:49 2005
@@ -582,9 +582,8 @@
 }
 
 #define xspy_transaction_start_doc "\n"                                \
-       "Start a transaction on a path.\n"                      \
+       "Start a transaction.\n"                                \
        "Only one transaction can be active at a time.\n"       \
-       " path [string]: xenstore path.\n"                      \
        "\n"                                                    \
        "Returns None on success.\n"                            \
        "Raises RuntimeError on error.\n"                       \
@@ -593,8 +592,8 @@
 static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
                                         PyObject *kwds)
 {
-    static char *kwd_spec[] = { "path", NULL };
-    static char *arg_spec = "s|";
+    static char *kwd_spec[] = { NULL };
+    static char *arg_spec = "";
     char *path = NULL;
 
     struct xs_handle *xh = xshandle(self);
@@ -606,7 +605,7 @@
     if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
         goto exit;
     Py_BEGIN_ALLOW_THREADS
-    xsval = xs_transaction_start(xh, path);
+    xsval = xs_transaction_start(xh);
     Py_END_ALLOW_THREADS
     if (!xsval) {
         PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -623,7 +622,7 @@
        "Attempts to commit the transaction unless abort is true.\n"    \
        " abort [int]: abort flag (default 0).\n"                       \
        "\n"                                                            \
-       "Returns None on success.\n"                                    \
+       "Returns True on success, False if you need to try again.\n"    \
        "Raises RuntimeError on error.\n"                               \
        "\n"
 
@@ -646,11 +645,16 @@
     xsval = xs_transaction_end(xh, abort);
     Py_END_ALLOW_THREADS
     if (!xsval) {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
-        goto exit;
-    }
-    Py_INCREF(Py_None);
-    val = Py_None;
+       if (errno == EAGAIN) {
+           Py_INCREF(Py_False);
+           val = Py_False;
+           goto exit;
+       }
+        PyErr_SetFromErrno(PyExc_RuntimeError);
+        goto exit;
+    }
+    Py_INCREF(Py_True);
+    val = Py_True;
  exit:
     return val;
 }
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xend/PrettyPrint.py
--- a/tools/python/xen/xend/PrettyPrint.py      Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/PrettyPrint.py      Mon Sep 26 17:07:49 2005
@@ -252,7 +252,7 @@
         self.block = self.block.parent
 
     def prettyprint(self, out=sys.stdout):
-        self.top.prettyprint(Line(out, self.width))
+        self.top.prettyprint(Line(out, self.width), self.width)
 
 class SXPPrettyPrinter(PrettyPrinter):
     """An SXP prettyprinter.
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/XendDomain.py       Mon Sep 26 17:07:49 2005
@@ -433,12 +433,11 @@
             self.domain_shutdowns()
         return val
 
+
     def domain_sysrq(self, id, key):
-        """Send a SysRq to a domain
-        """
-        dominfo = self.domain_lookup(id)
-        val = dominfo.send_sysrq(key)
-        return val
+        """Send a SysRq to the specified domain."""
+        return self.callInfo(id, XendDomainInfo.send_sysrq, key)
+
 
     def domain_shutdowns(self):
         """Process pending domain shutdowns.
@@ -630,73 +629,45 @@
         except Exception, ex:
             raise XendError(str(ex))
 
-    def domain_device_create(self, id, devconfig):
-        """Create a new device for a domain.
-
-        @param id:       domain id
-        @param devconfig: device configuration
-        """
-        dominfo = self.domain_lookup(id)
-        val = dominfo.device_create(devconfig)
-        dominfo.exportToDB()
-        return val
-
-    def domain_device_configure(self, id, devconfig, devid):
-        """Configure an existing device for a domain.
-
-        @param id:   domain id
-        @param devconfig: device configuration
-        @param devid:  device id
+
+    def domain_device_create(self, domid, devconfig):
+        """Create a new device for the specified domain.
+        """
+        return self.callInfo(domid, XendDomainInfo.device_create, devconfig)
+
+
+    def domain_device_configure(self, domid, devconfig, devid):
+        """Configure an existing device in the specified domain.
         @return: updated device configuration
         """
-        dominfo = self.domain_lookup(id)
-        val = dominfo.device_configure(devconfig, devid)
-        dominfo.exportToDB()
-        return val
+        return self.callInfo(domid, XendDomainInfo.device_configure,
+                             devconfig, devid)
+
     
-    def domain_device_refresh(self, id, type, devid):
-        """Refresh a device.
-
-        @param id:  domain id
-        @param devid:  device id
-        @param type: device type
-        """
-        dominfo = self.domain_lookup(id)
-        val = dominfo.device_refresh(type, devid)
-        dominfo.exportToDB()
-        return val
-
-    def domain_device_destroy(self, id, type, devid):
-        """Destroy a device.
-
-        @param id:  domain id
-        @param devid:  device id
-        @param type: device type
-        """
-        dominfo = self.domain_lookup(id)
-        return dominfo.destroyDevice(type, devid)
-
-
-    def domain_devtype_ls(self, id, type):
-        """Get list of device sxprs for a domain.
-
-        @param id:  domain
-        @param type: device type
-        @return: device sxprs
-        """
-        dominfo = self.domain_lookup(id)
-        return dominfo.getDeviceSxprs(type)
-
-    def domain_devtype_get(self, id, type, devid):
+    def domain_device_refresh(self, domid, devtype, devid):
+        """Refresh a device."""
+        return self.callInfo(domid, XendDomainInfo.device_refresh, devtype,
+                             devid)
+
+
+    def domain_device_destroy(self, domid, devtype, devid):
+        """Destroy a device."""
+        return self.callInfo(domid, XendDomainInfo.destroyDevice, devtype,
+                             devid)
+
+
+    def domain_devtype_ls(self, domid, devtype):
+        """Get list of device sxprs for the specified domain."""
+        return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype)
+
+
+    def domain_devtype_get(self, domid, devtype, devid):
         """Get a device from a domain.
         
-        @param id:  domain
-        @param type: device type
-        @param devid:  device id
         @return: device object (or None)
         """
-        dominfo = self.domain_lookup(id)
-        return dominfo.getDevice(type, devid)
+        return self.callInfo(domid, XendDomainInfo.getDevice, devtype, devid)
+
 
     def domain_vif_limit_set(self, id, vif, credit, period):
         """Limit the vif's transmission rate
@@ -723,7 +694,7 @@
         """Set the memory limit for a domain.
 
         @param id: domain
-        @param mem: memory limit (in MB)
+        @param mem: memory limit (in MiB)
         @return: 0 on success, -1 on error
         """
         dominfo = self.domain_lookup(id)
@@ -734,42 +705,37 @@
         except Exception, ex:
             raise XendError(str(ex))
 
-    def domain_mem_target_set(self, id, mem):
+    def domain_mem_target_set(self, domid, mem):
         """Set the memory target for a domain.
 
-        @param id: domain
-        @param mem: memory target (in MB)
-        @return: 0 on success, -1 on error
-        """
-        dominfo = self.domain_lookup(id)
-        return dominfo.setMemoryTarget(mem << 10)
-
-    def domain_vcpu_hotplug(self, id, vcpu, state):
-        """Enable or disable VCPU vcpu in DOM id
-
-        @param id: domain
+        @param mem: memory target (in MiB)
+        """
+        self.callInfo(domid, XendDomainInfo.setMemoryTarget, mem << 10)
+
+
+    def domain_vcpu_hotplug(self, domid, vcpu, state):
+        """Enable or disable specified VCPU in specified domain
+
         @param vcpu: target VCPU in domain
         @param state: which state VCPU will become
-        @return: 0 on success, -1 on error
-        """
-
-        dominfo = self.domain_lookup(id)
-        return dominfo.vcpu_hotplug(vcpu, state)
-
-    def domain_dumpcore(self, id):
-        """Save a core dump for a crashed domain.
-
-        @param id: domain
-        """
-        dominfo = self.domain_lookup(id)
-        corefile = "/var/xen/dump/%s.%s.core" % (dominfo.getName(),
-                                                 dominfo.getDomid())
-        try:
-            xc.domain_dumpcore(dom=dominfo.getDomid(), corefile=corefile)
-        except Exception, ex:
-            log.warning("Dumpcore failed, id=%s name=%s: %s",
-                        dominfo.getDomid(), dominfo.getName(), ex)
-        
+        """
+        self.callInfo(domid, XendDomainInfo.vcpu_hotplug, vcpu, state)
+
+
+    def domain_dumpcore(self, domid):
+        """Save a core dump for a crashed domain."""
+        self.callInfo(domid, XendDomainInfo.dumpCore)
+
+
+    ## private:
+
+    def callInfo(self, domid, fn, *args, **kwargs):
+        self.refresh()
+        dominfo = self.domains.get(domid)
+        if dominfo:
+            return fn(dominfo, *args, **kwargs)
+
+
 def instance():
     """Singleton constructor. Use this instead of the class constructor.
     """
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Mon Sep 26 17:07:49 2005
@@ -34,6 +34,7 @@
 
 from xen.xend.server.channel import EventChannel
 
+from xen.xend import image
 from xen.xend import sxp
 from xen.xend.XendBootloader import bootloader
 from xen.xend.XendLogging import log
@@ -319,6 +320,7 @@
 
         try:
             defaultInfo('name',         lambda: "Domain-%d" % self.domid)
+            defaultInfo('ssidref',      lambda: 0)
             defaultInfo('restart_mode', lambda: RESTART_ONREBOOT)
             defaultInfo('cpu_weight',   lambda: 1.0)
             defaultInfo('bootloader',   lambda: None)
@@ -511,6 +513,19 @@
                       self.info['backend'], 0)
 
 
+    def dumpCore(self):
+        """Create a core dump for this domain.  Nothrow guarantee."""
+        
+        try:
+            corefile = "/var/xen/dump/%s.%s.core" % (self.info['name'],
+                                                     self.domid)
+            xc.domain_dumpcore(dom = self.domid, corefile = corefile)
+
+        except Exception, exn:
+            log.error("XendDomainInfo.dumpCore failed: id = %s name = %s: %s",
+                      self.domid, self.info['name'], str(exn))
+
+
     def closeStoreChannel(self):
         """Close the store channel, if any.  Nothrow guarantee."""
         
@@ -614,7 +629,7 @@
             sxpr.append(['maxmem', self.info['maxmem_KiB'] / 1024])
 
             if self.infoIsSet('device'):
-                for (n, c) in self.info['device']:
+                for (_, c) in self.info['device']:
                     sxpr.append(['device', c])
 
             def stateChar(name):
@@ -706,13 +721,6 @@
         """
         # todo - add support for scheduling params?
         try:
-            if 'image' not in self.info:
-                raise VmError('Missing image in configuration')
-
-            self.image = ImageHandler.create(self,
-                                             self.info['image'],
-                                             self.info['device'])
-
             self.initDomain()
 
             # Create domain devices.
@@ -737,6 +745,14 @@
 
         self.domid = xc.domain_create(dom = self.domid or 0,
                                       ssidref = self.info['ssidref'])
+
+        if 'image' not in self.info:
+            raise VmError('Missing image in configuration')
+
+        self.image = image.create(self,
+                                  self.info['image'],
+                                  self.info['device'])
+
         if self.domid <= 0:
             raise VmError('Creating domain failed: name=%s' %
                           self.info['name'])
@@ -839,20 +855,20 @@
         """Release all vm devices.
         """
 
-        t = xstransact("%s/device" % self.path)
-
-        for n in controllerClasses.keys():
-            for d in t.list(n):
-                try:
-                    t.remove(d)
-                except ex:
-                    # Log and swallow any exceptions in removal -- there's
-                    # nothing more we can do.
-                    log.exception(
-                        "Device release failed: %s; %s; %s; %s" %
-                        (self.info['name'], n, d, str(ex)))
-        t.commit()
-
+        while True:
+            t = xstransact("%s/device" % self.path)
+            for n in controllerClasses.keys():
+                for d in t.list(n):
+                    try:
+                        t.remove(d)
+                    except ex:
+                        # Log and swallow any exceptions in removal --
+                        # there's nothing more we can do.
+                        log.exception(
+                           "Device release failed: %s; %s; %s; %s" %
+                            (self.info['name'], n, d, str(ex)))
+            if t.commit():
+                break
 
     def eventChannel(self, path=None):
         """Create an event channel to the domain.
@@ -1085,19 +1101,6 @@
 
 
 #============================================================================
-# Register image handlers.
-
-from image import          \
-     addImageHandlerClass, \
-     ImageHandler,         \
-     LinuxImageHandler,    \
-     VmxImageHandler
-
-addImageHandlerClass(LinuxImageHandler)
-addImageHandlerClass(VmxImageHandler)
-
-
-#============================================================================
 # Register device controllers and their device config types.
 
 """A map from device-class names to the subclass of DevController that
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/image.py    Mon Sep 26 17:07:49 2005
@@ -33,6 +33,15 @@
 
 MAX_GUEST_CMDLINE = 1024
 
+
+def create(vm, imageConfig, deviceConfig):
+    """Create an image handler for a vm.
+
+    @return ImageHandler instance
+    """
+    return findImageHandlerClass(imageConfig)(vm, imageConfig, deviceConfig)
+
+
 class ImageHandler:
     """Abstract base class for image handlers.
 
@@ -48,81 +57,39 @@
 
     The method destroy() is called when the domain is destroyed.
     The default is to do nothing.
-    
     """
 
-    #======================================================================
-    # Class vars and methods.
-
-    """Table of image handler classes for virtual machine images.
-    Indexed by image type.
-    """
-    imageHandlerClasses = {}
-
-    def addImageHandlerClass(cls, h):
-        """Add a handler class for an image type
-        @param h:        handler: ImageHandler subclass
-        """
-        cls.imageHandlerClasses[h.ostype] = h
-
-    addImageHandlerClass = classmethod(addImageHandlerClass)
-
-    def findImageHandlerClass(cls, image):
-        """Find the image handler class for an image config.
-
-        @param image config
-        @return ImageHandler subclass or None
-        """
-        ty = sxp.name(image)
-        if ty is None:
-            raise VmError('missing image type')
-        imageClass = cls.imageHandlerClasses.get(ty)
-        if imageClass is None:
-            raise VmError('unknown image type: ' + ty)
-        return imageClass
-
-    findImageHandlerClass = classmethod(findImageHandlerClass)
-
-    def create(cls, vm, imageConfig, deviceConfig):
-        """Create an image handler for a vm.
-
-        @return ImageHandler instance
-        """
-        imageClass = cls.findImageHandlerClass(imageConfig)
-        return imageClass(vm, imageConfig, deviceConfig)
-
-    create = classmethod(create)
-
-    #======================================================================
-    # Instance vars and methods.
-
     ostype = None
 
-    kernel = None
-    ramdisk = None
-    cmdline = None
-
-    flags = 0
 
     def __init__(self, vm, imageConfig, deviceConfig):
         self.vm = vm
+
+        self.kernel = None
+        self.ramdisk = None
+        self.cmdline = None
+        self.flags = 0
+
         self.configure(imageConfig, deviceConfig)
 
     def configure(self, imageConfig, _):
         """Config actions common to all unix-like domains."""
 
-        self.kernel = sxp.child_value(imageConfig, "kernel")
+        def get_cfg(name, default = None):
+            return sxp.child_value(imageConfig, name, default)
+
+        self.kernel = get_cfg("kernel")
         self.cmdline = ""
-        ip = sxp.child_value(imageConfig, "ip", None)
+        ip = get_cfg("ip")
         if ip:
             self.cmdline += " ip=" + ip
-        root = sxp.child_value(imageConfig, "root")
+        root = get_cfg("root")
         if root:
             self.cmdline += " root=" + root
-        args = sxp.child_value(imageConfig, "args")
+        args = get_cfg("args")
         if args:
             self.cmdline += " " + args
-        self.ramdisk = sxp.child_value(imageConfig, "ramdisk", '')
+        self.ramdisk = get_cfg("ramdisk", '')
         
         self.vm.storeVm(("image/ostype", self.ostype),
                         ("image/kernel", self.kernel),
@@ -130,7 +97,7 @@
                         ("image/ramdisk", self.ramdisk))
 
 
-    def handleBootloading():
+    def handleBootloading(self):
         self.unlink(self.kernel)
         self.unlink(self.ramdisk)
 
@@ -194,7 +161,6 @@
         if d.has_key('console_mfn'):
             self.vm.setConsoleRef(d.get('console_mfn'))
 
-addImageHandlerClass = ImageHandler.addImageHandlerClass
 
 class LinuxImageHandler(ImageHandler):
 
@@ -238,22 +204,19 @@
 
     def configure(self, imageConfig, deviceConfig):
         ImageHandler.configure(self, imageConfig, deviceConfig)
-        
-        self.memmap = sxp.child_value(imageConfig, 'memmap')
+
         self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
         self.device_model = sxp.child_value(imageConfig, 'device_model')
         if not self.device_model:
             raise VmError("vmx: missing device model")
         self.display = sxp.child_value(imageConfig, 'display')
 
-        self.vm.storeVm(("image/memmap", self.memmap),
-                        ("image/dmargs", " ".join(self.dmargs)),
+        self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
                         ("image/device-model", self.device_model),
                         ("image/display", self.display))
 
         self.device_channel = None
         self.pid = 0
-        self.memmap_value = []
 
         self.dmargs += self.configVNC(imageConfig)
 
@@ -261,7 +224,6 @@
     def createImage(self):
         """Create a VM for the VMX environment.
         """
-        self.parseMemmap()
         self.createDomain()
 
     def buildDomain(self):
@@ -278,9 +240,6 @@
         log.debug("control_evtchn = %d", self.device_channel.port2)
         log.debug("store_evtchn   = %d", store_evtchn)
         log.debug("memsize        = %d", self.vm.getMemoryTarget() / 1024)
-        log.debug("memmap         = %s", self.memmap_value)
-        log.debug("cmdline        = %s", self.cmdline)
-        log.debug("ramdisk        = %s", self.ramdisk)
         log.debug("flags          = %d", self.flags)
         log.debug("vcpus          = %d", self.vm.getVCpuCount())
 
@@ -289,9 +248,6 @@
                            control_evtchn = self.device_channel.port2,
                            store_evtchn   = store_evtchn,
                            memsize        = self.vm.getMemoryTarget() / 1024,
-                           memmap         = self.memmap_value,
-                           cmdline        = self.cmdline,
-                           ramdisk        = self.ramdisk,
                            flags          = self.flags,
                            vcpus          = self.vm.getVCpuCount())
         if isinstance(ret, dict):
@@ -299,18 +255,11 @@
             return 0
         return ret
 
-    def parseMemmap(self):
-        if self.memmap is None:
-            return
-        memmap = sxp.parse(open(self.memmap))[0]
-        from xen.util.memmap import memmap_parse
-        self.memmap_value = memmap_parse(memmap)
-        
     # Return a list of cmd line args to the device models based on the
     # xm config file
     def parseDeviceModelArgs(self, imageConfig, deviceConfig):
         dmargs = [ 'cdrom', 'boot', 'fda', 'fdb',
-                   'localtime', 'serial', 'stdvga', 'isa', 'vcpus' ] 
+                   'localtime', 'serial', 'stdvga', 'isa', 'vcpus' ]
         ret = []
         for a in dmargs:
             v = sxp.child_value(imageConfig, a)
@@ -439,3 +388,28 @@
             return 16 * 1024
         else:
             return (1 + ((mem_mb + 3) >> 2)) * 4
+
+
+"""Table of image handler classes for virtual machine images.  Indexed by
+image type.
+"""
+imageHandlerClasses = {}
+
+
+for h in LinuxImageHandler, VmxImageHandler:
+    imageHandlerClasses[h.ostype] = h
+
+
+def findImageHandlerClass(image):
+    """Find the image handler class for an image config.
+
+    @param image config
+    @return ImageHandler subclass or None
+    """
+    ty = sxp.name(image)
+    if ty is None:
+        raise VmError('missing image type')
+    imageClass = imageHandlerClasses.get(ty)
+    if imageClass is None:
+        raise VmError('unknown image type: ' + ty)
+    return imageClass
diff -r eaedc6b4ec0f -r ef9591d03fdd 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/server/DevController.py     Mon Sep 26 17:07:49 2005
@@ -126,20 +126,21 @@
         compulsory to use it; subclasses may prefer to allocate IDs based upon
         the device configuration instead.
         """
-        path = self.frontendMiscPath()
-        t = xstransact(path)
-        try:
-            result = t.read("nextDeviceID")
-            if result:
-                result = int(result)
-            else:
-                result = 1
-            t.write("nextDeviceID", str(result + 1))
-            t.commit()
-            return result
-        except:
-            t.abort()
-            raise
+        while True:
+            path = self.frontendMiscPath()
+            t = xstransact(path)
+            try:
+                result = t.read("nextDeviceID")
+                if result:
+                    result = int(result)
+                else:
+                    result = 1
+                t.write("nextDeviceID", str(result + 1))
+                if t.commit():
+                    return result
+            except:
+                t.abort()
+                raise
 
 
     ## private:
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xend/xenstore/xsnode.py
--- a/tools/python/xen/xend/xenstore/xsnode.py  Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/xenstore/xsnode.py  Mon Sep 26 17:07:49 2005
@@ -280,8 +280,8 @@
                                (', while writing %s : %s' % (str(path),
                                                              str(data))))
 
-    def begin(self, path):
-        self.getxs().transaction_start(path)
+    def begin(self):
+        self.getxs().transaction_start()
 
     def commit(self, abandon=False):
         self.getxs().transaction_end(abort=abandon)
diff -r eaedc6b4ec0f -r ef9591d03fdd 
tools/python/xen/xend/xenstore/xstransact.py
--- a/tools/python/xen/xend/xenstore/xstransact.py      Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/xenstore/xstransact.py      Mon Sep 26 17:07:49 2005
@@ -14,16 +14,8 @@
     def __init__(self, path):
         self.in_transaction = False
         self.path = path.rstrip("/")
-        while True:
-            try:
-                xshandle().transaction_start(path)
-                self.in_transaction = True
-                return
-            except RuntimeError, ex:
-                if ex.args[0] == errno.ENOENT and path != "/":
-                    path = "/".join(path.split("/")[0:-1]) or "/"
-                else:
-                    raise
+        xshandle().transaction_start()
+        self.in_transaction = True
 
     def __del__(self):
         if self.in_transaction:
@@ -175,14 +167,8 @@
             t = cls(path)
             try:
                 v = t.read(*args)
-                t.commit()
+                t.abort()
                 return v
-            except RuntimeError, ex:
-                t.abort()
-                if ex.args[0] == errno.ETIMEDOUT:
-                    pass
-                else:
-                    raise
             except:
                 t.abort()
                 raise
@@ -194,14 +180,8 @@
             t = cls(path)
             try:
                 t.write(*args, **opts)
-                t.commit()
-                return
-            except RuntimeError, ex:
-                t.abort()
-                if ex.args[0] == errno.ETIMEDOUT:
-                    pass
-                else:
-                    raise
+                if t.commit():
+                    return
             except:
                 t.abort()
                 raise
@@ -217,14 +197,8 @@
             t = cls(path)
             try:
                 t.remove(*args)
-                t.commit()
-                return
-            except RuntimeError, ex:
-                t.abort()
-                if ex.args[0] == errno.ETIMEDOUT:
-                    pass
-                else:
-                    raise
+                if t.commit():
+                    return
             except:
                 t.abort()
                 raise
@@ -236,14 +210,8 @@
             t = cls(path)
             try:
                 v = t.list(*args)
-                t.commit()
-                return v
-            except RuntimeError, ex:
-                t.abort()
-                if ex.args[0] == errno.ETIMEDOUT:
-                    pass
-                else:
-                    raise
+                if t.commit():
+                    return v
             except:
                 t.abort()
                 raise
@@ -255,14 +223,8 @@
             t = cls(path)
             try:
                 v = t.gather(*args)
-                t.commit()
-                return v
-            except RuntimeError, ex:
-                t.abort()
-                if ex.args[0] == errno.ETIMEDOUT:
-                    pass
-                else:
-                    raise
+                if t.commit():
+                    return v
             except:
                 t.abort()
                 raise
@@ -274,14 +236,8 @@
             t = cls(path)
             try:
                 v = t.store(*args)
-                t.commit()
-                return v
-            except RuntimeError, ex:
-                t.abort()
-                if ex.args[0] == errno.ETIMEDOUT:
-                    pass
-                else:
-                    raise
+                if t.commit():
+                    return v
             except:
                 t.abort()
                 raise
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xm/main.py       Mon Sep 26 17:07:49 2005
@@ -1,5 +1,6 @@
 # (C) Copyright IBM Corp. 2005
 # Copyright (C) 2004 Mike Wray
+# Copyright (c) 2005 XenSource Ltd
 #
 # Authors:
 #     Sean Dague <sean at dague dot net>
@@ -169,12 +170,6 @@
 #
 #########################################################################
 
-def xm_create(args):
-    from xen.xm import create
-    # ugly hack because the opt parser apparently wants
-    # the subcommand name just to throw it away!
-    create.main(["bogus"] + args)
-
 def xm_save(args):
     arg_check(args,2,"save")
 
@@ -195,13 +190,6 @@
     id = sxp.child_value(info, 'domid')
     if id is not None:
         server.xend_domain_unpause(domid)
-
-def xm_migrate(args):
-    # TODO: arg_check
-    from xen.xm import migrate
-    # ugly hack because the opt parser apparently wants
-    # the subcommand name just to throw it away!
-    migrate.main(["bogus"] + args)
 
 def xm_list(args):
     use_long = 0
@@ -290,14 +278,6 @@
 def xm_vcpu_list(args):
     xm_list(["-v"] + args)
 
-def xm_destroy(args):
-    arg_check(args,1,"destroy")
-
-    from xen.xm import destroy
-    # ugly hack because the opt parser apparently wants
-    # the subcommand name just to throw it away!
-    destroy.main(["bogus"] + args)
-            
 def xm_reboot(args):
     arg_check(args,1,"reboot")
     from xen.xm import shutdown
@@ -305,20 +285,6 @@
     # the subcommand name just to throw it away!
     shutdown.main(["bogus", "-R"] + args)
 
-def xm_shutdown(args):
-    arg_check(args,1,"shutdown")
-
-    from xen.xm import shutdown
-    # ugly hack because the opt parser apparently wants
-    # the subcommand name just to throw it away!
-    shutdown.main(["bogus"] + args)
-
-def xm_sysrq(args):
-    from xen.xm import sysrq
-    # ugly hack because the opt parser apparently wants
-    # the subcommand name just to throw it away!
-    sysrq.main(["bogus"] + args)
-
 def xm_pause(args):
     arg_check(args, 1, "pause")
     dom = args[0]
@@ -332,6 +298,11 @@
 
     from xen.xend.XendClient import server
     server.xend_domain_unpause(dom)
+
+def xm_subcommand(command, args):
+    cmd = __import__(command, globals(), locals(), 'xen.xm')
+    cmd.main(["bogus"] + args)
+
 
 #############################################################
 
@@ -506,14 +477,6 @@
         sxp.show(x)
         print
 
-def xm_network_attach(args):
-
-    print "Not implemented"
-
-def xm_network_detach(args):
-
-    print "Not implemented"
-    
 def xm_block_list(args):
     arg_check(args,1,"block-list")
     dom = args[0]
@@ -609,11 +572,8 @@
     # domain commands
     "domid": xm_domid,
     "domname": xm_domname,
-    "create": xm_create,
-    "destroy": xm_destroy,
     "restore": xm_restore,
     "save": xm_save,
-    "shutdown": xm_shutdown,
     "reboot": xm_reboot,
     "list": xm_list,
     # memory commands
@@ -625,10 +585,7 @@
     "vcpu-enable": xm_vcpu_enable,
     "vcpu-disable": xm_vcpu_disable,
     "vcpu-list": xm_vcpu_list,
-    # migration
-    "migrate": xm_migrate,
     # special
-    "sysrq": xm_sysrq,
     "pause": xm_pause,
     "unpause": xm_unpause,
     # host commands
@@ -647,13 +604,23 @@
     # network
     "network-limit": xm_network_limit,
     "network-list": xm_network_list,
-    "network-attach": xm_network_attach,
-    "network-detach": xm_network_detach,
     # vnet
     "vnet-list": xm_vnet_list,
     "vnet-create": xm_vnet_create,
     "vnet-delete": xm_vnet_delete,
     }
+
+## The commands supported by a separate argument parser in xend.xm.
+subcommands = [
+    'create',
+    'destroy',
+    'migrate',
+    'sysrq',
+    'shutdown'
+    ]
+
+for c in subcommands:
+    commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c)
 
 aliases = {
     "balloon": "mem-set",
@@ -669,6 +636,7 @@
     "--long": longhelp
    }
 
+
 def xm_lookup_cmd(cmd):
     if commands.has_key(cmd):
         return commands[cmd]
@@ -688,9 +656,7 @@
     err('Option %s is the new replacement, see "xm help %s" for more info' % 
(new, new))
 
 def usage(cmd=None):
-    if cmd == "full":
-        print fullhelp
-    elif help.has_key(cmd):
+    if help.has_key(cmd):
         print help[cmd]
     else:
         print shorthelp
@@ -701,7 +667,7 @@
         usage()
     
     if re.compile('-*help').match(argv[1]):
-       if len(argv) > 2 and help.has_key(argv[2]):
+       if len(argv) > 2:
            usage(argv[2])
        else:
            usage()
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/Makefile   Mon Sep 26 17:07:49 2005
@@ -28,11 +28,11 @@
 CLIENTS += xenstore-write
 CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS))
 
-all: libxenstore.so xenstored $(CLIENTS)
+all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump
 
 testcode: xs_test xenstored_test xs_random xs_dom0_test
 
-xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o 
xenstored_transaction.o xs_lib.o talloc.o utils.o
+xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o 
xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@
 
 $(CLIENTS): libxenstore.so
@@ -42,13 +42,21 @@
 $(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c
        $(COMPILE.c) -DCLIENT_$(*F) -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
+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 $@
+
+xs_tdb_dump: xs_tdb_dump.o utils.o tdb.o talloc.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
 
 xs_test: xs_test.o xs_lib.o utils.o
 xs_random: xs_random.o xs_test_lib.o xs_lib.o talloc.o utils.o
 xs_stress: xs_stress.o xs_test_lib.o xs_lib.o talloc.o utils.o
 xs_crashme: xs_crashme.o xs_lib.o talloc.o utils.o
+
+speedtest: speedtest.o xs.o xs_lib.o utils.o talloc.o
+
+check-speed: speedtest xenstored_test $(TESTDIR)
+       $(TESTENV) time ./speedtest 100
 
 xs_test.o xs_stress.o xenstored_core_test.o xenstored_watch_test.o 
xenstored_transaction_test.o xenstored_domain_test.o xs_random.o xs_test_lib.o 
talloc_test.o fake_libxc.o xs_crashme.o: CFLAGS=$(BASECFLAGS) $(TESTFLAGS)
 
@@ -98,7 +106,7 @@
 randomcheck: xs_random xenstored_test $(TESTDIR)
        $(TESTENV) ./xs_random --simple --fast /tmp/xs_random 200000 
$(RANDSEED) && echo
        $(TESTENV) ./xs_random --fast /tmp/xs_random 100000 $(RANDSEED) && echo
-       $(TESTENV) ./xs_random --fail /tmp/xs_random 10000 $(RANDSEED)
+#      $(TESTENV) ./xs_random --fail /tmp/xs_random 10000 $(RANDSEED)
 
 crashme:  xs_crashme xenstored_test $(TESTDIR)
        rm -rf $(TESTDIR)/store $(TESTDIR)/transactions /tmp/xs_crashme.vglog* 
/tmp/trace
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/testsuite/04rm.test
--- a/tools/xenstore/testsuite/04rm.test        Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/04rm.test        Mon Sep 26 17:07:49 2005
@@ -6,6 +6,8 @@
 # Create file and remove it
 write /test contents
 rm /test
+expect tool
+dir /
 
 # Create directory and remove it.
 mkdir /dir
@@ -15,3 +17,4 @@
 mkdir /dir
 write /dir/test contents
 rm /dir
+
diff -r eaedc6b4ec0f -r ef9591d03fdd 
tools/xenstore/testsuite/08transaction.slowtest
--- a/tools/xenstore/testsuite/08transaction.slowtest   Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/08transaction.slowtest   Mon Sep 26 17:07:49 2005
@@ -1,21 +1,43 @@
-# Test transaction timeouts.  Take a second each.
+# Test transaction clashes.
 
 mkdir /test
 write /test/entry1 contents
 
-# Transactions can take as long as the want...
-start /test
-sleep 1100
-rm /test/entry1
+# Start transaction, do read-only op, transaction succeeds
+1 start
+1 write /test/entry1 contents2
+expect contents
+read /test/entry1
+1 commit
+expect contents2
+read /test/entry1
+
+# Start transaction, abort other transaction, transaction succeeds.
+1 start
+1 write /test/entry1 contents3
+start
+write /test/entry1 contents
+abort
+1 commit
+expect contents3
+read /test/entry1
+
+# Start transaction, do write op, transaction fails
+1 start
+1 write /test/entry1 contents4
+write /test/entry1 contents
+expect 1: commit failed: Resource temporarily unavailable
+1 commit
+expect contents
+read /test/entry1
+
+# Start transaction, do other transaction, transaction fails
+1 start
+1 write /test/entry1 contents4
+start
+write /test/entry1 contents5
 commit
-dir /test
-
-# ... as long as noone is waiting.
-1 start /test
-notimeout
-2 mkdir /test/dir
-1 mkdir /test/dir
-expect 1:dir
-1 dir /test
-expect 1: commit failed: Connection timed out
+expect 1: commit failed: Resource temporarily unavailable
 1 commit
+expect contents5
+read /test/entry1
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/testsuite/08transaction.test
--- a/tools/xenstore/testsuite/08transaction.test       Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/08transaction.test       Mon Sep 26 17:07:49 2005
@@ -3,7 +3,7 @@
 mkdir /test
 
 # Simple transaction: create a file inside transaction.
-1 start /test
+1 start
 1 write /test/entry1 contents
 2 dir /test
 expect 1:entry1
@@ -15,7 +15,7 @@
 rm /test/entry1
 
 # Create a file and abort transaction.
-1 start /test
+1 start
 1 write /test/entry1 contents
 2 dir /test
 expect 1:entry1
@@ -25,7 +25,7 @@
 
 write /test/entry1 contents
 # Delete in transaction, commit
-1 start /test
+1 start
 1 rm /test/entry1
 expect 2:entry1
 2 dir /test
@@ -35,7 +35,7 @@
 
 # Delete in transaction, abort.
 write /test/entry1 contents
-1 start /test
+1 start
 1 rm /test/entry1
 expect 2:entry1
 2 dir /test
@@ -47,7 +47,7 @@
 # Events inside transactions don't trigger watches until (successful) commit.
 mkdir /test/dir
 1 watch /test token
-2 start /test
+2 start
 2 mkdir /test/dir/sub
 expect 1: waitwatch failed: Connection timed out
 1 waitwatch
@@ -55,7 +55,7 @@
 1 close
 
 1 watch /test token
-2 start /test
+2 start
 2 mkdir /test/dir/sub
 2 abort
 expect 1: waitwatch failed: Connection timed out
@@ -63,7 +63,7 @@
 1 close
 
 1 watch /test token
-2 start /test
+2 start
 2 mkdir /test/dir/sub
 2 commit
 expect 1:/test/dir/sub:token
@@ -73,7 +73,7 @@
 
 # Rm inside transaction works like rm outside: children get notified.
 1 watch /test/dir/sub token
-2 start /test
+2 start
 2 rm /test/dir
 2 commit
 expect 1:/test/dir/sub:token
@@ -83,7 +83,7 @@
 
 # Multiple events from single transaction don't trigger assert
 1 watch /test token
-2 start /test
+2 start
 2 write /test/1 contents
 2 write /test/2 contents
 2 commit
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/testsuite/12readonly.test
--- a/tools/xenstore/testsuite/12readonly.test  Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/12readonly.test  Mon Sep 26 17:07:49 2005
@@ -13,23 +13,23 @@
 getperm /test
 watch /test token
 unwatch /test token 
-start /
+start
 commit
-start /
+start
 abort
 
 # These don't work
-expect write failed: Read-only file system
+expect write failed: Permission denied
 write /test2 contents
-expect write failed: Read-only file system
+expect write failed: Permission denied
 write /test contents
-expect setperm failed: Read-only file system
+expect setperm failed: Permission denied
 setperm /test 100 NONE
-expect setperm failed: Read-only file system
+expect setperm failed: Permission denied
 setperm /test 100 NONE
-expect shutdown failed: Read-only file system
+expect shutdown failed: Permission denied
 shutdown
-expect introduce failed: Read-only file system
+expect introduce failed: Permission denied
 introduce 1 100 7 /home
 
 # Check that watches work like normal.
diff -r eaedc6b4ec0f -r ef9591d03fdd 
tools/xenstore/testsuite/14complexperms.test
--- a/tools/xenstore/testsuite/14complexperms.test      Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/14complexperms.test      Mon Sep 26 17:07:49 2005
@@ -33,14 +33,6 @@
 expect *No such file or directory
 unwatch /dir/file token 
 expect *Permission denied
-start /dir/file
-expect *No such file or directory
-abort
-expect *Permission denied
-start /dir/file
-expect *No such file or directory
-commit
-expect *Permission denied
 introduce 2 100 7 /dir/file
 
 # Now it exists
@@ -73,12 +65,4 @@
 expect *No such file or directory
 unwatch /dir/file token 
 expect *Permission denied
-start /dir/file
-expect *No such file or directory
-abort
-expect *Permission denied
-start /dir/file
-expect *No such file or directory
-commit
-expect *Permission denied
 introduce 2 100 7 /dir/file
diff -r eaedc6b4ec0f -r ef9591d03fdd 
tools/xenstore/testsuite/16block-watch-crash.test
--- a/tools/xenstore/testsuite/16block-watch-crash.test Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/16block-watch-crash.test Mon Sep 26 17:07:49 2005
@@ -1,13 +1,14 @@
 # Test case where blocked connection gets sent watch.
 
-mkdir /test
-watch /test token
-1 start /test
-# This will block on above
-noackwrite /test/entry contents
-1 write /test/entry2 contents
-1 commit
-readack
-expect /test/entry2:token
-waitwatch
-ackwatch token
+# FIXME: We no longer block connections 
+# mkdir /test
+# watch /test token
+# 1 start
+# # This will block on above
+# noackwrite /test/entry contents
+# 1 write /test/entry2 contents
+# 1 commit
+# readack
+# expect /test/entry2:token
+# waitwatch
+# ackwatch token
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/xenstore_client.c
--- a/tools/xenstore/xenstore_client.c  Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/xenstore_client.c  Mon Sep 26 17:07:49 2005
@@ -14,6 +14,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <xs.h>
+#include <errno.h>
 
 static void
 usage(const char *progname)
@@ -82,8 +83,8 @@
     }
 #endif
 
-    /* XXX maybe find longest common prefix */
-    success = xs_transaction_start(xsh, "/");
+  again:
+    success = xs_transaction_start(xsh);
     if (!success)
        errx(1, "couldn't start transaction");
 
@@ -145,8 +146,10 @@
 
  out:
     success = xs_transaction_end(xsh, ret ? true : false);
-    if (!success)
+    if (!success) {
+       if (ret == 0 && errno == EAGAIN)
+           goto again;
        errx(1, "couldn't end transaction");
-
+    }
     return ret;
 }
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/xenstored.h
--- a/tools/xenstore/xenstored.h        Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/xenstored.h        Mon Sep 26 17:07:49 2005
@@ -75,7 +75,7 @@
        XSD_ERROR(ENOSYS),
        XSD_ERROR(EROFS),
        XSD_ERROR(EBUSY),
-       XSD_ERROR(ETIMEDOUT),
+       XSD_ERROR(EAGAIN),
        XSD_ERROR(EISCONN),
 };
 struct xsd_sockmsg
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/xenstored_core.c   Mon Sep 26 17:07:49 2005
@@ -50,10 +50,12 @@
 #include "xenstored_transaction.h"
 #include "xenstored_domain.h"
 #include "xenctrl.h"
+#include "tdb.h"
 
 static bool verbose;
 LIST_HEAD(connections);
 static int tracefd = -1;
+static TDB_CONTEXT *tdb_ctx;
 
 #ifdef TESTING
 static bool failtest = false;
@@ -124,6 +126,23 @@
               "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)
+{
+       /* conn = NULL used in manual_node at setup. */
+       if (!conn || !conn->transaction)
+               return tdb_ctx;
+       return tdb_transaction_context(conn->transaction);
+}
+
+bool replace_tdb(const char *newname, TDB_CONTEXT *newtdb)
+{
+       if (rename(newname, xs_daemon_tdb()) != 0)
+               return false;
+       tdb_close(tdb_ctx);
+       tdb_ctx = talloc_steal(talloc_autofree_context(), newtdb);
+       return true;
 }
 
 static char *sockmsg_string(enum xsd_sockmsg_type type)
@@ -202,37 +221,6 @@
        write(tracefd, string, strlen(string));
 }
 
-void trace_watch_timeout(const struct connection *conn, const char *node, 
const char *token)
-{
-       char string[64];
-       if (tracefd < 0)
-               return;
-       write(tracefd, "WATCH_TIMEOUT ", strlen("WATCH_TIMEOUT "));
-       sprintf(string, " %p ", conn);
-       write(tracefd, string, strlen(string));
-       write(tracefd, " (", 2);
-       write(tracefd, node, strlen(node));
-       write(tracefd, " ", 1);
-       write(tracefd, token, strlen(token));
-       write(tracefd, ")\n", 2);
-}
-
-static void trace_blocked(const struct connection *conn,
-                         const struct buffered_data *data)
-{
-       char string[64];
-
-       if (tracefd < 0)
-               return;
-
-       write(tracefd, "BLOCKED", strlen("BLOCKED"));
-       sprintf(string, " %p (", conn);
-       write(tracefd, string, strlen(string));
-       write(tracefd, sockmsg_string(data->hdr.msg.type),
-             strlen(sockmsg_string(data->hdr.msg.type)));
-       write(tracefd, ")\n", 2);
-}
-
 void trace(const char *fmt, ...)
 {
        va_list arglist;
@@ -253,7 +241,6 @@
        int ret;
        struct buffered_data *out = conn->out;
 
-       assert(conn->state != BLOCKED);
        if (out->inhdr) {
                if (verbose)
                        xprintf("Writing msg %s (%s) out to %p\n",
@@ -351,24 +338,6 @@
        return max;
 }
 
-/* Read everything from a talloc_open'ed fd. */
-void *read_all(int *fd, unsigned int *size)
-{
-       unsigned int max = 4;
-       int ret;
-       void *buffer = talloc_size(fd, max);
-
-       *size = 0;
-       while ((ret = read(*fd, buffer + *size, max - *size)) > 0) {
-               *size += ret;
-               if (*size == max)
-                       buffer = talloc_realloc_size(fd, buffer, max *= 2);
-       }
-       if (ret < 0)
-               return NULL;
-       return buffer;
-}
-
 static int destroy_fd(void *_fd)
 {
        int *fd = _fd;
@@ -409,42 +378,167 @@
        return child[len] == '/' || child[len] == '\0';
 }
 
-/* Answer never ends in /. */
-char *node_dir_outside_transaction(const char *node)
-{
-       if (streq(node, "/"))
-               return talloc_strdup(node, xs_daemon_store());
-       return talloc_asprintf(node, "%s%s", xs_daemon_store(), node);
-}
-
-static char *node_dir(struct transaction *trans, const char *node)
-{
-       if (!trans || !within_transaction(trans, node))
-               return node_dir_outside_transaction(node);
-       return node_dir_inside_transaction(trans, node);
-}
-
-static char *datafile(const char *dir)
-{
-       return talloc_asprintf(dir, "%s/.data", dir);
-}
-
-static char *node_datafile(struct transaction *trans, const char *node)
-{
-       return datafile(node_dir(trans, node));
-}
-
-static char *permfile(const char *dir)
-{
-       return talloc_asprintf(dir, "%s/.perms", dir);
-}
-
-static char *node_permfile(struct transaction *trans, const char *node)
-{
-       return permfile(node_dir(trans, node));
-}
-
-struct buffered_data *new_buffer(void *ctx)
+/* If it fails, returns NULL and sets errno. */
+static struct node *read_node(struct connection *conn, const char *name)
+{
+       TDB_DATA key, data;
+       u32 *p;
+       struct node *node;
+
+       key.dptr = (void *)name;
+       key.dsize = strlen(name);
+       data = tdb_fetch(tdb_context(conn), key);
+
+       if (data.dptr == NULL) {
+               if (tdb_error(tdb_context(conn)) == TDB_ERR_NOEXIST)
+                       errno = ENOENT;
+               else
+                       errno = EIO;
+               return NULL;
+       }
+
+       node = talloc(name, struct node);
+       node->name = talloc_strdup(node, name);
+       node->parent = NULL;
+       node->tdb = tdb_context(conn);
+       talloc_steal(node, data.dptr);
+
+       /* Datalen, childlen, number of permissions */
+       p = (u32 *)data.dptr;
+       node->num_perms = p[0];
+       node->datalen = p[1];
+       node->childlen = p[2];
+
+       /* Permissions are struct xs_permissions. */
+       node->perms = (void *)&p[3];
+       /* Data is binary blob (usually ascii, no nul). */
+       node->data = node->perms + node->num_perms;
+       /* Children is strings, nul separated. */
+       node->children = node->data + node->datalen;
+
+       return node;
+}
+
+static bool write_node(struct connection *conn, const struct node *node)
+{
+       TDB_DATA key, data;
+       void *p;
+