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

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



# 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


 


Rackspace

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