WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] [xen-unstable] Merge.

# HG changeset patch
# User Steven Smith <ssmith@xxxxxxxxxxxxx>
# Date 1177677069 -3600
# Node ID 3c352bbc894dad767255a3103bf9d81594354736
# Parent  491bed0350f1f813951f6e45c291512bb58b0632
# Parent  499e50c3115f0e7fd62bedb083119edb76cdb18c
Merge.
---
 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 
 tools/blktap/drivers/block-qcow.c                                           |  
 67 +
 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/python/xen/xend/XendAPI.py                                            |  
343 ++-------
 tools/python/xen/xend/XendAPIStore.py                                       |  
 59 +
 tools/python/xen/xend/XendBase.py                                           |  
126 +++
 tools/python/xen/xend/XendConfig.py                                         |  
  7 
 tools/python/xen/xend/XendDomain.py                                         |  
  6 
 tools/python/xen/xend/XendDomainInfo.py                                     |  
 13 
 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/main.py                                                 |  
108 ++
 tools/python/xen/xm/messages/en/xen-xm.po                                   |  
 24 
 tools/python/xen/xm/xenapi_create.py                                        |  
 69 +
 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/acm/acm_policy.c                                                        |  
  8 
 xen/arch/x86/domain.c                                                       |  
 40 -
 xen/arch/x86/hvm/vmx/intr.c                                                 |  
  3 
 xen/arch/x86/hvm/vmx/vmcs.c                                                 |  
 86 +-
 xen/arch/x86/mm.c                                                           |  
  5 
 xen/arch/x86/mm/shadow/common.c                                             |  
 14 
 xen/arch/x86/mm/shadow/multi.c                                              |  
 35 
 xen/arch/x86/x86_32/entry.S                                                 |  
 11 
 xen/arch/x86/x86_64/compat/entry.S                                          |  
 26 
 xen/arch/x86/x86_64/entry.S                                                 |  
 22 
 xen/arch/x86/x86_64/traps.c                                                 |  
  3 
 xen/common/Makefile                                                         |  
  1 
 xen/common/acm_ops.c                                                        |  
 49 -
 xen/include/Makefile                                                        |  
  2 
 xen/include/acm/acm_core.h                                                  |  
  8 
 xen/include/asm-x86/domain.h                                                |  
 21 
 xen/include/asm-x86/hvm/vmx/vmcs.h                                          |  
  2 
 xen/include/asm-x86/shadow.h                                                |  
 10 
 xen/include/public/hvm/save.h                                               |  
  7 
 xen/include/xlat.lst                                                        |  
  1 
 65 files changed, 1735 insertions(+), 1107 deletions(-)

diff -r 491bed0350f1 -r 3c352bbc894d docs/man/xm.pod.1
--- a/docs/man/xm.pod.1 Fri Apr 27 13:25:58 2007 +0100
+++ b/docs/man/xm.pod.1 Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/blktap/drivers/block-qcow.c Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/firmware/hvmloader/acpi/acpi2_0.h
--- a/tools/firmware/hvmloader/acpi/acpi2_0.h   Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/firmware/hvmloader/acpi/acpi2_0.h   Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/firmware/hvmloader/config.h Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c      Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/firmware/hvmloader/hypercall.h
--- a/tools/firmware/hvmloader/hypercall.h      Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/firmware/hvmloader/hypercall.h      Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/firmware/hvmloader/smbios.c Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/firmware/hvmloader/smbios.h
--- a/tools/firmware/hvmloader/smbios.h Fri Apr 27 13:25:58 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 491bed0350f1 -r 3c352bbc894d tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c   Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/firmware/hvmloader/util.c   Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/firmware/hvmloader/util.h   Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/firmware/rombios/rombios.c  Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/ioemu/hw/pc.c       Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/libxc/xc_core_x86.c
--- a/tools/libxc/xc_core_x86.c Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/libxc/xc_core_x86.c Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/libxc/xc_dom_core.c
--- a/tools/libxc/xc_dom_core.c Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/libxc/xc_dom_core.c Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/libxc/xc_domain_save.c      Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/libxc/xc_hvm_build.c        Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendAPI.py  Fri Apr 27 13:31:09 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
@@ -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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendAPIStore.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/XendAPIStore.py     Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendBase.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/XendBase.py Fri Apr 27 13:31:09 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 [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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendConfig.py       Fri Apr 27 13:31:09 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",
@@ -1049,6 +1050,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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendDomain.py       Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Fri Apr 27 13:31:09 2007 +0100
@@ -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"
@@ -2246,9 +2246,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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py        Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendError.py        Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendNetwork.py
--- a/tools/python/xen/xend/XendNetwork.py      Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendNetwork.py      Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendNode.py Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendPBD.py
--- a/tools/python/xen/xend/XendPBD.py  Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendPBD.py  Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendPIF.py
--- a/tools/python/xen/xend/XendPIF.py  Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendPIF.py  Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendPIFMetrics.py
--- a/tools/python/xen/xend/XendPIFMetrics.py   Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendPIFMetrics.py   Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d 
tools/python/xen/xend/XendQCoWStorageRepo.py
--- a/tools/python/xen/xend/XendQCoWStorageRepo.py      Fri Apr 27 13:25:58 
2007 +0100
+++ b/tools/python/xen/xend/XendQCoWStorageRepo.py      Fri Apr 27 13:31:09 
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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendStateStore.py
--- a/tools/python/xen/xend/XendStateStore.py   Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendStateStore.py   Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d 
tools/python/xen/xend/XendStorageRepository.py
--- a/tools/python/xen/xend/XendStorageRepository.py    Fri Apr 27 13:25:58 
2007 +0100
+++ b/tools/python/xen/xend/XendStorageRepository.py    Fri Apr 27 13:31:09 
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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/XendVMMetrics.py
--- a/tools/python/xen/xend/XendVMMetrics.py    Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/XendVMMetrics.py    Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xend/server/SrvServer.py Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xm/create.dtd
--- a/tools/python/xen/xm/create.dtd    Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xm/create.dtd    Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xm/main.py       Fri Apr 27 13:31:09 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()]
 
@@ -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'], record['uuid'])
+                             for record in server.xenapi.network
+                             .get_all_records()])
+            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,93 @@ 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'], record['uuid'])
+                     for record in
+                     server.xenapi.network.get_all_records()])
+
+    if network not in networks.keys():
+        raise ValueError("'%s' is not a valid network name" % network)
+    
+    server.xenapi.network.destroy(networks[network])
+
+def uuid_dict_trans(records):
+    return dict([(record['uuid'], record)
+                 for record in records])
+
+def xm_network_show(args):
+    xenapi_only()
+    arg_check(args, "network-show", 0)
+
+    networks = server.xenapi.network.get_all_records()
+    pifs     = uuid_dict_trans(
+        server.xenapi.PIF.get_all_records())
+    vifs     = uuid_dict_trans(
+        server.xenapi.VIF.get_all_records())
+
+    print '%-20s %-40s %-10s' % \
+          ('Name', 'VIFs', 'PIFs')
+    
+    format2 = "%(name_label)-20s %(vif)-40s %(pif)-10s"
+
+    for network in networks:
+        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, {'device':''}) 
+            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 +2367,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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xm/messages/en/xen-xm.po
--- a/tools/python/xen/xm/messages/en/xen-xm.po Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xm/messages/en/xen-xm.po Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py      Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/python/xen/xm/xenapi_create.py      Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d 
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      Fri Apr 27 13:31:09 
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 491bed0350f1 -r 3c352bbc894d 
tools/xm-test/tests/network-attach/01_network_attach_pos.py
--- a/tools/xm-test/tests/network-attach/01_network_attach_pos.py       Fri Apr 
27 13:25:58 2007 +0100
+++ b/tools/xm-test/tests/network-attach/01_network_attach_pos.py       Fri Apr 
27 13:31:09 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 491bed0350f1 -r 3c352bbc894d 
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        
Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py        
Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d 
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   
    Fri Apr 27 13:25:58 2007 +0100
+++ 
b/tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py   
    Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d 
tools/xm-test/tests/network-attach/network_utils.py
--- a/tools/xm-test/tests/network-attach/network_utils.py       Fri Apr 27 
13:25:58 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 491bed0350f1 -r 3c352bbc894d 
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   Fri Apr 27 13:31:09 
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 491bed0350f1 -r 3c352bbc894d tools/xm-test/tests/xapi/Makefile.am
--- a/tools/xm-test/tests/xapi/Makefile.am      Fri Apr 27 13:25:58 2007 +0100
+++ b/tools/xm-test/tests/xapi/Makefile.am      Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c      Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/acm/acm_policy.c      Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/arch/x86/domain.c     Fri Apr 27 13:31:09 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)
@@ -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 (pv_32on64_vcpu(v) ? setup_compat_l4(v) : 0);
 }
 
 void vcpu_destroy(struct vcpu *v)
 {
-    if ( IS_COMPAT(v->domain) )
+    if ( pv_32on64_vcpu(v) )
         release_compat_l4(v);
 }
 
@@ -491,7 +489,7 @@ void arch_domain_destroy(struct domain *
     free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3));
 #endif
 
-    if ( IS_COMPAT(d) )
+    if ( pv_32on64_domain(d) )
         release_arg_xlat_area(d);
 
     free_xenheap_page(d->shared_info);
@@ -508,7 +506,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 = pv_32on64_domain(d);
 
 #ifdef CONFIG_COMPAT
 #define c(fld) (compat ? (c.cmp->fld) : (c.nat->fld))
@@ -1268,7 +1266,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 +1447,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 ( pv_32on64_vcpu(v) )
+    {
+        pfn = l4e_get_pfn(*(l4_pgentry_t *)
+                          __va(pagetable_get_paddr(v->arch.guest_table)));
 
         if ( pfn != 0 )
         {
@@ -1466,12 +1461,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 491bed0350f1 -r 3c352bbc894d xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/intr.c       Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/arch/x86/mm.c Fri Apr 27 13:31:09 2007 +0100
@@ -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(
diff -r 491bed0350f1 -r 3c352bbc894d xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/arch/x86/mm/shadow/common.c   Fri Apr 27 13:31:09 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
+           (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(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 ( pv_32on64_domain(d) )
         d->arch.paging.shadow.opt_flags = SHOPT_LINUX_L3_TOPLEVEL;
 #endif
 
diff -r 491bed0350f1 -r 3c352bbc894d xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/arch/x86/mm/shadow/multi.c    Fri Apr 27 13:31:09 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 ( !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 ( !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) && !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)                                            \
+             || !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 ( 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 ( !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 ( 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 ( 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 ( 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) && !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))
+                                       pv_32on64_vcpu(v))
                                       && !shadow_mode_external(v->domain)
                                       && (guest_index(gl3e) % 4) == 3)
                                      ? SH_type_l2h_shadow
diff -r 491bed0350f1 -r 3c352bbc894d xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/arch/x86/x86_32/entry.S       Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S        Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/arch/x86/x86_64/compat/entry.S        Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/arch/x86/x86_64/entry.S       Fri Apr 27 13:31:09 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,7 +231,7 @@ 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
@@ -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
@@ -401,6 +400,7 @@ 1:      movq  %rsp,%rdi
         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 491bed0350f1 -r 3c352bbc894d xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/arch/x86/x86_64/traps.c       Fri Apr 27 13:31:09 2007 +0100
@@ -357,9 +357,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;
     tb->eip   = ti->address;
diff -r 491bed0350f1 -r 3c352bbc894d xen/common/Makefile
--- a/xen/common/Makefile       Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/common/Makefile       Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/common/acm_ops.c
--- a/xen/common/acm_ops.c      Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/common/acm_ops.c      Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/common/compat/acm_ops.c
--- a/xen/common/compat/acm_ops.c       Fri Apr 27 13:25:58 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 491bed0350f1 -r 3c352bbc894d xen/include/Makefile
--- a/xen/include/Makefile      Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/include/Makefile      Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/include/acm/acm_core.h
--- a/xen/include/acm/acm_core.h        Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/include/acm/acm_core.h        Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/include/asm-x86/domain.h      Fri Apr 27 13:31:09 2007 +0100
@@ -7,11 +7,24 @@
 #include <asm/hvm/domain.h>
 #include <asm/e820.h>
 
+#ifdef __x86_64__
+#define pv_32bit_vcpu(v)    (!is_hvm_vcpu(v) && IS_COMPAT((v)->domain))
+#define pv_32bit_domain(d)  (!is_hvm_domain(d) && IS_COMPAT(d))
+#define pv_32on64_vcpu(v)   (pv_32bit_vcpu(v))
+#define pv_32on64_domain(d) (pv_32bit_domain(d))
+#else
+#define pv_32bit_vcpu(v)    (!is_hvm_vcpu(v))
+#define pv_32bit_domain(d)  (!is_hvm_domain(d))
+#define pv_32on64_vcpu(v)   (0)
+#define pv_32on64_domain(d) (0)
+#endif
+
+
 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
diff -r 491bed0350f1 -r 3c352bbc894d xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/include/asm-x86/shadow.h      Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/include/public/hvm/save.h
--- a/xen/include/public/hvm/save.h     Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/include/public/hvm/save.h     Fri Apr 27 13:31:09 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 491bed0350f1 -r 3c352bbc894d xen/include/xlat.lst
--- a/xen/include/xlat.lst      Fri Apr 27 13:25:58 2007 +0100
+++ b/xen/include/xlat.lst      Fri Apr 27 13:31:09 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-unstable] Merge., Xen patchbot-unstable <=