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

[Xen-changelog] merge?



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 291e816acbf46071a69b5d1b12ac3b5c46eaa49b
# Parent  edd1616cf8cb6f0d7ab32600a27d3a98ac8414b2
# Parent  fc12b08bf4fe858b29317427cc0db82d29764c5f
merge?

diff -r edd1616cf8cb -r 291e816acbf4 extras/mini-os/README
--- a/extras/mini-os/README     Fri Sep  2 14:15:49 2005
+++ b/extras/mini-os/README     Fri Sep  2 14:17:08 2005
@@ -23,13 +23,8 @@
 
 - to build it just type make.
 
-- copy image.final somewhere where dom0 can access it
+- to start it do the following in domain0 (assuming xend is running)
+  # xm create domain_config
 
-- in dom0
-  # xi_create 16000 test
-    <domid>
-  # xi_build <domid> image.final 0
-  # xi_start <domid>
-
-this prints out a bunch of stuff and then every 1000 timer interrupts the
-system time.
+this starts the kernel and prints out a bunch of stuff and then every
+1000 timer interrupts the system time.
diff -r edd1616cf8cb -r 291e816acbf4 extras/mini-os/include/hypervisor.h
--- a/extras/mini-os/include/hypervisor.h       Fri Sep  2 14:15:49 2005
+++ b/extras/mini-os/include/hypervisor.h       Fri Sep  2 14:17:08 2005
@@ -329,7 +329,7 @@
     int ret;
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
+        : "=a" (ret) : "0" (__HYPERVISOR_memory_op),
         _a1 (dom_mem_op) : "memory" );
 
     return ret;
diff -r edd1616cf8cb -r 291e816acbf4 linux-2.6-xen-sparse/arch/xen/Kconfig
--- a/linux-2.6-xen-sparse/arch/xen/Kconfig     Fri Sep  2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/Kconfig     Fri Sep  2 14:17:08 2005
@@ -109,15 +109,8 @@
          dedicated device-driver domain, or your master control domain
          (domain 0), then you almost certainly want to say Y here.
 
-config XEN_NETDEV_GRANT_TX
-        bool "Grant table substrate for net drivers tx path (DANGEROUS)"
-        default n
-        help
-          This introduces the use of grant tables as a data exhange mechanism
-          between the frontend and backend network drivers.
-
-config XEN_NETDEV_GRANT_RX
-        bool "Grant table substrate for net drivers rx path (DANGEROUS)"
+config XEN_NETDEV_GRANT
+        bool "Grant table substrate for network drivers (DANGEROUS)"
         default n
         help
           This introduces the use of grant tables as a data exhange mechanism
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32       Fri Sep 
 2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32       Fri Sep 
 2 14:17:08 2005
@@ -19,8 +19,7 @@
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
@@ -1124,7 +1123,7 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64       Fri Sep 
 2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64       Fri Sep 
 2 14:17:08 2005
@@ -19,8 +19,7 @@
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
@@ -1033,7 +1032,7 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32       Fri Sep 
 2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32       Fri Sep 
 2 14:17:08 2005
@@ -16,8 +16,7 @@
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64       Fri Sep 
 2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64       Fri Sep 
 2 14:17:08 2005
@@ -16,8 +16,7 @@
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32        Fri Sep 
 2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32        Fri Sep 
 2 14:17:08 2005
@@ -19,8 +19,7 @@
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64        Fri Sep 
 2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64        Fri Sep 
 2 14:17:08 2005
@@ -19,8 +19,7 @@
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU        Fri Sep  2 
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU        Fri Sep  2 
14:17:08 2005
@@ -19,7 +19,7 @@
 
 config TCG_XEN
        tristate "XEN TPM Interface"
-       depends on TCG_TPM && ARCH_XEN
+       depends on TCG_TPM && ARCH_XEN && XEN_TPMDEV_FRONTEND
        ---help---
          If you want to make TPM support available to a Xen
          user domain, say Yes and it will
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Fri Sep  2 
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Fri Sep  2 
14:17:08 2005
@@ -105,7 +105,7 @@
                xen_start_info.console_evtchn, handle_input,
                0, "xencons", inring());
        if (err) {
-               xprintk(KERN_ERR "XEN console request irq failed %i\n", err);
+               xprintk("XEN console request irq failed %i\n", err);
                unbind_evtchn_from_irq(xen_start_info.console_evtchn);
                return err;
        }
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Sep  2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Sep  2 14:17:08 2005
@@ -20,9 +20,12 @@
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
+#ifdef CONFIG_XEN_NETDEV_GRANT
 #include <asm-xen/xen-public/grant_table.h>
 #include <asm-xen/gnttab.h>
+
+#define GRANT_INVALID_REF (0xFFFF)
+
 #endif
 
 
@@ -37,6 +40,11 @@
 #define ASSERT(_p) ((void)0)
 #define DPRINTK(_f, _a...) ((void)0)
 #endif
+#define IPRINTK(fmt, args...) \
+    printk(KERN_INFO "xen_net: " fmt, ##args)
+#define WPRINTK(fmt, args...) \
+    printk(KERN_WARNING "xen_net: " fmt, ##args)
+
 
 typedef struct netif_st {
     /* Unique identifier for this interface. */
@@ -47,13 +55,13 @@
 
     /* Physical parameters of the comms window. */
     unsigned long    tx_shmem_frame;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     u16              tx_shmem_handle;
     unsigned long    tx_shmem_vaddr; 
     grant_ref_t      tx_shmem_ref; 
 #endif
     unsigned long    rx_shmem_frame;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     u16              rx_shmem_handle;
     unsigned long    rx_shmem_vaddr; 
     grant_ref_t      rx_shmem_ref; 
@@ -68,7 +76,7 @@
     /* Private indexes into shared ring. */
     NETIF_RING_IDX rx_req_cons;
     NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     NETIF_RING_IDX rx_resp_prod_copy; /* private version of shared variable */
 #endif
     NETIF_RING_IDX tx_req_cons;
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Fri Sep  2 
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Fri Sep  2 
14:17:08 2005
@@ -111,91 +111,81 @@
     return netif;
 }
 
-static int map_frontend_page(netif_t *netif, unsigned long localaddr,
-                            unsigned long tx_ring_ref, unsigned long 
rx_ring_ref)
-{
-#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX)
+static int map_frontend_pages(netif_t *netif, unsigned long localaddr,
+                              unsigned long tx_ring_ref, 
+                              unsigned long rx_ring_ref)
+{
+#ifdef CONFIG_XEN_NETDEV_GRANT
+    struct gnttab_map_grant_ref op;
+
+    /* Map: Use the Grant table reference */
+    op.host_addr = localaddr;
+    op.flags     = GNTMAP_host_map;
+    op.ref       = tx_ring_ref;
+    op.dom       = netif->domid;
+    
+    BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+    if (op.handle < 0) { 
+        DPRINTK(" Grant table operation failure mapping tx_ring_ref!\n");
+        return op.handle;
+    }
+
+    netif->tx_shmem_ref    = tx_ring_ref;
+    netif->tx_shmem_handle = op.handle;
+    netif->tx_shmem_vaddr  = localaddr;
+
+    /* Map: Use the Grant table reference */
+    op.host_addr = localaddr + PAGE_SIZE;
+    op.flags     = GNTMAP_host_map;
+    op.ref       = rx_ring_ref;
+    op.dom       = netif->domid;
+
+    BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+    if (op.handle < 0) { 
+        DPRINTK(" Grant table operation failure mapping rx_ring_ref!\n");
+        return op.handle;
+    }
+
+    netif->rx_shmem_ref    = rx_ring_ref;
+    netif->rx_shmem_handle = op.handle;
+    netif->rx_shmem_vaddr  = localaddr + PAGE_SIZE;
+
+#else
     pgprot_t      prot = __pgprot(_KERNPG_TABLE);
     int           err;
-#endif
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX)
-    {
-        struct gnttab_map_grant_ref op;
-
-        /* Map: Use the Grant table reference */
-        op.host_addr = localaddr;
-        op.flags     = GNTMAP_host_map;
-        op.ref       = tx_ring_ref;
-        op.dom       = netif->domid;
-       
-       BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
-        if (op.handle < 0) { 
-            DPRINTK(" Grant table operation failure !\n");
-            return op.handle;
-        }
-
-        netif->tx_shmem_ref    = tx_ring_ref;
-        netif->tx_shmem_handle = op.handle;
-        netif->tx_shmem_vaddr  = localaddr;
-    }
-#else 
+
     err = direct_remap_area_pages(&init_mm, localaddr,
                                  tx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
                                  prot, netif->domid); 
+    
+    err |= direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE,
+                                 rx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
+                                 prot, netif->domid);
+
     if (err)
        return err;
 #endif
 
-#if defined(CONFIG_XEN_NETDEV_GRANT_RX)
-    {
-        struct gnttab_map_grant_ref op;
-
-        /* Map: Use the Grant table reference */
-        op.host_addr = localaddr + PAGE_SIZE;
-        op.flags     = GNTMAP_host_map;
-        op.ref       = rx_ring_ref;
-        op.dom       = netif->domid;
-
-       BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
-        if (op.handle < 0) { 
-            DPRINTK(" Grant table operation failure !\n");
-            return op.handle;
-        }
-
-        netif->rx_shmem_ref    = rx_ring_ref;
-        netif->rx_shmem_handle = op.handle;
-        netif->rx_shmem_vaddr  = localaddr + PAGE_SIZE;
-    }
-#else 
-    err = direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE,
-                                 rx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
-                                 prot, netif->domid);
-    if (err)
-       return err;
-#endif
-
     return 0;
 }
 
-static void unmap_frontend_page(netif_t *netif)
-{
-#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX)
+static void unmap_frontend_pages(netif_t *netif)
+{
+#ifdef CONFIG_XEN_NETDEV_GRANT
     struct gnttab_unmap_grant_ref op;
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+
     op.host_addr    = netif->tx_shmem_vaddr;
     op.handle       = netif->tx_shmem_handle;
     op.dev_bus_addr = 0;
     BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
     op.host_addr    = netif->rx_shmem_vaddr;
     op.handle       = netif->rx_shmem_handle;
     op.dev_bus_addr = 0;
     BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
 #endif
+
+    return; 
 }
 
 int netif_map(netif_t *netif, unsigned long tx_ring_ref,
@@ -209,8 +199,8 @@
     if (vma == NULL)
         return -ENOMEM;
 
-    err = map_frontend_page(netif, (unsigned long)vma->addr, tx_ring_ref,
-                           rx_ring_ref);
+    err = map_frontend_pages(netif, (unsigned long)vma->addr, tx_ring_ref,
+                             rx_ring_ref);
     if (err) {
         vfree(vma->addr);
        return err;
@@ -222,7 +212,7 @@
     op.u.bind_interdomain.port2 = evtchn;
     err = HYPERVISOR_event_channel_op(&op);
     if (err) {
-       unmap_frontend_page(netif);
+       unmap_frontend_pages(netif);
        vfree(vma->addr);
        return err;
     }
@@ -267,7 +257,7 @@
     unregister_netdev(netif->dev);
 
     if (netif->tx) {
-       unmap_frontend_page(netif);
+       unmap_frontend_pages(netif);
        vfree(netif->tx); /* Frees netif->rx as well. */
     }
 
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Fri Sep  2 
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Fri Sep  2 
14:17:08 2005
@@ -14,23 +14,6 @@
 #include <asm-xen/balloon.h>
 #include <asm-xen/xen-public/memory.h>
 
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-#include <asm-xen/xen-public/grant_table.h>
-#include <asm-xen/gnttab.h>
-#ifdef GRANT_DEBUG
-static void
-dump_packet(int tag, u32 addr, unsigned char *p)
-{
-       int i;
-
-       printk(KERN_ALERT "#### rx_action %c %08x ", tag & 0xff, addr);
-       for (i = 0; i < 20; i++) {
-               printk("%02x", p[i]);
-       }
-       printk("\n");
-}
-#endif
-#endif
 
 static void netif_idx_release(u16 pending_idx);
 static void netif_page_release(struct page *page);
@@ -57,7 +40,8 @@
 static struct sk_buff_head rx_queue;
 static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2+1];
 static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
 static gnttab_donate_t grant_rx_op[MAX_PENDING_REQS];
 #else
 static struct mmuext_op rx_mmuext[NETIF_RX_RING_SIZE];
@@ -88,16 +72,13 @@
 
 static struct sk_buff_head tx_queue;
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
 static u16 grant_tx_ref[MAX_PENDING_REQS];
 static gnttab_unmap_grant_ref_t tx_unmap_ops[MAX_PENDING_REQS];
 static gnttab_map_grant_ref_t tx_map_ops[MAX_PENDING_REQS];
+
 #else
 static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
-#endif
-
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-#define GRANT_INVALID_REF (0xFFFF)
 #endif
 
 static struct list_head net_schedule_list;
@@ -127,7 +108,7 @@
     return mfn;
 }
 
-#ifndef CONFIG_XEN_NETDEV_GRANT_RX
+#ifndef CONFIG_XEN_NETDEV_GRANT
 static void free_mfn(unsigned long mfn)
 {
     unsigned long flags;
@@ -200,7 +181,7 @@
         dev_kfree_skb(skb);
         skb = nskb;
     }
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
 #ifdef DEBUG_GRANT
     printk(KERN_ALERT "#### be_xmit: req_prod=%d req_cons=%d id=%04x 
gr=%04x\n",
            netif->rx->req_prod,
@@ -246,12 +227,12 @@
 
 static void net_rx_action(unsigned long unused)
 {
-    netif_t *netif;
+    netif_t *netif = NULL; 
     s8 status;
     u16 size, id, evtchn;
     multicall_entry_t *mcl;
     mmu_update_t *mmu;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     gnttab_donate_t *gop;
 #else
     struct mmuext_op *mmuext;
@@ -266,7 +247,7 @@
 
     mcl = rx_mcl;
     mmu = rx_mmu;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     gop = grant_rx_op;
 #else
     mmuext = rx_mmuext;
@@ -282,7 +263,7 @@
         if ( (new_mfn = alloc_mfn()) == 0 )
         {
             if ( net_ratelimit() )
-                printk(KERN_WARNING "Memory squeeze in netback driver.\n");
+                WPRINTK("Memory squeeze in netback driver.\n");
             mod_timer(&net_timer, jiffies + HZ);
             skb_queue_head(&rx_queue, skb);
             break;
@@ -297,7 +278,7 @@
                                pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
         mcl++;
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         gop->mfn = old_mfn;
         gop->domid = netif->domid;
         gop->handle = netif->rx->ring[
@@ -340,7 +321,7 @@
     mcl->args[3] = DOMID_SELF;
     mcl++;
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
 #else
     mcl[-3].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
@@ -349,9 +330,17 @@
         BUG();
 
     mcl = rx_mcl;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    BUG_ON(HYPERVISOR_grant_table_op(
-        GNTTABOP_donate, grant_rx_op, gop - grant_rx_op));
+#ifdef CONFIG_XEN_NETDEV_GRANT
+    if(HYPERVISOR_grant_table_op(GNTTABOP_donate, grant_rx_op, 
+                                 gop - grant_rx_op)) { 
+        /* 
+        ** The other side has given us a bad grant ref, or has no headroom, 
+        ** or has gone away. Unfortunately the current grant table code 
+        ** doesn't inform us which is the case, so not much we can do. 
+        */
+        DPRINTK("net_rx: donate to DOM%u failed; dropping (up to) %d "
+                "packets.\n", grant_rx_op[0].domid, gop - grant_rx_op); 
+    }
     gop = grant_rx_op;
 #else
     mmuext = rx_mmuext;
@@ -363,7 +352,7 @@
 
         /* Rederive the machine addresses. */
         new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */
 #else
         old_mfn = mmuext[0].mfn;
@@ -380,8 +369,13 @@
 
         /* Check the reassignment error code. */
         status = NETIF_RSP_OKAY;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-        BUG_ON(gop->status != 0); /* XXX */
+#ifdef CONFIG_XEN_NETDEV_GRANT
+        if(gop->status != 0) { 
+            DPRINTK("Bad status %d from grant donate to DOM%u\n", 
+                    gop->status, netif->domid);
+            /* XXX SMH: should free 'old_mfn' here */
+            status = NETIF_RSP_ERROR; 
+        } 
 #else
         if ( unlikely(mcl[1].result != 0) )
         {
@@ -404,7 +398,7 @@
 
         netif_put(netif);
         dev_kfree_skb(skb);
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         mcl++;
         gop++;
 #else
@@ -420,6 +414,7 @@
         notify_via_evtchn(evtchn);
     }
 
+  out: 
     /* More work to do? */
     if ( !skb_queue_empty(&rx_queue) && !timer_pending(&net_timer) )
         tasklet_schedule(&net_rx_tasklet);
@@ -496,7 +491,7 @@
 
 inline static void net_tx_action_dealloc(void)
 {
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     gnttab_unmap_grant_ref_t *gop;
 #else
     multicall_entry_t *mcl;
@@ -508,7 +503,7 @@
     dc = dealloc_cons;
     dp = dealloc_prod;
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     /*
      * Free up any grants we have finished using
      */
@@ -542,7 +537,7 @@
 #endif
     while ( dealloc_cons != dp )
     {
-#ifndef CONFIG_XEN_NETDEV_GRANT_TX
+#ifndef CONFIG_XEN_NETDEV_GRANT
         /* The update_va_mapping() must not fail. */
         BUG_ON(mcl[0].result != 0);
 #endif
@@ -569,7 +564,7 @@
         
         netif_put(netif);
 
-#ifndef CONFIG_XEN_NETDEV_GRANT_TX
+#ifndef CONFIG_XEN_NETDEV_GRANT
         mcl++;
 #endif
     }
@@ -585,7 +580,7 @@
     netif_tx_request_t txreq;
     u16 pending_idx;
     NETIF_RING_IDX i;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     gnttab_map_grant_ref_t *mop;
 #else
     multicall_entry_t *mcl;
@@ -595,7 +590,7 @@
     if ( dealloc_cons != dealloc_prod )
         net_tx_action_dealloc();
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     mop = tx_map_ops;
 #else
     mcl = tx_mcl;
@@ -696,7 +691,7 @@
 
         /* Packets passed to netif_rx() must have some headroom. */
         skb_reserve(skb, 16);
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         mop->host_addr = MMAP_VADDR(pending_idx);
         mop->dom       = netif->domid;
         mop->ref       = txreq.addr >> PAGE_SHIFT;
@@ -719,7 +714,7 @@
 
         pending_cons++;
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         if ( (mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops) )
             break;
 #else
@@ -729,7 +724,7 @@
 #endif
     }
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     if ( mop == tx_map_ops )
         return;
 
@@ -752,7 +747,7 @@
         memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq));
 
         /* Check the remap error code. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         /* 
            XXX SMH: error returns from grant operations are pretty poorly
            specified/thought out, but the below at least conforms with 
@@ -826,7 +821,7 @@
         netif_rx(skb);
         netif->dev->last_rx = jiffies;
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         mop++;
 #else
         mcl++;
@@ -949,12 +944,9 @@
          !(xen_start_info.flags & SIF_INITDOMAIN) )
         return 0;
 
-    printk("Initialising Xen netif backend\n");
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    printk("#### netback tx using grant tables\n");
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    printk("#### netback rx using grant tables\n");
+    IPRINTK("Initialising Xen netif backend.\n");
+#ifdef CONFIG_XEN_NETDEV_GRANT
+    IPRINTK("Using grant tables.\n");
 #endif
 
     /* We can increase reservation by this much in net_rx_action(). */
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Sep  2 
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Sep  2 
14:17:08 2005
@@ -55,9 +55,18 @@
 #include <asm/page.h>
 #include <asm/uaccess.h>
 
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
+#ifdef CONFIG_XEN_NETDEV_GRANT
 #include <asm-xen/xen-public/grant_table.h>
 #include <asm-xen/gnttab.h>
+
+static grant_ref_t gref_tx_head;
+static grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1]; 
+
+static grant_ref_t gref_rx_head;
+static grant_ref_t grant_rx_ref[NETIF_RX_RING_SIZE + 1];
+
+#define GRANT_INVALID_REF      (0xFFFF)
+
 #ifdef GRANT_DEBUG
 static void
 dump_packet(int tag, void *addr, u32 ap)
@@ -71,8 +80,17 @@
     }
     printk("\n");
 }
-#endif
-#endif
+
+#define GDPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
+                           __FILE__ , __LINE__ , ## _a )
+#else 
+#define dump_packet(x,y,z)  ((void)0)  
+#define GDPRINTK(_f, _a...) ((void)0)
+#endif
+
+#endif
+
+
 
 #ifndef __GFP_NOWARN
 #define __GFP_NOWARN 0
@@ -102,22 +120,10 @@
 #define TX_TEST_IDX req_cons  /* conservative: not seen all our requests? */
 #endif
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-static grant_ref_t gref_tx_head;
-static grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1];
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-static grant_ref_t gref_rx_head;
-static grant_ref_t grant_rx_ref[NETIF_RX_RING_SIZE + 1];
-#endif
-
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-#define GRANT_INVALID_REF      (0xFFFF)
-#endif
 
 #define NETIF_STATE_DISCONNECTED 0
 #define NETIF_STATE_CONNECTED    1
+
 
 static unsigned int netif_state = NETIF_STATE_DISCONNECTED;
 
@@ -279,7 +285,7 @@
         for (i = np->tx_resp_cons; i != prod; i++) {
             id  = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id;
             skb = np->tx_skbs[id];
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
             if (unlikely(gnttab_query_foreign_access(grant_tx_ref[id]) != 0)) {
                 /* other domain is still using this grant - shouldn't happen
                    but if it does, we'll try to reclaim the grant later */
@@ -310,7 +316,7 @@
         mb();
     } while (prod != np->tx->resp_prod);
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
   out: 
 #endif
 
@@ -330,8 +336,8 @@
     int i, batch_target;
     NETIF_RING_IDX req_prod = np->rx->req_prod;
     struct xen_memory_reservation reservation;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    int ref;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+    grant_ref_t ref;
 #endif
 
     if (unlikely(np->backend_state != BEST_CONNECTED))
@@ -365,9 +371,9 @@
         np->rx_skbs[id] = skb;
         
         np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
        ref = gnttab_claim_grant_reference(&gref_rx_head);
-        if (unlikely(ref < 0)) {
+        if (unlikely((signed short)ref < 0)) {
             printk(KERN_ALERT "#### netfront can't claim rx reference\n");
             BUG();
         }
@@ -426,8 +432,8 @@
     struct net_private *np = netdev_priv(dev);
     netif_tx_request_t *tx;
     NETIF_RING_IDX i;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    unsigned int ref;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+    grant_ref_t ref;
     unsigned long mfn;
 #endif
 
@@ -464,9 +470,9 @@
     tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req;
 
     tx->id   = id;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     ref = gnttab_claim_grant_reference(&gref_tx_head);
-    if (unlikely(ref < 0)) {
+    if (unlikely((signed short)ref < 0)) {
         printk(KERN_ALERT "#### netfront can't claim tx grant reference\n");
         BUG();
     }
@@ -519,7 +525,7 @@
     network_tx_buf_gc(dev);
     spin_unlock_irqrestore(&np->tx_lock, flags);
 
-    if ((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state == 
UST_OPEN))
+    if((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state == UST_OPEN))
         netif_rx_schedule(dev);
 
     return IRQ_HANDLED;
@@ -537,7 +543,7 @@
     int work_done, budget, more_to_do = 1;
     struct sk_buff_head rxq;
     unsigned long flags;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     unsigned long mfn;
     grant_ref_t ref;
 #endif
@@ -574,8 +580,19 @@
             continue;
         }
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-        ref = grant_rx_ref[rx->id];
+#ifdef CONFIG_XEN_NETDEV_GRANT
+        ref = grant_rx_ref[rx->id]; 
+
+        if(ref == GRANT_INVALID_REF) { 
+            printk(KERN_WARNING "Bad rx grant reference %d from dom %d.\n",
+                   ref, np->backend_id);
+            np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id;
+            wmb();
+            np->rx->req_prod++;
+            work_done--;
+            continue;
+        }
+
         grant_rx_ref[rx->id] = GRANT_INVALID_REF;
         mfn = gnttab_end_foreign_transfer_ref(ref);
         gnttab_release_grant_reference(&gref_rx_head, ref);
@@ -585,7 +602,7 @@
         ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
 
         /* NB. We handle skb overflow later. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         skb->data = skb->head + rx->addr;
 #else
         skb->data = skb->head + (rx->addr & ~PAGE_MASK);
@@ -600,14 +617,14 @@
         np->stats.rx_bytes += rx->status;
 
         /* Remap the page. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         mmu->ptr = mfn << PAGE_SHIFT | MMU_MACHPHYS_UPDATE;
 #else
         mmu->ptr  = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE;
 #endif
         mmu->val  = __pa(skb->head) >> PAGE_SHIFT;
         mmu++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
        MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
                                pfn_pte_ma(mfn, PAGE_KERNEL), 0);
 #else
@@ -617,19 +634,19 @@
 #endif
         mcl++;
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = mfn;
+        GDPRINTK("#### rx_poll     enqueue vdata=%p mfn=%lu ref=%x\n",
+                skb->data, mfn, ref);
 #else
         phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = 
             rx->addr >> PAGE_SHIFT;
-#endif
-
-#ifdef GRANT_DEBUG
-        printk(KERN_ALERT "#### rx_poll     enqueue vdata=%p mfn=%lu ref=%x\n",
-               skb->data, mfn, ref);
-#endif
+#endif 
+
+
         __skb_queue_tail(&rxq, skb);
     }
+
 
     /* Some pages are no longer absent... */
     balloon_update_driver_allowance(-work_done);
@@ -646,9 +663,9 @@
     }
 
     while ((skb = __skb_dequeue(&rxq)) != NULL) {
-#ifdef GRANT_DEBUG
-        printk(KERN_ALERT "#### rx_poll     dequeue vdata=%p mfn=%lu\n",
-               skb->data, virt_to_mfn(skb->data));
+#ifdef CONFIG_XEN_NETDEV_GRANT
+        GDPRINTK("#### rx_poll     dequeue vdata=%p mfn=%lu\n",
+                skb->data, virt_to_mfn(skb->data));
         dump_packet('d', skb->data, (unsigned long)skb->data);
 #endif
         /*
@@ -747,7 +764,6 @@
     return &np->stats;
 }
 
-
 static void network_connect(struct net_device *dev)
 {
     struct net_private *np;
@@ -787,8 +803,11 @@
             tx = &np->tx->ring[requeue_idx++].req;
 
             tx->id   = i;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-            tx->addr = 0; /*(ref << PAGE_SHIFT) |*/
+#ifdef CONFIG_XEN_NETDEV_GRANT
+            gnttab_grant_foreign_access_ref(grant_tx_ref[i], np->backend_id, 
+                                            virt_to_mfn(np->tx_skbs[i]->data),
+                                            GNTMAP_readonly); 
+            tx->addr = grant_tx_ref[i] << PAGE_SHIFT; 
 #else
             tx->addr = virt_to_mfn(skb->data) << PAGE_SHIFT;
 #endif
@@ -803,9 +822,20 @@
     np->tx->req_prod = requeue_idx;
 
     /* Rebuild the RX buffer freelist and the RX ring itself. */
-    for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++)
-        if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET)
-            np->rx->ring[requeue_idx++].req.id = i;
+    for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) { 
+        if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) {
+#ifdef CONFIG_XEN_NETDEV_GRANT 
+            /* Reinstate the grant ref so backend can 'donate' mfn to us. */
+            gnttab_grant_foreign_transfer_ref(grant_rx_ref[i], np->backend_id,
+                                              virt_to_mfn(np->rx_skbs[i]->head)
+                );
+            np->rx->ring[requeue_idx].req.gref = grant_rx_ref[i];
+#endif
+            np->rx->ring[requeue_idx].req.id   = i;
+            requeue_idx++; 
+        }
+    }
+
     wmb();                
     np->rx->req_prod = requeue_idx;
 
@@ -901,13 +931,14 @@
     /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
     for (i = 0; i <= NETIF_TX_RING_SIZE; i++) {
         np->tx_skbs[i] = (void *)((unsigned long) i+1);
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         grant_tx_ref[i] = GRANT_INVALID_REF;
 #endif
     }
+
     for (i = 0; i <= NETIF_RX_RING_SIZE; i++) {
         np->rx_skbs[i] = (void *)((unsigned long) i+1);
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
         grant_rx_ref[i] = GRANT_INVALID_REF;
 #endif
     }
@@ -991,10 +1022,8 @@
        evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
        int err;
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
        info->tx_ring_ref = GRANT_INVALID_REF;
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
        info->rx_ring_ref = GRANT_INVALID_REF;
 #endif
 
@@ -1014,7 +1043,7 @@
        memset(info->rx, 0, PAGE_SIZE);
        info->backend_state = BEST_DISCONNECTED;
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
        err = gnttab_grant_foreign_access(info->backend_id,
                                          virt_to_mfn(info->tx), 0);
        if (err < 0) {
@@ -1022,11 +1051,7 @@
                goto out;
        }
        info->tx_ring_ref = err;
-#else
-       info->tx_ring_ref = virt_to_mfn(info->tx);
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
        err = gnttab_grant_foreign_access(info->backend_id,
                                          virt_to_mfn(info->rx), 0);
        if (err < 0) {
@@ -1034,7 +1059,9 @@
                goto out;
        }
        info->rx_ring_ref = err;
+
 #else
+       info->tx_ring_ref = virt_to_mfn(info->tx);
        info->rx_ring_ref = virt_to_mfn(info->rx);
 #endif
 
@@ -1054,16 +1081,17 @@
        if (info->rx)
                free_page((unsigned long)info->rx);
        info->rx = 0;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
        if (info->tx_ring_ref != GRANT_INVALID_REF)
                gnttab_end_foreign_access(info->tx_ring_ref, 0);
        info->tx_ring_ref = GRANT_INVALID_REF;
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
        if (info->rx_ring_ref != GRANT_INVALID_REF)
                gnttab_end_foreign_access(info->rx_ring_ref, 0);
        info->rx_ring_ref = GRANT_INVALID_REF;
 #endif
+
        return err;
 }
 
@@ -1075,16 +1103,17 @@
        if (info->rx)
                free_page((unsigned long)info->rx);
        info->rx = 0;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
        if (info->tx_ring_ref != GRANT_INVALID_REF)
                gnttab_end_foreign_access(info->tx_ring_ref, 0);
        info->tx_ring_ref = GRANT_INVALID_REF;
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
        if (info->rx_ring_ref != GRANT_INVALID_REF)
                gnttab_end_foreign_access(info->rx_ring_ref, 0);
        info->rx_ring_ref = GRANT_INVALID_REF;
 #endif
+
        unbind_evtchn_from_irqhandler(info->evtchn, info->netdev);
        info->evtchn = 0;
 }
@@ -1294,6 +1323,7 @@
        int err;
 
        err = talk_to_backend(dev, np);
+
        return err;
 }
 
@@ -1342,29 +1372,28 @@
     if (xen_start_info.flags & SIF_INITDOMAIN)
         return 0;
 
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    /* A grant for every ring slot */
+    if ((err = xennet_proc_init()) != 0)
+        return err;
+
+    IPRINTK("Initialising virtual ethernet driver.\n");
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
+    IPRINTK("Using grant tables.\n"); 
+
+    /* A grant for every tx ring slot */
     if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE,
                                       &gref_tx_head) < 0) {
         printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
         return 1;
     }
-    printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n"); 
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    /* A grant for every ring slot */
+    /* A grant for every rx ring slot */
     if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE,
                                       &gref_rx_head) < 0) {
         printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
         return 1;
     }
-    printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n"); 
-#endif
-
-    if ((err = xennet_proc_init()) != 0)
-        return err;
-
-    IPRINTK("Initialising virtual ethernet driver.\n");
+#endif
+
 
     (void)register_inetaddr_notifier(&notifier_inetdev);
 
@@ -1377,10 +1406,8 @@
 
 static void netif_exit(void)
 {
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     gnttab_free_grant_references(gref_tx_head);
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
     gnttab_free_grant_references(gref_rx_head);
 #endif
 }
diff -r edd1616cf8cb -r 291e816acbf4 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Fri Sep  2 
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Fri Sep  2 
14:17:08 2005
@@ -212,7 +212,7 @@
                xen_start_info.store_evtchn, wake_waiting,
                0, "xenbus", &xb_waitq);
        if (err) {
-               printk(KERN_ERR "XENBUS request irq failed %i\n", err);
+               xprintk("XENBUS request irq failed %i\n", err);
                unbind_evtchn_from_irq(xen_start_info.store_evtchn);
                return err;
        }
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_brctl
--- a/tools/check/check_brctl   Fri Sep  2 14:15:49 2005
+++ b/tools/check/check_brctl   Fri Sep  2 14:17:08 2005
@@ -2,8 +2,9 @@
 # CHECK-INSTALL
 
 function error {
-   echo 'Check for the bridge control utils (brctl) failed.'
+   echo
+   echo '  *** Check for the bridge control utils (brctl) FAILED'
    exit 1
 }
 
-brctl show || error
\ No newline at end of file
+which brctl 1>/dev/null 2>&1 || error
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_iproute
--- a/tools/check/check_iproute Fri Sep  2 14:15:49 2005
+++ b/tools/check/check_iproute Fri Sep  2 14:17:08 2005
@@ -2,9 +2,10 @@
 # CHECK-INSTALL
 
 function error {
-   echo 'Check for iproute (ip addr) failed.'
+   echo
+   echo '  *** Check for iproute (ip addr) FAILED'
    exit 1
 }
 
-ip addr list || error
+ip addr list 1>/dev/null 2>&1 || error
 
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_logging
--- a/tools/check/check_logging Fri Sep  2 14:15:49 2005
+++ b/tools/check/check_logging Fri Sep  2 14:17:08 2005
@@ -18,11 +18,12 @@
         import logging
     except ImportError:
         hline()
-        msg("Python logging is not installed.")
-        msg("Use 'make install-logging' at the xen root to install.")
         msg("")
-        msg("Alternatively download and install from")
-        msg("http://www.red-dove.com/python_logging.html";)
+        msg("  *** Python logging is not installed.")
+        msg("  *** Use 'make install-logging' at the xen root to install.")
+        msg("  *** ")
+        msg("  *** Alternatively download and install from")
+        msg("  *** http://www.red-dove.com/python_logging.html";)
         hline()
         sys.exit(1)
 
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_python
--- a/tools/check/check_python  Fri Sep  2 14:15:49 2005
+++ b/tools/check/check_python  Fri Sep  2 14:17:08 2005
@@ -2,9 +2,9 @@
 # CHECK-BUILD CHECK-INSTALL
 
 function error {
-    echo "Check for Python version 2.2 or higher failed."
+    echo
+    echo "  *** Check for Python version >= 2.2 FAILED"
     exit 1
 }
 
-python -V
 python -V 2>&1 | cut -d ' ' -f 2 | grep -q -E '^2.2|^2.3|^2.4' || error
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_zlib_devel
--- a/tools/check/check_zlib_devel      Fri Sep  2 14:15:49 2005
+++ b/tools/check/check_zlib_devel      Fri Sep  2 14:17:08 2005
@@ -2,9 +2,10 @@
 # CHECK-BUILD
 
 function error {
-    echo 'Check for zlib includes failed.'
+    echo
+    echo "  *** Check for zlib headers FAILED"
     exit 1
 }
 
 set -e
-[ -e /usr/include/zlib.h ] || error
\ No newline at end of file
+[ -e /usr/include/zlib.h ] || error
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_zlib_lib
--- a/tools/check/check_zlib_lib        Fri Sep  2 14:15:49 2005
+++ b/tools/check/check_zlib_lib        Fri Sep  2 14:17:08 2005
@@ -2,9 +2,10 @@
 # CHECK-BUILD CHECK-INSTALL
 
 function error {
-    echo 'Check for zlib library failed.'
+    echo
+    echo "  *** Check for zlib library FAILED"
     exit 1
 }
 
 set -e
-ldconfig -p | grep libz.so || error
\ No newline at end of file
+ldconfig -p | grep -q libz.so || error
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/chk
--- a/tools/check/chk   Fri Sep  2 14:15:49 2005
+++ b/tools/check/chk   Fri Sep  2 14:17:08 2005
@@ -17,14 +17,11 @@
 case $1 in
     build)
         check="CHECK-BUILD"
-        info=".chkbuild"
         ;;
     install)
         check="CHECK-INSTALL"
-        info=".chkinstall"
         ;;
     clean)
-        rm -f .chkbuild .chkinstall
         exit 0
         ;;
     *)
@@ -34,7 +31,7 @@
 
 failed=0
 
-echo "Xen ${check} " $(date) > ${info}
+echo "Xen ${check} " $(date)
 for f in check_* ; do
     case $f in
         *~)
@@ -49,24 +46,12 @@
     if ! grep -q ${check} $f ; then
         continue
     fi
-    echo ' ' >> ${info}
-    echo "Checking $f" >> ${info}
-    if ./$f 1>>${info} 2>&1 ; then
-        echo OK >> ${info}
+    echo -n "Checking $f: "
+    if ./$f 2>&1 ; then
+        echo OK
     else
         failed=1
-        echo "FAILED $f"
-        echo FAILED >> ${info}
     fi
 done
 
-echo >> ${info}
-
-if [ "$failed" == "1" ] ; then
-    echo "Checks failed. See `pwd`/${info} for details."
-    echo "FAILED" >> ${info}
-    exit 1
-else
-    echo "OK" >> ${info}
-    exit 0
-fi
+exit $failed
diff -r edd1616cf8cb -r 291e816acbf4 tools/console/daemon/utils.c
--- a/tools/console/daemon/utils.c      Fri Sep  2 14:15:49 2005
+++ b/tools/console/daemon/utils.c      Fri Sep  2 14:17:08 2005
@@ -234,7 +234,7 @@
        }
 
        if (!xs_watch(xs, "/console", "console")) {
-               dolog(LOG_ERR, "xenstore watch on /console failes.");
+               dolog(LOG_ERR, "xenstore watch on /console fails.");
                goto out_close_data;
        }
 
diff -r edd1616cf8cb -r 291e816acbf4 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Fri Sep  2 14:15:49 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Fri Sep  2 14:17:08 2005
@@ -1028,6 +1028,7 @@
 
         """
         try:
+            self.clear_shutdown()
             self.state = STATE_VM_OK
             self.shutdown_pending = None
             self.restart_check()
diff -r edd1616cf8cb -r 291e816acbf4 tools/security/Makefile
--- a/tools/security/Makefile   Fri Sep  2 14:15:49 2005
+++ b/tools/security/Makefile   Fri Sep  2 14:17:08 2005
@@ -45,6 +45,7 @@
        $(MAKE) secpol_xml2bin
        chmod 700 ./setlabel.sh
        chmod 700 ./updategrub.sh
+       chmod 700 ./getlabel.sh
 
 secpol_tool : secpol_tool.c secpol_compat.h
        $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
diff -r edd1616cf8cb -r 291e816acbf4 tools/security/secpol_tool.c
--- a/tools/security/secpol_tool.c      Fri Sep  2 14:15:49 2005
+++ b/tools/security/secpol_tool.c      Fri Sep  2 14:17:08 2005
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <getopt.h>
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -40,6 +41,17 @@
 #define PERROR(_m, _a...) \
 fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a ,  \
                 errno, strerror(errno))
+
+void usage(char *progname)
+{
+    printf("Use: %s \n"
+           "\t getpolicy\n"
+           "\t dumpstats\n"
+           "\t loadpolicy <binary policy file>\n"
+           "\t getssid -d <domainid> [-f]\n"
+                  "\t getssid -s <ssidref> [-f]\n", progname);
+    exit(-1);
+}
 
 static inline int do_policycmd(int xc_handle, unsigned int cmd,
                                unsigned long data)
@@ -320,7 +332,7 @@
 
         if (ret)
             printf
-                ("ERROR setting policy. Use 'xm dmesg' to see details.\n");
+                ("ERROR setting policy. Try 'xm dmesg' to see details.\n");
         else
             printf("Successfully changed policy.\n");
 
@@ -370,7 +382,7 @@
 
     if (ret < 0)
     {
-        printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n");
+        printf("ERROR dumping policy stats. Try 'xm dmesg' to see details.\n");
         return ret;
     }
     stats = (struct acm_stats_buffer *) stats_buffer;
@@ -421,17 +433,121 @@
     }
     return ret;
 }
+/************************ get ssidref & types ******************************/
+/*
+ * the ssid (types) can be looked up either by domain id or by ssidref
+ */
+int acm_domain_getssid(int xc_handle, int argc, char * const argv[])
+{
+    /* this includes header and a set of types */
+    #define MAX_SSIDBUFFER  2000
+    int ret, i;
+    acm_op_t op;
+    struct acm_ssid_buffer *hdr;
+    unsigned char *buf;
+       int nice_print = 1;
+
+    op.cmd = ACM_GETSSID;
+    op.interface_version = ACM_INTERFACE_VERSION;
+       op.u.getssid.get_ssid_by = UNSET;
+       /* arguments
+          -d ... domain id to look up
+          -s ... ssidref number to look up
+          -f ... formatted print (scripts depend on this format)
+       */
+       while (1)
+    {
+               int c = getopt(argc, argv, "d:s:f");
+               if (c == -1)
+                       break;
+               if (c == 'd')
+        {
+                       if (op.u.getssid.get_ssid_by != UNSET)
+                               usage(argv[0]);
+                       op.u.getssid.get_ssid_by = DOMAINID;
+                       op.u.getssid.id.domainid = strtoul(optarg, NULL, 0);
+               }
+               else if (c== 's')
+        {
+                       if (op.u.getssid.get_ssid_by != UNSET)
+                               usage(argv[0]);
+                       op.u.getssid.get_ssid_by = SSIDREF;
+                       op.u.getssid.id.ssidref = strtoul(optarg, NULL, 0);
+               }
+               else if (c== 'f')
+               {
+                       nice_print = 0;
+               }
+               else
+                       usage(argv[0]);
+       }
+       if (op.u.getssid.get_ssid_by == UNSET)
+               usage(argv[0]);
+
+       buf = malloc(MAX_SSIDBUFFER);
+    if (!buf)
+        return -ENOMEM;
+
+    /* dump it and then push it down into xen/acm */
+    op.u.getssid.ssidbuf = buf;   /* out */
+    op.u.getssid.ssidbuf_size = MAX_SSIDBUFFER;
+    ret = do_acm_op(xc_handle, &op);
+
+    if (ret)
+    {
+        printf("ERROR getting ssidref. Try 'xm dmesg' to see details.\n");
+        goto out;
+    }
+    hdr = (struct acm_ssid_buffer *)buf;
+    if (hdr->len > MAX_SSIDBUFFER)
+    {
+        printf("ERROR: Buffer length inconsistent (ret=%d, hdr->len=%d)!\n",
+               ret, hdr->len);
+            return -EIO;
+    }
+       if (nice_print)
+    {
+               printf("SSID: ssidref = 0x%08x \n", hdr->ssidref);
+               printf("      P: %s, max_types = %d\n",
+                          ACM_POLICY_NAME(hdr->primary_policy_code), 
hdr->primary_max_types);
+               printf("          Types: ");
+               for (i=0; i< hdr->primary_max_types; i++)
+                       if (buf[hdr->primary_types_offset + i])
+                               printf("%02x ", i);
+                       else
+                               printf("-- ");
+               printf("\n");
+
+               printf("      S: %s, max_types = %d\n",
+                          ACM_POLICY_NAME(hdr->secondary_policy_code), 
hdr->secondary_max_types);
+               printf("          Types: ");
+               for (i=0; i< hdr->secondary_max_types; i++)
+                       if (buf[hdr->secondary_types_offset + i])
+                               printf("%02x ", i);
+                       else
+                               printf("-- ");
+               printf("\n");
+       }
+       else
+    {
+               /* formatted print for use with scripts (.sh)
+                *  update scripts when updating here (usually
+                *  used in combination with -d to determine a
+                *  running domain's label
+                */
+               printf("SSID: ssidref = 0x%08x \n", hdr->ssidref);
+       }
+
+    /* return ste ssidref */
+    if (hdr->primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+        ret = (hdr->ssidref) & 0xffff;
+    else if (hdr->secondary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+        ret = (hdr->ssidref) >> 16;
+ out:
+    return ret;
+}
 
 /***************************** main **************************************/
-
-void usage(char *progname)
-{
-    printf("Use: %s \n"
-           "\t getpolicy\n"
-           "\t dumpstats\n"
-           "\t loadpolicy <binary policy file>\n", progname);
-    exit(-1);
-}
 
 int main(int argc, char **argv)
 {
@@ -459,6 +575,8 @@
         if (argc != 2)
             usage(argv[0]);
         ret = acm_domain_dumpstats(acm_cmd_fd);
+    } else if (!strcmp(argv[1], "getssid")) {
+        ret = acm_domain_getssid(acm_cmd_fd, argc, argv);
     } else
         usage(argv[0]);
 
diff -r edd1616cf8cb -r 291e816acbf4 tools/security/setlabel.sh
--- a/tools/security/setlabel.sh        Fri Sep  2 14:15:49 2005
+++ b/tools/security/setlabel.sh        Fri Sep  2 14:17:08 2005
@@ -34,275 +34,27 @@
        exec sh -c "bash $0 $*"
 fi
 
+export PATH=$PATH:.
+source labelfuncs.sh
 
 usage ()
 {
-       echo "Usage: $0 [Option] <vmfile> <label> <policy name> "
-       echo "    or $0 -l <policy name>"
+       echo "Usage: $0 [Option] <vmfile> <label> [<policy name>]"
+       echo "    or $0 -l [<policy name>]"
        echo ""
-       echo "Valid Options are:"
+       echo "Valid options are:"
        echo "-r          : to relabel a file without being prompted"
        echo ""
        echo "vmfile      : XEN vm configuration file"
-       echo "label       : the label to map"
+       echo "label       : the label to map to an ssidref"
        echo "policy name : the name of the policy, i.e. 'chwall'"
+       echo "              If the policy name is omitted, it is attempted"
+       echo "              to find the current policy's name in grub.conf."
        echo ""
-       echo "-l <policy name> is used to show valid labels in the map file"
+       echo "-l [<policy name>] is used to show valid labels in the map file 
of"
+       echo "                   the given or current policy."
        echo ""
 }
-
-
-findMapFile ()
-{
-       mapfile="./$1.map"
-       if [ -r "$mapfile" ]; then
-               return 1
-       fi
-
-       mapfile="./policies/$1/$1.map"
-       if [ -r "$mapfile" ]; then
-               return 1
-       fi
-
-       return 0
-}
-
-showLabels ()
-{
-       mapfile=$1
-       if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
-               echo "Cannot read from vm configuration file $vmfile."
-               return -1
-       fi
-
-       getPrimaryPolicy $mapfile
-       getSecondaryPolicy $mapfile
-
-       echo "The following labels are available:"
-       let line=1
-       while [ 1 ]; do
-               ITEM=`cat $mapfile |         \
-                     awk -vline=$line       \
-                         -vprimary=$primary \
-                     '{                     \
-                        if ($1 == "LABEL->SSID" &&  \
-                            $2 == "VM" &&           \
-                            $3 == primary ) {       \
-                          ctr++;                    \
-                          if (ctr == line) {        \
-                            print $4;               \
-                          }                         \
-                        }                           \
-                      } END {                       \
-                      }'`
-
-               if [ "$ITEM" == "" ]; then
-                       break
-               fi
-               if [ "$secondary" != "NULL" ]; then
-                       LABEL=`cat $mapfile |     \
-                              awk -vitem=$ITEM   \
-                              '{
-                                 if ($1 == "LABEL->SSID" && \
-                                     $2 == "VM" &&          \
-                                     $3 == "CHWALL" &&      \
-                                     $4 == item ) {         \
-                                   result = item;           \
-                                 }                          \
-                               } END {                      \
-                                   print result             \
-                               }'`
-               else
-                       LABEL=$ITEM
-               fi
-
-               if [ "$LABEL" != "" ]; then
-                       echo "$LABEL"
-                       found=1
-               fi
-               let line=line+1
-       done
-       if [ "$found" != "1" ]; then
-               echo "No labels found."
-       fi
-}
-
-getPrimaryPolicy ()
-{
-       mapfile=$1
-       primary=`cat $mapfile  |   \
-                awk '             \
-                 {                \
-                   if ( $1 == "PRIMARY" ) { \
-                     res=$2;                \
-                   }                        \
-                 } END {                    \
-                   print res;               \
-                 } '`
-}
-
-getSecondaryPolicy ()
-{
-       mapfile=$1
-       secondary=`cat $mapfile  |   \
-                awk '             \
-                 {                \
-                   if ( $1 == "SECONDARY" ) { \
-                     res=$2;                \
-                   }                        \
-                 } END {                    \
-                   print res;               \
-                 } '`
-}
-
-
-getDefaultSsid ()
-{
-       mapfile=$1
-       pol=$2
-       RES=`cat $mapfile    \
-            awk -vpol=$pol  \
-             {              \
-               if ($1 == "LABEL->SSID" && \
-                   $2 == "ANY"         && \
-                   $3 == pol           && \
-                   $4 == "DEFAULT"       ) {\
-                     res=$5;                \
-               }                            \
-             } END {                        \
-               printf "%04x", strtonum(res) \
-            }'`
-       echo "default NULL mapping is $RES"
-       defaultssid=$RES
-}
-
-relabel ()
-{
-       vmfile=$1
-       label=$2
-       mapfile=$3
-       mode=$4
-
-       if [ ! -r "$vmfile" ]; then
-               echo "Cannot read from vm configuration file $vmfile."
-               return -1
-       fi
-
-       if [ ! -w "$vmfile" ]; then
-               echo "Cannot write to vm configuration file $vmfile."
-               return -1
-       fi
-
-       if [ ! -r "$mapfile" ] ; then
-               echo "Cannot read mapping file $mapfile."
-               return -1
-       fi
-
-       # Determine which policy is primary, which sec.
-       getPrimaryPolicy $mapfile
-       getSecondaryPolicy $mapfile
-
-       # Calculate the primary policy's SSIDREF
-       if [ "$primary" == "NULL" ]; then
-               SSIDLO="0000"
-       else
-               SSIDLO=`cat $mapfile |                    \
-                       awk -vlabel=$label                \
-                           -vprimary=$primary            \
-                          '{                             \
-                             if ( $1 == "LABEL->SSID" && \
-                                  $2 == "VM" &&          \
-                                  $3 == primary  &&      \
-                                  $4 == label ) {        \
-                               result=$5                 \
-                             }                           \
-                          } END {                        \
-                            if (result != "" )           \
-                              {printf "%04x", strtonum(result)}\
-                          }'`
-       fi
-
-       # Calculate the secondary policy's SSIDREF
-       if [ "$secondary" == "NULL" ]; then
-               SSIDHI="0000"
-       else
-               SSIDHI=`cat $mapfile |                    \
-                       awk -vlabel=$label                \
-                           -vsecondary=$secondary        \
-                          '{                             \
-                             if ( $1 == "LABEL->SSID" && \
-                                  $2 == "VM"          && \
-                                  $3 == secondary     && \
-                                  $4 == label ) {        \
-                               result=$5                 \
-                             }                           \
-                           }  END {                      \
-                             if (result != "" )          \
-                               {printf "%04x", strtonum(result)}\
-                           }'`
-       fi
-
-       if [ "$SSIDLO" == "" -o \
-            "$SSIDHI" == "" ]; then
-               echo "Could not map the given label '$label'."
-               return -1
-       fi
-
-       ACM_POLICY=`cat $mapfile |             \
-           awk ' { if ( $1 == "POLICY" ) {    \
-                     result=$2                \
-                   }                          \
-                 }                            \
-                 END {                        \
-                   if (result != "") {        \
-                     printf result            \
-                   }                          \
-                 }'`
-
-       if [ "$ACM_POLICY" == "" ]; then
-               echo "Could not find 'POLICY' entry in map file."
-               return -1
-       fi
-
-       SSIDREF="0x$SSIDHI$SSIDLO"
-
-       if [ "$mode" != "relabel" ]; then
-               RES=`cat $vmfile |  \
-                    awk '{         \
-                      if ( substr($1,0,7) == "ssidref" ) {\
-                        print $0;             \
-                      }                       \
-                    }'`
-               if [ "$RES" != "" ]; then
-                       echo "Do you want to overwrite the existing mapping 
($RES)? (y/N)"
-                       read user
-                       if [ "$user" != "y" -a "$user" != "Y" ]; then
-                               echo "Aborted."
-                               return 0
-                       fi
-               fi
-       fi
-
-       #Write the output
-       vmtmp1="/tmp/__setlabel.tmp1"
-       vmtmp2="/tmp/__setlabel.tmp2"
-       touch $vmtmp1
-       touch $vmtmp2
-       if [ ! -w "$vmtmp1" -o ! -w "$vmtmp2" ]; then
-               echo "Cannot create temporary files. Aborting."
-               return -1
-       fi
-       RES=`sed -e '/^#ACM_POLICY/d' $vmfile > $vmtmp1`
-       RES=`sed -e '/^#ACM_LABEL/d' $vmtmp1 > $vmtmp2`
-       RES=`sed -e '/^ssidref/d' $vmtmp2 > $vmtmp1`
-       echo "#ACM_POLICY=$ACM_POLICY" >> $vmtmp1
-       echo "#ACM_LABEL=$label" >> $vmtmp1
-       echo "ssidref = $SSIDREF" >> $vmtmp1
-       mv -f $vmtmp1 $vmfile
-       rm -rf $vmtmp1 $vmtmp2
-       echo "Mapped label '$label' to ssidref '$SSIDREF'."
-}
-
 
 
 if [ "$1" == "-r" ]; then
@@ -317,10 +69,25 @@
 
 if [ "$mode" == "show" ]; then
        if [ "$1" == "" ]; then
-               usage
-               exit -1;
+               findGrubConf
+               ret=$?
+               if [ $ret -eq 0 ]; then
+                       echo "Could not find grub.conf"
+                       exit -1;
+               fi
+               findPolicyInGrub $grubconf
+               if [ "$policy" != "" ]; then
+                       echo "Assuming policy to be '$policy'.";
+               else
+                       echo "Could not find policy."
+                       exit -1;
+               fi
+       else
+               policy=$3;
        fi
-       findMapFile $1
+
+
+       findMapFile $policy
        res=$?
        if [ "$res" != "0" ]; then
                showLabels $mapfile
@@ -330,11 +97,29 @@
 elif [ "$mode" == "usage" ]; then
        usage
 else
+       if [ "$2" == "" ]; then
+               usage
+               exit -1
+       fi
        if [ "$3" == "" ]; then
-               usage
-               exit -1;
+               findGrubConf
+               ret=$?
+               if [ $ret -eq 0 ]; then
+                       echo "Could not find grub.conf"
+                       exit -1;
+               fi
+               findPolicyInGrub $grubconf
+               if [ "$policy" != "" ]; then
+                       echo "Assuming policy to be '$policy'.";
+               else
+                       echo "Could not find policy."
+                       exit -1;
+               fi
+
+       else
+               policy=$3;
        fi
-       findMapFile $3
+       findMapFile $policy
        res=$?
        if [ "$res" != "0" ]; then
                relabel $1 $2 $mapfile $mode
diff -r edd1616cf8cb -r 291e816acbf4 xen/Rules.mk
--- a/xen/Rules.mk      Fri Sep  2 14:15:49 2005
+++ b/xen/Rules.mk      Fri Sep  2 14:17:08 2005
@@ -7,7 +7,6 @@
 perfc       ?= n
 perfc_arrays?= n
 trace       ?= n
-optimize    ?= y
 domu_debug  ?= n
 crash_debug ?= n
 
diff -r edd1616cf8cb -r 291e816acbf4 xen/acm/acm_chinesewall_hooks.c
--- a/xen/acm/acm_chinesewall_hooks.c   Fri Sep  2 14:15:49 2005
+++ b/xen/acm/acm_chinesewall_hooks.c   Fri Sep  2 14:17:08 2005
@@ -310,6 +310,28 @@
        return 0;
 }
 
+static int
+chwall_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len)
+{
+    int i;
+
+    /* fill in buffer */
+    if (chwall_bin_pol.max_types > len)
+        return -EFAULT;
+
+       if (ssidref >= chwall_bin_pol.max_ssidrefs)
+               return -EFAULT;
+
+    /* read types for chwall ssidref */
+    for(i=0; i< chwall_bin_pol.max_types; i++) {
+        if (chwall_bin_pol.ssidrefs[ssidref * chwall_bin_pol.max_types + i])
+            buf[i] = 1;
+        else
+            buf[i] = 0;
+    }
+    return chwall_bin_pol.max_types;
+}
+
 /***************************
  * Authorization functions
  ***************************/
@@ -492,6 +514,7 @@
        .dump_binary_policy             = chwall_dump_policy,
        .set_binary_policy              = chwall_set_policy,
        .dump_statistics                = chwall_dump_stats,
+    .dump_ssid_types        = chwall_dump_ssid_types,
        /* domain management control hooks */
        .pre_domain_create              = chwall_pre_domain_create,
        .post_domain_create             = chwall_post_domain_create,
diff -r edd1616cf8cb -r 291e816acbf4 xen/acm/acm_core.c
--- a/xen/acm/acm_core.c        Fri Sep  2 14:15:49 2005
+++ b/xen/acm/acm_core.c        Fri Sep  2 14:17:08 2005
@@ -64,16 +64,17 @@
 void acm_set_endian(void)
 {
     u32 test = 1;
-    if (*((u8 *)&test) == 1) {
+    if (*((u8 *)&test) == 1)
+    {
        printk("ACM module running in LITTLE ENDIAN.\n");
-       little_endian = 1;
-    } else {
-       printk("ACM module running in BIG ENDIAN.\n");
-       little_endian = 0;
-    }
-}
-
-#if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY)
+        little_endian = 1;
+    }
+    else
+    {
+        printk("ACM module running in BIG ENDIAN.\n");
+        little_endian = 0;
+    }
+}
 
 /* initialize global security policy for Xen; policy write-locked already */
 static void
@@ -101,7 +102,8 @@
      * Try all modules and see whichever could be the binary policy.
      * Adjust the initrdidx if module[1] is the binary policy.
      */
-    for (i = mbi->mods_count-1; i >= 1; i--) {
+    for (i = mbi->mods_count-1; i >= 1; i--)
+    {
         struct acm_policy_buffer *pol;
         char *_policy_start; 
         unsigned long _policy_len;
@@ -117,23 +119,32 @@
                continue; /* not a policy */
 
         pol = (struct acm_policy_buffer *)_policy_start;
-        if (ntohl(pol->magic) == ACM_MAGIC) {
+        if (ntohl(pol->magic) == ACM_MAGIC)
+        {
             rc = acm_set_policy((void *)_policy_start,
                                 (u16)_policy_len,
                                 0);
-            if (rc == ACM_OK) {
+            if (rc == ACM_OK)
+            {
                 printf("Policy len  0x%lx, start at 
%p.\n",_policy_len,_policy_start);
-                if (i == 1) {
-                    if (mbi->mods_count > 2) {
+                if (i == 1)
+                {
+                    if (mbi->mods_count > 2)
+                    {
                         *initrdidx = 2;
-                    } else {
+                    }
+                    else {
                         *initrdidx = 0;
                     }
-                } else {
+                }
+                else
+                {
                     *initrdidx = 1;
                 }
                 break;
-            } else {
+            }
+            else
+            {
                printk("Invalid policy. %d.th module line.\n", i+1);
             }
         } /* end if a binary policy definition, i.e., (ntohl(pol->magic) == 
ACM_MAGIC ) */
@@ -147,56 +158,84 @@
          const multiboot_info_t *mbi,
          unsigned long initial_images_start)
 {
-       int ret = -EINVAL;
-
-       acm_set_endian();
+       int ret = ACM_OK;
+
+    acm_set_endian();
        write_lock(&acm_bin_pol_rwlock);
-
-       if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_POLICY) {
-               acm_init_binary_policy(NULL, NULL);
-               acm_init_chwall_policy();
+    acm_init_binary_policy(NULL, NULL);
+
+    /* set primary policy component */
+    switch ((ACM_USE_SECURITY_POLICY) & 0x0f)
+    {
+
+    case ACM_CHINESE_WALL_POLICY:
+        acm_init_chwall_policy();
                acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
                acm_primary_ops = &acm_chinesewall_ops;
+        break;
+
+    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+        acm_init_ste_policy();
+               acm_bin_pol.primary_policy_code = 
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+               acm_primary_ops = &acm_simple_type_enforcement_ops;
+        break;
+
+    default:
+        /* NULL or Unknown policy not allowed primary;
+         * NULL/NULL will not compile this code */
+        ret = -EINVAL;
+        goto out;
+    }
+
+    /* secondary policy component part */
+    switch ((ACM_USE_SECURITY_POLICY) >> 4) {
+    case ACM_NULL_POLICY:
                acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
                acm_secondary_ops = &acm_null_ops;
-               ret = ACM_OK;
-       } else if (ACM_USE_SECURITY_POLICY == 
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
-               acm_init_binary_policy(NULL, NULL);
+               break;
+
+    case ACM_CHINESE_WALL_POLICY:
+        if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY)
+        {   /* not a valid combination */
+            ret = -EINVAL;
+            goto out;
+        }
+               acm_init_chwall_policy();
+        acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY;
+               acm_secondary_ops = &acm_chinesewall_ops;
+        break;
+
+    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+        if (acm_bin_pol.primary_policy_code == 
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+        {   /* not a valid combination */
+            ret = -EINVAL;
+            goto out;
+        }
                acm_init_ste_policy();
-               acm_bin_pol.primary_policy_code = 
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
-               acm_primary_ops = &acm_simple_type_enforcement_ops;
-               acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
-               acm_secondary_ops = &acm_null_ops;
-               ret = ACM_OK;
-       } else if (ACM_USE_SECURITY_POLICY == 
ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
-               acm_init_binary_policy(NULL, NULL);
-               acm_init_chwall_policy();
-               acm_init_ste_policy();
-               acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
-               acm_primary_ops = &acm_chinesewall_ops;
                acm_bin_pol.secondary_policy_code = 
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
                acm_secondary_ops = &acm_simple_type_enforcement_ops;
-               ret = ACM_OK;
-       } else if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) {
-               acm_init_binary_policy(NULL, NULL);
-               acm_bin_pol.primary_policy_code = ACM_NULL_POLICY;
-               acm_primary_ops = &acm_null_ops;
-               acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
-               acm_secondary_ops = &acm_null_ops;
-               ret = ACM_OK;
+        break;
+
+    default:
+        ret = -EINVAL;
+        goto out;
+    }
+
+ out:
+       write_unlock(&acm_bin_pol_rwlock);
+
+       if (ret != ACM_OK)
+    {
+        printk("%s: Error setting policies.\n", __func__);
+        /* here one could imagine a clean panic */
+               return -EINVAL;
        }
-       write_unlock(&acm_bin_pol_rwlock);
-
-       if (ret != ACM_OK)
-               return -EINVAL;         
        acm_setup(initrdidx, mbi, initial_images_start);
        printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, 
-              ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), 
ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
+              ACM_POLICY_NAME(acm_bin_pol.primary_policy_code),
+           ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
        return ret;
 }
-
-
-#endif
 
 int
 acm_init_domain_ssid(domid_t id, ssidref_t ssidref)
@@ -205,7 +244,8 @@
        struct domain *subj = find_domain_by_id(id);
        int ret1, ret2;
        
-       if (subj == NULL) {
+       if (subj == NULL)
+    {
                printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id);
                return ACM_NULL_POINTER_ERROR;
        }
@@ -235,14 +275,16 @@
        else
                ret2 = ACM_OK;
 
-       if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) {
+       if ((ret1 != ACM_OK) || (ret2 != ACM_OK))
+    {
                printk("%s: ERROR instantiating individual ssids for domain 
0x%02x.\n",
                       __func__, subj->domain_id);
                acm_free_domain_ssid(ssid);     
                put_domain(subj);
                return ACM_INIT_SSID_ERROR;
        }
-       printk("%s: assigned domain %x the ssidref=%x.\n", __func__, id, 
ssid->ssidref);
+       printk("%s: assigned domain %x the ssidref=%x.\n",
+           __func__, id, ssid->ssidref);
        put_domain(subj);
        return ACM_OK;
 }
@@ -254,11 +296,12 @@
        domid_t id;
 
        /* domain is already gone, just ssid is left */
-       if (ssid == NULL) {
+       if (ssid == NULL)
+    {
                printk("%s: ACM_NULL_POINTER ERROR.\n", __func__);
                return ACM_NULL_POINTER_ERROR;
        }
-               id = ssid->domainid;
+    id = ssid->domainid;
        ssid->subject        = NULL;
 
        if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
@@ -268,6 +311,7 @@
                acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid);
        ssid->secondary_ssid = NULL;
        xfree(ssid);
-       printkd("%s: Freed individual domain ssid (domain=%02x).\n",__func__, 
id);
+       printkd("%s: Freed individual domain ssid (domain=%02x).\n",
+            __func__, id);
        return ACM_OK;
 }
diff -r edd1616cf8cb -r 291e816acbf4 xen/acm/acm_null_hooks.c
--- a/xen/acm/acm_null_hooks.c  Fri Sep  2 14:15:49 2005
+++ b/xen/acm/acm_null_hooks.c  Fri Sep  2 14:17:08 2005
@@ -14,13 +14,13 @@
 #include <acm/acm_hooks.h>
 
 static int
-null_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
+null_init_domain_ssid(void **ssid, ssidref_t ssidref)
 {
        return ACM_OK;
 }
 
 static void
-null_free_domain_ssid(void *chwall_ssid)
+null_free_domain_ssid(void *ssid)
 {
        return;
 }
@@ -44,6 +44,14 @@
        return 0;
 }
 
+static int
+null_dump_ssid_types(ssidref_t ssidref, u8 *buffer, u16 buf_size)
+{
+    /* no types */
+    return 0;
+}
+
+
 /* now define the hook structure similarly to LSM */
 struct acm_operations acm_null_ops = {
        .init_domain_ssid               = null_init_domain_ssid,
@@ -51,6 +59,7 @@
        .dump_binary_policy             = null_dump_binary_policy,
        .set_binary_policy              = null_set_binary_policy,
        .dump_statistics                = null_dump_stats,
+    .dump_ssid_types        = null_dump_ssid_types,
        /* domain management control hooks */
        .pre_domain_create              = NULL,
        .post_domain_create             = NULL,
diff -r edd1616cf8cb -r 291e816acbf4 xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c      Fri Sep  2 14:15:49 2005
+++ b/xen/acm/acm_policy.c      Fri Sep  2 14:17:08 2005
@@ -26,8 +26,8 @@
 #include <xen/lib.h>
 #include <xen/delay.h>
 #include <xen/sched.h>
+#include <acm/acm_core.h>
 #include <public/acm_ops.h>
-#include <acm/acm_core.h>
 #include <acm/acm_hooks.h>
 #include <acm/acm_endian.h>
 
@@ -37,14 +37,16 @@
        u8 *policy_buffer = NULL;
        struct acm_policy_buffer *pol;
        
-       if (buf_size < sizeof(struct acm_policy_buffer))
+    if (buf_size < sizeof(struct acm_policy_buffer))
                return -EFAULT;
 
        /* 1. copy buffer from domain */
        if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
-           goto error_free;
+           return -ENOMEM;
+
        if (isuserbuffer) {
-               if (copy_from_user(policy_buffer, buf, buf_size)) {
+               if (copy_from_user(policy_buffer, buf, buf_size))
+        {
                        printk("%s: Error copying!\n",__func__);
                        goto error_free;
                }
@@ -57,11 +59,13 @@
        if ((ntohl(pol->magic) != ACM_MAGIC) || 
            (ntohl(pol->policy_version) != ACM_POLICY_VERSION) ||
            (ntohl(pol->primary_policy_code) != 
acm_bin_pol.primary_policy_code) ||
-           (ntohl(pol->secondary_policy_code) != 
acm_bin_pol.secondary_policy_code)) {
+           (ntohl(pol->secondary_policy_code) != 
acm_bin_pol.secondary_policy_code))
+    {
                printkd("%s: Wrong policy magics or versions!\n", __func__);
                goto error_free;
        }
-       if (buf_size != ntohl(pol->len)) {
+       if (buf_size != ntohl(pol->len))
+    {
                printk("%s: ERROR in buf size.\n", __func__);
                goto error_free;
        }
@@ -72,27 +76,25 @@
        /* 3. set primary policy data */
        if (acm_primary_ops->set_binary_policy(buf + 
ntohl(pol->primary_buffer_offset),
                                                
ntohl(pol->secondary_buffer_offset) -
-                                              
ntohl(pol->primary_buffer_offset))) {
+                                              
ntohl(pol->primary_buffer_offset)))
                goto error_lock_free;
-       }
+
        /* 4. set secondary policy data */
        if (acm_secondary_ops->set_binary_policy(buf + 
ntohl(pol->secondary_buffer_offset),
                                                 ntohl(pol->len) - 
-                                                
ntohl(pol->secondary_buffer_offset))) {
+                                                
ntohl(pol->secondary_buffer_offset)))
                goto error_lock_free;
-       }
+
        write_unlock(&acm_bin_pol_rwlock);
-       if (policy_buffer != NULL)
-               xfree(policy_buffer);
+       xfree(policy_buffer);
        return ACM_OK;
 
  error_lock_free:
        write_unlock(&acm_bin_pol_rwlock);
  error_free:
        printk("%s: Error setting policy.\n", __func__);
-       if (policy_buffer != NULL)
-               xfree(policy_buffer);
-       return -ENOMEM;
+    xfree(policy_buffer);
+       return -EFAULT;
 }
 
 int
@@ -102,11 +104,14 @@
      int ret;
      struct acm_policy_buffer *bin_pol;
        
+    if (buf_size < sizeof(struct acm_policy_buffer))
+               return -EFAULT;
+
      if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
            return -ENOMEM;
 
      read_lock(&acm_bin_pol_rwlock);
-     /* future: read policy from file and set it */
+
      bin_pol = (struct acm_policy_buffer *)policy_buffer;
      bin_pol->magic = htonl(ACM_MAGIC);
      bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
@@ -118,27 +123,30 @@
      
      ret = acm_primary_ops->dump_binary_policy (policy_buffer + 
ntohl(bin_pol->primary_buffer_offset),
                                       buf_size - 
ntohl(bin_pol->primary_buffer_offset));
-     if (ret < 0) {
-            printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
-            read_unlock(&acm_bin_pol_rwlock);
-            return -1;
-     }
+     if (ret < 0)
+         goto error_free_unlock;
+
      bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
      bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
 
      ret = acm_secondary_ops->dump_binary_policy(policy_buffer + 
ntohl(bin_pol->secondary_buffer_offset),
                                    buf_size - 
ntohl(bin_pol->secondary_buffer_offset));
-     if (ret < 0) {
-            printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
-            read_unlock(&acm_bin_pol_rwlock);
-            return -1;
-     }
+     if (ret < 0)
+         goto error_free_unlock;
+
      bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
-     read_unlock(&acm_bin_pol_rwlock);
      if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
-            return -EFAULT;
+            goto error_free_unlock;
+
+     read_unlock(&acm_bin_pol_rwlock);
      xfree(policy_buffer);
      return ACM_OK;
+
+ error_free_unlock:
+     read_unlock(&acm_bin_pol_rwlock);
+     printk("%s: Error getting policy.\n", __func__);
+     xfree(policy_buffer);
+     return -EFAULT;
 }
 
 int
@@ -185,4 +193,62 @@
      return -EFAULT;
 }
 
+
+int
+acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size)
+{
+    /* send stats to user space */
+     u8 *ssid_buffer;
+     int ret;
+     struct acm_ssid_buffer *acm_ssid;
+     if (buf_size < sizeof(struct acm_ssid_buffer))
+               return -EFAULT;
+
+     if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL)
+           return -ENOMEM;
+
+     read_lock(&acm_bin_pol_rwlock);
+
+     acm_ssid = (struct acm_ssid_buffer *)ssid_buffer;
+     acm_ssid->len = sizeof(struct acm_ssid_buffer);
+     acm_ssid->ssidref = ssidref;
+     acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code;
+     acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code;
+     acm_ssid->primary_types_offset = acm_ssid->len;
+
+     /* ret >= 0 --> ret == max_types */
+     ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref),
+                                            ssid_buffer + 
acm_ssid->primary_types_offset,
+                                            buf_size - 
acm_ssid->primary_types_offset);
+     if (ret < 0)
+         goto error_free_unlock;
+
+     acm_ssid->len += ret;
+     acm_ssid->primary_max_types = ret;
+
+     acm_ssid->secondary_types_offset = acm_ssid->len;
+
+     ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref),
+                                              ssid_buffer + 
acm_ssid->secondary_types_offset,
+                                              buf_size - 
acm_ssid->secondary_types_offset);
+     if (ret < 0)
+         goto error_free_unlock;
+
+     acm_ssid->len += ret;
+     acm_ssid->secondary_max_types = ret;
+
+     if (copy_to_user(buf, ssid_buffer, acm_ssid->len))
+            goto error_free_unlock;
+
+     read_unlock(&acm_bin_pol_rwlock);
+     xfree(ssid_buffer);
+     return ACM_OK;
+
+ error_free_unlock:
+     read_unlock(&acm_bin_pol_rwlock);
+     printk("%s: Error getting ssid.\n", __func__);
+     xfree(ssid_buffer);
+     return -ENOMEM;
+}
+
 /*eof*/
diff -r edd1616cf8cb -r 291e816acbf4 xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c       Fri Sep  2 14:15:49 2005
+++ b/xen/acm/acm_simple_type_enforcement_hooks.c       Fri Sep  2 14:17:08 2005
@@ -383,6 +383,27 @@
     return sizeof(struct acm_ste_stats_buffer);
 }
 
+static int
+ste_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len)
+{
+    int i;
+
+    /* fill in buffer */
+    if (ste_bin_pol.max_types > len)
+        return -EFAULT;
+
+       if (ssidref >= ste_bin_pol.max_ssidrefs)
+               return -EFAULT;
+
+    /* read types for chwall ssidref */
+    for(i=0; i< ste_bin_pol.max_types; i++) {
+               if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i])
+            buf[i] = 1;
+        else
+            buf[i] = 0;
+    }
+    return ste_bin_pol.max_types;
+}
 
 /* we need to go through this before calling the hooks,
  * returns 1 == cache hit */
@@ -625,22 +646,23 @@
        /* policy management services */
        .init_domain_ssid               = ste_init_domain_ssid,
        .free_domain_ssid               = ste_free_domain_ssid,
-       .dump_binary_policy             = ste_dump_policy,
-       .set_binary_policy              = ste_set_policy,
+       .dump_binary_policy     = ste_dump_policy,
+       .set_binary_policy      = ste_set_policy,
        .dump_statistics                = ste_dump_stats,
+    .dump_ssid_types        = ste_dump_ssid_types,
        /* domain management control hooks */
        .pre_domain_create              = ste_pre_domain_create,
-       .post_domain_create             = NULL,
-       .fail_domain_create             = NULL,
-       .post_domain_destroy            = ste_post_domain_destroy,
+       .post_domain_create         = NULL,
+       .fail_domain_create     = NULL,
+       .post_domain_destroy    = ste_post_domain_destroy,
        /* event channel control hooks */
-       .pre_eventchannel_unbound       = ste_pre_eventchannel_unbound,
+       .pre_eventchannel_unbound   = ste_pre_eventchannel_unbound,
        .fail_eventchannel_unbound      = NULL,
        .pre_eventchannel_interdomain   = ste_pre_eventchannel_interdomain,
        .fail_eventchannel_interdomain  = NULL,
        /* grant table control hooks */
-       .pre_grant_map_ref              = ste_pre_grant_map_ref,
-       .fail_grant_map_ref             = NULL,
-       .pre_grant_setup                = ste_pre_grant_setup,
-       .fail_grant_setup               = NULL,
+       .pre_grant_map_ref      = ste_pre_grant_map_ref,
+       .fail_grant_map_ref     = NULL,
+       .pre_grant_setup        = ste_pre_grant_setup,
+       .fail_grant_setup       = NULL,
 };
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/Makefile     Fri Sep  2 14:17:08 2005
@@ -17,7 +17,7 @@
 
 OBJS := $(patsubst shadow%.o,,$(OBJS)) # drop all
 ifeq ($(TARGET_SUBARCH),x86_64) 
- OBJS += shadow.o shadow_public.o      # x86_64: new code
+ OBJS += shadow.o shadow_public.o shadow_guest32.o     # x86_64: new code
 endif
 ifeq ($(TARGET_SUBARCH),x86_32) 
  ifneq ($(pae),n)
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/Rules.mk
--- a/xen/arch/x86/Rules.mk     Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/Rules.mk     Fri Sep  2 14:17:08 2005
@@ -13,10 +13,8 @@
 CFLAGS  += -I$(BASEDIR)/include/asm-x86/mach-generic
 CFLAGS  += -I$(BASEDIR)/include/asm-x86/mach-default
 
-ifeq ($(optimize),y)
+ifneq ($(debug),y)
 CFLAGS  += -O3 -fomit-frame-pointer
-else
-x86_32/usercopy.o: CFLAGS += -O1
 endif
 
 # Prevent floating-point variables from creeping into Xen.
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S        Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/boot/x86_32.S        Fri Sep  2 14:17:08 2005
@@ -9,6 +9,8 @@
                .text
 
 ENTRY(start)
+ENTRY(stext)
+ENTRY(_stext)
         jmp __start
 
         .align 4
@@ -260,6 +262,3 @@
         .org 0x2000 + STACK_SIZE + PAGE_SIZE
 
 #endif /* CONFIG_X86_PAE */
-
-ENTRY(stext)
-ENTRY(_stext)
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/boot/x86_64.S
--- a/xen/arch/x86/boot/x86_64.S        Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/boot/x86_64.S        Fri Sep  2 14:17:08 2005
@@ -10,6 +10,8 @@
         .code32
 
 ENTRY(start)
+ENTRY(stext)
+ENTRY(_stext)
         jmp __start
 
         .org    0x004
@@ -267,5 +269,3 @@
 
         .org 0x4000 + STACK_SIZE + PAGE_SIZE
         .code64
-ENTRY(stext)
-ENTRY(_stext)
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/shadow.c     Fri Sep  2 14:17:08 2005
@@ -53,6 +53,9 @@
     struct domain *d, unsigned long gpfn, unsigned long gmfn);
 static void shadow_map_into_current(struct vcpu *v,
     unsigned long va, unsigned int from, unsigned int to);
+static inline void validate_bl2e_change( struct domain *d,
+       guest_root_pgentry_t *new_gle_p, pgentry_64_t *shadow_l3, int index);
+
 #endif
 
 /********
@@ -217,10 +220,38 @@
         }
         else
         {
-            page = alloc_domheap_page(NULL);
-            void *l1 = map_domain_page(page_to_pfn(page));
-            memset(l1, 0, PAGE_SIZE);
-            unmap_domain_page(l1);
+            if (d->arch.ops->guest_paging_levels == PAGING_L2)
+            {
+#if CONFIG_PAGING_LEVELS >= 4
+                /* For 32-bit VMX guest, 2 shadow L1s to simulate 1 guest L1
+                 * So need allocate 2 continues shadow L1 each time.
+                 */
+                page = alloc_domheap_pages(NULL, SL1_ORDER, 0);
+                if (!page)
+                    domain_crash_synchronous();
+
+                void *l1_0 = map_domain_page(page_to_pfn(page));
+                memset(l1_0,0,PAGE_SIZE);
+                unmap_domain_page(l1_0);
+                void *l1_1 = map_domain_page(page_to_pfn(page+1));
+                memset(l1_1,0,PAGE_SIZE);
+                unmap_domain_page(l1_1);
+#else
+                page = alloc_domheap_page(NULL);
+                if (!page)
+                    domain_crash_synchronous();
+                void *l1 = map_domain_page(page_to_pfn(page));
+                memset(l1, 0, PAGE_SIZE);
+                unmap_domain_page(l1);
+#endif
+            }
+            else
+            {
+                page = alloc_domheap_page(NULL);
+                void *l1 = map_domain_page(page_to_pfn(page));
+                memset(l1, 0, PAGE_SIZE);
+                unmap_domain_page(l1);
+            }
         }
     }
     else {
@@ -331,7 +362,21 @@
   fail:
     FSH_LOG("promotion of pfn=%lx mfn=%lx failed!  external gnttab refs?",
             gpfn, gmfn);
-    free_domheap_page(page);
+    if (psh_type == PGT_l1_shadow)
+    {
+        if (d->arch.ops->guest_paging_levels == PAGING_L2)
+        {
+#if CONFIG_PAGING_LEVELS >=4
+            free_domheap_pages(page, SL1_ORDER);
+#else
+            free_domheap_page(page);
+#endif
+        }
+        else
+            free_domheap_page(page);
+    }
+    else
+        free_domheap_page(page);
     return 0;
 }
 
@@ -478,8 +523,10 @@
 { 
     struct vcpu *v = current;
     struct domain *d = v->domain;
-    l1_pgentry_t *gpl1e, *spl1e;
-    l2_pgentry_t gl2e, sl2e;
+    l1_pgentry_t *spl1e;
+    l2_pgentry_t sl2e;
+    guest_l1_pgentry_t *gpl1e;
+    guest_l2_pgentry_t gl2e;
     unsigned long gl1pfn, gl1mfn, sl1mfn;
     int i, init_table = 0;
 
@@ -523,28 +570,49 @@
     ASSERT( !(l2e_get_flags(old_sl2e) & _PAGE_PRESENT) );
 #endif
 
-    if ( !get_shadow_ref(sl1mfn) )
-        BUG();
-    l2pde_general(d, &gl2e, &sl2e, sl1mfn);
-    __guest_set_l2e(v, va, &gl2e);
-    __shadow_set_l2e(v, va, &sl2e);
+#if CONFIG_PAGING_LEVELS >=4
+    if (d->arch.ops->guest_paging_levels == PAGING_L2)
+    {
+        /* for 32-bit VMX guest on 64-bit host, 
+         * need update two L2 entries each time
+         */
+        if ( !get_shadow_ref(sl1mfn))
+                BUG();
+        l2pde_general(d, &gl2e, &sl2e, sl1mfn);
+        __guest_set_l2e(v, va, &gl2e);
+        __shadow_set_l2e(v, va & ~((1<<L2_PAGETABLE_SHIFT_32) - 1), &sl2e);
+        if ( !get_shadow_ref(sl1mfn+1))
+            BUG();
+        sl2e = l2e_empty();
+        l2pde_general(d, &gl2e, &sl2e, sl1mfn+1);
+        __shadow_set_l2e(v,((va & ~((1<<L2_PAGETABLE_SHIFT_32) - 1)) + (1 << 
L2_PAGETABLE_SHIFT)) , &sl2e);
+    } else
+#endif
+    {
+        if ( !get_shadow_ref(sl1mfn) )
+            BUG();
+        l2pde_general(d, &gl2e, &sl2e, sl1mfn);
+        __guest_set_l2e(v, va, &gl2e);
+        __shadow_set_l2e(v, va , &sl2e);
+    }
 
     if ( init_table )
     {
         l1_pgentry_t sl1e;
-        int index = l1_table_offset(va);
+        int index = guest_l1_table_offset(va);
         int min = 1, max = 0;
         
         unsigned long entries, pt_va;
         l1_pgentry_t tmp_sl1e;
-        l1_pgentry_t tmp_gl1e;//Prepare for double compile
-
-
-        entries = PAGE_SIZE / sizeof(l1_pgentry_t);
+        guest_l1_pgentry_t tmp_gl1e;//Prepare for double compile
+
+
+        entries = PAGE_SIZE / sizeof(guest_l1_pgentry_t);
         pt_va = ((va >> L1_PAGETABLE_SHIFT) & ~(entries - 1)) << 
L1_PAGETABLE_SHIFT;
-        gpl1e = (l1_pgentry_t *) __guest_get_l1e(v, pt_va, &tmp_gl1e);
-
-        entries = PAGE_SIZE / sizeof(l1_pgentry_t);
+        gpl1e = (guest_l1_pgentry_t *) __guest_get_l1e(v, pt_va, &tmp_gl1e);
+
+        /* If the PGT_l1_shadow has two continual pages */
+        entries = PAGE_SIZE / sizeof(guest_l1_pgentry_t); //1024 entry!!!
         pt_va = ((va >> L1_PAGETABLE_SHIFT) & ~(entries - 1)) << 
L1_PAGETABLE_SHIFT;
         spl1e = (l1_pgentry_t *) __shadow_get_l1e(v, pt_va, &tmp_sl1e);
 
@@ -555,7 +623,7 @@
         spl1e = &(shadow_linear_pg_table[l1_linear_offset(va) &
                                      ~(L1_PAGETABLE_ENTRIES-1)]);*/
 
-        for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
+        for ( i = 0; i < GUEST_L1_PAGETABLE_ENTRIES; i++ )
         {
             l1pte_propagate_from_guest(d, gpl1e[i], &sl1e);
             if ( (l1e_get_flags(sl1e) & _PAGE_PRESENT) &&
@@ -584,7 +652,7 @@
     }
 }
 
-static void 
+static void
 shadow_set_l1e(unsigned long va, l1_pgentry_t new_spte, int create_l1_shadow)
 {
     struct vcpu *v = current;
@@ -616,7 +684,7 @@
                 perfc_incrc(shadow_set_l1e_unlinked);
                 if ( !get_shadow_ref(sl1mfn) )
                     BUG();
-                l2pde_general(d, &gpde, &sl2e, sl1mfn);
+                l2pde_general(d, (guest_l2_pgentry_t *)&gpde, &sl2e, sl1mfn);
                 __guest_set_l2e(v, va, &gpde);
                 __shadow_set_l2e(v, va, &sl2e);
             }
@@ -651,6 +719,7 @@
     shadow_update_min_max(l2e_get_pfn(sl2e), l1_table_offset(va));
 }
 
+#if CONFIG_PAGING_LEVELS <= 3
 static void shadow_invlpg_32(struct vcpu *v, unsigned long va)
 {
     struct domain *d = v->domain;
@@ -679,6 +748,7 @@
 
     shadow_unlock(d);
 }
+#endif
 
 static struct out_of_sync_entry *
 shadow_alloc_oos_entry(struct domain *d)
@@ -759,8 +829,8 @@
     length = max - min + 1;
     perfc_incr_histo(snapshot_copies, length, PT_UPDATES);
 
-    min *= sizeof(l1_pgentry_t);
-    length *= sizeof(l1_pgentry_t);
+    min *= sizeof(guest_l1_pgentry_t);
+    length *= sizeof(guest_l1_pgentry_t);
 
     original = map_domain_page(gmfn);
     snapshot = map_domain_page(smfn);
@@ -841,7 +911,7 @@
 
         __shadow_get_l4e(v, va, &sl4e);
         if ( !(l4e_get_flags(sl4e) & _PAGE_PRESENT)) {
-            shadow_map_into_current(v, va, L3, L4);
+            shadow_map_into_current(v, va, PAGING_L3, PAGING_L4);
         }
 
         if (!__shadow_get_l3e(v, va, &sl3e)) {
@@ -849,7 +919,7 @@
         }
 
         if ( !(l3e_get_flags(sl3e) & _PAGE_PRESENT)) {
-            shadow_map_into_current(v, va, L2, L3);
+            shadow_map_into_current(v, va, PAGING_L2, PAGING_L3);
         }
     }
 #endif
@@ -887,11 +957,11 @@
  * Returns 0 otherwise.
  */
 static int snapshot_entry_matches(
-    struct domain *d, l1_pgentry_t *guest_pt,
+    struct domain *d, guest_l1_pgentry_t *guest_pt,
     unsigned long gpfn, unsigned index)
 {
     unsigned long smfn = __shadow_status(d, gpfn, PGT_snapshot);
-    l1_pgentry_t *snapshot, gpte; // could be L1s or L2s or ...
+    guest_l1_pgentry_t *snapshot, gpte; // could be L1s or L2s or ...
     int entries_match;
 
     perfc_incrc(snapshot_entry_matches_calls);
@@ -908,7 +978,7 @@
     // This could probably be smarter, but this is sufficent for
     // our current needs.
     //
-    entries_match = !l1e_has_changed(gpte, snapshot[index],
+    entries_match = !guest_l1e_has_changed(gpte, snapshot[index],
                                      PAGE_FLAG_MASK);
 
     unmap_domain_page(snapshot);
@@ -936,10 +1006,10 @@
     unsigned long l2mfn = pagetable_get_pfn(v->arch.guest_table);
 #endif
     unsigned long l2pfn = __mfn_to_gpfn(d, l2mfn);
-    l2_pgentry_t l2e;
+    guest_l2_pgentry_t l2e;
     unsigned long l1pfn, l1mfn;
-    l1_pgentry_t *guest_pt;
-    l1_pgentry_t tmp_gle;
+    guest_l1_pgentry_t *guest_pt;
+    guest_l1_pgentry_t tmp_gle;
     unsigned long pt_va;
 
     ASSERT(shadow_lock_is_acquired(d));
@@ -948,7 +1018,7 @@
     perfc_incrc(shadow_out_of_sync_calls);
 
 #if CONFIG_PAGING_LEVELS >= 4
-    if (d->arch.ops->guest_paging_levels == L4) { /* Mode F */
+    if (d->arch.ops->guest_paging_levels == PAGING_L4) { /* Mode F */
         pgentry_64_t le;
         unsigned long gmfn;
         unsigned long gpfn;
@@ -956,9 +1026,9 @@
 
         gmfn = l2mfn;
         gpfn = l2pfn;
-        guest_pt = (l1_pgentry_t *)v->arch.guest_vtable;
-
-        for (i = L4; i >= L3; i--) {
+        guest_pt = (guest_l1_pgentry_t *)v->arch.guest_vtable;
+
+        for (i = PAGING_L4; i >= PAGING_L3; i--) {
             if ( page_out_of_sync(&frame_table[gmfn]) &&
               !snapshot_entry_matches(
                   d, guest_pt, gpfn, table_offset_64(va, i)) )
@@ -972,7 +1042,7 @@
             if ( !VALID_MFN(gmfn) )
                 return 0;
             /* Todo: check!*/
-            guest_pt = (l1_pgentry_t *)map_domain_page(gmfn);
+            guest_pt = (guest_l1_pgentry_t *)map_domain_page(gmfn);
 
         }
 
@@ -986,13 +1056,13 @@
 #endif
 
     if ( page_out_of_sync(&frame_table[l2mfn]) &&
-         !snapshot_entry_matches(d, (l1_pgentry_t *)v->arch.guest_vtable,
-                                 l2pfn, l2_table_offset(va)) )
+         !snapshot_entry_matches(d, (guest_l1_pgentry_t *)v->arch.guest_vtable,
+                                 l2pfn, guest_l2_table_offset(va)) )
         return 1;
 
     __guest_get_l2e(v, va, &l2e);
-    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) || 
-         (l2e_get_flags(l2e) & _PAGE_PSE))
+    if ( !(guest_l2e_get_flags(l2e) & _PAGE_PRESENT) || 
+         (guest_l2e_get_flags(l2e) & _PAGE_PSE))
         return 0;
 
     l1pfn = l2e_get_pfn(l2e);
@@ -1001,20 +1071,20 @@
     // If the l1 pfn is invalid, it can't be out of sync...
     if ( !VALID_MFN(l1mfn) )
         return 0;
-    
-    pt_va = ((va >> L1_PAGETABLE_SHIFT) & ~(L1_PAGETABLE_ENTRIES - 1))
+
+    pt_va = ((va >> L1_PAGETABLE_SHIFT) & ~(GUEST_L1_PAGETABLE_ENTRIES - 1))
       << L1_PAGETABLE_SHIFT;
-    guest_pt = (l1_pgentry_t *) __guest_get_l1e(v, pt_va, &tmp_gle);
+    guest_pt = (guest_l1_pgentry_t *) __guest_get_l1e(v, pt_va, &tmp_gle);
 
     if ( page_out_of_sync(&frame_table[l1mfn]) &&
          !snapshot_entry_matches(
-             d, guest_pt, l1pfn, l1_table_offset(va)) )
+             d, guest_pt, l1pfn, guest_l1_table_offset(va)) )
         return 1;
 
     return 0;
 }
 
-#define GPFN_TO_GPTEPAGE(_gpfn) ((_gpfn) / (PAGE_SIZE / sizeof(l1_pgentry_t)))
+#define GPFN_TO_GPTEPAGE(_gpfn) ((_gpfn) / (PAGE_SIZE / 
sizeof(guest_l1_pgentry_t)))
 static inline unsigned long
 predict_writable_pte_page(struct domain *d, unsigned long gpfn)
 {
@@ -1108,7 +1178,7 @@
         return (found == max_refs_to_find);
     }
 
-    i = readonly_gpfn & (L1_PAGETABLE_ENTRIES - 1);
+    i = readonly_gpfn & (GUEST_L1_PAGETABLE_ENTRIES - 1);
     if ( !l1e_has_changed(pt[i], match, flags) && fix_entry(i) )
     {
         perfc_incrc(remove_write_fast_exit);
@@ -1117,7 +1187,7 @@
         return found;
     }
  
-    for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
+    for (i = 0; i < GUEST_L1_PAGETABLE_ENTRIES; i++)
     {
         if ( unlikely(!l1e_has_changed(pt[i], match, flags)) && fix_entry(i) )
             break;
@@ -1282,15 +1352,15 @@
         switch ( stype ) {
         case PGT_l1_shadow:
         {
-            l1_pgentry_t *guest1 = guest;
+            guest_l1_pgentry_t *guest1 = guest;
             l1_pgentry_t *shadow1 = shadow;
-            l1_pgentry_t *snapshot1 = snapshot;
+            guest_l1_pgentry_t *snapshot1 = snapshot;
 
             ASSERT(VM_ASSIST(d, VMASST_TYPE_writable_pagetables) ||
                    shadow_mode_write_all(d));
 
             if ( !shadow_mode_refcounts(d) )
-                revalidate_l1(d, guest1, snapshot1);
+                revalidate_l1(d, (l1_pgentry_t *)guest1, (l1_pgentry_t 
*)snapshot1);
 
             if ( !smfn )
                 break;
@@ -1301,7 +1371,7 @@
             for ( i = min_shadow; i <= max_shadow; i++ )
             {
                 if ( (i < min_snapshot) || (i > max_snapshot) ||
-                     l1e_has_changed(guest1[i], snapshot1[i], PAGE_FLAG_MASK) )
+                     guest_l1e_has_changed(guest1[i], snapshot1[i], 
PAGE_FLAG_MASK) )
                 {
                     need_flush |= validate_pte_change(d, guest1[i], 
&shadow1[i]);
 
@@ -1431,32 +1501,36 @@
         {
             int max = -1;
 
-            l4_pgentry_t *guest4 = guest;
+            guest_root_pgentry_t *guest_root = guest;
             l4_pgentry_t *shadow4 = shadow;
-            l4_pgentry_t *snapshot4 = snapshot;
+            guest_root_pgentry_t *snapshot_root = snapshot;
 
             changed = 0;
-            for ( i = 0; i < L4_PAGETABLE_ENTRIES; i++ )
+            for ( i = 0; i < GUEST_ROOT_PAGETABLE_ENTRIES; i++ )
             {
                 if ( !is_guest_l4_slot(i) && !external )
                     continue;
-                l4_pgentry_t new_l4e = guest4[i];
-                if ( l4e_has_changed(new_l4e, snapshot4[i], PAGE_FLAG_MASK))
+                guest_root_pgentry_t new_root_e = guest_root[i];
+                if ( root_entry_has_changed(
+                        new_root_e, snapshot_root[i], PAGE_FLAG_MASK))
                 {
-                    need_flush |= validate_entry_change(
-                      d, (pgentry_64_t *)&new_l4e,
-                      (pgentry_64_t *)&shadow4[i], 
shadow_type_to_level(stype));
-
+                    if (d->arch.ops->guest_paging_levels == PAGING_L4) {
+                        need_flush |= validate_entry_change(
+                          d, (pgentry_64_t *)&new_root_e,
+                          (pgentry_64_t *)&shadow4[i], 
shadow_type_to_level(stype));
+                    } else {
+                        validate_bl2e_change(d, &new_root_e, shadow, i);
+                    }
                     changed++;
                     ESH_LOG("%d: shadow4 mfn: %lx, shadow root: %lx\n", i,
                       smfn, pagetable_get_paddr(current->arch.shadow_table));
                 }
-                if ( l4e_get_intpte(new_l4e) != 0 ) /* FIXME: check flags? */
+                if ( guest_root_get_intpte(new_root_e) != 0 ) /* FIXME: check 
flags? */
                     max = i;
 
                 //  Need a better solution in the long term.
-                if ( !(l4e_get_flags(new_l4e) & _PAGE_PRESENT) &&
-                  unlikely(l4e_get_intpte(new_l4e) != 0) &&
+                if ( !(guest_root_get_flags(new_root_e) & _PAGE_PRESENT) &&
+                  unlikely(guest_root_get_intpte(new_root_e) != 0) &&
                   !unshadow &&
                   (frame_table[smfn].u.inuse.type_info & PGT_pinned) )
                     unshadow = 1;
@@ -1555,8 +1629,14 @@
     if ( shadow_mode_translate(d) )
         need_flush |= resync_all(d, PGT_hl2_shadow);
 #endif
-    need_flush |= resync_all(d, PGT_l2_shadow);
-    need_flush |= resync_all(d, PGT_l3_shadow);
+
+    /*
+     * Fixme: for i386 host
+     */
+    if (d->arch.ops->guest_paging_levels == PAGING_L4) {
+        need_flush |= resync_all(d, PGT_l2_shadow);
+        need_flush |= resync_all(d, PGT_l3_shadow);
+    }
     need_flush |= resync_all(d, PGT_l4_shadow);
 
     if ( need_flush && !unlikely(shadow_mode_external(d)) )
@@ -1566,11 +1646,11 @@
 }
 
 static inline int l1pte_write_fault(
-    struct vcpu *v, l1_pgentry_t *gpte_p, l1_pgentry_t *spte_p,
+    struct vcpu *v, guest_l1_pgentry_t *gpte_p, l1_pgentry_t *spte_p,
     unsigned long va)
 {
     struct domain *d = v->domain;
-    l1_pgentry_t gpte = *gpte_p;
+    guest_l1_pgentry_t gpte = *gpte_p;
     l1_pgentry_t spte;
     unsigned long gpfn = l1e_get_pfn(gpte);
     unsigned long gmfn = __gpfn_to_mfn(d, gpfn);
@@ -1585,8 +1665,8 @@
     }
 
     ASSERT(l1e_get_flags(gpte) & _PAGE_RW);
-    l1e_add_flags(gpte, _PAGE_DIRTY | _PAGE_ACCESSED);
-    spte = l1e_from_pfn(gmfn, l1e_get_flags(gpte) & ~_PAGE_GLOBAL);
+    guest_l1e_add_flags(gpte, _PAGE_DIRTY | _PAGE_ACCESSED);
+    spte = l1e_from_pfn(gmfn, guest_l1e_get_flags(gpte) & ~_PAGE_GLOBAL);
 
     SH_VVLOG("l1pte_write_fault: updating spte=0x%" PRIpte " gpte=0x%" PRIpte,
              l1e_get_intpte(spte), l1e_get_intpte(gpte));
@@ -1604,9 +1684,9 @@
 }
 
 static inline int l1pte_read_fault(
-    struct domain *d, l1_pgentry_t *gpte_p, l1_pgentry_t *spte_p)
+    struct domain *d, guest_l1_pgentry_t *gpte_p, l1_pgentry_t *spte_p)
 { 
-    l1_pgentry_t gpte = *gpte_p;
+    guest_l1_pgentry_t gpte = *gpte_p;
     l1_pgentry_t spte = *spte_p;
     unsigned long pfn = l1e_get_pfn(gpte);
     unsigned long mfn = __gpfn_to_mfn(d, pfn);
@@ -1618,10 +1698,10 @@
         return 0;
     }
 
-    l1e_add_flags(gpte, _PAGE_ACCESSED);
-    spte = l1e_from_pfn(mfn, l1e_get_flags(gpte) & ~_PAGE_GLOBAL);
-
-    if ( shadow_mode_log_dirty(d) || !(l1e_get_flags(gpte) & _PAGE_DIRTY) ||
+    guest_l1e_add_flags(gpte, _PAGE_ACCESSED);
+    spte = l1e_from_pfn(mfn, guest_l1e_get_flags(gpte) & ~_PAGE_GLOBAL);
+
+    if ( shadow_mode_log_dirty(d) || !(guest_l1e_get_flags(gpte) & 
_PAGE_DIRTY) ||
          mfn_is_page_table(mfn) )
     {
         l1e_remove_flags(spte, _PAGE_RW);
@@ -1634,7 +1714,7 @@
 
     return 1;
 }
-
+#if CONFIG_PAGING_LEVELS <= 3
 static int shadow_fault_32(unsigned long va, struct cpu_user_regs *regs)
 {
     l1_pgentry_t gpte, spte, orig_gpte;
@@ -1768,6 +1848,7 @@
     shadow_unlock(d);
     return 0;
 }
+#endif
 
 static int do_update_va_mapping(unsigned long va,
                                 l1_pgentry_t val,
@@ -1787,7 +1868,7 @@
     //
     __shadow_sync_va(v, va);
 
-    l1pte_propagate_from_guest(d, val, &spte);
+    l1pte_propagate_from_guest(d, *(guest_l1_pgentry_t *)&val, &spte);
     shadow_set_l1e(va, spte, 0);
 
     /*
@@ -1848,7 +1929,7 @@
 #if CONFIG_PAGING_LEVELS == 2
     unsigned long hl2mfn;
 #endif
-  
+
     int max_mode = ( shadow_mode_external(d) ? SHM_external
                      : shadow_mode_translate(d) ? SHM_translate
                      : shadow_mode_enabled(d) ? SHM_enable
@@ -1954,17 +2035,6 @@
 #endif
 }
 
-struct shadow_ops MODE_A_HANDLER = {
-    .guest_paging_levels        = 2,
-    .invlpg                     = shadow_invlpg_32,
-    .fault                      = shadow_fault_32,
-    .update_pagetables          = shadow_update_pagetables,
-    .sync_all                   = sync_all,
-    .remove_all_write_access    = remove_all_write_access,
-    .do_update_va_mapping       = do_update_va_mapping,
-    .mark_mfn_out_of_sync       = mark_mfn_out_of_sync,
-    .is_out_of_sync             = is_out_of_sync,
-};
 
 /************************************************************************/
 /************************************************************************/
@@ -2445,12 +2515,90 @@
     BUG();                      /* not implemenated yet */
     return 42;
 }
+static unsigned long gva_to_gpa_pae(unsigned long gva)
+{
+    BUG();
+    return 43;
+}
 #endif
 
 #if CONFIG_PAGING_LEVELS >= 4
 /****************************************************************************/
 /* 64-bit shadow-mode code testing */
 /****************************************************************************/
+/*
+ * validate_bl2e_change()
+ * The code is for 32-bit VMX gues on 64-bit host.
+ * To sync guest L2.
+ */
+
+static inline void
+validate_bl2e_change(
+  struct domain *d,
+  guest_root_pgentry_t *new_gle_p,
+  pgentry_64_t *shadow_l3,
+  int index)
+{
+    int sl3_idx, sl2_idx;
+    unsigned long sl2mfn, sl1mfn;
+    pgentry_64_t *sl2_p;
+
+    /* Using guest l2 pte index to get shadow l3&l2 index
+     * index: 0 ~ 1023, PAGETABLE_ENTRIES: 512
+     */
+    sl3_idx = index / (PAGETABLE_ENTRIES / 2);
+    sl2_idx = (index % (PAGETABLE_ENTRIES / 2)) * 2;
+
+    sl2mfn = entry_get_pfn(shadow_l3[sl3_idx]);
+    sl2_p = (pgentry_64_t *)map_domain_page(sl2mfn);
+
+    validate_pde_change(
+        d, *(guest_l2_pgentry_t *)new_gle_p, (l2_pgentry_t *)&sl2_p[sl2_idx]);
+
+    /* Mapping the second l1 shadow page */
+    if (entry_get_flags(sl2_p[sl2_idx]) & _PAGE_PRESENT) {
+       sl1mfn = entry_get_pfn(sl2_p[sl2_idx]);
+       sl2_p[sl2_idx + 1] =
+            entry_from_pfn(sl1mfn + 1, entry_get_flags(sl2_p[sl2_idx]));
+    }
+    unmap_domain_page(sl2_p);
+
+}
+
+/*
+ * init_bl2() is for 32-bit VMX guest on 64-bit host
+ * Using 1 shadow L4(l3) and 4 shadow L2s to simulate guest L2
+ */
+static inline unsigned long init_bl2(l4_pgentry_t *spl4e, unsigned long smfn)
+{
+    unsigned int count;
+    unsigned long sl2mfn;
+    struct pfn_info *page;
+
+    memset(spl4e, 0, PAGE_SIZE);
+
+    /* Map the self entry, L4&L3 share the same page */
+    spl4e[PAE_SHADOW_SELF_ENTRY] = l4e_from_pfn(smfn, __PAGE_HYPERVISOR);
+
+    /* Allocate 4 shadow L2s */
+    page = alloc_domheap_pages(NULL, SL2_ORDER, 0);
+    if (!page)
+        domain_crash_synchronous();
+
+    for (count = 0; count < PDP_ENTRIES; count++)
+    {
+        sl2mfn = page_to_pfn(page+count);
+        void *l2 = map_domain_page(sl2mfn);
+        memset(l2, 0, PAGE_SIZE);
+        unmap_domain_page(l2);
+        spl4e[count] = l4e_from_pfn(sl2mfn, _PAGE_PRESENT);
+    }
+
+    unmap_domain_page(spl4e);
+    return smfn;
+
+
+}
 
 static unsigned long shadow_l4_table(
   struct domain *d, unsigned long gpfn, unsigned long gmfn)
@@ -2464,11 +2612,16 @@
 
     if ( unlikely(!(smfn = alloc_shadow_page(d, gpfn, gmfn, PGT_l4_shadow))) )
     {
-        printk("Couldn't alloc an L2 shadow for pfn=%lx mfn=%lx\n", gpfn, 
gmfn);
+        printk("Couldn't alloc an L4 shadow for pfn=%lx mfn=%lx\n", gpfn, 
gmfn);
         BUG(); /* XXX Deal gracefully with failure. */
     }
 
     spl4e = (l4_pgentry_t *)map_domain_page(smfn);
+
+    if (d->arch.ops->guest_paging_levels == PAGING_L2) {
+        return init_bl2(spl4e, smfn);
+    }
+
     /* Install hypervisor and 4x linear p.t. mapings. */
     if ( (PGT_base_page_table == PGT_l4_page_table) &&
       !shadow_mode_external(d) )
@@ -2576,7 +2729,7 @@
     pgentry_64_t gle, sle;
     unsigned long gpfn, smfn;
 
-    if (from == L1 && to == L2) {
+    if (from == PAGING_L1 && to == PAGING_L2) {
         shadow_map_l1_into_current_l2(va);
         return;
     }
@@ -2608,7 +2761,7 @@
     if (!(l4e_get_flags(sl4e) & _PAGE_PRESENT)) {
         if (create_l2_shadow) {
             perfc_incrc(shadow_set_l3e_force_map);
-            shadow_map_into_current(v, va, L3, L4);
+            shadow_map_into_current(v, va, PAGING_L3, PAGING_L4);
             __shadow_get_l4e(v, va, &sl4e);
         } else {
             printk("For non VMX shadow, create_l1_shadow:%d\n", 
create_l2_shadow);
@@ -2619,7 +2772,7 @@
     if (!(l3e_get_flags(sl3e) & _PAGE_PRESENT)) {
          if (create_l2_shadow) {
             perfc_incrc(shadow_set_l2e_force_map);
-            shadow_map_into_current(v, va, L2, L3);
+            shadow_map_into_current(v, va, PAGING_L2, PAGING_L3);
             __shadow_get_l3e(v, va, &sl3e);
         } else {
             printk("For non VMX shadow, create_l1_shadow:%d\n", 
create_l2_shadow);
@@ -2655,8 +2808,15 @@
     l1_pgentry_t old_spte;
     l1_pgentry_t sl1e = *(l1_pgentry_t *)sl1e_p;
     int i;
-
-    for (i = L4; i >= L2; i--) {
+    unsigned long orig_va = 0;
+
+    if (d->arch.ops->guest_paging_levels == PAGING_L2) {
+        /* This is for 32-bit VMX guest on 64-bit host */
+        orig_va = va;
+        va = va & (~((1<<L2_PAGETABLE_SHIFT_32)-1));
+    }
+
+    for (i = PAGING_L4; i >= PAGING_L2; i--) {
         if (!__rw_entry(v, va, &sle, SHADOW_ENTRY | GET_ENTRY | i)) {
             printk("<%s> i = %d\n", __func__, i);
             BUG();
@@ -2672,9 +2832,13 @@
 #endif
             }
         }
-        if(i < L4)
+        if(i < PAGING_L4)
             shadow_update_min_max(entry_get_pfn(sle_up), table_offset_64(va, 
i));
         sle_up = sle;
+    }
+
+    if (d->arch.ops->guest_paging_levels == PAGING_L2) {
+        va = orig_va;
     }
 
     if ( shadow_mode_refcounts(d) )
@@ -2692,9 +2856,13 @@
     }
 
     __shadow_set_l1e(v, va, &sl1e);
-    shadow_update_min_max(entry_get_pfn(sle_up), table_offset_64(va, L1));
-}
-
+
+    shadow_update_min_max(entry_get_pfn(sle_up), guest_l1_table_offset(va));
+}
+
+/* As 32-bit guest don't support 4M page yet,
+ * we don't concern double compile for this function
+ */
 static inline int l2e_rw_fault(
     struct vcpu *v, l2_pgentry_t *gl2e_p, unsigned long va, int rw)
 {
@@ -2825,12 +2993,120 @@
 
 }
 
+/*
+ * Check P, R/W, U/S bits in the guest page table.
+ * If the fault belongs to guest return 1,
+ * else return 0.
+ */
+#if defined( GUEST_PGENTRY_32 )
+static inline int guest_page_fault(struct vcpu *v,
+  unsigned long va, unsigned int error_code, 
+  guest_l2_pgentry_t *gpl2e, guest_l1_pgentry_t *gpl1e)
+{
+    /* The following check for 32-bit guest on 64-bit host */
+
+    __guest_get_l2e(v, va, gpl2e);
+
+    /* Check the guest L2 page-table entry first*/
+    if (unlikely(!(guest_l2e_get_flags(*gpl2e) & _PAGE_PRESENT)))
+        return 1;
+
+    if (error_code & ERROR_W) {
+        if (unlikely(!(guest_l2e_get_flags(*gpl2e) & _PAGE_RW)))
+            return 1;
+    }
+    if (error_code & ERROR_U) {
+        if (unlikely(!(guest_l2e_get_flags(*gpl2e) & _PAGE_USER)))
+            return 1;
+    }
+
+    if (guest_l2e_get_flags(*gpl2e) & _PAGE_PSE)
+        return 0;
+
+    __guest_get_l1e(v, va, gpl1e);
+
+    /* Then check the guest L1 page-table entry */
+    if (unlikely(!(guest_l1e_get_flags(*gpl1e) & _PAGE_PRESENT)))
+        return 1;
+
+    if (error_code & ERROR_W) {
+        if (unlikely(!(guest_l1e_get_flags(*gpl1e) & _PAGE_RW)))
+            return 1;
+    }
+    if (error_code & ERROR_U) {
+        if (unlikely(!(guest_l1e_get_flags(*gpl1e) & _PAGE_USER)))
+            return 1;
+    }
+
+    return 0;
+}
+#else
+static inline int guest_page_fault(struct vcpu *v,
+  unsigned long va, unsigned int error_code, 
+  guest_l2_pgentry_t *gpl2e, guest_l1_pgentry_t *gpl1e)
+{
+    struct domain *d = v->domain;
+    pgentry_64_t gle, *lva;
+    unsigned long mfn;
+    int i;
+
+    __rw_entry(v, va, &gle, GUEST_ENTRY | GET_ENTRY | PAGING_L4);
+    if (unlikely(!(entry_get_flags(gle) & _PAGE_PRESENT)))
+        return 1;
+
+    if (error_code & ERROR_W) {
+        if (unlikely(!(entry_get_flags(gle) & _PAGE_RW)))
+            return 1;
+    }
+    if (error_code & ERROR_U) {
+        if (unlikely(!(entry_get_flags(gle) & _PAGE_USER)))
+            return 1;
+    }
+    for (i = PAGING_L3; i >= PAGING_L1; i--) {
+        /*
+         * If it's not external mode, then mfn should be machine physical.
+         */
+        mfn = __gpfn_to_mfn(d, (entry_get_value(gle) >> PAGE_SHIFT));
+
+        lva = (pgentry_64_t *) phys_to_virt(
+          mfn << PAGE_SHIFT);
+        gle = lva[table_offset_64(va, i)];
+
+        if (unlikely(!(entry_get_flags(gle) & _PAGE_PRESENT)))
+            return 1;
+
+        if (error_code & ERROR_W) {
+            if (unlikely(!(entry_get_flags(gle) & _PAGE_RW)))
+                return 1;
+        }
+        if (error_code & ERROR_U) {
+            if (unlikely(!(entry_get_flags(gle) & _PAGE_USER)))
+                return 1;
+        }
+
+        if (i == PAGING_L2) {
+            if (gpl2e)
+                gpl2e->l2 = gle.lo;
+
+            if (likely(entry_get_flags(gle) & _PAGE_PSE))
+                return 0;
+
+        }
+
+        if (i == PAGING_L1)
+            if (gpl1e)
+                gpl1e->l1 = gle.lo;
+    }
+    return 0;
+}
+#endif
 static int shadow_fault_64(unsigned long va, struct cpu_user_regs *regs)
 {
     struct vcpu *v = current;
     struct domain *d = v->domain;
-    l2_pgentry_t gl2e;
-    l1_pgentry_t sl1e, gl1e;
+    guest_l2_pgentry_t gl2e;
+    guest_l1_pgentry_t gl1e;
+    l1_pgentry_t sl1e;
 
     perfc_incrc(shadow_fault_calls);
 
@@ -2853,12 +3129,11 @@
      * STEP 2. Check if the fault belongs to guest
      */
     if ( guest_page_fault(
-            v, va, regs->error_code, 
-            (pgentry_64_t *)&gl2e, (pgentry_64_t *)&gl1e) ) {
+            v, va, regs->error_code, &gl2e, &gl1e) ) {
         goto fail;
     }
     
-    if ( unlikely(!(l2e_get_flags(gl2e) & _PAGE_PSE)) ) {
+    if ( unlikely(!(guest_l2e_get_flags(gl2e) & _PAGE_PSE)) ) {
         /*
          * Handle 4K pages here
          */
@@ -2892,11 +3167,11 @@
          */
         /* Write fault? */
         if ( regs->error_code & 2 ) {
-            if ( !l2e_rw_fault(v, &gl2e, va, WRITE_FAULT) ) {
+            if ( !l2e_rw_fault(v, (l2_pgentry_t *)&gl2e, va, WRITE_FAULT) ) {
                 goto fail;
             }
         } else {
-            l2e_rw_fault(v, &gl2e, va, READ_FAULT);
+            l2e_rw_fault(v, (l2_pgentry_t *)&gl2e, va, READ_FAULT);
         }
 
         /*
@@ -2944,7 +3219,27 @@
     shadow_unlock(d);
 }
 
-#ifndef PGENTRY_32
+static unsigned long gva_to_gpa_64(unsigned long gva)
+{
+    struct vcpu *v = current;
+    guest_l1_pgentry_t gl1e = {0};
+    guest_l2_pgentry_t gl2e = {0};
+    unsigned long gpa;
+
+    if (guest_page_fault(v, gva, 0, &gl2e, &gl1e))
+        return 0;
+    
+    if (guest_l2e_get_flags(gl2e) & _PAGE_PSE)
+        gpa = guest_l2e_get_paddr(gl2e) + (gva & ((1 << 
GUEST_L2_PAGETABLE_SHIFT) - 1));
+    else
+        gpa = guest_l1e_get_paddr(gl1e) + (gva & ~PAGE_MASK);
+
+    return gpa;
+
+}
+
+#ifndef GUEST_PGENTRY_32
+
 struct shadow_ops MODE_F_HANDLER = {
     .guest_paging_levels              = 4,
     .invlpg                     = shadow_invlpg_64,
@@ -2955,10 +3250,42 @@
     .do_update_va_mapping       = do_update_va_mapping,
     .mark_mfn_out_of_sync       = mark_mfn_out_of_sync,
     .is_out_of_sync             = is_out_of_sync,
+    .gva_to_gpa                 = gva_to_gpa_64,
 };
 #endif
 
 #endif
+
+#if CONFIG_PAGING_LEVELS == 2
+struct shadow_ops MODE_A_HANDLER = {
+    .guest_paging_levels        = 2,
+    .invlpg                     = shadow_invlpg_32,
+    .fault                      = shadow_fault_32,
+    .update_pagetables          = shadow_update_pagetables,
+    .sync_all                   = sync_all,
+    .remove_all_write_access    = remove_all_write_access,
+    .do_update_va_mapping       = do_update_va_mapping,
+    .mark_mfn_out_of_sync       = mark_mfn_out_of_sync,
+    .is_out_of_sync             = is_out_of_sync,
+    .gva_to_gpa                 = gva_to_gpa_64,
+};
+
+#elif CONFIG_PAGING_LEVELS == 3
+struct shadow_ops MODE_B_HANDLER = {
+    .guest_paging_levels              = 3,
+    .invlpg                     = shadow_invlpg_32,
+    .fault                      = shadow_fault_32,
+    .update_pagetables          = shadow_update_pagetables,
+    .sync_all                   = sync_all,
+    .remove_all_write_access    = remove_all_write_access,
+    .do_update_va_mapping       = do_update_va_mapping,
+    .mark_mfn_out_of_sync       = mark_mfn_out_of_sync,
+    .is_out_of_sync             = is_out_of_sync,
+    .gva_to_gpa                 = gva_to_gpa_pae,
+};
+
+#endif
+
 
 /*
  * Local variables:
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c      Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/shadow_public.c      Fri Sep  2 14:17:08 2005
@@ -33,11 +33,15 @@
 #if CONFIG_PAGING_LEVELS >= 3
 #include <asm/shadow_64.h>
 
+#endif
+#if CONFIG_PAGING_LEVELS == 4
 extern struct shadow_ops MODE_F_HANDLER;
+extern struct shadow_ops MODE_D_HANDLER;
 #endif
 
 extern struct shadow_ops MODE_A_HANDLER;
 
+#define SHADOW_MAX_GUEST32(_encoded) ((L1_PAGETABLE_ENTRIES_32 - 1) - 
((_encoded) >> 16))
 /****************************************************************************/
 /************* export interface functions ***********************************/
 /****************************************************************************/
@@ -48,7 +52,7 @@
     shadow_lock(d);
 
     switch(levels) {
-#if CONFIG_PAGING_LEVELS >= 4 
+#if CONFIG_PAGING_LEVELS >= 4
     case 4:
        if ( d->arch.ops != &MODE_F_HANDLER )
            d->arch.ops = &MODE_F_HANDLER;
@@ -56,9 +60,14 @@
         return 1;
 #endif
     case 3:
-    case 2:                     
+    case 2:
+#if CONFIG_PAGING_LEVELS == 2
        if ( d->arch.ops != &MODE_A_HANDLER )
            d->arch.ops = &MODE_A_HANDLER;
+#elif CONFIG_PAGING_LEVELS == 4
+       if ( d->arch.ops != &MODE_D_HANDLER )
+           d->arch.ops = &MODE_D_HANDLER;
+#endif
        shadow_unlock(d);
         return 1;
    default:
@@ -122,13 +131,17 @@
     return d->arch.ops->is_out_of_sync(v, va);
 }
 
+unsigned long gva_to_gpa(unsigned long gva)
+{
+    struct domain *d = current->domain;
+    return d->arch.ops->gva_to_gpa(gva);
+}
 /****************************************************************************/
 /****************************************************************************/
 #if CONFIG_PAGING_LEVELS >= 4
 /*
  * Convert PAE 3-level page-table to 4-level page-table
  */
-#define PDP_ENTRIES   4
 static pagetable_t page_table_convert(struct domain *d)
 {
     struct pfn_info *l4page, *l3page;
@@ -203,19 +216,41 @@
 /*
  * Free l2, l3, l4 shadow tables
  */
+
+void free_fake_shadow_l2(struct domain *d,unsigned long smfn);
+
 static void inline
 free_shadow_tables(struct domain *d, unsigned long smfn, u32 level)
 {
     pgentry_64_t *ple = map_domain_page(smfn);
     int i, external = shadow_mode_external(d);
-
-    for ( i = 0; i < PAGETABLE_ENTRIES; i++ )
-        if ( external || is_guest_l4_slot(i) )
-            if ( entry_get_flags(ple[i]) & _PAGE_PRESENT )
-                put_shadow_ref(entry_get_pfn(ple[i]));
-
-    unmap_domain_page(ple);
-}
+    struct pfn_info *page = &frame_table[smfn];
+
+    if (d->arch.ops->guest_paging_levels == PAGING_L2)
+    {
+#if CONFIG_PAGING_LEVELS >=4
+        for ( i = 0; i < PDP_ENTRIES; i++ )
+        {
+            if (entry_get_flags(ple[i]) & _PAGE_PRESENT )
+                free_fake_shadow_l2(d,entry_get_pfn(ple[i]));
+        }
+   
+        page = &frame_table[entry_get_pfn(ple[0])];
+        free_domheap_pages(page, SL2_ORDER);
+        unmap_domain_page(ple);
+#endif
+    }
+    else
+    {
+        for ( i = 0; i < PAGETABLE_ENTRIES; i++ )
+            if ( external || is_guest_l4_slot(i) )
+                if ( entry_get_flags(ple[i]) & _PAGE_PRESENT )
+                        put_shadow_ref(entry_get_pfn(ple[i]));
+
+        unmap_domain_page(ple);
+    }
+}
+
 
 void free_monitor_pagetable(struct vcpu *v)
 {
@@ -453,7 +488,12 @@
     struct pfn_info *spage = pfn_to_page(smfn);
     u32 min_max = spage->tlbflush_timestamp;
     int min = SHADOW_MIN(min_max);
-    int max = SHADOW_MAX(min_max);
+    int max;
+    
+    if (d->arch.ops->guest_paging_levels == PAGING_L2)
+        max = SHADOW_MAX_GUEST32(min_max);
+    else
+        max = SHADOW_MAX(min_max);
 
     for ( i = min; i <= max; i++ )
     {
@@ -512,9 +552,24 @@
     unmap_domain_page(pl2e);
 }
 
+void free_fake_shadow_l2(struct domain *d, unsigned long smfn)
+{
+    pgentry_64_t *ple = map_domain_page(smfn);
+    int i;
+
+    for ( i = 0; i < PAGETABLE_ENTRIES; i = i + 2 )
+    {
+        if ( entry_get_flags(ple[i]) & _PAGE_PRESENT )
+            put_shadow_ref(entry_get_pfn(ple[i]));
+    }
+
+    unmap_domain_page(ple);
+}
+
 void free_shadow_page(unsigned long smfn)
 {
     struct pfn_info *page = &frame_table[smfn];
+
     unsigned long gmfn = page->u.inuse.type_info & PGT_mfn_mask;
     struct domain *d = page_get_owner(pfn_to_page(gmfn));
     unsigned long gpfn = __mfn_to_gpfn(d, gmfn);
@@ -531,6 +586,7 @@
             gpfn |= (1UL << 63);
     }
 #endif
+
     delete_shadow_status(d, gpfn, gmfn, type);
 
     switch ( type )
@@ -687,7 +743,7 @@
     int                   i;
     struct shadow_status *x;
     struct vcpu          *v;
- 
+
     /*
      * WARNING! The shadow page table must not currently be in use!
      * e.g., You are expected to have paused the domain and synchronized CR3.
@@ -794,7 +850,16 @@
         perfc_decr(free_l1_pages);
 
         struct pfn_info *page = list_entry(list_ent, struct pfn_info, list);
-        free_domheap_page(page);
+       if (d->arch.ops->guest_paging_levels == PAGING_L2)
+       {
+#if CONFIG_PAGING_LEVELS >=4
+        free_domheap_pages(page, SL1_ORDER);
+#else
+       free_domheap_page(page);
+#endif
+       }
+       else
+       free_domheap_page(page);
     }
 
     shadow_audit(d, 0);
@@ -1191,7 +1256,7 @@
     {
         DPRINTK("Don't try to do a shadow op on yourself!\n");
         return -EINVAL;
-    }   
+    }
 
     domain_pause(d);
 
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/traps.c      Fri Sep  2 14:17:08 2005
@@ -100,7 +100,14 @@
 
 static int debug_stack_lines = 20;
 integer_param("debug_stack_lines", debug_stack_lines);
-#define stack_words_per_line (32 / BYTES_PER_LONG)
+
+#ifdef CONFIG_X86_32
+#define stack_words_per_line 8
+#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)&regs->esp)
+#else
+#define stack_words_per_line 4
+#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->esp)
+#endif
 
 int is_kernel_text(unsigned long addr)
 {
@@ -118,17 +125,16 @@
     return (unsigned long) &_etext;
 }
 
-void show_guest_stack(void)
+static void show_guest_stack(struct cpu_user_regs *regs)
 {
     int i;
-    struct cpu_user_regs *regs = guest_cpu_user_regs();
     unsigned long *stack = (unsigned long *)regs->esp, addr;
 
     printk("Guest stack trace from "__OP"sp=%p:\n   ", stack);
 
     for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
     {
-        if ( ((long)stack & (STACK_SIZE-1)) == 0 )
+        if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 )
             break;
         if ( get_user(addr, stack) )
         {
@@ -148,38 +154,98 @@
     printk("\n");
 }
 
-void show_trace(unsigned long *esp)
-{
-    unsigned long *stack = esp, addr;
-    int i = 0;
-
-    printk("Xen call trace from "__OP"sp=%p:\n   ", stack);
-
-    while ( ((long) stack & (STACK_SIZE-1)) != 0 )
+#ifdef NDEBUG
+
+static void show_trace(struct cpu_user_regs *regs)
+{
+    unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
+
+    printk("Xen call trace:\n   ");
+
+    printk("[<%p>]", _p(regs->eip));
+    print_symbol(" %s\n   ", regs->eip);
+
+    while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
     {
         addr = *stack++;
         if ( is_kernel_text(addr) )
         {
             printk("[<%p>]", _p(addr));
             print_symbol(" %s\n   ", addr);
-            i++;
-        }
-    }
-    if ( i == 0 )
-        printk("Trace empty.");
+        }
+    }
+
     printk("\n");
 }
 
-void show_stack(unsigned long *esp)
-{
-    unsigned long *stack = esp, addr;
+#else
+
+static void show_trace(struct cpu_user_regs *regs)
+{
+    unsigned long *frame, next, addr, low, high;
+
+    printk("Xen call trace:\n   ");
+
+    printk("[<%p>]", _p(regs->eip));
+    print_symbol(" %s\n   ", regs->eip);
+
+    /* 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));
+
+    /* The initial frame pointer. */
+    next = regs->ebp;
+
+    for ( ; ; )
+    {
+        /* Valid frame pointer? */
+        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) )
+                break;
+            frame = (unsigned long *)next;
+            next  = frame[0];
+            addr  = frame[(offsetof(struct cpu_user_regs, eip) -
+                           offsetof(struct cpu_user_regs, ebp))
+                         / BYTES_PER_LONG];
+        }
+        else
+        {
+            /* Ordinary stack frame. */
+            frame = (unsigned long *)next;
+            next  = frame[0];
+            addr  = frame[1];
+        }
+
+        printk("[<%p>]", _p(addr));
+        print_symbol(" %s\n   ", addr);
+
+        low = (unsigned long)&frame[2];
+    }
+
+    printk("\n");
+}
+
+#endif
+
+void show_stack(struct cpu_user_regs *regs)
+{
+    unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
     int i;
 
+    if ( GUEST_MODE(regs) )
+        return show_guest_stack(regs);
+
     printk("Xen stack trace from "__OP"sp=%p:\n   ", stack);
 
     for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
     {
-        if ( ((long)stack & (STACK_SIZE-1)) == 0 )
+        if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 )
             break;
         if ( (i != 0) && ((i % stack_words_per_line) == 0) )
             printk("\n   ");
@@ -190,7 +256,7 @@
         printk("Stack empty.");
     printk("\n");
 
-    show_trace(esp);
+    show_trace(regs);
 }
 
 /*
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c        Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/vmx.c        Fri Sep  2 14:17:08 2005
@@ -412,7 +412,7 @@
     if ( !result )
     {
         __vmread(GUEST_RIP, &eip);
-        printk("vmx pgfault to guest va=%p eip=%p\n", va, eip);
+        printk("vmx pgfault to guest va=%lx eip=%lx\n", va, eip);
     }
 #endif
 
@@ -456,7 +456,16 @@
         clear_bit(X86_FEATURE_PSE, &edx);
         clear_bit(X86_FEATURE_PAE, &edx);
         clear_bit(X86_FEATURE_PSE36, &edx);
+#else
+        struct vcpu *d = current;
+        if (d->domain->arch.ops->guest_paging_levels == PAGING_L2)
+        {
+            clear_bit(X86_FEATURE_PSE, &edx);
+            clear_bit(X86_FEATURE_PAE, &edx);
+            clear_bit(X86_FEATURE_PSE36, &edx);
+        }
 #endif
+
     }
 
     regs->eax = (unsigned long) eax;
@@ -650,7 +659,7 @@
         p->df = (eflags & X86_EFLAGS_DF) ? 1 : 0;
 
         if (test_bit(5, &exit_qualification)) /* "rep" prefix */
-           p->count = vm86 ? regs->ecx & 0xFFFF : regs->ecx;
+            p->count = vm86 ? regs->ecx & 0xFFFF : regs->ecx;
 
         /*
          * Split up string I/O operations that cross page boundaries. Don't
@@ -1006,6 +1015,15 @@
 
 #if CONFIG_PAGING_LEVELS >= 4 
             if(!shadow_set_guest_paging_levels(d->domain, 4)) {
+                printk("Unsupported guest paging levels\n");
+                domain_crash_synchronous(); /* need to take a clean path */
+            }
+#endif
+        }
+        else
+        {
+#if CONFIG_PAGING_LEVELS >= 4
+            if(!shadow_set_guest_paging_levels(d->domain, 2)) {
                 printk("Unsupported guest paging levels\n");
                 domain_crash_synchronous(); /* need to take a clean path */
             }
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/x86_32/traps.c       Fri Sep  2 14:17:08 2005
@@ -79,11 +79,8 @@
            "ss: %04lx   cs: %04lx\n",
            ds, es, fs, gs, ss, cs);
 
-    if ( GUEST_MODE(regs) )
-        show_guest_stack();
-    else
-        show_stack((unsigned long *)&regs->esp);
-} 
+    show_stack(regs);
+}
 
 void show_page_walk(unsigned long addr)
 {
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/x86_64/traps.c       Fri Sep  2 14:17:08 2005
@@ -32,10 +32,7 @@
            regs->r12, regs->r13, regs->r14);
     printk("r15: %016lx\n", regs->r15);
 
-    if ( GUEST_MODE(regs) )
-        show_guest_stack();
-    else
-        show_stack((unsigned long *)regs->rsp);
+    show_stack(regs);
 }
 
 void show_page_walk(unsigned long addr)
diff -r edd1616cf8cb -r 291e816acbf4 xen/common/acm_ops.c
--- a/xen/common/acm_ops.c      Fri Sep  2 14:15:49 2005
+++ b/xen/common/acm_ops.c      Fri Sep  2 14:17:08 2005
@@ -19,6 +19,7 @@
 #include <xen/types.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <public/acm.h>
 #include <public/acm_ops.h>
 #include <xen/sched.h>
 #include <xen/event.h>
@@ -41,7 +42,8 @@
     POLICY,                     /* access to policy interface (early drop) */
     GETPOLICY,                  /* dump policy cache */
     SETPOLICY,                  /* set policy cache (controls security) */
-    DUMPSTATS                   /* dump policy statistics */
+    DUMPSTATS,                  /* dump policy statistics */
+    GETSSID                     /* retrieve ssidref for domain id */
 } acm_operation_t;
 
 int acm_authorize_acm_ops(struct domain *d, acm_operation_t pops)
@@ -117,6 +119,35 @@
         }
         break;
 
+    case ACM_GETSSID:
+        {
+                       ssidref_t ssidref;
+
+            if (acm_authorize_acm_ops(current->domain, GETSSID))
+                return -EACCES;
+
+                       if (op->u.getssid.get_ssid_by == SSIDREF)
+                               ssidref = op->u.getssid.id.ssidref;
+                       else if (op->u.getssid.get_ssid_by == DOMAINID) {
+                               struct domain *subj = 
find_domain_by_id(op->u.getssid.id.domainid);
+                               if (!subj)
+                                       return -ESRCH; /* domain not found */
+
+                               ssidref = ((struct acm_ssid_domain 
*)(subj->ssid))->ssidref;
+                               put_domain(subj);
+                       } else
+                               return -ESRCH;
+
+            ret = acm_get_ssid(ssidref,
+                               op->u.getssid.ssidbuf,
+                               op->u.getssid.ssidbuf_size);
+            if (ret == ACM_OK)
+                ret = 0;
+            else
+                ret = -ESRCH;
+        }
+        break;
+
     default:
         ret = -ESRCH;
 
diff -r edd1616cf8cb -r 291e816acbf4 xen/common/domain.c
--- a/xen/common/domain.c       Fri Sep  2 14:15:49 2005
+++ b/xen/common/domain.c       Fri Sep  2 14:17:08 2005
@@ -178,6 +178,9 @@
     struct domain *d = current->domain;
     struct vcpu *v;
 
+    if(reason == SHUTDOWN_crash) 
+        printk("Domain %d crash detected.\n", d->domain_id); 
+
     if ( d->domain_id == 0 )
     {
         extern void machine_restart(char *);
diff -r edd1616cf8cb -r 291e816acbf4 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Fri Sep  2 14:15:49 2005
+++ b/xen/common/grant_table.c  Fri Sep  2 14:17:08 2005
@@ -887,21 +887,21 @@
                    e->tot_pages, e->max_pages);
             spin_unlock(&e->page_alloc_lock);
             put_domain(e);
-            result = GNTST_general_error;
+            gop->status = result = GNTST_general_error;
             break;
         }
         if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags))) {
             printk("gnttab_donate: target domain is dying\n");
             spin_unlock(&e->page_alloc_lock);
             put_domain(e);
-            result = GNTST_general_error;
+            gop->status = result = GNTST_general_error;
             break;
         }
         if (unlikely(!gnttab_prepare_for_transfer(e, d, gop->handle))) {
-            printk("gnttab_donate: gnttab_prepare_for_transfer fails\n");
+            printk("gnttab_donate: gnttab_prepare_for_transfer fails.\n");
             spin_unlock(&e->page_alloc_lock);
             put_domain(e);
-            result = GNTST_general_error;
+            gop->status = result = GNTST_general_error;
             break;
         }
 #else
@@ -914,7 +914,8 @@
                    e->tot_pages, e->max_pages, gop->handle, e->d_flags);
             spin_unlock(&e->page_alloc_lock);
             put_domain(e);
-            result = GNTST_general_error;
+            /* XXX SMH: better error return here would be useful */
+            gop->status = result = GNTST_general_error;
             break;
         }
 #endif
@@ -1020,7 +1021,7 @@
     lgt = ld->grant_table;
     
 #if GRANT_DEBUG_VERBOSE
-    if ( ld->domain_ id != 0 ) {
+    if ( ld->domain_id != 0 ) {
             DPRINTK("Foreign unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n",
                     rd->domain_id, ld->domain_id, frame, readonly);
       }
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/acm/acm_core.h
--- a/xen/include/acm/acm_core.h        Fri Sep  2 14:15:49 2005
+++ b/xen/include/acm/acm_core.h        Fri Sep  2 14:17:08 2005
@@ -101,9 +101,15 @@
  *     primary ssidref   = lower 16 bit
  *      secondary ssidref = higher 16 bit
  */
+#define ACM_PRIMARY(ssidref) \
+       ((ssidref) & 0xffff)
+
+#define ACM_SECONDARY(ssidref) \
+       ((ssidref) >> 16)
+
 #define GET_SSIDREF(POLICY, ssidref) \
        ((POLICY) == acm_bin_pol.primary_policy_code) ? \
-       ((ssidref) & 0xffff) : ((ssidref) >> 16)
+       ACM_PRIMARY(ssidref) : ACM_SECONDARY(ssidref)
 
 /* macros to access ssid pointer for primary / secondary policy */
 #define GET_SSIDP(POLICY, ssid) \
@@ -116,6 +122,7 @@
 int acm_set_policy(void *buf, u16 buf_size, int isuserbuffer);
 int acm_get_policy(void *buf, u16 buf_size);
 int acm_dump_statistics(void *buf, u16 buf_size);
+int acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size);
 
 #endif
 
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/acm/acm_hooks.h
--- a/xen/include/acm/acm_hooks.h       Fri Sep  2 14:15:49 2005
+++ b/xen/include/acm/acm_hooks.h       Fri Sep  2 14:17:08 2005
@@ -92,6 +92,7 @@
     int  (*dump_binary_policy)         (u8 *buffer, u16 buf_size);
     int  (*set_binary_policy)          (u8 *buffer, u16 buf_size);
     int  (*dump_statistics)            (u8 *buffer, u16 buf_size);
+    int  (*dump_ssid_types)            (ssidref_t ssidref, u8 *buffer, u16 
buf_size);
     /* domain management control hooks (can be NULL) */
     int  (*pre_domain_create)          (void *subject_ssid, ssidref_t ssidref);
     void (*post_domain_create)         (domid_t domid, ssidref_t ssidref);
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/page-guest32.h
--- a/xen/include/asm-x86/page-guest32.h        Fri Sep  2 14:15:49 2005
+++ b/xen/include/asm-x86/page-guest32.h        Fri Sep  2 14:17:08 2005
@@ -32,6 +32,11 @@
 /* Get pte access flags (unsigned int). */
 #define l1e_get_flags_32(x)           (get_pte_flags_32((x).l1))
 #define l2e_get_flags_32(x)           (get_pte_flags_32((x).l2))
+
+#define l1e_get_paddr_32(x)           \
+    ((physaddr_t)(((x).l1 & (PADDR_MASK&PAGE_MASK))))
+#define l2e_get_paddr_32(x)           \
+    ((physaddr_t)(((x).l2 & (PADDR_MASK&PAGE_MASK))))
 
 /* Construct an empty pte. */
 #define l1e_empty_32()                ((l1_pgentry_32_t) { 0 })
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Fri Sep  2 14:15:49 2005
+++ b/xen/include/asm-x86/processor.h   Fri Sep  2 14:17:08 2005
@@ -496,9 +496,7 @@
 
 #endif
 
-void show_guest_stack();
-void show_trace(unsigned long *esp);
-void show_stack(unsigned long *esp);
+void show_stack(struct cpu_user_regs *regs);
 void show_registers(struct cpu_user_regs *regs);
 void show_page_walk(unsigned long addr);
 asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      Fri Sep  2 14:15:49 2005
+++ b/xen/include/asm-x86/shadow.h      Fri Sep  2 14:17:08 2005
@@ -34,6 +34,8 @@
 #include <asm/vmx.h>
 #include <public/dom0_ops.h>
 #include <asm/shadow_public.h>
+#include <asm/page-guest32.h>
+#include <asm/shadow_ops.h>
 
 /* Shadow PT operation mode : shadow-mode variable in arch_domain. */
 
@@ -104,9 +106,9 @@
 } while (0)
 #endif
 
-#define SHADOW_ENCODE_MIN_MAX(_min, _max) ((((L1_PAGETABLE_ENTRIES - 1) - 
(_max)) << 16) | (_min))
+#define SHADOW_ENCODE_MIN_MAX(_min, _max) ((((GUEST_L1_PAGETABLE_ENTRIES - 1) 
- (_max)) << 16) | (_min))
 #define SHADOW_MIN(_encoded) ((_encoded) & ((1u<<16) - 1))
-#define SHADOW_MAX(_encoded) ((L1_PAGETABLE_ENTRIES - 1) - ((_encoded) >> 16))
+#define SHADOW_MAX(_encoded) ((GUEST_L1_PAGETABLE_ENTRIES - 1) - ((_encoded) 
>> 16))
 
 extern void shadow_mode_init(void);
 extern int shadow_mode_control(struct domain *p, dom0_shadow_control_t *sc);
@@ -132,6 +134,7 @@
                                        struct domain_mmap_cache *cache);
 #if CONFIG_PAGING_LEVELS >= 3
 #include <asm/page-guest32.h>
+extern unsigned long gva_to_gpa(unsigned long gva);
 extern void shadow_l3_normal_pt_update(struct domain *d,
                                        unsigned long pa, l3_pgentry_t l3e,
                                        struct domain_mmap_cache *cache);
@@ -794,22 +797,22 @@
 #endif
 
 static inline void l1pte_propagate_from_guest(
-    struct domain *d, l1_pgentry_t gpte, l1_pgentry_t *spte_p)
+    struct domain *d, guest_l1_pgentry_t gpte, l1_pgentry_t *spte_p)
 { 
     unsigned long mfn;
     l1_pgentry_t spte;
 
     spte = l1e_empty();
 
-    if ( ((l1e_get_flags(gpte) & (_PAGE_PRESENT|_PAGE_ACCESSED) ) ==
+    if ( ((guest_l1e_get_flags(gpte) & (_PAGE_PRESENT|_PAGE_ACCESSED) ) ==
           (_PAGE_PRESENT|_PAGE_ACCESSED)) &&
          VALID_MFN(mfn = __gpfn_to_mfn(d, l1e_get_pfn(gpte))) )
     {
         spte = l1e_from_pfn(
-            mfn, l1e_get_flags(gpte) & ~(_PAGE_GLOBAL | _PAGE_AVAIL));
+            mfn, guest_l1e_get_flags(gpte) & ~(_PAGE_GLOBAL | _PAGE_AVAIL));
 
         if ( shadow_mode_log_dirty(d) ||
-             !(l1e_get_flags(gpte) & _PAGE_DIRTY) ||
+             !(guest_l1e_get_flags(gpte) & _PAGE_DIRTY) ||
              mfn_is_page_table(mfn) )
         {
             l1e_remove_flags(spte, _PAGE_RW);
@@ -859,22 +862,22 @@
 
 static inline void l2pde_general(
     struct domain *d,
-    l2_pgentry_t *gpde_p,
+    guest_l2_pgentry_t *gpde_p,
     l2_pgentry_t *spde_p,
     unsigned long sl1mfn)
 {
-    l2_pgentry_t gpde = *gpde_p;
+    guest_l2_pgentry_t gpde = *gpde_p;
     l2_pgentry_t spde;
 
     spde = l2e_empty();
-    if ( (l2e_get_flags(gpde) & _PAGE_PRESENT) && (sl1mfn != 0) )
+    if ( (guest_l2e_get_flags(gpde) & _PAGE_PRESENT) && (sl1mfn != 0) )
     {
         spde = l2e_from_pfn(
-            sl1mfn, 
-            (l2e_get_flags(gpde) | _PAGE_RW | _PAGE_ACCESSED) & ~_PAGE_AVAIL);
+            sl1mfn,
+            (guest_l2e_get_flags(gpde) | _PAGE_RW | _PAGE_ACCESSED) & 
~_PAGE_AVAIL);
 
         /* N.B. PDEs do not have a dirty bit. */
-        l2e_add_flags(gpde, _PAGE_ACCESSED);
+        guest_l2e_add_flags(gpde, _PAGE_ACCESSED);
 
         *gpde_p = gpde;
     }
@@ -887,12 +890,12 @@
 }
 
 static inline void l2pde_propagate_from_guest(
-    struct domain *d, l2_pgentry_t *gpde_p, l2_pgentry_t *spde_p)
-{
-    l2_pgentry_t gpde = *gpde_p;
+    struct domain *d, guest_l2_pgentry_t *gpde_p, l2_pgentry_t *spde_p)
+{
+    guest_l2_pgentry_t gpde = *gpde_p;
     unsigned long sl1mfn = 0;
 
-    if ( l2e_get_flags(gpde) & _PAGE_PRESENT )
+    if ( guest_l2e_get_flags(gpde) & _PAGE_PRESENT )
         sl1mfn =  __shadow_status(d, l2e_get_pfn(gpde), PGT_l1_shadow);
     l2pde_general(d, gpde_p, spde_p, sl1mfn);
 }
@@ -904,7 +907,7 @@
 static int inline
 validate_pte_change(
     struct domain *d,
-    l1_pgentry_t new_pte,
+    guest_l1_pgentry_t new_pte,
     l1_pgentry_t *shadow_pte_p)
 {
     l1_pgentry_t old_spte, new_spte;
@@ -1004,7 +1007,7 @@
 static int inline
 validate_pde_change(
     struct domain *d,
-    l2_pgentry_t new_gpde,
+    guest_l2_pgentry_t new_gpde,
     l2_pgentry_t *shadow_pde_p)
 {
     l2_pgentry_t old_spde, new_spde;
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/shadow_64.h
--- a/xen/include/asm-x86/shadow_64.h   Fri Sep  2 14:15:49 2005
+++ b/xen/include/asm-x86/shadow_64.h   Fri Sep  2 14:17:08 2005
@@ -27,6 +27,7 @@
 #ifndef _XEN_SHADOW_64_H
 #define _XEN_SHADOW_64_H
 #include <asm/shadow.h>
+#include <asm/shadow_ops.h>
 
 #define READ_FAULT  0
 #define WRITE_FAULT 1
@@ -42,14 +43,14 @@
 #define ESH_LOG(_f, _a...) ((void)0)
 #endif
 
-#define L4      4UL
-#define L3      3UL
-#define L2      2UL
-#define L1      1UL
+#define PAGING_L4      4UL
+#define PAGING_L3      3UL
+#define PAGING_L2      2UL
+#define PAGING_L1      1UL
 #define L_MASK  0xff
 
-#define ROOT_LEVEL_64   L4
-#define ROOT_LEVEL_32   L2
+#define ROOT_LEVEL_64   PAGING_L4
+#define ROOT_LEVEL_32   PAGING_L2
 
 #define SHADOW_ENTRY    (2UL << 16)
 #define GUEST_ENTRY     (1UL << 16)
@@ -58,6 +59,10 @@
 #define SET_ENTRY   (1UL << 8)
 
 #define PAGETABLE_ENTRIES    (1<<PAGETABLE_ORDER)
+
+/* For 32-bit VMX guest to allocate shadow L1 & L2*/
+#define SL1_ORDER   1
+#define SL2_ORDER   2
 
 typedef struct { intpte_t lo; } pgentry_64_t;
 #define shadow_level_to_type(l)    (l << 29)
@@ -76,6 +81,10 @@
 #define entry_remove_flags(x, flags) ((x).lo &= ~put_pte_flags(flags))
 #define entry_has_changed(x,y,flags) \
         ( !!(((x).lo ^ (y).lo) & 
((PADDR_MASK&PAGE_MASK)|put_pte_flags(flags))) )
+
+#define PAE_SHADOW_SELF_ENTRY   259
+#define PDP_ENTRIES   4
+
 static inline int  table_offset_64(unsigned long va, int level)
 {
     switch(level) {
@@ -86,8 +95,13 @@
         case 3:
             return  (((va) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 
1));
 #if CONFIG_PAGING_LEVELS >= 4
+#ifndef GUEST_PGENTRY_32
         case 4:
             return  (((va) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 
1));
+#else
+        case 4:
+            return PAE_SHADOW_SELF_ENTRY; 
+#endif
 #endif
         default:
             //printk("<table_offset_64> level %d is too big\n", level);
@@ -165,30 +179,30 @@
     return le_e;
 }
 #define __shadow_set_l4e(v, va, value) \
-  __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | L4)
+  __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | PAGING_L4)
 #define __shadow_get_l4e(v, va, sl4e) \
-  __rw_entry(v, va, sl4e, SHADOW_ENTRY | GET_ENTRY | L4)
+  __rw_entry(v, va, sl4e, SHADOW_ENTRY | GET_ENTRY | PAGING_L4)
 #define __shadow_set_l3e(v, va, value) \
-  __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | L3)
+  __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | PAGING_L3)
 #define __shadow_get_l3e(v, va, sl3e) \
-  __rw_entry(v, va, sl3e, SHADOW_ENTRY | GET_ENTRY | L3)
+  __rw_entry(v, va, sl3e, SHADOW_ENTRY | GET_ENTRY | PAGING_L3)
 #define __shadow_set_l2e(v, va, value) \
-  __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | L2)
+  __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | PAGING_L2)
 #define __shadow_get_l2e(v, va, sl2e) \
-  __rw_entry(v, va, sl2e, SHADOW_ENTRY | GET_ENTRY | L2)
+  __rw_entry(v, va, sl2e, SHADOW_ENTRY | GET_ENTRY | PAGING_L2)
 #define __shadow_set_l1e(v, va, value) \
-  __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | L1)
+  __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | PAGING_L1)
 #define __shadow_get_l1e(v, va, sl1e) \
-  __rw_entry(v, va, sl1e, SHADOW_ENTRY | GET_ENTRY | L1)
+  __rw_entry(v, va, sl1e, SHADOW_ENTRY | GET_ENTRY | PAGING_L1)
 
 #define __guest_set_l4e(v, va, value) \
-  __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | L4)
+  __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | PAGING_L4)
 #define __guest_get_l4e(v, va, gl4e) \
-  __rw_entry(v, va, gl4e, GUEST_ENTRY | GET_ENTRY | L4)
+  __rw_entry(v, va, gl4e, GUEST_ENTRY | GET_ENTRY | PAGING_L4)
 #define __guest_set_l3e(v, va, value) \
-  __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | L3)
+  __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | PAGING_L3)
 #define __guest_get_l3e(v, va, sl3e) \
-  __rw_entry(v, va, gl3e, GUEST_ENTRY | GET_ENTRY | L3)
+  __rw_entry(v, va, gl3e, GUEST_ENTRY | GET_ENTRY | PAGING_L3)
 
 static inline void *  __guest_set_l2e(
     struct vcpu *v, u64 va, void *value, int size)
@@ -205,7 +219,7 @@
                 return &l2va[l2_table_offset_32(va)];
             }
         case 8:
-            return __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | L2);
+            return __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | 
PAGING_L2);
         default:
             BUG();
             return NULL;
@@ -230,7 +244,7 @@
                 return &l2va[l2_table_offset_32(va)];
             }
         case 8:
-            return __rw_entry(v, va, gl2e, GUEST_ENTRY | GET_ENTRY | L2);
+            return __rw_entry(v, va, gl2e, GUEST_ENTRY | GET_ENTRY | 
PAGING_L2);
         default:
             BUG();
             return NULL;
@@ -269,7 +283,7 @@
             }
 
         case 8:
-            return __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | L1);
+            return __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | 
PAGING_L1);
         default:
             BUG();
             return NULL;
@@ -310,7 +324,7 @@
             }
         case 8:
             // 64-bit guest
-            return __rw_entry(v, va, gl1e, GUEST_ENTRY | GET_ENTRY | L1);
+            return __rw_entry(v, va, gl1e, GUEST_ENTRY | GET_ENTRY | 
PAGING_L1);
         default:
             BUG();
             return NULL;
@@ -334,7 +348,7 @@
     sle = entry_empty();
     if ( (entry_get_flags(gle) & _PAGE_PRESENT) && (smfn != 0) )
     {
-        if ((entry_get_flags(gle) & _PAGE_PSE) && level == L2) {
+        if ((entry_get_flags(gle) & _PAGE_PSE) && level == PAGING_L2) {
             sle = entry_from_pfn(smfn, entry_get_flags(gle));
             entry_remove_flags(sle, _PAGE_PSE);
 
@@ -376,7 +390,7 @@
     unsigned long smfn = 0;
 
     if ( entry_get_flags(gle) & _PAGE_PRESENT ) {
-        if ((entry_get_flags(gle) & _PAGE_PSE) && level == L2) {
+        if ((entry_get_flags(gle) & _PAGE_PSE) && level == PAGING_L2) {
             smfn =  __shadow_status(d, entry_get_value(gle) >> PAGE_SHIFT, 
PGT_fl1_shadow);
         } else {
             smfn =  __shadow_status(d, entry_get_pfn(gle), 
@@ -421,88 +435,6 @@
     return 1;
 }
 
-/*
- * Check P, R/W, U/S bits in the guest page table.
- * If the fault belongs to guest return 1,
- * else return 0.
- */
-static inline int guest_page_fault(struct vcpu *v,
-  unsigned long va, unsigned int error_code, pgentry_64_t *gpl2e, pgentry_64_t 
*gpl1e)
-{
-    struct domain *d = v->domain;
-    pgentry_64_t gle, *lva;
-    unsigned long mfn;
-    int i;
-
-    __rw_entry(v, va, &gle, GUEST_ENTRY | GET_ENTRY | L4);
-    if (unlikely(!(entry_get_flags(gle) & _PAGE_PRESENT)))
-        return 1;
-
-    if (error_code & ERROR_W) {
-        if (unlikely(!(entry_get_flags(gle) & _PAGE_RW)))
-            return 1;
-    }
-    if (error_code & ERROR_U) {
-        if (unlikely(!(entry_get_flags(gle) & _PAGE_USER)))
-            return 1;
-    }
-    for (i = L3; i >= L1; i--) {
-       /*
-        * If it's not external mode, then mfn should be machine physical.
-        */
-       mfn = __gpfn_to_mfn(d, (entry_get_paddr(gle) >> PAGE_SHIFT));
-        if (mfn == -1)
-            return 1;
-
-        lva = (pgentry_64_t *) phys_to_virt(
-           mfn << PAGE_SHIFT);
-        gle = lva[table_offset_64(va, i)];
-
-        if (unlikely(!(entry_get_flags(gle) & _PAGE_PRESENT)))
-            return 1;
-
-        if (error_code & ERROR_W) {
-            if (unlikely(!(entry_get_flags(gle) & _PAGE_RW)))
-                return 1;
-        }
-        if (error_code & ERROR_U) {
-            if (unlikely(!(entry_get_flags(gle) & _PAGE_USER)))
-                return 1;
-        }
-
-        if (i == L2) {
-            if (gpl2e)
-                *gpl2e = gle;
-
-            if (likely(entry_get_flags(gle) & _PAGE_PSE))
-                return 0;
-
-        }
-
-        if (i == L1)
-            if (gpl1e)
-                *gpl1e = gle;
-    }
-    return 0;
-}
-
-static inline unsigned long gva_to_gpa(unsigned long gva)
-{
-    struct vcpu *v = current;
-    pgentry_64_t gl1e = {0};
-    pgentry_64_t gl2e = {0};
-    unsigned long gpa;
-
-    if (guest_page_fault(v, gva, 0, &gl2e, &gl1e))
-        return 0;
-    if (entry_get_flags(gl2e) & _PAGE_PSE)
-        gpa = entry_get_paddr(gl2e) + (gva & ((1 << L2_PAGETABLE_SHIFT) - 1));
-    else
-        gpa = entry_get_paddr(gl1e) + (gva & ~PAGE_MASK);
-
-    return gpa;
-
-}
 #endif
 
 
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/shadow_public.h
--- a/xen/include/asm-x86/shadow_public.h       Fri Sep  2 14:15:49 2005
+++ b/xen/include/asm-x86/shadow_public.h       Fri Sep  2 14:17:08 2005
@@ -49,6 +49,7 @@
          (*mark_mfn_out_of_sync)(struct vcpu *v, unsigned long gpfn,
                               unsigned long mfn);
     int  (*is_out_of_sync)(struct vcpu *v, unsigned long va);
+    unsigned long (*gva_to_gpa)(unsigned long gva);
 };
 #endif
 
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/x86_32/asm_defns.h
--- a/xen/include/asm-x86/x86_32/asm_defns.h    Fri Sep  2 14:15:49 2005
+++ b/xen/include/asm-x86/x86_32/asm_defns.h    Fri Sep  2 14:17:08 2005
@@ -1,10 +1,20 @@
 #ifndef __X86_32_ASM_DEFNS_H__
 #define __X86_32_ASM_DEFNS_H__
+
+#ifndef NDEBUG
+/* Indicate special exception stack frame by inverting the frame pointer. */
+#define SETUP_EXCEPTION_FRAME_POINTER           \
+        movl  %esp,%ebp;                        \
+        notl  %ebp
+#else
+#define SETUP_EXCEPTION_FRAME_POINTER
+#endif
 
 #define __SAVE_ALL_PRE                                  \
         cld;                                            \
         pushl %eax;                                     \
         pushl %ebp;                                     \
+        SETUP_EXCEPTION_FRAME_POINTER;                  \
         pushl %edi;                                     \
         pushl %esi;                                     \
         pushl %edx;                                     \
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/x86_64/asm_defns.h
--- a/xen/include/asm-x86/x86_64/asm_defns.h    Fri Sep  2 14:15:49 2005
+++ b/xen/include/asm-x86/x86_64/asm_defns.h    Fri Sep  2 14:17:08 2005
@@ -1,5 +1,14 @@
 #ifndef __X86_64_ASM_DEFNS_H__
 #define __X86_64_ASM_DEFNS_H__
+
+#ifndef NDEBUG
+/* Indicate special exception stack frame by inverting the frame pointer. */
+#define SETUP_EXCEPTION_FRAME_POINTER           \
+        movq  %rsp,%rbp;                        \
+        notq  %rbp
+#else
+#define SETUP_EXCEPTION_FRAME_POINTER
+#endif
 
 #define SAVE_ALL                                \
         cld;                                    \
@@ -14,6 +23,7 @@
         pushq %r11;                             \
         pushq %rbx;                             \
         pushq %rbp;                             \
+        SETUP_EXCEPTION_FRAME_POINTER;          \
         pushq %r12;                             \
         pushq %r13;                             \
         pushq %r14;                             \
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/public/acm.h
--- a/xen/include/public/acm.h  Fri Sep  2 14:15:49 2005
+++ b/xen/include/public/acm.h  Fri Sep  2 14:17:08 2005
@@ -56,20 +56,22 @@
 #define ACM_ACCESS_DENIED              -111
 #define ACM_NULL_POINTER_ERROR         -200
 
-#define ACM_MAX_POLICY  3
-
+/* primary policy in lower 4 bits */
 #define ACM_NULL_POLICY        0
 #define ACM_CHINESE_WALL_POLICY        1
 #define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2
-#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY 3
+
+/* combinations have secondary policy component in higher 4bit */
+#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY \
+    ((ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY << 4) | ACM_CHINESE_WALL_POLICY)
 
 /* policy: */
 #define ACM_POLICY_NAME(X) \
-       (X == ACM_NULL_POLICY) ? "NULL policy" : \
-       (X == ACM_CHINESE_WALL_POLICY) ? "CHINESE WALL policy" : \
-       (X == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "SIMPLE TYPE ENFORCEMENT 
policy" : \
-       (X == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "CHINESE 
WALL AND SIMPLE TYPE ENFORCEMENT policy" : \
-       "UNDEFINED policy"
+       ((X) == (ACM_NULL_POLICY)) ? "NULL policy" :                        \
+    ((X) == (ACM_CHINESE_WALL_POLICY)) ? "CHINESE WALL policy" :        \
+    ((X) == (ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "SIMPLE TYPE ENFORCEMENT 
policy" : \
+    ((X) == (ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "CHINESE 
WALL AND SIMPLE TYPE ENFORCEMENT policy" : \
+     "UNDEFINED policy"
 
 /* the following policy versions must be increased
  * whenever the interpretation of the related
@@ -122,7 +124,7 @@
  */
 struct acm_policy_buffer {
        u32 policy_version; /* ACM_POLICY_VERSION */
-        u32 magic;
+    u32 magic;
        u32 len;
        u32 primary_policy_code;
        u32 primary_buffer_offset;
@@ -151,7 +153,7 @@
 };
 
 struct acm_stats_buffer {
-        u32 magic;
+    u32 magic;
        u32 len;
        u32 primary_policy_code;
        u32 primary_stats_offset;
@@ -168,5 +170,15 @@
        u32 gt_cachehit_count;
 };
 
+struct acm_ssid_buffer {
+       u32 len;
+    ssidref_t ssidref;
+       u32 primary_policy_code;
+       u32 primary_max_types;
+    u32 primary_types_offset;
+       u32 secondary_policy_code;
+    u32 secondary_max_types;
+       u32 secondary_types_offset;
+};
 
 #endif
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/public/acm_ops.h
--- a/xen/include/public/acm_ops.h      Fri Sep  2 14:15:49 2005
+++ b/xen/include/public/acm_ops.h      Fri Sep  2 14:17:08 2005
@@ -1,3 +1,4 @@
+
 /******************************************************************************
  * acm_ops.h
  *
@@ -27,7 +28,7 @@
  * This makes sure that old versions of acm tools will stop working in a
  * well-defined way (rather than crashing the machine, for instance).
  */
-#define ACM_INTERFACE_VERSION   0xAAAA0003
+#define ACM_INTERFACE_VERSION   0xAAAA0004
 
 /************************************************************************/
 
@@ -46,12 +47,25 @@
     u16 pullcache_size;
 } acm_getpolicy_t;
 
+
 #define ACM_DUMPSTATS          6
 typedef struct acm_dumpstats {
     void *pullcache;
     u16 pullcache_size;
 } acm_dumpstats_t;
 
+
+#define ACM_GETSSID            7
+enum get_type {UNSET, SSIDREF, DOMAINID};
+typedef struct acm_getssid {
+       enum get_type get_ssid_by;
+       union {
+               domaintype_t domainid;
+               ssidref_t    ssidref;
+       } id;
+    void *ssidbuf;
+    u16 ssidbuf_size;
+} acm_getssid_t;
 
 typedef struct acm_op {
     u32 cmd;
@@ -60,6 +74,7 @@
         acm_setpolicy_t setpolicy;
         acm_getpolicy_t getpolicy;
         acm_dumpstats_t dumpstats;
+        acm_getssid_t getssid;
     } u;
 } acm_op_t;
 
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h     Fri Sep  2 14:15:49 2005
+++ b/xen/include/public/io/netif.h     Fri Sep  2 14:17:08 2005
@@ -23,13 +23,13 @@
 
 typedef struct {
     u16       id;    /* Echoed in response message.        */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     grant_ref_t gref;  /* 2: Reference to incoming granted frame */
 #endif
 } netif_rx_request_t;
 
 typedef struct {
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
     u32      addr;   /*  0: Offset in page of start of received packet  */
 #else
     unsigned long addr; /* Machine address of packet.              */
diff -r edd1616cf8cb -r 291e816acbf4 extras/mini-os/domain_config
--- /dev/null   Fri Sep  2 14:15:49 2005
+++ b/extras/mini-os/domain_config      Fri Sep  2 14:17:08 2005
@@ -0,0 +1,17 @@
+#  -*- mode: python; -*-
+#============================================================================
+# Python configuration setup for 'xm create'.
+# This script sets the parameters used when a domain is created using 'xm 
create'.
+# You use a separate script for each domain you want to create, or 
+# you can set the parameters for the domain on the xm command line.
+#============================================================================
+
+#----------------------------------------------------------------------------
+# Kernel image file.
+kernel = "mini-os.elf"
+
+# Initial memory allocation (in megabytes) for the new domain.
+memory = 32
+
+# A name for your domain. All domains must have different names.
+name = "Mini-OS"
diff -r edd1616cf8cb -r 291e816acbf4 extras/mini-os/include/list.h
--- /dev/null   Fri Sep  2 14:15:49 2005
+++ b/extras/mini-os/include/list.h     Fri Sep  2 14:17:08 2005
@@ -0,0 +1,184 @@
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+       struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+       struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD(ptr) do { \
+       (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+/*
+ * Insert a new entry between two known consecutive entries. 
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static __inline__ void __list_add(struct list_head * new,
+       struct list_head * prev,
+       struct list_head * next)
+{
+       next->prev = new;
+       new->next = next;
+       new->prev = prev;
+       prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static __inline__ void list_add(struct list_head *new, struct list_head *head)
+{
+       __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static __inline__ void list_add_tail(struct list_head *new, struct list_head 
*head)
+{
+       __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static __inline__ void __list_del(struct list_head * prev,
+                                 struct list_head * next)
+{
+       next->prev = prev;
+       prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is in 
an undefined state.
+ */
+static __inline__ void list_del(struct list_head *entry)
+{
+       __list_del(entry->prev, entry->next);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static __inline__ void list_del_init(struct list_head *entry)
+{
+       __list_del(entry->prev, entry->next);
+       INIT_LIST_HEAD(entry); 
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static __inline__ int list_empty(struct list_head *head)
+{
+       return head->next == head;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static __inline__ void list_splice(struct list_head *list, struct list_head 
*head)
+{
+       struct list_head *first = list->next;
+
+       if (first != list) {
+               struct list_head *last = list->prev;
+               struct list_head *at = head->next;
+
+               first->prev = head;
+               head->next = first;
+
+               last->next = at;
+               at->prev = last;
+       }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:       the &struct list_head pointer.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+       ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+/**
+ * list_for_each       -       iterate over a list
+ * @pos:       the &struct list_head to use as a loop counter.
+ * @head:      the head for your list.
+ */
+#define list_for_each(pos, head) \
+       for (pos = (head)->next; pos != (head); pos = pos->next)
+               
+/**
+ * list_for_each_safe  -       iterate over a list safe against removal of 
list entry
+ * @pos:       the &struct list_head to use as a loop counter.
+ * @n:         another &struct list_head to use as temporary storage
+ * @head:      the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+       for (pos = (head)->next, n = pos->next; pos != (head); \
+               pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry -       iterate over list of given type
+ * @pos:       the type * to use as a loop counter.
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)                         \
+       for (pos = list_entry((head)->next, typeof(*pos), member);      \
+            &pos->member != (head);                                    \
+            pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against 
removal of list entry
+ * @pos:       the type * to use as a loop counter.
+ * @n:         another type * to use as temporary storage
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)                 \
+       for (pos = list_entry((head)->next, typeof(*pos), member),      \
+               n = list_entry(pos->member.next, typeof(*pos), member); \
+            &pos->member != (head);                                    \
+            pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#endif /* _LINUX_LIST_H */
+
diff -r edd1616cf8cb -r 291e816acbf4 tools/security/getlabel.sh
--- /dev/null   Fri Sep  2 14:15:49 2005
+++ b/tools/security/getlabel.sh        Fri Sep  2 14:17:08 2005
@@ -0,0 +1,130 @@
+#!/bin/sh
+# *
+# * getlabel
+# *
+# * Copyright (C) 2005 IBM Corporation
+# *
+# * Authors:
+# * Stefan Berger <stefanb@xxxxxxxxxx>
+# *
+# * This program is free software; you can redistribute it and/or
+# * modify it under the terms of the GNU General Public License as
+# * published by the Free Software Foundation, version 2 of the
+# * License.
+# *
+# * 'getlabel' tries to find the labels corresponding to the ssidref
+# *
+# * 'getlabel -?' shows the usage of the program
+# *
+# * 'getlabel -sid <ssidref> [<policy name>]' lists the label corresponding
+# *                              to the given ssidref.
+# *
+# * 'getlabel -dom <domain id> [<policy name>]' lists the label of the
+# *                              domain with given id
+# *
+#
+
+if [ -z "$runbash" ]; then
+       runbash="1"
+       export runbash
+       exec sh -c "bash $0 $*"
+fi
+
+
+export PATH=$PATH:.
+source labelfuncs.sh
+
+usage ()
+{
+       echo "Usage: $0 -sid <ssidref> [<policy name>] or"
+       echo "       $0 -dom <domid>   [<policy name>]  "
+       echo ""
+       echo "policy name : the name of the policy, i.e. 'chwall'"
+       echo "              If the policy name is omitted, the grub.conf"
+       echo "              entry of the running system is tried to be read"
+       echo "              and the policy name determined from there."
+       echo "ssidref     : an ssidref in hex or decimal format, i.e., 
'0x00010002'"
+       echo "              or '65538'"
+       echo "domid       : id of the domain, i.e., '1'; Use numbers from the 
2nd"
+       echo "              column shown when invoking 'xm list'"
+       echo ""
+}
+
+
+
+if [ "$1" == "-?" ]; then
+       mode="usage"
+elif [ "$1" == "-dom" ]; then
+       mode="domid"
+       shift
+elif [ "$1" == "-sid" ]; then
+       mode="sid"
+       shift
+elif [ "$1" == "" ]; then
+       usage
+       exit -1
+fi
+
+
+if [ "$mode" == "usage" ]; then
+       usage
+elif [ "$mode" == "domid" ]; then
+       if [ "$2" == "" ]; then
+               findGrubConf
+               ret=$?
+               if [ $ret -eq 0 ]; then
+                       echo "Could not find grub.conf"
+                       exit -1;
+               fi
+               findPolicyInGrub $grubconf
+               if [ "$policy" != "" ]; then
+                       echo "Assuming policy to be '$policy'.";
+               else
+                       echo "Could not find policy."
+                       exit -1;
+               fi
+       else
+               policy=$2
+       fi
+       findMapFile $policy
+       res=$?
+       if [ "$res" != "0" ]; then
+               getSSIDUsingSecpolTool $1
+               res=$?
+               if [ "$res" != "0" ]; then
+                       translateSSIDREF $ssid $mapfile
+               else
+                       echo "Could not determine the SSID of the domain."
+               fi
+       else
+               echo "Could not find map file for policy '$policy'."
+       fi
+elif [ "$mode" == "sid" ]; then
+       if [ "$2" == "" ]; then
+               findGrubConf
+               ret=$?
+               if [ $ret -eq 0 ]; then
+                       echo "Could not find grub.conf"
+                       exit -1;
+               fi
+               findPolicyInGrub $grubconf
+               if [ "$policy" != "" ]; then
+                       echo "Assuming policy to be '$policy'.";
+               else
+                       echo "Could not find policy."
+                       exit -1;
+               fi
+       else
+               policy=$2
+       fi
+       findMapFile $policy
+       res=$?
+       if [ "$res" != "0" ]; then
+               translateSSIDREF $1 $mapfile
+       else
+               echo "Could not find map file for policy '$policy'."
+       fi
+
+else
+    usage
+fi
diff -r edd1616cf8cb -r 291e816acbf4 tools/security/labelfuncs.sh
--- /dev/null   Fri Sep  2 14:15:49 2005
+++ b/tools/security/labelfuncs.sh      Fri Sep  2 14:17:08 2005
@@ -0,0 +1,675 @@
+# *
+# * labelfuncs.sh
+# *
+# * Copyright (C) 2005 IBM Corporation
+# *
+# * Authors:
+# * Stefan Berger <stefanb@xxxxxxxxxx>
+# *
+# * This program is free software; you can redistribute it and/or
+# * modify it under the terms of the GNU General Public License as
+# * published by the Free Software Foundation, version 2 of the
+# * License.
+# *
+# *
+# * A collection of functions to handle polcies, mapfiles,
+# * and ssidrefs.
+#
+
+
+# Find the mapfile given a policy nmame
+# Parameters:
+# 1st : the name of the policy whose map file is to be found, i.e.,
+#       chwall
+# Results:
+# The variable mapfile will hold the realtive path to the mapfile
+# for the given policy.
+# In case the mapfile could be found, the functions returns a '1',
+# a '0' otherwise.
+findMapFile ()
+{
+       mapfile="./$1.map"
+       if [ -r "$mapfile" ]; then
+               return 1
+       fi
+
+       mapfile="./policies/$1/$1.map"
+       if [ -r "$mapfile" ]; then
+               return 1
+       fi
+
+       return 0
+}
+
+
+# Determine the name of the primary policy
+# Parameters
+# 1st : the path to the mapfile; the path may be relative
+#       to the current directory
+# Results
+# The variable primary will hold the name of the primary policy
+getPrimaryPolicy ()
+{
+       mapfile=$1
+       primary=`cat $mapfile  |   \
+                awk '             \
+                 {                \
+                   if ( $1 == "PRIMARY" ) { \
+                     res=$2;                \
+                   }                        \
+                 } END {                    \
+                   print res;               \
+                 } '`
+}
+
+
+# Determine the name of the secondary policy
+# Parameters
+# 1st : the path to the mapfile; the path may be relative
+#       to the current directory
+# Results
+# The variable secondary will hold the name of the secondary policy
+getSecondaryPolicy ()
+{
+       mapfile=$1
+       secondary=`cat $mapfile  |   \
+                awk '             \
+                 {                \
+                   if ( $1 == "SECONDARY" ) { \
+                     res=$2;                \
+                   }                        \
+                 } END {                    \
+                   print res;               \
+                 } '`
+}
+
+
+#Return where the grub.conf file is.
+#I only know of one place it can be.
+findGrubConf()
+{
+       grubconf="/boot/grub/grub.conf"
+       if [ -w $grubconf ]; then
+               return 1
+       fi
+       if [ -r $grubconf ]; then
+               return 2
+       fi
+       return 0
+}
+
+
+# This function sets the global variable 'linux'
+# to the name and version of the Linux kernel that was compiled
+# for domain 0.
+# If this variable could not be found, the variable 'linux'
+# will hold a pattern
+# Parameters:
+# 1st: the path to reach the root directory of the XEN build tree
+#      where linux-*-xen0 is located at
+# Results:
+# The variable linux holds then name and version of the compiled
+# kernel, i.e., 'vmlinuz-2.6.12-xen0'
+getLinuxVersion ()
+{
+       path=$1
+       linux=""
+       for f in $path/linux-*-xen0 ; do
+               versionfile=$f/include/linux/version.h
+               if [ -r $versionfile ]; then
+                       lnx=`cat $versionfile | \
+                            grep UTS_RELEASE | \
+                            awk '{             \
+                              len=length($3);  \
+                              print substr($3,2,len-2) }'`
+               fi
+               if [ "$lnx" != "" ]; then
+                       linux="[./0-9a-zA-z]*$lnx"
+                       return;
+               fi
+       done
+
+       #Last resort.
+       linux="vmlinuz-2.[45678].[0-9]*[.0-9]*-xen0$"
+}
+
+
+# Find out with which policy the hypervisor was booted with.
+# Parameters
+# 1st : The complete path to grub.conf, i.e., /boot/grub/grub.conf
+#
+findPolicyInGrub ()
+{
+       grubconf=$1
+       linux=`uname -r`
+       policy=`cat $grubconf |                        \
+                awk -vlinux=$linux '{                 \
+                  if ( $1 == "title" ) {              \
+                    kernelfound = 0;                  \
+                    policymaycome = 0;                \
+                  }                                   \
+                  else if ( $1 == "kernel" ) {        \
+                    if ( match($2,"xen.gz$") ) {      \
+                      pathlen=RSTART;                 \
+                      kernelfound = 1;                \
+                    }                                 \
+                  }                                   \
+                  else if ( $1 == "module" &&         \
+                            kernelfound == 1 &&       \
+                            match($2,linux) ) {       \
+                     policymaycome = 1;               \
+                  }                                   \
+                  else if ( $1 == "module" &&         \
+                            kernelfound == 1 &&       \
+                            policymaycome == 1 &&     \
+                            match($2,"[0-9a-zA-Z_]*.bin$") ) { \
+                     policymaycome = 0;               \
+                     kernelfound = 0;                 \
+                     polname = substr($2,pathlen);    \
+                     len=length(polname);             \
+                     polname = substr(polname,0,len-4); \
+                  }                                   \
+                } END {                               \
+                  print polname                       \
+                }'`
+}
+
+
+# Get the SSID of a domain
+# Parameters:
+# 1st : domain ID, i.e. '1'
+# Results
+# If the ssid could be found, the variable 'ssid' will hold
+# the currently used ssid in the hex format, i.e., '0x00010001'.
+# The funtion returns '1' on success, '0' on failure
+getSSIDUsingSecpolTool ()
+{
+       domid=$1
+       export PATH=$PATH:.
+       ssid=`secpol_tool getssid -d $domid -f | \
+               grep -E "SSID:" |          \
+               awk '{ print $4 }'`
+
+       if [ "$ssid" != "" ]; then
+               return 1
+       fi
+       return 0
+}
+
+
+# Break the ssid identifier into its high and low values,
+# which are equal to the secondary and primary policy references.
+# Parameters:
+# 1st: ssid to break into high and low value, i.e., '0x00010002'
+# Results:
+# The variable ssidlo_int and ssidhi_int will hold the low and
+# high ssid values as integers.
+getSSIDLOHI ()
+{
+       ssid=$1
+       ssidlo_int=`echo $ssid | awk          \
+                   '{                        \
+                      len=length($0);        \
+                      beg=substr($0,1,2);    \
+                      if ( beg == "0x" ) {   \
+                          dig = len - 2;     \
+                          if (dig <= 0) {    \
+                            exit;            \
+                          }                  \
+                          if (dig > 4) {     \
+                            dig=4;           \
+                          }                  \
+                          lo=sprintf("0x%s",substr($0,len-dig+1,dig)); \
+                          print strtonum(lo);\
+                      } else {               \
+                          lo=strtonum($0);   \
+                          if (lo < 65536) {  \
+                            print lo;        \
+                          } else {           \
+                            hi=lo;           \
+                            hi2= (hi / 65536);\
+                            hi2_str=sprintf("%d",hi2); \
+                            hi2=strtonum(hi2_str);\
+                            lo=hi-(hi2*65536); \
+                            printf("%d",lo); \
+                          }                  \
+                       }                     \
+                   }'`
+       ssidhi_int=`echo $ssid | awk          \
+                   '{                        \
+                      len=length($0);        \
+                      beg=substr($0,1,2);    \
+                      if ( beg == "0x" ) {   \
+                          dig = len - 2;     \
+                          if (dig <= 0 ||    \
+                            dig >  8) {      \
+                            exit;            \
+                          }                  \
+                          if (dig < 4) {     \
+                            print 0;         \
+                            exit;            \
+                          }                  \
+                          dig -= 4;          \
+                          hi=sprintf("0x%s",substr($0,len-4-dig+1,dig)); \
+                          print strtonum(hi);\
+                      } else {               \
+                          hi=strtonum($0);   \
+                          if (hi >= 65536) { \
+                            hi = hi / 65536; \
+                            printf ("%d",hi);\
+                          } else {           \
+                            printf ("0");    \
+                          }                  \
+                      }                      \
+                   }'`
+       if [ "$ssidhi_int" == "" -o \
+            "$ssidlo_int" == "" ]; then
+               return 0;
+       fi
+       return 1
+}
+
+
+#Update the grub configuration file.
+#Search for existing entries and replace the current
+#policy entry with the policy passed to this script
+#
+#Arguments passed to this function
+# 1st : the grub configuration file with full path
+# 2nd : the binary policy file name, i.e. chwall.bin
+# 3rd : the name or pattern of the linux kernel name to match
+#       (this determines where the module entry will be made)
+#
+# The algorithm here is based on pattern matching
+# and is working correctly if
+# - under a title a line beginning with 'kernel' is found
+#   whose following item ends with "xen.gz"
+#   Example:  kernel /xen.gz dom0_mem=....
+# - a module line matching the 3rd parameter is found
+#
+updateGrub ()
+{
+       grubconf=$1
+       policyfile=$2
+       linux=$3
+
+       tmpfile="/tmp/new_grub.conf"
+
+       cat $grubconf |                                \
+                awk -vpolicy=$policyfile              \
+                    -vlinux=$linux '{                 \
+                  if ( $1 == "title" ) {              \
+                    kernelfound = 0;                  \
+                    if ( policymaycome == 1 ){        \
+                      printf ("\tmodule %s%s\n", path, policy);      \
+                    }                                 \
+                    policymaycome = 0;                \
+                  }                                   \
+                  else if ( $1 == "kernel" ) {        \
+                    if ( match($2,"xen.gz$") ) {      \
+                      path=substr($2,1,RSTART-1);     \
+                      kernelfound = 1;                \
+                    }                                 \
+                  }                                   \
+                  else if ( $1 == "module" &&         \
+                            kernelfound == 1 &&       \
+                            match($2,linux) ) {       \
+                     policymaycome = 1;               \
+                  }                                   \
+                  else if ( $1 == "module" &&         \
+                            kernelfound == 1 &&       \
+                            policymaycome == 1 &&     \
+                            match($2,"[0-9a-zA-Z]*.bin$") ) { \
+                     printf ("\tmodule %s%s\n", path, policy); \
+                     policymaycome = 0;               \
+                     kernelfound = 0;                 \
+                     dontprint = 1;                   \
+                  }                                   \
+                  else if ( $1 == "" &&               \
+                            kernelfound == 1 &&       \
+                            policymaycome == 1) {     \
+                     dontprint = 1;                   \
+                  }                                   \
+                  if (dontprint == 0) {               \
+                    printf ("%s\n", $0);              \
+                  }                                   \
+                  dontprint = 0;                      \
+                } END {                               \
+                  if ( policymaycome == 1 ) {         \
+                    printf ("\tmodule %s%s\n", path, policy);  \
+                  }                                   \
+                }' > $tmpfile
+       if [ ! -r $tmpfile ]; then
+               echo "Could not create temporary file! Aborting."
+               exit -1
+       fi
+       mv -f $tmpfile $grubconf
+}
+
+
+# Display all the labels in a given mapfile
+# Parameters
+# 1st: Full or relative path to the policy's mapfile
+showLabels ()
+{
+       mapfile=$1
+       if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
+               echo "Cannot read from vm configuration file $vmfile."
+               return -1
+       fi
+
+       getPrimaryPolicy $mapfile
+       getSecondaryPolicy $mapfile
+
+       echo "The following labels are available:"
+       let line=1
+       while [ 1 ]; do
+               ITEM=`cat $mapfile |         \
+                     awk -vline=$line       \
+                         -vprimary=$primary \
+                     '{                     \
+                        if ($1 == "LABEL->SSID" &&  \
+                            $2 == "VM" &&           \
+                            $3 == primary ) {       \
+                          ctr++;                    \
+                          if (ctr == line) {        \
+                            print $4;               \
+                          }                         \
+                        }                           \
+                      } END {                       \
+                      }'`
+
+               if [ "$ITEM" == "" ]; then
+                       break
+               fi
+               if [ "$secondary" != "NULL" ]; then
+                       LABEL=`cat $mapfile |     \
+                              awk -vitem=$ITEM   \
+                              '{
+                                 if ($1 == "LABEL->SSID" && \
+                                     $2 == "VM" &&          \
+                                     $3 == "CHWALL" &&      \
+                                     $4 == item ) {         \
+                                   result = item;           \
+                                 }                          \
+                               } END {                      \
+                                   print result             \
+                               }'`
+               else
+                       LABEL=$ITEM
+               fi
+
+               if [ "$LABEL" != "" ]; then
+                       echo "$LABEL"
+                       found=1
+               fi
+               let line=line+1
+       done
+       if [ "$found" != "1" ]; then
+               echo "No labels found."
+       fi
+}
+
+
+# Get the default SSID given a mapfile and the policy name
+# Parameters
+# 1st: Full or relative path to the policy's mapfile
+# 2nd: the name of the policy
+getDefaultSsid ()
+{
+       mapfile=$1
+       pol=$2
+       RES=`cat $mapfile    \
+            awk -vpol=$pol  \
+             {              \
+               if ($1 == "LABEL->SSID" && \
+                   $2 == "ANY"         && \
+                   $3 == pol           && \
+                   $4 == "DEFAULT"       ) {\
+                     res=$5;                \
+               }                            \
+             } END {                        \
+               printf "%04x", strtonum(res) \
+            }'`
+       echo "default NULL mapping is $RES"
+       defaultssid=$RES
+}
+
+
+#Relabel a VM configuration file
+# Parameters
+# 1st: Full or relative path to the VM configuration file
+# 2nd: The label to translate into an ssidref
+# 3rd: Full or relative path to the policy's map file
+# 4th: The mode this function is supposed to operate in:
+#      'relabel' : Relabels the file without querying the user
+#      other     : Prompts the user whether to proceed
+relabel ()
+{
+       vmfile=$1
+       label=$2
+       mapfile=$3
+       mode=$4
+
+       if [ ! -r "$vmfile" ]; then
+               echo "Cannot read from vm configuration file $vmfile."
+               return -1
+       fi
+
+       if [ ! -w "$vmfile" ]; then
+               echo "Cannot write to vm configuration file $vmfile."
+               return -1
+       fi
+
+       if [ ! -r "$mapfile" ] ; then
+               echo "Cannot read mapping file $mapfile."
+               return -1
+       fi
+
+       # Determine which policy is primary, which sec.
+       getPrimaryPolicy $mapfile
+       getSecondaryPolicy $mapfile
+
+       # Calculate the primary policy's SSIDREF
+       if [ "$primary" == "NULL" ]; then
+               SSIDLO="0001"
+       else
+               SSIDLO=`cat $mapfile |                    \
+                       awk -vlabel=$label                \
+                           -vprimary=$primary            \
+                          '{                             \
+                             if ( $1 == "LABEL->SSID" && \
+                                  $2 == "VM" &&          \
+                                  $3 == primary  &&      \
+                                  $4 == label ) {        \
+                               result=$5                 \
+                             }                           \
+                          } END {                        \
+                            if (result != "" )           \
+                              {printf "%04x", strtonum(result)}\
+                          }'`
+       fi
+
+       # Calculate the secondary policy's SSIDREF
+       if [ "$secondary" == "NULL" ]; then
+               if [ "$primary" == "NULL" ]; then
+                       SSIDHI="0001"
+               else
+                       SSIDHI="0000"
+               fi
+       else
+               SSIDHI=`cat $mapfile |                    \
+                       awk -vlabel=$label                \
+                           -vsecondary=$secondary        \
+                          '{                             \
+                             if ( $1 == "LABEL->SSID" && \
+                                  $2 == "VM"          && \
+                                  $3 == secondary     && \
+                                  $4 == label ) {        \
+                               result=$5                 \
+                             }                           \
+                           }  END {                      \
+                             if (result != "" )          \
+                               {printf "%04x", strtonum(result)}\
+                           }'`
+       fi
+
+       if [ "$SSIDLO" == "" -o \
+            "$SSIDHI" == "" ]; then
+               echo "Could not map the given label '$label'."
+               return -1
+       fi
+
+       ACM_POLICY=`cat $mapfile |             \
+           awk ' { if ( $1 == "POLICY" ) {    \
+                     result=$2                \
+                   }                          \
+                 }                            \
+                 END {                        \
+                   if (result != "") {        \
+                     printf result            \
+                   }                          \
+                 }'`
+
+       if [ "$ACM_POLICY" == "" ]; then
+               echo "Could not find 'POLICY' entry in map file."
+               return -1
+       fi
+
+       SSIDREF="0x$SSIDHI$SSIDLO"
+
+       if [ "$mode" != "relabel" ]; then
+               RES=`cat $vmfile |  \
+                    awk '{         \
+                      if ( substr($1,0,7) == "ssidref" ) {\
+                        print $0;             \
+                      }                       \
+                    }'`
+               if [ "$RES" != "" ]; then
+                       echo "Do you want to overwrite the existing mapping 
($RES)? (y/N)"
+                       read user
+                       if [ "$user" != "y" -a "$user" != "Y" ]; then
+                               echo "Aborted."
+                               return 0
+                       fi
+               fi
+       fi
+
+       #Write the output
+       vmtmp1="/tmp/__setlabel.tmp1"
+       vmtmp2="/tmp/__setlabel.tmp2"
+       touch $vmtmp1
+       touch $vmtmp2
+       if [ ! -w "$vmtmp1" -o ! -w "$vmtmp2" ]; then
+               echo "Cannot create temporary files. Aborting."
+               return -1
+       fi
+       RES=`sed -e '/^#ACM_POLICY/d' $vmfile > $vmtmp1`
+       RES=`sed -e '/^#ACM_LABEL/d' $vmtmp1 > $vmtmp2`
+       RES=`sed -e '/^ssidref/d' $vmtmp2 > $vmtmp1`
+       echo "#ACM_POLICY=$ACM_POLICY" >> $vmtmp1
+       echo "#ACM_LABEL=$label" >> $vmtmp1
+       echo "ssidref = $SSIDREF" >> $vmtmp1
+       mv -f $vmtmp1 $vmfile
+       rm -rf $vmtmp1 $vmtmp2
+       echo "Mapped label '$label' to ssidref '$SSIDREF'."
+}
+
+
+# Translate an ssidref into its label. This does the reverse lookup
+# to the relabel function above.
+# This function displays the results.
+# Parameters:
+# 1st: The ssidref to translate; must be in the form '0x00010002'
+# 2nd: Full or relative path to the policy's mapfile
+translateSSIDREF ()
+{
+       ssidref=$1
+       mapfile=$2
+
+       if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
+               echo "Cannot read from vm configuration file $vmfile."
+               return -1
+       fi
+
+       getPrimaryPolicy $mapfile
+       getSecondaryPolicy $mapfile
+
+       if [ "$primary" == "NULL" -a "$secondary" == "NULL" ]; then
+               echo "There are no labels for the NULL policy."
+               return
+       fi
+
+       getSSIDLOHI $ssidref
+       ret=$?
+       if [ $ret -ne 1 ]; then
+               echo "Error while parsing the ssid ref number '$ssidref'."
+       fi;
+
+       let line1=0
+       let line2=0
+       while [ 1 ]; do
+               ITEM1=`cat $mapfile |                       \
+                     awk -vprimary=$primary                \
+                         -vssidlo=$ssidlo_int              \
+                         -vline=$line1                     \
+                     '{                                    \
+                        if ( $1 == "LABEL->SSID" &&        \
+                             $3 == primary &&              \
+                             int($5) == ssidlo     ) {     \
+                            if (l == line) {               \
+                                print $4;                  \
+                                exit;                      \
+                            }                              \
+                            l++;                           \
+                        }                                  \
+                      }'`
+
+               ITEM2=`cat $mapfile |                       \
+                     awk -vsecondary=$secondary            \
+                         -vssidhi=$ssidhi_int              \
+                         -vline=$line2                     \
+                     '{                                    \
+                        if ( $1 == "LABEL->SSID" &&        \
+                             $3 == secondary &&            \
+                             int($5) == ssidhi     ) {     \
+                            if (l == line) {               \
+                                print $4;                  \
+                                exit;                      \
+                            }                              \
+                            l++;                           \
+                        }                                  \
+                      }'`
+
+               if [ "$secondary" != "NULL" ]; then
+                       if [ "$ITEM1" == "" ]; then
+                               let line1=0
+                               let line2=line2+1
+                       else
+                               let line1=line1+1
+                       fi
+
+                       if [ "$ITEM1" == "" -a \
+                            "$ITEM2" == "" ]; then
+                               echo "Could not determine the referenced label."
+                               break
+                       fi
+
+                       if [ "$ITEM1" == "$ITEM2" ]; then
+                               echo "Label: $ITEM1"
+                               break
+                       fi
+               else
+                       if [ "$ITEM1" != "" ]; then
+                               echo "Label: $ITEM1"
+                       else
+                               if [ "$found" == "0" ]; then
+                                       found=1
+                               else
+                                       break
+                               fi
+                       fi
+                       let line1=line1+1
+               fi
+       done
+}
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/shadow_guest32.c
--- /dev/null   Fri Sep  2 14:15:49 2005
+++ b/xen/arch/x86/shadow_guest32.c     Fri Sep  2 14:17:08 2005
@@ -0,0 +1,18 @@
+#define GUEST_PGENTRY_32
+#if defined (__x86_64__)
+
+#include "shadow.c"
+struct shadow_ops MODE_D_HANDLER = {
+    .guest_paging_levels              = 2,
+    .invlpg                     = shadow_invlpg_64,
+    .fault                      = shadow_fault_64,
+    .update_pagetables          = shadow_update_pagetables,
+    .sync_all                   = sync_all,
+    .remove_all_write_access    = remove_all_write_access,
+    .do_update_va_mapping       = do_update_va_mapping,
+    .mark_mfn_out_of_sync       = mark_mfn_out_of_sync,
+    .is_out_of_sync             = is_out_of_sync,
+    .gva_to_gpa                 = gva_to_gpa_64,
+};
+
+#endif
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/shadow_ops.h
--- /dev/null   Fri Sep  2 14:15:49 2005
+++ b/xen/include/asm-x86/shadow_ops.h  Fri Sep  2 14:17:08 2005
@@ -0,0 +1,130 @@
+/******************************************************************************
+ * include/asm-x86/shadow_ops.h
+ * 
+ * Copyright (c) 2005 Michael A Fetterman
+ * Based on an earlier implementation by Ian Pratt et al
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XEN_SHADOW_OPS_H
+#define _XEN_SHADOW_OPS_H
+
+#if defined( GUEST_PGENTRY_32 )
+
+#define GUEST_L1_PAGETABLE_ENTRIES     L1_PAGETABLE_ENTRIES_32
+#define GUEST_L2_PAGETABLE_ENTRIES     L2_PAGETABLE_ENTRIES_32
+#define GUEST_ROOT_PAGETABLE_ENTRIES   ROOT_PAGETABLE_ENTRIES_32
+#define GUEST_L2_PAGETABLE_SHIFT       L2_PAGETABLE_SHIFT_32
+
+#define guest_l1_pgentry_t      l1_pgentry_32_t
+#define guest_l2_pgentry_t      l2_pgentry_32_t
+#define guest_root_pgentry_t    l2_pgentry_32_t
+
+#define guest_l1e_get_paddr     l1e_get_paddr_32
+#define guest_l2e_get_paddr     l2e_get_paddr_32
+
+#define guest_get_pte_flags     get_pte_flags_32
+#define guest_put_pte_flags     put_pte_flags_32
+
+#define guest_l1e_get_flags     l1e_get_flags_32
+#define guest_l2e_get_flags     l2e_get_flags_32
+#define guest_root_get_flags          l2e_get_flags_32
+#define guest_root_get_intpte         l2e_get_intpte
+
+#define guest_l1e_empty         l1e_empty_32
+#define guest_l2e_empty         l2e_empty_32
+
+#define guest_l1e_from_pfn      l1e_from_pfn_32
+#define guest_l2e_from_pfn      l2e_from_pfn_32
+
+#define guest_l1e_from_paddr    l1e_from_paddr_32
+#define guest_l2e_from_paddr    l2e_from_paddr_32
+
+#define guest_l1e_from_page     l1e_from_page_32
+#define guest_l2e_from_page     l2e_from_page_32
+
+#define guest_l1e_add_flags     l1e_add_flags_32
+#define guest_l2e_add_flags     l2e_add_flags_32
+
+#define guest_l1e_remove_flag   l1e_remove_flags_32
+#define guest_l2e_remove_flag   l2e_remove_flags_32
+
+#define guest_l1e_has_changed   l1e_has_changed_32
+#define guest_l2e_has_changed   l2e_has_changed_32
+#define root_entry_has_changed  l2e_has_changed_32
+
+#define guest_l1_table_offset   l1_table_offset_32
+#define guest_l2_table_offset   l2_table_offset_32
+
+#define guest_linear_l1_table   linear_pg_table_32
+#define guest_linear_l2_table   linear_l2_table_32
+
+#define guest_va_to_l1mfn       va_to_l1mfn_32
+
+#else
+
+#define GUEST_L1_PAGETABLE_ENTRIES      L1_PAGETABLE_ENTRIES
+#define GUEST_L2_PAGETABLE_ENTRIES      L2_PAGETABLE_ENTRIES
+#define GUEST_ROOT_PAGETABLE_ENTRIES    ROOT_PAGETABLE_ENTRIES
+#define GUEST_L2_PAGETABLE_SHIFT        L2_PAGETABLE_SHIFT
+
+#define guest_l1_pgentry_t      l1_pgentry_t
+#define guest_l2_pgentry_t      l2_pgentry_t
+#define guest_root_pgentry_t    l4_pgentry_t
+
+#define guest_l1e_get_paddr     l1e_get_paddr
+#define guest_l2e_get_paddr     l2e_get_paddr
+
+#define guest_get_pte_flags     get_pte_flags
+#define guest_put_pte_flags     put_pte_flags
+
+#define guest_l1e_get_flags     l1e_get_flags
+#define guest_l2e_get_flags     l2e_get_flags
+#define guest_root_get_flags    l4e_get_flags
+#define guest_root_get_intpte   l4e_get_intpte
+
+#define guest_l1e_empty         l1e_empty
+#define guest_l2e_empty         l2e_empty
+
+#define guest_l1e_from_pfn      l1e_from_pfn
+#define guest_l2e_from_pfn      l2e_from_pfn
+
+#define guest_l1e_from_paddr    l1e_from_paddr
+#define guest_l2e_from_paddr    l2e_from_paddr
+
+#define guest_l1e_from_page     l1e_from_page
+#define guest_l2e_from_page     l2e_from_page
+
+#define guest_l1e_add_flags     l1e_add_flags
+#define guest_l2e_add_flags     l2e_add_flags
+
+#define guest_l1e_remove_flag   l1e_remove_flags
+#define guest_l2e_remove_flag   l2e_remove_flags
+
+#define guest_l1e_has_changed   l1e_has_changed
+#define guest_l2e_has_changed   l2e_has_changed
+#define root_entry_has_changed  l4e_has_changed
+
+#define guest_l1_table_offset   l1_table_offset
+#define guest_l2_table_offset   l2_table_offset
+
+#define guest_linear_l1_table   linear_pg_table
+#define guest_linear_l2_table   linear_l2_table
+
+#define guest_va_to_l1mfn       va_to_l1mfn
+#endif
+
+#endif /* _XEN_SHADOW_OPS_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®.