[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.