WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] [xen-3.0.5-testing] Merge with xen-unstable for 3.0.5-rc

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-3.0.5-testing] Merge with xen-unstable for 3.0.5-rc4.
From: "Xen patchbot-3.0.5-testing" <patchbot-3.0.5-testing@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 28 Apr 2007 10:51:01 -0700
Delivery-date: Sat, 28 Apr 2007 11:50:51 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1177752539 -3600
# Node ID 1668299c0ea4bbd530cdf67e71c64ff8baa10efb
# Parent  ee16cdeddade3ba0e826c85e84d10431edccdb15
# Parent  0f9b97523450aae06d42852bdac9bbca3d6033d1
Merge with xen-unstable for 3.0.5-rc4.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/firmware/hvmloader/smbios.h                                           |  
 38 -
 tools/xm-test/tests/network-attach/network_utils.py                         |  
 56 -
 xen/common/compat/acm_ops.c                                                 |  
 47 -
 docs/man/xm.pod.1                                                           |  
 18 
 docs/xen-api/xenapi-coversheet.tex                                          |  
  6 
 linux-2.6-xen-sparse/drivers/xen/blkback/interface.c                        |  
  1 
 linux-2.6-xen-sparse/drivers/xen/blktap/interface.c                         |  
  1 
 tools/blktap/drivers/block-qcow.c                                           |  
 67 +
 tools/examples/init.d/xend                                                  |  
 12 
 tools/firmware/hvmloader/acpi/acpi2_0.h                                     |  
  2 
 tools/firmware/hvmloader/config.h                                           |  
  9 
 tools/firmware/hvmloader/hvmloader.c                                        |  
 58 +
 tools/firmware/hvmloader/hypercall.h                                        |  
 11 
 tools/firmware/hvmloader/smbios.c                                           |  
 14 
 tools/firmware/hvmloader/util.c                                             |  
  1 
 tools/firmware/hvmloader/util.h                                             |  
  1 
 tools/firmware/rombios/rombios.c                                            |  
 12 
 tools/ioemu/hw/pc.c                                                         |  
 11 
 tools/libxc/xc_core_x86.c                                                   |  
  8 
 tools/libxc/xc_dom_core.c                                                   |  
  4 
 tools/libxc/xc_domain_save.c                                                |  
  2 
 tools/libxc/xc_hvm_build.c                                                  |  
 15 
 tools/libxen/Makefile                                                       |  
  4 
 tools/libxen/Makefile.dist                                                  |  
  4 
 tools/python/xen/xend/XendAPI.py                                            |  
347 ++-------
 tools/python/xen/xend/XendAPIStore.py                                       |  
 59 +
 tools/python/xen/xend/XendAPIVersion.py                                     |  
  4 
 tools/python/xen/xend/XendBase.py                                           |  
126 +++
 tools/python/xen/xend/XendConfig.py                                         |  
 10 
 tools/python/xen/xend/XendDomain.py                                         |  
  6 
 tools/python/xen/xend/XendDomainInfo.py                                     |  
 41 -
 tools/python/xen/xend/XendError.py                                          |  
120 +++
 tools/python/xen/xend/XendNetwork.py                                        |  
175 ++++
 tools/python/xen/xend/XendNode.py                                           |  
269 +++----
 tools/python/xen/xend/XendPBD.py                                            |  
108 +-
 tools/python/xen/xend/XendPIF.py                                            |  
372 +++++++---
 tools/python/xen/xend/XendPIFMetrics.py                                     |  
 40 -
 tools/python/xen/xend/XendQCoWStorageRepo.py                                |  
  2 
 tools/python/xen/xend/XendStateStore.py                                     |  
 65 -
 tools/python/xen/xend/XendStorageRepository.py                              |  
  2 
 tools/python/xen/xend/XendVMMetrics.py                                      |  
 55 -
 tools/python/xen/xend/server/SrvServer.py                                   |  
  2 
 tools/python/xen/xm/create.dtd                                              |  
  9 
 tools/python/xen/xm/create.py                                               |  
  7 
 tools/python/xen/xm/main.py                                                 |  
130 +++
 tools/python/xen/xm/messages/en/xen-xm.po                                   |  
 24 
 tools/python/xen/xm/xenapi_create.py                                        |  
 69 +
 tools/vnet/vnet-module/00README                                             |  
  4 
 tools/vnet/vnet-module/Makefile.ver                                         |  
 14 
 tools/vnet/vnet-module/varp.c                                               |  
  5 
 tools/vnet/vnet-module/vnet.c                                               |  
  9 
 tools/vnet/vnetd/Makefile                                                   |  
  4 
 tools/vnet/vnetd/sys_kernel.h                                               |  
  1 
 tools/xenstore/xenstored_core.c                                             |  
  2 
 tools/xm-test/lib/XmTestLib/network_utils.py                                |  
 60 +
 tools/xm-test/tests/network-attach/01_network_attach_pos.py                 |  
  2 
 tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py          |  
  2 
 tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py |  
  2 
 tools/xm-test/tests/xapi/03_xapi-network_pos.py                             |  
 71 +
 tools/xm-test/tests/xapi/Makefile.am                                        |  
  3 
 xen/Makefile                                                                |  
  2 
 xen/acm/acm_policy.c                                                        |  
  8 
 xen/arch/x86/domain.c                                                       |  
 87 +-
 xen/arch/x86/domain_build.c                                                 |  
 53 -
 xen/arch/x86/domctl.c                                                       |  
  8 
 xen/arch/x86/hvm/hvm.c                                                      |  
  4 
 xen/arch/x86/hvm/save.c                                                     |  
  2 
 xen/arch/x86/hvm/vmx/intr.c                                                 |  
  3 
 xen/arch/x86/hvm/vmx/vmcs.c                                                 |  
 86 +-
 xen/arch/x86/machine_kexec.c                                                |  
  5 
 xen/arch/x86/mm.c                                                           |  
 67 -
 xen/arch/x86/mm/shadow/common.c                                             |  
 14 
 xen/arch/x86/mm/shadow/multi.c                                              |  
 35 
 xen/arch/x86/traps.c                                                        |  
 18 
 xen/arch/x86/x86_32/entry.S                                                 |  
 11 
 xen/arch/x86/x86_64/asm-offsets.c                                           |  
  2 
 xen/arch/x86/x86_64/compat/entry.S                                          |  
 26 
 xen/arch/x86/x86_64/entry.S                                                 |  
 30 
 xen/arch/x86/x86_64/mm.c                                                    |  
  6 
 xen/arch/x86/x86_64/traps.c                                                 |  
  7 
 xen/common/Makefile                                                         |  
  1 
 xen/common/acm_ops.c                                                        |  
 49 -
 xen/common/compat/grant_table.c                                             |  
  4 
 xen/common/sched_credit.c                                                   |  
  4 
 xen/include/Makefile                                                        |  
  2 
 xen/include/acm/acm_core.h                                                  |  
  8 
 xen/include/asm-x86/desc.h                                                  |  
  4 
 xen/include/asm-x86/domain.h                                                |  
 24 
 xen/include/asm-x86/hvm/vmx/vmcs.h                                          |  
  2 
 xen/include/asm-x86/ldt.h                                                   |  
  2 
 xen/include/asm-x86/shadow.h                                                |  
 10 
 xen/include/asm-x86/shared.h                                                |  
 94 +-
 xen/include/asm-x86/x86_64/page.h                                           |  
  4 
 xen/include/asm-x86/x86_64/regs.h                                           |  
 10 
 xen/include/public/domctl.h                                                 |  
  6 
 xen/include/public/hvm/save.h                                               |  
  7 
 xen/include/xen/sched.h                                                     |  
  8 
 xen/include/xen/shared.h                                                    |  
 20 
 xen/include/xlat.lst                                                        |  
  1 
 99 files changed, 2010 insertions(+), 1347 deletions(-)

diff -r ee16cdeddade -r 1668299c0ea4 docs/man/xm.pod.1
--- a/docs/man/xm.pod.1 Wed Apr 25 10:39:08 2007 +0100
+++ b/docs/man/xm.pod.1 Sat Apr 28 10:28:59 2007 +0100
@@ -555,29 +555,29 @@ I<normal EDF (20ms/5ms):>
 I<normal EDF (20ms/5ms):>
 
     xm sched-sedf <dom-id> 20000000 5000000 0 0 0
-  
+
 I<best-effort domains (i.e. non-realtime):>
 
     xm sched-sedf <dom-id> 20000000 0 0 1 0
- 
+
 I<normal EDF (20ms/5ms) + share of extra-time:>
-  
+
     xm sched-sedf <dom-id> 20000000 5000000 0 1 0
 
 I<4 domains with weights 2:3:4:2>
 
     xm sched-sedf <d1> 0 0 0 0 2
-    xm sched-sedf <d2> 0 0 0 0 3
-    xm sched-sedf <d3> 0 0 0 0 4
-    xm sched-sedf <d4> 0 0 0 0 2
+    xm sched-sedf <d2> 0 0 0 0 3
+    xm sched-sedf <d3> 0 0 0 0 4
+    xm sched-sedf <d4> 0 0 0 0 2
   
 I<1 fully-specified (10ms/3ms) domain, 3 other domains share available
 rest in 2:7:3 ratio:>
 
-    xm sched-sedf <d1> 10000000 3000000 0 0 0   
-    xm sched-sedf <d2> 0 0 0 0 2   
+    xm sched-sedf <d1> 10000000 3000000 0 0 0
+    xm sched-sedf <d2> 0 0 0 0 2
     xm sched-sedf <d3> 0 0 0 0 7
-    xm sched-sedf <d4> 0 0 0 0 3
+    xm sched-sedf <d4> 0 0 0 0 3
 
 =back
 
diff -r ee16cdeddade -r 1668299c0ea4 docs/xen-api/xenapi-coversheet.tex
--- a/docs/xen-api/xenapi-coversheet.tex        Wed Apr 25 10:39:08 2007 +0100
+++ b/docs/xen-api/xenapi-coversheet.tex        Sat Apr 28 10:28:59 2007 +0100
@@ -17,12 +17,12 @@
 \newcommand{\coversheetlogo}{xen.eps}
 
 %% Document date
-\newcommand{\datestring}{21st April 2007}
+\newcommand{\datestring}{27th April 2007}
 
-\newcommand{\releasestatement}{Candidate for Release\\Comments are welcome!}
+\newcommand{\releasestatement}{Stable Release}
 
 %% Document revision
-\newcommand{\revstring}{API Revision 0.9.1}
+\newcommand{\revstring}{API Revision 1.0.0}
 
 %% Document authors
 \newcommand{\docauthors}{
diff -r ee16cdeddade -r 1668299c0ea4 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Wed Apr 25 
10:39:08 2007 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Sat Apr 28 
10:28:59 2007 +0100
@@ -136,6 +136,7 @@ int blkif_map(blkif_t *blkif, unsigned l
        {
                unmap_frontend_page(blkif);
                free_vm_area(blkif->blk_ring_area);
+               blkif->blk_rings.common.sring = NULL;
                return err;
        }
        blkif->irq = err;
diff -r ee16cdeddade -r 1668299c0ea4 
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Wed Apr 25 
10:39:08 2007 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Sat Apr 28 
10:28:59 2007 +0100
@@ -137,6 +137,7 @@ int tap_blkif_map(blkif_t *blkif, unsign
        if (err < 0) {
                unmap_frontend_page(blkif);
                free_vm_area(blkif->blk_ring_area);
+               blkif->blk_rings.common.sring = NULL;
                return err;
        }
        blkif->irq = err;
diff -r ee16cdeddade -r 1668299c0ea4 tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/blktap/drivers/block-qcow.c Sat Apr 28 10:28:59 2007 +0100
@@ -55,7 +55,6 @@
 
 /******AIO DEFINES******/
 #define REQUEST_ASYNC_FD 1
-#define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ)
 
 struct pending_aio {
         td_callback_t cb;
@@ -146,18 +145,37 @@ struct tdqcow_state {
        AES_KEY aes_encrypt_key;       /*AES key*/
        AES_KEY aes_decrypt_key;       /*AES key*/
         /* libaio state */
-        io_context_t       aio_ctx;
-        struct iocb        iocb_list  [MAX_AIO_REQS];
-        struct iocb       *iocb_free  [MAX_AIO_REQS];
-        struct pending_aio pending_aio[MAX_AIO_REQS];
-        int                iocb_free_count;
-        struct iocb       *iocb_queue[MAX_AIO_REQS];
-        int                iocb_queued;
-        int                poll_fd;      /* NB: we require aio_poll support */
-        struct io_event    aio_events[MAX_AIO_REQS];
+        io_context_t        aio_ctx;
+        int                 max_aio_reqs;
+        struct iocb        *iocb_list;
+        struct iocb       **iocb_free;
+        struct pending_aio *pending_aio;
+        int                 iocb_free_count;
+        struct iocb       **iocb_queue;
+        int                 iocb_queued;
+        int                 poll_fd;      /* NB: we require aio_poll support */
+        struct io_event    *aio_events;
 };
 
 static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset);
+
+static void free_aio_state(struct disk_driver *dd)
+{
+        struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
+
+        if (s->sector_lock)
+                free(s->sector_lock);
+        if (s->iocb_list)
+                free(s->iocb_list);
+        if (s->pending_aio)
+                free(s->pending_aio);
+        if (s->aio_events)
+                free(s->aio_events);
+        if (s->iocb_free)
+                free(s->iocb_free);
+        if (s->iocb_queue)
+                free(s->iocb_queue);
+}
 
 static int init_aio_state(struct disk_driver *dd)
 {
@@ -166,6 +184,12 @@ static int init_aio_state(struct disk_dr
        struct tdqcow_state  *s = (struct tdqcow_state *)dd->private;
         long     ioidx;
 
+        s->iocb_list = NULL;
+        s->pending_aio = NULL;
+        s->aio_events = NULL;
+        s->iocb_free = NULL;
+        s->iocb_queue = NULL;
+
         /*Initialize Locking bitmap*/
        s->sector_lock = calloc(1, bs->size);
        
@@ -174,13 +198,26 @@ static int init_aio_state(struct disk_dr
                goto fail;
        }
 
+        /* A segment (i.e. a page) can span multiple clusters */
+        s->max_aio_reqs = (getpagesize() / s->cluster_size) + 1;
+
         /* Initialize AIO */
-        s->iocb_free_count = MAX_AIO_REQS;
+        s->iocb_free_count = s->max_aio_reqs;
         s->iocb_queued     = 0;
+
+        if (!(s->iocb_list = malloc(sizeof(struct iocb) * s->max_aio_reqs)) ||
+            !(s->pending_aio = malloc(sizeof(struct pending_aio) * 
s->max_aio_reqs)) ||
+            !(s->aio_events = malloc(sizeof(struct io_event) * 
s->max_aio_reqs)) ||
+            !(s->iocb_free = malloc(sizeof(struct iocb *) * s->max_aio_reqs)) 
||
+            !(s->iocb_queue = malloc(sizeof(struct iocb *) * 
s->max_aio_reqs))) {
+                DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n",
+                        s->max_aio_reqs);
+                goto fail;
+        }
 
         /*Signal kernel to create Poll FD for Asyc completion events*/
         s->aio_ctx = (io_context_t) REQUEST_ASYNC_FD;   
-        s->poll_fd = io_setup(MAX_AIO_REQS, &s->aio_ctx);
+        s->poll_fd = io_setup(s->max_aio_reqs, &s->aio_ctx);
 
        if (s->poll_fd < 0) {
                 if (s->poll_fd == -EAGAIN) {
@@ -198,7 +235,7 @@ static int init_aio_state(struct disk_dr
                goto fail;
        }
 
-        for (i=0;i<MAX_AIO_REQS;i++)
+        for (i=0;i<s->max_aio_reqs;i++)
                 s->iocb_free[i] = &s->iocb_list[i];
 
         DPRINTF("AIO state initialised\n");
@@ -946,6 +983,7 @@ int tdqcow_open (struct disk_driver *dd,
  end_xenhdr:
        if (init_aio_state(dd)!=0) {
                DPRINTF("Unable to initialise AIO state\n");
+                free_aio_state(dd);
                goto fail;
        }
        init_fds(dd);
@@ -962,6 +1000,7 @@ int tdqcow_open (struct disk_driver *dd,
        
 fail:
        DPRINTF("QCOW Open failed\n");
+       free_aio_state(dd);
        free(s->l1_table);
        free(s->l2_cache);
        free(s->cluster_cache);
@@ -1145,7 +1184,7 @@ int tdqcow_do_callbacks(struct disk_driv
         if (sid > MAX_IOFD) return 1;
        
        /* Non-blocking test for completed io. */
-        ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events,
+        ret = io_getevents(prv->aio_ctx, 0, prv->max_aio_reqs, prv->aio_events,
                            NULL);
 
         for (ep = prv->aio_events, i = ret; i-- > 0; ep++) {
diff -r ee16cdeddade -r 1668299c0ea4 tools/examples/init.d/xend
--- a/tools/examples/init.d/xend        Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/examples/init.d/xend        Sat Apr 28 10:28:59 2007 +0100
@@ -6,6 +6,18 @@
 #
 # chkconfig: 2345 98 01
 # description: Starts and stops the Xen control daemon.
+### BEGIN INIT INFO
+# Provides:          xend
+# Required-Start:    $syslog $remote_fs
+# Should-Start:
+# Required-Stop:     $syslog $remote_fs
+# Should-Stop:
+# Default-Start:     3 4 5
+# Default-Stop:      0 1 2 6
+# Default-Enabled:   yes
+# Short-Description: Start/stop xend
+# Description:       Starts and stops the Xen control daemon.
+### END INIT INFO
 
 if ! grep -q "control_d" /proc/xen/capabilities ; then
        exit 0
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/acpi/acpi2_0.h
--- a/tools/firmware/hvmloader/acpi/acpi2_0.h   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/acpi/acpi2_0.h   Sat Apr 28 10:28:59 2007 +0100
@@ -394,8 +394,6 @@ struct acpi_20_madt_intsrcovr {
 
 #pragma pack ()
 
-#define ACPI_PHYSICAL_ADDRESS 0xEA000
-
 int acpi_build_tables(uint8_t *);
 
 #endif /* _ACPI_2_0_H_ */
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/config.h Sat Apr 28 10:28:59 2007 +0100
@@ -17,5 +17,14 @@
 #define ROMBIOS_MAXOFFSET      0x0000FFFF
 #define ROMBIOS_END            (ROMBIOS_BEGIN + ROMBIOS_SIZE)
 
+/* Memory map. */
+#define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
+#define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
+#define ETHERBOOT_PHYSICAL_ADDRESS    0x000C8000
+#define VMXASSIST_PHYSICAL_ADDRESS    0x000D0000
+#define SMBIOS_PHYSICAL_ADDRESS       0x000E9000
+#define SMBIOS_MAXIMUM_SIZE           0x00001000
+#define ACPI_PHYSICAL_ADDRESS         0x000EA000
+#define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
 
 #endif /* __HVMLOADER_CONFIG_H__ */
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c      Sat Apr 28 10:28:59 2007 +0100
@@ -19,23 +19,16 @@
  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  */
+
 #include "roms.h"
-#include "acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
+#include "acpi/acpi2_0.h"
 #include "hypercall.h"
 #include "util.h"
-#include "smbios.h"
 #include "config.h"
 #include "apic_regs.h"
 #include "pci_regs.h"
 #include <xen/version.h>
 #include <xen/hvm/params.h>
-
-/* memory map */
-#define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
-#define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
-#define ETHERBOOT_PHYSICAL_ADDRESS    0x000C8000
-#define VMXASSIST_PHYSICAL_ADDRESS    0x000D0000
-#define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
 
 asm(
     "    .text                       \n"
@@ -103,7 +96,8 @@ asm(
     "stack_top:                      \n"
     );
 
-extern void create_mp_tables(void);
+void create_mp_tables(void);
+int hvm_write_smbios_tables(void);
 
 static int
 cirrus_check(void)
@@ -351,17 +345,20 @@ static void cmos_write_memory_size(void)
 
 int main(void)
 {
-    int acpi_sz;
+    int acpi_sz = 0, vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz;
 
     printf("HVM Loader\n");
 
     init_hypercalls();
 
     printf("Writing SMBIOS tables ...\n");
-    hvm_write_smbios_tables();
+    smbios_sz = hvm_write_smbios_tables();
 
     printf("Loading ROMBIOS ...\n");
-    memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
+    rombios_sz = sizeof(rombios);
+    if ( rombios_sz > 0x10000 )
+        rombios_sz = 0x10000;
+    memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, rombios_sz);
     highbios_setup();
 
     apic_setup();
@@ -375,12 +372,14 @@ int main(void)
         printf("Loading Cirrus VGABIOS ...\n");
         memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
                vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
+        vgabios_sz = sizeof(vgabios_cirrusvga);
     }
     else
     {
         printf("Loading Standard VGABIOS ...\n");
         memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
                vgabios_stdvga, sizeof(vgabios_stdvga));
+        vgabios_sz = sizeof(vgabios_stdvga);
     }
 
     if ( must_load_nic() )
@@ -388,9 +387,10 @@ int main(void)
         printf("Loading ETHERBOOT ...\n");
         memcpy((void *)ETHERBOOT_PHYSICAL_ADDRESS,
                etherboot, sizeof(etherboot));
-    }
-
-    if ( get_acpi_enabled() != 0 )
+        etherboot_sz = sizeof(etherboot);
+    }
+
+    if ( get_acpi_enabled() )
     {
         printf("Loading ACPI ...\n");
         acpi_sz = acpi_build_tables((uint8_t *)ACPI_PHYSICAL_ADDRESS);
@@ -398,6 +398,32 @@ int main(void)
     }
 
     cmos_write_memory_size();
+
+    printf("BIOS map:\n");
+    if ( vgabios_sz )
+        printf(" %05x-%05x: VGA BIOS\n",
+               VGABIOS_PHYSICAL_ADDRESS,
+               VGABIOS_PHYSICAL_ADDRESS + vgabios_sz - 1);
+    if ( etherboot_sz )
+        printf(" %05x-%05x: Etherboot ROM\n",
+               ETHERBOOT_PHYSICAL_ADDRESS,
+               ETHERBOOT_PHYSICAL_ADDRESS + etherboot_sz - 1);
+    if ( !check_amd() )
+        printf(" %05x-%05x: VMXAssist\n",
+               VMXASSIST_PHYSICAL_ADDRESS,
+               VMXASSIST_PHYSICAL_ADDRESS + sizeof(vmxassist) - 1);
+    if ( smbios_sz )
+        printf(" %05x-%05x: SMBIOS tables\n",
+               SMBIOS_PHYSICAL_ADDRESS,
+               SMBIOS_PHYSICAL_ADDRESS + smbios_sz - 1);
+    if ( acpi_sz )
+        printf(" %05x-%05x: ACPI tables\n",
+               ACPI_PHYSICAL_ADDRESS,
+               ACPI_PHYSICAL_ADDRESS + acpi_sz - 1);
+    if ( rombios_sz )
+        printf(" %05x-%05x: Main BIOS\n",
+               ROMBIOS_PHYSICAL_ADDRESS,
+               ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1);
 
     if ( !check_amd() )
     {
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/hypercall.h
--- a/tools/firmware/hvmloader/hypercall.h      Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/hypercall.h      Sat Apr 28 10:28:59 2007 +0100
@@ -31,17 +31,18 @@
 #ifndef __HVMLOADER_HYPERCALL_H__
 #define __HVMLOADER_HYPERCALL_H__
 
+#include <stdint.h>
 #include <xen/xen.h>
+#include "config.h"
+
+#define __STR(...) #__VA_ARGS__
+#define STR(...) __STR(__VA_ARGS__)
 
 /*
  * NB. Hypercall address needs to be relative to a linkage symbol for
  * some version of ld to relocate the relative calls properly.
- * Keep this in sync with HYPERCALL_PHYSICAL_ADDRESS in hvmloader.c!
  */
-#define hypercall_pa "_start - 0x80000"
-
-#define __STR(x) #x
-#define STR(x) __STR(x)
+#define hypercall_pa "_start - " STR(HYPERCALL_PHYSICAL_ADDRESS)
 
 #define _hypercall0(type, name)                                                
\
 ({                                                                     \
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/smbios.c Sat Apr 28 10:28:59 2007 +0100
@@ -22,12 +22,11 @@
 
 #include <stdint.h>
 #include <xen/version.h>
-#include "smbios.h"
 #include "smbios_types.h"
 #include "util.h"
 #include "hypercall.h"
 
-static size_t
+static int
 write_smbios_tables(void *start,
                     uint32_t vcpus, uint64_t memsize,
                     uint8_t uuid[16], char *xen_version,
@@ -82,7 +81,7 @@ get_cpu_manufacturer(char *buf, int len)
         strncpy(buf, "unknown", len);
 }
 
-static size_t
+static int
 write_smbios_tables(void *start,
                     uint32_t vcpus, uint64_t memsize,
                     uint8_t uuid[16], char *xen_version,
@@ -125,7 +124,7 @@ write_smbios_tables(void *start,
         SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point),
         nr_structs);
 
-    return (size_t)((char *)p - (char *)start);
+    return ((char *)p - (char *)start);
 }
 
 /* Calculate how much pseudo-physical memory (in MB) is allocated to us. */
@@ -156,7 +155,7 @@ get_memsize(void)
     return (memsize + (1 << 20) - 1) >> 20;
 }
 
-void
+int
 hvm_write_smbios_tables(void)
 {
     uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is
@@ -221,16 +220,17 @@ hvm_write_smbios_tables(void)
                               get_vcpu_nr(), get_memsize(),
                               uuid, xen_version_str,
                               xen_major_version, xen_minor_version);
-    if ( len > SMBIOS_SIZE_LIMIT )
+    if ( len > SMBIOS_MAXIMUM_SIZE )
         goto error_out;
     /* Okay, not too large: copy out of scratch to final location. */
     memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len);
 
-    return;
+    return len;
 
  error_out:
     printf("Could not write SMBIOS tables, error in hvmloader.c:"
            "hvm_write_smbios_tables()\n");
+    return 0;
 }
 
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/smbios.h
--- a/tools/firmware/hvmloader/smbios.h Wed Apr 25 10:39:08 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * smbios.h - interface for Xen HVM SMBIOS generation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2006
- *
- * Authors: Andrew D. Ball <aball@xxxxxxxxxx>
- */
-
-#ifndef SMBIOS_H
-#define SMBIOS_H
-
-#include <stdint.h>
-#include <stdlib.h>
-
-/* These constants must agree with the ACPI e820 memory map as defined
-   in tools/libxc/xc_hvm_build.c and the address the ROMBIOS pulls the
-   SMBIOS entry point from in the smbios_init subroutine.
- */
-#define SMBIOS_PHYSICAL_ADDRESS 0x9f000
-#define SMBIOS_SIZE_LIMIT 0x800
-
-void hvm_write_smbios_tables(void);
-
-#endif /* SMBIOS_H */
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/util.c   Sat Apr 28 10:28:59 2007 +0100
@@ -18,7 +18,6 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  */
 
-#include "acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
 #include "util.h"
 #include "config.h"
 #include <stdint.h>
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/util.h   Sat Apr 28 10:28:59 2007 +0100
@@ -2,6 +2,7 @@
 #define __HVMLOADER_UTIL_H__
 
 #include <stdarg.h>
+#include <stdint.h>
 
 #undef offsetof
 #define offsetof(t, m) ((unsigned long)&((t *)0)->m)
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/rombios/rombios.c  Sat Apr 28 10:28:59 2007 +0100
@@ -25,6 +25,8 @@
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
 // ROM BIOS for use with Bochs/Plex x86 emulation environment
+
+#include "../hvmloader/config.h"
 
 #define HVMASSIST
 #undef HVMTEST
@@ -9409,9 +9411,9 @@ rom_scan_increment:
 
 #ifdef HVMASSIST
 
-; Copy the SMBIOS entry point over from 0x9f000, where hvmloader left it.
+; Copy the SMBIOS entry point from where hvmloader left it.
 ; The entry point must be somewhere in 0xf0000-0xfffff on a 16-byte boundary,
-; but the tables themeselves can be elsewhere.
+; but the tables themselves can be elsewhere.
 smbios_init:
   push ax
   push cx
@@ -9424,9 +9426,9 @@ smbios_init:
   mov ax, #0xf000
   mov es, ax      ; destination segment is 0xf0000
   mov di, #smbios_entry_point ; destination offset
-  mov ax, #0x9f00
-  mov ds, ax      ; source segment is 0x9f000
-  mov si, #0x0000 ; source offset is 0
+  mov ax, #(SMBIOS_PHYSICAL_ADDRESS>>4)
+  mov ds, ax
+  mov si, #(SMBIOS_PHYSICAL_ADDRESS&15)
   cld
   rep
     movsb
diff -r ee16cdeddade -r 1668299c0ea4 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/ioemu/hw/pc.c       Sat Apr 28 10:28:59 2007 +0100
@@ -922,12 +922,13 @@ static void pc_init1(uint64_t ram_size, 
 #endif
 #else
     if (pci_enabled) {
-        void *scsi;
-
-        scsi = lsi_scsi_init(pci_bus, -1);
+        void *scsi = NULL;
         for (i = 0; i < MAX_SCSI_DISKS ; i++) {
-            if (bs_table[i + MAX_DISKS]) 
-                lsi_scsi_attach(scsi, bs_table[i + MAX_DISKS], -1);
+            if (!bs_table[i + MAX_DISKS])
+                continue;
+            if (!scsi)
+                scsi = lsi_scsi_init(pci_bus, -1);
+            lsi_scsi_attach(scsi, bs_table[i + MAX_DISKS], -1);
         }
     }
 #endif /* !CONFIG_DM */
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_core_x86.c
--- a/tools/libxc/xc_core_x86.c Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxc/xc_core_x86.c Sat Apr 28 10:28:59 2007 +0100
@@ -21,9 +21,9 @@
 #include "xg_private.h"
 #include "xc_core.h"
 
-static int max_gpfn(int xc_handle, domid_t domid)
+static int nr_gpfns(int xc_handle, domid_t domid)
 {
-    return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid);
+    return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid) + 1;
 }
 
 int
@@ -38,7 +38,7 @@ xc_core_arch_memory_map_get(int xc_handl
                             xc_core_memory_map_t **mapp,
                             unsigned int *nr_entries)
 {
-    unsigned long p2m_size = max_gpfn(xc_handle, info->domid);
+    unsigned long p2m_size = nr_gpfns(xc_handle, info->domid);
     xc_core_memory_map_t *map;
 
     map = malloc(sizeof(*map));
@@ -65,7 +65,7 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
     xen_pfn_t *live_p2m_frame_list_list = NULL;
     xen_pfn_t *live_p2m_frame_list = NULL;
     uint32_t dom = info->domid;
-    unsigned long p2m_size = max_gpfn(xc_handle, info->domid);
+    unsigned long p2m_size = nr_gpfns(xc_handle, info->domid);
     int ret = -1;
     int err;
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_dom_core.c
--- a/tools/libxc/xc_dom_core.c Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxc/xc_dom_core.c Sat Apr 28 10:28:59 2007 +0100
@@ -209,13 +209,13 @@ size_t xc_dom_check_gzip(void *blob, siz
     unsigned char *gzlen;
     size_t unziplen;
 
-    if (strncmp(blob, "\037\213", 2))
+    if ( strncmp(blob, "\037\213", 2) )
         /* not gzipped */
         return 0;
 
     gzlen = blob + ziplen - 4;
     unziplen = gzlen[3] << 24 | gzlen[2] << 16 | gzlen[1] << 8 | gzlen[0];
-    if ( (unziplen < ziplen) || (unziplen > (ziplen * 8)) )
+    if ( (unziplen < 0) || (unziplen > (1024*1024*1024)) ) /* 1GB limit */
     {
         xc_dom_printf
             ("%s: size (zip %zd, unzip %zd) looks insane, skip gunzip\n",
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxc/xc_domain_save.c      Sat Apr 28 10:28:59 2007 +0100
@@ -870,7 +870,7 @@ int xc_domain_save(int xc_handle, int io
     }
 
     /* Get the size of the P2M table */
-    p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom);
+    p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom) + 1;
 
     /* Domain is still running at this point */
     if ( live )
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxc/xc_hvm_build.c        Sat Apr 28 10:28:59 2007 +0100
@@ -47,20 +47,15 @@ static void build_e820map(void *e820_pag
         mem_size = HVM_BELOW_4G_RAM_END;
     }
 
-    /* 0x0-0x9F000: Ordinary RAM. */
+    /* 0x0-0x9FC00: Ordinary RAM. */
     e820entry[nr_map].addr = 0x0;
-    e820entry[nr_map].size = 0x9F000;
+    e820entry[nr_map].size = 0x9FC00;
     e820entry[nr_map].type = E820_RAM;
     nr_map++;
 
-    /*
-     * 0x9F000-0x9F800: SMBIOS tables.
-     * 0x9FC00-0xA0000: Extended BIOS Data Area (EBDA).
-     * TODO: SMBIOS tables should be moved higher (>=0xE0000).
-     *       They are unusually low in our memory map: could cause problems?
-     */
-    e820entry[nr_map].addr = 0x9F000;
-    e820entry[nr_map].size = 0x1000;
+    /* 0x9FC00-0xA0000: Extended BIOS Data Area (EBDA). */
+    e820entry[nr_map].addr = 0x9FC00;
+    e820entry[nr_map].size = 0x400;
     e820entry[nr_map].type = E820_RESERVED;
     nr_map++;
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxen/Makefile
--- a/tools/libxen/Makefile     Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxen/Makefile     Sat Apr 28 10:28:59 2007 +0100
@@ -18,8 +18,8 @@ XEN_ROOT=../..
 XEN_ROOT=../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-MAJOR = 0.9
-MINOR = 1
+MAJOR = 1.0
+MINOR = 0
 
 CFLAGS = -Iinclude                     \
          $(shell xml2-config --cflags) \
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxen/Makefile.dist
--- a/tools/libxen/Makefile.dist        Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxen/Makefile.dist        Sat Apr 28 10:28:59 2007 +0100
@@ -16,8 +16,8 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 #
 
-MAJOR = 0.9
-MINOR = 1
+MAJOR = 1.0
+MINOR = 0
 
 CFLAGS = -Iinclude                     \
          $(shell xml2-config --cflags) \
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendAPI.py  Sat Apr 28 10:28:59 2007 +0100
@@ -27,7 +27,7 @@ import xmlrpclib
 import xmlrpclib
 
 import XendDomain, XendDomainInfo, XendNode, XendDmesg
-import XendLogging, XendTaskManager
+import XendLogging, XendTaskManager, XendAPIStore
 
 from XendAPIVersion import *
 from XendAuthSessions import instance as auth_manager
@@ -38,8 +38,8 @@ from XendTask import XendTask
 from XendTask import XendTask
 from XendPIFMetrics import XendPIFMetrics
 from XendVMMetrics import XendVMMetrics
-
-import XendPBD
+from XendPIF import XendPIF
+from XendPBD import XendPBD
 
 from XendAPIConstants import *
 from xen.util.xmlrpclib2 import stringify
@@ -237,6 +237,8 @@ def catch_typeerror(func):
                     finally:
                         del tb
             raise
+        except XendAPIError, exn:
+            return xen_api_error(exn.get_api_error())
 
     return f
 
@@ -307,26 +309,6 @@ def valid_vm(func):
            _check_ref(XendDomain.instance().is_valid_vm,
                       'VM', func, *args, **kwargs)
 
-def valid_vm_metrics(func):
-    """Decorator to verify if vm_metrics_ref is valid before calling method.
-
-    @param func: function with params: (self, session, vm_metrics_ref, ...)
-    @rtype: callable object
-    """    
-    return lambda *args, **kwargs: \
-           _check_ref(XendVMMetrics.is_valid_vm_metrics,
-                      'VM_metrics', func, *args, **kwargs)
-
-def valid_network(func):
-    """Decorator to verify if network_ref is valid before calling method.
-
-    @param func: function with params: (self, session, network_ref, ...)
-    @rtype: callable object
-    """    
-    return lambda *args, **kwargs: \
-           _check_ref(XendNode.instance().is_valid_network,
-                      'network', func, *args, **kwargs)
-
 def valid_vbd(func):
     """Decorator to verify if vbd_ref is valid before calling method.
 
@@ -409,39 +391,6 @@ def valid_sr(func):
            _check_ref(lambda r: XendNode.instance().is_valid_sr,
                       'SR', func, *args, **kwargs)
 
-def valid_pbd(func):
-    """Decorator to verify if pbd_ref is valid before calling
-    method.
-
-    @param func: function with params: (self, session, pbd_ref)
-    @rtype: callable object
-    """
-    return lambda *args, **kwargs: \
-           _check_ref(lambda r: r in XendPBD.get_all_refs(),
-                      'PBD', func, *args, **kwargs)
-
-def valid_pif(func):
-    """Decorator to verify if pif_ref is valid before calling
-    method.
-
-    @param func: function with params: (self, session, pif_ref)
-    @rtype: callable object
-    """
-    return lambda *args, **kwargs: \
-           _check_ref(lambda r: r in XendNode.instance().pifs,
-                      'PIF', func, *args, **kwargs)
-
-def valid_pif_metrics(func):
-    """Decorator to verify if pif_metrics_ref is valid before calling
-    method.
-
-    @param func: function with params: (self, session, pif_metrics_ref)
-    @rtype: callable object
-    """
-    return lambda *args, **kwargs: \
-           _check_ref(lambda r: r in XendNode.instance().pif_metrics,
-                      'PIF_metrics', func, *args, **kwargs)
-
 def valid_task(func):
     """Decorator to verify if task_ref is valid before calling
     method.
@@ -463,6 +412,20 @@ def valid_debug(func):
     return lambda *args, **kwargs: \
            _check_ref(lambda r: r in XendAPI._debug,
                       'debug', func, *args, **kwargs)
+
+
+def valid_object(class_name):
+    """Decorator to verify if object is valid before calling
+    method.
+
+    @param func: function with params: (self, session, pif_ref)
+    @rtype: callable object
+    """
+    return lambda func: \
+           lambda *args, **kwargs: \
+           _check_ref(lambda r: \
+                          XendAPIStore.get(r, class_name) is not None,
+                      'PIF', func, *args, **kwargs)
 
 # -----------------------------
 # Bridge to Legacy XM API calls
@@ -494,9 +457,7 @@ classes = {
     'host'         : valid_host,
     'host_cpu'     : valid_host_cpu,
     'host_metrics' : valid_host_metrics,
-    'network'      : valid_network,
     'VM'           : valid_vm,
-    'VM_metrics'   : valid_vm_metrics,
     'VBD'          : valid_vbd,
     'VBD_metrics'  : valid_vbd_metrics,
     'VIF'          : valid_vif,
@@ -505,20 +466,22 @@ classes = {
     'VTPM'         : valid_vtpm,
     'console'      : valid_console,
     'SR'           : valid_sr,
-    'PBD'          : valid_pbd,
-    'PIF'          : valid_pif,
-    'PIF_metrics'  : valid_pif_metrics,
     'task'         : valid_task,
     'debug'        : valid_debug,
+    'network'      : valid_object("network"),
+    'PIF'          : valid_object("PIF"),
+    'VM_metrics'   : valid_object("VM_metrics"),
+    'PBD'          : valid_object("PBD"),
+    'PIF_metrics'  : valid_object("PIF_metrics")
 }
 
 autoplug_classes = {
     'network'     : XendNetwork,
+    'PIF'         : XendPIF,
     'VM_metrics'  : XendVMMetrics,
-    'PBD'         : XendPBD.XendPBD,
+    'PBD'         : XendPBD,
     'PIF_metrics' : XendPIFMetrics,
 }
-
 
 class XendAPI(object):
     """Implementation of the Xen-API in Xend. Expects to be
@@ -570,7 +533,9 @@ class XendAPI(object):
         #    all get_by_uuid() methods.
         
         for api_cls in classes.keys():
-            if api_cls == 'session':
+            # We'll let the autoplug classes implement these functions
+            # themselves - its much cleaner to do it in the base class
+            if api_cls == 'session' or api_cls in autoplug_classes.keys():
                 continue
             
             get_by_uuid = '%s_get_by_uuid' % api_cls
@@ -588,8 +553,8 @@ class XendAPI(object):
 
             def _get_all_records(_api_cls):
                 return lambda s, session: \
-                    xen_api_success([unpack(getattr(cls, '%s_get_record' % 
_api_cls)(s, session, ref))\
-                                     for ref in unpack(getattr(cls, 
'%s_get_all' % _api_cls)(s, session))])
+                    xen_api_success(dict([(ref, unpack(getattr(cls, 
'%s_get_record' % _api_cls)(s, session, ref)))\
+                                          for ref in unpack(getattr(cls, 
'%s_get_all' % _api_cls)(s, session))]))
 
             setattr(cls, get_by_uuid, _get_by_uuid)
             setattr(cls, get_uuid,    _get_uuid)
@@ -599,34 +564,48 @@ class XendAPI(object):
         # --------------------
         # These have all of their methods grabbed out from the implementation
         # class, and wrapped up to be compatible with the Xen-API.
+
+        def getter(ref, type):
+            return XendAPIStore.get(ref, type)
         
         for api_cls, impl_cls in autoplug_classes.items():
-            def doit(n):
-                getter = getattr(cls, '_%s_get' % api_cls)
+            def doit(n):           
                 dot_n = '%s.%s' % (api_cls, n)
                 full_n = '%s_%s' % (api_cls, n)
                 if not hasattr(cls, full_n):
                     f = getattr(impl_cls, n)
                     argcounts[dot_n] = f.func_code.co_argcount + 1
-                    setattr(cls, full_n,
+                    g = lambda api_cls: \
+                    setattr(cls, full_n, \
                             lambda s, session, ref, *args: \
                                xen_api_success( \
-                                   f(getter(s, session, ref), *args)))
-
-            ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
-            rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
-            methods  = getattr(cls, '%s_methods' % api_cls, [])
-            funcs    = getattr(cls, '%s_funcs'   % api_cls, [])
+                                   f(getter(ref, api_cls), *args)))
+                    g(api_cls) # Force api_cls to be captured
+                    
+            def doit_func(n):           
+                dot_n = '%s.%s' % (api_cls, n)
+                full_n = '%s_%s' % (api_cls, n)
+                if not hasattr(cls, full_n):
+                    f = getattr(impl_cls, n)
+                    argcounts[dot_n] = f.func_code.co_argcount
+                    setattr(cls, full_n, \
+                            lambda s, session, *args: \
+                               xen_api_success( \
+                                   f(*args)))
+
+            ro_attrs = impl_cls.getAttrRO()
+            rw_attrs = impl_cls.getAttrRW()
+            methods  = impl_cls.getMethods()
+            funcs    = impl_cls.getFuncs()
             
             for attr_name in ro_attrs + rw_attrs:
                 doit('get_%s' % attr_name)
-            for attr_name in rw_attrs + cls.Base_attr_rw:
+            for attr_name in rw_attrs:
                 doit('set_%s' % attr_name)
-            for method_name, return_type in methods + cls.Base_methods:
-                doit('%s' % method_name)
-            for func_name, return_type in funcs + cls.Base_funcs:
-                doit('%s' % func_name)
-
+            for method in methods:
+                doit('%s' % method)
+            for func in funcs:
+                doit_func('%s' % func)
 
         def wrap_method(name, new_f):
             try:
@@ -692,31 +671,42 @@ class XendAPI(object):
                 except AttributeError:
                     log.warn("API call: %s not found" % n)
 
-
-            ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
-            rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
-            methods  = getattr(cls, '%s_methods' % api_cls, [])
-            funcs    = getattr(cls, '%s_funcs'   % api_cls, [])
+            if api_cls in autoplug_classes.keys():
+                impl_cls = autoplug_classes[api_cls]
+                ro_attrs = impl_cls.getAttrRO()
+                rw_attrs = impl_cls.getAttrRW()
+                methods  = map(lambda x: (x, ""), impl_cls.getMethods())
+                funcs    = map(lambda x: (x, ""), impl_cls.getFuncs())
+            else:
+                ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, []) \
+                           + cls.Base_attr_ro
+                rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, []) \
+                           + cls.Base_attr_rw
+                methods  = getattr(cls, '%s_methods' % api_cls, []) \
+                           + cls.Base_methods
+                funcs    = getattr(cls, '%s_funcs'   % api_cls, []) \
+                           + cls.Base_funcs
 
             # wrap validators around readable class attributes
-            for attr_name in ro_attrs + rw_attrs + cls.Base_attr_ro:
+            for attr_name in ro_attrs + rw_attrs:
                 doit('%s.get_%s' % (api_cls, attr_name), True,
                      async_support = False)
 
             # wrap validators around writable class attrributes
-            for attr_name in rw_attrs + cls.Base_attr_rw:
+            for attr_name in rw_attrs:
                 doit('%s.set_%s' % (api_cls, attr_name), True,
                      async_support = False)
                 setter_event_wrapper(api_cls, attr_name)
 
             # wrap validators around methods
-            for method_name, return_type in methods + cls.Base_methods:
+            for method_name, return_type in methods:
                 doit('%s.%s' % (api_cls, method_name), True,
                      async_support = True)
 
             # wrap validators around class functions
-            for func_name, return_type in funcs + cls.Base_funcs:
-                doit('%s.%s' % (api_cls, func_name), False, async_support = 
True,
+            for func_name, return_type in funcs:
+                doit('%s.%s' % (api_cls, func_name), False,
+                     async_support = True,
                      return_type = return_type)
 
             ctor_event_wrapper(api_cls)
@@ -952,7 +942,7 @@ class XendAPI(object):
     def host_get_resident_VMs(self, session, host_ref):
         return xen_api_success(XendDomain.instance().get_domain_refs())
     def host_get_PBDs(self, _, ref):
-        return xen_api_success(XendPBD.get_all_refs())
+        return xen_api_success(XendPBD.get_all())
     def host_get_PIFs(self, session, ref):
         return xen_api_success(XendNode.instance().get_PIF_refs())
     def host_get_host_CPUs(self, session, host_ref):
@@ -1130,130 +1120,6 @@ class XendAPI(object):
     def _host_metrics_get_memory_free(self):
         node = XendNode.instance()
         return node.xc.physinfo()['free_memory'] * 1024
-
-
-    # Xen API: Class network
-    # ----------------------------------------------------------------
-
-    network_attr_ro = ['VIFs', 'PIFs']
-    network_attr_rw = ['name_label',
-                       'name_description',
-                       'other_config']
-    network_methods = [('add_to_other_config', None),
-                       ('remove_from_other_config', None),
-                       ('destroy', None)]
-    network_funcs = [('create', None)]
-    
-    def _network_get(self, _, ref):
-        return XendNode.instance().get_network(ref)
-
-    def network_get_all(self, _):
-        return xen_api_success(XendNode.instance().get_network_refs())
-
-    def network_create(self, _, record):
-        return xen_api_success(XendNode.instance().network_create(record))
-
-    def network_destroy(self, _, ref):
-        return xen_api_success(XendNode.instance().network_destroy(ref))
-
-
-    # Xen API: Class PIF
-    # ----------------------------------------------------------------
-
-    PIF_attr_ro = ['network',
-                   'host',
-                   'metrics']
-    PIF_attr_rw = ['device',
-                   'MAC',
-                   'MTU',
-                   'VLAN']
-
-    PIF_attr_inst = PIF_attr_rw
-
-    PIF_methods = [('create_VLAN', 'int'), ('destroy', None)]
-
-    def _get_PIF(self, ref):
-        return XendNode.instance().pifs[ref]
-
-    def PIF_destroy(self, _, ref):
-        try:
-            return xen_api_success(XendNode.instance().PIF_destroy(ref))
-        except PIFIsPhysical, exn:
-            return xen_api_error(['PIF_IS_PHYSICAL', ref])
-
-    # object methods
-    def PIF_get_record(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).get_record())
-
-    def PIF_get_all(self, _):
-        return xen_api_success(XendNode.instance().pifs.keys())
-
-    def PIF_get_metrics(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).metrics.uuid)
-
-    def PIF_get_device(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).device)
-
-    def PIF_get_network(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).network.uuid)
-
-    def PIF_get_host(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).host.uuid)
-
-    def PIF_get_MAC(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).mac)
-
-    def PIF_get_MTU(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).mtu)
-
-    def PIF_get_VLAN(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).vlan)
-
-    def PIF_set_device(self, _, ref, device):
-        return xen_api_success(self._get_PIF(ref).set_device(device))
-
-    def PIF_set_MAC(self, _, ref, mac):
-        return xen_api_success(self._get_PIF(ref).set_mac(mac))
-
-    def PIF_set_MTU(self, _, ref, mtu):
-        return xen_api_success(self._get_PIF(ref).set_mtu(mtu))
-
-    def PIF_create_VLAN(self, _, ref, network, vlan):
-        try:
-            vlan = int(vlan)
-        except:
-            return xen_api_error(['VLAN_TAG_INVALID', vlan])
-
-        try:
-            node = XendNode.instance()
-            
-            if _is_valid_ref(network, node.is_valid_network):
-                return xen_api_success(
-                    node.PIF_create_VLAN(ref, network, vlan))
-            else:
-                return xen_api_error(['HANDLE_INVALID', 'network', network])
-        except NetworkAlreadyConnected, exn:
-            return xen_api_error(['NETWORK_ALREADY_CONNECTED',
-                                  network, exn.pif_uuid])
-        except VLANTagInvalid:
-            return xen_api_error(['VLAN_TAG_INVALID', vlan])
-
-
-    # Xen API: Class PIF_metrics
-    # ----------------------------------------------------------------
-
-    PIF_metrics_attr_ro = ['io_read_kbs',
-                           'io_write_kbs',
-                           'last_updated']
-    PIF_metrics_attr_rw = []
-    PIF_metrics_methods = []
-
-    def PIF_metrics_get_all(self, _):
-        return xen_api_success(XendNode.instance().pif_metrics.keys())
-
-    def _PIF_metrics_get(self, _, ref):
-        return XendNode.instance().pif_metrics[ref]
-
 
     # Xen API: Class VM
     # ----------------------------------------------------------------        
@@ -1865,28 +1731,6 @@ class XendAPI(object):
         return xen_api_success_void()
 
 
-    # Xen API: Class VM_metrics
-    # ----------------------------------------------------------------
-
-    VM_metrics_attr_ro = ['memory_actual',
-                          'VCPUs_number',
-                          'VCPUs_utilisation',
-                          'VCPUs_CPU',
-                          'VCPUs_flags',
-                          'VCPUs_params',
-                          'state',
-                          'start_time',
-                          'last_updated']
-    VM_metrics_attr_rw = []
-    VM_metrics_methods = []
-
-    def _VM_metrics_get(self, _, ref):
-        return XendVMMetrics.get_by_uuid(ref)
-
-    def VM_metrics_get_all(self, _):
-        return xen_api_success(XendVMMetrics.get_all())
-
-
     # Xen API: Class VBD
     # ----------------------------------------------------------------
 
@@ -2570,33 +2414,6 @@ class XendAPI(object):
         return xen_api_success_void()
 
 
-    # Xen API: Class PBD
-    # ----------------------------------------------------------------
-
-    PBD_attr_ro = ['host',
-                   'SR',
-                   'device_config',
-                   'currently_attached']
-    PBD_attr_rw = []
-    PBD_methods = [('destroy', None)]
-    PBD_funcs   = [('create', None)]
-
-    def PBD_get_all(self, _):
-        return xen_api_success(XendPBD.get_all_refs())
-
-    def _PBD_get(self, _, ref):
-        return XendPBD.get(ref)
-
-    def PBD_create(self, _, record):
-        if 'uuid' in record:
-            return xen_api_error(['VALUE_NOT_SUPPORTED',
-                                  'uuid', record['uuid'],
-                                  'You may not specify a UUID on creation'])
-        new_uuid = XendPBD.XendPBD(record).get_uuid()
-        XendNode.instance().save()
-        return xen_api_success(new_uuid)
-
-
     # Xen API: Class event
     # ----------------------------------------------------------------
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendAPIStore.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/XendAPIStore.py     Sat Apr 28 10:28:59 2007 +0100
@@ -0,0 +1,59 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2007 Tom Wilkie <tom.wilkie@xxxxxxxxx>
+#============================================================================
+"""
+This is a place to put instances of XenAPI objects,
+instead of just holding them in arbitrary places.
+
+All objects which subclass XendBase should use this
+mechanism.
+
+You must register both the uuid and type, and get objects
+by type, to ensure safety
+"""
+
+__classes = {}
+
+def register(uuid, type, inst):
+    __classes[(uuid, type)] = inst
+    return inst
+
+def deregister(uuid, type):
+    old = get(uuid, type)
+    del __classes[(uuid, type)]
+    return old
+
+def get(uuid, type):
+    """
+    Get the instances by uuid and type
+    """
+    return __classes.get((uuid, type), None)
+
+def get_all(all_type):
+    """
+    Get all instances by type
+    """
+    return [inst
+            for ((uuid, t), inst) in __classes.items()
+            if t == all_type]        
+
+def get_all_uuid(all_type):
+    """
+    Get all uuids by type
+    """
+    return [uuid
+            for (uuid, t) in __classes.keys()
+            if t == all_type]
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendAPIVersion.py
--- a/tools/python/xen/xend/XendAPIVersion.py   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendAPIVersion.py   Sat Apr 28 10:28:59 2007 +0100
@@ -16,7 +16,7 @@
 #============================================================================
 
 
-XEN_API_VERSION_MAJOR = 0
-XEN_API_VERSION_MINOR = 5
+XEN_API_VERSION_MAJOR = 1
+XEN_API_VERSION_MINOR = 0
 XEN_API_VERSION_VENDOR = 'xenbits'
 XEN_API_VERSION_VENDOR_IMPLEMENTATION = {}
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendBase.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/XendBase.py Sat Apr 28 10:28:59 2007 +0100
@@ -0,0 +1,126 @@
+#!/usr/bin/python
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2007 Tom Wilkie <tom.wilkie@xxxxxxxxx>
+#============================================================================
+"""
+Base class for all XenAPI classes
+"""
+
+from xen.xend.XendError import *
+from xen.xend import XendAPIStore
+
+class XendBase:
+    #
+    # These functions describe the object, and what is exposed via the API
+    #
+    def getClass(self):
+        return "Base"
+    
+    def getAttrRO(self):
+        return ['uuid']
+
+    def getAttrRW(self):
+        return []
+
+    def getAttrInst(self):
+        return []
+
+    def getMethods(self):
+        return ["get_record"]
+
+    def getFuncs(self):
+        return ["get_all", "get_by_uuid", "get_all_records"]
+
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
+    
+    def __init__(self, uuid, record):
+        self.__uuid = uuid
+        
+        # First check this class implements all the correct methods:
+        for attr_ro in self.getAttrRO() + self.getAttrRW():
+            if not hasattr(self, "get_%s" % attr_ro):
+                raise ImplementationError(self.getClass(),
+                                          "get_%s" % attr_ro)
+
+        for attr_rw in self.getAttrRW():
+            if not hasattr(self, "set_%s" % attr_rw):
+                raise ImplementationError(self.getClass(),
+                                          "set_%s" % attr_rw)
+
+        for method in self.getMethods():
+            if not hasattr(self, method):
+                raise ImplementationError(self.getClass(),
+                                          method)
+
+        for func in self.getFuncs():
+            if not hasattr(self.__class__, func):
+                raise ImplementationError(self.getClass(),
+                                          func)
+
+        # Next check that the class is being created with the correct
+        # parameters
+        if not isinstance(record, dict):
+            raise CreateUnspecifiedAttributeError(
+                    "record" , self.getClass())
+        
+        for attr_inst in self.getAttrInst():
+            if attr_inst not in record:
+                raise CreateUnspecifiedAttributeError(
+                    attr_inst, self.getClass())
+            setattr(self, attr_inst, record[attr_inst])
+
+        # Finally register it
+        XendAPIStore.register(uuid, self.getClass(), self)
+
+    def destroy(self):
+        XendAPIStore.deregister(self.get_uuid(), self.getClass())
+
+    def get_uuid(self):
+        return self.__uuid
+
+    def get_record(self):
+        keys = self.getAttrRO() + self.getAttrRW()
+        return dict([(key, getattr(self, "get_%s" % key)())
+                     for key in keys])
+
+    #
+    # Class methods
+    #
+
+    def get_all(cls):
+        return XendAPIStore.get_all_uuid(cls.getClass())
+
+    def get_by_uuid(cls, uuid):
+        # Sanity check the uuid is one of us
+        me = XendAPIStore.get(uuid, cls.getClass())
+        if me is not None and me.getClass() == cls.getClass():
+            # In OSS, ref == uuid
+            return uuid
+        else:
+            raise "Big Error.. TODO!"
+
+    def get_all_records(cls):
+        return dict([(inst.get_uuid(), inst.get_record())
+                     for inst in XendAPIStore.get_all(cls.getClass())])
+
+    get_all = classmethod(get_all)
+    get_by_uuid = classmethod(get_by_uuid)
+    get_all_records = classmethod(get_all_records)
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendConfig.py       Sat Apr 28 10:28:59 2007 +0100
@@ -22,6 +22,7 @@ import types
 
 from xen.xend import sxp
 from xen.xend import uuid
+from xen.xend import XendAPIStore
 from xen.xend.XendError import VmError
 from xen.xend.XendDevices import XendDevices
 from xen.xend.PrettyPrint import prettyprintstring
@@ -341,7 +342,7 @@ class XendConfig(dict):
     # try and 'fix it up' but acutually fix the cause ;-)
     #
     def _memory_sanity_check(self):
-        log.debug("_memory_sanity_check memory_static_min: %s, "
+        log.trace("_memory_sanity_check memory_static_min: %s, "
                       "memory_static_max: %i, "
                       "memory_dynamic_min: %i, " 
                       "memory_dynamic_max: %i",
@@ -353,9 +354,6 @@ class XendConfig(dict):
         if not self["memory_static_min"] <= self["memory_static_max"]:
             raise XendConfigError("memory_static_min must be less " \
                                   "than or equal to memory_static_max") 
-        if not self["memory_dynamic_min"] <= self["memory_dynamic_max"]:
-            raise XendConfigError("memory_dynamic_min must be less " \
-                                  "than or equal to memory_dynamic_max")
         if not self["memory_static_min"] <= self["memory_dynamic_min"]:
             raise XendConfigError("memory_static_min must be less " \
                                   "than or equal to memory_dynamic_min")
@@ -1049,6 +1047,10 @@ class XendConfig(dict):
                     dev_info['type'] = cfg_xenapi.get('type')
                 if cfg_xenapi.get('name'):
                     dev_info['name'] = cfg_xenapi.get('name')
+                if cfg_xenapi.get('network'):
+                    network = XendAPIStore.get(
+                        cfg_xenapi.get('network'), 'network')
+                    dev_info['bridge'] = network.get_name_label()
                 
                 dev_uuid = cfg_xenapi.get('uuid', None)
                 if not dev_uuid:
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendDomain.py       Sat Apr 28 10:28:59 2007 +0100
@@ -293,10 +293,12 @@ class XendDomain:
                                 width = 78)
                 finally:
                     f.close()
+                    
                 try:
-                    os.rename(fn, self._managed_config_path(dom_uuid))
+                    shutil.move(fn, self._managed_config_path(dom_uuid))
                 except:
-                    log.exception("Renaming %s" % fn)
+                    log.exception("Renaming %s to %s", fn,
+                                  self._managed_config_path(dom_uuid))
                     os.remove(fn)
             except:
                 log.exception("Error occurred saving configuration file " +
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Sat Apr 28 10:28:59 2007 +0100
@@ -580,12 +580,9 @@ class XendDomainInfo:
         log.debug("Setting memory target of domain %s (%s) to %d MiB.",
                   self.info['name_label'], str(self.domid), target)
         
-        if target <= 0:
-            raise XendError('Invalid memory size')
-        
         MiB = 1024 * 1024
-        self.info['memory_dynamic_min'] = target * MiB
-        self.info['memory_dynamic_max'] = target * MiB
+        self._safe_set_memory('memory_dynamic_min', target * MiB)
+        self._safe_set_memory('memory_dynamic_max', target * MiB)
 
         if self.domid >= 0:
             self.storeVm("memory", target)
@@ -1422,6 +1419,9 @@ class XendDomainInfo:
                 raise VmError("HVM guest support is unavailable: is VT/AMD-V "
                               "supported by your CPU and enabled in your "
                               "BIOS?")
+            # Hack to pre-reserve some memory for HVM setup.
+            # Needed because Xen allocates 1MB by default immediately.
+            balloon.free(2*1024) # 2MB should be plenty
 
         self.domid = xc.domain_create(
             domid = 0,
@@ -1820,7 +1820,7 @@ class XendDomainInfo:
                     log.info("Unmounting %s from %s." %
                              (fn, BOOTLOADER_LOOPBACK_DEVICE))
 
-                    dom0.destroyDevice('tap', '/dev/xvdp')
+                    dom0.destroyDevice('tap', BOOTLOADER_LOOPBACK_DEVICE)
 
             if blcfg is None:
                 msg = "Had a bootloader specified, but can't find disk"
@@ -2134,14 +2134,24 @@ class XendDomainInfo:
     def get_memory_dynamic_min(self):
         return self.info.get('memory_dynamic_min', 0)
 
+    # only update memory-related config values if they maintain sanity 
+    def _safe_set_memory(self, key, newval):
+        oldval = self.info.get(key, 0)
+        try:
+            self.info[key] = newval
+            self.info._memory_sanity_check()
+        except Exception, ex:
+            self.info[key] = oldval
+            raise 
+    
     def set_memory_static_max(self, val):
-        self.info['memory_static_max'] = val
+        self._safe_set_memory('memory_static_max', val)
     def set_memory_static_min(self, val):
-        self.info['memory_static_min'] = val
+        self._safe_set_memory('memory_static_min', val)
     def set_memory_dynamic_max(self, val):
-        self.info['memory_dynamic_max'] = val
+        self._safe_set_memory('memory_dynamic_max', val)
     def set_memory_dynamic_min(self, val):
-        self.info['memory_dynamic_min'] = val
+        self._safe_set_memory('memory_dynamic_min', val)
     
     def get_vcpus_params(self):
         if self.getDomid() is None:
@@ -2246,9 +2256,18 @@ class XendDomainInfo:
 
             if not config.has_key('network'):
                 try:
+                    bridge = config.get('bridge', None)
+                    if bridge is None:
+                        from xen.util import Brctl
+                        if_to_br = dict([(i,b)
+                            for (b,ifs) in Brctl.get_state().items()
+                                for i in ifs])
+                        vifname = "vif%s.%s" % (self.getDomid(),
+                                                config.get('id'))
+                        bridge = if_to_br.get(vifname, None)
                     config['network'] = \
                         XendNode.instance().bridge_to_network(
-                        config.get('bridge')).uuid
+                        config.get('bridge')).get_uuid()
                 except Exception:
                     log.exception('bridge_to_network')
                     # Ignore this for now -- it may happen if the device
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py        Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendError.py        Sat Apr 28 10:28:59 2007 +0100
@@ -48,10 +48,6 @@ class PIFIsPhysical(XendError):
     def __init__(self):
         XendError.__init__(self, 'PIF is physical')
 
-class VLANTagInvalid(XendError):
-    def __init__(self):
-        XendError.__init__(self, 'VLAN tag invalid')
-
 class VmError(XendError):
     """Vm construction error."""
     pass
@@ -62,7 +58,123 @@ class HVMRequired(VmError):
                            'HVM guest support is unavailable: is VT/AMD-V '
                            'supported by your CPU and enabled in your BIOS?')
 
+class XendAPIError(XendError):
+    """Extend this class for all error thrown by
+    autoplugged classes"""
+    def __init__(self):
+        XendError.__init__(self, 'XendAPI Error: You should never see this'
+                           ' message; this class need to be overidden')
 
+    def get_api_error(self):
+        return ['INTERNAL_ERROR', 'You should never see this message; '
+                'this method needs to be overidden']
+
+class CreateUnspecifiedAttributeError(XendAPIError):
+    def __init__(self, attr_name, class_name):
+        XendAPIError.__init__(self)
+        self.attr_name = attr_name
+        self.class_name = class_name
+
+    def get_api_error(self):
+        return ['CREATE_UNSPECIFIED_ATTRIBUTE', self.attr_name,
+                self.class_name]
+
+    def __str__(self):
+        return "CREATE_UNSPECIFIED_ATTRIBUTE: %s, %s" % (self.attr_name,
+                 self.class_name)
+
+class UnmanagedNetworkError(XendAPIError):
+    def __init__(self, attr_name):
+        XendAPIError.__init__(self)
+        self.attr_name = attr_name
+
+    def get_api_error(self):
+        return ['UNMANAGED_NETWORK_ERROR', self.attr_name]
+
+    def __str__(self):
+        return "UNMANAGED_NETWORK_ERROR: %s" % self.attr_name
+
+class UniqueNameError(XendAPIError):
+    def __init__(self, name, class_name):
+        XendAPIError.__init__(self)
+        self.name = name
+        self.class_name = class_name
+        
+    def get_api_error(self):
+        return ['UNIQUE_NAME_ERROR', self.name, self.class_name]        
+
+    def __str__(self):
+        return 'UNIQUE_NAME_ERROR: %s, %s' % (self.name, self.class_name)
+
+class InvalidDeviceError(XendAPIError):
+    def __init__(self, dev):
+        XendAPIError.__init__(self)
+        self.dev = dev
+        
+    def get_api_error(self):
+        return ['INVALID_DEVICE_ERROR', self.dev]        
+
+    def __str__(self):
+        return 'INVALID_DEVICE_ERROR: %s' % self.dev
+    
+class DeviceExistsError(XendAPIError):
+    def __init__(self, dev):
+        XendAPIError.__init__(self)
+        self.dev = dev
+        
+    def get_api_error(self):
+        return ['DEVICE_EXISTS_ERROR', self.dev]        
+
+    def __str__(self):
+        return 'DEVICE_EXISTS_ERROR: %s' % self.dev
+
+class InvalidHandleError(XendAPIError):
+    def __init__(self, klass, handle):
+        XendAPIError.__init__(self)
+        self.klass = klass
+        self.handle = handle
+        
+    def get_api_error(self):
+        return ['HANDLE_INVALID', self.klass, self.handle]        
+
+    def __str__(self):
+        return 'HANDLE_INVALID: %s %s' % (self.klass, self.handle)
+
+class ImplementationError(XendAPIError):
+    def __init__(self, klass, func):
+        XendAPIError.__init__(self)
+        self.klass = klass
+        self.func = func
+
+    def get_api_error(self):
+        return ['IMPLEMENTATION_ERROR', self.klass, self.func]        
+
+    def __str__(self):
+        return 'IMPLEMENTATION_ERROR: %s %s' % (self.klass, self.func)
+
+class VLANTagInvalid(XendAPIError):
+    def __init__(self, vlan):
+        XendAPIError.__init__(self)
+        self.vlan = vlan
+
+    def get_api_error(self):
+        return ['VLAN_TAG_INVALID', self.vlan]
+
+    def __str__(self):
+        return 'VLAN_TAG_INVALID: %s' % self.vlan
+
+class NetworkError(XendAPIError):
+    def __init__(self, error, network):
+        XendAPIError.__init__(self)
+        self.network = network
+        self.error = error
+
+    def get_api_error(self):
+        return ['NETWORK_ERROR', self.error, self.network]
+
+    def __str__(self):
+        return 'NETWORK_ERROR: %s %s' % (self.error, self.network)
+    
 XEND_ERROR_AUTHENTICATION_FAILED = ('ELUSER', 'Authentication Failed')
 XEND_ERROR_SESSION_INVALID       = ('EPERMDENIED', 'Session Invalid')
 XEND_ERROR_DOMAIN_INVALID        = ('EINVALIDDOMAIN', 'Domain Invalid')
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendNetwork.py
--- a/tools/python/xen/xend/XendNetwork.py      Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendNetwork.py      Sat Apr 28 10:28:59 2007 +0100
@@ -24,15 +24,139 @@ import XendDomain
 import XendDomain
 import XendNode
 from XendLogging import log
+from xen.xend import uuid as genuuid
+from xen.xend.XendBase import XendBase
+from xen.xend.XendError import *
+from xen.util import Brctl
+from xen.xend import XendAPIStore
 
 IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)'
 
-class XendNetwork:
-    def __init__(self, uuid, record):
-        self.uuid = uuid
-        self.name_label = record.get('name_label', '')
-        self.name_description = record.get('name_description', '')
-        self.other_config = record.get('other_config', {})
+def bridge_exists(name):
+    return name in Brctl.get_state().keys()
+
+class XendNetwork(XendBase):
+    """We're going to assert that the name_label of this
+    network is just the name of the bridge"""
+
+    def getClass(self):
+        return "network"
+
+    def getAttrRW(self):
+        attrRW = ['name_label',
+                  'name_description',
+                  'other_config',
+                  'default_gateway',
+                  'default_netmask']
+        return XendBase.getAttrRW() + attrRW
+
+    def getAttrRO(self):
+        attrRO =  ['VIFs',
+                   'PIFs']
+        return XendBase.getAttrRO() + attrRO
+
+    def getAttrInst(self):
+        return XendBase.getAttrInst() + self.getAttrRW()
+
+    def getMethods(self):
+        methods = ['add_to_other_config',
+                   'remove_from_other_config',
+                   'destroy']
+        return XendBase.getMethods() + methods
+
+    def getFuncs(self):
+        funcs = ['create']
+        return XendBase.getFuncs() + funcs
+
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
+
+    def create_phy(self, name):
+        """
+        Called when a new bridge is found on xend start
+        """
+        # Create new uuids
+        uuid = genuuid.createString()
+
+        # Create instance
+        record = {
+                'name_label':       name,
+                'name_description': '',
+                'other_config':     {},
+                'default_gateway':  '',
+                'default_netmask':  ''
+            }
+        network = XendNetwork(record, uuid)
+
+        return uuid
+        
+    def recreate(self, record, uuid):
+        """
+        Called on xend start / restart, or machine
+        restart, when read from saved config.
+        Needs to check network exists, create it otherwise
+        """
+
+        # Create instance (do this first, to check record)
+        network = XendNetwork(record, uuid)
+
+        # Create network if it doesn't already exist
+        if not bridge_exists(network.name_label):
+            Brctl.bridge_create(network.name_label)
+
+        return uuid
+
+    def create(self, record):
+        """
+        Called from API, to create a new network
+        """
+        # Create new uuids
+        uuid = genuuid.createString()
+
+        # Create instance (do this first, to check record)
+        network = XendNetwork(record, uuid)
+
+        # Check network doesn't already exist
+        name_label = network.name_label
+        if bridge_exists(name_label):
+            del network
+            raise UniqueNameError(name_label, "network")
+
+        # Create the bridge
+        Brctl.bridge_create(network.name_label)
+
+        XendNode.instance().save_networks()
+
+        return uuid
+
+    create_phy  = classmethod(create_phy)
+    recreate    = classmethod(recreate)
+    create      = classmethod(create)
+        
+    def __init__(self, record, uuid):       
+        XendBase.__init__(self, uuid, record)
+        
+    #
+    # XenAPI Mehtods
+    #
+
+    def destroy(self):
+        # check no VIFs or PIFs attached
+        if len(self.get_VIFs()) > 0:
+            raise NetworkError("Cannot destroy network with VIFs attached",
+                               self.get_name_label())
+
+        if len(self.get_PIFs()) > 0:
+            raise NetworkError("Cannot destroy network with PIFs attached",
+                               self.get_name_label())        
+        
+        XendBase.destroy(self)
+        Brctl.bridge_del(self.get_name_label())
+        XendNode.instance().save_networks()
 
     def get_name_label(self):
         return self.name_label
@@ -41,9 +165,8 @@ class XendNetwork:
         return self.name_description
 
     def set_name_label(self, new_name):
-        self.name_label = new_name
-        XendNode.instance().save_networks()
-
+        pass
+        
     def set_name_description(self, new_desc):
         self.name_description = new_desc
         XendNode.instance().save_networks()
@@ -55,13 +178,14 @@ class XendNetwork:
             vifs = vm.get_vifs()
             for vif in vifs:
                 vif_cfg = vm.get_dev_xenapi_config('vif', vif)
-                if vif_cfg.get('network') == self.uuid:
+                if vif_cfg.get('network') == self.get_uuid():
                     result.append(vif)
         return result
 
     def get_PIFs(self):
-        return [x.uuid for x in XendNode.instance().pifs.values()
-                if x.network == self]
+        pifs = XendAPIStore.get_all("PIF")
+        return [pif.get_uuid() for pif in pifs
+                if pif.get_network() == self.get_uuid()]
 
     def get_other_config(self):
         return self.other_config
@@ -79,17 +203,16 @@ class XendNetwork:
             del self.other_config[key]
         XendNode.instance().save_networks()
 
-    def get_record(self):
-        return self.get_record_internal(True)
-
-    def get_record_internal(self, transient):
-        result = {
-            'uuid': self.uuid,
-            'name_label': self.name_label,
-            'name_description': self.name_description,
-            'other_config' : self.other_config,
-        }
-        if transient:
-            result['VIFs'] = self.get_VIFs()
-            result['PIFs'] = self.get_PIFs()
-        return result
+    def get_default_gateway(self):
+        return self.default_gateway
+
+    def set_default_gateway(self, gateway):
+        self.default_gateway = gateway
+        XendNode.instance().save_networks()
+
+    def get_default_netmask(self):
+        return self.default_netmask
+
+    def set_default_netmask(self, netmask):
+        self.default_netmask = netmask
+        XendNode.instance().save_networks()
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendNode.py Sat Apr 28 10:28:59 2007 +0100
@@ -21,9 +21,10 @@ import xen.lowlevel.xc
 import xen.lowlevel.xc
 
 from xen.util import Brctl
+from xen.xend import XendAPIStore
 
 import uuid, arch
-import XendPBD
+from XendPBD import XendPBD
 from XendError import *
 from XendOptions import instance as xendoptions
 from XendQCoWStorageRepo import XendQCoWStorageRepo
@@ -34,7 +35,7 @@ from XendNetwork import *
 from XendNetwork import *
 from XendStateStore import XendStateStore
 from XendMonitor import XendMonitor
-
+     
 class XendNode:
     """XendNode - Represents a Domain 0 Host."""
     
@@ -133,70 +134,78 @@ class XendNode:
                       'features' : cpu_features,
                     })
 
-        self.pifs = {}
-        self.pif_metrics = {}
-        self.networks = {}
         self.srs = {}
-        
-        # initialise networks
+
+        # Initialise networks
+        # First configure ones off disk
         saved_networks = self.state_store.load_state('network')
         if saved_networks:
             for net_uuid, network in saved_networks.items():
-                self.network_create(network, False, net_uuid)
-        else:
-            bridges = Brctl.get_state().keys()
-            for bridge in bridges:
-                self.network_create({'name_label' : bridge }, False)
+                try:
+                    XendNetwork.recreate(network, net_uuid)
+                except CreateUnspecifiedAttributeError:
+                    log.warn("Error recreating network %s", net_uuid)
                 
-        # Get a mapping from interface to bridge
-
-        if_to_br = dict([(i,b)
-                         for (b,ifs) in Brctl.get_state().items()
-                         for i in ifs])
-
-        # initialise PIFs
+        # Next discover any existing bridges and check
+        # they are not already configured
+        bridges = Brctl.get_state().keys()
+        configured_bridges = [XendAPIStore.get(
+                                  network_uuid, "network")
+                                      .get_name_label()
+                              for network_uuid in XendNetwork.get_all()]
+        unconfigured_bridges = [bridge
+                                for bridge in bridges
+                                if bridge not in configured_bridges]
+        for unconfigured_bridge in unconfigured_bridges:
+            XendNetwork.create_phy(unconfigured_bridge)
+
+        # Initialise PIFs
+        # First configure ones off disk
         saved_pifs = self.state_store.load_state('pif')
         if saved_pifs:
             for pif_uuid, pif in saved_pifs.items():
-                if pif.get('network') in self.networks:
-                    network = self.networks[pif['network']]
-                    try:
-                        if 'device' not in pif and 'name' in pif:
-                            # Compatibility hack, can go pretty soon.
-                            pif['device'] = pif['name']
-                        if 'metrics' not in pif:
-                            # Compatibility hack, can go pretty soon.
-                            pif['metrics'] = uuid.createString()
-
-                        try:
-                            pif['VLAN'] = int(pif.get('VLAN', -1))
-                        except (ValueError, TypeError):
-                            pif['VLAN'] = -1
-
-                        self._PIF_create(pif['device'], pif['MTU'],
-                                         pif['VLAN'],
-                                         pif['MAC'], network, False, pif_uuid,
-                                         pif['metrics'])
-                    except NetworkAlreadyConnected, exn:
-                        log.error('Cannot load saved PIF %s, as network %s ' +
-                                  'is already connected to PIF %s',
-                                  pif_uuid, pif['network'], exn.pif_uuid)
-        else:
-            for name, mtu, mac in linux_get_phy_ifaces():
-                bridge_name = if_to_br.get(name, None)
-                if bridge_name is not None:
-                    networks = [network for
-                                network in self.networks.values()
-                                if network.get_name_label() == bridge_name]
-                    if len(networks) > 0:
-                        network = networks[0]
-                        self._PIF_create(name, mtu, -1, mac, network, False)
-
+                try:
+                    XendPIF.recreate(pif, pif_uuid)
+                except CreateUnspecifiedAttributeError:
+                    log.warn("Error recreating PIF %s", pif_uuid)
+        
+        # Next discover any existing PIFs and check
+        # they are not already configured
+        configured_pifs = [XendAPIStore.get(
+                               pif_uuid, "PIF")
+                                   .get_interface_name()
+                           for pif_uuid in XendPIF.get_all()]
+        unconfigured_pifs = [(name, mtu, mac)
+                             for name, mtu, mac in linux_get_phy_ifaces()
+                             if name not in configured_pifs]
+
+        # Get a mapping from interface to bridge          
+        if_to_br = dict([(i,b)
+                         for (b,ifs) in Brctl.get_state().items()
+                             for i in ifs])
+
+        for name, mtu, mac in unconfigured_pifs:
+            # Check PIF is on bridge
+            # if not, ignore
+            bridge_name = if_to_br.get(name, None)
+            if bridge_name is not None:
+                # Translate bridge name to network uuid
+                for network_uuid in XendNetwork.get_all():
+                    network = XendAPIStore.get(
+                        network_uuid, 'network')
+                    if network.get_name_label() == bridge_name:
+                        XendPIF.create_phy(network_uuid, name,
+                                           mtu, mac)
+                        break
+                else:
+                    log.debug("Cannot find network for bridge %s "
+                              "when configuring PIF %s",
+                              (bridge_name, name))     
+        
         # initialise storage
         saved_srs = self.state_store.load_state('sr')
         if saved_srs:
             for sr_uuid, sr_cfg in saved_srs.items():
-                log.error("SAved SRS %s %s", sr_uuid, sr_cfg['type'])
                 if sr_cfg['type'] == 'qcow_file':
                     self.srs[sr_uuid] = XendQCoWStorageRepo(sr_uuid)
                 elif sr_cfg['type'] == 'local':
@@ -214,69 +223,50 @@ class XendNode:
         saved_pbds = self.state_store.load_state('pbd')
         if saved_pbds:
             for pbd_uuid, pbd_cfg in saved_pbds.items():
-                pbd_cfg['uuid'] = pbd_uuid
-                XendPBD.XendPBD(pbd_cfg)
-
-
-    def network_create(self, record, persist = True, net_uuid = None):
-        if net_uuid is None:
-            net_uuid = uuid.createString()
-        self.networks[net_uuid] = XendNetwork(net_uuid, record)
-        if persist:
-            self.save_networks()
-        return net_uuid
-
-
-    def network_destroy(self, net_uuid):
-        del self.networks[net_uuid]
-        self.save_networks()
-
-
-    def get_PIF_refs(self):
-        return self.pifs.keys()
-
-
-    def _PIF_create(self, name, mtu, vlan, mac, network, persist = True,
-                    pif_uuid = None, metrics_uuid = None):
-        for pif in self.pifs.values():
-            if pif.network == network:
-                raise NetworkAlreadyConnected(pif.uuid)
-
-        if pif_uuid is None:
-            pif_uuid = uuid.createString()
-        if metrics_uuid is None:
-            metrics_uuid = uuid.createString()
-
-        metrics = XendPIFMetrics(metrics_uuid)
-        pif = XendPIF(pif_uuid, metrics, name, mtu, vlan, mac, network, self)
-        metrics.set_PIF(pif)
-
-        self.pif_metrics[metrics_uuid] = metrics
-        self.pifs[pif_uuid] = pif
-
-        if persist:
-            self.save_PIFs()
-            self.refreshBridges()
-        return pif_uuid
-
-
-    def PIF_create_VLAN(self, pif_uuid, network_uuid, vlan):
-        if vlan < 0 or vlan >= 4096:
-            raise VLANTagInvalid()
-            
-        pif = self.pifs[pif_uuid]
-        network = self.networks[network_uuid]
-        return self._PIF_create(pif.device, pif.mtu, vlan, pif.mac, network)
-
-
-    def PIF_destroy(self, pif_uuid):
-        pif = self.pifs[pif_uuid]
-
-        if pif.vlan == -1:
-            raise PIFIsPhysical()
-
-        del self.pifs[pif_uuid]
-        self.save_PIFs()
+                try:
+                    XendPBD.recreate(pbd_uuid, pbd_cfg)
+                except CreateUnspecifiedAttributeError:
+                    log.warn("Error recreating PBD %s", pbd_uuid) 
+
+##    def network_destroy(self, net_uuid):
+ ##       del self.networks[net_uuid]
+  ##      self.save_networks()
+
+
+##    def get_PIF_refs(self):
+##       return self.pifs[:]
+
+##   def _PIF_create(self, name, mtu, vlan, mac, network, persist = True,
+##                     pif_uuid = None, metrics_uuid = None):
+##         for pif in self.pifs.values():
+##             if pif.network == network:
+##                 raise NetworkAlreadyConnected(pif.uuid)
+
+##         if pif_uuid is None:
+##             pif_uuid = uuid.createString()
+##         if metrics_uuid is None:
+##             metrics_uuid = uuid.createString()
+
+##         metrics = XendPIFMetrics(metrics_uuid)
+##         pif = XendPIF(pif_uuid, metrics, name, mtu, vlan, mac, network, 
self)
+##         metrics.set_PIF(pif)
+
+##         self.pif_metrics[metrics_uuid] = metrics
+##         self.pifs[pif_uuid] = pif
+
+##         if persist:
+##             self.save_PIFs()
+##             self.refreshBridges()
+##         return pif_uuid
+
+##     def PIF_destroy(self, pif_uuid):
+##         pif = self.pifs[pif_uuid]
+
+##         if pif.vlan == -1:
+##             raise PIFIsPhysical()
+
+##         del self.pifs[pif_uuid]
+##         self.save_PIFs()
 
 
     def save(self):
@@ -284,7 +274,7 @@ class XendNode:
         host_record = {self.uuid: {'name_label':self.name,
                                    'name_description':self.desc,
                                    'metrics_uuid': self.host_metrics_uuid,
-                                   'other_config': repr(self.other_config)}}
+                                   'other_config': self.other_config}}
         self.state_store.save_state('host',host_record)
         self.state_store.save_state('cpu', self.cpus)
         self.save_PIFs()
@@ -293,18 +283,21 @@ class XendNode:
         self.save_SRs()
 
     def save_PIFs(self):
-        pif_records = dict([(k, v.get_record())
-                            for k, v in self.pifs.items()])
+        pif_records = dict([(pif_uuid, XendAPIStore.get(
+                                 pif_uuid, "PIF").get_record())
+                            for pif_uuid in XendPIF.get_all()])
         self.state_store.save_state('pif', pif_records)
 
     def save_networks(self):
-        net_records = dict([(k, v.get_record_internal(False))
-                            for k, v in self.networks.items()])
+        net_records = dict([(network_uuid, XendAPIStore.get(
+                                 network_uuid, "network").get_record())
+                            for network_uuid in XendNetwork.get_all()])
         self.state_store.save_state('network', net_records)
 
     def save_PBDs(self):
-        pbd_records = dict([(v.get_uuid(), v.get_record())
-                            for v in XendPBD.get_all()])
+        pbd_records = dict([(pbd_uuid, XendAPIStore.get(
+                                 pbd_uuid, "PBD").get_record())
+                            for pbd_uuid in XendPBD.get_all()])
         self.state_store.save_state('pbd', pbd_records)
 
     def save_SRs(self):
@@ -330,9 +323,6 @@ class XendNode:
 
     def is_valid_cpu(self, cpu_ref):
         return (cpu_ref in self.cpus)
-
-    def is_valid_network(self, network_ref):
-        return (network_ref in self.networks)
 
     def is_valid_sr(self, sr_ref):
         return (sr_ref in self.srs)
@@ -495,12 +485,6 @@ class XendNode:
     # Network Functions
     #
     
-    def get_network_refs(self):
-        return self.networks.keys()
-
-    def get_network(self, network_ref):
-        return self.networks[network_ref]
-
     def bridge_to_network(self, bridge):
         """
         Determine which network a particular bridge is attached to.
@@ -518,13 +502,12 @@ class XendNode:
                 raise Exception(
                     'Could not find default bridge, and none was specified')
 
-        bridges = Brctl.get_state()
-        if bridge not in bridges:
-            raise Exception('Bridge %s is not up' % bridge)
-        for pif in self.pifs.values():
-            if pif.interface_name() in bridges[bridge]:
-                return pif.network
-        raise Exception('Bridge %s is not connected to a network' % bridge)
+        for network_uuid in XendNetwork.get_all():
+            network = XendAPIStore.get(network_uuid, "network")
+            if network.get_name_label() == bridge:
+                return network
+        else:
+            raise Exception('Cannot find network for bridge %s' % bridge)
 
     #
     # Debug keys.
@@ -641,12 +624,6 @@ class XendNode:
         return dict(self.physinfo())
     def info_dict(self):
         return dict(self.info())
-
-
-    def refreshBridges(self):
-        for pif in self.pifs.values():
-            pif.refresh(Brctl.get_state())
-
 
 def parse_proc_cpuinfo():
     cpuinfo = {}
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendPBD.py
--- a/tools/python/xen/xend/XendPBD.py  Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendPBD.py  Sat Apr 28 10:28:59 2007 +0100
@@ -18,62 +18,82 @@
 
 import uuid
 from XendLogging import log
+from xen.xend.XendBase import XendBase
+from xen.xend import XendAPIStore
 
+class XendPBD(XendBase):
+    """Physical block devices."""
 
-attr_inst = ['uuid',
-             'host',
-             'SR',
-             'device_config']
-attr_ro = attr_inst + ['currently_attached']
+    def getClass(self):
+        return "PBD"
+    
+    def getAttrRO(self):
+        attrRO = ['host',
+                  'SR',
+                  'device_config',
+                  'currently_attached']
+        return XendBase.getAttrRO() + attrRO
 
+    def getAttrRW(self):
+        attrRW = []
+        return XendBase.getAttrRW() + attrRW
 
-_all = {}
+    def getAttrInst(self):
+        return ['uuid',
+                'host',
+                'SR',
+                'device_config']
 
+    def getMethods(self):
+        methods = ['destroy']
+        return XendBase.getMethods() + methods
 
-def get(ref):
-    return _all[ref]
+    def getFuncs(self):
+        funcs = ['create',
+                 'get_by_SR']
+        return XendBase.getFuncs() + funcs
 
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
 
-def get_all():
-    return _all.values()
+    def recreate(uuid, record):
+        pbd = XendPBD(uuid, record)
+        return uuid
+    
+    def create(cls, record):
+        uuid = genuuid.createString()
+        pbd = XendPBD(uuid, record)
+        return uuid       
 
+    create = classmethod(create)
+    
+    def __init__(self, uuid, record):
+        XendBase.__init__(self, uuid, record)
+        this.currently_attached = True
 
-def get_all_refs():
-    return _all.keys()
+    def get_host(self):
+        return this.host
+    
+    def get_SR(self):
+        return this.SR
 
+    def get_device_config(self):
+        return this.device_config
 
-def get_by_SR(sr_ref):
-    return [k for (k, v) in _all.items() if v.get_SR() == sr_ref]
-
-
-class XendPBD:
-    """Physical block devices."""
-    
-    def __init__(self, record):
-        if 'uuid' not in record:
-            record['uuid'] = uuid.createString()
-
-        import XendAPI
-        for v in attr_inst:
-            setattr(self, v, record[v])
-        self.currently_attached = True
-        _all[record['uuid']] = self
-
+    def get_currently_attached(self):
+        return this.currently_attached
 
     def destroy(self):
-        if self.uuid in _all:
-            del _all[self.uuid]
+        pass
+    
+    def get_by_SR(cls, sr_ref):
+        pbds = XendAPIStore.get_all("PBD")
+        return [pbd.get_uuid()
+                for pbd in pbds
+                if pbd.get_SR() == sr_ref]
 
-
-    def get_record(self):
-        import XendAPI
-        result = {}
-        for v in attr_ro:
-            result[v] = getattr(self, v)
-        return result
-
-
-for v in attr_ro:
-    def f(v_):
-        setattr(XendPBD, 'get_' + v_, lambda s: getattr(s, v_))
-    f(v)
+    get_by_SR = classmethod(get_by_SR)
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendPIF.py
--- a/tools/python/xen/xend/XendPIF.py  Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendPIF.py  Sat Apr 28 10:28:59 2007 +0100
@@ -19,11 +19,14 @@ import logging
 import logging
 import os
 import re
-
+from xen.xend import uuid as genuuid
+from xen.xend import XendAPIStore
+from xen.xend.XendBase import XendBase
+from xen.xend.XendPIFMetrics import XendPIFMetrics
+from xen.xend.XendError import *
 
 log = logging.getLogger("xend.XendPIF")
 log.setLevel(logging.TRACE)
-
 
 MAC_RE = re.compile(':'.join(['[0-9a-f]{2}'] * 6))
 IP_IFACE_RE = re.compile(r'^\d+: (\w+):.*mtu (\d+) .* link/\w+ ([0-9a-f:]+)')
@@ -87,106 +90,279 @@ def linux_set_mtu(iface, mtu):
     except ValueError:
         return False
 
-class XendPIF:
+def _create_VLAN(dev, vlan):
+    rc, _ = commands.getstatusoutput('vconfig add %s %d' %
+                                     (dev, vlan))
+    if rc != 0:
+        return False
+
+    rc, _ = commands.getstatusoutput('ifconfig %s.%d up' %
+                                     (dev, vlan))
+    return rc == 0
+
+def _destroy_VLAN(dev, vlan):
+    rc, _ = commands.getstatusoutput('ifconfig %s.%d down' %
+                                     (dev, vlan))
+    if rc != 0:
+        return False
+                                     
+    rc, _ = commands.getstatusoutput('vconfig rem %s.%d' %
+                                     (dev, vlan))
+    return rc == 0
+
+class XendPIF(XendBase):
     """Representation of a Physical Network Interface."""
-    
-    def __init__(self, uuid, metrics, device, mtu, vlan, mac, network,
-                 host):
-        self.uuid = uuid
-        self.metrics = metrics
-        self.device = device
-        self.mac = mac
-        self.mtu = mtu
-        self.vlan = vlan
-        self.network = network
-        self.host = host
-
-    def set_device(self, new_device):
-        self.device = new_device
-
-    def set_mac(self, new_mac):
-        success = linux_set_mac(new_mac)
+
+    def getClass(self):
+        return "PIF"
+
+    def getAttrRO(self):
+        attrRO = ['network',
+                  'host',
+                  'metrics',
+                  'device',
+                  'VLAN']
+        return XendBase.getAttrRO() + attrRO
+    
+    def getAttrRW(self):
+        attrRW = ['MAC',
+                  'MTU']
+        return XendBase.getAttrRW() + attrRW
+
+    def getAttrInst(self):
+        attrInst = ['network',
+                    'device',
+                    'MAC',
+                    'MTU',
+                    'VLAN']
+        return attrInst
+
+    def getMethods(self):
+        methods = ['plug',
+                   'unplug',
+                   'destroy']
+        return XendBase.getMethods() + methods
+
+    def getFuncs(self):
+        funcs = ['create_VLAN']
+        return XendBase.getFuncs() + funcs
+
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
+    
+    def create_phy(self, network_uuid, device,
+                   MAC, MTU):
+        """
+        Called when a new physical PIF is found
+        Could be a VLAN...
+        """
+        # Create new uuids
+        pif_uuid = genuuid.createString()
+        metrics_uuid = genuuid.createString()
+
+        # Create instances
+        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)
+
+        # Is this a VLAN?
+        VLANdot = device.split(".")
+        VLANcolon = device.split(":")
+
+        if len(VLANdot) > 1:
+            VLAN = VLANdot[1]
+            device = VLANdot[0]
+        elif len(VLANcolon) > 1:
+            VLAN = VLANcolon[1]
+            device = VLANcolon[0] 
+        else:
+            VLAN = -1
+            
+        record = {
+            'network': network_uuid,
+            'device':  device,
+            'MAC':     MAC,
+            'MTU':     MTU,
+            'VLAN':    VLAN
+            }
+        pif = XendPIF(record, pif_uuid, metrics_uuid)
+
+        return pif_uuid
+
+    def recreate(self, record, uuid):
+        """Called on xend start / restart"""        
+        pif_uuid = uuid
+        metrics_uuid = record['metrics']
+
+        # Create instances
+        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)
+        pif = XendPIF(record, pif_uuid, metrics_uuid)
+
+        # If physical PIF, check exists
+        # If VLAN, create if not exist
+        ifs = [dev for dev, _1, _2 in linux_get_phy_ifaces()]
+        if pif.get_VLAN() == -1:
+            if pif.get_device() not in ifs:
+                pif.destroy()
+                metrics.destroy()
+                return None
+        else:
+            if pif.get_interface_name() not in ifs:
+                _create_VLAN(pif.get_device(), pif.get_VLAN())
+                pif.plug()
+
+        return pif_uuid
+
+    def create_VLAN(self, device, network_uuid, host_ref, vlan):
+        """Exposed via API - create a new VLAN from existing VIF"""
+        
+        ifs = [name for name, _, _ in linux_get_phy_ifaces()]
+
+        vlan = int(vlan)
+
+        # Check VLAN tag is valid
+        if vlan < 0 or vlan >= 4096:
+            raise VLANTagInvalid(vlan)
+        
+        # Check device exists
+        if device not in ifs:
+            raise InvalidDeviceError(device)
+
+        # Check VLAN doesn't already exist
+        if "%s.%d" % (device, vlan) in ifs:
+            raise DeviceExistsError("%s.%d" % (device, vlan))
+
+        # Check network ref is valid
+        from XendNetwork import XendNetwork
+        if network_uuid not in XendNetwork.get_all():
+            raise InvalidHandleError("Network", network_uuid)
+
+        # Check host_ref is this host
+        import XendNode
+        if host_ref != XendNode.instance().get_uuid():
+            raise InvalidHandleError("Host", host_ref)
+
+        # Create the VLAN
+        _create_VLAN(device, vlan)
+
+        # Create new uuids
+        pif_uuid = genuuid.createString()
+        metrics_uuid = genuuid.createString()
+
+        # Create the record
+        record = {
+            "device":  device,
+            "MAC":     '',
+            "MTU":     '',
+            "network": network_uuid,
+            "VLAN":    vlan
+            }
+
+        # Create instances
+        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)
+        pif = XendPIF(record, pif_uuid, metrics_uuid)
+
+        # Not sure if they should be created plugged or not...
+        pif.plug()
+
+        XendNode.instance().save_PIFs()
+        return pif_uuid
+
+    create_phy  = classmethod(create_phy)
+    recreate    = classmethod(recreate)
+    create_VLAN = classmethod(create_VLAN)
+    
+    def __init__(self, record, uuid, metrics_uuid):
+        XendBase.__init__(self, uuid, record)
+        self.metrics = metrics_uuid
+
+    def plug(self):
+        """Plug the PIF into the network"""
+        network = XendAPIStore.get(self.network,
+                                   "network")
+        bridge_name = network.get_name_label()
+
+        from xen.util import Brctl
+        Brctl.vif_bridge_add({
+            "bridge": bridge_name,
+            "vif":    self.get_interface_name()
+            })
+
+    def unplug(self):
+        """Unplug the PIF from the network"""
+        network = XendAPIStore.get(self.network,
+                                   "network")
+        bridge_name = network.get_name_label()
+
+        from xen.util import Brctl
+        Brctl.vif_bridge_rem({
+            "bridge": bridge_name,
+            "vif":    self.get_interface_name()
+            })
+
+    def destroy(self):
+        # Figure out if this is a physical device
+        if self.get_interface_name() == \
+           self.get_device():
+            raise PIFIsPhysical(self.get_uuid())
+
+        self.unplug()
+
+        if _destroy_VLAN(self.get_device(), self.get_VLAN()):
+            XendBase.destroy(self)
+            import XendNode
+            XendNode.instance().save_PIFs()
+        else:
+            raise NetworkError("Unable to delete VLAN", self.get_uuid())
+
+    def get_interface_name(self):
+        if self.get_VLAN() == -1:
+            return self.get_device()
+        else:
+            return "%s.%d" % (self.get_device(), self.get_VLAN())
+        
+    def get_device(self):
+        """
+        This is the base interface.
+        For phy if (VLAN == -1) this is same as
+        if name.
+        For VLANs, this it the bit before the period
+        """
+        return self.device
+
+    def get_network(self):
+        return self.network
+
+    def get_host(self):
+        from xen.xend import XendNode
+        return XendNode.instance().get_uuid()
+
+    def get_metrics(self):
+        return self.metrics
+
+    def get_MAC(self):
+        return self.MAC
+
+    def set_MAC(self, new_mac):
+        success = linux_set_mac(self.device, new_mac)
         if success:
-            self.mac = new_mac
+            self.MAC = new_mac
+            import XendNode
+            XendNode.instance().save_PIFs()
         return success
 
-    def set_mtu(self, new_mtu):
-        success = linux_set_mtu(new_mtu)
+    def get_MTU(self):
+        return self.MTU
+
+    def set_MTU(self, new_mtu):
+        success = linux_set_mtu(self.device, new_mtu)
         if success:
-            self.mtu = new_mtu
+            self.MTU = new_mtu
+            import XendNode
+            XendNode.instance().save_PIFs()
         return success
 
-    def get_record(self):
-        return {'uuid': self.uuid,
-                'device': self.device,
-                'MAC': self.mac,
-                'MTU': self.mtu,
-                'VLAN': self.vlan,
-                'host': self.host.uuid,
-                'network': self.network.uuid,
-                'metrics': self.metrics.uuid}
-
-    def refresh(self, bridges):
-        ifname = self.interface_name()
-        rc, _ = _cmd('ip link show %s', ifname)
-        if rc != 0:
-            # Interface does not exist.  If it's a physical interface, then
-            # there's nothing we can do -- this should have been set up with
-            # the network script.  Otherwise, we can use vconfig to derive
-            # a subinterface.
-            if self.vlan == -1:
-                return
-            
-            rc, _ = _cmd('vconfig add %s %d', self.device, self.vlan)
-            if rc != 0:
-                log.error('Could not refresh VLAN for interface %s', ifname)
-                return
-            
-            log.info('Created network interface %s', ifname)
-
-        for brname, nics in bridges.items():
-            if ifname in nics:
-                log.debug('%s is already attached to %s', ifname, brname)
-                return
-
-        # The interface is not attached to a bridge.  Create one, and attach
-        # the interface to it.
-        brname = _new_bridge_name(bridges)
-        rc, _ = _cmd('brctl addbr %s', brname)
-        if rc != 0:
-            log.error('Could not create bridge %s for interface %s', brname,
-                      ifname)
-            return
-        log.info('Created network bridge %s', brname)
-        
-        rc, _ = _cmd('brctl addif %s %s', brname, ifname)
-        if rc != 0:
-            log.error('Could not add %s to %s', ifname, brname)
-            return
-        log.info('Added network interface %s to bridge %s', ifname, brname)
-
-
-    def interface_name(self):
-        if self.vlan != -1:
-            return '%s.%d' % (self.device, self.vlan)
-        else:
-            return self.device
-
-
-def _cmd(cmd, *args):
-    if len(args) > 0:
-        cmd = cmd % args
-    rc, output = commands.getstatusoutput(cmd)
-    if rc != 0:
-        log.debug('%s failed with code %d' % (cmd, rc))
-    log.trace('%s: %s' % (cmd, output))
-    return rc, output
-
-
-def _new_bridge_name(bridges):
-    n = 0
-    while True:
-        brname = 'xenbr%d' % n
-        if brname not in bridges:
-            return brname
-        n += 1
+    def get_VLAN(self):
+        return self.VLAN
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendPIFMetrics.py
--- a/tools/python/xen/xend/XendPIFMetrics.py   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendPIFMetrics.py   Sat Apr 28 10:28:59 2007 +0100
@@ -15,15 +15,30 @@
 # Copyright (c) 2006-2007 Xensource Inc.
 #============================================================================
 
+from XendBase import XendBase
 
-class XendPIFMetrics:
+class XendPIFMetrics(XendBase):
     """PIF Metrics."""
+
+    def getClass(self):
+        return "PIF_metrics"
     
-    def __init__(self, uuid):
-        self.uuid = uuid
+    def getAttrRO(self):
+        attrRO =  ['io_read_kbs',
+                   'io_write_kbs',
+                   'last_updated',
+                   'pif']
+        return XendBase.getAttrRO() + attrRO
 
-    def set_PIF(self, pif):
-        self.pif = pif
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+
+    def __init__(self, uuid, pif_uuid):
+        XendBase.__init__(self, uuid, {})
+        self.pif_uuid = pif_uuid
+
+    def get_pif(self):
+        return self.pif_uuid
 
     def get_io_read_kbs(self):
         return self._get_stat(0)
@@ -33,19 +48,12 @@ class XendPIFMetrics:
 
     def _get_stat(self, n):
         from xen.xend.XendNode import instance as xennode
-        pifname = self.pif.device
-        pifs_util = xennode().monitor.get_pifs_util()
-        if pifname in pifs_util:
-            return pifs_util[pifname][n]
+        #pifname = self.pif.device
+        #pifs_util = xennode().monitor.get_pifs_util()
+        #if pifname in pifs_util:
+        #    return pifs_util[pifname][n]
         return 0.0
 
     def get_last_updated(self):
         import xen.xend.XendAPI as XendAPI
         return XendAPI.now()
-
-    def get_record(self):
-        return {'uuid'         : self.uuid,
-                'io_read_kbs'  : self.get_io_read_kbs(),
-                'io_write_kbs' : self.get_io_write_kbs(),
-                'last_updated' : self.get_last_updated(),
-                }
diff -r ee16cdeddade -r 1668299c0ea4 
tools/python/xen/xend/XendQCoWStorageRepo.py
--- a/tools/python/xen/xend/XendQCoWStorageRepo.py      Wed Apr 25 10:39:08 
2007 +0100
+++ b/tools/python/xen/xend/XendQCoWStorageRepo.py      Sat Apr 28 10:28:59 
2007 +0100
@@ -30,7 +30,7 @@ import struct
 
 from xen.util import mkdir
 import uuid
-import XendPBD
+from XendPBD import XendPBD
 from XendError import XendError
 from XendVDI import *
 from XendTask import XendTask
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendStateStore.py
--- a/tools/python/xen/xend/XendStateStore.py   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendStateStore.py   Sat Apr 28 10:28:59 2007 +0100
@@ -57,10 +57,12 @@ class XendStateStore:
 
     <hosts>
        <host uuid='49c01812-3c28-1ad4-a59d-2a3f81b13ec2'>
-           <name type='string'>norwich</name>
-           <description type='string'>Test Xen Host</description>
-           <cpu uuid='6fc2d1ed-7eb0-4c9d-8006-3657d5483ae0' />
-           <cpu uuid='669df3b8-62be-4e61-800b-bbe8ee63a760' />
+          <name type='string'>norwich</name>
+          <description type='string'>Test Xen Host</description>
+          <cpu type='dict'>
+             <item uuid='6fc2d1ed-7eb0-4c9d-8006-3657d5483ae0' />
+             <item uuid='669df3b8-62be-4e61-800b-bbe8ee63a760' />
+          </cpu>
        </host>
     </hosts>
 
@@ -121,18 +123,20 @@ class XendStateStore:
                 if val_elem.firstChild:
                     val_text = val_elem.firstChild.nodeValue.strip()
                 
-                if val_type == '' and val_uuid != '':
-                    # this is a reference
-                    if val_name not in cls_dict:
-                        cls_dict[val_name] = {}
-                    cls_dict[val_name][val_uuid] = None
-                elif val_type == '':
-                    # dictionary
-                    k = val_elem.getAttribute('key').encode('utf8')
-                    v = val_elem.getAttribute('value').encode('utf8')
-                    if val_name not in cls_dict:
-                        cls_dict[val_name] = {}
-                    cls_dict[val_name][k] = v
+                if val_type == 'list':
+                    cls_dict[val_name] = []
+                    for item in val_elem.childNodes:
+                        if item.nodeType != Node.ELEMENT_NODE:
+                            continue # skip non element nodes
+                        cls_dict[val_name].append(item.getAttribute('uuid'))
+                elif val_type == 'dict':
+                    cls_dict[val_name] = {}
+                    for item in val_elem.childNodes:
+                        if item.nodeType != Node.ELEMENT_NODE:
+                            continue # skip non element nodes
+                        k = item.getAttribute('key').encode('utf8')
+                        v = item.getAttribute('value').encode('utf8')
+                        cls_dict[val_name][k] = v
                 elif val_type == 'string':
                     cls_dict[val_name] = val_text.encode('utf8')
                 elif val_type == 'float':
@@ -158,8 +162,7 @@ class XendStateStore:
         @param state: a Xen API struct of the state of the class.
         @type  state: dict
         @rtype: None
-        """
-        
+        """        
         xml_path = self._xml_file(cls)
 
         doc = minidom.getDOMImplementation().createDocument(None,
@@ -191,7 +194,7 @@ class XendStateStore:
                     store_val = str(int(val))
                     store_type = 'bool'
 
-                if store_type != None:
+                if store_type is not None:
                     val_node = doc.createElement(key)
                     val_node.setAttribute('type', store_type)
                     node.appendChild(val_node)
@@ -202,19 +205,25 @@ class XendStateStore:
 
                 # deal with dicts and lists
                 if type(val) == dict:
-                    for val_uuid in val.keys():
-                        val_node = doc.createElement(key)
+                    val_node = doc.createElement(key)
+                    val_node.setAttribute('type', 'dict')
+                    for val_item in val.keys():
+                        tmp = doc.createElement("item")
                         if key in ['other_config', 'device_config']:
-                            val_node.setAttribute('key', str(val_uuid))
-                            val_node.setAttribute('value', str(val[val_uuid]))
+                            tmp.setAttribute('key', str(val_item))
+                            tmp.setAttribute('value', str(val[val_item]))
                         else:
-                            val_node.setAttribute('uuid', val_uuid)
-                        node.appendChild(val_node)
+                            tmp.setAttribute('uuid', val_uuid)
+                        val_node.appendChild(tmp)
+                    node.appendChild(val_node)
                 elif type(val) in (list, tuple):
+                    val_node = doc.createElement(key)
+                    val_node.setAttribute('type', 'list')
                     for val_uuid in val:
-                        val_node = doc.createElement(key)
-                        val_node.setAttribute('uuid', val_uuid)
-                        node.appendChild(val_node)
+                        tmp = doc.createElement("item")
+                        tmp.setAttribute('uuid', val_uuid)
+                        val_node.appendChild(tmp)
+                    node.appendChild(val_node)
 
         open(xml_path, 'w').write(doc.toprettyxml())
         
diff -r ee16cdeddade -r 1668299c0ea4 
tools/python/xen/xend/XendStorageRepository.py
--- a/tools/python/xen/xend/XendStorageRepository.py    Wed Apr 25 10:39:08 
2007 +0100
+++ b/tools/python/xen/xend/XendStorageRepository.py    Sat Apr 28 10:28:59 
2007 +0100
@@ -24,7 +24,7 @@ import sys
 
 from XendError import XendError
 from XendVDI import *
-import XendPBD
+from XendPBD import XendPBD
 
 XEND_STORAGE_NO_MAXIMUM = sys.maxint
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendVMMetrics.py
--- a/tools/python/xen/xend/XendVMMetrics.py    Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendVMMetrics.py    Sat Apr 28 10:28:59 2007 +0100
@@ -17,38 +17,36 @@
 #============================================================================
 
 from xen.xend.XendLogging import log
+from xen.xend.XendBase import XendBase
 import xen.lowlevel.xc
 
 xc = xen.lowlevel.xc.xc()
 
-instances = {}
-
-class XendVMMetrics:
+class XendVMMetrics(XendBase):
     """VM Metrics."""
 
-    def get_by_uuid(_, uuid):
-        return instances[uuid]
+    def getClass(self):
+        return "VM_metrics"
+    
+    def getAttrRO(self):
+        attrRO = ['memory_actual',
+                  'VCPUs_number',
+                  'VCPUs_utilisation',
+                  'VCPUs_CPU',
+                  'VCPUs_flags',
+                  'VCPUs_params',
+                  'state',
+                  'start_time',
+                  'last_updated']
+        return XendBase.getAttrRO() + attrRO
 
-    get_by_uuid = classmethod(get_by_uuid)
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
 
-    def is_valid_vm_metrics(_, uuid):
-        return uuid in instances
-
-    is_valid_vm_metrics = classmethod(is_valid_vm_metrics)
-
-    def get_all(_):
-        return instances.keys()
-
-    get_all = classmethod(get_all)
-   
     def __init__(self, uuid, xend_domain_instance):
-        self.uuid = uuid
+        XendBase.__init__(self, uuid, {})
         self.xend_domain_instance = xend_domain_instance
-        instances[uuid] = self
-
-    def get_uuid(self):
-        return self.uuid
-
+        
     def get_memory_actual(self):
         domInfo = self.xend_domain_instance.getDomInfo()
         if domInfo:
@@ -145,16 +143,3 @@ class XendVMMetrics:
     def get_last_updated(self):
         import xen.xend.XendAPI as XendAPI
         return XendAPI.now()
-    
-    def get_record(self):
-        return { 'uuid'              : self.uuid,
-                 'memory_actual'     : self.get_memory_actual(),
-                 'VCPUs_number'      : self.get_VCPUs_number(),
-                 'VCPUs_utilisation' : self.get_VCPUs_utilisation(),
-                 'VCPUs_CPU'         : self.get_VCPUs_CPU(),
-                 'VCPUs_flags'       : self.get_VCPUs_flags(),
-                 'VCPUs_params'      : self.get_VCPUs_params(),
-                 'start_time'        : self.get_start_time(),
-                 'state'             : self.get_state(),
-                 'last_updated'      : self.get_last_updated(),
-               }
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/server/SrvServer.py Sat Apr 28 10:28:59 2007 +0100
@@ -109,8 +109,6 @@ class XendServers:
         signal.signal(signal.SIGHUP, self.reloadConfig)
 
         while True:
-            XendNode.instance().refreshBridges()
-
             threads = []
             for server in self.servers:
                 if server.ready:
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xm/create.dtd
--- a/tools/python/xen/xm/create.dtd    Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xm/create.dtd    Sat Apr 28 10:28:59 2007 +0100
@@ -27,7 +27,8 @@
                             | crashdump )">
 
 <!ELEMENT xm (vm*, 
-              vdi*)> 
+              vdi*,
+              network*)> 
 
 <!ELEMENT version (#PCDATA)>
  
@@ -98,6 +99,12 @@
                  sharable        CDATA #REQUIRED
                  read_only       CDATA #REQUIRED>
 
+<!ELEMENT network (name,
+                  other_config*)>
+<!ATTLIST network %NAMEID;
+                  default_gateway CDATA #REQUIRED
+                  default_netmask CDATA #REQUIRED>
+
 <!ELEMENT name   (label, 
                   description)> 
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xm/create.py     Sat Apr 28 10:28:59 2007 +0100
@@ -777,8 +777,11 @@ def make_config(vals):
         config.append(['bootloader', vals.bootloader])
         if vals.bootargs:
             config.append(['bootloader_args', vals.bootargs])
-        else: 
-            config.append(['bootloader_args', '-q'])        
+        else:
+            if vals.console_autoconnect:
+                config.append(['bootloader_args', ''])
+            else:
+                config.append(['bootloader_args', '-q'])
     config.append(['image', config_image])
 
     config_devs = []
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xm/main.py       Sat Apr 28 10:28:59 2007 +0100
@@ -510,6 +510,10 @@ def xenapi_unsupported():
     if serverType == SERVER_XEN_API:
         raise XenAPIUnsupportedException, "This function is not supported by 
Xen-API"
 
+def xenapi_only():
+    if serverType != SERVER_XEN_API:
+        raise XenAPIUnsupportedException, "This function is only supported by 
Xen-API"
+
 def map2sxp(m):
     return [[k, m[k]] for k in m.keys()]
 
@@ -565,14 +569,14 @@ def get_single_vm(dom):
 
         try:
             domid = int(dom)
-            uuids = [server.xenapi.VM.get_domid(vm_ref)
-                     for vm_ref in server.xenapi.VM.get_all()
-                     if int(server.xenapi.VM.get_domid(vm_ref)) == domid]
+            refs = [vm_ref
+                    for vm_ref in server.xenapi.VM.get_all()
+                    if int(server.xenapi.VM.get_domid(vm_ref)) == domid]
         except:
             pass
             
-        if len(uuids) > 0:
-            return uuids[0]
+        if len(refs) > 0:
+            return refs[0]
 
         raise OptionError("Domain '%s' not found." % dom)
     else:
@@ -743,15 +747,15 @@ def getDomains(domain_names, state, full
         doms_dict = []
 
         dom_recs = server.xenapi.VM.get_all_records()
-        dom_metrics_recs = dict(map(lambda x: (x['uuid'], x), 
server.xenapi.VM_metrics.get_all_records()))
-
-        for dom_rec in dom_recs:
-            dom_metrics  = dom_metrics_recs[dom_rec['metrics']]
+        dom_metrics_recs = server.xenapi.VM_metrics.get_all_records()
+
+        for dom_ref, dom_rec in dom_recs.items():
+            dom_metrics_rec = dom_metrics_recs[dom_rec['metrics']]
 
             states = ('running', 'blocked', 'paused', 'shutdown',
                       'crashed', 'dying')
             def state_on_off(state):
-                if state in dom_metrics['state']:
+                if state in dom_metrics_rec['state']:
                     return state[0]
                 else:
                     return "-"
@@ -759,12 +763,12 @@ def getDomains(domain_names, state, full
                                  for state in states])
             
             dom_rec.update({'name':     dom_rec['name_label'],
-                            'memory_actual': 
int(dom_metrics['memory_actual'])/1024,
-                            'vcpus':    dom_metrics['VCPUs_number'],
+                            'memory_actual': 
int(dom_metrics_rec['memory_actual'])/1024,
+                            'vcpus':    dom_metrics_rec['VCPUs_number'],
                             'state':    state_str,
-                            'cpu_time': dom_metrics['VCPUs_utilisation'],
+                            'cpu_time': dom_metrics_rec['VCPUs_utilisation'],
                             'start_time': datetime_to_secs(
-                                              dom_metrics['start_time'])})
+                                              dom_metrics_rec['start_time'])})
 
             doms_sxp.append(['domain'] + map2sxp(dom_rec))
             doms_dict.append(dom_rec)
@@ -2070,8 +2074,14 @@ def xm_network_attach(args):
             record[keys[-1]] = val
 
         def get_net_from_bridge(bridge):
-            raise "Not supported just yet"
-         
+            # In OSS, we just assert network.name_label == bridge name
+            networks = dict([(record['name_label'], ref)
+                             for ref, record in server.xenapi.network
+                             .get_all_records().items()])
+            if bridge not in networks.keys():
+                raise "Unknown bridge name!"
+            return networks[bridge]
+
         vif_conv = {
             'type':
                 lambda x: None,
@@ -2102,7 +2112,6 @@ def xm_network_attach(args):
             else:
                 vif_conv[vif_param[0]](vif_param[1])
 
-        print str(vif_record)
         server.xenapi.VIF.create(vif_record)
     else:
         for a in args[1:]:
@@ -2222,6 +2231,87 @@ def xm_vnet_delete(args):
     vnet = args[0]
     server.xend_vnet_delete(vnet)
 
+def xm_network_new(args):
+    xenapi_only()
+    arg_check(args, "network-new", 1)
+    network = args[0]
+
+    record = {
+        "name_label":       network,
+        "name_description": "",
+        "other_config":     {},
+        "default_gateway":  "",
+        "default_netmask":  ""
+        }
+    
+    server.xenapi.network.create(record)
+    
+def xm_network_del(args):
+    xenapi_only()
+    arg_check(args, "network-del", 1)
+    network = args[0]
+
+    networks = dict([(record['name_label'], ref)
+                     for ref, record in
+                     server.xenapi.network.get_all_records().items()])
+
+    if network not in networks.keys():
+        raise ValueError("'%s' is not a valid network name" % network)
+    
+    server.xenapi.network.destroy(networks[network])
+
+def xm_network_show(args):
+    xenapi_only()
+    arg_check(args, "network-show", 0)
+
+    networks = server.xenapi.network.get_all_records()
+    pifs     = server.xenapi.PIF.get_all_records()
+    vifs     = server.xenapi.VIF.get_all_records()
+
+    print '%-20s %-40s %-10s' % \
+          ('Name', 'VIFs', 'PIFs')
+    
+    format2 = "%(name_label)-20s %(vif)-40s %(pif)-10s"
+
+    for network_ref, network in networks.items():
+        for i in range(max(len(network['PIFs']),
+                           len(network['VIFs']), 1)):
+            if i < len(network['PIFs']):
+                pif_uuid = network['PIFs'][i]
+            else:
+                pif_uuid = None
+                
+            if i < len(network['VIFs']):
+                vif_uuid = network['VIFs'][i]
+            else:
+                vif_uuid = None
+                
+            pif = pifs.get(pif_uuid, None) 
+            vif = vifs.get(vif_uuid, None)
+
+            if vif:
+                dom_name = server.xenapi.VM.get_name_label(vif['VM'])
+                vif = "%s.%s" % (dom_name, vif['device'])
+            else:
+                vif = '' 
+
+            if pif:
+                if int(pif['VLAN']) > -1:
+                    pif = '%s.%s' % (pif['device'], pif['VLAN'])
+                else:
+                    pif = pif['device']
+            else:
+                pif = ''
+
+            if i == 0:
+                r = {'name_label':network['name_label'],
+                     'vif':vif, 'pif':pif}
+            else:
+                r = {'name_label':'', 'vif':vif, 'pif':pif}
+
+            print format2 % r
+
+            
 commands = {
     "shell": xm_shell,
     "event-monitor": xm_event_monitor,
@@ -2271,10 +2361,14 @@ commands = {
     "block-detach": xm_block_detach,
     "block-list": xm_block_list,
     "block-configure": xm_block_configure,
-    # network
+    # network (AKA vifs)
     "network-attach": xm_network_attach,
     "network-detach": xm_network_detach,
     "network-list": xm_network_list,
+    # network (as in XenAPI)
+    "network-new": xm_network_new,
+    "network-del": xm_network_del,
+    "network-show": xm_network_show,
     # vnet
     "vnet-list": xm_vnet_list,
     "vnet-create": xm_vnet_create,
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xm/messages/en/xen-xm.po
--- a/tools/python/xen/xm/messages/en/xen-xm.po Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xm/messages/en/xen-xm.po Sat Apr 28 10:28:59 2007 +0100
@@ -67,3 +67,27 @@ msgstr "HVM guest support is unavailable
 
 msgid "SESSION_NOT_REGISTERED"
 msgstr "This session is not registered to receive events.  You must call 
event.register before event.next.  (Session handle is %(1)s.)"
+
+msgid "CREATE_UNSPECIFIED_ATTRIBUTE"
+msgstr "You need to specify %s when creating a new %s"
+ 
+msgid "UNMANAGED_NETWORK_ERROR"
+msgstr "Cannot change %s on an unmanaged network"
+ 
+msgid "UNIQUE_NAME_ERROR"
+msgstr "Name %s for class %s is not unique"
+
+msgid "INVALID_DEVICE_ERROR"
+msgstr "Invalid device %s"
+
+msgid "DEVICE_EXISTS_ERROR"
+msgstr "Device already exists %s"
+
+msgid "IMPLEMENTATION_ERROR"
+msgstr "Class %s does not implement %s"
+
+msgid "VLAN_TAG_INVALID"
+msgstr "VLAN tag invalid %s"
+
+msgid "NETWORK_ERROR"
+msgstr "Network Error: %s - %s"
\ No newline at end of file
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py      Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xm/xenapi_create.py      Sat Apr 28 10:28:59 2007 +0100
@@ -93,10 +93,13 @@ class xenapi_create:
 
         vdis = document.getElementsByTagName("vdi")
         vdi_refs_dict = self.create_vdis(vdis)
+
+        networks = document.getElementsByTagName("network")
+        network_refs_dict = self.create_networks(networks)
         
         try:    
             vms = document.getElementsByTagName("vm")
-            return self.create_vms(vms, vdi_refs_dict)
+            return self.create_vms(vms, vdi_refs_dict, network_refs_dict)
         except Exception, exn:
             try_quietly(self.cleanup_vdis(vdi_refs_dict))
             raise exn
@@ -223,11 +226,33 @@ class xenapi_create:
         
         return (key, value)
 
-    def create_vms(self, vms, vdis):
+    def create_networks(self, networks):
+        log(DEBUG, "create_networks")
+        return dict(map(self.create_network, networks))
+
+    def create_network(self, network):
+        log(DEBUG, "create_network")
+
+        network_record = {
+            "name_label":       get_name_label(network),
+            "name_description": get_name_description(network),
+            "other_config":
+                get_child_nodes_as_dict(network, "other_config",
+                                        "key", "value"),
+            "default_netmask":  network.attributes["default_netmask"].value,
+            "default_gateway":  network.attributes["default_gateway"].value
+            }
+
+        key = network.attributes["name"].value
+        value = server.xenapi.network.create(network_record)
+
+        return (key, value)
+        
+    def create_vms(self, vms, vdis, networks):
         log(DEBUG, "create_vms")
-        return map(lambda vm: self.create_vm(vm, vdis), vms)
-
-    def create_vm(self, vm, vdis):
+        return map(lambda vm: self.create_vm(vm, vdis, networks), vms)
+
+    def create_vm(self, vm, vdis, networks):
         log(DEBUG, "create_vm")
 
         vm_record = {
@@ -321,7 +346,7 @@ class xenapi_create:
 
             vifs = vm.getElementsByTagName("vif")
 
-            self.create_vifs(vm_ref, vifs)
+            self.create_vifs(vm_ref, vifs, networks)
 
             # Now create consoles
 
@@ -363,31 +388,35 @@ class xenapi_create:
 
         return server.xenapi.VBD.create(vbd_record)
 
-    def create_vifs(self, vm_ref, vifs):
+    def create_vifs(self, vm_ref, vifs, networks):
         log(DEBUG, "create_vifs")
-        return map(lambda vif: self.create_vif(vm_ref, vif), vifs)
-
-    def create_vif(self, vm_ref, vif):
+        return map(lambda vif: self.create_vif(vm_ref, vif, networks), vifs)
+
+    def create_vif(self, vm_ref, vif, networks):
         log(DEBUG, "create_vif")
 
-        if "network" in vif.attributes.keys():
-            networks = [network_ref
-                for network_ref in server.xenapi.network.get_all()
-                if server.xenapi.network.get_name_label(network_ref)
-                       == vif.attributes["network"].value]
-            if len(networks) > 0:
-                network = networks[0]
+        if 'network' in vif.attributes.keys():
+            network_name = vif.attributes['network'].value
+
+            if network_name in networks.keys():
+                network_uuid = networks[network_name]
             else:
-                raise OptionError("Network %s doesn't exist"
+                networks = dict([(record['name_label'], record['uuid'])
+                                 for record in
+                                 server.xenapi.network.get_all_records()])
+                if network_name in networks.keys():
+                    network_uuid = networks[network_name]
+                else:
+                    raise OptionError("Network %s doesn't exist"
                                   % vif.attributes["network"].value)
         else:
-            network = self._get_network_ref()
+            network_uuid = self._get_network_ref()
 
         vif_record = {
             "device":
                 vif.attributes["device"].value,
             "network":
-                network,
+                network_uuid,
             "VM":
                 vm_ref,
             "MAC":
diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnet-module/00README
--- a/tools/vnet/vnet-module/00README   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/vnet/vnet-module/00README   Sat Apr 28 10:28:59 2007 +0100
@@ -9,8 +9,8 @@ LINUX_SERIES:   linux release to compile
 LINUX_SERIES:   linux release to compile for: 2.4, or 2.6 (default).
 XEN_ROOT:       root of the xen tree containing kernel source.
 KERNEL_VERSION: kernel version, default got from XEN_ROOT.
-KERNEL_MINOR:   kernel minor version, default -xen0.
-KERNEL_SRC:     path to kernel source, default linux-<VERSION> under XEN_ROOT.
+KERNEL_SRC:     path to kernel source, default build-linux-<VERSION> 
+                under XEN_ROOT.
 
 *) For 2.4 kernel
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnet-module/Makefile.ver
--- a/tools/vnet/vnet-module/Makefile.ver       Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/vnet/vnet-module/Makefile.ver       Sat Apr 28 10:28:59 2007 +0100
@@ -19,7 +19,6 @@
 #============================================================================
 
 LINUX_SERIES?=2.6
-KERNEL_MINOR=-xen
 
 LINUX_VERSION?=$(shell (/bin/ls -d 
$(XEN_ROOT)/pristine-linux-$(LINUX_SERIES).* 2>/dev/null) | \
                       sed -e 's!^.*linux-\(.\+\)!\1!' )
@@ -28,22 +27,25 @@ ifeq ($(LINUX_VERSION),)
 $(error Kernel source for linux $(LINUX_SERIES) not found)
 endif
 
-KERNEL_VERSION=$(LINUX_VERSION)$(KERNEL_MINOR)
+KERNEL_VERSION?=$(shell (/bin/ls -d 
$(XEN_ROOT)/build-linux-$(LINUX_VERSION)-xen* 2>/dev/null) | \
+                      grep -v -m 1 -e '-xenU' | \
+                      sed -e 's!^.*linux-\(.\+\)!\1!' )
 
-KERNEL_SRC?=$(shell cd $(XEN_ROOT)/linux-$(KERNEL_VERSION) && pwd)
+KERNEL_SRC ?= $(XEN_ROOT)/build-linux-$(KERNEL_VERSION)
 
 ifeq ($(KERNEL_SRC),)
 $(error Kernel source for kernel $(KERNEL_VERSION) not found)
 endif
 
 # Get the full kernel release version from its makefile, as the source path
-# may not have the extraversion, e.g. linux-2.6.12-xen0 may contain release 
2.6.12.6-xen0.
+# may not have the extraversion, e.g. linux-2.6.12-xen0 may contain release 
+# 2.6.12.6-xen0.
 KERNEL_RELEASE=$(shell make -s -C $(KERNEL_SRC) kernelrelease)
 
-KERNEL_MODULE_DIR=/lib/modules/$$(KERNEL_RELEASE)/kernel
+KERNEL_MODULE_DIR=/lib/modules/$(KERNEL_RELEASE)/kernel
 
 $(warning KERNEL_SRC           $(KERNEL_SRC))
 $(warning LINUX_VERSION                $(LINUX_VERSION))
 $(warning KERNEL_VERSION       $(KERNEL_VERSION))
 $(warning KERNEL_RELEASE       $(KERNEL_RELEASE))
-$(warning KERNEL_ MODULE_DIR   $(KERNEL_MODULE_DIR))
+$(warning KERNEL_MODULE_DIR    $(KERNEL_MODULE_DIR))
diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnet-module/varp.c
--- a/tools/vnet/vnet-module/varp.c     Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/vnet/vnet-module/varp.c     Sat Apr 28 10:28:59 2007 +0100
@@ -1530,12 +1530,7 @@ void varp_exit(void){
     dprintf("<\n");
 }
 
-#ifdef MODULE_PARM
-MODULE_PARM(varp_mcaddr, "s");
-MODULE_PARM(varp_device, "s");
-#else
 module_param(varp_mcaddr, charp, 0644);
 module_param(varp_device, charp, 0644);
-#endif
 MODULE_PARM_DESC(varp_mcaddr, "VARP multicast address");
 MODULE_PARM_DESC(varp_device, "VARP network device");
diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnet-module/vnet.c
--- a/tools/vnet/vnet-module/vnet.c     Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/vnet/vnet-module/vnet.c     Sat Apr 28 10:28:59 2007 +0100
@@ -693,12 +693,7 @@ module_exit(vnet_module_exit);
 module_exit(vnet_module_exit);
 MODULE_LICENSE("GPL");
 
-#ifdef MODULE_PARM
-MODULE_PARM(vnet_encaps, "s");
-#else
 module_param(vnet_encaps, charp, 0644);
+MODULE_PARM_DESC(vnet_encaps, "Vnet encapsulation: etherip or udp.");
+
 #endif
-
-MODULE_PARM_DESC(vnet_encaps, "Vnet encapsulation: etherip or udp.");
-
-#endif
diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnetd/Makefile
--- a/tools/vnet/vnetd/Makefile Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/vnet/vnetd/Makefile Sat Apr 28 10:28:59 2007 +0100
@@ -16,7 +16,7 @@
 # Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #----------------------------------------------------------------------------
 
-VNET_ROOT = $(shell cd .. && pwd)
+VNET_ROOT ?= $(shell cd .. && pwd)
 include $(VNET_ROOT)/Make.env
 
 .PHONY: all
@@ -26,6 +26,8 @@ all: vnetd
 
 # Comment out when outside xen.
 #include $(XEN_ROOT)/tools/Rules.mk
+
+INSTALL_PROG ?= $(INSTALL) -m0755 -p
 
 VNETD_INSTALL_DIR = /usr/sbin
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnetd/sys_kernel.h
--- a/tools/vnet/vnetd/sys_kernel.h     Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/vnet/vnetd/sys_kernel.h     Sat Apr 28 10:28:59 2007 +0100
@@ -45,6 +45,7 @@
 #define module_exit(x)
 #define MODULE_LICENSE(x)
 #define MODULE_PARM(v, t)
+#define module_param(v, t, s)
 #define MODULE_PARM_DESC(v, s)
 
 enum {
diff -r ee16cdeddade -r 1668299c0ea4 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/xenstore/xenstored_core.c   Sat Apr 28 10:28:59 2007 +0100
@@ -1336,7 +1336,7 @@ static void handle_input(struct connecti
 
        bytes = conn->read(conn, in->buffer + in->used,
                           in->hdr.msg.len - in->used);
-       if (bytes < 0)
+       if (bytes <= 0)
                goto bad_client;
 
        in->used += bytes;
diff -r ee16cdeddade -r 1668299c0ea4 
tools/xm-test/lib/XmTestLib/network_utils.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/lib/XmTestLib/network_utils.py      Sat Apr 28 10:28:59 
2007 +0100
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Murillo F. Bernardes <mfb@xxxxxxxxxx>
+
+from XmTestLib import *
+
+def count_eth(console):
+    try:
+        run = console.runCmd("ifconfig -a | grep eth")
+    except ConsoleError, e:
+        FAIL(str(e))
+    return len(run['output'].splitlines())
+
+def get_state(domain_name, number):
+    s, o = traceCommand("xm network-list %s | awk '/^%d/ {print $5}'" %
+                        (domain_name, number))
+    print o
+    
+    if s != 0:
+        FAIL("network-list failed")
+    if o == "":
+        return 0
+    else:
+        return int(o)
+
+def network_attach(domain_name, console, bridge=None):
+    eths_before = count_eth(console)
+    if bridge:
+        status, output = traceCommand("xm network-attach %s bridge=%s"
+                                      % (domain_name, bridge))
+    else:
+        status, output = traceCommand("xm network-attach %s" % domain_name)
+    if status != 0:
+        return -1, "xm network-attach returned invalid %i != 0" % status
+
+    eths_after = count_eth(console)
+    if (eths_after != (eths_before+1)):
+        return -2, "Network device is not actually connected to domU"
+
+    return 0, None 
+
+def network_detach(domain_name, console, num=0):
+    eths_before = count_eth(console)
+    status, output = traceCommand("xm network-detach %s %d" % (domain_name, 
num))
+    if status != 0:
+        return -1, "xm network-detach returned invalid %i != 0" % status
+
+    for i in range(10):
+        if get_state(domain_name, num) == 0:
+            break
+        time.sleep(1)
+    else:
+        FAIL("network-detach failed: device did not disappear")
+
+    eths_after = count_eth(console)
+    if eths_after != (eths_before-1):
+        return -2, "Network device was not actually disconnected from domU"
+
+    return 0, None
diff -r ee16cdeddade -r 1668299c0ea4 
tools/xm-test/tests/network-attach/01_network_attach_pos.py
--- a/tools/xm-test/tests/network-attach/01_network_attach_pos.py       Wed Apr 
25 10:39:08 2007 +0100
+++ b/tools/xm-test/tests/network-attach/01_network_attach_pos.py       Sat Apr 
28 10:28:59 2007 +0100
@@ -6,7 +6,7 @@ import sys
 import sys
 
 from XmTestLib import *
-from network_utils import *
+from XmTestLib.network_utils import *
 
 if ENABLE_HVM_SUPPORT:
     SKIP("Network-attach not supported for HVM domains")
diff -r ee16cdeddade -r 1668299c0ea4 
tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py
--- a/tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py        
Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py        
Sat Apr 28 10:28:59 2007 +0100
@@ -8,7 +8,7 @@ import time
 import time
 
 from XmTestLib import *
-from network_utils import *
+from XmTestLib.network_utils import *
 
 if ENABLE_HVM_SUPPORT:
     SKIP("Network-attach not supported for HVM domains")
diff -r ee16cdeddade -r 1668299c0ea4 
tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py
--- 
a/tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py   
    Wed Apr 25 10:39:08 2007 +0100
+++ 
b/tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py   
    Sat Apr 28 10:28:59 2007 +0100
@@ -8,7 +8,7 @@ import time
 import time
 
 from XmTestLib import *
-from network_utils import *
+from XmTestLib.network_utils import *
 
 if ENABLE_HVM_SUPPORT:
     SKIP("Network-attach not supported for HVM domains")
diff -r ee16cdeddade -r 1668299c0ea4 
tools/xm-test/tests/network-attach/network_utils.py
--- a/tools/xm-test/tests/network-attach/network_utils.py       Wed Apr 25 
10:39:08 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (C) International Business Machines Corp., 2005
-# Author: Murillo F. Bernardes <mfb@xxxxxxxxxx>
-
-from XmTestLib import *
-
-def count_eth(console):
-    try:
-        run = console.runCmd("ifconfig -a | grep eth")
-    except ConsoleError, e:
-        FAIL(str(e))
-    return len(run['output'].splitlines())
-
-def get_state(domain_name, number):
-    s, o = traceCommand("xm network-list %s | awk '/^%d/ {print $5}'" %
-                        (domain_name, number))
-    print o
-    
-    if s != 0:
-        FAIL("network-list failed")
-    if o == "":
-        return 0
-    else:
-        return int(o)
-
-def network_attach(domain_name, console):
-    eths_before = count_eth(console)
-    status, output = traceCommand("xm network-attach %s" % domain_name)
-    if status != 0:
-        return -1, "xm network-attach returned invalid %i != 0" % status
-
-    eths_after = count_eth(console)
-    if (eths_after != (eths_before+1)):
-        return -2, "Network device is not actually connected to domU"
-
-    return 0, None 
-
-def network_detach(domain_name, console, num=0):
-    eths_before = count_eth(console)
-    status, output = traceCommand("xm network-detach %s %d" % (domain_name, 
num))
-    if status != 0:
-        return -1, "xm network-detach returned invalid %i != 0" % status
-
-    for i in range(10):
-        if get_state(domain_name, num) == 0:
-            break
-        time.sleep(1)
-    else:
-        FAIL("network-detach failed: device did not disappear")
-
-    eths_after = count_eth(console)
-    if eths_after != (eths_before-1):
-        return -2, "Network device was not actually disconnected from domU"
-
-    return 0, None
diff -r ee16cdeddade -r 1668299c0ea4 
tools/xm-test/tests/xapi/03_xapi-network_pos.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/xapi/03_xapi-network_pos.py   Sat Apr 28 10:28:59 
2007 +0100
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+
+# Try and create two VMs and a private network betwene the two
+
+import sys
+
+from XmTestLib import *
+from XmTestLib.network_utils import *
+
+# Create two domains (default XmTestDomain, with our ramdisk)
+try:
+    domain1 = XmTestDomain()
+    console1 = domain1.start()
+    domain2 = XmTestDomain()
+    console2 = domain2.start()
+except DomainError, e:
+    if verbose:
+        print "Failed to create test domain because:"
+        print e.extra
+    FAIL(str(e))
+
+# Create a network
+
+status, ouptut = traceCommand("xm network-new xapi-network")
+if status:
+    FAIL(output)
+
+# Attach two domains to it
+status, msg = network_attach(domain1.getName(),
+                             console1, bridge='xapi-network')
+if status:
+    FAIL(msg)
+
+status, msg = network_attach(domain2.getName(),
+                             console2, bridge='xapi-network')
+if status:
+    FAIL(msg)
+
+# Configure IP addresses on two domains
+try:
+    # Run 'ls'
+    run = console1.runCmd("ifconfig eth0 192.168.0.1 netmask 255.255.255.0 up")
+    run = console2.runCmd("ifconfig eth0 192.168.0.2 netmask 255.255.255.0 up")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    FAIL(str(e))
+
+# Now ping...
+try:
+    run = console1.runCmd("ping -c 4 192.168.0.2")
+    if run['return'] > 0:
+        FAIL("Could not ping other host")
+    run = console2.runCmd("ping -c 4 192.168.0.1")
+    if run['return'] > 0:
+        FAIL("Could not pint other host")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    FAIL(str(e))
+
+status, msg = network_detach(domain1.getName(), console1)
+status, msg = network_detach(domain2.getName(), console2)
+
+# Clean up
+domain1.closeConsole()
+domain1.stop()
+domain2.closeConsole()
+domain2.stop()
+
+status, ouptut = traceCommand("xm network-del xapi-network")
+if status:
+    FAIL(output)
diff -r ee16cdeddade -r 1668299c0ea4 tools/xm-test/tests/xapi/Makefile.am
--- a/tools/xm-test/tests/xapi/Makefile.am      Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/xm-test/tests/xapi/Makefile.am      Sat Apr 28 10:28:59 2007 +0100
@@ -1,7 +1,8 @@ SUBDIRS =
 SUBDIRS =
 
 TESTS = 01_xapi-vm_basic.test \
-       02_xapi-vbd_basic.test
+       02_xapi-vbd_basic.test \
+       03_xapi-network_pos.test
 
 XFAIL_TESTS =
 
diff -r ee16cdeddade -r 1668299c0ea4 xen/Makefile
--- a/xen/Makefile      Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/Makefile      Sat Apr 28 10:28:59 2007 +0100
@@ -2,7 +2,7 @@
 # All other places this is stored (eg. compile.h) should be autogenerated.
 export XEN_VERSION       = 3
 export XEN_SUBVERSION    = 0
-export XEN_EXTRAVERSION ?= .5-rc3$(XEN_VENDORVERSION)
+export XEN_EXTRAVERSION ?= .5-rc4$(XEN_VENDORVERSION)
 export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
 -include xen-version
 
diff -r ee16cdeddade -r 1668299c0ea4 xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c      Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/acm/acm_policy.c      Sat Apr 28 10:28:59 2007 +0100
@@ -46,7 +46,7 @@ static ssidref_t oldssid_to_newssid(cons
 
 
 int
-acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size)
+acm_set_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size)
 {
     u8 *policy_buffer = NULL;
     int ret = -EFAULT;
@@ -213,7 +213,7 @@ do_acm_set_policy(void *buf, u32 buf_siz
 }
 
 int
-acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size)
+acm_get_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size)
 { 
     u8 *policy_buffer;
     int ret;
@@ -278,7 +278,7 @@ acm_get_policy(XEN_GUEST_HANDLE(void) bu
 }
 
 int
-acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size)
+acm_dump_statistics(XEN_GUEST_HANDLE_64(void) buf, u16 buf_size)
 { 
     /* send stats to user space */
     u8 *stats_buffer;
@@ -324,7 +324,7 @@ acm_dump_statistics(XEN_GUEST_HANDLE(voi
 
 
 int
-acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size)
+acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE_64(void) buf, u16 buf_size)
 {
     /* send stats to user space */
     u8 *ssid_buffer;
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/domain.c     Sat Apr 28 10:28:59 2007 +0100
@@ -237,7 +237,8 @@ static int setup_compat_l4(struct vcpu *
     l4tab[l4_table_offset(LINEAR_PT_VIRT_START)] =
         l4e_from_page(pg, __PAGE_HYPERVISOR);
     l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] =
-        l4e_from_paddr(__pa(v->domain->arch.mm_perdomain_l3), 
__PAGE_HYPERVISOR);
+        l4e_from_paddr(__pa(v->domain->arch.mm_perdomain_l3),
+                       __PAGE_HYPERVISOR);
     v->arch.guest_table = pagetable_from_page(pg);
     v->arch.guest_table_user = v->arch.guest_table;
 
@@ -259,7 +260,7 @@ static void release_compat_l4(struct vcp
 
 static inline int may_switch_mode(struct domain *d)
 {
-    return (d->tot_pages == 0);
+    return (!is_hvm_domain(d) && (d->tot_pages == 0));
 }
 
 int switch_native(struct domain *d)
@@ -271,10 +272,10 @@ int switch_native(struct domain *d)
         return -EINVAL;
     if ( !may_switch_mode(d) )
         return -EACCES;
-    if ( !IS_COMPAT(d) )
+    if ( !is_pv_32on64_domain(d) )
         return 0;
 
-    d->is_compat = 0;
+    d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 0;
     release_arg_xlat_area(d);
 
     /* switch gdt */
@@ -303,10 +304,10 @@ int switch_compat(struct domain *d)
         return -ENOSYS;
     if ( !may_switch_mode(d) )
         return -EACCES;
-    if ( IS_COMPAT(d) )
+    if ( is_pv_32on64_domain(d) )
         return 0;
 
-    d->is_compat = 1;
+    d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 1;
 
     /* switch gdt */
     gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR);
@@ -371,15 +372,12 @@ int vcpu_initialise(struct vcpu *v)
     v->arch.perdomain_ptes =
         d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT);
 
-    if ( IS_COMPAT(d) && (rc = setup_compat_l4(v)) != 0 )
-        return rc;
-
-    return 0;
+    return (is_pv_32on64_vcpu(v) ? setup_compat_l4(v) : 0);
 }
 
 void vcpu_destroy(struct vcpu *v)
 {
-    if ( IS_COMPAT(v->domain) )
+    if ( is_pv_32on64_vcpu(v) )
         release_compat_l4(v);
 }
 
@@ -455,7 +453,20 @@ int arch_domain_create(struct domain *d)
             virt_to_page(d->shared_info), d, XENSHARE_writable);
     }
 
-    return is_hvm_domain(d) ? hvm_domain_initialise(d) : 0;
+    if ( is_hvm_domain(d) )
+    {
+        if ( (rc = hvm_domain_initialise(d)) != 0 )
+            goto fail;
+    }
+    else
+    {
+        /* 32-bit PV guest by default only if Xen is not 64-bit. */
+        d->arch.is_32bit_pv = d->arch.has_32bit_shinfo =
+            (CONFIG_PAGING_LEVELS != 4);
+    }
+        
+
+    return 0;
 
  fail:
     free_xenheap_page(d->shared_info);
@@ -491,7 +502,7 @@ void arch_domain_destroy(struct domain *
     free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3));
 #endif
 
-    if ( IS_COMPAT(d) )
+    if ( is_pv_32on64_domain(d) )
         release_arg_xlat_area(d);
 
     free_xenheap_page(d->shared_info);
@@ -508,7 +519,7 @@ int arch_set_info_guest(
 
     /* The context is a compat-mode one if the target domain is compat-mode;
      * we expect the tools to DTRT even in compat-mode callers. */
-    compat = IS_COMPAT(d);
+    compat = is_pv_32on64_domain(d);
 
 #ifdef CONFIG_COMPAT
 #define c(fld) (compat ? (c.cmp->fld) : (c.nat->fld))
@@ -833,7 +844,7 @@ static void load_segments(struct vcpu *n
             all_segs_okay &= loadsegment(gs, nctxt->user_regs.gs);
     }
 
-    if ( !IS_COMPAT(n->domain) )
+    if ( !is_pv_32on64_domain(n->domain) )
     {
         /* This can only be non-zero if selector is NULL. */
         if ( nctxt->fs_base )
@@ -867,7 +878,7 @@ static void load_segments(struct vcpu *n
             (unsigned long *)nctxt->kernel_sp;
         unsigned long cs_and_mask, rflags;
 
-        if ( IS_COMPAT(n->domain) )
+        if ( is_pv_32on64_domain(n->domain) )
         {
             unsigned int *esp = ring_1(regs) ?
                                 (unsigned int *)regs->rsp :
@@ -977,7 +988,7 @@ static void save_segments(struct vcpu *v
     if ( regs->es )
         dirty_segment_mask |= DIRTY_ES;
 
-    if ( regs->fs || IS_COMPAT(v->domain) )
+    if ( regs->fs || is_pv_32on64_domain(v->domain) )
     {
         dirty_segment_mask |= DIRTY_FS;
         ctxt->fs_base = 0; /* != 0 selector kills fs_base */
@@ -987,7 +998,7 @@ static void save_segments(struct vcpu *v
         dirty_segment_mask |= DIRTY_FS_BASE;
     }
 
-    if ( regs->gs || IS_COMPAT(v->domain) )
+    if ( regs->gs || is_pv_32on64_domain(v->domain) )
     {
         dirty_segment_mask |= DIRTY_GS;
         ctxt->gs_base_user = 0; /* != 0 selector kills gs_base_user */
@@ -1123,15 +1134,17 @@ void context_switch(struct vcpu *prev, s
         __context_switch();
 
 #ifdef CONFIG_COMPAT
-        if ( is_idle_vcpu(prev)
-             || IS_COMPAT(prev->domain) != IS_COMPAT(next->domain) )
+        if ( is_idle_vcpu(prev) ||
+             (is_pv_32on64_domain(prev->domain) !=
+              is_pv_32on64_domain(next->domain)) )
         {
             uint32_t efer_lo, efer_hi;
 
-            local_flush_tlb_one(GDT_VIRT_START(next) + 
FIRST_RESERVED_GDT_BYTE);
+            local_flush_tlb_one(GDT_VIRT_START(next) +
+                                FIRST_RESERVED_GDT_BYTE);
 
             rdmsr(MSR_EFER, efer_lo, efer_hi);
-            if ( !IS_COMPAT(next->domain) == !(efer_lo & EFER_SCE) )
+            if ( !is_pv_32on64_domain(next->domain) == !(efer_lo & EFER_SCE) )
             {
                 efer_lo ^= EFER_SCE;
                 wrmsr(MSR_EFER, efer_lo, efer_hi);
@@ -1154,7 +1167,7 @@ void context_switch(struct vcpu *prev, s
     /* Update per-VCPU guest runstate shared memory area (if registered). */
     if ( !guest_handle_is_null(runstate_guest(next)) )
     {
-        if ( !IS_COMPAT(next->domain) )
+        if ( !is_pv_32on64_domain(next->domain) )
             __copy_to_guest(runstate_guest(next), &next->runstate, 1);
 #ifdef CONFIG_COMPAT
         else
@@ -1236,7 +1249,7 @@ unsigned long hypercall_create_continuat
 
         for ( i = 0; *p != '\0'; i++ )
             mcs->call.args[i] = next_arg(p, args);
-        if ( IS_COMPAT(current->domain) )
+        if ( is_pv_32on64_domain(current->domain) )
         {
             for ( ; i < 6; i++ )
                 mcs->call.args[i] = 0;
@@ -1249,7 +1262,7 @@ unsigned long hypercall_create_continuat
         regs->eip -= 2;  /* re-execute 'syscall' / 'int 0x82' */
 
 #ifdef __x86_64__
-        if ( !IS_COMPAT(current->domain) )
+        if ( !is_pv_32on64_domain(current->domain) )
         {
             for ( i = 0; *p != '\0'; i++ )
             {
@@ -1268,7 +1281,7 @@ unsigned long hypercall_create_continuat
         else
 #endif
         {
-            if ( supervisor_mode_kernel || is_hvm_vcpu(current) )
+            if ( supervisor_mode_kernel )
                 regs->eip &= ~31; /* re-execute entire hypercall entry stub */
 
             for ( i = 0; *p != '\0'; i++ )
@@ -1449,14 +1462,11 @@ static void vcpu_destroy_pagetables(stru
     struct domain *d = v->domain;
     unsigned long pfn;
 
-#ifdef CONFIG_COMPAT
-    if ( IS_COMPAT(d) )
-    {
-        if ( is_hvm_vcpu(v) )
-            pfn = pagetable_get_pfn(v->arch.guest_table);
-        else
-            pfn = l4e_get_pfn(*(l4_pgentry_t *)
-                              __va(pagetable_get_paddr(v->arch.guest_table)));
+#ifdef __x86_64__
+    if ( is_pv_32on64_vcpu(v) )
+    {
+        pfn = l4e_get_pfn(*(l4_pgentry_t *)
+                          __va(pagetable_get_paddr(v->arch.guest_table)));
 
         if ( pfn != 0 )
         {
@@ -1466,12 +1476,9 @@ static void vcpu_destroy_pagetables(stru
                 put_page_and_type(mfn_to_page(pfn));
         }
 
-        if ( is_hvm_vcpu(v) )
-            v->arch.guest_table = pagetable_null();
-        else
-            l4e_write(
-                (l4_pgentry_t *) 
__va(pagetable_get_paddr(v->arch.guest_table)),
-                l4e_empty());
+        l4e_write(
+            (l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)),
+            l4e_empty());
 
         v->arch.cr3 = 0;
         return;
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/domain_build.c       Sat Apr 28 10:28:59 2007 +0100
@@ -320,11 +320,11 @@ int construct_dom0(struct domain *d,
     }
 
 #ifdef CONFIG_COMPAT
-    if (compat32)
+    if ( compat32 )
     {
         l1_pgentry_t gdt_l1e;
 
-        d->is_compat = 1;
+        d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 1;
         v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0];
 
         if ( nr_pages != (unsigned int)nr_pages )
@@ -350,19 +350,19 @@ int construct_dom0(struct domain *d,
 #if CONFIG_PAGING_LEVELS < 4
         unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1;
 #else
-        unsigned long mask = !IS_COMPAT(d)
-                             ? (1UL << L4_PAGETABLE_SHIFT) - 1
-                             : (1UL << L2_PAGETABLE_SHIFT) - 1;
+        unsigned long mask = is_pv_32bit_domain(d)
+                             ? (1UL << L2_PAGETABLE_SHIFT) - 1
+                             : (1UL << L4_PAGETABLE_SHIFT) - 1;
 #endif
 
         value = (parms.virt_hv_start_low + mask) & ~mask;
 #ifdef CONFIG_COMPAT
         HYPERVISOR_COMPAT_VIRT_START(d) =
             max_t(unsigned int, m2p_compat_vstart, value);
-        d->arch.physaddr_bitsize = !IS_COMPAT(d) ? 64 :
+        d->arch.physaddr_bitsize = !is_pv_32on64_domain(d) ? 64 :
             fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 1
             + (PAGE_SIZE - 2);
-        if ( value > (!IS_COMPAT(d) ?
+        if ( value > (!is_pv_32on64_domain(d) ?
                       HYPERVISOR_VIRT_START :
                       __HYPERVISOR_COMPAT_VIRT_START) )
 #else
@@ -387,7 +387,7 @@ int construct_dom0(struct domain *d,
     vinitrd_start    = round_pgup(vkern_end);
     vinitrd_end      = vinitrd_start + initrd_len;
     vphysmap_start   = round_pgup(vinitrd_end);
-    vphysmap_end     = vphysmap_start + (nr_pages * (!IS_COMPAT(d) ?
+    vphysmap_end     = vphysmap_start + (nr_pages * (!is_pv_32on64_domain(d) ?
                                                      sizeof(unsigned long) :
                                                      sizeof(unsigned int)));
     vstartinfo_start = round_pgup(vphysmap_end);
@@ -418,7 +418,7 @@ int construct_dom0(struct domain *d,
        ((_l) & ~((1UL<<(_s))-1))) >> (_s))
         if ( (1 + /* # L4 */
               NR(v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
-              (!IS_COMPAT(d) ?
+              (!is_pv_32on64_domain(d) ?
                NR(v_start, v_end, L3_PAGETABLE_SHIFT) : /* # L2 */
                4) + /* # compat L2 */
               NR(v_start, v_end, L2_PAGETABLE_SHIFT))  /* # L1 */
@@ -613,7 +613,7 @@ int construct_dom0(struct domain *d,
 #elif defined(__x86_64__)
 
     /* Overlap with Xen protected area? */
-    if ( !IS_COMPAT(d) ?
+    if ( !is_pv_32on64_domain(d) ?
          ((v_start < HYPERVISOR_VIRT_END) &&
           (v_end > HYPERVISOR_VIRT_START)) :
          (v_end > HYPERVISOR_COMPAT_VIRT_START(d)) )
@@ -622,14 +622,14 @@ int construct_dom0(struct domain *d,
         return -EINVAL;
     }
 
-    if ( IS_COMPAT(d) )
+    if ( is_pv_32on64_domain(d) )
     {
         v->arch.guest_context.failsafe_callback_cs = FLAT_COMPAT_KERNEL_CS;
         v->arch.guest_context.event_callback_cs    = FLAT_COMPAT_KERNEL_CS;
     }
 
     /* WARNING: The new domain must have its 'processor' field filled in! */
-    if ( !IS_COMPAT(d) )
+    if ( !is_pv_32on64_domain(d) )
     {
         maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l4_page_table;
         l4start = l4tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE;
@@ -647,7 +647,7 @@ int construct_dom0(struct domain *d,
     l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] =
         l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR);
     v->arch.guest_table = pagetable_from_paddr(__pa(l4start));
-    if ( IS_COMPAT(d) )
+    if ( is_pv_32on64_domain(d) )
     {
         v->arch.guest_table_user = v->arch.guest_table;
         if ( setup_arg_xlat_area(v, l4start) < 0 )
@@ -689,7 +689,8 @@ int construct_dom0(struct domain *d,
             *l2tab = l2e_from_paddr(__pa(l1start), L2_PROT);
             l2tab++;
         }
-        *l1tab = l1e_from_pfn(mfn, !IS_COMPAT(d) ? L1_PROT : COMPAT_L1_PROT);
+        *l1tab = l1e_from_pfn(mfn, (!is_pv_32on64_domain(d) ?
+                                    L1_PROT : COMPAT_L1_PROT));
         l1tab++;
 
         page = mfn_to_page(mfn);
@@ -701,7 +702,7 @@ int construct_dom0(struct domain *d,
     }
 
 #ifdef CONFIG_COMPAT
-    if ( IS_COMPAT(d) )
+    if ( is_pv_32on64_domain(d) )
     {
         /* Ensure the first four L3 entries are all populated. */
         for ( i = 0, l3tab = l3start; i < 4; ++i, ++l3tab )
@@ -743,7 +744,8 @@ int construct_dom0(struct domain *d,
 
         /* Top-level p.t. is pinned. */
         if ( (page->u.inuse.type_info & PGT_type_mask) ==
-             (!IS_COMPAT(d) ? PGT_l4_page_table : PGT_l3_page_table) )
+             (!is_pv_32on64_domain(d) ?
+              PGT_l4_page_table : PGT_l3_page_table) )
         {
             page->count_info        += 1;
             page->u.inuse.type_info += 1 | PGT_pinned;
@@ -823,7 +825,7 @@ int construct_dom0(struct domain *d,
     si->shared_info = virt_to_maddr(d->shared_info);
 
     si->flags        = SIF_PRIVILEGED | SIF_INITDOMAIN;
-    si->pt_base      = vpt_start + 2 * PAGE_SIZE * !!IS_COMPAT(d);
+    si->pt_base      = vpt_start + 2 * PAGE_SIZE * !!is_pv_32on64_domain(d);
     si->nr_pt_frames = nr_pt_pages;
     si->mfn_list     = vphysmap_start;
     snprintf(si->magic, sizeof(si->magic), "xen-%i.%i-x86_%d%s",
@@ -840,7 +842,7 @@ int construct_dom0(struct domain *d,
         if ( pfn > REVERSE_START )
             mfn = alloc_epfn - (pfn - REVERSE_START);
 #endif
-        if ( !IS_COMPAT(d) )
+        if ( !is_pv_32on64_domain(d) )
             ((unsigned long *)vphysmap_start)[pfn] = mfn;
         else
             ((unsigned int *)vphysmap_start)[pfn] = mfn;
@@ -856,7 +858,7 @@ int construct_dom0(struct domain *d,
 #ifndef NDEBUG
 #define pfn (nr_pages - 1 - (pfn - (alloc_epfn - alloc_spfn)))
 #endif
-            if ( !IS_COMPAT(d) )
+            if ( !is_pv_32on64_domain(d) )
                 ((unsigned long *)vphysmap_start)[pfn] = mfn;
             else
                 ((unsigned int *)vphysmap_start)[pfn] = mfn;
@@ -885,7 +887,7 @@ int construct_dom0(struct domain *d,
     }
 
 #ifdef CONFIG_COMPAT
-    if ( IS_COMPAT(d) )
+    if ( is_pv_32on64_domain(d) )
         xlat_start_info(si, XLAT_start_info_console_dom0);
 #endif
 
@@ -913,11 +915,12 @@ int construct_dom0(struct domain *d,
      *  [EAX,EBX,ECX,EDX,EDI,EBP are zero]
      */
     regs = &v->arch.guest_context.user_regs;
-    regs->ds = regs->es = regs->fs = regs->gs = !IS_COMPAT(d)
-                                                ? FLAT_KERNEL_DS
-                                                : FLAT_COMPAT_KERNEL_DS;
-    regs->ss = !IS_COMPAT(d) ? FLAT_KERNEL_SS : FLAT_COMPAT_KERNEL_SS;
-    regs->cs = !IS_COMPAT(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS;
+    regs->ds = regs->es = regs->fs = regs->gs =
+        !is_pv_32on64_domain(d) ? FLAT_KERNEL_DS : FLAT_COMPAT_KERNEL_DS;
+    regs->ss = (!is_pv_32on64_domain(d) ?
+                FLAT_KERNEL_SS : FLAT_COMPAT_KERNEL_SS);
+    regs->cs = (!is_pv_32on64_domain(d) ?
+                FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS);
     regs->eip = parms.virt_entry;
     regs->esp = vstack_end;
     regs->esi = vstartinfo_start;
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/domctl.c     Sat Apr 28 10:28:59 2007 +0100
@@ -435,12 +435,12 @@ void arch_get_info_guest(struct vcpu *v,
 void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
 {
 #ifdef CONFIG_COMPAT
-#define c(fld) (!IS_COMPAT(v->domain) ? (c.nat->fld) : (c.cmp->fld))
+#define c(fld) (!is_pv_32on64_domain(v->domain) ? (c.nat->fld) : (c.cmp->fld))
 #else
 #define c(fld) (c.nat->fld)
 #endif
 
-    if ( !IS_COMPAT(v->domain) )
+    if ( !is_pv_32on64_domain(v->domain) )
         memcpy(c.nat, &v->arch.guest_context, sizeof(*c.nat));
 #ifdef CONFIG_COMPAT
     else
@@ -455,7 +455,7 @@ void arch_get_info_guest(struct vcpu *v,
 
     if ( is_hvm_vcpu(v) )
     {
-        if ( !IS_COMPAT(v->domain) )
+        if ( !is_pv_32on64_domain(v->domain) )
             hvm_store_cpu_guest_regs(v, &c.nat->user_regs, c.nat->ctrlreg);
 #ifdef CONFIG_COMPAT
         else
@@ -477,7 +477,7 @@ void arch_get_info_guest(struct vcpu *v,
         BUG_ON((c(user_regs.eflags) & EF_IOPL) != 0);
         c(user_regs.eflags |= v->arch.iopl << 12);
 
-        if ( !IS_COMPAT(v->domain) )
+        if ( !is_pv_32on64_domain(v->domain) )
         {
             c.nat->ctrlreg[3] = xen_pfn_to_cr3(
                 pagetable_get_pfn(v->arch.guest_table));
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Sat Apr 28 10:28:59 2007 +0100
@@ -1049,15 +1049,13 @@ long do_hvm_op(unsigned long op, XEN_GUE
                 break;
             case HVM_PARAM_CALLBACK_IRQ:
                 hvm_set_callback_via(d, a.value);
-#if defined(__x86_64__)
                 /*
                  * Since this operation is one of the very first executed
                  * by PV drivers on initialisation or after save/restore, it
                  * is a sensible point at which to sample the execution mode of
                  * the guest and latch 32- or 64-bit format for shared state.
                  */
-                d->is_compat = (hvm_guest_x86_mode(current) == 4);
-#endif
+                d->arch.has_32bit_shinfo = (hvm_guest_x86_mode(current) != 8);
                 break;
             }
             d->arch.hvm_domain.params[a.index] = a.value;
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/hvm/save.c
--- a/xen/arch/x86/hvm/save.c   Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/hvm/save.c   Sat Apr 28 10:28:59 2007 +0100
@@ -99,6 +99,8 @@ int hvm_save(struct domain *d, hvm_domai
         hdr.changeset = simple_strtoll(c, NULL, 16);
     else 
         hdr.changeset = -1ULL; /* Unknown */
+
+    hdr.pad0 = 0;
 
     if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
     {
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/intr.c       Sat Apr 28 10:28:59 2007 +0100
@@ -71,6 +71,9 @@ static void update_tpr_threshold(struct 
 static void update_tpr_threshold(struct vlapic *vlapic)
 {
     int max_irr, tpr;
+
+    if ( !cpu_has_vmx_tpr_shadow )
+        return;
 
     if ( !vlapic_enabled(vlapic) || 
          ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Sat Apr 28 10:28:59 2007 +0100
@@ -38,16 +38,16 @@
 #include <asm/shadow.h>
 
 /* Dynamic (run-time adjusted) execution control flags. */
-u32 vmx_pin_based_exec_control;
-u32 vmx_cpu_based_exec_control;
-u32 vmx_vmexit_control;
-u32 vmx_vmentry_control;
-
-static u32 vmcs_revision_id;
-
-static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_max, u32 msr)
-{
-    u32 vmx_msr_low, vmx_msr_high, ctl = ctl_max;
+u32 vmx_pin_based_exec_control __read_mostly;
+u32 vmx_cpu_based_exec_control __read_mostly;
+u32 vmx_vmexit_control __read_mostly;
+u32 vmx_vmentry_control __read_mostly;
+
+static u32 vmcs_revision_id __read_mostly;
+
+static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, u32 msr)
+{
+    u32 vmx_msr_low, vmx_msr_high, ctl = ctl_min | ctl_opt;
 
     rdmsr(msr, vmx_msr_low, vmx_msr_high);
 
@@ -56,46 +56,55 @@ static u32 adjust_vmx_controls(u32 ctl_m
 
     /* Ensure minimum (required) set of control bits are supported. */
     BUG_ON(ctl_min & ~ctl);
-    BUG_ON(ctl_min & ~ctl_max);
 
     return ctl;
 }
 
 void vmx_init_vmcs_config(void)
 {
-    u32 vmx_msr_low, vmx_msr_high, min, max;
+    u32 vmx_msr_low, vmx_msr_high, min, opt;
     u32 _vmx_pin_based_exec_control;
     u32 _vmx_cpu_based_exec_control;
     u32 _vmx_vmexit_control;
     u32 _vmx_vmentry_control;
 
-    min = max = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING;
+    min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING;
+    opt = 0;
     _vmx_pin_based_exec_control = adjust_vmx_controls(
-        min, max, MSR_IA32_VMX_PINBASED_CTLS_MSR);
-
-    min = max = (CPU_BASED_HLT_EXITING |
-                 CPU_BASED_INVDPG_EXITING |
-                 CPU_BASED_MWAIT_EXITING |
-                 CPU_BASED_MOV_DR_EXITING |
-                 CPU_BASED_ACTIVATE_IO_BITMAP |
-                 CPU_BASED_USE_TSC_OFFSETING);
+        min, opt, MSR_IA32_VMX_PINBASED_CTLS_MSR);
+
+    min = (CPU_BASED_HLT_EXITING |
+           CPU_BASED_INVDPG_EXITING |
+           CPU_BASED_MWAIT_EXITING |
+           CPU_BASED_MOV_DR_EXITING |
+           CPU_BASED_ACTIVATE_IO_BITMAP |
+           CPU_BASED_USE_TSC_OFFSETING);
+    opt = CPU_BASED_ACTIVATE_MSR_BITMAP;
 #ifdef __x86_64__
-    min = max |= CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING;
-#endif
-    max |= CPU_BASED_ACTIVATE_MSR_BITMAP;
+    opt |= CPU_BASED_TPR_SHADOW;
+#endif
     _vmx_cpu_based_exec_control = adjust_vmx_controls(
-        min, max, MSR_IA32_VMX_PROCBASED_CTLS_MSR);
-
-    min = max = VM_EXIT_ACK_INTR_ON_EXIT;
+        min, opt, MSR_IA32_VMX_PROCBASED_CTLS_MSR);
 #ifdef __x86_64__
-    min = max |= VM_EXIT_IA32E_MODE;
+    if ( !(_vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW) )
+    {
+        min |= CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING;
+        _vmx_cpu_based_exec_control = adjust_vmx_controls(
+            min, opt, MSR_IA32_VMX_PROCBASED_CTLS_MSR);
+    }
+#endif
+
+    min = VM_EXIT_ACK_INTR_ON_EXIT;
+    opt = 0;
+#ifdef __x86_64__
+    min |= VM_EXIT_IA32E_MODE;
 #endif
     _vmx_vmexit_control = adjust_vmx_controls(
-        min, max, MSR_IA32_VMX_EXIT_CTLS_MSR);
-
-    min = max = 0;
+        min, opt, MSR_IA32_VMX_EXIT_CTLS_MSR);
+
+    min = opt = 0;
     _vmx_vmentry_control = adjust_vmx_controls(
-        min, max, MSR_IA32_VMX_ENTRY_CTLS_MSR);
+        min, opt, MSR_IA32_VMX_ENTRY_CTLS_MSR);
 
     rdmsr(MSR_IA32_VMX_BASIC_MSR, vmx_msr_low, vmx_msr_high);
 
@@ -414,13 +423,12 @@ static void construct_vmcs(struct vcpu *
 
 #ifdef __x86_64__ 
     /* VLAPIC TPR optimisation. */
-    v->arch.hvm_vcpu.u.vmx.exec_control |= CPU_BASED_TPR_SHADOW;
-    v->arch.hvm_vcpu.u.vmx.exec_control &=
-        ~(CPU_BASED_CR8_STORE_EXITING | CPU_BASED_CR8_LOAD_EXITING);
-    __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vcpu.u.vmx.exec_control);
-    __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
-              page_to_maddr(vcpu_vlapic(v)->regs_page));
-    __vmwrite(TPR_THRESHOLD, 0);
+    if ( cpu_has_vmx_tpr_shadow )
+    {
+        __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
+                  page_to_maddr(vcpu_vlapic(v)->regs_page));
+        __vmwrite(TPR_THRESHOLD, 0);
+    }
 #endif
 
     __vmwrite(GUEST_LDTR_SELECTOR, 0);
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/machine_kexec.c
--- a/xen/arch/x86/machine_kexec.c      Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/machine_kexec.c      Sat Apr 28 10:28:59 2007 +0100
@@ -44,9 +44,8 @@ int machine_kexec_load(int type, int slo
         else
         {
             /* Odd pages: va for previous ma. */
-            if ( IS_COMPAT(dom0) )
+            if ( is_pv_32on64_domain(dom0) )
             {
-
                 /*
                  * The compatability bounce code sets up a page table
                  * with a 1-1 mapping of the first 1G of memory so
@@ -119,7 +118,7 @@ void machine_kexec(xen_kexec_image_t *im
 void machine_kexec(xen_kexec_image_t *image)
 {
 #ifdef CONFIG_COMPAT
-    if ( IS_COMPAT(dom0) )
+    if ( is_pv_32on64_domain(dom0) )
     {
         extern void compat_machine_kexec(unsigned long rnk,
                                          unsigned long indirection_page,
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/mm.c Sat Apr 28 10:28:59 2007 +0100
@@ -149,8 +149,8 @@ unsigned long total_pages;
 
 #ifdef CONFIG_COMPAT
 l2_pgentry_t *compat_idle_pg_table_l2 = NULL;
-#define l3_disallow_mask(d) (!IS_COMPAT(d) ? \
-                             L3_DISALLOW_MASK : \
+#define l3_disallow_mask(d) (!is_pv_32on64_domain(d) ?  \
+                             L3_DISALLOW_MASK :         \
                              COMPAT_L3_DISALLOW_MASK)
 #else
 #define l3_disallow_mask(d) L3_DISALLOW_MASK
@@ -249,7 +249,10 @@ int memory_is_conventional_ram(paddr_t p
 
 unsigned long domain_get_maximum_gpfn(struct domain *d)
 {
-    return is_hvm_domain(d) ? d->arch.p2m.max_mapped_pfn : arch_get_max_pfn(d);
+    if ( is_hvm_domain(d) )
+        return d->arch.p2m.max_mapped_pfn;
+    /* NB. PV guests specify nr_pfns rather than max_pfn so we adjust here. */
+    return arch_get_max_pfn(d) - 1;
 }
 
 void share_xen_page_with_guest(
@@ -718,7 +721,7 @@ get_page_from_l4e(
 #define adjust_guest_l1e(pl1e, d)                                            \
     do {                                                                     \
         if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) &&                \
-             likely(!IS_COMPAT(d)) )                                         \
+             likely(!is_pv_32on64_domain(d)) )                               \
         {                                                                    \
             /* _PAGE_GUEST_KERNEL page cannot have the Global bit set. */    \
             if ( (l1e_get_flags((pl1e)) & (_PAGE_GUEST_KERNEL|_PAGE_GLOBAL)) \
@@ -735,7 +738,7 @@ get_page_from_l4e(
 #define adjust_guest_l1e(pl1e, d)                               \
     do {                                                        \
         if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) &&   \
-             likely(!IS_COMPAT(d)) )                            \
+             likely(!is_pv_32on64_domain(d)) )                  \
             l1e_add_flags((pl1e), _PAGE_USER);                  \
     } while ( 0 )
 #endif
@@ -743,22 +746,22 @@ get_page_from_l4e(
 #define adjust_guest_l2e(pl2e, d)                               \
     do {                                                        \
         if ( likely(l2e_get_flags((pl2e)) & _PAGE_PRESENT) &&   \
-             likely(!IS_COMPAT(d)) )                            \
+             likely(!is_pv_32on64_domain(d)) )                  \
             l2e_add_flags((pl2e), _PAGE_USER);                  \
     } while ( 0 )
 
-#define adjust_guest_l3e(pl3e, d)                               \
-    do {                                                        \
-        if ( likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) )    \
-            l3e_add_flags((pl3e), likely(!IS_COMPAT(d)) ?       \
-                                         _PAGE_USER :           \
-                                         _PAGE_USER|_PAGE_RW);  \
+#define adjust_guest_l3e(pl3e, d)                                   \
+    do {                                                            \
+        if ( likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) )        \
+            l3e_add_flags((pl3e), likely(!is_pv_32on64_domain(d)) ? \
+                                         _PAGE_USER :               \
+                                         _PAGE_USER|_PAGE_RW);      \
     } while ( 0 )
 
 #define adjust_guest_l4e(pl4e, d)                               \
     do {                                                        \
         if ( likely(l4e_get_flags((pl4e)) & _PAGE_PRESENT) &&   \
-             likely(!IS_COMPAT(d)) )                            \
+             likely(!is_pv_32on64_domain(d)) )                  \
             l4e_add_flags((pl4e), _PAGE_USER);                  \
     } while ( 0 )
 
@@ -771,11 +774,11 @@ get_page_from_l4e(
 #endif
 
 #ifdef CONFIG_COMPAT
-#define unadjust_guest_l3e(pl3e, d)                             \
-    do {                                                        \
-        if ( unlikely(IS_COMPAT(d)) &&                          \
-             likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) )    \
-            l3e_remove_flags((pl3e), _PAGE_USER|_PAGE_RW|_PAGE_ACCESSED); \
+#define unadjust_guest_l3e(pl3e, d)                                         \
+    do {                                                                    \
+        if ( unlikely(is_pv_32on64_domain(d)) &&                            \
+             likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) )                \
+            l3e_remove_flags((pl3e), _PAGE_USER|_PAGE_RW|_PAGE_ACCESSED);   \
     } while ( 0 )
 #else
 #define unadjust_guest_l3e(_p, _d) ((void)(_d))
@@ -907,11 +910,10 @@ static int create_pae_xen_mappings(struc
 #ifndef CONFIG_COMPAT
     l2_pgentry_t     l2e;
     int              i;
-#else
-
-    if ( !IS_COMPAT(d) )
+#endif
+
+    if ( !is_pv_32bit_domain(d) )
         return 1;
-#endif
 
     pl3e = (l3_pgentry_t *)((unsigned long)pl3e & PAGE_MASK);
 
@@ -1106,13 +1108,13 @@ static int alloc_l3_table(struct page_in
      * 512 entries must be valid/verified, which is most easily achieved
      * by clearing them out.
      */
-    if ( IS_COMPAT(d) )
+    if ( is_pv_32on64_domain(d) )
         memset(pl3e + 4, 0, (L3_PAGETABLE_ENTRIES - 4) * sizeof(*pl3e));
 
     for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ )
     {
 #if defined(CONFIG_X86_PAE) || defined(CONFIG_COMPAT)
-        if ( (CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d)) && i == 3 )
+        if ( is_pv_32bit_domain(d) && (i == 3) )
         {
             if ( !(l3e_get_flags(pl3e[i]) & _PAGE_PRESENT) ||
                  (l3e_get_flags(pl3e[i]) & l3_disallow_mask(d)) ||
@@ -1176,7 +1178,7 @@ static int alloc_l4_table(struct page_in
     pl4e[l4_table_offset(PERDOMAIN_VIRT_START)] =
         l4e_from_page(virt_to_page(d->arch.mm_perdomain_l3),
                       __PAGE_HYPERVISOR);
-    if ( IS_COMPAT(d) )
+    if ( is_pv_32on64_domain(d) )
         pl4e[l4_table_offset(COMPAT_ARG_XLAT_VIRT_BASE)] =
             l4e_from_page(virt_to_page(d->arch.mm_arg_xlat_l3),
                           __PAGE_HYPERVISOR);
@@ -1443,8 +1445,7 @@ static int mod_l3_entry(l3_pgentry_t *pl
      * Disallow updates to final L3 slot. It contains Xen mappings, and it
      * would be a pain to ensure they remain continuously valid throughout.
      */
-    if ( (CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d)) &&
-         pgentry_ptr_to_slot(pl3e) >= 3 )
+    if ( is_pv_32bit_domain(d) && (pgentry_ptr_to_slot(pl3e) >= 3) )
         return 0;
 #endif 
 
@@ -1791,7 +1792,7 @@ int new_guest_cr3(unsigned long mfn)
     unsigned long old_base_mfn;
 
 #ifdef CONFIG_COMPAT
-    if ( IS_COMPAT(d) )
+    if ( is_pv_32on64_domain(d) )
     {
         okay = paging_mode_refcounts(d)
             ? 0 /* Old code was broken, but what should it be? */
@@ -2023,7 +2024,7 @@ int do_mmuext_op(
             goto pin_page;
 
         case MMUEXT_PIN_L4_TABLE:
-            if ( IS_COMPAT(FOREIGNDOM) )
+            if ( is_pv_32bit_domain(FOREIGNDOM) )
                 break;
             type = PGT_l4_page_table;
 
@@ -2768,7 +2769,7 @@ int do_update_va_mapping(unsigned long v
             flush_tlb_mask(d->domain_dirty_cpumask);
             break;
         default:
-            if ( unlikely(!IS_COMPAT(d) ?
+            if ( unlikely(!is_pv_32on64_domain(d) ?
                           get_user(vmask, (unsigned long *)bmap_ptr) :
                           get_user(vmask, (unsigned int *)bmap_ptr)) )
                 rc = -EFAULT;
@@ -2790,7 +2791,7 @@ int do_update_va_mapping(unsigned long v
             flush_tlb_one_mask(d->domain_dirty_cpumask, va);
             break;
         default:
-            if ( unlikely(!IS_COMPAT(d) ?
+            if ( unlikely(!is_pv_32on64_domain(d) ?
                           get_user(vmask, (unsigned long *)bmap_ptr) :
                           get_user(vmask, (unsigned int *)bmap_ptr)) )
                 rc = -EFAULT;
@@ -3247,7 +3248,7 @@ static int ptwr_emulated_update(
     nl1e = l1e_from_intpte(val);
     if ( unlikely(!get_page_from_l1e(gl1e_to_ml1e(d, nl1e), d)) )
     {
-        if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) &&
+        if ( (CONFIG_PAGING_LEVELS >= 3) && is_pv_32bit_domain(d) &&
              (bytes == 4) && (addr & 4) && !do_cmpxchg &&
              (l1e_get_flags(nl1e) & _PAGE_PRESENT) )
         {
@@ -3384,7 +3385,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
 
     ptwr_ctxt.ctxt.regs = regs;
     ptwr_ctxt.ctxt.addr_size = ptwr_ctxt.ctxt.sp_size =
-        IS_COMPAT(d) ? 32 : BITS_PER_LONG;
+        is_pv_32on64_domain(d) ? 32 : BITS_PER_LONG;
     ptwr_ctxt.cr2 = addr;
     ptwr_ctxt.pte = pte;
 
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/mm/shadow/common.c   Sat Apr 28 10:28:59 2007 +0100
@@ -1577,9 +1577,7 @@ void sh_destroy_shadow(struct vcpu *v, m
            t == SH_type_fl1_pae_shadow ||  
            t == SH_type_fl1_64_shadow  || 
            t == SH_type_monitor_table  || 
-#ifdef CONFIG_COMPAT
-           (IS_COMPAT(v->domain) && t == SH_type_l4_64_shadow) ||
-#endif
+           (is_pv_32on64_vcpu(v) && t == SH_type_l4_64_shadow) ||
            (page_get_owner(mfn_to_page(_mfn(sp->backpointer))) 
             == v->domain)); 
 
@@ -1622,7 +1620,7 @@ void sh_destroy_shadow(struct vcpu *v, m
         SHADOW_INTERNAL_NAME(sh_destroy_l1_shadow, 4, 4)(v, smfn);
         break;
     case SH_type_l2h_64_shadow:
-        ASSERT( IS_COMPAT(v->domain) );
+        ASSERT(is_pv_32on64_vcpu(v));
         /* Fall through... */
     case SH_type_l2_64_shadow:
         SHADOW_INTERNAL_NAME(sh_destroy_l2_shadow, 4, 4)(v, smfn);
@@ -2668,8 +2666,7 @@ sh_alloc_log_dirty_bitmap(struct domain 
 {
     ASSERT(d->arch.paging.shadow.dirty_bitmap == NULL);
     d->arch.paging.shadow.dirty_bitmap_size =
-        (domain_get_maximum_gpfn(d) + (BITS_PER_LONG - 1)) &
-        ~(BITS_PER_LONG - 1);
+        (domain_get_maximum_gpfn(d) + BITS_PER_LONG) & ~(BITS_PER_LONG - 1);
     d->arch.paging.shadow.dirty_bitmap =
         xmalloc_array(unsigned long,
                       d->arch.paging.shadow.dirty_bitmap_size / BITS_PER_LONG);
@@ -2717,7 +2714,10 @@ static int shadow_log_dirty_enable(struc
     }
 
 #if (SHADOW_OPTIMIZATIONS & SHOPT_LINUX_L3_TOPLEVEL)
-    if ( IS_COMPAT(d) )
+    /* 32bit PV guests on 64bit xen behave like older 64bit linux: they
+     * change an l4e instead of cr3 to switch tables.  Give them the
+     * same optimization */
+    if ( is_pv_32on64_domain(d) )
         d->arch.paging.shadow.opt_flags = SHOPT_LINUX_L3_TOPLEVEL;
 #endif
 
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/mm/shadow/multi.c    Sat Apr 28 10:28:59 2007 +0100
@@ -134,9 +134,8 @@ set_shadow_status(struct vcpu *v, mfn_t 
                    d->domain_id, v->vcpu_id, mfn_x(gmfn),
                    shadow_type, mfn_x(smfn));
 
-#ifdef CONFIG_COMPAT
-    if ( !IS_COMPAT(d) || shadow_type != SH_type_l4_64_shadow )
-#endif
+    /* 32-on-64 PV guests don't own their l4 pages so can't get_page them */
+    if ( !is_pv_32on64_vcpu(v) || shadow_type != SH_type_l4_64_shadow )
     {
         res = get_page(mfn_to_page(gmfn), d);
         ASSERT(res == 1);
@@ -162,9 +161,8 @@ delete_shadow_status(struct vcpu *v, mfn
                    v->domain->domain_id, v->vcpu_id,
                    mfn_x(gmfn), shadow_type, mfn_x(smfn));
     shadow_hash_delete(v, mfn_x(gmfn), shadow_type, smfn);
-#ifdef CONFIG_COMPAT
-    if ( !IS_COMPAT(v->domain) || shadow_type != SH_type_l4_64_shadow )
-#endif
+    /* 32-on-64 PV guests don't own their l4 pages; see set_shadow_status */
+    if ( !is_pv_32on64_vcpu(v) || shadow_type != SH_type_l4_64_shadow )
         put_page(mfn_to_page(gmfn));
 }
 
@@ -746,7 +744,8 @@ _sh_propagate(struct vcpu *v,
     // PV guests in 64-bit mode use two different page tables for user vs
     // supervisor permissions, making the guest's _PAGE_USER bit irrelevant.
     // It is always shadowed as present...
-    if ( (GUEST_PAGING_LEVELS == 4) && !IS_COMPAT(d) && !is_hvm_domain(d) )
+    if ( (GUEST_PAGING_LEVELS == 4) && !is_pv_32on64_domain(d) 
+         && !is_hvm_domain(d) )
     {
         sflags |= _PAGE_USER;
     }
@@ -1300,7 +1299,7 @@ do {                                    
     for ( _i = 0; _i < SHADOW_L2_PAGETABLE_ENTRIES; _i++ )                  \
     {                                                                       \
         if ( (!(_xen))                                                      \
-             || !IS_COMPAT(_dom)                                            \
+             || !is_pv_32on64_domain(_dom)                                  \
              || mfn_to_shadow_page(_sl2mfn)->type != SH_type_l2h_64_shadow  \
              || (_i < COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(_dom)) )           \
         {                                                                   \
@@ -1411,7 +1410,7 @@ void sh_install_xen_entries_in_l4(struct
                                 __PAGE_HYPERVISOR);
     }
 
-    if ( IS_COMPAT(v->domain) )
+    if ( is_pv_32on64_domain(v->domain) )
     {
         /* install compat arg xlat entry */
         sl4e[shadow_l4_table_offset(COMPAT_ARG_XLAT_VIRT_BASE)] =
@@ -1437,7 +1436,7 @@ static void sh_install_xen_entries_in_l2
     int i;
 #else
 
-    if ( !pv_32bit_guest(v) )
+    if ( !is_pv_32on64_vcpu(v) )
         return;
 #endif
 
@@ -1622,9 +1621,6 @@ sh_make_shadow(struct vcpu *v, mfn_t gmf
 #endif
 #if CONFIG_PAGING_LEVELS >= 3 && GUEST_PAGING_LEVELS >= 3
         case SH_type_l2h_shadow:
-#ifdef CONFIG_COMPAT
-            ASSERT( IS_COMPAT(v->domain) );
-#endif
             sh_install_xen_entries_in_l2h(v, smfn); break;
 #endif
 #if CONFIG_PAGING_LEVELS == 2 && GUEST_PAGING_LEVELS == 2
@@ -1685,7 +1681,7 @@ sh_make_monitor_table(struct vcpu *v)
             l4e = sh_map_domain_page(m4mfn);
             l4e[0] = l4e_from_pfn(mfn_x(m3mfn), __PAGE_HYPERVISOR);
             sh_unmap_domain_page(l4e);
-            if ( pv_32bit_guest(v) )
+            if ( is_pv_32on64_vcpu(v) )
             {
                 // Install a monitor l2 table in slot 3 of the l3 table.
                 // This is used for all Xen entries.
@@ -1840,13 +1836,12 @@ static shadow_l2e_t * shadow_get_and_cre
         shadow_l3e_t new_sl3e;
         unsigned int t = SH_type_l2_shadow;
 
-#ifdef CONFIG_COMPAT
         /* Tag compat L2 containing hypervisor (m2p) mappings */
-        if ( IS_COMPAT(v->domain) &&
+        if ( is_pv_32on64_domain(v->domain) &&
              guest_l4_table_offset(gw->va) == 0 &&
              guest_l3_table_offset(gw->va) == 3 )
             t = SH_type_l2h_shadow;
-#endif
+
         /* No l2 shadow installed: find and install it. */
         *sl2mfn = get_shadow_status(v, gw->l2mfn, t);
         if ( !mfn_valid(*sl2mfn) ) 
@@ -2111,7 +2106,7 @@ void sh_destroy_monitor_table(struct vcp
         l4_pgentry_t *l4e = sh_map_domain_page(mmfn);
         ASSERT(l4e_get_flags(l4e[0]) & _PAGE_PRESENT);
         m3mfn = _mfn(l4e_get_pfn(l4e[0]));
-        if ( pv_32bit_guest(v) )
+        if ( is_pv_32on64_vcpu(v) )
         {
             /* Need to destroy the l2 monitor page in slot 3 too */
             l3_pgentry_t *l3e = sh_map_domain_page(m3mfn);
@@ -3474,7 +3469,7 @@ sh_update_cr3(struct vcpu *v, int do_loc
                    (unsigned long)pagetable_get_pfn(v->arch.guest_table));
 
 #if GUEST_PAGING_LEVELS == 4
-    if ( !(v->arch.flags & TF_kernel_mode) && !IS_COMPAT(v->domain) )
+    if ( !(v->arch.flags & TF_kernel_mode) && !is_pv_32on64_vcpu(v) )
         gmfn = pagetable_get_mfn(v->arch.guest_table_user);
     else
 #endif
@@ -4285,7 +4280,7 @@ int sh_audit_l3_table(struct vcpu *v, mf
             mfn = shadow_l3e_get_mfn(*sl3e);
             gmfn = get_shadow_status(v, audit_gfn_to_mfn(v, gfn, gl3mfn), 
                                      ((GUEST_PAGING_LEVELS == 3 ||
-                                       IS_COMPAT(v->domain))
+                                       is_pv_32on64_vcpu(v))
                                       && !shadow_mode_external(v->domain)
                                       && (guest_index(gl3e) % 4) == 3)
                                      ? SH_type_l2h_shadow
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/traps.c      Sat Apr 28 10:28:59 2007 +0100
@@ -124,7 +124,7 @@ static void show_guest_stack(struct cpu_
     if ( is_hvm_vcpu(current) )
         return;
 
-    if ( IS_COMPAT(container_of(regs, struct cpu_info, 
guest_cpu_user_regs)->current_vcpu->domain) )
+    if ( is_pv_32on64_vcpu(current) )
     {
         compat_show_guest_stack(regs, debug_stack_lines);
         return;
@@ -1568,7 +1568,7 @@ static int emulate_privileged_op(struct 
             break;
             
         case 3: /* Read CR3 */
-            if ( !IS_COMPAT(v->domain) )
+            if ( !is_pv_32on64_vcpu(v) )
                 *reg = xen_pfn_to_cr3(mfn_to_gmfn(
                     v->domain, pagetable_get_pfn(v->arch.guest_table)));
 #ifdef CONFIG_COMPAT
@@ -1625,7 +1625,7 @@ static int emulate_privileged_op(struct 
 
         case 3: /* Write CR3 */
             LOCK_BIGLOCK(v->domain);
-            if ( !IS_COMPAT(v->domain) )
+            if ( !is_pv_32on64_vcpu(v) )
                 rc = new_guest_cr3(gmfn_to_mfn(v->domain, 
xen_cr3_to_pfn(*reg)));
 #ifdef CONFIG_COMPAT
             else
@@ -1663,7 +1663,7 @@ static int emulate_privileged_op(struct 
         {
 #ifdef CONFIG_X86_64
         case MSR_FS_BASE:
-            if ( IS_COMPAT(v->domain) )
+            if ( is_pv_32on64_vcpu(v) )
                 goto fail;
             if ( wrmsr_safe(MSR_FS_BASE, regs->eax, regs->edx) )
                 goto fail;
@@ -1671,7 +1671,7 @@ static int emulate_privileged_op(struct 
                 ((u64)regs->edx << 32) | regs->eax;
             break;
         case MSR_GS_BASE:
-            if ( IS_COMPAT(v->domain) )
+            if ( is_pv_32on64_vcpu(v) )
                 goto fail;
             if ( wrmsr_safe(MSR_GS_BASE, regs->eax, regs->edx) )
                 goto fail;
@@ -1679,7 +1679,7 @@ static int emulate_privileged_op(struct 
                 ((u64)regs->edx << 32) | regs->eax;
             break;
         case MSR_SHADOW_GS_BASE:
-            if ( IS_COMPAT(v->domain) )
+            if ( is_pv_32on64_vcpu(v) )
                 goto fail;
             if ( wrmsr_safe(MSR_SHADOW_GS_BASE, regs->eax, regs->edx) )
                 goto fail;
@@ -1705,19 +1705,19 @@ static int emulate_privileged_op(struct 
         {
 #ifdef CONFIG_X86_64
         case MSR_FS_BASE:
-            if ( IS_COMPAT(v->domain) )
+            if ( is_pv_32on64_vcpu(v) )
                 goto fail;
             regs->eax = v->arch.guest_context.fs_base & 0xFFFFFFFFUL;
             regs->edx = v->arch.guest_context.fs_base >> 32;
             break;
         case MSR_GS_BASE:
-            if ( IS_COMPAT(v->domain) )
+            if ( is_pv_32on64_vcpu(v) )
                 goto fail;
             regs->eax = v->arch.guest_context.gs_base_kernel & 0xFFFFFFFFUL;
             regs->edx = v->arch.guest_context.gs_base_kernel >> 32;
             break;
         case MSR_SHADOW_GS_BASE:
-            if ( IS_COMPAT(v->domain) )
+            if ( is_pv_32on64_vcpu(v) )
                 goto fail;
             regs->eax = v->arch.guest_context.gs_base_user & 0xFFFFFFFFUL;
             regs->edx = v->arch.guest_context.gs_base_user >> 32;
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/x86_32/entry.S       Sat Apr 28 10:28:59 2007 +0100
@@ -75,6 +75,7 @@
 
         ALIGN
 restore_all_guest:
+        ASSERT_INTERRUPTS_DISABLED
         testl $X86_EFLAGS_VM,UREGS_eflags(%esp)
         jnz  restore_all_vm86
 #ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL
@@ -129,10 +130,10 @@ failsafe_callback:
         movl  %eax,TRAPBOUNCE_eip(%edx)
         movl  VCPU_failsafe_sel(%ebx),%eax
         movw  %ax,TRAPBOUNCE_cs(%edx)
-        movw  $TBF_FAILSAFE,TRAPBOUNCE_flags(%edx)
+        movb  $TBF_FAILSAFE,TRAPBOUNCE_flags(%edx)
         bt    $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%ebx)
         jnc   1f
-        orw   $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
+        orb   $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
 1:      call  create_bounce_frame
         xorl  %eax,%eax
         movl  %eax,UREGS_ds(%esp)
@@ -247,7 +248,7 @@ test_guest_events:
         movl %eax,TRAPBOUNCE_eip(%edx)
         movl VCPU_event_sel(%ebx),%eax
         movw %ax,TRAPBOUNCE_cs(%edx)
-        movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
+        movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
         call create_bounce_frame
         jmp  test_all_events
 
@@ -270,7 +271,7 @@ process_nmi:
         leal VCPU_trap_bounce(%ebx),%edx
         movl %eax,TRAPBOUNCE_eip(%edx)
         movw $FLAT_KERNEL_CS,TRAPBOUNCE_cs(%edx)
-        movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
+        movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
         call create_bounce_frame
         jmp  test_all_events
 
@@ -383,7 +384,6 @@ 2:      testl $X86_EFLAGS_VM,UREGS_eflag
         movl %eax,UREGS_cs+4(%esp)
         movl TRAPBOUNCE_eip(%edx),%eax
         movl %eax,UREGS_eip+4(%esp)
-        movb $0,TRAPBOUNCE_flags(%edx)
         ret
 .section __ex_table,"a"
         .long  .Lft6,domain_crash_synchronous ,  .Lft7,domain_crash_synchronous
@@ -441,6 +441,7 @@ 1:      xorl  %eax,%eax
         testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%edx)
         jz    test_all_events
         call  create_bounce_frame
+        movb  $0,TRAPBOUNCE_flags(%edx)
         jmp   test_all_events
 
 exception_with_ints_disabled:
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_64/asm-offsets.c
--- a/xen/arch/x86/x86_64/asm-offsets.c Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/x86_64/asm-offsets.c Sat Apr 28 10:28:59 2007 +0100
@@ -91,7 +91,7 @@ void __dummy__(void)
     OFFSET(VCPU_vmx_cr2, struct vcpu, arch.hvm_vmx.cpu_cr2);
     BLANK();
 
-    OFFSET(DOMAIN_is_compat, struct domain, is_compat);
+    OFFSET(DOMAIN_is_32bit_pv, struct domain, arch.is_32bit_pv);
     BLANK();
 
     OFFSET(VMCB_rax, struct vmcb_struct, rax);
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S        Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/x86_64/compat/entry.S        Sat Apr 28 10:28:59 2007 +0100
@@ -101,8 +101,8 @@ compat_test_guest_events:
         movl  VCPU_event_addr(%rbx),%eax
         movl  %eax,TRAPBOUNCE_eip(%rdx)
         movl  VCPU_event_sel(%rbx),%eax
-        movl  %eax,TRAPBOUNCE_cs(%rdx)
-        movw  $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
+        movw  %ax,TRAPBOUNCE_cs(%rdx)
+        movb  $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
         call  compat_create_bounce_frame
         jmp   compat_test_all_events
 
@@ -126,8 +126,8 @@ compat_process_nmi:
         sti
         leaq  VCPU_trap_bounce(%rbx),%rdx
         movl  %eax,TRAPBOUNCE_eip(%rdx)
-        movl  $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx)
-        movw  $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
+        movw  $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx)
+        movb  $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
         call  compat_create_bounce_frame
         jmp   compat_test_all_events
 
@@ -164,13 +164,12 @@ compat_failsafe_callback:
         movl  VCPU_failsafe_addr(%rbx),%eax
         movl  %eax,TRAPBOUNCE_eip(%rdx)
         movl  VCPU_failsafe_sel(%rbx),%eax
-        movl  %eax,TRAPBOUNCE_cs(%rdx)
-        movw  $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx)
+        movw  %ax,TRAPBOUNCE_cs(%rdx)
+        movb  $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx)
         btq   $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%rbx)
         jnc   1f
-        orw   $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
-1:
-        call  compat_create_bounce_frame
+        orb   $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
+1:      call  compat_create_bounce_frame
         jmp   compat_test_all_events
 .previous
 .section __pre_ex_table,"a"
@@ -185,6 +184,7 @@ ENTRY(compat_post_handle_exception)
         testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
         jz    compat_test_all_events
         call  compat_create_bounce_frame
+        movb  $0,TRAPBOUNCE_flags(%rdx)
         jmp   compat_test_all_events
 
 ENTRY(compat_int80_direct_trap)
@@ -194,7 +194,7 @@ ENTRY(compat_int80_direct_trap)
 /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:            */
 /*   {[ERRCODE,] EIP, CS, EFLAGS, [ESP, SS]}                             */
 /* %rdx: trap_bounce, %rbx: struct vcpu                                  */
-/* On return only %rbx is guaranteed non-clobbered.                      */
+/* On return only %rbx and %rdx are guaranteed non-clobbered.            */
 compat_create_bounce_frame:
         ASSERT_INTERRUPTS_ENABLED
         mov   %fs,%edi
@@ -253,7 +253,6 @@ 2:
 2:
         /* Rewrite our stack frame and return to guest-OS mode. */
         /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */
-        movl  $TRAP_syscall,UREGS_entry_vector+8(%rsp)
         andl  $~(X86_EFLAGS_VM|X86_EFLAGS_RF|\
                  X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+8(%rsp)
         mov   %fs,UREGS_ss+8(%rsp)
@@ -266,7 +265,6 @@ 2:
         movl  %eax,UREGS_cs+8(%rsp)
         movl  TRAPBOUNCE_eip(%rdx),%eax
         movl  %eax,UREGS_rip+8(%rsp)
-        movb  $0,TRAPBOUNCE_flags(%rdx)
         ret
 .section .fixup,"ax"
 .Lfx13:
@@ -333,7 +331,7 @@ ENTRY(compat_hypercall_table)
         .quad compat_vcpu_op
         .quad compat_ni_hypercall       /* 25 */
         .quad compat_mmuext_op
-        .quad compat_acm_op
+        .quad do_acm_op
         .quad compat_nmi_op
         .quad compat_sched_op
         .quad compat_callback_op        /* 30 */
@@ -376,7 +374,7 @@ ENTRY(compat_hypercall_args_table)
         .byte 3 /* compat_vcpu_op           */
         .byte 0 /* compat_ni_hypercall      */  /* 25 */
         .byte 4 /* compat_mmuext_op         */
-        .byte 1 /* compat_acm_op            */
+        .byte 1 /* do_acm_op                */
         .byte 2 /* compat_nmi_op            */
         .byte 2 /* compat_sched_op          */
         .byte 2 /* compat_callback_op       */  /* 30 */
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/x86_64/entry.S       Sat Apr 28 10:28:59 2007 +0100
@@ -29,10 +29,10 @@ switch_to_kernel:
         leaq  VCPU_trap_bounce(%rbx),%rdx
         movq  VCPU_syscall_addr(%rbx),%rax
         movq  %rax,TRAPBOUNCE_eip(%rdx)
-        movw  $0,TRAPBOUNCE_flags(%rdx)
+        movb  $0,TRAPBOUNCE_flags(%rdx)
         bt    $_VGCF_syscall_disables_events,VCPU_guest_context_flags(%rbx)
         jnc   1f
-        orw   $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
+        movb  $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
 1:      call  create_bounce_frame
         jmp   test_all_events
 
@@ -80,10 +80,10 @@ failsafe_callback:
         leaq  VCPU_trap_bounce(%rbx),%rdx
         movq  VCPU_failsafe_addr(%rbx),%rax
         movq  %rax,TRAPBOUNCE_eip(%rdx)
-        movw  $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx)
+        movb  $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx)
         bt    $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%rbx)
         jnc   1f
-        orw   $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
+        orb   $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
 1:      call  create_bounce_frame
         jmp   test_all_events
 .previous
@@ -191,7 +191,7 @@ test_guest_events:
         leaq  VCPU_trap_bounce(%rbx),%rdx
         movq  VCPU_event_addr(%rbx),%rax
         movq  %rax,TRAPBOUNCE_eip(%rdx)
-        movw  $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
+        movb  $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
         call  create_bounce_frame
         jmp   test_all_events
 
@@ -215,7 +215,7 @@ process_nmi:
         sti
         leaq VCPU_trap_bounce(%rbx),%rdx
         movq %rax,TRAPBOUNCE_eip(%rdx)
-        movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
+        movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
         call create_bounce_frame
         jmp  test_all_events
 
@@ -231,11 +231,11 @@ ENTRY(int80_direct_trap)
 
         /* Check that the callback is non-null. */
         leaq  VCPU_int80_bounce(%rbx),%rdx
-        cmp   $0,TRAPBOUNCE_flags(%rdx)
+        cmpb  $0,TRAPBOUNCE_flags(%rdx)
         jz    int80_slow_path
 
         movq  VCPU_domain(%rbx),%rax
-        testb $1,DOMAIN_is_compat(%rax)
+        testb $1,DOMAIN_is_32bit_pv(%rax)
         jnz   compat_int80_direct_trap
 
         call  create_bounce_frame
@@ -249,13 +249,13 @@ int80_slow_path:
         movl  $((0x80 << 3) | 0x2),UREGS_error_code(%rsp)
         movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
         /* A GPF wouldn't have incremented the instruction pointer. */
-        sub   $2,UREGS_rip(%rsp)
+        subq  $2,UREGS_rip(%rsp)
         jmp   handle_exception_saved
 
 /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS STACK:                     */
 /*   { RCX, R11, [DS-GS,] [CR2,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS }   */
-/* %rdx: trap_bounce, %rbx: struct vcpu                           */
-/* On return only %rbx is guaranteed non-clobbered.                      */
+/* %rdx: trap_bounce, %rbx: struct vcpu                                  */
+/* On return only %rbx and %rdx are guaranteed non-clobbered.            */
 create_bounce_frame:
         ASSERT_INTERRUPTS_ENABLED
         testb $TF_kernel_mode,VCPU_thread_flags(%rbx)
@@ -336,7 +336,6 @@ 2:      subq  $16,%rsi
         testq %rax,%rax
         jz    domain_crash_synchronous
         movq  %rax,UREGS_rip+8(%rsp)
-        movb  $0,TRAPBOUNCE_flags(%rdx)
         ret
 .section __ex_table,"a"
         .quad  .Lft2,domain_crash_synchronous ,  .Lft3,domain_crash_synchronous
@@ -357,7 +356,7 @@ ENTRY(domain_crash_synchronous)
         # create_bounce_frame() temporarily clobbers CS.RPL. Fix up.
         movq  CPUINFO_current_vcpu(%rax),%rax
         movq  VCPU_domain(%rax),%rax
-        testb $1,DOMAIN_is_compat(%rax)
+        testb $1,DOMAIN_is_32bit_pv(%rax)
         setz  %al
         leal  (%rax,%rax,2),%eax
         orb   %al,UREGS_cs(%rsp)
@@ -374,7 +373,7 @@ ENTRY(ret_from_intr)
         testb $3,UREGS_cs(%rsp)
         jz    restore_all_xen
         movq  VCPU_domain(%rbx),%rax
-        testb $1,DOMAIN_is_compat(%rax)
+        testb $1,DOMAIN_is_32bit_pv(%rax)
         jz    test_all_events
         jmp   compat_test_all_events
 
@@ -396,11 +395,12 @@ 1:      movq  %rsp,%rdi
         jz    restore_all_xen
         leaq  VCPU_trap_bounce(%rbx),%rdx
         movq  VCPU_domain(%rbx),%rax
-        testb $1,DOMAIN_is_compat(%rax)
+        testb $1,DOMAIN_is_32bit_pv(%rax)
         jnz   compat_post_handle_exception
         testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
         jz    test_all_events
         call  create_bounce_frame
+        movb  $0,TRAPBOUNCE_flags(%rdx)
         jmp   test_all_events
 
 /* No special register assumptions. */
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/x86_64/mm.c  Sat Apr 28 10:28:59 2007 +0100
@@ -384,9 +384,9 @@ int check_descriptor(const struct domain
     /* All code and data segments are okay. No base/limit checking. */
     if ( (b & _SEGMENT_S) )
     {
-        if ( !IS_COMPAT(dom) || !(b & _SEGMENT_L) )
-            goto good;
-        goto bad;
+        if ( is_pv_32bit_domain(dom) && (b & _SEGMENT_L) )
+            goto bad;
+        goto good;
     }
 
     /* Invalid type 0 is harmless. It is used for 2nd half of a call gate. */
diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/arch/x86/x86_64/traps.c       Sat Apr 28 10:28:59 2007 +0100
@@ -179,7 +179,7 @@ asmlinkage void do_double_fault(struct c
 
 void toggle_guest_mode(struct vcpu *v)
 {
-    if ( IS_COMPAT(v->domain) )
+    if ( is_pv_32bit_vcpu(v) )
         return;
     v->arch.flags ^= TF_kernel_mode;
     __asm__ __volatile__ ( "swapgs" );
@@ -356,9 +356,6 @@ void init_int80_direct_trap(struct vcpu 
 {
     struct trap_info *ti = &v->arch.guest_context.trap_ctxt[0x80];
     struct trap_bounce *tb = &v->arch.int80_bounce;
-
-    if ( !guest_gate_selector_okay(v->domain, ti->cs) )
-         return;
 
     tb->flags = TBF_EXCEPTION;
     tb->cs    = ti->cs;
@@ -537,7 +534,7 @@ void hypercall_page_initialise(struct do
 {
     if ( is_hvm_domain(d) )
         hvm_hypercall_page_initialise(d, hypercall_page);
-    else if ( !IS_COMPAT(d) )
+    else if ( !is_pv_32bit_domain(d) )
         hypercall_page_initialise_ring3_kernel(hypercall_page);
     else
         hypercall_page_initialise_ring1_kernel(hypercall_page);
diff -r ee16cdeddade -r 1668299c0ea4 xen/common/Makefile
--- a/xen/common/Makefile       Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/common/Makefile       Sat Apr 28 10:28:59 2007 +0100
@@ -43,7 +43,6 @@ version.o: $(BASEDIR)/include/xen/compil
 
 ifeq ($(CONFIG_COMPAT),y)
 # extra dependencies
-acm_ops.o: compat/acm_ops.c
 grant_table.o: compat/grant_table.c
 kexec.o: compat/kexec.c
 schedule.o: compat/schedule.c
diff -r ee16cdeddade -r 1668299c0ea4 xen/common/acm_ops.c
--- a/xen/common/acm_ops.c      Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/common/acm_ops.c      Sat Apr 28 10:28:59 2007 +0100
@@ -12,10 +12,8 @@
  * License.
  *
  * Process acm command requests from guest OS.
- *
  */
 
-#ifndef COMPAT
 #include <xen/config.h>
 #include <xen/types.h>
 #include <xen/lib.h>
@@ -29,38 +27,25 @@
 #include <xen/guest_access.h>
 #include <acm/acm_hooks.h>
 
-typedef long ret_t;
-
-#endif /* !COMPAT */
-
 #ifndef ACM_SECURITY
 
-
 long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
 {
     return -ENOSYS;
 }
 
-
 #else
 
-
-#ifndef COMPAT
 int acm_authorize_acm_ops(struct domain *d)
 {
-    /* currently, policy management functions are restricted to privileged 
domains */
-    if (!IS_PRIV(d))
-        return -EPERM;
-    return 0;
-}
-#endif
-
-
-ret_t do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
-{
-    ret_t rc = -EFAULT;
-
-    if (acm_authorize_acm_ops(current->domain))
+    return (IS_PRIV(d) ? 0 : -EPERM);
+}
+
+long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
+{
+    long rc = -EFAULT;
+
+    if ( acm_authorize_acm_ops(current->domain) )
         return -EPERM;
 
     switch ( cmd )
@@ -226,11 +211,9 @@ ret_t do_acm_op(int cmd, XEN_GUEST_HANDL
 
         rc = acm_change_policy(&chgpolicy);
 
-        if (rc == 0) {
-            if (copy_to_guest(arg, &chgpolicy, 1) != 0) {
+        if (rc == 0)
+            if (copy_to_guest(arg, &chgpolicy, 1) != 0)
                 rc = -EFAULT;
-            }
-        }
         break;
     }
 
@@ -244,11 +227,9 @@ ret_t do_acm_op(int cmd, XEN_GUEST_HANDL
 
         rc = acm_relabel_domains(&relabeldoms);
 
-        if (rc == 0) {
-            if (copy_to_guest(arg, &relabeldoms, 1) != 0) {
+        if (rc == 0)
+            if (copy_to_guest(arg, &relabeldoms, 1) != 0)
                 rc = -EFAULT;
-            }
-        }
         break;
     }
 
@@ -260,11 +241,7 @@ ret_t do_acm_op(int cmd, XEN_GUEST_HANDL
     return rc;
 }
 
-#endif
-
-#if defined(CONFIG_COMPAT) && !defined(COMPAT)
-#include "compat/acm_ops.c"
-#endif
+#endif /* defined(ACM_SECURITY) */
 
 /*
  * Local variables:
diff -r ee16cdeddade -r 1668299c0ea4 xen/common/compat/acm_ops.c
--- a/xen/common/compat/acm_ops.c       Wed Apr 25 10:39:08 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/******************************************************************************
- * compat/acm_ops.c
- */
-
-#include <compat/acm.h>
-#include <compat/acm_ops.h>
-
-#define COMPAT
-#define ret_t int
-
-#define do_acm_op compat_acm_op
-
-static inline XEN_GUEST_HANDLE(void) acm_xlat_handle(COMPAT_HANDLE(void) cmp)
-{
-    XEN_GUEST_HANDLE(void) nat;
-
-    guest_from_compat_handle(nat, cmp);
-    return nat;
-}
-
-#define acm_setpolicy compat_acm_setpolicy
-#define acm_set_policy(h, sz) acm_set_policy(acm_xlat_handle(h), sz)
-
-#define acm_getpolicy compat_acm_getpolicy
-#define acm_get_policy(h, sz) acm_get_policy(acm_xlat_handle(h), sz)
-
-#define acm_dumpstats compat_acm_dumpstats
-#define acm_dump_statistics(h, sz) acm_dump_statistics(acm_xlat_handle(h), sz)
-
-#define acm_getssid compat_acm_getssid
-#define acm_get_ssid(r, h, sz) acm_get_ssid(r, acm_xlat_handle(h), sz)
-
-#define xen_acm_getdecision acm_getdecision
-CHECK_acm_getdecision;
-#undef xen_acm_getdecision
-
-#include "../acm_ops.c"
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r ee16cdeddade -r 1668299c0ea4 xen/common/compat/grant_table.c
--- a/xen/common/compat/grant_table.c   Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/common/compat/grant_table.c   Sat Apr 28 10:28:59 2007 +0100
@@ -133,7 +133,7 @@ int compat_grant_table_op(unsigned int c
             break;
 
         case GNTTABOP_transfer:
-            for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.xfer) && i < 
count && rc == 0; ++i, ++n )
+            for ( n = 0; n < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.xfer) && i < 
count && rc == 0; ++i, ++n )
             {
                 if ( unlikely(__copy_from_guest_offset(&cmp.xfer, cmp_uop, i, 
1)) )
                     rc = -EFAULT;
@@ -160,7 +160,7 @@ int compat_grant_table_op(unsigned int c
             break;
 
         case GNTTABOP_copy:
-            for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.copy) && i < 
count && rc == 0; ++i, ++n )
+            for ( n = 0; n < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.copy) && i < 
count && rc == 0; ++i, ++n )
             {
                 if ( unlikely(__copy_from_guest_offset(&cmp.copy, cmp_uop, i, 
1)) )
                     rc = -EFAULT;
diff -r ee16cdeddade -r 1668299c0ea4 xen/common/sched_credit.c
--- a/xen/common/sched_credit.c Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/common/sched_credit.c Sat Apr 28 10:28:59 2007 +0100
@@ -1355,6 +1355,10 @@ static __init int csched_start_tickers(v
     struct csched_pcpu *spc;
     unsigned int cpu;
 
+    /* Is the credit scheduler initialised? */
+    if ( csched_priv.ncpus == 0 )
+        return 0;
+
     for_each_online_cpu ( cpu )
     {
         spc = CSCHED_PCPU(cpu);
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/Makefile
--- a/xen/include/Makefile      Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/Makefile      Sat Apr 28 10:28:59 2007 +0100
@@ -3,8 +3,6 @@ compat-arch-$(CONFIG_X86) := x86_32
 compat-arch-$(CONFIG_X86) := x86_32
 
 headers-y := \
-    compat/acm.h \
-    compat/acm_ops.h \
     compat/callback.h \
     compat/elfnote.h \
     compat/event_channel.h \
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/acm/acm_core.h
--- a/xen/include/acm/acm_core.h        Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/acm/acm_core.h        Sat Apr 28 10:28:59 2007 +0100
@@ -155,13 +155,13 @@ int acm_init_domain_ssid_new(struct doma
 int acm_init_domain_ssid_new(struct domain *, ssidref_t ssidref);
 void acm_free_domain_ssid(struct acm_ssid_domain *ssid);
 int acm_init_binary_policy(u32 policy_code);
-int acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size);
+int acm_set_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size);
 int do_acm_set_policy(void *buf, u32 buf_size, int is_bootpolicy,
                       struct acm_sized_buffer *, struct acm_sized_buffer *,
                       struct acm_sized_buffer *);
-int acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size);
-int acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size);
-int acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size);
+int acm_get_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size);
+int acm_dump_statistics(XEN_GUEST_HANDLE_64(void) buf, u16 buf_size);
+int acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE_64(void) buf, u16 
buf_size);
 int acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook);
 int acm_set_policy_reference(u8 * buf, u32 buf_size);
 int acm_dump_policy_reference(u8 *buf, u32 buf_size);
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/desc.h
--- a/xen/include/asm-x86/desc.h        Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/asm-x86/desc.h        Sat Apr 28 10:28:59 2007 +0100
@@ -64,7 +64,7 @@
 #define load_TR(n)  __asm__ __volatile__ ("ltr  %%ax" : : "a" (__TSS(n)<<3) )
 
 #if defined(__x86_64__)
-#define GUEST_KERNEL_RPL(d) (!IS_COMPAT(d) ? 3 : 1)
+#define GUEST_KERNEL_RPL(d) (is_pv_32bit_domain(d) ? 1 : 3)
 #elif defined(__i386__)
 #define GUEST_KERNEL_RPL(d) ((void)(d), 1)
 #endif
@@ -104,7 +104,7 @@
  */
 #define guest_gate_selector_okay(d, sel)                                \
     ((((sel)>>3) < FIRST_RESERVED_GDT_ENTRY) || /* Guest seg? */        \
-     ((sel) == (!IS_COMPAT(d) ?                                         \
+     ((sel) == (!is_pv_32on64_domain(d) ?                               \
                 FLAT_KERNEL_CS :                /* Xen default seg? */  \
                 FLAT_COMPAT_KERNEL_CS)) ||                              \
      ((sel) & 4))                               /* LDT seg? */
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/asm-x86/domain.h      Sat Apr 28 10:28:59 2007 +0100
@@ -7,11 +7,22 @@
 #include <asm/hvm/domain.h>
 #include <asm/e820.h>
 
+#define has_32bit_shinfo(d)    ((d)->arch.has_32bit_shinfo)
+#define is_pv_32bit_domain(d)  ((d)->arch.is_32bit_pv)
+#define is_pv_32bit_vcpu(v)    (is_pv_32bit_domain((v)->domain))
+#ifdef __x86_64__
+#define is_pv_32on64_domain(d) (is_pv_32bit_domain(d))
+#else
+#define is_pv_32on64_domain(d) (0)
+#endif
+#define is_pv_32on64_vcpu(v)   (is_pv_32on64_domain((v)->domain))
+#define IS_COMPAT(d)           (is_pv_32on64_domain(d))
+
 struct trap_bounce {
-    unsigned long  error_code;
-    unsigned short flags; /* TBF_ */
-    unsigned short cs;
-    unsigned long  eip;
+    uint32_t      error_code;
+    uint8_t       flags; /* TBF_ */
+    uint16_t      cs;
+    unsigned long eip;
 };
 
 #define MAPHASH_ENTRIES 8
@@ -200,6 +211,11 @@ struct arch_domain
 
     /* Maximum physical-address bitwidth supported by this guest. */
     unsigned int physaddr_bitsize;
+
+    /* Is a 32-bit PV (non-HVM) guest? */
+    bool_t is_32bit_pv;
+    /* Is shared-info page in 32-bit format? */
+    bool_t has_32bit_shinfo;
 } __cacheline_aligned;
 
 #ifdef CONFIG_X86_PAE
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Sat Apr 28 10:28:59 2007 +0100
@@ -119,6 +119,8 @@ extern u32 vmx_vmexit_control;
 #define VM_ENTRY_DEACT_DUAL_MONITOR     0x00000800
 extern u32 vmx_vmentry_control;
 
+#define cpu_has_vmx_tpr_shadow \
+    (vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW)
 #define cpu_has_vmx_msr_bitmap \
     (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP)
 extern char *vmx_msr_bitmap;
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/ldt.h
--- a/xen/include/asm-x86/ldt.h Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/asm-x86/ldt.h Sat Apr 28 10:28:59 2007 +0100
@@ -17,7 +17,7 @@ static inline void load_LDT(struct vcpu 
     else
     {
         cpu = smp_processor_id();
-        desc = (!IS_COMPAT(v->domain) ? gdt_table : compat_gdt_table)
+        desc = (!is_pv_32on64_vcpu(v) ? gdt_table : compat_gdt_table)
                + __LDT(cpu) - FIRST_RESERVED_GDT_ENTRY;
         _set_tssldt_desc(desc, LDT_VIRT_START(v), ents*8-1, 2);
         __asm__ __volatile__ ( "lldt %%ax" : : "a" (__LDT(cpu)<<3) );
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/asm-x86/shadow.h      Sat Apr 28 10:28:59 2007 +0100
@@ -48,16 +48,6 @@
  * not yet supported */
 #define shadow_mode_trap_reads(_d) ({ (void)(_d); 0; })
 
-/*
- * 32on64 support
- */
-#ifdef __x86_64__
-#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v) && IS_COMPAT((_v)->domain))
-#else
-#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v))
-#endif
-
-
 /*****************************************************************************
  * Entry points into the shadow code */
 
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/shared.h
--- a/xen/include/asm-x86/shared.h      Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/asm-x86/shared.h      Sat Apr 28 10:28:59 2007 +0100
@@ -3,66 +3,66 @@
 
 #ifdef CONFIG_COMPAT
 
-#define nmi_reason(d) (!IS_COMPAT(d) ? \
+#define nmi_reason(d) (!has_32bit_shinfo(d) ?                              \
                        (void *)&(d)->shared_info->native.arch.nmi_reason : \
                        (void *)&(d)->shared_info->compat.arch.nmi_reason)
 
-#define GET_SET_SHARED(type, field) \
-static inline type arch_get_##field(const struct domain *d) \
-{ \
-    return !IS_COMPAT(d) ? \
-           d->shared_info->native.arch.field : \
-           d->shared_info->compat.arch.field; \
-} \
-static inline void arch_set_##field(struct domain *d, \
-                                    type val) \
-{ \
-    if ( !IS_COMPAT(d) ) \
-        d->shared_info->native.arch.field = val; \
-    else \
-        d->shared_info->compat.arch.field = val; \
+#define GET_SET_SHARED(type, field)                             \
+static inline type arch_get_##field(const struct domain *d)     \
+{                                                               \
+    return !has_32bit_shinfo(d) ?                               \
+           d->shared_info->native.arch.field :                  \
+           d->shared_info->compat.arch.field;                   \
+}                                                               \
+static inline void arch_set_##field(struct domain *d,           \
+                                    type val)                   \
+{                                                               \
+    if ( !has_32bit_shinfo(d) )                                 \
+        d->shared_info->native.arch.field = val;                \
+    else                                                        \
+        d->shared_info->compat.arch.field = val;                \
 }
 
-#define GET_SET_VCPU(type, field) \
-static inline type arch_get_##field(const struct vcpu *v) \
-{ \
-    return !IS_COMPAT(v->domain) ? \
-           v->vcpu_info->native.arch.field : \
-           v->vcpu_info->compat.arch.field; \
-} \
-static inline void arch_set_##field(struct vcpu *v, \
-                                    type val) \
-{ \
-    if ( !IS_COMPAT(v->domain) ) \
-        v->vcpu_info->native.arch.field = val; \
-    else \
-        v->vcpu_info->compat.arch.field = val; \
+#define GET_SET_VCPU(type, field)                               \
+static inline type arch_get_##field(const struct vcpu *v)       \
+{                                                               \
+    return !has_32bit_shinfo(v->domain) ?                       \
+           v->vcpu_info->native.arch.field :                    \
+           v->vcpu_info->compat.arch.field;                     \
+}                                                               \
+static inline void arch_set_##field(struct vcpu *v,             \
+                                    type val)                   \
+{                                                               \
+    if ( !has_32bit_shinfo(v->domain) )                         \
+        v->vcpu_info->native.arch.field = val;                  \
+    else                                                        \
+        v->vcpu_info->compat.arch.field = val;                  \
 }
 
 #else
 
 #define nmi_reason(d) ((void *)&(d)->shared_info->arch.nmi_reason)
 
-#define GET_SET_SHARED(type, field) \
-static inline type arch_get_##field(const struct domain *d) \
-{ \
-    return d->shared_info->arch.field; \
-} \
-static inline void arch_set_##field(struct domain *d, \
-                                    type val) \
-{ \
-    d->shared_info->arch.field = val; \
+#define GET_SET_SHARED(type, field)                             \
+static inline type arch_get_##field(const struct domain *d)     \
+{                                                               \
+    return d->shared_info->arch.field;                          \
+}                                                               \
+static inline void arch_set_##field(struct domain *d,           \
+                                    type val)                   \
+{                                                               \
+    d->shared_info->arch.field = val;                           \
 }
 
-#define GET_SET_VCPU(type, field) \
-static inline type arch_get_##field(const struct vcpu *v) \
-{ \
-    return v->vcpu_info->arch.field; \
-} \
-static inline void arch_set_##field(struct vcpu *v, \
-                                    type val) \
-{ \
-    v->vcpu_info->arch.field = val; \
+#define GET_SET_VCPU(type, field)                               \
+static inline type arch_get_##field(const struct vcpu *v)       \
+{                                                               \
+    return v->vcpu_info->arch.field;                            \
+}                                                               \
+static inline void arch_set_##field(struct vcpu *v,             \
+                                    type val)                   \
+{                                                               \
+    v->vcpu_info->arch.field = val;                             \
 }
 #endif
 
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/x86_64/page.h
--- a/xen/include/asm-x86/x86_64/page.h Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/asm-x86/x86_64/page.h Sat Apr 28 10:28:59 2007 +0100
@@ -55,12 +55,12 @@ typedef l4_pgentry_t root_pgentry_t;
 
 #define is_guest_l1_slot(_s) (1)
 #define is_guest_l2_slot(_d, _t, _s)                   \
-    ( !IS_COMPAT(_d) ||                                \
+    ( !is_pv_32bit_domain(_d) ||                       \
       !((_t) & PGT_pae_xen_l2) ||                      \
       ((_s) < COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(_d)) )
 #define is_guest_l3_slot(_s) (1)
 #define is_guest_l4_slot(_d, _s)                    \
-    ( IS_COMPAT(_d)                                 \
+    ( is_pv_32bit_domain(_d)                        \
       ? ((_s) == 0)                                 \
       : (((_s) < ROOT_PAGETABLE_FIRST_XEN_SLOT) ||  \
          ((_s) > ROOT_PAGETABLE_LAST_XEN_SLOT)))
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/x86_64/regs.h
--- a/xen/include/asm-x86/x86_64/regs.h Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/asm-x86/x86_64/regs.h Sat Apr 28 10:28:59 2007 +0100
@@ -10,17 +10,17 @@
 #define ring_2(r)    (((r)->cs & 3) == 2)
 #define ring_3(r)    (((r)->cs & 3) == 3)
 
-#define guest_kernel_mode(v, r)   \
-    (!IS_COMPAT((v)->domain) ? \
-     ring_3(r) && ((v)->arch.flags & TF_kernel_mode) : \
-     ring_1(r))
+#define guest_kernel_mode(v, r)                                 \
+    (!is_pv_32bit_vcpu(v) ?                                     \
+     (ring_3(r) && ((v)->arch.flags & TF_kernel_mode)) :        \
+     (ring_1(r)))
 
 #define permit_softint(dpl, v, r) \
     ((dpl) >= (guest_kernel_mode(v, r) ? 1 : 3))
 
 /* Check for null trap callback handler: Is the EIP null? */
 #define null_trap_bounce(v, tb) \
-    (!IS_COMPAT((v)->domain) ? (tb)->eip == 0 : ((tb)->cs & ~3) == 0)
+    (!is_pv_32bit_vcpu(v) ? ((tb)->eip == 0) : (((tb)->cs & ~3) == 0))
 
 /* Number of bytes of on-stack execution state to be context-switched. */
 /* NB. Segment registers and bases are not saved/restored on x86/64 stack. */
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h       Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/public/domctl.h       Sat Apr 28 10:28:59 2007 +0100
@@ -394,8 +394,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_setti
 #define XEN_DOMCTL_sethvmcontext     34
 typedef struct xen_domctl_hvmcontext {
     uint32_t size; /* IN/OUT: size of buffer / bytes filled */
-    XEN_GUEST_HANDLE(uint8_t) buffer; /* IN/OUT: data, or call gethvmcontext 
-                                       * with NULL buffer to get size req'd */
+    XEN_GUEST_HANDLE_64(uint8_t) buffer; /* IN/OUT: data, or call
+                                          * gethvmcontext with NULL
+                                          * buffer to get size
+                                          * req'd */
 } xen_domctl_hvmcontext_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t);
 
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/public/hvm/save.h
--- a/xen/include/public/hvm/save.h     Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/public/hvm/save.h     Sat Apr 28 10:28:59 2007 +0100
@@ -32,7 +32,8 @@
 /*
  * Structures in this header *must* have the same layout in 32bit 
  * and 64bit environments: this means that all fields must be explicitly 
- * sized types and aligned to their sizes.
+ * sized types and aligned to their sizes, and the structs must be 
+ * a multiple of eight bytes long.
  *
  * Only the state necessary for saving and restoring (i.e. fields 
  * that are analogous to actual hardware state) should go in this file. 
@@ -77,6 +78,7 @@ struct hvm_save_header {
     uint32_t version;           /* File format version */
     uint64_t changeset;         /* Version of Xen that saved this file */
     uint32_t cpuid;             /* CPUID[0x01][%eax] on the saving machine */
+    uint32_t pad0;
 };
 
 DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
@@ -340,6 +342,7 @@ struct hvm_hw_pci_link {
      * The router provides a programmable mapping from each link to a GSI.
      */
     uint8_t route[4];
+    uint8_t pad0[4];
 };
 
 DECLARE_HVM_SAVE_TYPE(PCI_LINK, 9, struct hvm_hw_pci_link);
@@ -364,6 +367,7 @@ struct hvm_hw_pit {
         uint8_t gate; /* timer start */
     } channels[3];  /* 3 x 16 bytes */
     uint32_t speaker_data_on;
+    uint32_t pad0;
 };
 
 DECLARE_HVM_SAVE_TYPE(PIT, 10, struct hvm_hw_pit);
@@ -379,6 +383,7 @@ struct hvm_hw_rtc {
     uint8_t cmos_data[RTC_CMOS_SIZE];
     /* Index register for 2-part operations */
     uint8_t cmos_index;
+    uint8_t pad0;
 };
 
 DECLARE_HVM_SAVE_TYPE(RTC, 11, struct hvm_hw_rtc);
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/xen/sched.h   Sat Apr 28 10:28:59 2007 +0100
@@ -188,8 +188,6 @@ struct domain
     bool_t           is_privileged;
     /* Is this guest being debugged by dom0? */
     bool_t           debugger_attached;
-    /* Is a 'compatibility mode' guest (semantics are arch specific)? */
-    bool_t           is_compat;
     /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
     bool_t           is_polling;
     /* Is this guest dying (i.e., a zombie)? */
@@ -489,10 +487,8 @@ static inline void vcpu_unblock(struct v
 
 #define IS_PRIV(_d) ((_d)->is_privileged)
 
-#ifdef CONFIG_COMPAT
-#define IS_COMPAT(_d) ((_d)->is_compat)
-#else
-#define IS_COMPAT(_d) 0
+#ifndef IS_COMPAT
+#define IS_COMPAT(d) 0
 #endif
 
 #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist))
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/xen/shared.h
--- a/xen/include/xen/shared.h  Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/xen/shared.h  Sat Apr 28 10:28:59 2007 +0100
@@ -12,25 +12,27 @@ typedef union {
     struct compat_shared_info compat;
 } shared_info_t;
 
-#define __shared_info(d, s, field)      (*(!IS_COMPAT(d) ? \
-                                           &(s)->native.field : \
+#define __shared_info(d, s, field)      (*(!has_32bit_shinfo(d) ?       \
+                                           &(s)->native.field :         \
                                            &(s)->compat.field))
-#define __shared_info_addr(d, s, field) (!IS_COMPAT(d) ? \
-                                         (void *)&(s)->native.field : \
+#define __shared_info_addr(d, s, field) (!has_32bit_shinfo(d) ?         \
+                                         (void *)&(s)->native.field :   \
                                          (void *)&(s)->compat.field)
 
-#define shared_info(d, field)      __shared_info(d, (d)->shared_info, field)
-#define shared_info_addr(d, field) __shared_info_addr(d, (d)->shared_info, 
field)
+#define shared_info(d, field)                   \
+    __shared_info(d, (d)->shared_info, field)
+#define shared_info_addr(d, field)                      \
+    __shared_info_addr(d, (d)->shared_info, field)
 
 typedef union {
     struct vcpu_info native;
     struct compat_vcpu_info compat;
 } vcpu_info_t;
 
-#define vcpu_info(v, field)      (*(!IS_COMPAT((v)->domain) ? \
-                                    &(v)->vcpu_info->native.field : \
+#define vcpu_info(v, field)      (*(!has_32bit_shinfo((v)->domain) ?    \
+                                    &(v)->vcpu_info->native.field :     \
                                     &(v)->vcpu_info->compat.field))
-#define vcpu_info_addr(v, field) (!IS_COMPAT((v)->domain) ? \
+#define vcpu_info_addr(v, field) (!has_32bit_shinfo((v)->domain) ?        \
                                   (void *)&(v)->vcpu_info->native.field : \
                                   (void *)&(v)->vcpu_info->compat.field)
 
diff -r ee16cdeddade -r 1668299c0ea4 xen/include/xlat.lst
--- a/xen/include/xlat.lst      Wed Apr 25 10:39:08 2007 +0100
+++ b/xen/include/xlat.lst      Sat Apr 28 10:28:59 2007 +0100
@@ -9,7 +9,6 @@
 !      cpu_user_regs                   arch-x86/xen-@arch@.h
 !      trap_info                       arch-x86/xen.h
 !      vcpu_guest_context              arch-x86/xen.h
-?      acm_getdecision                 acm_ops.h
 ?      evtchn_alloc_unbound            event_channel.h
 ?      evtchn_bind_interdomain         event_channel.h
 ?      evtchn_bind_ipi                 event_channel.h

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-3.0.5-testing] Merge with xen-unstable for 3.0.5-rc4., Xen patchbot-3.0.5-testing <=