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

[Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1172227113 0
# Node ID 6510cb03aae13988925ef1707ee6ad7987c8e226
# Parent  202eb735b425d4f99fb8a78ab6df6e7c9b70c6cb
# Parent  e8470a1a01afe85e3dcdf42cfa149b09a06c0653
Merge with xen-ia64-unstable.hg.
---
 tools/blktap/drivers/block-aio.c  |   33 ++++----
 tools/blktap/drivers/block-qcow.c |   85 +++++++++++---------
 tools/blktap/drivers/block-ram.c  |   28 +++---
 tools/blktap/drivers/block-sync.c |   28 +++---
 tools/blktap/drivers/block-vmdk.c |   29 ++++---
 tools/blktap/drivers/img2qcow.c   |    2 
 tools/blktap/drivers/qcow2raw.c   |    4 
 tools/blktap/drivers/tapdisk.c    |  154 +++++++++++++++++++++++---------------
 tools/blktap/drivers/tapdisk.h    |   44 +++++++---
 xen/arch/x86/hvm/svm/svm.c        |    8 +
 xen/arch/x86/hvm/vmx/vmx.c        |   12 ++
 xen/arch/x86/mm/shadow/common.c   |    4 
 xen/arch/x86/mm/shadow/multi.c    |   22 +++++
 xen/arch/x86/setup.c              |   13 +--
 xen/arch/x86/x86_64/mm.c          |    3 
 xen/common/page_alloc.c           |   74 ++++++++++++------
 xen/include/asm-x86/hvm/hvm.h     |    7 +
 xen/include/asm-x86/perfc_defn.h  |    1 
 xen/include/xen/mm.h              |    7 +
 xen/include/xen/perfc.h           |    1 
 20 files changed, 364 insertions(+), 195 deletions(-)

diff -r 202eb735b425 -r 6510cb03aae1 tools/blktap/drivers/block-aio.c
--- a/tools/blktap/drivers/block-aio.c  Thu Feb 22 10:15:29 2007 -0700
+++ b/tools/blktap/drivers/block-aio.c  Fri Feb 23 10:38:33 2007 +0000
@@ -152,9 +152,9 @@ static inline void init_fds(struct disk_
 }
 
 /* Open the disk file and initialize aio state. */
-int tdaio_open (struct disk_driver *dd, const char *name)
-{
-       int i, fd, ret = 0;
+int tdaio_open (struct disk_driver *dd, const char *name, td_flag_t flags)
+{
+       int i, fd, ret = 0, o_flags;
        struct td_state    *s   = dd->td_state;
        struct tdaio_state *prv = (struct tdaio_state *)dd->private;
 
@@ -187,12 +187,15 @@ int tdaio_open (struct disk_driver *dd, 
                prv->iocb_free[i] = &prv->iocb_list[i];
 
        /* Open the file */
-        fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
+       o_flags = O_DIRECT | O_LARGEFILE | 
+               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+        fd = open(name, o_flags);
 
         if ( (fd == -1) && (errno == EINVAL) ) {
 
                 /* Maybe O_DIRECT isn't supported. */
-                fd = open(name, O_RDWR | O_LARGEFILE);
+               o_flags &= ~O_DIRECT;
+                fd = open(name, o_flags);
                 if (fd != -1) DPRINTF("WARNING: Accessing image without"
                                      "O_DIRECT! (%s)\n", name);
 
@@ -279,6 +282,9 @@ int tdaio_submit(struct disk_driver *dd)
 {
        int ret;
        struct tdaio_state *prv = (struct tdaio_state *)dd->private;
+
+       if (!prv->iocb_queued)
+               return 0;
 
        ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
        
@@ -324,12 +330,13 @@ int tdaio_do_callbacks(struct disk_drive
        return rsp;
 }
 
-int tdaio_has_parent(struct disk_driver *dd)
-{
-       return 0;
-}
-
-int tdaio_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+int tdaio_get_parent_id(struct disk_driver *dd, struct disk_id *id)
+{
+       return TD_NO_PARENT;
+}
+
+int tdaio_validate_parent(struct disk_driver *dd, 
+                         struct disk_driver *parent, td_flag_t flags)
 {
        return -EINVAL;
 }
@@ -341,8 +348,8 @@ struct tap_disk tapdisk_aio = {
        .td_queue_read      = tdaio_queue_read,
        .td_queue_write     = tdaio_queue_write,
        .td_submit          = tdaio_submit,
-       .td_has_parent      = tdaio_has_parent,
-       .td_get_parent      = tdaio_get_parent,
        .td_close           = tdaio_close,
        .td_do_callbacks    = tdaio_do_callbacks,
+       .td_get_parent_id   = tdaio_get_parent_id,
+       .td_validate_parent = tdaio_validate_parent
 };
diff -r 202eb735b425 -r 6510cb03aae1 tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Thu Feb 22 10:15:29 2007 -0700
+++ b/tools/blktap/drivers/block-qcow.c Fri Feb 23 10:38:33 2007 +0000
@@ -207,23 +207,6 @@ static int init_aio_state(struct disk_dr
 
  fail:
        return -1;
-}
-
-/*
- *Test if block is zero. 
- * Return: 
- *       1 for TRUE
- *       0 for FALSE
- */
-static inline int IS_ZERO(char *buf, int len)
-{
-       int i;
-
-       for (i = 0; i < len; i++) {
-               /*if not zero, return false*/
-               if (ZERO_TEST(*(buf + i))) return 0; 
-       }
-       return 1;
 }
 
 static uint32_t gen_cksum(char *ptr, int len)
@@ -825,9 +808,9 @@ static inline void init_fds(struct disk_
 }
 
 /* Open the disk file and initialize qcow state. */
-int tdqcow_open (struct disk_driver *dd, const char *name)
-{
-       int fd, len, i, shift, ret, size, l1_table_size;
+int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags)
+{
+       int fd, len, i, shift, ret, size, l1_table_size, o_flags;
        struct td_state     *bs = dd->td_state;
        struct tdqcow_state *s  = (struct tdqcow_state *)dd->private;
        char *buf;
@@ -838,7 +821,9 @@ int tdqcow_open (struct disk_driver *dd,
 
        DPRINTF("QCOW: Opening %s\n",name);
 
-       fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
+       o_flags = O_DIRECT | O_LARGEFILE | 
+               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+       fd = open(name, o_flags);
        if (fd < 0) {
                DPRINTF("Unable to open %s (%d)\n",name,0 - errno);
                return -1;
@@ -1016,7 +1001,8 @@ int tdqcow_queue_read(struct disk_driver
                                 * as busy and try again later */
                                return cb(dd, -EBUSY, sector + n,
                                          nb_sectors - n, id, private);
-                       } else rsp += ret;
+                       } else
+                               rsp += ret;
                } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
                        aio_unlock(s, sector);
                        if (decompress_cluster(s, cluster_offset) < 0) {
@@ -1403,21 +1389,15 @@ int qcow_compress_cluster(struct tdqcow_
        return 0;
 }
 
-int tdqcow_has_parent(struct disk_driver *dd)
-{
-       struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
-       return (s->backing_file_offset ? 1 : 0);
-}
-
-int tdqcow_get_parent(struct disk_driver *cdd, struct disk_driver *pdd)
+int tdqcow_get_parent_id(struct disk_driver *dd, struct disk_id *id)
 {
        off_t off;
        char *buf, *filename;
-       int len, secs, ret = -1;
-       struct tdqcow_state *child  = (struct tdqcow_state *)cdd->private;
+       int len, secs, err = -EINVAL;
+       struct tdqcow_state *child  = (struct tdqcow_state *)dd->private;
 
        if (!child->backing_file_offset)
-               return -1;
+               return TD_NO_PARENT;
 
        /* read the backing file name */
        len  = child->backing_file_size;
@@ -1432,14 +1412,39 @@ int tdqcow_get_parent(struct disk_driver
 
        if (read(child->fd, buf, secs << 9) != secs << 9)
                goto out;
-       filename      = buf + (child->backing_file_offset - off);
-       filename[len] = '\0';
-
-       /*Open backing file*/
-       ret = tdqcow_open(pdd, filename);
+       filename       = buf + (child->backing_file_offset - off);
+       filename[len]  = '\0';
+
+       id->name       = strdup(filename);
+       id->drivertype = DISK_TYPE_QCOW;
+       err            = 0;
  out:
        free(buf);
-       return ret;
+       return err;
+}
+
+int tdqcow_validate_parent(struct disk_driver *child,
+                          struct disk_driver *parent, td_flag_t flags)
+{
+       struct stat stats;
+       uint64_t psize, csize;
+       struct tdqcow_state *c = (struct tdqcow_state *)child->private;
+       struct tdqcow_state *p = (struct tdqcow_state *)parent->private;
+       
+       if (stat(p->name, &stats))
+               return -EINVAL;
+       if (get_filesize(p->name, &psize, &stats))
+               return -EINVAL;
+
+       if (stat(c->name, &stats))
+               return -EINVAL;
+       if (get_filesize(c->name, &csize, &stats))
+               return -EINVAL;
+
+       if (csize != psize)
+               return -EINVAL;
+
+       return 0;
 }
 
 struct tap_disk tapdisk_qcow = {
@@ -1449,8 +1454,8 @@ struct tap_disk tapdisk_qcow = {
        .td_queue_read       = tdqcow_queue_read,
        .td_queue_write      = tdqcow_queue_write,
        .td_submit           = tdqcow_submit,
-       .td_has_parent       = tdqcow_has_parent,
-       .td_get_parent       = tdqcow_get_parent,
        .td_close            = tdqcow_close,
        .td_do_callbacks     = tdqcow_do_callbacks,
+       .td_get_parent_id    = tdqcow_get_parent_id,
+       .td_validate_parent  = tdqcow_validate_parent
 };
diff -r 202eb735b425 -r 6510cb03aae1 tools/blktap/drivers/block-ram.c
--- a/tools/blktap/drivers/block-ram.c  Thu Feb 22 10:15:29 2007 -0700
+++ b/tools/blktap/drivers/block-ram.c  Fri Feb 23 10:38:33 2007 +0000
@@ -135,11 +135,11 @@ static inline void init_fds(struct disk_
 }
 
 /* Open the disk file and initialize ram state. */
-int tdram_open (struct disk_driver *dd, const char *name)
+int tdram_open (struct disk_driver *dd, const char *name, td_flag_t flags)
 {
        char *p;
        uint64_t size;
-       int i, fd, ret = 0, count = 0;
+       int i, fd, ret = 0, count = 0, o_flags;
        struct td_state    *s     = dd->td_state;
        struct tdram_state *prv   = (struct tdram_state *)dd->private;
 
@@ -167,12 +167,15 @@ int tdram_open (struct disk_driver *dd, 
        }
 
        /* Open the file */
-        fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
+       o_flags = O_DIRECT | O_LARGEFILE | 
+               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+        fd = open(name, o_flags);
 
         if ((fd == -1) && (errno == EINVAL)) {
 
                 /* Maybe O_DIRECT isn't supported. */
-                fd = open(name, O_RDWR | O_LARGEFILE);
+               o_flags &= ~O_DIRECT;
+                fd = open(name, o_flags);
                 if (fd != -1) DPRINTF("WARNING: Accessing image without"
                                      "O_DIRECT! (%s)\n", name);
 
@@ -275,12 +278,13 @@ int tdram_do_callbacks(struct disk_drive
        return 1;
 }
 
-int tdram_has_parent(struct disk_driver *dd)
-{
-       return 0;
-}
-
-int tdram_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+int tdram_get_parent_id(struct disk_driver *dd, struct disk_id *id)
+{
+       return TD_NO_PARENT;
+}
+
+int tdram_validate_parent(struct disk_driver *dd, 
+                         struct disk_driver *parent, td_flag_t flags)
 {
        return -EINVAL;
 }
@@ -292,8 +296,8 @@ struct tap_disk tapdisk_ram = {
        .td_queue_read      = tdram_queue_read,
        .td_queue_write     = tdram_queue_write,
        .td_submit          = tdram_submit,
-       .td_has_parent      = tdram_has_parent,
-       .td_get_parent      = tdram_get_parent,
        .td_close           = tdram_close,
        .td_do_callbacks    = tdram_do_callbacks,
+       .td_get_parent_id   = tdram_get_parent_id,
+       .td_validate_parent = tdram_validate_parent
 };
diff -r 202eb735b425 -r 6510cb03aae1 tools/blktap/drivers/block-sync.c
--- a/tools/blktap/drivers/block-sync.c Thu Feb 22 10:15:29 2007 -0700
+++ b/tools/blktap/drivers/block-sync.c Fri Feb 23 10:38:33 2007 +0000
@@ -118,9 +118,9 @@ static inline void init_fds(struct disk_
 }
 
 /* Open the disk file and initialize aio state. */
-int tdsync_open (struct disk_driver *dd, const char *name)
-{
-       int i, fd, ret = 0;
+int tdsync_open (struct disk_driver *dd, const char *name, td_flag_t flags)
+{
+       int i, fd, ret = 0, o_flags;
        struct td_state     *s   = dd->td_state;
        struct tdsync_state *prv = (struct tdsync_state *)dd->private;
        
@@ -130,11 +130,14 @@ int tdsync_open (struct disk_driver *dd,
                return (0 - errno);
        
        /* Open the file */
-        fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
+       o_flags = O_DIRECT | O_LARGEFILE | 
+               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+        fd = open(name, o_flags);
 
         if ( (fd == -1) && (errno == EINVAL) ) {
 
                 /* Maybe O_DIRECT isn't supported. */
+               o_flags &= ~O_DIRECT;
                 fd = open(name, O_RDWR | O_LARGEFILE);
                 if (fd != -1) DPRINTF("WARNING: Accessing image without"
                                      "O_DIRECT! (%s)\n", name);
@@ -223,12 +226,13 @@ int tdsync_do_callbacks(struct disk_driv
        return 1;
 }
 
-int tdsync_has_parent(struct disk_driver *dd)
-{
-       return 0;
-}
-
-int tdsync_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+int tdsync_get_parent_id(struct disk_driver *dd, struct disk_id *id)
+{
+       return TD_NO_PARENT;
+}
+
+int tdsync_validate_parent(struct disk_driver *dd, 
+                          struct disk_driver *parent, td_flag_t flags)
 {
        return -EINVAL;
 }
@@ -240,8 +244,8 @@ struct tap_disk tapdisk_sync = {
        .td_queue_read       = tdsync_queue_read,
        .td_queue_write      = tdsync_queue_write,
        .td_submit           = tdsync_submit,
-       .td_has_parent       = tdsync_has_parent,
-       .td_get_parent       = tdsync_get_parent,
        .td_close            = tdsync_close,
        .td_do_callbacks     = tdsync_do_callbacks,
+       .td_get_parent_id    = tdsync_get_parent_id,
+       .td_validate_parent  = tdsync_validate_parent
 };
diff -r 202eb735b425 -r 6510cb03aae1 tools/blktap/drivers/block-vmdk.c
--- a/tools/blktap/drivers/block-vmdk.c Thu Feb 22 10:15:29 2007 -0700
+++ b/tools/blktap/drivers/block-vmdk.c Fri Feb 23 10:38:33 2007 +0000
@@ -119,10 +119,11 @@ static inline void init_fds(struct disk_
 }
 
 /* Open the disk file and initialize aio state. */
-static int tdvmdk_open (struct disk_driver *dd, const char *name)
+static int tdvmdk_open (struct disk_driver *dd, 
+                       const char *name, td_flag_t flags)
 {
        int ret, fd;
-       int l1_size, i;
+       int l1_size, i, o_flags;
        uint32_t magic;
        struct td_state     *s   = dd->td_state;
        struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
@@ -133,12 +134,15 @@ static int tdvmdk_open (struct disk_driv
                return -1;
        
        /* Open the file */
-        fd = open(name, O_RDWR | O_LARGEFILE); 
+       o_flags = O_DIRECT | O_LARGEFILE | 
+               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+        fd = open(name, o_flags); 
 
         if ( (fd == -1) && (errno == EINVAL) ) {
 
                 /* Maybe O_DIRECT isn't supported. */
-                fd = open(name, O_RDWR | O_LARGEFILE);
+               o_flags &= ~O_DIRECT;
+                fd = open(name, o_flags);
                 if (fd != -1) DPRINTF("WARNING: Accessing image without"
                                      "O_DIRECT! (%s)\n", name);
 
@@ -394,12 +398,13 @@ static int tdvmdk_do_callbacks(struct di
        return 1;
 }
 
-static int tdvmdk_has_parent(struct disk_driver *dd)
-{
-       return 0;
-}
-
-static int tdvmdk_get_parent(struct disk_driver *dd, struct disk_driver 
*parent)
+static int tdvmdk_get_parent_id(struct disk_driver *dd, struct disk_id *id)
+{
+       return TD_NO_PARENT;
+}
+
+static int tdvmdk_validate_parent(struct disk_driver *dd, 
+                                 struct disk_driver *parent, td_flag_t flags)
 {
        return -EINVAL;
 }
@@ -411,8 +416,8 @@ struct tap_disk tapdisk_vmdk = {
        .td_queue_read       = tdvmdk_queue_read,
        .td_queue_write      = tdvmdk_queue_write,
        .td_submit           = tdvmdk_submit,
-       .td_has_parent       = tdvmdk_has_parent,
-       .td_get_parent       = tdvmdk_get_parent,
        .td_close            = tdvmdk_close,
        .td_do_callbacks     = tdvmdk_do_callbacks,
+       .td_get_parent_id    = tdvmdk_get_parent_id,
+       .td_validate_parent  = tdvmdk_validate_parent
 };
diff -r 202eb735b425 -r 6510cb03aae1 tools/blktap/drivers/img2qcow.c
--- a/tools/blktap/drivers/img2qcow.c   Thu Feb 22 10:15:29 2007 -0700
+++ b/tools/blktap/drivers/img2qcow.c   Fri Feb 23 10:38:33 2007 +0000
@@ -201,7 +201,7 @@ int main(int argc, char *argv[])
        dd.private  = malloc(dd.drv->private_data_size);
 
         /*Open qcow file*/
-        if (dd.drv->td_open(&dd, argv[1])!=0) {
+        if (dd.drv->td_open(&dd, argv[1], 0)!=0) {
                DFPRINTF("Unable to open Qcow file [%s]\n",argv[1]);
                exit(-1);
        }
diff -r 202eb735b425 -r 6510cb03aae1 tools/blktap/drivers/qcow2raw.c
--- a/tools/blktap/drivers/qcow2raw.c   Thu Feb 22 10:15:29 2007 -0700
+++ b/tools/blktap/drivers/qcow2raw.c   Fri Feb 23 10:38:33 2007 +0000
@@ -169,7 +169,7 @@ int main(int argc, char *argv[])
        ddqcow.drv = &tapdisk_qcow;
        ddqcow.private = malloc(ddqcow.drv->private_data_size);
 
-        if (ddqcow.drv->td_open(&ddqcow, argv[2])!=0) {
+        if (ddqcow.drv->td_open(&ddqcow, argv[2], TD_RDONLY)!=0) {
                DFPRINTF("Unable to open Qcow file [%s]\n",argv[2]);
                exit(-1);
        } else DFPRINTF("QCOW file opened, size %llu\n",
@@ -270,7 +270,7 @@ int main(int argc, char *argv[])
        ddaio.drv = &tapdisk_aio;
        ddaio.private = malloc(ddaio.drv->private_data_size);
 
-        if (ddaio.drv->td_open(&ddaio, argv[1])!=0) {
+        if (ddaio.drv->td_open(&ddaio, argv[1], 0)!=0) {
                DFPRINTF("Unable to open Qcow file [%s]\n", argv[1]);
                exit(-1);
        }
diff -r 202eb735b425 -r 6510cb03aae1 tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c    Thu Feb 22 10:15:29 2007 -0700
+++ b/tools/blktap/drivers/tapdisk.c    Fri Feb 23 10:38:33 2007 +0000
@@ -81,6 +81,15 @@ void daemonize(void)
        return;
 }
 
+static void free_driver(struct disk_driver *d)
+{
+       if (d->name)
+               free(d->name);
+       if (d->private)
+               free(d->private);
+       free(d);
+}
+
 static void unmap_disk(struct td_state *s)
 {
        tapdev_info_t *info = s->ring_info;
@@ -91,8 +100,7 @@ static void unmap_disk(struct td_state *
        while (dd) {
                tmp = dd->next;
                dd->drv->td_close(dd);
-               free(dd->private);
-               free(dd);
+               free_driver(dd);
                dd = tmp;
        }
 
@@ -112,7 +120,6 @@ static void unmap_disk(struct td_state *
        free(s);
 
        return;
-
 }
 
 void sig_handler(int sig)
@@ -205,26 +212,6 @@ static struct td_state *state_init(void)
        return s;
 }
 
-static struct disk_driver *disk_init(struct td_state *s, struct tap_disk *drv)
-{
-       struct disk_driver *dd;
-
-       dd = calloc(1, sizeof(struct disk_driver));
-       if (!dd)
-               return NULL;
-       
-       dd->private = malloc(drv->private_data_size);
-       if (!dd->private) {
-               free(dd);
-               return NULL;
-       }
-
-       dd->drv      = drv;
-       dd->td_state = s;
-
-       return dd;
-}
-
 static int map_new_dev(struct td_state *s, int minor)
 {
        int tap_fd;
@@ -280,49 +267,94 @@ static int map_new_dev(struct td_state *
        return -1;
 }
 
-static int open_disk(struct td_state *s, struct disk_driver *dd, char *path)
+static struct disk_driver *disk_init(struct td_state *s, 
+                                    struct tap_disk *drv, char *name)
+{
+       struct disk_driver *dd;
+
+       dd = calloc(1, sizeof(struct disk_driver));
+       if (!dd)
+               return NULL;
+       
+       dd->private = malloc(drv->private_data_size);
+       if (!dd->private) {
+               free(dd);
+               return NULL;
+       }
+
+       dd->drv      = drv;
+       dd->td_state = s;
+       dd->name     = name;
+
+       return dd;
+}
+
+static int open_disk(struct td_state *s, struct tap_disk *drv, char *path)
 {
        int err;
-       struct disk_driver *d = dd;
-
-       err = dd->drv->td_open(dd, path);
+       char *dup;
+       struct disk_id id;
+       struct disk_driver *d;
+
+       dup = strdup(path);
+       if (!dup)
+               return -ENOMEM;
+
+       memset(&id, 0, sizeof(struct disk_id));
+       s->disks = d = disk_init(s, drv, dup);
+       if (!d)
+               return -ENOMEM;
+
+       err = drv->td_open(d, path, 0);
        if (err)
-               return err;
+               goto fail;
 
        /* load backing files as necessary */
-       while (d->drv->td_has_parent(d)) {
+       while ((err = d->drv->td_get_parent_id(d, &id)) == 0) {
                struct disk_driver *new;
                
-               new = calloc(1, sizeof(struct disk_driver));
+               if (id.drivertype > MAX_DISK_TYPES || 
+                   !get_driver(id.drivertype) || !id.name)
+                       goto fail;
+
+               dup = strdup(id.name);
+               if (!dup)
+                       goto fail;
+
+               new = disk_init(s, get_driver(id.drivertype), dup);
                if (!new)
                        goto fail;
-               new->drv      = d->drv;
-               new->td_state = s;
-               new->private  = malloc(new->drv->private_data_size);
-               if (!new->private) {
-                       free(new);
+
+               err = new->drv->td_open(new, new->name, TD_RDONLY);
+               if (err)
+                       goto fail;
+
+               err = d->drv->td_validate_parent(d, new, 0);
+               if (err) {
+                       d->next = new;
                        goto fail;
                }
-               
-               err = d->drv->td_get_parent(d, new);
-               if (err)
-                       goto fail;
 
                d = d->next = new;
-       }
-
-       return 0;
+               free(id.name);
+       }
+
+       if (err >= 0)
+               return 0;
 
  fail:
        DPRINTF("failed opening disk\n");
-       while (dd) {
-               d = dd->next;
-               dd->drv->td_close(dd);
-               free(dd->private);
-               free(dd);
-               dd = d;
-       }
-       return err;
+       if (id.name)
+               free(id.name);
+       d = s->disks;
+       while (d) {
+               struct disk_driver *tmp = d->next;
+               d->drv->td_close(d);
+               free_driver(d);
+               d = tmp;
+       }
+       s->disks = NULL;
+       return -1;
 }
 
 static int read_msg(char *buf)
@@ -334,7 +366,6 @@ static int read_msg(char *buf)
        msg_newdev_t *msg_dev;
        msg_pid_t *msg_pid;
        struct tap_disk *drv;
-       struct disk_driver *dd;
        int ret = -1;
        struct td_state *s = NULL;
        fd_list_entry_t *entry;
@@ -369,14 +400,8 @@ static int read_msg(char *buf)
                        if (s == NULL)
                                goto params_done;
 
-                       s->disks = dd = disk_init(s, drv);
-                       if (!dd) {
-                               free(s);
-                               goto params_done;
-                       }
-
                        /*Open file*/
-                       ret = open_disk(s, dd, path);
+                       ret = open_disk(s, drv, path);
                        if (ret)
                                goto params_done;
 
@@ -785,6 +810,19 @@ int main(int argc, char *argv[])
                                        }
                                }
 
+                               /* completed io from above may have 
+                                * queued new requests on chained disks */
+                               if (progress_made) {
+                                       td_for_each_disk(ptr->s, dd) {
+                                               dd->early += 
+                                                       dd->drv->td_submit(dd);
+                                               if (dd->early > 0) {
+                                                       io_done(dd, 10);
+                                                       dd->early = 0;
+                                               }
+                                       }
+                               }
+
                                if (FD_ISSET(ptr->tap_fd, &readfds) ||
                                    (info->busy.req && progress_made))
                                        get_io_request(ptr->s);
diff -r 202eb735b425 -r 6510cb03aae1 tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h    Thu Feb 22 10:15:29 2007 -0700
+++ b/tools/blktap/drivers/tapdisk.h    Fri Feb 23 10:38:33 2007 +0000
@@ -42,10 +42,15 @@
  * 
  *   - The fd used for poll is an otherwise unused pipe, which allows poll to 
  *     be safely called without ever returning anything.
- * 
+ *
  * NOTE: tapdisk uses the number of sectors submitted per request as a 
  * ref count.  Plugins must use the callback function to communicate the
  * completion--or error--of every sector submitted to them.
+ *
+ * td_get_parent_id returns:
+ *     0 if parent id successfully retrieved
+ *     TD_NO_PARENT if no parent exists
+ *     -errno on error
  */
 
 #ifndef TAPDISK_H_
@@ -71,12 +76,23 @@
 #define MAX_IOFD                 2
 
 #define BLK_NOT_ALLOCATED       99
+#define TD_NO_PARENT             1
+
+typedef uint32_t td_flag_t;
+
+#define TD_RDONLY                1
 
 struct td_state;
 struct tap_disk;
 
+struct disk_id {
+       char *name;
+       int drivertype;
+};
+
 struct disk_driver {
        int early;
+       char *name;
        void *private;
        int io_fd[MAX_IOFD];
        struct tap_disk *drv;
@@ -105,18 +121,20 @@ struct tap_disk {
 struct tap_disk {
        const char *disk_type;
        int private_data_size;
-       int (*td_open)        (struct disk_driver *dd, const char *name);
-       int (*td_queue_read)  (struct disk_driver *dd, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb, 
-                              int id, void *prv);
-       int (*td_queue_write) (struct disk_driver *dd, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb, 
-                              int id, void *prv);
-       int (*td_submit)      (struct disk_driver *dd);
-       int (*td_has_parent)  (struct disk_driver *dd);
-       int (*td_get_parent)  (struct disk_driver *dd, struct disk_driver *p);
-       int (*td_close)       (struct disk_driver *dd);
-       int (*td_do_callbacks)(struct disk_driver *dd, int sid);
+       int (*td_open)           (struct disk_driver *dd, 
+                                 const char *name, td_flag_t flags);
+       int (*td_queue_read)     (struct disk_driver *dd, uint64_t sector,
+                                 int nb_sectors, char *buf, td_callback_t cb,
+                                 int id, void *prv);
+       int (*td_queue_write)    (struct disk_driver *dd, uint64_t sector,
+                                 int nb_sectors, char *buf, td_callback_t cb, 
+                                 int id, void *prv);
+       int (*td_submit)         (struct disk_driver *dd);
+       int (*td_close)          (struct disk_driver *dd);
+       int (*td_do_callbacks)   (struct disk_driver *dd, int sid);
+       int (*td_get_parent_id)  (struct disk_driver *dd, struct disk_id *id);
+       int (*td_validate_parent)(struct disk_driver *dd, 
+                                 struct disk_driver *p, td_flag_t flags);
 };
 
 typedef struct disk_info {
diff -r 202eb735b425 -r 6510cb03aae1 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/arch/x86/hvm/svm/svm.c        Fri Feb 23 10:38:33 2007 +0000
@@ -982,6 +982,12 @@ static void svm_hvm_inject_exception(
         v->arch.hvm_svm.vmcb->cr2 = v->arch.hvm_svm.cpu_cr2 = cr2;
 }
 
+static int svm_event_injection_faulted(struct vcpu *v)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+    return vmcb->exitintinfo.fields.v;
+}
+
 int start_svm(void)
 {
     u32 eax, ecx, edx;
@@ -1057,6 +1063,8 @@ int start_svm(void)
 
     hvm_funcs.init_ap_context = svm_init_ap_context;
     hvm_funcs.init_hypercall_page = svm_init_hypercall_page;
+
+    hvm_funcs.event_injection_faulted = svm_event_injection_faulted;
 
     hvm_enable();
 
diff -r 202eb735b425 -r 6510cb03aae1 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Feb 23 10:38:33 2007 +0000
@@ -990,6 +990,16 @@ static void vmx_update_vtpr(struct vcpu 
     /* VMX doesn't have a V_TPR field */
 }
 
+static int vmx_event_injection_faulted(struct vcpu *v)
+{
+    unsigned int idtv_info_field;
+
+    ASSERT(v == current);
+
+    idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD);
+    return (idtv_info_field & INTR_INFO_VALID_MASK);
+}
+
 /* Setup HVM interfaces */
 static void vmx_setup_hvm_funcs(void)
 {
@@ -1025,6 +1035,8 @@ static void vmx_setup_hvm_funcs(void)
     hvm_funcs.init_ap_context = vmx_init_ap_context;
 
     hvm_funcs.init_hypercall_page = vmx_init_hypercall_page;
+
+    hvm_funcs.event_injection_faulted = vmx_event_injection_faulted;
 }
 
 int start_vmx(void)
diff -r 202eb735b425 -r 6510cb03aae1 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/arch/x86/mm/shadow/common.c   Fri Feb 23 10:38:33 2007 +0000
@@ -274,6 +274,10 @@ hvm_emulate_write(enum x86_segment seg,
     struct vcpu *v = current;
     unsigned long addr;
     int rc;
+
+    /* How many emulations could we save if we unshadowed on stack writes? */
+    if ( seg == x86_seg_ss )
+        perfc_incrc(shadow_fault_emulate_stack);
 
     rc = hvm_translate_linear_addr(
         seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
diff -r 202eb735b425 -r 6510cb03aae1 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/arch/x86/mm/shadow/multi.c    Fri Feb 23 10:38:33 2007 +0000
@@ -2901,8 +2901,28 @@ static int sh_page_fault(struct vcpu *v,
         goto not_a_shadow_fault;
 
     if ( is_hvm_domain(d) )
+    {
+        /*
+         * If we are in the middle of injecting an exception or interrupt then
+         * we should not emulate: it is not the instruction at %eip that caused
+         * the fault. Furthermore it is almost certainly the case the handler
+         * stack is currently considered to be a page table, so we should
+         * unshadow the faulting page before exiting.
+         */
+        if ( unlikely(hvm_event_injection_faulted(v)) )
+        {
+            gdprintk(XENLOG_DEBUG, "write to pagetable during event "
+                     "injection: cr2=%#lx, mfn=%#lx\n", 
+                     va, mfn_x(gmfn));
+            sh_remove_shadows(v, gmfn, 0 /* thorough */, 1 /* must succeed */);
+            goto done;
+        }
+
         hvm_store_cpu_guest_regs(v, regs, NULL);
-    SHADOW_PRINTK("emulate: eip=%#lx\n", (unsigned long)regs->eip);
+    }
+
+    SHADOW_PRINTK("emulate: eip=%#lx esp=%#lx\n", 
+                  (unsigned long)regs->eip, (unsigned long)regs->esp);
 
     emul_ops = shadow_init_emulation(&emul_ctxt, regs);
 
diff -r 202eb735b425 -r 6510cb03aae1 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/arch/x86/setup.c      Fri Feb 23 10:38:33 2007 +0000
@@ -476,7 +476,7 @@ void __init __start_xen(multiboot_info_t
             s = initial_images_end;
         init_boot_pages(s, e);
 
-#if defined (CONFIG_X86_64)
+#if defined(CONFIG_X86_64)
         /*
          * x86/64 maps all registered RAM. Points to note:
          *  1. The initial pagetable already maps low 1GB, so skip that.
@@ -508,7 +508,6 @@ void __init __start_xen(multiboot_info_t
         unsigned long kdump_start, kdump_size, k;
 
         /* Mark images pages as free for now. */
-
         init_boot_pages(initial_images_start, initial_images_end);
 
         kdump_start = kexec_crash_area.start;
@@ -526,17 +525,19 @@ void __init __start_xen(multiboot_info_t
         kdump_size >>= PAGE_SHIFT;
 
         /* Allocate pages for Kdump memory area. */
-
-        k = alloc_boot_pages_at(kdump_size, kdump_start);
-        if ( k != kdump_start )
+        if ( !reserve_boot_pages(kdump_start, kdump_size) )
             panic("Unable to reserve Kdump memory\n");
 
         /* Allocate pages for relocated initial images. */
-
         k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0;
         k += (initial_images_end - initial_images_start) >> PAGE_SHIFT;
 
+#if defined(CONFIG_X86_32)
+        /* Must allocate within bootstrap 1:1 limits. */
+        k = alloc_boot_low_pages(k, 1); /* 0x0 - HYPERVISOR_VIRT_START */
+#else
         k = alloc_boot_pages(k, 1);
+#endif
         if ( k == 0 )
             panic("Unable to allocate initial images memory\n");
 
diff -r 202eb735b425 -r 6510cb03aae1 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/arch/x86/x86_64/mm.c  Fri Feb 23 10:38:33 2007 +0000
@@ -44,7 +44,8 @@ struct page_info *alloc_xen_pagetable(vo
     if ( !early_boot )
         return alloc_domheap_page(NULL);
 
-    pfn = alloc_boot_pages(1, 1);
+    /* Early pagetables must come from low 1GB of memory. */
+    pfn = alloc_boot_low_pages(1, 1); /* 0x0 - 0x40000000 */
     return ((pfn == 0) ? NULL : mfn_to_page(pfn));
 }
 
diff -r 202eb735b425 -r 6510cb03aae1 xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/common/page_alloc.c   Fri Feb 23 10:38:33 2007 +0000
@@ -95,9 +95,10 @@ static unsigned long *alloc_bitmap;
 static unsigned long *alloc_bitmap;
 #define PAGES_PER_MAPWORD (sizeof(unsigned long) * 8)
 
-#define allocated_in_map(_pn)                 \
-( !! (alloc_bitmap[(_pn)/PAGES_PER_MAPWORD] & \
-     (1UL<<((_pn)&(PAGES_PER_MAPWORD-1)))) )
+#define allocated_in_map(_pn)                       \
+({  unsigned long ___pn = (_pn);                    \
+    !!(alloc_bitmap[___pn/PAGES_PER_MAPWORD] &      \
+       (1UL<<(___pn&(PAGES_PER_MAPWORD-1)))); })
 
 /*
  * Hint regarding bitwise arithmetic in map_{alloc,free}:
@@ -240,36 +241,65 @@ void init_boot_pages(paddr_t ps, paddr_t
     }
 }
 
-unsigned long alloc_boot_pages_at(unsigned long nr_pfns, unsigned long pfn_at)
+int reserve_boot_pages(unsigned long first_pfn, unsigned long nr_pfns)
 {
     unsigned long i;
 
     for ( i = 0; i < nr_pfns; i++ )
-        if ( allocated_in_map(pfn_at + i) )
+        if ( allocated_in_map(first_pfn + i) )
              break;
 
-    if ( i == nr_pfns )
-    {
-        map_alloc(pfn_at, nr_pfns);
-        return pfn_at;
+    if ( i != nr_pfns )
+        return 0;
+
+    map_alloc(first_pfn, nr_pfns);
+    return 1;
+}
+
+unsigned long alloc_boot_low_pages(
+    unsigned long nr_pfns, unsigned long pfn_align)
+{
+    unsigned long pg, i;
+
+    /* Search forwards to obtain lowest available range. */
+    for ( pg = first_valid_mfn & ~(pfn_align-1);
+          (pg + nr_pfns) < max_page;
+          pg = (pg + i + pfn_align - 1) & ~(pfn_align - 1) )
+    {
+        for ( i = 0; i < nr_pfns; i++ )
+            if ( allocated_in_map(pg+i) )
+                break;
+        if ( i == nr_pfns )
+        {
+            map_alloc(pg, nr_pfns);
+            return pg;
+        }
     }
 
     return 0;
 }
 
-unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align)
-{
-    unsigned long pg;
-
-    pg = first_valid_mfn & ~(pfn_align-1);
-    while ( (pg + nr_pfns) < max_page )
-    {
-        if ( alloc_boot_pages_at(nr_pfns, pg) != 0 )
-            break;
-        pg += pfn_align;
-    }
-
-    return pg;
+unsigned long alloc_boot_pages(
+    unsigned long nr_pfns, unsigned long pfn_align)
+{
+    unsigned long pg, i;
+
+    /* Search backwards to obtain highest available range. */
+    for ( pg = (max_page - nr_pfns) & ~(pfn_align - 1);
+          pg >= first_valid_mfn;
+          pg = (pg + i - nr_pfns) & ~(pfn_align - 1) )
+    {
+        for ( i = 0; i < nr_pfns; i++ )
+            if ( allocated_in_map(pg+i) )
+                break;
+        if ( i == nr_pfns )
+        {
+            map_alloc(pg, nr_pfns);
+            return pg;
+        }
+    }
+
+    return 0;
 }
 
 
diff -r 202eb735b425 -r 6510cb03aae1 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/include/asm-x86/hvm/hvm.h     Fri Feb 23 10:38:33 2007 +0000
@@ -134,6 +134,8 @@ struct hvm_function_table {
                             int vcpuid, int trampoline_vector);
 
     void (*init_hypercall_page)(struct domain *d, void *hypercall_page);
+
+    int  (*event_injection_faulted)(struct vcpu *v);
 };
 
 extern struct hvm_function_table hvm_funcs;
@@ -262,4 +264,9 @@ hvm_inject_exception(unsigned int trapnr
 
 int hvm_bringup_ap(int vcpuid, int trampoline_vector);
 
+static inline int hvm_event_injection_faulted(struct vcpu *v)
+{
+    return hvm_funcs.event_injection_faulted(v);
+}
+
 #endif /* __ASM_X86_HVM_HVM_H__ */
diff -r 202eb735b425 -r 6510cb03aae1 xen/include/asm-x86/perfc_defn.h
--- a/xen/include/asm-x86/perfc_defn.h  Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/include/asm-x86/perfc_defn.h  Fri Feb 23 10:38:33 2007 +0000
@@ -56,6 +56,7 @@ PERFCOUNTER_CPU(shadow_fault_emulate_rea
 PERFCOUNTER_CPU(shadow_fault_emulate_read, "shadow_fault emulates a read")
 PERFCOUNTER_CPU(shadow_fault_emulate_write, "shadow_fault emulates a write")
 PERFCOUNTER_CPU(shadow_fault_emulate_failed, "shadow_fault emulator fails")
+PERFCOUNTER_CPU(shadow_fault_emulate_stack, "shadow_fault emulate stack write")
 PERFCOUNTER_CPU(shadow_fault_mmio,     "shadow_fault handled as mmio")
 PERFCOUNTER_CPU(shadow_fault_fixed,    "shadow_fault fixed fault")
 PERFCOUNTER_CPU(shadow_ptwr_emulate,   "shadow causes ptwr to emulate")
diff -r 202eb735b425 -r 6510cb03aae1 xen/include/xen/mm.h
--- a/xen/include/xen/mm.h      Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/include/xen/mm.h      Fri Feb 23 10:38:33 2007 +0000
@@ -39,8 +39,11 @@ struct page_info;
 /* Boot-time allocator. Turns into generic allocator after bootstrap. */
 paddr_t init_boot_allocator(paddr_t bitmap_start);
 void init_boot_pages(paddr_t ps, paddr_t pe);
-unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align);
-unsigned long alloc_boot_pages_at(unsigned long nr_pfns, unsigned long pfn_at);
+unsigned long alloc_boot_pages(
+    unsigned long nr_pfns, unsigned long pfn_align);
+unsigned long alloc_boot_low_pages(
+    unsigned long nr_pfns, unsigned long pfn_align);
+int reserve_boot_pages(unsigned long first_pfn, unsigned long nr_pfns);
 void end_boot_allocator(void);
 
 /* Generic allocator. These functions are *not* interrupt-safe. */
diff -r 202eb735b425 -r 6510cb03aae1 xen/include/xen/perfc.h
--- a/xen/include/xen/perfc.h   Thu Feb 22 10:15:29 2007 -0700
+++ b/xen/include/xen/perfc.h   Fri Feb 23 10:38:33 2007 +0000
@@ -5,6 +5,7 @@
 #ifdef PERF_COUNTERS
 
 #include <xen/lib.h>
+#include <xen/smp.h>
 #include <asm/atomic.h>
 
 /* 

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


 


Rackspace

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