WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 23 Feb 2007 09:50:21 -0800
Delivery-date: Fri, 23 Feb 2007 09:50:42 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1171573779 25200
# Node ID 9529d667d0426eb02077cb33abdc6e434e27d293
# Parent  ac18d251df63401e67c63b83d3face99f5a9aeb3
# Parent  9af0c7e4ff513c02f9bd1548f21612e9cf59b022
merge with xen-unstable.hg
---
 tools/libxc/xc_dom_powerpc64.c                              |  100 -
 tools/python/xen/xend/FlatDeviceTree.py                     |  359 ---
 xen/arch/powerpc/elf32.c                                    |    7 
 xen/arch/powerpc/of_handler/strncpy.c                       |   54 
 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c           |    5 
 linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c            |    5 
 linux-2.6-xen-sparse/drivers/xen/core/reboot.c              |    3 
 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c           |    2 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c        |    6 
 tools/libxc/Makefile                                        |    7 
 tools/libxc/powerpc64/Makefile                              |    1 
 tools/libxc/powerpc64/flatdevtree.c                         |    7 
 tools/libxc/powerpc64/flatdevtree.h                         |    2 
 tools/libxc/powerpc64/mk_flatdevtree.c                      |  650 ++++++
 tools/libxc/powerpc64/mk_flatdevtree.h                      |   47 
 tools/libxc/powerpc64/utils.c                               |   25 
 tools/libxc/powerpc64/utils.h                               |    3 
 tools/libxc/powerpc64/xc_linux_build.c                      |  270 +-
 tools/libxc/powerpc64/xc_prose_build.c                      |  124 -
 tools/libxc/xc_dom.h                                        |    5 
 tools/libxc/xenguest.h                                      |    3 
 tools/libxc/xg_private.c                                    |   12 
 tools/python/xen/lowlevel/xc/xc.c                           |   27 
 tools/python/xen/xend/image.py                              |   56 
 unmodified_drivers/linux-2.6/platform-pci/platform-compat.c |    6 
 xen/arch/powerpc/Makefile                                   |    4 
 xen/arch/powerpc/backtrace.c                                |    1 
 xen/arch/powerpc/boot_of.c                                  |   43 
 xen/arch/powerpc/domain.c                                   |   35 
 xen/arch/powerpc/domain_build.c                             |  214 --
 xen/arch/powerpc/hcalls.c                                   |    6 
 xen/arch/powerpc/memory.c                                   |  150 -
 xen/arch/powerpc/mm.c                                       |    1 
 xen/arch/powerpc/of-devtree.c                               |    2 
 xen/arch/powerpc/of-devtree.h                               |    3 
 xen/arch/powerpc/of_handler/Makefile                        |    2 
 xen/arch/powerpc/of_handler/strlcpy.c                       |   58 
 xen/arch/powerpc/ofd_fixup.c                                |   11 
 xen/arch/powerpc/papr/xlate.c                               |   17 
 xen/arch/powerpc/powerpc64/asm-offsets.c                    |    2 
 xen/arch/powerpc/powerpc64/exceptions.S                     |    8 
 xen/arch/powerpc/powerpc64/ppc970.c                         |    7 
 xen/arch/powerpc/powerpc64/ppc970_scom.c                    |    4 
 xen/arch/powerpc/powerpc64/traps.c                          |   10 
 xen/arch/powerpc/setup.c                                    |   23 
 xen/arch/powerpc/sysctl.c                                   |   10 
 xen/arch/powerpc/time.c                                     |    6 
 xen/arch/powerpc/xen.lds.S                                  |   23 
 xen/arch/x86/domain.c                                       |   52 
 xen/arch/x86/domain_build.c                                 |   10 
 xen/arch/x86/domctl.c                                       |   11 
 xen/arch/x86/hvm/hvm.c                                      |    9 
 xen/arch/x86/hvm/io.c                                       |    2 
 xen/arch/x86/hvm/platform.c                                 |   41 
 xen/arch/x86/hvm/svm/intr.c                                 |    2 
 xen/arch/x86/hvm/svm/svm.c                                  |   32 
 xen/arch/x86/hvm/svm/vmcb.c                                 |    4 
 xen/arch/x86/hvm/vlapic.c                                   |    1 
 xen/arch/x86/hvm/vmx/vmcs.c                                 |    2 
 xen/arch/x86/hvm/vmx/vmx.c                                  |   34 
 xen/arch/x86/mm.c                                           |  107 -
 xen/arch/x86/mm/Makefile                                    |    3 
 xen/arch/x86/mm/p2m.c                                       |  699 +++++++
 xen/arch/x86/mm/paging.c                                    |  143 +
 xen/arch/x86/mm/shadow/common.c                             | 1197 +++---------
 xen/arch/x86/mm/shadow/multi.c                              |  245 +-
 xen/arch/x86/mm/shadow/multi.h                              |    2 
 xen/arch/x86/mm/shadow/page-guest32.h                       |    5 
 xen/arch/x86/mm/shadow/private.h                            |  107 -
 xen/arch/x86/mm/shadow/types.h                              |   12 
 xen/arch/x86/setup.c                                        |    2 
 xen/arch/x86/sysctl.c                                       |    1 
 xen/arch/x86/traps.c                                        |   10 
 xen/arch/x86/x86_32/domain_page.c                           |    1 
 xen/arch/x86/x86_64/traps.c                                 |    1 
 xen/common/libelf/libelf-dominfo.c                          |  557 ++---
 xen/common/libelf/libelf-loader.c                           |  125 -
 xen/common/libelf/libelf-private.h                          |   26 
 xen/common/libelf/libelf-relocate.c                         |  375 +--
 xen/common/libelf/libelf-tools.c                            |  153 -
 xen/include/asm-powerpc/config.h                            |    5 
 xen/include/asm-powerpc/domain.h                            |    7 
 xen/include/asm-powerpc/init.h                              |   10 
 xen/include/asm-powerpc/mm.h                                |    3 
 xen/include/asm-powerpc/nmi.h                               |    6 
 xen/include/asm-powerpc/processor.h                         |    1 
 xen/include/asm-x86/domain.h                                |   96 
 xen/include/asm-x86/mm.h                                    |   63 
 xen/include/asm-x86/p2m.h                                   |  142 +
 xen/include/asm-x86/page.h                                  |    5 
 xen/include/asm-x86/paging.h                                |  376 +++
 xen/include/asm-x86/shadow.h                                |  375 ---
 xen/include/public/arch-ia64.h                              |    1 
 xen/include/public/arch-powerpc.h                           |   22 
 xen/include/public/arch-x86/xen.h                           |    1 
 95 files changed, 4112 insertions(+), 3398 deletions(-)

diff -r ac18d251df63 -r 9529d667d042 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Feb 15 13:13:36 
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Feb 15 14:09:39 
2007 -0700
@@ -344,7 +344,7 @@ static void frontend_changed(struct xenb
        switch (frontend_state) {
        case XenbusStateInitialising:
                if (dev->state == XenbusStateClosed) {
-                       printk("%s: %s: prepare for reconnect\n",
+                       printk(KERN_INFO "%s: %s: prepare for reconnect\n",
                               __FUNCTION__, dev->nodename);
                        xenbus_switch_state(dev, XenbusStateInitWait);
                }
@@ -488,7 +488,8 @@ static int connect_ring(struct backend_i
                xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol);
                return -1;
        }
-       printk("blkback: ring-ref %ld, event-channel %d, protocol %d (%s)\n",
+       printk(KERN_INFO
+              "blkback: ring-ref %ld, event-channel %d, protocol %d (%s)\n",
               ring_ref, evtchn, be->blkif->blk_protocol, protocol);
 
        /* Map the shared frame, irq etc. */
diff -r ac18d251df63 -r 9529d667d042 
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c  Thu Feb 15 13:13:36 
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c  Thu Feb 15 14:09:39 
2007 -0700
@@ -272,7 +272,7 @@ static void tap_frontend_changed(struct 
        switch (frontend_state) {
        case XenbusStateInitialising:
                if (dev->state == XenbusStateClosed) {
-                       printk("%s: %s: prepare for reconnect\n",
+                       printk(KERN_INFO "%s: %s: prepare for reconnect\n",
                               __FUNCTION__, dev->nodename);
                        xenbus_switch_state(dev, XenbusStateInitWait);
                }
@@ -369,7 +369,8 @@ static int connect_ring(struct backend_i
                xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol);
                return -1;
        }
-       printk("blktap: ring-ref %ld, event-channel %d, protocol %d (%s)\n",
+       printk(KERN_INFO
+              "blktap: ring-ref %ld, event-channel %d, protocol %d (%s)\n",
               ring_ref, evtchn, be->blkif->blk_protocol, protocol);
 
        /* Map the shared frame, irq etc. */
diff -r ac18d251df63 -r 9529d667d042 
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Thu Feb 15 13:13:36 
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Thu Feb 15 14:09:39 
2007 -0700
@@ -100,6 +100,7 @@ static void shutdown_handler(struct xenb
 static void shutdown_handler(struct xenbus_watch *watch,
                             const char **vec, unsigned int len)
 {
+       extern void ctrl_alt_del(void);
        char *str;
        struct xenbus_transaction xbt;
        int err;
@@ -129,7 +130,7 @@ static void shutdown_handler(struct xenb
        if (strcmp(str, "poweroff") == 0)
                shutting_down = SHUTDOWN_POWEROFF;
        else if (strcmp(str, "reboot") == 0)
-               kill_proc(1, SIGINT, 1); /* interrupt init */
+               ctrl_alt_del();
        else if (strcmp(str, "suspend") == 0)
                shutting_down = SHUTDOWN_SUSPEND;
        else if (strcmp(str, "halt") == 0)
diff -r ac18d251df63 -r 9529d667d042 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Feb 15 13:13:36 
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Feb 15 14:09:39 
2007 -0700
@@ -217,7 +217,7 @@ static void frontend_changed(struct xenb
        switch (frontend_state) {
        case XenbusStateInitialising:
                if (dev->state == XenbusStateClosed) {
-                       printk("%s: %s: prepare for reconnect\n",
+                       printk(KERN_INFO "%s: %s: prepare for reconnect\n",
                               __FUNCTION__, dev->nodename);
                        if (be->netif) {
                                netif_disconnect(be->netif);
diff -r ac18d251df63 -r 9529d667d042 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Thu Feb 15 
13:13:36 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Thu Feb 15 
14:09:39 2007 -0700
@@ -1505,7 +1505,7 @@ static void netif_release_rx_bufs(struct
        int id, ref;
 
        if (np->copying_receiver) {
-               printk("%s: fix me for copying receiver.\n", __FUNCTION__);
+               WPRINTK("%s: fix me for copying receiver.\n", __FUNCTION__);
                return;
        }
 
@@ -1555,8 +1555,8 @@ static void netif_release_rx_bufs(struct
                xfer++;
        }
 
-       printk("%s: %d xfer, %d noxfer, %d unused\n",
-              __FUNCTION__, xfer, noxfer, unused);
+       IPRINTK("%s: %d xfer, %d noxfer, %d unused\n",
+               __FUNCTION__, xfer, noxfer, unused);
 
        if (xfer) {
                /* Some pages are no longer absent... */
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/Makefile
--- a/tools/libxc/Makefile      Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/Makefile      Thu Feb 15 14:09:39 2007 -0700
@@ -49,15 +49,8 @@ GUEST_SRCS-y += xc_dom_core.c xc_dom_boo
 GUEST_SRCS-y += xc_dom_core.c xc_dom_boot.c
 GUEST_SRCS-y += xc_dom_elfloader.c
 GUEST_SRCS-y += xc_dom_binloader.c
-
-ifeq ($(CONFIG_POWERPC),y)
-# big endian boxes
-GUEST_SRCS-y += xc_dom_powerpc64.c
-else
-# little endian boxes
 GUEST_SRCS-y += xc_dom_x86.c
 GUEST_SRCS-y += xc_dom_ia64.c
-endif
 
 GUEST_SRCS-$(CONFIG_X86)     += xc_dom_compat_linux.c
 GUEST_SRCS-$(CONFIG_IA64)    += xc_dom_compat_linux.c
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/powerpc64/Makefile
--- a/tools/libxc/powerpc64/Makefile    Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/powerpc64/Makefile    Thu Feb 15 14:09:39 2007 -0700
@@ -1,4 +1,5 @@ GUEST_SRCS-y += powerpc64/flatdevtree.c
 GUEST_SRCS-y += powerpc64/flatdevtree.c
+GUEST_SRCS-y += powerpc64/mk_flatdevtree.c
 GUEST_SRCS-y += powerpc64/xc_linux_build.c
 GUEST_SRCS-y += powerpc64/xc_prose_build.c
 GUEST_SRCS-y += powerpc64/utils.c
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/powerpc64/flatdevtree.c
--- a/tools/libxc/powerpc64/flatdevtree.c       Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/powerpc64/flatdevtree.c       Thu Feb 15 14:09:39 2007 -0700
@@ -14,7 +14,7 @@
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
  * Copyright Pantelis Antoniou 2006
- * Copyright (C) IBM Corporation 2006
+ * Copyright IBM Corporation 2006, 2007
  * 2006 (c) MontaVista, Software, Inc.
  *
  * Authors: Pantelis Antoniou <pantelis@xxxxxxxxxxxxxxxxx>
@@ -209,7 +209,7 @@ void ft_add_rsvmap(struct ft_cxt *cxt, u
        ((u64 *) cxt->pres)[0] = cpu_to_be64(physaddr); /* phys = 0, size = 0, 
terminate */
        ((u64 *) cxt->pres)[1] = cpu_to_be64(size);
 
-       cxt->pres += 18;        /* advance */
+       cxt->pres += 16;        /* advance two u64s worth */
 
        ((u64 *) cxt->pres)[0] = 0;     /* phys = 0, size = 0, terminate */
        ((u64 *) cxt->pres)[1] = 0;
@@ -317,6 +317,9 @@ int ft_end_tree(struct ft_cxt *cxt)
        /* the new strings start */
        cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
        cxt->pstr = cxt->pstr_begin + cxt->strings_size;
+
+       /* mark the size of string structure in bph */
+       bph->size_dt_strings = cxt->strings_size;
 
        return 0;
 }
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/powerpc64/flatdevtree.h
--- a/tools/libxc/powerpc64/flatdevtree.h       Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/powerpc64/flatdevtree.h       Thu Feb 15 14:09:39 2007 -0700
@@ -40,7 +40,7 @@ struct boot_param_header {
        /* version 2 fields below */
        u32 boot_cpuid_phys;    /* Physical CPU id we're booting on */
        /* version 3 fields below */
-       u32 dt_strings_size;    /* size of the DT strings block */
+       u32 size_dt_strings;    /* size of the DT strings block */
 };
 
 struct ft_cxt {
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/powerpc64/mk_flatdevtree.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/mk_flatdevtree.c    Thu Feb 15 14:09:39 2007 -0700
@@ -0,0 +1,650 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright IBM Corporation 2007
+ *
+ * Authors: Ryan Harper <ryanh@xxxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <libgen.h>    
+#include <inttypes.h>
+#include <math.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#include <xc_private.h> /* for PERROR() */
+
+#include "mk_flatdevtree.h"
+
+static uint32_t current_phandle = 0;
+
+static uint32_t get_phandle(void)
+{
+   return current_phandle++;
+}
+
+static int readfile(const char *fullpath, void *data, int len)
+{
+    struct stat st;
+    int saved_errno;
+    int rc = -1;
+    int fd;
+   
+    if ((fd = open(fullpath, O_RDONLY)) == -1) {
+        PERROR("%s: failed to open file %s", __func__, fullpath);
+        return -1;
+    }
+
+    if ((rc = fstat(fd, &st)) == -1) {
+        PERROR("%s: failed to stat fd %d", __func__, fd);
+        goto error;
+    }
+
+    if (S_ISREG(st.st_mode))
+        rc = read(fd, data, len); 
+
+    close(fd);
+    return rc;
+
+error:
+    saved_errno = errno;
+    close(fd);
+    errno = saved_errno;
+    return -1;
+}
+
+/* 
+ * @property - string to check against the filter list
+ * @filter   - NULL terminated list of strings 
+ *
+ * compare @property string to each string in @filter
+ *
+ * return 1 if @property matches any filter, otherwise 0
+ *
+ */
+static int match(const char *property, const char **filter)
+{
+    int i;
+    
+    for (i=0; filter[i] != NULL; i++) {
+        /* compare the filter to property */
+        if (strncmp(property, filter[i], strlen(filter[i])) == 0)
+            return 1;
+    }
+
+    return 0;
+}
+
+/*
+ * copy the node at @dirpath filtering out any properties that match in 
@propfilter
+ */
+static int copynode(struct ft_cxt *cxt, const char *dirpath, const char 
**propfilter)
+{   
+    struct dirent *tree;
+    struct stat st;
+    DIR *dir;
+    char fullpath[MAX_PATH];
+    char *bname = NULL;
+    char *basec = NULL;
+    int saved_errno;
+
+    if ((dir = opendir(dirpath)) == NULL) {
+        PERROR("%s: failed to open dir %s", __func__, dirpath);
+        return -1;
+    }
+
+    while (1) {
+        if ((tree = readdir(dir)) == NULL)
+            break;  /* reached end of directory entries */
+
+        /* ignore . and .. */
+        if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0)
+            continue;
+
+        /* build full path name of the file, for stat() */
+        if (snprintf(fullpath, sizeof(fullpath), "%s/%s", dirpath,
+                     tree->d_name) >= sizeof(fullpath)) {
+            PERROR("%s: failed to build full path", __func__);
+            goto error;
+        }
+
+        /* stat the entry */
+        if (stat(fullpath, &st) < 0) {
+            PERROR("%s: failed to stat file %s", __func__, fullpath);
+            goto error;
+        }
+
+        if (S_ISDIR(st.st_mode)) {
+            /* start a new node for a dir */
+            ft_begin_node(cxt, tree->d_name);
+
+            /* copy everything in this dir */
+            if (copynode(cxt, fullpath, propfilter) < 0) {
+                PERROR("%s: failed to copy node @ %s", __func__, fullpath);
+                goto error;
+            }
+
+            /* end the node */
+            ft_end_node(cxt);
+        }
+        /* add files in dir as properties */
+        else if (S_ISREG(st.st_mode)) {
+
+            if ((basec = strdup(fullpath)) == NULL) {
+                PERROR("%s: failed to dupe string", __func__);
+                goto error;
+            }
+
+            if ((bname = basename(basec)) == NULL) {
+                PERROR("%s: basename() failed", __func__);
+                goto error;
+            }
+
+            /* only add files that don't match the property filter string */
+            if (!match(bname, propfilter)) {
+                char data[BUFSIZE];
+                int len;
+
+                /* snarf the data and push into the property */
+                if ((len = readfile(fullpath, data, sizeof(data))) < 0) {
+                    PERROR("%s: failed to read data from file %s", __func__,
+                                                                   fullpath);
+                    goto error;
+                }
+                ft_prop(cxt, tree->d_name, data, len);
+
+            }
+
+            /* strdup mallocs memory */
+            if (basec != NULL ) {
+                free(basec);
+                basec = NULL;
+            }
+
+        }
+    }
+
+    closedir(dir);
+    return 0;
+
+error:
+    saved_errno = errno;
+
+    /* strdup mallocs memory */
+    if (basec != NULL ) {
+        free(basec);
+        basec = NULL;
+    }
+
+    closedir(dir);
+
+    errno = saved_errno;
+    return -1;
+}
+
+static int find_cpu0(char *cpupath, int len)
+{   
+    const char path[] = "/proc/device-tree/cpus";
+    const char device[] = "device_type";
+    const char dev_cpu[] = "cpu";
+    const char reg[] = "reg";
+    char data[sizeof(dev_cpu)];
+    char prop[MAX_PATH];
+    char node[MAX_PATH];
+    struct dirent *tree;
+    struct stat st;
+    DIR* dir;
+    int saved_errno;
+    int found = 0;
+
+    if ((dir = opendir(path)) == NULL) {
+        PERROR("%s: failed to open directory %s", __func__, path);
+        return -1;
+    }    
+
+    while (!found) {
+
+        if ((tree = readdir(dir)) == NULL)
+            break;  /* reached end of directory entries */
+
+        /* ignore ., .. */
+        if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0)
+            continue;
+
+        /* build full path name of the file, for stat() */
+        if (snprintf(node, sizeof(node), "%s/%s", path,
+                     tree->d_name) >= sizeof(node)) {
+            PERROR("%s: failed to concat strings", __func__);
+            goto error;
+        }
+
+        /* stat the entry */
+        if (stat(node, &st) < 0) {
+            PERROR("%s: failed to stat file %s", __func__, node);
+            /* something funny happen in /proc/device-tree, but march onward */
+            continue;
+        }
+
+        /* for each dir, check the device_type property until we find 'cpu'*/
+        if (S_ISDIR(st.st_mode)) {
+
+            /* construct path to device_type */
+            if (snprintf(prop, sizeof(prop), "%s/%s", node,
+                         device) >= sizeof(prop)) {
+                PERROR("%s: failed to concat strings", __func__);
+                goto error;
+            }
+
+            /* read device_type into buffer */
+            if ((readfile(prop, data, sizeof(data))) < 0) {
+                PERROR("%s: failed to read data from file %s", __func__, prop);
+                goto error;
+            }
+
+            /* if the device_type is 'cpu',  and reg is 0 
+             * return the path where we found it */
+            if (strcmp(data, "cpu") == 0) {
+
+                /* construct path to reg */
+                if (snprintf(prop, sizeof(prop), "%s/%s", node,
+                             reg) >= sizeof(prop)) {
+                    PERROR("%s: failed to concat strings", __func__);
+                    goto error;
+                }
+
+                /* using data buffer since reg and device_type values have 
same size */
+                if ((readfile(prop, data, sizeof(data))) < 0) {
+                    PERROR("%s: failed to read data from file %s", __func__, 
prop);
+                    goto error;
+                }
+
+                /* now check property "reg" for value 0 */
+                if ((u32)*data == 0) {
+                    if (snprintf(cpupath, len, "%s", node) >= len) {
+                        PERROR("%s: failed to copy cpupath", __func__);
+                        goto error;
+                    }
+                    found = 1;
+                }
+            }
+        }
+    }
+
+    closedir(dir);
+    return found;
+
+error:
+    saved_errno = errno;
+    closedir(dir);
+    errno = saved_errno;
+    return -1;
+}
+
+void free_devtree(struct ft_cxt *root)
+{
+    if ((root != NULL) && root->bph != NULL) {
+        free(root->bph);
+        root->bph = NULL;
+    }
+}
+
+int make_devtree(struct ft_cxt *root,
+                 uint32_t domid, 
+                 uint32_t mem_mb,
+                 unsigned long rma_bytes,
+                 unsigned long shadow_mb,
+                 unsigned long initrd_base,
+                 unsigned long initrd_len,
+                 const char *bootargs,
+                 uint64_t shared_info_paddr,
+                 unsigned long console_evtchn,
+                 uint64_t console_paddr,
+                 unsigned long store_evtchn,
+                 uint64_t store_paddr)
+{
+    struct boot_param_header *bph = NULL;
+    uint64_t val[2];
+    uint32_t val32[2];
+    unsigned long remaining;
+    unsigned long initrd_end = initrd_base + initrd_len;
+    int64_t shadow_mb_log;
+    uint64_t pft_size;
+    char cpupath[MAX_PATH];
+    const char *propfilter[] = { "ibm", "linux,", NULL };
+    char *cpupath_copy = NULL;
+    char *cpuname = NULL;
+    int saved_errno;
+    int dtb_fd = -1;
+    uint32_t cpu0_phandle = get_phandle();
+    uint32_t xen_phandle = get_phandle();
+    uint32_t rma_phandle = get_phandle();
+
+    /* initialize bph to prevent double free on error path */
+    root->bph = NULL;
+
+    /* carve out space for bph */
+    if ((bph = (struct boot_param_header *)malloc(BPH_SIZE)) == NULL) {
+        PERROR("%s: Failed to malloc bph buffer size", __func__);
+        goto error;
+    }
+
+    /* NB: struct ft_cxt root defined at top of file */
+    /* root = Tree() */
+    ft_begin(root, bph, BPH_SIZE);
+
+    /* you MUST set reservations BEFORE _starting_the_tree_ */
+
+    /* reserve shared_info_t page */
+    if (shared_info_paddr) {
+        val[0] = cpu_to_be64((u64) shared_info_paddr);
+        val[1] = cpu_to_be64((u64) PAGE_SIZE);
+        ft_add_rsvmap(root, val[0], val[1]);
+    }
+
+    /* reserve console page for domU */
+    if (console_paddr) {
+        val[0] = cpu_to_be64((u64) console_paddr);
+        val[1] = cpu_to_be64((u64) PAGE_SIZE);
+        ft_add_rsvmap(root, val[0], val[1]);
+    }
+
+    /* reserve xen store page for domU */
+    if (store_paddr) {
+        val[0] = cpu_to_be64((u64) store_paddr);
+        val[1] = cpu_to_be64((u64) PAGE_SIZE);
+        ft_add_rsvmap(root, val[0], val[1]);
+    }
+
+    /* reserve space for initrd if needed */
+    if ( initrd_len > 0 )  {
+        val[0] = cpu_to_be64((u64) initrd_base);
+        val[1] = cpu_to_be64((u64) initrd_len);
+        ft_add_rsvmap(root, val[0], val[1]);
+    }
+
+    /* NB: ft_add_rsvmap() already terminates with a NULL reservation for us */
+
+    /* done with reservations, _starting_the_tree_ */
+    ft_begin_tree(root);
+
+    /* make root node */
+    ft_begin_node(root, "");
+
+    /* root.addprop('device_type', 'chrp-but-not-really\0') */
+    ft_prop_str(root, "device_type", "chrp-but-not-really");
+
+    /* root.addprop('#size-cells', 2) */
+    ft_prop_int(root, "#size-cells", 2);
+
+    /* root.addprop('#address-cells', 2) */
+    ft_prop_int(root, "#address-cells", 2);
+
+    /* root.addprop('model', 'Momentum,Maple-D\0') */
+    ft_prop_str(root, "model", "Momentum,Maple-D");
+
+    /* root.addprop('compatible', 'Momentum,Maple\0') */
+    ft_prop_str(root, "compatible", "Momentum,Maple");
+
+    /* start chosen node */
+    ft_begin_node(root, "chosen");
+
+    /* chosen.addprop('cpu', cpu0.get_phandle()) */
+    ft_prop_int(root, "cpu", cpu0_phandle);
+
+    /* chosen.addprop('rma', rma.get_phandle()) */
+    ft_prop_int(root, "memory", rma_phandle);
+
+    /* chosen.addprop('linux,stdout-path', '/xen/console\0') */
+    ft_prop_str(root, "linux,stdout-path", "/xen/console");
+
+    /* chosen.addprop('interrupt-controller, xen.get_phandle()) */
+    ft_prop_int(root, "interrupt-controller", xen_phandle);
+
+    /* chosen.addprop('bootargs', imghandler.cmdline + '\0') */
+    if ( bootargs != NULL )
+        ft_prop_str(root, "bootargs", bootargs);
+
+    /* mark where the initrd is, if present */
+    if ( initrd_len > 0 ) {
+        val[0] = cpu_to_be64((u64) initrd_base);
+        val[1] = cpu_to_be64((u64) initrd_end);
+        ft_prop(root, "linux,initrd-start", &(val[0]), sizeof(val[0]));
+        ft_prop(root, "linux,initrd-end", &(val[1]), sizeof(val[1]));
+    }
+
+    /* end chosen node */
+    ft_end_node(root);
+
+    /* xen = root.addnode('xen') */
+    ft_begin_node(root, "xen");
+
+    /*  xen.addprop('version', 'Xen-3.0-unstable\0') */
+    ft_prop_str(root, "compatible", "Xen-3.0-unstable");
+
+    /* xen.addprop('reg', long(imghandler.vm.domid), long(0)) */
+    val[0] = cpu_to_be64((u64) domid);
+    val[1] = cpu_to_be64((u64) 0);
+    ft_prop(root, "reg", val, sizeof(val));
+
+    /* point to shared_info_t page base addr */
+    val[0] = cpu_to_be64((u64) shared_info_paddr);
+    val[1] = cpu_to_be64((u64) PAGE_SIZE);
+    ft_prop(root, "shared-info", val, sizeof(val));
+
+    /* xen.addprop('domain-name', imghandler.vm.getName() + '\0') */
+    /* libxc doesn't know the domain name, that is purely a xend thing */
+    /* ft_prop_str(root, "domain-name", domain_name); */
+
+    /* add xen/linux,phandle for chosen/interrupt-controller */
+    ft_prop_int(root, "linux,phandle", xen_phandle);
+
+    if (console_paddr != 0) {
+        /* xencons = xen.addnode('console') */
+        ft_begin_node(root, "console");
+
+        /* console_paddr */
+        val[0] = cpu_to_be64((u64) console_paddr);
+        val[1] = cpu_to_be64((u64) PAGE_SIZE);
+        ft_prop(root, "reg", val, sizeof(val));
+
+        /* xencons.addprop('interrupts', console_evtchn, 0) */
+        val32[0] = cpu_to_be32((u32) console_evtchn);
+        val32[1] = cpu_to_be32((u32) 0);
+        ft_prop(root, "interrupts", val32, sizeof(val32));
+
+        /* end of console */
+        ft_end_node(root);
+    }
+
+    if (store_paddr != 0) {
+        /* start store node */
+        ft_begin_node(root, "store");
+
+        /* store paddr */
+        val[0] = cpu_to_be64((u64) store_paddr);
+        val[1] = cpu_to_be64((u64) PAGE_SIZE);
+        ft_prop(root, "reg", val, sizeof(val));
+
+        /* store event channel */
+        val32[0] = cpu_to_be32((u32) store_evtchn);
+        val32[1] = cpu_to_be32((u32) 0);
+        ft_prop(root, "interrupts", val32, sizeof(val32));
+
+        /* end of store */
+        ft_end_node(root);
+    }
+
+    /* end of xen node */
+    ft_end_node(root);
+
+    /* rma = root.addnode('memory@0') */
+    ft_begin_node(root, "memory@0");
+
+    /* rma.addprop('reg', long(0), long(rma_bytes)) */
+    val[0] = cpu_to_be64((u64) 0);
+    val[1] = cpu_to_be64((u64) rma_bytes);
+    ft_prop(root, "reg", val, sizeof(val));
+
+    /* rma.addprop('device_type', 'memory\0') */
+    ft_prop_str(root, "device_type", "memory");
+
+    /* add linux,phandle for chosen/rma node */
+    ft_prop_int(root, "linux,phandle", rma_phandle);
+
+    /* end of memory@0 */
+    ft_end_node(root);
+
+    /* calculate remaining bytes from total - rma size */
+    remaining = (mem_mb * 1024 * 1024) - rma_bytes;
+
+    /* memory@<rma_bytes> is all remaining memory after RMA */
+    if (remaining > 0)
+    {
+        char mem[MAX_PATH];
+        
+        if (snprintf(mem, sizeof(mem), "memory@%lx",
+                     rma_bytes) >= sizeof(mem)) {
+            PERROR("%s: failed to build memory string", __func__);
+            goto error;
+        }
+
+        /* memory@<rma_bytes> is all remaining memory after RMA */
+        ft_begin_node(root, mem);
+
+        /* mem.addprop('reg', long(rma_bytes), long(remaining)) */
+        val[0] = cpu_to_be64((u64) rma_bytes);
+        val[1] = cpu_to_be64((u64) remaining);
+        ft_prop(root, "reg", val, sizeof(val));
+
+        /* mem.addprop('device_type', 'memory\0') */
+        ft_prop_str(root, "device_type", "memory");
+
+        /* end memory@<rma_bytes> node */
+        ft_end_node(root);
+    }
+
+    /* add CPU nodes */
+    /* cpus = root.addnode('cpus') */
+    ft_begin_node(root, "cpus");
+
+    /* cpus.addprop('smp-enabled') */
+    ft_prop(root, "smp-enabled", NULL, 0);
+
+    /* cpus.addprop('#size-cells', 0) */
+    ft_prop_int(root, "#size-cells", 0);
+
+    /* cpus.addprop('#address-cells', 1) */
+    ft_prop_int(root, "#address-cells", 1);
+
+    /*
+     * Copy all properties the system firmware gave us from a 
+     * CPU node in the device tree.
+     */
+    if (find_cpu0(cpupath, sizeof(cpupath)) <= 0) {
+        PERROR("%s: failed find cpu0 node in host devtree", __func__);
+        goto error;
+    }
+
+    /* get the basename from path to cpu device */
+    if ((cpupath_copy = strdup(cpupath)) == NULL) {
+        PERROR("%s: failed to dupe string", __func__);
+        goto error;
+    }
+    if ((cpuname = basename(cpupath_copy)) == NULL) {
+        PERROR("%s: basename() failed", __func__);
+        goto error;
+    }
+     
+    /* start node for the cpu */
+    ft_begin_node(root, cpuname);
+
+    /* strdup() mallocs memory */
+    if ( cpupath_copy != NULL ) {
+        free(cpupath_copy);
+        cpupath_copy = NULL;
+    }
+
+    /* copy over most properties from host tree for cpu */
+    if (copynode(root, cpupath, propfilter) < 0) {
+        PERROR("%s: failed to copy node", __func__);
+            goto error;
+    }
+
+    /* calculate the pft-size */
+    shadow_mb_log = (int)log2((double)shadow_mb);
+    pft_size = shadow_mb_log + 20;
+
+    val32[0] = cpu_to_be32((u32) 0);
+    val32[1] = cpu_to_be32((u32) pft_size);
+    ft_prop(root, "ibm,pft-size", val32, sizeof(val32));
+
+    /* make phandle for cpu0 */
+    ft_prop_int(root, "linux,phandle", cpu0_phandle);
+
+    /* end <cpuname> node */
+    ft_end_node(root);
+
+    /* end cpus node */
+    ft_end_node(root);
+
+    /* end root node */
+    ft_end_node(root);
+
+    /* end of the tree */
+    if (ft_end_tree(root) != 0) {
+        PERROR("%s: failed to end tree", __func__);
+        goto error;
+    }
+
+    /* write a copy of the tree to a file */
+    if ((dtb_fd = open(DTB_FILE , O_RDWR)) == -1) {
+        PERROR("%s: failed to open file %s", __func__, DTB_FILE);
+        goto error;
+    }
+
+    if (write(dtb_fd, (const void *)bph, bph->totalsize) != bph->totalsize) {
+        PERROR("%s: failed to write blob to file", __func__);
+        goto error; 
+    }
+
+    return 0;
+ 
+error:
+    saved_errno = errno;
+
+    /* strdup() mallocs memory */
+    if ( cpupath_copy != NULL ) {
+        free(cpupath_copy);
+        cpupath_copy = NULL;
+    }
+
+    /* free bph buffer */
+    free_devtree(root);
+
+    if (dtb_fd)
+        close(dtb_fd);
+
+    errno = saved_errno;
+    return -1;
+}
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/powerpc64/mk_flatdevtree.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/mk_flatdevtree.h    Thu Feb 15 14:09:39 2007 -0700
@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright IBM Corporation 2007
+ *
+ * Authors: Ryan Harper <ryanh@xxxxxxxxxx>
+ */
+
+#ifndef MK_FLATDEVTREE_H
+#define MK_FLATDEVTREE_H
+
+#include "flatdevtree_env.h"
+#include "flatdevtree.h"
+
+extern void free_devtree(struct ft_cxt *root);
+extern int make_devtree(struct ft_cxt *root,
+                        uint32_t domid, 
+                        uint32_t mem_mb,
+                        unsigned long rma_bytes,
+                        unsigned long shadow_mb,
+                        unsigned long initrd_base,
+                        unsigned long initrd_len,
+                        const char *bootargs,
+                        uint64_t shared_info_paddr,
+                        unsigned long console_evtchn,
+                        uint64_t console_paddr,
+                        unsigned long store_evtchn,
+                        uint64_t store_paddr);
+
+#define MAX_PATH 200
+#define BUFSIZE 1024
+#define BPH_SIZE 16*1024
+#define DTB_FILE "/tmp/domU.dtb"
+
+#endif /* MK_FLATDEVTREE_H */
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/powerpc64/utils.c
--- a/tools/libxc/powerpc64/utils.c     Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/powerpc64/utils.c     Thu Feb 15 14:09:39 2007 -0700
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * Copyright (C) IBM Corporation 2006
+ * Copyright IBM Corporation 2006, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  *          Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
@@ -36,29 +36,6 @@
 #include "flatdevtree_env.h"
 #include "flatdevtree.h"
 #include "utils.h"
-
-unsigned long get_rma_pages(void *devtree)
-{
-    void *rma;
-    uint64_t rma_reg[2];
-    int rc;
-
-    rma = ft_find_node(devtree, "/memory@0");
-    if (rma == NULL) {
-        DPRINTF("couldn't find /memory@0\n");
-        return 0;
-    }
-    rc = ft_get_prop(devtree, rma, "reg", rma_reg, sizeof(rma_reg));
-    if (rc < 0) {
-        DPRINTF("couldn't get /memory@0/reg\n");
-        return 0;
-    }
-    if (rma_reg[0] != 0) {
-        DPRINTF("RMA did not start at 0\n");
-        return 0;
-    }
-    return rma_reg[1] >> PAGE_SHIFT;
-}
 
 int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
                       unsigned long nr_pages)
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/powerpc64/utils.h
--- a/tools/libxc/powerpc64/utils.h     Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/powerpc64/utils.h     Thu Feb 15 14:09:39 2007 -0700
@@ -13,13 +13,12 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * Copyright (C) IBM Corporation 2006
+ * Copyright IBM Corporation 2006, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  *          Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
  */
 
-extern unsigned long get_rma_pages(void *devtree);
 extern int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
                              unsigned long nr_pages);
 extern int install_image(int xc_handle, int domid, xen_pfn_t *page_array,
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/powerpc64/xc_linux_build.c
--- a/tools/libxc/powerpc64/xc_linux_build.c    Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/powerpc64/xc_linux_build.c    Thu Feb 15 14:09:39 2007 -0700
@@ -13,9 +13,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * Copyright (C) IBM Corporation 2006
+ * Copyright IBM Corporation 2006, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Ryan Harper <ryanh@xxxxxxxxxx>
  */
 
 #include <stdio.h>
@@ -32,10 +33,12 @@
 #include <xc_private.h>
 #include <xg_private.h>
 #include <xenctrl.h>
+#include <xen/arch-powerpc.h>
 
 #include "flatdevtree_env.h"
 #include "flatdevtree.h"
 #include "utils.h"
+#include "mk_flatdevtree.h"
 
 #define INITRD_ADDR (24UL << 20)
 #define DEVTREE_ADDR (16UL << 20)
@@ -78,85 +81,6 @@ static int init_boot_vcpu(
     return rc;
 }
 
-static int load_devtree(
-    int xc_handle,
-    int domid,
-    xen_pfn_t *page_array,
-    void *devtree,
-    unsigned long devtree_addr,
-    uint64_t initrd_base,
-    unsigned long initrd_len,
-    start_info_t *start_info __attribute__((unused)),
-    unsigned long start_info_addr)
-{
-    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
-    struct boot_param_header *header;
-    void *chosen;
-    void *xen;
-    uint64_t initrd_end = initrd_base + initrd_len;
-    unsigned int devtree_size;
-    int rc = 0;
-
-    DPRINTF("adding initrd props\n");
-
-    chosen = ft_find_node(devtree, "/chosen");
-    if (chosen == NULL) {
-        DPRINTF("couldn't find /chosen\n");
-        return -1;
-    }
-
-    xen = ft_find_node(devtree, "/xen");
-    if (xen == NULL) {
-        DPRINTF("couldn't find /xen\n");
-        return -1;
-    }
-
-    /* initrd-start */
-    rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
-            &initrd_base, sizeof(initrd_base));
-    if (rc < 0) {
-        DPRINTF("couldn't set /chosen/linux,initrd-start\n");
-        return rc;
-    }
-
-    /* initrd-end */
-    rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
-            &initrd_end, sizeof(initrd_end));
-    if (rc < 0) {
-        DPRINTF("couldn't set /chosen/linux,initrd-end\n");
-        return rc;
-    }
-
-    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
-    if (rc < 0) {
-        DPRINTF("couldn't set initrd reservation\n");
-        return ~0UL;
-    }
-
-    /* start-info (XXX being removed soon) */
-    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
-    if (rc < 0) {
-        DPRINTF("couldn't set /xen/start-info\n");
-        return rc;
-    }
-
-    header = devtree;
-    devtree_size = header->totalsize;
-    {
-        static const char dtb[] = "/tmp/xc_domU.dtb";
-        int dfd = creat(dtb, 0666);
-        if (dfd != -1) {
-            write(dfd, devtree, devtree_size);
-            close(dfd);
-        } else
-            DPRINTF("could not open(\"%s\")\n", dtb);
-    }
-
-    DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, 
devtree_size);
-    return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
-                       devtree_size);
-}
-
 static int load_initrd(
     int xc_handle,
     int domid,
@@ -186,46 +110,46 @@ out:
     return rc;
 }
 
-static unsigned long create_start_info(
-       void *devtree, start_info_t *start_info,
-        unsigned int console_evtchn, unsigned int store_evtchn,
-       unsigned long nr_pages, unsigned long rma_pages)
-{
-    unsigned long start_info_addr;
-    uint64_t rma_top;
-    int rc;
-
-    memset(start_info, 0, sizeof(*start_info));
-    snprintf(start_info->magic, sizeof(start_info->magic),
-             "xen-%d.%d-powerpc64HV", 3, 0);
-
-    rma_top = rma_pages << PAGE_SHIFT;
-    DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
-
-    start_info->nr_pages = nr_pages;
-    start_info->shared_info = rma_top - PAGE_SIZE;
-    start_info->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
-    start_info->store_evtchn = store_evtchn;
-    start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
-    start_info->console.domU.evtchn = console_evtchn;
-    start_info_addr = rma_top - 4*PAGE_SIZE;
-
-    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
-    if (rc < 0) {
-        DPRINTF("couldn't set start_info reservation\n");
-        return ~0UL;
-    }
-
-
-    return start_info_addr;
-}
-
 static void free_page_array(xen_pfn_t *page_array)
 {
     free(page_array);
 }
 
-
+static int check_memory_config(int rma_log, unsigned int mem_mb)
+{
+    u64 mem_kb = (mem_mb << 10);
+    u64 rma_kb = (1 << rma_log) >> 10;
+
+    switch(rma_log)
+    {
+        case 26:
+        case 27:
+        case 28:
+        case 30:
+        case 34:
+        case 38:
+            if (mem_kb < rma_kb) {
+                DPRINTF("Domain memory must be at least %dMB\n", 
+                        (1 << rma_log)>>20);
+                break;
+            }
+
+            if (mem_kb % (16 << 10)) {
+                DPRINTF("Domain memory %dMB must be a multiple of 16MB\n",
+                        mem_mb);
+                       
+                break;
+            }
+
+            /* rma_log and mem_mb OK */
+            return 0;
+
+        default:
+            DPRINTF("Invalid rma_log (%d)\n", rma_log);
+    }
+
+    return 1;
+}
 
 int xc_linux_build(int xc_handle,
                    uint32_t domid,
@@ -238,10 +162,8 @@ int xc_linux_build(int xc_handle,
                    unsigned int store_evtchn,
                    unsigned long *store_mfn,
                    unsigned int console_evtchn,
-                   unsigned long *console_mfn,
-                   void *devtree)
-{
-    start_info_t start_info;
+                   unsigned long *console_mfn)
+{
     struct domain_setup_info dsi;
     xen_pfn_t *page_array = NULL;
     unsigned long nr_pages;
@@ -249,19 +171,59 @@ int xc_linux_build(int xc_handle,
     unsigned long kern_addr;
     unsigned long initrd_base = 0;
     unsigned long initrd_len = 0;
-    unsigned long start_info_addr;
     unsigned long rma_pages;
+    unsigned long shadow_mb;
+    u64 shared_info_paddr;
+    u64 store_paddr;
+    u64 console_paddr;
+    u32 remaining_kb;
+    u32 extent_order;
+    u64 nr_extents;
+    int rma_log = 26;  /* 64MB RMA */
     int rc = 0;
+    int op;
+    struct ft_cxt devtree;
 
     DPRINTF("%s\n", __func__);
 
     nr_pages = mem_mb << (20 - PAGE_SHIFT);
     DPRINTF("nr_pages 0x%lx\n", nr_pages);
 
-    rma_pages = get_rma_pages(devtree);
+    rma_pages = (1 << rma_log) >> PAGE_SHIFT;
     if (rma_pages == 0) {
-           rc = -1;
-           goto out;
+        rc = -1;
+        goto out;
+    }
+
+    /* validate rma_log and domain memory config */
+    if (check_memory_config(rma_log, mem_mb)) {
+        rc = -1;
+        goto out;
+    }
+    
+    /* alloc RMA */
+    if (xc_alloc_real_mode_area(xc_handle, domid, rma_log)) {
+        rc = -1;
+        goto out;
+    }
+
+    /* subtract already allocated RMA to determine remaining KB to alloc */
+    remaining_kb = (nr_pages - rma_pages) * (PAGE_SIZE / 1024);
+    DPRINTF("totalmem - RMA = %dKB\n", remaining_kb);
+
+    /* to allocate in 16MB chunks, we need to determine the order of 
+     * the number of PAGE_SIZE pages contained in 16MB. */
+    extent_order = 24 - 12; /* extent_order = log2((1 << 24) - (1 << 12)) */
+    nr_extents = (remaining_kb / (PAGE_SIZE/1024)) >> extent_order;
+    DPRINTF("allocating memory in %llu chunks of %luMB\n", nr_extents,
+            (((1 << extent_order) >> 10) * PAGE_SIZE) >> 10);
+
+    /* now allocate the remaining memory as large-order allocations */
+    DPRINTF("increase_reservation(%u, %llu, %u)\n", domid, nr_extents, 
extent_order);
+    if (xc_domain_memory_increase_reservation(xc_handle, domid, nr_extents, 
+                                              extent_order, 0, NULL)) {
+        rc = -1;
+        goto out;
     }
 
     if (get_rma_page_array(xc_handle, domid, &page_array, rma_pages)) {
@@ -285,27 +247,46 @@ int xc_linux_build(int xc_handle,
         }
     }
 
-    /* start_info stuff: about to be removed  */
-    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
-                                        store_evtchn, nr_pages, rma_pages);
-    *console_mfn = page_array[start_info.console.domU.mfn];
-    *store_mfn = page_array[start_info.store_mfn];
-    if (install_image(xc_handle, domid, page_array, &start_info,
-                      start_info_addr, sizeof(start_info_t))) {
-        rc = -1;
-        goto out;
-    }
-
-    if (devtree) {
-        DPRINTF("loading flattened device tree\n");
-        devtree_addr = DEVTREE_ADDR;
-        if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
-                         initrd_base, initrd_len, &start_info,
-                         start_info_addr)) {
-            DPRINTF("couldn't load flattened device tree.\n");
-            rc = -1;
-            goto out;
-        }
+    /* fetch the current shadow_memory value for this domain */
+    op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
+    if (xc_shadow_control(xc_handle, domid, op, NULL, 0, 
+                          &shadow_mb, 0, NULL) < 0 ) {
+        rc = -1;
+        goto out;
+    }
+
+    /* determine shared_info, console, and store paddr */
+    shared_info_paddr = (rma_pages << PAGE_SHIFT) -
+                        (RMA_SHARED_INFO * PAGE_SIZE);
+    console_paddr = (rma_pages << PAGE_SHIFT) - (RMA_CONSOLE * PAGE_SIZE);
+    store_paddr = (rma_pages << PAGE_SHIFT) - (RMA_STORE * PAGE_SIZE);
+
+    /* map paddrs to mfns */
+    *store_mfn = page_array[(xen_pfn_t)(store_paddr >> PAGE_SHIFT)];
+    *console_mfn = page_array[(xen_pfn_t)(console_paddr >> PAGE_SHIFT)];
+    DPRINTF("console_mfn->%08lx store_mfn->%08lx\n", *console_mfn,
+            *store_mfn);
+
+    /* build the devtree here */
+    DPRINTF("constructing devtree\n");
+    if (make_devtree(&devtree, domid, mem_mb, (rma_pages << PAGE_SHIFT),
+                     shadow_mb, initrd_base, initrd_len, cmdline, 
+                     shared_info_paddr, console_evtchn, console_paddr,
+                     store_evtchn, store_paddr) < 0) {
+        DPRINTF("failed to create flattened device tree\n");
+        rc = -1;
+        goto out;
+    }
+
+    devtree_addr = DEVTREE_ADDR;
+    DPRINTF("loading flattened device tree to 0x%lx[0x%x]\n",
+            devtree_addr, devtree.bph->totalsize);
+
+    if (install_image(xc_handle, domid, page_array, (void *)devtree.bph,
+                      devtree_addr, devtree.bph->totalsize)) {
+        DPRINTF("couldn't load flattened device tree.\n");
+        rc = -1;
+        goto out;
     }
 
     if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) {
@@ -314,6 +295,7 @@ int xc_linux_build(int xc_handle,
     }
 
 out:
+    free_devtree(&devtree);
     free_page_array(page_array);
     return rc;
 }
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/powerpc64/xc_prose_build.c
--- a/tools/libxc/powerpc64/xc_prose_build.c    Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/powerpc64/xc_prose_build.c    Thu Feb 15 14:09:39 2007 -0700
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * Copyright (C) IBM Corporation 2006
+ * Copyright IBM Corporation 2006, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  *          Jonathan Appavoo <jappavoo@xxxxxxxxxx>
@@ -34,18 +34,14 @@
 #include <xg_private.h>
 #include <xenctrl.h>
 
-#include "flatdevtree_env.h"
-#include "flatdevtree.h"
 #include "utils.h"
 
 #define INITRD_ADDR (24UL << 20)
-#define DEVTREE_ADDR (16UL << 20)
 
 static int init_boot_vcpu(
     int xc_handle,
     int domid,
     struct domain_setup_info *dsi,
-    unsigned long devtree_addr,
     unsigned long kern_addr)
 {
     vcpu_guest_context_t ctxt;
@@ -55,7 +51,7 @@ static int init_boot_vcpu(
     ctxt.user_regs.pc = dsi->v_kernentry;
     ctxt.user_regs.msr = 0;
     ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
-    ctxt.user_regs.gprs[3] = devtree_addr;
+    ctxt.user_regs.gprs[3] = 0;
     ctxt.user_regs.gprs[4] = kern_addr;
     ctxt.user_regs.gprs[5] = 0; /* reserved for specifying OF handler */
     /* There is a buggy kernel that does not zero the "local_paca", so
@@ -79,85 +75,6 @@ static int init_boot_vcpu(
     return rc;
 }
 
-static int load_devtree(
-    int xc_handle,
-    int domid,
-    xen_pfn_t *page_array,
-    void *devtree,
-    unsigned long devtree_addr,
-    uint64_t initrd_base,
-    unsigned long initrd_len,
-    start_info_t *start_info __attribute__((unused)),
-    unsigned long start_info_addr)
-{
-    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
-    struct boot_param_header *header;
-    void *chosen;
-    void *xen;
-    uint64_t initrd_end = initrd_base + initrd_len;
-    unsigned int devtree_size;
-    int rc = 0;
-
-    DPRINTF("adding initrd props\n");
-
-    chosen = ft_find_node(devtree, "/chosen");
-    if (chosen == NULL) {
-        DPRINTF("couldn't find /chosen\n");
-        return -1;
-    }
-
-    xen = ft_find_node(devtree, "/xen");
-    if (xen == NULL) {
-        DPRINTF("couldn't find /xen\n");
-        return -1;
-    }
-
-    /* initrd-start */
-    rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
-            &initrd_base, sizeof(initrd_base));
-    if (rc < 0) {
-        DPRINTF("couldn't set /chosen/linux,initrd-start\n");
-        return rc;
-    }
-
-    /* initrd-end */
-    rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
-            &initrd_end, sizeof(initrd_end));
-    if (rc < 0) {
-        DPRINTF("couldn't set /chosen/linux,initrd-end\n");
-        return rc;
-    }
-
-    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
-    if (rc < 0) {
-        DPRINTF("couldn't set initrd reservation\n");
-        return ~0UL;
-    }
-
-    /* start-info (XXX being removed soon) */
-    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
-    if (rc < 0) {
-        DPRINTF("couldn't set /xen/start-info\n");
-        return rc;
-    }
-
-    header = devtree;
-    devtree_size = header->totalsize;
-    {
-        static const char dtb[] = "/tmp/xc_domU.dtb";
-        int dfd = creat(dtb, 0666);
-        if (dfd != -1) {
-            write(dfd, devtree, devtree_size);
-            close(dfd);
-        } else
-            DPRINTF("could not open(\"%s\")\n", dtb);
-    }
-
-    DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, 
devtree_size);
-    return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
-                       devtree_size);
-}
-
 static int load_initrd(
     int xc_handle,
     int domid,
@@ -188,13 +105,12 @@ out:
 }
 
 static unsigned long create_start_info(
-       void *devtree, start_info_t *start_info,
+       start_info_t *start_info,
         unsigned int console_evtchn, unsigned int store_evtchn,
        unsigned long nr_pages, unsigned long rma_pages, const char *cmdline)
 {
     unsigned long start_info_addr;
     uint64_t rma_top;
-    int rc;
 
     memset(start_info, 0, sizeof(*start_info));
     snprintf(start_info->magic, sizeof(start_info->magic),
@@ -213,12 +129,6 @@ static unsigned long create_start_info(
     /* just in case we truncated cmdline with strncpy add 0 at the end */
     start_info->cmd_line[MAX_GUEST_CMDLINE-1]=0;
     start_info_addr = rma_top - 4*PAGE_SIZE;
-
-    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
-    if (rc < 0) {
-        DPRINTF("couldn't set start_info reservation\n");
-        return ~0UL;
-    }
 
     return start_info_addr;
 }
@@ -239,14 +149,12 @@ int xc_prose_build(int xc_handle,
                    unsigned int store_evtchn,
                    unsigned long *store_mfn,
                    unsigned int console_evtchn,
-                   unsigned long *console_mfn,
-                   void *devtree)
+                   unsigned long *console_mfn)
 {
     start_info_t start_info;
     struct domain_setup_info dsi;
     xen_pfn_t *page_array = NULL;
     unsigned long nr_pages;
-    unsigned long devtree_addr = 0;
     unsigned long kern_addr;
     unsigned long initrd_base = 0;
     unsigned long initrd_len = 0;
@@ -261,11 +169,7 @@ int xc_prose_build(int xc_handle,
     nr_pages = mem_mb << (20 - PAGE_SHIFT);
     DPRINTF("nr_pages 0x%lx\n", nr_pages);
 
-    rma_pages = get_rma_pages(devtree);
-    if (rma_pages == 0) {
-           rc = -1;
-           goto out;
-    }
+    rma_pages = (1 << 26) >> PAGE_SHIFT; /* 64 MB */
 
     if (get_rma_page_array(xc_handle, domid, &page_array, rma_pages)) {
         rc = -1;
@@ -289,9 +193,9 @@ int xc_prose_build(int xc_handle,
     }
 
     /* start_info stuff: about to be removed  */
-    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
+    start_info_addr = create_start_info(&start_info, console_evtchn,
                                         store_evtchn, nr_pages,
-                                       rma_pages, cmdline);
+                                        rma_pages, cmdline);
     *console_mfn = page_array[start_info.console.domU.mfn];
     *store_mfn = page_array[start_info.store_mfn];
     if (install_image(xc_handle, domid, page_array, &start_info,
@@ -300,19 +204,7 @@ int xc_prose_build(int xc_handle,
         goto out;
     }
 
-    if (devtree) {
-        DPRINTF("loading flattened device tree\n");
-        devtree_addr = DEVTREE_ADDR;
-        if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
-                         initrd_base, initrd_len, &start_info,
-                         start_info_addr)) {
-            DPRINTF("couldn't load flattened device tree.\n");
-            rc = -1;
-            goto out;
-        }
-    }
-
-    if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) {
+    if (init_boot_vcpu(xc_handle, domid, &dsi, kern_addr)) {
         rc = -1;
         goto out;
     }
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/xc_dom.h
--- a/tools/libxc/xc_dom.h      Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/xc_dom.h      Thu Feb 15 14:09:39 2007 -0700
@@ -6,11 +6,6 @@
 
 typedef uint64_t xen_vaddr_t;
 typedef uint64_t xen_paddr_t;
-
-/* FIXME: temporary hack ... */
-#ifndef PRIpfn
-#define PRIpfn "lx"
-#endif
 
 struct xc_dom_seg {
     xen_vaddr_t vstart;
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/xc_dom_powerpc64.c
--- a/tools/libxc/xc_dom_powerpc64.c    Thu Feb 15 13:13:36 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Xen domain builder -- ia64 bits.
- *
- * Most architecture-specific code for ia64 goes here.
- *   - fill architecture-specific structs.
- *
- * This code is licenced under the GPL.
- * written 2006 by Gerd Hoffmann <kraxel@xxxxxxx>.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include <xen/xen.h>
-
-#include "xg_private.h"
-#include "xc_dom.h"
-
-/* ------------------------------------------------------------------------ */
-
-static int alloc_magic_pages(struct xc_dom_image *dom)
-{
-    /* allocate special pages */
-    dom->low_top--; /* shared_info */
-    dom->xenstore_pfn = --dom->low_top;
-    dom->console_pfn = --dom->low_top;
-    dom->start_info_pfn = --dom->low_top;
-    return 0;
-}
-
-static int start_info(struct xc_dom_image *dom)
-{
-    start_info_t *si =
-       xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1);
-
-    xc_dom_printf("%s\n", __FUNCTION__);
-
-    snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
-
-    si->nr_pages = dom->total_pages;
-    si->shared_info = (dom->total_pages - 1) << PAGE_SHIFT;
-    si->store_mfn = dom->xenstore_pfn;
-    si->store_evtchn = dom->store_evtchn;
-    si->console.domU.mfn = dom->console_pfn;
-    si->console.domU.evtchn = dom->console_evtchn;
-    return 0;
-}
-
-static int shared_info(struct xc_dom_image *dom, void *ptr)
-{
-    shared_info_t *shared_info = ptr;
-    int i;
-
-    xc_dom_printf("%s: called\n", __FUNCTION__);
-
-    memset(shared_info, 0, sizeof(*shared_info));
-    return 0;
-}
-
-static int vcpu(struct xc_dom_image *dom, void *ptr)
-{
-    vcpu_guest_context_t *ctxt = ptr;
-
-    xc_dom_printf("%s: called\n", __FUNCTION__);
-
-    /* clear everything */
-    memset(ctxt, 0, sizeof(*ctxt));
-
-    memset(&ctxt->user_regs, 0x55, sizeof(ctxt.user_regs));
-    ctxt->user_regs.pc = dsi->v_kernentry;
-    ctxt->user_regs.msr = 0;
-    ctxt->user_regs.gprs[1] = 0; /* Linux uses its own stack */
-    ctxt->user_regs.gprs[3] = devtree_addr;
-    ctxt->user_regs.gprs[4] = kern_addr;
-    ctxt->user_regs.gprs[5] = 0;
-
-    /* There is a buggy kernel that does not zero the "local_paca", so
-     * we must make sure this register is 0 */
-    ctxt->user_regs.gprs[13] = 0;
-
-    return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static struct xc_dom_arch xc_dom_arch = {
-    .guest_type = "xen-3.0-powerpc64",
-    .page_shift = FIXME,
-    .alloc_magic_pages = alloc_magic_pages,
-    .start_info = start_info,
-    .shared_info = shared_info,
-    .vcpu = vcpu,
-};
-
-static void __init register_arch_hooks(void)
-{
-    xc_dom_register_arch_hooks(&xc_dom_arch);
-}
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/xenguest.h    Thu Feb 15 14:09:39 2007 -0700
@@ -153,7 +153,6 @@ int xc_prose_build(int xc_handle,
                    unsigned int store_evtchn,
                    unsigned long *store_mfn,
                    unsigned int console_evtchn,
-                   unsigned long *console_mfn,
-                   void *arch_args);
+                   unsigned long *console_mfn);
 
 #endif /* XENGUEST_H */
diff -r ac18d251df63 -r 9529d667d042 tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c  Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/libxc/xg_private.c  Thu Feb 15 14:09:39 2007 -0700
@@ -216,3 +216,15 @@ int xc_hvm_restore(int xc_handle, int io
     errno = ENOSYS;
     return -1;
 }
+
+__attribute__((weak)) int xc_get_hvm_param(
+    int handle, domid_t dom, int param, unsigned long *value)
+{
+    return -ENOSYS;
+}
+
+__attribute__((weak)) int xc_set_hvm_param(
+    int handle, domid_t dom, int param, unsigned long value)
+{
+    return -ENOSYS;
+}
diff -r ac18d251df63 -r 9529d667d042 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/python/xen/lowlevel/xc/xc.c Thu Feb 15 14:09:39 2007 -0700
@@ -966,7 +966,7 @@ static PyObject *pyxc_alloc_real_mode_ar
         return NULL;
 
     if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     Py_INCREF(zero);
     return zero;
@@ -980,33 +980,32 @@ static PyObject *pyxc_prose_build(XcObje
     char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
     int flags = 0;
     int store_evtchn, console_evtchn;
+    unsigned int mem_mb;
     unsigned long store_mfn = 0;
     unsigned long console_mfn = 0;
-    void *arch_args = NULL;
     int unused;
 
     static char *kwd_list[] = { "dom", "store_evtchn",
-                                "console_evtchn", "image",
+                                "console_evtchn", "image", "memsize",
                                 /* optional */
                                 "ramdisk", "cmdline", "flags",
-                                "features", "arch_args", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssiss#", kwd_list,
-                                      &dom, &store_evtchn,
+                                "features", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis#", kwd_list,
+                                      &dom, &store_evtchn, &mem_mb,
                                       &console_evtchn, &image,
                                       /* optional */
                                       &ramdisk, &cmdline, &flags,
-                                      &features, &arch_args, &unused) )
-        return NULL;
-
-    if ( xc_prose_build(self->xc_handle, dom, image,
+                                      &features, &unused) )
+        return NULL;
+
+    if ( xc_prose_build(self->xc_handle, dom, mem_mb, image,
                         ramdisk, cmdline, features, flags,
                         store_evtchn, &store_mfn,
-                        console_evtchn, &console_mfn,
-                        arch_args) != 0 ) {
+                        console_evtchn, &console_mfn) != 0 ) {
         if (!errno)
              errno = EINVAL;
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     }
     return Py_BuildValue("{s:i,s:i}", 
                          "store_mfn", store_mfn,
diff -r ac18d251df63 -r 9529d667d042 tools/python/xen/xend/FlatDeviceTree.py
--- a/tools/python/xen/xend/FlatDeviceTree.py   Thu Feb 15 13:13:36 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,359 +0,0 @@
-#!/usr/bin/env python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of version 2.1 of the GNU Lesser General Public
-# License as published by the Free Software Foundation.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#
-# Copyright (C) IBM Corp. 2006
-#
-# Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
-
-import os
-import sys
-import struct
-import stat
-import re
-import glob
-import math
-
-_host_devtree_root = '/proc/device-tree'
-
-_OF_DT_HEADER = int("d00dfeed", 16) # avoid signed/unsigned FutureWarning
-_OF_DT_BEGIN_NODE = 0x1
-_OF_DT_END_NODE = 0x2
-_OF_DT_PROP = 0x3
-_OF_DT_END = 0x9
-
-def _bincat(seq, separator=''):
-    '''Concatenate the contents of seq into a bytestream.'''
-    strs = []
-    for item in seq:
-        if isinstance(item, int):
-            strs.append(struct.pack(">I", item))
-        elif isinstance(item, long):
-            strs.append(struct.pack(">Q", item))
-        else:
-            try:
-                strs.append(item.to_bin())
-            except AttributeError, e:
-                strs.append(item)
-    return separator.join(strs)
-
-def _alignup(val, alignment):
-    return (val + alignment - 1) & ~(alignment - 1)
-
-def _pad(buf, alignment):
-    '''Pad bytestream with NULLs to specified alignment.'''
-    padlen = _alignup(len(buf), alignment)
-    return buf + '\0' * (padlen - len(buf))
-    # not present in Python 2.3:
-    #return buf.ljust(_padlen, '\0')
-
-def _indent(item):
-    indented = []
-    for line in str(item).splitlines(True):
-        indented.append('    ' + line)
-    return ''.join(indented)
-
-class _Property:
-    _nonprint = re.compile('[\000-\037\200-\377]')
-    def __init__(self, node, name, value):
-        self.node = node
-        self.value = value
-        self.name = name
-        self.node.tree.stradd(name)
-
-    def __str__(self):
-        result = self.name
-        if self.value:
-            searchtext = self.value
-            # it's ok for a string to end in NULL
-            if searchtext.find('\000') == len(searchtext)-1:
-                searchtext = searchtext[:-1]
-            m = self._nonprint.search(searchtext)
-            if m:
-                bytes = struct.unpack("B" * len(self.value), self.value)
-                hexbytes = [ '%02x' % b for b in bytes ]
-                words = []
-                for i in range(0, len(self.value), 4):
-                    words.append(''.join(hexbytes[i:i+4]))
-                v = '<' + ' '.join(words) + '>'
-            else:
-                v = '"%s"' % self.value
-            result += ': ' + v
-        return result
-
-    def to_bin(self):
-        offset = self.node.tree.stroffset(self.name)
-        return struct.pack('>III', _OF_DT_PROP, len(self.value), offset) \
-            + _pad(self.value, 4)
-
-class _Node:
-    def __init__(self, tree, name):
-        self.tree = tree
-        self.name = name
-        self.props = {}
-        self.children = {}
-        self.phandle = 0
-
-    def __str__(self):
-        propstrs = [ _indent(prop) for prop in self.props.values() ]
-        childstrs = [ _indent(child) for child in self.children.values() ]
-        return '%s:\n%s\n%s' % (self.name, '\n'.join(propstrs),
-            '\n'.join(childstrs))
-
-    def to_bin(self):
-        name = _pad(self.name + '\0', 4)
-        return struct.pack('>I', _OF_DT_BEGIN_NODE) + \
-                name + \
-                _bincat(self.props.values()) + \
-                _bincat(self.children.values()) + \
-                struct.pack('>I', _OF_DT_END_NODE)
-
-    def addprop(self, propname, *cells):
-        '''setprop with duplicate error-checking.'''
-        if propname in self.props:
-            raise AttributeError('%s/%s already exists' % (self.name, 
propname))
-        self.setprop(propname, *cells)
-
-    def setprop(self, propname, *cells):
-        self.props[propname] = _Property(self, propname, _bincat(cells))
-
-    def addnode(self, nodename):
-        '''newnode with duplicate error-checking.'''
-        if nodename in self.children:
-            raise AttributeError('%s/%s already exists' % (self.name, 
nodename))
-        return self.newnode(nodename)
-
-    def newnode(self, nodename):
-        node = _Node(self.tree, nodename)
-        self.children[nodename] = node
-        return node
-
-    def getprop(self, propname):
-        return self.props[propname]
-
-    def getchild(self, nodename):
-        return self.children[nodename]
-
-    def get_phandle(self):
-        if self.phandle:
-            return self.phandle
-        self.phandle = self.tree.alloc_phandle()
-        self.addprop('linux,phandle', self.phandle)
-        return self.phandle
-
-class _Header:
-    def __init__(self):
-        self.magic = 0
-        self.totalsize = 0
-        self.off_dt_struct = 0
-        self.off_dt_strings = 0
-        self.off_mem_rsvmap = 0
-        self.version = 0
-        self.last_comp_version = 0
-        self.boot_cpuid_phys = 0
-        self.size_dt_strings = 0
-    def to_bin(self):
-        return struct.pack('>9I',
-            self.magic,
-            self.totalsize,
-            self.off_dt_struct,
-            self.off_dt_strings,
-            self.off_mem_rsvmap,
-            self.version,
-            self.last_comp_version,
-            self.boot_cpuid_phys,
-            self.size_dt_strings)
-
-class _StringBlock:
-    def __init__(self):
-        self.table = []
-    def to_bin(self):
-        return _bincat(self.table, '\0') + '\0'
-    def add(self, str):
-        self.table.append(str)
-    def getoffset(self, str):
-        return self.to_bin().index(str + '\0')
-
-class Tree(_Node):
-    def __init__(self):
-        self.last_phandle = 0
-        self.strings = _StringBlock()
-        self.reserved = [(0, 0)]
-        _Node.__init__(self, self, '\0')
-
-    def alloc_phandle(self):
-        self.last_phandle += 1
-        return self.last_phandle
-
-    def stradd(self, str):
-        return self.strings.add(str)
-
-    def stroffset(self, str):
-        return self.strings.getoffset(str)
-
-    def reserve(self, start, len):
-        self.reserved.insert(0, (start, len))
-
-    def to_bin(self):
-        # layout:
-        #   header
-        #   reservation map
-        #   string block
-        #   data block
-
-        datablock = _Node.to_bin(self)
-
-        r = [ struct.pack('>QQ', rsrv[0], rsrv[1]) for rsrv in self.reserved ]
-        reserved = _bincat(r)
-
-        strblock = _pad(self.strings.to_bin(), 4)
-        strblocklen = len(strblock)
-
-        header = _Header()
-        header.magic = _OF_DT_HEADER
-        header.off_mem_rsvmap = _alignup(len(header.to_bin()), 8)
-        header.off_dt_strings = header.off_mem_rsvmap + len(reserved)
-        header.off_dt_struct = header.off_dt_strings + strblocklen
-        header.version = 0x10
-        header.last_comp_version = 0x10
-        header.boot_cpuid_phys = 0
-        header.size_dt_strings = strblocklen
-
-        payload = reserved + \
-                strblock + \
-                datablock + \
-                struct.pack('>I', _OF_DT_END)
-        header.totalsize = len(payload) + _alignup(len(header.to_bin()), 8)
-        return _pad(header.to_bin(), 8) + payload
-
-def _readfile(fullpath):
-    '''Return full contents of a file.'''
-    f = file(fullpath, 'r')
-    data = f.read()
-    f.close()
-    return data
-
-def _find_first_cpu(dirpath):
-    '''Find the first node of type 'cpu' in a directory tree.'''
-    cpulist = glob.glob(os.path.join(dirpath, 'cpus', '*'))
-    for node in cpulist:
-        try:
-            data = _readfile(os.path.join(node, 'device_type'))
-        except IOError:
-            continue
-        if 'cpu' in data:
-            return node
-    raise IOError("couldn't find any CPU nodes under " + dirpath)
-
-def _copynode(node, dirpath, propfilter):
-    '''Copy all properties and children nodes from a directory tree.'''
-    dirents = os.listdir(dirpath)
-    for dirent in dirents:
-        fullpath = os.path.join(dirpath, dirent)
-        st = os.lstat(fullpath)
-        if stat.S_ISDIR(st.st_mode):
-            child = node.addnode(dirent)
-            _copynode(child, fullpath, propfilter)
-        elif stat.S_ISREG(st.st_mode) and propfilter(fullpath):
-            node.addprop(dirent, _readfile(fullpath))
-
-def build(imghandler):
-    '''Construct a device tree by combining the domain's configuration and
-    the host's device tree.'''
-    root = Tree()
-
-    # 1st reseravtion entry used for start_info, console, store, shared_info
-    root.reserve(0x3ffc000, 0x4000)
-
-    # 2nd reservation enrty used for initrd, later on when we load the
-    # initrd we may fill this in with zeroes which signifies the end
-    # of the reservation map.  So as to avoid adding a zero map now we
-    # put some bogus yet sensible numbers here.
-    root.reserve(0x1000000, 0x1000)
-
-    root.addprop('device_type', 'chrp-but-not-really\0')
-    root.addprop('#size-cells', 2)
-    root.addprop('#address-cells', 2)
-    root.addprop('model', 'Momentum,Maple-D\0')
-    root.addprop('compatible', 'Momentum,Maple\0')
-
-    xen = root.addnode('xen')
-    xen.addprop('start-info', long(0x3ffc000), long(0x1000))
-    xen.addprop('version', 'Xen-3.0-unstable\0')
-    xen.addprop('reg', long(imghandler.vm.domid), long(0))
-    xen.addprop('domain-name', imghandler.vm.getName() + '\0')
-    xencons = xen.addnode('console')
-    xencons.addprop('interrupts', 1, 0)
-
-    # add memory nodes
-    totalmem = imghandler.vm.getMemoryTarget() * 1024
-    rma_log = 26 ### imghandler.vm.info.get('powerpc_rma_log')
-    rma_bytes = 1 << rma_log
-
-    # RMA node
-    rma = root.addnode('memory@0')
-    rma.addprop('reg', long(0), long(rma_bytes))
-    rma.addprop('device_type', 'memory\0')
-
-    # all the rest in a single node
-    remaining = totalmem - rma_bytes
-    if remaining > 0:
-        mem = root.addnode('memory@1')
-        mem.addprop('reg', long(rma_bytes), long(remaining))
-        mem.addprop('device_type', 'memory\0')
-
-    # add CPU nodes
-    cpus = root.addnode('cpus')
-    cpus.addprop('smp-enabled')
-    cpus.addprop('#size-cells', 0)
-    cpus.addprop('#address-cells', 1)
-
-    # Copy all properties the system firmware gave us, except for 'linux,'
-    # properties, from the first CPU node in the device tree. Do this once for
-    # every vcpu. Hopefully all cpus are identical...
-    cpu0 = None
-    cpu0path = _find_first_cpu(_host_devtree_root)
-    def _nolinuxprops(fullpath):
-        return not os.path.basename(fullpath).startswith('linux,')
-    for i in range(imghandler.vm.getVCpuCount()):
-        # create new node and copy all properties
-        cpu = cpus.addnode('PowerPC,970@%d' % i)
-        _copynode(cpu, cpu0path, _nolinuxprops)
-
-        # overwrite what we need to
-        shadow_mb = imghandler.vm.info.get('shadow_memory', 1)
-        shadow_mb_log = int(math.log(shadow_mb, 2))
-        pft_size = shadow_mb_log + 20
-        cpu.setprop('ibm,pft-size', 0, pft_size)
-
-        # set default CPU
-        if cpu0 == None:
-            cpu0 = cpu
-
-    chosen = root.addnode('chosen')
-    chosen.addprop('cpu', cpu0.get_phandle())
-    chosen.addprop('memory', rma.get_phandle())
-    chosen.addprop('linux,stdout-path', '/xen/console\0')
-    chosen.addprop('interrupt-controller', xen.get_phandle())
-    chosen.addprop('bootargs', imghandler.cmdline + '\0')
-    # xc_linux_load.c will overwrite these 64-bit properties later
-    chosen.addprop('linux,initrd-start', long(0))
-    chosen.addprop('linux,initrd-end', long(0))
-
-    if 1:
-        f = file('/tmp/domU.dtb', 'w')
-        f.write(root.to_bin())
-        f.close()
-
-    return root
diff -r ac18d251df63 -r 9529d667d042 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Thu Feb 15 13:13:36 2007 -0700
+++ b/tools/python/xen/xend/image.py    Thu Feb 15 14:09:39 2007 -0700
@@ -30,7 +30,6 @@ from xen.xend.server.netif import random
 from xen.xend.server.netif import randomMAC
 from xen.xend.xenstore.xswatch import xswatch
 from xen.xend import arch
-from xen.xend import FlatDeviceTree
 
 xc = xen.lowlevel.xc.xc()
 
@@ -219,39 +218,7 @@ class PPC_LinuxImageHandler(LinuxImageHa
 class PPC_LinuxImageHandler(LinuxImageHandler):
 
     ostype = "linux"
-
-    def configure(self, vmConfig, imageConfig, deviceConfig):
-        LinuxImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
-        self.imageConfig = imageConfig
-
-    def buildDomain(self):
-        store_evtchn = self.vm.getStorePort()
-        console_evtchn = self.vm.getConsolePort()
-
-        mem_mb = self.getRequiredInitialReservation() / 1024
-
-        log.debug("domid          = %d", self.vm.getDomid())
-        log.debug("memsize        = %d", mem_mb)
-        log.debug("image          = %s", self.kernel)
-        log.debug("store_evtchn   = %d", store_evtchn)
-        log.debug("console_evtchn = %d", console_evtchn)
-        log.debug("cmdline        = %s", self.cmdline)
-        log.debug("ramdisk        = %s", self.ramdisk)
-        log.debug("vcpus          = %d", self.vm.getVCpuCount())
-        log.debug("features       = %s", self.vm.getFeatures())
-
-        devtree = FlatDeviceTree.build(self)
-
-        return xc.linux_build(domid          = self.vm.getDomid(),
-                              memsize        = mem_mb,
-                              image          = self.kernel,
-                              store_evtchn   = store_evtchn,
-                              console_evtchn = console_evtchn,
-                              cmdline        = self.cmdline,
-                              ramdisk        = self.ramdisk,
-                              features       = self.vm.getFeatures(),
-                              arch_args      = devtree.to_bin())
-
+    
     def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
         """@param shadow_mem_kb The configured shadow memory, in KiB.
         @param maxmem_kb The configured maxmem, in KiB.
@@ -261,13 +228,10 @@ class PPC_LinuxImageHandler(LinuxImageHa
         return max(maxmem_kb / 64, shadow_mem_kb)
 
 
-class PPC_ProseImageHandler(LinuxImageHandler):
+
+class PPC_ProseImageHandler(PPC_LinuxImageHandler):
 
     ostype = "prose"
-
-    def configure(self, imageConfig, deviceConfig):
-        LinuxImageHandler.configure(self, imageConfig, deviceConfig)
-        self.imageConfig = imageConfig
 
     def buildDomain(self):
         store_evtchn = self.vm.getStorePort()
@@ -285,8 +249,6 @@ class PPC_ProseImageHandler(LinuxImageHa
         log.debug("vcpus          = %d", self.vm.getVCpuCount())
         log.debug("features       = %s", self.vm.getFeatures())
 
-        devtree = FlatDeviceTree.build(self)
-
         return xc.arch_prose_build(dom            = self.vm.getDomid(),
                                    memsize        = mem_mb,
                                    image          = self.kernel,
@@ -294,17 +256,7 @@ class PPC_ProseImageHandler(LinuxImageHa
                                    console_evtchn = console_evtchn,
                                    cmdline        = self.cmdline,
                                    ramdisk        = self.ramdisk,
-                                   features       = self.vm.getFeatures(),
-                                   arch_args      = devtree.to_bin())
-
-    def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
-        """@param shadow_mem_kb The configured shadow memory, in KiB.
-        @param maxmem_kb The configured maxmem, in KiB.
-        @return The corresponding required amount of shadow memory, also in
-        KiB.
-        PowerPC currently uses "shadow memory" to refer to the hash table."""
-        return max(maxmem_kb / 64, shadow_mem_kb)
-
+                                   features       = self.vm.getFeatures())
 
 class HVMImageHandler(ImageHandler):
 
diff -r ac18d251df63 -r 9529d667d042 
unmodified_drivers/linux-2.6/platform-pci/platform-compat.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c       Thu Feb 
15 13:13:36 2007 -0700
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c       Thu Feb 
15 14:09:39 2007 -0700
@@ -12,6 +12,12 @@ static int system_state = 1;
 static int system_state = 1;
 EXPORT_SYMBOL(system_state);
 #endif
+
+static inline void ctrl_alt_del(void)
+{
+       kill_proc(1, SIGINT, 1); /* interrupt init */
+}
+EXPORT_SYMBOL(ctrl_alt_del);
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
 size_t strcspn(const char *s, const char *reject)
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/Makefile Thu Feb 15 14:09:39 2007 -0700
@@ -51,8 +51,6 @@ obj-$(builtin_dom0) += dom0.o
 
 obj-y += firmware_image.o
 
-obj-y += elf32.o
-
 # These are extra warnings like for the arch/ppc directory but may not
 # allow the rest of the tree to build.
 PPC_C_WARNINGS += -Wundef -Wmissing-prototypes -Wmissing-declarations
@@ -64,7 +62,7 @@ CFLAGS += $(PPC_C_WARNINGS)
 # objects into a single ELF segment and to not link in any additional
 # objects that gcc would normally like to
 #
-OMAGIC = -N -nodefaultlibs -nostartfiles
+OMAGIC = -nodefaultlibs -nostartfiles
 
 firmware: of_handler/built_in.o $(TARGET_SUBARCH)/memcpy.o of-devtree.o
        $(CC) $(CFLAGS) $(OMAGIC) -e __ofh_start -Wl,-Ttext,0x0 $^ -o $@
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/backtrace.c
--- a/xen/arch/powerpc/backtrace.c      Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/backtrace.c      Thu Feb 15 14:09:39 2007 -0700
@@ -198,7 +198,6 @@ void show_backtrace_regs(struct cpu_user
     console_start_sync();
     
     show_registers(regs);
-    printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr());
     printk("hid4 0x%016lx\n", regs->hid4);
     printk("---[ backtrace ]---\n");
     show_backtrace(regs->gprs[1], regs->lr, regs->pc);
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/boot_of.c
--- a/xen/arch/powerpc/boot_of.c        Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/boot_of.c        Thu Feb 15 14:09:39 2007 -0700
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005, 2006
+ * Copyright IBM Corp. 2005, 2006, 2007
  *
  * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
  *          Hollis Blanchard <hollisb@xxxxxxxxxx>
@@ -43,6 +43,14 @@ static int of_out;
 static int of_out;
 static ulong eomem;
 
+/* Track memory during early boot with a limited per-page bitmap. We need an
+ * allocator to tell us where we can place RTAS, our copy of the device tree.
+ * We could examine the "available" properties in memory nodes, but we
+ * apparently can't depend on firmware to update those when we call "claim". So
+ * we need to track it ourselves.
+ * We can't dynamically allocate the bitmap, because we would need something
+ * to tell us where it's safe to allocate...
+ */
 #define MEM_AVAILABLE_PAGES ((32 << 20) >> PAGE_SHIFT)
 static DECLARE_BITMAP(mem_available_pages, MEM_AVAILABLE_PAGES);
 
@@ -530,6 +538,37 @@ static ulong boot_of_alloc(ulong size)
 
         pos = pos + i;
     }
+}
+
+int boot_of_mem_avail(int pos, ulong *startpage, ulong *endpage)
+{
+    ulong freebit;
+    ulong usedbit;
+
+    if (pos >= MEM_AVAILABLE_PAGES)
+        /* Stop iterating. */
+        return -1;
+
+    /* Find first free page. */
+    freebit = find_next_zero_bit(mem_available_pages, MEM_AVAILABLE_PAGES, 
pos);
+    if (freebit >= MEM_AVAILABLE_PAGES) {
+        /* We know everything after MEM_AVAILABLE_PAGES is still free. */
+        *startpage = MEM_AVAILABLE_PAGES << PAGE_SHIFT;
+        *endpage = ~0UL;
+        return freebit;
+    }
+    *startpage = freebit << PAGE_SHIFT;
+
+    /* Now find first used page after that. */
+    usedbit = find_next_bit(mem_available_pages, MEM_AVAILABLE_PAGES, freebit);
+    if (usedbit >= MEM_AVAILABLE_PAGES) {
+        /* We know everything after MEM_AVAILABLE_PAGES is still free. */
+        *endpage = ~0UL;
+        return usedbit;
+    }
+
+    *endpage = usedbit << PAGE_SHIFT;
+    return usedbit;
 }
 
 static ulong boot_of_mem_init(void)
@@ -1302,7 +1341,7 @@ multiboot_info_t __init *boot_of_init(
             __func__,
             r3, r4, vec, r6, r7, orig_msr);
 
-    if ((vec >= (ulong)_start) && (vec <= (ulong)_end)) {
+    if (is_kernel(vec)) {
         of_panic("Hmm.. OF[0x%lx] seems to have stepped on our image "
                 "that ranges: %p .. %p.\n",
                 vec, _start, _end);
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/domain.c
--- a/xen/arch/powerpc/domain.c Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/domain.c Thu Feb 15 14:09:39 2007 -0700
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005, 2006
+ * Copyright IBM Corp. 2005, 2006, 2007
  *
  * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
  */
@@ -105,13 +105,13 @@ void arch_domain_destroy(struct domain *
 
 static void machine_fail(const char *s)
 {
-    printk("%s failed, manual powercycle required!\n", s);
+    printk("%s failed, manual powercycle required!\n"
+           "  spinning....\n", s);
     for (;;)
         sleep();
 }
 void machine_halt(void)
 {
-    printk("machine_halt called: spinning....\n");
     console_start_sync();
     printk("%s called\n", __func__);
     rtas_halt();
@@ -121,7 +121,6 @@ void machine_halt(void)
 
 void machine_restart(char * __unused)
 {
-    printk("machine_restart called: spinning....\n");
     console_start_sync();
     printk("%s called\n", __func__);
     rtas_reboot();
@@ -152,22 +151,32 @@ void vcpu_destroy(struct vcpu *v)
 
 int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
 { 
+    struct domain *d = v->domain;
+
     memcpy(&v->arch.ctxt, &c.nat->user_regs, sizeof(c.nat->user_regs));
 
-    printk("Domain[%d].%d: initializing\n",
-           v->domain->domain_id, v->vcpu_id);
-
-    if (v->domain->arch.htab.order == 0)
-        panic("Page table never allocated for Domain: %d\n",
-              v->domain->domain_id);
-    if (v->domain->arch.rma_order == 0)
-        panic("RMA never allocated for Domain: %d\n",
-              v->domain->domain_id);
+    printk("Domain[%d].%d: initializing\n", d->domain_id, v->vcpu_id);
+
+    if (d->arch.htab.order == 0)
+        panic("Page table never allocated for Domain: %d\n", d->domain_id);
+    if (d->arch.rma_order == 0)
+        panic("RMA never allocated for Domain: %d\n", d->domain_id);
+
+    d->shared_info->wc_sec = dom0->shared_info->wc_sec;
+    d->shared_info->wc_nsec = dom0->shared_info->wc_nsec;
+    d->shared_info->arch.boot_timebase = dom0->shared_info->arch.boot_timebase;
 
     set_bit(_VCPUF_initialised, &v->vcpu_flags);
 
     cpu_init_vcpu(v);
 
+    return 0;
+}
+
+int arch_vcpu_reset(struct vcpu *v)
+{
+    panic("%s: called for Dom%d[%d]\n",
+          __func__, v->domain->domain_id, v->vcpu_id);
     return 0;
 }
 
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/domain_build.c
--- a/xen/arch/powerpc/domain_build.c   Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/domain_build.c   Thu Feb 15 14:09:39 2007 -0700
@@ -20,19 +20,18 @@
 
 #include <xen/config.h>
 #include <xen/lib.h>
-#include <xen/elf.h>
 #include <xen/sched.h>
 #include <xen/init.h>
 #include <xen/ctype.h>
 #include <xen/iocap.h>
 #include <xen/shadow.h>
+#include <xen/domain.h>
 #include <xen/version.h>
 #include <asm/processor.h>
 #include <asm/papr.h>
+#include <public/arch-powerpc.h>
+#include <public/libelf.h>
 #include "oftree.h"
-
-extern int parseelfimage_32(struct domain_setup_info *dsi);
-extern int loadelfimage_32(struct domain_setup_info *dsi);
 
 /* opt_dom0_mem: memory allocated to domain 0. */
 static unsigned int dom0_nrpages;
@@ -51,63 +50,18 @@ static unsigned int opt_dom0_shadow;
 static unsigned int opt_dom0_shadow;
 boolean_param("dom0_shadow", opt_dom0_shadow);
 
-int elf_sanity_check(const Elf_Ehdr *ehdr)
-{
-    if (IS_ELF(*ehdr))
-        /* we are happy with either */
-        if ((ehdr->e_ident[EI_CLASS] == ELFCLASS32
-             && ehdr->e_machine == EM_PPC)
-            || (ehdr->e_ident[EI_CLASS] == ELFCLASS64
-                && ehdr->e_machine == EM_PPC64)) {
-            if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB
-                && ehdr->e_type == ET_EXEC)
-                return 1;
-        }
-    printk("DOM0 image is not a Xen-compatible Elf image.\n");
-    return 0;
-}
-
 /* adapted from common/elf.c */
 #define RM_MASK(a,l) ((a) & ((1UL << (l)) - 1))
-
-static int rm_loadelfimage_64(struct domain_setup_info *dsi, ulong rma)
-{
-    char *elfbase = (char *)dsi->image_addr;
-    Elf64_Ehdr *ehdr = (Elf64_Ehdr *)dsi->image_addr;
-    Elf64_Phdr *phdr;
-    int h;
-  
-    for (h = 0; h < ehdr->e_phnum; h++ ) 
-    {
-        phdr = (Elf64_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
-        if (!((phdr->p_type == PT_LOAD) &&
-             ((phdr->p_flags & (PF_W|PF_X)) != 0)))
-            continue;
-
-        if (phdr->p_filesz != 0)
-            memcpy((char *)(rma + RM_MASK(phdr->p_paddr, 42)),
-                   elfbase + phdr->p_offset, 
-                   phdr->p_filesz);
-        if (phdr->p_memsz > phdr->p_filesz)
-            memset((char *)(rma + RM_MASK(phdr->p_paddr, 42) + phdr->p_filesz),
-                   0, phdr->p_memsz - phdr->p_filesz);
-    }
-
-#ifdef NOT_YET
-    loadelfsymtab(dsi, 1);
-#endif
-
-    return 0;
-}
 
 int construct_dom0(struct domain *d,
                    unsigned long image_start, unsigned long image_len, 
                    unsigned long initrd_start, unsigned long initrd_len,
                    char *cmdline)
 {
+    struct elf_binary elf;
+    struct elf_dom_parms parms;
     int rc;
     struct vcpu *v = d->vcpu[0];
-    struct domain_setup_info dsi;
     ulong dst;
     u64 *ofh_tree;
     uint rma_nrpages = 1 << d->arch.rma_order;
@@ -115,11 +69,8 @@ int construct_dom0(struct domain *d,
     ulong rma = page_to_maddr(d->arch.rma_page);
     start_info_t *si;
     ulong eomem;
-    int am64 = 1;
     int preempt = 0;
-    ulong msr;
-    ulong pc;
-    ulong r2;
+    int vcpu;
 
     /* Sanity! */
     BUG_ON(d->domain_id != 0);
@@ -130,26 +81,27 @@ int construct_dom0(struct domain *d,
 
     cpu_init_vcpu(v);
 
-    memset(&dsi, 0, sizeof(struct domain_setup_info));
-    dsi.image_addr = image_start;
-    dsi.image_len  = image_len;
-
-    printk("Trying Dom0 as 64bit ELF\n");
-    if ((rc = parseelfimage(&dsi)) != 0) {
-        printk("Trying Dom0 as 32bit ELF\n");
-        if ((rc = parseelfimage_32(&dsi)) != 0)
-            return rc;
-        am64 = 0;
-    }
+    printk("*** LOADING DOMAIN 0 ***\n");
+
+    rc = elf_init(&elf, (void *)image_start, image_len);
+    if (rc)
+        return rc;
+#ifdef VERBOSE
+    elf_set_verbose(&elf);
+#endif
+    elf_parse_binary(&elf);
+    if (0 != (elf_xen_parse(&elf, &parms)))
+        return rc;
+
+    printk("Dom0 kernel: %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
+            elf_64bit(&elf) ? "64-bit" : "32-bit",
+            elf.pstart, elf.pend);
 
     /* elf contains virtual addresses that can have the upper bits
      * masked while running in real mode, so we do the masking as well
      * as well */
-    dsi.v_kernstart = RM_MASK(dsi.v_kernstart, 42);
-    dsi.v_kernend = RM_MASK(dsi.v_kernend, 42);
-    dsi.v_kernentry = RM_MASK(dsi.v_kernentry, 42);
-
-    printk("*** LOADING DOMAIN 0 ***\n");
+    parms.virt_kend = RM_MASK(parms.virt_kend, 42);
+    parms.virt_entry = RM_MASK(parms.virt_entry, 42);
 
     /* By default DOM0 is allocated all available memory. */
     d->max_pages = ~0U;
@@ -210,6 +162,27 @@ int construct_dom0(struct domain *d,
     /* put stack below everything */
     v->arch.ctxt.gprs[1] = dst - STACK_FRAME_OVERHEAD;
 
+    /* startup secondary processors */
+    if ( opt_dom0_max_vcpus == 0 )
+        opt_dom0_max_vcpus = num_online_cpus();
+    if ( opt_dom0_max_vcpus > num_online_cpus() )
+        opt_dom0_max_vcpus = num_online_cpus();
+    if ( opt_dom0_max_vcpus > MAX_VIRT_CPUS )
+        opt_dom0_max_vcpus = MAX_VIRT_CPUS;
+#ifdef BITS_PER_GUEST_LONG
+    if ( opt_dom0_max_vcpus > BITS_PER_GUEST_LONG(d) )
+        opt_dom0_max_vcpus = BITS_PER_GUEST_LONG(d);
+#endif
+    printk("Dom0 has maximum %u VCPUs\n", opt_dom0_max_vcpus);
+
+    for (vcpu = 1; vcpu < opt_dom0_max_vcpus; vcpu++) {
+        if (NULL == alloc_vcpu(dom0, vcpu, vcpu))
+            panic("Error creating domain 0 vcpu %d\n", vcpu);
+        /* for now we pin Dom0 VCPUs to their coresponding CPUs */
+        if (cpu_isset(vcpu, cpu_online_map))
+            dom0->vcpu[vcpu]->cpu_affinity = cpumask_of_cpu(vcpu);
+    }
+
     /* copy relative to Xen */
     dst += rma;
 
@@ -229,75 +202,56 @@ int construct_dom0(struct domain *d,
     printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma,
            oftree_len);
     memcpy((void *)dst, (void *)oftree, oftree_len);
-
     dst = ALIGN_UP(dst + oftree_len, PAGE_SIZE);
 
-    if (am64) {
-        ulong kbase;
-        ulong *fdesc;
-
-        printk("loading 64-bit Dom0: 0x%lx, in RMA:0x%lx\n", dst, dst - rma);
-        rm_loadelfimage_64(&dsi, dst);
-
-        kbase = dst;
-        /* move dst to end of bss */
-        dst = ALIGN_UP(dsi.v_kernend + dst, PAGE_SIZE);
-
-        if ( initrd_len > 0 ) {
-            ASSERT( (dst - rma) + image_len < eomem );
-
-            printk("loading initrd: 0x%lx, 0x%lx\n", dst, initrd_len);
-            memcpy((void *)dst, (void *)initrd_start, initrd_len);
-
-            si->mod_start = dst - rma;
-            si->mod_len = image_len;
-
-            dst = ALIGN_UP(dst + initrd_len, PAGE_SIZE);
-        } else {
-            printk("no initrd\n");
-            si->mod_start = 0;
-            si->mod_len = 0;
-        }
-        /* it may be a function descriptor */
-        fdesc = (ulong *)(dsi.v_kernstart + dsi.v_kernentry + kbase);
-
-        if (fdesc[2] == 0
-            && ((fdesc[0] >= dsi.v_kernstart)
-                && (fdesc[0] < dsi.v_kernend)) /* text entry is in range */
-            && ((fdesc[1] >= dsi.v_kernstart)  /* toc can be > image */
-                && (fdesc[1] < (dsi.v_kernend + (0x7fff * sizeof (ulong)))))) {
-            /* it is almost certainly a function descriptor */
-            pc = RM_MASK(fdesc[0], 42) + kbase - rma;
-            r2 = RM_MASK(fdesc[1], 42) + kbase - rma;
-        } else {
-            pc = ((ulong)fdesc) - rma;
-            r2 = 0;
-        }
-        msr = MSR_SF;
+    /* Load the dom0 kernel. */
+    elf.dest = (void *)dst;
+    elf_load_binary(&elf);
+    v->arch.ctxt.pc = dst - rma;
+    dst = ALIGN_UP(dst + parms.virt_kend, PAGE_SIZE);
+
+    /* Load the initrd. */
+    if (initrd_len > 0) {
+        ASSERT((dst - rma) + image_len < eomem);
+
+        printk("loading initrd: 0x%lx, 0x%lx\n", dst, initrd_len);
+        memcpy((void *)dst, (void *)initrd_start, initrd_len);
+
+        si->mod_start = dst - rma;
+        si->mod_len = image_len;
+
+        dst = ALIGN_UP(dst + initrd_len, PAGE_SIZE);
     } else {
-        printk("loading 32-bit Dom0: 0x%lx, in RMA:0x%lx\n",
-               dsi.v_kernstart + rma, dsi.v_kernstart);
-        dsi.v_start = rma;
-        loadelfimage_32(&dsi);
-
-        pc = dsi.v_kernentry;
-        r2 = 0;
-        msr = 0;
-    }
-
+        printk("no initrd\n");
+        si->mod_start = 0;
+        si->mod_len = 0;
+    }
+
+    if (elf_64bit(&elf)) {
+        v->arch.ctxt.msr = MSR_SF;
+    } else {
+        v->arch.ctxt.msr = 0;
+    }
+    v->arch.ctxt.gprs[2] = 0;
     v->arch.ctxt.gprs[3] = si->mod_start;
     v->arch.ctxt.gprs[4] = si->mod_len;
+
+       printk("dom0 initial register state:\n"
+                       "    pc %016lx msr %016lx\n"
+                       "    r1 %016lx r2 %016lx r3 %016lx\n"
+                       "    r4 %016lx r5 %016lx\n",
+                       v->arch.ctxt.pc,
+                       v->arch.ctxt.msr,
+                       v->arch.ctxt.gprs[1],
+                       v->arch.ctxt.gprs[2],
+                       v->arch.ctxt.gprs[3],
+                       v->arch.ctxt.gprs[4],
+                       v->arch.ctxt.gprs[5]);
 
     memset(si->cmd_line, 0, sizeof(si->cmd_line));
     if ( cmdline != NULL )
         strlcpy((char *)si->cmd_line, cmdline, sizeof(si->cmd_line));
 
-    v->arch.ctxt.msr = msr;
-    v->arch.ctxt.pc = pc;
-    v->arch.ctxt.gprs[2] = r2;
-
-    printk("DOM: pc = 0x%lx, r2 = 0x%lx\n", pc, r2);
-
     ofd_dom0_fixup(d, *ofh_tree + rma, si);
 
     set_bit(_VCPUF_initialised, &v->vcpu_flags);
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/elf32.c
--- a/xen/arch/powerpc/elf32.c  Thu Feb 15 13:13:36 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-#define parseelfimage parseelfimage_32
-#define loadelfimage loadelfimage_32
-#define xen_elfnote_string xen_elfnote_string32
-#define xen_elfnote_numeric xen_elfnote_numeric32
-#define ELFSIZE 32
-#include "../../common/elf.c"
-
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/hcalls.c
--- a/xen/arch/powerpc/hcalls.c Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/hcalls.c Thu Feb 15 14:09:39 2007 -0700
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright IBM Corp. 2005, 2006, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
@@ -130,7 +130,7 @@ static void register_papr_hcall(ulong nu
 
 static void init_papr_hcalls(void)
 {
-    inithcall_t *hcall;
+    init_hcall_t *hcall;
     int i;
 
     /* initialize PAPR hcall table */
@@ -140,7 +140,7 @@ static void init_papr_hcalls(void)
         register_papr_hcall(i, do_ni_papr_hypercall);
 
     /* register the PAPR hcalls */
-    for (hcall = &__inithcall_start; hcall < &__inithcall_end; hcall++) {
+    for (hcall = &__init_hcall_start; hcall < &__init_hcall_end; hcall++) {
         register_papr_hcall(hcall->number, hcall->handler);
     }
 }
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/memory.c
--- a/xen/arch/powerpc/memory.c Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/memory.c Thu Feb 15 14:09:39 2007 -0700
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2006
+ * Copyright IBM Corp. 2006, 2007
  *
  * Authors: Dan Poff <poff@xxxxxxxxxx>
  *          Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
@@ -25,7 +25,7 @@
 #include "oftree.h"
 #include "rtas.h"
 
-#undef DEBUG
+#define DEBUG
 #ifdef DEBUG
 #define DBG(fmt...) printk(fmt)
 #else
@@ -42,8 +42,6 @@ unsigned long xenheap_phys_end;
 unsigned long xenheap_phys_end;
 static uint nr_pages;
 static ulong xenheap_size;
-static ulong save_start;
-static ulong save_end;
 
 struct membuf {
     ulong start;
@@ -51,30 +49,6 @@ struct membuf {
 };
 
 typedef void (*walk_mem_fn)(struct membuf *, uint);
-
-static ulong free_xenheap(ulong start, ulong end)
-{
-    start = ALIGN_UP(start, PAGE_SIZE);
-    end = ALIGN_DOWN(end, PAGE_SIZE);
-
-    DBG("%s: 0x%lx - 0x%lx\n", __func__, start, end);
-
-    /* need to do this better */
-    if (save_start <= end && save_start >= start) {
-        DBG("%s:     Go around the saved area: 0x%lx - 0x%lx\n",
-               __func__, save_start, save_end);
-        init_xenheap_pages(start, ALIGN_DOWN(save_start, PAGE_SIZE));
-        xenheap_size += ALIGN_DOWN(save_start, PAGE_SIZE) - start;
-
-        init_xenheap_pages(ALIGN_UP(save_end, PAGE_SIZE), end);
-        xenheap_size += end - ALIGN_UP(save_end, PAGE_SIZE);
-    } else {
-        init_xenheap_pages(start, end);
-        xenheap_size += end - start;
-    }
-
-    return ALIGN_UP(end, PAGE_SIZE);
-}
 
 static void set_max_page(struct membuf *mb, uint entries)
 {
@@ -113,6 +87,7 @@ static void heap_init(struct membuf *mb,
             start_blk = xenheap_phys_end;
         }
 
+        DBG("boot free: %016lx - %016lx\n", start_blk, end_blk);
         init_boot_pages(start_blk, end_blk);
         total_pages += (end_blk - start_blk) >> PAGE_SHIFT;
     }
@@ -141,72 +116,31 @@ static void ofd_walk_mem(void *m, walk_m
     }
 }
 
-static void setup_xenheap(module_t *mod, int mcount)
-{
-    int i;
-    ulong freemem;
-
-    freemem = ALIGN_UP((ulong)_end, PAGE_SIZE);
-
-    for (i = 0; i < mcount; i++) {
-        u32 s;
-
-        if (mod[i].mod_end == mod[i].mod_start)
-            continue;
-
-        s = ALIGN_DOWN(mod[i].mod_start, PAGE_SIZE);
-
-        if (mod[i].mod_start > (ulong)_start &&
-            mod[i].mod_start < (ulong)_end) {
-            /* mod was linked in */
-            continue;
-        }
-
-        if (s < freemem) 
-            panic("module addresses must assend\n");
-
-        free_xenheap(freemem, s);
-        freemem = ALIGN_UP(mod[i].mod_end, PAGE_SIZE);
-        
-    }
-
-    /* the rest of the xenheap, starting at the end of modules */
-    free_xenheap(freemem, xenheap_phys_end);
-}
-
 void memory_init(module_t *mod, int mcount)
 {
     ulong eomem;
-    ulong heap_start;
+    ulong bitmap_start = ~0UL;
+    ulong bitmap_end = 0;
+    ulong bitmap_size;
     ulong xh_pages;
+    ulong start;
+    ulong end;
+    int pos;
 
     /* lets find out how much memory there is and set max_page */
     max_page = 0;
     printk("Physical RAM map:\n");
     ofd_walk_mem((void *)oftree, set_max_page);
     eomem = max_page << PAGE_SHIFT;
-
-    if (eomem == 0){
+    if (eomem == 0) {
         panic("ofd_walk_mem() failed\n");
     }
 
-    /* find the portion of memory we need to keep safe */
-    save_start = oftree;
-    save_end = oftree_end;
-    if (rtas_base) {
-        if (save_start > rtas_base)
-            save_start = rtas_base;
-        if (save_end < rtas_end)
-            save_end = rtas_end;
-    }
-
-    /* minimum heap has to reach to the end of all Xen required memory */
-    xh_pages = ALIGN_UP(save_end, PAGE_SIZE) >> PAGE_SHIFT;
-    xh_pages += opt_xenheap_megabytes << (20 - PAGE_SHIFT);
+    xh_pages = opt_xenheap_megabytes << (20 - PAGE_SHIFT);
 
     /* While we are allocating HTABS from The Xen Heap we need it to
      * be larger */
-    xh_pages  += nr_pages >> 5;
+    xh_pages += nr_pages >> 5;
 
     xenheap_phys_end = xh_pages << PAGE_SHIFT;
     printk("End of Xen Area: %luMiB (%luKiB)\n",
@@ -214,17 +148,20 @@ void memory_init(module_t *mod, int mcou
 
     printk("End of RAM: %luMiB (%luKiB)\n", eomem >> 20, eomem >> 10);
 
-    /* Architecturally the first 4 pages are exception hendlers, we
-     * will also be copying down some code there */
-    heap_start = 4 << PAGE_SHIFT;
-    if (oftree < (ulong)_start)
-        heap_start = ALIGN_UP(oftree_end, PAGE_SIZE);
-
-    heap_start = init_boot_allocator(heap_start);
-    if (heap_start > (ulong)_start) {
-        panic("space below _start (%p) is not enough memory "
-              "for heap (0x%lx)\n", _start, heap_start);
-    }
+    /* The boot allocator requires one bit per page. Find a spot for it. */
+    bitmap_size = max_page / 8;
+    pos = boot_of_mem_avail(0, &start, &end);
+    while (pos >= 0) {
+        if (end - start >= bitmap_size) {
+            bitmap_start = start;
+            bitmap_end = init_boot_allocator(bitmap_start);
+            printk("boot allocator @ %lx - %lx\n", bitmap_start, bitmap_end);
+            break;
+        }
+        pos = boot_of_mem_avail(pos, &start, &end);
+    }
+    if (bitmap_start == ~0UL)
+        panic("Couldn't find 0x%lx bytes for boot allocator.", bitmap_size);
 
     /* allow everything else to be allocated */
     total_pages = 0;
@@ -242,12 +179,39 @@ void memory_init(module_t *mod, int mcou
 
     numa_initmem_init(0, max_page);
 
+    /* Domain heap gets all the unclaimed memory. */
     end_boot_allocator();
 
-    /* Add memory between the beginning of the heap and the beginning
-     * of our text */
-    free_xenheap(heap_start, (ulong)_start);
-    setup_xenheap(mod, mcount);
+    /* Create initial xen heap by finding non-reserved memory. */
+    pos = boot_of_mem_avail(0, &start, &end);
+    while (pos >= 0) {
+        if (end == ~0UL)
+            end = xenheap_phys_end;
+
+        /* Problem: the bitmap itself is not reserved. */
+        if ((start >= bitmap_start) && (start < bitmap_end)) {
+            /* Start is inside bitmap. */
+            start = bitmap_end;
+        }
+        if ((end > bitmap_start) && (end <= bitmap_end)) {
+            /* End is inside bitmap. */
+            end = bitmap_start;
+        }
+        if ((start < bitmap_start) && (end > bitmap_end)) {
+            /* Range encompasses bitmap. First free low part, then high. */
+            xenheap_size += bitmap_start - start;
+            DBG("xenheap: %016lx - %016lx\n", start, bitmap_start);
+            init_xenheap_pages(start, bitmap_start);
+            start = bitmap_end;
+        }
+
+        xenheap_size += end - start;
+        DBG("xenheap: %016lx - %016lx\n", start, end);
+        init_xenheap_pages(start, end);
+
+        pos = boot_of_mem_avail(pos, &start, &end);
+    }
+
     printk("Xen Heap: %luMiB (%luKiB)\n",
            xenheap_size >> 20, xenheap_size >> 10);
 
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/mm.c
--- a/xen/arch/powerpc/mm.c     Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/mm.c     Thu Feb 15 14:09:39 2007 -0700
@@ -28,6 +28,7 @@
 #include <asm/init.h>
 #include <asm/page.h>
 #include <asm/string.h>
+#include <public/arch-powerpc.h>
 
 #ifdef VERBOSE
 #define MEM_LOG(_f, _a...)                                  \
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/of-devtree.c
--- a/xen/arch/powerpc/of-devtree.c     Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/of-devtree.c     Thu Feb 15 14:09:39 2007 -0700
@@ -358,7 +358,7 @@ static ofdn_t ofd_node_create(
     n->on_io = 0;
     n->on_pathlen = pathlen;
     n->on_last = ofd_pathsplit_left(path, '/', pathlen);
-    strlcpy(n->on_path, path, pathlen);
+    strlcpy(n->on_path, path, pathlen + 1);
 
     return pos;
 }
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/of-devtree.h
--- a/xen/arch/powerpc/of-devtree.h     Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/of-devtree.h     Thu Feb 15 14:09:39 2007 -0700
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright IBM Corp. 2005, 2006, 2007
  *
  * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
  */
@@ -23,6 +23,7 @@
 
 #include <xen/types.h>
 #include <xen/string.h>
+#include <xen/kernel.h>
 #include <public/xen.h>
 
 enum {
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/of_handler/Makefile
--- a/xen/arch/powerpc/of_handler/Makefile      Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/of_handler/Makefile      Thu Feb 15 14:09:39 2007 -0700
@@ -27,5 +27,5 @@ obj-y += strcmp.o
 obj-y += strcmp.o
 obj-y += strlen.o
 obj-y += strncmp.o
-obj-y += strncpy.o
+obj-y += strlcpy.o
 obj-y += strnlen.o
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/of_handler/strlcpy.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/powerpc/of_handler/strlcpy.c     Thu Feb 15 14:09:39 2007 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright IBM Corp. 2005, 2007
+ *
+ * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ *          Hollis Blanchard <hollisb@xxxxxxxxxx>
+ */
+
+#include <xen/string.h>
+
+size_t
+strlcpy(char *dest, const char *src, size_t n)
+{
+       size_t ret;
+    char *dp;
+
+    /* cases to consider:
+     *   dest is NULL, s is NULL;
+     *   src is empty (0);
+     *   src is not empty, less than n;
+     *   src is not empty, equal to n;
+     *   src is not empty, greater than n;
+     */
+
+    if (n <= 0) {
+        return 0;
+    }
+  
+    dp = dest;
+
+    do {
+        *dp++ = *src;
+        --n;
+        ++src;
+    } while ((*src != '\0') && (n > 1));
+
+    ret = n;
+  
+    /* clear remainder of buffer (if any);  ANSI semantics */
+    while (n > 0) {
+        *dp++ = '\0';
+        --n;
+    }
+    return ret;
+}
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/of_handler/strncpy.c
--- a/xen/arch/powerpc/of_handler/strncpy.c     Thu Feb 15 13:13:36 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Copyright (C) IBM Corp. 2005
- *
- * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
- */
-
-#include <xen/string.h>
-
-char *
-strncpy(char *dest, const char *src, size_t n)
-{
-    char *dp;
-
-    /* cases to consider:
-     *   dest is NULL, s is NULL;
-     *   src is empty (0);
-     *   src is not empty, less than n;
-     *   src is not empty, equal to n;
-     *   src is not empty, greater than n;
-     */
-
-    if (n <= 0) {
-        return dest;
-    }
-  
-    dp = dest;
-
-    do {
-        *dp++ = *src;
-        --n;
-        ++src;
-    } while ((*src != '\0') && (n > 0));
-  
-    /* clear remainder of buffer (if any);  ANSI semantics */
-    while (n > 0) {
-        *dp++ = '\0';
-        --n;
-    }
-    return dest;
-}
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/ofd_fixup.c
--- a/xen/arch/powerpc/ofd_fixup.c      Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/ofd_fixup.c      Thu Feb 15 14:09:39 2007 -0700
@@ -178,11 +178,20 @@ static ofdn_t ofd_cpus_props(void *m, st
     if (ofd_boot_cpu == -1)
         ofd_boot_cpu = c;
     while (c > 0) {
-        /* Since we are not MP yet we prune all but the booting cpu */
+        /* We do not use the OF tree to identify secondary processors
+         * so we must prune them from the tree */
         if (c == ofd_boot_cpu) {
+            ofdn_t p;
+
             ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE;
             ofd_prop_add(m, c, "ibm,pft-size",
                          ibm_pft_size, sizeof (ibm_pft_size));
+
+            /* get rid of non-standard properties */
+            p = ofd_prop_find(m, c, "cpu#");
+            if (p > 0) {
+                ofd_prop_remove(m, c, p);
+            }
 
             /* FIXME: Check the the "l2-cache" property who's
              * contents is an orphaned phandle? */
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/papr/xlate.c
--- a/xen/arch/powerpc/papr/xlate.c     Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/papr/xlate.c     Thu Feb 15 14:09:39 2007 -0700
@@ -72,6 +72,20 @@ static inline void pte_insert(union pte 
 }
 #endif
 
+/*
+ * POWER Arch 2.03 Sec 4.12.1 (Yes 970 is one)
+ *
+ *   when a tlbsync instruction has been executed by a processor in a
+ *   given partition, a ptesync instruction must be executed by that
+ *   processor before a tlbie or tlbsync instruction is executed by
+ *   another processor in that partition.
+ *
+ * So for now, here is a BFLock to deal with it, the lock should be per-domain.
+ *
+ * XXX Will need to audit all tlb usege soon enough.
+ */
+
+static DEFINE_SPINLOCK(native_tlbie_lock);
 static void pte_tlbie(union pte volatile *pte, ulong ptex)
 {
     ulong va;
@@ -91,6 +105,7 @@ static void pte_tlbie(union pte volatile
     va = (pi << 12) | (vsid << 28);
     va &= ~(0xffffULL << 48);
 
+    spin_lock(&native_tlbie_lock);
 #ifndef FLUSH_THE_WHOLE_THING
     if (pte->bits.l) {
         va |= (pte->bits.rpn & 1);
@@ -114,7 +129,7 @@ static void pte_tlbie(union pte volatile
         }
     }
 #endif
-
+    spin_unlock(&native_tlbie_lock);
 }
 
 long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn)
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/powerpc64/asm-offsets.c
--- a/xen/arch/powerpc/powerpc64/asm-offsets.c  Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/powerpc64/asm-offsets.c  Thu Feb 15 14:09:39 2007 -0700
@@ -48,6 +48,8 @@ void __dummy__(void)
     OFFSET(UREGS_ctr, struct cpu_user_regs, ctr);
     OFFSET(UREGS_xer, struct cpu_user_regs, xer);
     OFFSET(UREGS_hid4, struct cpu_user_regs, hid4);
+    OFFSET(UREGS_dar, struct cpu_user_regs, dar);
+    OFFSET(UREGS_dsisr, struct cpu_user_regs, dsisr);
     OFFSET(UREGS_cr, struct cpu_user_regs, cr);
     OFFSET(UREGS_fpscr, struct cpu_user_regs, fpscr);
     DEFINE(UREGS_sizeof, sizeof(struct cpu_user_regs));
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/powerpc64/exceptions.S
--- a/xen/arch/powerpc/powerpc64/exceptions.S   Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/powerpc64/exceptions.S   Thu Feb 15 14:09:39 2007 -0700
@@ -373,9 +373,15 @@ ex_machcheck_continued:
  * a better way, but this works for now. */
 ex_program_continued:
     SAVE_GPRS r14, r31, r1              /* save all the non-volatiles */
-    /* save hid4 for debug */
+
+    /* save these for debug, no needed for restore */
     mfspr r14, SPRN_HID4
     std r14, UREGS_hid4(r1)
+    mfdar r14
+    std r14, UREGS_dar(r1)
+    mfdsisr r14
+    stw r14, UREGS_dsisr(r1)
+
     mr r14, r0
     EXCEPTION_SAVE_STATE r1
     mr r4, r14
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/powerpc64/ppc970.c
--- a/xen/arch/powerpc/powerpc64/ppc970.c       Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/powerpc64/ppc970.c       Thu Feb 15 14:09:39 2007 -0700
@@ -129,7 +129,6 @@ unsigned int cpu_extent_order(void)
     return log_large_page_sizes[0] - PAGE_SHIFT;
 }
 
-
 /* This is more a platform thing than a CPU thing, but we only have
  * one platform now */
 int cpu_io_mfn(ulong mfn)
@@ -141,6 +140,12 @@ int cpu_io_mfn(ulong mfn)
 
     return 0;
 }
+
+int cpu_threads(int cpuid)
+{
+    return 1;
+}
+
 
 static u64 cpu0_hids[6];
 static u64 cpu0_hior;
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/powerpc64/ppc970_scom.c
--- a/xen/arch/powerpc/powerpc64/ppc970_scom.c  Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/powerpc64/ppc970_scom.c  Thu Feb 15 14:09:39 2007 -0700
@@ -158,7 +158,7 @@ void cpu_scom_init(void)
 {
 #ifdef CONFIG_SCOM
     ulong val;
-    if (PVR_REV(mfpvr()) == 0x0300) {
+    if (PVR_REV(mfpvr()) == PV_970FX) {
         /* these address are only good for 970FX */
         console_start_sync();
         if (!cpu_scom_read(SCOM_PTSR, &val))
@@ -174,7 +174,7 @@ void cpu_scom_AMCR(void)
 #ifdef CONFIG_SCOM
     ulong val;
 
-    if (PVR_REV(mfpvr()) == 0x0300) {
+    if (PVR_REV(mfpvr()) == PV_970FX) {
         /* these address are only good for 970FX */
         cpu_scom_read(SCOM_AMC_REG, &val);
         printk("SCOM AMCR: 0x%016lx\n", val);
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/powerpc64/traps.c
--- a/xen/arch/powerpc/powerpc64/traps.c        Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/powerpc64/traps.c        Thu Feb 15 14:09:39 2007 -0700
@@ -41,7 +41,15 @@ void show_registers(struct cpu_user_regs
            regs->pc, regs->msr,
            regs->lr, regs->ctr,
            regs->srr0, regs->srr1);
-    for (i=0; i<32; i+=4) {
+
+    /* These come in handy for debugging but are not always saved, so
+     * what is "actually" in the register should be good */
+    printk("dar %016lx dsisr %08x *** saved\n"
+           "dar %016lx dsisr %08x *** actual\n",
+           regs->dar, regs->dsisr,
+           mfdar(), mfdsisr());
+
+    for (i = 0; i < 32; i += 4) {
         printk("r%02i: %016lx %016lx %016lx %016lx\n", i,
             regs->gprs[i], regs->gprs[i+1], regs->gprs[i+2], regs->gprs[i+3]);
     }
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/setup.c  Thu Feb 15 14:09:39 2007 -0700
@@ -36,6 +36,7 @@
 #include <xen/symbols.h>
 #include <xen/keyhandler.h>
 #include <xen/numa.h>
+#include <xen/rcupdate.h>
 #include <acm/acm_hooks.h>
 #include <public/version.h>
 #include <asm/mpic.h>
@@ -166,9 +167,6 @@ static void __init start_of_day(void)
     set_current(idle_domain->vcpu[0]);
     idle_vcpu[0] = current;
 
-    /* for some reason we need to set our own bit in the thread map */
-    cpu_set(0, cpu_sibling_map[0]);
-
     initialize_keytable();
     /* Register another key that will allow for the the Harware Probe
      * to be contacted, this works with RiscWatch probes and should
@@ -179,6 +177,7 @@ static void __init start_of_day(void)
     register_keyhandler('D', key_ofdump , "Dump OF Devtree");
 
     timer_init();
+    rcu_init();
     serial_init_postirq();
     do_initcalls();
 }
@@ -234,6 +233,21 @@ static int kick_secondary_cpus(int maxcp
     int cpuid;
 
     for_each_present_cpu(cpuid) {
+        int threads;
+        int i;
+        
+        threads = cpu_threads(cpuid);
+        for (i = 0; i < threads; i++)
+            cpu_set(i, cpu_sibling_map[cpuid]);
+
+        /* For now everything is single core */
+        cpu_set(cpuid, cpu_core_map[cpuid]);
+
+        rcu_online_cpu(cpuid);
+
+        numa_set_node(cpuid, 0);
+        numa_add_cpu(cpuid);
+
         if (cpuid == 0)
             continue;
         if (cpuid >= maxcpus)
@@ -244,9 +258,6 @@ static int kick_secondary_cpus(int maxcp
         /* wait for it */
         while (!cpu_online(cpuid))
             cpu_relax();
-
-        numa_set_node(cpuid, 0);
-        numa_add_cpu(cpuid);
     }
 
     return 0;
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/sysctl.c
--- a/xen/arch/powerpc/sysctl.c Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/sysctl.c Thu Feb 15 14:09:39 2007 -0700
@@ -41,9 +41,13 @@ long arch_do_sysctl(struct xen_sysctl *s
     {
         xen_sysctl_physinfo_t *pi = &sysctl->u.physinfo;
 
-        pi->threads_per_core = 1;
-        pi->cores_per_socket = 1;
-        pi->sockets_per_node = 1;
+        pi->threads_per_core =
+            cpus_weight(cpu_sibling_map[0]);
+        pi->cores_per_socket =
+            cpus_weight(cpu_core_map[0]) / pi->threads_per_core;
+        pi->sockets_per_node = 
+            num_online_cpus() / cpus_weight(cpu_core_map[0]);
+
         pi->nr_nodes         = 1;
         pi->total_pages      = total_pages;
         pi->free_pages       = avail_domheap_pages();
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/time.c
--- a/xen/arch/powerpc/time.c   Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/time.c   Thu Feb 15 14:09:39 2007 -0700
@@ -85,12 +85,6 @@ void send_timer_event(struct vcpu *v)
     vcpu_unblock(v);
 }
 
-/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
-void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base)
-{
-    unimplemented();
-}
-
 void update_vcpu_system_time(struct vcpu *v)
 {
 }
diff -r ac18d251df63 -r 9529d667d042 xen/arch/powerpc/xen.lds.S
--- a/xen/arch/powerpc/xen.lds.S        Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/powerpc/xen.lds.S        Thu Feb 15 14:09:39 2007 -0700
@@ -17,6 +17,8 @@ SECTIONS
 SECTIONS
 {
   . = 0x00400000;
+  PROVIDE(_text = .);
+  PROVIDE(_stext = .);
   /* Read-only sections, merged into text segment: */
   .interp         : { *(.interp) } :text
   .hash           : { *(.hash) }
@@ -111,17 +113,26 @@ SECTIONS
     SORT(CONSTRUCTORS)
   }
 
+  . = ALIGN(4096);
+  __init_begin = .;
+  _sinittext = .;
+  .init.text : { *(.init.text) } : text
+  _einittext = .;
+  .init.data : { *(.init.data) } : text
   . = ALIGN(32);
   __setup_start = .;
-  .init.setup : { *(.init.setup) }
+  .init.setup : { *(.init.setup) } : text
   __setup_end = .;
   __initcall_start = .;
-  .initcall.init : { *(.initcall1.init) }
+  .initcall.init : { *(.initcall1.init) } : text
   __initcall_end = .;
-  __inithcall_start = .;
-  .inithcall.text : { *(.inithcall.text) }
-  __inithcall_end = .;
-
+  __init_hcall_start = .;
+  .init_hcall.init : { *(.init_hcall.init) } : text
+  __init_hcall_end = .;
+  __builtin_cmdline : { *(__builtin_cmdline) } : text
+  . = ALIGN(4096);
+  __init_end = .;
+       
   __per_cpu_start = .;
   .data.percpu : { *(.data.percpu) }
   __per_cpu_data_end = .;
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/domain.c     Thu Feb 15 14:09:39 2007 -0700
@@ -37,7 +37,7 @@
 #include <asm/i387.h>
 #include <asm/mpspec.h>
 #include <asm/ldt.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
 #include <asm/msr.h>
@@ -331,6 +331,7 @@ int vcpu_initialise(struct vcpu *v)
 
     pae_l3_cache_init(&v->arch.pae_l3_cache);
 
+    paging_vcpu_init(v);
 
     if ( is_hvm_domain(d) )
     {
@@ -424,7 +425,7 @@ int arch_domain_create(struct domain *d)
     HYPERVISOR_COMPAT_VIRT_START(d) = __HYPERVISOR_COMPAT_VIRT_START;
 #endif
 
-    shadow_domain_init(d);
+    paging_domain_init(d);
 
     if ( !is_idle_domain(d) )
     {
@@ -464,7 +465,7 @@ void arch_domain_destroy(struct domain *
         hvm_domain_destroy(d);
     }
 
-    shadow_final_teardown(d);
+    paging_final_teardown(d);
 
     free_xenheap_pages(
         d->arch.mm_perdomain_pt,
@@ -613,7 +614,7 @@ int arch_set_info_guest(
         {
             cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3]));
 
-            if ( shadow_mode_refcounts(d)
+            if ( paging_mode_refcounts(d)
                  ? !get_page(mfn_to_page(cr3_pfn), d)
                  : !get_page_and_type(mfn_to_page(cr3_pfn), d,
                                       PGT_base_page_table) )
@@ -631,7 +632,7 @@ int arch_set_info_guest(
 
             cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
 
-            if ( shadow_mode_refcounts(d)
+            if ( paging_mode_refcounts(d)
                  ? !get_page(mfn_to_page(cr3_pfn), d)
                  : !get_page_and_type(mfn_to_page(cr3_pfn), d,
                                     PGT_l3_page_table) )
@@ -652,8 +653,8 @@ int arch_set_info_guest(
     /* Don't redo final setup */
     set_bit(_VCPUF_initialised, &v->vcpu_flags);
 
-    if ( shadow_mode_enabled(d) )
-        shadow_update_paging_modes(v);
+    if ( paging_mode_enabled(d) )
+        paging_update_paging_modes(v);
 
     update_cr3(v);
 
@@ -1406,7 +1407,7 @@ static void vcpu_destroy_pagetables(stru
 
         if ( pfn != 0 )
         {
-            if ( shadow_mode_refcounts(d) )
+            if ( paging_mode_refcounts(d) )
                 put_page(mfn_to_page(pfn));
             else
                 put_page_and_type(mfn_to_page(pfn));
@@ -1427,7 +1428,7 @@ static void vcpu_destroy_pagetables(stru
     pfn = pagetable_get_pfn(v->arch.guest_table);
     if ( pfn != 0 )
     {
-        if ( shadow_mode_refcounts(d) )
+        if ( paging_mode_refcounts(d) )
             put_page(mfn_to_page(pfn));
         else
             put_page_and_type(mfn_to_page(pfn));
@@ -1443,7 +1444,7 @@ static void vcpu_destroy_pagetables(stru
     pfn = pagetable_get_pfn(v->arch.guest_table_user);
     if ( pfn != 0 )
     {
-        if ( shadow_mode_refcounts(d) )
+        if ( paging_mode_refcounts(d) )
             put_page(mfn_to_page(pfn));
         else
             put_page_and_type(mfn_to_page(pfn));
@@ -1464,8 +1465,8 @@ void domain_relinquish_resources(struct 
     for_each_vcpu ( d, v )
         vcpu_destroy_pagetables(v);
 
-    /* Tear down shadow mode stuff. */
-    shadow_teardown(d);
+    /* Tear down paging-assistance stuff. */
+    paging_teardown(d);
 
     /*
      * Relinquish GDT mappings. No need for explicit unmapping of the LDT as
@@ -1484,35 +1485,12 @@ void domain_relinquish_resources(struct 
 
 void arch_dump_domain_info(struct domain *d)
 {
-    if ( shadow_mode_enabled(d) )
-    {
-        printk("    shadow mode: ");
-        if ( d->arch.shadow.mode & SHM2_enable )
-            printk("enabled ");
-        if ( shadow_mode_refcounts(d) )
-            printk("refcounts ");
-        if ( shadow_mode_log_dirty(d) )
-            printk("log_dirty ");
-        if ( shadow_mode_translate(d) )
-            printk("translate ");
-        if ( shadow_mode_external(d) )
-            printk("external ");
-        printk("\n");
-    }
+    paging_dump_domain_info(d);
 }
 
 void arch_dump_vcpu_info(struct vcpu *v)
 {
-    if ( shadow_mode_enabled(v->domain) )
-    {
-        if ( v->arch.shadow.mode )
-            printk("    shadowed %u-on-%u, %stranslated\n",
-                   v->arch.shadow.mode->guest_levels,
-                   v->arch.shadow.mode->shadow_levels,
-                   shadow_vcpu_mode_translate(v) ? "" : "not ");
-        else
-            printk("    not shadowed\n");
-    }
+    paging_dump_vcpu_info(v);
 }
 
 /*
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/domain_build.c       Thu Feb 15 14:09:39 2007 -0700
@@ -25,7 +25,7 @@
 #include <asm/processor.h>
 #include <asm/desc.h>
 #include <asm/i387.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
 
 #include <public/version.h>
 #include <public/libelf.h>
@@ -777,8 +777,8 @@ int construct_dom0(struct domain *d,
         (void)alloc_vcpu(d, i, i);
 
     /* Set up CR3 value for write_ptbase */
-    if ( shadow_mode_enabled(v->domain) )
-        shadow_update_paging_modes(v);
+    if ( paging_mode_enabled(v->domain) )
+        paging_update_paging_modes(v);
     else
         update_cr3(v);
 
@@ -918,8 +918,8 @@ int construct_dom0(struct domain *d,
     regs->eflags = X86_EFLAGS_IF;
 
     if ( opt_dom0_shadow )
-        if ( shadow_enable(d, SHM2_enable) == 0 ) 
-            shadow_update_paging_modes(v);
+        if ( paging_enable(d, PG_SH_enable) == 0 ) 
+            paging_update_paging_modes(v);
 
     if ( supervisor_mode_kernel )
     {
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/domctl.c     Thu Feb 15 14:09:39 2007 -0700
@@ -19,7 +19,7 @@
 #include <xen/trace.h>
 #include <xen/console.h>
 #include <xen/iocap.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
 #include <asm/irq.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
@@ -42,7 +42,7 @@ long arch_do_domctl(
         d = get_domain_by_id(domctl->domain);
         if ( d != NULL )
         {
-            ret = shadow_domctl(d,
+            ret = paging_domctl(d,
                                 &domctl->u.shadow_op,
                                 guest_handle_cast(u_domctl, void));
             put_domain(d);
@@ -398,6 +398,7 @@ long arch_do_domctl(
 
         put_domain(d);
     }
+    break;
 
     case XEN_DOMCTL_get_address_size:
     {
@@ -411,7 +412,11 @@ long arch_do_domctl(
 
         ret = 0;
         put_domain(d);
-    }
+
+        if ( copy_to_guest(u_domctl, domctl, 1) )
+            ret = -EFAULT;
+    }
+    break;
 
     default:
         ret = -ENOSYS;
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/hvm/hvm.c    Thu Feb 15 14:09:39 2007 -0700
@@ -30,11 +30,10 @@
 #include <xen/hypercall.h>
 #include <xen/guest_access.h>
 #include <xen/event.h>
-#include <xen/shadow.h>
 #include <asm/current.h>
 #include <asm/e820.h>
 #include <asm/io.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
 #include <asm/regs.h>
 #include <asm/cpufeature.h>
 #include <asm/processor.h>
@@ -155,7 +154,7 @@ int hvm_domain_initialise(struct domain 
     spin_lock_init(&d->arch.hvm_domain.buffered_io_lock);
     spin_lock_init(&d->arch.hvm_domain.irq_lock);
 
-    rc = shadow_enable(d, SHM2_refcounts|SHM2_translate|SHM2_external);
+    rc = paging_enable(d, PG_SH_enable|PG_refcounts|PG_translate|PG_external);
     if ( rc != 0 )
         return rc;
 
@@ -383,7 +382,7 @@ static int __hvm_copy(void *buf, paddr_t
         count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), todo);
 
         if ( virt )
-            mfn = get_mfn_from_gpfn(shadow_gva_to_gfn(current, addr));
+            mfn = get_mfn_from_gpfn(paging_gva_to_gfn(current, addr));
         else
             mfn = get_mfn_from_gpfn(addr >> PAGE_SHIFT);
 
@@ -600,7 +599,7 @@ void hvm_do_hypercall(struct cpu_user_re
         return;
     }
 
-    if ( current->arch.shadow.mode->guest_levels == 4 )
+    if ( current->arch.paging.mode->guest_levels == 4 )
     {
         pregs->rax = hvm_hypercall64_table[pregs->rax](pregs->rdi,
                                                        pregs->rsi,
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/hvm/io.c     Thu Feb 15 14:09:39 2007 -0700
@@ -32,7 +32,7 @@
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/apic.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
 #include <asm/hvm/vpt.h>
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/hvm/platform.c       Thu Feb 15 14:09:39 2007 -0700
@@ -21,7 +21,6 @@
 #include <xen/config.h>
 #include <xen/types.h>
 #include <xen/mm.h>
-#include <xen/shadow.h>
 #include <xen/domain_page.h>
 #include <asm/page.h>
 #include <xen/event.h>
@@ -29,6 +28,7 @@
 #include <xen/sched.h>
 #include <asm/regs.h>
 #include <asm/x86_emulate.h>
+#include <asm/paging.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
 #include <asm/hvm/io.h>
@@ -690,6 +690,39 @@ static int mmio_decode(int address_bytes
         } else
             return DECODE_failure;
 
+    case 0xFE:
+    case 0xFF:
+    {
+        unsigned char ins_subtype = (opcode[1] >> 3) & 7;
+
+        if ( opcode[0] == 0xFE ) {
+            *op_size = BYTE;
+            GET_OP_SIZE_FOR_BYTE(size_reg);
+        } else {
+            GET_OP_SIZE_FOR_NONEBYTE(*op_size);
+            size_reg = *op_size;
+        }
+
+        mmio_op->immediate = 1;
+        mmio_op->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
+        mmio_op->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
+
+        switch ( ins_subtype ) {
+        case 0: /* inc */
+            mmio_op->instr = INSTR_ADD;
+            return DECODE_success;
+
+        case 1: /* dec */
+            mmio_op->instr = INSTR_SUB;
+            return DECODE_success;
+
+        default:
+            printk("%x/%x, This opcode isn't handled yet!\n",
+                   *opcode, ins_subtype);
+            return DECODE_failure;
+        }
+    }
+
     case 0x0F:
         break;
 
@@ -809,7 +842,7 @@ void send_pio_req(unsigned long port, un
     if ( value_is_ptr )   /* get physical address of data */
     {
         if ( hvm_paging_enabled(current) )
-            p->data = shadow_gva_to_gpa(current, value);
+            p->data = paging_gva_to_gpa(current, value);
         else
             p->data = value; /* guest VA == guest PA */
     }
@@ -865,7 +898,7 @@ static void send_mmio_req(unsigned char 
     if ( value_is_ptr )
     {
         if ( hvm_paging_enabled(v) )
-            p->data = shadow_gva_to_gpa(v, value);
+            p->data = paging_gva_to_gpa(v, value);
         else
             p->data = value; /* guest VA == guest PA */
     }
@@ -981,7 +1014,7 @@ void handle_mmio(unsigned long gpa)
         if ( ad_size == WORD )
             addr &= 0xFFFF;
         addr += hvm_get_segment_base(v, x86_seg_es);
-        if ( shadow_gva_to_gpa(v, addr) == gpa )
+        if ( paging_gva_to_gpa(v, addr) == gpa )
         {
             enum x86_segment seg;
 
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c       Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/hvm/svm/intr.c       Thu Feb 15 14:09:39 2007 -0700
@@ -24,10 +24,10 @@
 #include <xen/lib.h>
 #include <xen/trace.h>
 #include <xen/errno.h>
-#include <xen/shadow.h>
 #include <asm/cpufeature.h>
 #include <asm/processor.h>
 #include <asm/msr.h>
+#include <asm/paging.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/io.h>
 #include <asm/hvm/support.h>
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/hvm/svm/svm.c        Thu Feb 15 14:09:39 2007 -0700
@@ -29,7 +29,8 @@
 #include <xen/domain_page.h>
 #include <asm/current.h>
 #include <asm/io.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
+#include <asm/p2m.h>
 #include <asm/regs.h>
 #include <asm/cpufeature.h>
 #include <asm/processor.h>
@@ -491,9 +492,6 @@ int svm_vmcb_restore(struct vcpu *v, str
         v->arch.guest_table = pagetable_from_pfn(mfn);
         if (old_base_mfn)
              put_page(mfn_to_page(old_base_mfn));
-        /*
-         * arch.shadow_table should now hold the next CR3 for shadow
-         */
         v->arch.hvm_svm.cpu_cr3 = c->cr3;
     }
 
@@ -560,7 +558,7 @@ int svm_vmcb_restore(struct vcpu *v, str
     vmcb->sysenter_esp = c->sysenter_esp;
     vmcb->sysenter_eip = c->sysenter_eip;
 
-    shadow_update_paging_modes(v);
+    paging_update_paging_modes(v);
     return 0;
  
  bad_cr3:
@@ -1095,7 +1093,7 @@ static int svm_do_page_fault(unsigned lo
                 "svm_do_page_fault = 0x%lx, eip = %lx, error_code = %lx",
                 va, (unsigned long)current->arch.hvm_svm.vmcb->rip,
                 (unsigned long)regs->error_code);
-    return shadow_fault(va, regs); 
+    return paging_fault(va, regs); 
 }
 
 
@@ -1730,7 +1728,7 @@ static int svm_set_cr0(unsigned long val
         v->arch.guest_table = pagetable_from_pfn(mfn);
         if ( old_base_mfn )
             put_page(mfn_to_page(old_base_mfn));
-        shadow_update_paging_modes(v);
+        paging_update_paging_modes(v);
 
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", 
                     (unsigned long) (mfn << PAGE_SHIFT));
@@ -1753,7 +1751,7 @@ static int svm_set_cr0(unsigned long val
             svm_inject_exception(v, TRAP_gp_fault, 1, 0);
             return 0;
         }
-        shadow_update_paging_modes(v);
+        paging_update_paging_modes(v);
     }
     else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
     {
@@ -1763,7 +1761,7 @@ static int svm_set_cr0(unsigned long val
             clear_bit(SVM_CPU_STATE_LMA_ENABLED, &v->arch.hvm_svm.cpu_state);
         }
         /* we should take care of this kind of situation */
-        shadow_update_paging_modes(v);
+        paging_update_paging_modes(v);
     }
 
     return 1;
@@ -1866,7 +1864,7 @@ static int mov_to_cr(int gpreg, int cr, 
             mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
             if (mfn != pagetable_get_pfn(v->arch.guest_table))
                 goto bad_cr3;
-            shadow_update_cr3(v);
+            paging_update_cr3(v);
         }
         else 
         {
@@ -1917,7 +1915,7 @@ static int mov_to_cr(int gpreg, int cr, 
                 v->arch.guest_table = pagetable_from_pfn(mfn);
                 if ( old_base_mfn )
                     put_page(mfn_to_page(old_base_mfn));
-                shadow_update_paging_modes(v);
+                paging_update_paging_modes(v);
 
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
                             (unsigned long) (mfn << PAGE_SHIFT));
@@ -1946,7 +1944,7 @@ static int mov_to_cr(int gpreg, int cr, 
          * all TLB entries except global entries.
          */
         if ((old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE))
-            shadow_update_paging_modes(v);
+            paging_update_paging_modes(v);
         break;
 
     case 8:
@@ -2289,7 +2287,7 @@ void svm_handle_invlpg(const short invlp
         __update_guest_eip (vmcb, inst_len);
     }
 
-    shadow_invlpg(v, g_vaddr);
+    paging_invlpg(v, g_vaddr);
 }
 
 
@@ -2660,7 +2658,7 @@ void walk_shadow_and_guest_pt(unsigned l
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     paddr_t gpa;
 
-    gpa = shadow_gva_to_gpa(current, gva);
+    gpa = paging_gva_to_gpa(current, gva);
     printk("gva = %lx, gpa=%"PRIpaddr", gCR3=%x\n", gva, gpa, (u32)vmcb->cr3);
     if( !svm_paging_enabled(v) || mmio_space(gpa) )
         return;
@@ -2681,7 +2679,7 @@ void walk_shadow_and_guest_pt(unsigned l
     shadow_sync_va(v, gva);
 
     gpte.l1 = 0;
-    __copy_from_user(&gpte, &linear_pg_table[ l1_linear_offset(gva) ],
+    __copy_from_user(&gpte, &__linear_l1_table[ l1_linear_offset(gva) ],
                      sizeof(gpte) );
     printk( "G-PTE = %x, flags=%x\n", gpte.l1, l1e_get_flags(gpte) );
 
@@ -2726,7 +2724,7 @@ asmlinkage void svm_vmexit_handler(struc
         if (svm_dbg_on && exit_reason == VMEXIT_EXCEPTION_PF) 
         {
             if (svm_paging_enabled(v) && 
-                !mmio_space(shadow_gva_to_gpa(current, vmcb->exitinfo2)))
+                !mmio_space(paging_gva_to_gpa(current, vmcb->exitinfo2)))
             {
                 printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
                        "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64", "
@@ -2736,7 +2734,7 @@ asmlinkage void svm_vmexit_handler(struc
                        (u64)vmcb->exitinfo1,
                        (u64)vmcb->exitinfo2,
                        (u64)vmcb->exitintinfo.bytes,
-                       (u64)shadow_gva_to_gpa(current, vmcb->exitinfo2));
+                       (u64)paging_gva_to_gpa(current, vmcb->exitinfo2));
             }
             else 
             {
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Thu Feb 15 14:09:39 2007 -0700
@@ -23,10 +23,10 @@
 #include <xen/mm.h>
 #include <xen/lib.h>
 #include <xen/errno.h>
-#include <xen/shadow.h>
 #include <asm/cpufeature.h>
 #include <asm/processor.h>
 #include <asm/msr.h>
+#include <asm/paging.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/io.h>
 #include <asm/hvm/support.h>
@@ -196,7 +196,7 @@ static int construct_vmcb(struct vcpu *v
         read_cr4() & ~(X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE);
     vmcb->cr4 = arch_svm->cpu_shadow_cr4 | SVM_CR4_HOST_MASK;
 
-    shadow_update_paging_modes(v);
+    paging_update_paging_modes(v);
     vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
 
     arch_svm->vmcb->exception_intercepts = MONITOR_DEFAULT_EXCEPTION_BITMAP;
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/hvm/vlapic.c Thu Feb 15 14:09:39 2007 -0700
@@ -22,7 +22,6 @@
 #include <xen/types.h>
 #include <xen/mm.h>
 #include <xen/xmalloc.h>
-#include <xen/shadow.h>
 #include <xen/domain_page.h>
 #include <asm/page.h>
 #include <xen/event.h>
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Thu Feb 15 14:09:39 2007 -0700
@@ -448,7 +448,7 @@ static void construct_vmcs(struct vcpu *
 
     vmx_vmcs_exit(v);
 
-    shadow_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */
+    paging_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */
 }
 
 int vmx_create_vmcs(struct vcpu *v)
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Thu Feb 15 14:09:39 2007 -0700
@@ -35,12 +35,13 @@
 #include <asm/types.h>
 #include <asm/msr.h>
 #include <asm/spinlock.h>
+#include <asm/paging.h>
+#include <asm/p2m.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
 #include <asm/hvm/vmx/vmx.h>
 #include <asm/hvm/vmx/vmcs.h>
 #include <asm/hvm/vmx/cpu.h>
-#include <asm/shadow.h>
 #include <public/sched.h>
 #include <public/hvm/ioreq.h>
 #include <asm/hvm/vpic.h>
@@ -484,9 +485,6 @@ int vmx_vmcs_restore(struct vcpu *v, str
         v->arch.guest_table = pagetable_from_pfn(mfn);
         if (old_base_mfn)
              put_page(mfn_to_page(old_base_mfn));
-        /*
-         * arch.shadow_table should now hold the next CR3 for shadow
-         */
         v->arch.hvm_vmx.cpu_cr3 = c->cr3;
     }
 
@@ -556,7 +554,7 @@ int vmx_vmcs_restore(struct vcpu *v, str
 
     vmx_vmcs_exit(v);
 
-    shadow_update_paging_modes(v);
+    paging_update_paging_modes(v);
     return 0;
 
  bad_cr3:
@@ -1126,7 +1124,7 @@ static int vmx_do_page_fault(unsigned lo
     }
 #endif
 
-    result = shadow_fault(va, regs);
+    result = paging_fault(va, regs);
 
     TRACE_VMEXIT(2, result);
 #if 0
@@ -1277,7 +1275,7 @@ static void vmx_do_invlpg(unsigned long 
      * We do the safest things first, then try to update the shadow
      * copying from guest
      */
-    shadow_invlpg(v, va);
+    paging_invlpg(v, va);
 }
 
 
@@ -1691,9 +1689,6 @@ static int vmx_world_restore(struct vcpu
         v->arch.guest_table = pagetable_from_pfn(mfn);
         if (old_base_mfn)
              put_page(mfn_to_page(old_base_mfn));
-        /*
-         * arch.shadow_table should now hold the next CR3 for shadow
-         */
         v->arch.hvm_vmx.cpu_cr3 = c->cr3;
     }
 
@@ -1753,7 +1748,7 @@ static int vmx_world_restore(struct vcpu
     __vmwrite(GUEST_LDTR_BASE, c->ldtr_base);
     __vmwrite(GUEST_LDTR_AR_BYTES, c->ldtr_arbytes.bytes);
 
-    shadow_update_paging_modes(v);
+    paging_update_paging_modes(v);
     return 0;
 
  bad_cr3:
@@ -1906,14 +1901,11 @@ static int vmx_set_cr0(unsigned long val
         v->arch.guest_table = pagetable_from_pfn(mfn);
         if (old_base_mfn)
             put_page(mfn_to_page(old_base_mfn));
-        shadow_update_paging_modes(v);
+        paging_update_paging_modes(v);
 
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
                     (unsigned long) (mfn << PAGE_SHIFT));
 
-        /*
-         * arch->shadow_table should hold the next CR3 for shadow
-         */
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx",
                     v->arch.hvm_vmx.cpu_cr3, mfn);
     }
@@ -1981,7 +1973,7 @@ static int vmx_set_cr0(unsigned long val
             vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
             __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
         }
-        shadow_update_paging_modes(v);
+        paging_update_paging_modes(v);
     }
 
     return 1;
@@ -2070,7 +2062,7 @@ static int mov_to_cr(int gp, int cr, str
             mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
             if (mfn != pagetable_get_pfn(v->arch.guest_table))
                 goto bad_cr3;
-            shadow_update_cr3(v);
+            paging_update_cr3(v);
         } else {
             /*
              * If different, make a shadow. Check if the PDBR is valid
@@ -2084,9 +2076,6 @@ static int mov_to_cr(int gp, int cr, str
             v->arch.guest_table = pagetable_from_pfn(mfn);
             if (old_base_mfn)
                 put_page(mfn_to_page(old_base_mfn));
-            /*
-             * arch.shadow_table should now hold the next CR3 for shadow
-             */
             v->arch.hvm_vmx.cpu_cr3 = value;
             update_cr3(v);
             HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value);
@@ -2120,9 +2109,6 @@ static int mov_to_cr(int gp, int cr, str
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
                             (unsigned long) (mfn << PAGE_SHIFT));
 
-                /*
-                 * arch->shadow_table should hold the next CR3 for shadow
-                 */
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, 
                             "Update CR3 value = %lx, mfn = %lx",
                             v->arch.hvm_vmx.cpu_cr3, mfn);
@@ -2148,7 +2134,7 @@ static int mov_to_cr(int gp, int cr, str
          * all TLB entries except global entries.
          */
         if ( (old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE) )
-            shadow_update_paging_modes(v);
+            paging_update_paging_modes(v);
         break;
 
     case 8:
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/mm.c Thu Feb 15 14:09:39 2007 -0700
@@ -99,6 +99,7 @@
 #include <xen/event.h>
 #include <xen/iocap.h>
 #include <xen/guest_access.h>
+#include <asm/paging.h>
 #include <asm/shadow.h>
 #include <asm/page.h>
 #include <asm/flushtlb.h>
@@ -373,9 +374,6 @@ void write_ptbase(struct vcpu *v)
 /* Should be called after CR3 is updated.
  * Updates vcpu->arch.cr3 and, for HVM guests, vcpu->arch.hvm_vcpu.cpu_cr3.
  * 
- * Also updates other state derived from CR3 (vcpu->arch.guest_vtable,
- * shadow_vtable, etc).
- *
  * Uses values found in vcpu->arch.(guest_table and guest_table_user), and
  * for HVM guests, arch.monitor_table and hvm's guest CR3.
  *
@@ -385,9 +383,9 @@ void update_cr3(struct vcpu *v)
 {
     unsigned long cr3_mfn=0;
 
-    if ( shadow_mode_enabled(v->domain) )
-    {
-        shadow_update_cr3(v);
+    if ( paging_mode_enabled(v->domain) )
+    {
+        paging_update_cr3(v);
         return;
     }
 
@@ -615,7 +613,7 @@ get_page_from_l1e(
      * qemu-dm helper process in dom0 to map the domain's memory without
      * messing up the count of "real" writable mappings.) */
     okay = (((l1e_get_flags(l1e) & _PAGE_RW) && 
-             !(unlikely(shadow_mode_external(d) && (d != current->domain))))
+             !(unlikely(paging_mode_external(d) && (d != current->domain))))
             ? get_page_and_type(page, d, PGT_writable_page)
             : get_page(page, d));
     if ( !okay )
@@ -804,9 +802,9 @@ void put_page_from_l1e(l1_pgentry_t l1e,
     }
 
     /* Remember we didn't take a type-count of foreign writable mappings
-     * to shadow external domains */
+     * to paging-external domains */
     if ( (l1e_get_flags(l1e) & _PAGE_RW) && 
-         !(unlikely((e != d) && shadow_mode_external(e))) )
+         !(unlikely((e != d) && paging_mode_external(e))) )
     {
         put_page_and_type(page);
     }
@@ -976,6 +974,19 @@ static void pae_flush_pgd(
     l3_pgentry_t  *l3tab_ptr;
     struct pae_l3_cache *cache;
 
+    if ( unlikely(shadow_mode_enabled(d)) )
+    {
+        cpumask_t m = CPU_MASK_NONE;
+        /* Re-shadow this l3 table on any vcpus that are using it */
+        for_each_vcpu ( d, v )
+            if ( pagetable_get_pfn(v->arch.guest_table) == mfn )
+            {
+                paging_update_cr3(v);
+                cpus_or(m, m, v->vcpu_dirty_cpumask);
+            }
+        flush_tlb_mask(m);
+    }
+
     /* If below 4GB then the pgdir is not shadowed in low memory. */
     if ( !l3tab_needs_shadow(mfn) )
         return;
@@ -1259,20 +1270,13 @@ static inline int update_intpte(intpte_t
 {
     int rv = 1;
 #ifndef PTE_UPDATE_WITH_CMPXCHG
-    if ( unlikely(shadow_mode_enabled(v->domain)) )
-        rv = shadow_write_guest_entry(v, p, new, _mfn(mfn));
-    else
-        rv = (!__copy_to_user(p, &new, sizeof(new)));
+    rv = paging_write_guest_entry(v, p, new, _mfn(mfn));
 #else
     {
         intpte_t t = old;
         for ( ; ; )
         {
-            if ( unlikely(shadow_mode_enabled(v->domain)) )
-                rv = shadow_cmpxchg_guest_entry(v, p, &t, new, _mfn(mfn));
-            else
-                rv = (!cmpxchg_user(p, t, new));
-
+            rv = paging_cmpxchg_guest_entry(v, p, &t, new, _mfn(mfn));
             if ( unlikely(rv == 0) )
             {
                 MEM_LOG("Failed to update %" PRIpte " -> %" PRIpte
@@ -1310,7 +1314,7 @@ static int mod_l1_entry(l1_pgentry_t *pl
     if ( unlikely(__copy_from_user(&ol1e, pl1e, sizeof(ol1e)) != 0) )
         return 0;
 
-    if ( unlikely(shadow_mode_refcounts(d)) )
+    if ( unlikely(paging_mode_refcounts(d)) )
         return UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, current);
 
     if ( l1e_get_flags(nl1e) & _PAGE_PRESENT )
@@ -1572,7 +1576,7 @@ void free_page_type(struct page_info *pa
          */
         queue_deferred_ops(owner, DOP_FLUSH_ALL_TLBS);
 
-        if ( unlikely(shadow_mode_enabled(owner)) )
+        if ( unlikely(paging_mode_enabled(owner)) )
         {
             /* A page table is dirtied when its type count becomes zero. */
             mark_dirty(owner, page_to_mfn(page));
@@ -1771,7 +1775,7 @@ int new_guest_cr3(unsigned long mfn)
 #ifdef CONFIG_COMPAT
     if ( IS_COMPAT(d) )
     {
-        okay = shadow_mode_refcounts(d)
+        okay = paging_mode_refcounts(d)
             ? 0 /* Old code was broken, but what should it be? */
             : mod_l4_entry(__va(pagetable_get_paddr(v->arch.guest_table)),
                            l4e_from_pfn(mfn, (_PAGE_PRESENT|_PAGE_RW|
@@ -1788,7 +1792,7 @@ int new_guest_cr3(unsigned long mfn)
         return 1;
     }
 #endif
-    okay = shadow_mode_refcounts(d)
+    okay = paging_mode_refcounts(d)
         ? get_page_from_pagenr(mfn, d)
         : get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d);
     if ( unlikely(!okay) )
@@ -1808,7 +1812,7 @@ int new_guest_cr3(unsigned long mfn)
 
     if ( likely(old_base_mfn != 0) )
     {
-        if ( shadow_mode_refcounts(d) )
+        if ( paging_mode_refcounts(d) )
             put_page(mfn_to_page(old_base_mfn));
         else
             put_page_and_type(mfn_to_page(old_base_mfn));
@@ -1861,7 +1865,7 @@ static int set_foreigndom(domid_t domid)
                 d->domain_id);
         okay = 0;
     }
-    else if ( unlikely(shadow_mode_translate(d)) )
+    else if ( unlikely(paging_mode_translate(d)) )
     {
         MEM_LOG("Cannot mix foreign mappings with translated domains");
         okay = 0;
@@ -2007,7 +2011,7 @@ int do_mmuext_op(
             if ( (op.cmd - MMUEXT_PIN_L1_TABLE) > (CONFIG_PAGING_LEVELS - 1) )
                 break;
 
-            if ( shadow_mode_refcounts(FOREIGNDOM) )
+            if ( paging_mode_refcounts(FOREIGNDOM) )
                 break;
 
             okay = get_page_and_type_from_pagenr(mfn, type, FOREIGNDOM);
@@ -2032,7 +2036,7 @@ int do_mmuext_op(
             break;
 
         case MMUEXT_UNPIN_TABLE:
-            if ( shadow_mode_refcounts(d) )
+            if ( paging_mode_refcounts(d) )
                 break;
 
             if ( unlikely(!(okay = get_page_from_pagenr(mfn, d))) )
@@ -2070,7 +2074,7 @@ int do_mmuext_op(
             }
             if (likely(mfn != 0))
             {
-                if ( shadow_mode_refcounts(d) )
+                if ( paging_mode_refcounts(d) )
                     okay = get_page_from_pagenr(mfn, d);
                 else
                     okay = get_page_and_type_from_pagenr(
@@ -2087,7 +2091,7 @@ int do_mmuext_op(
                 v->arch.guest_table_user = pagetable_from_pfn(mfn);
                 if ( old_mfn != 0 )
                 {
-                    if ( shadow_mode_refcounts(d) )
+                    if ( paging_mode_refcounts(d) )
                         put_page(mfn_to_page(old_mfn));
                     else
                         put_page_and_type(mfn_to_page(old_mfn));
@@ -2101,8 +2105,8 @@ int do_mmuext_op(
             break;
     
         case MMUEXT_INVLPG_LOCAL:
-            if ( !shadow_mode_enabled(d) 
-                 || shadow_invlpg(v, op.arg1.linear_addr) != 0 )
+            if ( !paging_mode_enabled(d) 
+                 || paging_invlpg(v, op.arg1.linear_addr) != 0 )
                 local_flush_tlb_one(op.arg1.linear_addr);
             break;
 
@@ -2149,7 +2153,7 @@ int do_mmuext_op(
             unsigned long ptr  = op.arg1.linear_addr;
             unsigned long ents = op.arg2.nr_ents;
 
-            if ( shadow_mode_external(d) )
+            if ( paging_mode_external(d) )
             {
                 MEM_LOG("ignoring SET_LDT hypercall from external "
                         "domain %u", d->domain_id);
@@ -2298,9 +2302,9 @@ int do_mmu_update(
             case PGT_l3_page_table:
             case PGT_l4_page_table:
             {
-                if ( shadow_mode_refcounts(d) )
+                if ( paging_mode_refcounts(d) )
                 {
-                    MEM_LOG("mmu update on shadow-refcounted domain!");
+                    MEM_LOG("mmu update on auto-refcounted domain!");
                     break;
                 }
 
@@ -2351,13 +2355,7 @@ int do_mmu_update(
                 if ( unlikely(!get_page_type(page, PGT_writable_page)) )
                     break;
 
-                if ( unlikely(shadow_mode_enabled(d)) )
-                    okay = shadow_write_guest_entry(v, va, req.val, _mfn(mfn));
-                else
-                {
-                    *(intpte_t *)va = req.val;
-                    okay = 1;
-                }
+                okay = paging_write_guest_entry(v, va, req.val, _mfn(mfn));
 
                 put_page_type(page);
             }
@@ -2380,9 +2378,9 @@ int do_mmu_update(
                 break;
             }
 
-            if ( unlikely(shadow_mode_translate(FOREIGNDOM)) )
+            if ( unlikely(paging_mode_translate(FOREIGNDOM)) )
             {
-                MEM_LOG("Mach-phys update on shadow-translate guest");
+                MEM_LOG("Mach-phys update on auto-translate guest");
                 break;
             }
 
@@ -2472,7 +2470,7 @@ static int create_grant_pte_mapping(
         goto failed;
     } 
 
-    if ( !shadow_mode_refcounts(d) )
+    if ( !paging_mode_refcounts(d) )
         put_page_from_l1e(ol1e, d);
 
     put_page_type(page);
@@ -2578,7 +2576,7 @@ static int create_grant_va_mapping(
     if ( !okay )
             return GNTST_general_error;
 
-    if ( !shadow_mode_refcounts(d) )
+    if ( !paging_mode_refcounts(d) )
         put_page_from_l1e(ol1e, d);
 
     return GNTST_okay;
@@ -2704,7 +2702,7 @@ int do_update_va_mapping(unsigned long v
 
     perfc_incrc(calls_to_update_va);
 
-    if ( unlikely(!__addr_ok(va) && !shadow_mode_external(d)) )
+    if ( unlikely(!__addr_ok(va) && !paging_mode_external(d)) )
         return -EINVAL;
 
     LOCK_BIGLOCK(d);
@@ -2744,8 +2742,8 @@ int do_update_va_mapping(unsigned long v
         switch ( (bmap_ptr = flags & ~UVMF_FLUSHTYPE_MASK) )
         {
         case UVMF_LOCAL:
-            if ( !shadow_mode_enabled(d) 
-                 || (shadow_invlpg(current, va) != 0) ) 
+            if ( !paging_mode_enabled(d) 
+                 || (paging_invlpg(current, va) != 0) ) 
                 local_flush_tlb_one(va);
             break;
         case UVMF_ALL:
@@ -2980,7 +2978,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
             break;
         }
 
-        if ( !shadow_mode_translate(d) || (mfn == 0) )
+        if ( !paging_mode_translate(d) || (mfn == 0) )
         {
             put_domain(d);
             return -EINVAL;
@@ -3235,17 +3233,12 @@ static int ptwr_emulated_update(
     if ( do_cmpxchg )
     {
         int okay;
+        intpte_t t = old;
         ol1e = l1e_from_intpte(old);
 
-        if ( shadow_mode_enabled(d) )
-        {
-            intpte_t t = old;
-            okay = shadow_cmpxchg_guest_entry(v, (intpte_t *) pl1e, 
-                                              &t, val, _mfn(mfn));
-            okay = (okay && t == old);
-        }
-        else 
-            okay = (cmpxchg((intpte_t *)pl1e, old, val) == old);
+        okay = paging_cmpxchg_guest_entry(v, (intpte_t *) pl1e, 
+                                          &t, val, _mfn(mfn));
+        okay = (okay && t == old);
 
         if ( !okay )
         {
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/mm/Makefile
--- a/xen/arch/x86/mm/Makefile  Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/mm/Makefile  Thu Feb 15 14:09:39 2007 -0700
@@ -1,1 +1,4 @@ subdir-y += shadow
 subdir-y += shadow
+
+obj-y += paging.o
+obj-y += p2m.o
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/mm/p2m.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/mm/p2m.c     Thu Feb 15 14:09:39 2007 -0700
@@ -0,0 +1,699 @@
+/******************************************************************************
+ * arch/x86/mm/p2m.c
+ *
+ * physical-to-machine mappings for automatically-translated domains.
+ * 
+ * Parts of this code are Copyright (c) 2007 by Advanced Micro Devices.
+ * Parts of this code are Copyright (c) 2006 by XenSource Inc.
+ * Parts of this code are Copyright (c) 2006 by Michael A Fetterman
+ * Parts based on earlier work by Michael A Fetterman, 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
+ */
+
+#include <asm/domain.h>
+#include <asm/page.h>
+#include <asm/paging.h>
+#include <asm/p2m.h>
+
+/* Debugging and auditing of the P2M code? */
+#define P2M_AUDIT     0
+#define P2M_DEBUGGING 1
+
+/* The P2M lock.  This protects all updates to the p2m table.
+ * Updates are expected to be safe against concurrent reads, 
+ * which do *not* require the lock */
+
+#define p2m_lock_init(_d)                            \
+    do {                                             \
+        spin_lock_init(&(_d)->arch.p2m.lock);        \
+        (_d)->arch.p2m.locker = -1;                  \
+        (_d)->arch.p2m.locker_function = "nobody";   \
+    } while (0)
+
+#define p2m_lock(_d)                                                \
+    do {                                                            \
+        if ( unlikely((_d)->arch.p2m.locker == current->processor) )\
+        {                                                           \
+            printk("Error: p2m lock held by %s\n",                  \
+                   (_d)->arch.p2m.locker_function);                 \
+            BUG();                                                  \
+        }                                                           \
+        spin_lock(&(_d)->arch.p2m.lock);                            \
+        ASSERT((_d)->arch.p2m.locker == -1);                        \
+        (_d)->arch.p2m.locker = current->processor;                 \
+        (_d)->arch.p2m.locker_function = __func__;                  \
+    } while (0)
+
+#define p2m_unlock(_d)                                              \
+    do {                                                            \
+        ASSERT((_d)->arch.p2m.locker == current->processor); \
+        (_d)->arch.p2m.locker = -1;                          \
+        (_d)->arch.p2m.locker_function = "nobody";           \
+        spin_unlock(&(_d)->arch.p2m.lock);                   \
+    } while (0)
+
+
+
+/* Printouts */
+#define P2M_PRINTK(_f, _a...)                                \
+    debugtrace_printk("p2m: %s(): " _f, __func__, ##_a)
+#define P2M_ERROR(_f, _a...)                                 \
+    printk("pg error: %s(): " _f, __func__, ##_a)
+#if P2M_DEBUGGING
+#define P2M_DEBUG(_f, _a...)                                 \
+    debugtrace_printk("p2mdebug: %s(): " _f, __func__, ##_a)
+#else
+#define P2M_DEBUG(_f, _a...) do { (void)(_f); } while(0) 
+#endif
+
+
+/* Override macros from asm/page.h to make them work with mfn_t */
+#undef mfn_to_page
+#define mfn_to_page(_m) (frame_table + mfn_x(_m))
+#undef mfn_valid
+#define mfn_valid(_mfn) (mfn_x(_mfn) < max_page)
+#undef page_to_mfn
+#define page_to_mfn(_pg) (_mfn((_pg) - frame_table))
+
+
+
+// Find the next level's P2M entry, checking for out-of-range gfn's...
+// Returns NULL on error.
+//
+static l1_pgentry_t *
+p2m_find_entry(void *table, unsigned long *gfn_remainder,
+                   unsigned long gfn, u32 shift, u32 max)
+{
+    u32 index;
+
+    index = *gfn_remainder >> shift;
+    if ( index >= max )
+    {
+        P2M_DEBUG("gfn=0x%lx out of range "
+                  "(gfn_remainder=0x%lx shift=%d index=0x%x max=0x%x)\n",
+                  gfn, *gfn_remainder, shift, index, max);
+        return NULL;
+    }
+    *gfn_remainder &= (1 << shift) - 1;
+    return (l1_pgentry_t *)table + index;
+}
+
+// Walk one level of the P2M table, allocating a new table if required.
+// Returns 0 on error.
+//
+static int
+p2m_next_level(struct domain *d, mfn_t *table_mfn, void **table, 
+               unsigned long *gfn_remainder, unsigned long gfn, u32 shift, 
+               u32 max, unsigned long type)
+{
+    l1_pgentry_t *p2m_entry;
+    l1_pgentry_t new_entry;
+    void *next;
+    ASSERT(d->arch.p2m.alloc_page);
+
+    if ( !(p2m_entry = p2m_find_entry(*table, gfn_remainder, gfn,
+                                      shift, max)) )
+        return 0;
+
+    if ( !(l1e_get_flags(*p2m_entry) & _PAGE_PRESENT) )
+    {
+        struct page_info *pg = d->arch.p2m.alloc_page(d);
+        if ( pg == NULL )
+            return 0;
+        list_add_tail(&pg->list, &d->arch.p2m.pages);
+        pg->u.inuse.type_info = type | 1 | PGT_validated;
+        pg->count_info = 1;
+
+        new_entry = l1e_from_pfn(mfn_x(page_to_mfn(pg)),
+                                 __PAGE_HYPERVISOR|_PAGE_USER);
+
+        switch ( type ) {
+        case PGT_l3_page_table:
+            paging_write_p2m_entry(d, gfn, p2m_entry, new_entry, 4);
+            break;
+        case PGT_l2_page_table:
+            paging_write_p2m_entry(d, gfn, p2m_entry, new_entry, 3);
+            break;
+        case PGT_l1_page_table:
+            paging_write_p2m_entry(d, gfn, p2m_entry, new_entry, 2);
+            break;
+        default:
+            BUG();
+            break;
+        }
+    }
+    *table_mfn = _mfn(l1e_get_pfn(*p2m_entry));
+    next = map_domain_page(mfn_x(*table_mfn));
+    unmap_domain_page(*table);
+    *table = next;
+
+    return 1;
+}
+
+// Returns 0 on error (out of memory)
+static int
+set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
+{
+    // XXX -- this might be able to be faster iff current->domain == d
+    mfn_t table_mfn = pagetable_get_mfn(d->arch.phys_table);
+    void *table =map_domain_page(mfn_x(table_mfn));
+    unsigned long gfn_remainder = gfn;
+    l1_pgentry_t *p2m_entry;
+    l1_pgentry_t entry_content;
+    int rv=0;
+
+#if CONFIG_PAGING_LEVELS >= 4
+    if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
+                         L4_PAGETABLE_SHIFT - PAGE_SHIFT,
+                         L4_PAGETABLE_ENTRIES, PGT_l3_page_table) )
+        goto out;
+#endif
+#if CONFIG_PAGING_LEVELS >= 3
+    // When using PAE Xen, we only allow 33 bits of pseudo-physical
+    // address in translated guests (i.e. 8 GBytes).  This restriction
+    // comes from wanting to map the P2M table into the 16MB RO_MPT hole
+    // in Xen's address space for translated PV guests.
+    //
+    if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
+                         L3_PAGETABLE_SHIFT - PAGE_SHIFT,
+                         (CONFIG_PAGING_LEVELS == 3
+                          ? 8
+                          : L3_PAGETABLE_ENTRIES),
+                         PGT_l2_page_table) )
+        goto out;
+#endif
+    if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
+                         L2_PAGETABLE_SHIFT - PAGE_SHIFT,
+                         L2_PAGETABLE_ENTRIES, PGT_l1_page_table) )
+        goto out;
+
+    p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn,
+                               0, L1_PAGETABLE_ENTRIES);
+    ASSERT(p2m_entry);
+
+    /* Track the highest gfn for which we have ever had a valid mapping */
+    if ( mfn_valid(mfn) && (gfn > d->arch.p2m.max_mapped_pfn) ) 
+        d->arch.p2m.max_mapped_pfn = gfn;
+
+    if ( mfn_valid(mfn) )
+        entry_content = l1e_from_pfn(mfn_x(mfn), __PAGE_HYPERVISOR|_PAGE_USER);
+    else
+        entry_content = l1e_empty();
+
+    /* level 1 entry */
+    paging_write_p2m_entry(d, gfn, p2m_entry, entry_content, 1);
+
+    /* Success */
+    rv = 1;
+ 
+ out:
+    unmap_domain_page(table);
+    return rv;
+}
+
+
+/* Init the datastructures for later use by the p2m code */
+void p2m_init(struct domain *d)
+{
+    p2m_lock_init(d);
+    INIT_LIST_HEAD(&d->arch.p2m.pages);
+}
+
+
+// Allocate a new p2m table for a domain.
+//
+// The structure of the p2m table is that of a pagetable for xen (i.e. it is
+// controlled by CONFIG_PAGING_LEVELS).
+//
+// The alloc_page and free_page functions will be used to get memory to
+// build the p2m, and to release it again at the end of day. 
+//
+// Returns 0 for success or -errno.
+//
+int p2m_alloc_table(struct domain *d,
+                    struct page_info * (*alloc_page)(struct domain *d),
+                    void (*free_page)(struct domain *d, struct page_info *pg))
+
+{
+    mfn_t mfn;
+    struct list_head *entry;
+    struct page_info *page, *p2m_top;
+    unsigned int page_count = 0;
+    unsigned long gfn;
+    
+    p2m_lock(d);
+
+    if ( pagetable_get_pfn(d->arch.phys_table) != 0 )
+    {
+        P2M_ERROR("p2m already allocated for this domain\n");
+        p2m_unlock(d);
+        return -EINVAL;
+    }
+
+    P2M_PRINTK("allocating p2m table\n");
+
+    d->arch.p2m.alloc_page = alloc_page;
+    d->arch.p2m.free_page = free_page;
+
+    p2m_top = d->arch.p2m.alloc_page(d);
+    if ( p2m_top == NULL )
+    {
+        p2m_unlock(d);
+        return -ENOMEM;
+    }
+list_add_tail(&p2m_top->list, &d->arch.p2m.pages);
+
+    p2m_top->count_info = 1;
+    p2m_top->u.inuse.type_info = 
+#if CONFIG_PAGING_LEVELS == 4
+        PGT_l4_page_table
+#elif CONFIG_PAGING_LEVELS == 3
+        PGT_l3_page_table
+#elif CONFIG_PAGING_LEVELS == 2
+        PGT_l2_page_table
+#endif
+        | 1 | PGT_validated;
+
+    d->arch.phys_table = pagetable_from_mfn(page_to_mfn(p2m_top));
+
+    P2M_PRINTK("populating p2m table\n");
+ 
+    /* Initialise physmap tables for slot zero. Other code assumes this. */
+    gfn = 0;
+mfn = _mfn(INVALID_MFN);
+    if ( !set_p2m_entry(d, gfn, mfn) )
+        goto error;
+
+    for ( entry = d->page_list.next;
+          entry != &d->page_list;
+          entry = entry->next )
+    {
+        page = list_entry(entry, struct page_info, list);
+        mfn = page_to_mfn(page);
+        gfn = get_gpfn_from_mfn(mfn_x(mfn));
+        page_count++;
+        if (
+#ifdef __x86_64__
+            (gfn != 0x5555555555555555L)
+#else
+            (gfn != 0x55555555L)
+#endif
+             && gfn != INVALID_M2P_ENTRY
+             && !set_p2m_entry(d, gfn, mfn) )
+            goto error;
+    }
+
+    P2M_PRINTK("p2m table initialised (%u pages)\n", page_count);
+    p2m_unlock(d);
+    return 0;
+
+ error:
+    P2M_PRINTK("failed to initialize p2m table, gfn=%05lx, mfn=%"
+               PRI_mfn "\n", gfn, mfn_x(mfn));
+    p2m_unlock(d);
+    return -ENOMEM;
+}
+
+void p2m_teardown(struct domain *d)
+/* Return all the p2m pages to Xen.
+ * We know we don't have any extra mappings to these pages */
+{
+    struct list_head *entry, *n;
+    struct page_info *pg;
+
+    p2m_lock(d);
+    d->arch.phys_table = pagetable_null();
+
+    list_for_each_safe(entry, n, &d->arch.p2m.pages)
+    {
+        pg = list_entry(entry, struct page_info, list);
+        list_del(entry);
+        d->arch.p2m.free_page(d, pg);
+    }
+    p2m_unlock(d);
+}
+
+mfn_t
+gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn)
+/* Read another domain's p2m entries */
+{
+    mfn_t mfn;
+    paddr_t addr = ((paddr_t)gpfn) << PAGE_SHIFT;
+    l2_pgentry_t *l2e;
+    l1_pgentry_t *l1e;
+    
+    ASSERT(paging_mode_translate(d));
+    mfn = pagetable_get_mfn(d->arch.phys_table);
+
+
+    if ( gpfn > d->arch.p2m.max_mapped_pfn ) 
+        /* This pfn is higher than the highest the p2m map currently holds */
+        return _mfn(INVALID_MFN);
+
+#if CONFIG_PAGING_LEVELS >= 4
+    { 
+        l4_pgentry_t *l4e = map_domain_page(mfn_x(mfn));
+        l4e += l4_table_offset(addr);
+        if ( (l4e_get_flags(*l4e) & _PAGE_PRESENT) == 0 )
+        {
+            unmap_domain_page(l4e);
+            return _mfn(INVALID_MFN);
+        }
+        mfn = _mfn(l4e_get_pfn(*l4e));
+        unmap_domain_page(l4e);
+    }
+#endif
+#if CONFIG_PAGING_LEVELS >= 3
+    {
+        l3_pgentry_t *l3e = map_domain_page(mfn_x(mfn));
+#if CONFIG_PAGING_LEVELS == 3
+        /* On PAE hosts the p2m has eight l3 entries, not four (see
+         * shadow_set_p2m_entry()) so we can't use l3_table_offset.
+         * Instead, just count the number of l3es from zero.  It's safe
+         * to do this because we already checked that the gfn is within
+         * the bounds of the p2m. */
+        l3e += (addr >> L3_PAGETABLE_SHIFT);
+#else
+        l3e += l3_table_offset(addr);        
+#endif
+        if ( (l3e_get_flags(*l3e) & _PAGE_PRESENT) == 0 )
+        {
+            unmap_domain_page(l3e);
+            return _mfn(INVALID_MFN);
+        }
+        mfn = _mfn(l3e_get_pfn(*l3e));
+        unmap_domain_page(l3e);
+    }
+#endif
+
+    l2e = map_domain_page(mfn_x(mfn));
+    l2e += l2_table_offset(addr);
+    if ( (l2e_get_flags(*l2e) & _PAGE_PRESENT) == 0 )
+    {
+        unmap_domain_page(l2e);
+        return _mfn(INVALID_MFN);
+    }
+    mfn = _mfn(l2e_get_pfn(*l2e));
+    unmap_domain_page(l2e);
+
+    l1e = map_domain_page(mfn_x(mfn));
+    l1e += l1_table_offset(addr);
+    if ( (l1e_get_flags(*l1e) & _PAGE_PRESENT) == 0 )
+    {
+        unmap_domain_page(l1e);
+        return _mfn(INVALID_MFN);
+    }
+    mfn = _mfn(l1e_get_pfn(*l1e));
+    unmap_domain_page(l1e);
+
+    return mfn;
+}
+
+#if P2M_AUDIT
+static void audit_p2m(struct domain *d)
+{
+    struct list_head *entry;
+    struct page_info *page;
+    struct domain *od;
+    unsigned long mfn, gfn, m2pfn, lp2mfn = 0;
+    mfn_t p2mfn;
+    unsigned long orphans_d = 0, orphans_i = 0, mpbad = 0, pmbad = 0;
+    int test_linear;
+    
+    if ( !paging_mode_translate(d) )
+        return;
+
+    //P2M_PRINTK("p2m audit starts\n");
+
+    test_linear = ( (d == current->domain) 
+                    && !pagetable_is_null(current->arch.monitor_table) );
+    if ( test_linear )
+        local_flush_tlb(); 
+
+    /* Audit part one: walk the domain's page allocation list, checking 
+     * the m2p entries. */
+    for ( entry = d->page_list.next;
+          entry != &d->page_list;
+          entry = entry->next )
+    {
+        page = list_entry(entry, struct page_info, list);
+        mfn = mfn_x(page_to_mfn(page));
+
+        // P2M_PRINTK("auditing guest page, mfn=%#lx\n", mfn); 
+
+        od = page_get_owner(page);
+
+        if ( od != d ) 
+        {
+            P2M_PRINTK("wrong owner %#lx -> %p(%u) != %p(%u)\n",
+                       mfn, od, (od?od->domain_id:-1), d, d->domain_id);
+            continue;
+        }
+
+        gfn = get_gpfn_from_mfn(mfn);
+        if ( gfn == INVALID_M2P_ENTRY ) 
+        {
+            orphans_i++;
+            //P2M_PRINTK("orphaned guest page: mfn=%#lx has invalid gfn\n",
+            //               mfn); 
+            continue;
+        }
+
+        if ( gfn == 0x55555555 ) 
+        {
+            orphans_d++;
+            //P2M_PRINTK("orphaned guest page: mfn=%#lx has debug gfn\n", 
+            //               mfn); 
+            continue;
+        }
+
+        p2mfn = gfn_to_mfn_foreign(d, gfn);
+        if ( mfn_x(p2mfn) != mfn )
+        {
+            mpbad++;
+            P2M_PRINTK("map mismatch mfn %#lx -> gfn %#lx -> mfn %#lx"
+                       " (-> gfn %#lx)\n",
+                       mfn, gfn, mfn_x(p2mfn),
+                       (mfn_valid(p2mfn)
+                        ? get_gpfn_from_mfn(mfn_x(p2mfn))
+                        : -1u));
+            /* This m2p entry is stale: the domain has another frame in
+             * this physical slot.  No great disaster, but for neatness,
+             * blow away the m2p entry. */ 
+            set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
+        }
+
+        if ( test_linear && (gfn <= d->arch.p2m.max_mapped_pfn) )
+        {
+            lp2mfn = mfn_x(gfn_to_mfn_current(gfn));
+            if ( lp2mfn != mfn_x(p2mfn) )
+            {
+                P2M_PRINTK("linear mismatch gfn %#lx -> mfn %#lx "
+                           "(!= mfn %#lx)\n", gfn, lp2mfn, mfn_x(p2mfn));
+            }
+        }
+
+        // P2M_PRINTK("OK: mfn=%#lx, gfn=%#lx, p2mfn=%#lx, lp2mfn=%#lx\n", 
+        //                mfn, gfn, p2mfn, lp2mfn); 
+    }   
+
+    /* Audit part two: walk the domain's p2m table, checking the entries. */
+    if ( pagetable_get_pfn(d->arch.phys_table) != 0 )
+    {
+        l2_pgentry_t *l2e;
+        l1_pgentry_t *l1e;
+        int i1, i2;
+        
+#if CONFIG_PAGING_LEVELS == 4
+        l4_pgentry_t *l4e;
+        l3_pgentry_t *l3e;
+        int i3, i4;
+        l4e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table)));
+#elif CONFIG_PAGING_LEVELS == 3
+        l3_pgentry_t *l3e;
+        int i3;
+        l3e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table)));
+#else /* CONFIG_PAGING_LEVELS == 2 */
+        l2e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table)));
+#endif
+
+        gfn = 0;
+#if CONFIG_PAGING_LEVELS >= 3
+#if CONFIG_PAGING_LEVELS >= 4
+        for ( i4 = 0; i4 < L4_PAGETABLE_ENTRIES; i4++ )
+        {
+            if ( !(l4e_get_flags(l4e[i4]) & _PAGE_PRESENT) )
+            {
+                gfn += 1 << (L4_PAGETABLE_SHIFT - PAGE_SHIFT);
+                continue;
+            }
+            l3e = map_domain_page(mfn_x(_mfn(l4e_get_pfn(l4e[i4]))));
+#endif /* now at levels 3 or 4... */
+            for ( i3 = 0; 
+                  i3 < ((CONFIG_PAGING_LEVELS==4) ? L3_PAGETABLE_ENTRIES : 8); 
+                  i3++ )
+            {
+                if ( !(l3e_get_flags(l3e[i3]) & _PAGE_PRESENT) )
+                {
+                    gfn += 1 << (L3_PAGETABLE_SHIFT - PAGE_SHIFT);
+                    continue;
+                }
+                l2e = map_domain_page(mfn_x(_mfn(l3e_get_pfn(l3e[i3]))));
+#endif /* all levels... */
+                for ( i2 = 0; i2 < L2_PAGETABLE_ENTRIES; i2++ )
+                {
+                    if ( !(l2e_get_flags(l2e[i2]) & _PAGE_PRESENT) )
+                    {
+                        gfn += 1 << (L2_PAGETABLE_SHIFT - PAGE_SHIFT);
+                        continue;
+                    }
+                    l1e = map_domain_page(mfn_x(_mfn(l2e_get_pfn(l2e[i2]))));
+                    
+                    for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; i1++, gfn++ )
+                    {
+                        if ( !(l1e_get_flags(l1e[i1]) & _PAGE_PRESENT) )
+                            continue;
+                        mfn = l1e_get_pfn(l1e[i1]);
+                        ASSERT(mfn_valid(_mfn(mfn)));
+                        m2pfn = get_gpfn_from_mfn(mfn);
+                        if ( m2pfn != gfn )
+                        {
+                            pmbad++;
+                            P2M_PRINTK("mismatch: gfn %#lx -> mfn %#lx"
+                                       " -> gfn %#lx\n", gfn, mfn, m2pfn);
+                            BUG();
+                        }
+                    }
+                    unmap_domain_page(l1e);
+                }
+#if CONFIG_PAGING_LEVELS >= 3
+                unmap_domain_page(l2e);
+            }
+#if CONFIG_PAGING_LEVELS >= 4
+            unmap_domain_page(l3e);
+        }
+#endif
+#endif
+
+#if CONFIG_PAGING_LEVELS == 4
+        unmap_domain_page(l4e);
+#elif CONFIG_PAGING_LEVELS == 3
+        unmap_domain_page(l3e);
+#else /* CONFIG_PAGING_LEVELS == 2 */
+        unmap_domain_page(l2e);
+#endif
+
+    }
+
+    //P2M_PRINTK("p2m audit complete\n");
+    //if ( orphans_i | orphans_d | mpbad | pmbad ) 
+    //    P2M_PRINTK("p2m audit found %lu orphans (%lu inval %lu debug)\n",
+    //                   orphans_i + orphans_d, orphans_i, orphans_d,
+    if ( mpbad | pmbad ) 
+        P2M_PRINTK("p2m audit found %lu odd p2m, %lu bad m2p entries\n",
+                   pmbad, mpbad);
+}
+#else 
+#define audit_p2m(_d) do { (void)(_d); } while(0)
+#endif /* P2M_AUDIT */
+
+
+
+static void
+p2m_remove_page(struct domain *d, unsigned long gfn, unsigned long mfn)
+{
+    if ( !paging_mode_translate(d) )
+        return;
+    P2M_DEBUG("removing gfn=%#lx mfn=%#lx\n", gfn, mfn);
+
+    ASSERT(mfn_x(gfn_to_mfn(d, gfn)) == mfn);
+    //ASSERT(mfn_to_gfn(d, mfn) == gfn);
+
+    set_p2m_entry(d, gfn, _mfn(INVALID_MFN));
+    set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
+}
+
+void
+guest_physmap_remove_page(struct domain *d, unsigned long gfn,
+                          unsigned long mfn)
+{
+    p2m_lock(d);
+    audit_p2m(d);
+    p2m_remove_page(d, gfn, mfn);
+    audit_p2m(d);
+    p2m_unlock(d);    
+}
+
+void
+guest_physmap_add_page(struct domain *d, unsigned long gfn,
+                       unsigned long mfn)
+{
+    unsigned long ogfn;
+    mfn_t omfn;
+
+    if ( !paging_mode_translate(d) )
+        return;
+
+    p2m_lock(d);
+    audit_p2m(d);
+
+    P2M_DEBUG("adding gfn=%#lx mfn=%#lx\n", gfn, mfn);
+
+    omfn = gfn_to_mfn(d, gfn);
+    if ( mfn_valid(omfn) )
+    {
+        set_p2m_entry(d, gfn, _mfn(INVALID_MFN));
+        set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY);
+    }
+
+    ogfn = mfn_to_gfn(d, _mfn(mfn));
+    if (
+#ifdef __x86_64__
+        (ogfn != 0x5555555555555555L)
+#else
+        (ogfn != 0x55555555L)
+#endif
+        && (ogfn != INVALID_M2P_ENTRY)
+        && (ogfn != gfn) )
+    {
+        /* This machine frame is already mapped at another physical address */
+        P2M_DEBUG("aliased! mfn=%#lx, old gfn=%#lx, new gfn=%#lx\n",
+                  mfn, ogfn, gfn);
+        if ( mfn_valid(omfn = gfn_to_mfn(d, ogfn)) ) 
+        {
+            P2M_DEBUG("old gfn=%#lx -> mfn %#lx\n", 
+                      ogfn , mfn_x(omfn));
+            if ( mfn_x(omfn) == mfn ) 
+                p2m_remove_page(d, ogfn, mfn);
+        }
+    }
+
+    set_p2m_entry(d, gfn, _mfn(mfn));
+    set_gpfn_from_mfn(mfn, gfn);
+
+    audit_p2m(d);
+    p2m_unlock(d);
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/mm/paging.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/mm/paging.c  Thu Feb 15 14:09:39 2007 -0700
@@ -0,0 +1,143 @@
+/******************************************************************************
+ * arch/x86/paging.c
+ *
+ * x86 specific paging support
+ * Copyright (c) 2007 Advanced Micro Devices (Wei Huang)
+ * Copyright (c) 2007 XenSource Inc.
+ *
+ * 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
+ */
+
+#include <xen/init.h>
+#include <asm/paging.h>
+#include <asm/shadow.h>
+#include <asm/p2m.h>
+
+/* Xen command-line option to enable hardware-assisted paging */
+int opt_hap_enabled = 0; 
+boolean_param("hap", opt_hap_enabled);
+
+/* Printouts */
+#define PAGING_PRINTK(_f, _a...)                                     \
+    debugtrace_printk("pg: %s(): " _f, __func__, ##_a)
+#define PAGING_ERROR(_f, _a...)                                      \
+    printk("pg error: %s(): " _f, __func__, ##_a)
+#define PAGING_DEBUG(flag, _f, _a...)                                \
+    do {                                                             \
+        if (PAGING_DEBUG_ ## flag)                                   \
+            debugtrace_printk("pgdebug: %s(): " _f, __func__, ##_a); \
+    } while (0)
+
+
+/* Domain paging struct initialization. */
+void paging_domain_init(struct domain *d)
+{
+    p2m_init(d);
+    shadow_domain_init(d);
+}
+
+/* vcpu paging struct initialization goes here */
+void paging_vcpu_init(struct vcpu *v)
+{
+    shadow_vcpu_init(v);
+}
+
+
+int paging_domctl(struct domain *d, xen_domctl_shadow_op_t *sc,
+                  XEN_GUEST_HANDLE(void) u_domctl)
+{
+    /* Here, dispatch domctl to the appropriate paging code */
+    return shadow_domctl(d, sc, u_domctl);
+}
+
+/* Call when destroying a domain */
+void paging_teardown(struct domain *d)
+{
+    shadow_teardown(d);
+    /* Call other modes' teardown code here */    
+}
+
+/* Call once all of the references to the domain have gone away */
+void paging_final_teardown(struct domain *d)
+{
+    shadow_teardown(d);
+    /* Call other modes' final teardown code here */
+}
+
+/* Enable an arbitrary paging-assistance mode.  Call once at domain
+ * creation. */
+int paging_enable(struct domain *d, u32 mode)
+{
+    if ( mode & PG_SH_enable ) 
+        return shadow_enable(d, mode);
+    else
+        /* No other modes supported yet */
+        return -EINVAL; 
+}
+
+/* Print paging-assistance info to the console */
+void paging_dump_domain_info(struct domain *d)
+{
+    if ( paging_mode_enabled(d) )
+    {
+        printk("    paging assistance: ");
+        if ( paging_mode_shadow(d) )
+            printk("shadow ");
+        if ( paging_mode_hap(d) )
+            printk("hap ");
+        if ( paging_mode_refcounts(d) )
+            printk("refcounts ");
+        if ( paging_mode_log_dirty(d) )
+            printk("log_dirty ");
+        if ( paging_mode_translate(d) )
+            printk("translate ");
+        if ( paging_mode_external(d) )
+            printk("external ");
+        printk("\n");
+    }
+}
+
+void paging_dump_vcpu_info(struct vcpu *v)
+{
+    if ( paging_mode_enabled(v->domain) )
+    {
+        printk("    paging assistance: ");        
+        if ( paging_mode_shadow(v->domain) )
+        {
+            if ( v->arch.paging.mode )
+                printk("shadowed %u-on-%u, %stranslated\n",
+                       v->arch.paging.mode->guest_levels,
+                       v->arch.paging.mode->shadow.shadow_levels,
+                       paging_vcpu_mode_translate(v) ? "" : "not ");
+            else
+                printk("not shadowed\n");
+        }
+        else if ( paging_mode_hap(v->domain) && v->arch.paging.mode )
+            printk("hap, %u levels\n", 
+                   v->arch.paging.mode->guest_levels);
+        else
+            printk("none\n");
+    }
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/mm/shadow/common.c   Thu Feb 15 14:09:39 2007 -0700
@@ -47,12 +47,27 @@ void shadow_domain_init(struct domain *d
     int i;
     shadow_lock_init(d);
     for ( i = 0; i <= SHADOW_MAX_ORDER; i++ )
-        INIT_LIST_HEAD(&d->arch.shadow.freelists[i]);
-    INIT_LIST_HEAD(&d->arch.shadow.p2m_freelist);
-    INIT_LIST_HEAD(&d->arch.shadow.p2m_inuse);
-    INIT_LIST_HEAD(&d->arch.shadow.pinned_shadows);
-}
-
+        INIT_LIST_HEAD(&d->arch.paging.shadow.freelists[i]);
+    INIT_LIST_HEAD(&d->arch.paging.shadow.p2m_freelist);
+    INIT_LIST_HEAD(&d->arch.paging.shadow.pinned_shadows);
+}
+
+/* Setup the shadow-specfic parts of a vcpu struct. Note: The most important
+ * job is to initialize the update_paging_modes() function pointer, which is
+ * used to initialized the rest of resources. Therefore, it really does not
+ * matter to have v->arch.paging.mode pointing to any mode, as long as it can
+ * be compiled.
+ */
+void shadow_vcpu_init(struct vcpu *v)
+{
+#if CONFIG_PAGING_LEVELS == 4
+    v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
+#elif CONFIG_PAGING_LEVELS == 3
+    v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
+#elif CONFIG_PAGING_LEVELS == 2
+    v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,2,2);
+#endif
+}
 
 #if SHADOW_AUDIT
 int shadow_audit_enable = 0;
@@ -265,7 +280,7 @@ hvm_emulate_write(enum x86_segment seg,
     if ( rc )
         return rc;
 
-    return v->arch.shadow.mode->x86_emulate_write(
+    return v->arch.paging.mode->shadow.x86_emulate_write(
         v, addr, &val, bytes, sh_ctxt);
 }
 
@@ -288,7 +303,7 @@ hvm_emulate_cmpxchg(enum x86_segment seg
     if ( rc )
         return rc;
 
-    return v->arch.shadow.mode->x86_emulate_cmpxchg(
+    return v->arch.paging.mode->shadow.x86_emulate_cmpxchg(
         v, addr, old, new, bytes, sh_ctxt);
 }
 
@@ -312,7 +327,7 @@ hvm_emulate_cmpxchg8b(enum x86_segment s
     if ( rc )
         return rc;
 
-    return v->arch.shadow.mode->x86_emulate_cmpxchg8b(
+    return v->arch.paging.mode->shadow.x86_emulate_cmpxchg8b(
         v, addr, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
 }
 
@@ -353,7 +368,7 @@ pv_emulate_write(enum x86_segment seg,
     struct sh_emulate_ctxt *sh_ctxt =
         container_of(ctxt, struct sh_emulate_ctxt, ctxt);
     struct vcpu *v = current;
-    return v->arch.shadow.mode->x86_emulate_write(
+    return v->arch.paging.mode->shadow.x86_emulate_write(
         v, offset, &val, bytes, sh_ctxt);
 }
 
@@ -368,7 +383,7 @@ pv_emulate_cmpxchg(enum x86_segment seg,
     struct sh_emulate_ctxt *sh_ctxt =
         container_of(ctxt, struct sh_emulate_ctxt, ctxt);
     struct vcpu *v = current;
-    return v->arch.shadow.mode->x86_emulate_cmpxchg(
+    return v->arch.paging.mode->shadow.x86_emulate_cmpxchg(
         v, offset, old, new, bytes, sh_ctxt);
 }
 
@@ -384,7 +399,7 @@ pv_emulate_cmpxchg8b(enum x86_segment se
     struct sh_emulate_ctxt *sh_ctxt =
         container_of(ctxt, struct sh_emulate_ctxt, ctxt);
     struct vcpu *v = current;
-    return v->arch.shadow.mode->x86_emulate_cmpxchg8b(
+    return v->arch.paging.mode->shadow.x86_emulate_cmpxchg8b(
         v, offset, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
 }
 
@@ -721,7 +736,7 @@ static inline int chunk_is_available(str
     int i;
     
     for ( i = order; i <= SHADOW_MAX_ORDER; i++ )
-        if ( !list_empty(&d->arch.shadow.freelists[i]) )
+        if ( !list_empty(&d->arch.paging.shadow.freelists[i]) )
             return 1;
     return 0;
 }
@@ -783,7 +798,7 @@ void shadow_prealloc(struct domain *d, u
 
     /* Stage one: walk the list of pinned pages, unpinning them */
     perfc_incrc(shadow_prealloc_1);
-    list_for_each_backwards_safe(l, t, &d->arch.shadow.pinned_shadows)
+    list_for_each_backwards_safe(l, t, &d->arch.paging.shadow.pinned_shadows)
     {
         sp = list_entry(l, struct shadow_page_info, list);
         smfn = shadow_page_to_mfn(sp);
@@ -823,9 +838,9 @@ void shadow_prealloc(struct domain *d, u
     SHADOW_PRINTK("Can't pre-allocate %i shadow pages!\n"
                    "  shadow pages total = %u, free = %u, p2m=%u\n",
                    1 << order, 
-                   d->arch.shadow.total_pages, 
-                   d->arch.shadow.free_pages, 
-                   d->arch.shadow.p2m_pages);
+                   d->arch.paging.shadow.total_pages, 
+                   d->arch.paging.shadow.free_pages, 
+                   d->arch.paging.shadow.p2m_pages);
     BUG();
 }
 
@@ -840,7 +855,7 @@ static void shadow_blow_tables(struct do
     int i;
     
     /* Pass one: unpin all pinned pages */
-    list_for_each_backwards_safe(l,t, &d->arch.shadow.pinned_shadows)
+    list_for_each_backwards_safe(l,t, &d->arch.paging.shadow.pinned_shadows)
     {
         sp = list_entry(l, struct shadow_page_info, list);
         smfn = shadow_page_to_mfn(sp);
@@ -905,9 +920,9 @@ mfn_t shadow_alloc(struct domain *d,
 
     /* Find smallest order which can satisfy the request. */
     for ( i = order; i <= SHADOW_MAX_ORDER; i++ )
-        if ( !list_empty(&d->arch.shadow.freelists[i]) )
+        if ( !list_empty(&d->arch.paging.shadow.freelists[i]) )
         {
-            sp = list_entry(d->arch.shadow.freelists[i].next, 
+            sp = list_entry(d->arch.paging.shadow.freelists[i].next, 
                             struct shadow_page_info, list);
             list_del(&sp->list);
             
@@ -916,10 +931,10 @@ mfn_t shadow_alloc(struct domain *d,
             {
                 i--;
                 sp->order = i;
-                list_add_tail(&sp->list, &d->arch.shadow.freelists[i]);
+                list_add_tail(&sp->list, &d->arch.paging.shadow.freelists[i]);
                 sp += 1 << i;
             }
-            d->arch.shadow.free_pages -= 1 << order;
+            d->arch.paging.shadow.free_pages -= 1 << order;
 
             /* Init page info fields and clear the pages */
             for ( i = 0; i < 1<<order ; i++ ) 
@@ -976,7 +991,7 @@ void shadow_free(struct domain *d, mfn_t
     ASSERT(shadow_type != SH_type_p2m_table);
     order = shadow_order(shadow_type);
 
-    d->arch.shadow.free_pages += 1 << order;
+    d->arch.paging.shadow.free_pages += 1 << order;
 
     for ( i = 0; i < 1<<order; i++ ) 
     {
@@ -985,8 +1000,8 @@ void shadow_free(struct domain *d, mfn_t
         for_each_vcpu(d, v) 
         {
             /* No longer safe to look for a writeable mapping in this shadow */
-            if ( v->arch.shadow.last_writeable_pte_smfn == mfn_x(smfn) + i ) 
-                v->arch.shadow.last_writeable_pte_smfn = 0;
+            if ( v->arch.paging.shadow.last_writeable_pte_smfn == mfn_x(smfn) 
+ i ) 
+                v->arch.paging.shadow.last_writeable_pte_smfn = 0;
         }
 #endif
         /* Strip out the type: this is now a free shadow page */
@@ -1019,7 +1034,7 @@ void shadow_free(struct domain *d, mfn_t
     }
 
     sp->order = order;
-    list_add_tail(&sp->list, &d->arch.shadow.freelists[order]);
+    list_add_tail(&sp->list, &d->arch.paging.shadow.freelists[order]);
 }
 
 /* Divert some memory from the pool to be used by the p2m mapping.
@@ -1033,19 +1048,19 @@ void shadow_free(struct domain *d, mfn_t
  * returns non-zero on success.
  */
 static int
-shadow_alloc_p2m_pages(struct domain *d)
+sh_alloc_p2m_pages(struct domain *d)
 {
     struct page_info *pg;
     u32 i;
     ASSERT(shadow_locked_by_me(d));
     
-    if ( d->arch.shadow.total_pages 
+    if ( d->arch.paging.shadow.total_pages 
          < (shadow_min_acceptable_pages(d) + (1<<SHADOW_MAX_ORDER)) )
         return 0; /* Not enough shadow memory: need to increase it first */
     
     pg = mfn_to_page(shadow_alloc(d, SH_type_p2m_table, 0));
-    d->arch.shadow.p2m_pages += (1<<SHADOW_MAX_ORDER);
-    d->arch.shadow.total_pages -= (1<<SHADOW_MAX_ORDER);
+    d->arch.paging.shadow.p2m_pages += (1<<SHADOW_MAX_ORDER);
+    d->arch.paging.shadow.total_pages -= (1<<SHADOW_MAX_ORDER);
     for (i = 0; i < (1<<SHADOW_MAX_ORDER); i++)
     {
         /* Unlike shadow pages, mark p2m pages as owned by the domain.
@@ -1055,34 +1070,59 @@ shadow_alloc_p2m_pages(struct domain *d)
          * believed to be a concern.
          */
         page_set_owner(&pg[i], d);
-        list_add_tail(&pg[i].list, &d->arch.shadow.p2m_freelist);
+        pg->count_info = 1;
+        list_add_tail(&pg[i].list, &d->arch.paging.shadow.p2m_freelist);
     }
     return 1;
 }
 
 // Returns 0 if no memory is available...
-mfn_t
+struct page_info * 
 shadow_alloc_p2m_page(struct domain *d)
 {
     struct list_head *entry;
     struct page_info *pg;
     mfn_t mfn;
     void *p;
-
-    if ( list_empty(&d->arch.shadow.p2m_freelist) &&
-         !shadow_alloc_p2m_pages(d) )
-        return _mfn(0);
-    entry = d->arch.shadow.p2m_freelist.next;
+    
+    shadow_lock(d);
+
+    if ( list_empty(&d->arch.paging.shadow.p2m_freelist) &&
+         !sh_alloc_p2m_pages(d) )
+    {
+        shadow_unlock(d);
+        return NULL;
+    }
+    entry = d->arch.paging.shadow.p2m_freelist.next;
     list_del(entry);
-    list_add_tail(entry, &d->arch.shadow.p2m_inuse);
+
+    shadow_unlock(d);
+
     pg = list_entry(entry, struct page_info, list);
-    pg->count_info = 1;
     mfn = page_to_mfn(pg);
     p = sh_map_domain_page(mfn);
     clear_page(p);
     sh_unmap_domain_page(p);
 
-    return mfn;
+    return pg;
+}
+
+void
+shadow_free_p2m_page(struct domain *d, struct page_info *pg)
+{
+    ASSERT(page_get_owner(pg) == d);
+    /* Should have just the one ref we gave it in alloc_p2m_page() */
+    if ( (pg->count_info & PGC_count_mask) != 1 )
+    {
+        SHADOW_ERROR("Odd p2m page count c=%#x t=%"PRtype_info"\n",
+                     pg->count_info, pg->u.inuse.type_info);
+    }
+    /* Free should not decrement domain's total allocation, since 
+     * these pages were allocated without an owner. */
+    page_set_owner(pg, NULL); 
+    free_domheap_pages(pg, 0);
+    d->arch.paging.shadow.p2m_pages--;
+    perfc_decr(shadow_alloc_count);
 }
 
 #if CONFIG_PAGING_LEVELS == 3
@@ -1130,344 +1170,6 @@ static void p2m_install_entry_in_monitor
 }
 #endif
 
-// Find the next level's P2M entry, checking for out-of-range gfn's...
-// Returns NULL on error.
-//
-static l1_pgentry_t *
-p2m_find_entry(void *table, unsigned long *gfn_remainder,
-                   unsigned long gfn, u32 shift, u32 max)
-{
-    u32 index;
-
-    index = *gfn_remainder >> shift;
-    if ( index >= max )
-    {
-        SHADOW_DEBUG(P2M, "gfn=0x%lx out of range "
-                      "(gfn_remainder=0x%lx shift=%d index=0x%x max=0x%x)\n",
-                       gfn, *gfn_remainder, shift, index, max);
-        return NULL;
-    }
-    *gfn_remainder &= (1 << shift) - 1;
-    return (l1_pgentry_t *)table + index;
-}
-
-// Walk one level of the P2M table, allocating a new table if required.
-// Returns 0 on error.
-//
-static int
-p2m_next_level(struct domain *d, mfn_t *table_mfn, void **table, 
-               unsigned long *gfn_remainder, unsigned long gfn, u32 shift, 
-               u32 max, unsigned long type)
-{
-    l1_pgentry_t *p2m_entry;
-    void *next;
-
-    if ( !(p2m_entry = p2m_find_entry(*table, gfn_remainder, gfn,
-                                      shift, max)) )
-        return 0;
-
-    if ( !(l1e_get_flags(*p2m_entry) & _PAGE_PRESENT) )
-    {
-        mfn_t mfn = shadow_alloc_p2m_page(d);
-        if ( mfn_x(mfn) == 0 )
-            return 0;
-        *p2m_entry = l1e_from_pfn(mfn_x(mfn), __PAGE_HYPERVISOR|_PAGE_USER);
-        mfn_to_page(mfn)->u.inuse.type_info = type | 1 | PGT_validated;
-        mfn_to_page(mfn)->count_info = 1;
-#if CONFIG_PAGING_LEVELS == 3
-        if (type == PGT_l2_page_table)
-        {
-            struct vcpu *v;
-            /* We have written to the p2m l3: need to sync the per-vcpu
-             * copies of it in the monitor tables */
-            p2m_install_entry_in_monitors(d, (l3_pgentry_t *)p2m_entry);
-            /* Also, any vcpus running on shadows of the p2m need to 
-             * reload their CR3s so the change propagates to the shadow */
-            ASSERT(shadow_locked_by_me(d));
-            for_each_vcpu(d, v) 
-            {
-                if ( pagetable_get_pfn(v->arch.guest_table) 
-                     == pagetable_get_pfn(d->arch.phys_table) 
-                     && v->arch.shadow.mode != NULL )
-                    v->arch.shadow.mode->update_cr3(v, 0);
-            }
-        }
-#endif
-        /* The P2M can be shadowed: keep the shadows synced */
-        if ( d->vcpu[0] != NULL )
-            (void)sh_validate_guest_entry(d->vcpu[0], *table_mfn,
-                                          p2m_entry, sizeof *p2m_entry);
-    }
-    *table_mfn = _mfn(l1e_get_pfn(*p2m_entry));
-    next = sh_map_domain_page(*table_mfn);
-    sh_unmap_domain_page(*table);
-    *table = next;
-
-    return 1;
-}
-
-// Returns 0 on error (out of memory)
-int
-shadow_set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
-{
-    // XXX -- this might be able to be faster iff current->domain == d
-    mfn_t table_mfn = pagetable_get_mfn(d->arch.phys_table);
-    void *table = sh_map_domain_page(table_mfn);
-    unsigned long gfn_remainder = gfn;
-    l1_pgentry_t *p2m_entry;
-    int rv=0;
-
-#if CONFIG_PAGING_LEVELS >= 4
-    if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
-                         L4_PAGETABLE_SHIFT - PAGE_SHIFT,
-                         L4_PAGETABLE_ENTRIES, PGT_l3_page_table) )
-        goto out;
-#endif
-#if CONFIG_PAGING_LEVELS >= 3
-    // When using PAE Xen, we only allow 33 bits of pseudo-physical
-    // address in translated guests (i.e. 8 GBytes).  This restriction
-    // comes from wanting to map the P2M table into the 16MB RO_MPT hole
-    // in Xen's address space for translated PV guests.
-    //
-    if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
-                         L3_PAGETABLE_SHIFT - PAGE_SHIFT,
-                         (CONFIG_PAGING_LEVELS == 3
-                          ? 8
-                          : L3_PAGETABLE_ENTRIES),
-                         PGT_l2_page_table) )
-        goto out;
-#endif
-    if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
-                         L2_PAGETABLE_SHIFT - PAGE_SHIFT,
-                         L2_PAGETABLE_ENTRIES, PGT_l1_page_table) )
-        goto out;
-
-    p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn,
-                               0, L1_PAGETABLE_ENTRIES);
-    ASSERT(p2m_entry);
-    if ( mfn_valid(mfn) )
-        *p2m_entry = l1e_from_pfn(mfn_x(mfn), __PAGE_HYPERVISOR|_PAGE_USER);
-    else
-        *p2m_entry = l1e_empty();
-
-    /* Track the highest gfn for which we have ever had a valid mapping */
-    if ( mfn_valid(mfn) && (gfn > d->arch.max_mapped_pfn) ) 
-        d->arch.max_mapped_pfn = gfn;
-
-    /* The P2M can be shadowed: keep the shadows synced */
-    if ( d->vcpu[0] != NULL )
-        (void)sh_validate_guest_entry(d->vcpu[0], table_mfn, 
-                                      p2m_entry, sizeof(*p2m_entry));
-
-    /* Success */
-    rv = 1;
- 
- out:
-    sh_unmap_domain_page(table);
-    return rv;
-}
-
-// Allocate a new p2m table for a domain.
-//
-// The structure of the p2m table is that of a pagetable for xen (i.e. it is
-// controlled by CONFIG_PAGING_LEVELS).
-//
-// Returns 0 if p2m table could not be initialized
-//
-static int
-shadow_alloc_p2m_table(struct domain *d)
-{
-    mfn_t p2m_top, mfn;
-    struct list_head *entry;
-    struct page_info *page;
-    unsigned int page_count = 0;
-    unsigned long gfn;
-    
-    SHADOW_PRINTK("allocating p2m table\n");
-    ASSERT(pagetable_get_pfn(d->arch.phys_table) == 0);
-
-    p2m_top = shadow_alloc_p2m_page(d);
-    mfn_to_page(p2m_top)->count_info = 1;
-    mfn_to_page(p2m_top)->u.inuse.type_info = 
-#if CONFIG_PAGING_LEVELS == 4
-        PGT_l4_page_table
-#elif CONFIG_PAGING_LEVELS == 3
-        PGT_l3_page_table
-#elif CONFIG_PAGING_LEVELS == 2
-        PGT_l2_page_table
-#endif
-        | 1 | PGT_validated;
-   
-    if ( mfn_x(p2m_top) == 0 )
-        return 0;
-
-    d->arch.phys_table = pagetable_from_mfn(p2m_top);
-
-    SHADOW_PRINTK("populating p2m table\n");
- 
-    /* Initialise physmap tables for slot zero. Other code assumes this. */
-    gfn = 0;
-    mfn = _mfn(INVALID_MFN);
-    if ( !shadow_set_p2m_entry(d, gfn, mfn) )
-        goto error;
-
-    /* Build a p2m map that matches the m2p entries for this domain's
-     * allocated pages.  Skip any pages that have an explicitly invalid
-     * or obviously bogus m2p entry. */
-    for ( entry = d->page_list.next;
-          entry != &d->page_list;
-          entry = entry->next )
-    {
-        page = list_entry(entry, struct page_info, list);
-        mfn = page_to_mfn(page);
-        gfn = get_gpfn_from_mfn(mfn_x(mfn));
-        page_count++;
-        if (
-#ifdef __x86_64__
-            (gfn != 0x5555555555555555L)
-#else
-            (gfn != 0x55555555L)
-#endif
-             && gfn != INVALID_M2P_ENTRY
-             && (gfn < 
-                 (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof (l1_pgentry_t))
-             && !shadow_set_p2m_entry(d, gfn, mfn) )
-            goto error;
-    }
-
-    SHADOW_PRINTK("p2m table initialised (%u pages)\n", page_count);
-    return 1;
-
- error:
-    SHADOW_PRINTK("failed to initialize p2m table, gfn=%05lx, mfn=%"
-                  SH_PRI_mfn "\n", gfn, mfn_x(mfn));
-    return 0;
-}
-
-mfn_t
-sh_gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn)
-/* Read another domain's p2m entries */
-{
-    mfn_t mfn;
-    paddr_t addr = ((paddr_t)gpfn) << PAGE_SHIFT;
-    l2_pgentry_t *l2e;
-    l1_pgentry_t *l1e;
-    
-    ASSERT(shadow_mode_translate(d));
-    mfn = pagetable_get_mfn(d->arch.phys_table);
-
-
-    if ( gpfn > d->arch.max_mapped_pfn ) 
-        /* This pfn is higher than the highest the p2m map currently holds */
-        return _mfn(INVALID_MFN);
-
-#if CONFIG_PAGING_LEVELS >= 4
-    { 
-        l4_pgentry_t *l4e = sh_map_domain_page(mfn);
-        l4e += l4_table_offset(addr);
-        if ( (l4e_get_flags(*l4e) & _PAGE_PRESENT) == 0 )
-        {
-            sh_unmap_domain_page(l4e);
-            return _mfn(INVALID_MFN);
-        }
-        mfn = _mfn(l4e_get_pfn(*l4e));
-        sh_unmap_domain_page(l4e);
-    }
-#endif
-#if CONFIG_PAGING_LEVELS >= 3
-    {
-        l3_pgentry_t *l3e = sh_map_domain_page(mfn);
-#if CONFIG_PAGING_LEVELS == 3
-        /* On PAE hosts the p2m has eight l3 entries, not four (see
-         * shadow_set_p2m_entry()) so we can't use l3_table_offset.
-         * Instead, just count the number of l3es from zero.  It's safe
-         * to do this because we already checked that the gfn is within
-         * the bounds of the p2m. */
-        l3e += (addr >> L3_PAGETABLE_SHIFT);
-#else
-        l3e += l3_table_offset(addr);        
-#endif
-        if ( (l3e_get_flags(*l3e) & _PAGE_PRESENT) == 0 )
-        {
-            sh_unmap_domain_page(l3e);
-            return _mfn(INVALID_MFN);
-        }
-        mfn = _mfn(l3e_get_pfn(*l3e));
-        sh_unmap_domain_page(l3e);
-    }
-#endif
-
-    l2e = sh_map_domain_page(mfn);
-    l2e += l2_table_offset(addr);
-    if ( (l2e_get_flags(*l2e) & _PAGE_PRESENT) == 0 )
-    {
-        sh_unmap_domain_page(l2e);
-        return _mfn(INVALID_MFN);
-    }
-    mfn = _mfn(l2e_get_pfn(*l2e));
-    sh_unmap_domain_page(l2e);
-
-    l1e = sh_map_domain_page(mfn);
-    l1e += l1_table_offset(addr);
-    if ( (l1e_get_flags(*l1e) & _PAGE_PRESENT) == 0 )
-    {
-        sh_unmap_domain_page(l1e);
-        return _mfn(INVALID_MFN);
-    }
-    mfn = _mfn(l1e_get_pfn(*l1e));
-    sh_unmap_domain_page(l1e);
-
-    return mfn;
-}
-
-unsigned long
-shadow_gfn_to_mfn_foreign(unsigned long gpfn)
-{
-    return mfn_x(sh_gfn_to_mfn_foreign(current->domain, gpfn));
-}
-
-
-static void shadow_p2m_teardown(struct domain *d)
-/* Return all the p2m pages to Xen.
- * We know we don't have any extra mappings to these pages */
-{
-    struct list_head *entry, *n;
-    struct page_info *pg;
-
-    d->arch.phys_table = pagetable_null();
-
-    list_for_each_safe(entry, n, &d->arch.shadow.p2m_inuse)
-    {
-        pg = list_entry(entry, struct page_info, list);
-        list_del(entry);
-        /* Should have just the one ref we gave it in alloc_p2m_page() */
-        if ( (pg->count_info & PGC_count_mask) != 1 )
-        {
-            SHADOW_PRINTK("Odd p2m page count c=%#x t=%"PRtype_info"\n",
-                           pg->count_info, pg->u.inuse.type_info);
-        }
-        ASSERT(page_get_owner(pg) == d);
-        /* Free should not decrement domain's total allocation, since 
-         * these pages were allocated without an owner. */
-        page_set_owner(pg, NULL); 
-        free_domheap_pages(pg, 0);
-        d->arch.shadow.p2m_pages--;
-        perfc_decr(shadow_alloc_count);
-    }
-    list_for_each_safe(entry, n, &d->arch.shadow.p2m_freelist)
-    {
-        list_del(entry);
-        pg = list_entry(entry, struct page_info, list);
-        ASSERT(page_get_owner(pg) == d);
-        /* Free should not decrement domain's total allocation. */
-        page_set_owner(pg, NULL); 
-        free_domheap_pages(pg, 0);
-        d->arch.shadow.p2m_pages--;
-        perfc_decr(shadow_alloc_count);
-    }
-    ASSERT(d->arch.shadow.p2m_pages == 0);
-}
-
 /* Set the pool of shadow pages to the required number of pages.
  * Input will be rounded up to at least shadow_min_acceptable_pages(),
  * plus space for the p2m table.
@@ -1491,11 +1193,11 @@ static unsigned int sh_set_allocation(st
     pages = (pages + ((1<<SHADOW_MAX_ORDER)-1)) & ~((1<<SHADOW_MAX_ORDER)-1);
 
     SHADOW_PRINTK("current %i target %i\n", 
-                   d->arch.shadow.total_pages, pages);
-
-    while ( d->arch.shadow.total_pages != pages ) 
-    {
-        if ( d->arch.shadow.total_pages < pages ) 
+                   d->arch.paging.shadow.total_pages, pages);
+
+    while ( d->arch.paging.shadow.total_pages != pages ) 
+    {
+        if ( d->arch.paging.shadow.total_pages < pages ) 
         {
             /* Need to allocate more memory from domheap */
             sp = (struct shadow_page_info *)
@@ -1505,8 +1207,8 @@ static unsigned int sh_set_allocation(st
                 SHADOW_PRINTK("failed to allocate shadow pages.\n");
                 return -ENOMEM;
             }
-            d->arch.shadow.free_pages += 1<<SHADOW_MAX_ORDER;
-            d->arch.shadow.total_pages += 1<<SHADOW_MAX_ORDER;
+            d->arch.paging.shadow.free_pages += 1<<SHADOW_MAX_ORDER;
+            d->arch.paging.shadow.total_pages += 1<<SHADOW_MAX_ORDER;
             for ( j = 0; j < 1<<SHADOW_MAX_ORDER; j++ ) 
             {
                 sp[j].type = 0;  
@@ -1518,18 +1220,18 @@ static unsigned int sh_set_allocation(st
             }
             sp->order = SHADOW_MAX_ORDER;
             list_add_tail(&sp->list, 
-                          &d->arch.shadow.freelists[SHADOW_MAX_ORDER]);
+                          &d->arch.paging.shadow.freelists[SHADOW_MAX_ORDER]);
         } 
-        else if ( d->arch.shadow.total_pages > pages ) 
+        else if ( d->arch.paging.shadow.total_pages > pages ) 
         {
             /* Need to return memory to domheap */
             shadow_prealloc(d, SHADOW_MAX_ORDER);
-            ASSERT(!list_empty(&d->arch.shadow.freelists[SHADOW_MAX_ORDER]));
-            sp = list_entry(d->arch.shadow.freelists[SHADOW_MAX_ORDER].next, 
+            
ASSERT(!list_empty(&d->arch.paging.shadow.freelists[SHADOW_MAX_ORDER]));
+            sp = 
list_entry(d->arch.paging.shadow.freelists[SHADOW_MAX_ORDER].next, 
                             struct shadow_page_info, list);
             list_del(&sp->list);
-            d->arch.shadow.free_pages -= 1<<SHADOW_MAX_ORDER;
-            d->arch.shadow.total_pages -= 1<<SHADOW_MAX_ORDER;
+            d->arch.paging.shadow.free_pages -= 1<<SHADOW_MAX_ORDER;
+            d->arch.paging.shadow.total_pages -= 1<<SHADOW_MAX_ORDER;
             free_domheap_pages((struct page_info *)sp, SHADOW_MAX_ORDER);
         }
 
@@ -1547,7 +1249,7 @@ static unsigned int sh_set_allocation(st
 /* Return the size of the shadow pool, rounded up to the nearest MB */
 static unsigned int shadow_get_allocation(struct domain *d)
 {
-    unsigned int pg = d->arch.shadow.total_pages;
+    unsigned int pg = d->arch.paging.shadow.total_pages;
     return ((pg >> (20 - PAGE_SHIFT))
             + ((pg & ((1 << (20 - PAGE_SHIFT)) - 1)) ? 1 : 0));
 }
@@ -1583,7 +1285,7 @@ static void sh_hash_audit_bucket(struct 
     if ( !(SHADOW_AUDIT_ENABLE) )
         return;
 
-    sp = d->arch.shadow.hash_table[bucket];
+    sp = d->arch.paging.shadow.hash_table[bucket];
     while ( sp )
     {
         /* Not a shadow? */
@@ -1608,7 +1310,7 @@ static void sh_hash_audit_bucket(struct 
             if ( (gpg->u.inuse.type_info & PGT_type_mask) == PGT_writable_page 
                  && (gpg->u.inuse.type_info & PGT_count_mask) != 0 )
             {
-                SHADOW_ERROR("MFN %#lx shadowed (by %#"SH_PRI_mfn")"
+                SHADOW_ERROR("MFN %#lx shadowed (by %#"PRI_mfn")"
                              " but has typecount %#lx\n",
                              sp->backpointer, mfn_x(shadow_page_to_mfn(sp)), 
                              gpg->u.inuse.type_info);
@@ -1652,13 +1354,13 @@ static int shadow_hash_alloc(struct doma
     struct shadow_page_info **table;
 
     ASSERT(shadow_locked_by_me(d));
-    ASSERT(!d->arch.shadow.hash_table);
+    ASSERT(!d->arch.paging.shadow.hash_table);
 
     table = xmalloc_array(struct shadow_page_info *, SHADOW_HASH_BUCKETS);
     if ( !table ) return 1;
     memset(table, 0, 
            SHADOW_HASH_BUCKETS * sizeof (struct shadow_page_info *));
-    d->arch.shadow.hash_table = table;
+    d->arch.paging.shadow.hash_table = table;
     return 0;
 }
 
@@ -1667,10 +1369,10 @@ static void shadow_hash_teardown(struct 
 static void shadow_hash_teardown(struct domain *d)
 {
     ASSERT(shadow_locked_by_me(d));
-    ASSERT(d->arch.shadow.hash_table);
-
-    xfree(d->arch.shadow.hash_table);
-    d->arch.shadow.hash_table = NULL;
+    ASSERT(d->arch.paging.shadow.hash_table);
+
+    xfree(d->arch.paging.shadow.hash_table);
+    d->arch.paging.shadow.hash_table = NULL;
 }
 
 
@@ -1683,7 +1385,7 @@ mfn_t shadow_hash_lookup(struct vcpu *v,
     key_t key;
 
     ASSERT(shadow_locked_by_me(d));
-    ASSERT(d->arch.shadow.hash_table);
+    ASSERT(d->arch.paging.shadow.hash_table);
     ASSERT(t);
 
     sh_hash_audit(d);
@@ -1692,16 +1394,16 @@ mfn_t shadow_hash_lookup(struct vcpu *v,
     key = sh_hash(n, t);
     sh_hash_audit_bucket(d, key);
 
-    sp = d->arch.shadow.hash_table[key];
+    sp = d->arch.paging.shadow.hash_table[key];
     prev = NULL;
     while(sp)
     {
         if ( sp->backpointer == n && sp->type == t )
         {
             /* Pull-to-front if 'sp' isn't already the head item */
-            if ( unlikely(sp != d->arch.shadow.hash_table[key]) )
+            if ( unlikely(sp != d->arch.paging.shadow.hash_table[key]) )
             {
-                if ( unlikely(d->arch.shadow.hash_walking != 0) )
+                if ( unlikely(d->arch.paging.shadow.hash_walking != 0) )
                     /* Can't reorder: someone is walking the hash chains */
                     return shadow_page_to_mfn(sp);
                 else 
@@ -1710,8 +1412,8 @@ mfn_t shadow_hash_lookup(struct vcpu *v,
                     /* Delete sp from the list */
                     prev->next_shadow = sp->next_shadow;                    
                     /* Re-insert it at the head of the list */
-                    sp->next_shadow = d->arch.shadow.hash_table[key];
-                    d->arch.shadow.hash_table[key] = sp;
+                    sp->next_shadow = d->arch.paging.shadow.hash_table[key];
+                    d->arch.paging.shadow.hash_table[key] = sp;
                 }
             }
             else
@@ -1737,7 +1439,7 @@ void shadow_hash_insert(struct vcpu *v, 
     key_t key;
     
     ASSERT(shadow_locked_by_me(d));
-    ASSERT(d->arch.shadow.hash_table);
+    ASSERT(d->arch.paging.shadow.hash_table);
     ASSERT(t);
 
     sh_hash_audit(d);
@@ -1748,8 +1450,8 @@ void shadow_hash_insert(struct vcpu *v, 
     
     /* Insert this shadow at the top of the bucket */
     sp = mfn_to_shadow_page(smfn);
-    sp->next_shadow = d->arch.shadow.hash_table[key];
-    d->arch.shadow.hash_table[key] = sp;
+    sp->next_shadow = d->arch.paging.shadow.hash_table[key];
+    d->arch.paging.shadow.hash_table[key] = sp;
     
     sh_hash_audit_bucket(d, key);
 }
@@ -1763,7 +1465,7 @@ void shadow_hash_delete(struct vcpu *v, 
     key_t key;
 
     ASSERT(shadow_locked_by_me(d));
-    ASSERT(d->arch.shadow.hash_table);
+    ASSERT(d->arch.paging.shadow.hash_table);
     ASSERT(t);
 
     sh_hash_audit(d);
@@ -1773,13 +1475,13 @@ void shadow_hash_delete(struct vcpu *v, 
     sh_hash_audit_bucket(d, key);
     
     sp = mfn_to_shadow_page(smfn);
-    if ( d->arch.shadow.hash_table[key] == sp ) 
+    if ( d->arch.paging.shadow.hash_table[key] == sp ) 
         /* Easy case: we're deleting the head item. */
-        d->arch.shadow.hash_table[key] = sp->next_shadow;
+        d->arch.paging.shadow.hash_table[key] = sp->next_shadow;
     else 
     {
         /* Need to search for the one we want */
-        x = d->arch.shadow.hash_table[key];
+        x = d->arch.paging.shadow.hash_table[key];
         while ( 1 )
         {
             ASSERT(x); /* We can't have hit the end, since our target is
@@ -1818,15 +1520,15 @@ static void hash_foreach(struct vcpu *v,
 
     /* Say we're here, to stop hash-lookups reordering the chains */
     ASSERT(shadow_locked_by_me(d));
-    ASSERT(d->arch.shadow.hash_walking == 0);
-    d->arch.shadow.hash_walking = 1;
+    ASSERT(d->arch.paging.shadow.hash_walking == 0);
+    d->arch.paging.shadow.hash_walking = 1;
 
     for ( i = 0; i < SHADOW_HASH_BUCKETS; i++ ) 
     {
         /* WARNING: This is not safe against changes to the hash table.
          * The callback *must* return non-zero if it has inserted or
          * deleted anything from the hash (lookups are OK, though). */
-        for ( x = d->arch.shadow.hash_table[i]; x; x = x->next_shadow )
+        for ( x = d->arch.paging.shadow.hash_table[i]; x; x = x->next_shadow )
         {
             if ( callback_mask & (1 << x->type) ) 
             {
@@ -1839,7 +1541,7 @@ static void hash_foreach(struct vcpu *v,
         }
         if ( done ) break; 
     }
-    d->arch.shadow.hash_walking = 0; 
+    d->arch.paging.shadow.hash_walking = 0; 
 }
 
 
@@ -2008,27 +1710,27 @@ int sh_remove_write_access(struct vcpu *
          * and that mapping is likely to be in the current pagetable,
          * in the guest's linear map (on non-HIGHPTE linux and windows)*/
 
-#define GUESS(_a, _h) do {                                              \
-            if ( v->arch.shadow.mode->guess_wrmap(v, (_a), gmfn) )      \
-                perfc_incrc(shadow_writeable_h_ ## _h);                 \
-            if ( (pg->u.inuse.type_info & PGT_count_mask) == 0 )        \
-                return 1;                                               \
+#define GUESS(_a, _h) do {                                                \
+            if ( v->arch.paging.mode->shadow.guess_wrmap(v, (_a), gmfn) ) \
+                perfc_incrc(shadow_writeable_h_ ## _h);                   \
+            if ( (pg->u.inuse.type_info & PGT_count_mask) == 0 )          \
+                return 1;                                                 \
         } while (0)
 
         
-        if ( v->arch.shadow.mode->guest_levels == 2 )
+        if ( v->arch.paging.mode->guest_levels == 2 )
         {
             if ( level == 1 )
                 /* 32bit non-PAE w2k3: linear map at 0xC0000000 */
                 GUESS(0xC0000000UL + (fault_addr >> 10), 1);
 
             /* Linux lowmem: first 896MB is mapped 1-to-1 above 0xC0000000 */
-            if ((gfn = sh_mfn_to_gfn(v->domain, gmfn)) < 0x38000 ) 
+            if ((gfn = mfn_to_gfn(v->domain, gmfn)) < 0x38000 ) 
                 GUESS(0xC0000000UL + (gfn << PAGE_SHIFT), 4);
 
         }
 #if CONFIG_PAGING_LEVELS >= 3
-        else if ( v->arch.shadow.mode->guest_levels == 3 )
+        else if ( v->arch.paging.mode->guest_levels == 3 )
         {
             /* 32bit PAE w2k3: linear map at 0xC0000000 */
             switch ( level ) 
@@ -2038,11 +1740,11 @@ int sh_remove_write_access(struct vcpu *
             }
 
             /* Linux lowmem: first 896MB is mapped 1-to-1 above 0xC0000000 */
-            if ((gfn = sh_mfn_to_gfn(v->domain, gmfn)) < 0x38000 ) 
+            if ((gfn = mfn_to_gfn(v->domain, gmfn)) < 0x38000 ) 
                 GUESS(0xC0000000UL + (gfn << PAGE_SHIFT), 4);
         }
 #if CONFIG_PAGING_LEVELS >= 4
-        else if ( v->arch.shadow.mode->guest_levels == 4 )
+        else if ( v->arch.paging.mode->guest_levels == 4 )
         {
             /* 64bit w2k3: linear map at 0x0000070000000000 */
             switch ( level ) 
@@ -2054,7 +1756,7 @@ int sh_remove_write_access(struct vcpu *
 
             /* 64bit Linux direct map at 0xffff810000000000; older kernels 
              * had it at 0x0000010000000000UL */
-            gfn = sh_mfn_to_gfn(v->domain, gmfn); 
+            gfn = mfn_to_gfn(v->domain, gmfn); 
             GUESS(0xffff810000000000UL + (gfn << PAGE_SHIFT), 4); 
             GUESS(0x0000010000000000UL + (gfn << PAGE_SHIFT), 4); 
         }
@@ -2073,10 +1775,10 @@ int sh_remove_write_access(struct vcpu *
      * the writeable mapping by looking at the same MFN where the last
      * brute-force search succeeded. */
 
-    if ( v->arch.shadow.last_writeable_pte_smfn != 0 )
+    if ( v->arch.paging.shadow.last_writeable_pte_smfn != 0 )
     {
         unsigned long old_count = (pg->u.inuse.type_info & PGT_count_mask);
-        mfn_t last_smfn = _mfn(v->arch.shadow.last_writeable_pte_smfn);
+        mfn_t last_smfn = _mfn(v->arch.paging.shadow.last_writeable_pte_smfn);
         int shtype = mfn_to_shadow_page(last_smfn)->type;
 
         if ( callbacks[shtype] ) 
@@ -2431,7 +2133,7 @@ static void sh_update_paging_modes(struc
 static void sh_update_paging_modes(struct vcpu *v)
 {
     struct domain *d = v->domain;
-    struct shadow_paging_mode *old_mode = v->arch.shadow.mode;
+    struct paging_mode *old_mode = v->arch.paging.mode;
     mfn_t old_guest_table;
 
     ASSERT(shadow_locked_by_me(d));
@@ -2446,8 +2148,8 @@ static void sh_update_paging_modes(struc
 
     // First, tear down any old shadow tables held by this vcpu.
     //
-    if ( v->arch.shadow.mode )
-        v->arch.shadow.mode->detach_old_tables(v);
+    if ( v->arch.paging.mode )
+        v->arch.paging.mode->shadow.detach_old_tables(v);
 
     if ( !is_hvm_domain(d) )
     {
@@ -2456,17 +2158,17 @@ static void sh_update_paging_modes(struc
         ///
 #if CONFIG_PAGING_LEVELS == 4
         if ( pv_32bit_guest(v) )
-            v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
+            v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
         else
-            v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,4,4);
+            v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,4,4);
 #elif CONFIG_PAGING_LEVELS == 3
-        v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
+        v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
 #elif CONFIG_PAGING_LEVELS == 2
-        v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,2,2);
+        v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,2,2);
 #else
 #error unexpected paging mode
 #endif
-        v->arch.shadow.translate_enabled = !!shadow_mode_translate(d);
+        v->arch.paging.translate_enabled = !!shadow_mode_translate(d);
     }
     else
     {
@@ -2476,8 +2178,8 @@ static void sh_update_paging_modes(struc
         ASSERT(shadow_mode_translate(d));
         ASSERT(shadow_mode_external(d));
 
-        v->arch.shadow.translate_enabled = !!hvm_paging_enabled(v);
-        if ( !v->arch.shadow.translate_enabled )
+        v->arch.paging.translate_enabled = !!hvm_paging_enabled(v);
+        if ( !v->arch.paging.translate_enabled )
         {
             /* Set v->arch.guest_table to use the p2m map, and choose
              * the appropriate shadow mode */
@@ -2485,11 +2187,11 @@ static void sh_update_paging_modes(struc
 #if CONFIG_PAGING_LEVELS == 2
             v->arch.guest_table =
                 pagetable_from_pfn(pagetable_get_pfn(d->arch.phys_table));
-            v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,2,2);
+            v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,2,2);
 #elif CONFIG_PAGING_LEVELS == 3 
             v->arch.guest_table =
                 pagetable_from_pfn(pagetable_get_pfn(d->arch.phys_table));
-            v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
+            v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
 #else /* CONFIG_PAGING_LEVELS == 4 */
             { 
                 l4_pgentry_t *l4e; 
@@ -2501,7 +2203,7 @@ static void sh_update_paging_modes(struc
                     pagetable_from_pfn(l4e_get_pfn(l4e[0]));
                 sh_unmap_domain_page(l4e);
             }
-            v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
+            v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
 #endif
             /* Fix up refcounts on guest_table */
             get_page(mfn_to_page(pagetable_get_mfn(v->arch.guest_table)), d);
@@ -2514,7 +2216,7 @@ static void sh_update_paging_modes(struc
             if ( hvm_long_mode_enabled(v) )
             {
                 // long mode guest...
-                v->arch.shadow.mode =
+                v->arch.paging.mode =
                     &SHADOW_INTERNAL_NAME(sh_paging_mode, 4, 4);
             }
             else
@@ -2523,7 +2225,7 @@ static void sh_update_paging_modes(struc
                 {
 #if CONFIG_PAGING_LEVELS >= 3
                     // 32-bit PAE mode guest...
-                    v->arch.shadow.mode =
+                    v->arch.paging.mode =
                         &SHADOW_INTERNAL_NAME(sh_paging_mode, 3, 3);
 #else
                     SHADOW_ERROR("PAE not supported in 32-bit Xen\n");
@@ -2535,10 +2237,10 @@ static void sh_update_paging_modes(struc
                 {
                     // 32-bit 2 level guest...
 #if CONFIG_PAGING_LEVELS >= 3
-                    v->arch.shadow.mode =
+                    v->arch.paging.mode =
                         &SHADOW_INTERNAL_NAME(sh_paging_mode, 3, 2);
 #else
-                    v->arch.shadow.mode =
+                    v->arch.paging.mode =
                         &SHADOW_INTERNAL_NAME(sh_paging_mode, 2, 2);
 #endif
                 }
@@ -2546,25 +2248,25 @@ static void sh_update_paging_modes(struc
 
         if ( pagetable_is_null(v->arch.monitor_table) )
         {
-            mfn_t mmfn = v->arch.shadow.mode->make_monitor_table(v);
+            mfn_t mmfn = v->arch.paging.mode->shadow.make_monitor_table(v);
             v->arch.monitor_table = pagetable_from_mfn(mmfn);
             make_cr3(v, mfn_x(mmfn));
             hvm_update_host_cr3(v);
         }
 
-        if ( v->arch.shadow.mode != old_mode )
+        if ( v->arch.paging.mode != old_mode )
         {
             SHADOW_PRINTK("new paging mode: d=%u v=%u pe=%d g=%u s=%u "
                           "(was g=%u s=%u)\n",
                           d->domain_id, v->vcpu_id,
                           is_hvm_domain(d) ? !!hvm_paging_enabled(v) : 1,
-                          v->arch.shadow.mode->guest_levels,
-                          v->arch.shadow.mode->shadow_levels,
+                          v->arch.paging.mode->guest_levels,
+                          v->arch.paging.mode->shadow.shadow_levels,
                           old_mode ? old_mode->guest_levels : 0,
-                          old_mode ? old_mode->shadow_levels : 0);
+                          old_mode ? old_mode->shadow.shadow_levels : 0);
             if ( old_mode &&
-                 (v->arch.shadow.mode->shadow_levels !=
-                  old_mode->shadow_levels) )
+                 (v->arch.paging.mode->shadow.shadow_levels !=
+                  old_mode->shadow.shadow_levels) )
             {
                 /* Need to make a new monitor table for the new mode */
                 mfn_t new_mfn, old_mfn;
@@ -2584,9 +2286,9 @@ static void sh_update_paging_modes(struc
 
                 old_mfn = pagetable_get_mfn(v->arch.monitor_table);
                 v->arch.monitor_table = pagetable_null();
-                new_mfn = v->arch.shadow.mode->make_monitor_table(v);
+                new_mfn = v->arch.paging.mode->shadow.make_monitor_table(v);
                 v->arch.monitor_table = pagetable_from_mfn(new_mfn);
-                SHADOW_PRINTK("new monitor table %"SH_PRI_mfn "\n",
+                SHADOW_PRINTK("new monitor table %"PRI_mfn "\n",
                                mfn_x(new_mfn));
 
                 /* Don't be running on the old monitor table when we 
@@ -2596,7 +2298,7 @@ static void sh_update_paging_modes(struc
                 if ( v == current )
                     write_ptbase(v);
                 hvm_update_host_cr3(v);
-                old_mode->destroy_monitor_table(v, old_mfn);
+                old_mode->shadow.destroy_monitor_table(v, old_mfn);
             }
         }
 
@@ -2606,7 +2308,7 @@ static void sh_update_paging_modes(struc
         //        This *does* happen, at least for CR4.PGE...
     }
 
-    v->arch.shadow.mode->update_cr3(v, 0);
+    v->arch.paging.mode->update_cr3(v, 0);
 }
 
 void shadow_update_paging_modes(struct vcpu *v)
@@ -2626,9 +2328,7 @@ static void sh_new_mode(struct domain *d
 
     ASSERT(shadow_locked_by_me(d));
     ASSERT(d != current->domain);
-    d->arch.shadow.mode = new_mode;
-    if ( new_mode & SHM2_translate ) 
-        shadow_audit_p2m(d);
+    d->arch.paging.mode = new_mode;
     for_each_vcpu(d, v)
         sh_update_paging_modes(v);
 }
@@ -2642,75 +2342,75 @@ int shadow_enable(struct domain *d, u32 
     unsigned int old_pages;
     int rv = 0;
 
-    mode |= SHM2_enable;
+    mode |= PG_SH_enable;
 
     domain_pause(d);
-    shadow_lock(d);
 
     /* Sanity check the arguments */
     if ( (d == current->domain) ||
          shadow_mode_enabled(d) ||
-         ((mode & SHM2_translate) && !(mode & SHM2_refcounts)) ||
-         ((mode & SHM2_external) && !(mode & SHM2_translate)) )
+         ((mode & PG_translate) && !(mode & PG_refcounts)) ||
+         ((mode & PG_external) && !(mode & PG_translate)) )
     {
         rv = -EINVAL;
-        goto out;
-    }
-
-    // XXX -- eventually would like to require that all memory be allocated
-    // *after* shadow_enabled() is called...  So here, we would test to make
-    // sure that d->page_list is empty.
-#if 0
-    spin_lock(&d->page_alloc_lock);
-    if ( !list_empty(&d->page_list) )
-    {
-        spin_unlock(&d->page_alloc_lock);
-        rv = -EINVAL;
-        goto out;
-    }
-    spin_unlock(&d->page_alloc_lock);
-#endif
+        goto out_unlocked;
+    }
 
     /* Init the shadow memory allocation if the user hasn't done so */
-    old_pages = d->arch.shadow.total_pages;
+    old_pages = d->arch.paging.shadow.total_pages;
     if ( old_pages == 0 )
-        if ( sh_set_allocation(d, 256, NULL) != 0 ) /* Use at least 1MB */
+    {
+        unsigned int r;
+        shadow_lock(d);                
+        r = sh_set_allocation(d, 256, NULL); /* Use at least 1MB */
+        shadow_unlock(d);
+        if ( r != 0 )
         {
             sh_set_allocation(d, 0, NULL);
             rv = -ENOMEM;
-            goto out;
-        }
+            goto out_unlocked;
+        }        
+    }
+
+    /* Init the P2M table.  Must be done before we take the shadow lock 
+     * to avoid possible deadlock. */
+    if ( mode & PG_translate )
+    {
+        rv = p2m_alloc_table(d, shadow_alloc_p2m_page, shadow_free_p2m_page);
+        if (rv != 0)
+            goto out_unlocked;
+    }
+
+    shadow_lock(d);
+
+    /* Sanity check again with the lock held */
+    if ( shadow_mode_enabled(d) )
+    {
+        rv = -EINVAL;
+        goto out_locked;
+    }
 
     /* Init the hash table */
     if ( shadow_hash_alloc(d) != 0 )
     {
-        sh_set_allocation(d, old_pages, NULL);            
         rv = -ENOMEM;
-        goto out;
-    }
-
-    /* Init the P2M table */
-    if ( mode & SHM2_translate )
-        if ( !shadow_alloc_p2m_table(d) )
-        {
-            shadow_hash_teardown(d);
-            sh_set_allocation(d, old_pages, NULL);
-            shadow_p2m_teardown(d);
-            rv = -ENOMEM;
-            goto out;
-        }
+        goto out_locked;
+    }
 
 #if (SHADOW_OPTIMIZATIONS & SHOPT_LINUX_L3_TOPLEVEL) 
     /* We assume we're dealing with an older 64bit linux guest until we 
      * see the guest use more than one l4 per vcpu. */
-    d->arch.shadow.opt_flags = SHOPT_LINUX_L3_TOPLEVEL;
+    d->arch.paging.shadow.opt_flags = SHOPT_LINUX_L3_TOPLEVEL;
 #endif
 
     /* Update the bits */
     sh_new_mode(d, mode);
-    shadow_audit_p2m(d);
- out:
+
+ out_locked:
     shadow_unlock(d);
+ out_unlocked:
+    if ( rv != 0 && !pagetable_is_null(d->arch.phys_table) )
+        p2m_teardown(d);
     domain_unpause(d);
     return rv;
 }
@@ -2721,6 +2421,8 @@ void shadow_teardown(struct domain *d)
 {
     struct vcpu *v;
     mfn_t mfn;
+    struct list_head *entry, *n;
+    struct page_info *pg;
 
     ASSERT(test_bit(_DOMF_dying, &d->domain_flags));
     ASSERT(d != current->domain);
@@ -2733,48 +2435,55 @@ void shadow_teardown(struct domain *d)
         /* Release the shadow and monitor tables held by each vcpu */
         for_each_vcpu(d, v)
         {
-            if ( v->arch.shadow.mode )
+            if ( v->arch.paging.mode )
             {
-                v->arch.shadow.mode->detach_old_tables(v);
+                v->arch.paging.mode->shadow.detach_old_tables(v);
                 if ( shadow_mode_external(d) )
                 {
                     mfn = pagetable_get_mfn(v->arch.monitor_table);
                     if ( mfn_valid(mfn) && (mfn_x(mfn) != 0) )
-                        v->arch.shadow.mode->destroy_monitor_table(v, mfn);
+                        v->arch.paging.mode->shadow.destroy_monitor_table(v, 
mfn);
                     v->arch.monitor_table = pagetable_null();
                 }
             }
         }
     }
 
-    if ( d->arch.shadow.total_pages != 0 )
+    list_for_each_safe(entry, n, &d->arch.paging.shadow.p2m_freelist)
+    {
+        list_del(entry);
+        pg = list_entry(entry, struct page_info, list);
+        shadow_free_p2m_page(d, pg);
+    }
+
+    if ( d->arch.paging.shadow.total_pages != 0 )
     {
         SHADOW_PRINTK("teardown of domain %u starts."
                        "  Shadow pages total = %u, free = %u, p2m=%u\n",
                        d->domain_id,
-                       d->arch.shadow.total_pages, 
-                       d->arch.shadow.free_pages, 
-                       d->arch.shadow.p2m_pages);
+                       d->arch.paging.shadow.total_pages, 
+                       d->arch.paging.shadow.free_pages, 
+                       d->arch.paging.shadow.p2m_pages);
         /* Destroy all the shadows and release memory to domheap */
         sh_set_allocation(d, 0, NULL);
         /* Release the hash table back to xenheap */
-        if (d->arch.shadow.hash_table) 
+        if (d->arch.paging.shadow.hash_table) 
             shadow_hash_teardown(d);
         /* Release the log-dirty bitmap of dirtied pages */
         sh_free_log_dirty_bitmap(d);
         /* Should not have any more memory held */
         SHADOW_PRINTK("teardown done."
                        "  Shadow pages total = %u, free = %u, p2m=%u\n",
-                       d->arch.shadow.total_pages, 
-                       d->arch.shadow.free_pages, 
-                       d->arch.shadow.p2m_pages);
-        ASSERT(d->arch.shadow.total_pages == 0);
+                       d->arch.paging.shadow.total_pages, 
+                       d->arch.paging.shadow.free_pages, 
+                       d->arch.paging.shadow.p2m_pages);
+        ASSERT(d->arch.paging.shadow.total_pages == 0);
     }
 
     /* We leave the "permanent" shadow modes enabled, but clear the
      * log-dirty mode bit.  We don't want any more mark_dirty()
      * calls now that we've torn down the bitmap */
-    d->arch.shadow.mode &= ~SHM2_log_dirty;
+    d->arch.paging.mode &= ~PG_log_dirty;
 
     shadow_unlock(d);
 }
@@ -2782,30 +2491,28 @@ void shadow_final_teardown(struct domain
 void shadow_final_teardown(struct domain *d)
 /* Called by arch_domain_destroy(), when it's safe to pull down the p2m map. */
 {
-
     SHADOW_PRINTK("dom %u final teardown starts."
                    "  Shadow pages total = %u, free = %u, p2m=%u\n",
                    d->domain_id,
-                   d->arch.shadow.total_pages, 
-                   d->arch.shadow.free_pages, 
-                   d->arch.shadow.p2m_pages);
+                   d->arch.paging.shadow.total_pages, 
+                   d->arch.paging.shadow.free_pages, 
+                   d->arch.paging.shadow.p2m_pages);
 
     /* Double-check that the domain didn't have any shadow memory.  
      * It is possible for a domain that never got domain_kill()ed
      * to get here with its shadow allocation intact. */
-    if ( d->arch.shadow.total_pages != 0 )
+    if ( d->arch.paging.shadow.total_pages != 0 )
         shadow_teardown(d);
 
     /* It is now safe to pull down the p2m map. */
-    if ( d->arch.shadow.p2m_pages != 0 )
-        shadow_p2m_teardown(d);
+    p2m_teardown(d);
 
     SHADOW_PRINTK("dom %u final teardown done."
                    "  Shadow pages total = %u, free = %u, p2m=%u\n",
                    d->domain_id,
-                   d->arch.shadow.total_pages, 
-                   d->arch.shadow.free_pages, 
-                   d->arch.shadow.p2m_pages);
+                   d->arch.paging.shadow.total_pages, 
+                   d->arch.paging.shadow.free_pages, 
+                   d->arch.paging.shadow.p2m_pages);
 }
 
 static int shadow_one_bit_enable(struct domain *d, u32 mode)
@@ -2814,12 +2521,14 @@ static int shadow_one_bit_enable(struct 
     ASSERT(shadow_locked_by_me(d));
 
     /* Sanity check the call */
-    if ( d == current->domain || (d->arch.shadow.mode & mode) )
+    if ( d == current->domain || (d->arch.paging.mode & mode) )
     {
         return -EINVAL;
     }
 
-    if ( d->arch.shadow.mode == 0 )
+    mode |= PG_SH_enable;
+
+    if ( d->arch.paging.mode == 0 )
     {
         /* Init the shadow memory allocation and the hash table */
         if ( sh_set_allocation(d, 1, NULL) != 0 
@@ -2831,7 +2540,7 @@ static int shadow_one_bit_enable(struct 
     }
 
     /* Update the bits */
-    sh_new_mode(d, d->arch.shadow.mode | mode);
+    sh_new_mode(d, d->arch.paging.mode | mode);
 
     return 0;
 }
@@ -2843,26 +2552,26 @@ static int shadow_one_bit_disable(struct
     ASSERT(shadow_locked_by_me(d));
 
     /* Sanity check the call */
-    if ( d == current->domain || !(d->arch.shadow.mode & mode) )
+    if ( d == current->domain || !(d->arch.paging.mode & mode) )
     {
         return -EINVAL;
     }
 
     /* Update the bits */
-    sh_new_mode(d, d->arch.shadow.mode & ~mode);
-    if ( d->arch.shadow.mode == 0 )
+    sh_new_mode(d, d->arch.paging.mode & ~mode);
+    if ( d->arch.paging.mode == 0 )
     {
         /* Get this domain off shadows */
         SHADOW_PRINTK("un-shadowing of domain %u starts."
                        "  Shadow pages total = %u, free = %u, p2m=%u\n",
                        d->domain_id,
-                       d->arch.shadow.total_pages, 
-                       d->arch.shadow.free_pages, 
-                       d->arch.shadow.p2m_pages);
+                       d->arch.paging.shadow.total_pages, 
+                       d->arch.paging.shadow.free_pages, 
+                       d->arch.paging.shadow.p2m_pages);
         for_each_vcpu(d, v)
         {
-            if ( v->arch.shadow.mode )
-                v->arch.shadow.mode->detach_old_tables(v);
+            if ( v->arch.paging.mode )
+                v->arch.paging.mode->shadow.detach_old_tables(v);
 #if CONFIG_PAGING_LEVELS == 4
             if ( !(v->arch.flags & TF_kernel_mode) )
                 make_cr3(v, pagetable_get_pfn(v->arch.guest_table_user));
@@ -2885,9 +2594,9 @@ static int shadow_one_bit_disable(struct
         SHADOW_PRINTK("un-shadowing of domain %u done."
                        "  Shadow pages total = %u, free = %u, p2m=%u\n",
                        d->domain_id,
-                       d->arch.shadow.total_pages, 
-                       d->arch.shadow.free_pages, 
-                       d->arch.shadow.p2m_pages);
+                       d->arch.paging.shadow.total_pages, 
+                       d->arch.paging.shadow.free_pages, 
+                       d->arch.paging.shadow.p2m_pages);
     }
 
     return 0;
@@ -2909,7 +2618,7 @@ static int shadow_test_enable(struct dom
         goto out;
     }
 
-    ret = shadow_one_bit_enable(d, SHM2_enable);
+    ret = shadow_one_bit_enable(d, PG_SH_enable);
  out:
     shadow_unlock(d);
     domain_unpause(d);
@@ -2923,7 +2632,7 @@ static int shadow_test_disable(struct do
 
     domain_pause(d);
     shadow_lock(d);
-    ret = shadow_one_bit_disable(d, SHM2_enable);
+    ret = shadow_one_bit_disable(d, PG_SH_enable);
     shadow_unlock(d);
     domain_unpause(d);
 
@@ -2933,19 +2642,19 @@ static int
 static int
 sh_alloc_log_dirty_bitmap(struct domain *d)
 {
-    ASSERT(d->arch.shadow.dirty_bitmap == NULL);
-    d->arch.shadow.dirty_bitmap_size =
+    ASSERT(d->arch.paging.shadow.dirty_bitmap == NULL);
+    d->arch.paging.shadow.dirty_bitmap_size =
         (arch_get_max_pfn(d) + (BITS_PER_LONG - 1)) &
         ~(BITS_PER_LONG - 1);
-    d->arch.shadow.dirty_bitmap =
+    d->arch.paging.shadow.dirty_bitmap =
         xmalloc_array(unsigned long,
-                      d->arch.shadow.dirty_bitmap_size / BITS_PER_LONG);
-    if ( d->arch.shadow.dirty_bitmap == NULL )
-    {
-        d->arch.shadow.dirty_bitmap_size = 0;
+                      d->arch.paging.shadow.dirty_bitmap_size / BITS_PER_LONG);
+    if ( d->arch.paging.shadow.dirty_bitmap == NULL )
+    {
+        d->arch.paging.shadow.dirty_bitmap_size = 0;
         return -ENOMEM;
     }
-    memset(d->arch.shadow.dirty_bitmap, 0, d->arch.shadow.dirty_bitmap_size/8);
+    memset(d->arch.paging.shadow.dirty_bitmap, 0, 
d->arch.paging.shadow.dirty_bitmap_size/8);
 
     return 0;
 }
@@ -2953,11 +2662,11 @@ static void
 static void
 sh_free_log_dirty_bitmap(struct domain *d)
 {
-    d->arch.shadow.dirty_bitmap_size = 0;
-    if ( d->arch.shadow.dirty_bitmap )
-    {
-        xfree(d->arch.shadow.dirty_bitmap);
-        d->arch.shadow.dirty_bitmap = NULL;
+    d->arch.paging.shadow.dirty_bitmap_size = 0;
+    if ( d->arch.paging.shadow.dirty_bitmap )
+    {
+        xfree(d->arch.paging.shadow.dirty_bitmap);
+        d->arch.paging.shadow.dirty_bitmap = NULL;
     }
 }
 
@@ -2989,7 +2698,7 @@ static int shadow_log_dirty_enable(struc
         goto out;
     }
 
-    ret = shadow_one_bit_enable(d, SHM2_log_dirty);
+    ret = shadow_one_bit_enable(d, PG_log_dirty);
     if ( ret != 0 )
         sh_free_log_dirty_bitmap(d);
 
@@ -3005,7 +2714,7 @@ static int shadow_log_dirty_disable(stru
 
     domain_pause(d);
     shadow_lock(d);
-    ret = shadow_one_bit_disable(d, SHM2_log_dirty);
+    ret = shadow_one_bit_disable(d, PG_log_dirty);
     if ( !shadow_mode_log_dirty(d) )
         sh_free_log_dirty_bitmap(d);
     shadow_unlock(d);
@@ -3017,100 +2726,52 @@ static int shadow_log_dirty_disable(stru
 /**************************************************************************/
 /* P2M map manipulations */
 
-static void
-sh_p2m_remove_page(struct domain *d, unsigned long gfn, unsigned long mfn)
-{
-    struct vcpu *v;
-
-    if ( !shadow_mode_translate(d) )
-        return;
-
-    v = current;
-    if ( v->domain != d )
-        v = d->vcpu[0];
-
-    SHADOW_DEBUG(P2M, "removing gfn=%#lx mfn=%#lx\n", gfn, mfn);
-
-    ASSERT(mfn_x(sh_gfn_to_mfn(d, gfn)) == mfn);
-    //ASSERT(sh_mfn_to_gfn(d, mfn) == gfn);
-
-    if ( v != NULL )
-    {
-        sh_remove_all_shadows_and_parents(v, _mfn(mfn));
-        if ( sh_remove_all_mappings(v, _mfn(mfn)) )
-            flush_tlb_mask(d->domain_dirty_cpumask);
-    }
-
-    shadow_set_p2m_entry(d, gfn, _mfn(INVALID_MFN));
-    set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
-}
-
+/* shadow specific code which should be called when P2M table entry is updated
+ * with new content. It is responsible for update the entry, as well as other 
+ * shadow processing jobs.
+ */
 void
-shadow_guest_physmap_remove_page(struct domain *d, unsigned long gfn,
-                                  unsigned long mfn)
-{
+shadow_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p, 
+                       l1_pgentry_t new, unsigned int level)
+{
+    struct domain *d = v->domain;
+    mfn_t table_mfn = pagetable_get_mfn(d->arch.phys_table);
+    mfn_t mfn;
+    
     shadow_lock(d);
-    shadow_audit_p2m(d);
-    sh_p2m_remove_page(d, gfn, mfn);
-    shadow_audit_p2m(d);
-    shadow_unlock(d);    
-}
-
-void
-shadow_guest_physmap_add_page(struct domain *d, unsigned long gfn,
-                               unsigned long mfn)
-{
-    unsigned long ogfn;
-    mfn_t omfn;
-
-    if ( !shadow_mode_translate(d) )
-        return;
-
-    shadow_lock(d);
-    shadow_audit_p2m(d);
-
-    SHADOW_DEBUG(P2M, "adding gfn=%#lx mfn=%#lx\n", gfn, mfn);
-
-    omfn = sh_gfn_to_mfn(d, gfn);
-    if ( mfn_valid(omfn) )
-    {
-        /* Get rid of the old mapping, especially any shadows */
-        struct vcpu *v = current;
-        if ( v->domain != d )
-            v = d->vcpu[0];
-        if ( v != NULL )
-        {
-            sh_remove_all_shadows_and_parents(v, omfn);
-            if ( sh_remove_all_mappings(v, omfn) )
-                flush_tlb_mask(d->domain_dirty_cpumask);
-        }
-        set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY);
-    }
-
-    ogfn = sh_mfn_to_gfn(d, _mfn(mfn));
-    if (
-#ifdef __x86_64__
-        (ogfn != 0x5555555555555555L)
-#else
-        (ogfn != 0x55555555L)
-#endif
-        && (ogfn != INVALID_M2P_ENTRY)
-        && (ogfn != gfn) )
-    {
-        /* This machine frame is already mapped at another physical address */
-        SHADOW_DEBUG(P2M, "aliased! mfn=%#lx, old gfn=%#lx, new gfn=%#lx\n",
-                       mfn, ogfn, gfn);
-        if ( mfn_valid(omfn = sh_gfn_to_mfn(d, ogfn)) ) 
-        {
-            SHADOW_DEBUG(P2M, "old gfn=%#lx -> mfn %#lx\n", 
-                           ogfn , mfn_x(omfn));
-            if ( mfn_x(omfn) == mfn ) 
-                sh_p2m_remove_page(d, ogfn, mfn);
-        }
-    }
-
-    shadow_set_p2m_entry(d, gfn, _mfn(mfn));
-    set_gpfn_from_mfn(mfn, gfn);
+
+    /* handle physmap_add and physmap_remove */
+    mfn = gfn_to_mfn(d, gfn);
+    if ( v != NULL && level == 1 && mfn_valid(mfn) ) {
+        sh_remove_all_shadows_and_parents(v, mfn);
+        if ( sh_remove_all_mappings(v, mfn) )
+            flush_tlb_mask(d->domain_dirty_cpumask);    
+    }
+    
+    /* update the entry with new content */
+    safe_write_pte(p, new);
+
+    /* The P2M can be shadowed: keep the shadows synced */
+    if ( d->vcpu[0] != NULL )
+        (void)sh_validate_guest_entry(d->vcpu[0], table_mfn, p, sizeof(*p));
+
+    /* install P2M in monitors for PAE Xen */
+#if CONFIG_PAGING_LEVELS == 3
+    if ( level == 3 ) {
+        struct vcpu *v;
+        /* We have written to the p2m l3: need to sync the per-vcpu
+         * copies of it in the monitor tables */
+        p2m_install_entry_in_monitors(d, (l3_pgentry_t *)p);
+        /* Also, any vcpus running on shadows of the p2m need to 
+         * reload their CR3s so the change propagates to the shadow */
+        for_each_vcpu(d, v) {
+            if ( pagetable_get_pfn(v->arch.guest_table) 
+                 == pagetable_get_pfn(d->arch.phys_table) 
+                 && v->arch.paging.mode != NULL )
+                v->arch.paging.mode->update_cr3(v, 0);
+        }
+    }
+#endif
 
 #if (SHADOW_OPTIMIZATIONS & SHOPT_FAST_FAULT_PATH)
     /* If we're doing FAST_FAULT_PATH, then shadow mode may have
@@ -3122,7 +2783,6 @@ shadow_guest_physmap_add_page(struct dom
     shadow_blow_tables(d);
 #endif
 
-    shadow_audit_p2m(d);
     shadow_unlock(d);
 }
 
@@ -3151,11 +2811,11 @@ static int shadow_log_dirty_op(
     SHADOW_DEBUG(LOGDIRTY, "log-dirty %s: dom %u faults=%u dirty=%u\n", 
                   (clean) ? "clean" : "peek",
                   d->domain_id,
-                  d->arch.shadow.fault_count, 
-                  d->arch.shadow.dirty_count);
-
-    sc->stats.fault_count = d->arch.shadow.fault_count;
-    sc->stats.dirty_count = d->arch.shadow.dirty_count;
+                  d->arch.paging.shadow.fault_count, 
+                  d->arch.paging.shadow.dirty_count);
+
+    sc->stats.fault_count = d->arch.paging.shadow.fault_count;
+    sc->stats.dirty_count = d->arch.paging.shadow.dirty_count;
 
     if ( clean )
     {
@@ -3164,22 +2824,22 @@ static int shadow_log_dirty_op(
          * but for now, we just unshadow everything except Xen. */
         shadow_blow_tables(d);
 
-        d->arch.shadow.fault_count = 0;
-        d->arch.shadow.dirty_count = 0;
+        d->arch.paging.shadow.fault_count = 0;
+        d->arch.paging.shadow.dirty_count = 0;
     }
 
     if ( guest_handle_is_null(sc->dirty_bitmap) )
         /* caller may have wanted just to clean the state or access stats. */
         peek = 0;
 
-    if ( (peek || clean) && (d->arch.shadow.dirty_bitmap == NULL) )
+    if ( (peek || clean) && (d->arch.paging.shadow.dirty_bitmap == NULL) )
     {
         rv = -EINVAL; /* perhaps should be ENOMEM? */
         goto out;
     }
  
-    if ( sc->pages > d->arch.shadow.dirty_bitmap_size )
-        sc->pages = d->arch.shadow.dirty_bitmap_size;
+    if ( sc->pages > d->arch.paging.shadow.dirty_bitmap_size )
+        sc->pages = d->arch.paging.shadow.dirty_bitmap_size;
 
 #define CHUNK (8*1024) /* Transfer and clear in 1kB chunks for L1 cache. */
     for ( i = 0; i < sc->pages; i += CHUNK )
@@ -3192,7 +2852,7 @@ static int shadow_log_dirty_op(
         {
             if ( copy_to_guest_offset(
                 sc->dirty_bitmap, i/8,
-                (uint8_t *)d->arch.shadow.dirty_bitmap + (i/8), bytes) )
+                (uint8_t *)d->arch.paging.shadow.dirty_bitmap + (i/8), bytes) )
             {
                 rv = -EFAULT;
                 goto out;
@@ -3200,7 +2860,7 @@ static int shadow_log_dirty_op(
         }
 
         if ( clean )
-            memset((uint8_t *)d->arch.shadow.dirty_bitmap + (i/8), 0, bytes);
+            memset((uint8_t *)d->arch.paging.shadow.dirty_bitmap + (i/8), 0, 
bytes);
     }
 #undef CHUNK
 
@@ -3221,7 +2881,7 @@ void sh_mark_dirty(struct domain *d, mfn
     if ( !shadow_mode_log_dirty(d) || !mfn_valid(gmfn) )
         return;
 
-    ASSERT(d->arch.shadow.dirty_bitmap != NULL);
+    ASSERT(d->arch.paging.shadow.dirty_bitmap != NULL);
 
     /* We /really/ mean PFN here, even for non-translated guests. */
     pfn = get_gpfn_from_mfn(mfn_x(gmfn));
@@ -3235,24 +2895,24 @@ void sh_mark_dirty(struct domain *d, mfn
         return;
 
     /* N.B. Can use non-atomic TAS because protected by shadow_lock. */
-    if ( likely(pfn < d->arch.shadow.dirty_bitmap_size) ) 
+    if ( likely(pfn < d->arch.paging.shadow.dirty_bitmap_size) ) 
     { 
-        if ( !__test_and_set_bit(pfn, d->arch.shadow.dirty_bitmap) )
+        if ( !__test_and_set_bit(pfn, d->arch.paging.shadow.dirty_bitmap) )
         {
             SHADOW_DEBUG(LOGDIRTY, 
-                          "marked mfn %" SH_PRI_mfn " (pfn=%lx), dom %d\n",
+                          "marked mfn %" PRI_mfn " (pfn=%lx), dom %d\n",
                           mfn_x(gmfn), pfn, d->domain_id);
-            d->arch.shadow.dirty_count++;
+            d->arch.paging.shadow.dirty_count++;
         }
     }
     else
     {
         SHADOW_PRINTK("mark_dirty OOR! "
-                       "mfn=%" SH_PRI_mfn " pfn=%lx max=%x (dom %d)\n"
+                       "mfn=%" PRI_mfn " pfn=%lx max=%x (dom %d)\n"
                        "owner=%d c=%08x t=%" PRtype_info "\n",
                        mfn_x(gmfn), 
                        pfn, 
-                       d->arch.shadow.dirty_bitmap_size,
+                       d->arch.paging.shadow.dirty_bitmap_size,
                        d->domain_id,
                        (page_get_owner(mfn_to_page(gmfn))
                         ? page_get_owner(mfn_to_page(gmfn))->domain_id
@@ -3292,7 +2952,7 @@ int shadow_domctl(struct domain *d,
                 return rc;
         if ( is_hvm_domain(d) )
             return -EINVAL;
-        if ( d->arch.shadow.mode & SHM2_enable )
+        if ( d->arch.paging.mode & PG_SH_enable )
             if ( (rc = shadow_test_disable(d)) != 0 ) 
                 return rc;
         return 0;
@@ -3304,7 +2964,7 @@ int shadow_domctl(struct domain *d,
         return shadow_log_dirty_enable(d);
 
     case XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE:
-        return shadow_enable(d, SHM2_refcounts|SHM2_translate);
+        return shadow_enable(d, PG_refcounts|PG_translate);
 
     case XEN_DOMCTL_SHADOW_OP_CLEAN:
     case XEN_DOMCTL_SHADOW_OP_PEEK:
@@ -3313,7 +2973,7 @@ int shadow_domctl(struct domain *d,
     case XEN_DOMCTL_SHADOW_OP_ENABLE:
         if ( sc->mode & XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY )
             return shadow_log_dirty_enable(d);
-        return shadow_enable(d, sc->mode << SHM2_shift);
+        return shadow_enable(d, sc->mode << PG_mode_shift);
 
     case XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION:
         sc->mb = shadow_get_allocation(d);
@@ -3390,7 +3050,7 @@ void shadow_audit_tables(struct vcpu *v)
     else 
     {
         /* Audit only the current mode's tables */
-        switch ( v->arch.shadow.mode->guest_levels )
+        switch ( v->arch.paging.mode->guest_levels )
         {
         case 2: mask = (SHF_L1_32|SHF_FL1_32|SHF_L2_32); break;
         case 3: mask = (SHF_L1_PAE|SHF_FL1_PAE|SHF_L2_PAE
@@ -3405,199 +3065,6 @@ void shadow_audit_tables(struct vcpu *v)
 }
 
 #endif /* Shadow audit */
-
-
-/**************************************************************************/
-/* Auditing p2m tables */
-
-#if SHADOW_AUDIT & SHADOW_AUDIT_P2M
-
-void shadow_audit_p2m(struct domain *d)
-{
-    struct list_head *entry;
-    struct page_info *page;
-    struct domain *od;
-    unsigned long mfn, gfn, m2pfn, lp2mfn = 0;
-    mfn_t p2mfn;
-    unsigned long orphans_d = 0, orphans_i = 0, mpbad = 0, pmbad = 0;
-    int test_linear;
-    
-    if ( !(SHADOW_AUDIT_ENABLE) || !shadow_mode_translate(d) )
-        return;
-
-    //SHADOW_PRINTK("p2m audit starts\n");
-
-    test_linear = ( (d == current->domain) 
-                    && !pagetable_is_null(current->arch.monitor_table) );
-    if ( test_linear )
-        local_flush_tlb(); 
-
-    /* Audit part one: walk the domain's page allocation list, checking 
-     * the m2p entries. */
-    for ( entry = d->page_list.next;
-          entry != &d->page_list;
-          entry = entry->next )
-    {
-        page = list_entry(entry, struct page_info, list);
-        mfn = mfn_x(page_to_mfn(page));
-
-        // SHADOW_PRINTK("auditing guest page, mfn=%#lx\n", mfn); 
-
-        od = page_get_owner(page);
-
-        if ( od != d ) 
-        {
-            SHADOW_PRINTK("wrong owner %#lx -> %p(%u) != %p(%u)\n",
-                           mfn, od, (od?od->domain_id:-1), d, d->domain_id);
-            continue;
-        }
-
-        gfn = get_gpfn_from_mfn(mfn);
-        if ( gfn == INVALID_M2P_ENTRY ) 
-        {
-            orphans_i++;
-            //SHADOW_PRINTK("orphaned guest page: mfn=%#lx has invalid gfn\n",
-            //               mfn); 
-            continue;
-        }
-
-        if ( gfn == 0x55555555 ) 
-        {
-            orphans_d++;
-            //SHADOW_PRINTK("orphaned guest page: mfn=%#lx has debug gfn\n", 
-            //               mfn); 
-            continue;
-        }
-
-        p2mfn = sh_gfn_to_mfn_foreign(d, gfn);
-        if ( mfn_x(p2mfn) != mfn )
-        {
-            mpbad++;
-            SHADOW_PRINTK("map mismatch mfn %#lx -> gfn %#lx -> mfn %#lx"
-                           " (-> gfn %#lx)\n",
-                           mfn, gfn, mfn_x(p2mfn),
-                           (mfn_valid(p2mfn)
-                            ? get_gpfn_from_mfn(mfn_x(p2mfn))
-                            : -1u));
-            /* This m2p entry is stale: the domain has another frame in
-             * this physical slot.  No great disaster, but for neatness,
-             * blow away the m2p entry. */ 
-            set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
-        }
-
-        if ( test_linear && (gfn <= d->arch.max_mapped_pfn) )
-        {
-            lp2mfn = gfn_to_mfn_current(gfn);
-            if ( mfn_x(lp2mfn) != mfn_x(p2mfn) )
-            {
-                SHADOW_PRINTK("linear mismatch gfn %#lx -> mfn %#lx "
-                              "(!= mfn %#lx)\n", gfn, 
-                              mfn_x(lp2mfn), mfn_x(p2mfn));
-            }
-        }
-
-        // SHADOW_PRINTK("OK: mfn=%#lx, gfn=%#lx, p2mfn=%#lx, lp2mfn=%#lx\n", 
-        //                mfn, gfn, p2mfn, lp2mfn); 
-    }   
-
-    /* Audit part two: walk the domain's p2m table, checking the entries. */
-    if ( pagetable_get_pfn(d->arch.phys_table) != 0 )
-    {
-        l2_pgentry_t *l2e;
-        l1_pgentry_t *l1e;
-        int i1, i2;
-        
-#if CONFIG_PAGING_LEVELS == 4
-        l4_pgentry_t *l4e;
-        l3_pgentry_t *l3e;
-        int i3, i4;
-        l4e = sh_map_domain_page(pagetable_get_mfn(d->arch.phys_table));
-#elif CONFIG_PAGING_LEVELS == 3
-        l3_pgentry_t *l3e;
-        int i3;
-        l3e = sh_map_domain_page(pagetable_get_mfn(d->arch.phys_table));
-#else /* CONFIG_PAGING_LEVELS == 2 */
-        l2e = sh_map_domain_page(pagetable_get_mfn(d->arch.phys_table));
-#endif
-
-        gfn = 0;
-#if CONFIG_PAGING_LEVELS >= 3
-#if CONFIG_PAGING_LEVELS >= 4
-        for ( i4 = 0; i4 < L4_PAGETABLE_ENTRIES; i4++ )
-        {
-            if ( !(l4e_get_flags(l4e[i4]) & _PAGE_PRESENT) )
-            {
-                gfn += 1 << (L4_PAGETABLE_SHIFT - PAGE_SHIFT);
-                continue;
-            }
-            l3e = sh_map_domain_page(_mfn(l4e_get_pfn(l4e[i4])));
-#endif /* now at levels 3 or 4... */
-            for ( i3 = 0; 
-                  i3 < ((CONFIG_PAGING_LEVELS==4) ? L3_PAGETABLE_ENTRIES : 8); 
-                  i3++ )
-            {
-                if ( !(l3e_get_flags(l3e[i3]) & _PAGE_PRESENT) )
-                {
-                    gfn += 1 << (L3_PAGETABLE_SHIFT - PAGE_SHIFT);
-                    continue;
-                }
-                l2e = sh_map_domain_page(_mfn(l3e_get_pfn(l3e[i3])));
-#endif /* all levels... */
-                for ( i2 = 0; i2 < L2_PAGETABLE_ENTRIES; i2++ )
-                {
-                    if ( !(l2e_get_flags(l2e[i2]) & _PAGE_PRESENT) )
-                    {
-                        gfn += 1 << (L2_PAGETABLE_SHIFT - PAGE_SHIFT);
-                        continue;
-                    }
-                    l1e = sh_map_domain_page(_mfn(l2e_get_pfn(l2e[i2])));
-                    
-                    for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; i1++, gfn++ )
-                    {
-                        if ( !(l1e_get_flags(l1e[i1]) & _PAGE_PRESENT) )
-                            continue;
-                        mfn = l1e_get_pfn(l1e[i1]);
-                        ASSERT(mfn_valid(_mfn(mfn)));
-                        m2pfn = get_gpfn_from_mfn(mfn);
-                        if ( m2pfn != gfn )
-                        {
-                            pmbad++;
-                            SHADOW_PRINTK("mismatch: gfn %#lx -> mfn %#lx"
-                                           " -> gfn %#lx\n", gfn, mfn, m2pfn);
-                            BUG();
-                        }
-                    }
-                    sh_unmap_domain_page(l1e);
-                }
-#if CONFIG_PAGING_LEVELS >= 3
-                sh_unmap_domain_page(l2e);
-            }
-#if CONFIG_PAGING_LEVELS >= 4
-            sh_unmap_domain_page(l3e);
-        }
-#endif
-#endif
-
-#if CONFIG_PAGING_LEVELS == 4
-        sh_unmap_domain_page(l4e);
-#elif CONFIG_PAGING_LEVELS == 3
-        sh_unmap_domain_page(l3e);
-#else /* CONFIG_PAGING_LEVELS == 2 */
-        sh_unmap_domain_page(l2e);
-#endif
-
-    }
-
-    //SHADOW_PRINTK("p2m audit complete\n");
-    //if ( orphans_i | orphans_d | mpbad | pmbad ) 
-    //    SHADOW_PRINTK("p2m audit found %lu orphans (%lu inval %lu debug)\n",
-    //                   orphans_i + orphans_d, orphans_i, orphans_d,
-    if ( mpbad | pmbad ) 
-        SHADOW_PRINTK("p2m audit found %lu odd p2m, %lu bad m2p entries\n",
-                       pmbad, mpbad);
-}
-
-#endif /* p2m audit */
 
 /*
  * Local variables:
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/mm/shadow/multi.c    Thu Feb 15 14:09:39 2007 -0700
@@ -237,7 +237,8 @@ guest_walk_tables(struct vcpu *v, unsign
 #if GUEST_PAGING_LEVELS >= 4 /* 64-bit only... */
     /* Get l4e from the top level table */
     gw->l4mfn = pagetable_get_mfn(v->arch.guest_table);
-    gw->l4e = (guest_l4e_t *)v->arch.guest_vtable + guest_l4_table_offset(va);
+    gw->l4e = (guest_l4e_t *)v->arch.paging.shadow.guest_vtable 
+        + guest_l4_table_offset(va);
     /* Walk down to the l3e */
     if ( !(guest_l4e_get_flags(*gw->l4e) & _PAGE_PRESENT) ) return 0;
     gw->l3mfn = vcpu_gfn_to_mfn(v, guest_l4e_get_gfn(*gw->l4e));
@@ -248,9 +249,8 @@ guest_walk_tables(struct vcpu *v, unsign
     gw->l3e = ((guest_l3e_t *)sh_map_domain_page(gw->l3mfn))
         + guest_l3_table_offset(va);
 #else /* PAE only... */
-    /* Get l3e from the top level table */
-    gw->l3mfn = pagetable_get_mfn(v->arch.guest_table);
-    gw->l3e = (guest_l3e_t *)v->arch.guest_vtable + guest_l3_table_offset(va);
+    /* Get l3e from the cache of the guest's top level table */
+    gw->l3e = (guest_l3e_t 
*)&v->arch.paging.shadow.gl3e[guest_l3_table_offset(va)];
 #endif /* PAE or 64... */
     /* Walk down to the l2e */
     if ( !(guest_l3e_get_flags(*gw->l3e) & _PAGE_PRESENT) ) return 0;
@@ -264,7 +264,8 @@ guest_walk_tables(struct vcpu *v, unsign
 #else /* 32-bit only... */
     /* Get l2e from the top level table */
     gw->l2mfn = pagetable_get_mfn(v->arch.guest_table);
-    gw->l2e = (guest_l2e_t *)v->arch.guest_vtable + guest_l2_table_offset(va);
+    gw->l2e = (guest_l2e_t *)v->arch.paging.shadow.guest_vtable 
+        + guest_l2_table_offset(va);
 #endif /* All levels... */
     
     if ( !(guest_l2e_get_flags(*gw->l2e) & _PAGE_PRESENT) ) return 0;
@@ -353,21 +354,21 @@ static inline void print_gw(walk_t *gw)
     SHADOW_PRINTK("GUEST WALK TO %#lx:\n", gw->va);
 #if GUEST_PAGING_LEVELS >= 3 /* PAE or 64... */
 #if GUEST_PAGING_LEVELS >= 4 /* 64-bit only... */
-    SHADOW_PRINTK("   l4mfn=%" SH_PRI_mfn "\n", mfn_x(gw->l4mfn));
+    SHADOW_PRINTK("   l4mfn=%" PRI_mfn "\n", mfn_x(gw->l4mfn));
     SHADOW_PRINTK("   l4e=%p\n", gw->l4e);
     if ( gw->l4e )
         SHADOW_PRINTK("   *l4e=%" SH_PRI_gpte "\n", gw->l4e->l4);
+    SHADOW_PRINTK("   l3mfn=%" PRI_mfn "\n", mfn_x(gw->l3mfn));
 #endif /* PAE or 64... */
-    SHADOW_PRINTK("   l3mfn=%" SH_PRI_mfn "\n", mfn_x(gw->l3mfn));
     SHADOW_PRINTK("   l3e=%p\n", gw->l3e);
     if ( gw->l3e )
         SHADOW_PRINTK("   *l3e=%" SH_PRI_gpte "\n", gw->l3e->l3);
 #endif /* All levels... */
-    SHADOW_PRINTK("   l2mfn=%" SH_PRI_mfn "\n", mfn_x(gw->l2mfn));
+    SHADOW_PRINTK("   l2mfn=%" PRI_mfn "\n", mfn_x(gw->l2mfn));
     SHADOW_PRINTK("   l2e=%p\n", gw->l2e);
     if ( gw->l2e )
         SHADOW_PRINTK("   *l2e=%" SH_PRI_gpte "\n", gw->l2e->l2);
-    SHADOW_PRINTK("   l1mfn=%" SH_PRI_mfn "\n", mfn_x(gw->l1mfn));
+    SHADOW_PRINTK("   l1mfn=%" PRI_mfn "\n", mfn_x(gw->l1mfn));
     SHADOW_PRINTK("   l1e=%p\n", gw->l1e);
     if ( gw->l1e )
         SHADOW_PRINTK("   *l1e=%" SH_PRI_gpte "\n", gw->l1e->l1);
@@ -1572,7 +1573,7 @@ sh_make_shadow(struct vcpu *v, mfn_t gmf
 #if GUEST_PAGING_LEVELS == 4
 #if (SHADOW_OPTIMIZATIONS & SHOPT_LINUX_L3_TOPLEVEL) 
     if ( shadow_type == SH_type_l4_64_shadow &&
-         unlikely(v->domain->arch.shadow.opt_flags & SHOPT_LINUX_L3_TOPLEVEL) )
+         unlikely(v->domain->arch.paging.shadow.opt_flags & 
SHOPT_LINUX_L3_TOPLEVEL) )
     {
         /* We're shadowing a new l4, but we've been assuming the guest uses
          * only one l4 per vcpu and context switches using an l4 entry. 
@@ -1584,7 +1585,7 @@ sh_make_shadow(struct vcpu *v, mfn_t gmf
         struct shadow_page_info *sp;
         struct vcpu *v2;
         int l4count = 0, vcpus = 0;
-        list_for_each(l, &v->domain->arch.shadow.pinned_shadows)
+        list_for_each(l, &v->domain->arch.paging.shadow.pinned_shadows)
         {
             sp = list_entry(l, struct shadow_page_info, list);
             if ( sp->type == SH_type_l4_64_shadow )
@@ -1595,13 +1596,13 @@ sh_make_shadow(struct vcpu *v, mfn_t gmf
         if ( l4count > 2 * vcpus ) 
         {
             /* Unpin all the pinned l3 tables, and don't pin any more. */
-            list_for_each_safe(l, t, &v->domain->arch.shadow.pinned_shadows)
+            list_for_each_safe(l, t, 
&v->domain->arch.paging.shadow.pinned_shadows)
             {
                 sp = list_entry(l, struct shadow_page_info, list);
                 if ( sp->type == SH_type_l3_64_shadow )
                     sh_unpin(v, shadow_page_to_mfn(sp));
             }
-            v->domain->arch.shadow.opt_flags &= ~SHOPT_LINUX_L3_TOPLEVEL;
+            v->domain->arch.paging.shadow.opt_flags &= 
~SHOPT_LINUX_L3_TOPLEVEL;
         }
     }
 #endif
@@ -1641,7 +1642,7 @@ make_fl1_shadow(struct vcpu *v, gfn_t gf
     mfn_t smfn = shadow_alloc(v->domain, SH_type_fl1_shadow,
                                (unsigned long) gfn_x(gfn));
 
-    SHADOW_DEBUG(MAKE_SHADOW, "(%" SH_PRI_gfn ")=>%" SH_PRI_mfn "\n",
+    SHADOW_DEBUG(MAKE_SHADOW, "(%" SH_PRI_gfn ")=>%" PRI_mfn "\n",
                   gfn_x(gfn), mfn_x(smfn));
 
     set_fl1_shadow_status(v, gfn, smfn);
@@ -1851,7 +1852,7 @@ static shadow_l2e_t * shadow_get_and_cre
 #elif GUEST_PAGING_LEVELS == 3 /* PAE... */
     /* We never demand-shadow PAE l3es: they are only created in
      * sh_update_cr3().  Check if the relevant sl3e is present. */
-    shadow_l3e_t *sl3e = ((shadow_l3e_t *)&v->arch.shadow.l3table) 
+    shadow_l3e_t *sl3e = ((shadow_l3e_t *)&v->arch.paging.shadow.l3table) 
         + shadow_l3_linear_offset(gw->va);
     if ( !(shadow_l3e_get_flags(*sl3e) & _PAGE_PRESENT) ) 
         return NULL;
@@ -2358,7 +2359,7 @@ static int validate_gl1e(struct vcpu *v,
     gfn = guest_l1e_get_gfn(*new_gl1e);
     gmfn = vcpu_gfn_to_mfn(v, gfn);
 
-    mmio = (is_hvm_vcpu(v) && shadow_vcpu_mode_translate(v) && 
!mfn_valid(gmfn));
+    mmio = (is_hvm_vcpu(v) && paging_vcpu_mode_translate(v) && 
!mfn_valid(gmfn));
     l1e_propagate_from_guest(v, new_gl1e, _mfn(INVALID_MFN), gmfn, &new_sl1e, 
                              ft_prefetch, mmio);
     
@@ -2506,7 +2507,7 @@ static inline void check_for_early_unsha
 static inline void check_for_early_unshadow(struct vcpu *v, mfn_t gmfn)
 {
 #if SHADOW_OPTIMIZATIONS & SHOPT_EARLY_UNSHADOW
-    if ( v->arch.shadow.last_emulated_mfn == mfn_x(gmfn) &&
+    if ( v->arch.paging.shadow.last_emulated_mfn == mfn_x(gmfn) &&
          sh_mfn_is_a_page_table(gmfn) )
     {
         u32 flags = mfn_to_page(gmfn)->shadow_flags;
@@ -2516,7 +2517,7 @@ static inline void check_for_early_unsha
             sh_remove_shadows(v, gmfn, 1, 0 /* Fast, can fail to unshadow */ );
         } 
     }
-    v->arch.shadow.last_emulated_mfn = mfn_x(gmfn);
+    v->arch.paging.shadow.last_emulated_mfn = mfn_x(gmfn);
 #endif
 }
 
@@ -2524,7 +2525,7 @@ static inline void reset_early_unshadow(
 static inline void reset_early_unshadow(struct vcpu *v)
 {
 #if SHADOW_OPTIMIZATIONS & SHOPT_EARLY_UNSHADOW
-    v->arch.shadow.last_emulated_mfn = INVALID_MFN;
+    v->arch.paging.shadow.last_emulated_mfn = INVALID_MFN;
 #endif
 }
 
@@ -2589,7 +2590,7 @@ static void sh_prefetch(struct vcpu *v, 
         gfn = guest_l1e_get_gfn(gl1e);
         gmfn = vcpu_gfn_to_mfn(v, gfn);
         mmio = ( is_hvm_vcpu(v) 
-                 && shadow_vcpu_mode_translate(v) 
+                 && paging_vcpu_mode_translate(v) 
                  && mmio_space(gfn_to_paddr(gfn)) );
 
         /* Propagate the entry.  Safe to use a pointer to our local 
@@ -2631,6 +2632,7 @@ static int sh_page_fault(struct vcpu *v,
     SHADOW_PRINTK("d:v=%u:%u va=%#lx err=%u\n",
                    v->domain->domain_id, v->vcpu_id, va, regs->error_code);
 
+    perfc_incrc(shadow_fault);
     //
     // XXX: Need to think about eventually mapping superpages directly in the
     //      shadow (when possible), as opposed to splintering them into a
@@ -2651,7 +2653,7 @@ static int sh_page_fault(struct vcpu *v,
             if ( sh_l1e_is_gnp(sl1e) )
             {
                 if ( likely(!is_hvm_domain(d) ||
-                            shadow_vcpu_mode_translate(v)) )
+                            paging_vcpu_mode_translate(v)) )
                 { 
                     /* Not-present in a guest PT: pass to the guest as
                      * a not-present fault (by flipping two bits). */
@@ -2701,7 +2703,7 @@ static int sh_page_fault(struct vcpu *v,
     if ( unlikely(shadow_locked_by_me(d)) )
     {
         SHADOW_ERROR("Recursive shadow fault: lock was taken by %s\n",
-                     d->arch.shadow.locker_function);
+                     d->arch.paging.shadow.locker_function);
         return 0;
     }
 
@@ -2726,7 +2728,7 @@ static int sh_page_fault(struct vcpu *v,
     //
     if ( unlikely(!(guest_l1e_get_flags(gw.eff_l1e) & _PAGE_PRESENT)) )
     {
-        if ( is_hvm_domain(d) && !shadow_vcpu_mode_translate(v) )
+        if ( is_hvm_domain(d) && !paging_vcpu_mode_translate(v) )
         {
             /* Not present in p2m map, means this is mmio */
             gpa = va;
@@ -2784,13 +2786,13 @@ static int sh_page_fault(struct vcpu *v,
     gfn = guest_l1e_get_gfn(gw.eff_l1e);
     gmfn = vcpu_gfn_to_mfn(v, gfn);
     mmio = (is_hvm_domain(d)
-            && shadow_vcpu_mode_translate(v) 
+            && paging_vcpu_mode_translate(v) 
             && mmio_space(gfn_to_paddr(gfn)));
 
     if ( !mmio && !mfn_valid(gmfn) )
     {
         perfc_incrc(shadow_fault_bail_bad_gfn);
-        SHADOW_PRINTK("BAD gfn=%"SH_PRI_gfn" gmfn=%"SH_PRI_mfn"\n", 
+        SHADOW_PRINTK("BAD gfn=%"SH_PRI_gfn" gmfn=%"PRI_mfn"\n", 
                       gfn_x(gfn), mfn_x(gmfn));
         goto not_a_shadow_fault;
     }
@@ -2848,7 +2850,7 @@ static int sh_page_fault(struct vcpu *v,
     }
 
     perfc_incrc(shadow_fault_fixed);
-    d->arch.shadow.fault_count++;
+    d->arch.paging.shadow.fault_count++;
     reset_early_unshadow(v);
 
  done:
@@ -2949,7 +2951,7 @@ sh_invlpg(struct vcpu *v, unsigned long 
             return 0;
     }
 #elif SHADOW_PAGING_LEVELS == 3
-    if ( !(l3e_get_flags(v->arch.shadow.l3table[shadow_l3_linear_offset(va)])
+    if ( 
!(l3e_get_flags(v->arch.paging.shadow.l3table[shadow_l3_linear_offset(va)])
            & _PAGE_PRESENT) )
         // no need to flush anything if there's no SL2...
         return 0;
@@ -3120,7 +3122,7 @@ sh_update_linear_entries(struct vcpu *v)
         }
 
         /* Shadow l3 tables are made up by sh_update_cr3 */
-        sl3e = v->arch.shadow.l3table;
+        sl3e = v->arch.paging.shadow.l3table;
 
         for ( i = 0; i < SHADOW_L3_PAGETABLE_ENTRIES; i++ )
         {
@@ -3161,15 +3163,14 @@ sh_update_linear_entries(struct vcpu *v)
 #if GUEST_PAGING_LEVELS == 2
         /* Shadow l3 tables were built by sh_update_cr3 */
         if ( shadow_mode_external(d) )
-            shadow_l3e = (shadow_l3e_t *)&v->arch.shadow.l3table;
+            shadow_l3e = (shadow_l3e_t *)&v->arch.paging.shadow.l3table;
         else
             BUG(); /* PV 2-on-3 is not supported yet */
         
 #else /* GUEST_PAGING_LEVELS == 3 */
         
-        shadow_l3e = (shadow_l3e_t *)&v->arch.shadow.l3table;
-        /* Always safe to use guest_vtable, because it's globally mapped */
-        guest_l3e = v->arch.guest_vtable;
+        shadow_l3e = (shadow_l3e_t *)&v->arch.paging.shadow.l3table;
+        guest_l3e = (guest_l3e_t *)&v->arch.paging.shadow.gl3e;
 
 #endif /* GUEST_PAGING_LEVELS */
         
@@ -3267,38 +3268,36 @@ sh_update_linear_entries(struct vcpu *v)
 }
 
 
-/* Removes vcpu->arch.guest_vtable and vcpu->arch.shadow_table[].
+/* Removes vcpu->arch.paging.shadow.guest_vtable and vcpu->arch.shadow_table[].
  * Does all appropriate management/bookkeeping/refcounting/etc...
  */
 static void
 sh_detach_old_tables(struct vcpu *v)
 {
-    struct domain *d = v->domain;
     mfn_t smfn;
     int i = 0;
 
     ////
-    //// vcpu->arch.guest_vtable
+    //// vcpu->arch.paging.shadow.guest_vtable
     ////
-    if ( v->arch.guest_vtable )
-    {
-#if GUEST_PAGING_LEVELS == 4
+
+#if GUEST_PAGING_LEVELS == 3
+    /* PAE guests don't have a mapping of the guest top-level table */
+    ASSERT(v->arch.paging.shadow.guest_vtable == NULL);
+#else
+    if ( v->arch.paging.shadow.guest_vtable )
+    {
+        struct domain *d = v->domain;
         if ( shadow_mode_external(d) || shadow_mode_translate(d) )
-            sh_unmap_domain_page_global(v->arch.guest_vtable);
-#elif GUEST_PAGING_LEVELS == 3
-        if ( 1 || shadow_mode_external(d) || shadow_mode_translate(d) )
-            sh_unmap_domain_page_global(v->arch.guest_vtable);
-#elif GUEST_PAGING_LEVELS == 2
-        if ( shadow_mode_external(d) || shadow_mode_translate(d) )
-            sh_unmap_domain_page_global(v->arch.guest_vtable);
-#endif
-        v->arch.guest_vtable = NULL;
-    }
+            sh_unmap_domain_page_global(v->arch.paging.shadow.guest_vtable);
+        v->arch.paging.shadow.guest_vtable = NULL;
+    }
+#endif
+
 
     ////
     //// vcpu->arch.shadow_table[]
     ////
-
 
 #if GUEST_PAGING_LEVELS == 3
     /* PAE guests have four shadow_table entries */
@@ -3370,7 +3369,7 @@ sh_set_toplevel_shadow(struct vcpu *v,
 
  install_new_entry:
     /* Done.  Install it */
-    SHADOW_PRINTK("%u/%u [%u] gmfn %#"SH_PRI_mfn" smfn %#"SH_PRI_mfn"\n",
+    SHADOW_PRINTK("%u/%u [%u] gmfn %#"PRI_mfn" smfn %#"PRI_mfn"\n",
                   GUEST_PAGING_LEVELS, SHADOW_PAGING_LEVELS, slot,
                   mfn_x(gmfn), mfn_x(pagetable_get_mfn(new_entry)));
     v->arch.shadow_table[slot] = new_entry;
@@ -3397,7 +3396,9 @@ sh_update_cr3(struct vcpu *v, int do_loc
     struct domain *d = v->domain;
     mfn_t gmfn;
 #if GUEST_PAGING_LEVELS == 3
+    guest_l3e_t *gl3e;
     u32 guest_idx=0;
+    int i;
 #endif
 
     /* Don't do anything on an uninitialised vcpu */
@@ -3410,7 +3411,7 @@ sh_update_cr3(struct vcpu *v, int do_loc
     if ( do_locking ) shadow_lock(v->domain);
 
     ASSERT(shadow_locked_by_me(v->domain));
-    ASSERT(v->arch.shadow.mode);
+    ASSERT(v->arch.paging.mode);
 
     ////
     //// vcpu->arch.guest_table is already set
@@ -3425,7 +3426,7 @@ sh_update_cr3(struct vcpu *v, int do_loc
         ASSERT(shadow_mode_external(d));
 
         // Is paging enabled on this vcpu?
-        if ( shadow_vcpu_mode_translate(v) )
+        if ( paging_vcpu_mode_translate(v) )
         {
             gfn = _gfn(paddr_to_pfn(hvm_get_guest_ctrl_reg(v, 3)));
             gmfn = vcpu_gfn_to_mfn(v, gfn);
@@ -3456,55 +3457,54 @@ sh_update_cr3(struct vcpu *v, int do_loc
 
 
     ////
-    //// vcpu->arch.guest_vtable
+    //// vcpu->arch.paging.shadow.guest_vtable
     ////
 #if GUEST_PAGING_LEVELS == 4
     if ( shadow_mode_external(d) || shadow_mode_translate(d) )
     {
-        if ( v->arch.guest_vtable )
-            sh_unmap_domain_page_global(v->arch.guest_vtable);
-        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
+        if ( v->arch.paging.shadow.guest_vtable )
+            sh_unmap_domain_page_global(v->arch.paging.shadow.guest_vtable);
+        v->arch.paging.shadow.guest_vtable = sh_map_domain_page_global(gmfn);
     }
     else
-        v->arch.guest_vtable = __linear_l4_table;
+        v->arch.paging.shadow.guest_vtable = __linear_l4_table;
 #elif GUEST_PAGING_LEVELS == 3
-    if ( v->arch.guest_vtable )
-        sh_unmap_domain_page_global(v->arch.guest_vtable);
-    if ( shadow_mode_external(d) )
-    {
-        if ( shadow_vcpu_mode_translate(v) ) 
-            /* Paging enabled: find where in the page the l3 table is */
-            guest_idx = guest_index((void *)hvm_get_guest_ctrl_reg(v, 3));
-        else
-            /* Paging disabled: l3 is at the start of a page (in the p2m) */ 
-            guest_idx = 0; 
-
-        // Ignore the low 2 bits of guest_idx -- they are really just
-        // cache control.
-        guest_idx &= ~3;
-
-        // XXX - why does this need a global map?
-        v->arch.guest_vtable =
-            (guest_l3e_t *)sh_map_domain_page_global(gmfn) + guest_idx;
-    }
+     /* On PAE guests we don't use a mapping of the guest's own top-level
+      * table.  We cache the current state of that table and shadow that,
+      * until the next CR3 write makes us refresh our cache. */
+     ASSERT(v->arch.paging.shadow.guest_vtable == NULL);
+ 
+     if ( shadow_mode_external(d) && paging_vcpu_mode_translate(v) ) 
+         /* Paging enabled: find where in the page the l3 table is */
+         guest_idx = guest_index((void *)hvm_get_guest_ctrl_reg(v, 3));
     else
-        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
+        /* Paging disabled or PV: l3 is at the start of a page */ 
+        guest_idx = 0; 
+     
+     // Ignore the low 2 bits of guest_idx -- they are really just
+     // cache control.
+     guest_idx &= ~3;
+     
+     gl3e = ((guest_l3e_t *)sh_map_domain_page(gmfn)) + guest_idx;
+     for ( i = 0; i < 4 ; i++ )
+         v->arch.paging.shadow.gl3e[i] = gl3e[i];
+     sh_unmap_domain_page(gl3e);
 #elif GUEST_PAGING_LEVELS == 2
     if ( shadow_mode_external(d) || shadow_mode_translate(d) )
     {
-        if ( v->arch.guest_vtable )
-            sh_unmap_domain_page_global(v->arch.guest_vtable);
-        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
+        if ( v->arch.paging.shadow.guest_vtable )
+            sh_unmap_domain_page_global(v->arch.paging.shadow.guest_vtable);
+        v->arch.paging.shadow.guest_vtable = sh_map_domain_page_global(gmfn);
     }
     else
-        v->arch.guest_vtable = __linear_l2_table;
+        v->arch.paging.shadow.guest_vtable = __linear_l2_table;
 #else
 #error this should never happen
 #endif
 
 #if 0
-    printk("%s %s %d gmfn=%05lx guest_vtable=%p\n",
-           __func__, __FILE__, __LINE__, gmfn, v->arch.guest_vtable);
+    printk("%s %s %d gmfn=%05lx shadow.guest_vtable=%p\n",
+           __func__, __FILE__, __LINE__, gmfn, 
v->arch.paging.shadow.guest_vtable);
 #endif
 
     ////
@@ -3522,10 +3522,10 @@ sh_update_cr3(struct vcpu *v, int do_loc
     /* PAE guests have four shadow_table entries, based on the 
      * current values of the guest's four l3es. */
     {
-        int i, flush = 0;
+        int flush = 0;
         gfn_t gl2gfn;
         mfn_t gl2mfn;
-        guest_l3e_t *gl3e = (guest_l3e_t*)v->arch.guest_vtable;
+        guest_l3e_t *gl3e = (guest_l3e_t*)&v->arch.paging.shadow.gl3e;
         /* First, make all four entries read-only. */
         for ( i = 0; i < 4; i++ )
         {
@@ -3566,7 +3566,7 @@ sh_update_cr3(struct vcpu *v, int do_loc
 #endif
 
     /// 
-    /// v->arch.shadow.l3table
+    /// v->arch.paging.shadow.l3table
     ///
 #if SHADOW_PAGING_LEVELS == 3
         {
@@ -3581,7 +3581,7 @@ sh_update_cr3(struct vcpu *v, int do_loc
                 /* 3-on-3: make a PAE l3 that points at the four l2 pages */
                 smfn = pagetable_get_mfn(v->arch.shadow_table[i]);
 #endif
-                v->arch.shadow.l3table[i] = 
+                v->arch.paging.shadow.l3table[i] = 
                     (mfn_x(smfn) == 0) 
                     ? shadow_l3e_empty()
                     : shadow_l3e_from_mfn(smfn, _PAGE_PRESENT);
@@ -3605,8 +3605,8 @@ sh_update_cr3(struct vcpu *v, int do_loc
         /* 2-on-3 or 3-on-3: Use the PAE shadow l3 table we just fabricated.
          * Don't use make_cr3 because (a) we know it's below 4GB, and
          * (b) it's not necessarily page-aligned, and make_cr3 takes a pfn */
-        ASSERT(virt_to_maddr(&v->arch.shadow.l3table) <= 0xffffffe0ULL);
-        v->arch.cr3 = virt_to_maddr(&v->arch.shadow.l3table);
+        ASSERT(virt_to_maddr(&v->arch.paging.shadow.l3table) <= 0xffffffe0ULL);
+        v->arch.cr3 = virt_to_maddr(&v->arch.paging.shadow.l3table);
 #else
         /* 2-on-2 or 4-on-4: Just use the shadow top-level directly */
         make_cr3(v, pagetable_get_pfn(v->arch.shadow_table[0]));
@@ -3622,7 +3622,7 @@ sh_update_cr3(struct vcpu *v, int do_loc
         ASSERT(is_hvm_domain(d));
 #if SHADOW_PAGING_LEVELS == 3
         /* 2-on-3 or 3-on-3: Use the PAE shadow l3 table we just fabricated */
-        hvm_update_guest_cr3(v, virt_to_maddr(&v->arch.shadow.l3table));
+        hvm_update_guest_cr3(v, virt_to_maddr(&v->arch.paging.shadow.l3table));
 #else
         /* 2-on-2 or 4-on-4: Just use the shadow top-level directly */
         hvm_update_guest_cr3(v, pagetable_get_paddr(v->arch.shadow_table[0]));
@@ -3665,7 +3665,7 @@ static int sh_guess_wrmap(struct vcpu *v
     if ( !(shadow_l3e_get_flags(*sl3p) & _PAGE_PRESENT) )
         return 0;
 #elif SHADOW_PAGING_LEVELS == 3
-    sl3p = ((shadow_l3e_t *) v->arch.shadow.l3table) 
+    sl3p = ((shadow_l3e_t *) v->arch.paging.shadow.l3table) 
         + shadow_l3_linear_offset(vaddr);
     if ( !(shadow_l3e_get_flags(*sl3p) & _PAGE_PRESENT) )
         return 0;
@@ -3709,7 +3709,7 @@ int sh_rm_write_access_from_l1(struct vc
             (void) shadow_set_l1e(v, sl1e, ro_sl1e, sl1mfn);
 #if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC 
             /* Remember the last shadow that we shot a writeable mapping in */
-            v->arch.shadow.last_writeable_pte_smfn = mfn_x(base_sl1mfn);
+            v->arch.paging.shadow.last_writeable_pte_smfn = mfn_x(base_sl1mfn);
 #endif
             if ( (mfn_to_page(readonly_mfn)->u.inuse.type_info
                   & PGT_count_mask) == 0 )
@@ -4050,8 +4050,8 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
 
 #define AUDIT_FAIL(_level, _fmt, _a...) do {                               \
     printk("Shadow %u-on-%u audit failed at level %i, index %i\n"         \
-           "gl" #_level "mfn = %" SH_PRI_mfn                              \
-           " sl" #_level "mfn = %" SH_PRI_mfn                             \
+           "gl" #_level "mfn = %" PRI_mfn                              \
+           " sl" #_level "mfn = %" PRI_mfn                             \
            " &gl" #_level "e = %p &sl" #_level "e = %p"                    \
            " gl" #_level "e = %" SH_PRI_gpte                              \
            " sl" #_level "e = %" SH_PRI_pte "\nError: " _fmt "\n",        \
@@ -4105,7 +4105,7 @@ audit_gfn_to_mfn(struct vcpu *v, gfn_t g
          != PGT_writable_page ) 
         return _mfn(gfn_x(gfn)); /* This is a paging-disabled shadow */
     else 
-        return sh_gfn_to_mfn(v->domain, gfn_x(gfn));
+        return gfn_to_mfn(v->domain, gfn_x(gfn));
 } 
 
 
@@ -4156,7 +4156,7 @@ int sh_audit_l1_table(struct vcpu *v, mf
                 gmfn = audit_gfn_to_mfn(v, gfn, gl1mfn);
                 if ( mfn_x(gmfn) != mfn_x(mfn) )
                     AUDIT_FAIL(1, "bad translation: gfn %" SH_PRI_gfn
-                               " --> %" SH_PRI_mfn " != mfn %" SH_PRI_mfn,
+                               " --> %" PRI_mfn " != mfn %" PRI_mfn,
                                gfn_x(gfn), mfn_x(gmfn), mfn_x(mfn));
             }
         }
@@ -4219,8 +4219,8 @@ int sh_audit_l2_table(struct vcpu *v, mf
                                     SH_type_l1_shadow);
             if ( mfn_x(gmfn) != mfn_x(mfn) )
                 AUDIT_FAIL(2, "bad translation: gfn %" SH_PRI_gfn
-                           " (--> %" SH_PRI_mfn ")"
-                           " --> %" SH_PRI_mfn " != mfn %" SH_PRI_mfn,
+                           " (--> %" PRI_mfn ")"
+                           " --> %" PRI_mfn " != mfn %" PRI_mfn,
                            gfn_x(gfn), 
                            (guest_l2e_get_flags(*gl2e) & _PAGE_PSE) ? 0
                            : mfn_x(audit_gfn_to_mfn(v, gfn, gl2mfn)),
@@ -4262,7 +4262,7 @@ int sh_audit_l3_table(struct vcpu *v, mf
                                      : SH_type_l2_shadow);
             if ( mfn_x(gmfn) != mfn_x(mfn) )
                 AUDIT_FAIL(3, "bad translation: gfn %" SH_PRI_gfn
-                           " --> %" SH_PRI_mfn " != mfn %" SH_PRI_mfn,
+                           " --> %" PRI_mfn " != mfn %" PRI_mfn,
                            gfn_x(gfn), mfn_x(gmfn), mfn_x(mfn));
         }
     });
@@ -4297,7 +4297,7 @@ int sh_audit_l4_table(struct vcpu *v, mf
                                      SH_type_l3_shadow);
             if ( mfn_x(gmfn) != mfn_x(mfn) )
                 AUDIT_FAIL(4, "bad translation: gfn %" SH_PRI_gfn
-                           " --> %" SH_PRI_mfn " != mfn %" SH_PRI_mfn,
+                           " --> %" PRI_mfn " != mfn %" PRI_mfn,
                            gfn_x(gfn), mfn_x(gmfn), mfn_x(mfn));
         }
     });
@@ -4314,30 +4314,29 @@ int sh_audit_l4_table(struct vcpu *v, mf
 /**************************************************************************/
 /* Entry points into this mode of the shadow code.
  * This will all be mangled by the preprocessor to uniquify everything. */
-struct shadow_paging_mode sh_paging_mode = {
-    .page_fault             = sh_page_fault, 
-    .invlpg                 = sh_invlpg,
-    .gva_to_gpa             = sh_gva_to_gpa,
-    .gva_to_gfn             = sh_gva_to_gfn,
-    .update_cr3             = sh_update_cr3,
-    .map_and_validate_gl1e  = sh_map_and_validate_gl1e,
-    .map_and_validate_gl2e  = sh_map_and_validate_gl2e,
-    .map_and_validate_gl2he = sh_map_and_validate_gl2he,
-    .map_and_validate_gl3e  = sh_map_and_validate_gl3e,
-    .map_and_validate_gl4e  = sh_map_and_validate_gl4e,
-    .detach_old_tables      = sh_detach_old_tables,
-    .x86_emulate_write      = sh_x86_emulate_write,
-    .x86_emulate_cmpxchg    = sh_x86_emulate_cmpxchg,
-    .x86_emulate_cmpxchg8b  = sh_x86_emulate_cmpxchg8b,
-    .make_monitor_table     = sh_make_monitor_table,
-    .destroy_monitor_table  = sh_destroy_monitor_table,
-    .guest_map_l1e          = sh_guest_map_l1e,
-    .guest_get_eff_l1e      = sh_guest_get_eff_l1e,
+struct paging_mode sh_paging_mode = {
+    .page_fault                    = sh_page_fault, 
+    .invlpg                        = sh_invlpg,
+    .gva_to_gpa                    = sh_gva_to_gpa,
+    .gva_to_gfn                    = sh_gva_to_gfn,
+    .update_cr3                    = sh_update_cr3,
+    .update_paging_modes           = shadow_update_paging_modes,
+    .write_p2m_entry               = shadow_write_p2m_entry,
+    .write_guest_entry             = shadow_write_guest_entry,
+    .cmpxchg_guest_entry           = shadow_cmpxchg_guest_entry,
+    .guest_map_l1e                 = sh_guest_map_l1e,
+    .guest_get_eff_l1e             = sh_guest_get_eff_l1e,
+    .guest_levels                  = GUEST_PAGING_LEVELS,
+    .shadow.detach_old_tables      = sh_detach_old_tables,
+    .shadow.x86_emulate_write      = sh_x86_emulate_write,
+    .shadow.x86_emulate_cmpxchg    = sh_x86_emulate_cmpxchg,
+    .shadow.x86_emulate_cmpxchg8b  = sh_x86_emulate_cmpxchg8b,
+    .shadow.make_monitor_table     = sh_make_monitor_table,
+    .shadow.destroy_monitor_table  = sh_destroy_monitor_table,
 #if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC
-    .guess_wrmap            = sh_guess_wrmap,
-#endif
-    .guest_levels           = GUEST_PAGING_LEVELS,
-    .shadow_levels          = SHADOW_PAGING_LEVELS,
+    .shadow.guess_wrmap            = sh_guess_wrmap,
+#endif
+    .shadow.shadow_levels          = SHADOW_PAGING_LEVELS,
 };
 
 /*
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/mm/shadow/multi.h
--- a/xen/arch/x86/mm/shadow/multi.h    Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/mm/shadow/multi.h    Thu Feb 15 14:09:39 2007 -0700
@@ -115,5 +115,5 @@ SHADOW_INTERNAL_NAME(sh_destroy_monitor_
     (struct vcpu *v, mfn_t mmfn);
 #endif
 
-extern struct shadow_paging_mode 
+extern struct paging_mode 
 SHADOW_INTERNAL_NAME(sh_paging_mode, SHADOW_LEVELS, GUEST_LEVELS);
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/mm/shadow/page-guest32.h
--- a/xen/arch/x86/mm/shadow/page-guest32.h     Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/mm/shadow/page-guest32.h     Thu Feb 15 14:09:39 2007 -0700
@@ -87,11 +87,6 @@ static inline l2_pgentry_32_t l2e_from_p
 #define l2_table_offset_32(a)         \
     (((a) >> L2_PAGETABLE_SHIFT_32) & (L2_PAGETABLE_ENTRIES_32 - 1))
 
-#define linear_l1_table_32                                                 \
-    ((l1_pgentry_32_t *)(LINEAR_PT_VIRT_START))
-
-#define linear_pg_table_32 linear_l1_table_32
-
 #endif /* __X86_PAGE_GUEST_H__ */
 
 /*
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/mm/shadow/private.h
--- a/xen/arch/x86/mm/shadow/private.h  Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/mm/shadow/private.h  Thu Feb 15 14:09:39 2007 -0700
@@ -41,13 +41,12 @@
 #define SHADOW_AUDIT_ENTRIES        0x04  /* Check this walk's shadows */
 #define SHADOW_AUDIT_ENTRIES_FULL   0x08  /* Check every shadow */
 #define SHADOW_AUDIT_ENTRIES_MFNS   0x10  /* Check gfn-mfn map in shadows */
-#define SHADOW_AUDIT_P2M            0x20  /* Check the p2m table */
 
 #ifdef NDEBUG
 #define SHADOW_AUDIT                   0
 #define SHADOW_AUDIT_ENABLE            0
 #else
-#define SHADOW_AUDIT                0x15  /* Basic audit of all except p2m. */
+#define SHADOW_AUDIT                0x15  /* Basic audit of all */
 #define SHADOW_AUDIT_ENABLE         shadow_audit_enable
 extern int shadow_audit_enable;
 #endif
@@ -84,9 +83,9 @@ extern int shadow_audit_enable;
 #define SHADOW_DEBUG_PROPAGATE         1
 #define SHADOW_DEBUG_MAKE_SHADOW       1
 #define SHADOW_DEBUG_DESTROY_SHADOW    1
-#define SHADOW_DEBUG_P2M               0
 #define SHADOW_DEBUG_A_AND_D           1
 #define SHADOW_DEBUG_EMULATE           1
+#define SHADOW_DEBUG_P2M               1
 #define SHADOW_DEBUG_LOGDIRTY          0
 
 /******************************************************************************
@@ -108,36 +107,36 @@ extern int shadow_audit_enable;
 #error shadow.h currently requires CONFIG_SMP
 #endif
 
-#define shadow_lock_init(_d)                            \
-    do {                                                \
-        spin_lock_init(&(_d)->arch.shadow.lock);        \
-        (_d)->arch.shadow.locker = -1;                  \
-        (_d)->arch.shadow.locker_function = "nobody";   \
+#define shadow_lock_init(_d)                                   \
+    do {                                                       \
+        spin_lock_init(&(_d)->arch.paging.shadow.lock);        \
+        (_d)->arch.paging.shadow.locker = -1;                  \
+        (_d)->arch.paging.shadow.locker_function = "nobody";   \
     } while (0)
 
 #define shadow_locked_by_me(_d)                     \
-    (current->processor == (_d)->arch.shadow.locker)
-
-#define shadow_lock(_d)                                                 \
-    do {                                                                \
-        if ( unlikely((_d)->arch.shadow.locker == current->processor) ) \
-        {                                                               \
-            printk("Error: shadow lock held by %s\n",                   \
-                   (_d)->arch.shadow.locker_function);                  \
-            BUG();                                                      \
-        }                                                               \
-        spin_lock(&(_d)->arch.shadow.lock);                             \
-        ASSERT((_d)->arch.shadow.locker == -1);                         \
-        (_d)->arch.shadow.locker = current->processor;                  \
-        (_d)->arch.shadow.locker_function = __func__;                   \
+    (current->processor == (_d)->arch.paging.shadow.locker)
+
+#define shadow_lock(_d)                                                       \
+    do {                                                                      \
+        if ( unlikely((_d)->arch.paging.shadow.locker == current->processor) )\
+        {                                                                     \
+            printk("Error: shadow lock held by %s\n",                         \
+                   (_d)->arch.paging.shadow.locker_function);                 \
+            BUG();                                                            \
+        }                                                                     \
+        spin_lock(&(_d)->arch.paging.shadow.lock);                            \
+        ASSERT((_d)->arch.paging.shadow.locker == -1);                        \
+        (_d)->arch.paging.shadow.locker = current->processor;                 \
+        (_d)->arch.paging.shadow.locker_function = __func__;                  \
     } while (0)
 
-#define shadow_unlock(_d)                                       \
-    do {                                                        \
-        ASSERT((_d)->arch.shadow.locker == current->processor); \
-        (_d)->arch.shadow.locker = -1;                          \
-        (_d)->arch.shadow.locker_function = "nobody";           \
-        spin_unlock(&(_d)->arch.shadow.lock);                   \
+#define shadow_unlock(_d)                                              \
+    do {                                                               \
+        ASSERT((_d)->arch.paging.shadow.locker == current->processor); \
+        (_d)->arch.paging.shadow.locker = -1;                          \
+        (_d)->arch.paging.shadow.locker_function = "nobody";           \
+        spin_unlock(&(_d)->arch.paging.shadow.lock);                   \
     } while (0)
 
 
@@ -151,13 +150,6 @@ extern void shadow_audit_tables(struct v
 #else
 #define shadow_audit_tables(_v) do {} while(0)
 #endif
-
-#if SHADOW_AUDIT & SHADOW_AUDIT_P2M
-extern void shadow_audit_p2m(struct domain *d);
-#else
-#define shadow_audit_p2m(_d) do {} while(0)
-#endif
-
 
 /******************************************************************************
  * Macro for dealing with the naming of the internal names of the
@@ -304,7 +296,7 @@ static inline int sh_type_is_pinnable(st
      * page.  When we're shadowing those kernels, we have to pin l3
      * shadows so they don't just evaporate on every context switch.
      * For all other guests, we'd rather use the up-pointer field in l3s. */ 
-    if ( unlikely((v->domain->arch.shadow.opt_flags & SHOPT_LINUX_L3_TOPLEVEL) 
+    if ( unlikely((v->domain->arch.paging.shadow.opt_flags & 
SHOPT_LINUX_L3_TOPLEVEL) 
                   && CONFIG_PAGING_LEVELS >= 4
                   && t == SH_type_l3_64_shadow) )
         return 1;
@@ -379,12 +371,11 @@ void sh_install_xen_entries_in_l2(struct
 void sh_install_xen_entries_in_l2(struct vcpu *v, mfn_t gl2mfn, mfn_t sl2mfn);
 
 /* Update the shadows in response to a pagetable write from Xen */
-extern int sh_validate_guest_entry(struct vcpu *v, mfn_t gmfn, 
-                                   void *entry, u32 size);
+int sh_validate_guest_entry(struct vcpu *v, mfn_t gmfn, void *entry, u32 size);
 
 /* Update the shadows in response to a pagetable write from a HVM guest */
-extern void sh_validate_guest_pt_write(struct vcpu *v, mfn_t gmfn, 
-                                       void *entry, u32 size);
+void sh_validate_guest_pt_write(struct vcpu *v, mfn_t gmfn, 
+                                void *entry, u32 size);
 
 /* Remove all writeable mappings of a guest frame from the shadows.
  * Returns non-zero if we need to flush TLBs. 
@@ -394,6 +385,21 @@ extern int sh_remove_write_access(struct
                                   unsigned int level,
                                   unsigned long fault_addr);
 
+/* Allocate/free functions for passing to the P2M code. */
+struct page_info *shadow_alloc_p2m_page(struct domain *d);
+void shadow_free_p2m_page(struct domain *d, struct page_info *pg);
+
+/* Functions that atomically write PT/P2M entries and update state */
+void shadow_write_p2m_entry(struct vcpu *v, unsigned long gfn, 
+                            l1_pgentry_t *p, l1_pgentry_t new, 
+                            unsigned int level);
+int shadow_write_guest_entry(struct vcpu *v, intpte_t *p,
+                             intpte_t new, mfn_t gmfn);
+int shadow_cmpxchg_guest_entry(struct vcpu *v, intpte_t *p,
+                               intpte_t *old, intpte_t new, mfn_t gmfn);
+
+
+
 /******************************************************************************
  * Flags used in the return value of the shadow_set_lXe() functions...
  */
@@ -477,19 +483,6 @@ sh_unmap_domain_page_global(void *p)
     unmap_domain_page_global(p);
 }
 
-static inline mfn_t
-pagetable_get_mfn(pagetable_t pt)
-{
-    return _mfn(pagetable_get_pfn(pt));
-}
-
-static inline pagetable_t
-pagetable_from_mfn(mfn_t mfn)
-{
-    return pagetable_from_pfn(mfn_x(mfn));
-}
-
-
 /******************************************************************************
  * Log-dirty mode bitmap handling
  */
@@ -502,13 +495,13 @@ sh_mfn_is_dirty(struct domain *d, mfn_t 
 {
     unsigned long pfn;
     ASSERT(shadow_mode_log_dirty(d));
-    ASSERT(d->arch.shadow.dirty_bitmap != NULL);
+    ASSERT(d->arch.paging.shadow.dirty_bitmap != NULL);
 
     /* We /really/ mean PFN here, even for non-translated guests. */
     pfn = get_gpfn_from_mfn(mfn_x(gmfn));
     if ( likely(VALID_M2P(pfn))
-         && likely(pfn < d->arch.shadow.dirty_bitmap_size) 
-         && test_bit(pfn, d->arch.shadow.dirty_bitmap) )
+         && likely(pfn < d->arch.paging.shadow.dirty_bitmap_size) 
+         && test_bit(pfn, d->arch.paging.shadow.dirty_bitmap) )
         return 1;
 
     return 0;
@@ -612,7 +605,7 @@ static inline int sh_pin(struct vcpu *v,
         sp->pinned = 1;
     }
     /* Put it at the head of the list of pinned shadows */
-    list_add(&sp->list, &v->domain->arch.shadow.pinned_shadows);
+    list_add(&sp->list, &v->domain->arch.paging.shadow.pinned_shadows);
     return 1;
 }
 
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/mm/shadow/types.h
--- a/xen/arch/x86/mm/shadow/types.h    Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/mm/shadow/types.h    Thu Feb 15 14:09:39 2007 -0700
@@ -414,15 +414,9 @@ static inline mfn_t
 static inline mfn_t
 vcpu_gfn_to_mfn(struct vcpu *v, gfn_t gfn)
 {
-    if ( !shadow_vcpu_mode_translate(v) )
+    if ( !paging_vcpu_mode_translate(v) )
         return _mfn(gfn_x(gfn));
-    return sh_gfn_to_mfn(v->domain, gfn_x(gfn));
-}
-
-static inline gfn_t
-mfn_to_gfn(struct domain *d, mfn_t mfn)
-{
-    return _gfn(sh_mfn_to_gfn(d, mfn));
+    return gfn_to_mfn(v->domain, gfn_x(gfn));
 }
 
 static inline paddr_t
@@ -453,10 +447,8 @@ struct shadow_walk_t
     guest_l2e_t *l2e;           /* Pointer to guest's level 2 entry */
     guest_l1e_t *l1e;           /* Pointer to guest's level 1 entry */
     guest_l1e_t eff_l1e;        /* Effective level 1 entry */
-#if GUEST_PAGING_LEVELS >= 3
 #if GUEST_PAGING_LEVELS >= 4
     mfn_t l4mfn;                /* MFN that the level 4 entry is in */
-#endif
     mfn_t l3mfn;                /* MFN that the level 3 entry is in */
 #endif
     mfn_t l2mfn;                /* MFN that the level 2 entry is in */
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/setup.c      Thu Feb 15 14:09:39 2007 -0700
@@ -29,7 +29,7 @@
 #include <asm/mpspec.h>
 #include <asm/apic.h>
 #include <asm/desc.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
 #include <asm/e820.h>
 #include <acm/acm_hooks.h>
 #include <xen/kexec.h>
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/sysctl.c
--- a/xen/arch/x86/sysctl.c     Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/sysctl.c     Thu Feb 15 14:09:39 2007 -0700
@@ -19,7 +19,6 @@
 #include <xen/trace.h>
 #include <xen/console.h>
 #include <xen/iocap.h>
-#include <asm/shadow.h>
 #include <asm/irq.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/traps.c      Thu Feb 15 14:09:39 2007 -0700
@@ -46,7 +46,7 @@
 #include <xen/nmi.h>
 #include <xen/version.h>
 #include <xen/kexec.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/atomic.h>
@@ -860,8 +860,8 @@ static int fixup_page_fault(unsigned lon
 
     if ( unlikely(IN_HYPERVISOR_RANGE(addr)) )
     {
-        if ( shadow_mode_external(d) && guest_mode(regs) )
-            return shadow_fault(addr, regs);
+        if ( paging_mode_external(d) && guest_mode(regs) )
+            return paging_fault(addr, regs);
         if ( (addr >= GDT_LDT_VIRT_START) && (addr < GDT_LDT_VIRT_END) )
             return handle_gdt_ldt_mapping_fault(
                 addr - GDT_LDT_VIRT_START, regs);
@@ -876,8 +876,8 @@ static int fixup_page_fault(unsigned lon
          ptwr_do_page_fault(v, addr, regs) )
         return EXCRET_fault_fixed;
 
-    if ( shadow_mode_enabled(d) )
-        return shadow_fault(addr, regs);
+    if ( paging_mode_enabled(d) )
+        return paging_fault(addr, regs);
 
     return 0;
 }
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/x86_32/domain_page.c
--- a/xen/arch/x86/x86_32/domain_page.c Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/x86_32/domain_page.c Thu Feb 15 14:09:39 2007 -0700
@@ -11,7 +11,6 @@
 #include <xen/mm.h>
 #include <xen/perfc.h>
 #include <xen/domain_page.h>
-#include <xen/shadow.h>
 #include <asm/current.h>
 #include <asm/flushtlb.h>
 #include <asm/hardirq.h>
diff -r ac18d251df63 -r 9529d667d042 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/arch/x86/x86_64/traps.c       Thu Feb 15 14:09:39 2007 -0700
@@ -16,7 +16,6 @@
 #include <asm/flushtlb.h>
 #include <asm/msr.h>
 #include <asm/page.h>
-#include <asm/shadow.h>
 #include <asm/shared.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
diff -r ac18d251df63 -r 9529d667d042 xen/common/libelf/libelf-dominfo.c
--- a/xen/common/libelf/libelf-dominfo.c        Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/common/libelf/libelf-dominfo.c        Thu Feb 15 14:09:39 2007 -0700
@@ -15,61 +15,63 @@ const char *elf_xen_feature_names[] = {
     [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb"
 };
 const int elf_xen_features =
-    sizeof(elf_xen_feature_names) / sizeof(elf_xen_feature_names[0]);
+sizeof(elf_xen_feature_names) / sizeof(elf_xen_feature_names[0]);
 
 int elf_xen_parse_features(const char *features,
-                          uint32_t *supported,
-                          uint32_t *required)
+                           uint32_t *supported,
+                           uint32_t *required)
 {
     char feature[64];
     int pos, len, i;
 
-    if (NULL == features)
-       return 0;
-    for (pos = 0; features[pos] != '\0'; pos += len)
-    {
-       memset(feature, 0, sizeof(feature));
-       for (len = 0;; len++)
-       {
-           if (len >= sizeof(feature)-1)
-               break;
-           if (features[pos + len] == '\0')
-               break;
-           if (features[pos + len] == '|')
-           {
-               len++;
-               break;
-           }
-           feature[len] = features[pos + len];
-       }
-
-       for (i = 0; i < elf_xen_features; i++)
-       {
-           if (!elf_xen_feature_names[i])
-               continue;
-           if (NULL != required && feature[0] == '!')
-           {
-               /* required */
-               if (0 == strcmp(feature + 1, elf_xen_feature_names[i]))
-               {
-                   elf_xen_feature_set(i, supported);
-                   elf_xen_feature_set(i, required);
-                   break;
-               }
-           }
-           else
-           {
-               /* supported */
-               if (0 == strcmp(feature, elf_xen_feature_names[i]))
-               {
-                   elf_xen_feature_set(i, supported);
-                   break;
-               }
-           }
-       }
-       if (i == elf_xen_features)
-           return -1;
-    }
+    if ( features == NULL )
+        return 0;
+
+    for ( pos = 0; features[pos] != '\0'; pos += len )
+    {
+        memset(feature, 0, sizeof(feature));
+        for ( len = 0;; len++ )
+        {
+            if ( len >= sizeof(feature)-1 )
+                break;
+            if ( features[pos + len] == '\0' )
+                break;
+            if ( features[pos + len] == '|' )
+            {
+                len++;
+                break;
+            }
+            feature[len] = features[pos + len];
+        }
+
+        for ( i = 0; i < elf_xen_features; i++ )
+        {
+            if ( !elf_xen_feature_names[i] )
+                continue;
+            if ( (required != NULL) && (feature[0] == '!') )
+            {
+                /* required */
+                if ( !strcmp(feature + 1, elf_xen_feature_names[i]) )
+                {
+                    elf_xen_feature_set(i, supported);
+                    elf_xen_feature_set(i, required);
+                    break;
+                }
+            }
+            else
+            {
+                /* supported */
+                if ( !strcmp(feature, elf_xen_feature_names[i]) )
+                {
+                    elf_xen_feature_set(i, supported);
+                    break;
+                }
+            }
+        }
+        if ( i == elf_xen_features )
+            return -1;
+    }
+
     return 0;
 }
 
@@ -77,26 +79,26 @@ int elf_xen_parse_features(const char *f
 /* xen elf notes                                                            */
 
 int elf_xen_parse_note(struct elf_binary *elf,
-                      struct elf_dom_parms *parms,
-                      const elf_note *note)
+                       struct elf_dom_parms *parms,
+                       const elf_note *note)
 {
 /* *INDENT-OFF* */
     static const struct {
-       char *name;
-       int str;
+        char *name;
+        int str;
     } note_desc[] = {
-       [XEN_ELFNOTE_ENTRY] = { "ENTRY", 0},
-       [XEN_ELFNOTE_HYPERCALL_PAGE] = { "HYPERCALL_PAGE", 0},
-       [XEN_ELFNOTE_VIRT_BASE] = { "VIRT_BASE", 0},
-       [XEN_ELFNOTE_PADDR_OFFSET] = { "PADDR_OFFSET", 0},
-       [XEN_ELFNOTE_HV_START_LOW] = { "HV_START_LOW", 0},
-       [XEN_ELFNOTE_XEN_VERSION] = { "XEN_VERSION", 1},
-       [XEN_ELFNOTE_GUEST_OS] = { "GUEST_OS", 1},
-       [XEN_ELFNOTE_GUEST_VERSION] = { "GUEST_VERSION", 1},
-       [XEN_ELFNOTE_LOADER] = { "LOADER", 1},
-       [XEN_ELFNOTE_PAE_MODE] = { "PAE_MODE", 1},
-       [XEN_ELFNOTE_FEATURES] = { "FEATURES", 1},
-       [XEN_ELFNOTE_BSD_SYMTAB] = { "BSD_SYMTAB", 1},
+        [XEN_ELFNOTE_ENTRY] = { "ENTRY", 0},
+        [XEN_ELFNOTE_HYPERCALL_PAGE] = { "HYPERCALL_PAGE", 0},
+        [XEN_ELFNOTE_VIRT_BASE] = { "VIRT_BASE", 0},
+        [XEN_ELFNOTE_PADDR_OFFSET] = { "PADDR_OFFSET", 0},
+        [XEN_ELFNOTE_HV_START_LOW] = { "HV_START_LOW", 0},
+        [XEN_ELFNOTE_XEN_VERSION] = { "XEN_VERSION", 1},
+        [XEN_ELFNOTE_GUEST_OS] = { "GUEST_OS", 1},
+        [XEN_ELFNOTE_GUEST_VERSION] = { "GUEST_VERSION", 1},
+        [XEN_ELFNOTE_LOADER] = { "LOADER", 1},
+        [XEN_ELFNOTE_PAE_MODE] = { "PAE_MODE", 1},
+        [XEN_ELFNOTE_FEATURES] = { "FEATURES", 1},
+        [XEN_ELFNOTE_BSD_SYMTAB] = { "BSD_SYMTAB", 1},
     };
 /* *INDENT-ON* */
 
@@ -104,73 +106,73 @@ int elf_xen_parse_note(struct elf_binary
     uint64_t val = 0;
     int type = elf_uval(elf, note, type);
 
-    if ((type >= sizeof(note_desc) / sizeof(note_desc[0])) ||
-       (NULL == note_desc[type].name))
-    {
-       elf_err(elf, "%s: unknown xen elf note (0x%x)\n",
-               __FUNCTION__, type);
-       return -1;
-    }
-
-    if (note_desc[type].str)
-    {
-       str = elf_note_desc(elf, note);
-       elf_msg(elf, "%s: %s = \"%s\"\n", __FUNCTION__,
-               note_desc[type].name, str);
+    if ( (type >= sizeof(note_desc) / sizeof(note_desc[0])) ||
+         (note_desc[type].name == NULL) )
+    {
+        elf_msg(elf, "%s: unknown xen elf note (0x%x)\n",
+                __FUNCTION__, type);
+        return 0;
+    }
+
+    if ( note_desc[type].str )
+    {
+        str = elf_note_desc(elf, note);
+        elf_msg(elf, "%s: %s = \"%s\"\n", __FUNCTION__,
+                note_desc[type].name, str);
     }
     else
     {
-       val = elf_note_numeric(elf, note);
-       elf_msg(elf, "%s: %s = 0x%" PRIx64 "\n", __FUNCTION__,
-               note_desc[type].name, val);
-    }
-
-    switch (type)
+        val = elf_note_numeric(elf, note);
+        elf_msg(elf, "%s: %s = 0x%" PRIx64 "\n", __FUNCTION__,
+                note_desc[type].name, val);
+    }
+
+    switch ( type )
     {
     case XEN_ELFNOTE_LOADER:
-       safe_strcpy(parms->loader, str);
-       break;
+        safe_strcpy(parms->loader, str);
+        break;
     case XEN_ELFNOTE_GUEST_OS:
-       safe_strcpy(parms->guest_os, str);
-       break;
+        safe_strcpy(parms->guest_os, str);
+        break;
     case XEN_ELFNOTE_GUEST_VERSION:
-       safe_strcpy(parms->guest_ver, str);
-       break;
+        safe_strcpy(parms->guest_ver, str);
+        break;
     case XEN_ELFNOTE_XEN_VERSION:
-       safe_strcpy(parms->xen_ver, str);
-       break;
+        safe_strcpy(parms->xen_ver, str);
+        break;
     case XEN_ELFNOTE_PAE_MODE:
-       if (0 == strcmp(str, "yes"))
-           parms->pae = 2 /* extended_cr3 */;
-       if (strstr(str, "bimodal"))
-           parms->pae = 3 /* bimodal */;
-       break;
+        if ( !strcmp(str, "yes") )
+            parms->pae = 2 /* extended_cr3 */;
+        if ( strstr(str, "bimodal") )
+            parms->pae = 3 /* bimodal */;
+        break;
     case XEN_ELFNOTE_BSD_SYMTAB:
-       if (0 == strcmp(str, "yes"))
-           parms->bsd_symtab = 1;
-       break;
+        if ( !strcmp(str, "yes") )
+            parms->bsd_symtab = 1;
+        break;
 
     case XEN_ELFNOTE_VIRT_BASE:
-       parms->virt_base = val;
-       break;
+        parms->virt_base = val;
+        break;
     case XEN_ELFNOTE_ENTRY:
-       parms->virt_entry = val;
-       break;
+        parms->virt_entry = val;
+        break;
     case XEN_ELFNOTE_PADDR_OFFSET:
-       parms->elf_paddr_offset = val;
-       break;
+        parms->elf_paddr_offset = val;
+        break;
     case XEN_ELFNOTE_HYPERCALL_PAGE:
-       parms->virt_hypercall = val;
-       break;
+        parms->virt_hypercall = val;
+        break;
     case XEN_ELFNOTE_HV_START_LOW:
-       parms->virt_hv_start_low = val;
-       break;
+        parms->virt_hv_start_low = val;
+        break;
 
     case XEN_ELFNOTE_FEATURES:
-       if (0 != elf_xen_parse_features(str, parms->f_supported,
-                                       parms->f_required))
-           return -1;
-       break;
+        if ( elf_xen_parse_features(str, parms->f_supported,
+                                    parms->f_required) )
+            return -1;
+        break;
 
     }
     return 0;
@@ -180,83 +182,85 @@ int elf_xen_parse_note(struct elf_binary
 /* __xen_guest section                                                      */
 
 int elf_xen_parse_guest_info(struct elf_binary *elf,
-                            struct elf_dom_parms *parms)
+                             struct elf_dom_parms *parms)
 {
     const char *h;
     char name[32], value[128];
     int len;
 
     h = parms->guest_info;
-    while (*h)
-    {
-       memset(name, 0, sizeof(name));
-       memset(value, 0, sizeof(value));
-       for (len = 0;; len++, h++) {
-           if (len >= sizeof(name)-1)
-               break;
-           if (*h == '\0')
-               break;
-           if (*h == ',')
-           {
-               h++;
-               break;
-           }
-           if (*h == '=')
-           {
-               h++;
-               for (len = 0;; len++, h++) {
-                   if (len >= sizeof(value)-1)
-                       break;
-                   if (*h == '\0')
-                       break;
-                   if (*h == ',')
-                   {
-                       h++;
-                       break;
-                   }
-                   value[len] = *h;
-               }
-               break;
-           }
-           name[len] = *h;
-       }
-       elf_msg(elf, "%s: %s=\"%s\"\n", __FUNCTION__, name, value);
-
-       /* strings */
-       if (0 == strcmp(name, "LOADER"))
-           safe_strcpy(parms->loader, value);
-       if (0 == strcmp(name, "GUEST_OS"))
-           safe_strcpy(parms->guest_os, value);
-       if (0 == strcmp(name, "GUEST_VER"))
-           safe_strcpy(parms->guest_ver, value);
-       if (0 == strcmp(name, "XEN_VER"))
-           safe_strcpy(parms->xen_ver, value);
-       if (0 == strcmp(name, "PAE"))
-       {
-           if (0 == strcmp(value, "yes[extended-cr3]"))
-               parms->pae = 2 /* extended_cr3 */;
-           else if (0 == strncmp(value, "yes", 3))
-               parms->pae = 1 /* yes */;
-       }
-       if (0 == strcmp(name, "BSD_SYMTAB"))
-           parms->bsd_symtab = 1;
-
-       /* longs */
-       if (0 == strcmp(name, "VIRT_BASE"))
-           parms->virt_base = strtoull(value, NULL, 0);
-       if (0 == strcmp(name, "VIRT_ENTRY"))
-           parms->virt_entry = strtoull(value, NULL, 0);
-       if (0 == strcmp(name, "ELF_PADDR_OFFSET"))
-           parms->elf_paddr_offset = strtoull(value, NULL, 0);
-       if (0 == strcmp(name, "HYPERCALL_PAGE"))
-           parms->virt_hypercall = (strtoull(value, NULL, 0) << 12) +
-               parms->virt_base;
-
-       /* other */
-       if (0 == strcmp(name, "FEATURES"))
-           if (0 != elf_xen_parse_features(value, parms->f_supported,
-                                           parms->f_required))
-               return -1;
+    while ( *h )
+    {
+        memset(name, 0, sizeof(name));
+        memset(value, 0, sizeof(value));
+        for ( len = 0;; len++, h++ )
+        {
+            if ( len >= sizeof(name)-1 )
+                break;
+            if ( *h == '\0' )
+                break;
+            if ( *h == ',' )
+            {
+                h++;
+                break;
+            }
+            if ( *h == '=' )
+            {
+                h++;
+                for ( len = 0;; len++, h++ )
+                {
+                    if ( len >= sizeof(value)-1 )
+                        break;
+                    if ( *h == '\0' )
+                        break;
+                    if ( *h == ',' )
+                    {
+                        h++;
+                        break;
+                    }
+                    value[len] = *h;
+                }
+                break;
+            }
+            name[len] = *h;
+        }
+        elf_msg(elf, "%s: %s=\"%s\"\n", __FUNCTION__, name, value);
+
+        /* strings */
+        if ( !strcmp(name, "LOADER") )
+            safe_strcpy(parms->loader, value);
+        if ( !strcmp(name, "GUEST_OS") )
+            safe_strcpy(parms->guest_os, value);
+        if ( !strcmp(name, "GUEST_VER") )
+            safe_strcpy(parms->guest_ver, value);
+        if ( !strcmp(name, "XEN_VER") )
+            safe_strcpy(parms->xen_ver, value);
+        if ( !strcmp(name, "PAE") )
+        {
+            if ( !strcmp(value, "yes[extended-cr3]") )
+                parms->pae = 2 /* extended_cr3 */;
+            else if ( !strncmp(value, "yes", 3) )
+                parms->pae = 1 /* yes */;
+        }
+        if ( !strcmp(name, "BSD_SYMTAB") )
+            parms->bsd_symtab = 1;
+
+        /* longs */
+        if ( !strcmp(name, "VIRT_BASE") )
+            parms->virt_base = strtoull(value, NULL, 0);
+        if ( !strcmp(name, "VIRT_ENTRY") )
+            parms->virt_entry = strtoull(value, NULL, 0);
+        if ( !strcmp(name, "ELF_PADDR_OFFSET") )
+            parms->elf_paddr_offset = strtoull(value, NULL, 0);
+        if ( !strcmp(name, "HYPERCALL_PAGE") )
+            parms->virt_hypercall = (strtoull(value, NULL, 0) << 12) +
+                parms->virt_base;
+
+        /* other */
+        if ( !strcmp(name, "FEATURES") )
+            if ( elf_xen_parse_features(value, parms->f_supported,
+                                        parms->f_required) )
+                return -1;
     }
     return 0;
 }
@@ -265,54 +269,59 @@ int elf_xen_parse_guest_info(struct elf_
 /* sanity checks                                                            */
 
 static int elf_xen_note_check(struct elf_binary *elf,
-                             struct elf_dom_parms *parms)
-{
-    if (NULL == parms->elf_note_start && NULL == parms->guest_info) {
-       int machine = elf_uval(elf, elf->ehdr, e_machine);
-       if (EM_386 == machine || EM_X86_64 == machine) {
-           elf_err(elf, "%s: ERROR: Not a Xen-ELF image: "
-                   "No ELF notes or '__xen_guest' section found.\n",
-                   __FUNCTION__);
-           return -1;
-       }
-       return 0;
+                              struct elf_dom_parms *parms)
+{
+    if ( (parms->elf_note_start == NULL) && (parms->guest_info == NULL) )
+    {
+        int machine = elf_uval(elf, elf->ehdr, e_machine);
+        if ( (machine == EM_386) || (machine == EM_X86_64) )
+        {
+            elf_err(elf, "%s: ERROR: Not a Xen-ELF image: "
+                    "No ELF notes or '__xen_guest' section found.\n",
+                    __FUNCTION__);
+            return -1;
+        }
+        return 0;
     }
 
     /* Check the contents of the Xen notes or guest string. */
-    if ( ( 0 == strlen(parms->loader) || strncmp(parms->loader, "generic", 7) 
) &&
-        ( 0 == strlen(parms->guest_os) || strncmp(parms->guest_os, "linux", 5) 
) )
-    {
-       elf_err(elf, "%s: ERROR: Will only load images built for the generic "
-               "loader or Linux images", __FUNCTION__);
-       return -1;
-    }
-
-    if ( 0 == strlen(parms->xen_ver) || strncmp(parms->xen_ver, "xen-3.0", 7) )
-    {
-       elf_err(elf, "%s: ERROR: Xen will only load images built for Xen 
v3.0\n",
-               __FUNCTION__);
-       return -1;
+    if ( ((strlen(parms->loader) == 0) ||
+          strncmp(parms->loader, "generic", 7)) &&
+         ((strlen(parms->guest_os) == 0) ||
+          strncmp(parms->guest_os, "linux", 5)) )
+    {
+        elf_err(elf, "%s: ERROR: Will only load images built for the generic "
+                "loader or Linux images", __FUNCTION__);
+        return -1;
+    }
+
+    if ( (strlen(parms->xen_ver) == 0) ||
+         strncmp(parms->xen_ver, "xen-3.0", 7) )
+    {
+        elf_err(elf, "%s: ERROR: Xen will only load images built "
+                "for Xen v3.0\n", __FUNCTION__);
+        return -1;
     }
     return 0;
 }
 
 static int elf_xen_addr_calc_check(struct elf_binary *elf,
-                                  struct elf_dom_parms *parms)
-{
-    if (UNSET_ADDR != parms->elf_paddr_offset &&
-       UNSET_ADDR == parms->virt_base )
-    {
-       elf_err(elf, "%s: ERROR: ELF_PADDR_OFFSET set, VIRT_BASE unset\n",
-               __FUNCTION__);
+                                   struct elf_dom_parms *parms)
+{
+    if ( (parms->elf_paddr_offset != UNSET_ADDR) &&
+         (parms->virt_base == UNSET_ADDR) )
+    {
+        elf_err(elf, "%s: ERROR: ELF_PADDR_OFFSET set, VIRT_BASE unset\n",
+                __FUNCTION__);
         return -1;
     }
 
     /* Initial guess for virt_base is 0 if it is not explicitly defined. */
-    if (UNSET_ADDR == parms->virt_base)
-    {
-       parms->virt_base = 0;
-       elf_msg(elf, "%s: VIRT_BASE unset, using 0x%" PRIx64 "\n",
-               __FUNCTION__, parms->virt_base);
+    if ( parms->virt_base == UNSET_ADDR )
+    {
+        parms->virt_base = 0;
+        elf_msg(elf, "%s: VIRT_BASE unset, using 0x%" PRIx64 "\n",
+                __FUNCTION__, parms->virt_base);
     }
 
     /*
@@ -324,22 +333,22 @@ static int elf_xen_addr_calc_check(struc
      * If we are using the modern ELF notes interface then the default
      * is 0.
      */
-    if (UNSET_ADDR == parms->elf_paddr_offset)
-    {
-       if (parms->elf_note_start)
-           parms->elf_paddr_offset = 0;
-       else
-           parms->elf_paddr_offset = parms->virt_base;
-       elf_msg(elf, "%s: ELF_PADDR_OFFSET unset, using 0x%" PRIx64 "\n",
-               __FUNCTION__, parms->elf_paddr_offset);
+    if ( parms->elf_paddr_offset == UNSET_ADDR )
+    {
+        if ( parms->elf_note_start )
+            parms->elf_paddr_offset = 0;
+        else
+            parms->elf_paddr_offset = parms->virt_base;
+        elf_msg(elf, "%s: ELF_PADDR_OFFSET unset, using 0x%" PRIx64 "\n",
+                __FUNCTION__, parms->elf_paddr_offset);
     }
 
     parms->virt_offset = parms->virt_base - parms->elf_paddr_offset;
     parms->virt_kstart = elf->pstart + parms->virt_offset;
     parms->virt_kend   = elf->pend   + parms->virt_offset;
 
-    if (UNSET_ADDR == parms->virt_entry)
-       parms->virt_entry = elf_uval(elf, elf->ehdr, e_entry);
+    if ( parms->virt_entry == UNSET_ADDR )
+        parms->virt_entry = elf_uval(elf, elf->ehdr, e_entry);
 
     elf_msg(elf, "%s: addresses:\n", __FUNCTION__);
     elf_msg(elf, "    virt_base        = 0x%" PRIx64 "\n", parms->virt_base);
@@ -355,7 +364,7 @@ static int elf_xen_addr_calc_check(struc
          (parms->virt_base > parms->virt_kstart) )
     {
         elf_err(elf, "%s: ERROR: ELF start or entries are out of bounds.\n",
-               __FUNCTION__);
+                __FUNCTION__);
         return -1;
     }
 
@@ -366,7 +375,7 @@ static int elf_xen_addr_calc_check(struc
 /* glue it all together ...                                                 */
 
 int elf_xen_parse(struct elf_binary *elf,
-                 struct elf_dom_parms *parms)
+                  struct elf_dom_parms *parms)
 {
     const elf_note *note;
     const elf_shdr *shdr;
@@ -382,39 +391,49 @@ int elf_xen_parse(struct elf_binary *elf
 
     /* find and parse elf notes */
     count = elf_shdr_count(elf);
-    for (i = 0; i < count; i++)
-    {
-       shdr = elf_shdr_by_index(elf, i);
-       if (0 == strcmp(elf_section_name(elf, shdr), "__xen_guest"))
-           parms->guest_info = elf_section_start(elf, shdr);
-       if (elf_uval(elf, shdr, sh_type) != SHT_NOTE)
-           continue;
-       parms->elf_note_start = elf_section_start(elf, shdr);
-       parms->elf_note_end   = elf_section_end(elf, shdr);
-       for (note = parms->elf_note_start;
-            (void *)note < parms->elf_note_end;
-            note = elf_note_next(elf, note))
-       {
-           if (0 != strcmp(elf_note_name(elf, note), "Xen"))
-               continue;
-           if (0 != elf_xen_parse_note(elf, parms, note))
-               return -1;
-           xen_elfnotes++;
-       }
-    }
-
-    if (!xen_elfnotes && parms->guest_info)
-    {
-       parms->elf_note_start = NULL;
-       parms->elf_note_end   = NULL;
-       elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
-               parms->guest_info);
-       elf_xen_parse_guest_info(elf, parms);
-    }
-
-    if (0 != elf_xen_note_check(elf, parms))
-       return -1;
-    if (0 != elf_xen_addr_calc_check(elf, parms))
-       return -1;
-    return 0;
-}
+    for ( i = 0; i < count; i++ )
+    {
+        shdr = elf_shdr_by_index(elf, i);
+        if ( !strcmp(elf_section_name(elf, shdr), "__xen_guest") )
+            parms->guest_info = elf_section_start(elf, shdr);
+        if ( elf_uval(elf, shdr, sh_type) != SHT_NOTE )
+            continue;
+        parms->elf_note_start = elf_section_start(elf, shdr);
+        parms->elf_note_end   = elf_section_end(elf, shdr);
+        for ( note = parms->elf_note_start;
+              (void *)note < parms->elf_note_end;
+              note = elf_note_next(elf, note) )
+        {
+            if ( strcmp(elf_note_name(elf, note), "Xen") )
+                continue;
+            if ( elf_xen_parse_note(elf, parms, note) )
+                return -1;
+            xen_elfnotes++;
+        }
+    }
+
+    if ( !xen_elfnotes && parms->guest_info )
+    {
+        parms->elf_note_start = NULL;
+        parms->elf_note_end   = NULL;
+        elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
+                parms->guest_info);
+        elf_xen_parse_guest_info(elf, parms);
+    }
+
+    if ( elf_xen_note_check(elf, parms) != 0 )
+        return -1;
+    if ( elf_xen_addr_calc_check(elf, parms) != 0 )
+        return -1;
+    return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r ac18d251df63 -r 9529d667d042 xen/common/libelf/libelf-loader.c
--- a/xen/common/libelf/libelf-loader.c Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/common/libelf/libelf-loader.c Thu Feb 15 14:09:39 2007 -0700
@@ -11,10 +11,10 @@ int elf_init(struct elf_binary *elf, con
     const elf_shdr *shdr;
     uint64_t i, count, section, offset;
 
-    if (!elf_is_elfbinary(image))
+    if ( !elf_is_elfbinary(image) )
     {
-       elf_err(elf, "%s: not an ELF binary\n", __FUNCTION__);
-       return -1;
+        elf_err(elf, "%s: not an ELF binary\n", __FUNCTION__);
+        return -1;
     }
 
     memset(elf, 0, sizeof(*elf));
@@ -26,46 +26,46 @@ int elf_init(struct elf_binary *elf, con
 
     /* sanity check phdr */
     offset = elf_uval(elf, elf->ehdr, e_phoff) +
-       elf_uval(elf, elf->ehdr, e_phentsize) * elf_phdr_count(elf);
-    if (offset > elf->size)
+        elf_uval(elf, elf->ehdr, e_phentsize) * elf_phdr_count(elf);
+    if ( offset > elf->size )
     {
-       elf_err(elf, "%s: phdr overflow (off %" PRIx64 " > size %lx)\n",
-               __FUNCTION__, offset, (unsigned long)elf->size);
-       return -1;
+        elf_err(elf, "%s: phdr overflow (off %" PRIx64 " > size %lx)\n",
+                __FUNCTION__, offset, (unsigned long)elf->size);
+        return -1;
     }
 
     /* sanity check shdr */
     offset = elf_uval(elf, elf->ehdr, e_shoff) +
-       elf_uval(elf, elf->ehdr, e_shentsize) * elf_shdr_count(elf);
-    if (offset > elf->size)
+        elf_uval(elf, elf->ehdr, e_shentsize) * elf_shdr_count(elf);
+    if ( offset > elf->size )
     {
-       elf_err(elf, "%s: shdr overflow (off %" PRIx64 " > size %lx)\n",
-               __FUNCTION__, offset, (unsigned long)elf->size);
-       return -1;
+        elf_err(elf, "%s: shdr overflow (off %" PRIx64 " > size %lx)\n",
+                __FUNCTION__, offset, (unsigned long)elf->size);
+        return -1;
     }
 
     /* find section string table */
     section = elf_uval(elf, elf->ehdr, e_shstrndx);
     shdr = elf_shdr_by_index(elf, section);
-    if (NULL != shdr)
-       elf->sec_strtab = elf_section_start(elf, shdr);
+    if ( shdr != NULL )
+        elf->sec_strtab = elf_section_start(elf, shdr);
 
     /* find symbol table, symbol string table */
     count = elf_shdr_count(elf);
-    for (i = 0; i < count; i++)
+    for ( i = 0; i < count; i++ )
     {
-       shdr = elf_shdr_by_index(elf, i);
-       if (elf_uval(elf, shdr, sh_type) != SHT_SYMTAB)
-           continue;
-       elf->sym_tab = shdr;
-       shdr = elf_shdr_by_index(elf, elf_uval(elf, shdr, sh_link));
-       if (NULL == shdr)
-       {
-           elf->sym_tab = NULL;
-           continue;
-       }
-       elf->sym_strtab = elf_section_start(elf, shdr);
-       break;
+        shdr = elf_shdr_by_index(elf, i);
+        if ( elf_uval(elf, shdr, sh_type) != SHT_SYMTAB )
+            continue;
+        elf->sym_tab = shdr;
+        shdr = elf_shdr_by_index(elf, elf_uval(elf, shdr, sh_link));
+        if ( shdr == NULL )
+        {
+            elf->sym_tab = NULL;
+            continue;
+        }
+        elf->sym_strtab = elf_section_start(elf, shdr);
+        break;
     }
     return 0;
 }
@@ -91,24 +91,24 @@ void elf_parse_binary(struct elf_binary 
     uint64_t i, count, paddr, memsz;
 
     count = elf_uval(elf, elf->ehdr, e_phnum);
-    for (i = 0; i < count; i++)
+    for ( i = 0; i < count; i++ )
     {
-       phdr = elf_phdr_by_index(elf, i);
-       if (!elf_phdr_is_loadable(elf, phdr))
-           continue;
-       paddr = elf_uval(elf, phdr, p_paddr);
-       memsz = elf_uval(elf, phdr, p_memsz);
-       elf_msg(elf, "%s: phdr: paddr=0x%" PRIx64
-               " memsz=0x%" PRIx64 "\n", __FUNCTION__, paddr, memsz);
-       if (low > paddr)
-           low = paddr;
-       if (high < paddr + memsz)
-           high = paddr + memsz;
+        phdr = elf_phdr_by_index(elf, i);
+        if ( !elf_phdr_is_loadable(elf, phdr) )
+            continue;
+        paddr = elf_uval(elf, phdr, p_paddr);
+        memsz = elf_uval(elf, phdr, p_memsz);
+        elf_msg(elf, "%s: phdr: paddr=0x%" PRIx64
+                " memsz=0x%" PRIx64 "\n", __FUNCTION__, paddr, memsz);
+        if ( low > paddr )
+            low = paddr;
+        if ( high < paddr + memsz )
+            high = paddr + memsz;
     }
     elf->pstart = low;
     elf->pend = high;
     elf_msg(elf, "%s: memory: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
-           __FUNCTION__, elf->pstart, elf->pend);
+            __FUNCTION__, elf->pstart, elf->pend);
 }
 
 void elf_load_binary(struct elf_binary *elf)
@@ -118,18 +118,20 @@ void elf_load_binary(struct elf_binary *
     char *dest;
 
     count = elf_uval(elf, elf->ehdr, e_phnum);
-    for (i = 0; i < count; i++)
+    for ( i = 0; i < count; i++ )
     {
-       phdr = elf_phdr_by_index(elf, i);
-       if (!elf_phdr_is_loadable(elf, phdr))
-           continue;
-       paddr = elf_uval(elf, phdr, p_paddr);
-       offset = elf_uval(elf, phdr, p_offset);
-       filesz = elf_uval(elf, phdr, p_filesz);
-       memsz = elf_uval(elf, phdr, p_memsz);
-       dest = elf_get_ptr(elf, paddr);
-       memcpy(dest, elf->image + offset, filesz);
-       memset(dest + filesz, 0, memsz - filesz);
+        phdr = elf_phdr_by_index(elf, i);
+        if ( !elf_phdr_is_loadable(elf, phdr) )
+            continue;
+        paddr = elf_uval(elf, phdr, p_paddr);
+        offset = elf_uval(elf, phdr, p_offset);
+        filesz = elf_uval(elf, phdr, p_filesz);
+        memsz = elf_uval(elf, phdr, p_memsz);
+        dest = elf_get_ptr(elf, paddr);
+        elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%p -> 0x%p\n",
+                __func__, i, dest, dest + filesz);
+        memcpy(dest, elf->image + offset, filesz);
+        memset(dest + filesz, 0, memsz - filesz);
     }
 }
 
@@ -144,13 +146,24 @@ uint64_t elf_lookup_addr(struct elf_bina
     uint64_t value;
 
     sym = elf_sym_by_name(elf, symbol);
-    if (NULL == sym)
+    if ( sym == NULL )
     {
-       elf_err(elf, "%s: not found: %s\n", __FUNCTION__, symbol);
-       return -1;
+        elf_err(elf, "%s: not found: %s\n", __FUNCTION__, symbol);
+        return -1;
     }
+
     value = elf_uval(elf, sym, st_value);
     elf_msg(elf, "%s: symbol \"%s\" at 0x%" PRIx64 "\n", __FUNCTION__,
-           symbol, value);
+            symbol, value);
     return value;
 }
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r ac18d251df63 -r 9529d667d042 xen/common/libelf/libelf-private.h
--- a/xen/common/libelf/libelf-private.h        Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/common/libelf/libelf-private.h        Thu Feb 15 14:09:39 2007 -0700
@@ -12,9 +12,9 @@
 #include <public/libelf.h>
 
 #define elf_msg(elf, fmt, args ... ) \
-       if (elf->verbose) printk(fmt, ## args )
+   if (elf->verbose) printk(fmt, ## args )
 #define elf_err(elf, fmt, args ... ) \
-       printk(fmt, ## args )
+   printk(fmt, ## args )
 
 #define strtoull(str, end, base) simple_strtoull(str, end, base)
 #define bswap_16(x) swab16(x)
@@ -43,12 +43,12 @@
 #include "xc_private.h"
 
 #define elf_msg(elf, fmt, args ... ) \
-       if (elf->log && elf->verbose) fprintf(elf->log, fmt , ## args )
-#define elf_err(elf, fmt, args ... ) do {                 \
-       if (elf->log)                                     \
-            fprintf(elf->log, fmt , ## args );            \
-        xc_set_error(XC_INVALID_KERNEL, fmt , ## args );  \
-       } while (0)
+    if (elf->log && elf->verbose) fprintf(elf->log, fmt , ## args )
+#define elf_err(elf, fmt, args ... ) do {               \
+    if (elf->log)                                       \
+        fprintf(elf->log, fmt , ## args );              \
+    xc_set_error(XC_INVALID_KERNEL, fmt , ## args );    \
+} while (0)
 
 #define safe_strcpy(d,s)                        \
 do { strncpy((d),(s),sizeof((d))-1);            \
@@ -58,3 +58,13 @@ do { strncpy((d),(s),sizeof((d))-1);    
 #endif
 
 #endif /* __LIBELF_PRIVATE_H_ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r ac18d251df63 -r 9529d667d042 xen/common/libelf/libelf-relocate.c
--- a/xen/common/libelf/libelf-relocate.c       Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/common/libelf/libelf-relocate.c       Thu Feb 15 14:09:39 2007 -0700
@@ -46,22 +46,22 @@ static const char *rel_names_i386[] = {
 };
 
 static int elf_reloc_i386(struct elf_binary *elf, int type,
-                         uint64_t addr, uint64_t value)
+                          uint64_t addr, uint64_t value)
 {
     void *ptr = elf_get_ptr(elf, addr);
     uint32_t *u32;
 
-    switch (type)
+    switch ( type )
     {
     case 1 /* R_386_32 */ :
-       u32 = ptr;
-       *u32 += elf->reloc_offset;
-       break;
+        u32 = ptr;
+        *u32 += elf->reloc_offset;
+        break;
     case 2 /* R_386_PC32 */ :
-       /* nothing */
-       break;
+        /* nothing */
+        break;
     default:
-       return -1;
+        return -1;
     }
     return 0;
 }
@@ -96,54 +96,57 @@ static const char *rel_names_x86_64[] = 
 };
 
 static int elf_reloc_x86_64(struct elf_binary *elf, int type,
-                           uint64_t addr, uint64_t value)
+                            uint64_t addr, uint64_t value)
 {
     void *ptr = elf_get_ptr(elf, addr);
     uint64_t *u64;
     uint32_t *u32;
     int32_t *s32;
 
-    switch (type)
+    switch ( type )
     {
     case 1 /* R_X86_64_64 */ :
-       u64 = ptr;
-       value += elf->reloc_offset;
-       *u64 = value;
-       break;
+        u64 = ptr;
+        value += elf->reloc_offset;
+        *u64 = value;
+        break;
     case 2 /* R_X86_64_PC32 */ :
-       u32 = ptr;
-       *u32 = value - addr;
-       if (*u32 != (uint32_t) (value - addr))
-       {
-           elf_err(elf, "R_X86_64_PC32 overflow: 0x%" PRIx32 " != 0x%" PRIx32 
"\n",
-                   *u32, (uint32_t) (value - addr));
-           return -1;
-       }
-       break;
+        u32 = ptr;
+        *u32 = value - addr;
+        if ( *u32 != (uint32_t)(value - addr) )
+        {
+            elf_err(elf, "R_X86_64_PC32 overflow: 0x%" PRIx32
+                    " != 0x%" PRIx32 "\n",
+                    *u32, (uint32_t) (value - addr));
+            return -1;
+        }
+        break;
     case 10 /* R_X86_64_32 */ :
-       u32 = ptr;
-       value += elf->reloc_offset;
-       *u32 = value;
-       if (*u32 != value)
-       {
-           elf_err(elf, "R_X86_64_32 overflow: 0x%" PRIx32 " != 0x%" PRIx64 
"\n",
-                   *u32, value);
-           return -1;
-       }
-       break;
+        u32 = ptr;
+        value += elf->reloc_offset;
+        *u32 = value;
+        if ( *u32 != value )
+        {
+            elf_err(elf, "R_X86_64_32 overflow: 0x%" PRIx32
+                    " != 0x%" PRIx64 "\n",
+                    *u32, value);
+            return -1;
+        }
+        break;
     case 11 /* R_X86_64_32S */ :
-       s32 = ptr;
-       value += elf->reloc_offset;
-       *s32 = value;
-       if (*s32 != (int64_t) value)
-       {
-           elf_err(elf, "R_X86_64_32S overflow: 0x%" PRIx32 " != 0x%" PRIx64 
"\n",
-                   *s32, (int64_t) value);
-           return -1;
-       }
-       break;
+        s32 = ptr;
+        value += elf->reloc_offset;
+        *s32 = value;
+        if ( *s32 != (int64_t) value )
+        {
+            elf_err(elf, "R_X86_64_32S overflow: 0x%" PRIx32
+                    " != 0x%" PRIx64 "\n",
+                    *s32, (int64_t) value);
+            return -1;
+        }
+        break;
     default:
-       return -1;
+        return -1;
     }
     return 0;
 }
@@ -154,19 +157,19 @@ static struct relocs {
     const char **names;
     int count;
     int (*func) (struct elf_binary * elf, int type, uint64_t addr,
-                uint64_t value);
+                 uint64_t value);
 } relocs[] =
 /* *INDENT-OFF* */
 {
     [EM_386] = {
-       .names = rel_names_i386,
-       .count = sizeof(rel_names_i386) / sizeof(rel_names_i386[0]),
-       .func = elf_reloc_i386,
+        .names = rel_names_i386,
+        .count = sizeof(rel_names_i386) / sizeof(rel_names_i386[0]),
+        .func = elf_reloc_i386,
     },
     [EM_X86_64] = {
-       .names = rel_names_x86_64,
-       .count = sizeof(rel_names_x86_64) / sizeof(rel_names_x86_64[0]),
-       .func = elf_reloc_x86_64,
+        .names = rel_names_x86_64,
+        .count = sizeof(rel_names_x86_64) / sizeof(rel_names_x86_64[0]),
+        .func = elf_reloc_x86_64,
     }
 };
 /* *INDENT-ON* */
@@ -175,18 +178,18 @@ static struct relocs {
 
 static const char *rela_name(int machine, int type)
 {
-    if (machine > sizeof(relocs) / sizeof(relocs[0]))
-       return "unknown mach";
-    if (!relocs[machine].names)
-       return "unknown mach";
-    if (type > relocs[machine].count)
-       return "unknown rela";
+    if ( machine > sizeof(relocs) / sizeof(relocs[0]) )
+        return "unknown mach";
+    if ( !relocs[machine].names )
+        return "unknown mach";
+    if ( type > relocs[machine].count )
+        return "unknown rela";
     return relocs[machine].names[type];
 }
 
 static int elf_reloc_section(struct elf_binary *elf,
-                            const elf_shdr * rels,
-                            const elf_shdr * sect, const elf_shdr * syms)
+                             const elf_shdr * rels,
+                             const elf_shdr * sect, const elf_shdr * syms)
 {
     const void *ptr, *end;
     const elf_shdr *shdr;
@@ -204,18 +207,18 @@ static int elf_reloc_section(struct elf_
     int machine;
 
     machine = elf_uval(elf, elf->ehdr, e_machine);
-    if (machine >= sizeof(relocs) / sizeof(relocs[0]) ||
-       NULL == relocs[machine].func)
-    {
-       elf_err(elf, "%s: can't handle machine %d\n",
-               __FUNCTION__, machine);
-       return -1;
-    }
-    if (elf_swap(elf))
-    {
-       elf_err(elf, "%s: non-native byte order, relocation not supported\n",
-               __FUNCTION__);
-       return -1;
+    if ( (machine >= (sizeof(relocs) / sizeof(relocs[0]))) ||
+         (relocs[machine].func == NULL) )
+    {
+        elf_err(elf, "%s: can't handle machine %d\n",
+                __FUNCTION__, machine);
+        return -1;
+    }
+    if ( elf_swap(elf) )
+    {
+        elf_err(elf, "%s: non-native byte order, relocation not supported\n",
+                __FUNCTION__);
+        return -1;
     }
 
     s_type = elf_uval(elf, rels, sh_type);
@@ -223,89 +226,89 @@ static int elf_reloc_section(struct elf_
     ptr = elf_section_start(elf, rels);
     end = elf_section_end(elf, rels);
 
-    for (; ptr < end; ptr += rsize)
-    {
-       switch (s_type)
-       {
-       case SHT_REL:
-           rel = ptr;
-           r_offset = elf_uval(elf, rel, r_offset);
-           r_info = elf_uval(elf, rel, r_info);
-           r_addend = 0;
-           break;
-       case SHT_RELA:
-           rela = ptr;
-           r_offset = elf_uval(elf, rela, r_offset);
-           r_info = elf_uval(elf, rela, r_info);
-           r_addend = elf_uval(elf, rela, r_addend);
-           break;
-       default:
-           /* can't happen */
-           return -1;
-       }
-       if (elf_64bit(elf))
-       {
-           r_type = ELF64_R_TYPE(r_info);
-           r_sym = ELF64_R_SYM(r_info);
-       }
-       else
-       {
-           r_type = ELF32_R_TYPE(r_info);
-           r_sym = ELF32_R_SYM(r_info);
-       }
-
-       sym = elf_sym_by_index(elf, r_sym);
-       shndx = elf_uval(elf, sym, st_shndx);
-       switch (shndx)
-       {
-       case SHN_UNDEF:
-           sname = "*UNDEF*";
-           sbase = 0;
-           break;
-       case SHN_COMMON:
-           elf_err(elf, "%s: invalid section: %" PRId64 "\n",
-                   __FUNCTION__, shndx);
-           return -1;
-       case SHN_ABS:
-           sname = "*ABS*";
-           sbase = 0;
-           break;
-       default:
-           shdr = elf_shdr_by_index(elf, shndx);
-           if (NULL == shdr)
-           {
-               elf_err(elf, "%s: invalid section: %" PRId64 "\n",
-                       __FUNCTION__, shndx);
-               return -1;
-           }
-           sname = elf_section_name(elf, shdr);
-           sbase = elf_uval(elf, shdr, sh_addr);
-       }
-
-       addr = r_offset;
-       value = elf_uval(elf, sym, st_value);
-       value += r_addend;
-
-       if (elf->log && elf->verbose > 1)
-       {
-           uint64_t st_name = elf_uval(elf, sym, st_name);
-           const char *name = st_name ? elf->sym_strtab + st_name : "*NONE*";
-
-           elf_msg(elf,
-                   "%s: type %s [%d], off 0x%" PRIx64 ", add 0x%" PRIx64 ","
-                   " sym %s [0x%" PRIx64 "], sec %s [0x%" PRIx64 "]"
-                   "  ->  addr 0x%" PRIx64 " value 0x%" PRIx64 "\n",
-                   __FUNCTION__, rela_name(machine, r_type), r_type, r_offset,
-                   r_addend, name, elf_uval(elf, sym, st_value), sname, sbase,
-                   addr, value);
-       }
-
-       if (-1 == relocs[machine].func(elf, r_type, addr, value))
-       {
-           elf_err(elf, "%s: unknown/unsupported reloc type %s [%d]\n",
-                   __FUNCTION__, rela_name(machine, r_type), r_type);
-           return -1;
-       }
+    for ( ; ptr < end; ptr += rsize )
+    {
+        switch ( s_type )
+        {
+        case SHT_REL:
+            rel = ptr;
+            r_offset = elf_uval(elf, rel, r_offset);
+            r_info = elf_uval(elf, rel, r_info);
+            r_addend = 0;
+            break;
+        case SHT_RELA:
+            rela = ptr;
+            r_offset = elf_uval(elf, rela, r_offset);
+            r_info = elf_uval(elf, rela, r_info);
+            r_addend = elf_uval(elf, rela, r_addend);
+            break;
+        default:
+            /* can't happen */
+            return -1;
+        }
+        if ( elf_64bit(elf) )
+        {
+            r_type = ELF64_R_TYPE(r_info);
+            r_sym = ELF64_R_SYM(r_info);
+        }
+        else
+        {
+            r_type = ELF32_R_TYPE(r_info);
+            r_sym = ELF32_R_SYM(r_info);
+        }
+
+        sym = elf_sym_by_index(elf, r_sym);
+        shndx = elf_uval(elf, sym, st_shndx);
+        switch ( shndx )
+        {
+        case SHN_UNDEF:
+            sname = "*UNDEF*";
+            sbase = 0;
+            break;
+        case SHN_COMMON:
+            elf_err(elf, "%s: invalid section: %" PRId64 "\n",
+                    __FUNCTION__, shndx);
+            return -1;
+        case SHN_ABS:
+            sname = "*ABS*";
+            sbase = 0;
+            break;
+        default:
+            shdr = elf_shdr_by_index(elf, shndx);
+            if ( shdr == NULL )
+            {
+                elf_err(elf, "%s: invalid section: %" PRId64 "\n",
+                        __FUNCTION__, shndx);
+                return -1;
+            }
+            sname = elf_section_name(elf, shdr);
+            sbase = elf_uval(elf, shdr, sh_addr);
+        }
+
+        addr = r_offset;
+        value = elf_uval(elf, sym, st_value);
+        value += r_addend;
+
+        if ( elf->log && (elf->verbose > 1) )
+        {
+            uint64_t st_name = elf_uval(elf, sym, st_name);
+            const char *name = st_name ? elf->sym_strtab + st_name : "*NONE*";
+
+            elf_msg(elf,
+                    "%s: type %s [%d], off 0x%" PRIx64 ", add 0x%" PRIx64 ","
+                    " sym %s [0x%" PRIx64 "], sec %s [0x%" PRIx64 "]"
+                    "  ->  addr 0x%" PRIx64 " value 0x%" PRIx64 "\n",
+                    __FUNCTION__, rela_name(machine, r_type), r_type, r_offset,
+                    r_addend, name, elf_uval(elf, sym, st_value), sname, sbase,
+                    addr, value);
+        }
+
+        if ( relocs[machine].func(elf, r_type, addr, value) == -1 )
+        {
+            elf_err(elf, "%s: unknown/unsupported reloc type %s [%d]\n",
+                    __FUNCTION__, rela_name(machine, r_type), r_type);
+            return -1;
+        }
     }
     return 0;
 }
@@ -316,30 +319,40 @@ int elf_reloc(struct elf_binary *elf)
     uint64_t i, count, type;
 
     count = elf_shdr_count(elf);
-    for (i = 0; i < count; i++)
-    {
-       rels = elf_shdr_by_index(elf, i);
-       type = elf_uval(elf, rels, sh_type);
-       if (type != SHT_REL && type != SHT_RELA)
-           continue;
-
-       sect = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_info));
-       syms = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_link));
-       if (NULL == sect || NULL == syms)
-           continue;
-
-       if (!(elf_uval(elf, sect, sh_flags) & SHF_ALLOC))
-       {
-           elf_msg(elf, "%s: relocations for %s, skipping\n",
-                   __FUNCTION__, elf_section_name(elf, sect));
-           continue;
-       }
-
-       elf_msg(elf, "%s: relocations for %s @ 0x%" PRIx64 "\n",
-               __FUNCTION__, elf_section_name(elf, sect),
-               elf_uval(elf, sect, sh_addr));
-       if (0 != elf_reloc_section(elf, rels, sect, syms))
-           return -1;
-    }
-    return 0;
-}
+    for ( i = 0; i < count; i++ )
+    {
+        rels = elf_shdr_by_index(elf, i);
+        type = elf_uval(elf, rels, sh_type);
+        if ( (type != SHT_REL) && (type != SHT_RELA) )
+            continue;
+
+        sect = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_info));
+        syms = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_link));
+        if ( NULL == sect || NULL == syms )
+            continue;
+
+        if ( !(elf_uval(elf, sect, sh_flags) & SHF_ALLOC) )
+        {
+            elf_msg(elf, "%s: relocations for %s, skipping\n",
+                    __FUNCTION__, elf_section_name(elf, sect));
+            continue;
+        }
+
+        elf_msg(elf, "%s: relocations for %s @ 0x%" PRIx64 "\n",
+                __FUNCTION__, elf_section_name(elf, sect),
+                elf_uval(elf, sect, sh_addr));
+        if ( elf_reloc_section(elf, rels, sect, syms) != 0 )
+            return -1;
+    }
+    return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r ac18d251df63 -r 9529d667d042 xen/common/libelf/libelf-tools.c
--- a/xen/common/libelf/libelf-tools.c  Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/common/libelf/libelf-tools.c  Thu Feb 15 14:09:39 2007 -0700
@@ -7,7 +7,7 @@
 /* ------------------------------------------------------------------------ */
 
 uint64_t elf_access_unsigned(struct elf_binary * elf, const void *ptr,
-                            uint64_t offset, size_t size)
+                             uint64_t offset, size_t size)
 {
     int need_swap = elf_swap(elf);
     const uint8_t *u8;
@@ -15,27 +15,27 @@ uint64_t elf_access_unsigned(struct elf_
     const uint32_t *u32;
     const uint64_t *u64;
 
-    switch (size)
-    {
-    case 1:
-       u8 = ptr + offset;
-       return *u8;
-    case 2:
-       u16 = ptr + offset;
-       return need_swap ? bswap_16(*u16) : *u16;
-    case 4:
-       u32 = ptr + offset;
-       return need_swap ? bswap_32(*u32) : *u32;
-    case 8:
-       u64 = ptr + offset;
-       return need_swap ? bswap_64(*u64) : *u64;
-    default:
-       return 0;
+    switch ( size )
+    {
+    case 1:
+        u8 = ptr + offset;
+        return *u8;
+    case 2:
+        u16 = ptr + offset;
+        return need_swap ? bswap_16(*u16) : *u16;
+    case 4:
+        u32 = ptr + offset;
+        return need_swap ? bswap_32(*u32) : *u32;
+    case 8:
+        u64 = ptr + offset;
+        return need_swap ? bswap_64(*u64) : *u64;
+    default:
+        return 0;
     }
 }
 
 int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
-                         uint64_t offset, size_t size)
+                          uint64_t offset, size_t size)
 {
     int need_swap = elf_swap(elf);
     const int8_t *s8;
@@ -43,22 +43,22 @@ int64_t elf_access_signed(struct elf_bin
     const int32_t *s32;
     const int64_t *s64;
 
-    switch (size)
-    {
-    case 1:
-       s8 = ptr + offset;
-       return *s8;
-    case 2:
-       s16 = ptr + offset;
-       return need_swap ? bswap_16(*s16) : *s16;
-    case 4:
-       s32 = ptr + offset;
-       return need_swap ? bswap_32(*s32) : *s32;
-    case 8:
-       s64 = ptr + offset;
-       return need_swap ? bswap_64(*s64) : *s64;
-    default:
-       return 0;
+    switch ( size )
+    {
+    case 1:
+        s8 = ptr + offset;
+        return *s8;
+    case 2:
+        s16 = ptr + offset;
+        return need_swap ? bswap_16(*s16) : *s16;
+    case 4:
+        s32 = ptr + offset;
+        return need_swap ? bswap_32(*s32) : *s32;
+    case 8:
+        s64 = ptr + offset;
+        return need_swap ? bswap_64(*s64) : *s64;
+    default:
+        return 0;
     }
 }
 
@@ -88,11 +88,12 @@ const elf_shdr *elf_shdr_by_name(struct 
     const char *sname;
     int i;
 
-    for (i = 0; i < count; i++) {
-       shdr = elf_shdr_by_index(elf, i);
-       sname = elf_section_name(elf, shdr);
-       if (sname && 0 == strcmp(sname, name))
-           return shdr;
+    for ( i = 0; i < count; i++ )
+    {
+        shdr = elf_shdr_by_index(elf, i);
+        sname = elf_section_name(elf, shdr);
+        if ( sname && !strcmp(sname, name) )
+            return shdr;
     }
     return NULL;
 }
@@ -100,31 +101,35 @@ const elf_shdr *elf_shdr_by_index(struct
 const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index)
 {
     uint64_t count = elf_shdr_count(elf);
-    const void *ptr = NULL;
-
-    if (index < count)
-       ptr = elf->image
-           + elf_uval(elf, elf->ehdr, e_shoff)
-           + elf_uval(elf, elf->ehdr, e_shentsize) * index;
+    const void *ptr;
+
+    if ( index >= count )
+        return NULL;
+
+    ptr = (elf->image
+           + elf_uval(elf, elf->ehdr, e_shoff)
+           + elf_uval(elf, elf->ehdr, e_shentsize) * index);
     return ptr;
 }
 
 const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index)
 {
     uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
-    const void *ptr = NULL;
-
-    if (index < count)
-       ptr = elf->image
-           + elf_uval(elf, elf->ehdr, e_phoff)
-           + elf_uval(elf, elf->ehdr, e_phentsize) * index;
+    const void *ptr;
+
+    if ( index >= count )
+        return NULL;
+
+    ptr = (elf->image
+           + elf_uval(elf, elf->ehdr, e_phoff)
+           + elf_uval(elf, elf->ehdr, e_phentsize) * index);
     return ptr;
 }
 
 const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr)
 {
-    if (NULL == elf->sec_strtab)
-       return "unknown";
+    if ( elf->sec_strtab == NULL )
+        return "unknown";
     return elf->sec_strtab + elf_uval(elf, shdr, sh_name);
 }
 
@@ -136,7 +141,7 @@ const void *elf_section_end(struct elf_b
 const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr)
 {
     return elf->image
-       + elf_uval(elf, shdr, sh_offset) + elf_uval(elf, shdr, sh_size);
+        + elf_uval(elf, shdr, sh_offset) + elf_uval(elf, shdr, sh_size);
 }
 
 const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol)
@@ -146,16 +151,16 @@ const elf_sym *elf_sym_by_name(struct el
     const elf_sym *sym;
     uint64_t info, name;
 
-    for (; ptr < end; ptr += elf_size(elf, sym))
-    {
-       sym = ptr;
-       info = elf_uval(elf, sym, st_info);
-       name = elf_uval(elf, sym, st_name);
-       if (ELF32_ST_BIND(info) != STB_GLOBAL)
-           continue;
-       if (strcmp(elf->sym_strtab + name, symbol) != 0)
-           continue;
-       return sym;
+    for ( ; ptr < end; ptr += elf_size(elf, sym) )
+    {
+        sym = ptr;
+        info = elf_uval(elf, sym, st_info);
+        name = elf_uval(elf, sym, st_name);
+        if ( ELF32_ST_BIND(info) != STB_GLOBAL )
+            continue;
+        if ( strcmp(elf->sym_strtab + name, symbol) )
+            continue;
+        return sym;
     }
     return NULL;
 }
@@ -192,9 +197,9 @@ uint64_t elf_note_numeric(struct elf_bin
     case 2:
     case 4:
     case 8:
-       return elf_access_unsigned(elf, desc, 0, descsz);
-    default:
-       return 0;
+        return elf_access_unsigned(elf, desc, 0, descsz);
+    default:
+        return 0;
     }
 }
 const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note)
@@ -211,9 +216,7 @@ int elf_is_elfbinary(const void *image)
 {
     const Elf32_Ehdr *ehdr = image;
 
-    if (IS_ELF(*ehdr))
-       return 1;
-    return 0;
+    return IS_ELF(*ehdr);
 }
 
 int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr)
@@ -223,3 +226,13 @@ int elf_phdr_is_loadable(struct elf_bina
 
     return ((p_type == PT_LOAD) && (p_flags & (PF_W | PF_X)) != 0);
 }
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r ac18d251df63 -r 9529d667d042 xen/include/asm-powerpc/config.h
--- a/xen/include/asm-powerpc/config.h  Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/include/asm-powerpc/config.h  Thu Feb 15 14:09:39 2007 -0700
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright IBM Corp. 2005, 2006, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
@@ -34,9 +34,6 @@
 
 #define U(x) (x ## U)
 #define UL(x) (x ## UL)
-extern char _start[];
-extern char _end[];
-extern char _etext[];
 extern char __bss_start[];
 #endif
 
diff -r ac18d251df63 -r 9529d667d042 xen/include/asm-powerpc/domain.h
--- a/xen/include/asm-powerpc/domain.h  Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/include/asm-powerpc/domain.h  Thu Feb 15 14:09:39 2007 -0700
@@ -107,13 +107,6 @@ extern void save_float(struct vcpu *);
 extern void save_float(struct vcpu *);
 extern void load_float(struct vcpu *);
 
-#define RMA_SHARED_INFO 1
-#define RMA_START_INFO 2
-#define RMA_LAST_DOM0 2
-/* these are not used for dom0 so they should be last */
-#define RMA_CONSOLE 3
-#define RMA_LAST_DOMU 3
-
 #define rma_size(rma_order) (1UL << ((rma_order) + PAGE_SHIFT))
 
 static inline ulong rma_addr(struct arch_domain *ad, int type)
diff -r ac18d251df63 -r 9529d667d042 xen/include/asm-powerpc/init.h
--- a/xen/include/asm-powerpc/init.h    Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/include/asm-powerpc/init.h    Thu Feb 15 14:09:39 2007 -0700
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2006
+ * Copyright IBM Corp. 2006, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
@@ -27,14 +27,14 @@ typedef struct {
 typedef struct {
     unsigned long number;
     hcall_handler_t handler;
-} inithcall_t;
-extern inithcall_t __inithcall_start, __inithcall_end;
+} init_hcall_t;
+extern init_hcall_t __init_hcall_start, __init_hcall_end;
 
 #define __init_papr_hcall(nr, fn) \
-    static inithcall_t __inithcall_##fn __init_hcall \
+    static init_hcall_t __init_hcall_##fn __init_hcall \
     = { .number = nr, .handler = fn }
 
 #define __init_hcall  \
-    __attribute_used__ __attribute__ ((__section__ (".inithcall.text")))
+    __attribute_used__ __attribute__ ((__section__ (".init_hcall.init")))
 
 #endif /* _XEN_ASM_INIT_H */
diff -r ac18d251df63 -r 9529d667d042 xen/include/asm-powerpc/mm.h
--- a/xen/include/asm-powerpc/mm.h      Thu Feb 15 13:13:36 2007 -0700
+++ b/xen/include/asm-powerpc/mm.h      Thu Feb 15 14:09:39 2007 -0700
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005, 2006
+ * Copyright IBM Corp. 2005, 2006, 2007
  *

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