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

[Xen-changelog] Merge



# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID cd914808acf1f5a32fc6fa575432cd96f9a4ad10
# Parent  903fb46f240eeafaeefbc32e31ea9a3b00fb906f
# Parent  5b30599761b3f0b85e6bb1768f0236294881e900
Merge

diff -r 903fb46f240e -r cd914808acf1 .hgignore
--- a/.hgignore Tue Jan  3 14:59:00 2006
+++ b/.hgignore Tue Jan  3 16:19:20 2006
@@ -181,6 +181,7 @@
 ^xen/TAGS$
 ^xen/arch/x86/asm-offsets\.s$
 ^xen/arch/x86/boot/mkelf32$
+^xen/arch/x86/xen\.lds$
 ^xen/ddb/.*$
 ^xen/include/asm$
 ^xen/include/asm-.*/asm-offsets\.h$
diff -r 903fb46f240e -r cd914808acf1 
linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Tue Jan  3 14:59:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Tue Jan  3 16:19:20 2006
@@ -389,6 +389,30 @@
        return -ENOSYS;
 }
 
+static int __init
+gnttab_proc_init(void)
+{
+       /*
+        *  /proc/xen/grant : used by libxc to access grant tables
+        */
+       if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) {
+               WPRINTK("Unable to create grant xen proc entry\n");
+               return -1;
+       }
+
+       grant_file_ops.read   = grant_pde->proc_fops->read;
+       grant_file_ops.write  = grant_pde->proc_fops->write;
+
+       grant_pde->proc_fops  = &grant_file_ops;
+
+       grant_pde->read_proc  = &grant_read;
+       grant_pde->write_proc = &grant_write;
+
+       return 0;
+}
+
+device_initcall(gnttab_proc_init);
+
 #endif /* CONFIG_PROC_FS */
 
 int
@@ -446,29 +470,11 @@
        gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
        gnttab_free_head  = NR_RESERVED_ENTRIES;
 
-#ifdef CONFIG_PROC_FS
-       /*
-        *  /proc/xen/grant : used by libxc to access grant tables
-        */
-       if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) {
-               WPRINTK("Unable to create grant xen proc entry\n");
-               return -1;
-       }
-
-       grant_file_ops.read   = grant_pde->proc_fops->read;
-       grant_file_ops.write  = grant_pde->proc_fops->write;
-
-       grant_pde->proc_fops  = &grant_file_ops;
-
-       grant_pde->read_proc  = &grant_read;
-       grant_pde->write_proc = &grant_write;
-#endif
-
        printk("Grant table initialized\n");
        return 0;
 }
 
-__initcall(gnttab_init);
+core_initcall(gnttab_init);
 
 /*
  * Local variables:
diff -r 903fb46f240e -r cd914808acf1 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue Jan  3 
14:59:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue Jan  3 
16:19:20 2006
@@ -331,7 +331,12 @@
                return;
        }
 
-        xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
+       err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
+       if (err) {
+               xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
+                                info->xbdev->otherend);
+               return;
+       }
 
        (void)xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected); 
 
diff -r 903fb46f240e -r cd914808acf1 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Jan  3 14:59:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Jan  3 16:19:20 2006
@@ -82,7 +82,7 @@
 #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
 
 void netif_creditlimit(netif_t *netif);
-int  netif_disconnect(netif_t *netif);
+void netif_disconnect(netif_t *netif);
 
 netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
 void free_netif(netif_t *netif);
diff -r 903fb46f240e -r cd914808acf1 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Tue Jan  3 
14:59:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Tue Jan  3 
16:19:20 2006
@@ -196,9 +196,13 @@
                return 0;
 
        netif->tx_comms_area = alloc_vm_area(PAGE_SIZE);
+       if (netif->tx_comms_area == NULL)
+               return -ENOMEM;
        netif->rx_comms_area = alloc_vm_area(PAGE_SIZE);
-       if (netif->tx_comms_area == NULL || netif->rx_comms_area == NULL)
+       if (netif->rx_comms_area == NULL) {
+               free_vm_area(netif->tx_comms_area);
                return -ENOMEM;
+       }
 
        err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref);
        if (err) {
@@ -247,13 +251,9 @@
 {
        netif_t *netif = (netif_t *)arg;
 
-       /* Already disconnected? */
-       if (!netif->irq)
-               return;
-
-       unbind_from_irqhandler(netif->irq, netif);
-       netif->irq = 0;
-
+       if (netif->irq)
+               unbind_from_irqhandler(netif->irq, netif);
+       
        unregister_netdev(netif->dev);
 
        if (netif->tx.sring) {
@@ -290,10 +290,10 @@
 #endif
 }
 
-int netif_disconnect(netif_t *netif)
-{
-
-       if (netif->status == CONNECTED) {
+void netif_disconnect(netif_t *netif)
+{
+       switch (netif->status) {
+       case CONNECTED:
                rtnl_lock();
                netif->status = DISCONNECTING;
                wmb();
@@ -301,10 +301,14 @@
                        __netif_down(netif);
                rtnl_unlock();
                netif_put(netif);
-               return 0; /* Caller should not send response message. */
-       }
-
-       return 1;
+               break;
+       case DISCONNECTED:
+               BUG_ON(atomic_read(&netif->refcnt) != 0);
+               free_netif(netif);
+               break;
+       default:
+               BUG();
+       }
 }
 
 /*
diff -r 903fb46f240e -r cd914808acf1 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Jan  3 
14:59:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Jan  3 
16:19:20 2006
@@ -116,6 +116,8 @@
 #define RX_MAX_TARGET NET_RX_RING_SIZE
        int rx_min_target, rx_max_target, rx_target;
        struct sk_buff_head rx_batch;
+
+       struct timer_list rx_refill_timer;
 
        /*
         * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
@@ -517,6 +519,13 @@
 }
 
 
+static void rx_refill_timeout(unsigned long data)
+{
+       struct net_device *dev = (struct net_device *)data;
+       netif_rx_schedule(dev);
+}
+
+
 static void network_alloc_rx_buffers(struct net_device *dev)
 {
        unsigned short id;
@@ -534,7 +543,7 @@
         * Allocate skbuffs greedily, even though we batch updates to the
         * receive ring. This creates a less bursty demand on the memory
         * allocator, so should reduce the chance of failed allocation requests
-        *  both for ourself and for other kernel subsystems.
+        * both for ourself and for other kernel subsystems.
         */
        batch_target = np->rx_target - (req_prod - np->rx.rsp_cons);
        for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
@@ -545,8 +554,15 @@
                skb = alloc_xen_skb(
                        ((PAGE_SIZE - sizeof(struct skb_shared_info)) &
                         (-SKB_DATA_ALIGN(1))) - 16);
-               if (skb == NULL)
-                       break;
+               if (skb == NULL) {
+                       /* Any skbuffs queued for refill? Force them out. */
+                       if (i != 0)
+                               goto refill;
+                       /* Could not allocate any skbuffs. Try again later. */
+                       mod_timer(&np->rx_refill_timer,
+                                 jiffies + (HZ/10));
+                       return;
+               }
                __skb_queue_tail(&np->rx_batch, skb);
        }
 
@@ -554,6 +570,12 @@
        if (i < (np->rx_target/2))
                return;
 
+       /* Adjust our fill target if we risked running out of buffers. */
+       if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) &&
+           ((np->rx_target *= 2) > np->rx_max_target))
+               np->rx_target = np->rx_max_target;
+
+ refill:
        for (i = 0; ; i++) {
                if ((skb = __skb_dequeue(&np->rx_batch)) == NULL)
                        break;
@@ -608,11 +630,6 @@
        /* Above is a suitable barrier to ensure backend will see requests. */
        np->rx.req_prod_pvt = req_prod + i;
        RING_PUSH_REQUESTS(&np->rx);
-
-       /* Adjust our fill target if we risked running out of buffers. */
-       if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) &&
-           ((np->rx_target *= 2) > np->rx_max_target))
-               np->rx_target = np->rx_max_target;
 }
 
 
@@ -1077,6 +1094,10 @@
        np->rx_min_target = RX_MIN_TARGET;
        np->rx_max_target = RX_MAX_TARGET;
 
+       init_timer(&np->rx_refill_timer);
+       np->rx_refill_timer.data = (unsigned long)netdev;
+       np->rx_refill_timer.function = rx_refill_timeout;
+
        /* Initialise {tx,rx}_skbs as a free chain containing every entry. */
        for (i = 0; i <= NET_TX_RING_SIZE; i++) {
                np->tx_skbs[i] = (void *)((unsigned long) i+1);
@@ -1188,33 +1209,14 @@
 
        DPRINTK("%s\n", dev->nodename);
 
-       netif_free(info);
-       kfree(info);
+       netif_disconnect_backend(info);
+       free_netdev(info->netdev);
 
        return 0;
 }
 
 
-static void netif_free(struct netfront_info *info)
-{
-       netif_disconnect_backend(info);
-       close_netdev(info);
-}
-
-
 static void close_netdev(struct netfront_info *info)
-{
-       if (info->netdev) {
-#ifdef CONFIG_PROC_FS
-               xennet_proc_delif(info->netdev);
-#endif
-               unregister_netdev(info->netdev);
-               info->netdev = NULL;
-       }
-}
-
-
-static void netif_disconnect_backend(struct netfront_info *info)
 {
        /* Stop old i/f to prevent errors whilst we rebuild the state. */
        spin_lock_irq(&info->tx_lock);
@@ -1223,17 +1225,37 @@
        /* info->backend_state = BEST_DISCONNECTED; */
        spin_unlock(&info->rx_lock);
        spin_unlock_irq(&info->tx_lock);
-    
+
+#ifdef CONFIG_PROC_FS
+       xennet_proc_delif(info->netdev);
+#endif
+
+       if (info->irq)
+               unbind_from_irqhandler(info->irq, info->netdev);
+       info->evtchn = info->irq = 0;
+
+       del_timer_sync(&info->rx_refill_timer);
+
+       unregister_netdev(info->netdev);
+}
+
+
+static void netif_disconnect_backend(struct netfront_info *info)
+{
        end_access(info->tx_ring_ref, info->tx.sring);
        end_access(info->rx_ring_ref, info->rx.sring);
        info->tx_ring_ref = GRANT_INVALID_REF;
        info->rx_ring_ref = GRANT_INVALID_REF;
        info->tx.sring = NULL;
        info->rx.sring = NULL;
-
-       if (info->irq)
-               unbind_from_irqhandler(info->irq, info->netdev);
-       info->evtchn = info->irq = 0;
+}
+
+
+static void netif_free(struct netfront_info *info)
+{
+       close_netdev(info);
+       netif_disconnect_backend(info);
+       free_netdev(info->netdev);
 }
 
 
diff -r 903fb46f240e -r cd914808acf1 tools/examples/xmexample.vmx
--- a/tools/examples/xmexample.vmx      Tue Jan  3 14:59:00 2006
+++ b/tools/examples/xmexample.vmx      Tue Jan  3 16:19:20 2006
@@ -29,6 +29,9 @@
 #-----------------------------------------------------------------------------
 # the number of cpus guest platform has, default=1
 vcpus=1
+
+# enable/disalbe vmx guest ACPI, default=0 (disabled)
+#acpi=0
 
 # List of which CPUS this domain is allowed to use, default Xen picks
 #cpus = ""         # leave to Xen to pick
diff -r 903fb46f240e -r cd914808acf1 tools/firmware/vmxassist/Makefile
--- a/tools/firmware/vmxassist/Makefile Tue Jan  3 14:59:00 2006
+++ b/tools/firmware/vmxassist/Makefile Tue Jan  3 16:19:20 2006
@@ -24,7 +24,7 @@
 # The emulator code lives in ROM space
 TEXTADDR=0x000D0000
 
-DEFINES=-DDEBUG -D_ACPI_ -DTEXTADDR=$(TEXTADDR)
+DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR)
 XENINC=-I$(XEN_ROOT)/tools/libxc
 
 LD       = ld
diff -r 903fb46f240e -r cd914808acf1 tools/firmware/vmxassist/acpi_madt.c
--- a/tools/firmware/vmxassist/acpi_madt.c      Tue Jan  3 14:59:00 2006
+++ b/tools/firmware/vmxassist/acpi_madt.c      Tue Jan  3 16:19:20 2006
@@ -24,23 +24,75 @@
 
 extern int puts(const char *s);
 
-#define VCPU_NR_PAGE        0x0009F000
-#define VCPU_NR_OFFSET      0x00000800
-#define VCPU_MAGIC          0x76637075  /* "vcpu" */
+#define HVM_INFO_PAGE  0x0009F000
+#define HVM_INFO_OFFSET        0x00000800
 
-/* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */
+struct hvm_info_table {
+       char     signature[8]; /* "HVM INFO" */
+       uint32_t length;
+       uint8_t  checksum;
+       uint8_t  acpi_enabled;
+       uint8_t  pad[2];
+       uint32_t nr_vcpus;
+};
+
+static struct hvm_info_table *table = NULL;
+
 static int
+checksum_valid(uint8_t *ptr, int len)
+{
+       uint8_t sum=0;
+       int i;
+
+       for (i = 0; i < len; i++)
+               sum += ptr[i];
+
+       return (sum == 0);
+}
+
+/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
+static struct hvm_info_table *
+get_hvm_info_table(void)
+{
+       struct hvm_info_table *t;
+       char signature[] = "HVM INFO";
+       int i;
+
+       if (table != NULL)
+               return table;
+
+       t = (struct hvm_info_table *)(HVM_INFO_PAGE + HVM_INFO_OFFSET);
+
+       /* strncmp(t->signature, "HVM INFO", 8) */
+       for (i = 0; i < 8; i++) {
+               if (signature[i] != t->signature[i]) {
+                       puts("Bad hvm info signature\n");
+                       return NULL;
+               }
+       }
+
+       if (!checksum_valid((uint8_t *)t, t->length)) {
+               puts("Bad hvm info checksum\n");
+               return NULL;
+       }
+
+       table = t;
+
+       return table;
+}
+
+int
 get_vcpu_nr(void)
 {
-       unsigned int *vcpus;
+       struct hvm_info_table *t = get_hvm_info_table();
+       return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
+}
 
-       vcpus = (unsigned int *)(VCPU_NR_PAGE + VCPU_NR_OFFSET);
-       if (vcpus[0] != VCPU_MAGIC) {
-               puts("Bad vcpus magic, set vcpu number to 1 by default.\n");
-               return 1;
-       }
-
-       return vcpus[1];
+int
+get_acpi_enabled(void)
+{
+       struct hvm_info_table *t = get_hvm_info_table();
+       return (t ? t->acpi_enabled : 0); /* default no acpi */
 }
 
 static void *
diff -r 903fb46f240e -r cd914808acf1 tools/firmware/vmxassist/vmxloader.c
--- a/tools/firmware/vmxassist/vmxloader.c      Tue Jan  3 14:59:00 2006
+++ b/tools/firmware/vmxassist/vmxloader.c      Tue Jan  3 16:19:20 2006
@@ -24,12 +24,10 @@
 #include "machine.h"
 #include "roms.h"
 
-#ifdef _ACPI_
 #include "acpi.h"
 #include "../acpi/acpi2_0.h"  // for ACPI_PHYSICAL_ADDRESS
 int acpi_madt_update(unsigned char* acpi_start);
-#endif
-
+int get_acpi_enabled(void);
 
 /*
  * C runtime start off
@@ -120,18 +118,17 @@
                memcpy((void *)0xC0000,
                        vgabios_stdvga, sizeof(vgabios_stdvga));
        }
-#ifdef _ACPI_
-       puts("Loading ACPI ...\n");
 
-       acpi_madt_update(acpi);
-
-       if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
-               /* make sure acpi table does not overlap rombios
-                * currently acpi less than 8K will be OK.
-                */
-                memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
+       if (get_acpi_enabled() != 0) {
+               puts("Loading ACPI ...\n");
+               acpi_madt_update((unsigned char*)acpi);
+               if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
+                       /* make sure acpi table does not overlap rombios
+                        * currently acpi less than 8K will be OK.
+                        */
+                       memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, 
sizeof(acpi));
+               }
        }
-#endif
 
        puts("Loading VMXAssist ...\n");
        memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
diff -r 903fb46f240e -r cd914808acf1 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Jan  3 14:59:00 2006
+++ b/tools/ioemu/vl.c  Tue Jan  3 16:19:20 2006
@@ -2948,6 +2948,7 @@
             case QEMU_OPTION_vcpus:
                 vcpus = atoi(optarg);
                 fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
+                break;
             case QEMU_OPTION_pci:
                 pci_enabled = 1;
                 break;
diff -r 903fb46f240e -r cd914808acf1 tools/libxc/Makefile
--- a/tools/libxc/Makefile      Tue Jan  3 14:59:00 2006
+++ b/tools/libxc/Makefile      Tue Jan  3 16:19:20 2006
@@ -27,6 +27,11 @@
 ifeq ($(XEN_TARGET_ARCH),x86_32)
 SRCS       += xc_ptrace.c
 SRCS       += xc_ptrace_core.c
+SRCS       += xc_pagetab.c
+endif
+
+ifeq ($(XEN_TARGET_ARCH),x86_64)
+SRCS       += xc_pagetab.c
 endif
 
 BUILD_SRCS :=
diff -r 903fb46f240e -r cd914808acf1 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Tue Jan  3 14:59:00 2006
+++ b/tools/libxc/xc_domain.c   Tue Jan  3 16:19:20 2006
@@ -404,6 +404,38 @@
 
 }
 
+int xc_domain_irq_permission(int xc_handle,
+                             uint32_t domid,
+                             uint8_t pirq,
+                             uint8_t allow_access)
+{
+    dom0_op_t op;
+
+    op.cmd = DOM0_IRQ_PERMISSION;
+    op.u.irq_permission.domain = domid;
+    op.u.irq_permission.pirq = pirq;
+    op.u.irq_permission.allow_access = allow_access;
+
+    return do_dom0_op(xc_handle, &op);
+}
+
+int xc_domain_iomem_permission(int xc_handle,
+                               uint32_t domid,
+                               unsigned long first_pfn,
+                               unsigned long nr_pfns,
+                               uint8_t allow_access)
+{
+    dom0_op_t op;
+
+    op.cmd = DOM0_IOMEM_PERMISSION;
+    op.u.iomem_permission.domain = domid;
+    op.u.iomem_permission.first_pfn = first_pfn;
+       op.u.iomem_permission.nr_pfns = nr_pfns;
+    op.u.iomem_permission.allow_access = allow_access;
+
+    return do_dom0_op(xc_handle, &op);
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 903fb46f240e -r cd914808acf1 tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c        Tue Jan  3 14:59:00 2006
+++ b/tools/libxc/xc_vmx_build.c        Tue Jan  3 16:19:20 2006
@@ -33,8 +33,17 @@
 #define E820_MAP_NR_OFFSET  0x000001E8
 #define E820_MAP_OFFSET     0x000002D0
 
-#define VCPU_NR_PAGE        0x0009F000
-#define VCPU_NR_OFFSET      0x00000800
+#define HVM_INFO_PAGE        0x0009F000
+#define HVM_INFO_OFFSET      0x00000800
+
+struct hvm_info_table {
+    char     signature[8]; /* "HVM INFO" */
+    uint32_t length;
+    uint8_t  checksum;
+    uint8_t  acpi_enabled;
+    uint8_t  pad[2];
+    uint32_t nr_vcpus;
+};
 
 struct e820entry {
     uint64_t addr;
@@ -119,26 +128,45 @@
     return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
 }
 
+static void 
+set_hvm_info_checksum(struct hvm_info_table *t)
+{
+    uint8_t *ptr = (uint8_t *)t, sum = 0;
+    unsigned int i;
+
+    t->checksum = 0;
+
+    for (i = 0; i < t->length; i++)
+        sum += *ptr++;
+
+    t->checksum = -sum;
+}
+
 /*
- * Use E820 reserved memory 0x9F800 to pass number of vcpus to vmxloader
- * vmxloader will use it to config ACPI MADT table
+ * Use E820 reserved memory 0x9F800 to pass HVM info to vmxloader
+ * vmxloader will use this info to set BIOS accordingly
  */
-#define VCPU_MAGIC      0x76637075  /* "vcpu" */
-static int set_vcpu_nr(int xc_handle, uint32_t dom,
-                        unsigned long *pfn_list, unsigned int vcpus)
-{
-    char         *va_map;
-    unsigned int *va_vcpus;
+static int set_hvm_info(int xc_handle, uint32_t dom,
+                        unsigned long *pfn_list, unsigned int vcpus,
+                        unsigned int acpi)
+{
+    char *va_map;
+    struct hvm_info_table *va_hvm;
 
     va_map = xc_map_foreign_range(xc_handle, dom,
                                   PAGE_SIZE, PROT_READ|PROT_WRITE,
-                                  pfn_list[VCPU_NR_PAGE >> PAGE_SHIFT]);
+                                  pfn_list[HVM_INFO_PAGE >> PAGE_SHIFT]);
     if ( va_map == NULL )
         return -1;
 
-    va_vcpus = (unsigned int *)(va_map + VCPU_NR_OFFSET);
-    va_vcpus[0] = VCPU_MAGIC;
-    va_vcpus[1] = vcpus;
+    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
+    memset(va_hvm, 0, sizeof(*va_hvm));
+    strncpy(va_hvm->signature, "HVM INFO", 8);
+    va_hvm->length       = sizeof(struct hvm_info_table);
+    va_hvm->acpi_enabled = acpi;
+    va_hvm->nr_vcpus     = vcpus;
+    
+    set_hvm_info_checksum(va_hvm);
 
     munmap(va_map, PAGE_SIZE);
 
@@ -281,6 +309,7 @@
                        unsigned int control_evtchn,
                        unsigned int lapic,
                        unsigned int vcpus,
+                       unsigned int acpi,
                        unsigned int store_evtchn,
                        unsigned long *store_mfn)
 {
@@ -490,8 +519,8 @@
             goto error_out;
     }
 
-    if (set_vcpu_nr(xc_handle, dom, page_array, vcpus)) {
-        fprintf(stderr, "Couldn't set vcpu number for VMX guest.\n");
+    if (set_hvm_info(xc_handle, dom, page_array, vcpus, acpi)) {
+        fprintf(stderr, "Couldn't set hvm info for VMX guest.\n");
         goto error_out;
     }
 
@@ -574,29 +603,6 @@
     return -1;
 }
 
-#define VMX_FEATURE_FLAG 0x20
-
-static int vmx_identify(void)
-{
-    int eax, ecx;
-
-    __asm__ __volatile__ (
-#if defined(__i386__)
-                          "push %%ebx; cpuid; pop %%ebx"
-#elif defined(__x86_64__)
-                          "push %%rbx; cpuid; pop %%rbx"
-#endif
-                          : "=a" (eax), "=c" (ecx)
-                          : "0" (1)
-                          : "dx");
-
-    if (!(ecx & VMX_FEATURE_FLAG)) {
-        return -1;
-    }
-
-    return 0;
-}
-
 int xc_vmx_build(int xc_handle,
                  uint32_t domid,
                  int memsize,
@@ -604,6 +610,7 @@
                  unsigned int control_evtchn,
                  unsigned int lapic,
                  unsigned int vcpus,
+                 unsigned int acpi,
                  unsigned int store_evtchn,
                  unsigned long *store_mfn)
 {
@@ -613,10 +620,18 @@
     unsigned long nr_pages;
     char         *image = NULL;
     unsigned long image_size;
-
-    if ( vmx_identify() < 0 )
-    {
-        PERROR("CPU doesn't support VMX Extensions");
+    xen_capabilities_info_t xen_caps;
+
+    if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 )
+    {
+        PERROR("Failed to get xen version info");
+        goto error_out;
+    }
+
+    if ( !strstr(xen_caps, "hvm") )
+    {
+        PERROR("CPU doesn't support VMX Extensions or "
+               "CPU VMX Extensions are not turned on");
         goto error_out;
     }
 
@@ -659,7 +674,7 @@
 
     if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
                      ctxt, op.u.getdomaininfo.shared_info_frame, 
control_evtchn,
-                     lapic, vcpus, store_evtchn, store_mfn) < 0)
+                     lapic, vcpus, acpi, store_evtchn, store_mfn) < 0)
     {
         ERROR("Error constructing guest OS");
         goto error_out;
diff -r 903fb46f240e -r cd914808acf1 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Tue Jan  3 14:59:00 2006
+++ b/tools/libxc/xenctrl.h     Tue Jan  3 16:19:20 2006
@@ -380,6 +380,17 @@
                                 uint32_t nr_ports,
                                 uint32_t allow_access);
 
+int xc_domain_irq_permission(int xc_handle,
+                             uint32_t domid,
+                             uint8_t pirq,
+                             uint8_t allow_access);
+
+int xc_domain_iomem_permission(int xc_handle,
+                               uint32_t domid,
+                               unsigned long first_pfn,
+                               unsigned long nr_pfns,
+                               uint8_t allow_access);
+
 unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid, 
                                    unsigned long mfn);
 
@@ -415,6 +426,19 @@
 
 void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
                            unsigned long *arr, int num );
+
+/**
+ * Translates a virtual address in the context of a given domain and
+ * vcpu returning the machine page frame number of the associated
+ * page.
+ *
+ * @parm xc_handle a handle on an open hypervisor interface
+ * @parm dom the domain to perform the translation in
+ * @parm vcpu the vcpu to perform the translation on
+ * @parm virt the virtual address to translate
+ */
+unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
+                                          int vcpu, unsigned long long virt);
 
 int xc_get_pfn_list(int xc_handle, uint32_t domid, unsigned long *pfn_buf, 
                     unsigned long max_pfns);
diff -r 903fb46f240e -r cd914808acf1 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Tue Jan  3 14:59:00 2006
+++ b/tools/libxc/xenguest.h    Tue Jan  3 16:19:20 2006
@@ -58,6 +58,7 @@
                  unsigned int control_evtchn,
                  unsigned int lapic,
                  unsigned int vcpus,
+                 unsigned int acpi,
                  unsigned int store_evtchn,
                  unsigned long *store_mfn);
 
diff -r 903fb46f240e -r cd914808acf1 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Tue Jan  3 14:59:00 2006
+++ b/tools/python/xen/lowlevel/xc/xc.c Tue Jan  3 16:19:20 2006
@@ -364,19 +364,20 @@
     int control_evtchn, store_evtchn;
     int vcpus = 1;
     int lapic = 0;
+    int acpi = 0;
     int memsize;
     unsigned long store_mfn = 0;
 
     static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
-                                "memsize", "image", "lapic", "vcpus", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list,
+                                "memsize", "image", "lapic", "vcpus", 
"acpi",NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisiii", kwd_list,
                                       &dom, &control_evtchn, &store_evtchn,
-                                      &memsize, &image, &lapic, &vcpus) )
+                                      &memsize, &image, &lapic, &vcpus,&acpi) )
         return NULL;
 
     if ( xc_vmx_build(self->xc_handle, dom, memsize, image, control_evtchn,
-                      lapic, vcpus, store_evtchn, &store_mfn) != 0 )
+                      lapic, vcpus, acpi, store_evtchn, &store_mfn) != 0 )
         return PyErr_SetFromErrno(xc_error);
 
     return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
@@ -774,6 +775,52 @@
     return zero;
 }
 
+static PyObject *pyxc_domain_irq_permission(PyObject *self,
+                                            PyObject *args,
+                                            PyObject *kwds)
+{
+    XcObject *xc = (XcObject *)self;
+    uint32_t dom;
+    int pirq, allow_access, ret;
+
+    static char *kwd_list[] = { "dom", "pirq", "allow_access", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list, 
+                                      &dom, &pirq, &allow_access) )
+        return NULL;
+
+    ret = xc_domain_irq_permission(
+        xc->xc_handle, dom, pirq, allow_access);
+    if ( ret != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    Py_INCREF(zero);
+    return zero;
+}
+
+static PyObject *pyxc_domain_iomem_permission(PyObject *self,
+                                               PyObject *args,
+                                               PyObject *kwds)
+{
+    XcObject *xc = (XcObject *)self;
+    uint32_t dom;
+    unsigned long first_pfn, nr_pfns, allow_access, ret;
+
+    static char *kwd_list[] = { "dom", "first_pfn", "nr_pfns", "allow_access", 
NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list, 
+                                      &dom, &first_pfn, &nr_pfns, 
&allow_access) )
+        return NULL;
+
+    ret = xc_domain_iomem_permission(
+        xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
+    if ( ret != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    Py_INCREF(zero);
+    return zero;
+}
+
 
 static PyObject *dom_op(XcObject *self, PyObject *args,
                         int (*fn)(int, uint32_t))
@@ -1067,6 +1114,25 @@
       " dom          [int]: Identifier of domain to be allowed access.\n"
       " first_port   [int]: First IO port\n"
       " nr_ports     [int]: Number of IO ports\n"
+      " allow_access [int]: Non-zero means enable access; else disable 
access\n\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+
+    { "domain_irq_permission",
+      (PyCFunction)pyxc_domain_irq_permission,
+      METH_VARARGS | METH_KEYWORDS, "\n"
+      "Allow a domain access to a physical IRQ\n"
+      " dom          [int]: Identifier of domain to be allowed access.\n"
+      " pirq         [int]: The Physical IRQ\n"
+      " allow_access [int]: Non-zero means enable access; else disable 
access\n\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+
+    { "domain_iomem_permission",
+      (PyCFunction)pyxc_domain_iomem_permission,
+      METH_VARARGS | METH_KEYWORDS, "\n"
+      "Allow a domain access to a range of IO memory pages\n"
+      " dom          [int]: Identifier of domain to be allowed access.\n"
+      " first_pfn   [long]: First page of I/O Memory\n"
+      " nr_pfns     [long]: Number of pages of I/O Memory (>0)\n"
       " allow_access [int]: Non-zero means enable access; else disable 
access\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
diff -r 903fb46f240e -r cd914808acf1 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Tue Jan  3 14:59:00 2006
+++ b/tools/python/xen/xend/image.py    Tue Jan  3 16:19:20 2006
@@ -189,11 +189,16 @@
     def configure(self, imageConfig, deviceConfig):
         ImageHandler.configure(self, imageConfig, deviceConfig)
 
+        info = xc.xeninfo()
+        if not 'hvm' in info['xen_caps']:
+            raise VmError("vmx: not an Intel VT platform, we stop creating!")
+
         self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
         self.device_model = sxp.child_value(imageConfig, 'device_model')
         if not self.device_model:
             raise VmError("vmx: missing device model")
         self.display = sxp.child_value(imageConfig, 'display')
+        self.xauthority = sxp.child_value(imageConfig, 'xauthority')
 
         self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
                         ("image/device-model", self.device_model),
@@ -209,6 +214,8 @@
         if not lapic is None:
             self.lapic = int(lapic)
 
+        self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0))
+        
     def buildDomain(self):
         # Create an event channel
         self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
@@ -224,6 +231,7 @@
         log.debug("memsize        = %d", self.vm.getMemoryTarget() / 1024)
         log.debug("lapic          = %d", self.lapic)
         log.debug("vcpus          = %d", self.vm.getVCpuCount())
+        log.debug("acpi           = %d", self.acpi)
 
         return xc.vmx_build(dom            = self.vm.getDomid(),
                             image          = self.kernel,
@@ -231,8 +239,8 @@
                             store_evtchn   = store_evtchn,
                             memsize        = self.vm.getMemoryTarget() / 1024,
                             lapic          = self.lapic,
+                            acpi           = self.acpi,
                             vcpus          = self.vm.getVCpuCount())
-
 
     # Return a list of cmd line args to the device models based on the
     # xm config file
@@ -264,44 +272,44 @@
         nics = 0
         for (name, info) in deviceConfig:
             if name == 'vbd':
-               uname = sxp.child_value(info, 'uname')
-               typedev = sxp.child_value(info, 'dev')
-               (_, vbdparam) = string.split(uname, ':', 1)
-               if re.match('^ioemu:', typedev):
-                  (emtype, vbddev) = string.split(typedev, ':', 1)
-               else:
-                  emtype = 'vbd'
-                  vbddev = typedev
-               if emtype != 'ioemu':
-                  continue;
-               vbddev_list = ['hda', 'hdb', 'hdc', 'hdd']
-               if vbddev not in vbddev_list:
-                  raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd")
-               ret.append("-%s" % vbddev)
-               ret.append("%s" % vbdparam)
+                uname = sxp.child_value(info, 'uname')
+                typedev = sxp.child_value(info, 'dev')
+                (_, vbdparam) = string.split(uname, ':', 1)
+                if 'ioemu:' in typedev:
+                    (emtype, vbddev) = string.split(typedev, ':', 1)
+                else:
+                    emtype = 'vbd'
+                    vbddev = typedev
+                if emtype == 'vbd':
+                    continue;
+                vbddev_list = ['hda', 'hdb', 'hdc', 'hdd']
+                if vbddev not in vbddev_list:
+                    raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd")
+                ret.append("-%s" % vbddev)
+                ret.append("%s" % vbdparam)
             if name == 'vif':
-               type = sxp.child_value(info, 'type')
-               if type != 'ioemu':
-                   continue
-               nics += 1
-               if mac != None:
-                   continue
-               mac = sxp.child_value(info, 'mac')
-               bridge = sxp.child_value(info, 'bridge')
-               if mac == None:
-                   mac = randomMAC()
-               if bridge == None:
-                   bridge = 'xenbr0'
-               ret.append("-macaddr")
-               ret.append("%s" % mac)
-               ret.append("-bridge")
-               ret.append("%s" % bridge)
+                type = sxp.child_value(info, 'type')
+                if type != 'ioemu':
+                    continue
+                nics += 1
+                if mac != None:
+                    continue
+                mac = sxp.child_value(info, 'mac')
+                bridge = sxp.child_value(info, 'bridge')
+                if mac == None:
+                    mac = randomMAC()
+                if bridge == None:
+                    bridge = 'xenbr0'
+                ret.append("-macaddr")
+                ret.append("%s" % mac)
+                ret.append("-bridge")
+                ret.append("%s" % bridge)
             if name == 'vtpm':
-               instance = sxp.child_value(info, 'pref_instance')
-               ret.append("-instance")
-               ret.append("%s" % instance)
+                instance = sxp.child_value(info, 'pref_instance')
+                ret.append("-instance")
+                ret.append("%s" % instance)
         ret.append("-nics")
-        ret.append("%d" % nics) 
+        ret.append("%d" % nics)
         return ret
 
     def configVNC(self, config):
@@ -340,6 +348,8 @@
         env = dict(os.environ)
         if self.display:
             env['DISPLAY'] = self.display
+        if self.xauthority:
+            env['XAUTHORITY'] = self.xauthority
         log.info("spawning device models: %s %s", self.device_model, args)
         self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
         log.info("device model pid: %d", self.pid)
diff -r 903fb46f240e -r cd914808acf1 tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py     Tue Jan  3 14:59:00 2006
+++ b/tools/python/xen/xend/server/blkif.py     Tue Jan  3 16:19:20 2006
@@ -31,7 +31,7 @@
     """Block device interface controller. Handles all block devices
     for a domain.
     """
-    
+
     def __init__(self, vm):
         """Create a block device controller.
         """
@@ -40,9 +40,9 @@
 
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
-        
+
         dev = sxp.child_value(config, 'dev')
-        if re.match('^ioemu:', dev):
+        if 'ioemu:' in dev:
             return (None,{},{})
 
         devid = blkif.blkdev_name_to_number(dev)
diff -r 903fb46f240e -r cd914808acf1 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Tue Jan  3 14:59:00 2006
+++ b/tools/python/xen/xm/create.py     Tue Jan  3 16:19:20 2006
@@ -164,6 +164,10 @@
           fn=set_int, default=0,
           use="Disable or enable local APIC of VMX domain.")
 
+gopts.var('acpi', val='ACPI',
+          fn=set_int, default=0,
+          use="Disable or enable ACPI of VMX domain.")
+
 gopts.var('vcpus', val='VCPUS',
           fn=set_int, default=1,
           use="# of Virtual CPUS in domain.")
@@ -387,6 +391,10 @@
 gopts.var('display', val='DISPLAY',
           fn=set_value, default=None,
           use="X11 display to use")
+
+gopts.var('xauthority', val='XAUTHORITY',
+          fn=set_value, default=None,
+          use="X11 Authority to use")
 
 
 def err(msg):
@@ -526,7 +534,8 @@
     """
     args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
              'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
-             'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic']
+             'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic',
+             'xauthority', 'acpi' ]
     for a in args:
         if (vals.__dict__[a]):
             config_image.append([a, vals.__dict__[a]])
@@ -801,6 +810,9 @@
     if not gopts.vals.display:
         gopts.vals.display = os.getenv("DISPLAY")
 
+    if not gopts.vals.xauthority:
+        gopts.vals.xauthority = os.getenv("XAUTHORITY")
+
     # Process remaining args as config variables.
     for arg in args:
         if '=' in arg:
diff -r 903fb46f240e -r cd914808acf1 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Tue Jan  3 14:59:00 2006
+++ b/tools/python/xen/xm/main.py       Tue Jan  3 16:19:20 2006
@@ -75,7 +75,7 @@
 vcpu_set_help = """vcpu-set <DomId> <VCPUs>         Set the number of VCPUs 
for a domain"""
 vcpu_list_help = "vcpu-list <DomId>                List the VCPUs for a domain 
(or all domains)"
 vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs>   Set which cpus a VCPU can 
use" 
-dmesg_help =   "dmesg [--clear]                  Read or clear Xen's message 
buffer"
+dmesg_help =   "dmesg [-c|--clear]               Read or clear Xen's message 
buffer"
 info_help =    "info                             Get information about the xen 
host"
 rename_help =  "rename <DomId> <New Name>        Rename a domain"
 log_help =     "log                              Print the xend log"
@@ -672,7 +672,7 @@
         server.xend_node_clear_dmesg()
 
 def xm_log(args):
-    arg_check(args, 'xm-log', 0)
+    arg_check(args, "log", 0)
     
     from xen.xend.XendClient import server
     print server.xend_node_log()
@@ -845,8 +845,8 @@
     "balloon": "mem-set",
     "set-vcpus": "vcpu-set",
     "vif-list": "network-list",
-    "vbd-create": "block-create",
-    "vbd-destroy": "block-destroy",
+    "vbd-create": "block-attach",
+    "vbd-destroy": "block-detach",
     "vbd-list": "block-list",
     }
 
diff -r 903fb46f240e -r cd914808acf1 tools/vtpm_manager/README
--- a/tools/vtpm_manager/README Tue Jan  3 14:59:00 2006
+++ b/tools/vtpm_manager/README Tue Jan  3 16:19:20 2006
@@ -53,11 +53,6 @@
 
 MANUAL_DM_LAUNCH             -> Must manually launch & kill VTPMs
 
-WELL_KNOWN_SRK_AUTH          -> Rather than randomly generating the password 
for the SRK,
-                                use a well known value. This is necessary for 
sharing use
-                                of the SRK across applications. Such as VTPM 
and Dom0
-                                measurement software.
-
 WELL_KNOWN_OWNER_AUTH        -> Rather than randomly generating the password 
for the owner,
                                 use a well known value. This is useful for 
debugging and for
                                 poor bios which do not support clearing TPM if 
OwnerAuth is
diff -r 903fb46f240e -r cd914808acf1 tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk       Tue Jan  3 14:59:00 2006
+++ b/tools/vtpm_manager/Rules.mk       Tue Jan  3 16:19:20 2006
@@ -56,8 +56,7 @@
 # Do not have manager launch DMs.
 #CFLAGS += -DMANUAL_DM_LAUNCH
 
-# Fixed SRK
-CFLAGS += -DWELL_KNOWN_SRK_AUTH
+# Fixed OwnerAuth
 #CFLAGS += -DWELL_KNOWN_OWNER_AUTH
 
 # TPM Hardware Device or TPM Simulator
diff -r 903fb46f240e -r cd914808acf1 tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c        Tue Jan  3 14:59:00 2006
+++ b/tools/vtpm_manager/manager/securestorage.c        Tue Jan  3 16:19:20 2006
@@ -65,7 +65,7 @@
   UINT32 i;
   struct pack_constbuf_t symkey_cipher32, data_cipher32;
   
-  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping[%d]: 0x", buffer_len(inbuf));
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Input[%d]: 0x", 
buffer_len(inbuf));
   for (i=0; i< buffer_len(inbuf); i++)
     vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
   vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
@@ -94,6 +94,12 @@
               BSG_TPM_SIZE32_DATA, &data_cipher32);
 
   vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of 
E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher));
+
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Output[%d]: 0x", 
buffer_len(sealed_data));
+  for (i=0; i< buffer_len(sealed_data); i++)
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_data->bytes[i]);
+  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
   goto egress;
 
  abort_egress:
@@ -125,7 +131,7 @@
 
   memset(&symkey, 0, sizeof(symkey_t));
 
-  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "envelope decrypting[%ld]: 0x", cipher_size);
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%ld]: 0x", 
cipher_size);
   for (i=0; i< cipher_size; i++)
     vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]);
   vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
@@ -155,6 +161,11 @@
   
   // Decrypt State
   TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, 
unsealed_data) );
+
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x", 
buffer_len(unsealed_data));
+  for (i=0; i< buffer_len(unsealed_data); i++)
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", unsealed_data->bytes[i]);
+  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   
   goto egress;
   
@@ -291,124 +302,175 @@
   return status;
 }
 
+
 TPM_RESULT VTPM_SaveService(void) {
   TPM_RESULT status=TPM_SUCCESS;
   int fh, dmis=-1;
-  
-  BYTE *flat_global;
-  int flat_global_size, bytes_written;
+
+  BYTE *flat_boot_key, *flat_dmis, *flat_enc;
+  buffer_t clear_flat_global, enc_flat_global;
   UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
+  UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
   struct pack_buf_t storage_key_pack = {storageKeySize, 
vtpm_globals->storageKeyWrap.bytes};
-  
+  struct pack_buf_t boot_key_pack = {bootKeySize, 
vtpm_globals->bootKeyWrap.bytes};
+
   struct hashtable_itr *dmi_itr;
   VTPM_DMI_RESOURCE *dmi_res;
-  
-  UINT32 flat_global_full_size;
-  
-  // Global Values needing to be saved
-  flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths
-    sizeof(UINT32) +       // storagekeysize
-    storageKeySize +       // storage key
-    hashtable_count(vtpm_globals->dmi_map) * // num DMIS
-    (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
-  
-  
-  flat_global = (BYTE *) malloc( flat_global_full_size);
-  
-  flat_global_size = BSG_PackList(flat_global, 4,
-                                 BSG_TPM_AUTHDATA, 
&vtpm_globals->owner_usage_auth,
-                                 BSG_TPM_AUTHDATA, 
&vtpm_globals->srk_usage_auth,
-                                 BSG_TPM_SECRET,   
&vtpm_globals->storage_key_usage_auth,
-                                 BSG_TPM_SIZE32_DATA, &storage_key_pack);
-  
+
+  UINT32 boot_key_size, flat_dmis_size;
+
+  // Initially fill these with buffer sizes for each data type. Later fill
+  // in actual size, once flattened.
+  boot_key_size =  sizeof(UINT32) +       // bootkeysize
+                   bootKeySize;           // boot key
+
+  TPMTRYRETURN(buffer_init(&clear_flat_global, 3*sizeof(TPM_DIGEST) + // Auths
+                                              sizeof(UINT32) +// storagekeysize
+                                              storageKeySize, NULL) ); // 
storage key
+
+  flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS 
(-1 for Dom0)
+                   (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
+
+  flat_boot_key = (BYTE *) malloc( boot_key_size );
+  flat_enc = (BYTE *) malloc( sizeof(UINT32) );
+  flat_dmis = (BYTE *) malloc( flat_dmis_size );
+
+  boot_key_size = BSG_PackList(flat_boot_key, 1,
+                               BSG_TPM_SIZE32_DATA, &boot_key_pack);
+
+  BSG_PackList(clear_flat_global.bytes, 3,
+                BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
+                BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
+                BSG_TPM_SIZE32_DATA, &storage_key_pack);
+
+  TPMTRYRETURN(envelope_encrypt(&clear_flat_global,
+                                &vtpm_globals->bootKey,
+                                &enc_flat_global) );
+
+  BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc);
+
   // Per DMI values to be saved
   if (hashtable_count(vtpm_globals->dmi_map) > 0) {
-    
+
     dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
     do {
       dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
       dmis++;
 
       // No need to save dmi0.
-      if (dmi_res->dmi_id == 0)        
-       continue;
-      
-      
-      flat_global_size += BSG_PackList( flat_global + flat_global_size, 3,
-                                       BSG_TYPE_UINT32, &dmi_res->dmi_id,
-                                       BSG_TPM_DIGEST, 
&dmi_res->NVM_measurement,
-                                       BSG_TPM_DIGEST, 
&dmi_res->DMI_measurement);
-      
+      if (dmi_res->dmi_id == 0)
+        continue;
+
+
+      flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 3,
+                                        BSG_TYPE_UINT32, &dmi_res->dmi_id,
+                                        BSG_TPM_DIGEST, 
&dmi_res->NVM_measurement,
+                                        BSG_TPM_DIGEST, 
&dmi_res->DMI_measurement);
+
     } while (hashtable_iterator_advance(dmi_itr));
   }
-  
-  //FIXME: Once we have a way to protect a TPM key, we should use it to 
-  //       encrypt this blob. BUT, unless there is a way to ensure the key is
-  //       not used by other apps, this encryption is useless.
+
   fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
   if (fh == -1) {
     vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", 
STATE_FILE);
     status = TPM_IOERROR;
     goto abort_egress;
   }
-  
-  if ( (bytes_written = write(fh, flat_global, flat_global_size)) != 
flat_global_size ) {
-    vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes 
written.\n", bytes_written, flat_global_size);
-    status = TPM_IOERROR;
-    goto abort_egress;
-  }
-  vtpm_globals->DMI_table_dirty = FALSE; 
-  
+
+  if ( ( write(fh, flat_boot_key, boot_key_size) != boot_key_size ) ||
+       ( write(fh, flat_enc, sizeof(UINT32)) != sizeof(UINT32) ) ||
+       ( write(fh, enc_flat_global.bytes, buffer_len(&enc_flat_global)) != 
buffer_len(&enc_flat_global) ) ||
+       ( write(fh, flat_dmis, flat_dmis_size) != flat_dmis_size ) ) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to completely write service data.\n");
+    status = TPM_IOERROR;
+    goto abort_egress;
+ }
+
+  vtpm_globals->DMI_table_dirty = FALSE;
+
   goto egress;
-  
+
  abort_egress:
  egress:
-  
-  free(flat_global);
+
+  free(flat_boot_key);
+  free(flat_enc);
+  buffer_free(&enc_flat_global);
+  free(flat_dmis);
   close(fh);
-  
+
   vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = 
%d)\n", (int) status, dmis);
   return status;
 }
 
 TPM_RESULT VTPM_LoadService(void) {
-  
+
   TPM_RESULT status=TPM_SUCCESS;
   int fh, stat_ret, dmis=0;
   long fh_size = 0, step_size;
-  BYTE *flat_global=NULL;
-  struct pack_buf_t storage_key_pack;
-  UINT32 *dmi_id_key;
-  
+  BYTE *flat_table=NULL;
+  buffer_t  unsealed_data;
+  struct pack_buf_t storage_key_pack, boot_key_pack;
+  UINT32 *dmi_id_key, enc_size;
+
   VTPM_DMI_RESOURCE *dmi_res;
   struct stat file_stat;
-  
+
+  TPM_HANDLE boot_key_handle;
+  TPM_AUTHDATA boot_usage_auth;
+  memset(&boot_usage_auth, 0, sizeof(TPM_AUTHDATA));
+
   fh = open(STATE_FILE, O_RDONLY );
   stat_ret = fstat(fh, &file_stat);
-  if (stat_ret == 0) 
+  if (stat_ret == 0)
     fh_size = file_stat.st_size;
   else {
     status = TPM_IOERROR;
     goto abort_egress;
   }
-  
-  flat_global = (BYTE *) malloc(fh_size);
-  
-  if ((long) read(fh, flat_global, fh_size) != fh_size ) {
-    status = TPM_IOERROR;
-    goto abort_egress;
-  }
-  
+
+  flat_table = (BYTE *) malloc(fh_size);
+
+  if ((long) read(fh, flat_table, fh_size) != fh_size ) {
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+
+  // Read Boot Key
+  step_size = BSG_UnpackList( flat_table, 2,
+                              BSG_TPM_SIZE32_DATA, &boot_key_pack,
+                              BSG_TYPE_UINT32, &enc_size);
+
+  TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, 0, 0) );
+  TPMTRYRETURN(buffer_append_raw(&vtpm_globals->bootKeyWrap, 
boot_key_pack.size, boot_key_pack.data) );
+
+  //Load Boot Key
+  TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
+                              TPM_SRK_KEYHANDLE,
+                              &vtpm_globals->bootKeyWrap,
+                              &SRK_AUTH,
+                              &boot_key_handle,
+                              &vtpm_globals->keyAuth,
+                              &vtpm_globals->bootKey,
+                              FALSE) );
+
+  TPMTRYRETURN( envelope_decrypt(enc_size,
+                                 flat_table + step_size,
+                                 vtpm_globals->manager_tcs_handle,
+                                 boot_key_handle,
+                                 (const TPM_AUTHDATA*) &boot_usage_auth,
+                                 &unsealed_data) );
+  step_size += enc_size;
+
   // Global Values needing to be saved
-  step_size = BSG_UnpackList( flat_global, 4,
-                             BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
-                             BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
-                             BSG_TPM_SECRET,   
&vtpm_globals->storage_key_usage_auth,
-                             BSG_TPM_SIZE32_DATA, &storage_key_pack);
-  
+  BSG_UnpackList( unsealed_data.bytes, 3,
+                  BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
+                  BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
+                  BSG_TPM_SIZE32_DATA, &storage_key_pack);
+
   TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
   TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, 
storage_key_pack.size, storage_key_pack.data) );
-  
+
   // Per DMI values to be saved
   while ( step_size < fh_size ){
     if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
@@ -417,35 +479,38 @@
     } else {
       dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
       dmis++;
-      
+
       dmi_res->connected = FALSE;
-      
-      step_size += BSG_UnpackList(flat_global + step_size, 3,
-                                 BSG_TYPE_UINT32, &dmi_res->dmi_id, 
-                                 BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
-                                 BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
-      
+
+      step_size += BSG_UnpackList(flat_table + step_size, 3,
+                                 BSG_TYPE_UINT32, &dmi_res->dmi_id,
+                                 BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
+                                 BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
+
       // install into map
       dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
       *dmi_id_key = dmi_res->dmi_id;
       if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
-       status = TPM_FAIL;
-       goto abort_egress;
+        status = TPM_FAIL;
+        goto abort_egress;
       }
-      
+
     }
-    
-  }
-  
+
+  }
+
   vtpmloginfo(VTPM_LOG_VTPM, "Loaded saved state (dmis = %d).\n", dmis);
   goto egress;
-  
+
  abort_egress:
   vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n", 
tpm_get_error_name(status));
  egress:
-  
-  free(flat_global);
+
+  free(flat_table);
   close(fh);
-  
+
+  // TODO: Could be nice and evict BootKey. (Need to add EvictKey to VTSP.
+
   return status;
 }
+
diff -r 903fb46f240e -r cd914808acf1 tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Tue Jan  3 14:59:00 2006
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Tue Jan  3 16:19:20 2006
@@ -74,16 +74,15 @@
 #endif
 
 // --------------------------- Well Known Auths --------------------------
-#ifdef WELL_KNOWN_SRK_AUTH
-static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff,
+const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff,
                                   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff};
-#endif
 
 #ifdef WELL_KNOWN_OWNER_AUTH
 static BYTE FIXED_OWNER_AUTH[20] =  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff,
                                   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff};
 #endif
-                                  
+
+
 // -------------------------- Hash table functions --------------------
 
 static unsigned int hashfunc32(void *ky) {
@@ -100,13 +99,7 @@
   
   TPM_RESULT status = TPM_SUCCESS;
   
-  // Generate Auth's for SRK & Owner
-#ifdef WELL_KNOWN_SRK_AUTH 
-  memcpy(vtpm_globals->srk_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA));
-#else    
-  Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) );  
-#endif
-  
+  // Generate Auth for Owner
 #ifdef WELL_KNOWN_OWNER_AUTH 
   memcpy(vtpm_globals->owner_usage_auth, FIXED_OWNER_AUTH, 
sizeof(TPM_AUTHDATA));
 #else    
@@ -116,14 +109,14 @@
   // Take Owership of TPM
   CRYPTO_INFO ek_cryptoInfo;
   
-  vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n");
   status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
   
   // If we can read PubEK then there is no owner and we should take it.
   if (status == TPM_SUCCESS) { 
+    vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. 
Creating Keys off existing SRK.\n");
     TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
                                    (const 
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 
-                                   (const 
TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+                                   &SRK_AUTH,
                                    &ek_cryptoInfo,
                                    &vtpm_globals->keyAuth)); 
   
@@ -142,7 +135,7 @@
   TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
                          TPM_ET_KEYHANDLE,
                          TPM_SRK_KEYHANDLE, 
-                         (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+                         &SRK_AUTH,
                          &sharedsecret, 
                          &osap) ); 
 
@@ -157,8 +150,43 @@
                                    &vtpm_globals->storageKeyWrap,
                                    &osap) );
   
-  vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
-  
+  // Generate boot key's auth
+  Crypto_GetRandom(  &vtpm_globals->storage_key_usage_auth, 
+                    sizeof(TPM_AUTHDATA) );
+  
+  TPM_AUTHDATA bootKeyWrapAuth;
+  memset(&bootKeyWrapAuth, 0, sizeof(bootKeyWrapAuth));
+  
+  TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
+                         TPM_ET_KEYHANDLE,
+                         TPM_SRK_KEYHANDLE, 
+                         &SRK_AUTH,
+                         &sharedsecret, 
+                         &osap) ); 
+
+  osap.fContinueAuthSession = FALSE;
+ 
+  // FIXME: This key protects the global secrets on disk. It should use TPM
+  //        PCR bindings to limit its use to legit configurations.
+  //        Current binds are open, implying a Trusted VM contains this code.
+  //        If this VM is not Trusted, use measurement and PCR bindings.
+  TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
+                                   TPM_KEY_BIND,
+                                   (const TPM_AUTHDATA*)&bootKeyWrapAuth,
+                                   TPM_SRK_KEYHANDLE, 
+                                   (const TPM_AUTHDATA*)&sharedsecret,
+                                   &vtpm_globals->bootKeyWrap,
+                                   &osap) );
+
+  // Populate CRYPTO_INFO vtpm_globals->bootKey. This does not load it into 
the TPM
+  TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
+                              TPM_SRK_KEYHANDLE,
+                              &vtpm_globals->bootKeyWrap,
+                              NULL,
+                              NULL,
+                              NULL,
+                              &vtpm_globals->bootKey,
+                              TRUE ) );
   goto egress;
   
  abort_egress:
@@ -278,24 +306,26 @@
 #endif
 
     // Check status of rx_fh. If necessary attempt to re-open it.    
+    char* s = NULL;
     if (*rx_fh < 0) {
 #ifdef VTPM_MULTI_VM
-      *rx_fh = open(VTPM_BE_DEV, O_RDWR);
+      s = VTPM_BE_DEV;
 #else
       if (threadType == BE_LISTENER_THREAD) 
   #ifdef DUMMY_BACKEND
-       *rx_fh = open("/tmp/in.fifo", O_RDWR);
+       s = "/tmp/in.fifo";
   #else
-        *rx_fh = open(VTPM_BE_DEV, O_RDWR);
+      s = VTPM_BE_DEV;
   #endif
       else  // DMI Listener   
-       *rx_fh = open(VTPM_RX_FIFO, O_RDWR);
+       s = VTPM_RX_FIFO;
+      *rx_fh = open(s, O_RDWR);
 #endif    
     }
     
     // Respond to failures to open rx_fh
     if (*rx_fh < 0) {
-      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n");
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh for %s.\n", s);
 #ifdef VTPM_MULTI_VM
       return TPM_IOERROR; 
 #else
@@ -713,7 +743,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 TPM_RESULT VTPM_Init_Service() {
-  TPM_RESULT status = TPM_FAIL;   
+  TPM_RESULT status = TPM_FAIL, serviceStatus;   
   BYTE *randomsead;
   UINT32 randomsize;
 
@@ -737,7 +767,7 @@
   
   // Create new TCS Object
   vtpm_globals->manager_tcs_handle = 0;
-  
+ 
   TPMTRYRETURN(TCS_create());
   
   // Create TCS Context for service
@@ -756,17 +786,24 @@
   vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
 
        // If failed, create new Service.
-  if (VTPM_LoadService() != TPM_SUCCESS)
+  serviceStatus = VTPM_LoadService();
+  if (serviceStatus == TPM_IOERROR) {
+    vtpmloginfo(VTPM_LOG_VTPM, "Failed to read service file. Assuming first 
time initialization.\n");
     TPMTRYRETURN( VTPM_Create_Service() );    
+  } else if (serviceStatus != TPM_SUCCESS) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing service file");
+    exit(1);
+  }
 
   //Load Storage Key 
   TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
                              TPM_SRK_KEYHANDLE,
                              &vtpm_globals->storageKeyWrap,
-                             (const 
TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+                             &SRK_AUTH,
                              &vtpm_globals->storageKeyHandle,
                              &vtpm_globals->keyAuth,
-                             &vtpm_globals->storageKey) );
+                             &vtpm_globals->storageKey,
+                              FALSE ) );
 
   // Create entry for Dom0 for control messages
   TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
@@ -797,12 +834,11 @@
                free (dmi_itr);
   }
   
-       
+  if ( (vtpm_globals->DMI_table_dirty) && (VTPM_SaveService() != TPM_SUCCESS) )
+    vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
+
   TCS_CloseContext(vtpm_globals->manager_tcs_handle);
-  
-  if ( (vtpm_globals->DMI_table_dirty) &&
-       (VTPM_SaveService() != TPM_SUCCESS) )
-    vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
+  TCS_destroy();
   
   hashtable_destroy(vtpm_globals->dmi_map, 1);
   free(vtpm_globals);
diff -r 903fb46f240e -r cd914808acf1 tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h     Tue Jan  3 14:59:00 2006
+++ b/tools/vtpm_manager/manager/vtpmpriv.h     Tue Jan  3 16:19:20 2006
@@ -108,6 +108,7 @@
   TCS_CONTEXT_HANDLE  manager_tcs_handle;     // TCS Handle used by manager
   TPM_HANDLE          storageKeyHandle;       // Key used by persistent store
   CRYPTO_INFO         storageKey;             // For software encryption
+  CRYPTO_INFO         bootKey;                // For saving table
   TCS_AUTH            keyAuth;                // OIAP session for storageKey 
   BOOL                DMI_table_dirty;        // Indicates that a command
                                               // has updated the DMI table
@@ -115,15 +116,17 @@
     
   // Persistent Data
   TPM_AUTHDATA        owner_usage_auth;       // OwnerAuth of real TPM
-  TPM_AUTHDATA        srk_usage_auth;         // SRK Auth of real TPM    
   buffer_t            storageKeyWrap;         // Wrapped copy of storageKey
+  TPM_AUTHDATA        srk_usage_auth;
+  TPM_AUTHDATA        storage_key_usage_auth; 
 
-  TPM_AUTHDATA        storage_key_usage_auth; 
-    
+  buffer_t            bootKeyWrap;            // Wrapped copy of boot key 
+
 }VTPM_GLOBALS;
 
-//Global dmi map
-extern VTPM_GLOBALS *vtpm_globals;
+// --------------------------- Global Values --------------------------
+extern VTPM_GLOBALS *vtpm_globals;   // Key info and DMI states
+extern const TPM_AUTHDATA SRK_AUTH;  // SRK Well Known Auth Value
 
 // ********************** Command Handler Prototypes ***********************
 TPM_RESULT VTPM_Handle_Load_NVM(       VTPM_DMI_RESOURCE *myDMI, 
diff -r 903fb46f240e -r cd914808acf1 tools/vtpm_manager/manager/vtsp.c
--- a/tools/vtpm_manager/manager/vtsp.c Tue Jan  3 14:59:00 2006
+++ b/tools/vtpm_manager/manager/vtsp.c Tue Jan  3 16:19:20 2006
@@ -563,63 +563,69 @@
                         const TPM_AUTHDATA          *parentAuth,
                         TPM_HANDLE                  *newKeyHandle,
                         TCS_AUTH                    *auth,
-                        CRYPTO_INFO                 *cryptoinfo /*= NULL*/) {
-  
-  
-  vtpmloginfo(VTPM_LOG_VTSP, "Loading Key.\n%s","");
+                        CRYPTO_INFO                 *cryptoinfo,
+                        const BOOL                  skipTPMLoad) { 
+  
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Loading Key %s.\n", (!skipTPMLoad ? "into TPM" : 
"only into memory"));
   
   TPM_RESULT status = TPM_SUCCESS;
   TPM_COMMAND_CODE command = TPM_ORD_LoadKey;
-  
-  BYTE *paramText;        // Digest to make Auth.
+
+  BYTE *paramText=NULL;        // Digest to make Auth.
   UINT32 paramTextSize;
-  
-  if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 
-      (newKeyHandle==NULL) || (auth==NULL)) {
-    status = TPM_BAD_PARAMETER;
-    goto abort_egress;
-  }
-  
-  // Generate Extra TCS Parameters
-  TPM_HANDLE phKeyHMAC;
-  
-  // Generate HMAC
-  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
-  
-  paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
-  
-  paramTextSize = BSG_PackList(paramText, 1,
-                              BSG_TPM_COMMAND_CODE, &command);
-  
-  memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, 
buffer_len(rgbWrappedKeyBlob));
-  paramTextSize += buffer_len(rgbWrappedKeyBlob);
-  
-  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+
+  // SkipTPMLoad stops key from being loaded into TPM, but still generates 
CRYPTO_INFO for it
+  if (! skipTPMLoad) { 
+  
+    if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 
+        (newKeyHandle==NULL) || (auth==NULL)) {
+      status = TPM_BAD_PARAMETER;
+      goto abort_egress;
+    }
+  
+    // Generate Extra TCS Parameters
+    TPM_HANDLE phKeyHMAC;
+  
+    // Generate HMAC
+    Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+    paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
+  
+    paramTextSize = BSG_PackList(paramText, 1,
+                                BSG_TPM_COMMAND_CODE, &command);
+  
+    memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, 
buffer_len(rgbWrappedKeyBlob));
+    paramTextSize += buffer_len(rgbWrappedKeyBlob);
+  
+    TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
                              parentAuth, auth) );
   
-  // Call TCS
-  TPMTRYRETURN( TCSP_LoadKeyByBlob(  hContext,
-                                    hUnwrappingKey,
-                                    buffer_len(rgbWrappedKeyBlob),
-                                    rgbWrappedKeyBlob->bytes,
-                                    auth,
-                                    newKeyHandle,
-                                    &phKeyHMAC) );
-  
-  // Verify Auth
-  paramTextSize = BSG_PackList(paramText, 3,
-                              BSG_TPM_RESULT, &status,
-                              BSG_TPM_COMMAND_CODE, &command,
-                              BSG_TPM_HANDLE, newKeyHandle);
-  
-  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
-                           parentAuth, auth, 
-                           hContext) );
-  
-  // Unpack/return key structure
+    // Call TCS
+    TPMTRYRETURN( TCSP_LoadKeyByBlob(  hContext,
+                                      hUnwrappingKey,
+                                      buffer_len(rgbWrappedKeyBlob),
+                                      rgbWrappedKeyBlob->bytes,
+                                      auth,
+                                      newKeyHandle,
+                                      &phKeyHMAC) );
+  
+    // Verify Auth
+    paramTextSize = BSG_PackList(paramText, 3,
+                                BSG_TPM_RESULT, &status,
+                                BSG_TPM_COMMAND_CODE, &command,
+                                BSG_TPM_HANDLE, newKeyHandle);
+  
+    TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+                             parentAuth, auth, 
+                             hContext) );
+  } 
+  
+  // Build cryptoinfo structure for software crypto function. 
   if (cryptoinfo != NULL) {
     TPM_KEY newKey;
     
+    // Unpack/return key structure
     BSG_Unpack(BSG_TPM_KEY, rgbWrappedKeyBlob->bytes , &newKey);
     TPM_RSA_KEY_PARMS rsaKeyParms;
     
diff -r 903fb46f240e -r cd914808acf1 tools/vtpm_manager/manager/vtsp.h
--- a/tools/vtpm_manager/manager/vtsp.h Tue Jan  3 14:59:00 2006
+++ b/tools/vtpm_manager/manager/vtsp.h Tue Jan  3 16:19:20 2006
@@ -86,7 +86,8 @@
                         const TPM_AUTHDATA          *parentAuth,
                         TPM_HANDLE                  *newKeyHandle,
                         TCS_AUTH                    *pAuth,
-                        CRYPTO_INFO                 *cryptoinfo);
+                        CRYPTO_INFO                 *cryptoinfo,
+                        const BOOL                  skipTPMLoad);
 
 TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE    hContext,
                         const TPM_KEY_HANDLE        key_handle,
diff -r 903fb46f240e -r cd914808acf1 tools/xentrace/Makefile
--- a/tools/xentrace/Makefile   Tue Jan  3 14:59:00 2006
+++ b/tools/xentrace/Makefile   Tue Jan  3 16:19:20 2006
@@ -15,25 +15,37 @@
 OBJS     = $(patsubst %.c,%.o,$(wildcard *.c))
 
 BIN      = xentrace tbctl setsize
+LIBBIN   = 
 SCRIPTS  = xentrace_format
 MAN1     = $(wildcard *.1)
 MAN8     = $(wildcard *.8)
 
+ifeq ($(XEN_TARGET_ARCH),x86_32)
+LIBBIN  += xenctx
+endif
+
+ifeq ($(XEN_TARGET_ARCH),x86_64)
+LIBBIN  += xenctx
+endif
+
 all: build
-build: $(BIN)
+build: $(BIN) $(LIBBIN)
 
 install: build
        [ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
+       [ -z "$(LIBBIN)"] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
+               $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
        [ -d $(DESTDIR)/usr/share/man/man1 ] || \
                $(INSTALL_DIR) $(DESTDIR)/usr/share/man/man1
        [ -d $(DESTDIR)/usr/share/man/man8 ] || \
                $(INSTALL_DIR) $(DESTDIR)/usr/share/man/man8
        $(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin
+       [ -z "$(LIBBIN)"] || $(INSTALL_PROG) $(LIBBIN) 
$(DESTDIR)/usr/$(LIBDIR)/xen/bin
        $(INSTALL_DATA) $(MAN1) $(DESTDIR)/usr/share/man/man1
        $(INSTALL_DATA) $(MAN8) $(DESTDIR)/usr/share/man/man8
 
 clean:
-       $(RM) *.a *.so *.o *.rpm $(BIN)
+       $(RM) *.a *.so *.o *.rpm $(BIN) $(LIBBIN)
 
 %: %.c $(HDRS) Makefile
        $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl
diff -r 903fb46f240e -r cd914808acf1 tools/xentrace/xenctx.c
--- a/tools/xentrace/xenctx.c   Tue Jan  3 14:59:00 2006
+++ b/tools/xentrace/xenctx.c   Tue Jan  3 16:19:20 2006
@@ -20,15 +20,184 @@
 #include <errno.h>
 #include <argp.h>
 #include <signal.h>
+#include <string.h>
+#include <getopt.h>
 
 #include "xenctrl.h"
+
+int xc_handle = 0;
+int domid = 0;
+int frame_ptrs = 0;
+int stack_trace = 0;
+
+#if defined (__i386__)
+#define FMT_SIZE_T             "%08x"
+#define STACK_POINTER(regs)    (regs->esp)
+#define FRAME_POINTER(regs)    (regs->ebp)
+#define INSTR_POINTER(regs)    (regs->eip)
+#define STACK_ROWS             4
+#define STACK_COLS             8
+#elif defined (__x86_64__)
+#define FMT_SIZE_T             "%016lx"
+#define STACK_POINTER(regs)    (regs->rsp)
+#define FRAME_POINTER(regs)    (regs->rbp)
+#define INSTR_POINTER(regs)    (regs->rip)
+#define STACK_ROWS             4
+#define STACK_COLS             4
+#endif
+
+struct symbol {
+    size_t address;
+    char type;
+    char *name;
+    struct symbol *next;
+} *symbol_table = NULL;
+
+size_t kernel_stext, kernel_etext, kernel_sinittext, kernel_einittext;
+
+int is_kernel_text(size_t addr)
+{
+#if defined (__i386__)
+    if (symbol_table == NULL)
+        return (addr > 0xc000000);
+#elif defined (__x86_64__)
+    if (symbol_table == NULL)
+        return (addr > 0xffffffff80000000UL);
+#endif
+
+    if (addr >= kernel_stext &&
+        addr <= kernel_etext)
+        return 1;
+    if (addr >= kernel_sinittext &&
+        addr <= kernel_einittext)
+        return 1;
+    return 0;
+}
+
+void free_symbol(struct symbol *symbol)
+{
+    if (symbol == NULL)
+        return;
+    if (symbol->name)
+        free(symbol->name);
+    free(symbol);
+}
+
+void insert_symbol(struct symbol *symbol)
+{
+    static struct symbol *prev = NULL;
+    struct symbol *s = symbol_table;
+
+    if (s == NULL) {
+        symbol_table = symbol;
+        symbol->next = NULL;
+        return;
+    }
+
+    /* The System.map is usually already sorted... */
+    if (prev
+        && prev->address < symbol->address
+        && (!prev->next || prev->next->address > symbol->address)) {
+        s = prev;
+    } else {
+        /* ... otherwise do crappy/slow search for the correct place */
+        while(s && s->next && s->next->address < symbol->address)
+            s = s->next;
+    }
+
+    symbol->next = s->next;
+    s->next = symbol;
+    prev = symbol;
+}
+
+struct symbol *lookup_symbol(size_t address)
+{
+    struct symbol *s = symbol_table;
+
+    while(s && s->next && s->next->address < address)
+        s = s->next;
+
+    if (s && s->address < address)
+        return s;
+
+    return NULL;
+}
+
+void print_symbol(size_t addr)
+{
+    struct symbol *s;
+
+    if (!is_kernel_text(addr))
+        return;
+
+    s = lookup_symbol(addr);
+
+    if (s==NULL)
+        return;
+
+    if (addr==s->address)
+        printf("%s", s->name);
+    else
+        printf("%s+%#x", s->name, (unsigned int)(addr - s->address));
+}
+
+void read_symbol_table(const char *symtab)
+{
+    char line[256];
+    char *p;
+    struct symbol *symbol;
+    FILE *f;
+
+    f = fopen(symtab, "r");
+    if(f == NULL) {
+        fprintf(stderr, "failed to open symbol table %s\n", symtab);
+        exit(-1);
+    }
+
+    while(!feof(f)) {
+        if(fgets(line,256,f)==NULL)
+            break;
+
+        symbol = malloc(sizeof(*symbol));
+
+        /* need more checks for syntax here... */
+        symbol->address = strtoull(line, &p, 16);
+        p++;
+        symbol->type = *p++;
+        p++;
+
+        /* in the future we should handle the module name
+         * being appended here, this would allow us to use
+         * /proc/kallsyms as our symbol table
+         */
+        if (p[strlen(p)-1] == '\n')
+            p[strlen(p)-1] = '\0';
+        symbol->name = strdup(p);
+
+        insert_symbol(symbol);
+
+        if (strcmp(symbol->name, "_stext") == 0)
+            kernel_stext = symbol->address;
+        else if (strcmp(symbol->name, "_etext") == 0)
+            kernel_etext = symbol->address;
+        else if (strcmp(symbol->name, "_sinittext") == 0)
+            kernel_sinittext = symbol->address;
+        else if (strcmp(symbol->name, "_einittext") == 0)
+            kernel_einittext = symbol->address;
+    }
+
+    fclose(f);
+}
 
 #ifdef __i386__
 void print_ctx(vcpu_guest_context_t *ctx1)
 {
     struct cpu_user_regs *regs = &ctx1->user_regs;
 
-    printf("eip: %08x\t", regs->eip);
+    printf("eip: %08x ", regs->eip);
+    print_symbol(regs->eip);
+    printf("\n");
+
     printf("esp: %08x\n", regs->esp);
 
     printf("eax: %08x\t", regs->eax);
@@ -51,7 +220,9 @@
 {
     struct cpu_user_regs *regs = &ctx1->user_regs;
 
-    printf("rip: %08lx\t", regs->rip);
+    printf("rip: %08lx ", regs->rip);
+    print_symbol(regs->rip);
+    printf("\n");
     printf("rsp: %08lx\n", regs->rsp);
 
     printf("rax: %08lx\t", regs->rax);
@@ -63,8 +234,8 @@
     printf("rdi: %08lx\t", regs->rdi);
     printf("rbp: %08lx\n", regs->rbp);
 
-    printf("r8: %08lx\t", regs->r8);
-    printf("r9: %08lx\t", regs->r9);
+    printf(" r8: %08lx\t", regs->r8);
+    printf(" r9: %08lx\t", regs->r9);
     printf("r10: %08lx\t", regs->r10);
     printf("r11: %08lx\n", regs->r11);
 
@@ -81,35 +252,238 @@
 }
 #endif
 
-void dump_ctx(uint32_t domid, uint32_t vcpu)
+void *map_page(vcpu_guest_context_t *ctx, int vcpu, size_t virt)
+{
+    static unsigned long previous_mfn = 0;
+    static void *mapped = NULL;
+
+    unsigned long mfn = xc_translate_foreign_address(xc_handle, domid, vcpu, 
virt);
+    unsigned long offset = virt & ~XC_PAGE_MASK;
+
+    if (mapped && mfn == previous_mfn)
+        goto out;
+
+    if (mapped)
+        munmap(mapped, XC_PAGE_SIZE);
+
+    previous_mfn = mfn;
+
+    mapped = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE, PROT_READ, 
mfn);
+
+    if (mapped == NULL) {
+        fprintf(stderr, "failed to map page.\n");
+        exit(-1);
+    }
+
+ out:
+    return (void *)(mapped + offset);
+}
+
+void print_stack(vcpu_guest_context_t *ctx, int vcpu)
+{
+    struct cpu_user_regs *regs = &ctx->user_regs;
+    size_t stack = STACK_POINTER(regs);
+    size_t stack_limit = (STACK_POINTER(regs) & XC_PAGE_MASK) + XC_PAGE_SIZE;
+    size_t frame;
+    size_t instr;
+    size_t *p;
+    int i;
+
+    printf("\n");
+    printf("Stack:\n");
+    for (i=1; i<STACK_ROWS+1 && stack < stack_limit; i++) {
+        while(stack < stack_limit && stack < STACK_POINTER(regs) + 
i*STACK_COLS*sizeof(stack)) {
+            p = map_page(ctx, vcpu, stack);
+            printf(" " FMT_SIZE_T, *p);
+            stack += sizeof(stack);
+        }
+        printf("\n");
+    }
+    printf("\n");
+
+    printf("Code:\n");
+    instr = INSTR_POINTER(regs) - 21;
+    for(i=0; i<32; i++) {
+        unsigned char *c = map_page(ctx, vcpu, instr+i);
+        if (instr+i == INSTR_POINTER(regs))
+            printf("<%02x> ", *c);
+        else
+            printf("%02x ", *c);
+    }
+    printf("\n");
+
+    printf("\n");
+
+    if(stack_trace)
+        printf("Stack Trace:\n");
+    else
+        printf("Call Trace:\n");
+    printf("%c [<" FMT_SIZE_T ">] ", stack_trace ? '*' : ' ', 
INSTR_POINTER(regs));
+
+    print_symbol(INSTR_POINTER(regs));
+    printf(" <--\n");
+    if (frame_ptrs) {
+        stack = STACK_POINTER(regs);
+        frame = FRAME_POINTER(regs);
+        while(frame && stack < stack_limit) {
+            if (stack_trace) {
+                while (stack < frame) {
+                    p = map_page(ctx, vcpu, stack);
+                    printf("|   " FMT_SIZE_T "   ", *p);
+                    printf("\n");
+                    stack += sizeof(*p);
+                }
+            } else {
+                stack = frame;
+            }
+
+            p = map_page(ctx, vcpu, stack);
+            frame = *p;
+            if (stack_trace)
+                printf("|-- " FMT_SIZE_T "\n", *p);
+            stack += sizeof(*p);
+
+            if (frame) {
+                p = map_page(ctx, vcpu, stack);
+                printf("%c [<" FMT_SIZE_T ">] ", stack_trace ? '|' : ' ', *p);
+                print_symbol(*p);
+                printf("\n");
+                stack += sizeof(*p);
+            }
+        }
+    } else {
+        stack = STACK_POINTER(regs);
+        while(stack < stack_limit) {
+            p = map_page(ctx, vcpu, stack);
+            if (is_kernel_text(*p)) {
+                printf("  [<" FMT_SIZE_T ">] ", *p);
+                print_symbol(*p);
+                printf("\n");
+            } else if (stack_trace) {
+                printf("    " FMT_SIZE_T "\n", *p);
+            }
+            stack += sizeof(*p);
+        }
+    }
+}
+
+void dump_ctx(int vcpu)
 {
     int ret;
     vcpu_guest_context_t ctx;
 
-    int xc_handle = xc_interface_open(); /* for accessing control interface */
+    xc_handle = xc_interface_open(); /* for accessing control interface */
+
+    ret = xc_domain_pause(xc_handle, domid);
+    if (ret < 0) {
+        perror("xc_domain_pause");
+        exit(-1);
+    }
 
     ret = xc_domain_get_vcpu_context(xc_handle, domid, vcpu, &ctx);
-    if (ret != 0) {
+    if (ret < 0) {
+        xc_domain_unpause(xc_handle, domid);
         perror("xc_domain_get_vcpu_context");
         exit(-1);
     }
+
     print_ctx(&ctx);
+    if (is_kernel_text(ctx.user_regs.eip))
+        print_stack(&ctx, vcpu);
+
+    ret = xc_domain_unpause(xc_handle, domid);
+    if (ret < 0) {
+        perror("xc_domain_unpause");
+        exit(-1);
+    }
+
     xc_interface_close(xc_handle);
+    if (ret < 0) {
+        perror("xc_interface_close");
+        exit(-1);
+    }
+}
+
+void usage(void)
+{
+    printf("usage:\n\n");
+
+    printf("  xenctx [options] <DOMAIN> [VCPU]\n\n");
+
+    printf("options:\n");
+    printf("  -f, --frame-pointers\n");
+    printf("                    assume the kernel was compiled with\n");
+    printf("                    frame pointers.\n");
+    printf("  -s SYMTAB, --symbol-table=SYMTAB\n");
+    printf("                    read symbol table from SYMTAB.\n");
+    printf("  --stack-trace     print a complete stack trace.\n");
 }
 
 int main(int argc, char **argv)
 {
+    int ch;
+    const char *sopts = "fs:h";
+    const struct option lopts[] = {
+        {"stack-trace", 0, NULL, 'S'},
+        {"symbol-table", 1, NULL, 's'},
+        {"frame-pointers", 0, NULL, 'f'},
+        {"help", 0, NULL, 'h'},
+        {0, 0, 0, 0}
+    };
+    const char *symbol_table = NULL;
+
     int vcpu = 0;
 
-    if (argc < 2) {
-        printf("usage: xenctx <domid> <optional vcpu>\n");
-        exit(-1);
-    }
-
-    if (argc == 3)
-        vcpu = atoi(argv[2]);
-
-    dump_ctx(atoi(argv[1]), vcpu);
+    while ((ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
+        switch(ch) {
+        case 'f':
+            frame_ptrs = 1;
+            break;
+        case 's':
+            symbol_table = optarg;
+            break;
+        case 'S':
+            stack_trace = 1;
+            break;
+        case 'h':
+            usage();
+            exit(-1);
+        case '?':
+            fprintf(stderr, "%s --help for more options\n", argv[0]);
+            exit(-1);
+        }
+    }
+
+    argv += optind; argc -= optind;
+
+    if (argc < 1 || argc > 2) {
+        printf("usage: xenctx [options] <domid> <optional vcpu>\n");
+        exit(-1);
+    }
+
+    domid = atoi(argv[0]);
+    if (domid==0) {
+            fprintf(stderr, "cannot trace dom0\n");
+            exit(-1);
+    }
+
+    if (argc == 2)
+        vcpu = atoi(argv[1]);
+
+    if (symbol_table)
+        read_symbol_table(symbol_table);
+
+    dump_ctx(vcpu);
 
     return 0;
 }
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 903fb46f240e -r cd914808acf1 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Tue Jan  3 14:59:00 2006
+++ b/xen/arch/ia64/xen/domain.c        Tue Jan  3 16:19:20 2006
@@ -181,7 +181,7 @@
        memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
 }
 
-void arch_do_createdomain(struct vcpu *v)
+int arch_do_createdomain(struct vcpu *v)
 {
        struct domain *d = v->domain;
        struct thread_info *ti = alloc_thread_info(v);
@@ -248,7 +248,9 @@
                }
        } else
                d->arch.mm = NULL;
-       printf ("arch_do_create_domain: domain=%p\n", d);
+       printf ("arch_do_create_domain: domain=%p\n", d);
+
+       return 0;
 }
 
 void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
@@ -754,7 +756,10 @@
  */
 void physdev_init_dom0(struct domain *d)
 {
-       set_bit(_DOMF_physdev_access, &d->domain_flags);
+       if (iomem_permit_access(d, 0UL, ~0UL))
+               BUG();
+       if (irqs_permit_access(d, 0, NR_PIRQS-1))
+               BUG();
 }
 
 unsigned int vmx_dom0 = 0;
diff -r 903fb46f240e -r cd914808acf1 xen/arch/ia64/xen/irq.c
--- a/xen/arch/ia64/xen/irq.c   Tue Jan  3 14:59:00 2006
+++ b/xen/arch/ia64/xen/irq.c   Tue Jan  3 16:19:20 2006
@@ -1377,9 +1377,6 @@
     irq_guest_action_t *action;
     unsigned long       flags;
     int                 rc = 0;
-
-    if ( !IS_CAPABLE_PHYSDEV(d->domain) )
-        return -EPERM;
 
     spin_lock_irqsave(&desc->lock, flags);
 
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/Makefile     Tue Jan  3 16:19:20 2006
@@ -29,6 +29,7 @@
 endif
 
 OBJS := $(subst $(TARGET_SUBARCH)/asm-offsets.o,,$(OBJS))
+OBJS := $(subst $(TARGET_SUBARCH)/xen.lds.o,,$(OBJS))
 
 ifneq ($(crash_debug),y)
 OBJS := $(patsubst cdb%.o,,$(OBJS))
@@ -43,21 +44,24 @@
 $(CURDIR)/arch.o: $(OBJS)
        $(LD) $(LDFLAGS) -r -o $@ $(OBJS)
 
-$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(TARGET_SUBARCH)/xen.lds
-       $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \
+$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) xen.lds
+       $(LD) $(LDFLAGS) -T xen.lds -N \
            boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $@
        $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
        $(MAKE) $(BASEDIR)/xen-syms.o
-       $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \
+       $(LD) $(LDFLAGS) -T xen.lds -N \
            boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@
        $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
        $(MAKE) $(BASEDIR)/xen-syms.o
-       $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \
+       $(LD) $(LDFLAGS) -T xen.lds -N \
            boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@
        rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o
 
 asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS)
        $(CC) $(CFLAGS) -S -o $@ $<
+
+xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(HDRS)
+       $(CC) $(CFLAGS) -P -E -Ui386 -D__ASSEMBLY__ -o $@ $<
 
 boot/mkelf32: boot/mkelf32.c
        $(HOSTCC) $(HOSTCFLAGS) -o $@ $<
@@ -73,5 +77,6 @@
        rm -f dm/*.o dm/*~ dm/core
        rm -f genapic/*.o genapic/*~ genapic/core
        rm -f cpu/*.o cpu/*~ cpu/core
+       rm -f xen.lds
 
 .PHONY: default clean
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S        Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/boot/x86_32.S        Tue Jan  3 16:19:20 2006
@@ -1,5 +1,6 @@
 #include <xen/config.h>
 #include <public/xen.h>
+#include <asm/asm_defns.h>
 #include <asm/desc.h>
 #include <asm/page.h>
 #include <asm/msr.h>
@@ -53,6 +54,7 @@
         mov     %ecx,%gs
         ljmp    $(__HYPERVISOR_CS),$(1f)-__PAGE_OFFSET
 1:      lss     stack_start-__PAGE_OFFSET,%esp
+        add     $(STACK_SIZE-CPUINFO_sizeof-__PAGE_OFFSET),%esp
 
         /* Reset EFLAGS (subsumes CLI and CLD). */
        pushl   $0
@@ -189,7 +191,7 @@
 /*** STACK LOCATION ***/
         
 ENTRY(stack_start)
-        .long cpu0_stack + STACK_SIZE - 200 - __PAGE_OFFSET
+        .long cpu0_stack
         .long __HYPERVISOR_DS
         
 /*** DESCRIPTOR TABLES ***/
@@ -256,10 +258,6 @@
         .fill 1*PAGE_SIZE,1,0
 #endif
 
-#if (STACK_ORDER == 0)
-.section ".bss.page_aligned","w"
-#else
-.section ".bss.twopage_aligned","w"
-#endif
+.section ".bss.stack_aligned","w"
 ENTRY(cpu0_stack)
         .fill STACK_SIZE,1,0
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/boot/x86_64.S
--- a/xen/arch/x86/boot/x86_64.S        Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/boot/x86_64.S        Tue Jan  3 16:19:20 2006
@@ -1,5 +1,6 @@
 #include <xen/config.h>
 #include <public/xen.h>
+#include <asm/asm_defns.h>
 #include <asm/desc.h>
 #include <asm/page.h>
 #include <asm/msr.h>
@@ -121,7 +122,8 @@
         mov     %rcx,%cr4
 
         mov     stack_start(%rip),%rsp
-        
+        or      $(STACK_SIZE-CPUINFO_sizeof),%rsp
+
         /* Reset EFLAGS (subsumes CLI and CLD). */
         pushq   $0
         popf
@@ -140,7 +142,7 @@
         mov     %ecx,%ss
 
         lidt    idt_descr(%rip)
-                
+
         cmp     $(SECONDARY_CPU_FLAG),%ebx
         je      start_secondary
 
@@ -219,7 +221,7 @@
         .quad   idt_table
 
 ENTRY(stack_start)
-        .quad   cpu0_stack + STACK_SIZE - 200
+        .quad   cpu0_stack
 
 high_start:
         .quad   __high_start
@@ -265,10 +267,6 @@
         .org 0x4000 + PAGE_SIZE
         .code64
 
-#if (STACK_ORDER == 0)
-.section ".bss.page_aligned","w"
-#else
-.section ".bss.twopage_aligned","w"
-#endif
+.section ".bss.stack_aligned","w"
 ENTRY(cpu0_stack)
         .fill STACK_SIZE,1,0
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/dom0_ops.c   Tue Jan  3 16:19:20 2006
@@ -17,6 +17,7 @@
 #include <asm/msr.h>
 #include <xen/trace.h>
 #include <xen/console.h>
+#include <xen/iocap.h>
 #include <asm/shadow.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
@@ -141,7 +142,6 @@
         struct domain *d;
         unsigned int fp = op->u.ioport_permission.first_port;
         unsigned int np = op->u.ioport_permission.nr_ports;
-        unsigned int p;
 
         ret = -EINVAL;
         if ( (fp + np) > 65536 )
@@ -152,26 +152,12 @@
             op->u.ioport_permission.domain)) == NULL) )
             break;
 
-        ret = -ENOMEM;
-        if ( d->arch.iobmp_mask != NULL )
-        {
-            if ( (d->arch.iobmp_mask = xmalloc_array(
-                u8, IOBMP_BYTES)) == NULL )
-            {
-                put_domain(d);
-                break;
-            }
-            memset(d->arch.iobmp_mask, 0xFF, IOBMP_BYTES);
-        }
-
-        ret = 0;
-        for ( p = fp; p < (fp + np); p++ )
-        {
-            if ( op->u.ioport_permission.allow_access )
-                clear_bit(p, d->arch.iobmp_mask);
-            else
-                set_bit(p, d->arch.iobmp_mask);
-        }
+        if ( np == 0 )
+            ret = 0;
+        else if ( op->u.ioport_permission.allow_access )
+            ret = ioports_permit_access(d, fp, fp + np - 1);
+        else
+            ret = ioports_deny_access(d, fp, fp + np - 1);
 
         put_domain(d);
     }
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/domain.c     Tue Jan  3 16:19:20 2006
@@ -20,6 +20,7 @@
 #include <xen/delay.h>
 #include <xen/softirq.h>
 #include <xen/grant_table.h>
+#include <xen/iocap.h>
 #include <asm/regs.h>
 #include <asm/mc146818rtc.h>
 #include <asm/system.h>
@@ -35,9 +36,7 @@
 #include <xen/console.h>
 #include <xen/elf.h>
 #include <asm/vmx.h>
-#include <asm/vmx_vmcs.h>
 #include <asm/msr.h>
-#include <asm/physdev.h>
 #include <xen/kernel.h>
 #include <xen/multicall.h>
 
@@ -98,7 +97,7 @@
     cpu_set(smp_processor_id(), v->domain->cpumask);
     v->arch.schedule_tail = continue_idle_task;
 
-    idle_loop();
+    reset_stack_and_jump(idle_loop);
 }
 
 static long no_idt[2];
@@ -185,11 +184,17 @@
 {
     struct pfn_info *page;
 
-    if ( d->tot_pages < 10 )
+    printk("Memory pages belonging to domain %u:\n", d->domain_id);
+
+    if ( d->tot_pages >= 10 )
+    {
+        printk("    DomPage list too long to display\n");
+    }
+    else
     {
         list_for_each_entry ( page, &d->page_list, list )
         {
-            printk("Page %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
+            printk("    DomPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
                    _p(page_to_phys(page)), _p(page_to_pfn(page)),
                    page->count_info, page->u.inuse.type_info);
         }
@@ -197,15 +202,10 @@
 
     list_for_each_entry ( page, &d->xenpage_list, list )
     {
-        printk("XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
+        printk("    XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
                _p(page_to_phys(page)), _p(page_to_pfn(page)),
                page->count_info, page->u.inuse.type_info);
     }
-
-    page = virt_to_page(d->shared_info);
-    printk("Shared_info@%p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
-           _p(page_to_phys(page)), _p(page_to_pfn(page)), page->count_info,
-           page->u.inuse.type_info);
 }
 
 struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
@@ -250,21 +250,34 @@
 #endif
 }
 
-void arch_do_createdomain(struct vcpu *v)
+int arch_do_createdomain(struct vcpu *v)
 {
     struct domain *d = v->domain;
     l1_pgentry_t gdt_l1e;
-    int vcpuid, pdpt_order;
+    int vcpuid, pdpt_order, rc;
 #ifdef __x86_64__
     int i;
 #endif
 
     if ( is_idle_task(d) )
-        return;
+        return 0;
+
+    d->arch.ioport_caps = 
+        rangeset_new(d, "I/O Ports", RANGESETF_prettyprint_hex);
+    if ( d->arch.ioport_caps == NULL )
+        return -ENOMEM;
+
+    if ( (d->shared_info = alloc_xenheap_page()) == NULL )
+        return -ENOMEM;
+
+    if ( (rc = ptwr_init(d)) != 0 )
+    {
+        free_xenheap_page(d->shared_info);
+        return rc;
+    }
 
     v->arch.schedule_tail = continue_nonidle_task;
 
-    d->shared_info = alloc_xenheap_page();
     memset(d->shared_info, 0, PAGE_SIZE);
     v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
     v->cpumap = CPUMAP_RUNANYWHERE;
@@ -308,10 +321,10 @@
                             __PAGE_HYPERVISOR);
 #endif
 
-    (void)ptwr_init(d);
-
     shadow_lock_init(d);
     INIT_LIST_HEAD(&d->arch.free_shadow_frames);
+
+    return 0;
 }
 
 void vcpu_migrate_cpu(struct vcpu *v, int newcpu)
@@ -348,6 +361,8 @@
              ((c->user_regs.ss & 3) == 0) )
             return -EINVAL;
     }
+    else if ( !hvm_enabled )
+        return -EINVAL;
 
     clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
     if ( c->flags & VGCF_I387_VALID )
@@ -953,8 +968,6 @@
 
     BUG_ON(!cpus_empty(d->cpumask));
 
-    physdev_destroy_state(d);
-
     ptwr_destroy(d);
 
     /* Drop the in-use references to page-table bases. */
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/domain_build.c       Tue Jan  3 16:19:20 2006
@@ -16,13 +16,13 @@
 #include <xen/kernel.h>
 #include <xen/domain.h>
 #include <xen/compile.h>
+#include <xen/iocap.h>
 #include <asm/regs.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/desc.h>
 #include <asm/i387.h>
-#include <asm/physdev.h>
 #include <asm/shadow.h>
 
 static long dom0_nrpages;
@@ -94,9 +94,9 @@
     return page;
 }
 
-static void process_dom0_ioports_disable()
+static void process_dom0_ioports_disable(void)
 {
-    unsigned long io_from, io_to, io_nr;
+    unsigned long io_from, io_to;
     char *t, *u, *s = opt_dom0_ioports_disable;
 
     if ( *s == '\0' )
@@ -126,8 +126,8 @@
         printk("Disabling dom0 access to ioport range %04lx-%04lx\n",
             io_from, io_to);
 
-        io_nr = io_to - io_from + 1;
-        physdev_modify_ioport_access_range(dom0, 0, io_from, io_nr);
+        if ( ioports_deny_access(dom0, io_from, io_to) != 0 )
+            BUG();
     }
 }
 
@@ -183,7 +183,6 @@
     /* Machine address of next candidate page-table page. */
     unsigned long mpt_alloc;
 
-    extern void physdev_init_dom0(struct domain *);
     extern void translate_l2pgtable(
         struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn);
 
@@ -692,9 +691,6 @@
     zap_low_mappings(l2start);
     zap_low_mappings(idle_pg_table_l2);
 #endif
-    
-    /* DOM0 gets access to everything. */
-    physdev_init_dom0(d);
 
     init_domain_time(d);
 
@@ -746,19 +742,28 @@
         printk("dom0: shadow setup done\n");
     }
 
+    i = 0;
+
+    /* DOM0 is permitted full I/O capabilities. */
+    i |= ioports_permit_access(dom0, 0, 0xFFFF);
+    i |= iomem_permit_access(dom0, 0UL, ~0UL);
+    i |= irqs_permit_access(dom0, 0, NR_PIRQS-1);
+
     /*
      * Modify I/O port access permissions.
      */
     /* Master Interrupt Controller (PIC). */
-    physdev_modify_ioport_access_range(dom0, 0, 0x20, 2);
+    i |= ioports_deny_access(dom0, 0x20, 0x21);
     /* Slave Interrupt Controller (PIC). */
-    physdev_modify_ioport_access_range(dom0, 0, 0xA0, 2);
+    i |= ioports_deny_access(dom0, 0xA0, 0xA1);
     /* Interval Timer (PIT). */
-    physdev_modify_ioport_access_range(dom0, 0, 0x40, 4);
+    i |= ioports_deny_access(dom0, 0x40, 0x43);
     /* PIT Channel 2 / PC Speaker Control. */
-    physdev_modify_ioport_access_range(dom0, 0, 0x61, 1);
-    /* Command-line passed i/o ranges */
+    i |= ioports_deny_access(dom0, 0x61, 0x61);
+    /* Command-line I/O ranges. */
     process_dom0_ioports_disable();
+
+    BUG_ON(i != 0);
 
     return 0;
 }
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/irq.c        Tue Jan  3 16:19:20 2006
@@ -199,15 +199,11 @@
 int pirq_guest_bind(struct vcpu *v, int irq, int will_share)
 {
     unsigned int        vector = irq_to_vector(irq);
-    struct domain      *d = v->domain;
     irq_desc_t         *desc = &irq_desc[vector];
     irq_guest_action_t *action;
     unsigned long       flags;
     int                 rc = 0;
     cpumask_t           cpumask = CPU_MASK_NONE;
-
-    if ( !IS_CAPABLE_PHYSDEV(d) )
-        return -EPERM;
 
     if ( vector == 0 )
         return -EBUSY;
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/mm.c Tue Jan  3 16:19:20 2006
@@ -96,6 +96,7 @@
 #include <xen/softirq.h>
 #include <xen/domain_page.h>
 #include <xen/event.h>
+#include <xen/iocap.h>
 #include <asm/shadow.h>
 #include <asm/page.h>
 #include <asm/flushtlb.h>
@@ -437,7 +438,6 @@
     unsigned long mfn = l1e_get_pfn(l1e);
     struct pfn_info *page = pfn_to_page(mfn);
     int okay;
-    extern int domain_iomem_in_pfn(struct domain *d, unsigned long pfn);
 
     if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) )
         return 1;
@@ -455,8 +455,7 @@
         if ( d == dom_io )
             d = current->domain;
 
-        if ( (!IS_PRIV(d)) &&
-             (!IS_CAPABLE_PHYSDEV(d) || !domain_iomem_in_pfn(d, mfn)) )
+        if ( !iomem_access_permitted(d, mfn, mfn) )
         {
             MEM_LOG("Non-privileged attempt to map I/O space %08lx", mfn);
             return 0;
@@ -1887,7 +1886,7 @@
             break;
 
         case MMUEXT_FLUSH_CACHE:
-            if ( unlikely(!IS_CAPABLE_PHYSDEV(d)) )
+            if ( unlikely(!cache_flush_permitted(d)) )
             {
                 MEM_LOG("Non-physdev domain tried to FLUSH_CACHE.");
                 okay = 0;
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/physdev.c    Tue Jan  3 16:19:20 2006
@@ -13,27 +13,6 @@
 
 extern int ioapic_guest_read(int apicid, int address, u32 *pval);
 extern int ioapic_guest_write(int apicid, int address, u32 pval);
-
-void physdev_modify_ioport_access_range(
-    struct domain *d, int enable, int port, int num)
-{
-    int i;
-    for ( i = port; i < (port + num); i++ )
-        (enable ? clear_bit : set_bit)(i, d->arch.iobmp_mask);
-}
-
-void physdev_destroy_state(struct domain *d)
-{
-    xfree(d->arch.iobmp_mask);
-    d->arch.iobmp_mask = NULL;
-}
-
-/* Check if a domain controls a device with IO memory within frame @pfn.
- * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise.  */
-int domain_iomem_in_pfn(struct domain *p, unsigned long pfn)
-{
-    return 0;
-}
 
 /*
  * Demuxing hypercall.
@@ -120,18 +99,6 @@
     return ret;
 }
 
-/* Domain 0 has read access to all devices. */
-void physdev_init_dom0(struct domain *d)
-{
-    /* Access to all I/O ports. */
-    d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES);
-    BUG_ON(d->arch.iobmp_mask == NULL);
-    memset(d->arch.iobmp_mask, 0, IOBMP_BYTES);
-
-    set_bit(_DOMF_physdev_access, &d->domain_flags);
-}
-
-
 /*
  * Local variables:
  * mode: C
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/setup.c      Tue Jan  3 16:19:20 2006
@@ -138,131 +138,19 @@
         (*call)();
 }
 
-static void __init start_of_day(void)
-{
-    int i;
-    unsigned long vgdt, gdt_pfn;
-
-    early_cpu_init();
-
-    paging_init();
-
-    /* Unmap the first page of CPU0's stack. */
-    memguard_guard_stack(cpu0_stack);
-
-    open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
-
-    if ( opt_watchdog ) 
-        nmi_watchdog = NMI_LOCAL_APIC;
-
-    sort_exception_tables();
-
-    arch_do_createdomain(current);
-    
-    /*
-     * Map default GDT into its final positions in the idle page table. As
-     * noted in arch_do_createdomain(), we must map for every possible VCPU#.
-     */
-    vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE;
-    gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT;
-    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-    {
-        map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR);
-        vgdt += 1 << PDPT_VCPU_VA_SHIFT;
-    }
-
-    find_smp_config();
-
-    smp_alloc_memory();
-
-    dmi_scan_machine();
-
-    generic_apic_probe();
-
-    acpi_boot_table_init();
-    acpi_boot_init();
-
-    if ( smp_found_config ) 
-        get_smp_config();
-
-    init_apic_mappings();
-
-    init_IRQ();
-
-    trap_init();
-
-    ac_timer_init();
-
-    early_time_init();
-
-    arch_init_memory();
-
-    scheduler_init();
-
-    identify_cpu(&boot_cpu_data);
-    if ( cpu_has_fxsr )
-        set_in_cr4(X86_CR4_OSFXSR);
-    if ( cpu_has_xmm )
-        set_in_cr4(X86_CR4_OSXMMEXCPT);
-
-    if ( opt_nosmp )
-    {
-        max_cpus = 0;
-        smp_num_siblings = 1;
-        boot_cpu_data.x86_num_cores = 1;
-    }
-
-    smp_prepare_cpus(max_cpus);
-
-    /* We aren't hotplug-capable yet. */
-    BUG_ON(!cpus_empty(cpu_present_map));
-    for_each_cpu ( i )
-        cpu_set(i, cpu_present_map);
-
-    /*
-     * Initialise higher-level timer functions. We do this fairly late
-     * (post-SMP) because the time bases and scale factors need to be updated 
-     * regularly, and SMP initialisation can cause a long delay with 
-     * interrupts not yet enabled.
-     */
-    init_xen_time();
-
-    initialize_keytable();
-
-    serial_init_postirq();
-
-    BUG_ON(!local_irq_is_enabled());
-
-    for_each_present_cpu ( i )
-    {
-        if ( num_online_cpus() >= max_cpus )
-            break;
-        if ( !cpu_online(i) )
-            __cpu_up(i);
-    }
-
-    printk("Brought up %ld CPUs\n", (long)num_online_cpus());
-    smp_cpus_done(max_cpus);
-
-    do_initcalls();
-
-    schedulers_start();
-
-    watchdog_enable();
-}
-
 #define EARLY_FAIL() for ( ; ; ) __asm__ __volatile__ ( "hlt" )
 
 static struct e820entry e820_raw[E820MAX];
 
 void __init __start_xen(multiboot_info_t *mbi)
 {
+    unsigned long vgdt, gdt_pfn;
     char *cmdline;
+    unsigned long _initrd_start = 0, _initrd_len = 0;
+    unsigned int initrdidx = 1;
     module_t *mod = (module_t *)__va(mbi->mods_addr);
     unsigned long nr_pages, modules_length;
     unsigned long initial_images_start, initial_images_end;
-    unsigned long _initrd_start = 0, _initrd_len = 0;
-    unsigned int initrdidx = 1;
     physaddr_t s, e;
     int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
     struct ns16550_defaults ns16550 = {
@@ -486,7 +374,113 @@
 
     early_boot = 0;
 
-    start_of_day();
+    early_cpu_init();
+
+    paging_init();
+
+    /* Unmap the first page of CPU0's stack. */
+    memguard_guard_stack(cpu0_stack);
+
+    open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
+
+    if ( opt_watchdog ) 
+        nmi_watchdog = NMI_LOCAL_APIC;
+
+    sort_exception_tables();
+
+    if ( arch_do_createdomain(current) != 0 )
+        BUG();
+
+    /*
+     * Map default GDT into its final positions in the idle page table. As
+     * noted in arch_do_createdomain(), we must map for every possible VCPU#.
+     */
+    vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE;
+    gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT;
+    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
+    {
+        map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR);
+        vgdt += 1 << PDPT_VCPU_VA_SHIFT;
+    }
+
+    find_smp_config();
+
+    smp_alloc_memory();
+
+    dmi_scan_machine();
+
+    generic_apic_probe();
+
+    acpi_boot_table_init();
+    acpi_boot_init();
+
+    if ( smp_found_config ) 
+        get_smp_config();
+
+    init_apic_mappings();
+
+    init_IRQ();
+
+    trap_init();
+
+    ac_timer_init();
+
+    early_time_init();
+
+    arch_init_memory();
+
+    scheduler_init();
+
+    identify_cpu(&boot_cpu_data);
+    if ( cpu_has_fxsr )
+        set_in_cr4(X86_CR4_OSFXSR);
+    if ( cpu_has_xmm )
+        set_in_cr4(X86_CR4_OSXMMEXCPT);
+
+    if ( opt_nosmp )
+    {
+        max_cpus = 0;
+        smp_num_siblings = 1;
+        boot_cpu_data.x86_num_cores = 1;
+    }
+
+    smp_prepare_cpus(max_cpus);
+
+    /* We aren't hotplug-capable yet. */
+    BUG_ON(!cpus_empty(cpu_present_map));
+    for_each_cpu ( i )
+        cpu_set(i, cpu_present_map);
+
+    /*
+     * Initialise higher-level timer functions. We do this fairly late
+     * (post-SMP) because the time bases and scale factors need to be updated 
+     * regularly, and SMP initialisation can cause a long delay with 
+     * interrupts not yet enabled.
+     */
+    init_xen_time();
+
+    initialize_keytable();
+
+    serial_init_postirq();
+
+    BUG_ON(!local_irq_is_enabled());
+
+    for_each_present_cpu ( i )
+    {
+        if ( num_online_cpus() >= max_cpus )
+            break;
+        if ( !cpu_online(i) )
+            __cpu_up(i);
+    }
+
+    printk("Brought up %ld CPUs\n", (long)num_online_cpus());
+    smp_cpus_done(max_cpus);
+
+    do_initcalls();
+
+    schedulers_start();
+
+    watchdog_enable();
 
     shadow_mode_init();
 
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/smpboot.c    Tue Jan  3 16:19:20 2006
@@ -763,7 +763,6 @@
 {
        struct domain *idle;
        struct vcpu *v;
-       void *stack;
        unsigned long boot_error;
        int timeout, cpu;
        unsigned long start_eip;
@@ -786,16 +785,10 @@
        /* So we see what's up   */
        printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip);
 
-       stack = alloc_xenheap_pages(STACK_ORDER);
-#if defined(__i386__)
-       stack_start.esp = (void *)__pa(stack);
-#elif defined(__x86_64__)
-       stack_start.esp = stack;
-#endif
-       stack_start.esp += STACK_SIZE - sizeof(struct cpu_info);
+       stack_start.esp = alloc_xenheap_pages(STACK_ORDER);
 
        /* Debug build: detect stack overflow by setting up a guard page. */
-       memguard_guard_stack(stack);
+       memguard_guard_stack(stack_start.esp);
 
        /*
         * This grunge runs the startup process for
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/traps.c      Tue Jan  3 16:19:20 2006
@@ -41,6 +41,7 @@
 #include <xen/softirq.h>
 #include <xen/domain_page.h>
 #include <xen/symbols.h>
+#include <xen/iocap.h>
 #include <asm/shadow.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -192,7 +193,8 @@
 
     /* Bounds for range of valid frame pointer. */
     low  = (unsigned long)(ESP_BEFORE_EXCEPTION(regs) - 2);
-    high = (low & ~(STACK_SIZE - 1)) + (STACK_SIZE - sizeof(struct cpu_info));
+    high = (low & ~(STACK_SIZE - 1)) + 
+        (STACK_SIZE - sizeof(struct cpu_info) - 2*sizeof(unsigned long));
 
     /* The initial frame pointer. */
     next = regs->ebp;
@@ -200,14 +202,14 @@
     for ( ; ; )
     {
         /* Valid frame pointer? */
-        if ( (next < low) || (next > high) )
+        if ( (next < low) || (next >= high) )
         {
             /*
              * Exception stack frames have a different layout, denoted by an
              * inverted frame pointer.
              */
             next = ~next;
-            if ( (next < low) || (next > high) )
+            if ( (next < low) || (next >= high) )
                 break;
             frame = (unsigned long *)next;
             next  = frame[0];
@@ -621,17 +623,7 @@
     unsigned int port, unsigned int bytes,
     struct vcpu *v, struct cpu_user_regs *regs)
 {
-    struct domain *d = v->domain;
-    u16 x;
-
-    if ( d->arch.iobmp_mask != NULL )
-    {
-        x = *(u16 *)(d->arch.iobmp_mask + (port >> 3));
-        if ( (x & (((1<<bytes)-1) << (port&7))) == 0 )
-            return 1;
-    }
-
-    return 0;
+    return ioports_access_permitted(v->domain, port, port + bytes - 1);
 }
 
 /* Check admin limits. Silently fail the access if it is disallowed. */
@@ -871,7 +863,7 @@
 
     case 0x09: /* WBINVD */
         /* Ignore the instruction if unprivileged. */
-        if ( !IS_CAPABLE_PHYSDEV(v->domain) )
+        if ( !cache_flush_permitted(v->domain) )
             DPRINTK("Non-physdev domain attempted WBINVD.\n");
         else
             wbinvd();
@@ -885,7 +877,8 @@
         switch ( modrm_reg )
         {
         case 0: /* Read CR0 */
-            *reg = v->arch.guest_context.ctrlreg[0];
+            *reg = (read_cr0() & ~X86_CR0_TS) |
+                v->arch.guest_context.ctrlreg[0];
             break;
 
         case 2: /* Read CR2 */
@@ -927,6 +920,11 @@
         switch ( modrm_reg )
         {
         case 0: /* Write CR0 */
+            if ( (*reg ^ read_cr0()) & ~X86_CR0_TS )
+            {
+                DPRINTK("Attempt to change unmodifiable CR0 flags.\n");
+                goto fail;
+            }
             (void)do_fpu_taskswitch(!!(*reg & X86_CR0_TS));
             break;
 
@@ -939,6 +937,14 @@
             LOCK_BIGLOCK(v->domain);
             (void)new_guest_cr3(*reg);
             UNLOCK_BIGLOCK(v->domain);
+            break;
+
+        case 4:
+            if ( *reg != (read_cr4() & ~(X86_CR4_PGE|X86_CR4_PSE)) )
+            {
+                DPRINTK("Attempt to change CR4 flags.\n");
+                goto fail;
+            }
             break;
 
         default:
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/x86_emulate.c        Tue Jan  3 16:19:20 2006
@@ -371,6 +371,21 @@
    (_type)_x; \
 })
 
+/* Access/update address held in a register, based on addressing mode. */
+#define register_address(sel, reg)                                      \
+    ((ad_bytes == sizeof(unsigned long)) ? (reg) :                      \
+     ((mode == X86EMUL_MODE_REAL) ? /* implies ad_bytes == 2 */         \
+      (((unsigned long)(sel) << 4) + ((reg) & 0xffff)) :                \
+      ((reg) & ((1UL << (ad_bytes << 3)) - 1))))
+#define register_address_increment(reg, inc)                            \
+do {                                                                    \
+    if ( ad_bytes == sizeof(unsigned long) )                            \
+        (reg) += (inc);                                                 \
+    else                                                                \
+        (reg) = ((reg) & ~((1UL << (ad_bytes << 3)) - 1)) |             \
+                (((reg) + (inc)) & ((1UL << (ad_bytes << 3)) - 1));     \
+} while (0)
+
 void *
 decode_register(
     uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs)
@@ -420,32 +435,64 @@
 {
     uint8_t b, d, sib, twobyte = 0, rex_prefix = 0;
     uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
-    unsigned int op_bytes = (mode == 8) ? 4 : mode, ad_bytes = mode;
-    unsigned int lock_prefix = 0, rep_prefix = 0, i;
+    uint16_t *seg = NULL; /* override segment */
+    unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
     int rc = 0;
     struct operand src, dst;
 
     /* Shadow copy of register state. Committed on successful emulation. */
     struct cpu_user_regs _regs = *regs;
 
+    switch ( mode )
+    {
+    case X86EMUL_MODE_REAL:
+    case X86EMUL_MODE_PROT16:
+        op_bytes = ad_bytes = 2;
+        break;
+    case X86EMUL_MODE_PROT32:
+        op_bytes = ad_bytes = 4;
+        break;
+#ifdef __x86_64__
+    case X86EMUL_MODE_PROT64:
+        op_bytes = 4;
+        ad_bytes = 8;
+        break;
+#endif
+    default:
+        return -1;
+    }
+
     /* Legacy prefixes. */
     for ( i = 0; i < 8; i++ )
     {
         switch ( b = insn_fetch(uint8_t, 1, _regs.eip) )
         {
         case 0x66: /* operand-size override */
-            op_bytes ^= 6;                    /* switch between 2/4 bytes */
+            op_bytes ^= 6;      /* switch between 2/4 bytes */
             break;
         case 0x67: /* address-size override */
-            ad_bytes ^= (mode == 8) ? 12 : 6; /* switch between 2/4/8 bytes */
+            if ( mode == X86EMUL_MODE_PROT64 )
+                ad_bytes ^= 12; /* switch between 4/8 bytes */
+            else
+                ad_bytes ^= 6;  /* switch between 2/4 bytes */
             break;
         case 0x2e: /* CS override */
+            seg = &_regs.cs;
+            break;
         case 0x3e: /* DS override */
+            seg = &_regs.ds;
+            break;
         case 0x26: /* ES override */
+            seg = &_regs.es;
+            break;
         case 0x64: /* FS override */
+            seg = &_regs.fs;
+            break;
         case 0x65: /* GS override */
+            seg = &_regs.gs;
+            break;
         case 0x36: /* SS override */
-            DPRINTF("Warning: ignoring a segment override.\n");
+            seg = &_regs.ss;
             break;
         case 0xf0: /* LOCK */
             lock_prefix = 1;
@@ -461,8 +508,12 @@
     }
  done_prefixes:
 
+    /* Note quite the same as 80386 real mode, but hopefully good enough. */
+    if ( (mode == X86EMUL_MODE_REAL) && (ad_bytes != 2) )
+        goto cannot_emulate;
+
     /* REX prefix. */
-    if ( (mode == 8) && ((b & 0xf0) == 0x40) )
+    if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) )
     {
         rex_prefix = b;
         if ( b & 8 )
@@ -674,7 +725,7 @@
         emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
         break;
     case 0x63: /* movsxd */
-        if ( mode != 8 ) /* x86/64 long mode only */
+        if ( mode != X86EMUL_MODE_PROT64 )
             goto cannot_emulate;
         dst.val = (int32_t)src.val;
         break;
@@ -721,12 +772,13 @@
         dst.val = src.val;
         break;
     case 0x8f: /* pop (sole member of Grp1a) */
-        /* 64-bit mode: POP defaults to 64-bit operands. */
-        if ( (mode == 8) && (dst.bytes == 4) )
+        /* 64-bit mode: POP always pops a 64-bit operand. */
+        if ( mode == X86EMUL_MODE_PROT64 )
             dst.bytes = 8;
-        if ( (rc = ops->read_std(_regs.esp, &dst.val, dst.bytes)) != 0 )
+        if ( (rc = ops->read_std(register_address(_regs.ss, _regs.esp),
+                                 &dst.val, dst.bytes)) != 0 )
             goto done;
-        _regs.esp += dst.bytes;
+        register_address_increment(_regs.esp, dst.bytes);
         break;
     case 0xc0 ... 0xc1: grp2: /* Grp2 */
         switch ( modrm_reg )
@@ -797,16 +849,17 @@
             emulate_1op("dec", dst, _regs.eflags);
             break;
         case 6: /* push */
-            /* 64-bit mode: PUSH defaults to 64-bit operands. */
-            if ( (mode == 8) && (dst.bytes == 4) )
+            /* 64-bit mode: PUSH always pushes a 64-bit operand. */
+            if ( mode == X86EMUL_MODE_PROT64 )
             {
                 dst.bytes = 8;
                 if ( (rc = ops->read_std((unsigned long)dst.ptr,
                                          &dst.val, 8)) != 0 )
                     goto done;
             }
-            _regs.esp -= dst.bytes;
-            if ( (rc = ops->write_std(_regs.esp, dst.val, dst.bytes)) != 0 )
+            register_address_increment(_regs.esp, -dst.bytes);
+            if ( (rc = ops->write_std(register_address(_regs.ss, _regs.esp),
+                                      dst.val, dst.bytes)) != 0 )
                 goto done;
             dst.val = dst.orig_val; /* skanky: disable writeback */
             break;
@@ -873,19 +926,22 @@
         {
             /* Write fault: destination is special memory. */
             dst.ptr = (unsigned long *)cr2;
-            if ( (rc = ops->read_std(_regs.esi - _regs.edi + cr2, 
+            if ( (rc = ops->read_std(register_address(seg ? *seg : _regs.ds,
+                                                      _regs.esi),
                                      &dst.val, dst.bytes)) != 0 )
                 goto done;
         }
         else
         {
             /* Read fault: source is special memory. */
-            dst.ptr = (unsigned long *)(_regs.edi - _regs.esi + cr2);
+            dst.ptr = (unsigned long *)register_address(_regs.es, _regs.edi);
             if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 )
                 goto done;
         }
-        _regs.esi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
-        _regs.edi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
+        register_address_increment(
+            _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
+        register_address_increment(
+            _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
         break;
     case 0xa6 ... 0xa7: /* cmps */
         DPRINTF("Urk! I don't handle CMPS.\n");
@@ -895,7 +951,8 @@
         dst.bytes = (d & ByteOp) ? 1 : op_bytes;
         dst.ptr   = (unsigned long *)cr2;
         dst.val   = _regs.eax;
-        _regs.edi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
+        register_address_increment(
+            _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
         break;
     case 0xac ... 0xad: /* lods */
         dst.type  = OP_REG;
@@ -903,7 +960,8 @@
         dst.ptr   = (unsigned long *)&_regs.eax;
         if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 )
             goto done;
-        _regs.esi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
+        register_address_increment(
+            _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
         break;
     case 0xae ... 0xaf: /* scas */
         DPRINTF("Urk! I don't handle SCAS.\n");
diff -r 903fb46f240e -r cd914808acf1 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c     Tue Jan  3 14:59:00 2006
+++ b/xen/common/dom0_ops.c     Tue Jan  3 16:19:20 2006
@@ -16,6 +16,7 @@
 #include <xen/domain_page.h>
 #include <xen/trace.h>
 #include <xen/console.h>
+#include <xen/iocap.h>
 #include <asm/current.h>
 #include <public/dom0_ops.h>
 #include <public/sched_ctl.h>
@@ -582,6 +583,7 @@
         }
     }
     break;
+
     case DOM0_SETDEBUGGING:
     {
         struct domain *d; 
@@ -596,6 +598,53 @@
             put_domain(d);
             ret = 0;
         }
+    }
+    break;
+
+    case DOM0_IRQ_PERMISSION:
+    {
+        struct domain *d;
+        unsigned int pirq = op->u.irq_permission.pirq;
+
+        ret = -EINVAL;
+        if ( pirq >= NR_PIRQS )
+            break;
+
+        ret = -ESRCH;
+        d = find_domain_by_id(op->u.irq_permission.domain);
+        if ( d == NULL )
+            break;
+
+        if ( op->u.irq_permission.allow_access )
+            ret = irq_permit_access(d, pirq);
+        else
+            ret = irq_deny_access(d, pirq);
+
+        put_domain(d);
+    }
+    break;
+
+    case DOM0_IOMEM_PERMISSION:
+    {
+        struct domain *d;
+        unsigned long pfn = op->u.iomem_permission.first_pfn;
+        unsigned long nr_pfns = op->u.iomem_permission.nr_pfns;
+
+        ret = -EINVAL;
+        if ( (pfn + nr_pfns - 1) < pfn ) /* wrap? */
+            break;
+
+        ret = -ESRCH;
+        d = find_domain_by_id(op->u.iomem_permission.domain);
+        if ( d == NULL )
+            break;
+
+        if ( op->u.iomem_permission.allow_access )
+            ret = iomem_permit_access(d, pfn, pfn + nr_pfns - 1);
+        else
+            ret = iomem_deny_access(d, pfn, pfn + nr_pfns - 1);
+
+        put_domain(d);
     }
     break;
 
diff -r 903fb46f240e -r cd914808acf1 xen/common/domain.c
--- a/xen/common/domain.c       Tue Jan  3 14:59:00 2006
+++ b/xen/common/domain.c       Tue Jan  3 16:19:20 2006
@@ -16,6 +16,7 @@
 #include <xen/console.h>
 #include <xen/softirq.h>
 #include <xen/domain_page.h>
+#include <xen/rangeset.h>
 #include <asm/debugger.h>
 #include <public/dom0_ops.h>
 #include <public/sched.h>
@@ -52,22 +53,21 @@
 
     if ( !is_idle_task(d) &&
          ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) )
-    {
-        evtchn_destroy(d);
-        free_domain(d);
-        return NULL;
-    }
+        goto fail1;
     
     if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
-    {
-        grant_table_destroy(d);
-        evtchn_destroy(d);
-        free_domain(d);
-        return NULL;
-    }
-
-    arch_do_createdomain(v);
-    
+        goto fail2;
+
+    rangeset_domain_initialise(d);
+
+    d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
+    d->irq_caps   = rangeset_new(d, "Interrupts", 0);
+
+    if ( (d->iomem_caps == NULL) ||
+         (d->irq_caps == NULL) ||
+         (arch_do_createdomain(v) != 0) )
+        goto fail3;
+
     if ( !is_idle_task(d) )
     {
         write_lock(&domlist_lock);
@@ -83,6 +83,15 @@
     }
 
     return d;
+
+ fail3:
+    rangeset_domain_destroy(d);
+ fail2:
+    grant_table_destroy(d);
+ fail1:
+    evtchn_destroy(d);
+    free_domain(d);
+    return NULL;
 }
 
 
@@ -271,6 +280,8 @@
     *pd = d->next_in_hashbucket;
     write_unlock(&domlist_lock);
 
+    rangeset_domain_destroy(d);
+
     evtchn_destroy(d);
     grant_table_destroy(d);
 
diff -r 903fb46f240e -r cd914808acf1 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Tue Jan  3 14:59:00 2006
+++ b/xen/common/event_channel.c        Tue Jan  3 16:19:20 2006
@@ -22,6 +22,7 @@
 #include <xen/sched.h>
 #include <xen/event.h>
 #include <xen/irq.h>
+#include <xen/iocap.h>
 #include <asm/current.h>
 
 #include <public/xen.h>
@@ -241,6 +242,9 @@
 
     if ( pirq >= ARRAY_SIZE(d->pirq_to_evtchn) )
         return -EINVAL;
+
+    if ( !irq_access_permitted(d, pirq) )
+        return -EPERM;
 
     spin_lock(&d->evtchn_lock);
 
diff -r 903fb46f240e -r cd914808acf1 xen/common/keyhandler.c
--- a/xen/common/keyhandler.c   Tue Jan  3 14:59:00 2006
+++ b/xen/common/keyhandler.c   Tue Jan  3 16:19:20 2006
@@ -11,6 +11,7 @@
 #include <xen/sched.h>
 #include <xen/softirq.h>
 #include <xen/domain.h>
+#include <xen/rangeset.h>
 #include <asm/debugger.h>
 
 #define KEY_MAX 256
@@ -109,31 +110,32 @@
 
     for_each_domain ( d )
     {
-        printk("Xen: DOM %u, flags=%lx refcnt=%d nr_pages=%d "
-               "xenheap_pages=%d\n", d->domain_id, d->domain_flags,
-               atomic_read(&d->refcnt), d->tot_pages, d->xenheap_pages);
-        /* The handle is printed according to the OSF DCE UUID spec., even
-           though it is not necessarily such a thing, for ease of use when it
-           _is_ one of those. */
-        printk("     handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+        printk("General information for domain %u:\n", d->domain_id);
+        printk("    flags=%lx refcnt=%d nr_pages=%d xenheap_pages=%d\n",
+               d->domain_flags, atomic_read(&d->refcnt),
+               d->tot_pages, d->xenheap_pages);
+        printk("    handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
                "%02x%02x-%02x%02x%02x%02x%02x%02x\n",
                d->handle[ 0], d->handle[ 1], d->handle[ 2], d->handle[ 3],
                d->handle[ 4], d->handle[ 5], d->handle[ 6], d->handle[ 7],
                d->handle[ 8], d->handle[ 9], d->handle[10], d->handle[11],
                d->handle[12], d->handle[13], d->handle[14], d->handle[15]);
 
+        rangeset_domain_printk(d);
+
         dump_pageframe_info(d);
                
+        printk("VCPU information and callbacks for domain %u:\n",
+               d->domain_id);
         for_each_vcpu ( d, v ) {
-            printk("Guest: %p CPU %d [has=%c] flags=%lx "
-                   "upcall_pend = %02x, upcall_mask = %02x\n", v,
-                   v->processor,
+            printk("    VCPU%d: CPU%d [has=%c] flags=%lx "
+                   "upcall_pend = %02x, upcall_mask = %02x\n",
+                   v->vcpu_id, v->processor,
                    test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F',
                    v->vcpu_flags,
                    v->vcpu_info->evtchn_upcall_pending, 
                    v->vcpu_info->evtchn_upcall_mask);
-            printk("Notifying guest... %d/%d\n", d->domain_id, v->vcpu_id); 
-            printk("port %d/%d stat %d %d %d\n",
+            printk("    Notifying guest (virq %d, port %d, stat %d/%d/%d)\n",
                    VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG],
                    test_bit(v->virq_to_evtchn[VIRQ_DEBUG], 
                             &d->shared_info->evtchn_pending[0]),
diff -r 903fb46f240e -r cd914808acf1 xen/common/memory.c
--- a/xen/common/memory.c       Tue Jan  3 14:59:00 2006
+++ b/xen/common/memory.c       Tue Jan  3 16:19:20 2006
@@ -15,6 +15,7 @@
 #include <xen/sched.h>
 #include <xen/event.h>
 #include <xen/shadow.h>
+#include <xen/iocap.h>
 #include <asm/current.h>
 #include <asm/hardirq.h>
 #include <public/memory.h>
@@ -35,7 +36,8 @@
          !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
         return 0;
 
-    if ( (extent_order != 0) && !IS_CAPABLE_PHYSDEV(current->domain) )
+    if ( (extent_order != 0) &&
+         !multipage_allocation_permitted(current->domain) )
     {
         DPRINTK("Only I/O-capable domains may allocate multi-page extents.\n");
         return 0;
diff -r 903fb46f240e -r cd914808acf1 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Tue Jan  3 14:59:00 2006
+++ b/xen/drivers/char/ns16550.c        Tue Jan  3 16:19:20 2006
@@ -13,6 +13,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/serial.h>
+#include <xen/iocap.h>
 #include <asm/io.h>
 
 /*
@@ -233,11 +234,11 @@
 }
 
 #ifdef CONFIG_X86
-#include <asm/physdev.h>
 static void ns16550_endboot(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
-    physdev_modify_ioport_access_range(dom0, 0, uart->io_base, 8);
+    if ( ioports_deny_access(dom0, uart->io_base, uart->io_base + 7) != 0 )
+        BUG();
 }
 #else
 #define ns16550_endboot NULL
diff -r 903fb46f240e -r cd914808acf1 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Tue Jan  3 14:59:00 2006
+++ b/xen/include/asm-ia64/domain.h     Tue Jan  3 16:19:20 2006
@@ -10,7 +10,7 @@
 #include <asm/vmx_platform.h>
 #include <xen/list.h>
 
-extern void arch_do_createdomain(struct vcpu *);
+extern int arch_do_createdomain(struct vcpu *);
 
 extern void domain_relinquish_resources(struct domain *);
 
diff -r 903fb46f240e -r cd914808acf1 xen/include/asm-x86/current.h
--- a/xen/include/asm-x86/current.h     Tue Jan  3 14:59:00 2006
+++ b/xen/include/asm-x86/current.h     Tue Jan  3 16:19:20 2006
@@ -49,7 +49,7 @@
 #define reset_stack_and_jump(__fn)              \
     __asm__ __volatile__ (                      \
         "mov %0,%%"__OP"sp; jmp "STR(__fn)      \
-        : : "r" (guest_cpu_user_regs()) )
+        : : "r" (guest_cpu_user_regs()) : "memory" )
 
 #define schedule_tail(_ed) (((_ed)->arch.schedule_tail)(_ed))
 
diff -r 903fb46f240e -r cd914808acf1 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Tue Jan  3 14:59:00 2006
+++ b/xen/include/asm-x86/domain.h      Tue Jan  3 16:19:20 2006
@@ -24,8 +24,8 @@
     /* Writable pagetables. */
     struct ptwr_info ptwr[2];
 
-    /* I/O-port access bitmap mask. */
-    u8 *iobmp_mask;       /* Address of IO bitmap mask, or NULL.      */
+    /* I/O-port admin-specified access capabilities. */
+    struct rangeset *ioport_caps;
 
     /* Shadow mode status and controls. */
     struct shadow_ops *ops;
diff -r 903fb46f240e -r cd914808acf1 xen/include/asm-x86/msr.h
--- a/xen/include/asm-x86/msr.h Tue Jan  3 14:59:00 2006
+++ b/xen/include/asm-x86/msr.h Tue Jan  3 16:19:20 2006
@@ -12,7 +12,7 @@
        __asm__ __volatile__("rdmsr" \
                            : "=a" (a__), "=d" (b__) \
                            : "c" (msr)); \
-       val = a__ | (b__<<32); \
+       val = a__ | ((u64)b__<<32); \
 } while(0); 
 
 #define wrmsr(msr,val1,val2) \
diff -r 903fb46f240e -r cd914808acf1 xen/include/asm-x86/x86_emulate.h
--- a/xen/include/asm-x86/x86_emulate.h Tue Jan  3 14:59:00 2006
+++ b/xen/include/asm-x86/x86_emulate.h Tue Jan  3 16:19:20 2006
@@ -141,6 +141,12 @@
 
 struct cpu_user_regs;
 
+/* Current execution mode, passed to the emulator. */
+#define X86EMUL_MODE_REAL     0
+#define X86EMUL_MODE_PROT16   2
+#define X86EMUL_MODE_PROT32   4
+#define X86EMUL_MODE_PROT64   8
+
 /*
  * x86_emulate_memop: Emulate an instruction that faulted attempting to
  *                    read/write a 'special' memory area.
@@ -149,6 +155,8 @@
  *  @ops:  Interface to access special memory.
  *  @mode: Current execution mode, represented by the default size of memory
  *         addresses, in bytes. Valid values are 2, 4 and 8 (x86/64 only).
+ *         Alternatively use the appropriate X86EMUL_MODE value (which also
+ *         includes a value for emulating real mode).
  */
 extern int
 x86_emulate_memop(
diff -r 903fb46f240e -r cd914808acf1 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Tue Jan  3 14:59:00 2006
+++ b/xen/include/public/dom0_ops.h     Tue Jan  3 16:19:20 2006
@@ -410,6 +410,21 @@
     uint8_t enable;
 } dom0_setdebugging_t;
 
+#define DOM0_IRQ_PERMISSION 46
+typedef struct {
+    domid_t domain;          /* domain to be affected */
+    uint8_t pirq;
+    uint8_t allow_access;    /* flag to specify enable/disable of IRQ access */
+} dom0_irq_permission_t;
+
+#define DOM0_IOMEM_PERMISSION 47
+typedef struct {
+    domid_t  domain;          /* domain to be affected */
+    unsigned long first_pfn;  /* first page (physical page number) in range */
+    unsigned long nr_pfns;    /* number of pages in range (>0) */
+    uint8_t allow_access;     /* allow (!0) or deny (0) access to range? */
+} dom0_iomem_permission_t;
+ 
 typedef struct {
     uint32_t cmd;
     uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
@@ -448,6 +463,8 @@
         dom0_max_vcpus_t         max_vcpus;
         dom0_setdomainhandle_t   setdomainhandle;        
         dom0_setdebugging_t      setdebugging;
+        dom0_irq_permission_t    irq_permission;
+        dom0_iomem_permission_t  iomem_permission;
         uint8_t                  pad[128];
     } u;
 } dom0_op_t;
diff -r 903fb46f240e -r cd914808acf1 xen/include/xen/compiler.h
--- a/xen/include/xen/compiler.h        Tue Jan  3 14:59:00 2006
+++ b/xen/include/xen/compiler.h        Tue Jan  3 16:19:20 2006
@@ -19,4 +19,10 @@
 #define __attribute_used__ __attribute__((__unused__))
 #endif
 
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define __must_check __attribute__((warn_unused_result))
+#else
+#define __must_check
+#endif
+
 #endif /* __LINUX_COMPILER_H */
diff -r 903fb46f240e -r cd914808acf1 xen/include/xen/domain.h
--- a/xen/include/xen/domain.h  Tue Jan  3 14:59:00 2006
+++ b/xen/include/xen/domain.h  Tue Jan  3 16:19:20 2006
@@ -13,9 +13,9 @@
 
 extern void free_vcpu_struct(struct vcpu *v);
 
-extern void arch_do_createdomain(struct vcpu *v);
+extern int arch_do_createdomain(struct vcpu *v);
 
-extern int  arch_set_info_guest(
+extern int arch_set_info_guest(
     struct vcpu *v, struct vcpu_guest_context *c);
 
 extern void vcpu_migrate_cpu(struct vcpu *v, int newcpu);
diff -r 903fb46f240e -r cd914808acf1 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Tue Jan  3 14:59:00 2006
+++ b/xen/include/xen/sched.h   Tue Jan  3 16:19:20 2006
@@ -11,6 +11,7 @@
 #include <xen/time.h>
 #include <xen/ac_timer.h>
 #include <xen/grant_table.h>
+#include <xen/rangeset.h>
 #include <asm/domain.h>
 
 extern unsigned long volatile jiffies;
@@ -110,6 +111,9 @@
     struct domain   *next_in_list;
     struct domain   *next_in_hashbucket;
 
+    struct list_head rangesets;
+    spinlock_t       rangesets_lock;
+
     /* Event channel information. */
     struct evtchn   *evtchn[NR_EVTCHN_BUCKETS];
     spinlock_t       evtchn_lock;
@@ -124,6 +128,10 @@
 #define NR_PIRQS 256 /* Put this somewhere sane! */
     u16              pirq_to_evtchn[NR_PIRQS];
     u32              pirq_mask[NR_PIRQS/32];
+
+    /* I/O capabilities (access to IRQs and memory-mapped I/O). */
+    struct rangeset *iomem_caps;
+    struct rangeset *irq_caps;
 
     unsigned long    domain_flags;
     unsigned long    vm_assist;
@@ -378,23 +386,20 @@
  /* Is this domain privileged? */
 #define _DOMF_privileged       1
 #define DOMF_privileged        (1UL<<_DOMF_privileged)
- /* May this domain do IO to physical devices? */
-#define _DOMF_physdev_access   2
-#define DOMF_physdev_access    (1UL<<_DOMF_physdev_access)
  /* Guest shut itself down for some reason. */
-#define _DOMF_shutdown         3
+#define _DOMF_shutdown         2
 #define DOMF_shutdown          (1UL<<_DOMF_shutdown)
  /* Guest is in process of shutting itself down (becomes DOMF_shutdown). */
-#define _DOMF_shuttingdown     4
+#define _DOMF_shuttingdown     3
 #define DOMF_shuttingdown      (1UL<<_DOMF_shuttingdown)
  /* Death rattle. */
-#define _DOMF_dying            5
+#define _DOMF_dying            4
 #define DOMF_dying             (1UL<<_DOMF_dying)
  /* Domain is paused by controller software. */
-#define _DOMF_ctrl_pause       6
+#define _DOMF_ctrl_pause       5
 #define DOMF_ctrl_pause        (1UL<<_DOMF_ctrl_pause)
  /* Domain is being debugged by controller software. */
-#define _DOMF_debugging        7
+#define _DOMF_debugging        6
 #define DOMF_debugging         (1UL<<_DOMF_debugging)
 
 
@@ -422,8 +427,6 @@
 
 #define IS_PRIV(_d)                                         \
     (test_bit(_DOMF_privileged, &(_d)->domain_flags))
-#define IS_CAPABLE_PHYSDEV(_d)                              \
-    (test_bit(_DOMF_physdev_access, &(_d)->domain_flags))
 
 #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist))
 
diff -r 903fb46f240e -r cd914808acf1 tools/libxc/xc_pagetab.c
--- /dev/null   Tue Jan  3 14:59:00 2006
+++ b/tools/libxc/xc_pagetab.c  Tue Jan  3 16:19:20 2006
@@ -0,0 +1,192 @@
+/******************************************************************************
+ * xc_pagetab.c
+ *
+ * Function to translate virtual to physical addresses.
+ */
+#include "xc_private.h"
+
+#if defined(__i386__)
+
+#define L1_PAGETABLE_SHIFT_PAE 12
+#define L2_PAGETABLE_SHIFT_PAE 21
+#define L3_PAGETABLE_SHIFT_PAE 30
+
+#define L1_PAGETABLE_SHIFT             12
+#define L2_PAGETABLE_SHIFT             22
+
+#define L0_PAGETABLE_MASK_PAE  0x0000000ffffff000ULL
+#define L1_PAGETABLE_MASK_PAE  0x1ffULL
+#define L2_PAGETABLE_MASK_PAE  0x1ffULL
+#define L3_PAGETABLE_MASK_PAE  0x3ULL
+
+#define L0_PAGETABLE_MASK              0xfffff000ULL
+#define L1_PAGETABLE_MASK              0x3ffULL
+#define L2_PAGETABLE_MASK              0x3ffULL
+
+#elif defined(__x86_64__)
+
+#define L1_PAGETABLE_SHIFT_PAE 12
+#define L2_PAGETABLE_SHIFT_PAE 21
+#define L3_PAGETABLE_SHIFT_PAE 30
+#define L4_PAGETABLE_SHIFT_PAE 39
+
+#define L1_PAGETABLE_SHIFT             L1_PAGETABLE_SHIFT_PAE
+#define L2_PAGETABLE_SHIFT             L2_PAGETABLE_SHIFT_PAE
+
+#define L0_PAGETABLE_MASK_PAE  0x000000fffffff000ULL
+#define L1_PAGETABLE_MASK_PAE  0x1ffULL
+#define L2_PAGETABLE_MASK_PAE  0x1ffULL
+#define L3_PAGETABLE_MASK_PAE  0x1ffULL
+#define L4_PAGETABLE_MASK_PAE  0x1ffULL
+
+#define L0_PAGETABLE_MASK              L0_PAGETABLE_MASK_PAE
+#define L1_PAGETABLE_MASK              L1_PAGETABLE_MASK_PAE
+#define L2_PAGETABLE_MASK              L2_PAGETABLE_MASK_PAE
+
+#endif
+
+unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
+                                           int vcpu, unsigned long long virt )
+{
+    vcpu_guest_context_t ctx;
+    unsigned long long cr3;
+    void *pd, *pt, *pdppage = NULL, *pdp, *pml = NULL;
+    unsigned long long pde, pte, pdpe, pmle;
+    unsigned long mfn = 0;
+#if defined (__i386__)
+    static int pt_levels = 0;
+
+    if (pt_levels == 0) {
+        xen_capabilities_info_t xen_caps = "";
+
+        if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0)
+            goto out;
+        if (strstr(xen_caps, "xen-3.0-x86_64"))
+            pt_levels = 4;
+        else if (strstr(xen_caps, "xen-3.0-x86_32p"))
+            pt_levels = 3;
+        else if (strstr(xen_caps, "xen-3.0-x86_32"))
+            pt_levels = 2;
+        else
+            goto out;
+    }
+#elif defined (__x86_64__)
+#define pt_levels 4
+#endif
+
+    if (xc_domain_get_vcpu_context(xc_handle, dom, vcpu, &ctx) != 0) {
+        fprintf(stderr, "failed to retreive vcpu context\n");
+        goto out;
+    }
+    cr3 = ctx.ctrlreg[3];
+
+    /* Page Map Level 4 */
+
+#if defined(__i386__)
+    pmle = cr3;
+#elif defined(__x86_64__)
+    pml = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, cr3 >> 
PAGE_SHIFT);
+    if (pml == NULL) {
+        fprintf(stderr, "failed to map PML4\n");
+        goto out;
+    }
+    pmle = *(unsigned long long *)(pml + 8 * ((virt >> L4_PAGETABLE_SHIFT_PAE) 
& L4_PAGETABLE_MASK_PAE));
+    if((pmle & 1) == 0) {
+        fprintf(stderr, "page entry not present in PML4\n");
+        goto out_unmap_pml;
+    }
+#endif
+
+    /* Page Directory Pointer Table */
+
+    if (pt_levels >= 3) {
+        pdppage = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, 
pmle >> PAGE_SHIFT);
+        if (pdppage == NULL) {
+            fprintf(stderr, "failed to map PDP\n");
+            goto out_unmap_pml;
+        }
+        if (pt_levels >= 4)
+            pdp = pdppage;
+        else
+            /* PDP is only 32 bit aligned with 3 level pts */
+            pdp = pdppage + (pmle & ~(XC_PAGE_MASK | 0x1f));
+
+        pdpe = *(unsigned long long *)(pdp + 8 * ((virt >> 
L3_PAGETABLE_SHIFT_PAE) & L3_PAGETABLE_MASK_PAE));
+
+        if((pdpe & 1) == 0) {
+            fprintf(stderr, "page entry not present in PDP\n");
+            goto out_unmap_pdp;
+        }
+    } else {
+        pdpe = pmle;
+    }
+
+    /* Page Directory */
+
+    pd = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, pdpe >> 
PAGE_SHIFT);
+    if (pd == NULL) {
+        fprintf(stderr, "failed to map PD\n");
+        goto out_unmap_pdp;
+    }
+
+    if (pt_levels >= 3)
+        pde = *(unsigned long long *)(pd + 8 * ((virt >> 
L2_PAGETABLE_SHIFT_PAE) & L2_PAGETABLE_MASK_PAE));
+    else
+        pde = *(unsigned long long *)(pd + 4 * ((virt >> L2_PAGETABLE_SHIFT) & 
L2_PAGETABLE_MASK));
+
+    if ((pde & 1) == 0) {
+        fprintf(stderr, "page entry not present in PD\n");
+        goto out_unmap_pd;
+    }
+
+    /* Page Table */
+
+    if (pde & 0x00000008) { /* 4M page (or 2M in PAE mode) */
+        fprintf(stderr, "Cannot currently cope with 2/4M pages\n");
+        exit(-1);
+    } else { /* 4k page */
+        pt = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
+                                  pde >> PAGE_SHIFT);
+
+        if (pt == NULL) {
+            fprintf(stderr, "failed to map PT\n");
+            goto out_unmap_pd;
+        }
+
+        if (pt_levels >= 3)
+            pte = *(unsigned long long *)(pt + 8 * ((virt >> 
L1_PAGETABLE_SHIFT_PAE) & L1_PAGETABLE_MASK_PAE));
+        else
+            pte = *(unsigned long long *)(pt + 4 * ((virt >> 
L1_PAGETABLE_SHIFT) & L1_PAGETABLE_MASK));
+
+        if ((pte & 0x00000001) == 0) {
+            fprintf(stderr, "page entry not present in PT\n");
+            goto out_unmap_pt;
+        }
+
+        if (pt_levels >= 3)
+            mfn = (pte & L0_PAGETABLE_MASK_PAE) >> PAGE_SHIFT;
+        else
+            mfn = (pte & L0_PAGETABLE_MASK) >> PAGE_SHIFT;
+    }
+
+ out_unmap_pt:
+    munmap(pt, PAGE_SIZE);
+ out_unmap_pd:
+    munmap(pd, PAGE_SIZE);
+ out_unmap_pdp:
+    munmap(pdppage, PAGE_SIZE);
+ out_unmap_pml:
+    munmap(pml, PAGE_SIZE);
+ out:
+    return mfn;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/x86_32/xen.lds.S
--- /dev/null   Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/x86_32/xen.lds.S     Tue Jan  3 16:19:20 2006
@@ -0,0 +1,85 @@
+/* ld script to make i386 Linux kernel
+ * Written by Martin Mares <mj@xxxxxxxxxxxxxxxxxxxxxxxx>
+ * Modified for i386 Xen by Keir Fraser
+ */
+
+#include <xen/config.h>
+#include <asm/page.h>
+#undef ENTRY
+#undef ALIGN
+
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(start)
+PHDRS
+{
+  text PT_LOAD ;
+}
+SECTIONS
+{
+  . = 0xFF000000 + 0x100000;
+  _text = .;                   /* Text and read-only data */
+  .text : {
+       *(.text)
+       *(.fixup)
+       *(.gnu.warning)
+       } :text =0x9090
+  .text.lock : { *(.text.lock) } :text /* out-of-line lock text */
+
+  _etext = .;                  /* End of text section */
+
+  .rodata : { *(.rodata) *(.rodata.*) } :text
+
+  . = ALIGN(32);               /* Exception table */
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) } :text
+  __stop___ex_table = .;
+
+  . = ALIGN(32);               /* Pre-exception table */
+  __start___pre_ex_table = .;
+  __pre_ex_table : { *(__pre_ex_table) } :text
+  __stop___pre_ex_table = .;
+
+  .data : {                    /* Data */
+       *(.data)
+       CONSTRUCTORS
+       } :text
+
+  . = ALIGN(4096);             /* Init code and data */
+  __init_begin = .;
+  .text.init : { *(.text.init) } :text
+  .data.init : { *(.data.init) } :text
+  . = ALIGN(32);
+  __setup_start = .;
+  .setup.init : { *(.setup.init) } :text
+  __setup_end = .;
+  __initcall_start = .;
+  .initcall.init : { *(.initcall.init) } :text
+  __initcall_end = .;
+  . = ALIGN(STACK_SIZE);
+  __init_end = .;
+
+  __bss_start = .;             /* BSS */
+  .bss : {
+       *(.bss.stack_aligned)
+       *(.bss.page_aligned)
+       *(.bss)
+       } :text
+  _end = . ;
+
+  /* Sections to be discarded */
+  /DISCARD/ : {
+       *(.text.exit)
+       *(.data.exit)
+       *(.exitcall.exit)
+       }
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+}
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/x86_64/xen.lds.S
--- /dev/null   Tue Jan  3 14:59:00 2006
+++ b/xen/arch/x86/x86_64/xen.lds.S     Tue Jan  3 16:19:20 2006
@@ -0,0 +1,83 @@
+/* Excerpts written by Martin Mares <mj@xxxxxxxxxxxxxxxxxxxxxxxx> */
+/* Modified for x86-64 Xen by Keir Fraser */
+
+#include <xen/config.h>
+#include <asm/page.h>
+#undef ENTRY
+#undef ALIGN
+
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(start)
+PHDRS
+{
+  text PT_LOAD ;
+}
+SECTIONS
+{
+  . = 0xFFFF830000100000;
+  _text = .;                   /* Text and read-only data */
+  .text : {
+       *(.text)
+       *(.fixup)
+       *(.gnu.warning)
+       } :text = 0x9090
+  .text.lock : { *(.text.lock) } :text /* out-of-line lock text */
+
+  _etext = .;                  /* End of text section */
+
+  .rodata : { *(.rodata) *(.rodata.*) } :text
+
+  . = ALIGN(32);               /* Exception table */
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) } :text
+  __stop___ex_table = .;
+
+  . = ALIGN(32);                /* Pre-exception table */
+  __start___pre_ex_table = .;
+  __pre_ex_table : { *(__pre_ex_table) } :text
+  __stop___pre_ex_table = .;
+
+  .data : {                    /* Data */
+       *(.data)
+       CONSTRUCTORS
+       } :text
+
+  . = ALIGN(4096);             /* Init code and data */
+  __init_begin = .;
+  .text.init : { *(.text.init) } :text
+  .data.init : { *(.data.init) } :text
+  . = ALIGN(32);
+  __setup_start = .;
+  .setup.init : { *(.setup.init) } :text
+  __setup_end = .;
+  __initcall_start = .;
+  .initcall.init : { *(.initcall.init) } :text
+  __initcall_end = .;
+  . = ALIGN(STACK_SIZE);
+  __init_end = .;
+
+  __bss_start = .;             /* BSS */
+  .bss : {
+       *(.bss.stack_aligned)
+       *(.bss.page_aligned)
+       *(.bss)
+       } :text
+  _end = . ;
+
+  /* Sections to be discarded */
+  /DISCARD/ : {
+       *(.text.exit)
+       *(.data.exit)
+       *(.exitcall.exit)
+       }
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+}
diff -r 903fb46f240e -r cd914808acf1 xen/common/rangeset.c
--- /dev/null   Tue Jan  3 14:59:00 2006
+++ b/xen/common/rangeset.c     Tue Jan  3 16:19:20 2006
@@ -0,0 +1,399 @@
+/******************************************************************************
+ * rangeset.c
+ * 
+ * Creation, maintenance and automatic destruction of per-domain sets of
+ * numeric ranges.
+ * 
+ * Copyright (c) 2005, K A Fraser
+ */
+
+#include <xen/sched.h>
+#include <xen/rangeset.h>
+
+/* An inclusive range [s,e] and pointer to next range in ascending order. */
+struct range {
+    struct list_head list;
+    unsigned long s, e;
+};
+
+struct rangeset {
+    /* Owning domain and threaded list of rangesets. */
+    struct list_head rangeset_list;
+    struct domain   *domain;
+
+    /* Ordered list of ranges contained in this set, and protecting lock. */
+    struct list_head range_list;
+    spinlock_t       lock;
+
+    /* Pretty-printing name. */
+    char             name[32];
+
+    /* RANGESETF flags. */
+    unsigned int     flags;
+};
+
+/*****************************
+ * Private range functions hide the underlying linked-list implemnetation.
+ */
+
+/* Find highest range lower than or containing s. NULL if no such range. */
+static struct range *find_range(
+    struct rangeset *r, unsigned long s)
+{
+    struct range *x = NULL, *y;
+
+    list_for_each_entry ( y, &r->range_list, list )
+    {
+        if ( y->s > s )
+            break;
+        x = y;
+    }
+
+    return x;
+}
+
+/* Return the lowest range in the set r, or NULL if r is empty. */
+static struct range *first_range(
+    struct rangeset *r)
+{
+    if ( list_empty(&r->range_list) )
+        return NULL;
+    return list_entry(r->range_list.next, struct range, list);
+}
+
+/* Return range following x in ascending order, or NULL if x is the highest. */
+static struct range *next_range(
+    struct rangeset *r, struct range *x)
+{
+    if ( x->list.next == &r->range_list )
+        return NULL;
+    return list_entry(x->list.next, struct range, list);
+}
+
+/* Insert range y after range x in r. Insert as first range if x is NULL. */
+static void insert_range(
+    struct rangeset *r, struct range *x, struct range *y)
+{
+    list_add(&y->list, (x != NULL) ? &x->list : &r->range_list);
+}
+
+/* Remove a range from its list and free it. */
+static void destroy_range(
+    struct range *x)
+{
+    list_del(&x->list);
+    xfree(x);
+}
+
+/*****************************
+ * Core public functions
+ */
+
+int rangeset_add_range(
+    struct rangeset *r, unsigned long s, unsigned long e)
+{
+    struct range *x, *y;
+    int rc = 0;
+
+    spin_lock(&r->lock);
+
+    x = find_range(r, s);
+    y = find_range(r, e);
+
+    if ( x == y )
+    {
+        if ( (x == NULL) || ((x->e < s) && ((x->e + 1) != s)) )
+        {
+            x = xmalloc(struct range);
+            if ( x == NULL )
+            {
+                rc = -ENOMEM;
+                goto out;
+            }
+
+            x->s = s;
+            x->e = e;
+
+            insert_range(r, y, x);
+        }
+        else if ( x->e < e )
+            x->e = e;
+    }
+    else
+    {
+        if ( x == NULL )
+        {
+            x = first_range(r);
+            x->s = s;
+        }
+        else if ( (x->e < s) && ((x->e + 1) != s) )
+        {
+            x = next_range(r, x);
+            x->s = s;
+        }
+        
+        x->e = (y->e > e) ? y->e : e;
+
+        for ( ; ; )
+        {
+            y = next_range(r, x);
+            if ( (y == NULL) || (y->e > x->e) )
+                break;
+            destroy_range(y);
+        }
+    }
+
+    y = next_range(r, x);
+    if ( (y != NULL) && ((x->e + 1) == y->s) )
+    {
+        x->e = y->e;
+        destroy_range(y);
+    }
+
+ out:
+    spin_unlock(&r->lock);
+    return rc;
+}
+
+int rangeset_remove_range(
+    struct rangeset *r, unsigned long s, unsigned long e)
+{
+    struct range *x, *y, *t;
+    int rc = 0;
+
+    spin_lock(&r->lock);
+
+    x = find_range(r, s);
+    y = find_range(r, e);
+
+    if ( x == y )
+    {
+        if ( (x == NULL) || (x->e < s) )
+            goto out;
+
+        if ( (x->s < s) && (x->e > e) )
+        {
+            y = xmalloc(struct range);
+            if ( y == NULL )
+            {
+                rc = -ENOMEM;
+                goto out;
+            }
+
+            y->s = e + 1;
+            y->e = x->e;
+            x->e = s - 1;
+
+            insert_range(r, x, y);
+        }
+        else if ( (x->s == s) && (x->e <= e) )
+            destroy_range(x);
+        else if ( x->s == s )
+            x->s = e + 1;
+        else if ( x->e <= e )
+            x->e = s - 1;
+    }
+    else
+    {
+        if ( x == NULL )
+            x = first_range(r);
+
+        if ( x->s < s )
+        {
+            x->e = s - 1;
+            x = next_range(r, x);
+        }
+
+        while ( x != y )
+        {
+            t = x;
+            x = next_range(r, x);
+            destroy_range(t);
+        }
+
+        x->s = e + 1;
+        if ( x->s > x->e )
+            destroy_range(x);
+    }
+
+ out:
+    spin_unlock(&r->lock);
+    return rc;
+}
+
+int rangeset_contains_range(
+    struct rangeset *r, unsigned long s, unsigned long e)
+{
+    struct range *x;
+    int contains;
+
+    spin_lock(&r->lock);
+    x = find_range(r, s);
+    contains = (x && (x->e >= e));
+    spin_unlock(&r->lock);
+
+    return contains;
+}
+
+int rangeset_add_singleton(
+    struct rangeset *r, unsigned long s)
+{
+    return rangeset_add_range(r, s, s);
+}
+
+int rangeset_remove_singleton(
+    struct rangeset *r, unsigned long s)
+{
+    return rangeset_remove_range(r, s, s);
+}
+
+int rangeset_contains_singleton(
+    struct rangeset *r, unsigned long s)
+{
+    return rangeset_contains_range(r, s, s);
+}
+
+int rangeset_is_empty(
+    struct rangeset *r)
+{
+    return list_empty(&r->range_list);
+}
+
+struct rangeset *rangeset_new(
+    struct domain *d, char *name, unsigned int flags)
+{
+    struct rangeset *r;
+
+    r = xmalloc(struct rangeset);
+    if ( r == NULL )
+        return NULL;
+
+    spin_lock_init(&r->lock);
+    INIT_LIST_HEAD(&r->range_list);
+
+    BUG_ON(flags & ~RANGESETF_prettyprint_hex);
+    r->flags = flags;
+
+    if ( name != NULL )
+    {
+        strncpy(r->name, name, sizeof(r->name));
+        r->name[sizeof(r->name)-1] = '\0';
+    }
+    else
+    {
+        sprintf(r->name, "(no name)");
+    }
+
+    if ( (r->domain = d) != NULL )
+    {
+        spin_lock(&d->rangesets_lock);
+        list_add(&r->rangeset_list, &d->rangesets);
+        spin_unlock(&d->rangesets_lock);
+    }
+
+    return r;
+}
+
+void rangeset_destroy(
+    struct rangeset *r)
+{
+    struct range *x;
+
+    if ( r == NULL )
+        return;
+
+    if ( r->domain != NULL )
+    {
+        spin_lock(&r->domain->rangesets_lock);
+        list_del(&r->rangeset_list);
+        spin_unlock(&r->domain->rangesets_lock);
+    }
+
+    while ( (x = first_range(r)) != NULL )
+        destroy_range(x);
+
+    xfree(r);
+}
+
+void rangeset_domain_initialise(
+    struct domain *d)
+{
+    INIT_LIST_HEAD(&d->rangesets);
+    spin_lock_init(&d->rangesets_lock);
+}
+
+void rangeset_domain_destroy(
+    struct domain *d)
+{
+    struct rangeset *r;
+
+    while ( !list_empty(&d->rangesets) )
+    {
+        r = list_entry(d->rangesets.next, struct rangeset, rangeset_list);
+
+        BUG_ON(r->domain != d);
+        r->domain = NULL;
+        list_del(&r->rangeset_list);
+
+        rangeset_destroy(r);
+    }
+}
+
+/*****************************
+ * Pretty-printing functions
+ */
+
+static void print_limit(struct rangeset *r, unsigned long s)
+{
+    printk((r->flags & RANGESETF_prettyprint_hex) ? "%lx" : "%lu", s);
+}
+
+void rangeset_printk(
+    struct rangeset *r)
+{
+    int nr_printed = 0;
+    struct range *x;
+
+    spin_lock(&r->lock);
+
+    printk("%-10s {", r->name);
+
+    for ( x = first_range(r); x != NULL; x = next_range(r, x) )
+    {
+        if ( nr_printed++ )
+            printk(",");
+        printk(" ");
+        print_limit(r, x->s);
+        if ( x->s != x->e )
+        {
+            printk("-");
+            print_limit(r, x->e);
+        }
+    }
+
+    printk(" }");
+
+    spin_unlock(&r->lock);
+}
+
+void rangeset_domain_printk(
+    struct domain *d)
+{
+    struct rangeset *r;
+
+    printk("Rangesets belonging to domain %u:\n", d->domain_id);
+
+    spin_lock(&d->rangesets_lock);
+
+    if ( list_empty(&d->rangesets) )
+        printk("    None\n");
+
+    list_for_each_entry ( r, &d->rangesets, rangeset_list )
+    {
+        printk("    ");
+        rangeset_printk(r);
+        printk("\n");
+    }
+
+    spin_unlock(&d->rangesets_lock);
+}
diff -r 903fb46f240e -r cd914808acf1 xen/include/asm-ia64/iocap.h
--- /dev/null   Tue Jan  3 14:59:00 2006
+++ b/xen/include/asm-ia64/iocap.h      Tue Jan  3 16:19:20 2006
@@ -0,0 +1,10 @@
+/******************************************************************************
+ * iocap.h
+ * 
+ * Architecture-specific per-domain I/O capabilities.
+ */
+
+#ifndef __IA64_IOCAP_H__
+#define __IA64_IOCAP_H__
+
+#endif /* __IA64_IOCAP_H__ */
diff -r 903fb46f240e -r cd914808acf1 xen/include/asm-x86/iocap.h
--- /dev/null   Tue Jan  3 14:59:00 2006
+++ b/xen/include/asm-x86/iocap.h       Tue Jan  3 16:19:20 2006
@@ -0,0 +1,20 @@
+/******************************************************************************
+ * iocap.h
+ * 
+ * Architecture-specific per-domain I/O capabilities.
+ */
+
+#ifndef __X86_IOCAP_H__
+#define __X86_IOCAP_H__
+
+#define ioports_permit_access(d, s, e)                  \
+    rangeset_add_range((d)->arch.ioport_caps, s, e)
+#define ioports_deny_access(d, s, e)                    \
+    rangeset_remove_range((d)->arch.ioport_caps, s, e)
+#define ioports_access_permitted(d, s, e)               \
+    rangeset_contains_range((d)->arch.ioport_caps, s, e)
+
+#define cache_flush_permitted(d)                       \
+    (!rangeset_is_empty((d)->iomem_caps))
+
+#endif /* __X86_IOCAP_H__ */
diff -r 903fb46f240e -r cd914808acf1 xen/include/xen/iocap.h
--- /dev/null   Tue Jan  3 14:59:00 2006
+++ b/xen/include/xen/iocap.h   Tue Jan  3 16:19:20 2006
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * iocap.h
+ * 
+ * Per-domain I/O capabilities.
+ */
+
+#ifndef __XEN_IOCAP_H__
+#define __XEN_IOCAP_H__
+
+#include <xen/rangeset.h>
+#include <asm/iocap.h>
+
+#define iomem_permit_access(d, s, e)                    \
+    rangeset_add_range((d)->iomem_caps, s, e)
+#define iomem_deny_access(d, s, e)                      \
+    rangeset_remove_range((d)->iomem_caps, s, e)
+#define iomem_access_permitted(d, s, e)                 \
+    rangeset_contains_range((d)->iomem_caps, s, e)
+
+#define irq_permit_access(d, i)                         \
+    rangeset_add_singleton((d)->irq_caps, i)
+#define irq_deny_access(d, i)                           \
+    rangeset_remove_singleton((d)->irq_caps, i)
+#define irqs_permit_access(d, s, e)                     \
+    rangeset_add_range((d)->irq_caps, s, e)
+#define irqs_deny_access(d, s, e)                       \
+    rangeset_remove_range((d)->irq_caps, s, e)
+#define irq_access_permitted(d, i)                      \
+    rangeset_contains_singleton((d)->irq_caps, i)
+
+#define multipage_allocation_permitted(d)               \
+    (!rangeset_is_empty((d)->iomem_caps))
+
+#endif /* __XEN_IOCAP_H__ */
diff -r 903fb46f240e -r cd914808acf1 xen/include/xen/rangeset.h
--- /dev/null   Tue Jan  3 14:59:00 2006
+++ b/xen/include/xen/rangeset.h        Tue Jan  3 16:19:20 2006
@@ -0,0 +1,71 @@
+/******************************************************************************
+ * rangeset.h
+ * 
+ * Creation, maintenance and automatic destruction of per-domain sets of
+ * numeric ranges.
+ * 
+ * Copyright (c) 2005, K A Fraser
+ */
+
+#ifndef __XEN_RANGESET_H__
+#define __XEN_RANGESET_H__
+
+struct domain;
+struct rangeset;
+
+/*
+ * Initialise/destroy per-domain rangeset information.
+ * 
+ * It is invalid to create or destroy a rangeset belonging to a domain @d
+ * before rangeset_domain_initialise(d) returns or after calling
+ * rangeset_domain_destroy(d).
+ */
+void rangeset_domain_initialise(
+    struct domain *d);
+void rangeset_domain_destroy(
+    struct domain *d);
+
+/*
+ * Create/destroy a rangeset. Optionally attach to specified domain @d for
+ * auto-destruction when the domain dies. A name may be specified, for use
+ * in debug pretty-printing, and various RANGESETF flags (defined below).
+ * 
+ * It is invalid to perform any operation on a rangeset @r after calling
+ * rangeset_destroy(r).
+ */
+struct rangeset *rangeset_new(
+    struct domain *d, char *name, unsigned int flags);
+void rangeset_destroy(
+    struct rangeset *r);
+
+/* Flags for passing to rangeset_new(). */
+ /* Pretty-print range limits in hexadecimal. */
+#define _RANGESETF_prettyprint_hex 0
+#define RANGESETF_prettyprint_hex  (1U << _RANGESETF_prettyprint_hex)
+
+int __must_check rangeset_is_empty(
+    struct rangeset *r);
+
+/* Add/remove/query a numeric range. */
+int __must_check rangeset_add_range(
+    struct rangeset *r, unsigned long s, unsigned long e);
+int __must_check rangeset_remove_range(
+    struct rangeset *r, unsigned long s, unsigned long e);
+int __must_check rangeset_contains_range(
+    struct rangeset *r, unsigned long s, unsigned long e);
+
+/* Add/remove/query a single number. */
+int __must_check rangeset_add_singleton(
+    struct rangeset *r, unsigned long s);
+int __must_check rangeset_remove_singleton(
+    struct rangeset *r, unsigned long s);
+int __must_check rangeset_contains_singleton(
+    struct rangeset *r, unsigned long s);
+
+/* Rangeset pretty printing. */
+void rangeset_printk(
+    struct rangeset *r);
+void rangeset_domain_printk(
+    struct domain *d);
+
+#endif /* __XEN_RANGESET_H__ */
diff -r 903fb46f240e -r cd914808acf1 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/bug.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/bug.h       Tue Jan  3 
14:59:00 2006
+++ /dev/null   Tue Jan  3 16:19:20 2006
@@ -1,16 +0,0 @@
-#ifndef _I386_BUG_H
-#define _I386_BUG_H
-
-#include <linux/config.h>
-
-#define BUG() do { \
-       printk("kernel BUG at %s:%d (%s)!\n", \
-              __FILE__, __LINE__, __FUNCTION__); \
-       dump_stack(); \
-       panic("BUG!"); \
-} while (0)
-#define HAVE_ARCH_BUG
-
-#include <asm-generic/bug.h>
-
-#endif
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/x86_32/xen.lds
--- a/xen/arch/x86/x86_32/xen.lds       Tue Jan  3 14:59:00 2006
+++ /dev/null   Tue Jan  3 16:19:20 2006
@@ -1,79 +0,0 @@
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@xxxxxxxxxxxxxxxxxxxxxxxx>
- * Modified for i386 Xen by Keir Fraser
- */
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-ENTRY(start)
-PHDRS
-{
-  text PT_LOAD ;
-}
-SECTIONS
-{
-  . = 0xFF000000 + 0x100000;
-  _text = .;                   /* Text and read-only data */
-  .text : {
-       *(.text)
-       *(.fixup)
-       *(.gnu.warning)
-       } :text =0x9090
-  .text.lock : { *(.text.lock) } :text /* out-of-line lock text */
-
-  _etext = .;                  /* End of text section */
-
-  .rodata : { *(.rodata) *(.rodata.*) } :text
-
-  . = ALIGN(32);               /* Exception table */
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) } :text
-  __stop___ex_table = .;
-
-  . = ALIGN(32);               /* Pre-exception table */
-  __start___pre_ex_table = .;
-  __pre_ex_table : { *(__pre_ex_table) } :text
-  __stop___pre_ex_table = .;
-
-  .data : {                    /* Data */
-       *(.data)
-       CONSTRUCTORS
-       } :text
-
-  . = ALIGN(4096);             /* Init code and data */
-  __init_begin = .;
-  .text.init : { *(.text.init) } :text
-  .data.init : { *(.data.init) } :text
-  . = ALIGN(32);
-  __setup_start = .;
-  .setup.init : { *(.setup.init) } :text
-  __setup_end = .;
-  __initcall_start = .;
-  .initcall.init : { *(.initcall.init) } :text
-  __initcall_end = .;
-  . = ALIGN(8192);
-  __init_end = .;
-
-  __bss_start = .;             /* BSS */
-  .bss : {
-       *(.bss.twopage_aligned)
-       *(.bss.page_aligned)
-       *(.bss)
-       } :text
-  _end = . ;
-
-  /* Sections to be discarded */
-  /DISCARD/ : {
-       *(.text.exit)
-       *(.data.exit)
-       *(.exitcall.exit)
-       }
-
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
-}
diff -r 903fb46f240e -r cd914808acf1 xen/arch/x86/x86_64/xen.lds
--- a/xen/arch/x86/x86_64/xen.lds       Tue Jan  3 14:59:00 2006
+++ /dev/null   Tue Jan  3 16:19:20 2006
@@ -1,77 +0,0 @@
-/* Excerpts written by Martin Mares <mj@xxxxxxxxxxxxxxxxxxxxxxxx> */
-/* Modified for x86-64 Xen by Keir Fraser */
-OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
-OUTPUT_ARCH(i386:x86-64)
-ENTRY(start)
-PHDRS
-{
-  text PT_LOAD ;
-}
-SECTIONS
-{
-  . = 0xFFFF830000100000;
-  _text = .;                   /* Text and read-only data */
-  .text : {
-       *(.text)
-       *(.fixup)
-       *(.gnu.warning)
-       } :text = 0x9090
-  .text.lock : { *(.text.lock) } :text /* out-of-line lock text */
-
-  _etext = .;                  /* End of text section */
-
-  .rodata : { *(.rodata) *(.rodata.*) } :text
-
-  . = ALIGN(32);               /* Exception table */
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) } :text
-  __stop___ex_table = .;
-
-  . = ALIGN(32);                /* Pre-exception table */
-  __start___pre_ex_table = .;
-  __pre_ex_table : { *(__pre_ex_table) } :text
-  __stop___pre_ex_table = .;
-
-  .data : {                    /* Data */
-       *(.data)
-       CONSTRUCTORS
-       } :text
-
-  . = ALIGN(4096);             /* Init code and data */
-  __init_begin = .;
-  .text.init : { *(.text.init) } :text
-  .data.init : { *(.data.init) } :text
-  . = ALIGN(32);
-  __setup_start = .;
-  .setup.init : { *(.setup.init) } :text
-  __setup_end = .;
-  __initcall_start = .;
-  .initcall.init : { *(.initcall.init) } :text
-  __initcall_end = .;
-  . = ALIGN(8192);
-  __init_end = .;
-
-  __bss_start = .;             /* BSS */
-  .bss : {
-       *(.bss.twopage_aligned)
-       *(.bss.page_aligned)
-       *(.bss)
-       } :text
-  _end = . ;
-
-  /* Sections to be discarded */
-  /DISCARD/ : {
-       *(.text.exit)
-       *(.data.exit)
-       *(.exitcall.exit)
-       }
-
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
-}
diff -r 903fb46f240e -r cd914808acf1 xen/include/asm-x86/physdev.h
--- a/xen/include/asm-x86/physdev.h     Tue Jan  3 14:59:00 2006
+++ /dev/null   Tue Jan  3 16:19:20 2006
@@ -1,17 +0,0 @@
-/******************************************************************************
- * physdev.h
- */
-
-#ifndef __XEN_PHYSDEV_H__
-#define __XEN_PHYSDEV_H__
-
-#include <public/physdev.h>
-
-void physdev_modify_ioport_access_range(
-    struct domain *d, int enable, int port, int num );
-void physdev_destroy_state(struct domain *d);
-int domain_iomem_in_pfn(struct domain *p, unsigned long pfn);
-long do_physdev_op(physdev_op_t *uop);
-void physdev_init_dom0(struct domain *d);
-
-#endif /* __XEN_PHYSDEV_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®.