# 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, ®s);
+ 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__, ®s);
+ 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(®s);
- pdb_handle_exception(1, ®s, 1);
- svm_debug_restore_cpu_user_regs(®s);
+ 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(®s, v);
+ svm_store_cpu_user_regs(regs, v);
domain_pause_for_debugger();
#endif
}
break;
case VMEXIT_NMI:
- do_nmi(®s, 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(®s);
- pdb_handle_exception(3, ®s, 1);
- svm_debug_restore_cpu_user_regs(®s);
+ 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, ®s);
+ 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, ®s)))
+ (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__, ®s);
+ 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(®s);
+ __hvm_bug(regs);
break;
case VMEXIT_CPUID:
- svm_vmexit_do_cpuid(vmcb, regs.eax, ®s);
+ 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, ®s);
+ svm_handle_invlpg(0, regs);
break;
case VMEXIT_INVLPGA:
- svm_handle_invlpg(1, ®s);
+ svm_handle_invlpg(1, regs);
break;
case VMEXIT_VMMCALL:
- svm_do_vmmcall(v, ®s);
+ svm_do_vmmcall(v, regs);
break;
case VMEXIT_CR0_READ:
- svm_cr_access(v, 0, TYPE_MOV_FROM_CR, ®s);
+ svm_cr_access(v, 0, TYPE_MOV_FROM_CR, regs);
break;
case VMEXIT_CR2_READ:
- svm_cr_access(v, 2, TYPE_MOV_FROM_CR, ®s);
+ svm_cr_access(v, 2, TYPE_MOV_FROM_CR, regs);
break;
case VMEXIT_CR3_READ:
- svm_cr_access(v, 3, TYPE_MOV_FROM_CR, ®s);
+ svm_cr_access(v, 3, TYPE_MOV_FROM_CR, regs);
break;
case VMEXIT_CR4_READ:
- svm_cr_access(v, 4, TYPE_MOV_FROM_CR, ®s);
+ svm_cr_access(v, 4, TYPE_MOV_FROM_CR, regs);
break;
case VMEXIT_CR8_READ:
- svm_cr_access(v, 8, TYPE_MOV_FROM_CR, ®s);
+ svm_cr_access(v, 8, TYPE_MOV_FROM_CR, regs);
break;
case VMEXIT_CR0_WRITE:
- svm_cr_access(v, 0, TYPE_MOV_TO_CR, ®s);
+ svm_cr_access(v, 0, TYPE_MOV_TO_CR, regs);
break;
case VMEXIT_CR2_WRITE:
- svm_cr_access(v, 2, TYPE_MOV_TO_CR, ®s);
+ svm_cr_access(v, 2, TYPE_MOV_TO_CR, regs);
break;
case VMEXIT_CR3_WRITE:
- svm_cr_access(v, 3, TYPE_MOV_TO_CR, ®s);
+ 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, ®s);
+ svm_cr_access(v, 4, TYPE_MOV_TO_CR, regs);
break;
case VMEXIT_CR8_WRITE:
- svm_cr_access(v, 8, TYPE_MOV_TO_CR, ®s);
+ svm_cr_access(v, 8, TYPE_MOV_TO_CR, regs);
break;
case VMEXIT_DR0_WRITE ... VMEXIT_DR7_WRITE:
- svm_dr_access(v, ®s);
+ 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, ®s);
+ 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(®s); /* 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__, ®s);
+ 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(®s);
- pdb_handle_exception(1, ®s, 1);
- restore_cpu_user_regs(®s);
+ save_cpu_user_regs(regs);
+ pdb_handle_exception(1, regs, 1);
+ restore_cpu_user_regs(regs);
break;
}
case TRAP_int3:
{
- save_cpu_user_regs(®s);
- pdb_handle_exception(3, ®s, 1);
- restore_cpu_user_regs(®s);
+ 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(®s);
+ 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, ®s.error_code);
-
- TRACE_VMEXIT(3,regs.error_code);
- TRACE_VMEXIT(4,va);
+ __vmread(VM_EXIT_INTR_ERROR_CODE, ®s->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, ®s) ) {
- /*
- * 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(®s);
+ 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(®s);
+ 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(®s);
+ 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(®s);
+ 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, ®s) )
+ 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, ®s);
+ 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(®s);
+ 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(®s);
+ 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, ®s) )
- {
- 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, ®s) )
- {
- 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
|