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: Thu, 26 Oct 2006 12:10:28 +0000
Delivery-date: Thu, 26 Oct 2006 05:12:22 -0700
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@xxxxxxxxxxx
# Node ID 2bfd19fc1b79c6a6712c99f875f1fbf883af3f35
# Parent  914c44d10c8d1dc0fd279f6aa1f9ab7d8a65cfcb
# Parent  02311d8aba867e2107cdc0c6448c55556def97ad
merge with xen-unstable.hg
---
 tools/debugger/pdb/Domain.ml                           |   61 
 tools/debugger/pdb/Domain.mli                          |   39 
 tools/debugger/pdb/Intel.ml                            |   66 
 tools/debugger/pdb/Makefile                            |   57 
 tools/debugger/pdb/OCamlMakefile                       | 1149 -----------------
 tools/debugger/pdb/PDB.ml                              |  342 -----
 tools/debugger/pdb/Process.ml                          |   79 -
 tools/debugger/pdb/Process.mli                         |   41 
 tools/debugger/pdb/Util.ml                             |  165 --
 tools/debugger/pdb/Xen_domain.ml                       |   43 
 tools/debugger/pdb/Xen_domain.mli                      |   25 
 tools/debugger/pdb/debugger.ml                         |  372 -----
 tools/debugger/pdb/evtchn.ml                           |   40 
 tools/debugger/pdb/evtchn.mli                          |   19 
 tools/debugger/pdb/linux-2.6-module/Makefile           |   21 
 tools/debugger/pdb/linux-2.6-module/debug.c            |  851 ------------
 tools/debugger/pdb/linux-2.6-module/module.c           |  337 ----
 tools/debugger/pdb/linux-2.6-module/pdb_debug.h        |   47 
 tools/debugger/pdb/linux-2.6-module/pdb_module.h       |  142 --
 tools/debugger/pdb/linux-2.6-patches/Makefile          |   11 
 tools/debugger/pdb/linux-2.6-patches/i386_ksyms.patch  |   18 
 tools/debugger/pdb/linux-2.6-patches/kdebug.patch      |   10 
 tools/debugger/pdb/linux-2.6-patches/makefile.patch    |   10 
 tools/debugger/pdb/linux-2.6-patches/ptrace.patch      |   10 
 tools/debugger/pdb/linux-2.6-patches/traps.patch       |   19 
 tools/debugger/pdb/pdb_caml_domain.c                   |  527 -------
 tools/debugger/pdb/pdb_caml_evtchn.c                   |  186 --
 tools/debugger/pdb/pdb_caml_process.c                  |  587 --------
 tools/debugger/pdb/pdb_caml_xc.c                       |  170 --
 tools/debugger/pdb/pdb_caml_xcs.c                      |  307 ----
 tools/debugger/pdb/pdb_caml_xen.h                      |   39 
 tools/debugger/pdb/pdb_xen.c                           |   75 -
 tools/debugger/pdb/readme                              |   96 -
 tools/debugger/pdb/server.ml                           |  241 ---
 tools/debugger/pdb/xcs.ml                              |   85 -
 tools/debugger/pdb/xcs.mli                             |   13 
 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c   |   10 
 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c       |  260 +--
 linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c       |    1 
 linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c       |    3 
 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c    |   64 
 linux-2.6-xen-sparse/drivers/xen/netback/netback.c     |    2 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c |   14 
 linux-2.6-xen-sparse/include/xen/public/evtchn.h       |    3 
 tools/blktap/drivers/Makefile                          |    2 
 tools/blktap/drivers/blktapctrl.c                      |   22 
 tools/blktap/drivers/tapdisk.c                         |    9 
 tools/blktap/lib/blktaplib.h                           |    3 
 tools/examples/init.d/xendomains                       |    8 
 tools/examples/xen-backend.rules                       |    1 
 tools/firmware/vmxassist/vm86.c                        |   34 
 tools/ioemu/target-i386-dm/helper2.c                   |    4 
 tools/libxc/xc_linux.c                                 |   82 +
 tools/libxc/xenctrl.h                                  |   10 
 tools/pygrub/src/pygrub                                |   20 
 tools/python/xen/util/blkif.py                         |    2 
 tools/python/xen/xend/image.py                         |    3 
 tools/python/xen/xm/addlabel.py                        |   72 -
 tools/python/xen/xm/cfgbootpolicy.py                   |   73 -
 tools/python/xen/xm/create.py                          |    2 
 tools/python/xen/xm/dry-run.py                         |   41 
 tools/python/xen/xm/dumppolicy.py                      |   20 
 tools/python/xen/xm/getlabel.py                        |   29 
 tools/python/xen/xm/loadpolicy.py                      |   17 
 tools/python/xen/xm/main.py                            |   30 
 tools/python/xen/xm/makepolicy.py                      |   15 
 tools/python/xen/xm/resources.py                       |   21 
 tools/python/xen/xm/rmlabel.py                         |   31 
 tools/xm-test/tests/vtpm/vtpm_utils.py                 |    6 
 xen/arch/ia64/Makefile                                 |   15 
 xen/arch/powerpc/Makefile                              |    3 
 xen/arch/x86/Makefile                                  |   13 
 xen/arch/x86/domain.c                                  |   11 
 xen/arch/x86/hvm/hvm.c                                 |   88 -
 xen/arch/x86/hvm/i8259.c                               |   66 
 xen/arch/x86/hvm/instrlen.c                            |   72 -
 xen/arch/x86/hvm/intercept.c                           |   16 
 xen/arch/x86/hvm/io.c                                  |    7 
 xen/arch/x86/hvm/platform.c                            |   14 
 xen/arch/x86/hvm/svm/emulate.c                         |    6 
 xen/arch/x86/hvm/svm/intr.c                            |   21 
 xen/arch/x86/hvm/svm/svm.c                             |  198 +-
 xen/arch/x86/hvm/svm/x86_32/exits.S                    |    3 
 xen/arch/x86/hvm/svm/x86_64/exits.S                    |    1 
 xen/arch/x86/hvm/vioapic.c                             |   22 
 xen/arch/x86/hvm/vmx/io.c                              |   14 
 xen/arch/x86/hvm/vmx/vmx.c                             |  131 +
 xen/arch/x86/hvm/vmx/x86_32/exits.S                    |    3 
 xen/arch/x86/hvm/vmx/x86_64/exits.S                    |    1 
 xen/arch/x86/mm.c                                      |  206 +--
 xen/arch/x86/mm/shadow/common.c                        |  165 +-
 xen/arch/x86/mm/shadow/multi.c                         |  433 ++++--
 xen/arch/x86/mm/shadow/multi.h                         |    7 
 xen/arch/x86/mm/shadow/private.h                       |   49 
 xen/arch/x86/mm/shadow/types.h                         |   31 
 xen/arch/x86/smp.c                                     |    2 
 xen/arch/x86/traps.c                                   |    2 
 xen/arch/x86/x86_32/entry.S                            |   18 
 xen/arch/x86/x86_emulate.c                             |   37 
 xen/common/gdbstub.c                                   |   30 
 xen/common/symbols-dummy.c                             |   16 
 xen/common/symbols.c                                   |   13 
 xen/include/asm-x86/debugger.h                         |   43 
 xen/include/asm-x86/domain.h                           |    2 
 xen/include/asm-x86/guest_access.h                     |   20 
 xen/include/asm-x86/hvm/io.h                           |    1 
 xen/include/asm-x86/hvm/support.h                      |   22 
 xen/include/asm-x86/hvm/vioapic.h                      |    2 
 xen/include/asm-x86/hvm/vpic.h                         |    8 
 xen/include/asm-x86/mm.h                               |    2 
 xen/include/asm-x86/shadow.h                           |   87 +
 111 files changed, 1630 insertions(+), 7485 deletions(-)

diff -r 914c44d10c8d -r 2bfd19fc1b79 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Sun Oct 01 
11:39:41 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Sun Oct 01 
19:10:18 2006 -0600
@@ -273,7 +273,7 @@ static void backend_changed(struct xenbu
                        xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
 
                down(&bd->bd_sem);
-               if (info->users > 0 && system_state == SYSTEM_RUNNING)
+               if (info->users > 0)
                        xenbus_dev_error(dev, -EBUSY,
                                         "Device in use; refusing to close");
                else
@@ -355,8 +355,10 @@ static void blkfront_closing(struct xenb
        blk_stop_queue(info->rq);
        /* No more gnttab callback work. */
        gnttab_cancel_free_callback(&info->callback);
+       spin_unlock_irqrestore(&blkif_io_lock, flags);
+
+       /* Flush gnttab callback work. Must be done with no locks held. */
        flush_scheduled_work();
-       spin_unlock_irqrestore(&blkif_io_lock, flags);
 
        xlvbd_del(info);
 
@@ -714,8 +716,10 @@ static void blkif_free(struct blkfront_i
                blk_stop_queue(info->rq);
        /* No more gnttab callback work. */
        gnttab_cancel_free_callback(&info->callback);
+       spin_unlock_irq(&blkif_io_lock);
+
+       /* Flush gnttab callback work. Must be done with no locks held. */
        flush_scheduled_work();
-       spin_unlock_irq(&blkif_io_lock);
 
        /* Free resources associated with old device channel. */
        if (info->ring_ref != GRANT_INVALID_REF) {
diff -r 914c44d10c8d -r 2bfd19fc1b79 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Sun Oct 01 11:39:41 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Sun Oct 01 19:10:18 
2006 -0600
@@ -44,7 +44,6 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
-#include <linux/miscdevice.h>
 #include <linux/errno.h>
 #include <linux/major.h>
 #include <linux/gfp.h>
@@ -54,6 +53,30 @@
 
 #define MAX_TAP_DEV 100     /*the maximum number of tapdisk ring devices    */
 #define MAX_DEV_NAME 100    /*the max tapdisk ring device name e.g. blktap0 */
+
+
+struct class *xen_class;
+EXPORT_SYMBOL_GPL(xen_class);
+
+/*
+ * Setup the xen class.  This should probably go in another file, but
+ * since blktap is the only user of it so far, it gets to keep it.
+ */
+int setup_xen_class(void)
+{
+       int ret;
+
+       if (xen_class)
+               return 0;
+
+       xen_class = class_create(THIS_MODULE, "xen");
+       if ((ret = IS_ERR(xen_class))) {
+               xen_class = NULL;
+               return ret;
+       }
+
+       return 0;
+}
 
 /*
  * The maximum number of requests that can be outstanding at any time
@@ -100,19 +123,14 @@ typedef struct tap_blkif {
        unsigned long *idx_map;       /*Record the user ring id to kern 
                                        [req id, idx] tuple                  */
        blkif_t *blkif;               /*Associate blkif with tapdev          */
+       int sysfs_set;                /*Set if it has a class device.        */
 } tap_blkif_t;
-
-/*Private data struct associated with the inode*/
-typedef struct private_info {
-       int idx;
-} private_info_t;
 
 /*Data struct handed back to userspace for tapdisk device to VBD mapping*/
 typedef struct domid_translate {
        unsigned short domid;
        unsigned short busid;
 } domid_translate_t ;
-
 
 static domid_translate_t  translate_domid[MAX_TAP_DEV];
 static tap_blkif_t *tapfds[MAX_TAP_DEV];
@@ -200,14 +218,12 @@ static struct grant_handle_pair
     + (_i)])
 
 
-static int blktap_read_ufe_ring(int idx); /*local prototypes*/
-
-#define BLKTAP_MINOR 0  /*/dev/xen/blktap resides at device number
-                         major=254, minor numbers begin at 0            */ 
-#define BLKTAP_DEV_MAJOR 254         /* TODO: Make major number dynamic  *
-                                      * and create devices in the kernel *
-                                     */
+static int blktap_read_ufe_ring(tap_blkif_t *info); /*local prototypes*/
+
+#define BLKTAP_MINOR 0  /*/dev/xen/blktap has a dynamic major */
 #define BLKTAP_DEV_DIR  "/dev/xen"
+
+static int blktap_major;
 
 /* blktap IOCTLs: */
 #define BLKTAP_IOCTL_KICK_FE         1
@@ -264,7 +280,8 @@ static inline int GET_NEXT_REQ(unsigned 
 {
        int i;
        for (i = 0; i < MAX_PENDING_REQS; i++)
-               if (idx_map[i] == INVALID_REQ) return i;
+               if (idx_map[i] == INVALID_REQ)
+                       return i;
 
        return INVALID_REQ;
 }
@@ -311,8 +328,6 @@ static int blktap_ioctl(struct inode *in
                         unsigned int cmd, unsigned long arg);
 static unsigned int blktap_poll(struct file *file, poll_table *wait);
 
-struct miscdevice *set_misc(int minor, char *name, int dev);
-
 static struct file_operations blktap_fops = {
        .owner   = THIS_MODULE,
        .poll    = blktap_poll,
@@ -344,6 +359,16 @@ static int get_next_free_dev(void)
        
 done:
        spin_unlock_irqrestore(&pending_free_lock, flags);
+
+       /*
+        * We are protected by having the dev_pending set.
+        */
+       if (!tapfds[i]->sysfs_set && xen_class) {
+               class_device_create(xen_class, NULL,
+                                   MKDEV(blktap_major, ret), NULL,
+                                   "blktap%d", ret);
+               tapfds[i]->sysfs_set = 1;
+       }
        return ret;
 }
 
@@ -369,9 +394,8 @@ void signal_tapdisk(int idx)
        info = tapfds[idx];
        if ( (idx > 0) && (idx < MAX_TAP_DEV) && (info->pid > 0) ) {
                ptask = find_task_by_pid(info->pid);
-               if (ptask) { 
+               if (ptask)
                        info->status = CLEANSHUTDOWN;
-               }
        }
        info->blkif = NULL;
        return;
@@ -382,7 +406,6 @@ static int blktap_open(struct inode *ino
        blkif_sring_t *sring;
        int idx = iminor(inode) - BLKTAP_MINOR;
        tap_blkif_t *info;
-       private_info_t *prv;
        int i;
        
        if (tapfds[idx] == NULL) {
@@ -410,9 +433,7 @@ static int blktap_open(struct inode *ino
        SHARED_RING_INIT(sring);
        FRONT_RING_INIT(&info->ufe_ring, sring, PAGE_SIZE);
        
-       prv = kzalloc(sizeof(private_info_t),GFP_KERNEL);
-       prv->idx = idx;
-       filp->private_data = prv;
+       filp->private_data = info;
        info->vma = NULL;
 
        info->idx_map = kmalloc(sizeof(unsigned long) * MAX_PENDING_REQS, 
@@ -433,17 +454,16 @@ static int blktap_open(struct inode *ino
 
 static int blktap_release(struct inode *inode, struct file *filp)
 {
-       int idx = iminor(inode) - BLKTAP_MINOR;
-       tap_blkif_t *info;
-       
-       if (tapfds[idx] == NULL) {
+       tap_blkif_t *info = filp->private_data;
+       
+       /* can this ever happen? - sdr */
+       if (!info) {
                WPRINTK("Trying to free device that doesn't exist "
-                      "[/dev/xen/blktap%d]\n",idx);
-               return -1;
-       }
-       info = tapfds[idx];
+                      "[/dev/xen/blktap%d]\n",iminor(inode) - BLKTAP_MINOR);
+               return -EBADF;
+       }
        info->dev_inuse = 0;
-       DPRINTK("Freeing device [/dev/xen/blktap%d]\n",idx);
+       DPRINTK("Freeing device [/dev/xen/blktap%d]\n",info->minor);
 
        /* Free the ring page. */
        ClearPageReserved(virt_to_page(info->ufe_ring.sring));
@@ -457,8 +477,6 @@ static int blktap_release(struct inode *
                info->vma = NULL;
        }
        
-       if (filp->private_data) kfree(filp->private_data);
-
        if ( (info->status != CLEANSHUTDOWN) && (info->blkif != NULL) ) {
                kthread_stop(info->blkif->xenblkd);
                info->blkif->xenblkd = NULL;
@@ -491,16 +509,12 @@ static int blktap_mmap(struct file *filp
        int size;
        struct page **map;
        int i;
-       private_info_t *prv;
-       tap_blkif_t *info;
-
-       /*Retrieve the dev info*/
-       prv = (private_info_t *)filp->private_data;
-       if (prv == NULL) {
+       tap_blkif_t *info = filp->private_data;
+
+       if (info == NULL) {
                WPRINTK("blktap: mmap, retrieving idx failed\n");
                return -ENOMEM;
        }
-       info = tapfds[prv->idx];
        
        vma->vm_flags |= VM_RESERVED;
        vma->vm_ops = &blktap_vm_ops;
@@ -556,20 +570,17 @@ static int blktap_ioctl(struct inode *in
 static int blktap_ioctl(struct inode *inode, struct file *filp,
                         unsigned int cmd, unsigned long arg)
 {
-       int idx = iminor(inode) - BLKTAP_MINOR;
+       tap_blkif_t *info = filp->private_data;
+
        switch(cmd) {
        case BLKTAP_IOCTL_KICK_FE: 
        {
                /* There are fe messages to process. */
-               return blktap_read_ufe_ring(idx);
+               return blktap_read_ufe_ring(info);
        }
        case BLKTAP_IOCTL_SETMODE:
        {
-               tap_blkif_t *info = tapfds[idx];
-               
-               if ( (idx > 0) && (idx < MAX_TAP_DEV) 
-                    && (tapfds[idx] != NULL) ) 
-               {
+               if (info) {
                        if (BLKTAP_MODE_VALID(arg)) {
                                info->mode = arg;
                                /* XXX: may need to flush rings here. */
@@ -582,11 +593,7 @@ static int blktap_ioctl(struct inode *in
        }
        case BLKTAP_IOCTL_PRINT_IDXS:
         {
-               tap_blkif_t *info = tapfds[idx];
-               
-               if ( (idx > 0) && (idx < MAX_TAP_DEV) 
-                    && (tapfds[idx] != NULL) ) 
-               {
+               if (info) {
                        printk("User Rings: \n-----------\n");
                        printk("UF: rsp_cons: %2d, req_prod_prv: %2d "
                                "| req_prod: %2d, rsp_prod: %2d\n",
@@ -599,11 +606,7 @@ static int blktap_ioctl(struct inode *in
         }
        case BLKTAP_IOCTL_SENDPID:
        {
-               tap_blkif_t *info = tapfds[idx];
-               
-               if ( (idx > 0) && (idx < MAX_TAP_DEV) 
-                    && (tapfds[idx] != NULL) ) 
-               {
+               if (info) {
                        info->pid = (pid_t)arg;
                        DPRINTK("blktap: pid received %d\n", 
                               info->pid);
@@ -631,26 +634,38 @@ static int blktap_ioctl(struct inode *in
        case BLKTAP_IOCTL_FREEINTF:
        {
                unsigned long dev = arg;
-               tap_blkif_t *info = NULL;
-
-               if ( (dev > 0) && (dev < MAX_TAP_DEV) ) info = tapfds[dev];
-
+               unsigned long flags;
+
+               /* Looking at another device */
+               info = NULL;
+
+               if ( (dev > 0) && (dev < MAX_TAP_DEV) )
+                       info = tapfds[dev];
+
+               spin_lock_irqsave(&pending_free_lock, flags);
                if ( (info != NULL) && (info->dev_pending) )
                        info->dev_pending = 0;
+               spin_unlock_irqrestore(&pending_free_lock, flags);
+
                return 0;
        }
        case BLKTAP_IOCTL_MINOR:
        {
                unsigned long dev = arg;
-               tap_blkif_t *info = NULL;
+
+               /* Looking at another device */
+               info = NULL;
                
-               if ( (dev > 0) && (dev < MAX_TAP_DEV) ) info = tapfds[dev];
+               if ( (dev > 0) && (dev < MAX_TAP_DEV) )
+                       info = tapfds[dev];
                
-               if (info != NULL) return info->minor;
-               else return -1;
+               if (info != NULL)
+                       return info->minor;
+               else
+                       return -1;
        }
        case BLKTAP_IOCTL_MAJOR:
-               return BLKTAP_DEV_MAJOR;
+               return blktap_major;
 
        case BLKTAP_QUERY_ALLOC_REQS:
        {
@@ -662,25 +677,21 @@ static int blktap_ioctl(struct inode *in
        return -ENOIOCTLCMD;
 }
 
-static unsigned int blktap_poll(struct file *file, poll_table *wait)
-{
-       private_info_t *prv;
-       tap_blkif_t *info;
-       
-       /*Retrieve the dev info*/
-       prv = (private_info_t *)file->private_data;
-       if (prv == NULL) {
+static unsigned int blktap_poll(struct file *filp, poll_table *wait)
+{
+       tap_blkif_t *info = filp->private_data;
+       
+       if (!info) {
                WPRINTK(" poll, retrieving idx failed\n");
                return 0;
        }
-       
-       if (prv->idx == 0) return 0;
-       
-       info = tapfds[prv->idx];
-       
-       poll_wait(file, &info->wait, wait);
+
+       /* do not work on the control device */
+       if (!info->minor)
+               return 0;
+
+       poll_wait(filp, &info->wait, wait);
        if (info->ufe_ring.req_prod_pvt != info->ufe_ring.sring->req_prod) {
-               flush_tlb_all();
                RING_PUSH_REQUESTS(&info->ufe_ring);
                return POLLIN | POLLRDNORM;
        }
@@ -691,11 +702,14 @@ void blktap_kick_user(int idx)
 {
        tap_blkif_t *info;
 
-       if (idx == 0) return;
+       if (idx == 0)
+               return;
        
        info = tapfds[idx];
        
-       if (info != NULL) wake_up_interruptible(&info->wait);
+       if (info != NULL)
+               wake_up_interruptible(&info->wait);
+
        return;
 }
 
@@ -713,10 +727,7 @@ static int req_increase(void)
 {
        int i, j;
        struct page *page;
-       unsigned long flags;
        int ret;
-
-       spin_lock_irqsave(&pending_free_lock, flags);
 
        ret = -EINVAL;
        if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) 
@@ -782,8 +793,7 @@ static int req_increase(void)
 
        mmap_alloc++;
        DPRINTK("# MMAPs increased to %d\n",mmap_alloc);
- done:
-       spin_unlock_irqrestore(&pending_free_lock, flags);
+done:
        return ret;
 }
 
@@ -811,36 +821,6 @@ static void mmap_req_del(int mmap)
        mmap_lock = 0;
        DPRINTK("# MMAPs decreased to %d\n",mmap_alloc);
        mmap_alloc--;
-}
-
-/*N.B. Currently unused - will be accessed via sysfs*/
-static void req_decrease(void)
-{
-       pending_req_t *req;
-       int i;
-       unsigned long flags;
-
-       spin_lock_irqsave(&pending_free_lock, flags);
-
-       DPRINTK("Req decrease called.\n");
-       if (mmap_lock || mmap_alloc == 1) 
-               goto done;
-
-       mmap_lock = 1;
-       mmap_inuse = MAX_PENDING_REQS;
-       
-        /*Go through reqs and remove any that aren't in use*/
-       for (i = 0; i < MAX_PENDING_REQS ; i++) {
-               req = &pending_reqs[mmap_alloc-1][i];
-               if (req->inuse == 0) {
-                       list_del(&req->free_list);
-                       mmap_inuse--;
-               }
-       }
-       if (mmap_inuse == 0) mmap_req_del(mmap_alloc-1);
- done:
-       spin_unlock_irqrestore(&pending_free_lock, flags);
-       return;
 }
 
 static pending_req_t* alloc_req(void)
@@ -1002,7 +982,7 @@ int tap_blkif_schedule(void *arg)
  * COMPLETION CALLBACK -- Called by user level ioctl()
  */
 
-static int blktap_read_ufe_ring(int idx)
+static int blktap_read_ufe_ring(tap_blkif_t *info)
 {
        /* This is called to read responses from the UFE ring. */
        RING_IDX i, j, rp;
@@ -1010,12 +990,9 @@ static int blktap_read_ufe_ring(int idx)
        blkif_t *blkif=NULL;
        int pending_idx, usr_idx, mmap_idx;
        pending_req_t *pending_req;
-       tap_blkif_t *info;
-       
-       info = tapfds[idx];
-       if (info == NULL) {
+       
+       if (!info)
                return 0;
-       }
 
        /* We currently only forward packets in INTERCEPT_FE mode. */
        if (!(info->mode & BLKTAP_MODE_INTERCEPT_FE))
@@ -1063,7 +1040,7 @@ static int blktap_read_ufe_ring(int idx)
                                >> PAGE_SHIFT;
                        map[offset] = NULL;
                }
-               fast_flush_area(pending_req, pending_idx, usr_idx, idx);
+               fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
                make_response(blkif, pending_req->id, resp->operation,
                              resp->status);
                info->idx_map[usr_idx] = INVALID_REQ;
@@ -1416,7 +1393,8 @@ static int __init blkif_init(void)
        /*Create the blktap devices, but do not map memory or waitqueue*/
        for(i = 0; i < MAX_TAP_DEV; i++) translate_domid[i].domid = 0xFFFF;
 
-       ret = register_chrdev(BLKTAP_DEV_MAJOR,"blktap",&blktap_fops);
+       /* Dynamically allocate a major for this device */
+       ret = register_chrdev(0, "blktap", &blktap_fops);
        blktap_dir = devfs_mk_dir(NULL, "xen", 0, NULL);
 
        if ( (ret < 0)||(blktap_dir < 0) ) {
@@ -1424,22 +1402,44 @@ static int __init blkif_init(void)
                return -ENOMEM;
        }       
        
+       blktap_major = ret;
+
        for(i = 0; i < MAX_TAP_DEV; i++ ) {
                info = tapfds[i] = kzalloc(sizeof(tap_blkif_t),GFP_KERNEL);
-               if(tapfds[i] == NULL) return -ENOMEM;
+               if(tapfds[i] == NULL)
+                       return -ENOMEM;
                info->minor = i;
                info->pid = 0;
                info->blkif = NULL;
 
-               ret = devfs_mk_cdev(MKDEV(BLKTAP_DEV_MAJOR, i),
+               ret = devfs_mk_cdev(MKDEV(blktap_major, i),
                        S_IFCHR|S_IRUGO|S_IWUSR, "xen/blktap%d", i);
 
-               if(ret != 0) return -ENOMEM;
+               if(ret != 0)
+                       return -ENOMEM;
                info->dev_pending = info->dev_inuse = 0;
 
                DPRINTK("Created misc_dev [/dev/xen/blktap%d]\n",i);
        }
        
+       /* Make sure the xen class exists */
+       if (!setup_xen_class()) {
+               /*
+                * This will allow udev to create the blktap ctrl device.
+                * We only want to create blktap0 first.  We don't want
+                * to flood the sysfs system with needless blktap devices.
+                * We only create the device when a request of a new device is
+                * made.
+                */
+               class_device_create(xen_class, NULL,
+                                   MKDEV(blktap_major, 0), NULL,
+                                   "blktap0");
+               tapfds[0]->sysfs_set = 1;
+       } else {
+               /* this is bad, but not fatal */
+               WPRINTK("blktap: sysfs xen_class not created\n");
+       }
+
        DPRINTK("Blktap device successfully created\n");
 
        return 0;
diff -r 914c44d10c8d -r 2bfd19fc1b79 
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c  Sun Oct 01 11:39:41 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c  Sun Oct 01 19:10:18 
2006 -0600
@@ -273,7 +273,6 @@ static void tap_frontend_changed(struct 
                        kthread_stop(be->blkif->xenblkd);
                        be->blkif->xenblkd = NULL;
                }
-               tap_blkif_unmap(be->blkif);
                xenbus_switch_state(dev, XenbusStateClosing);
                break;
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Sun Oct 01 11:39:41 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Sun Oct 01 19:10:18 
2006 -0600
@@ -419,10 +419,9 @@ static struct file_operations evtchn_fop
 };
 
 static struct miscdevice evtchn_miscdev = {
-       .minor        = EVTCHN_MINOR,
+       .minor        = MISC_DYNAMIC_MINOR,
        .name         = "evtchn",
        .fops         = &evtchn_fops,
-       .devfs_name   = "misc/evtchn",
 };
 
 static int __init evtchn_init(void)
diff -r 914c44d10c8d -r 2bfd19fc1b79 
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Sun Oct 01 
11:39:41 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Sun Oct 01 
19:10:18 2006 -0600
@@ -53,8 +53,10 @@
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
 #include <net/dst.h>
-
-static int nloopbacks = 8;
+#include <net/xfrm.h>          /* secpath_reset() */
+#include <asm/hypervisor.h>    /* is_initial_xendomain() */
+
+static int nloopbacks = -1;
 module_param(nloopbacks, int, 0);
 MODULE_PARM_DESC(nloopbacks, "Number of netback-loopback devices to create");
 
@@ -77,9 +79,59 @@ static int loopback_close(struct net_dev
        return 0;
 }
 
+#ifdef CONFIG_X86
+static int is_foreign(unsigned long pfn)
+{
+       /* NB. Play it safe for auto-translation mode. */
+       return (xen_feature(XENFEAT_auto_translated_physmap) ||
+               (phys_to_machine_mapping[pfn] & FOREIGN_FRAME_BIT));
+}
+#else
+/* How to detect a foreign mapping? Play it safe. */
+#define is_foreign(pfn)        (1)
+#endif
+
+static int skb_remove_foreign_references(struct sk_buff *skb)
+{
+       struct page *page;
+       unsigned long pfn;
+       int i, off;
+       char *vaddr;
+
+       BUG_ON(skb_shinfo(skb)->frag_list);
+
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               pfn = page_to_pfn(skb_shinfo(skb)->frags[i].page);
+               if (!is_foreign(pfn))
+                       continue;
+               
+               page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
+               if (unlikely(!page))
+                       return 0;
+
+               vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
+               off = skb_shinfo(skb)->frags[i].page_offset;
+               memcpy(page_address(page) + off,
+                      vaddr + off,
+                      skb_shinfo(skb)->frags[i].size);
+               kunmap_skb_frag(vaddr);
+
+               put_page(skb_shinfo(skb)->frags[i].page);
+               skb_shinfo(skb)->frags[i].page = page;
+       }
+
+       return 1;
+}
+
 static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct net_private *np = netdev_priv(dev);
+
+       if (!skb_remove_foreign_references(skb)) {
+               np->stats.tx_dropped++;
+               dev_kfree_skb(skb);
+               return 0;
+       }
 
        dst_release(skb->dst);
        skb->dst = NULL;
@@ -110,6 +162,11 @@ static int loopback_start_xmit(struct sk
        skb->protocol = eth_type_trans(skb, dev);
        skb->dev      = dev;
        dev->last_rx  = jiffies;
+
+       /* Flush netfilter context: rx'ed skbuffs not expected to have any. */
+       nf_reset(skb);
+       secpath_reset(skb);
+
        netif_rx(skb);
 
        return 0;
@@ -239,6 +296,9 @@ static int __init loopback_init(void)
 {
        int i, err = 0;
 
+       if (nloopbacks == -1)
+               nloopbacks = is_initial_xendomain() ? 4 : 0;
+
        for (i = 0; i < nloopbacks; i++)
                if ((err = make_loopback(i)) != 0)
                        break;
diff -r 914c44d10c8d -r 2bfd19fc1b79 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Sun Oct 01 
11:39:41 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Sun Oct 01 
19:10:18 2006 -0600
@@ -217,7 +217,7 @@ static struct sk_buff *netbk_copy_skb(st
                copy = len >= PAGE_SIZE ? PAGE_SIZE : len;
                zero = len >= PAGE_SIZE ? 0 : __GFP_ZERO;
 
-               page = alloc_page(GFP_ATOMIC | zero);
+               page = alloc_page(GFP_ATOMIC | __GFP_NOWARN | zero);
                if (unlikely(!page))
                        goto err_free;
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Sun Oct 01 
11:39:41 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Sun Oct 01 
19:10:18 2006 -0600
@@ -322,6 +322,20 @@ static void otherend_changed(struct xenb
        DPRINTK("state is %d (%s), %s, %s", state, xenbus_strstate(state),
                dev->otherend_watch.node, vec[XS_WATCH_PATH]);
 
+       /*
+        * Ignore xenbus transitions during shutdown. This prevents us doing
+        * work that can fail e.g., when the rootfs is gone.
+        */
+       if (system_state > SYSTEM_RUNNING) {
+               struct xen_bus_type *bus = bus;
+               bus = container_of(dev->dev.bus, struct xen_bus_type, bus);
+               /* If we're frontend, drive the state machine to Closed. */
+               /* This should cause the backend to release our resources. */
+               if ((bus == &xenbus_frontend) && (state == XenbusStateClosing))
+                       xenbus_frontend_closed(dev);
+               return;
+       }
+
        if (drv->otherend_changed)
                drv->otherend_changed(dev, state);
 }
diff -r 914c44d10c8d -r 2bfd19fc1b79 
linux-2.6-xen-sparse/include/xen/public/evtchn.h
--- a/linux-2.6-xen-sparse/include/xen/public/evtchn.h  Sun Oct 01 11:39:41 
2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/public/evtchn.h  Sun Oct 01 19:10:18 
2006 -0600
@@ -32,9 +32,6 @@
 
 #ifndef __LINUX_PUBLIC_EVTCHN_H__
 #define __LINUX_PUBLIC_EVTCHN_H__
-
-/* /dev/xen/evtchn resides at device number major=10, minor=201 */
-#define EVTCHN_MINOR 201
 
 /*
  * Bind a fresh port to VIRQ @virq.
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/blktap/drivers/Makefile
--- a/tools/blktap/drivers/Makefile     Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/blktap/drivers/Makefile     Sun Oct 01 19:10:18 2006 -0600
@@ -28,7 +28,7 @@ THREADLIB := -lpthread -lz
 THREADLIB := -lpthread -lz
 LIBS      := -L. -L.. -L../lib
 LIBS      += -L$(XEN_LIBXC)
-LIBS      += -lblktap
+LIBS      += -lblktap -lxenctrl
 LIBS      += -lcrypto
 LIBS      += -lz
 LIBS      += -L$(XEN_XENSTORE) -lxenstore
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/blktap/drivers/blktapctrl.c Sun Oct 01 19:10:18 2006 -0600
@@ -67,6 +67,8 @@ int max_timeout = MAX_TIMEOUT;
 int max_timeout = MAX_TIMEOUT;
 int ctlfd = 0;
 
+int blktap_major;
+
 static int open_ctrl_socket(char *devname);
 static int write_msg(int fd, int msgtype, void *ptr, void *ptr2);
 static int read_msg(int fd, int msgtype, void *ptr);
@@ -108,7 +110,18 @@ static void make_blktap_dev(char *devnam
                if (mknod(devname, S_IFCHR|0600,
                        makedev(major, minor)) == 0)
                        DPRINTF("Created %s device\n",devname);
-       } else DPRINTF("%s device already exists\n",devname);
+       } else {
+               DPRINTF("%s device already exists\n",devname);
+               /* it already exists, but is it the same major number */
+               if (((st.st_rdev>>8) & 0xff) != major) {
+                       DPRINTF("%s has old major %d\n",
+                               devname,
+                               (unsigned int)((st.st_rdev >> 8) & 0xff));
+                       /* only try again if we succed in deleting it */
+                       if (!unlink(devname))
+                               make_blktap_dev(devname, major, minor);
+               }
+       }
 }
 
 static int get_new_dev(int *major, int *minor, blkif_t *blkif)
@@ -644,9 +657,12 @@ int main(int argc, char *argv[])
        register_new_devmap_hook(map_new_blktapctrl);
        register_new_unmap_hook(unmap_blktapctrl);
 
-       /*Attach to blktap0 */  
+       /* Attach to blktap0 */
        asprintf(&devname,"%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME);
-       make_blktap_dev(devname,254,0);
+       if ((ret = xc_find_device_number("blktap0")) < 0)
+               goto open_failed;
+       blktap_major = major(ret);
+       make_blktap_dev(devname,blktap_major,0);
        ctlfd = open(devname, O_RDWR);
        if (ctlfd == -1) {
                DPRINTF("blktap0 open failed\n");
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c    Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/blktap/drivers/tapdisk.c    Sun Oct 01 19:10:18 2006 -0600
@@ -271,7 +271,6 @@ static int read_msg(char *buf)
        int length, len, msglen, tap_fd, *io_fd;
        char *ptr, *path;
        image_t *img;
-       struct timeval timeout;
        msg_hdr_t *msg;
        msg_newdev_t *msg_dev;
        msg_pid_t *msg_pid;
@@ -579,8 +578,7 @@ int main(int argc, char *argv[])
 {
        int len, msglen, ret;
        char *p, *buf;
-       fd_set readfds, writefds;
-       struct timeval timeout;
+       fd_set readfds, writefds;       
        fd_list_entry_t *ptr;
        struct tap_disk *drv;
        struct td_state *s;
@@ -622,12 +620,9 @@ int main(int argc, char *argv[])
                /*Set all tap fds*/
                LOCAL_FD_SET(&readfds);
 
-               timeout.tv_sec = 0; 
-               timeout.tv_usec = 1000; 
-
                /*Wait for incoming messages*/
                ret = select(maxfds + 1, &readfds, (fd_set *) 0, 
-                            (fd_set *) 0, &timeout);
+                            (fd_set *) 0, NULL);
 
                if (ret > 0) 
                {
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/blktap/lib/blktaplib.h
--- a/tools/blktap/lib/blktaplib.h      Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/blktap/lib/blktaplib.h      Sun Oct 01 19:10:18 2006 -0600
@@ -80,8 +80,9 @@ static inline int BLKTAP_MODE_VALID(unsi
 #define MAX_PENDING_REQS 64
 #define BLKTAP_DEV_DIR   "/dev/xen"
 #define BLKTAP_DEV_NAME  "blktap"
-#define BLKTAP_DEV_MAJOR 254
 #define BLKTAP_DEV_MINOR 0
+
+extern int blktap_major;
 
 #define BLKTAP_RING_PAGES       1 /* Front */
 #define BLKTAP_MMAP_REGION_SIZE (BLKTAP_RING_PAGES + MMAP_PAGES)
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/examples/init.d/xendomains
--- a/tools/examples/init.d/xendomains  Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/examples/init.d/xendomains  Sun Oct 01 19:10:18 2006 -0600
@@ -352,9 +352,9 @@ stop()
            if test $? -ne 0; then
                rc_failed $?
                echo -n '!'
-               kill $WDOG_PIG >/dev/null 2>&1
-           else
-               kill $WDOG_PIG >/dev/null 2>&1
+               kill $WDOG_PID >/dev/null 2>&1
+           else
+               kill $WDOG_PID >/dev/null 2>&1
                continue
            fi
        fi
@@ -368,7 +368,7 @@ stop()
                rc_failed $?
                echo -n '!'
            fi
-           kill $WDOG_PIG >/dev/null 2>&1
+           kill $WDOG_PID >/dev/null 2>&1
        fi
     done < <(xm list | grep -v '^Name')
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/examples/xen-backend.rules
--- a/tools/examples/xen-backend.rules  Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/examples/xen-backend.rules  Sun Oct 01 19:10:18 2006 -0600
@@ -5,3 +5,4 @@ SUBSYSTEM=="xen-backend", KERNEL=="vif*"
 SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", 
RUN+="$env{script} offline"
 SUBSYSTEM=="xen-backend", ACTION=="remove", 
RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
 KERNEL=="evtchn", NAME="xen/%k"
+KERNEL=="blktap[0-9]*", NAME="xen/%k"
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/firmware/vmxassist/vm86.c   Sun Oct 01 19:10:18 2006 -0600
@@ -68,7 +68,7 @@ guest_linear_to_real(uint32_t base)
                return base;
 
        if (!(oldctx.cr4 & CR4_PAE)) {
-               l1_mfn = ((uint32_t *)gcr3)[(base >> 22) & 0x3ff];
+               l1_mfn = ((uint32_t *)(long)gcr3)[(base >> 22) & 0x3ff];
                if (!(l1_mfn & PT_ENTRY_PRESENT))
                        panic("l2 entry not present\n");
 
@@ -79,19 +79,19 @@ guest_linear_to_real(uint32_t base)
 
                l1_mfn &= 0xfffff000;
 
-               l0_mfn = ((uint32_t *)l1_mfn)[(base >> 12) & 0x3ff];
+               l0_mfn = ((uint32_t *)(long)l1_mfn)[(base >> 12) & 0x3ff];
                if (!(l0_mfn & PT_ENTRY_PRESENT))
                        panic("l1 entry not present\n");
                l0_mfn &= 0xfffff000;
 
                return l0_mfn + (base & 0xfff);
        } else {
-               l2_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3];
+               l2_mfn = ((uint64_t *)(long)gcr3)[(base >> 30) & 0x3];
                if (!(l2_mfn & PT_ENTRY_PRESENT))
                        panic("l3 entry not present\n");
                l2_mfn &= 0x3fffff000ULL;
 
-               l1_mfn = ((uint64_t *)l2_mfn)[(base >> 21) & 0x1ff];
+               l1_mfn = ((uint64_t *)(long)l2_mfn)[(base >> 21) & 0x1ff];
                if (!(l1_mfn & PT_ENTRY_PRESENT))
                        panic("l2 entry not present\n");
 
@@ -102,7 +102,7 @@ guest_linear_to_real(uint32_t base)
 
                l1_mfn &= 0x3fffff000ULL;
 
-               l0_mfn = ((uint64_t *)l1_mfn)[(base >> 12) & 0x1ff];
+               l0_mfn = ((uint64_t *)(long)l1_mfn)[(base >> 12) & 0x1ff];
                if (!(l0_mfn & PT_ENTRY_PRESENT))
                        panic("l1 entry not present\n");
                l0_mfn &= 0x3fffff000ULL;
@@ -1230,6 +1230,18 @@ pushrm(struct regs *regs, int prefix, un
 
 enum { OPC_INVALID, OPC_EMULATED };
 
+#define rdmsr(msr,val1,val2)                           \
+       __asm__ __volatile__(                           \
+               "rdmsr"                                 \
+               : "=a" (val1), "=d" (val2)              \
+               : "c" (msr))
+
+#define wrmsr(msr,val1,val2)                           \
+       __asm__ __volatile__(                           \
+               "wrmsr"                                 \
+               : /* no outputs */                      \
+               : "c" (msr), "a" (val1), "d" (val2))
+
 /*
  * Emulate a single instruction, including all its prefixes. We only implement
  * a small subset of the opcodes, and not all opcodes are implemented for each
@@ -1288,6 +1300,12 @@ opcode(struct regs *regs)
                                if (!movcr(regs, prefix, opc))
                                        goto invalid;
                                return OPC_EMULATED;
+                       case 0x30: /* WRMSR */
+                               wrmsr(regs->ecx, regs->eax, regs->edx);
+                               return OPC_EMULATED;
+                       case 0x32: /* RDMSR */
+                               rdmsr(regs->ecx, regs->eax, regs->edx);
+                               return OPC_EMULATED;
                        default:
                                goto invalid;
                        }
@@ -1412,12 +1430,14 @@ opcode(struct regs *regs)
                        {
                                int addr, data;
                                int seg = segment(prefix, regs, regs->vds);
+                               int offset = prefix & ADDR32? fetch32(regs) : 
fetch16(regs);
+
                                if (prefix & DATA32) {
-                                       addr = address(regs, seg, 
fetch32(regs));
+                                       addr = address(regs, seg, offset);
                                        data = read32(addr);
                                        setreg32(regs, 0, data);
                                } else {
-                                       addr = address(regs, seg, 
fetch16(regs));
+                                       addr = address(regs, seg, offset);
                                        data = read16(addr);
                                        setreg16(regs, 0, data);
                                }
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/ioemu/target-i386-dm/helper2.c      Sun Oct 01 19:10:18 2006 -0600
@@ -520,8 +520,8 @@ int main_loop(void)
             }
         }
 
-        /* Wait up to 100 msec. */
-        main_loop_wait(100);
+        /* Wait up to 10 msec. */
+        main_loop_wait(10);
 
         if (env->send_event) {
             env->send_event = 0;
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/libxc/xc_linux.c
--- a/tools/libxc/xc_linux.c    Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/libxc/xc_linux.c    Sun Oct 01 19:10:18 2006 -0600
@@ -133,27 +133,95 @@ int do_xen_hypercall(int xc_handle, priv
                       (unsigned long)hypercall);
 }
 
+#define MTAB "/proc/mounts"
+#define MAX_PATH 255
+#define _STR(x) #x
+#define STR(x) _STR(x)
+
+static int find_sysfsdir(char *sysfsdir)
+{
+    FILE *fp;
+    char type[MAX_PATH + 1];
+
+    if ( (fp = fopen(MTAB, "r")) == NULL )
+        return -1;
+
+    while ( fscanf(fp, "%*s %"
+                   STR(MAX_PATH)
+                   "s %"
+                   STR(MAX_PATH)
+                   "s %*s %*d %*d\n",
+                   sysfsdir, type) == 2 )
+    {
+        if ( strncmp(type, "sysfs", 5) == 0 )
+            break;
+    }
+
+    fclose(fp);
+
+    return ((strncmp(type, "sysfs", 5) == 0) ? 0 : -1);
+}
+
+int xc_find_device_number(const char *name)
+{
+    FILE *fp;
+    int i, major, minor;
+    char sysfsdir[MAX_PATH + 1];
+    static char *classlist[] = { "xen", "misc" };
+
+    for ( i = 0; i < (sizeof(classlist) / sizeof(classlist[0])); i++ )
+    {
+        if ( find_sysfsdir(sysfsdir) < 0 )
+            goto not_found;
+
+        /* <base>/class/<classname>/<devname>/dev */
+        strncat(sysfsdir, "/class/", MAX_PATH);
+        strncat(sysfsdir, classlist[i], MAX_PATH);
+        strncat(sysfsdir, "/", MAX_PATH);
+        strncat(sysfsdir, name, MAX_PATH);
+        strncat(sysfsdir, "/dev", MAX_PATH);
+
+        if ( (fp = fopen(sysfsdir, "r")) != NULL )
+            goto found;
+    }
+
+ not_found:
+    errno = -ENOENT;
+    return -1;
+
+ found:
+    if ( fscanf(fp, "%d:%d", &major, &minor) != 2 )
+    {
+        fclose(fp);
+        goto not_found;
+    }
+
+    fclose(fp);
+
+    return makedev(major, minor);
+}
+
 #define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
-#define EVTCHN_DEV_MAJOR 10
-#define EVTCHN_DEV_MINOR 201
 
 int xc_evtchn_open(void)
 {
     struct stat st;
     int fd;
+    int devnum;
+
+    devnum = xc_find_device_number("evtchn");
 
     /* Make sure any existing device file links to correct device. */
-    if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
-        (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)))
+    if ( (lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
+         (st.st_rdev != devnum) )
         (void)unlink(EVTCHN_DEV_NAME);
 
-reopen:
+ reopen:
     if ( (fd = open(EVTCHN_DEV_NAME, O_RDWR)) == -1 )
     {
         if ( (errno == ENOENT) &&
             ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
-            (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
-            makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0) )
+             (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, devnum) == 0) )
             goto reopen;
 
         PERROR("Could not open event channel interface");
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/libxc/xenctrl.h     Sun Oct 01 19:10:18 2006 -0600
@@ -92,6 +92,16 @@ int xc_interface_close(int xc_handle);
 int xc_interface_close(int xc_handle);
 
 /*
+ * KERNEL INTERFACES
+ */
+
+/*
+ * Resolve a kernel device name (e.g., "evtchn", "blktap0") into a kernel
+ * device number. Returns -1 on error (and sets errno).
+ */
+int xc_find_device_number(const char *name);
+
+/*
  * DOMAIN DEBUGGING FUNCTIONS
  */
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub   Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/pygrub/src/pygrub   Sun Oct 01 19:10:18 2006 -0600
@@ -25,7 +25,18 @@ import grub.GrubConf
 import grub.GrubConf
 import grub.fsys
 
-PYGRUB_VER = 0.4
+PYGRUB_VER = 0.5
+
+def enable_cursor(ison):
+    if ison:
+        val = 2
+    else:
+        val = 0
+        
+    try:
+        curses.curs_set(val)
+    except _curses.error:
+        pass
 
 def is_disk_image(file):
     fd = os.open(file, os.O_RDONLY)
@@ -141,10 +152,7 @@ class Grub:
             self.screen.timeout(1000)
             if hasattr(curses, 'use_default_colors'):
                 curses.use_default_colors()
-            try:
-                curses.curs_set(0)
-            except _curses.error:
-                pass
+            enable_cursor(False)
             self.entry_win = curses.newwin(10, 74, 2, 1)
             self.text_win = curses.newwin(10, 70, 12, 5)
             
@@ -247,6 +255,7 @@ class Grub:
         self.screen.refresh()
 
         t = GrubLineEditor(self.screen, 5, 2, line)
+        enable_cursor(True)
         ret = t.edit()
         if ret:
             return ret
@@ -262,6 +271,7 @@ class Grub:
         lines = []
         while 1:
             t = GrubLineEditor(self.screen, y, 2)
+            enable_cursor(True)            
             ret = t.edit()
             if ret:
                 if ret in ("quit", "return"):
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/util/blkif.py
--- a/tools/python/xen/util/blkif.py    Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/util/blkif.py    Sun Oct 01 19:10:18 2006 -0600
@@ -67,6 +67,8 @@ def blkdev_uname_to_file(uname):
         (typ, fn) = uname.split(":")
         if typ == "phy" and not fn.startswith("/"):
             fn = "/dev/%s" %(fn,)
+        if typ == "tap":
+            (typ, fn) = fn.split(":", 1)
     return fn
 
 def mount_mode(name):
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xend/image.py    Sun Oct 01 19:10:18 2006 -0600
@@ -244,7 +244,8 @@ class HVMImageHandler(ImageHandler):
 
         info = xc.xeninfo()
         if not 'hvm' in info['xen_caps']:
-            raise VmError("Not an HVM capable platform, we stop creating!")
+            raise VmError("HVM guest support is unavailable: is VT/AMD-V "
+                          "supported by your CPU and enabled in your BIOS?")
 
         self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
         self.device_model = sxp.child_value(imageConfig, 'device_model')
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/addlabel.py
--- a/tools/python/xen/xm/addlabel.py   Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/addlabel.py   Sun Oct 01 19:10:18 2006 -0600
@@ -115,43 +115,45 @@ def add_domain_label(label, configfile, 
     config_fd.close()
 
 
-def main (argv):
+def main(argv):
+    policyref = None
+    if len(argv) not in (4, 5):
+        raise OptionError('Needs either 2 or 3 arguments')
+    
+    label = argv[1]
+    
+    if len(argv) == 5:
+        policyref = argv[4]
+    elif security.on():
+        policyref = security.active_policy
+    else:
+        raise OptionError("No active policy. Must specify policy on the "
+                          "command line.")
+
+    if argv[2].lower() == "dom":
+        configfile = argv[3]
+        if configfile[0] != '/':
+            for prefix in [".", "/etc/xen"]:
+                configfile = prefix + "/" + configfile
+                if os.path.isfile(configfile):
+                    break
+        if not validate_config_file(configfile):
+            raise OptionError('Invalid config file')
+        else:
+            add_domain_label(label, configfile, policyref)
+    elif argv[2].lower() == "res":
+        resource = argv[3]
+        add_resource_label(label, resource, policyref)
+    else:
+        raise OptionError('Need to specify either "dom" or "res" as '
+                          'object to add label to.')
+            
+if __name__ == '__main__':
     try:
-        policyref = None
-        if len(argv) not in (4, 5):
-            raise OptionError('Needs either 2 or 3 arguments')
-
-        label = argv[1]
-
-        if len(argv) == 5:
-            policyref = argv[4]
-        elif security.on():
-            policyref = security.active_policy
-        else:
-            security.err("No active policy. Policy must be specified in 
command line.")
-
-        if argv[2].lower() == "dom":
-            configfile = argv[3]
-            if configfile[0] != '/':
-                for prefix in [".", "/etc/xen"]:
-                    configfile = prefix + "/" + configfile
-                    if os.path.isfile(configfile):
-                        break
-            if not validate_config_file(configfile):
-                raise OptionError('Invalid config file')
-            else:
-                add_domain_label(label, configfile, policyref)
-        elif argv[2].lower() == "res":
-            resource = argv[3]
-            add_resource_label(label, resource, policyref)
-        else:
-            raise OptionError('Need to specify either "dom" or "res" as object 
to add label to.')
-            
-    except security.ACMError:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
         sys.exit(-1)
-
-if __name__ == '__main__':
-    main(sys.argv)
     
 
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/cfgbootpolicy.py
--- a/tools/python/xen/xm/cfgbootpolicy.py      Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/cfgbootpolicy.py      Sun Oct 01 19:10:18 2006 -0600
@@ -140,44 +140,41 @@ def insert_policy(boot_file, kernel_vers
 
 
 def main(argv):
-    try:
-        user_kver = None
-        policy = None
-        if len(argv) == 2:
-            policy = argv[1]
-        elif len(argv) == 3:
-            policy = argv[1]
-            user_kver = argv[2]
+    user_kver = None
+    policy = None
+    if len(argv) == 2:
+        policy = argv[1]
+    elif len(argv) == 3:
+        policy = argv[1]
+        user_kver = argv[2]
+    else:
+        raise OptionError('Invalid number of arguments')
+    
+    if not policy_name_re.match(policy):
+        raise OptionError("Illegal policy name: '%s'" % policy)
+
+    policy_file = '/'.join([policy_dir_prefix] + policy.split('.'))
+    src_binary_policy_file = policy_file + ".bin"
+    #check if .bin exists or if policy file exists
+    if not os.path.isfile(src_binary_policy_file):
+        if not os.path.isfile(policy_file + "-security_policy.xml"):
+            raise OptionError("Unknown policy '%s'" % policy)
         else:
-            raise OptionError('Invalid number of arguments')
-
-        if not policy_name_re.match(policy):
-            err("Illegal policy name \'" + policy + "\'")
-
-        policy_file = policy_dir_prefix + "/" + 
string.join(string.split(policy, "."), "/")
-        src_binary_policy_file = policy_file + ".bin"
-        #check if .bin exists or if policy file exists
-        if not os.path.isfile(src_binary_policy_file):
-            if not os.path.isfile(policy_file + "-security_policy.xml"):
-                err("Unknown policy \'" + policy +"\'")
-            else:
-                err("Cannot find binary file for policy \'" + policy +
-                    "\'. Please use makepolicy to create binary file.")
-        dst_binary_policy_file = "/boot/" + policy + ".bin"
-        shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
-
-        kernel_version = determine_kernelversion(user_kver)
-        insert_policy(boot_filename, kernel_version, policy)
-        print "Boot entry created and \'%s\' copied to /boot" % (policy + 
".bin")
-
-    except ACMError:
-        sys.exit(-1)
-    except:
-        traceback.print_exc(limit=1)
-        sys.exit(-1)
-
-
+            err_msg = "Cannot find binary file for policy '%s'." % policy
+            err_msg += " Please use makepolicy to create binary file."
+            raise OptionError(err_msg)
+    
+    dst_binary_policy_file = "/boot/" + policy + ".bin"
+    shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
+    
+    kernel_version = determine_kernelversion(user_kver)
+    insert_policy(boot_filename, kernel_version, policy)
+    print "Boot entry created and \'%s\' copied to /boot" % (policy + ".bin")
 
 if __name__ == '__main__':
-    main(sys.argv)
-
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: ' + str(e) + '\n')    
+        sys.exit(-1)
+        
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/create.py     Sun Oct 01 19:10:18 2006 -0600
@@ -693,7 +693,7 @@ def make_config(vals):
         config_image = run_bootloader(vals, config_image)
         config.append(['bootloader', vals.bootloader])
         if vals.bootargs:
-            config.append(['bootloader_args'], vals.bootargs)
+            config.append(['bootloader_args', vals.bootargs])
     config.append(['image', config_image])
 
     config_devs = []
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/dry-run.py
--- a/tools/python/xen/xm/dry-run.py    Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/dry-run.py    Sun Oct 01 19:10:18 2006 -0600
@@ -32,27 +32,26 @@ def help():
     individually along with the final security decision."""
 
 def main (argv):
-    try:
-        if len(argv) != 2:
-            raise OptionError('Invalid number of arguments')
-
-        passed = 0
-        (opts, config) = create.parseCommandLine(argv)
-        if create.check_domain_label(config, verbose=1):
-            if create.config_security_check(config, verbose=1):
-                passed = 1
-        else:
-            print "Checking resources: (skipped)"
-                
-        if passed:
-            print "Dry Run: PASSED"
-        else:
-            print "Dry Run: FAILED"
-            sys.exit(-1)
-
-    except security.ACMError:
+    if len(argv) != 2:
+        raise OptionError('Invalid number of arguments')
+    
+    passed = 0
+    (opts, config) = create.parseCommandLine(argv)
+    if create.check_domain_label(config, verbose=1):
+        if create.config_security_check(config, verbose=1):
+            passed = 1
+    else:
+        print "Checking resources: (skipped)"
+        
+    if passed:
+        print "Dry Run: PASSED"
+    else:
+        print "Dry Run: FAILED"
         sys.exit(-1)
 
-
 if __name__ == '__main__':
-    main(sys.argv)
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/dumppolicy.py
--- a/tools/python/xen/xm/dumppolicy.py Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/dumppolicy.py Sun Oct 01 19:10:18 2006 -0600
@@ -19,7 +19,7 @@
 """
 import sys
 from xen.util.security import ACMError, err, dump_policy
-
+from xen.xm.opts import OptionError
 
 def help():
     return """
@@ -27,16 +27,16 @@ def help():
     (low-level)."""
 
 def main(argv):
+    if len(argv) != 1:
+        raise OptionError("No arguments expected.")
+
+    dump_policy()
+
+if __name__ == '__main__':
     try:
-        if len(argv) != 1:
-            usage()
-
-        dump_policy()
-    except ACMError:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))    
         sys.exit(-1)
 
 
-if __name__ == '__main__':
-    main(sys.argv)
-
-
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/getlabel.py
--- a/tools/python/xen/xm/getlabel.py   Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/getlabel.py   Sun Oct 01 19:10:18 2006 -0600
@@ -25,8 +25,9 @@ from xen.xm.opts import OptionError
 
 def help():
     return """
-    Usage: xm getlabel dom <configfile>"
-           xm getlabel res <resource>\n"
+    Usage: xm getlabel dom <configfile>
+           xm getlabel res <resource>
+           
     This program shows the label for a domain or resource."""
 
 def get_resource_label(resource):
@@ -37,7 +38,7 @@ def get_resource_label(resource):
     try:
         access_control = dictio.dict_read("resources", file)
     except:
-        security.err("Resource label file not found")
+        raise OptionError("Resource label file not found")
 
     # get the entry and print label
     if access_control.has_key(resource):
@@ -45,23 +46,22 @@ def get_resource_label(resource):
         label = access_control[resource][1]
         print "policy="+policy+",label="+label
     else:
-        security.err("Resource not labeled")
+        raise security.ACMError("Resource not labeled")
 
 
 def get_domain_label(configfile):
     # open the domain config file
     fd = None
-    file = None
     if configfile[0] == '/':
         fd = open(configfile, "rb")
     else:
         for prefix in [".", "/etc/xen"]:
-            file = prefix + "/" + configfile
-            if os.path.isfile(file):
-                fd = open(file, "rb")
+            abs_file = prefix + "/" + configfile
+            if os.path.isfile(abs_file):
+                fd = open(abs_file, "rb")
                 break
     if not fd:
-        security.err("Configuration file '"+configfile+"' not found.")
+        raise OptionError("Configuration file '%s' not found." % configfile)
 
     # read in the domain config file, finding the label line
     ac_entry_re = re.compile("^access_control\s*=.*", re.IGNORECASE)
@@ -79,7 +79,7 @@ def get_domain_label(configfile):
 
     # send error message if we didn't find anything
     if acline == "":
-        security.err("Domain not labeled")
+        raise security.ACMError("Domain not labeled")
 
     # print out the label
     (title, data) = acline.split("=", 1)
@@ -89,7 +89,7 @@ def get_domain_label(configfile):
     print data
 
 
-def main (argv):
+def main(argv):
     if len(argv) != 3:
         raise OptionError('Requires 2 arguments')
 
@@ -103,6 +103,11 @@ def main (argv):
         raise OptionError('First subcommand argument must be "dom" or "res"')
 
 if __name__ == '__main__':
-    main(sys.argv)
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)
+        
 
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/loadpolicy.py
--- a/tools/python/xen/xm/loadpolicy.py Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/loadpolicy.py Sun Oct 01 19:10:18 2006 -0600
@@ -31,15 +31,12 @@ def main(argv):
     if len(argv) != 2:
         raise OptionError('No policy defined')
     
-    try:
-        load_policy(argv[1])
-
-    except ACMError:
-        sys.exit(-1)
-    except:
-        traceback.print_exc(limit = 1)
+    load_policy(argv[1])
 
 if __name__ == '__main__':
-    main(sys.argv)
-
-
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)
+        
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/main.py       Sun Oct 01 19:10:18 2006 -0600
@@ -526,7 +526,7 @@ def parse_sedf_info(info):
         return t(sxp.child_value(info, n, d))
 
     return {
-        'domid'    : get_info('domid',         int,   -1),
+        'domid'    : get_info('domain',        int,   -1),
         'period'   : get_info('period',        int,   -1),
         'slice'    : get_info('slice',         int,   -1),
         'latency'  : get_info('latency',       int,   -1),
@@ -979,7 +979,7 @@ def xm_uptime(args):
 
     for dom in doms:
         d = parse_doms_info(dom)
-        if d['dom'] > 0:
+        if d['domid'] > 0:
             uptime = int(round(d['up_time']))
         else:
             f=open('/proc/uptime', 'r')
@@ -1006,10 +1006,10 @@ def xm_uptime(args):
         if short_mode:
             now = datetime.datetime.now()
             upstring = now.strftime(" %H:%M:%S") + " up " + upstring
-            upstring += ", " + d['name'] + " (" + str(d['dom']) + ")"
+            upstring += ", " + d['name'] + " (" + str(d['domid']) + ")"
         else:
             upstring += ':%(seconds)02d' % vars()
-            upstring = ("%(name)-32s %(dom)3d " % d) + upstring
+            upstring = ("%(name)-32s %(domid)3d " % d) + upstring
 
         print upstring
 
@@ -1374,7 +1374,7 @@ IMPORTED_COMMANDS = [
     'cfgbootpolicy',
     'makepolicy',
     'loadpolicy',
-    'dumppolicy'
+    'dumppolicy',
     'rmlabel',
     'getlabel',
     'dry-run',
@@ -1423,13 +1423,14 @@ def main(argv=sys.argv):
     if len(argv) < 2:
         usage()
 
-    # intercept --help and output our own help
-    if '--help' in argv[1:]:
-        if '--help' == argv[1]:
-            longHelp()
-        else:
-            usage(argv[1])
-        sys.exit(0)
+    # intercept --help(-h) and output our own help
+    for help in ['--help', '-h']:
+        if help in argv[1:]:
+            if help == argv[1]:
+                longHelp()
+            else:
+                usage(argv[1])
+            sys.exit(0)
 
     cmd = xm_lookup_cmd(argv[1])
 
@@ -1477,10 +1478,15 @@ def main(argv=sys.argv):
         except (ValueError, OverflowError):
             err("Invalid argument.")
             usage(argv[1])
+            sys.exit(1)
         except OptionError, e:
             err(str(e))
             usage(argv[1])
             print e.usage()
+            sys.exit(1)
+        except security.ACMError, e:
+            err(str(e))
+            sys.exit(1)
         except:
             print "Unexpected error:", sys.exc_info()[0]
             print
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/makepolicy.py
--- a/tools/python/xen/xm/makepolicy.py Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/makepolicy.py Sun Oct 01 19:10:18 2006 -0600
@@ -33,16 +33,13 @@ def main(argv):
     if len(argv) != 2:
         raise OptionError('No XML policy file specified')
 
+    make_policy(argv[1])
+
+if __name__ == '__main__':
     try:
-        make_policy(argv[1])
-    except ACMError:
-        sys.exit(-1)
-    except:
-        traceback.print_exc(limit=1)
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
         sys.exit(-1)
 
 
-if __name__ == '__main__':
-    main(sys.argv)
-
-
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/resources.py
--- a/tools/python/xen/xm/resources.py  Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/resources.py  Sun Oct 01 19:10:18 2006 -0600
@@ -24,7 +24,7 @@ from xen.xm.opts import OptionError
 from xen.xm.opts import OptionError
 
 def help():
-    return """Usage: xm resource
+    return """
     This program lists information for each resource in the
     global resource label file."""
 
@@ -45,18 +45,13 @@ def main (argv):
         filename = security.res_label_filename
         access_control = dictio.dict_read("resources", filename)
     except:
-        print "Resource file not found."
-        return
+        raise OptionError("Resource file not found")
 
-        try:
-            file = security.res_label_filename
-            access_control = dictio.dict_read("resources", file)
-        except:
-            security.err("Error reading resource file.")
-
-        print_resource_data(access_control)
+    print_resource_data(access_control)
 
 if __name__ == '__main__':
-    main(sys.argv)
-
-
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)    
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/python/xen/xm/rmlabel.py
--- a/tools/python/xen/xm/rmlabel.py    Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/python/xen/xm/rmlabel.py    Sun Oct 01 19:10:18 2006 -0600
@@ -42,14 +42,14 @@ def rm_resource_label(resource):
     try:
         access_control = dictio.dict_read("resources", file)
     except:
-        security.err("Resource file not found, cannot remove label!")
+        raise security.ACMError("Resource file not found, cannot remove 
label!")
 
     # remove the entry and update file
     if access_control.has_key(resource):
         del access_control[resource]
         dictio.dict_write(access_control, "resources", file)
     else:
-        security.err("Resource not labeled.")
+        raise security.ACMError("Resource not labeled")
 
 
 def rm_domain_label(configfile):
@@ -65,8 +65,8 @@ def rm_domain_label(configfile):
                 fd = open(file, "rb")
                 break
     if not fd:
-        security.err("Configuration file '"+configfile+"' not found.")
-
+        raise OptionError("Configuration file '%s' not found." % configfile)
+        
     # read in the domain config file, removing label
     ac_entry_re = re.compile("^access_control\s*=.*", re.IGNORECASE)
     ac_exit_re = re.compile(".*'\].*")
@@ -86,7 +86,7 @@ def rm_domain_label(configfile):
 
     # send error message if we didn't find anything to remove
     if not removed:
-        security.err("Domain not labeled.")
+        raise security.ACMError('Domain not labeled')
 
     # write the data back out to the file
     fd = open(file, "wb")
@@ -102,17 +102,18 @@ def main (argv):
     if argv[1].lower() not in ('dom', 'res'):
         raise OptionError('Unrecognised type argument: %s' % argv[1])
 
-    try:
-        if argv[1].lower() == "dom":
-            configfile = argv[2]
-            rm_domain_label(configfile)
-        elif argv[1].lower() == "res":
-            resource = argv[2]
-            rm_resource_label(resource)
-    except security.ACMError:
-        sys.exit(-1)
+    if argv[1].lower() == "dom":
+        configfile = argv[2]
+        rm_domain_label(configfile)
+    elif argv[1].lower() == "res":
+        resource = argv[2]
+        rm_resource_label(resource)
 
 if __name__ == '__main__':
-    main(sys.argv)
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)    
 
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/xm-test/tests/vtpm/vtpm_utils.py
--- a/tools/xm-test/tests/vtpm/vtpm_utils.py    Sun Oct 01 11:39:41 2006 -0600
+++ b/tools/xm-test/tests/vtpm/vtpm_utils.py    Sun Oct 01 19:10:18 2006 -0600
@@ -8,12 +8,10 @@ if ENABLE_HVM_SUPPORT:
 if ENABLE_HVM_SUPPORT:
     SKIP("vtpm tests not supported for HVM domains")
 
-if not os.path.exists("/dev/tpm0"):
-    SKIP("This machine has no hardware TPM; cannot run this test")
-
 status, output = traceCommand("ps aux | grep vtpm_manager | grep -v grep")
 if output == "":
-    FAIL("virtual TPM manager must be started to run this test")
+    SKIP("virtual TPM manager must be started to run this test; might "
+         "need /dev/tpm0")
 
 def vtpm_cleanup(domName):
     traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/ia64/Makefile
--- a/xen/arch/ia64/Makefile    Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/ia64/Makefile    Sun Oct 01 19:10:18 2006 -0600
@@ -4,22 +4,27 @@ subdir-y += linux-xen
 subdir-y += linux-xen
 
 $(TARGET)-syms: linux-xen/head.o $(ALL_OBJS) xen.lds.s
+       $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/common/symbols-dummy.o
        $(LD) $(LDFLAGS) -T xen.lds.s -N \
-               -Map map.out linux-xen/head.o $(ALL_OBJS) -o $@
+               -Map map.out linux-xen/head.o $(ALL_OBJS) \
+               $(BASEDIR)/common/symbols-dummy.o -o $@
        $(NM) -n $@ | $(BASEDIR)/tools/symbols > $(BASEDIR)/xen-syms.S
        $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/xen-syms.o
        $(LD) $(LDFLAGS) -T xen.lds.s -N \
-               -Map map.out linux-xen/head.o $(ALL_OBJS) $(BASEDIR)/xen-syms.o 
-o $@
+               -Map map.out linux-xen/head.o $(ALL_OBJS) \
+               $(BASEDIR)/xen-syms.o -o $@
        $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
        $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/xen-syms.o
        $(LD) $(LDFLAGS) -T xen.lds.s -N \
-               -Map map.out linux-xen/head.o $(ALL_OBJS) $(BASEDIR)/xen-syms.o 
-o $@
+               -Map map.out linux-xen/head.o $(ALL_OBJS) \
+               $(BASEDIR)/xen-syms.o -o $@
        rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o
 
 $(TARGET): $(TARGET)-syms
        $(OBJCOPY) -R .note -R .comment -S $(TARGET)-syms $@
-       $(NM) -n $(TARGET)-syms | grep -v '\( [aUw] \)\|\(__crc_\)\|\( 
\$[adt]\)'\
-                > $(BASEDIR)/System.map
+       $(NM) -n $(TARGET)-syms | \
+               grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' \
+               > $(BASEDIR)/System.map
 
 # Headers do not depend on auto-generated header, but object files do.
 HDRS    := $(subst $(BASEDIR)/include/asm-ia64/asm-xsi-offsets.h,,$(HDRS))
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/powerpc/Makefile Sun Oct 01 19:10:18 2006 -0600
@@ -101,7 +101,8 @@ TARGET_OPTS += start.o $(ALL_OBJS)
 TARGET_OPTS += start.o $(ALL_OBJS)
 
 .xen-syms: start.o $(ALL_OBJS) xen.lds
-       $(CC) $(CFLAGS) $(TARGET_OPTS) -o $@
+       $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/common/symbols-dummy.o
+       $(CC) $(CFLAGS) $(TARGET_OPTS) $(BASEDIR)/common/symbols-dummy.o -o $@
 
 NM=$(CROSS_COMPILE)nm
 new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; 
then echo y; else echo n; fi)
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/Makefile     Sun Oct 01 19:10:18 2006 -0600
@@ -46,19 +46,24 @@ obj-$(crash_debug) += gdbstub.o
 
 $(TARGET): $(TARGET)-syms boot/mkelf32
        ./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \
-       `$(NM) $(TARGET)-syms | sort | tail -n 1 | sed -e 's/^\([^ 
]*\).*/0x\1/'`
+       `$(NM) $(TARGET)-syms | sort | tail -n 1 | \
+        sed -e 's/^\([^ ]*\).*/0x\1/'`
 
 $(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) xen.lds
+       $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/common/symbols-dummy.o
        $(LD) $(LDFLAGS) -T xen.lds -N \
-           boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $@
+           boot/$(TARGET_SUBARCH).o $(ALL_OBJS) \
+           $(BASEDIR)/common/symbols-dummy.o -o $@
        $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
        $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/xen-syms.o
        $(LD) $(LDFLAGS) -T xen.lds -N \
-           boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@
+           boot/$(TARGET_SUBARCH).o $(ALL_OBJS) \
+           $(BASEDIR)/xen-syms.o -o $@
        $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
        $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/xen-syms.o
        $(LD) $(LDFLAGS) -T xen.lds -N \
-           boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@
+           boot/$(TARGET_SUBARCH).o $(ALL_OBJS) \
+           $(BASEDIR)/xen-syms.o -o $@
        rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o
 
 asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS)
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/domain.c     Sun Oct 01 19:10:18 2006 -0600
@@ -334,8 +334,10 @@ int arch_set_info_guest(
     }
     else
     {
-        if ( !get_page_and_type(mfn_to_page(cr3_pfn), d,
-                                PGT_base_page_table) )
+        if ( shadow_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) )
         {
             destroy_gdt(v);
             return -EINVAL;
@@ -952,7 +954,10 @@ void domain_relinquish_resources(struct 
         pfn = pagetable_get_pfn(v->arch.guest_table_user);
         if ( pfn != 0 )
         {
-            put_page_and_type(mfn_to_page(pfn));
+            if ( shadow_mode_refcounts(d) )
+                put_page(mfn_to_page(pfn));
+            else
+                put_page_and_type(mfn_to_page(pfn));
             v->arch.guest_table_user = pagetable_null();
         }
 #endif
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/hvm.c    Sun Oct 01 19:10:18 2006 -0600
@@ -389,42 +389,68 @@ void hvm_hlt(unsigned long rflags)
 }
 
 /*
- * Copy from/to guest virtual.
+ * __hvm_copy():
+ *  @buf  = hypervisor buffer
+ *  @addr = guest virtual or physical address to copy to/from
+ *  @size = number of bytes to copy
+ *  @dir  = copy *to* guest (TRUE) or *from* guest (FALSE)?
+ *  @phy  = interpret addr as physical (TRUE) or virtual (FALSE) address?
+ * Returns number of bytes failed to copy (0 == complete success).
  */
-int hvm_copy(void *buf, unsigned long vaddr, int size, int dir)
+static int __hvm_copy(
+    void *buf, unsigned long addr, int size, int dir, int phy)
 {
     struct vcpu *v = current;
-    unsigned long gfn;
     unsigned long mfn;
-    char *addr;
-    int count;
-
-    while (size > 0) {
-        count = PAGE_SIZE - (vaddr & ~PAGE_MASK);
-        if (count > size)
-            count = size;
-
-        gfn = shadow_gva_to_gfn(v, vaddr);
-        mfn = mfn_x(sh_vcpu_gfn_to_mfn(v, gfn));
-
-        if (mfn == INVALID_MFN)
-            return 0;
-
-        addr = (char *)map_domain_page(mfn) + (vaddr & ~PAGE_MASK);
-
-        if (dir == HVM_COPY_IN)
-            memcpy(buf, addr, count);
+    char *p;
+    int count, todo;
+
+    todo = size;
+    while ( todo > 0 )
+    {
+        count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), todo);
+
+        mfn = phy ? 
+            get_mfn_from_gpfn(addr >> PAGE_SHIFT) :
+            mfn_x(sh_vcpu_gfn_to_mfn(v, shadow_gva_to_gfn(v, addr)));
+        if ( mfn == INVALID_MFN )
+            return todo;
+
+        p = (char *)map_domain_page(mfn) + (addr & ~PAGE_MASK);
+
+        if ( dir )
+            memcpy(p, buf, count); /* dir == TRUE:  *to* guest */
         else
-            memcpy(addr, buf, count);
-
-        unmap_domain_page(addr);
-
-        vaddr += count;
-        buf += count;
-        size -= count;
-    }
-
-    return 1;
+            memcpy(buf, p, count); /* dir == FALSE: *from guest */
+
+        unmap_domain_page(p);
+
+        addr += count;
+        buf  += count;
+        todo -= count;
+    }
+
+    return 0;
+}
+
+int hvm_copy_to_guest_phys(unsigned long paddr, void *buf, int size)
+{
+    return __hvm_copy(buf, paddr, size, 1, 1);
+}
+
+int hvm_copy_from_guest_phys(void *buf, unsigned long paddr, int size)
+{
+    return __hvm_copy(buf, paddr, size, 0, 1);
+}
+
+int hvm_copy_to_guest_virt(unsigned long vaddr, void *buf, int size)
+{
+    return __hvm_copy(buf, vaddr, size, 1, 0);
+}
+
+int hvm_copy_from_guest_virt(void *buf, unsigned long vaddr, int size)
+{
+    return __hvm_copy(buf, vaddr, size, 0, 0);
 }
 
 /*
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/i8259.c
--- a/xen/arch/x86/hvm/i8259.c  Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/i8259.c  Sun Oct 01 19:10:18 2006 -0600
@@ -86,7 +86,7 @@ static int pic_get_irq(PicState *s)
 
     ASSERT(spin_is_locked(&s->pics_state->lock));
 
-    mask = s->irr & ~s->imr;
+    mask = (s->irr|s->irr_xen) & ~s->imr;
     priority = get_priority(s, mask);
     if (priority == 8)
         return -1;
@@ -128,6 +128,32 @@ void pic_update_irq(struct hvm_virpic *s
     }
 }
 
+void pic_set_xen_irq(void *opaque, int irq, int level)
+{
+    struct hvm_virpic *s = opaque;
+    unsigned long flags;
+    PicState *ps;
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    hvm_vioapic_set_xen_irq(current->domain, irq, level);
+
+    /* Set it on the 8259s */
+    ps = &s->pics[irq >> 3];
+    if (!(ps->elcr & (1 << (irq & 7)))) {
+       DPRINTK("edge-triggered override IRQ?\n");
+       domain_crash(current->domain);
+    }
+    if (level) {
+       ps->irr_xen |= 1 << (irq & 7);
+    } else {
+       ps->irr_xen &= ~(1 << (irq & 7));
+    }
+
+    pic_update_irq(s);
+    spin_unlock_irqrestore(&s->lock, flags);
+}
+
 void pic_set_irq_new(void *opaque, int irq, int level)
 {
     struct hvm_virpic *s = opaque;
@@ -136,9 +162,6 @@ void pic_set_irq_new(void *opaque, int i
     spin_lock_irqsave(&s->lock, flags);
     hvm_vioapic_set_irq(current->domain, irq, level);
     pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
-    /* used for IOAPIC irqs */
-    if (s->alt_irq_func)
-        s->alt_irq_func(s->alt_irq_opaque, irq, level);
     pic_update_irq(s);
     spin_unlock_irqrestore(&s->lock, flags);
 }
@@ -371,6 +394,7 @@ static uint32_t pic_poll_read (PicState 
             s->pics_state->pics[0].irr &= ~(1 << 2);
         }
         s->irr &= ~(1 << ret);
+        s->irr_xen &= ~(1 << ret);
         s->isr &= ~(1 << ret);
         if (addr1 >> 7 || ret != 2)
             pic_update_irq(s->pics_state);
@@ -400,7 +424,7 @@ static uint32_t pic_ioport_read(void *op
             if (s->read_reg_select)
                 ret = s->isr;
             else
-                ret = s->irr;
+                ret = s->irr | s->irr_xen;
         } else {
             ret = s->imr;
         }
@@ -472,18 +496,6 @@ void pic_init(struct hvm_virpic *s, void
     s->irq_request_opaque = irq_request_opaque;
 }
 
-void pic_set_alt_irq_func(struct hvm_virpic *s,
-                          void (*alt_irq_func)(void *, int, int),
-                          void *alt_irq_opaque)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&s->lock, flags);
-    s->alt_irq_func = alt_irq_func;
-    s->alt_irq_opaque = alt_irq_opaque;
-    spin_unlock_irqrestore(&s->lock, flags);
-}
-
 static int intercept_pic_io(ioreq_t *p)
 {
     struct hvm_virpic  *pic;
@@ -497,8 +509,9 @@ static int intercept_pic_io(ioreq_t *p)
     }
     pic = &v->domain->arch.hvm_domain.vpic;
     if ( p->dir == 0 ) {
-        if(p->pdata_valid) 
-            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_IN);
+        if (p->pdata_valid) 
+            (void)hvm_copy_from_guest_virt(
+                &data, (unsigned long)p->u.pdata, p->size);
         else
             data = p->u.data;
         spin_lock_irqsave(&pic->lock, flags);
@@ -511,8 +524,9 @@ static int intercept_pic_io(ioreq_t *p)
         data = pic_ioport_read(
             (void*)&pic->pics[p->addr>>7], (uint32_t) p->addr);
         spin_unlock_irqrestore(&pic->lock, flags);
-        if(p->pdata_valid) 
-            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_OUT);
+        if (p->pdata_valid) 
+            (void)hvm_copy_to_guest_virt(
+                (unsigned long)p->u.pdata, &data, p->size);
         else 
             p->u.data = (u64)data;
     }
@@ -533,8 +547,9 @@ static int intercept_elcr_io(ioreq_t *p)
 
     s = &v->domain->arch.hvm_domain.vpic;
     if ( p->dir == 0 ) {
-        if(p->pdata_valid) 
-            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_IN);
+        if (p->pdata_valid) 
+            (void)hvm_copy_from_guest_virt(
+                &data, (unsigned long)p->u.pdata, p->size);
         else
             data = p->u.data;
         spin_lock_irqsave(&s->lock, flags);
@@ -547,8 +562,9 @@ static int intercept_elcr_io(ioreq_t *p)
     else {
         data = (u64) elcr_ioport_read(
                 (void*)&s->pics[p->addr&1], (uint32_t) p->addr);
-        if(p->pdata_valid) 
-            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_OUT);
+        if (p->pdata_valid) 
+            (void)hvm_copy_to_guest_virt(
+                (unsigned long)p->u.pdata, &data, p->size);
         else 
             p->u.data = (u64)data;
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/instrlen.c
--- a/xen/arch/x86/hvm/instrlen.c       Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/instrlen.c       Sun Oct 01 19:10:18 2006 -0600
@@ -196,26 +196,17 @@ static uint8_t twobyte_table[256] = {
 
 /* 
  * insn_fetch - fetch the next 1 to 4 bytes from instruction stream 
- * 
  * @_type:   u8, u16, u32, s8, s16, or s32
  * @_size:   1, 2, or 4 bytes
- * @_eip:    address to fetch from guest memory
- * @_length: increments the current instruction length counter by _size
- *
- * This is used internally by hvm_instruction_length to fetch the next byte,
- * word, or dword from guest memory at location _eip.  we currently use a local
- * unsigned long as the storage buffer since the most bytes we're gonna get
- * is limited to 4.
- */
-#define insn_fetch(_type, _size, _eip, _length)                         \
-({  unsigned long _x;                                                   \
-        if ((rc = inst_copy_from_guest((unsigned char *)(&(_x)),        \
-                (unsigned long)(_eip), _size))                          \
-                    != _size)                                           \
-        goto done;                                                      \
-    (_eip) += (_size);                                                  \
-    (_length) += (_size);                                               \
-    (_type)_x;                                                          \
+ */
+#define insn_fetch(_type, _size)                                        \
+({ unsigned long _x, _ptr = _regs.eip;                                  \
+   if ( mode == X86EMUL_MODE_REAL ) _ptr += _regs.cs << 4;              \
+   rc = inst_copy_from_guest((unsigned char *)(&(_x)), _ptr, _size);    \
+   if ( rc != _size ) goto done;                                        \
+   _regs.eip += (_size);                                                \
+   length += (_size);                                                   \
+   (_type)_x;                                                           \
 })
 
 /**
@@ -231,17 +222,13 @@ int hvm_instruction_length(struct cpu_us
 {
     uint8_t b, d, twobyte = 0, rex_prefix = 0;
     uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
-    unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
+    unsigned int op_bytes, ad_bytes, i;
     int rc = 0;
     int length = 0;
     unsigned int tmp;
 
     /* Shadow copy of register state. Committed on successful emulation. */
     struct cpu_user_regs _regs = *regs;
-
-    /* include CS for 16-bit modes */
-    if (mode == X86EMUL_MODE_REAL || mode == X86EMUL_MODE_PROT16)
-        _regs.eip += (_regs.cs << 4);
 
     switch ( mode )
     {
@@ -265,7 +252,7 @@ int hvm_instruction_length(struct cpu_us
     /* Legacy prefixes. */
     for ( i = 0; i < 8; i++ )
     {
-        switch ( b = insn_fetch(uint8_t, 1, _regs.eip, length) )
+        switch ( b = insn_fetch(uint8_t, 1) )
         {
         case 0x66: /* operand-size override */
             op_bytes ^= 6;      /* switch between 2/4 bytes */
@@ -282,13 +269,8 @@ int hvm_instruction_length(struct cpu_us
         case 0x64: /* FS override */
         case 0x65: /* GS override */
         case 0x36: /* SS override */
-            break;
         case 0xf0: /* LOCK */
-            lock_prefix = 1;
-            break;
         case 0xf3: /* REP/REPE/REPZ */
-            rep_prefix = 1;
-            break;
         case 0xf2: /* REPNE/REPNZ */
             break;
         default:
@@ -296,12 +278,6 @@ int hvm_instruction_length(struct cpu_us
         }
     }
 done_prefixes:
-
-    /* Note quite the same as 80386 real mode, but hopefully good enough. */
-    if ( (mode == X86EMUL_MODE_REAL) && (ad_bytes != 2) ) {
-        printf("sonofabitch!! we don't support 32-bit addresses in 
realmode\n");
-        goto cannot_emulate;
-    }
 
     /* REX prefix. */
     if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) )
@@ -311,7 +287,7 @@ done_prefixes:
             op_bytes = 8;          /* REX.W */
         modrm_reg = (b & 4) << 1;  /* REX.R */
         /* REX.B and REX.X do not need to be decoded. */
-        b = insn_fetch(uint8_t, 1, _regs.eip, length);
+        b = insn_fetch(uint8_t, 1);
     }
 
     /* Opcode byte(s). */
@@ -322,7 +298,7 @@ done_prefixes:
         if ( b == 0x0f )
         {
             twobyte = 1;
-            b = insn_fetch(uint8_t, 1, _regs.eip, length);
+            b = insn_fetch(uint8_t, 1);
             d = twobyte_table[b];
         }
 
@@ -334,7 +310,7 @@ done_prefixes:
     /* ModRM and SIB bytes. */
     if ( d & ModRM )
     {
-        modrm = insn_fetch(uint8_t, 1, _regs.eip, length);
+        modrm = insn_fetch(uint8_t, 1);
         modrm_mod |= (modrm & 0xc0) >> 6;
         modrm_reg |= (modrm & 0x38) >> 3;
         modrm_rm  |= (modrm & 0x07);
@@ -374,7 +350,7 @@ done_prefixes:
             {
             case 0:
                 if ( (modrm_rm == 4) && 
-                     (((insn_fetch(uint8_t, 1, _regs.eip, length)) & 7) 
+                     (((insn_fetch(uint8_t, 1)) & 7) 
                         == 5) )
                 {
                     length += 4;
@@ -389,7 +365,7 @@ done_prefixes:
             case 1:
                 if ( modrm_rm == 4 )
                 {
-                    insn_fetch(uint8_t, 1, _regs.eip, length);
+                    insn_fetch(uint8_t, 1);
                 }
                 length += 1;
                 _regs.eip += 1; /* skip disp8 */
@@ -397,7 +373,7 @@ done_prefixes:
             case 2:
                 if ( modrm_rm == 4 )
                 {
-                    insn_fetch(uint8_t, 1, _regs.eip, length);
+                    insn_fetch(uint8_t, 1);
                 }
                 length += 4;
                 _regs.eip += 4; /* skip disp32 */
@@ -423,13 +399,13 @@ done_prefixes:
         /* NB. Immediates are sign-extended as necessary. */
         switch ( tmp )
         {
-        case 1: insn_fetch(int8_t,  1, _regs.eip, length); break;
-        case 2: insn_fetch(int16_t, 2, _regs.eip, length); break;
-        case 4: insn_fetch(int32_t, 4, _regs.eip, length); break;
+        case 1: insn_fetch(int8_t,  1); break;
+        case 2: insn_fetch(int16_t, 2); break;
+        case 4: insn_fetch(int32_t, 4); break;
         }
         break;
     case SrcImmByte:
-        insn_fetch(int8_t,  1, _regs.eip, length);
+        insn_fetch(int8_t,  1);
         break;
     }
 
@@ -455,9 +431,9 @@ done_prefixes:
             if ( tmp == 8 ) tmp = 4;
             switch ( tmp )
             {
-            case 1: insn_fetch(int8_t,  1, _regs.eip, length); break;
-            case 2: insn_fetch(int16_t, 2, _regs.eip, length); break;
-            case 4: insn_fetch(int32_t, 4, _regs.eip, length); break;
+            case 1: insn_fetch(int8_t,  1); break;
+            case 2: insn_fetch(int16_t, 2); break;
+            case 4: insn_fetch(int32_t, 4); break;
             }
             goto done;
         }
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c      Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/intercept.c      Sun Oct 01 19:10:18 2006 -0600
@@ -90,17 +90,17 @@ static inline void hvm_mmio_access(struc
                     data = read_handler(v,
                       req->addr + (sign * i * req->size),
                       req->size);
-                    hvm_copy(&data,
-                      (unsigned long)p->u.pdata + (sign * i * req->size),
-                      p->size,
-                      HVM_COPY_OUT);
+                    (void)hvm_copy_to_guest_virt(
+                        (unsigned long)p->u.pdata + (sign * i * req->size),
+                        &data,
+                        p->size);
                 }
             } else {                  /* !req->dir == IOREQ_READ */
                 for (i = 0; i < req->count; i++) {
-                    hvm_copy(&data,
-                      (unsigned long)p->u.pdata + (sign * i * req->size),
-                      p->size,
-                      HVM_COPY_IN);
+                    (void)hvm_copy_from_guest_virt(
+                        &data,
+                        (unsigned long)p->u.pdata + (sign * i * req->size),
+                        p->size);
                     write_handler(v,
                       req->addr + (sign * i * req->size),
                       req->size, data);
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/io.c     Sun Oct 01 19:10:18 2006 -0600
@@ -379,7 +379,7 @@ static void hvm_pio_assist(struct cpu_us
                     addr += regs->es << 4;
                 if (sign > 0)
                     addr -= p->size;
-                hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
+                (void)hvm_copy_to_guest_virt(addr, &p->u.data, p->size);
             }
         }
         else /* p->dir == IOREQ_WRITE */
@@ -493,7 +493,7 @@ static void hvm_mmio_assist(struct cpu_u
 
             if (sign > 0)
                 addr -= p->size;
-            hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
+            (void)hvm_copy_to_guest_virt(addr, &p->u.data, p->size);
         }
 
         if (mmio_opp->flags & REPZ)
@@ -596,6 +596,7 @@ static void hvm_mmio_assist(struct cpu_u
         break;
 
     case INSTR_CMP:
+    case INSTR_SUB:
         if (src & REGISTER) {
             index = operand_index(src);
             value = get_reg_value(size, index, 0, regs);
@@ -607,6 +608,8 @@ static void hvm_mmio_assist(struct cpu_u
             index = operand_index(dst);
             value = get_reg_value(size, index, 0, regs);
             diff = value - (unsigned long) p->u.data;
+            if ( mmio_opp->instr == INSTR_SUB )
+                set_reg_value(size, index, 0, regs, diff);
         }
 
         /*
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/platform.c       Sun Oct 01 19:10:18 2006 -0600
@@ -394,6 +394,11 @@ static int hvm_decode(int realmode, unsi
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         return mem_reg(instr->op_size, opcode, instr, rex);
 
+    case 0x2B: /* sub m32/16, r32/16 */
+        instr->instr = INSTR_SUB;
+        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+        return mem_reg(instr->op_size, opcode, instr, rex);
+
     case 0x30: /* xor r8, m8 */
         instr->instr = INSTR_XOR;
         instr->op_size = BYTE;
@@ -689,7 +694,7 @@ int inst_copy_from_guest(unsigned char *
 {
     if (inst_len > MAX_INST_LEN || inst_len <= 0)
         return 0;
-    if (!hvm_copy(buf, guest_eip, inst_len, HVM_COPY_IN))
+    if (hvm_copy_from_guest_virt(buf, guest_eip, inst_len))
         return 0;
     return inst_len;
 }
@@ -953,7 +958,7 @@ void handle_mmio(unsigned long va, unsig
             regs->eip -= inst_len; /* do not advance %eip */
 
             if (dir == IOREQ_WRITE)
-                hvm_copy(&value, addr, size, HVM_COPY_IN);
+                (void)hvm_copy_from_guest_virt(&value, addr, size);
             send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, size, value, dir, 0);
         } else {
             if ((addr & PAGE_MASK) != ((addr + sign * (count * size - 1)) & 
PAGE_MASK)) {
@@ -1011,6 +1016,7 @@ void handle_mmio(unsigned long va, unsig
 
     case INSTR_CMP:        /* Pass through */
     case INSTR_TEST:
+    case INSTR_SUB:
         mmio_opp->flags = mmio_inst.flags;
         mmio_opp->instr = mmio_inst.instr;
         mmio_opp->operand[0] = mmio_inst.operand[0]; /* source */
@@ -1094,7 +1100,7 @@ unsigned long copy_to_user_hvm(void *to,
         return 0;
     }
 
-    return !hvm_copy((void *)from, (unsigned long)to, len, HVM_COPY_OUT);
+    return hvm_copy_to_guest_virt((unsigned long)to, (void *)from, len);
 }
 
 unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len)
@@ -1105,7 +1111,7 @@ unsigned long copy_from_user_hvm(void *t
         return 0;
     }
 
-    return !hvm_copy(to, (unsigned long)from, len, HVM_COPY_IN);
+    return hvm_copy_from_guest_virt(to, (unsigned long)from, len);
 }
 
 /*
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/svm/emulate.c
--- a/xen/arch/x86/hvm/svm/emulate.c    Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/svm/emulate.c    Sun Oct 01 19:10:18 2006 -0600
@@ -341,7 +341,11 @@ unsigned long svm_rip2pointer(struct vmc
      * %cs is update, but fortunately, base contain the valid base address
      * no matter what kind of addressing is used.
      */
-    return vmcb->cs.base + vmcb->rip;
+    unsigned long p = vmcb->cs.base + vmcb->rip;
+    if (!(vmcb->cs.attributes.fields.l && vmcb->efer & EFER_LMA))
+        return (u32)p; /* mask to 32 bits */
+    /* NB. Should mask to 16 bits if in real mode or 16-bit protected mode. */
+    return p;
 }
 
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c       Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/svm/intr.c       Sun Oct 01 19:10:18 2006 -0600
@@ -74,7 +74,6 @@ asmlinkage void svm_intr_assist(void)
     int intr_type = APIC_DM_EXTINT;
     int intr_vector = -1;
     int re_injecting = 0;
-    unsigned long rflags;
 
     ASSERT(vmcb);
 
@@ -87,14 +86,6 @@ asmlinkage void svm_intr_assist(void)
         re_injecting = 1;
     }
 
-    /* Guest's interrputs masked? */
-    rflags = vmcb->rflags;
-    if (irq_masked(rflags)) {
-        HVM_DBG_LOG(DBG_LEVEL_1, "Guest IRQs masked: rflags: %lx", rflags);
-        /* bail out, we won't be injecting an interrupt this time */
-        return;
-    }
-    
     /* Previous interrupt still pending? */
     if (vmcb->vintr.fields.irq) {
 //        printk("Re-injecting IRQ from Vintr\n");
@@ -121,13 +112,11 @@ asmlinkage void svm_intr_assist(void)
           pic_set_irq(pic, pt->irq, 1);
       }
 
-      callback_irq = v->domain->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
-      if ( callback_irq != 0 &&
-           local_events_need_delivery() ) {
-          /*inject para-device call back irq*/
-          v->vcpu_info->evtchn_upcall_mask = 1;
-          pic_set_irq(pic, callback_irq, 0);
-          pic_set_irq(pic, callback_irq, 1);
+      if (v->vcpu_id == 0) {
+          callback_irq =
+              v->domain->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
+          if ( callback_irq != 0)
+              pic_set_xen_irq(pic, callback_irq, local_events_need_delivery());
       }
 
       if ( cpu_has_pending_irq(v) )
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Sun Oct 01 19:10:18 2006 -0600
@@ -57,7 +57,7 @@ extern void do_nmi(struct cpu_user_regs 
 extern void do_nmi(struct cpu_user_regs *, unsigned long);
 extern int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
                                 int inst_len);
- extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
+extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
 extern asmlinkage void do_IRQ(struct cpu_user_regs *);
 extern void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
                          unsigned long count, int size, long value, int dir, 
int pvalid);
@@ -282,7 +282,7 @@ static inline int long_mode_do_msr_read(
     switch (regs->ecx)
     {
     case MSR_EFER:
-        msr_content = vmcb->efer;      
+        msr_content = vmcb->efer;
         msr_content &= ~EFER_SVME;
         break;
 
@@ -320,14 +320,14 @@ static inline int long_mode_do_msr_read(
     HVM_DBG_LOG(DBG_LEVEL_2, "mode_do_msr_read: msr_content: %"PRIx64"\n", 
                 msr_content);
 
-    regs->eax = msr_content & 0xffffffff;
-    regs->edx = msr_content >> 32;
+    regs->eax = (u32)(msr_content >>  0);
+    regs->edx = (u32)(msr_content >> 32);
     return 1;
 }
 
 static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
 {
-    u64 msr_content = regs->eax | ((u64)regs->edx << 32);
+    u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
     struct vcpu *vc = current;
     struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
 
@@ -342,7 +342,8 @@ static inline int long_mode_do_msr_write
         /* offending reserved bit will cause #GP */
         if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
         {
-            printk("trying to set reserved bit in EFER\n");
+            printk("Trying to set reserved bit in EFER: %"PRIx64"\n",
+                   msr_content);
             svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
             return 0;
         }
@@ -355,7 +356,7 @@ static inline int long_mode_do_msr_write
                  !test_bit(SVM_CPU_STATE_PAE_ENABLED,
                            &vc->arch.hvm_svm.cpu_state) )
             {
-                printk("trying to set LME bit when "
+                printk("Trying to set LME bit when "
                        "in paging mode or PAE bit is not set\n");
                 svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
                 return 0;
@@ -903,9 +904,9 @@ static void svm_relinquish_guest_resourc
 
         destroy_vmcb(&v->arch.hvm_svm);
         kill_timer(&v->arch.hvm_vcpu.hlt_timer);
-        if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) ) 
-        {
-            kill_timer( &(VLAPIC(v)->vlapic_timer) );
+        if ( VLAPIC(v) != NULL )
+        {
+            kill_timer(&VLAPIC(v)->vlapic_timer);
             unmap_domain_page_global(VLAPIC(v)->regs);
             free_domheap_page(VLAPIC(v)->regs_page);
             xfree(VLAPIC(v));
@@ -929,12 +930,13 @@ static void svm_migrate_timers(struct vc
     struct periodic_time *pt = 
         &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
 
-    if ( pt->enabled ) {
-        migrate_timer( &pt->timer, v->processor );
-        migrate_timer( &v->arch.hvm_vcpu.hlt_timer, v->processor );
-    }
-    if ( hvm_apic_support(v->domain) && VLAPIC( v ))
-        migrate_timer( &(VLAPIC(v)->vlapic_timer ), v->processor );
+    if ( pt->enabled )
+    {
+        migrate_timer(&pt->timer, v->processor);
+        migrate_timer(&v->arch.hvm_vcpu.hlt_timer, v->processor);
+    }
+    if ( VLAPIC(v) != NULL )
+        migrate_timer(&VLAPIC(v)->vlapic_timer, v->processor);
 }
 
 
@@ -1075,9 +1077,6 @@ static void svm_vmexit_do_cpuid(struct v
                    clear_bit(X86_FEATURE_NX & 31, &edx);
             }
             clear_bit(X86_FEATURE_PSE36, &edx);
-            /* Disable machine check architecture */
-            clear_bit(X86_FEATURE_MCA, &edx);
-            clear_bit(X86_FEATURE_MCE, &edx);
             if (input == 0x00000001 )
             {
                 /* Clear out reserved bits. */
@@ -1470,7 +1469,7 @@ static void svm_io_instruction(struct vc
             pio_opp->flags |= OVERLAP;
 
             if (dir == IOREQ_WRITE)
-                hvm_copy(&value, addr, size, HVM_COPY_IN);
+                (void)hvm_copy_from_guest_virt(&value, addr, size);
 
             send_pio_req(regs, port, 1, size, value, dir, 0);
         } 
@@ -1636,9 +1635,11 @@ static void mov_from_cr(int cr, int gp, 
     case 4:
         value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr4;
         if (svm_dbg_on)
-            printk( "CR4 read=%lx\n", value );
+            printk("CR4 read=%lx\n", value);
         break;
     case 8:
+        if ( vlapic == NULL )
+            break;
         value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
         value = (value & 0xF0) >> 4;
         break;
@@ -1816,6 +1817,8 @@ static int mov_to_cr(int gpreg, int cr, 
 
     case 8:
     {
+        if ( vlapic == NULL )
+            break;
         vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
         vlapic_update_ppr(vlapic);
         break;
@@ -1997,7 +2000,7 @@ static inline void svm_do_msr_access(
     else
     {
         inst_len = __get_instruction_length(vmcb, INSTR_WRMSR, NULL);
-        msr_content = (regs->eax & 0xFFFFFFFF) | ((u64)regs->edx << 32);
+        msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
 
         switch (regs->ecx)
         {
@@ -2324,7 +2327,7 @@ void svm_dump_inst(unsigned long eip)
     ptr = eip & ~0xff;
     len = 0;
 
-    if (hvm_copy(opcode, ptr, sizeof(opcode), HVM_COPY_IN))
+    if (hvm_copy_from_guest_virt(opcode, ptr, sizeof(opcode)) == 0)
         len = sizeof(opcode);
 
     printf("Code bytes around(len=%d) %lx:", len, eip);
@@ -2563,9 +2566,7 @@ void walk_shadow_and_guest_pt(unsigned l
 #endif /* SVM_WALK_GUEST_PAGES */
 
 
-
-
-asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
+asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
 {
     unsigned int exit_reason;
     unsigned long eip;
@@ -2577,7 +2578,7 @@ asmlinkage void svm_vmexit_handler(struc
     ASSERT(vmcb);
 
     exit_reason = vmcb->exitcode;
-    save_svm_cpu_user_regs(v, &regs);
+    save_svm_cpu_user_regs(v, regs);
 
     vmcb->tlb_control = 1;
 
@@ -2601,26 +2602,26 @@ asmlinkage void svm_vmexit_handler(struc
             if (svm_paging_enabled(v) && 
                 !mmio_space(shadow_gva_to_gpa(current, vmcb->exitinfo2)))
             {
-                printk("I%08ld,ExC=%s(%d),IP=%x:%llx,"
-                       "I1=%llx,I2=%llx,INT=%llx, "
-                       "gpa=%llx\n", intercepts_counter,
-                       exit_reasons[exit_reason], exit_reason, regs.cs,
-                       (unsigned long long) regs.rip,
-                       (unsigned long long) vmcb->exitinfo1,
-                       (unsigned long long) vmcb->exitinfo2,
-                       (unsigned long long) vmcb->exitintinfo.bytes,
-                       (unsigned long long) shadow_gva_to_gpa(current, 
vmcb->exitinfo2));
+                printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
+                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64", "
+                       "gpa=%"PRIx64"\n", intercepts_counter,
+                       exit_reasons[exit_reason], exit_reason, regs->cs,
+                       (u64)regs->rip,
+                       (u64)vmcb->exitinfo1,
+                       (u64)vmcb->exitinfo2,
+                       (u64)vmcb->exitintinfo.bytes,
+                       (u64)shadow_gva_to_gpa(current, vmcb->exitinfo2));
             }
             else 
             {
-                printk("I%08ld,ExC=%s(%d),IP=%x:%llx,"
-                       "I1=%llx,I2=%llx,INT=%llx\n", 
+                printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
+                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n", 
                        intercepts_counter,
-                       exit_reasons[exit_reason], exit_reason, regs.cs,
-                       (unsigned long long) regs.rip,
-                       (unsigned long long) vmcb->exitinfo1,
-                       (unsigned long long) vmcb->exitinfo2,
-                       (unsigned long long) vmcb->exitintinfo.bytes );
+                       exit_reasons[exit_reason], exit_reason, regs->cs,
+                       (u64)regs->rip,
+                       (u64)vmcb->exitinfo1,
+                       (u64)vmcb->exitinfo2,
+                       (u64)vmcb->exitintinfo.bytes );
             }
         } 
         else if ( svm_dbg_on 
@@ -2630,24 +2631,24 @@ asmlinkage void svm_vmexit_handler(struc
 
             if (exit_reasons[exit_reason])
             {
-                printk("I%08ld,ExC=%s(%d),IP=%x:%llx,"
-                       "I1=%llx,I2=%llx,INT=%llx\n", 
+                printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
+                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n", 
                        intercepts_counter,
-                       exit_reasons[exit_reason], exit_reason, regs.cs,
-                       (unsigned long long) regs.rip,
-                       (unsigned long long) vmcb->exitinfo1,
-                       (unsigned long long) vmcb->exitinfo2,
-                       (unsigned long long) vmcb->exitintinfo.bytes);
+                       exit_reasons[exit_reason], exit_reason, regs->cs,
+                       (u64)regs->rip,
+                       (u64)vmcb->exitinfo1,
+                       (u64)vmcb->exitinfo2,
+                       (u64)vmcb->exitintinfo.bytes);
             } 
             else 
             {
-                printk("I%08ld,ExC=%d(0x%x),IP=%x:%llx,"
-                       "I1=%llx,I2=%llx,INT=%llx\n", 
-                       intercepts_counter, exit_reason, exit_reason, regs.cs, 
-                       (unsigned long long) regs.rip,
-                       (unsigned long long) vmcb->exitinfo1,
-                       (unsigned long long) vmcb->exitinfo2,
-                       (unsigned long long) vmcb->exitintinfo.bytes);
+                printk("I%08ld,ExC=%d(0x%x),IP=%x:%"PRIx64","
+                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n", 
+                       intercepts_counter, exit_reason, exit_reason, regs->cs, 
+                       (u64)regs->rip,
+                       (u64)vmcb->exitinfo1,
+                       (u64)vmcb->exitinfo2,
+                       (u64)vmcb->exitintinfo.bytes);
             }
         }
 
@@ -2679,7 +2680,7 @@ asmlinkage void svm_vmexit_handler(struc
                    (int) v->arch.shadow_table.pfn);
 
             svm_dump_vmcb(__func__, vmcb);
-            svm_dump_regs(__func__, &regs);
+            svm_dump_regs(__func__, regs);
             svm_dump_inst(svm_rip2pointer(vmcb));
         }
 
@@ -2709,18 +2710,18 @@ asmlinkage void svm_vmexit_handler(struc
     case VMEXIT_EXCEPTION_DB:
     {
 #ifdef XEN_DEBUGGER
-        svm_debug_save_cpu_user_regs(&regs);
-        pdb_handle_exception(1, &regs, 1);
-        svm_debug_restore_cpu_user_regs(&regs);
+        svm_debug_save_cpu_user_regs(regs);
+        pdb_handle_exception(1, regs, 1);
+        svm_debug_restore_cpu_user_regs(regs);
 #else
-        svm_store_cpu_user_regs(&regs, v);
+        svm_store_cpu_user_regs(regs, v);
         domain_pause_for_debugger();  
 #endif
     }
     break;
 
     case VMEXIT_NMI:
-        do_nmi(&regs, 0);
+        do_nmi(regs, 0);
         break;
 
     case VMEXIT_SMI:
@@ -2740,9 +2741,9 @@ asmlinkage void svm_vmexit_handler(struc
 
     case VMEXIT_EXCEPTION_BP:
 #ifdef XEN_DEBUGGER
-        svm_debug_save_cpu_user_regs(&regs);
-        pdb_handle_exception(3, &regs, 1);
-        svm_debug_restore_cpu_user_regs(&regs);
+        svm_debug_save_cpu_user_regs(regs);
+        pdb_handle_exception(3, regs, 1);
+        svm_debug_restore_cpu_user_regs(regs);
 #else
         if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
             domain_pause_for_debugger();
@@ -2757,25 +2758,25 @@ asmlinkage void svm_vmexit_handler(struc
 
     case VMEXIT_EXCEPTION_GP:
         /* This should probably not be trapped in the future */
-        regs.error_code = vmcb->exitinfo1;
-        svm_do_general_protection_fault(v, &regs);
+        regs->error_code = vmcb->exitinfo1;
+        svm_do_general_protection_fault(v, regs);
         break;  
 
     case VMEXIT_EXCEPTION_PF:
     {
         unsigned long va;
         va = vmcb->exitinfo2;
-        regs.error_code = vmcb->exitinfo1;
+        regs->error_code = vmcb->exitinfo1;
         HVM_DBG_LOG(DBG_LEVEL_VMMU, 
                     "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
-                    (unsigned long)regs.eax, (unsigned long)regs.ebx,
-                    (unsigned long)regs.ecx, (unsigned long)regs.edx,
-                    (unsigned long)regs.esi, (unsigned long)regs.edi);
-
-        if (!(error = svm_do_page_fault(va, &regs))) 
+                    (unsigned long)regs->eax, (unsigned long)regs->ebx,
+                    (unsigned long)regs->ecx, (unsigned long)regs->edx,
+                    (unsigned long)regs->esi, (unsigned long)regs->edi);
+
+        if (!(error = svm_do_page_fault(va, regs))) 
         {
             /* Inject #PG using Interruption-Information Fields */
-            svm_inject_exception(v, TRAP_page_fault, 1, regs.error_code);
+            svm_inject_exception(v, TRAP_page_fault, 1, regs->error_code);
 
             v->arch.hvm_svm.cpu_cr2 = va;
             vmcb->cr2 = va;
@@ -2788,7 +2789,7 @@ asmlinkage void svm_vmexit_handler(struc
     case VMEXIT_EXCEPTION_DF:
         /* Debug info to hopefully help debug WHY the guest double-faulted. */
         svm_dump_vmcb(__func__, vmcb);
-        svm_dump_regs(__func__, &regs);
+        svm_dump_regs(__func__, regs);
         svm_dump_inst(svm_rip2pointer(vmcb));
         svm_inject_exception(v, TRAP_double_fault, 1, 0);
         break;
@@ -2805,11 +2806,11 @@ asmlinkage void svm_vmexit_handler(struc
         break;
 
     case VMEXIT_TASK_SWITCH:
-        __hvm_bug(&regs);
+        __hvm_bug(regs);
         break;
 
     case VMEXIT_CPUID:
-        svm_vmexit_do_cpuid(vmcb, regs.eax, &regs);
+        svm_vmexit_do_cpuid(vmcb, regs->eax, regs);
         break;
 
     case VMEXIT_HLT:
@@ -2817,60 +2818,60 @@ asmlinkage void svm_vmexit_handler(struc
         break;
 
     case VMEXIT_INVLPG:
-        svm_handle_invlpg(0, &regs);
+        svm_handle_invlpg(0, regs);
         break;
 
     case VMEXIT_INVLPGA:
-        svm_handle_invlpg(1, &regs);
+        svm_handle_invlpg(1, regs);
         break;
 
     case VMEXIT_VMMCALL:
-        svm_do_vmmcall(v, &regs);
+        svm_do_vmmcall(v, regs);
         break;
 
     case VMEXIT_CR0_READ:
-        svm_cr_access(v, 0, TYPE_MOV_FROM_CR, &regs);
+        svm_cr_access(v, 0, TYPE_MOV_FROM_CR, regs);
         break;
 
     case VMEXIT_CR2_READ:
-        svm_cr_access(v, 2, TYPE_MOV_FROM_CR, &regs);
+        svm_cr_access(v, 2, TYPE_MOV_FROM_CR, regs);
         break;
 
     case VMEXIT_CR3_READ:
-        svm_cr_access(v, 3, TYPE_MOV_FROM_CR, &regs);
+        svm_cr_access(v, 3, TYPE_MOV_FROM_CR, regs);
         break;
 
     case VMEXIT_CR4_READ:
-        svm_cr_access(v, 4, TYPE_MOV_FROM_CR, &regs);
+        svm_cr_access(v, 4, TYPE_MOV_FROM_CR, regs);
         break;
 
     case VMEXIT_CR8_READ:
-        svm_cr_access(v, 8, TYPE_MOV_FROM_CR, &regs);
+        svm_cr_access(v, 8, TYPE_MOV_FROM_CR, regs);
         break;
 
     case VMEXIT_CR0_WRITE:
-        svm_cr_access(v, 0, TYPE_MOV_TO_CR, &regs);
+        svm_cr_access(v, 0, TYPE_MOV_TO_CR, regs);
         break;
 
     case VMEXIT_CR2_WRITE:
-        svm_cr_access(v, 2, TYPE_MOV_TO_CR, &regs);
+        svm_cr_access(v, 2, TYPE_MOV_TO_CR, regs);
         break;
 
     case VMEXIT_CR3_WRITE:
-        svm_cr_access(v, 3, TYPE_MOV_TO_CR, &regs);
+        svm_cr_access(v, 3, TYPE_MOV_TO_CR, regs);
         local_flush_tlb();
         break;
 
     case VMEXIT_CR4_WRITE:
-        svm_cr_access(v, 4, TYPE_MOV_TO_CR, &regs);
+        svm_cr_access(v, 4, TYPE_MOV_TO_CR, regs);
         break;
 
     case VMEXIT_CR8_WRITE:
-        svm_cr_access(v, 8, TYPE_MOV_TO_CR, &regs);
+        svm_cr_access(v, 8, TYPE_MOV_TO_CR, regs);
         break;
        
     case VMEXIT_DR0_WRITE ... VMEXIT_DR7_WRITE:
-        svm_dr_access(v, &regs);
+        svm_dr_access(v, regs);
         break;
 
     case VMEXIT_IOIO:
@@ -2878,7 +2879,7 @@ asmlinkage void svm_vmexit_handler(struc
         break;
 
     case VMEXIT_MSR:
-        svm_do_msr_access(v, &regs);
+        svm_do_msr_access(v, regs);
         break;
 
     case VMEXIT_SHUTDOWN:
@@ -2887,11 +2888,10 @@ asmlinkage void svm_vmexit_handler(struc
         break;
 
     default:
-        printk("unexpected VMEXIT: exit reason = 0x%x, exitinfo1 = %llx, "
-               "exitinfo2 = %llx\n", exit_reason, 
-               (unsigned long long)vmcb->exitinfo1, 
-               (unsigned long long)vmcb->exitinfo2);
-        __hvm_bug(&regs);       /* should not happen */
+        printk("unexpected VMEXIT: exit reason = 0x%x, exitinfo1 = %"PRIx64", "
+               "exitinfo2 = %"PRIx64"\n", exit_reason, 
+               (u64)vmcb->exitinfo1, (u64)vmcb->exitinfo2);
+        __hvm_bug(regs);       /* should not happen */
         break;
     }
 
@@ -2899,7 +2899,7 @@ asmlinkage void svm_vmexit_handler(struc
     if (do_debug) 
     {
         printk("%s: Done switch on vmexit_code\n", __func__);
-        svm_dump_regs(__func__, &regs);
+        svm_dump_regs(__func__, regs);
     }
 
     if (do_debug) 
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/svm/x86_32/exits.S
--- a/xen/arch/x86/hvm/svm/x86_32/exits.S       Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/svm/x86_32/exits.S       Sun Oct 01 19:10:18 2006 -0600
@@ -126,7 +126,10 @@ ENTRY(svm_asm_do_launch)
 
         HVM_SAVE_ALL_NOSEGREGS
         STGI
+        movl %esp,%eax
+        push %eax
         call svm_vmexit_handler
+        addl $4,%esp
         jmp  svm_asm_do_resume
 
         ALIGN
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/svm/x86_64/exits.S
--- a/xen/arch/x86/hvm/svm/x86_64/exits.S       Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/svm/x86_64/exits.S       Sun Oct 01 19:10:18 2006 -0600
@@ -144,6 +144,7 @@ ENTRY(svm_asm_do_launch)
         VMLOAD
 
         STGI
+        movq %rsp,%rdi
         call svm_vmexit_handler
         jmp  svm_asm_do_resume
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/vioapic.c        Sun Oct 01 19:10:18 2006 -0600
@@ -479,7 +479,7 @@ static void ioapic_deliver(hvm_vioapic_t
 
 static int ioapic_get_highest_irq(hvm_vioapic_t *s)
 {
-    uint32_t irqs = s->irr & ~s->isr & ~s->imr;
+    uint32_t irqs = (s->irr | s->irr_xen) & ~s->isr & ~s->imr;
     return fls(irqs) - 1;
 }
 
@@ -501,6 +501,7 @@ static void service_ioapic(hvm_vioapic_t
         }
 
         s->irr &= ~(1 << irqno);
+       s->irr_xen &= ~(1 << irqno);
     }
 }
 
@@ -524,6 +525,25 @@ void hvm_vioapic_do_irqs_clear(struct do
 
     s->irr &= ~irqs;
     service_ioapic(s);
+}
+
+void hvm_vioapic_set_xen_irq(struct domain *d, int irq, int level)
+{
+    hvm_vioapic_t *s = &d->arch.hvm_domain.vioapic;
+
+    if (!hvm_apic_support(d) || !IOAPICEnabled(s) ||
+       s->redirtbl[irq].RedirForm.mask)
+        return;
+
+    if (s->redirtbl[irq].RedirForm.trigmod != IOAPIC_LEVEL_TRIGGER) {
+       DPRINTK("Forcing edge triggered APIC irq %d?\n", irq);
+       domain_crash(d);
+    }
+
+    if (level)
+       s->irr_xen |= 1 << irq;
+    else
+       s->irr_xen &= ~(1 << irq);
 }
 
 void hvm_vioapic_set_irq(struct domain *d, int irq, int level)
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/io.c Sun Oct 01 19:10:18 2006 -0600
@@ -78,7 +78,6 @@ asmlinkage void vmx_intr_assist(void)
     struct hvm_domain *plat=&v->domain->arch.hvm_domain;
     struct periodic_time *pt = &plat->pl_time.periodic_tm;
     struct hvm_virpic *pic= &plat->vpic;
-    int callback_irq;
     unsigned int idtv_info_field;
     unsigned long inst_len;
     int    has_ext_irq;
@@ -91,13 +90,12 @@ asmlinkage void vmx_intr_assist(void)
         pic_set_irq(pic, pt->irq, 1);
     }
 
-    callback_irq = v->domain->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
-    if ( callback_irq != 0 &&
-         local_events_need_delivery() ) {
-        /*inject para-device call back irq*/
-        v->vcpu_info->evtchn_upcall_mask = 1;
-        pic_set_irq(pic, callback_irq, 0);
-        pic_set_irq(pic, callback_irq, 1);
+    if (v->vcpu_id == 0) {
+        int callback_irq;
+        callback_irq =
+            v->domain->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
+        if ( callback_irq != 0 )
+            pic_set_xen_irq(pic, callback_irq, local_events_need_delivery());
     }
 
     has_ext_irq = cpu_has_pending_irq(v);
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Sun Oct 01 19:10:18 2006 -0600
@@ -135,7 +135,7 @@ static void vmx_relinquish_guest_resourc
         if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
             continue;
         kill_timer(&v->arch.hvm_vcpu.hlt_timer);
-        if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
+        if ( VLAPIC(v) != NULL )
         {
             kill_timer(&VLAPIC(v)->vlapic_timer);
             unmap_domain_page_global(VLAPIC(v)->regs);
@@ -269,15 +269,15 @@ static inline int long_mode_do_msr_read(
 
     HVM_DBG_LOG(DBG_LEVEL_2, "msr_content: 0x%"PRIx64, msr_content);
 
-    regs->eax = msr_content & 0xffffffff;
-    regs->edx = msr_content >> 32;
+    regs->eax = (u32)(msr_content >>  0);
+    regs->edx = (u32)(msr_content >> 32);
 
     return 1;
 }
 
 static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
 {
-    u64 msr_content = regs->eax | ((u64)regs->edx << 32);
+    u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
     struct vcpu *v = current;
     struct vmx_msr_state *msr = &v->arch.hvm_vmx.msr_content;
     struct vmx_msr_state *host_state = &this_cpu(percpu_msr);
@@ -290,7 +290,8 @@ static inline int long_mode_do_msr_write
         /* offending reserved bit will cause #GP */
         if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
         {
-            printk("trying to set reserved bit in EFER\n");
+            printk("Trying to set reserved bit in EFER: %"PRIx64"\n",
+                   msr_content);
             vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
             return 0;
         }
@@ -303,7 +304,7 @@ static inline int long_mode_do_msr_write
                  !test_bit(VMX_CPU_STATE_PAE_ENABLED,
                            &v->arch.hvm_vmx.cpu_state) )
             {
-                printk("trying to set LME bit when "
+                printk("Trying to set LME bit when "
                        "in paging mode or PAE bit is not set\n");
                 vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
                 return 0;
@@ -484,20 +485,23 @@ static void vmx_ctxt_switch_to(struct vc
 
 static void stop_vmx(void)
 {
-    if (read_cr4() & X86_CR4_VMXE)
-        __vmxoff();
+    if ( !(read_cr4() & X86_CR4_VMXE) )
+        return;
+    __vmxoff();
+    clear_in_cr4(X86_CR4_VMXE);
 }
 
 void vmx_migrate_timers(struct vcpu *v)
 {
     struct periodic_time *pt = 
&(v->domain->arch.hvm_domain.pl_time.periodic_tm);
 
-    if ( pt->enabled ) {
+    if ( pt->enabled )
+    {
         migrate_timer(&pt->timer, v->processor);
         migrate_timer(&v->arch.hvm_vcpu.hlt_timer, v->processor);
     }
-    if ( hvm_apic_support(v->domain) && VLAPIC(v))
-        migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
+    if ( VLAPIC(v) != NULL )
+        migrate_timer(&VLAPIC(v)->vlapic_timer, v->processor);
 }
 
 static void vmx_store_cpu_guest_regs(
@@ -805,12 +809,14 @@ int start_vmx(void)
 
     if ( (vmcs = vmx_alloc_host_vmcs()) == NULL )
     {
+        clear_in_cr4(X86_CR4_VMXE);
         printk("Failed to allocate host VMCS\n");
         return 0;
     }
 
     if ( __vmxon(virt_to_maddr(vmcs)) )
     {
+        clear_in_cr4(X86_CR4_VMXE);
         printk("VMXON failed\n");
         vmx_free_host_vmcs(vmcs);
         return 0;
@@ -1163,7 +1169,7 @@ static void vmx_io_instruction(unsigned 
 
             pio_opp->flags |= OVERLAP;
             if (dir == IOREQ_WRITE)
-                hvm_copy(&value, addr, size, HVM_COPY_IN);
+                (void)hvm_copy_from_guest_virt(&value, addr, size);
             send_pio_req(regs, port, 1, size, value, dir, 0);
         } else {
             if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK)) 
{
@@ -1370,7 +1376,8 @@ static int vmx_assist(struct vcpu *v, in
     u32 cp;
 
     /* make sure vmxassist exists (this is not an error) */
-    if (!hvm_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), HVM_COPY_IN))
+    if (hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
+                                 sizeof(magic)))
         return 0;
     if (magic != VMXASSIST_MAGIC)
         return 0;
@@ -1384,20 +1391,20 @@ static int vmx_assist(struct vcpu *v, in
          */
     case VMX_ASSIST_INVOKE:
         /* save the old context */
-        if (!hvm_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
+        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)))
             goto error;
         if (cp != 0) {
             if (!vmx_world_save(v, &c))
                 goto error;
-            if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_OUT))
+            if (hvm_copy_to_guest_phys(cp, &c, sizeof(c)))
                 goto error;
         }
 
         /* restore the new context, this should activate vmxassist */
-        if (!hvm_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), HVM_COPY_IN))
+        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp)))
             goto error;
         if (cp != 0) {
-            if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_IN))
+            if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
                 goto error;
             if (!vmx_world_restore(v, &c))
                 goto error;
@@ -1411,10 +1418,10 @@ static int vmx_assist(struct vcpu *v, in
          */
     case VMX_ASSIST_RESTORE:
         /* save the old context */
-        if (!hvm_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
+        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)))
             goto error;
         if (cp != 0) {
-            if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_IN))
+            if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
                 goto error;
             if (!vmx_world_restore(v, &c))
                 goto error;
@@ -1761,6 +1768,8 @@ static int mov_to_cr(int gp, int cr, str
     }
     case 8:
     {
+        if ( vlapic == NULL )
+            break;
         vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
         vlapic_update_ppr(vlapic);
         break;
@@ -1782,15 +1791,19 @@ static void mov_from_cr(int cr, int gp, 
     struct vcpu *v = current;
     struct vlapic *vlapic = VLAPIC(v);
 
-    if ( cr != 3 && cr != 8)
-        __hvm_bug(regs);
-
-    if ( cr == 3 )
-        value = (unsigned long) v->arch.hvm_vmx.cpu_cr3;
-    else if ( cr == 8 )
-    {
+    switch ( cr )
+    {
+    case 3:
+        value = (unsigned long)v->arch.hvm_vmx.cpu_cr3;
+        break;
+    case 8:
+        if ( vlapic == NULL )
+            break;
         value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
         value = (value & 0xF0) >> 4;
+        break;
+    default:
+        __hvm_bug(regs);
     }
 
     switch ( gp ) {
@@ -1924,7 +1937,7 @@ static inline void vmx_do_msr_write(stru
                 (unsigned long)regs->ecx, (unsigned long)regs->eax,
                 (unsigned long)regs->edx);
 
-    msr_content = (regs->eax & 0xFFFFFFFF) | ((u64)regs->edx << 32);
+    msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
 
     switch (regs->ecx) {
     case MSR_IA32_TIME_STAMP_COUNTER:
@@ -2110,7 +2123,7 @@ static void vmx_reflect_exception(struct
     }
 }
 
-asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
+asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
 {
     unsigned int exit_reason;
     unsigned long exit_qualification, rip, inst_len = 0;
@@ -2181,16 +2194,16 @@ asmlinkage void vmx_vmexit_handler(struc
 #ifdef XEN_DEBUGGER
         case TRAP_debug:
         {
-            save_cpu_user_regs(&regs);
-            pdb_handle_exception(1, &regs, 1);
-            restore_cpu_user_regs(&regs);
+            save_cpu_user_regs(regs);
+            pdb_handle_exception(1, regs, 1);
+            restore_cpu_user_regs(regs);
             break;
         }
         case TRAP_int3:
         {
-            save_cpu_user_regs(&regs);
-            pdb_handle_exception(3, &regs, 1);
-            restore_cpu_user_regs(&regs);
+            save_cpu_user_regs(regs);
+            pdb_handle_exception(3, regs, 1);
+            restore_cpu_user_regs(regs);
             break;
         }
 #else
@@ -2200,7 +2213,7 @@ asmlinkage void vmx_vmexit_handler(struc
 
             if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
             {
-                store_cpu_user_regs(&regs);
+                store_cpu_user_regs(regs);
                 domain_pause_for_debugger();
                 __vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS,
                                PENDING_DEBUG_EXC_BS);
@@ -2231,29 +2244,29 @@ asmlinkage void vmx_vmexit_handler(struc
         case TRAP_page_fault:
         {
             __vmread(EXIT_QUALIFICATION, &va);
-            __vmread(VM_EXIT_INTR_ERROR_CODE, &regs.error_code);
-
-            TRACE_VMEXIT(3,regs.error_code);
-            TRACE_VMEXIT(4,va);
+            __vmread(VM_EXIT_INTR_ERROR_CODE, &regs->error_code);
+
+            TRACE_VMEXIT(3, regs->error_code);
+            TRACE_VMEXIT(4, va);
 
             HVM_DBG_LOG(DBG_LEVEL_VMMU,
                         "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
-                        (unsigned long)regs.eax, (unsigned long)regs.ebx,
-                        (unsigned long)regs.ecx, (unsigned long)regs.edx,
-                        (unsigned long)regs.esi, (unsigned long)regs.edi);
-
-            if ( !vmx_do_page_fault(va, &regs) ) {
-                /*
-                 * Inject #PG using Interruption-Information Fields
-                 */
-                vmx_inject_hw_exception(v, TRAP_page_fault, regs.error_code);
+                        (unsigned long)regs->eax, (unsigned long)regs->ebx,
+                        (unsigned long)regs->ecx, (unsigned long)regs->edx,
+                        (unsigned long)regs->esi, (unsigned long)regs->edi);
+
+            if ( !vmx_do_page_fault(va, regs) )
+            {
+                /* Inject #PG using Interruption-Information Fields. */
+                vmx_inject_hw_exception(v, TRAP_page_fault, regs->error_code);
                 v->arch.hvm_vmx.cpu_cr2 = va;
-                TRACE_3D(TRC_VMX_INT, v->domain->domain_id, TRAP_page_fault, 
va);
+                TRACE_3D(TRC_VMX_INT, v->domain->domain_id,
+                         TRAP_page_fault, va);
             }
             break;
         }
         case TRAP_nmi:
-            do_nmi(&regs);
+            do_nmi(regs);
             break;
         default:
             vmx_reflect_exception(v);
@@ -2262,7 +2275,7 @@ asmlinkage void vmx_vmexit_handler(struc
         break;
     }
     case EXIT_REASON_EXTERNAL_INTERRUPT:
-        vmx_vmexit_do_extint(&regs);
+        vmx_vmexit_do_extint(regs);
         break;
     case EXIT_REASON_TRIPLE_FAULT:
         domain_crash_synchronous();
@@ -2279,7 +2292,7 @@ asmlinkage void vmx_vmexit_handler(struc
     case EXIT_REASON_CPUID:
         inst_len = __get_instruction_length(); /* Safe: CPUID */
         __update_guest_eip(inst_len);
-        vmx_vmexit_do_cpuid(&regs);
+        vmx_vmexit_do_cpuid(regs);
         break;
     case EXIT_REASON_HLT:
         inst_len = __get_instruction_length(); /* Safe: HLT */
@@ -2301,7 +2314,7 @@ asmlinkage void vmx_vmexit_handler(struc
         __update_guest_eip(inst_len);
         __vmread(GUEST_RIP, &rip);
         __vmread(EXIT_QUALIFICATION, &exit_qualification);
-        hvm_do_hypercall(&regs);
+        hvm_do_hypercall(regs);
         break;
     }
     case EXIT_REASON_CR_ACCESS:
@@ -2309,15 +2322,15 @@ asmlinkage void vmx_vmexit_handler(struc
         __vmread(GUEST_RIP, &rip);
         __vmread(EXIT_QUALIFICATION, &exit_qualification);
         inst_len = __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
-        if ( vmx_cr_access(exit_qualification, &regs) )
+        if ( vmx_cr_access(exit_qualification, regs) )
             __update_guest_eip(inst_len);
-        TRACE_VMEXIT(3,regs.error_code);
-        TRACE_VMEXIT(4,exit_qualification);
+        TRACE_VMEXIT(3, regs->error_code);
+        TRACE_VMEXIT(4, exit_qualification);
         break;
     }
     case EXIT_REASON_DR_ACCESS:
         __vmread(EXIT_QUALIFICATION, &exit_qualification);
-        vmx_dr_access(exit_qualification, &regs);
+        vmx_dr_access(exit_qualification, regs);
         break;
     case EXIT_REASON_IO_INSTRUCTION:
         __vmread(EXIT_QUALIFICATION, &exit_qualification);
@@ -2328,12 +2341,12 @@ asmlinkage void vmx_vmexit_handler(struc
     case EXIT_REASON_MSR_READ:
         inst_len = __get_instruction_length(); /* Safe: RDMSR */
         __update_guest_eip(inst_len);
-        vmx_do_msr_read(&regs);
+        vmx_do_msr_read(regs);
         break;
     case EXIT_REASON_MSR_WRITE:
         inst_len = __get_instruction_length(); /* Safe: WRMSR */
         __update_guest_eip(inst_len);
-        vmx_do_msr_write(&regs);
+        vmx_do_msr_write(regs);
         break;
     case EXIT_REASON_MWAIT_INSTRUCTION:
     case EXIT_REASON_MONITOR_INSTRUCTION:
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/vmx/x86_32/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_32/exits.S       Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S       Sun Oct 01 19:10:18 2006 -0600
@@ -82,7 +82,10 @@ ENTRY(vmx_asm_vmexit_handler)
         /* selectors are restored/saved by VMX */
         HVM_SAVE_ALL_NOSEGREGS
         call vmx_trace_vmexit
+        movl %esp,%eax
+        push %eax
         call vmx_vmexit_handler
+        addl $4,%esp
         jmp vmx_asm_do_vmentry
 
         ALIGN
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/hvm/vmx/x86_64/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_64/exits.S       Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S       Sun Oct 01 19:10:18 2006 -0600
@@ -93,6 +93,7 @@ ENTRY(vmx_asm_vmexit_handler)
         /* selectors are restored/saved by VMX */
         HVM_SAVE_ALL_NOSEGREGS
         call vmx_trace_vmexit
+        movq %rsp,%rdi
         call vmx_vmexit_handler
         jmp vmx_asm_do_vmentry
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/mm.c Sun Oct 01 19:10:18 2006 -0600
@@ -427,23 +427,11 @@ int map_ldt_shadow_page(unsigned int off
     unsigned long gmfn, mfn;
     l1_pgentry_t l1e, nl1e;
     unsigned long gva = v->arch.guest_context.ldt_base + (off << PAGE_SHIFT);
-    int res;
-
-#if defined(__x86_64__)
-    /* If in user mode, switch to kernel mode just to read LDT mapping. */
-    int user_mode = !(v->arch.flags & TF_kernel_mode);
-#define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v)
-#elif defined(__i386__)
-#define TOGGLE_MODE() ((void)0)
-#endif
+    int okay;
 
     BUG_ON(unlikely(in_irq()));
 
-    TOGGLE_MODE();
-    __copy_from_user(&l1e, &linear_pg_table[l1_linear_offset(gva)],
-                     sizeof(l1e));
-    TOGGLE_MODE();
-
+    guest_get_eff_kern_l1e(v, gva, &l1e);
     if ( unlikely(!(l1e_get_flags(l1e) & _PAGE_PRESENT)) )
         return 0;
 
@@ -452,17 +440,17 @@ int map_ldt_shadow_page(unsigned int off
     if ( unlikely(!VALID_MFN(mfn)) )
         return 0;
 
-    res = get_page_and_type(mfn_to_page(mfn), d, PGT_ldt_page);
-
-    if ( !res && unlikely(shadow_mode_refcounts(d)) )
+    okay = get_page_and_type(mfn_to_page(mfn), d, PGT_ldt_page);
+
+    if ( !okay && unlikely(shadow_mode_refcounts(d)) )
     {
         shadow_lock(d);
         shadow_remove_write_access(d->vcpu[0], _mfn(mfn), 0, 0);
-        res = get_page_and_type(mfn_to_page(mfn), d, PGT_ldt_page);
+        okay = get_page_and_type(mfn_to_page(mfn), d, PGT_ldt_page);
         shadow_unlock(d);
     }
 
-    if ( unlikely(!res) )
+    if ( unlikely(!okay) )
         return 0;
 
     nl1e = l1e_from_pfn(mfn, l1e_get_flags(l1e) | _PAGE_RW);
@@ -1233,7 +1221,7 @@ static inline int update_l1e(l1_pgentry_
         }
     }
 #endif
-    if ( unlikely(shadow_mode_enabled(v->domain)) )
+    if ( unlikely(shadow_mode_enabled(v->domain)) && rv )
     {
         shadow_validate_guest_entry(v, _mfn(gl1mfn), pl1e);
         shadow_unlock(v->domain);    
@@ -1251,6 +1239,9 @@ 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)) )
+        return update_l1e(pl1e, ol1e, nl1e, gl1mfn, current);
 
     if ( l1e_get_flags(nl1e) & _PAGE_PRESENT )
     {
@@ -1544,9 +1535,7 @@ void free_page_type(struct page_info *pa
 
             gmfn = mfn_to_gmfn(owner, page_to_mfn(page));
             ASSERT(VALID_M2P(gmfn));
-            shadow_lock(owner);
             shadow_remove_all_shadows(owner->vcpu[0], _mfn(gmfn));
-            shadow_unlock(owner);
         }
     }
 
@@ -1618,8 +1607,8 @@ void put_page_type(struct page_info *pag
              *  2. Shadow mode reuses this field for shadowed page tables to
              *     store flags info -- we don't want to conflict with that.
              */
-            if ( !shadow_mode_enabled(page_get_owner(page)) ||
-                 ((nx & PGT_type_mask) == PGT_writable_page) )
+            if ( !(shadow_mode_enabled(page_get_owner(page)) &&
+                   (page->count_info & PGC_page_table)) )
                 page->tlbflush_timestamp = tlbflush_current_time();
         }
     }
@@ -1644,6 +1633,12 @@ int get_page_type(struct page_info *page
         }
         else if ( unlikely((x & PGT_count_mask) == 0) )
         {
+            struct domain *d = page_get_owner(page);
+
+            /* Never allow a shadowed frame to go from type count 0 to 1 */
+            if ( d && shadow_mode_enabled(d) )
+                shadow_remove_all_shadows(d->vcpu[0], _mfn(page_to_mfn(page)));
+
             ASSERT(!(x & PGT_pae_xen_l2));
             if ( (x & PGT_type_mask) != type )
             {
@@ -1652,8 +1647,9 @@ int get_page_type(struct page_info *page
                  * may be unnecessary (e.g., page was GDT/LDT) but those 
                  * circumstances should be very rare.
                  */
-                cpumask_t mask =
-                    page_get_owner(page)->domain_dirty_cpumask;
+                cpumask_t mask = d->domain_dirty_cpumask;
+
+                /* Don't flush if the timestamp is old enough */
                 tlbflush_filter(mask, page->tlbflush_timestamp);
 
                 if ( unlikely(!cpus_empty(mask)) &&
@@ -1866,6 +1862,14 @@ static int set_foreigndom(domid_t domid)
         }
     }
 
+    if ( unlikely(shadow_mode_translate(d)) )
+    {
+        MEM_LOG("%s: can not mix foreign mappings with translated domains",
+                __func__);
+        info->foreign = NULL;
+        okay = 0; 
+    }
+
  out:
     return okay;
 }
@@ -1897,7 +1901,7 @@ int do_mmuext_op(
 {
     struct mmuext_op op;
     int rc = 0, i = 0, okay;
-    unsigned long mfn, type;
+    unsigned long mfn = 0, gmfn = 0, type;
     unsigned int done = 0;
     struct page_info *page;
     struct vcpu *v = current;
@@ -1942,7 +1946,8 @@ int do_mmuext_op(
         }
 
         okay = 1;
-        mfn  = op.arg1.mfn;
+        gmfn  = op.arg1.mfn;
+        mfn = gmfn_to_mfn(FOREIGNDOM, gmfn);
         page = mfn_to_page(mfn);
 
         switch ( op.cmd )
@@ -2017,7 +2022,6 @@ int do_mmuext_op(
             break;
 
         case MMUEXT_NEW_BASEPTR:
-            mfn = gmfn_to_mfn(current->domain, mfn);
             okay = new_guest_cr3(mfn);
             this_cpu(percpu_mm_info).deferred_ops &= ~DOP_FLUSH_TLB;
             break;
@@ -2026,8 +2030,13 @@ int do_mmuext_op(
         case MMUEXT_NEW_USER_BASEPTR:
             okay = 1;
             if (likely(mfn != 0))
-                okay = get_page_and_type_from_pagenr(
-                    mfn, PGT_root_page_table, d);
+            {
+                if ( shadow_mode_refcounts(d) )
+                    okay = get_page_from_pagenr(mfn, d);
+                else
+                    okay = get_page_and_type_from_pagenr(
+                        mfn, PGT_root_page_table, d);
+            }
             if ( unlikely(!okay) )
             {
                 MEM_LOG("Error while installing new mfn %lx", mfn);
@@ -2038,7 +2047,12 @@ int do_mmuext_op(
                     pagetable_get_pfn(v->arch.guest_table_user);
                 v->arch.guest_table_user = pagetable_from_pfn(mfn);
                 if ( old_mfn != 0 )
-                    put_page_and_type(mfn_to_page(old_mfn));
+                {
+                    if ( shadow_mode_refcounts(d) )
+                        put_page(mfn_to_page(old_mfn));
+                    else
+                        put_page_and_type(mfn_to_page(old_mfn));
+                }
             }
             break;
 #endif
@@ -2499,17 +2513,26 @@ static int create_grant_va_mapping(
 {
     l1_pgentry_t *pl1e, ol1e;
     struct domain *d = v->domain;
+    unsigned long gl1mfn;
+    int okay;
     
     ASSERT(spin_is_locked(&d->big_lock));
 
     adjust_guest_l1e(nl1e);
 
-    pl1e = &linear_pg_table[l1_linear_offset(va)];
-
-    if ( unlikely(__copy_from_user(&ol1e, pl1e, sizeof(ol1e)) != 0) ||
-         !update_l1e(pl1e, ol1e, nl1e, 
-                    l2e_get_pfn(__linear_l2_table[l2_linear_offset(va)]), v) )
+    pl1e = guest_map_l1e(v, va, &gl1mfn);
+    if ( !pl1e )
+    {
+        MEM_LOG("Could not find L1 PTE for address %lx", va);
         return GNTST_general_error;
+    }
+    ol1e = *pl1e;
+    okay = update_l1e(pl1e, ol1e, nl1e, gl1mfn, v);
+    guest_unmap_l1e(v, pl1e);
+    pl1e = NULL;
+
+    if ( !okay )
+            return GNTST_general_error;
 
     if ( !shadow_mode_refcounts(d) )
         put_page_from_l1e(ol1e, d);
@@ -2518,17 +2541,19 @@ static int create_grant_va_mapping(
 }
 
 static int destroy_grant_va_mapping(
-    unsigned long addr, unsigned long frame, struct domain *d)
+    unsigned long addr, unsigned long frame, struct vcpu *v)
 {
     l1_pgentry_t *pl1e, ol1e;
+    unsigned long gl1mfn;
+    int rc = 0;
     
-    pl1e = &linear_pg_table[l1_linear_offset(addr)];
-
-    if ( unlikely(__get_user(ol1e.l1, &pl1e->l1) != 0) )
-    {
-        MEM_LOG("Could not find PTE entry for address %lx", addr);
+    pl1e = guest_map_l1e(v, addr, &gl1mfn);
+    if ( !pl1e )
+    {
+        MEM_LOG("Could not find L1 PTE for address %lx", addr);
         return GNTST_general_error;
     }
+    ol1e = *pl1e;
 
     /*
      * Check that the virtual address supplied is actually mapped to
@@ -2538,19 +2563,21 @@ static int destroy_grant_va_mapping(
     {
         MEM_LOG("PTE entry %lx for address %lx doesn't match frame %lx",
                 l1e_get_pfn(ol1e), addr, frame);
-        return GNTST_general_error;
+        rc = GNTST_general_error;
+        goto out;
     }
 
     /* Delete pagetable entry. */
-    if ( unlikely(!update_l1e(pl1e, ol1e, l1e_empty(), 
-                      l2e_get_pfn(__linear_l2_table[l2_linear_offset(addr)]),
-                      d->vcpu[0] /* Change for per-vcpu shadows */)) )
+    if ( unlikely(!update_l1e(pl1e, ol1e, l1e_empty(), gl1mfn, v)) )
     {
         MEM_LOG("Cannot delete PTE entry at %p", (unsigned long *)pl1e);
-        return GNTST_general_error;
-    }
-
-    return 0;
+        rc = GNTST_general_error;
+        goto out; // this is redundant & unnecessary, but informative
+    }
+
+ out:
+    guest_unmap_l1e(v, pl1e);
+    return rc;
 }
 
 int create_grant_host_mapping(
@@ -2573,7 +2600,7 @@ int destroy_grant_host_mapping(
 {
     if ( flags & GNTMAP_contains_pte )
         return destroy_grant_pte_mapping(addr, frame, current->domain);
-    return destroy_grant_va_mapping(addr, frame, current->domain);
+    return destroy_grant_va_mapping(addr, frame, current);
 }
 
 int steal_page(
@@ -2629,7 +2656,8 @@ int do_update_va_mapping(unsigned long v
     l1_pgentry_t   val = l1e_from_intpte(val64);
     struct vcpu   *v   = current;
     struct domain *d   = v->domain;
-    unsigned long  vmask, bmap_ptr;
+    l1_pgentry_t  *pl1e;
+    unsigned long  vmask, bmap_ptr, gl1mfn;
     cpumask_t      pmask;
     int            rc  = 0;
 
@@ -2638,35 +2666,17 @@ int do_update_va_mapping(unsigned long v
     if ( unlikely(!__addr_ok(va) && !shadow_mode_external(d)) )
         return -EINVAL;
 
-    if ( unlikely(shadow_mode_refcounts(d)) )
-    {
-        DPRINTK("Grant op on a shadow-refcounted domain\n");
-        return -EINVAL; 
-    }
-
     LOCK_BIGLOCK(d);
 
-    if ( likely(rc == 0) && unlikely(shadow_mode_enabled(d)) )
-    {
-        if ( unlikely(this_cpu(percpu_mm_info).foreign &&
-                      (shadow_mode_translate(d) ||
-                       shadow_mode_translate(
-                           this_cpu(percpu_mm_info).foreign))) )
-        {
-            /*
-             * The foreign domain's pfn's are in a different namespace. There's
-             * not enough information in just a gpte to figure out how to   
-             * (re-)shadow this entry.
-             */
-            domain_crash(d);
-        }
-    }
-
-    if ( unlikely(!mod_l1_entry(
-                      &linear_pg_table[l1_linear_offset(va)], val,
-                      l2e_get_pfn(__linear_l2_table[l2_linear_offset(va)]))) )
+    pl1e = guest_map_l1e(v, va, &gl1mfn);
+
+    if ( unlikely(!pl1e || !mod_l1_entry(pl1e, val, gl1mfn)) )
         rc = -EINVAL;
-    
+
+    if ( pl1e )
+        guest_unmap_l1e(v, pl1e);
+    pl1e = NULL;
+
     switch ( flags & UVMF_FLUSHTYPE_MASK )
     {
     case UVMF_TLB_FLUSH:
@@ -3028,7 +3038,7 @@ static int ptwr_emulated_update(
     unsigned int bytes,
     unsigned int do_cmpxchg)
 {
-    unsigned long pfn;
+    unsigned long gmfn, mfn;
     struct page_info *page;
     l1_pgentry_t pte, ol1e, nl1e, *pl1e;
     struct vcpu *v = current;
@@ -3068,15 +3078,17 @@ static int ptwr_emulated_update(
     }
 
     /* Read the PTE that maps the page being updated. */
-    if ( __copy_from_user(&pte, &linear_pg_table[l1_linear_offset(addr)],
-                          sizeof(pte)) )
-    {
-        MEM_LOG("ptwr_emulate: Cannot read thru linear_pg_table");
+    guest_get_eff_l1e(v, addr, &pte);
+    if ( unlikely(!(l1e_get_flags(pte) & _PAGE_PRESENT)) )
+    {
+        MEM_LOG("%s: Cannot get L1 PTE for guest address %lx",
+                __func__, addr);
         return X86EMUL_UNHANDLEABLE;
     }
 
-    pfn  = l1e_get_pfn(pte);
-    page = mfn_to_page(pfn);
+    gmfn  = l1e_get_pfn(pte);
+    mfn = gmfn_to_mfn(d, gmfn);
+    page = mfn_to_page(mfn);
 
     /* We are looking only for read-only mappings of p.t. pages. */
     ASSERT((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) == _PAGE_PRESENT);
@@ -3086,7 +3098,7 @@ static int ptwr_emulated_update(
 
     /* Check the new PTE. */
     nl1e = l1e_from_intpte(val);
-    if ( unlikely(!get_page_from_l1e(nl1e, d)) )
+    if ( unlikely(!get_page_from_l1e(gl1e_to_ml1e(d, nl1e), d)) )
     {
         if ( (CONFIG_PAGING_LEVELS == 3) &&
              (bytes == 4) &&
@@ -3125,13 +3137,13 @@ static int ptwr_emulated_update(
             if ( shadow_mode_enabled(d) )
                 shadow_unlock(d);
             unmap_domain_page(pl1e);
-            put_page_from_l1e(nl1e, d);
+            put_page_from_l1e(gl1e_to_ml1e(d, nl1e), d);
             return X86EMUL_CMPXCHG_FAILED;
         }
-        if ( unlikely(shadow_mode_enabled(v->domain)) )
+        if ( unlikely(shadow_mode_enabled(d)) )
         {
             shadow_validate_guest_entry(v, _mfn(page_to_mfn(page)), pl1e);
-            shadow_unlock(v->domain);    
+            shadow_unlock(d);    
         }
     }
     else
@@ -3144,7 +3156,7 @@ static int ptwr_emulated_update(
     unmap_domain_page(pl1e);
 
     /* Finally, drop the old PTE. */
-    put_page_from_l1e(ol1e, d);
+    put_page_from_l1e(gl1e_to_ml1e(d, ol1e), d);
 
     return X86EMUL_CONTINUE;
 }
@@ -3193,13 +3205,13 @@ static struct x86_emulate_ops ptwr_emula
 };
 
 /* Write page fault handler: check if guest is trying to modify a PTE. */
-int ptwr_do_page_fault(struct domain *d, unsigned long addr, 
+int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, 
                        struct cpu_user_regs *regs)
 {
+    struct domain *d = v->domain;
     unsigned long     pfn;
     struct page_info *page;
     l1_pgentry_t      pte;
-    l2_pgentry_t     *pl2e, l2e;
     struct x86_emulate_ctxt emul_ctxt;
 
     LOCK_BIGLOCK(d);
@@ -3208,13 +3220,9 @@ int ptwr_do_page_fault(struct domain *d,
      * Attempt to read the PTE that maps the VA being accessed. By checking for
      * PDE validity in the L2 we avoid many expensive fixups in __get_user().
      */
-    pl2e = &__linear_l2_table[l2_linear_offset(addr)];
-    if ( __copy_from_user(&l2e, pl2e, sizeof(l2e)) ||
-        !(l2e_get_flags(l2e) & _PAGE_PRESENT) ||
-         __copy_from_user(&pte, &linear_pg_table[l1_linear_offset(addr)],
-                          sizeof(pte)) )
+    guest_get_eff_l1e(v, addr, &pte);
+    if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) )
         goto bail;
-
     pfn  = l1e_get_pfn(pte);
     page = mfn_to_page(pfn);
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/mm/shadow/common.c   Sun Oct 01 19:10:18 2006 -0600
@@ -75,35 +75,27 @@ sh_x86_emulate_read_std(unsigned long ad
                          unsigned int bytes,
                          struct x86_emulate_ctxt *ctxt)
 {
-    struct vcpu *v = current;
-    if ( hvm_guest(v) )
-    {
-        *val = 0;
-        // XXX -- this is WRONG.
-        //        It entirely ignores the permissions in the page tables.
-        //        In this case, that is only a user vs supervisor access check.
-        //
-        if ( hvm_copy(val, addr, bytes, HVM_COPY_IN) )
-        {
+    *val = 0;
+    // XXX -- this is WRONG.
+    //        It entirely ignores the permissions in the page tables.
+    //        In this case, that is only a user vs supervisor access check.
+    //
+    if ( hvm_copy_from_guest_virt(val, addr, bytes) == 0 )
+    {
 #if 0
-            SHADOW_PRINTK("d=%u v=%u a=%#lx v=%#lx bytes=%u\n",
-                           v->domain->domain_id, v->vcpu_id, 
-                           addr, *val, bytes);
-#endif
-            return X86EMUL_CONTINUE;
-        }
-
-        /* If we got here, there was nothing mapped here, or a bad GFN 
-         * was mapped here.  This should never happen: we're here because
-         * of a write fault at the end of the instruction we're emulating. */ 
-        SHADOW_PRINTK("read failed to va %#lx\n", addr);
-        return X86EMUL_PROPAGATE_FAULT;
-    }
-    else 
-    {
-        SHADOW_PRINTK("this operation is not emulated yet\n");
-        return X86EMUL_UNHANDLEABLE;
-    }
+        struct vcpu *v = current;
+        SHADOW_PRINTK("d=%u v=%u a=%#lx v=%#lx bytes=%u\n",
+                       v->domain->domain_id, v->vcpu_id, 
+                       addr, *val, bytes);
+#endif
+        return X86EMUL_CONTINUE;
+    }
+
+    /* If we got here, there was nothing mapped here, or a bad GFN 
+     * was mapped here.  This should never happen: we're here because
+     * of a write fault at the end of the instruction we're emulating. */ 
+    SHADOW_PRINTK("read failed to va %#lx\n", addr);
+    return X86EMUL_PROPAGATE_FAULT;
 }
 
 static int
@@ -112,33 +104,26 @@ sh_x86_emulate_write_std(unsigned long a
                           unsigned int bytes,
                           struct x86_emulate_ctxt *ctxt)
 {
+#if 0
     struct vcpu *v = current;
-#if 0
     SHADOW_PRINTK("d=%u v=%u a=%#lx v=%#lx bytes=%u\n",
                   v->domain->domain_id, v->vcpu_id, addr, val, bytes);
 #endif
-    if ( hvm_guest(v) )
-    {
-        // XXX -- this is WRONG.
-        //        It entirely ignores the permissions in the page tables.
-        //        In this case, that includes user vs supervisor, and
-        //        write access.
-        //
-        if ( hvm_copy(&val, addr, bytes, HVM_COPY_OUT) )
-            return X86EMUL_CONTINUE;
-
-        /* If we got here, there was nothing mapped here, or a bad GFN 
-         * was mapped here.  This should never happen: we're here because
-         * of a write fault at the end of the instruction we're emulating,
-         * which should be handled by sh_x86_emulate_write_emulated. */ 
-        SHADOW_PRINTK("write failed to va %#lx\n", addr);
-        return X86EMUL_PROPAGATE_FAULT;
-    }
-    else 
-    {
-        SHADOW_PRINTK("this operation is not emulated yet\n");
-        return X86EMUL_UNHANDLEABLE;
-    }
+
+    // XXX -- this is WRONG.
+    //        It entirely ignores the permissions in the page tables.
+    //        In this case, that includes user vs supervisor, and
+    //        write access.
+    //
+    if ( hvm_copy_to_guest_virt(addr, &val, bytes) == 0 )
+        return X86EMUL_CONTINUE;
+
+    /* If we got here, there was nothing mapped here, or a bad GFN 
+     * was mapped here.  This should never happen: we're here because
+     * of a write fault at the end of the instruction we're emulating,
+     * which should be handled by sh_x86_emulate_write_emulated. */ 
+    SHADOW_PRINTK("write failed to va %#lx\n", addr);
+    return X86EMUL_PROPAGATE_FAULT;
 }
 
 static int
@@ -152,15 +137,7 @@ sh_x86_emulate_write_emulated(unsigned l
     SHADOW_PRINTK("d=%u v=%u a=%#lx v=%#lx bytes=%u\n",
                   v->domain->domain_id, v->vcpu_id, addr, val, bytes);
 #endif
-    if ( hvm_guest(v) )
-    {
-        return v->arch.shadow.mode->x86_emulate_write(v, addr, &val, bytes, 
ctxt);
-    }
-    else 
-    {
-        SHADOW_PRINTK("this operation is not emulated yet\n");
-        return X86EMUL_UNHANDLEABLE;
-    }
+    return v->arch.shadow.mode->x86_emulate_write(v, addr, &val, bytes, ctxt);
 }
 
 static int 
@@ -175,16 +152,8 @@ sh_x86_emulate_cmpxchg_emulated(unsigned
     SHADOW_PRINTK("d=%u v=%u a=%#lx o?=%#lx n:=%#lx bytes=%u\n",
                    v->domain->domain_id, v->vcpu_id, addr, old, new, bytes);
 #endif
-    if ( hvm_guest(v) )
-    {
-        return v->arch.shadow.mode->x86_emulate_cmpxchg(v, addr, old, new, 
-                                                    bytes, ctxt);
-    }
-    else 
-    {
-        SHADOW_PRINTK("this operation is not emulated yet\n");
-        return X86EMUL_UNHANDLEABLE;
-    }
+    return v->arch.shadow.mode->x86_emulate_cmpxchg(v, addr, old, new,
+                                                     bytes, ctxt);
 }
 
 static int 
@@ -201,16 +170,8 @@ sh_x86_emulate_cmpxchg8b_emulated(unsign
                    v->domain->domain_id, v->vcpu_id, addr, old_hi, old_lo,
                    new_hi, new_lo, ctxt);
 #endif
-    if ( hvm_guest(v) )
-    {
-        return v->arch.shadow.mode->x86_emulate_cmpxchg8b(v, addr, old_lo, 
old_hi,
-                                                      new_lo, new_hi, ctxt);
-    }
-    else 
-    {
-        SHADOW_PRINTK("this operation is not emulated yet\n");
-        return X86EMUL_UNHANDLEABLE;
-    }
+    return v->arch.shadow.mode->x86_emulate_cmpxchg8b(v, addr, old_lo, old_hi,
+                                                       new_lo, new_hi, ctxt);
 }
 
 
@@ -256,14 +217,18 @@ void shadow_demote(struct vcpu *v, mfn_t
     clear_bit(type >> PGC_SH_type_shift, &page->shadow_flags);
 
     if ( (page->shadow_flags & SHF_page_type_mask) == 0 )
+    {
+        /* tlbflush timestamp field is valid again */
+        page->tlbflush_timestamp = tlbflush_current_time();
         clear_bit(_PGC_page_table, &page->count_info);
+    }
 }
 
 /**************************************************************************/
 /* Validate a pagetable change from the guest and update the shadows.
  * Returns a bitmask of SHADOW_SET_* flags. */
 
-static int
+int
 __shadow_validate_guest_entry(struct vcpu *v, mfn_t gmfn, 
                                void *entry, u32 size)
 {
@@ -363,7 +328,9 @@ void
 void
 shadow_validate_guest_pt_write(struct vcpu *v, mfn_t gmfn,
                                 void *entry, u32 size)
-/* This is the entry point for emulated writes to pagetables in HVM guests */
+/* This is the entry point for emulated writes to pagetables in HVM guests and
+ * PV translated guests.
+ */
 {
     struct domain *d = v->domain;
     int rc;
@@ -802,7 +769,7 @@ void shadow_free(struct domain *d, mfn_t
 
 /* Divert some memory from the pool to be used by the p2m mapping.
  * This action is irreversible: the p2m mapping only ever grows.
- * That's OK because the p2m table only exists for external domains,
+ * That's OK because the p2m table only exists for translated domains,
  * and those domains can't ever turn off shadow mode.
  * Also, we only ever allocate a max-order chunk, so as to preserve
  * the invariant that shadow_prealloc() always works.
@@ -826,7 +793,12 @@ shadow_alloc_p2m_pages(struct domain *d)
     d->arch.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 */
+        /* Unlike shadow pages, mark p2m pages as owned by the domain.
+         * Marking the domain as the owner would normally allow the guest to
+         * create mappings of these pages, but these p2m pages will never be
+         * in the domain's guest-physical address space, and so that is not
+         * believed to be a concern.
+         */
         page_set_owner(&pg[i], d);
         list_add_tail(&pg[i].list, &d->arch.shadow.p2m_freelist);
     }
@@ -2265,7 +2237,7 @@ void sh_update_paging_modes(struct vcpu 
     //
     if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
     {
-        printk("%s: postponing determination of shadow mode\n", __func__);
+        SHADOW_PRINTK("%s: postponing determination of shadow mode\n", 
__func__);
         return;
     }
 
@@ -2290,6 +2262,7 @@ void sh_update_paging_modes(struct vcpu 
 #else
 #error unexpected paging mode
 #endif
+        v->arch.shadow.translate_enabled = !!shadow_mode_translate(d);
     }
     else
     {
@@ -2299,8 +2272,8 @@ void sh_update_paging_modes(struct vcpu 
         ASSERT(shadow_mode_translate(d));
         ASSERT(shadow_mode_external(d));
 
-        v->arch.shadow.hvm_paging_enabled = !!hvm_paging_enabled(v);
-        if ( !v->arch.shadow.hvm_paging_enabled )
+        v->arch.shadow.translate_enabled = !!hvm_paging_enabled(v);
+        if ( !v->arch.shadow.translate_enabled )
         {
             
             /* Set v->arch.guest_table to use the p2m map, and choose
@@ -2377,13 +2350,14 @@ void sh_update_paging_modes(struct vcpu 
 
         if ( v->arch.shadow.mode != old_mode )
         {
-            SHADOW_PRINTK("new paging mode: d=%u v=%u g=%u s=%u "
-                           "(was g=%u s=%u)\n",
-                           d->domain_id, v->vcpu_id, 
-                           v->arch.shadow.mode->guest_levels,
-                           v->arch.shadow.mode->shadow_levels,
-                           old_mode ? old_mode->guest_levels : 0,
-                           old_mode ? old_mode->shadow_levels : 0);
+            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,
+                          hvm_guest(v) ? !!hvm_paging_enabled(v) : 1,
+                          v->arch.shadow.mode->guest_levels,
+                          v->arch.shadow.mode->shadow_levels,
+                          old_mode ? old_mode->guest_levels : 0,
+                          old_mode ? old_mode->shadow_levels : 0);
             if ( old_mode &&
                  (v->arch.shadow.mode->shadow_levels !=
                   old_mode->shadow_levels) )
@@ -2463,6 +2437,7 @@ static int shadow_enable(struct domain *
     /* Sanity check the arguments */
     if ( (d == current->domain) ||
          shadow_mode_enabled(d) ||
+         ((mode & SHM2_translate) && !(mode & SHM2_refcounts)) ||
          ((mode & SHM2_external) && !(mode & SHM2_translate)) )
     {
         rv = -EINVAL;
@@ -2518,7 +2493,7 @@ static int shadow_enable(struct domain *
  out:
     shadow_unlock(d);
     domain_unpause(d);
-    return 0;
+    return rv;
 }
 
 void shadow_teardown(struct domain *d)
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/mm/shadow/multi.c    Sun Oct 01 19:10:18 2006 -0600
@@ -483,8 +483,7 @@ static u32 guest_set_ad_bits(struct vcpu
                              unsigned int level, 
                              fetch_type_t ft)
 {
-    u32 flags, shflags, bit;
-    struct page_info *pg;
+    u32 flags;
     int res = 0;
 
     ASSERT(valid_mfn(gmfn)
@@ -502,11 +501,10 @@ static u32 guest_set_ad_bits(struct vcpu
     if ( unlikely(GUEST_PAGING_LEVELS == 3 && level == 3) )
         return flags;
 
-    /* Need the D bit as well for writes, in l1es and 32bit/PAE PSE l2es. */
+    /* Need the D bit as well for writes, in L1es and PSE L2es. */
     if ( ft == ft_demand_write  
-         && (level == 1 || 
-             (level == 2 && GUEST_PAGING_LEVELS < 4 
-              && (flags & _PAGE_PSE) && guest_supports_superpages(v))) )
+         && (level == 1 ||
+             (level == 2 && (flags & _PAGE_PSE) && 
guest_supports_superpages(v))) )
     {
         if ( (flags & (_PAGE_DIRTY | _PAGE_ACCESSED)) 
              == (_PAGE_DIRTY | _PAGE_ACCESSED) )
@@ -524,76 +522,69 @@ static u32 guest_set_ad_bits(struct vcpu
 
     /* Set the bit(s) */
     sh_mark_dirty(v->domain, gmfn);
-    SHADOW_DEBUG(A_AND_D, "gfn = %"SH_PRI_gfn", "
+    SHADOW_DEBUG(A_AND_D, "gfn = %" SH_PRI_gfn ", "
                   "old flags = %#x, new flags = %#x\n", 
-                  guest_l1e_get_gfn(*ep), guest_l1e_get_flags(*ep), flags);
+                  gfn_x(guest_l1e_get_gfn(*ep)), guest_l1e_get_flags(*ep), 
flags);
     *ep = guest_l1e_from_gfn(guest_l1e_get_gfn(*ep), flags);
     
-    /* May need to propagate this change forward to other kinds of shadow */
-    pg = mfn_to_page(gmfn);
-    if ( !sh_mfn_is_a_page_table(gmfn) ) 
-    {
-        /* This guest pagetable is not yet shadowed at all. */
-        // MAF: I think this assert is busted...  If this gmfn has not yet
-        // been promoted, then it seems perfectly reasonable for there to be
-        // outstanding type refs to it...
-        /* TJD: No. If the gmfn has not been promoted, we must at least 
-         * have recognised that it is a pagetable, and pulled write access.
-         * The type count should only be non-zero if it is actually a page 
-         * table.  The test above was incorrect, though, so I've fixed it. */
-        ASSERT((pg->u.inuse.type_info & PGT_count_mask) == 0);
-        return flags;  
-    }
-
-    shflags = pg->shadow_flags & SHF_page_type_mask;
-    while ( shflags )
-    {
-        bit = find_first_set_bit(shflags);
-        ASSERT(shflags & (1u << bit));
-        shflags &= ~(1u << bit);
-        if ( !(pg->shadow_flags & (1u << bit)) )
-            continue;
-        switch ( bit )
-        {
-        case PGC_SH_type_to_index(PGC_SH_l1_shadow):
-            if (level != 1) 
-                res |= sh_map_and_validate_gl1e(v, gmfn, ep, sizeof (*ep));
-            break;
-        case PGC_SH_type_to_index(PGC_SH_l2_shadow):
-            if (level != 2) 
-                res |= sh_map_and_validate_gl2e(v, gmfn, ep, sizeof (*ep));
-            break;
-#if GUEST_PAGING_LEVELS == 3 /* PAE only */
-        case PGC_SH_type_to_index(PGC_SH_l2h_shadow):
-            if (level != 2) 
-                res |= sh_map_and_validate_gl2he(v, gmfn, ep, sizeof (*ep));
-            break;
-#endif
-#if GUEST_PAGING_LEVELS >= 3 /* PAE or 64... */
-        case PGC_SH_type_to_index(PGC_SH_l3_shadow):
-            if (level != 3) 
-                res |= sh_map_and_validate_gl3e(v, gmfn, ep, sizeof (*ep));
-            break;
-#if GUEST_PAGING_LEVELS >= 4 /* 64-bit only... */
-        case PGC_SH_type_to_index(PGC_SH_l4_shadow):
-            if (level != 4) 
-                res |= sh_map_and_validate_gl4e(v, gmfn, ep, sizeof (*ep));
-            break;
-#endif 
-#endif
-        default:
-            SHADOW_ERROR("mfn %"SH_PRI_mfn" is shadowed in multiple "
-                          "modes: A&D bits may be out of sync (flags=%#x).\n", 
-                          mfn_x(gmfn), pg->shadow_flags); 
-            /* XXX Shadows in other modes will not be updated, so will
-             * have their A and D bits out of sync. */
-        }
-    }
-    
+    /* Propagate this change to any existing shadows */
+    res = __shadow_validate_guest_entry(v, gmfn, ep, sizeof(*ep));
+
     /* We should never need to flush the TLB or recopy PAE entries */
-    ASSERT( res == 0 || res == SHADOW_SET_CHANGED );
+    ASSERT((res == 0) || (res == SHADOW_SET_CHANGED));
+
     return flags;
 }
+
+#if (CONFIG_PAGING_LEVELS == GUEST_PAGING_LEVELS) && (CONFIG_PAGING_LEVELS == 
SHADOW_PAGING_LEVELS)
+void *
+sh_guest_map_l1e(struct vcpu *v, unsigned long addr,
+                  unsigned long *gl1mfn)
+{
+    void *pl1e = NULL;
+    walk_t gw;
+
+    ASSERT(shadow_mode_translate(v->domain));
+        
+    // XXX -- this is expensive, but it's easy to cobble together...
+    // FIXME!
+
+    shadow_lock(v->domain);
+    guest_walk_tables(v, addr, &gw, 1);
+
+    if ( gw.l2e &&
+         (guest_l2e_get_flags(*gw.l2e) & _PAGE_PRESENT) &&
+         !(guest_supports_superpages(v) && (guest_l2e_get_flags(*gw.l2e) & 
_PAGE_PSE)) )
+    {
+        if ( gl1mfn )
+            *gl1mfn = mfn_x(gw.l1mfn);
+        pl1e = map_domain_page(mfn_x(gw.l1mfn)) +
+            (guest_l1_table_offset(addr) * sizeof(guest_l1e_t));
+    }
+
+    unmap_walk(v, &gw);
+    shadow_unlock(v->domain);
+
+    return pl1e;
+}
+
+void
+sh_guest_get_eff_l1e(struct vcpu *v, unsigned long addr, void *eff_l1e)
+{
+    walk_t gw;
+
+    ASSERT(shadow_mode_translate(v->domain));
+        
+    // XXX -- this is expensive, but it's easy to cobble together...
+    // FIXME!
+
+    shadow_lock(v->domain);
+    guest_walk_tables(v, addr, &gw, 1);
+    *(guest_l1e_t *)eff_l1e = gw.eff_l1e;
+    unmap_walk(v, &gw);
+    shadow_unlock(v->domain);
+}
+#endif /* CONFIG==SHADOW==GUEST */
 
 /**************************************************************************/
 /* Functions to compute the correct index into a shadow page, given an
@@ -709,17 +700,6 @@ shadow_l4_index(mfn_t *smfn, u32 guest_i
  * to the _PAGE_DIRTY bit handling), but for L[234], they are grouped together
  * into the respective demand_fault functions.
  */
-
-#define CHECK(_cond)                                    \
-do {                                                    \
-    if (unlikely(!(_cond)))                             \
-    {                                                   \
-        printk("%s %s %d ASSERTION (%s) FAILED\n",      \
-               __func__, __FILE__, __LINE__, #_cond);   \
-        return -1;                                      \
-    }                                                   \
-} while (0);
-
 // The function below tries to capture all of the flag manipulation for the
 // demand and propagate functions into one place.
 //
@@ -728,6 +708,16 @@ sh_propagate_flags(struct vcpu *v, mfn_t
                     u32 gflags, guest_l1e_t *guest_entry_ptr, mfn_t gmfn, 
                     int mmio, int level, fetch_type_t ft)
 {
+#define CHECK(_cond)                                    \
+do {                                                    \
+    if (unlikely(!(_cond)))                             \
+    {                                                   \
+        printk("%s %s %d ASSERTION (%s) FAILED\n",      \
+               __func__, __FILE__, __LINE__, #_cond);   \
+        domain_crash(d);                                \
+    }                                                   \
+} while (0);
+
     struct domain *d = v->domain;
     u32 pass_thru_flags;
     u32 sflags;
@@ -763,6 +753,10 @@ sh_propagate_flags(struct vcpu *v, mfn_t
             return 0;
     }
 
+    // Set the A and D bits in the guest entry, if we need to.
+    if ( guest_entry_ptr && (ft & FETCH_TYPE_DEMAND) )
+        gflags = guest_set_ad_bits(v, gmfn, guest_entry_ptr, level, ft);
+    
     // PAE does not allow NX, RW, USER, ACCESSED, or DIRTY bits in its L3e's...
     //
     if ( (SHADOW_PAGING_LEVELS == 3) && (level == 3) )
@@ -797,17 +791,12 @@ sh_propagate_flags(struct vcpu *v, mfn_t
     // Higher level entries do not, strictly speaking, have dirty bits, but
     // since we use shadow linear tables, each of these entries may, at some
     // point in time, also serve as a shadow L1 entry.
-    // By setting both the  A&D bits in each of these, we eliminate the burden
+    // By setting both the A&D bits in each of these, we eliminate the burden
     // on the hardware to update these bits on initial accesses.
     //
     if ( (level > 1) && !((SHADOW_PAGING_LEVELS == 3) && (level == 3)) )
         sflags |= _PAGE_ACCESSED | _PAGE_DIRTY;
 
-
-    // Set the A and D bits in the guest entry, if we need to.
-    if ( guest_entry_ptr && (ft & FETCH_TYPE_DEMAND) )
-        gflags = guest_set_ad_bits(v, gmfn, guest_entry_ptr, level, ft);
-    
     // If the A or D bit has not yet been set in the guest, then we must
     // prevent the corresponding kind of access.
     //
@@ -815,12 +804,12 @@ sh_propagate_flags(struct vcpu *v, mfn_t
                   !(gflags & _PAGE_ACCESSED)) )
         sflags &= ~_PAGE_PRESENT;
 
-    /* D bits exist in l1es, and 32bit/PAE PSE l2es, but not 64bit PSE l2es */
-    if ( unlikely( ((level == 1) 
-                    || ((level == 2) && (GUEST_PAGING_LEVELS < 4) 
-                        && guest_supports_superpages(v) &&
-                        (gflags & _PAGE_PSE)))
-                   && !(gflags & _PAGE_DIRTY)) )
+    /* D bits exist in L1es and PSE L2es */
+    if ( unlikely(((level == 1) ||
+                   ((level == 2) &&
+                    (gflags & _PAGE_PSE) &&
+                    guest_supports_superpages(v)))
+                  && !(gflags & _PAGE_DIRTY)) )
         sflags &= ~_PAGE_RW;
 
     // MMIO caching
@@ -869,10 +858,17 @@ sh_propagate_flags(struct vcpu *v, mfn_t
         }
     }
 
+    // PV guests in 64-bit mode use two different page tables for user vs
+    // supervisor permissions, making the guest's _PAGE_USER bit irrelevant.
+    // It is always shadowed as present...
+    if ( (GUEST_PAGING_LEVELS == 4) && !hvm_guest(v) )
+    {
+        sflags |= _PAGE_USER;
+    }
+
     return sflags;
-}
-
 #undef CHECK
+}
 
 #if GUEST_PAGING_LEVELS >= 4
 static void
@@ -1732,10 +1728,20 @@ void sh_install_xen_entries_in_l4(struct
                             __PAGE_HYPERVISOR);
 
     /* Linear mapping */
-    sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] =
-        shadow_l4e_from_mfn(gl4mfn, __PAGE_HYPERVISOR);
     sl4e[shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START)] =
         shadow_l4e_from_mfn(sl4mfn, __PAGE_HYPERVISOR);
+
+    if ( shadow_mode_translate(v->domain) && !shadow_mode_external(v->domain) )
+    {
+        // linear tables may not be used with translated PV guests
+        sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] =
+            shadow_l4e_empty();
+    }
+    else
+    {
+        sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] =
+            shadow_l4e_from_mfn(gl4mfn, __PAGE_HYPERVISOR);
+    }
 
     if ( shadow_mode_translate(v->domain) )
     {
@@ -1779,7 +1785,15 @@ void sh_install_xen_entries_in_l2h(struc
     
     /* We don't set up a linear mapping here because we can't until this
      * l2h is installed in an l3e.  sh_update_linear_entries() handles
-     * the linear mappings when the l3 is loaded. */
+     * the linear mappings when the l3 is loaded.  We zero them here, just as
+     * a safety measure.
+     */
+    for ( i = 0; i < SHADOW_L3_PAGETABLE_ENTRIES; i++ )
+        sl2e[shadow_l2_table_offset(LINEAR_PT_VIRT_START) + i] =
+            shadow_l2e_empty();
+    for ( i = 0; i < SHADOW_L3_PAGETABLE_ENTRIES; i++ )
+        sl2e[shadow_l2_table_offset(SH_LINEAR_PT_VIRT_START) + i] =
+            shadow_l2e_empty();
 
     if ( shadow_mode_translate(d) )
     {
@@ -1817,6 +1831,12 @@ void sh_install_xen_entries_in_l3(struct
     l2smfn = get_shadow_status(v, l2gmfn, PGC_SH_l2h_shadow);
     if ( !valid_mfn(l2smfn) )
     {
+        /* must remove write access to this page before shadowing it */
+        // XXX -- should check to see whether this is better with level==0 or
+        // level==2...
+        if ( shadow_remove_write_access(v, l2gmfn, 2, 0xc0000000ul) != 0 )
+            flush_tlb_mask(v->domain->domain_dirty_cpumask);
+ 
         l2smfn = sh_make_shadow(v, l2gmfn, PGC_SH_l2h_shadow);
     }
     l3e_propagate_from_guest(v, &gl3e[3], gl3mfn, l2smfn, &new_sl3e,
@@ -1852,10 +1872,20 @@ void sh_install_xen_entries_in_l2(struct
                 __PAGE_HYPERVISOR);
 
     /* Linear mapping */
-    sl2e[shadow_l2_table_offset(LINEAR_PT_VIRT_START)] =
-        shadow_l2e_from_mfn(gl2mfn, __PAGE_HYPERVISOR);
     sl2e[shadow_l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
         shadow_l2e_from_mfn(sl2mfn, __PAGE_HYPERVISOR);
+
+    if ( shadow_mode_translate(v->domain) && !shadow_mode_external(v->domain) )
+    {
+        // linear tables may not be used with translated PV guests
+        sl2e[shadow_l2_table_offset(LINEAR_PT_VIRT_START)] =
+            shadow_l2e_empty();
+    }
+    else
+    {
+        sl2e[shadow_l2_table_offset(LINEAR_PT_VIRT_START)] =
+            shadow_l2e_from_mfn(gl2mfn, __PAGE_HYPERVISOR);
+    }
 
     if ( shadow_mode_translate(d) )
     {
@@ -2150,7 +2180,12 @@ static shadow_l1e_t * shadow_get_and_cre
     /* Get the l2e */
     sl2e = shadow_get_and_create_l2e(v, gw, &sl2mfn, ft);
     if ( sl2e == NULL ) return NULL;
-    if ( shadow_l2e_get_flags(*sl2e) & _PAGE_PRESENT ) 
+    /* Install the sl1 in the l2e if it wasn't there or if we need to
+     * re-do it to fix a PSE dirty bit. */
+    if ( shadow_l2e_get_flags(*sl2e) & _PAGE_PRESENT 
+         && likely(ft != ft_demand_write
+                   || (guest_l2e_get_flags(*gw->l2e) & _PAGE_DIRTY) 
+                   || !(guest_l2e_get_flags(*gw->l2e) & _PAGE_PSE)) )
     {
         *sl1mfn = shadow_l2e_get_mfn(*sl2e);
         ASSERT(valid_mfn(*sl1mfn));
@@ -2527,6 +2562,32 @@ static int validate_gl4e(struct vcpu *v,
     }
     l4e_propagate_from_guest(v, new_gl4e, _mfn(INVALID_MFN),
                              sl3mfn, &new_sl4e, ft_prefetch);
+
+    // check for updates to xen reserved slots
+    if ( !shadow_mode_external(v->domain) )
+    {
+        int shadow_index = (((unsigned long)sl4p & ~PAGE_MASK) /
+                            sizeof(shadow_l4e_t));
+        int reserved_xen_slot = !is_guest_l4_slot(shadow_index);
+
+        if ( unlikely(reserved_xen_slot) )
+        {
+            // attempt by the guest to write to a xen reserved slot
+            //
+            SHADOW_PRINTK("%s out-of-range update "
+                           "sl4mfn=%05lx index=0x%x val=%" SH_PRI_pte "\n",
+                           __func__, mfn_x(sl4mfn), shadow_index, new_sl4e.l4);
+            if ( shadow_l4e_get_flags(new_sl4e) & _PAGE_PRESENT )
+            {
+                SHADOW_ERROR("out-of-range l4e update\n");
+                result |= SHADOW_SET_ERROR;
+            }
+
+            // do not call shadow_set_l4e...
+            return result;
+        }
+    }
+
     result |= shadow_set_l4e(v, sl4p, new_sl4e, sl4mfn);
     return result;
 }
@@ -2616,6 +2677,48 @@ static int validate_gl2e(struct vcpu *v,
     }
     l2e_propagate_from_guest(v, new_gl2e, _mfn(INVALID_MFN),
                              sl1mfn, &new_sl2e, ft_prefetch);
+
+    // check for updates to xen reserved slots in PV guests...
+    // XXX -- need to revisit this for PV 3-on-4 guests.
+    //
+#if SHADOW_PAGING_LEVELS < 4
+#if CONFIG_PAGING_LEVELS == SHADOW_PAGING_LEVELS
+    if ( !shadow_mode_external(v->domain) )
+    {
+        int shadow_index = (((unsigned long)sl2p & ~PAGE_MASK) /
+                            sizeof(shadow_l2e_t));
+        int reserved_xen_slot;
+
+#if SHADOW_PAGING_LEVELS == 3
+        reserved_xen_slot = 
+            (((mfn_to_page(sl2mfn)->count_info & PGC_SH_type_mask)
+              == PGC_SH_l2h_pae_shadow) &&
+             (shadow_index 
+              >= (L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1))));
+#else /* SHADOW_PAGING_LEVELS == 2 */
+        reserved_xen_slot = (shadow_index >= L2_PAGETABLE_FIRST_XEN_SLOT);
+#endif
+
+        if ( unlikely(reserved_xen_slot) )
+        {
+            // attempt by the guest to write to a xen reserved slot
+            //
+            SHADOW_PRINTK("%s out-of-range update "
+                           "sl2mfn=%05lx index=0x%x val=%" SH_PRI_pte "\n",
+                           __func__, mfn_x(sl2mfn), shadow_index, new_sl2e.l2);
+            if ( shadow_l2e_get_flags(new_sl2e) & _PAGE_PRESENT )
+            {
+                SHADOW_ERROR("out-of-range l2e update\n");
+                result |= SHADOW_SET_ERROR;
+            }
+
+            // do not call shadow_set_l2e...
+            return result;
+        }
+    }
+#endif /* CONFIG_PAGING_LEVELS == SHADOW_PAGING_LEVELS */
+#endif /* SHADOW_PAGING_LEVELS < 4 */
+
     result |= shadow_set_l2e(v, sl2p, new_sl2e, sl2mfn);
 
     return result;
@@ -2897,7 +3000,7 @@ static int sh_page_fault(struct vcpu *v,
     }
 
     // All levels of the guest page table are now known to be present.
-    accumulated_gflags = accumulate_guest_flags(&gw);
+    accumulated_gflags = accumulate_guest_flags(v, &gw);
 
     // Check for attempts to access supervisor-only pages from user mode,
     // i.e. ring 3.  Such errors are not caused or dealt with by the shadow
@@ -3348,6 +3451,7 @@ sh_update_linear_entries(struct vcpu *v)
         l2_pgentry_t *l2e, new_l2e;
         shadow_l3e_t *guest_l3e = NULL, *shadow_l3e;
         int i;
+        int unmap_l2e = 0;
 
 #if GUEST_PAGING_LEVELS == 2
         /* Shadow l3 tables were built by update_cr3 */
@@ -3365,39 +3469,45 @@ sh_update_linear_entries(struct vcpu *v)
 #endif /* GUEST_PAGING_LEVELS */
         
         /* Choose where to write the entries, using linear maps if possible */
-        if ( v == current && shadow_mode_external(d) ) 
-        {
-            /* From the monitor tables, it's safe to use linear maps to update
-             * monitor l2s */
-            l2e = __linear_l2_table + (3 * L2_PAGETABLE_ENTRIES);
-        }
-        else if ( shadow_mode_external(d) ) 
-        {
-            /* Map the monitor table's high l2 */
-            l3_pgentry_t *l3e;
-            l3e = sh_map_domain_page(
-                pagetable_get_mfn(v->arch.monitor_table));
-            ASSERT(l3e_get_flags(l3e[3]) & _PAGE_PRESENT);
-            l2e = sh_map_domain_page(_mfn(l3e_get_pfn(l3e[3])));
-            sh_unmap_domain_page(l3e);
-        } 
+        if ( shadow_mode_external(d) )
+        {
+            if ( v == current )
+            {
+                /* From the monitor tables, it's safe to use linear maps
+                 * to update monitor l2s */
+                l2e = __linear_l2_table + (3 * L2_PAGETABLE_ENTRIES);
+            }
+            else
+            {
+                /* Map the monitor table's high l2 */
+                l3_pgentry_t *l3e;
+                l3e = sh_map_domain_page(
+                    pagetable_get_mfn(v->arch.monitor_table));
+                ASSERT(l3e_get_flags(l3e[3]) & _PAGE_PRESENT);
+                l2e = sh_map_domain_page(_mfn(l3e_get_pfn(l3e[3])));
+                unmap_l2e = 1;
+                sh_unmap_domain_page(l3e);
+            }
+        }
         else 
         {
             /* Map the shadow table's high l2 */
             ASSERT(shadow_l3e_get_flags(shadow_l3e[3]) & _PAGE_PRESENT);
             l2e = sh_map_domain_page(shadow_l3e_get_mfn(shadow_l3e[3]));
+            unmap_l2e = 1;
         }
         
-        
-        if ( !shadow_mode_external(d) )
-        {
-            /* Write linear mapping of guest. */
+        /* Write linear mapping of guest (only in PV, and only when 
+         * not translated). */
+        if ( !shadow_mode_translate(d) )
+        {
             for ( i = 0; i < SHADOW_L3_PAGETABLE_ENTRIES; i++ )
-            { 
-                new_l2e = (shadow_l3e_get_flags(guest_l3e[i]) & _PAGE_PRESENT) 
-                    ? l2e_from_pfn(mfn_x(shadow_l3e_get_mfn(guest_l3e[i])),
-                                   __PAGE_HYPERVISOR) 
-                    : l2e_empty();
+            {
+                new_l2e = 
+                    ((shadow_l3e_get_flags(guest_l3e[i]) & _PAGE_PRESENT)
+                     ? l2e_from_pfn(mfn_x(shadow_l3e_get_mfn(guest_l3e[i])),
+                                    __PAGE_HYPERVISOR) 
+                     : l2e_empty());
                 safe_write_entry(
                     &l2e[l2_table_offset(LINEAR_PT_VIRT_START) + i],
                     &new_l2e);
@@ -3416,9 +3526,8 @@ sh_update_linear_entries(struct vcpu *v)
                 &new_l2e);
         }
         
-        if ( v != current || !shadow_mode_external(d) )
+        if ( unmap_l2e )
             sh_unmap_domain_page(l2e);
-        
     }
 
 #elif CONFIG_PAGING_LEVELS == 2
@@ -3521,16 +3630,24 @@ static void
 static void
 sh_detach_old_tables(struct vcpu *v)
 {
+    struct domain *d = v->domain;
     mfn_t smfn;
 
     ////
     //// vcpu->arch.guest_vtable
     ////
-    if ( (shadow_mode_external(v->domain) || (GUEST_PAGING_LEVELS == 3)) &&
-         v->arch.guest_vtable )
-    {
-        // Q: why does this need to use (un)map_domain_page_*global* ?
-        sh_unmap_domain_page_global(v->arch.guest_vtable);
+    if ( v->arch.guest_vtable )
+    {
+#if GUEST_PAGING_LEVELS == 4
+        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;
     }
 
@@ -3645,9 +3762,14 @@ sh_update_cr3(struct vcpu *v)
     ////
     //// vcpu->arch.guest_vtable
     ////
+#if GUEST_PAGING_LEVELS == 4
+    if ( shadow_mode_external(d) || shadow_mode_translate(d) )
+        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
+    else
+        v->arch.guest_vtable = __linear_l4_table;
+#elif GUEST_PAGING_LEVELS == 3
     if ( shadow_mode_external(d) )
     {
-#if GUEST_PAGING_LEVELS == 3
         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));
@@ -3658,25 +3780,21 @@ sh_update_cr3(struct vcpu *v)
         // 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;
+    }
+    else
+        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
+#elif GUEST_PAGING_LEVELS == 2
+    if ( shadow_mode_external(d) || shadow_mode_translate(d) )
+        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
+    else
+        v->arch.guest_vtable = __linear_l2_table;
 #else
-        // XXX - why does this need a global map?
-        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
-#endif
-    }
-    else
-    {
-#ifdef __x86_64__
-        v->arch.guest_vtable = __linear_l4_table;
-#elif GUEST_PAGING_LEVELS == 3
-        // XXX - why does this need a global map?
-        v->arch.guest_vtable = sh_map_domain_page_global(gmfn);
-#else
-        v->arch.guest_vtable = __linear_l2_table;
-#endif
-    }
+#error this should never happen
+#endif
 
 #if 0
     printk("%s %s %d gmfn=%05lx guest_vtable=%p\n",
@@ -3743,6 +3861,17 @@ sh_update_cr3(struct vcpu *v)
         v->arch.shadow_vtable = __sh_linear_l2_table;
 #endif
     }
+
+#if (CONFIG_PAGING_LEVELS == 3) && (GUEST_PAGING_LEVELS == 3)
+    // Now that shadow_vtable is in place, check that the sl3e[3] is properly
+    // shadowed and installed in PAE PV guests...
+    if ( !shadow_mode_external(d) &&
+         !(shadow_l3e_get_flags(((shadow_l3e_t *)v->arch.shadow_vtable)[3]) &
+           _PAGE_PRESENT) )
+    {
+        sh_install_xen_entries_in_l3(v, gmfn, smfn);
+    }
+#endif
 
     ////
     //// Take a ref to the new shadow table, and pin it.
@@ -4049,7 +4178,7 @@ static inline void * emulate_map_dest(st
     mfn_t mfn;
 
     guest_walk_tables(v, vaddr, &gw, 1);
-    flags = accumulate_guest_flags(&gw);
+    flags = accumulate_guest_flags(v, &gw);
     gfn = guest_l1e_get_gfn(gw.eff_l1e);
     mfn = vcpu_gfn_to_mfn(v, gfn);
     sh_audit_gw(v, &gw);
@@ -4453,6 +4582,8 @@ struct shadow_paging_mode sh_paging_mode
     .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,
 #if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC
     .guess_wrmap            = sh_guess_wrmap,
 #endif
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/mm/shadow/multi.h
--- a/xen/arch/x86/mm/shadow/multi.h    Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/mm/shadow/multi.h    Sun Oct 01 19:10:18 2006 -0600
@@ -103,6 +103,13 @@ SHADOW_INTERNAL_NAME(sh_audit_l4_table, 
     (struct vcpu *v, mfn_t sl4mfn, mfn_t x);
 #endif
 
+extern void *
+SHADOW_INTERNAL_NAME(sh_guest_map_l1e, CONFIG_PAGING_LEVELS, 
CONFIG_PAGING_LEVELS)
+    (struct vcpu *v, unsigned long va, unsigned long *gl1mfn);
+extern void
+SHADOW_INTERNAL_NAME(sh_guest_get_eff_l1e, CONFIG_PAGING_LEVELS, 
CONFIG_PAGING_LEVELS)
+    (struct vcpu *v, unsigned long va, void *eff_l1e);
+
 #if SHADOW_LEVELS == GUEST_LEVELS
 extern mfn_t
 SHADOW_INTERNAL_NAME(sh_make_monitor_table, SHADOW_LEVELS, GUEST_LEVELS)
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/mm/shadow/private.h
--- a/xen/arch/x86/mm/shadow/private.h  Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/mm/shadow/private.h  Sun Oct 01 19:10:18 2006 -0600
@@ -532,55 +532,6 @@ static inline void sh_unpin(struct vcpu 
     }
 }
 
-/**************************************************************************/
-/* Guest physmap (p2m) support */
-
-/* Read our own P2M table, checking in the linear pagetables first to be
- * sure that we will succeed.  Call this function if you expect it to
- * fail often, as it avoids page faults.  If you expect to succeed, use
- * vcpu_gfn_to_mfn, which copy_from_user()s the entry */
-static inline mfn_t
-vcpu_gfn_to_mfn_nofault(struct vcpu *v, unsigned long gfn)
-{
-    unsigned long entry_addr = (unsigned long) &phys_to_machine_mapping[gfn];
-#if CONFIG_PAGING_LEVELS >= 4
-    l4_pgentry_t *l4e;
-    l3_pgentry_t *l3e;
-#endif
-    l2_pgentry_t *l2e;
-    l1_pgentry_t *l1e;
-
-    ASSERT(current == v);
-    if ( !shadow_vcpu_mode_translate(v) )
-        return _mfn(gfn);
-
-#if CONFIG_PAGING_LEVELS > 2
-    if ( gfn >= (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof(l1_pgentry_t) ) 
-        /* This pfn is higher than the p2m map can hold */
-        return _mfn(INVALID_MFN);
-#endif
-    
-    /* Walk the linear pagetables.  Note that this is *not* the same as 
-     * the walk in sh_gfn_to_mfn_foreign, which is walking the p2m map */
-#if CONFIG_PAGING_LEVELS >= 4
-    l4e = __linear_l4_table + l4_linear_offset(entry_addr);
-    if ( !(l4e_get_flags(*l4e) & _PAGE_PRESENT) ) return _mfn(INVALID_MFN);
-    l3e = __linear_l3_table + l3_linear_offset(entry_addr);
-    if ( !(l3e_get_flags(*l3e) & _PAGE_PRESENT) ) return _mfn(INVALID_MFN);
-#endif
-    l2e = __linear_l2_table + l2_linear_offset(entry_addr);
-    if ( !(l2e_get_flags(*l2e) & _PAGE_PRESENT) ) return _mfn(INVALID_MFN);
-    l1e = __linear_l1_table + l1_linear_offset(entry_addr);
-    if ( !(l1e_get_flags(*l1e) & _PAGE_PRESENT) ) return _mfn(INVALID_MFN);
-
-    /* Safe to look at this part of the table */
-    if ( l1e_get_flags(phys_to_machine_mapping[gfn])  & _PAGE_PRESENT )
-        return _mfn(l1e_get_pfn(phys_to_machine_mapping[gfn]));
-    
-    return _mfn(INVALID_MFN);
-}
-
-
 #endif /* _XEN_SHADOW_PRIVATE_H */
 
 /*
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/mm/shadow/types.h
--- a/xen/arch/x86/mm/shadow/types.h    Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/mm/shadow/types.h    Sun Oct 01 19:10:18 2006 -0600
@@ -205,6 +205,9 @@ static inline shadow_l4e_t shadow_l4e_fr
     __sh_linear_l1_table; \
 })
 
+// XXX -- these should not be conditional on hvm_guest(v), but rather on
+//        shadow_mode_external(d)...
+//
 #define sh_linear_l2_table(v) ({ \
     ASSERT(current == (v)); \
     ((shadow_l2e_t *) \
@@ -507,10 +510,22 @@ struct shadow_walk_t
 #define sh_guess_wrmap             INTERNAL_NAME(sh_guess_wrmap)
 #define sh_clear_shadow_entry      INTERNAL_NAME(sh_clear_shadow_entry)
 
+/* The sh_guest_(map|get)_* functions only depends on the number of config
+ * levels
+ */
+#define sh_guest_map_l1e                                       \
+        SHADOW_INTERNAL_NAME(sh_guest_map_l1e,                \
+                              CONFIG_PAGING_LEVELS,             \
+                              CONFIG_PAGING_LEVELS)
+#define sh_guest_get_eff_l1e                                   \
+        SHADOW_INTERNAL_NAME(sh_guest_get_eff_l1e,            \
+                              CONFIG_PAGING_LEVELS,             \
+                              CONFIG_PAGING_LEVELS)
+
 /* sh_make_monitor_table only depends on the number of shadow levels */
-#define sh_make_monitor_table                          \
-        SHADOW_INTERNAL_NAME(sh_make_monitor_table,   \
-                              SHADOW_PAGING_LEVELS,     \
+#define sh_make_monitor_table                                  \
+        SHADOW_INTERNAL_NAME(sh_make_monitor_table,           \
+                              SHADOW_PAGING_LEVELS,             \
                               SHADOW_PAGING_LEVELS)
 #define sh_destroy_monitor_table                               \
         SHADOW_INTERNAL_NAME(sh_destroy_monitor_table,        \
@@ -652,7 +667,7 @@ static inline void sh_unpin_l3_subshadow
 #endif /* GUEST_PAGING_LEVELS >= 3 */
 
 static inline u32
-accumulate_guest_flags(walk_t *gw)
+accumulate_guest_flags(struct vcpu *v, walk_t *gw)
 {
     u32 accumulated_flags;
 
@@ -674,8 +689,14 @@ accumulate_guest_flags(walk_t *gw)
     accumulated_flags &= guest_l4e_get_flags(*gw->l4e) ^ _PAGE_NX_BIT;
 #endif
 
-    // Finally, revert the NX bit back to its original polarity
+    // Revert the NX bit back to its original polarity
     accumulated_flags ^= _PAGE_NX_BIT;
+
+    // In 64-bit PV guests, the _PAGE_USER bit is implied in all guest
+    // entries (since even the guest kernel runs in ring 3).
+    //
+    if ( (GUEST_PAGING_LEVELS == 4) && !hvm_guest(v) )
+        accumulated_flags |= _PAGE_USER;
 
     return accumulated_flags;
 }
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c        Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/smp.c        Sun Oct 01 19:10:18 2006 -0600
@@ -21,6 +21,7 @@
 #include <asm/smpboot.h>
 #include <asm/hardirq.h>
 #include <asm/ipi.h>
+#include <asm/hvm/hvm.h>
 #include <mach_apic.h>
 
 /*
@@ -306,6 +307,7 @@ static void stop_this_cpu (void *dummy)
 
     local_irq_disable();
     disable_local_APIC();
+    hvm_disable();
 
     for ( ; ; )
         __asm__ __volatile__ ( "hlt" );
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/traps.c      Sun Oct 01 19:10:18 2006 -0600
@@ -886,7 +886,7 @@ static int fixup_page_fault(unsigned lon
          /* Do not check if access-protection fault since the page may 
             legitimately be not present in shadow page tables */
          ((regs->error_code & PFEC_write_access) == PFEC_write_access) &&
-         ptwr_do_page_fault(d, addr, regs) )
+         ptwr_do_page_fault(v, addr, regs) )
         return EXCRET_fault_fixed;
 
     if ( shadow_mode_enabled(d) )
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/x86_32/entry.S       Sun Oct 01 19:10:18 2006 -0600
@@ -175,7 +175,7 @@ ENTRY(hypercall)
         jae   bad_hypercall
         PERFC_INCR(PERFC_hypercalls, %eax)
 #ifndef NDEBUG
-        /* Deliberately corrupt parameter regs not used by this hypercall. */
+        /* Create shadow parameters and corrupt those not used by this call. */
         pushl %eax
         pushl UREGS_eip+4(%esp)
         pushl 28(%esp) # EBP
@@ -192,11 +192,23 @@ ENTRY(hypercall)
         movl  $0xDEADBEEF,%eax
         rep   stosl
         movl  %esi,%eax
+#else
+        /* 
+         * We need shadow parameters even on non-debug builds. We depend on the
+         * original versions not being clobbered (needed to create a hypercall
+         * continuation). But that isn't guaranteed by the function-call ABI.
+         */ 
+        pushl 20(%esp) # EBP
+        pushl 20(%esp) # EDI
+        pushl 20(%esp) # ESI
+        pushl 20(%esp) # EDX
+        pushl 20(%esp) # ECX
+        pushl 20(%esp) # EBX
 #endif
         call *hypercall_table(,%eax,4)
+        addl  $24,%esp     # Discard the shadow parameters
 #ifndef NDEBUG
-        /* Deliberately corrupt parameter regs used by this hypercall. */
-        addl  $24,%esp     # Shadow parameters
+        /* Deliberately corrupt real parameter regs used by this hypercall. */
         popl  %ecx         # Shadow EIP
         cmpl  %ecx,UREGS_eip+4(%esp)
         popl  %ecx         # Shadow hypercall index
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/arch/x86/x86_emulate.c        Sun Oct 01 19:10:18 2006 -0600
@@ -368,12 +368,13 @@ do{ __asm__ __volatile__ (              
 #endif /* __i386__ */
 
 /* Fetch next part of the instruction being emulated. */
-#define insn_fetch(_type, _size, _eip)                                  \
-({ unsigned long _x;                                                    \
-   rc = ops->read_std((unsigned long)(_eip), &_x, (_size), ctxt);       \
+#define insn_fetch(_type, _size)                                        \
+({ unsigned long _x, _ptr = _regs.eip;                                  \
+   if ( mode == X86EMUL_MODE_REAL ) _ptr += _regs.cs << 4;              \
+   rc = ops->read_std(_ptr, &_x, (_size), ctxt);                        \
    if ( rc != 0 )                                                       \
        goto done;                                                       \
-   (_eip) += (_size);                                                   \
+   _regs.eip += (_size);                                                \
    (_type)_x;                                                           \
 })
 
@@ -478,7 +479,7 @@ x86_emulate_memop(
     /* Legacy prefixes. */
     for ( i = 0; i < 8; i++ )
     {
-        switch ( b = insn_fetch(uint8_t, 1, _regs.eip) )
+        switch ( b = insn_fetch(uint8_t, 1) )
         {
         case 0x66: /* operand-size override */
             op_bytes ^= 6;      /* switch between 2/4 bytes */
@@ -529,7 +530,7 @@ x86_emulate_memop(
             op_bytes = 8;          /* REX.W */
         modrm_reg = (b & 4) << 1;  /* REX.R */
         /* REX.B and REX.X do not need to be decoded. */
-        b = insn_fetch(uint8_t, 1, _regs.eip);
+        b = insn_fetch(uint8_t, 1);
     }
 
     /* Opcode byte(s). */
@@ -540,7 +541,7 @@ x86_emulate_memop(
         if ( b == 0x0f )
         {
             twobyte = 1;
-            b = insn_fetch(uint8_t, 1, _regs.eip);
+            b = insn_fetch(uint8_t, 1);
             d = twobyte_table[b];
         }
 
@@ -552,7 +553,7 @@ x86_emulate_memop(
     /* ModRM and SIB bytes. */
     if ( d & ModRM )
     {
-        modrm = insn_fetch(uint8_t, 1, _regs.eip);
+        modrm = insn_fetch(uint8_t, 1);
         modrm_mod |= (modrm & 0xc0) >> 6;
         modrm_reg |= (modrm & 0x38) >> 3;
         modrm_rm  |= (modrm & 0x07);
@@ -587,19 +588,19 @@ x86_emulate_memop(
             {
             case 0:
                 if ( (modrm_rm == 4) && 
-                     (((sib = insn_fetch(uint8_t, 1, _regs.eip)) & 7) == 5) )
+                     (((sib = insn_fetch(uint8_t, 1)) & 7) == 5) )
                     _regs.eip += 4; /* skip disp32 specified by SIB.base */
                 else if ( modrm_rm == 5 )
                     _regs.eip += 4; /* skip disp32 */
                 break;
             case 1:
                 if ( modrm_rm == 4 )
-                    sib = insn_fetch(uint8_t, 1, _regs.eip);
+                    sib = insn_fetch(uint8_t, 1);
                 _regs.eip += 1; /* skip disp8 */
                 break;
             case 2:
                 if ( modrm_rm == 4 )
-                    sib = insn_fetch(uint8_t, 1, _regs.eip);
+                    sib = insn_fetch(uint8_t, 1);
                 _regs.eip += 4; /* skip disp32 */
                 break;
             }
@@ -691,16 +692,16 @@ x86_emulate_memop(
         /* NB. Immediates are sign-extended as necessary. */
         switch ( src.bytes )
         {
-        case 1: src.val = insn_fetch(int8_t,  1, _regs.eip); break;
-        case 2: src.val = insn_fetch(int16_t, 2, _regs.eip); break;
-        case 4: src.val = insn_fetch(int32_t, 4, _regs.eip); break;
+        case 1: src.val = insn_fetch(int8_t,  1); break;
+        case 2: src.val = insn_fetch(int16_t, 2); break;
+        case 4: src.val = insn_fetch(int32_t, 4); break;
         }
         break;
     case SrcImmByte:
         src.type  = OP_IMM;
         src.ptr   = (unsigned long *)_regs.eip;
         src.bytes = 1;
-        src.val   = insn_fetch(int8_t,  1, _regs.eip);
+        src.val   = insn_fetch(int8_t,  1);
         break;
     }
 
@@ -840,9 +841,9 @@ x86_emulate_memop(
             if ( src.bytes == 8 ) src.bytes = 4;
             switch ( src.bytes )
             {
-            case 1: src.val = insn_fetch(int8_t,  1, _regs.eip); break;
-            case 2: src.val = insn_fetch(int16_t, 2, _regs.eip); break;
-            case 4: src.val = insn_fetch(int32_t, 4, _regs.eip); break;
+            case 1: src.val = insn_fetch(int8_t,  1); break;
+            case 2: src.val = insn_fetch(int16_t, 2); break;
+            case 4: src.val = insn_fetch(int32_t, 4); break;
             }
             goto test;
         case 2: /* not */
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/common/gdbstub.c
--- a/xen/common/gdbstub.c      Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/common/gdbstub.c      Sun Oct 01 19:10:18 2006 -0600
@@ -506,14 +506,13 @@ int
 int 
 __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
 {
-    int resume = 0;
-    int r;
+    int rc = 0;
     unsigned long flags;
 
     if ( gdb_ctx->serhnd < 0 )
     {
         dbg_printk("Debugger not ready yet.\n");
-        return 0;
+        return -EBUSY;
     }
 
     /* We rely on our caller to ensure we're only on one processor
@@ -532,7 +531,7 @@ __trap_to_gdb(struct cpu_user_regs *regs
     {
         printk("WARNING WARNING WARNING: Avoiding recursive gdb.\n");
         atomic_inc(&gdb_ctx->running);
-        return 0;
+        return -EBUSY;
     }
 
     if ( !gdb_ctx->connected )
@@ -565,19 +564,14 @@ __trap_to_gdb(struct cpu_user_regs *regs
         gdb_cmd_signum(gdb_ctx);
     }
 
-    while ( resume == 0 )
-    {
-        r = receive_command(gdb_ctx);
-        if ( r < 0 )
-        {
-            dbg_printk("GDB disappeared, trying to resume Xen...\n");
-            resume = 1;
-        }
-        else
-        {
-            resume = process_command(regs, gdb_ctx);
-        }
-    }
+    do {
+        if ( receive_command(gdb_ctx) < 0 )
+        {
+            dbg_printk("Error in GDB session...\n");
+            rc = -EIO;
+            break;
+        }
+    } while ( process_command(regs, gdb_ctx) == 0 );
 
     gdb_arch_exit(regs);
     console_end_sync();
@@ -586,7 +580,7 @@ __trap_to_gdb(struct cpu_user_regs *regs
 
     local_irq_restore(flags);
 
-    return 0;
+    return rc;
 }
 
 void
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/common/symbols.c
--- a/xen/common/symbols.c      Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/common/symbols.c      Sun Oct 01 19:10:18 2006 -0600
@@ -16,15 +16,14 @@
 #include <xen/lib.h>
 #include <xen/string.h>
 
-/* These will be re-linked against their real values during the second link 
stage */
-extern unsigned long symbols_addresses[] __attribute__((weak));
-extern unsigned long symbols_num_syms __attribute__((weak,section("data")));
-extern u8 symbols_names[] __attribute__((weak));
+extern unsigned long symbols_addresses[];
+extern unsigned long symbols_num_syms;
+extern u8 symbols_names[];
 
-extern u8 symbols_token_table[] __attribute__((weak));
-extern u16 symbols_token_index[] __attribute__((weak));
+extern u8 symbols_token_table[];
+extern u16 symbols_token_index[];
 
-extern unsigned long symbols_markers[] __attribute__((weak));
+extern unsigned long symbols_markers[];
 
 /* expand a compressed symbol data into the resulting uncompressed string,
    given the offset to where the symbol is in the compressed stream */
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/include/asm-x86/debugger.h
--- a/xen/include/asm-x86/debugger.h    Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/include/asm-x86/debugger.h    Sun Oct 01 19:10:18 2006 -0600
@@ -15,14 +15,13 @@
  * 2. debugger_trap_fatal():
  *  Called when Xen is about to give up and crash. Typically you will use this
  *  hook to drop into a debug session. It can also be used to hook off
- *  deliberately caused traps (which you then handle and return non-zero)
- *  but really these should be hooked off 'debugger_trap_entry'.
+ *  deliberately caused traps (which you then handle and return non-zero).
  *
  * 3. debugger_trap_immediate():
  *  Called if we want to drop into a debugger now.  This is essentially the
  *  same as debugger_trap_fatal, except that we use the current register state
  *  rather than the state which was in effect when we took the trap.
- *  Essentially, if we're dying because of an unhandled exception, we call
+ *  For example: if we're dying because of an unhandled exception, we call
  *  debugger_trap_fatal; if we're dying because of a panic() we call
  *  debugger_trap_immediate().
  */
@@ -44,42 +43,19 @@
 
 #include <xen/gdbstub.h>
 
-#define __debugger_trap_entry(_v, _r) (0)
-
-static inline int __debugger_trap_fatal(
+static inline int debugger_trap_fatal(
     unsigned int vector, struct cpu_user_regs *regs)
 {
-    (void)__trap_to_gdb(regs, vector);
-    return (vector == TRAP_int3); /* int3 is harmless */
+    return (__trap_to_gdb(regs, vector) == 0);
 }
 
 /* Int3 is a trivial way to gather cpu_user_regs context. */
 #define debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
 
-#elif 0
-
-extern int kdb_trap(int, int, struct cpu_user_regs *);
-
-static inline int __debugger_trap_entry(
-    unsigned int vector, struct cpu_user_regs *regs)
-{
-    return 0;
-}
-
-static inline int __debugger_trap_fatal(
-    unsigned int vector, struct cpu_user_regs *regs)
-{
-    return kdb_trap(vector, 0, regs);
-}
-
-/* Int3 is a trivial way to gather cpu_user_regs context. */
-#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" )
-
 #else
 
-#define __debugger_trap_entry(_v, _r) (0)
-#define __debugger_trap_fatal(_v, _r) (0)
-#define __debugger_trap_immediate()   ((void)0)
+#define debugger_trap_fatal(v, r) (0)
+#define debugger_trap_immediate() ((void)0)
 
 #endif
 
@@ -96,12 +72,7 @@ static inline int debugger_trap_entry(
         return 1;
     }
 
-    return __debugger_trap_entry(vector, regs);
+    return 0;
 }
 
-#define debugger_trap_fatal(v, r) (__debugger_trap_fatal(v, r))
-#ifndef debugger_trap_immediate
-#define debugger_trap_immediate() (__debugger_trap_immediate())
-#endif
-
 #endif /* __X86_DEBUGGER_H__ */
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/include/asm-x86/domain.h      Sun Oct 01 19:10:18 2006 -0600
@@ -139,7 +139,7 @@ struct shadow_vcpu {
     /* Last MFN that we emulated a write to. */
     unsigned long last_emulated_mfn;
     /* HVM guest: paging enabled (CR0.PG)?  */
-    unsigned int hvm_paging_enabled:1;
+    unsigned int translate_enabled:1;
     /* Emulated fault needs to be propagated to guest? */
     unsigned int propagate_fault:1;
 #if CONFIG_PAGING_LEVELS >= 3
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/include/asm-x86/guest_access.h
--- a/xen/include/asm-x86/guest_access.h        Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/include/asm-x86/guest_access.h        Sun Oct 01 19:10:18 2006 -0600
@@ -8,6 +8,7 @@
 #define __ASM_X86_GUEST_ACCESS_H__
 
 #include <asm/uaccess.h>
+#include <asm/shadow.h>
 #include <asm/hvm/support.h>
 #include <asm/hvm/guest_access.h>
 
@@ -33,7 +34,7 @@
 #define copy_to_guest_offset(hnd, off, ptr, nr) ({      \
     const typeof(ptr) _x = (hnd).p;                     \
     const typeof(ptr) _y = (ptr);                       \
-    hvm_guest(current) ?                                \
+    shadow_mode_translate(current->domain) ?            \
     copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) :  \
     copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));       \
 })
@@ -45,7 +46,7 @@
 #define copy_from_guest_offset(ptr, hnd, off, nr) ({    \
     const typeof(ptr) _x = (hnd).p;                     \
     const typeof(ptr) _y = (ptr);                       \
-    hvm_guest(current) ?                                \
+    shadow_mode_translate(current->domain) ?            \
     copy_from_user_hvm(_y, _x+(off), sizeof(*_x)*(nr)) :\
     copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));     \
 })
@@ -54,7 +55,7 @@
 #define copy_field_to_guest(hnd, ptr, field) ({         \
     const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
     const typeof(&(ptr)->field) _y = &(ptr)->field;     \
-    hvm_guest(current) ?                                \
+    shadow_mode_translate(current->domain) ?            \
     copy_to_user_hvm(_x, _y, sizeof(*_x)) :             \
     copy_to_user(_x, _y, sizeof(*_x));                  \
 })
@@ -63,7 +64,7 @@
 #define copy_field_from_guest(ptr, hnd, field) ({       \
     const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
     const typeof(&(ptr)->field) _y = &(ptr)->field;     \
-    hvm_guest(current) ?                                \
+    shadow_mode_translate(current->domain) ?            \
     copy_from_user_hvm(_y, _x, sizeof(*_x)) :           \
     copy_from_user(_y, _x, sizeof(*_x));                \
 })
@@ -73,12 +74,13 @@
  * Allows use of faster __copy_* functions.
  */
 #define guest_handle_okay(hnd, nr)                      \
-    (hvm_guest(current) || array_access_ok((hnd).p, (nr), sizeof(*(hnd).p)))
+    (shadow_mode_external(current->domain) ||           \
+     array_access_ok((hnd).p, (nr), sizeof(*(hnd).p)))
 
 #define __copy_to_guest_offset(hnd, off, ptr, nr) ({    \
     const typeof(ptr) _x = (hnd).p;                     \
     const typeof(ptr) _y = (ptr);                       \
-    hvm_guest(current) ?                                \
+    shadow_mode_translate(current->domain) ?            \
     copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) :  \
     __copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));     \
 })
@@ -86,7 +88,7 @@
 #define __copy_from_guest_offset(ptr, hnd, off, nr) ({  \
     const typeof(ptr) _x = (hnd).p;                     \
     const typeof(ptr) _y = (ptr);                       \
-    hvm_guest(current) ?                                \
+    shadow_mode_translate(current->domain) ?            \
     copy_from_user_hvm(_y, _x+(off),sizeof(*_x)*(nr)) : \
     __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));   \
 })
@@ -94,7 +96,7 @@
 #define __copy_field_to_guest(hnd, ptr, field) ({       \
     const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
     const typeof(&(ptr)->field) _y = &(ptr)->field;     \
-    hvm_guest(current) ?                                \
+    shadow_mode_translate(current->domain) ?            \
     copy_to_user_hvm(_x, _y, sizeof(*_x)) :             \
     __copy_to_user(_x, _y, sizeof(*_x));                \
 })
@@ -102,7 +104,7 @@
 #define __copy_field_from_guest(ptr, hnd, field) ({     \
     const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
     const typeof(&(ptr)->field) _y = &(ptr)->field;     \
-    hvm_guest(current) ?                                \
+    shadow_mode_translate(current->domain) ?            \
     copy_from_user_hvm(_x, _y, sizeof(*_x)) :           \
     __copy_from_user(_y, _x, sizeof(*_x));              \
 })
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h      Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/include/asm-x86/hvm/io.h      Sun Oct 01 19:10:18 2006 -0600
@@ -68,6 +68,7 @@
 #define INSTR_TEST  12
 #define INSTR_BT    13
 #define INSTR_XCHG  14
+#define INSTR_SUB   15
 
 struct instruction {
     __s8    instr;        /* instruction type */
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/include/asm-x86/hvm/support.h Sun Oct 01 19:10:18 2006 -0600
@@ -118,7 +118,7 @@ extern unsigned int opt_hvm_debug_level;
 extern unsigned int opt_hvm_debug_level;
 #define HVM_DBG_LOG(level, _f, _a...)                                         \
     do {                                                                      \
-        if ( (level) & opt_hvm_debug_level )                                  \
+        if ( unlikely((level) & opt_hvm_debug_level) )                        \
             printk("[HVM:%d.%d] <%s> " _f "\n",                               \
                    current->domain->domain_id, current->vcpu_id, __func__,    \
                    ## _a);                                                    \
@@ -136,16 +136,18 @@ extern unsigned int opt_hvm_debug_level;
 
 extern int hvm_enabled;
 
-enum { HVM_COPY_IN = 0, HVM_COPY_OUT };
-extern int hvm_copy(void *buf, unsigned long vaddr, int size, int dir);
+int hvm_copy_to_guest_phys(unsigned long paddr, void *buf, int size);
+int hvm_copy_from_guest_phys(void *buf, unsigned long paddr, int size);
+int hvm_copy_to_guest_virt(unsigned long vaddr, void *buf, int size);
+int hvm_copy_from_guest_virt(void *buf, unsigned long vaddr, int size);
 
-extern void hvm_setup_platform(struct domain* d);
-extern int hvm_mmio_intercept(ioreq_t *p);
-extern int hvm_io_intercept(ioreq_t *p, int type);
-extern int hvm_buffered_io_intercept(ioreq_t *p);
-extern void hvm_hooks_assist(struct vcpu *v);
-extern void hvm_print_line(struct vcpu *v, const char c);
-extern void hlt_timer_fn(void *data);
+void hvm_setup_platform(struct domain* d);
+int hvm_mmio_intercept(ioreq_t *p);
+int hvm_io_intercept(ioreq_t *p, int type);
+int hvm_buffered_io_intercept(ioreq_t *p);
+void hvm_hooks_assist(struct vcpu *v);
+void hvm_print_line(struct vcpu *v, const char c);
+void hlt_timer_fn(void *data);
 
 void hvm_do_hypercall(struct cpu_user_regs *pregs);
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/include/asm-x86/hvm/vioapic.h
--- a/xen/include/asm-x86/hvm/vioapic.h Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/include/asm-x86/hvm/vioapic.h Sun Oct 01 19:10:18 2006 -0600
@@ -88,6 +88,7 @@ typedef union RedirStatus
 
 typedef struct hvm_vioapic {
     uint32_t irr;
+    uint32_t irr_xen; /* interrupts forced on by the hypervisor. */
     uint32_t isr;           /* This is used for level trigger */
     uint32_t imr;
     uint32_t ioregsel;
@@ -105,6 +106,7 @@ hvm_vioapic_t *hvm_vioapic_init(struct d
 
 void hvm_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs);
 void hvm_vioapic_do_irqs(struct domain *d, uint16_t irqs);
+void hvm_vioapic_set_xen_irq(struct domain *d, int irq, int level);
 void hvm_vioapic_set_irq(struct domain *d, int irq, int level);
 
 int hvm_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v);
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/include/asm-x86/hvm/vpic.h
--- a/xen/include/asm-x86/hvm/vpic.h    Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/include/asm-x86/hvm/vpic.h    Sun Oct 01 19:10:18 2006 -0600
@@ -34,6 +34,8 @@ typedef struct PicState {
 typedef struct PicState {
     uint8_t last_irr; /* edge detection */
     uint8_t irr; /* interrupt request register */
+    uint8_t irr_xen; /* interrupts forced on by the hypervisor e.g.
+                       the callback irq. */
     uint8_t imr; /* interrupt mask register */
     uint8_t isr; /* interrupt service register */
     uint8_t priority_add; /* highest irq priority */
@@ -58,20 +60,16 @@ struct hvm_virpic {
     void (*irq_request)(void *opaque, int level);
     void *irq_request_opaque;
     /* IOAPIC callback support */
-    void (*alt_irq_func)(void *opaque, int irq_num, int level);
-    void *alt_irq_opaque;
     spinlock_t lock;
 };
 
 
+void pic_set_xen_irq(void *opaque, int irq, int level);
 void pic_set_irq(struct hvm_virpic *s, int irq, int level);
 void pic_set_irq_new(void *opaque, int irq, int level);
 void pic_init(struct hvm_virpic *s, 
               void (*irq_request)(void *, int),
               void *irq_request_opaque);
-void pic_set_alt_irq_func(struct hvm_virpic *s, 
-                          void (*alt_irq_func)(void *, int, int),
-                          void *alt_irq_opaque);
 int pic_read_irq(struct hvm_virpic *s);
 void pic_update_irq(struct hvm_virpic *s); /* Caller must hold s->lock */
 uint32_t pic_intack_read(struct hvm_virpic *s);
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/include/asm-x86/mm.h  Sun Oct 01 19:10:18 2006 -0600
@@ -348,7 +348,7 @@ void memguard_unguard_range(void *p, uns
 
 void memguard_guard_stack(void *p);
 
-int  ptwr_do_page_fault(struct domain *, unsigned long,
+int  ptwr_do_page_fault(struct vcpu *, unsigned long,
                         struct cpu_user_regs *);
 
 int audit_adjust_pgtables(struct domain *d, int dir, int noisy);
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      Sun Oct 01 11:39:41 2006 -0600
+++ b/xen/include/asm-x86/shadow.h      Sun Oct 01 19:10:18 2006 -0600
@@ -26,6 +26,7 @@
 #include <public/domctl.h> 
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/domain_page.h>
 #include <asm/flushtlb.h>
 
 /* How to make sure a page is not referred to in a shadow PT */
@@ -245,7 +246,9 @@ shadow_vcpu_mode_translate(struct vcpu *
     // enabled.  (HVM vcpu's with paging disabled are using the p2m table as
     // its paging table, so no translation occurs in this case.)
     //
-    return v->arch.shadow.hvm_paging_enabled;
+    // It is also true for translated PV domains.
+    //
+    return v->arch.shadow.translate_enabled;
 }
 
 
@@ -287,6 +290,10 @@ struct shadow_paging_mode {
                                             struct x86_emulate_ctxt *ctxt);
     mfn_t         (*make_monitor_table    )(struct vcpu *v);
     void          (*destroy_monitor_table )(struct vcpu *v, mfn_t mmfn);
+    void *        (*guest_map_l1e         )(struct vcpu *v, unsigned long va,
+                                            unsigned long *gl1mfn);
+    void          (*guest_get_eff_l1e     )(struct vcpu *v, unsigned long va,
+                                            void *eff_l1e);
 #if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC
     int           (*guess_wrmap           )(struct vcpu *v, 
                                             unsigned long vaddr, mfn_t gmfn);
@@ -452,9 +459,73 @@ shadow_destroy_monitor_table(struct vcpu
     v->arch.shadow.mode->destroy_monitor_table(v, mmfn);
 }
 
+static inline void *
+guest_map_l1e(struct vcpu *v, unsigned long addr, unsigned long *gl1mfn)
+{
+    if ( likely(!shadow_mode_translate(v->domain)) )
+    {
+        l2_pgentry_t l2e;
+        ASSERT(!shadow_mode_external(v->domain));
+        /* Find this l1e and its enclosing l1mfn in the linear map */
+        if ( __copy_from_user(&l2e, 
+                              &__linear_l2_table[l2_linear_offset(addr)],
+                              sizeof(l2_pgentry_t)) != 0 )
+            return NULL;
+        /* Check flags that it will be safe to read the l1e */
+        if ( (l2e_get_flags(l2e) & (_PAGE_PRESENT | _PAGE_PSE)) 
+             != _PAGE_PRESENT )
+            return NULL;
+        *gl1mfn = l2e_get_pfn(l2e);
+        return &__linear_l1_table[l1_linear_offset(addr)];
+    }
+
+    return v->arch.shadow.mode->guest_map_l1e(v, addr, gl1mfn);
+}
+
+static inline void
+guest_unmap_l1e(struct vcpu *v, void *p)
+{
+    if ( unlikely(shadow_mode_translate(v->domain)) )
+        unmap_domain_page(p);
+}
+
+static inline void
+guest_get_eff_l1e(struct vcpu *v, unsigned long addr, void *eff_l1e)
+{
+    if ( likely(!shadow_mode_translate(v->domain)) )
+    {
+        ASSERT(!shadow_mode_external(v->domain));
+        if ( __copy_from_user(eff_l1e, 
+                              &__linear_l1_table[l1_linear_offset(addr)],
+                              sizeof(l1_pgentry_t)) != 0 )
+            *(l1_pgentry_t *)eff_l1e = l1e_empty();
+        return;
+    }
+        
+    v->arch.shadow.mode->guest_get_eff_l1e(v, addr, eff_l1e);
+}
+
+static inline void
+guest_get_eff_kern_l1e(struct vcpu *v, unsigned long addr, void *eff_l1e)
+{
+#if defined(__x86_64__)
+    int user_mode = !(v->arch.flags & TF_kernel_mode);
+#define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v)
+#else
+#define TOGGLE_MODE() ((void)0)
+#endif
+
+    TOGGLE_MODE();
+    guest_get_eff_l1e(v, addr, eff_l1e);
+    TOGGLE_MODE();
+}
+
+
 /* Validate a pagetable change from the guest and update the shadows. */
 extern int shadow_validate_guest_entry(struct vcpu *v, mfn_t gmfn,
                                         void *new_guest_entry);
+extern int __shadow_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 shadow_validate_guest_pt_write(struct vcpu *v, mfn_t gmfn, 
@@ -481,7 +552,12 @@ extern void sh_remove_shadows(struct vcp
 extern void sh_remove_shadows(struct vcpu *v, mfn_t gmfn, int all);
 static inline void shadow_remove_all_shadows(struct vcpu *v, mfn_t gmfn)
 {
+    int was_locked = shadow_lock_is_acquired(v->domain);
+    if ( !was_locked )
+        shadow_lock(v->domain);
     sh_remove_shadows(v, gmfn, 1);
+    if ( !was_locked )
+        shadow_unlock(v->domain);
 }
 
 /* Add a page to a domain */
@@ -624,7 +700,14 @@ sh_mfn_to_gfn(struct domain *d, mfn_t mf
         return mfn_x(mfn);
 }
 
-
+static inline l1_pgentry_t
+gl1e_to_ml1e(struct domain *d, l1_pgentry_t l1e)
+{
+    if ( unlikely(shadow_mode_translate(d)) )
+        l1e = l1e_from_pfn(gmfn_to_mfn(d, l1e_get_pfn(l1e)),
+                           l1e_get_flags(l1e));
+    return l1e;
+}
 
 #endif /* _XEN_SHADOW_H */
 
diff -r 914c44d10c8d -r 2bfd19fc1b79 xen/common/symbols-dummy.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/common/symbols-dummy.c        Sun Oct 01 19:10:18 2006 -0600
@@ -0,0 +1,16 @@
+/*
+ * symbols-dummy.c: dummy symbol-table definitions for the inital partial
+ *                  link of the hypervisor image.
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+
+unsigned long symbols_addresses[1];
+unsigned long symbols_num_syms;
+u8 symbols_names[1];
+
+u8 symbols_token_table[1];
+u16 symbols_token_index[1];
+
+unsigned long symbols_markers[1];
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/Domain.ml
--- a/tools/debugger/pdb/Domain.ml      Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-(** Domain.ml
- *
- *  domain context implementation
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-open Int32
-open Intel
-
-type context_t =
-{
-  mutable domain : int;
-  mutable vcpu : int
-}
-
-let default_context = { domain = 0; vcpu = 0 }
-
-let new_context new_dom new_vcpu = {domain = new_dom; vcpu = new_vcpu}
-
-let set_domain ctx value =
-  ctx.domain <- value
-
-let set_vcpu ctx value =
-  ctx.vcpu <- value
-
-let get_domain ctx =
-  ctx.domain
-
-let get_vcpu ctx =
-  ctx.vcpu
-
-let string_of_context ctx =
-      Printf.sprintf "{domain} domain: %d, vcpu: %d"
-                      ctx.domain  ctx.vcpu
-
-external read_register : context_t -> int -> int32 = "dom_read_register"
-external read_registers : context_t -> registers = "dom_read_registers"
-external write_register : context_t -> register -> int32 -> unit =
-  "dom_write_register"
-external read_memory : context_t -> int32 -> int -> int list = 
-  "dom_read_memory"
-external write_memory : context_t -> int32 -> int list -> unit = 
-  "dom_write_memory"
-       
-external continue : context_t -> unit = "dom_continue_target"
-external step : context_t -> unit = "dom_step_target"
-
-external insert_memory_breakpoint : context_t -> int32 -> int -> unit = 
-  "dom_insert_memory_breakpoint"
-external remove_memory_breakpoint : context_t -> int32 -> int -> unit = 
-  "dom_remove_memory_breakpoint"
-
-external attach_debugger : int -> int -> unit = "dom_attach_debugger"
-external detach_debugger : int -> int -> unit = "dom_detach_debugger"
-external pause_target : int -> unit = "dom_pause_target"
-
-let pause ctx =
-  pause_target ctx.domain
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/Domain.mli
--- a/tools/debugger/pdb/Domain.mli     Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-(** Domain.mli
- *
- *  domain context interface
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-open Int32
-open Intel
-
-type context_t
-
-val default_context : context_t
-val new_context : int -> int -> context_t 
-
-val set_domain : context_t -> int -> unit
-val get_domain : context_t -> int
-val set_vcpu : context_t -> int -> unit
-val get_vcpu : context_t -> int
-
-val string_of_context : context_t -> string
-
-val read_register : context_t -> int -> int32
-val read_registers : context_t -> registers
-val write_register : context_t -> register -> int32 -> unit
-val read_memory : context_t -> int32 -> int -> int list
-val write_memory : context_t -> int32 -> int list -> unit
-       
-val continue : context_t -> unit
-val step : context_t -> unit
-
-val insert_memory_breakpoint : context_t -> int32 -> int -> unit
-val remove_memory_breakpoint : context_t -> int32 -> int -> unit
-
-val attach_debugger : int -> int -> unit
-val detach_debugger : int -> int -> unit
-val pause : context_t -> unit
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/Intel.ml
--- a/tools/debugger/pdb/Intel.ml       Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-(** Intel.ml
- *
- *  various sundry Intel x86 definitions
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-
-type register =
-  | EAX
-  | ECX
-  | EDX
-  | EBX
-  | ESP
-  | EBP
-  | ESI
-  | EDI
-  | EIP
-  | EFL
-  | CS
-  | SS
-  | DS
-  | ES
-  | FS
-  | GS
-
-type registers =
-    { eax : int32;
-      ecx : int32;
-      edx : int32;
-      ebx : int32;
-      esp : int32;
-      ebp : int32;
-      esi : int32;
-      edi : int32;
-      eip : int32;
-      efl : int32;
-      cs  : int32;
-      ss  : int32;
-      ds  : int32;
-      es  : int32;
-      fs  : int32;
-      gs  : int32
-    }
-
-let null_registers =
-    { eax = 0l;
-      ecx = 0l;
-      edx = 0l;
-      ebx = 0l;
-      esp = 0l;
-      ebp = 0l;
-      esi = 0l;
-      edi = 0l;
-      eip = 0l;
-      efl = 0l;
-      cs  = 0l;
-      ss  = 0l;
-      ds  = 0l;
-      es  = 0l;
-      fs  = 0l;
-      gs  = 0l
-    }
-
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/Makefile
--- a/tools/debugger/pdb/Makefile       Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-OCAMLMAKEFILE = OCamlMakefile
-
-XEN_ROOT    = ../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-# overwrite LDFLAGS from xen/tool/Rules.mk
-# otherwise, ocamlmktop gets confused.
-LDFLAGS     =
-
-# force ocaml 3.08
-OCAML_ROOT  = /usr/local
-OCAMLC      = $(OCAML_ROOT)/bin/ocamlc
-OCAMLMKTOP  = $(OCAML_ROOT)/bin/ocamlmktop
-OCAMLLIBPATH= $(OCAML_ROOT)/lib/ocaml
-
-INCLUDES   += -I $(XEN_XC)
-INCLUDES   += -I $(XEN_LIBXC)
-INCLUDES   += -I ../libxendebug
-INCLUDES   += -I ./linux-2.6-module
-INCLUDES   += -I $(OCAML_ROOT)/lib/ocaml
-
-CFLAGS     += $(INCLUDES)
-CFLAGS     += -Werror
-CFLAGS     += -g
-
-CLIBS      += xc
-CLIBS      += xendebug
-
-LIBDIRS    += $(XEN_LIBXC)
-LIBDIRS    += ../libxendebug
-
-LIBS       += unix str
-
-# bc = byte-code, dc = debug byte-code
-# patches = patch linux domU source code
-.PHONY: all 
-all : dc
-
-SOURCES    += pdb_caml_xc.c 
-SOURCES    += pdb_caml_domain.c pdb_caml_process.c
-SOURCES    += pdb_caml_evtchn.c pdb_caml_xcs.c pdb_xen.c
-SOURCES    += Util.ml Intel.ml 
-SOURCES    += evtchn.ml evtchn.mli
-SOURCES    += xcs.ml xcs.mli
-SOURCES    += Xen_domain.ml Xen_domain.mli
-SOURCES    += Domain.ml  Process.ml
-SOURCES    += Domain.mli Process.mli
-SOURCES    += PDB.ml debugger.ml server.ml
-
-RESULT      = pdb
-
-include $(OCAMLMAKEFILE)
-
-PATCHDIR    = ./linux-2.6-patches
-.PHONY: patches 
-patches :
-       make -C $(PATCHDIR) patches
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/OCamlMakefile
--- a/tools/debugger/pdb/OCamlMakefile  Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1149 +0,0 @@
-###########################################################################
-#                              OCamlMakefile
-#                  Copyright (C) 1999-2004  Markus Mottl
-#
-#                             For updates see:
-#                http://www.oefai.at/~markus/ocaml_sources
-#
-#        $Id: OCamlMakefile,v 1.1 2005/05/19 09:30:48 root Exp $
-#
-###########################################################################
-
-# Modified by damien for .glade.ml compilation
-
-# Set these variables to the names of the sources to be processed and
-# the result variable. Order matters during linkage!
-
-ifndef SOURCES
-  SOURCES := foo.ml
-endif
-export SOURCES
-
-ifndef RES_CLIB_SUF
-  RES_CLIB_SUF := _stubs
-endif
-export RES_CLIB_SUF
-
-ifndef RESULT
-  RESULT := foo
-endif
-export RESULT
-
-export LIB_PACK_NAME
-
-ifndef DOC_FILES
-  DOC_FILES := $(filter %.mli, $(SOURCES))
-endif
-export DOC_FILES
-
-export BCSUFFIX
-export NCSUFFIX
-
-ifndef TOPSUFFIX
-  TOPSUFFIX := .top
-endif
-export TOPSUFFIX
-
-# Eventually set include- and library-paths, libraries to link,
-# additional compilation-, link- and ocamlyacc-flags
-# Path- and library information needs not be written with "-I" and such...
-# Define THREADS if you need it, otherwise leave it unset (same for
-# USE_CAMLP4)!
-
-export THREADS
-export VMTHREADS
-export ANNOTATE
-export USE_CAMLP4
-
-export INCDIRS
-export LIBDIRS
-export EXTLIBDIRS
-export RESULTDEPS
-export OCAML_DEFAULT_DIRS
-
-export LIBS
-export CLIBS
-
-export OCAMLFLAGS
-export OCAMLNCFLAGS
-export OCAMLBCFLAGS
-
-export OCAMLLDFLAGS
-export OCAMLNLDFLAGS
-export OCAMLBLDFLAGS
-
-ifndef OCAMLCPFLAGS
-  OCAMLCPFLAGS := a
-endif
-
-export OCAMLCPFLAGS
-
-export PPFLAGS
-
-export YFLAGS
-export IDLFLAGS
-
-export OCAMLDOCFLAGS
-
-export OCAMLFIND_INSTFLAGS
-
-export DVIPSFLAGS
-
-export STATIC
-
-# Add a list of optional trash files that should be deleted by "make clean"
-export TRASH
-
-####################  variables depending on your OCaml-installation
-
-ifdef MINGW
-  export MINGW
-  WIN32   := 1
-  CFLAGS_WIN32 := -mno-cygwin
-endif
-ifdef MSVC
-  export MSVC
-  WIN32   := 1
-  ifndef STATIC
-    CPPFLAGS_WIN32 := -DCAML_DLL
-  endif
-  CFLAGS_WIN32 += -nologo
-  EXT_OBJ := obj
-  EXT_LIB := lib
-  ifeq ($(CC),gcc)
-    # work around GNU Make default value
-    ifdef THREADS
-      CC := cl -MT
-    else
-      CC := cl
-    endif
-  endif
-  ifeq ($(CXX),g++)
-    # work around GNU Make default value
-    CXX := $(CC)
-  endif
-  CFLAG_O := -Fo
-endif
-ifdef WIN32
-  EXT_CXX := cpp
-  EXE     := .exe
-endif
-
-ifndef EXT_OBJ
-  EXT_OBJ := o
-endif
-ifndef EXT_LIB
-  EXT_LIB := a
-endif
-ifndef EXT_CXX
-  EXT_CXX := cc
-endif
-ifndef EXE
-  EXE := # empty
-endif
-ifndef CFLAG_O
-  CFLAG_O := -o # do not delete this comment (preserves trailing whitespace)!
-endif
-
-export CC
-export CXX
-export CFLAGS
-export CXXFLAGS
-export LDFLAGS
-export CPPFLAGS
-
-ifndef RPATH_FLAG
-  RPATH_FLAG := -R
-endif
-export RPATH_FLAG
-
-ifndef MSVC
-ifndef PIC_CFLAGS
-  PIC_CFLAGS := -fPIC
-endif
-ifndef PIC_CPPFLAGS
-  PIC_CPPFLAGS := -DPIC
-endif
-endif
-
-export PIC_CFLAGS
-export PIC_CPPFLAGS
-
-BCRESULT  := $(addsuffix $(BCSUFFIX), $(RESULT))
-NCRESULT  := $(addsuffix $(NCSUFFIX), $(RESULT))
-TOPRESULT := $(addsuffix $(TOPSUFFIX), $(RESULT))
-
-ifndef OCAMLFIND
-  OCAMLFIND := ocamlfind
-endif
-export OCAMLFIND
-
-ifndef OCAMLC
-  OCAMLC := ocamlc
-endif
-export OCAMLC
-
-ifndef OCAMLOPT
-  OCAMLOPT := ocamlopt
-endif
-export OCAMLOPT
-
-ifndef OCAMLMKTOP
-  OCAMLMKTOP := ocamlmktop
-endif
-export OCAMLMKTOP
-
-ifndef OCAMLCP
-  OCAMLCP := ocamlcp
-endif
-export OCAMLCP
-
-ifndef OCAMLDEP
-  OCAMLDEP := ocamldep
-endif
-export OCAMLDEP
-
-ifndef OCAMLLEX
-  OCAMLLEX := ocamllex
-endif
-export OCAMLLEX
-
-ifndef OCAMLYACC
-  OCAMLYACC := ocamlyacc
-endif
-export OCAMLYACC
-
-ifndef OCAMLMKLIB
-  OCAMLMKLIB := ocamlmklib
-endif
-export OCAMLMKLIB
-
-ifndef OCAML_GLADECC
-  OCAML_GLADECC := lablgladecc2
-endif
-export OCAML_GLADECC
-
-ifndef OCAML_GLADECC_FLAGS
-  OCAML_GLADECC_FLAGS :=
-endif
-export OCAML_GLADECC_FLAGS
-
-ifndef CAMELEON_REPORT
-  CAMELEON_REPORT := report
-endif
-export CAMELEON_REPORT
-
-ifndef CAMELEON_REPORT_FLAGS
-  CAMELEON_REPORT_FLAGS :=
-endif
-export CAMELEON_REPORT_FLAGS
-
-ifndef CAMELEON_ZOGGY
-  CAMELEON_ZOGGY := camlp4o pa_zog.cma pr_o.cmo
-endif
-export CAMELEON_ZOGGY
-
-ifndef CAMELEON_ZOGGY_FLAGS
-  CAMELEON_ZOGGY_FLAGS :=
-endif
-export CAMELEON_ZOGGY_FLAGS
-
-ifndef OXRIDL
-  OXRIDL := oxridl
-endif
-export OXRIDL
-
-ifndef CAMLIDL
-  CAMLIDL := camlidl
-endif
-export CAMLIDL
-
-ifndef CAMLIDLDLL
-  CAMLIDLDLL := camlidldll
-endif
-export CAMLIDLDLL
-
-ifndef NOIDLHEADER
-  MAYBE_IDL_HEADER := -header
-endif
-export NOIDLHEADER
-
-export NO_CUSTOM
-
-ifndef CAMLP4
-  CAMLP4 := camlp4
-endif
-export CAMLP4
-
-ifndef REAL_OCAMLFIND
-  ifdef PACKS
-    ifndef CREATE_LIB
-      ifdef THREADS
-       PACKS += threads
-      endif
-    endif
-    empty :=
-    space := $(empty) $(empty)
-    comma := ,
-    ifdef PREDS
-      PRE_OCAML_FIND_PREDICATES := $(subst $(space),$(comma),$(PREDS))
-      PRE_OCAML_FIND_PACKAGES := $(subst $(space),$(comma),$(PACKS))
-      OCAML_FIND_PREDICATES := -predicates $(PRE_OCAML_FIND_PREDICATES)
-  #    OCAML_DEP_PREDICATES := -syntax $(PRE_OCAML_FIND_PREDICATES)
-      OCAML_FIND_PACKAGES := $(OCAML_FIND_PREDICATES) -package 
$(PRE_OCAML_FIND_PACKAGES)
-      OCAML_DEP_PACKAGES := $(OCAML_DEP_PREDICATES) -package 
$(PRE_OCAML_FIND_PACKAGES)
-    else
-      OCAML_FIND_PACKAGES := -package $(subst $(space),$(comma),$(PACKS))
-      OCAML_DEP_PACKAGES :=
-    endif
-    OCAML_FIND_LINKPKG := -linkpkg
-    REAL_OCAMLFIND := $(OCAMLFIND)
-  endif
-endif
-
-export OCAML_FIND_PACKAGES
-export OCAML_DEP_PACKAGES
-export OCAML_FIND_LINKPKG
-export REAL_OCAMLFIND
-
-ifndef OCAMLDOC
-  OCAMLDOC := ocamldoc
-endif
-export OCAMLDOC
-
-ifndef LATEX
-  LATEX := latex
-endif
-export LATEX
-
-ifndef DVIPS
-  DVIPS := dvips
-endif
-export DVIPS
-
-ifndef PS2PDF
-  PS2PDF := ps2pdf
-endif
-export PS2PDF
-
-ifndef OCAMLMAKEFILE
-  OCAMLMAKEFILE := OCamlMakefile
-endif
-export OCAMLMAKEFILE
-
-ifndef OCAMLLIBPATH
-  OCAMLLIBPATH := \
-    $(shell $(OCAMLC) 2>/dev/null -where || echo /usr/local/lib/ocaml)
-endif
-export OCAMLLIBPATH
-
-ifndef OCAML_LIB_INSTALL
-  OCAML_LIB_INSTALL := $(OCAMLLIBPATH)/contrib
-endif
-export OCAML_LIB_INSTALL
-
-###########################################################################
-
-####################  change following sections only if
-####################    you know what you are doing!
-
-# delete target files when a build command fails
-.PHONY: .DELETE_ON_ERROR
-.DELETE_ON_ERROR:
-
-# for pedants using "--warn-undefined-variables"
-export MAYBE_IDL
-export REAL_RESULT
-export CAMLIDLFLAGS
-export THREAD_FLAG
-export RES_CLIB
-export MAKEDLL
-export ANNOT_FLAG
-export C_OXRIDL
-export SUBPROJS
-export CFLAGS_WIN32
-export CPPFLAGS_WIN32
-
-INCFLAGS :=
-
-SHELL := /bin/sh
-
-MLDEPDIR := ._d
-BCDIDIR  := ._bcdi
-NCDIDIR  := ._ncdi
-
-FILTER_EXTNS := %.mli %.ml %.mll %.mly %.idl %.oxridl %.c %.$(EXT_CXX) %.rep 
%.zog %.glade
-
-FILTERED     := $(filter $(FILTER_EXTNS), $(SOURCES))
-SOURCE_DIRS  := $(filter-out ./, $(sort $(dir $(FILTERED))))
-
-FILTERED_REP := $(filter %.rep, $(FILTERED))
-DEP_REP      := $(FILTERED_REP:%.rep=$(MLDEPDIR)/%.d)
-AUTO_REP     := $(FILTERED_REP:.rep=.ml)
-
-FILTERED_ZOG := $(filter %.zog, $(FILTERED))
-DEP_ZOG      := $(FILTERED_ZOG:%.zog=$(MLDEPDIR)/%.d)
-AUTO_ZOG     := $(FILTERED_ZOG:.zog=.ml)
-
-FILTERED_GLADE := $(filter %.glade, $(FILTERED))
-DEP_GLADE      := $(FILTERED_GLADE:%.glade=$(MLDEPDIR)/%.d)
-AUTO_GLADE     := $(FILTERED_GLADE:.glade=.ml)
-
-FILTERED_ML  := $(filter %.ml, $(FILTERED))
-DEP_ML       := $(FILTERED_ML:%.ml=$(MLDEPDIR)/%.d)
-
-FILTERED_MLI := $(filter %.mli, $(FILTERED))
-DEP_MLI      := $(FILTERED_MLI:.mli=.di)
-
-FILTERED_MLL := $(filter %.mll, $(FILTERED))
-DEP_MLL      := $(FILTERED_MLL:%.mll=$(MLDEPDIR)/%.d)
-AUTO_MLL     := $(FILTERED_MLL:.mll=.ml)
-
-FILTERED_MLY := $(filter %.mly, $(FILTERED))
-DEP_MLY      := $(FILTERED_MLY:%.mly=$(MLDEPDIR)/%.d) $(FILTERED_MLY:.mly=.di)
-AUTO_MLY     := $(FILTERED_MLY:.mly=.mli) $(FILTERED_MLY:.mly=.ml)
-
-FILTERED_IDL := $(filter %.idl, $(FILTERED))
-DEP_IDL      := $(FILTERED_IDL:%.idl=$(MLDEPDIR)/%.d) $(FILTERED_IDL:.idl=.di)
-C_IDL        := $(FILTERED_IDL:%.idl=%_stubs.c)
-ifndef NOIDLHEADER
- C_IDL += $(FILTERED_IDL:.idl=.h)
-endif
-OBJ_C_IDL    := $(FILTERED_IDL:%.idl=%_stubs.$(EXT_OBJ))
-AUTO_IDL     := $(FILTERED_IDL:.idl=.mli) $(FILTERED_IDL:.idl=.ml) $(C_IDL)
-
-FILTERED_OXRIDL := $(filter %.oxridl, $(FILTERED))
-DEP_OXRIDL      := $(FILTERED_OXRIDL:%.oxridl=$(MLDEPDIR)/%.d) 
$(FILTERED_OXRIDL:.oxridl=.di)
-AUTO_OXRIDL     := $(FILTERED_OXRIDL:.oxridl=.mli) 
$(FILTERED_OXRIDL:.oxridl=.ml) $(C_OXRIDL)
-
-FILTERED_C_CXX := $(filter %.c %.$(EXT_CXX), $(FILTERED))
-OBJ_C_CXX      := $(FILTERED_C_CXX:.c=.$(EXT_OBJ))
-OBJ_C_CXX      := $(OBJ_C_CXX:.$(EXT_CXX)=.$(EXT_OBJ))
-
-PRE_TARGETS  += $(AUTO_MLL) $(AUTO_MLY) $(AUTO_IDL) $(AUTO_OXRIDL) $(AUTO_ZOG) 
$(AUTO_REP) $(AUTO_GLADE)
-
-ALL_DEPS     := $(DEP_ML) $(DEP_MLI) $(DEP_MLL) $(DEP_MLY) $(DEP_IDL) 
$(DEP_OXRIDL) $(DEP_ZOG) $(DEP_REP) $(DEP_GLADE)
-
-MLDEPS       := $(filter %.d, $(ALL_DEPS))
-MLIDEPS      := $(filter %.di, $(ALL_DEPS))
-BCDEPIS      := $(MLIDEPS:%.di=$(BCDIDIR)/%.di)
-NCDEPIS      := $(MLIDEPS:%.di=$(NCDIDIR)/%.di)
-
-ALLML        := $(filter %.mli %.ml %.mll %.mly %.idl %.oxridl %.rep %.zog 
%.glade, $(FILTERED))
-
-IMPLO_INTF   := $(ALLML:%.mli=%.mli.__)
-IMPLO_INTF   := $(foreach file, $(IMPLO_INTF), \
-                  $(basename $(file)).cmi $(basename $(file)).cmo)
-IMPLO_INTF   := $(filter-out %.mli.cmo, $(IMPLO_INTF))
-IMPLO_INTF   := $(IMPLO_INTF:%.mli.cmi=%.cmi)
-
-IMPLX_INTF   := $(IMPLO_INTF:.cmo=.cmx)
-
-INTF         := $(filter %.cmi, $(IMPLO_INTF))
-IMPL_CMO     := $(filter %.cmo, $(IMPLO_INTF))
-IMPL_CMX     := $(IMPL_CMO:.cmo=.cmx)
-IMPL_ASM     := $(IMPL_CMO:.cmo=.asm)
-IMPL_S       := $(IMPL_CMO:.cmo=.s)
-
-OBJ_LINK     := $(OBJ_C_IDL) $(OBJ_C_CXX)
-OBJ_FILES    := $(IMPL_CMO:.cmo=.$(EXT_OBJ)) $(OBJ_LINK)
-
-EXECS        := $(addsuffix $(EXE), \
-                            $(sort $(TOPRESULT) $(BCRESULT) $(NCRESULT)))
-ifdef WIN32
-  EXECS      += $(BCRESULT).dll $(NCRESULT).dll
-endif
-
-CLIB_BASE    := $(RESULT)$(RES_CLIB_SUF)
-ifneq ($(strip $(OBJ_LINK)),)
-  RES_CLIB     := lib$(CLIB_BASE).$(EXT_LIB)
-endif
-
-ifdef WIN32
-DLLSONAME := $(CLIB_BASE).dll
-else
-DLLSONAME := dll$(CLIB_BASE).so
-endif
-
-NONEXECS     := $(INTF) $(IMPL_CMO) $(IMPL_CMX) $(IMPL_ASM) $(IMPL_S) \
-               $(OBJ_FILES) $(PRE_TARGETS) $(BCRESULT).cma $(NCRESULT).cmxa \
-               $(NCRESULT).$(EXT_LIB) $(BCRESULT).cmi $(BCRESULT).cmo \
-               $(NCRESULT).cmi $(NCRESULT).cmx $(NCRESULT).o \
-               $(RES_CLIB) $(IMPL_CMO:.cmo=.annot) \
-               $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo $(LIB_PACK_NAME).cmx 
$(LIB_PACK_NAME).o
-
-ifndef STATIC
-  NONEXECS += $(DLLSONAME)
-endif
-
-ifndef LIBINSTALL_FILES
-  LIBINSTALL_FILES := $(RESULT).mli $(RESULT).cmi $(RESULT).cma \
-                     $(RESULT).cmxa $(RESULT).$(EXT_LIB) $(RES_CLIB)
-  ifndef STATIC
-    ifneq ($(strip $(OBJ_LINK)),)
-      LIBINSTALL_FILES += $(DLLSONAME)
-    endif
-  endif
-endif
-
-export LIBINSTALL_FILES
-
-ifdef WIN32
-  # some extra stuff is created while linking DLLs
-  NONEXECS   += $(BCRESULT).$(EXT_LIB) $(BCRESULT).exp $(NCRESULT).exp 
$(CLIB_BASE).exp $(CLIB_BASE).lib
-endif
-
-TARGETS      := $(EXECS) $(NONEXECS)
-
-# If there are IDL-files
-ifneq ($(strip $(FILTERED_IDL)),)
-  MAYBE_IDL := -cclib -lcamlidl
-endif
-
-ifdef USE_CAMLP4
-  CAMLP4PATH := \
-    $(shell $(CAMLP4) -where 2>/dev/null || echo /usr/local/lib/camlp4)
-  INCFLAGS := -I $(CAMLP4PATH)
-  CINCFLAGS := -I$(CAMLP4PATH)
-endif
-
-DINCFLAGS := $(INCFLAGS) $(SOURCE_DIRS:%=-I %) $(OCAML_DEFAULT_DIRS:%=-I %)
-INCFLAGS := $(DINCFLAGS) $(INCDIRS:%=-I %)
-CINCFLAGS += $(SOURCE_DIRS:%=-I%) $(INCDIRS:%=-I%) $(OCAML_DEFAULT_DIRS:%=-I%)
-
-ifndef MSVC
-CLIBFLAGS += $(SOURCE_DIRS:%=-L%) $(LIBDIRS:%=-L%) \
-             $(EXTLIBDIRS:%=-L%) $(EXTLIBDIRS:%=-Wl,$(RPATH_FLAG)%) \
-             $(OCAML_DEFAULT_DIRS:%=-L%)
-endif
-
-ifndef PROFILING
-  INTF_OCAMLC := $(OCAMLC)
-else
-  ifndef THREADS
-    INTF_OCAMLC := $(OCAMLCP) -p $(OCAMLCPFLAGS)
-  else
-    # OCaml does not support profiling byte code
-    # with threads (yet), therefore we force an error.
-    ifndef REAL_OCAMLC
-      $(error Profiling of multithreaded byte code not yet supported by OCaml)
-    endif
-    INTF_OCAMLC := $(OCAMLC)
-  endif
-endif
-
-ifndef MSVC
-COMMON_LDFLAGS := $(LDFLAGS:%=-ccopt %) $(SOURCE_DIRS:%=-ccopt -L%) \
-                 $(LIBDIRS:%=-ccopt -L%) $(EXTLIBDIRS:%=-ccopt -L%) \
-                 $(EXTLIBDIRS:%=-ccopt -Wl,$(RPATH_FLAG)%) \
-                 $(OCAML_DEFAULT_DIRS:%=-ccopt -L%)
-else
-COMMON_LDFLAGS := -ccopt "/link -NODEFAULTLIB:LIBC $(LDFLAGS:%=%) 
$(SOURCE_DIRS:%=-LIBPATH:%) \
-                 $(LIBDIRS:%=-LIBPATH:%) $(EXTLIBDIRS:%=-LIBPATH:%) \
-                 $(OCAML_DEFAULT_DIRS:%=-LIBPATH:%) "
-endif
-
-CLIBS_OPTS := $(CLIBS:%=-cclib -l%)
-ifdef MSVC
-  ifndef STATIC
-  # MSVC libraries do not have 'lib' prefix
-  CLIBS_OPTS := $(CLIBS:%=-cclib %.lib)
-  endif
-endif
-
-ifneq ($(strip $(OBJ_LINK)),)
-  ifdef CREATE_LIB
-    OBJS_LIBS := -cclib -l$(CLIB_BASE) $(CLIBS_OPTS) $(MAYBE_IDL)
-  else
-    OBJS_LIBS := $(OBJ_LINK) $(CLIBS_OPTS) $(MAYBE_IDL)
-  endif
-else
-  OBJS_LIBS := $(CLIBS_OPTS) $(MAYBE_IDL)
-endif
-
-# If we have to make byte-code
-ifndef REAL_OCAMLC
-  BYTE_OCAML := y
-
-  # EXTRADEPS is added dependencies we have to insert for all
-  # executable files we generate.  Ideally it should be all of the
-  # libraries we use, but it's hard to find the ones that get searched on
-  # the path since I don't know the paths built into the compiler, so
-  # just include the ones with slashes in their names.
-  EXTRADEPS := $(addsuffix .cma,$(foreach i,$(LIBS),$(if $(findstring 
/,$(i)),$(i))))
-  SPECIAL_OCAMLFLAGS := $(OCAMLBCFLAGS)
-
-  REAL_OCAMLC := $(INTF_OCAMLC)
-
-  REAL_IMPL := $(IMPL_CMO)
-  REAL_IMPL_INTF := $(IMPLO_INTF)
-  IMPL_SUF := .cmo
-
-  DEPFLAGS  :=
-  MAKE_DEPS := $(MLDEPS) $(BCDEPIS)
-
-  ifdef CREATE_LIB
-    CFLAGS := $(PIC_CFLAGS) $(CFLAGS)
-    CPPFLAGS := $(PIC_CPPFLAGS) $(CPPFLAGS)
-    ifndef STATIC
-      ifneq ($(strip $(OBJ_LINK)),)
-       MAKEDLL := $(DLLSONAME)
-       ALL_LDFLAGS := -dllib $(DLLSONAME)
-      endif
-    endif
-  endif
-
-  ifndef NO_CUSTOM
-    ifneq "$(strip $(OBJ_LINK) $(THREADS) $(MAYBE_IDL) $(CLIBS))" ""
-      ALL_LDFLAGS += -custom
-    endif
-  endif
-
-  ALL_LDFLAGS += $(INCFLAGS) $(OCAMLLDFLAGS) $(OCAMLBLDFLAGS) \
-                 $(COMMON_LDFLAGS) $(LIBS:%=%.cma)
-  CAMLIDLDLLFLAGS :=
-
-  ifdef THREADS
-    ifdef VMTHREADS
-      THREAD_FLAG := -vmthread
-    else
-      THREAD_FLAG := -thread
-    endif
-    ALL_LDFLAGS := $(THREAD_FLAG) $(ALL_LDFLAGS)
-    ifndef CREATE_LIB
-      ifndef REAL_OCAMLFIND
-        ALL_LDFLAGS := unix.cma threads.cma $(ALL_LDFLAGS)
-      endif
-    endif
-  endif
-
-# we have to make native-code
-else
-  EXTRADEPS := $(addsuffix .cmxa,$(foreach i,$(LIBS),$(if $(findstring 
/,$(i)),$(i))))
-  ifndef PROFILING
-    SPECIAL_OCAMLFLAGS := $(OCAMLNCFLAGS)
-    PLDFLAGS :=
-  else
-    SPECIAL_OCAMLFLAGS := -p $(OCAMLNCFLAGS)
-    PLDFLAGS := -p
-  endif
-
-  REAL_IMPL := $(IMPL_CMX)
-  REAL_IMPL_INTF := $(IMPLX_INTF)
-  IMPL_SUF := .cmx
-
-  CPPFLAGS := -DNATIVE_CODE $(CPPFLAGS)
-
-  DEPFLAGS  := -native
-  MAKE_DEPS := $(MLDEPS) $(NCDEPIS)
-
-  ALL_LDFLAGS := $(PLDFLAGS) $(INCFLAGS) $(OCAMLLDFLAGS) \
-                 $(OCAMLNLDFLAGS) $(COMMON_LDFLAGS)
-  CAMLIDLDLLFLAGS := -opt
-
-  ifndef CREATE_LIB
-    ALL_LDFLAGS += $(LIBS:%=%.cmxa)
-  else
-    CFLAGS := $(PIC_CFLAGS) $(CFLAGS)
-    CPPFLAGS := $(PIC_CPPFLAGS) $(CPPFLAGS)
-  endif
-
-  ifdef THREADS
-    THREAD_FLAG := -thread
-    ALL_LDFLAGS := $(THREAD_FLAG) $(ALL_LDFLAGS)
-    ifndef CREATE_LIB
-      ifndef REAL_OCAMLFIND
-        ALL_LDFLAGS := unix.cmxa threads.cmxa $(ALL_LDFLAGS)
-      endif
-    endif
-  endif
-endif
-
-export MAKE_DEPS
-
-ifdef ANNOTATE
-  ANNOT_FLAG := -dtypes
-else
-endif
-
-ALL_OCAMLCFLAGS := $(THREAD_FLAG) $(ANNOT_FLAG) $(OCAMLFLAGS) \
-                   $(INCFLAGS) $(SPECIAL_OCAMLFLAGS)
-
-ifdef make_deps
-  -include $(MAKE_DEPS)
-  PRE_TARGETS :=
-endif
-
-###########################################################################
-# USER RULES
-
-# Call "OCamlMakefile QUIET=" to get rid of all of the @'s.
-QUIET=@
-
-# generates byte-code (default)
-byte-code:             $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \
-                               REAL_RESULT="$(BCRESULT)" make_deps=yes
-bc:    byte-code
-
-byte-code-nolink:      $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \
-                               REAL_RESULT="$(BCRESULT)" make_deps=yes
-bcnl:  byte-code-nolink
-
-top:                   $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(TOPRESULT) \
-                               REAL_RESULT="$(BCRESULT)" make_deps=yes
-
-# generates native-code
-
-native-code:           $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \
-                               REAL_RESULT="$(NCRESULT)" \
-                               REAL_OCAMLC="$(OCAMLOPT)" \
-                               make_deps=yes
-nc:    native-code
-
-native-code-nolink:    $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \
-                               REAL_RESULT="$(NCRESULT)" \
-                               REAL_OCAMLC="$(OCAMLOPT)" \
-                               make_deps=yes
-ncnl:  native-code-nolink
-
-# generates byte-code libraries
-byte-code-library:     $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
-                               $(RES_CLIB) $(BCRESULT).cma \
-                               REAL_RESULT="$(BCRESULT)" \
-                               CREATE_LIB=yes \
-                               make_deps=yes
-bcl:   byte-code-library
-
-# generates native-code libraries
-native-code-library:   $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
-                               $(RES_CLIB) $(NCRESULT).cmxa \
-                               REAL_RESULT="$(NCRESULT)" \
-                               REAL_OCAMLC="$(OCAMLOPT)" \
-                               CREATE_LIB=yes \
-                               make_deps=yes
-ncl:   native-code-library
-
-ifdef WIN32
-# generates byte-code dll
-byte-code-dll:         $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
-                               $(RES_CLIB) $(BCRESULT).dll \
-                               REAL_RESULT="$(BCRESULT)" \
-                               make_deps=yes
-bcd:   byte-code-dll
-
-# generates native-code dll
-native-code-dll:       $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
-                               $(RES_CLIB) $(NCRESULT).dll \
-                               REAL_RESULT="$(NCRESULT)" \
-                               REAL_OCAMLC="$(OCAMLOPT)" \
-                               make_deps=yes
-ncd:   native-code-dll
-endif
-
-# generates byte-code with debugging information
-debug-code:            $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \
-                               REAL_RESULT="$(BCRESULT)" make_deps=yes \
-                               OCAMLFLAGS="-g $(OCAMLFLAGS)" \
-                               OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)"
-dc:    debug-code
-
-debug-code-nolink:     $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \
-                               REAL_RESULT="$(BCRESULT)" make_deps=yes \
-                               OCAMLFLAGS="-g $(OCAMLFLAGS)" \
-                               OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)"
-dcnl:  debug-code-nolink
-
-# generates byte-code libraries with debugging information
-debug-code-library:    $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
-                               $(RES_CLIB) $(BCRESULT).cma \
-                               REAL_RESULT="$(BCRESULT)" make_deps=yes \
-                               CREATE_LIB=yes \
-                               OCAMLFLAGS="-g $(OCAMLFLAGS)" \
-                               OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)"
-dcl:   debug-code-library
-
-# generates byte-code for profiling
-profiling-byte-code:           $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \
-                               REAL_RESULT="$(BCRESULT)" PROFILING="y" \
-                               make_deps=yes
-pbc:   profiling-byte-code
-
-# generates native-code
-
-profiling-native-code:         $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \
-                               REAL_RESULT="$(NCRESULT)" \
-                               REAL_OCAMLC="$(OCAMLOPT)" \
-                               PROFILING="y" \
-                               make_deps=yes
-pnc:   profiling-native-code
-
-# generates byte-code libraries
-profiling-byte-code-library:   $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
-                               $(RES_CLIB) $(BCRESULT).cma \
-                               REAL_RESULT="$(BCRESULT)" PROFILING="y" \
-                               CREATE_LIB=yes \
-                               make_deps=yes
-pbcl:  profiling-byte-code-library
-
-# generates native-code libraries
-profiling-native-code-library: $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
-                               $(RES_CLIB) $(NCRESULT).cmxa \
-                               REAL_RESULT="$(NCRESULT)" PROFILING="y" \
-                               REAL_OCAMLC="$(OCAMLOPT)" \
-                               CREATE_LIB=yes \
-                               make_deps=yes
-pncl:  profiling-native-code-library
-
-# packs byte-code objects
-pack-byte-code:                        $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT).cmo \
-                               REAL_RESULT="$(BCRESULT)" \
-                               PACK_LIB=yes make_deps=yes
-pabc:  pack-byte-code
-
-# packs native-code objects
-pack-native-code:              $(PRE_TARGETS)
-                       $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
-                               $(NCRESULT).cmx $(NCRESULT).o \
-                               REAL_RESULT="$(NCRESULT)" \
-                               REAL_OCAMLC="$(OCAMLOPT)" \
-                               PACK_LIB=yes make_deps=yes
-panc:  pack-native-code
-
-# generates HTML-documentation
-htdoc: doc/$(RESULT)/html
-
-# generates Latex-documentation
-ladoc: doc/$(RESULT)/latex
-
-# generates PostScript-documentation
-psdoc: doc/$(RESULT)/latex/doc.ps
-
-# generates PDF-documentation
-pdfdoc:        doc/$(RESULT)/latex/doc.pdf
-
-# generates all supported forms of documentation
-doc: htdoc ladoc psdoc pdfdoc
-
-###########################################################################
-# LOW LEVEL RULES
-
-$(REAL_RESULT):                $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) 
$(RESULTDEPS)
-                       $(REAL_OCAMLFIND) $(REAL_OCAMLC) \
-                               $(OCAML_FIND_PACKAGES) $(OCAML_FIND_LINKPKG) \
-                               $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \
-                               $(REAL_IMPL)
-
-nolink:                        $(REAL_IMPL_INTF) $(OBJ_LINK)
-
-ifdef WIN32
-$(REAL_RESULT).dll:    $(REAL_IMPL_INTF) $(OBJ_LINK)
-                       $(CAMLIDLDLL) $(CAMLIDLDLLFLAGS) $(OBJ_LINK) $(CLIBS) \
-                               -o $@ $(REAL_IMPL)
-endif
-
-%$(TOPSUFFIX):         $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS)
-                       $(REAL_OCAMLFIND) $(OCAMLMKTOP) \
-                               $(OCAML_FIND_PACKAGES) $(OCAML_FIND_LINKPKG) \
-                               $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \
-                               $(REAL_IMPL)
-
-.SUFFIXES:             .mli .ml .cmi .cmo .cmx .cma .cmxa .$(EXT_OBJ) \
-                        .mly .di .d .$(EXT_LIB) .idl %.oxridl .c .$(EXT_CXX) 
.h .so \
-                        .rep .zog .glade
-
-ifndef STATIC
-ifdef MINGW
-$(DLLSONAME):          $(OBJ_LINK)
-                       $(CC) $(CFLAGS) $(CFLAGS_WIN32) $(OBJ_LINK) -shared -o 
$@ \
-                       -Wl,--whole-archive $(wildcard $(foreach 
dir,$(LIBDIRS),$(CLIBS:%=$(dir)/lib%.a))) \
-                        $(OCAMLLIBPATH)/ocamlrun.a \
-                       -Wl,--export-all-symbols \
-                       -Wl,--no-whole-archive
-else
-ifdef MSVC
-$(DLLSONAME):          $(OBJ_LINK)
-                       link /NOLOGO /DLL /OUT:$@ $(OBJ_LINK) \
-                        $(wildcard $(foreach 
dir,$(LIBDIRS),$(CLIBS:%=$(dir)/%.lib))) \
-                        $(OCAMLLIBPATH)/ocamlrun.lib
-
-else
-$(DLLSONAME):          $(OBJ_LINK)
-                       $(OCAMLMKLIB) $(INCFLAGS) $(CLIBFLAGS) \
-                               -o $(CLIB_BASE) $(OBJ_LINK) $(CLIBS:%=-l%) \
-                               $(OCAMLMKLIB_FLAGS)
-endif
-endif
-endif
-
-ifndef LIB_PACK_NAME
-$(RESULT).cma:         $(REAL_IMPL_INTF) $(MAKEDLL) $(EXTRADEPS) $(RESULTDEPS)
-                       $(REAL_OCAMLFIND) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) \
-                               $(OBJS_LIBS) -o $@ $(OCAMLBLDFLAGS) $(REAL_IMPL)
-
-$(RESULT).cmxa $(RESULT).$(EXT_LIB):   $(REAL_IMPL_INTF) $(EXTRADEPS) 
$(RESULTDEPS)
-                       $(REAL_OCAMLFIND) $(OCAMLOPT) -a $(ALL_LDFLAGS) 
$(OBJS_LIBS) \
-                               $(OCAMLNLDFLAGS) -o $@ $(REAL_IMPL)
-else
-ifdef BYTE_OCAML
-$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo: $(REAL_IMPL_INTF)
-                       $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack -o 
$(LIB_PACK_NAME).cmo $(REAL_IMPL)
-else
-$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmx: $(REAL_IMPL_INTF)
-                       $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack -o 
$(LIB_PACK_NAME).cmx $(REAL_IMPL)
-endif
-
-$(RESULT).cma:         $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo $(MAKEDLL) 
$(EXTRADEPS) $(RESULTDEPS)
-                       $(REAL_OCAMLFIND) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) \
-                               $(OBJS_LIBS) -o $@ $(OCAMLBLDFLAGS) 
$(LIB_PACK_NAME).cmo
-
-$(RESULT).cmxa $(RESULT).$(EXT_LIB):   $(LIB_PACK_NAME).cmi 
$(LIB_PACK_NAME).cmx $(EXTRADEPS) $(RESULTDEPS)
-                       $(REAL_OCAMLFIND) $(OCAMLOPT) -a $(ALL_LDFLAGS) 
$(OBJS_LIBS) \
-                               $(OCAMLNLDFLAGS) -o $@ $(LIB_PACK_NAME).cmx
-endif
-
-$(RES_CLIB):           $(OBJ_LINK)
-ifndef MSVC
-  ifneq ($(strip $(OBJ_LINK)),)
-                     $(AR) rcs $@ $(OBJ_LINK)
-  endif
-else
-  ifneq ($(strip $(OBJ_LINK)),)
-                       lib -nologo -debugtype:cv -out:$(RES_CLIB) $(OBJ_LINK)
-  endif
-endif
-
-.mli.cmi: $(EXTRADEPS)
-                       $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) 
\*)/\1/p;q' $<`; \
-                       if [ -z "$$pp" ]; then \
-                         echo $(REAL_OCAMLFIND) $(INTF_OCAMLC) 
$(OCAML_FIND_PACKAGES) \
-                               -c $(THREAD_FLAG) $(ANNOT_FLAG) \
-                               $(OCAMLFLAGS) $(INCFLAGS) $<; \
-                         $(REAL_OCAMLFIND) $(INTF_OCAMLC) 
$(OCAML_FIND_PACKAGES) \
-                               -c $(THREAD_FLAG) $(ANNOT_FLAG) \
-                               $(OCAMLFLAGS) $(INCFLAGS) $<; \
-                       else \
-                           echo $(REAL_OCAMLFIND) $(INTF_OCAMLC) 
$(OCAML_FIND_PACKAGES) \
-                               -c -pp \"$$pp $(PPFLAGS)\" $(THREAD_FLAG) 
$(ANNOT_FLAG) \
-                               $(OCAMLFLAGS) $(INCFLAGS) $<; \
-                           $(REAL_OCAMLFIND) $(INTF_OCAMLC) 
$(OCAML_FIND_PACKAGES) \
-                               -c -pp "$$pp $(PPFLAGS)" $(THREAD_FLAG) 
$(ANNOT_FLAG) \
-                               $(OCAMLFLAGS) $(INCFLAGS) $<; \
-                       fi
-
-.ml.cmi .ml.$(EXT_OBJ) .ml.cmx .ml.cmo: $(EXTRADEPS)
-                       $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) 
\*)/\1/p;q' $<`; \
-                       if [ -z "$$pp" ]; then \
-                         echo $(REAL_OCAMLFIND) $(REAL_OCAMLC) 
$(OCAML_FIND_PACKAGES) \
-                               -c $(ALL_OCAMLCFLAGS) $<; \
-                         $(REAL_OCAMLFIND) $(REAL_OCAMLC) 
$(OCAML_FIND_PACKAGES) \
-                               -c $(ALL_OCAMLCFLAGS) $<; \
-                       else \
-                         echo $(REAL_OCAMLFIND) $(REAL_OCAMLC) 
$(OCAML_FIND_PACKAGES) \
-                               -c -pp \"$$pp $(PPFLAGS)\" $(ALL_OCAMLCFLAGS) 
$<; \
-                         $(REAL_OCAMLFIND) $(REAL_OCAMLC) 
$(OCAML_FIND_PACKAGES) \
-                               -c -pp "$$pp $(PPFLAGS)" $(ALL_OCAMLCFLAGS) $<; 
\
-                       fi
-
-ifdef PACK_LIB
-$(REAL_RESULT).cmo $(REAL_RESULT).cmx $(REAL_RESULT).o: $(REAL_IMPL_INTF) 
$(OBJ_LINK) $(EXTRADEPS)
-                       $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack $(ALL_LDFLAGS) \
-                               $(OBJS_LIBS) -o $@ $(REAL_IMPL)
-endif
-
-.PRECIOUS:             %.ml
-%.ml:                  %.mll
-                       $(OCAMLLEX) $<
-
-.PRECIOUS:              %.ml %.mli
-%.ml %.mli:             %.mly
-                       $(OCAMLYACC) $(YFLAGS) $<
-                       $(QUIET)pp=`sed -n -e 's/.*(\*pp \([^*]*\) 
\*).*/\1/p;q' $<`; \
-                       if [ ! -z "$$pp" ]; then \
-                         mv $*.ml $*.ml.temporary; \
-                         echo "(*pp $$pp $(PPFLAGS)*)" > $*.ml; \
-                         cat $*.ml.temporary >> $*.ml; \
-                         rm $*.ml.temporary; \
-                         mv $*.mli $*.mli.temporary; \
-                         echo "(*pp $$pp $(PPFLAGS)*)" > $*.mli; \
-                         cat $*.mli.temporary >> $*.mli; \
-                         rm $*.mli.temporary; \
-                       fi
-
-
-.PRECIOUS:             %.ml
-%.ml:                  %.rep
-                       $(CAMELEON_REPORT) $(CAMELEON_REPORT_FLAGS) -gen $<
-
-.PRECIOUS:             %.ml
-%.ml:                  %.zog
-                       $(CAMELEON_ZOGGY)  $(CAMELEON_ZOGGY_FLAGS) -impl $< > $@
-
-.PRECIOUS:             %.ml
-%.ml:                  %.glade
-                       $(OCAML_GLADECC)  $(OCAML_GLADECC_FLAGS) $< > $@
-
-.PRECIOUS:             %.ml %.mli
-%.ml %.mli:            %.oxridl
-                       $(OXRIDL) $<
-
-.PRECIOUS:             %.ml %.mli %_stubs.c %.h
-%.ml %.mli %_stubs.c %.h:              %.idl
-                       $(CAMLIDL) $(MAYBE_IDL_HEADER) $(IDLFLAGS) \
-                               $(CAMLIDLFLAGS) $<
-                       $(QUIET)if [ $(NOIDLHEADER) ]; then touch $*.h; fi
-
-.c.$(EXT_OBJ):
-                       $(OCAMLC) -c -cc "$(CC)" -ccopt "$(CFLAGS) \
-                               $(CPPFLAGS) $(CPPFLAGS_WIN32) \
-                               $(CFLAGS_WIN32) $(CINCFLAGS) $(CFLAG_O)$@ " $< 
-
-.$(EXT_CXX).$(EXT_OBJ):
-                       $(CXX) -c $(CXXFLAGS) $(CINCFLAGS) $(CPPFLAGS) \
-                               -I'$(OCAMLLIBPATH)' \
-                               $< $(CFLAG_O)$@
-
-$(MLDEPDIR)/%.d:       %.ml
-                       $(QUIET)echo making $@ from $<
-                       $(QUIET)if [ ! -d $(@D) ]; then mkdir -p $(@D); fi
-                       $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) 
\*)/\1/p;q' $<`; \
-                       if [ -z "$$pp" ]; then \
-                         $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \
-                               $(DINCFLAGS) $< > $@; \
-                       else \
-                         $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \
-                               -pp "$$pp $(PPFLAGS)" $(DINCFLAGS) $< > $@; \
-                       fi
-
-$(BCDIDIR)/%.di $(NCDIDIR)/%.di:       %.mli
-                       $(QUIET)echo making $@ from $<
-                       $(QUIET)if [ ! -d $(@D) ]; then mkdir -p $(@D); fi
-                       $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) 
\*)/\1/p;q' $<`; \
-                       if [ -z "$$pp" ]; then \
-                         $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) 
$(DINCFLAGS) $< > $@; \
-                       else \
-                         $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) \
-                           -pp "$$pp $(PPFLAGS)" $(DINCFLAGS) $< > $@; \
-                       fi
-
-doc/$(RESULT)/html: $(DOC_FILES)
-       rm -rf $@
-       mkdir -p $@
-       $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \
-       if [ -z "$$pp" ]; then \
-         echo $(OCAMLDOC) -html -d $@ $(OCAMLDOCFLAGS) $(INCFLAGS) 
$(DOC_FILES); \
-         $(OCAMLDOC) -html -d $@ $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES); \
-       else \
-         echo $(OCAMLDOC) -pp \"$$pp $(PPFLAGS)\" -html -d $@ $(OCAMLDOCFLAGS) 
\
-               $(INCFLAGS) $(DOC_FILES); \
-         $(OCAMLDOC) -pp "$$pp $(PPFLAGS)" -html -d $@ $(OCAMLDOCFLAGS) \
-               $(INCFLAGS) $(DOC_FILES); \
-       fi
-
-doc/$(RESULT)/latex: $(DOC_FILES)
-       rm -rf $@
-       mkdir -p $@
-       $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \
-       if [ -z "$$pp" ]; then \
-         echo $(OCAMLDOC) -latex $(OCAMLDOCFLAGS) $(INCFLAGS) \
-               $(DOC_FILES) -o $@/doc.tex; \
-         $(OCAMLDOC) -latex $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES) \
-               -o $@/doc.tex; \
-       else \
-         echo $(OCAMLDOC) -pp \"$$pp $(PPFLAGS)\" -latex $(OCAMLDOCFLAGS) \
-               $(INCFLAGS) $(DOC_FILES) -o $@/doc.tex; \
-         $(OCAMLDOC) -pp "$$pp $(PPFLAGS)" -latex $(OCAMLDOCFLAGS) \
-               $(INCFLAGS) $(DOC_FILES) -o $@/doc.tex; \
-       fi
-
-doc/$(RESULT)/latex/doc.ps: doc/$(RESULT)/latex
-       cd doc/$(RESULT)/latex && \
-         $(LATEX) doc.tex && \
-         $(LATEX) doc.tex && \
-         $(DVIPS) $(DVIPSFLAGS) doc.dvi -o $(@F)
-
-doc/$(RESULT)/latex/doc.pdf: doc/$(RESULT)/latex/doc.ps
-       cd doc/$(RESULT)/latex && $(PS2PDF) $(<F)
-
-define make_subproj
-.PHONY:
-subproj_$(1):
-       $$(eval $$(call PROJ_$(1)))
-       $(QUIET)if [ "$(SUBTARGET)" != "all" ]; then \
-         $(MAKE) -f $(OCAMLMAKEFILE) $(SUBTARGET); \
-       fi
-endef
-
-$(foreach subproj,$(SUBPROJS),$(eval $(call make_subproj,$(subproj))))
-
-.PHONY:
-subprojs: $(SUBPROJS:%=subproj_%)
-
-###########################################################################
-# (UN)INSTALL RULES FOR LIBRARIES
-
-.PHONY: libinstall
-libinstall:    all
-       $(QUIET)printf "\nInstalling library with ocamlfind\n"
-       $(OCAMLFIND) install $(OCAMLFIND_INSTFLAGS) $(RESULT) META 
$(LIBINSTALL_FILES)
-       $(QUIET)printf "\nInstallation successful.\n"
-
-.PHONY: libuninstall
-libuninstall:
-       $(QUIET)printf "\nUninstalling library with ocamlfind\n"
-       $(OCAMLFIND) remove $(OCAMLFIND_INSTFLAGS) $(RESULT)
-       $(QUIET)printf "\nUninstallation successful.\n"
-
-.PHONY: rawinstall
-rawinstall:    all
-       $(QUIET)printf "\nInstalling library to: $(OCAML_LIB_INSTALL)\n"
-       -install -d $(OCAML_LIB_INSTALL)
-       for i in $(LIBINSTALL_FILES); do \
-         if [ -f $$i ]; then \
-           install -c -m 0644 $$i $(OCAML_LIB_INSTALL); \
-         fi; \
-       done
-       $(QUIET)printf "\nInstallation successful.\n"
-
-.PHONY: rawuninstall
-rawuninstall:
-       $(QUIET)printf "\nUninstalling library from: $(OCAML_LIB_INSTALL)\n"
-       cd $(OCAML_LIB_INSTALL) && rm $(notdir $(LIBINSTALL_FILES))
-       $(QUIET)printf "\nUninstallation successful.\n"
-
-###########################################################################
-# MAINTAINANCE RULES
-
-.PHONY:        clean
-clean::
-       rm -f $(TARGETS) $(TRASH)
-       rm -rf $(BCDIDIR) $(NCDIDIR) $(MLDEPDIR)
-
-.PHONY:        cleanup
-cleanup::
-       rm -f $(NONEXECS) $(TRASH)
-       rm -rf $(BCDIDIR) $(NCDIDIR) $(MLDEPDIR)
-
-.PHONY: clean-doc
-clean-doc::
-       rm -rf doc
-
-.PHONY: nobackup
-nobackup:
-       rm -f *.bak *~ *.dup
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/PDB.ml
--- a/tools/debugger/pdb/PDB.ml Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,342 +0,0 @@
-(** PDB.ml
- *
- *  Dispatch debugger commands to the appropriate context
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-open Util
-
-exception Unimplemented of string
-exception Unknown_context of string
-exception Unknown_domain
-exception Unknown_process
-
-type context_t =
-  | Void
-  | Xen_virq
-  | Xen_xcs
-  | Xen_domain of Xen_domain.context_t
-  | Domain of Domain.context_t
-  | Process of Process.context_t
-
-let string_of_context ctx =
-  match ctx with
-  | Void -> "{void}"
-  | Xen_virq  -> "{Xen virq evtchn}"
-  | Xen_xcs   -> "{Xen xcs socket}"
-  | Xen_domain d -> Xen_domain.string_of_context d
-  | Domain d  -> Domain.string_of_context d
-  | Process p -> Process.string_of_context p
-
-
-let hash = Hashtbl.create 10
-
-
-(***************************************************************************)
-
-let find_context key =
-  try
-    Hashtbl.find hash key
-  with
-    Not_found ->
-      print_endline "error: (find_context) PDB context not found";
-      raise Not_found
-
-let delete_context key =
-  Hashtbl.remove hash key
-
-
-(**
-   find_process : Locate the socket associated with the context(s)
-   matching a particular (domain, process id) pair.  if there are multiple
-   contexts (there shouldn't be), then return the first one.
- *)
-
-let find_process dom pid =
-    let find key ctx list =
-      match ctx with
-      |        Process p ->
-         if (((Process.get_domain p) = dom) &&
-             ((Process.get_process p) = pid))
-         then
-           key :: list
-         else
-           list
-      | _ -> list
-    in
-    let sock_list = Hashtbl.fold find hash [] in
-    match sock_list with
-    | hd::tl -> hd
-    | [] -> raise Unknown_process
-
-
-(**
-   find_domain : Locate the socket associated with the context(s)
-   matching a particular (domain, vcpu) pair.  if there are multiple
-   contexts (there shouldn't be), then return the first one.
- *)
-
-let find_domain dom vcpu =
-    let find key ctx list =
-      match ctx with
-      |        Domain d ->
-         if (((Domain.get_domain d) = dom) &&
-             ((Domain.get_vcpu d) = vcpu))
-         then
-           key :: list
-         else
-           list
-      | _ -> list
-    in
-    let sock_list = Hashtbl.fold find hash [] in
-    match sock_list with
-    | hd::tl -> hd
-    | [] -> raise Unknown_domain
-
-(**
-   find_xen_domain_context : fetch the socket associated with the
-   xen_domain context for a domain.  if there are multiple contexts
-   (there shouldn't be), then return the first one.
- *)
-
-let find_xen_domain_context domain =
-  let find key ctx list =
-    match ctx with
-      | Xen_domain d ->
-         if ((Xen_domain.get_domain d) = domain)
-         then
-           key :: list
-         else
-           list
-      | _ -> list
-  in
-  let sock_list = Hashtbl.fold find hash [] in
-  match sock_list with
-    | hd::tl -> hd
-    | [] -> raise Unknown_domain
-
-let attach_debugger ctx =
-  match ctx with
-  | Domain d  -> Domain.attach_debugger (Domain.get_domain d) 
-                                       (Domain.get_vcpu d)
-  | Process p ->
-      begin
-       let xdom_sock = find_xen_domain_context (Process.get_domain p) in
-       let xdom_ctx = find_context xdom_sock in
-       begin
-         match xdom_ctx with
-           | Xen_domain d ->
-               Process.attach_debugger p d
-           | _ -> failwith ("context has wrong xen domain type")
-       end;
-       raise No_reply
-      end
-  | _ -> raise (Unimplemented "attach debugger")
-
-let detach_debugger ctx =
-  match ctx with
-  | Domain d  -> 
-      Domain.detach_debugger (Domain.get_domain d) 
-                            (Domain.get_vcpu d);
-      "OK"
-  | Process p  ->
-      Process.detach_debugger p;
-      raise No_reply
-  | _ -> raise (Unimplemented "detach debugger")
-
-
-let debug_contexts () =
-  print_endline "context list:";
-  let print_context key ctx = 
-    match ctx with
-    | Void -> print_endline (Printf.sprintf "  [%s] {void}" 
-                              (Util.get_connection_info key))
-    | Xen_virq  -> print_endline (Printf.sprintf "  [%s] {xen virq evtchn}" 
-                                 (Util.get_connection_info key))
-    | Xen_xcs   -> print_endline (Printf.sprintf "  [%s] {xen xcs socket}" 
-                                 (Util.get_connection_info key))
-    | Xen_domain d -> print_endline (Printf.sprintf "  [%s] %s" 
-                                 (Util.get_connection_info key) 
-                                  (Xen_domain.string_of_context d))
-    | Domain d  -> print_endline (Printf.sprintf "  [%s] %s" 
-                                 (Util.get_connection_info key)
-                                 (Domain.string_of_context d))
-    | Process p -> print_endline (Printf.sprintf "  [%s] %s" 
-                                 (Util.get_connection_info key)
-                                 (Process.string_of_context p))
-  in
-  Hashtbl.iter print_context hash
-
-(** add_context : add a new context to the hash table.
- *  if there is an existing context for the same key then it 
- *  is first removed implictly by the hash table replace function.
- *)
-let add_context (key:Unix.file_descr) context params =
-  match context with
-  | "void"     -> Hashtbl.replace hash key Void
-  | "xen virq" -> Hashtbl.replace hash key Xen_virq
-  | "xen xcs"  -> Hashtbl.replace hash key Xen_xcs
-  | "domain" -> 
-      begin
-       match params with
-       | dom::vcpu::_ ->
-            let d = Domain(Domain.new_context dom vcpu) in
-           attach_debugger d;
-            Hashtbl.replace hash key d
-       | _ -> failwith "bogus parameters to domain context"
-      end
-  | "process" -> 
-      begin
-       match params with
-       | dom::pid::_ ->
-           let p = Process(Process.new_context dom pid) in
-           Hashtbl.replace hash key p;
-           attach_debugger p
-       | _ -> failwith "bogus parameters to process context"
-      end
-  | "xen domain"
-  | _ -> raise (Unknown_context context)
-
-(* 
- * this is really bogus.  add_xen_domain_context should really
- * be a case within add_context.  however, we need to pass in
- * a pointer that can only be represented as an int32.
- * this would require a different type for params... :(
- * 31 bit integers suck.
- *)
-let add_xen_domain_context (key:Unix.file_descr) dom evtchn sring =
-  let d = Xen_domain.new_context dom evtchn sring in
-  Hashtbl.replace hash key (Xen_domain(d))
-
-
-let add_default_context sock =
-  add_context sock "void" []
-
-(***************************************************************************)
-
-(***************************************************************************)
-
-let read_register ctx register =    (* register is int32 because of sscanf *)
-  match ctx with
-  | Void -> 0l                                      (* default for startup *)
-  | Domain d  -> Domain.read_register d register
-  | Process p ->
-      begin
-       Process.read_register p register;
-       raise No_reply
-      end
-  | _ -> raise (Unimplemented "read registers")
-
-let read_registers ctx =
-  match ctx with
-  | Void -> Intel.null_registers                    (* default for startup *)
-  | Domain d  -> Domain.read_registers d 
-  | Process p ->
-      begin
-       Process.read_registers p;
-       raise No_reply
-      end
-  | _ -> raise (Unimplemented "read registers")
-
-let write_register ctx register value =
-  match ctx with
-  | Domain d  -> Domain.write_register d register value
-  | Process p ->
-      begin
-       Process.write_register p register value;
-       raise No_reply
-      end
-  | _ -> raise (Unimplemented "write register")
-
-
-let read_memory ctx addr len =
-  match ctx with
-  | Domain d  -> Domain.read_memory d addr len
-  | Process p ->
-      begin
-       Process.read_memory p addr len;
-       raise No_reply
-      end
-  | _ -> raise (Unimplemented "read memory")
-
-let write_memory ctx addr values =
-  match ctx with
-  | Domain d  -> Domain.write_memory d addr values
-  | Process p ->
-      begin
-       Process.write_memory p addr values;
-       raise No_reply
-      end
-  | _ -> raise (Unimplemented "write memory")
-
-
-let continue ctx =
-  match ctx with
-  | Domain d  -> Domain.continue d
-  | Process p  -> Process.continue p
-  | _ -> raise (Unimplemented "continue")
-
-let step ctx =
-  match ctx with
-  | Domain d  -> Domain.step d
-  | Process p  -> Process.step p
-  | _ -> raise (Unimplemented "step")
-
-
-let insert_memory_breakpoint ctx addr len =
-  match ctx with
-  | Domain d  -> Domain.insert_memory_breakpoint d addr len
-  | Process p  ->
-      begin
-       Process.insert_memory_breakpoint p addr len;
-       raise No_reply
-      end
-  | _ -> raise (Unimplemented "insert memory breakpoint")
-
-let remove_memory_breakpoint ctx addr len =
-  match ctx with
-  | Domain d  -> Domain.remove_memory_breakpoint d addr len
-  | Process p  ->
-      begin
-       Process.remove_memory_breakpoint p addr len;
-       raise No_reply
-      end
-  | _ -> raise (Unimplemented "remove memory breakpoint")
-
-let insert_watchpoint ctx kind addr len =
-  match ctx with
-(*  | Domain d  -> Domain.insert_watchpoint d kind addr len  TODO *)
-  | Process p  ->
-      begin
-       Process.insert_watchpoint p kind addr len;
-       raise No_reply
-      end
-  | _ -> raise (Unimplemented "insert watchpoint")
-
-let remove_watchpoint ctx kind addr len =
-  match ctx with
-(*  | Domain d  -> Domain.remove_watchpoint d kind addr len  TODO *)
-  | Process p  ->
-      begin
-       Process.remove_watchpoint p kind addr len;
-       raise No_reply
-      end
-  | _ -> raise (Unimplemented "remove watchpoint")
-
-
-let pause ctx =
-  match ctx with
-  | Domain d  -> Domain.pause d
-  | Process p  -> Process.pause p
-  | _ -> raise (Unimplemented "pause target")
-
-
-external open_debugger : unit -> unit = "open_context"
-external close_debugger : unit -> unit = "close_context"
-
-(* this is just the domains right now... expand to other contexts later *)
-external debugger_status : unit -> unit = "debugger_status"
-
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/Process.ml
--- a/tools/debugger/pdb/Process.ml     Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-(** Process.ml
- *
- *  process context implementation
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-open Int32
-open Intel
-
-type context_t =
-{
-  mutable domain  : int;
-  mutable process : int;
-  mutable evtchn  : int;
-  mutable ring    : int32;
-}
-
-let default_context = { domain = 0; process = 0; evtchn = 0; ring = 0l }
-
-let new_context dom proc = { domain = dom; process = proc; 
-                             evtchn = 0; ring = 0l }
-
-let string_of_context ctx =
-  Printf.sprintf "{process} domain: %d, process: %d"
-                 ctx.domain  ctx.process
-
-let set_domain ctx value =
-  ctx.domain <- value;
-  print_endline (Printf.sprintf "ctx.domain <- %d" ctx.domain)
-
-let set_process ctx value =
-  ctx.process <- value;
-  print_endline (Printf.sprintf "ctx.process <- %d" ctx.process)
-
-let get_domain ctx =
-  ctx.domain
-
-let get_process ctx =
-  ctx.process
-
-external _attach_debugger : context_t -> unit = "proc_attach_debugger"
-external detach_debugger : context_t -> unit = "proc_detach_debugger"
-external pause_target : context_t -> unit = "proc_pause_target"
-
-(* save the event channel and ring for the domain for future use *)
-let attach_debugger proc_ctx dom_ctx =
-  print_endline (Printf.sprintf "%d %lx"
-    (Xen_domain.get_evtchn dom_ctx)
-    (Xen_domain.get_ring dom_ctx));
-  proc_ctx.evtchn <- Xen_domain.get_evtchn dom_ctx;
-  proc_ctx.ring   <- Xen_domain.get_ring   dom_ctx;
-  _attach_debugger proc_ctx
-
-external read_register : context_t -> int -> unit = "proc_read_register"
-external read_registers : context_t -> unit = "proc_read_registers"
-external write_register : context_t -> register -> int32 -> unit =
-  "proc_write_register"
-external read_memory : context_t -> int32 -> int -> unit = 
-  "proc_read_memory"
-external write_memory : context_t -> int32 -> int list -> unit = 
-  "proc_write_memory"
-
-external continue : context_t -> unit = "proc_continue_target"
-external step : context_t -> unit = "proc_step_target"
-
-external insert_memory_breakpoint : context_t -> int32 -> int -> unit = 
-  "proc_insert_memory_breakpoint"
-external remove_memory_breakpoint : context_t -> int32 -> int -> unit = 
-  "proc_remove_memory_breakpoint"
-external insert_watchpoint : context_t -> int -> int32 -> int -> unit =
-  "proc_insert_watchpoint"
-external remove_watchpoint : context_t -> int -> int32 -> int -> unit =
-  "proc_remove_watchpoint"
-
-let pause ctx =
-  pause_target ctx
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/Process.mli
--- a/tools/debugger/pdb/Process.mli    Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-(** Process.mli
- *
- *  process context interface
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-open Int32
-open Intel
-
-type context_t
-
-val default_context : context_t
-val new_context : int -> int -> context_t
-
-val set_domain : context_t -> int -> unit
-val get_domain : context_t -> int
-val set_process : context_t -> int -> unit
-val get_process : context_t -> int
-
-val string_of_context : context_t -> string
-
-val attach_debugger : context_t -> Xen_domain.context_t -> unit
-val detach_debugger : context_t -> unit
-val pause : context_t -> unit
-
-val read_register : context_t -> int -> unit
-val read_registers : context_t -> unit
-val write_register : context_t -> register -> int32 -> unit
-val read_memory : context_t -> int32 -> int -> unit
-val write_memory : context_t -> int32 -> int list -> unit
-       
-val continue : context_t -> unit
-val step : context_t -> unit
-
-val insert_memory_breakpoint : context_t -> int32 -> int -> unit
-val remove_memory_breakpoint : context_t -> int32 -> int -> unit
-val insert_watchpoint : context_t -> int -> int32 -> int -> unit
-val remove_watchpoint : context_t -> int -> int32 -> int -> unit
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/Util.ml
--- a/tools/debugger/pdb/Util.ml        Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-(** Util.ml
- *
- *  various utility functions
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-let int_of_hexchar h = 
-  let i = int_of_char h in
-  match h with
-  | '0' .. '9' -> i - (int_of_char '0')
-  | 'a' .. 'f' -> i - (int_of_char 'a') + 10
-  | 'A' .. 'F' -> i - (int_of_char 'A') + 10
-  | _ -> raise (Invalid_argument "unknown hex character")
-
-let hexchar_of_int i = 
-  let hexchars = [| '0'; '1'; '2'; '3'; '4'; '5'; '6'; '7';
-                   '8'; '9'; 'a'; 'b'; 'c'; 'd'; 'e'; 'f' |]
-  in
-  hexchars.(i)
-
-
-(** flip the bytes of a four byte int 
- *)
-
-let flip_int num =
-  let a = num mod 256
-  and b = (num / 256) mod 256
-  and c = (num / (256 * 256)) mod 256
-  and d = (num / (256 * 256 * 256)) in
-  (a * 256 * 256 * 256) + (b * 256 * 256) + (c * 256) + d
-
-    
-let flip_int32 num =
-  let a = Int32.logand num 0xffl
-  and b = Int32.logand (Int32.shift_right_logical num 8)  0xffl
-  and c = Int32.logand (Int32.shift_right_logical num 16) 0xffl
-  and d =              (Int32.shift_right_logical num 24)       in
-  (Int32.logor
-     (Int32.logor (Int32.shift_left a 24) (Int32.shift_left b 16))
-     (Int32.logor (Int32.shift_left c 8)  d))
-
-
-let int_list_of_string_list list =
-  List.map (fun x -> int_of_string x) list
-    
-let int_list_of_string str len =
-  let array_of_string s =
-    let int_array = Array.make len 0 in
-    for loop = 0 to len - 1 do
-      int_array.(loop) <- (Char.code s.[loop]);
-    done;
-    int_array
-  in
-  Array.to_list (array_of_string str)
-
-
-(* remove leading and trailing whitespace from a string *)
-
-let chomp str =
-  let head = Str.regexp "^[ \t\r\n]+" in
-  let tail = Str.regexp "[ \t\r\n]+$" in
-  let str = Str.global_replace head "" str in
-  Str.global_replace tail "" str
-
-(* Stupid little parser for    "<key>=<value>[,<key>=<value>]*"
-   It first chops the entire command at each ',', so no ',' in key or value!
-   Mucked to return a list of words for "value"
- *)
-
-let list_of_string str =
-  let delim c = Str.regexp ("[ \t]*" ^ c ^ "[ \t]*") in
-  let str_list = Str.split (delim " ") str in
-  List.map (fun x -> chomp(x)) str_list
-
-let little_parser fn str =
-  let delim c = Str.regexp ("[ \t]*" ^ c ^ "[ \t]*") in
-  let str_list = Str.split (delim ",") str in
-  let pair s =
-    match Str.split (delim "=") s with
-    | [key;value] -> fn (chomp key) (list_of_string value)
-    | [key] -> fn (chomp key) []
-    | _ -> failwith (Printf.sprintf "error: (little_parser) parse error [%s]" 
str)
-  in
-  List.iter pair str_list
-
-(* boolean list membership test *)
-let not_list_member the_list element =
-  try 
-    List.find (fun x -> x = element) the_list;
-    false
-  with
-    Not_found -> true
-
-(* a very inefficient way to remove the elements of one list from another *)
-let list_remove the_list remove_list =
-  List.filter (not_list_member remove_list) the_list
-
-(* get a description of a file descriptor *)
-let get_connection_info fd =
-  let get_local_info fd =
-    let sockname = Unix.getsockname fd in
-    match sockname with
-    | Unix.ADDR_UNIX(s) -> "unix"
-    | Unix.ADDR_INET(a,p) -> ((Unix.string_of_inet_addr a) ^ ":" ^
-                             (string_of_int p))
-  and get_remote_info fd =
-    let sockname = Unix.getpeername fd in 
-    match sockname with
-    | Unix.ADDR_UNIX(s) -> s
-    | Unix.ADDR_INET(a,p) -> ((Unix.string_of_inet_addr a) ^ ":" ^
-                             (string_of_int p))
-  in
-  try
-    get_remote_info fd
-  with
-  | Unix.Unix_error (Unix.ENOTSOCK, s1, s2) -> 
-      let s = Unix.fstat fd in
-      Printf.sprintf "dev: %d, inode: %d" s.Unix.st_dev s.Unix.st_ino
-  | Unix.Unix_error (Unix.EBADF, s1, s2) -> 
-      let s = Unix.fstat fd in
-      Printf.sprintf "dev: %d, inode: %d" s.Unix.st_dev s.Unix.st_ino
-  | _ -> get_local_info fd
-
-
-(* really write a string *)
-let really_write fd str =
-  let strlen = String.length str in
-  let sent = ref 0 in
-  while (!sent < strlen) do
-    sent := !sent + (Unix.write fd str !sent (strlen - !sent))
-  done
-
-let write_character fd ch =
-  let str = String.create 1 in
-  str.[0] <- ch;
-  really_write fd str
-
-
-
-let send_reply fd reply =
-  let checksum = ref 0 in
-  write_character fd '$';
-  for loop = 0 to (String.length reply) - 1 do
-    write_character fd reply.[loop];
-    checksum := !checksum + int_of_char reply.[loop]
-  done;
-  write_character fd '#';
-  write_character fd (hexchar_of_int ((!checksum mod 256) / 16));
-  write_character fd (hexchar_of_int ((!checksum mod 256) mod 16))
-  (*
-   * BUG NEED TO LISTEN FOR REPLY +/- AND POSSIBLY RE-TRANSMIT
-   *)
-
-
-(** A few debugger commands such as step 's' and continue 'c' do 
- *  not immediately return a response to the debugger.  In these 
- *  cases we raise No_reply instead. 
- *  This is also used by some contexts (such as Linux processes)
- *  which utilize an asynchronous request / response protocol when
- *  communicating with their respective backends.
- *)
-exception No_reply
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/Xen_domain.ml
--- a/tools/debugger/pdb/Xen_domain.ml  Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-(** Xen_domain.ml
- *
- *  domain assist for debugging processes
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-type context_t =
-{
-  mutable domain : int;
-  mutable evtchn : int;
-  mutable pdb_front_ring : int32
-}
-
-let default_context = { domain = 0; evtchn = 0; pdb_front_ring = 0l }
-
-let new_context dom evtchn ring = 
-  {domain = dom; evtchn = evtchn; pdb_front_ring = ring}
-
-let set_domain ctx value =
-  ctx.domain <- value
-
-let set_evtchn ctx value =
-  ctx.evtchn <- value
-
-let set_ring ctx value =
-  ctx.pdb_front_ring <- value
-
-let get_domain ctx =
-  ctx.domain
-
-let get_evtchn ctx =
-  ctx.evtchn
-
-let get_ring ctx =
-  ctx.pdb_front_ring
-
-let string_of_context ctx =
-      Printf.sprintf "{xen domain assist} domain: %d" ctx.domain 
-
-external process_response : int32 -> int * int * string = 
"process_handle_response"
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/Xen_domain.mli
--- a/tools/debugger/pdb/Xen_domain.mli Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-(** Xen_domain.ml
- *
- *  domain assist for debugging processes
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-type context_t
-
-val default_context : context_t
-val new_context : int -> int -> int32 -> context_t 
-
-val set_domain : context_t -> int -> unit
-val get_domain : context_t -> int
-val set_evtchn : context_t -> int -> unit
-val get_evtchn : context_t -> int
-val set_ring   : context_t -> int32 -> unit
-val get_ring   : context_t -> int32
-
-val string_of_context : context_t -> string
-
-val process_response : int32 -> int * int * string
-
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/debugger.ml
--- a/tools/debugger/pdb/debugger.ml    Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,372 +0,0 @@
-(** debugger.ml
- *
- *  main debug functionality
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-open Intel
-open PDB
-open Util
-open Str
-
-let initialize_debugger () =
-  ()
-
-let exit_debugger () =
-  ()
-
-
-(**
-   Detach Command
-   Note: response is ignored by gdb.  We leave the context in the
-   hash.  It will be cleaned up with the socket is closed.
- *)
-let gdb_detach ctx =
-  PDB.detach_debugger ctx
-
-(**
-   Kill Command
-   Note: response is ignored by gdb.  We leave the context in the
-   hash.  It will be cleaned up with the socket is closed.
- *)
-let gdb_kill () =
-  ""
-
-
-
-(**
-   Continue Command.
-   resume the target
- *)
-let gdb_continue ctx =
-  PDB.continue ctx;
-  raise No_reply
-
-(**
-   Step Command.
-   single step the target
- *)
-let gdb_step ctx =
-  PDB.step ctx;
-  raise No_reply
-
-(**
-   Read Register Command.
-   return register as a 4-byte value.
- *)
-let gdb_read_register ctx command =
-  let read_reg register =
-    (Printf.sprintf "%08lx" (Util.flip_int32 (PDB.read_register ctx register)))
-  in
-  Scanf.sscanf command "p%x" read_reg
-    
-
-(**
-   Read Registers Command.
-   returns 16 4-byte registers in a particular format defined by gdb.
- *)
-let gdb_read_registers ctx =
-  let regs = PDB.read_registers ctx in
-  let str = 
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.eax)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.ecx)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.edx)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.ebx)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.esp)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.ebp)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.esi)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.edi)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.eip)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.efl)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.cs)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.ss)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.ds)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.es)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.fs)) ^
-    (Printf.sprintf "%08lx" (Util.flip_int32 regs.gs)) in
-  str
-      
-(**
-   Set Thread Command
- *)
-let gdb_set_thread command =
-  "OK"
-
-
-(**
-   Read Memory Packets
- *)
-let gdb_read_memory ctx command =
-  let int_list_to_string i str =
-    (Printf.sprintf "%02x" i) ^ str
-  in
-  let read_mem addr len =
-    try
-      let mem = PDB.read_memory ctx addr len  in
-      List.fold_right int_list_to_string mem ""
-    with
-      Failure s -> "E02"
-  in
-  Scanf.sscanf command "m%lx,%x" read_mem
-
-
-
-(**
-   Write Memory Packets
- *)
-let gdb_write_memory ctx command =
-  let write_mem addr len =
-    print_endline (Printf.sprintf "  gdb_write_memory %lx %x\n" addr len);
-    print_endline (Printf.sprintf "  [[ unimplemented ]]\n")
-  in
-  Scanf.sscanf command "M%lx,%d" write_mem;
-  "OK"
-
-
-
-(**
-   Write Register Packets
- *)
-let gdb_write_register ctx command =
-  let write_reg reg goofy_val =
-    let new_val = Util.flip_int32 goofy_val in
-    match reg with
-    |  0 -> PDB.write_register ctx EAX new_val
-    |  1 -> PDB.write_register ctx ECX new_val
-    |  2 -> PDB.write_register ctx EDX new_val
-    |  3 -> PDB.write_register ctx EBX new_val
-    |  4 -> PDB.write_register ctx ESP new_val
-    |  5 -> PDB.write_register ctx EBP new_val
-    |  6 -> PDB.write_register ctx ESI new_val
-    |  7 -> PDB.write_register ctx EDI new_val
-    |  8 -> PDB.write_register ctx EIP new_val
-    |  9 -> PDB.write_register ctx EFL new_val
-    | 10 -> PDB.write_register ctx CS new_val
-    | 11 -> PDB.write_register ctx SS new_val
-    | 12 -> PDB.write_register ctx DS new_val
-    | 13 -> PDB.write_register ctx ES new_val
-    | 14 -> PDB.write_register ctx FS new_val
-    | 15 -> PDB.write_register ctx GS new_val
-    | _  -> print_endline (Printf.sprintf "write unknown register [%d]" reg)
-  in
-  Scanf.sscanf command "P%x=%lx" write_reg;
-  "OK"
-
-
-(**
-   General Query Packets
- *)
-let gdb_query command =
-  match command with
-  | "qC" -> ""
-  | "qOffsets" -> ""
-  | "qSymbol::" -> ""
-  | _ -> 
-      print_endline (Printf.sprintf "unknown gdb query packet [%s]" command);
-      "E01"
-
-
-(**
-   Write Memory Binary Packets
- *)
-let gdb_write_memory_binary ctx command =
-  let write_mem addr len =
-    let pos = Str.search_forward (Str.regexp ":") command 0 in
-    let txt = Str.string_after command (pos + 1) in
-    PDB.write_memory ctx addr (int_list_of_string txt len)
-  in
-  Scanf.sscanf command "X%lx,%d" write_mem;
-  "OK"
-
-
-
-(**
-   Last Signal Command
- *)
-let gdb_last_signal =
-  "S00"
-
-
-
-
-(**
-   Process PDB extensions to the GDB serial protocol.
-   Changes the mutable context state.
- *)
-let pdb_extensions command sock =
-  let process_extension key value =
-    (* since this command can change the context, 
-       we need to grab it again each time *)
-    let ctx = PDB.find_context sock in
-    match key with
-    | "status" ->
-       PDB.debug_contexts ();
-       (* print_endline ("debugger status");
-          debugger_status () 
-       *)
-    | "context" ->
-        PDB.add_context sock (List.hd value) 
-                             (int_list_of_string_list (List.tl value))
-    | _ -> failwith (Printf.sprintf "unknown pdb extension command [%s:%s]" 
-                                   key (List.hd value))
-  in
-  try
-    Util.little_parser process_extension 
-                       (String.sub command 1 ((String.length command) - 1));
-    "OK"
-  with
-  | Unknown_context s -> 
-      print_endline (Printf.sprintf "unknown context [%s]" s);
-      "E01"
-  | Unknown_domain -> "E01"
-  | Failure s -> "E01"
-
-
-(**
-   Insert Breakpoint or Watchpoint Packet
- *)
-
-let bwc_watch_write  = 102                              (* from pdb_module.h *)
-let bwc_watch_read   = 103
-let bwc_watch_access = 104
-
-let gdb_insert_bwcpoint ctx command =
-  let insert cmd addr length =
-    try
-      match cmd with
-      | 0 -> PDB.insert_memory_breakpoint ctx addr length; "OK"
-      | 2 -> PDB.insert_watchpoint ctx bwc_watch_write  addr length; "OK"
-      | 3 -> PDB.insert_watchpoint ctx bwc_watch_read   addr length; "OK"
-      | 4 -> PDB.insert_watchpoint ctx bwc_watch_access addr length; "OK"
-      | _ -> ""
-    with
-      Failure s -> "E03"
-  in
-  Scanf.sscanf command "Z%d,%lx,%x" insert
-
-(**
-   Remove Breakpoint or Watchpoint Packet
- *)
-let gdb_remove_bwcpoint ctx command =
-  let insert cmd addr length =
-    try
-      match cmd with
-      | 0 -> PDB.remove_memory_breakpoint ctx addr length; "OK"
-      | 2 -> PDB.remove_watchpoint ctx bwc_watch_write  addr length; "OK"
-      | 3 -> PDB.remove_watchpoint ctx bwc_watch_read   addr length; "OK"
-      | 4 -> PDB.remove_watchpoint ctx bwc_watch_access addr length; "OK"
-      | _ -> ""
-    with
-      Failure s -> "E04"
-  in
-  Scanf.sscanf command "z%d,%lx,%d" insert
-
-(**
-   Do Work!
-
-   @param command  char list
- *)
-
-let process_command command sock =
-  let ctx = PDB.find_context sock in
-  try
-    match command.[0] with
-    | 'c' -> gdb_continue ctx
-    | 'D' -> gdb_detach ctx
-    | 'g' -> gdb_read_registers ctx
-    | 'H' -> gdb_set_thread command
-    | 'k' -> gdb_kill ()
-    | 'm' -> gdb_read_memory ctx command
-    | 'M' -> gdb_write_memory ctx command
-    | 'p' -> gdb_read_register ctx command
-    | 'P' -> gdb_write_register ctx command
-    | 'q' -> gdb_query command
-    | 's' -> gdb_step ctx
-    | 'x' -> pdb_extensions command sock
-    | 'X' -> gdb_write_memory_binary ctx command
-    | '?' -> gdb_last_signal
-    | 'z' -> gdb_remove_bwcpoint ctx command
-    | 'Z' -> gdb_insert_bwcpoint ctx command
-    | _ -> 
-       print_endline (Printf.sprintf "unknown gdb command [%s]" command);
-       ""
-  with
-    Unimplemented s ->
-      print_endline (Printf.sprintf "loser. unimplemented command [%s][%s]" 
-                                   command s);
-      "E03"
-
-(**
-   process_xen_domain
-
-   This is called whenever a domain debug assist responds to a
-   pdb packet.
-*)
-
-let process_xen_domain fd =
-  let channel = Evtchn.read fd in
-  let ctx = find_context fd in
-  
-  let (dom, pid, str) =
-  begin
-    match ctx with
-      | Xen_domain d -> Xen_domain.process_response (Xen_domain.get_ring d)
-      | _ -> failwith ("process_xen_domain called without Xen_domain context")
-  end 
-  in
-  let sock = PDB.find_process dom pid in
-  print_endline (Printf.sprintf "(linux) dom:%d pid:%d  %s  %s" 
-                  dom pid str (Util.get_connection_info sock));
-  Util.send_reply sock str;
-  Evtchn.unmask fd channel                                (* allow next virq *)
-  
-
-(**
-   process_xen_virq
-
-   This is called each time a virq_pdb is sent from xen to dom 0.
-   It is sent by Xen when a domain hits a breakpoint. 
-
-   Think of this as the continuation function for a "c" or "s" command
-   issued to a domain.
-*)
-
-external query_domain_stop : unit -> (int * int) list = "query_domain_stop"
-(* returns a list of paused domains : () -> (domain, vcpu) list *)
-
-let process_xen_virq fd =
-  let channel = Evtchn.read fd in
-  let find_pair (dom, vcpu) =
-    print_endline (Printf.sprintf "checking %d.%d" dom vcpu);
-    try
-      let sock = PDB.find_domain dom vcpu in
-      true
-    with
-      Unknown_domain -> false
-  in
-  let dom_list = query_domain_stop () in
-  let (dom, vcpu) = List.find find_pair dom_list in
-  let vec = 3 in
-  let sock = PDB.find_domain dom vcpu in
-  print_endline (Printf.sprintf "handle bkpt dom:%d vcpu:%d vec:%d  %s" 
-                  dom vcpu vec (Util.get_connection_info sock));
-  Util.send_reply sock "S05";
-  Evtchn.unmask fd channel                                (* allow next virq *)
-  
-
-(**
-   process_xen_xcs
-
-   This is called each time the software assist residing in a backend 
-   domain starts up.  The control message includes the address of a 
-   shared ring page and our end of an event channel (which indicates
-   when data is available on the ring).
-*)
-
-let process_xen_xcs xcs_fd =
-  let (local_evtchn_fd, evtchn, dom, ring) = Xcs.read xcs_fd in
-  add_xen_domain_context local_evtchn_fd dom evtchn ring;
-  local_evtchn_fd
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/evtchn.ml
--- a/tools/debugger/pdb/evtchn.ml      Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-(** evtchn.ml
- *
- *  event channel interface
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-let dev_name = "/dev/xen/evtchn"                          (* EVTCHN_DEV_NAME *)
-let dev_major = 10                                       (* EVTCHN_DEV_MAJOR *)
-let dev_minor = 201                                      (* EVTCHN_DEV_MINOR *)
-
-let virq_pdb = 6                                      (* as defined VIRQ_PDB *)
-
-external bind_virq : int -> int = "evtchn_bind_virq"
-external bind_interdomain : int -> int * int = "evtchn_bind_interdomain"
-external bind : Unix.file_descr -> int -> unit = "evtchn_bind"
-external unbind : Unix.file_descr -> int -> unit = "evtchn_unbind"
-external ec_open : string -> int -> int -> Unix.file_descr = "evtchn_open"
-external read : Unix.file_descr -> int = "evtchn_read"
-external ec_close : Unix.file_descr -> unit = "evtchn_close"
-external unmask : Unix.file_descr -> int -> unit = "evtchn_unmask"
-
-let _setup () =
-  let fd = ec_open dev_name dev_major dev_minor in
-  fd
-
-let _bind fd port =
-  bind fd port
-
-let setup () =
-  let port = bind_virq virq_pdb in
-  let fd = _setup() in
-  _bind fd port;
-  fd
-
-let teardown fd =
-  unbind fd virq_pdb;
-  ec_close fd
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/evtchn.mli
--- a/tools/debugger/pdb/evtchn.mli     Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-(** evtchn.mli
- *
- *  event channel interface
- *
- *  @author copyright (c) 2005 alex ho
- *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
- *  @version 1
- *)
-
-val _setup : unit -> Unix.file_descr
-val _bind : Unix.file_descr -> int -> unit
-
-val bind_interdomain : int -> int * int
-
-
-val setup : unit -> Unix.file_descr
-val read : Unix.file_descr -> int
-val teardown : Unix.file_descr -> unit
-val unmask : Unix.file_descr -> int -> unit
diff -r 914c44d10c8d -r 2bfd19fc1b79 
tools/debugger/pdb/linux-2.6-module/Makefile
--- a/tools/debugger/pdb/linux-2.6-module/Makefile      Sun Oct 01 11:39:41 
2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-XEN_ROOT   = ../../../..
-LINUX_DIR  = linux-2.6.12-xenU
-KDIR       = $(XEN_ROOT)/$(LINUX_DIR)
-
-obj-m    += pdb.o
-pdb-objs += module.o
-pdb-objs += debug.o
-
-CFLAGS += -g
-CFLAGS += -Wall
-CFLAGS += -Werror
-
-.PHONY: module 
-module : 
-#      make KBUILD_VERBOSE=1 ARCH=xen -C $(KDIR) M=$(PWD) modules
-       make                  ARCH=xen -C $(KDIR) M=$(PWD) modules
-
-.PHONY: clean 
-clean :
-       make -C $(KDIR) M=$(PWD) clean
-
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/linux-2.6-module/debug.c
--- a/tools/debugger/pdb/linux-2.6-module/debug.c       Sun Oct 01 11:39:41 
2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,851 +0,0 @@
-/*
- * debug.c
- * pdb debug functionality for processes.
- */
-
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <asm-i386/kdebug.h>
-#include <asm-i386/mach-xen/asm/processor.h>
-#include <asm-i386/mach-xen/asm/ptrace.h>
-#include <asm-i386/mach-xen/asm/tlbflush.h>
-#include <xen/interface/xen.h>
-#include "pdb_module.h"
-#include "pdb_debug.h"
-
-
-static int pdb_debug_fn (struct pt_regs *regs, long error_code,
-                         unsigned int condition);
-static int pdb_int3_fn (struct pt_regs *regs, long error_code);
-static int pdb_page_fault_fn (struct pt_regs *regs, long error_code,
-                              unsigned int condition);
-
-/***********************************************************************/
-
-typedef struct bwcpoint                           /* break/watch/catch point */
-{
-    struct list_head list;
-    unsigned long address;
-    int length;
-
-    uint8_t  type;                                                     /* 
BWC_??? */
-    uint8_t  mode;                   /* for BWC_PAGE, the current protection 
mode */
-    uint32_t process;
-    uint8_t  error;                /* error occured when enabling: don't 
disable. */
-
-    /* original values */
-    uint8_t    orig_bkpt;                               /* single byte 
breakpoint */
-    pte_t orig_pte;
-
-    struct list_head watchpt_read_list;     /* read watchpoints on this page */
-    struct list_head watchpt_write_list;                            /* write */
-    struct list_head watchpt_access_list;                          /* access */
-    struct list_head watchpt_disabled_list;                      /* disabled */
-
-    struct bwcpoint *parent;             /* watchpoint: bwc_watch (the page) */
-    struct bwcpoint *watchpoint;      /* bwc_watch_step: original watchpoint */
-} bwcpoint_t, *bwcpoint_p;
-
-static struct list_head bwcpoint_list = LIST_HEAD_INIT(bwcpoint_list);
-
-#define _pdb_bwcpoint_alloc(_var) \
-{ \
-    if ( (_var = kmalloc(sizeof(bwcpoint_t), GFP_KERNEL)) == NULL ) \
-        printk("error: unable to allocate memory %d\n", __LINE__); \
-    else { \
-        memset(_var, 0, sizeof(bwcpoint_t)); \
-        INIT_LIST_HEAD(&_var->watchpt_read_list); \
-        INIT_LIST_HEAD(&_var->watchpt_write_list); \
-        INIT_LIST_HEAD(&_var->watchpt_access_list); \
-        INIT_LIST_HEAD(&_var->watchpt_disabled_list); \
-    } \
-}
-
-/***********************************************************************/
-
-static void _pdb_bwc_print_list (struct list_head *, char *, int);
-
-static void
-_pdb_bwc_print (bwcpoint_p bwc, char *label, int level)
-{
-    printk("%s%03d 0x%08lx:0x%02x %c\n", label, bwc->type,
-           bwc->address, bwc->length, bwc->error ? 'e' : '-');
-
-    if ( !list_empty(&bwc->watchpt_read_list) )
-        _pdb_bwc_print_list(&bwc->watchpt_read_list, "r", level);
-    if ( !list_empty(&bwc->watchpt_write_list) )
-        _pdb_bwc_print_list(&bwc->watchpt_write_list, "w", level);
-    if ( !list_empty(&bwc->watchpt_access_list) )
-        _pdb_bwc_print_list(&bwc->watchpt_access_list, "a", level);
-    if ( !list_empty(&bwc->watchpt_disabled_list) )
-        _pdb_bwc_print_list(&bwc->watchpt_disabled_list, "d", level);
-}
-
-static void
-_pdb_bwc_print_list (struct list_head *bwc_list, char *label, int level)
-{
-    struct list_head *ptr;
-    int counter = 0;
-
-    list_for_each(ptr, bwc_list)
-    {
-        bwcpoint_p bwc = list_entry(ptr, bwcpoint_t, list);
-        printk("  %s[%02d]%s ", level > 0 ? "  " : "", counter++,
-                                level > 0 ? "" : "  ");
-        _pdb_bwc_print(bwc, label, level+1);
-    }
-
-    if (counter == 0)
-    {
-        printk("  empty list\n");
-    }
-}
-
-void
-pdb_bwc_print_list (void)
-{
-    _pdb_bwc_print_list(&bwcpoint_list, " ", 0);
-}
-
-bwcpoint_p
-pdb_search_watchpoint (uint32_t process, unsigned long address)
-{
-    bwcpoint_p bwc_watch = (bwcpoint_p) 0;
-    bwcpoint_p bwc_entry = (bwcpoint_p) 0;
-    struct list_head *ptr;
-
-    list_for_each(ptr, &bwcpoint_list)                /* find bwc page entry */
-    {
-        bwc_watch = list_entry(ptr, bwcpoint_t, list);
-        if (bwc_watch->address == (address & PAGE_MASK)) break;
-    }
-
-    if ( !bwc_watch )
-    {
-        return (bwcpoint_p) 0;
-    }
-
-#define __pdb_search_watchpoint_list(__list) \
-    list_for_each(ptr, (__list))  \
-    { \
-        bwc_entry = list_entry(ptr, bwcpoint_t, list); \
-        if ( bwc_entry->process == process &&          \
-             bwc_entry->address <= address &&          \
-             bwc_entry->address + bwc_entry->length > address ) \
-            return bwc_entry; \
-    }
-
-    __pdb_search_watchpoint_list(&bwc_watch->watchpt_read_list);
-    __pdb_search_watchpoint_list(&bwc_watch->watchpt_write_list);
-    __pdb_search_watchpoint_list(&bwc_watch->watchpt_access_list);
-
-#undef __pdb_search_watchpoint_list
-
-    return (bwcpoint_p) 0;
-}
-
-/*************************************************************/
-
-int
-pdb_suspend (struct task_struct *target)
-{
-    uint32_t rc = 0;
-
-    force_sig(SIGSTOP, target);                    /* force_sig_specific ??? */
-
-    return rc;
-}
-
-int
-pdb_resume (struct task_struct *target)
-{
-    int rc = 0;
-
-    wake_up_process(target);
-
-    return rc;
-}
-
-/*
- * from linux-2.6.11/arch/i386/kernel/ptrace.c::getreg()
- */
-static unsigned long
-_pdb_get_register (struct task_struct *target, int reg)
-{
-    unsigned long result = ~0UL;
-    unsigned long offset;
-    unsigned char *stack = 0L;
-
-    switch (reg)
-    {
-    case LINUX_FS:
-        result = target->thread.fs;
-        break;
-    case LINUX_GS:
-        result = target->thread.gs;
-        break;
-    case LINUX_DS:
-    case LINUX_ES:
-    case LINUX_SS:
-    case LINUX_CS:
-        result = 0xffff;
-        /* fall through */
-    default:
-        if (reg > LINUX_GS)
-            reg -= 2;
-
-        offset = reg * sizeof(long);
-        offset -= sizeof(struct pt_regs);
-        stack = (unsigned char *)target->thread.esp0;
-        stack += offset;
-        result &= *((int *)stack);
-    }
-
-    return result;
-}
-
-/*
- * from linux-2.6.11/arch/i386/kernel/ptrace.c::putreg()
- */
-static void
-_pdb_set_register (struct task_struct *target, int reg, unsigned long val)
-{
-    unsigned long offset;
-    unsigned char *stack;
-    unsigned long value = val;
-
-    switch (reg)
-    {
-    case LINUX_FS:
-        target->thread.fs = value;
-        return;
-    case LINUX_GS:
-        target->thread.gs = value;
-        return;
-    case LINUX_DS:
-    case LINUX_ES:
-        value &= 0xffff;
-        break;
-    case LINUX_SS:
-    case LINUX_CS:
-        value &= 0xffff;
-        break;
-    case LINUX_EFL:
-        break;
-    }
-
-    if (reg > LINUX_GS)
-        reg -= 2;
-    offset = reg * sizeof(long);
-    offset -= sizeof(struct pt_regs);
-    stack = (unsigned char *)target->thread.esp0;
-    stack += offset;
-    *(unsigned long *) stack = value;
-
-    return;
-}
-
-int
-pdb_read_register (struct task_struct *target, pdb_op_rd_reg_p op)
-{
-    int rc = 0;
-
-    switch (op->reg)
-    {
-    case  0: op->value = _pdb_get_register(target, LINUX_EAX); break;
-    case  1: op->value = _pdb_get_register(target, LINUX_ECX); break;
-    case  2: op->value = _pdb_get_register(target, LINUX_EDX); break;
-    case  3: op->value = _pdb_get_register(target, LINUX_EBX); break;
-    case  4: op->value = _pdb_get_register(target, LINUX_ESP); break;
-    case  5: op->value = _pdb_get_register(target, LINUX_EBP); break;
-    case  6: op->value = _pdb_get_register(target, LINUX_ESI); break;
-    case  7: op->value = _pdb_get_register(target, LINUX_EDI); break;
-    case  8: op->value = _pdb_get_register(target, LINUX_EIP); break;
-    case  9: op->value = _pdb_get_register(target, LINUX_EFL); break;
-
-    case 10: op->value = _pdb_get_register(target, LINUX_CS); break;
-    case 11: op->value = _pdb_get_register(target, LINUX_SS); break;
-    case 12: op->value = _pdb_get_register(target, LINUX_DS); break;
-    case 13: op->value = _pdb_get_register(target, LINUX_ES); break;
-    case 14: op->value = _pdb_get_register(target, LINUX_FS); break;
-    case 15: op->value = _pdb_get_register(target, LINUX_GS); break;
-    }
-
-    return rc;
-}
-
-int
-pdb_read_registers (struct task_struct *target, pdb_op_rd_regs_p op)
-{
-    int rc = 0;
-
-    op->reg[ 0] = _pdb_get_register(target, LINUX_EAX);
-    op->reg[ 1] = _pdb_get_register(target, LINUX_ECX);
-    op->reg[ 2] = _pdb_get_register(target, LINUX_EDX);
-    op->reg[ 3] = _pdb_get_register(target, LINUX_EBX);
-    op->reg[ 4] = _pdb_get_register(target, LINUX_ESP);
-    op->reg[ 5] = _pdb_get_register(target, LINUX_EBP);
-    op->reg[ 6] = _pdb_get_register(target, LINUX_ESI);
-    op->reg[ 7] = _pdb_get_register(target, LINUX_EDI);
-    op->reg[ 8] = _pdb_get_register(target, LINUX_EIP);
-    op->reg[ 9] = _pdb_get_register(target, LINUX_EFL);
-
-    op->reg[10] = _pdb_get_register(target, LINUX_CS);
-    op->reg[11] = _pdb_get_register(target, LINUX_SS);
-    op->reg[12] = _pdb_get_register(target, LINUX_DS);
-    op->reg[13] = _pdb_get_register(target, LINUX_ES);
-    op->reg[14] = _pdb_get_register(target, LINUX_FS);
-    op->reg[15] = _pdb_get_register(target, LINUX_GS);
-
-    return rc;
-}
-
-int
-pdb_write_register (struct task_struct *target, pdb_op_wr_reg_p op)
-{
-    int rc = 0;
-
-    _pdb_set_register(target, op->reg, op->value);
-
-    return rc;
-}
-
-int
-pdb_access_memory (struct task_struct *target, unsigned long address, 
-                   void *buffer, int length, int write)
-{
-    int rc = 0;
-
-    access_process_vm(target, address, buffer, length, write);
-
-    return rc;
-}
-
-int
-pdb_continue (struct task_struct *target)
-{
-    int rc = 0;
-    unsigned long eflags;
-
-    eflags = _pdb_get_register(target, LINUX_EFL);
-    eflags &= ~X86_EFLAGS_TF;
-    _pdb_set_register(target, LINUX_EFL, eflags);
-
-    wake_up_process(target);
-
-    return rc;
-}
-
-int
-pdb_step (struct task_struct *target)
-{
-    int rc = 0;
-    unsigned long eflags;
-    bwcpoint_p bkpt;
-    
-    eflags = _pdb_get_register(target, LINUX_EFL);
-    eflags |= X86_EFLAGS_TF;
-    _pdb_set_register(target, LINUX_EFL, eflags);
-
-    _pdb_bwcpoint_alloc(bkpt);
-    if ( bkpt == NULL )  return -1;
-
-    bkpt->process = target->pid;
-    bkpt->address = 0;
-    bkpt->type    = BWC_DEBUG;
-    
-    list_add_tail(&bkpt->list, &bwcpoint_list);
-
-    wake_up_process(target);
-
-    return rc;
-}
-
-int
-pdb_insert_memory_breakpoint (struct task_struct *target, 
-                              unsigned long address, uint32_t length)
-{
-    int rc = 0;
-    bwcpoint_p bkpt;
-    uint8_t breakpoint_opcode = 0xcc;
-
-    printk("insert breakpoint %d:%lx len: %d\n", target->pid, address, length);
-
-    if ( length != 1 )
-    {
-        printk("error: breakpoint length should be 1\n");
-        return -1;
-    }
-
-    _pdb_bwcpoint_alloc(bkpt);
-    if ( bkpt == NULL ) return -1;
-
-    bkpt->process = target->pid;
-    bkpt->address = address;
-    bkpt->type    = BWC_INT3;
-
-    pdb_access_memory(target, address, &bkpt->orig_bkpt, 1, PDB_MEM_READ);
-    pdb_access_memory(target, address, &breakpoint_opcode, 1, PDB_MEM_WRITE);
-    
-    list_add_tail(&bkpt->list, &bwcpoint_list);
-
-    printk("breakpoint_set %d:%lx  OLD: 0x%x\n",
-           target->pid, address, bkpt->orig_bkpt);
-    pdb_bwc_print_list();
-
-    return rc;
-}
-
-int
-pdb_remove_memory_breakpoint (struct task_struct *target,
-                              unsigned long address, uint32_t length)
-{
-    int rc = 0;
-    bwcpoint_p bkpt = NULL;
-
-    printk ("remove breakpoint %d:%lx\n", target->pid, address);
-
-    struct list_head *entry;
-    list_for_each(entry, &bwcpoint_list)
-    {
-        bkpt = list_entry(entry, bwcpoint_t, list);
-        if ( target->pid == bkpt->process && 
-             address == bkpt->address     &&
-             bkpt->type == BWC_INT3 )
-            break;
-    }
-    
-    if (entry == &bwcpoint_list)
-    {
-        printk ("error: no breakpoint found\n");
-        return -1;
-    }
-
-    pdb_access_memory(target, address, &bkpt->orig_bkpt, 1, PDB_MEM_WRITE);
-
-    list_del(&bkpt->list);
-    kfree(bkpt);
-
-    pdb_bwc_print_list();
-
-    return rc;
-}
-
-#define PDB_PTE_UPDATE   1
-#define PDB_PTE_RESTORE  2
-
-int
-pdb_change_pte (struct task_struct *target, bwcpoint_p bwc, int mode)
-{
-    int rc = 0;
-    pgd_t *pgd;
-    pud_t *pud;
-    pmd_t *pmd;
-    pte_t *ptep;
-
-    pgd = pgd_offset(target->mm, bwc->address);
-    if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))  return -1;
-
-    pud = pud_offset(pgd, bwc->address);
-    if (pud_none(*pud) || unlikely(pud_bad(*pud))) return -2;
-
-    pmd = pmd_offset(pud, bwc->address);
-    if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) return -3;
-
-    ptep = pte_offset_map(pmd, bwc->address);
-    if (!ptep)  return -4;
-
-    switch ( mode )
-    {
-    case PDB_PTE_UPDATE:      /* added or removed a watchpoint.  update pte. */
-    {
-        pte_t new_pte;
-
-        if ( pte_val(bwc->parent->orig_pte) == 0 )    /* new watchpoint page */
-        {
-            bwc->parent->orig_pte = *ptep;
-        }
-
-        new_pte = bwc->parent->orig_pte;
-
-        if ( !list_empty(&bwc->parent->watchpt_read_list)  || 
-             !list_empty(&bwc->parent->watchpt_access_list) )
-        {
-            new_pte = pte_rdprotect(new_pte);
-        }
-
-        if ( !list_empty(&bwc->parent->watchpt_write_list) ||
-             !list_empty(&bwc->parent->watchpt_access_list) )
-        {
-            new_pte = pte_wrprotect(new_pte);
-        }
-        
-        if ( pte_val(new_pte) != pte_val(*ptep) )
-        {
-            *ptep = new_pte;
-            flush_tlb_mm(target->mm);
-        }
-        break;
-    }
-    case PDB_PTE_RESTORE :   /* suspend watchpoint by restoring original pte */
-    {
-        *ptep = bwc->parent->orig_pte;
-        flush_tlb_mm(target->mm);
-        break;
-    }
-    default :
-    {
-        printk("(linux) unknown mode %d %d\n", mode, __LINE__);
-        break;
-    }
-    }
-
-    pte_unmap(ptep);                /* can i flush the tlb before pte_unmap? */
-
-    return rc;
-}
-
-int
-pdb_insert_watchpoint (struct task_struct *target, pdb_op_watchpt_p watchpt)
-{
-    int rc = 0;
-
-    bwcpoint_p bwc_watch;
-    bwcpoint_p bwc_entry;
-    struct list_head *ptr;
-    unsigned long page = watchpt->address & PAGE_MASK;
-    struct list_head *watchpoint_list;
-    
-    printk("insert watchpoint: %d %x %x\n", 
-           watchpt->type, watchpt->address, watchpt->length);
-
-    list_for_each(ptr, &bwcpoint_list) /* find existing bwc page entry */
-    {
-        bwc_watch = list_entry(ptr, bwcpoint_t, list);
-
-        if (bwc_watch->address == page)  goto got_bwc_watch;
-    }
-
-    _pdb_bwcpoint_alloc(bwc_watch);                  /* create new bwc:watch */
-    if ( bwc_watch == NULL ) return -1;
-
-    bwc_watch->type    = BWC_WATCH;
-    bwc_watch->process = target->pid;
-    bwc_watch->address = page;
-
-    list_add_tail(&bwc_watch->list, &bwcpoint_list);
-
- got_bwc_watch:
-
-    switch (watchpt->type)
-    {
-    case BWC_WATCH_READ:
-        watchpoint_list = &bwc_watch->watchpt_read_list; break;
-    case BWC_WATCH_WRITE: 
-        watchpoint_list = &bwc_watch->watchpt_write_list; break;
-    case BWC_WATCH_ACCESS:
-        watchpoint_list = &bwc_watch->watchpt_access_list; break;
-    default:
-        printk("unknown type %d\n", watchpt->type); return -2;
-    }
-
-    _pdb_bwcpoint_alloc(bwc_entry);                  /* create new bwc:entry */
-    if ( bwc_entry == NULL ) return -1;
-
-    bwc_entry->process = target->pid;
-    bwc_entry->address = watchpt->address;
-    bwc_entry->length  = watchpt->length;
-    bwc_entry->type    = watchpt->type;
-    bwc_entry->parent  = bwc_watch;
-
-    list_add_tail(&bwc_entry->list, watchpoint_list);
-    pdb_change_pte(target, bwc_entry, PDB_PTE_UPDATE);
-
-    pdb_bwc_print_list();
-
-    return rc;
-}
-
-int 
-pdb_remove_watchpoint (struct task_struct *target, pdb_op_watchpt_p watchpt)
-{
-    int rc = 0;
-    bwcpoint_p bwc_watch = (bwcpoint_p) NULL;
-    bwcpoint_p bwc_entry = (bwcpoint_p) NULL;
-    unsigned long page = watchpt->address & PAGE_MASK;
-    struct list_head *ptr;
-    struct list_head *watchpoint_list;
-
-    printk("remove watchpoint: %d %x %x\n", 
-           watchpt->type, watchpt->address, watchpt->length);
-
-    list_for_each(ptr, &bwcpoint_list)                /* find bwc page entry */
-    {
-        bwc_watch = list_entry(ptr, bwcpoint_t, list);
-        if (bwc_watch->address == page) break;
-    }
-
-    if ( !bwc_watch )
-    {
-        printk("(linux) delete watchpoint: can't find bwc page 0x%08x\n",
-               watchpt->address);
-        return -1;
-    }
-
-    switch (watchpt->type)
-    {
-    case BWC_WATCH_READ:
-        watchpoint_list = &bwc_watch->watchpt_read_list; break;
-    case BWC_WATCH_WRITE:
-        watchpoint_list = &bwc_watch->watchpt_write_list; break;
-    case BWC_WATCH_ACCESS:
-        watchpoint_list = &bwc_watch->watchpt_access_list; break;
-    default:
-        printk("unknown type %d\n", watchpt->type); return -2;
-    }
-
-    list_for_each(ptr, watchpoint_list)                   /* find watchpoint */
-    {
-        bwc_entry = list_entry(ptr, bwcpoint_t, list);
-        if ( bwc_entry->address == watchpt->address &&
-             bwc_entry->length  == watchpt->length ) break;
-    }
-
-    if ( !bwc_entry )                           /* or ptr == watchpoint_list */
-    {
-        printk("(linux) delete watchpoint: can't find watchpoint 0x%08x\n",
-               watchpt->address);
-        return -1;
-    }
-    
-    list_del(&bwc_entry->list);
-    pdb_change_pte(target, bwc_entry, PDB_PTE_UPDATE);
-    kfree(bwc_entry);
-
-
-    if ( list_empty(&bwc_watch->watchpt_read_list)  &&
-         list_empty(&bwc_watch->watchpt_write_list) &&
-         list_empty(&bwc_watch->watchpt_access_list) )
-    {
-        list_del(&bwc_watch->list);
-        kfree(bwc_watch);
-    }
-
-    pdb_bwc_print_list();
-
-    return rc;
-}
-
-
-/***************************************************************/
-
-int
-pdb_exceptions_notify (struct notifier_block *self, unsigned long val,
-                       void *data)
-{
-    struct die_args *args = (struct die_args *)data;
-
-       switch (val) 
-    {
-       case DIE_DEBUG:
-               if ( pdb_debug_fn(args->regs, args->trapnr, args->err) )
-                       return NOTIFY_STOP;
-               break;
-    case DIE_TRAP:
-               if ( args->trapnr == 3 && pdb_int3_fn(args->regs, args->err) )
-                       return NOTIFY_STOP;
-        break;
-       case DIE_INT3:          /* without kprobes, we should never see 
DIE_INT3 */
-               if ( pdb_int3_fn(args->regs, args->err) )
-                       return NOTIFY_STOP;
-               break;
-       case DIE_PAGE_FAULT:
-               if ( pdb_page_fault_fn(args->regs, args->trapnr, args->err) )
-                       return NOTIFY_STOP;
-               break;
-       case DIE_GPF:
-        printk("---------------GPF\n");
-        break;
-       default:
-               break;
-       }
-
-       return NOTIFY_DONE;
-}
-
-
-static int
-pdb_debug_fn (struct pt_regs *regs, long error_code, 
-                   unsigned int condition)
-{
-    pdb_response_t resp;
-    bwcpoint_p bkpt = NULL;
-    struct list_head *entry;
-
-    printk("pdb_debug_fn\n");
-
-    list_for_each(entry, &bwcpoint_list)
-    {
-        bkpt = list_entry(entry, bwcpoint_t, list);
-        if ( current->pid == bkpt->process && 
-             (bkpt->type == BWC_DEBUG ||                      /* single step */
-              bkpt->type == BWC_WATCH_STEP))  /* single step over watchpoint */
-            break;
-    }
-    
-    if (entry == &bwcpoint_list)
-    {
-        printk("not my debug  0x%x 0x%lx\n", current->pid, regs->eip);
-        return 0;
-    }
-
-    pdb_suspend(current);
-
-    printk("(pdb) %s  pid: %d, eip: 0x%08lx\n", 
-           bkpt->type == BWC_DEBUG ? "debug" : "watch-step",
-           current->pid, regs->eip);
-
-    regs->eflags &= ~X86_EFLAGS_TF;
-       set_tsk_thread_flag(current, TIF_SINGLESTEP);
-
-    switch (bkpt->type)
-    {
-    case BWC_DEBUG:
-        resp.operation = PDB_OPCODE_STEP;
-        break;
-    case BWC_WATCH_STEP:
-    {
-        struct list_head *watchpoint_list;
-        bwcpoint_p watch_page = bkpt->watchpoint->parent;
-
-        switch (bkpt->watchpoint->type)
-        {
-        case BWC_WATCH_READ:
-            watchpoint_list = &watch_page->watchpt_read_list; break;
-        case BWC_WATCH_WRITE: 
-            watchpoint_list = &watch_page->watchpt_write_list; break;
-        case BWC_WATCH_ACCESS:
-            watchpoint_list = &watch_page->watchpt_access_list; break;
-        default:
-            printk("unknown type %d\n", bkpt->watchpoint->type); return 0;
-        }
-
-        resp.operation = PDB_OPCODE_WATCHPOINT;
-        list_del_init(&bkpt->watchpoint->list);
-        list_add_tail(&bkpt->watchpoint->list, watchpoint_list);
-        pdb_change_pte(current, bkpt->watchpoint, PDB_PTE_UPDATE);
-        pdb_bwc_print_list();
-        break;
-    }
-    default:
-        printk("unknown breakpoint type %d %d\n", __LINE__, bkpt->type);
-        return 0;
-    }
-
-    resp.process   = current->pid;
-    resp.status    = PDB_RESPONSE_OKAY;
-
-    pdb_send_response(&resp);
-
-    list_del(&bkpt->list);
-    kfree(bkpt);
-
-    return 1;
-}
-
-
-static int
-pdb_int3_fn (struct pt_regs *regs, long error_code)
-{
-    pdb_response_t resp;
-    bwcpoint_p bkpt = NULL;
-    unsigned long address = regs->eip - 1;
-
-    struct list_head *entry;
-    list_for_each(entry, &bwcpoint_list)
-    {
-        bkpt = list_entry(entry, bwcpoint_t, list);
-        if ( current->pid == bkpt->process && 
-             address == bkpt->address      &&
-             bkpt->type == BWC_INT3 )
-            break;
-    }
-    
-    if (entry == &bwcpoint_list)
-    {
-        printk("not my int3 bkpt  0x%x 0x%lx\n", current->pid, address);
-        return 0;
-    }
-
-    printk("(pdb) int3  pid: %d, eip: 0x%08lx\n", current->pid, address);
-
-    pdb_suspend(current);
-
-    resp.operation = PDB_OPCODE_CONTINUE;
-    resp.process   = current->pid;
-    resp.status    = PDB_RESPONSE_OKAY;
-
-    pdb_send_response(&resp);
-
-    return 1;
-}
-
-static int
-pdb_page_fault_fn (struct pt_regs *regs, long error_code, 
-                   unsigned int condition)
-{
-    unsigned long cr2;
-    unsigned long cr3;
-    bwcpoint_p bwc;
-    bwcpoint_p watchpt;
-    bwcpoint_p bkpt;
-
-    __asm__ __volatile__ ("movl %%cr3,%0" : "=r" (cr3) : );
-    __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (cr2) : );
-
-    bwc = pdb_search_watchpoint(current->pid, cr2);
-    if ( !bwc )
-    {
-        return 0;                                                /* not mine */
-    }
-
-    printk("page_fault cr2:%08lx err:%lx eip:%08lx\n", 
-           cr2, error_code, regs->eip);
-
-    /* disable the watchpoint */
-    watchpt = bwc->watchpoint;
-    list_del_init(&bwc->list);
-    list_add_tail(&bwc->list, &bwc->parent->watchpt_disabled_list);
-    pdb_change_pte(current, bwc, PDB_PTE_RESTORE);
-
-    /* single step the faulting instruction */
-    regs->eflags |= X86_EFLAGS_TF;
-
-    /* create a bwcpoint entry so we know what to do once we regain control */
-    _pdb_bwcpoint_alloc(bkpt);
-    if ( bkpt == NULL )  return -1;
-
-    bkpt->process    = current->pid;
-    bkpt->address    = 0;
-    bkpt->type       = BWC_WATCH_STEP;
-    bkpt->watchpoint = bwc;
-
-    /* add to head so we see it first the next time we break */
-    list_add(&bkpt->list, &bwcpoint_list);                
-
-    pdb_bwc_print_list();
-    return 1;
-}
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-
diff -r 914c44d10c8d -r 2bfd19fc1b79 
tools/debugger/pdb/linux-2.6-module/module.c
--- a/tools/debugger/pdb/linux-2.6-module/module.c      Sun Oct 01 11:39:41 
2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,337 +0,0 @@
-
-/*
- * module.c
- *
- * Handles initial registration with pdb when the pdb module starts up
- * and cleanup when the module goes away (sortof :)
- * Also receives each request from pdb in domain 0 and dispatches to the
- * appropriate debugger function.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include <asm-i386/kdebug.h>
-
-#include <xen/evtchn.h>
-#include <xen/ctrl_if.h>
-#include <xen/hypervisor.h>
-#include <xen/interface/io/domain_controller.h>
-#include <xen/interface/xen.h>
-
-#include <xen/interface/io/ring.h>
-
-#include "pdb_module.h"
-#include "pdb_debug.h"
-
-#define PDB_RING_SIZE __RING_SIZE((pdb_sring_t *)0, PAGE_SIZE)
-
-static pdb_back_ring_t pdb_ring;
-static unsigned int    pdb_evtchn;
-static unsigned int    pdb_irq;
-static unsigned int    pdb_domain;
-
-/* work queue */
-static void pdb_work_handler(void *unused);
-static DECLARE_WORK(pdb_deferred_work, pdb_work_handler, NULL);
-
-/*
- * send response to a pdb request
- */
-void
-pdb_send_response (pdb_response_t *response)
-{
-    pdb_response_t *resp;
-
-    resp = RING_GET_RESPONSE(&pdb_ring, pdb_ring.rsp_prod_pvt);
-
-    memcpy(resp, response, sizeof(pdb_response_t));
-    resp->domain = pdb_domain;
-    
-    wmb();                 /* Ensure other side can see the response fields. */
-    pdb_ring.rsp_prod_pvt++;
-    RING_PUSH_RESPONSES(&pdb_ring);
-    notify_via_evtchn(pdb_evtchn);
-    return;
-}
-
-/*
- * handle a debug command from the front end
- */
-static void
-pdb_process_request (pdb_request_t *request)
-{
-    pdb_response_t resp;
-    struct task_struct *target;
-
-    read_lock(&tasklist_lock);
-    target = find_task_by_pid(request->process);
-    if (target)
-        get_task_struct(target);
-    read_unlock(&tasklist_lock);
-
-    resp.operation = request->operation;
-    resp.process   = request->process;
-
-    if (!target)
-    {
-        printk ("(linux) target not found 0x%x\n", request->process);
-        resp.status = PDB_RESPONSE_ERROR;
-        goto response;
-    }
-
-    switch (request->operation)
-    {
-    case PDB_OPCODE_PAUSE :
-        pdb_suspend(target);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_ATTACH :
-        pdb_suspend(target);
-        pdb_domain = request->u.attach.domain;
-        printk("(linux) attach  dom:0x%x pid:0x%x\n",
-               pdb_domain, request->process);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_DETACH :
-        pdb_resume(target);
-        printk("(linux) detach 0x%x\n", request->process);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_RD_REG :
-        resp.u.rd_reg.reg = request->u.rd_reg.reg;
-        pdb_read_register(target, &resp.u.rd_reg);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_RD_REGS :
-        pdb_read_registers(target, &resp.u.rd_regs);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_WR_REG :
-        pdb_write_register(target, &request->u.wr_reg);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_RD_MEM :
-        pdb_access_memory(target, request->u.rd_mem.address,
-                          &resp.u.rd_mem.data, request->u.rd_mem.length, 
-                          PDB_MEM_READ);
-        resp.u.rd_mem.address = request->u.rd_mem.address;
-        resp.u.rd_mem.length  = request->u.rd_mem.length;
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_WR_MEM :
-        pdb_access_memory(target, request->u.wr_mem.address,
-                         &request->u.wr_mem.data, request->u.wr_mem.length, 
-                          PDB_MEM_WRITE);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_CONTINUE :
-        pdb_continue(target);
-        goto no_response;
-        break;
-    case PDB_OPCODE_STEP :
-        pdb_step(target);
-        resp.status = PDB_RESPONSE_OKAY;
-        goto no_response;
-        break;
-    case PDB_OPCODE_SET_BKPT :
-        pdb_insert_memory_breakpoint(target, request->u.bkpt.address,
-                                     request->u.bkpt.length);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_CLR_BKPT :
-        pdb_remove_memory_breakpoint(target, request->u.bkpt.address,
-                                     request->u.bkpt.length);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_SET_WATCHPT :
-        pdb_insert_watchpoint(target, &request->u.watchpt);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    case PDB_OPCODE_CLR_WATCHPT :
-        pdb_remove_watchpoint(target, &request->u.watchpt);
-        resp.status = PDB_RESPONSE_OKAY;
-        break;
-    default:
-        printk("(pdb) unknown request operation %d\n", request->operation);
-        resp.status = PDB_RESPONSE_ERROR;
-    }
-
- response:        
-    pdb_send_response (&resp);
-
- no_response:
-    return;
-}
-
-/*
- * work queue
- */
-static void
-pdb_work_handler (void *unused)
-{
-    pdb_request_t *req;
-    RING_IDX i, rp;
-
-    rp = pdb_ring.sring->req_prod;
-    rmb();
-
-    for ( i = pdb_ring.req_cons; 
-          (i != rp) && !RING_REQUEST_CONS_OVERFLOW(&pdb_ring, i);
-          i++ )
-    {
-        req = RING_GET_REQUEST(&pdb_ring, i);
-        pdb_process_request(req);
-
-    }
-    pdb_ring.req_cons = i;
-}
-
-/*
- * receive a pdb request
- */
-static irqreturn_t
-pdb_interrupt (int irq, void *dev_id, struct pt_regs *ptregs)
-{
-    schedule_work(&pdb_deferred_work);
-
-    return IRQ_HANDLED;
-}
-
-static void
-pdb_send_connection_status(int status, unsigned long ring)
-{
-    ctrl_msg_t cmsg = 
-    {
-        .type = CMSG_DEBUG,
-        .subtype = CMSG_DEBUG_CONNECTION_STATUS,
-        .length  = sizeof(pdb_connection_t),
-    };
-    pdb_connection_t *conn = (pdb_connection_t *)cmsg.msg;
-
-    conn->status = status;
-    conn->ring = ring;
-    conn->evtchn = 0;
-
-    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-}
-
-
-/*
- * this is called each time a message is received on the control channel
- */
-static void
-pdb_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
-{
-    switch (msg->subtype)
-    {
-    case CMSG_DEBUG_CONNECTION_STATUS:
-        /* initialize event channel created by the pdb server */
-
-        pdb_evtchn = ((pdb_connection_p) msg->msg)->evtchn;
-        pdb_irq = bind_evtchn_to_irq(pdb_evtchn);
-
-        if ( request_irq(pdb_irq, pdb_interrupt, 
-                         SA_SAMPLE_RANDOM, "pdb", NULL) )
-        {
-            printk("(pdb) request irq failed: %d %d\n", pdb_evtchn, pdb_irq);
-        }
-        break;
-
-    default:
-        printk ("(pdb) unknown xcs control message: %d\n", msg->subtype);
-        break;
-    }
-
-    return;
-}
-
-
-/********************************************************************/
-
-static struct notifier_block pdb_exceptions_nb =
-{
-    .notifier_call = pdb_exceptions_notify,
-    .priority = 0x1                                          /* low priority */
-};
-
-
-static int __init 
-pdb_initialize (void)
-{
-    int err;
-    pdb_sring_t *sring;
-
-    printk("----\npdb initialize   %s %s\n", __DATE__, __TIME__);
-
-    /*
-    if ( xen_start_info.flags & SIF_INITDOMAIN )
-        return 1;
-    */
-
-    pdb_evtchn = 0;
-    pdb_irq    = 0;
-    pdb_domain = 0;
-
-    (void)ctrl_if_register_receiver(CMSG_DEBUG, pdb_ctrlif_rx,
-                                    CALLBACK_IN_BLOCKING_CONTEXT);
-
-    /* rings */
-    sring = (pdb_sring_t *)__get_free_page(GFP_KERNEL);
-    SHARED_RING_INIT(sring);
-    BACK_RING_INIT(&pdb_ring, sring, PAGE_SIZE);
- 
-    /* notify pdb in dom 0 */
-    pdb_send_connection_status(PDB_CONNECTION_STATUS_UP, 
-                               virt_to_machine(pdb_ring.sring) >> PAGE_SHIFT);
-
-    /* handler for int1 & int3 */
-    err = register_die_notifier(&pdb_exceptions_nb);
-
-    return err;
-}
-
-static void __exit
-pdb_terminate(void)
-{
-    int err = 0;
-
-    printk("pdb cleanup\n");
-
-    (void)ctrl_if_unregister_receiver(CMSG_DEBUG, pdb_ctrlif_rx);
-
-    if (pdb_irq)
-    {
-        free_irq(pdb_irq, NULL);
-        pdb_irq = 0;
-    }
-
-    if (pdb_evtchn)
-    {
-        unbind_evtchn_from_irq(pdb_evtchn); 
-        pdb_evtchn = 0;
-    }
-
-    pdb_send_connection_status(PDB_CONNECTION_STATUS_DOWN, 0);
-
-    /* handler for int1 & int3 */
-    err = unregister_die_notifier(&pdb_exceptions_nb);
-
-       return;
-}
-
-
-module_init(pdb_initialize);
-module_exit(pdb_terminate);
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-
diff -r 914c44d10c8d -r 2bfd19fc1b79 
tools/debugger/pdb/linux-2.6-module/pdb_debug.h
--- a/tools/debugger/pdb/linux-2.6-module/pdb_debug.h   Sun Oct 01 11:39:41 
2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-
-#ifndef __PDB_DEBUG_H_
-#define __PDB_DEBUG_H_
-
-/* debugger.c */
-void pdb_initialize_bwcpoint (void);
-int pdb_suspend (struct task_struct *target);
-int pdb_resume (struct task_struct *target);
-int pdb_read_register (struct task_struct *target, pdb_op_rd_reg_p op);
-int pdb_read_registers (struct task_struct *target, pdb_op_rd_regs_p op);
-int pdb_write_register (struct task_struct *target, pdb_op_wr_reg_p op);
-int pdb_read_memory (struct task_struct *target, pdb_op_rd_mem_req_p req, 
-                     pdb_op_rd_mem_resp_p resp);
-int pdb_write_memory (struct task_struct *target, pdb_op_wr_mem_p op);
-int pdb_access_memory (struct task_struct *target, unsigned long address, 
-                       void *buffer, int length, int write);
-int pdb_continue (struct task_struct *target);
-int pdb_step (struct task_struct *target);
-
-int pdb_insert_memory_breakpoint (struct task_struct *target, 
-                                  unsigned long address, uint32_t length);
-int pdb_remove_memory_breakpoint (struct task_struct *target,
-                                  unsigned long address, uint32_t length);
-int pdb_insert_watchpoint (struct task_struct *target,
-                           pdb_op_watchpt_p watchpt);
-int pdb_remove_watchpoint (struct task_struct *target,
-                           pdb_op_watchpt_p watchpt);
-
-int pdb_exceptions_notify (struct notifier_block *self, unsigned long val,
-                           void *data);
-
-/* module.c */
-void pdb_send_response (pdb_response_t *response);
-
-#endif
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-
diff -r 914c44d10c8d -r 2bfd19fc1b79 
tools/debugger/pdb/linux-2.6-module/pdb_module.h
--- a/tools/debugger/pdb/linux-2.6-module/pdb_module.h  Sun Oct 01 11:39:41 
2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-
-#ifndef __PDB_MODULE_H_
-#define __PDB_MODULE_H_
-
-#include "../pdb_caml_xen.h"
-
-#define PDB_OPCODE_PAUSE  1
-
-#define PDB_OPCODE_ATTACH 2
-typedef struct pdb_op_attach
-{
-    uint32_t  domain;
-} pdb_op_attach_t, *pdb_op_attach_p;
-
-#define PDB_OPCODE_DETACH 3
-
-#define PDB_OPCODE_RD_REG 4
-typedef struct pdb_op_rd_reg
-{
-    uint32_t reg;
-    uint32_t value;
-} pdb_op_rd_reg_t, *pdb_op_rd_reg_p;
-
-#define PDB_OPCODE_RD_REGS 5
-typedef struct pdb_op_rd_regs
-{
-    uint32_t reg[GDB_REGISTER_FRAME_SIZE];
-} pdb_op_rd_regs_t, *pdb_op_rd_regs_p;
-
-#define PDB_OPCODE_WR_REG 6
-typedef struct pdb_op_wr_reg
-{
-    uint32_t reg;
-    uint32_t value;
-} pdb_op_wr_reg_t, *pdb_op_wr_reg_p;
-
-#define PDB_OPCODE_RD_MEM 7
-typedef struct pdb_op_rd_mem_req
-{
-    uint32_t address;
-    uint32_t length;
-} pdb_op_rd_mem_req_t, *pdb_op_rd_mem_req_p;
-
-typedef struct pdb_op_rd_mem_resp
-{
-    uint32_t address;
-    uint32_t length;
-    uint8_t  data[1024];
-} pdb_op_rd_mem_resp_t, *pdb_op_rd_mem_resp_p;
-
-#define PDB_OPCODE_WR_MEM 8
-typedef struct pdb_op_wr_mem
-{
-    uint32_t address;
-    uint32_t length;
-    uint8_t  data[1024];                                             /* 
arbitrary */
-} pdb_op_wr_mem_t, *pdb_op_wr_mem_p;
-
-#define PDB_OPCODE_CONTINUE 9
-#define PDB_OPCODE_STEP     10
-
-#define PDB_OPCODE_SET_BKPT 11
-#define PDB_OPCODE_CLR_BKPT 12
-typedef struct pdb_op_bkpt
-{
-    uint32_t address;
-    uint32_t length;
-} pdb_op_bkpt_t, *pdb_op_bkpt_p;
-
-#define PDB_OPCODE_SET_WATCHPT 13
-#define PDB_OPCODE_CLR_WATCHPT 14
-#define PDB_OPCODE_WATCHPOINT  15
-typedef struct pdb_op_watchpt
-{
-#define BWC_DEBUG 1
-#define BWC_INT3  3
-#define BWC_WATCH        100                         /* pdb: watchpoint page */
-#define BWC_WATCH_STEP   101                  /* pdb: watchpoint single step */
-#define BWC_WATCH_WRITE  102
-#define BWC_WATCH_READ   103
-#define BWC_WATCH_ACCESS 104
-    uint32_t type;
-    uint32_t address;
-    uint32_t length;
-} pdb_op_watchpt_t, *pdb_op_watchpt_p;
-
-
-typedef struct 
-{
-    uint8_t   operation;       /* PDB_OPCODE_???      */
-    uint32_t  process;
-    union
-    {
-        pdb_op_attach_t     attach;
-        pdb_op_rd_reg_t     rd_reg;
-        pdb_op_wr_reg_t     wr_reg;
-        pdb_op_rd_mem_req_t rd_mem;
-        pdb_op_wr_mem_t     wr_mem;
-        pdb_op_bkpt_t       bkpt;
-        pdb_op_watchpt_t    watchpt;
-    } u;
-} pdb_request_t, *pdb_request_p;
-
- 
-
-#define PDB_RESPONSE_OKAY   0
-#define PDB_RESPONSE_ERROR -1
-
-typedef struct {
-    uint8_t  operation;       /* copied from request */
-    uint32_t domain;          
-    uint32_t process;
-    int16_t  status;          /* PDB_RESPONSE_???    */
-    union
-    {
-        pdb_op_rd_reg_t      rd_reg;
-        pdb_op_rd_regs_t     rd_regs;
-        pdb_op_rd_mem_resp_t rd_mem;
-    } u;
-} pdb_response_t, *pdb_response_p;
-
-
-DEFINE_RING_TYPES(pdb, pdb_request_t, pdb_response_t);
-
-
-/* from access_process_vm */
-#define PDB_MEM_READ  0
-#define PDB_MEM_WRITE 1
-
-#endif
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-
diff -r 914c44d10c8d -r 2bfd19fc1b79 
tools/debugger/pdb/linux-2.6-patches/Makefile
--- a/tools/debugger/pdb/linux-2.6-patches/Makefile     Sun Oct 01 11:39:41 
2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-XEN_ROOT   = ../../../..
-LINUX_DIR  = linux-2.6.12-xenU
-KDIR       = $(XEN_ROOT)/$(LINUX_DIR)
-PATCH_DIR  = $(CURDIR)
-
-.PHONY: patches 
-patches : patches-done
-
-patches-done :
-       ( for i in *.patch ; do ( cd $(KDIR) ; patch -p1 < $(PATCH_DIR)/$$i || 
exit 1 ) ; done )
-       touch $@
diff -r 914c44d10c8d -r 2bfd19fc1b79 
tools/debugger/pdb/linux-2.6-patches/i386_ksyms.patch
--- a/tools/debugger/pdb/linux-2.6-patches/i386_ksyms.patch     Sun Oct 01 
11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-diff -u linux-2.6.12/arch/xen/i386/kernel/i386_ksyms.c 
linux-2.6.12-pdb/arch/xen/i386/kernel/i386_ksyms.c
---- linux-2.6.12/arch/xen/i386/kernel/i386_ksyms.c     2005-07-31 
22:36:50.000000000 +0100
-+++ linux-2.6.12-pdb/arch/xen/i386/kernel/i386_ksyms.c 2005-08-01 
10:57:31.000000000 +0100
-@@ -151,6 +151,7 @@
- /* TLB flushing */
- EXPORT_SYMBOL(flush_tlb_page);
- #endif
-+EXPORT_SYMBOL(flush_tlb_mm);
- 
- #ifdef CONFIG_X86_IO_APIC
- EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
-@@ -172,6 +173,7 @@
- EXPORT_SYMBOL_GPL(unset_nmi_callback);
- 
- EXPORT_SYMBOL(register_die_notifier);
-+EXPORT_SYMBOL(unregister_die_notifier);
- #ifdef CONFIG_HAVE_DEC_LOCK
- EXPORT_SYMBOL(_atomic_dec_and_lock);
- #endif
diff -r 914c44d10c8d -r 2bfd19fc1b79 
tools/debugger/pdb/linux-2.6-patches/kdebug.patch
--- a/tools/debugger/pdb/linux-2.6-patches/kdebug.patch Sun Oct 01 11:39:41 
2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-diff -u linux-2.6.12/include/asm-i386/kdebug.h 
linux-2.6.12-pdb/include/asm-i386/kdebug.h
---- linux-2.6.12/include/asm-i386/kdebug.h     2005-06-17 20:48:29.000000000 
+0100
-+++ linux-2.6.12-pdb/include/asm-i386/kdebug.h 2005-08-01 11:11:53.000000000 
+0100
-@@ -21,6 +21,7 @@
-    If you really want to do it first unregister - then synchronize_kernel - 
then free.
-   */
- int register_die_notifier(struct notifier_block *nb);
-+int unregister_die_notifier(struct notifier_block *nb);
- extern struct notifier_block *i386die_chain;
- 
- 
diff -r 914c44d10c8d -r 2bfd19fc1b79 
tools/debugger/pdb/linux-2.6-patches/makefile.patch
--- a/tools/debugger/pdb/linux-2.6-patches/makefile.patch       Sun Oct 01 
11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-diff -Naur linux-2.6.12/Makefile linux-2.6.12-pdb/Makefile
---- linux-2.6.12/Makefile      2005-08-01 01:21:21.000000000 +0100
-+++ linux-2.6.12-pdb/Makefile  2005-08-01 10:28:10.000000000 +0100
-@@ -508,7 +508,7 @@
- ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
- CFLAGS                += -Os
- else
--CFLAGS                += -O2
-+CFLAGS                += -O
- endif
- 
- #Add align options if CONFIG_CC_* is not equal to 0
diff -r 914c44d10c8d -r 2bfd19fc1b79 
tools/debugger/pdb/linux-2.6-patches/ptrace.patch
--- a/tools/debugger/pdb/linux-2.6-patches/ptrace.patch Sun Oct 01 11:39:41 
2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-diff -u linux-2.6.12/kernel/ptrace.c linux-2.6.12-pdb/kernel/ptrace.c
---- linux-2.6.12/kernel/ptrace.c       2005-06-17 20:48:29.000000000 +0100
-+++ linux-2.6.12-pdb/kernel/ptrace.c   2005-07-22 13:23:16.000000000 +0100
-@@ -239,6 +239,7 @@
- 
-        return buf - old_buf;
- }
-+EXPORT_SYMBOL(access_process_vm);
- 
- int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user 
*dst, int len)
- {
diff -r 914c44d10c8d -r 2bfd19fc1b79 
tools/debugger/pdb/linux-2.6-patches/traps.patch
--- a/tools/debugger/pdb/linux-2.6-patches/traps.patch  Sun Oct 01 11:39:41 
2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-diff -u linux-2.6.12/arch/xen/i386/kernel/traps.c 
linux-2.6.12-pdb/arch/xen/i386/kernel/traps.c
---- linux-2.6.12/arch/xen/i386/kernel/traps.c  2005-07-31 22:47:00.000000000 
+0100
-+++ linux-2.6.12-pdb/arch/xen/i386/kernel/traps.c      2005-07-31 
22:47:32.000000000 +0100
-@@ -102,6 +102,16 @@
-       return err;
- }
- 
-+int unregister_die_notifier(struct notifier_block *nb)
-+{
-+      int err = 0;
-+      unsigned long flags;
-+      spin_lock_irqsave(&die_notifier_lock, flags);
-+      err = notifier_chain_unregister(&i386die_chain, nb);
-+      spin_unlock_irqrestore(&die_notifier_lock, flags);
-+      return err;
-+}
-+
- static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
- {
-       return  p > (void *)tinfo &&
diff -r 914c44d10c8d -r 2bfd19fc1b79 tools/debugger/pdb/pdb_caml_domain.c
--- a/tools/debugger/pdb/pdb_caml_domain.c      Sun Oct 01 11:39:41 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,527 +0,0 @@
-/*
- * pdb_caml_xc.c
- *
- * http://www.cl.cam.ac.uk/netos/pdb
- *
- * PDB's OCaml interface library for debugging domains
- */
-
-#include <xenctrl.h>
-#include <xendebug.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <caml/alloc.h>
-#include <caml/fail.h>
-#include <caml/memory.h>
-#include <caml/mlvalues.h>
-
-#include "pdb_caml_xen.h"
-
-typedef struct
-{
-    int domain;
-    int vcpu;
-} context_t;
-
-#define decode_context(_ctx, _ocaml)   \
-{  \
-    (_ctx)->domain = Int_val(Field((_ocaml),0));  \
-    (_ctx)->vcpu = Int_val(Field((_ocaml),1));  \
-}
-
-#define encode_context(_ctx, _ocaml)  \
-{  \
-    (_ocaml) = caml_alloc_tuple(2);  \
-    Store_field((_ocaml), 0, Val_int((_ctx)->domain));  \
-    Store_field((_ocaml), 1, Val_int((_ctx)->vcpu));  \
-}
-
-
-/****************************************************************************/
-
-/*
- * dom_read_register : context_t -> int -> int32
- */
-value
-dom_read_register (value context, value reg)
-{
-    CAMLparam2(context, reg);
-    CAMLlocal1(result);
-
-    int my_reg = Int_val(reg);
-    cpu_user_regs_t *regs;
-    context_t ctx;
-
-    decode_context(&ctx, context);
-
-    if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
-    {
-        printf("(pdb) read registers error!\n");  fflush(stdout);
-        failwith("read registers error");
-    }
-
-    dump_regs(regs);
-
-    result = caml_alloc_tuple(16);
-
-    switch (my_reg)
-    {
-    case GDB_EAX: result = caml_copy_int32(regs->eax); break;
-    case GDB_ECX: result = caml_copy_int32(regs->ecx); break;
-    case GDB_EDX: result = caml_copy_int32(regs->edx); break;
-    case GDB_EBX: result = caml_copy_int32(regs->ebx); break;
-    case GDB_ESP: result = caml_copy_int32(regs->esp); break;
-    case GDB_EBP: result = caml_copy_int32(regs->ebp); break;
-    case GDB_ESI: result = caml_copy_int32(regs->esi); break;
-    case GDB_EDI: result = caml_copy_int32(regs->edi); break;
-    case GDB_EIP: result = caml_copy_int32(regs->eip); break;
-    case GDB_EFL: result = caml_copy_int32(regs->eflags); break;
-    case GDB_CS:  result = caml_copy_int32(regs->cs);  break;
-    case GDB_SS: result = caml_copy_int32(regs->ss); break;
-    case GDB_DS: result = caml_copy_int32(regs->ds); break;
-    case GDB_ES: result = caml_copy_int32(regs->es); break;
-    case GDB_FS: result = caml_copy_int32(regs->fs); break;
-    case GDB_GS: result = caml_copy_int32(regs->gs); break;
-    }
-
-    CAMLreturn(result);
-}
-
-/*
- * dom_read_registers : context_t -> int32
- */
-value
-dom_read_registers (value context)
-{
-    CAMLparam1(context);
-    CAMLlocal1(result);
-
-    cpu_user_regs_t *regs;
-    context_t ctx;
-
-    decode_context(&ctx, context);
-
-    if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
-    {
-        printf("(pdb) read registers error!\n");  fflush(stdout);
-        failwith("read registers error");
-    }
-

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