WARNING - OLD ARCHIVES

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

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 23 Feb 2007 09:50:34 -0800
Delivery-date: Fri, 23 Feb 2007 09:51:42 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User 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

<Prev in Thread] Current Thread [Next in Thread>