Merge remote-tracking branch 'qemu-kvm/memory/exec-obsolete' into staging
diff --git a/Makefile.target b/Makefile.target
index 8be9b9a..3261383 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -92,12 +92,6 @@
 
 $(libobj-y): $(GENERATED_HEADERS)
 
-translate.o: translate.c cpu.h
-
-translate-all.o: translate-all.c cpu.h
-
-tcg/tcg.o: cpu.h
-
 # HELPER_CFLAGS is used for all the code compiled with static register
 # variables
 op_helper.o ldst_helper.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/block-migration.c b/block-migration.c
index 423c5a0..2b7edbc 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -251,22 +251,12 @@
 
     blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov,
                                 nr_sectors, blk_mig_read_cb, blk);
-    if (!blk->aiocb) {
-        goto error;
-    }
     block_mig_state.submitted++;
 
     bdrv_reset_dirty(bs, cur_sector, nr_sectors);
     bmds->cur_sector = cur_sector + nr_sectors;
 
     return (bmds->cur_sector >= total_sectors);
-
-error:
-    monitor_printf(mon, "Error reading sector %" PRId64 "\n", cur_sector);
-    qemu_file_set_error(f, -EIO);
-    g_free(blk->buf);
-    g_free(blk);
-    return 0;
 }
 
 static void set_dirty_tracking(int enable)
@@ -413,9 +403,6 @@
 
                 blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov,
                                             nr_sectors, blk_mig_read_cb, blk);
-                if (!blk->aiocb) {
-                    goto error;
-                }
                 block_mig_state.submitted++;
                 bmds_set_aio_inflight(bmds, sector, nr_sectors, 1);
             } else {
diff --git a/block.c b/block.c
index aa9d142..3f072f6 100644
--- a/block.c
+++ b/block.c
@@ -2812,7 +2812,6 @@
  */
 int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
 {
-    BlockDriverAIOCB *acb;
     MultiwriteCB *mcb;
     int i;
 
@@ -2843,59 +2842,14 @@
 
     trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs);
 
-    /*
-     * Run the aio requests. As soon as one request can't be submitted
-     * successfully, fail all requests that are not yet submitted (we must
-     * return failure for all requests anyway)
-     *
-     * num_requests cannot be set to the right value immediately: If
-     * bdrv_aio_writev fails for some request, num_requests would be too high
-     * and therefore multiwrite_cb() would never recognize the multiwrite
-     * request as completed. We also cannot use the loop variable i to set it
-     * when the first request fails because the callback may already have been
-     * called for previously submitted requests. Thus, num_requests must be
-     * incremented for each request that is submitted.
-     *
-     * The problem that callbacks may be called early also means that we need
-     * to take care that num_requests doesn't become 0 before all requests are
-     * submitted - multiwrite_cb() would consider the multiwrite request
-     * completed. A dummy request that is "completed" by a manual call to
-     * multiwrite_cb() takes care of this.
-     */
-    mcb->num_requests = 1;
-
-    // Run the aio requests
+    /* Run the aio requests. */
+    mcb->num_requests = num_reqs;
     for (i = 0; i < num_reqs; i++) {
-        mcb->num_requests++;
-        acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
+        bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
             reqs[i].nb_sectors, multiwrite_cb, mcb);
-
-        if (acb == NULL) {
-            // We can only fail the whole thing if no request has been
-            // submitted yet. Otherwise we'll wait for the submitted AIOs to
-            // complete and report the error in the callback.
-            if (i == 0) {
-                trace_bdrv_aio_multiwrite_earlyfail(mcb);
-                goto fail;
-            } else {
-                trace_bdrv_aio_multiwrite_latefail(mcb, i);
-                multiwrite_cb(mcb, -EIO);
-                break;
-            }
-        }
     }
 
-    /* Complete the dummy request */
-    multiwrite_cb(mcb, 0);
-
     return 0;
-
-fail:
-    for (i = 0; i < mcb->num_callbacks; i++) {
-        reqs[i].error = -EIO;
-    }
-    g_free(mcb);
-    return -1;
 }
 
 void bdrv_aio_cancel(BlockDriverAIOCB *acb)
@@ -3123,9 +3077,7 @@
     acb->is_write = is_write;
     acb->qiov = qiov;
     acb->bounce = qemu_blockalign(bs, qiov->size);
-
-    if (!acb->bh)
-        acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
+    acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
 
     if (is_write) {
         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
diff --git a/block.h b/block.h
index 0e3ff9f..3bd4398 100644
--- a/block.h
+++ b/block.h
@@ -22,7 +22,7 @@
     /* the following fields are informative. They are not needed for
        the consistency of the snapshot */
     char name[256]; /* user chosen name */
-    uint32_t vm_state_size; /* VM state info size */
+    uint64_t vm_state_size; /* VM state info size */
     uint32_t date_sec; /* UTC date of the snapshot */
     uint32_t date_nsec;
     uint64_t vm_clock_nsec; /* VM clock relative to boot */
diff --git a/block/blkverify.c b/block/blkverify.c
index 483f3b3..4ca8584 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -310,14 +310,10 @@
     qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov);
     blkverify_iovec_clone(&acb->raw_qiov, qiov, acb->buf);
 
-    if (!bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors,
-                        blkverify_aio_cb, acb)) {
-        blkverify_aio_cb(acb, -EIO);
-    }
-    if (!bdrv_aio_readv(bs->file, sector_num, &acb->raw_qiov, nb_sectors,
-                        blkverify_aio_cb, acb)) {
-        blkverify_aio_cb(acb, -EIO);
-    }
+    bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors,
+                   blkverify_aio_cb, acb);
+    bdrv_aio_readv(bs->file, sector_num, &acb->raw_qiov, nb_sectors,
+                   blkverify_aio_cb, acb);
     return &acb->common;
 }
 
@@ -329,14 +325,10 @@
     BlkverifyAIOCB *acb = blkverify_aio_get(bs, true, sector_num, qiov,
                                             nb_sectors, cb, opaque);
 
-    if (!bdrv_aio_writev(s->test_file, sector_num, qiov, nb_sectors,
-                         blkverify_aio_cb, acb)) {
-        blkverify_aio_cb(acb, -EIO);
-    }
-    if (!bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors,
-                         blkverify_aio_cb, acb)) {
-        blkverify_aio_cb(acb, -EIO);
-    }
+    bdrv_aio_writev(s->test_file, sector_num, qiov, nb_sectors,
+                    blkverify_aio_cb, acb);
+    bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors,
+                    blkverify_aio_cb, acb);
     return &acb->common;
 }
 
diff --git a/block/cow.c b/block/cow.c
index 3c52735..bb5927c 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -64,15 +64,26 @@
     struct cow_header_v2 cow_header;
     int bitmap_size;
     int64_t size;
+    int ret;
 
     /* see if it is a cow image */
-    if (bdrv_pread(bs->file, 0, &cow_header, sizeof(cow_header)) !=
-            sizeof(cow_header)) {
+    ret = bdrv_pread(bs->file, 0, &cow_header, sizeof(cow_header));
+    if (ret < 0) {
         goto fail;
     }
 
-    if (be32_to_cpu(cow_header.magic) != COW_MAGIC ||
-        be32_to_cpu(cow_header.version) != COW_VERSION) {
+    if (be32_to_cpu(cow_header.magic) != COW_MAGIC) {
+        ret = -EINVAL;
+        goto fail;
+    }
+
+    if (be32_to_cpu(cow_header.version) != COW_VERSION) {
+        char version[64];
+        snprintf(version, sizeof(version),
+               "COW version %d", cow_header.version);
+        qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
+            bs->device_name, "cow", version);
+        ret = -ENOTSUP;
         goto fail;
     }
 
@@ -88,7 +99,7 @@
     qemu_co_mutex_init(&s->lock);
     return 0;
  fail:
-    return -1;
+    return ret;
 }
 
 /*
@@ -182,17 +193,19 @@
             ret = bdrv_pread(bs->file,
                         s->cow_sectors_offset + sector_num * 512,
                         buf, n * 512);
-            if (ret != n * 512)
-                return -1;
+            if (ret < 0) {
+                return ret;
+            }
         } else {
             if (bs->backing_hd) {
                 /* read from the base image */
                 ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
-                if (ret < 0)
-                    return -1;
+                if (ret < 0) {
+                    return ret;
+                }
             } else {
-            memset(buf, 0, n * 512);
-        }
+                memset(buf, 0, n * 512);
+            }
         }
         nb_sectors -= n;
         sector_num += n;
@@ -220,8 +233,9 @@
 
     ret = bdrv_pwrite(bs->file, s->cow_sectors_offset + sector_num * 512,
                       buf, nb_sectors * 512);
-    if (ret != nb_sectors * 512)
-        return -1;
+    if (ret < 0) {
+        return ret;
+    }
 
     return cow_update_bitmap(bs, sector_num, nb_sectors);
 }
@@ -288,14 +302,14 @@
     cow_header.sectorsize = cpu_to_be32(512);
     cow_header.size = cpu_to_be64(image_sectors * 512);
     ret = bdrv_pwrite(cow_bs, 0, &cow_header, sizeof(cow_header));
-    if (ret != sizeof(cow_header)) {
+    if (ret < 0) {
         goto exit;
     }
 
     /* resize to include at least all the bitmap */
     ret = bdrv_truncate(cow_bs,
         sizeof(cow_header) + ((image_sectors + 7) >> 3));
-    if (ret) {
+    if (ret < 0) {
         goto exit;
     }
 
diff --git a/block/curl.c b/block/curl.c
index 4209ac8..e9102e3 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -509,10 +509,6 @@
 
     acb = qemu_aio_get(&curl_aio_pool, bs, cb, opaque);
 
-    if (!acb) {
-        return NULL;
-    }
-
     acb->qiov = qiov;
     acb->sector_num = sector_num;
     acb->nb_sectors = nb_sectors;
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index c3112bf..7d3fde5 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -46,6 +46,10 @@
     /* name follows  */
 } QCowSnapshotHeader;
 
+typedef struct QEMU_PACKED QCowSnapshotExtraData {
+    uint64_t vm_state_size_large;
+} QCowSnapshotExtraData;
+
 void qcow2_free_snapshots(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
@@ -64,6 +68,7 @@
 {
     BDRVQcowState *s = bs->opaque;
     QCowSnapshotHeader h;
+    QCowSnapshotExtraData extra;
     QCowSnapshot *sn;
     int i, id_str_size, name_size;
     int64_t offset;
@@ -100,9 +105,18 @@
         id_str_size = be16_to_cpu(h.id_str_size);
         name_size = be16_to_cpu(h.name_size);
 
-        /* Skip extra data */
+        /* Read extra data */
+        ret = bdrv_pread(bs->file, offset, &extra,
+                         MIN(sizeof(extra), extra_data_size));
+        if (ret < 0) {
+            goto fail;
+        }
         offset += extra_data_size;
 
+        if (extra_data_size >= 8) {
+            sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large);
+        }
+
         /* Read snapshot ID */
         sn->id_str = g_malloc(id_str_size + 1);
         ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size);
@@ -136,6 +150,7 @@
     BDRVQcowState *s = bs->opaque;
     QCowSnapshot *sn;
     QCowSnapshotHeader h;
+    QCowSnapshotExtraData extra;
     int i, name_size, id_str_size, snapshots_size;
     struct {
         uint32_t nb_snapshots;
@@ -150,6 +165,7 @@
         sn = s->snapshots + i;
         offset = align_offset(offset, 8);
         offset += sizeof(h);
+        offset += sizeof(extra);
         offset += strlen(sn->id_str);
         offset += strlen(sn->name);
     }
@@ -169,10 +185,18 @@
         memset(&h, 0, sizeof(h));
         h.l1_table_offset = cpu_to_be64(sn->l1_table_offset);
         h.l1_size = cpu_to_be32(sn->l1_size);
-        h.vm_state_size = cpu_to_be32(sn->vm_state_size);
+        /* If it doesn't fit in 32 bit, older implementations should treat it
+         * as a disk-only snapshot rather than truncate the VM state */
+        if (sn->vm_state_size <= 0xffffffff) {
+            h.vm_state_size = cpu_to_be32(sn->vm_state_size);
+        }
         h.date_sec = cpu_to_be32(sn->date_sec);
         h.date_nsec = cpu_to_be32(sn->date_nsec);
         h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec);
+        h.extra_data_size = cpu_to_be32(sizeof(extra));
+
+        memset(&extra, 0, sizeof(extra));
+        extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size);
 
         id_str_size = strlen(sn->id_str);
         name_size = strlen(sn->name);
@@ -186,6 +210,12 @@
         }
         offset += sizeof(h);
 
+        ret = bdrv_pwrite(bs->file, offset, &extra, sizeof(extra));
+        if (ret < 0) {
+            goto fail;
+        }
+        offset += sizeof(extra);
+
         ret = bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size);
         if (ret < 0) {
             goto fail;
diff --git a/block/qcow2.c b/block/qcow2.c
index 37cd442..aa32e8d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -635,6 +635,7 @@
     g_free(s->cluster_cache);
     qemu_vfree(s->cluster_data);
     qcow2_refcount_close(bs);
+    qcow2_free_snapshots(bs);
 }
 
 static void qcow2_invalidate_cache(BlockDriverState *bs)
diff --git a/block/qcow2.h b/block/qcow2.h
index 4e44eea..99e4536 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -78,7 +78,7 @@
     uint32_t l1_size;
     char *id_str;
     char *name;
-    uint32_t vm_state_size;
+    uint64_t vm_state_size;
     uint32_t date_sec;
     uint32_t date_nsec;
     uint64_t vm_clock_nsec;
diff --git a/block/qed-table.c b/block/qed-table.c
index 8ee8443..ce07b05 100644
--- a/block/qed-table.c
+++ b/block/qed-table.c
@@ -54,7 +54,6 @@
     QEDReadTableCB *read_table_cb = gencb_alloc(sizeof(*read_table_cb),
                                                 cb, opaque);
     QEMUIOVector *qiov = &read_table_cb->qiov;
-    BlockDriverAIOCB *aiocb;
 
     trace_qed_read_table(s, offset, table);
 
@@ -64,12 +63,9 @@
     read_table_cb->iov.iov_len = s->header.cluster_size * s->header.table_size,
 
     qemu_iovec_init_external(qiov, &read_table_cb->iov, 1);
-    aiocb = bdrv_aio_readv(s->bs->file, offset / BDRV_SECTOR_SIZE, qiov,
-                           qiov->size / BDRV_SECTOR_SIZE,
-                           qed_read_table_cb, read_table_cb);
-    if (!aiocb) {
-        qed_read_table_cb(read_table_cb, -EIO);
-    }
+    bdrv_aio_readv(s->bs->file, offset / BDRV_SECTOR_SIZE, qiov,
+                   qiov->size / BDRV_SECTOR_SIZE,
+                   qed_read_table_cb, read_table_cb);
 }
 
 typedef struct {
@@ -127,7 +123,6 @@
                             BlockDriverCompletionFunc *cb, void *opaque)
 {
     QEDWriteTableCB *write_table_cb;
-    BlockDriverAIOCB *aiocb;
     unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
     unsigned int start, end, i;
     size_t len_bytes;
@@ -158,13 +153,10 @@
     /* Adjust for offset into table */
     offset += start * sizeof(uint64_t);
 
-    aiocb = bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
-                            &write_table_cb->qiov,
-                            write_table_cb->qiov.size / BDRV_SECTOR_SIZE,
-                            qed_write_table_cb, write_table_cb);
-    if (!aiocb) {
-        qed_write_table_cb(write_table_cb, -EIO);
-    }
+    bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
+                    &write_table_cb->qiov,
+                    write_table_cb->qiov.size / BDRV_SECTOR_SIZE,
+                    qed_write_table_cb, write_table_cb);
 }
 
 /**
diff --git a/block/qed.c b/block/qed.c
index 22e4672..8da3ebe 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -123,7 +123,6 @@
 {
     QEDWriteHeaderCB *write_header_cb = opaque;
     BDRVQEDState *s = write_header_cb->s;
-    BlockDriverAIOCB *acb;
 
     if (ret) {
         qed_write_header_cb(write_header_cb, ret);
@@ -133,12 +132,9 @@
     /* Update header */
     qed_header_cpu_to_le(&s->header, (QEDHeader *)write_header_cb->buf);
 
-    acb = bdrv_aio_writev(s->bs->file, 0, &write_header_cb->qiov,
-                          write_header_cb->nsectors, qed_write_header_cb,
-                          write_header_cb);
-    if (!acb) {
-        qed_write_header_cb(write_header_cb, -EIO);
-    }
+    bdrv_aio_writev(s->bs->file, 0, &write_header_cb->qiov,
+                    write_header_cb->nsectors, qed_write_header_cb,
+                    write_header_cb);
 }
 
 /**
@@ -156,7 +152,6 @@
      * them, and write back.
      */
 
-    BlockDriverAIOCB *acb;
     int nsectors = (sizeof(QEDHeader) + BDRV_SECTOR_SIZE - 1) /
                    BDRV_SECTOR_SIZE;
     size_t len = nsectors * BDRV_SECTOR_SIZE;
@@ -170,11 +165,8 @@
     write_header_cb->iov.iov_len = len;
     qemu_iovec_init_external(&write_header_cb->qiov, &write_header_cb->iov, 1);
 
-    acb = bdrv_aio_readv(s->bs->file, 0, &write_header_cb->qiov, nsectors,
-                         qed_write_header_read_cb, write_header_cb);
-    if (!acb) {
-        qed_write_header_cb(write_header_cb, -EIO);
-    }
+    bdrv_aio_readv(s->bs->file, 0, &write_header_cb->qiov, nsectors,
+                   qed_write_header_read_cb, write_header_cb);
 }
 
 static uint64_t qed_max_image_size(uint32_t cluster_size, uint32_t table_size)
@@ -728,7 +720,6 @@
                                   QEMUIOVector *qiov,
                                   BlockDriverCompletionFunc *cb, void *opaque)
 {
-    BlockDriverAIOCB *aiocb;
     uint64_t backing_length = 0;
     size_t size;
 
@@ -760,11 +751,8 @@
     size = MIN((uint64_t)backing_length - pos, qiov->size);
 
     BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING);
-    aiocb = bdrv_aio_readv(s->bs->backing_hd, pos / BDRV_SECTOR_SIZE,
-                           qiov, size / BDRV_SECTOR_SIZE, cb, opaque);
-    if (!aiocb) {
-        cb(opaque, -EIO);
-    }
+    bdrv_aio_readv(s->bs->backing_hd, pos / BDRV_SECTOR_SIZE,
+                   qiov, size / BDRV_SECTOR_SIZE, cb, opaque);
 }
 
 typedef struct {
@@ -786,7 +774,6 @@
 {
     CopyFromBackingFileCB *copy_cb = opaque;
     BDRVQEDState *s = copy_cb->s;
-    BlockDriverAIOCB *aiocb;
 
     if (ret) {
         qed_copy_from_backing_file_cb(copy_cb, ret);
@@ -794,13 +781,9 @@
     }
 
     BLKDBG_EVENT(s->bs->file, BLKDBG_COW_WRITE);
-    aiocb = bdrv_aio_writev(s->bs->file, copy_cb->offset / BDRV_SECTOR_SIZE,
-                            &copy_cb->qiov,
-                            copy_cb->qiov.size / BDRV_SECTOR_SIZE,
-                            qed_copy_from_backing_file_cb, copy_cb);
-    if (!aiocb) {
-        qed_copy_from_backing_file_cb(copy_cb, -EIO);
-    }
+    bdrv_aio_writev(s->bs->file, copy_cb->offset / BDRV_SECTOR_SIZE,
+                    &copy_cb->qiov, copy_cb->qiov.size / BDRV_SECTOR_SIZE,
+                    qed_copy_from_backing_file_cb, copy_cb);
 }
 
 /**
@@ -1022,7 +1005,6 @@
     uint64_t offset = acb->cur_cluster +
                       qed_offset_into_cluster(s, acb->cur_pos);
     BlockDriverCompletionFunc *next_fn;
-    BlockDriverAIOCB *file_acb;
 
     trace_qed_aio_write_main(s, acb, ret, offset, acb->cur_qiov.size);
 
@@ -1042,13 +1024,9 @@
     }
 
     BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO);
-    file_acb = bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
-                               &acb->cur_qiov,
-                               acb->cur_qiov.size / BDRV_SECTOR_SIZE,
-                               next_fn, acb);
-    if (!file_acb) {
-        qed_aio_complete(acb, -EIO);
-    }
+    bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
+                    &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE,
+                    next_fn, acb);
 }
 
 /**
@@ -1215,7 +1193,6 @@
     QEDAIOCB *acb = opaque;
     BDRVQEDState *s = acb_to_s(acb);
     BlockDriverState *bs = acb->common.bs;
-    BlockDriverAIOCB *file_acb;
 
     /* Adjust offset into cluster */
     offset += qed_offset_into_cluster(s, acb->cur_pos);
@@ -1240,14 +1217,9 @@
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
-    file_acb = bdrv_aio_readv(bs->file, offset / BDRV_SECTOR_SIZE,
-                              &acb->cur_qiov,
-                              acb->cur_qiov.size / BDRV_SECTOR_SIZE,
-                              qed_aio_next_io, acb);
-    if (!file_acb) {
-        ret = -EIO;
-        goto err;
-    }
+    bdrv_aio_readv(bs->file, offset / BDRV_SECTOR_SIZE,
+                   &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE,
+                   qed_aio_next_io, acb);
     return;
 
 err:
diff --git a/block/rbd.c b/block/rbd.c
index 9088c52..7a2384c 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -632,9 +632,6 @@
     BDRVRBDState *s = bs->opaque;
 
     acb = qemu_aio_get(&rbd_aio_pool, bs, cb, opaque);
-    if (!acb) {
-        return NULL;
-    }
     acb->write = write;
     acb->qiov = qiov;
     acb->bounce = qemu_blockalign(bs, qiov->size);
@@ -808,7 +805,7 @@
     } while (snap_count == -ERANGE);
 
     if (snap_count <= 0) {
-        return snap_count;
+        goto done;
     }
 
     sn_tab = g_malloc0(snap_count * sizeof(QEMUSnapshotInfo));
@@ -827,6 +824,7 @@
     }
     rbd_snap_list_end(snaps);
 
+ done:
     *psn_tab = sn_tab;
     return snap_count;
 }
diff --git a/block/vdi.c b/block/vdi.c
index e1d8cff..31cdfab 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -515,28 +515,26 @@
            bs, sector_num, qiov, nb_sectors, cb, opaque, is_write);
 
     acb = qemu_aio_get(&vdi_aio_pool, bs, cb, opaque);
-    if (acb) {
-        acb->hd_aiocb = NULL;
-        acb->sector_num = sector_num;
-        acb->qiov = qiov;
-        acb->is_write = is_write;
+    acb->hd_aiocb = NULL;
+    acb->sector_num = sector_num;
+    acb->qiov = qiov;
+    acb->is_write = is_write;
 
-        if (qiov->niov > 1) {
-            acb->buf = qemu_blockalign(bs, qiov->size);
-            acb->orig_buf = acb->buf;
-            if (is_write) {
-                qemu_iovec_to_buffer(qiov, acb->buf);
-            }
-        } else {
-            acb->buf = (uint8_t *)qiov->iov->iov_base;
+    if (qiov->niov > 1) {
+        acb->buf = qemu_blockalign(bs, qiov->size);
+        acb->orig_buf = acb->buf;
+        if (is_write) {
+            qemu_iovec_to_buffer(qiov, acb->buf);
         }
-        acb->nb_sectors = nb_sectors;
-        acb->n_sectors = 0;
-        acb->bmap_first = VDI_UNALLOCATED;
-        acb->bmap_last = VDI_UNALLOCATED;
-        acb->block_buffer = NULL;
-        acb->header_modified = 0;
+    } else {
+        acb->buf = (uint8_t *)qiov->iov->iov_base;
     }
+    acb->nb_sectors = nb_sectors;
+    acb->n_sectors = 0;
+    acb->bmap_first = VDI_UNALLOCATED;
+    acb->bmap_last = VDI_UNALLOCATED;
+    acb->block_buffer = NULL;
+    acb->header_modified = 0;
     return acb;
 }
 
@@ -633,10 +631,6 @@
         qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
         acb->hd_aiocb = bdrv_aio_readv(bs->file, offset, &acb->hd_qiov,
                                        n_sectors, vdi_aio_read_cb, acb);
-        if (acb->hd_aiocb == NULL) {
-            ret = -EIO;
-            goto done;
-        }
     }
     return;
 done:
@@ -657,10 +651,6 @@
 
     logout("\n");
     acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
-    if (!acb) {
-        return NULL;
-    }
-
     ret = vdi_schedule_bh(vdi_aio_rw_bh, acb);
     if (ret < 0) {
         if (acb->qiov->niov > 1) {
@@ -708,10 +698,6 @@
             qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
             acb->hd_aiocb = bdrv_aio_writev(bs->file, 0, &acb->hd_qiov, 1,
                                             vdi_aio_write_cb, acb);
-            if (acb->hd_aiocb == NULL) {
-                ret = -EIO;
-                goto done;
-            }
             return;
         } else if (VDI_IS_ALLOCATED(acb->bmap_first)) {
             /* One or more new blocks were allocated. */
@@ -738,10 +724,6 @@
                    n_sectors, bmap_first);
             acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov,
                                             n_sectors, vdi_aio_write_cb, acb);
-            if (acb->hd_aiocb == NULL) {
-                ret = -EIO;
-                goto done;
-            }
             return;
         }
         ret = 0;
@@ -789,10 +771,6 @@
         acb->hd_aiocb = bdrv_aio_writev(bs->file, offset,
                                         &acb->hd_qiov, s->block_sectors,
                                         vdi_aio_write_cb, acb);
-        if (acb->hd_aiocb == NULL) {
-            ret = -EIO;
-            goto done;
-        }
     } else {
         uint64_t offset = s->header.offset_data / SECTOR_SIZE +
                           (uint64_t)bmap_entry * s->block_sectors +
@@ -802,10 +780,6 @@
         qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
         acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov,
                                         n_sectors, vdi_aio_write_cb, acb);
-        if (acb->hd_aiocb == NULL) {
-            ret = -EIO;
-            goto done;
-        }
     }
 
     return;
@@ -827,10 +801,6 @@
 
     logout("\n");
     acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
-    if (!acb) {
-        return NULL;
-    }
-
     ret = vdi_schedule_bh(vdi_aio_rw_bh, acb);
     if (ret < 0) {
         if (acb->qiov->niov > 1) {
diff --git a/configure b/configure
index 6fd580e..640e815 100755
--- a/configure
+++ b/configure
@@ -1082,7 +1082,7 @@
 
 # check that the C compiler works.
 cat > $TMPC <<EOF
-int main(void) {}
+int main(void) { return 0; }
 EOF
 
 if compile_object ; then
@@ -1274,11 +1274,11 @@
   cat > $TMPC <<EOF
 #include <sched.h>
 #include <linux/futex.h>
-void foo()
-{
+int main(void) {
 #if !defined(CLONE_SETTLS) || !defined(FUTEX_WAIT)
 #error bork
 #endif
+  return 0;
 }
 EOF
 
@@ -1317,10 +1317,30 @@
 if test "$xen" != "no" ; then
   xen_libs="-lxenstore -lxenctrl -lxenguest"
 
-  # Xen unstable
+  # First we test whether Xen headers and libraries are available.
+  # If no, we are done and there is no Xen support.
+  # If yes, more tests are run to detect the Xen version.
+
+  # Xen (any)
   cat > $TMPC <<EOF
 #include <xenctrl.h>
 #include <xs.h>
+int main(void) {
+  return 0;
+}
+EOF
+  if ! compile_prog "" "$xen_libs" ; then
+    # Xen not found
+    if test "$xen" = "yes" ; then
+      feature_not_found "xen"
+    fi
+    xen=no
+
+  # Xen unstable
+  elif (
+      cat > $TMPC <<EOF
+#include <xenctrl.h>
+#include <xs.h>
 #include <stdint.h>
 #include <xen/hvm/hvm_info_table.h>
 #if !defined(HVM_MAX_VCPUS)
@@ -1336,7 +1356,8 @@
   return 0;
 }
 EOF
-  if compile_prog "" "$xen_libs" ; then
+      compile_prog "" "$xen_libs"
+    ) ; then
     xen_ctrl_version=410
     xen=yes
 
@@ -1407,10 +1428,10 @@
     xen_ctrl_version=330
     xen=yes
 
-  # Xen not found or unsupported
+  # Xen version unsupported
   else
     if test "$xen" = "yes" ; then
-      feature_not_found "xen"
+      feature_not_found "xen (unsupported version)"
     fi
     xen=no
   fi
@@ -1670,6 +1691,7 @@
 # xfsctl() probe, used for raw-posix
 if test "$xfs" != "no" ; then
   cat > $TMPC << EOF
+#include <stddef.h>  /* NULL */
 #include <xfs/xfs.h>
 int main(void)
 {
@@ -1841,7 +1863,11 @@
 #ifdef __OpenBSD__
 #define resize_term resizeterm
 #endif
-int main(void) { resize_term(0, 0); return curses_version(); }
+int main(void) {
+  const char *s = curses_version();
+  resize_term(0, 0);
+  return s != 0;
+}
 EOF
   for curses_lib in $curses_list; do
     if compile_prog "" "$curses_lib" ; then
@@ -1947,7 +1973,12 @@
 pthread=no
 cat > $TMPC << EOF
 #include <pthread.h>
-int main(void) { pthread_create(0,0,0,0); return 0; }
+static void *f(void *p) { return NULL; }
+int main(void) {
+  pthread_t thread;
+  pthread_create(&thread, 0, f, 0);
+  return 0;
+}
 EOF
 if compile_prog "" "" ; then
   pthread=yes
@@ -2051,7 +2082,7 @@
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <unistd.h>
-int main(void) { struct iovec iov; return 0; }
+int main(void) { return sizeof(struct iovec); }
 EOF
 iovec=no
 if compile_prog "" "" ; then
@@ -2064,7 +2095,7 @@
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <unistd.h>
-int main(void) { preadv; }
+int main(void) { return preadv == preadv; }
 EOF
 preadv=no
 if compile_prog "" "" ; then
@@ -2097,7 +2128,7 @@
 #include <X11/Xlib.h>
 #include <GL/gl.h>
 #include <GL/glx.h>
-int main(void) { GL_VERSION; return 0; }
+int main(void) { return GL_VERSION != 0; }
 EOF
   if compile_prog "" "-lGL" ; then
     opengl=yes
@@ -2228,7 +2259,7 @@
 
 int main(void)
 {
-    int len, fd;
+    int len, fd = 0;
     len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
     splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
     return 0;
@@ -2242,7 +2273,6 @@
 # signalfd probe
 signalfd="no"
 cat > $TMPC << EOF
-#define _GNU_SOURCE
 #include <unistd.h>
 #include <sys/syscall.h>
 #include <signal.h>
@@ -2260,8 +2290,7 @@
 
 int main(void)
 {
-    int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-    return 0;
+    return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
 }
 EOF
 if compile_prog "" "" ; then
@@ -2361,8 +2390,7 @@
      * warning but not an error, and will proceed to fail the
      * qemu compile where we compile with -Werror.)
      */
-    epoll_create1;
-    return 0;
+    return epoll_create1 == epoll_create1;
 }
 EOF
 if compile_prog "$ARCH_CFLAGS" "" ; then
@@ -2441,7 +2469,7 @@
 cat > $TMPC <<EOF
 #include <signal.h>
 #include <time.h>
-int main(void) { clockid_t id; return clock_gettime(id, NULL); }
+int main(void) { return clock_gettime(CLOCK_REALTIME, NULL); }
 EOF
 
 if compile_prog "" "" ; then
@@ -2651,7 +2679,7 @@
 if test "$darwin" != "yes"; then
   cat > $TMPC << EOF
 #include <ucontext.h>
-int main(void) { makecontext(0, 0, 0); }
+int main(void) { makecontext(0, 0, 0); return 0; }
 EOF
   if compile_prog "" "" ; then
       ucontext_coroutine=yes
@@ -2664,7 +2692,7 @@
 open_by_hande_at=no
 cat > $TMPC << EOF
 #include <fcntl.h>
-int main(void) { struct file_handle fh; open_by_handle_at(0, &fh, 0); }
+int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
 EOF
 if compile_prog "" "" ; then
     open_by_handle_at=yes
@@ -2677,6 +2705,7 @@
 cat > $TMPC << EOF
 #include <linux/magic.h>
 int main(void) {
+  return 0;
 }
 EOF
 if compile_prog "" "" ; then
diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c
index 2b8d3e9..3d01075 100644
--- a/coroutine-ucontext.c
+++ b/coroutine-ucontext.c
@@ -35,6 +35,10 @@
     POOL_MAX_SIZE = 64,
 };
 
+/** Free list to speed up creation */
+static QLIST_HEAD(, Coroutine) pool = QLIST_HEAD_INITIALIZER(pool);
+static unsigned int pool_size;
+
 typedef struct {
     Coroutine base;
     void *stack;
@@ -48,10 +52,6 @@
     /** Currently executing coroutine */
     Coroutine *current;
 
-    /** Free list to speed up creation */
-    QLIST_HEAD(, Coroutine) pool;
-    unsigned int pool_size;
-
     /** The default coroutine */
     CoroutineUContext leader;
 } CoroutineThreadState;
@@ -75,7 +75,6 @@
     if (!s) {
         s = g_malloc0(sizeof(*s));
         s->current = &s->leader.base;
-        QLIST_INIT(&s->pool);
         pthread_setspecific(thread_state_key, s);
     }
     return s;
@@ -84,14 +83,19 @@
 static void qemu_coroutine_thread_cleanup(void *opaque)
 {
     CoroutineThreadState *s = opaque;
+
+    g_free(s);
+}
+
+static void __attribute__((destructor)) coroutine_cleanup(void)
+{
     Coroutine *co;
     Coroutine *tmp;
 
-    QLIST_FOREACH_SAFE(co, &s->pool, pool_next, tmp) {
+    QLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
         g_free(DO_UPCAST(CoroutineUContext, base, co)->stack);
         g_free(co);
     }
-    g_free(s);
 }
 
 static void __attribute__((constructor)) coroutine_init(void)
@@ -169,13 +173,12 @@
 
 Coroutine *qemu_coroutine_new(void)
 {
-    CoroutineThreadState *s = coroutine_get_thread_state();
     Coroutine *co;
 
-    co = QLIST_FIRST(&s->pool);
+    co = QLIST_FIRST(&pool);
     if (co) {
         QLIST_REMOVE(co, pool_next);
-        s->pool_size--;
+        pool_size--;
     } else {
         co = coroutine_new();
     }
@@ -184,13 +187,12 @@
 
 void qemu_coroutine_delete(Coroutine *co_)
 {
-    CoroutineThreadState *s = coroutine_get_thread_state();
     CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_);
 
-    if (s->pool_size < POOL_MAX_SIZE) {
-        QLIST_INSERT_HEAD(&s->pool, &co->base, pool_next);
+    if (pool_size < POOL_MAX_SIZE) {
+        QLIST_INSERT_HEAD(&pool, &co->base, pool_next);
         co->base.caller = NULL;
-        s->pool_size++;
+        pool_size++;
         return;
     }
 
diff --git a/cutils.c b/cutils.c
index 6db6304..24b3fe3 100644
--- a/cutils.c
+++ b/cutils.c
@@ -217,7 +217,10 @@
 {
     assert(qiov->nalloc != -1);
 
+    qemu_iovec_reset(qiov);
     g_free(qiov->iov);
+    qiov->nalloc = 0;
+    qiov->iov = NULL;
 }
 
 void qemu_iovec_reset(QEMUIOVector *qiov)
diff --git a/dma-helpers.c b/dma-helpers.c
index 9d6b6fa..f08cdb5 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -142,9 +142,7 @@
 
     dbs->acb = dbs->io_func(dbs->bs, dbs->sector_num, &dbs->iov,
                             dbs->iov.size / 512, dma_bdrv_cb, dbs);
-    if (!dbs->acb) {
-        dma_complete(dbs, -EIO);
-    }
+    assert(dbs->acb);
 }
 
 static void dma_aio_cancel(BlockDriverAIOCB *acb)
diff --git a/docs/migration.txt b/docs/migration.txt
index 4848c1e..f3ddd2f 100644
--- a/docs/migration.txt
+++ b/docs/migration.txt
@@ -219,6 +219,18 @@
 Example: You can look at hpet.c, that uses the three function to
          massage the state that is transferred.
 
+If you use memory API functions that update memory layout outside
+initialization (i.e., in response to a guest action), this is a strong
+indication that you need to call these functions in a post_load callback.
+Examples of such memory API functions are:
+
+  - memory_region_add_subregion()
+  - memory_region_del_subregion()
+  - memory_region_set_readonly()
+  - memory_region_set_enabled()
+  - memory_region_set_address()
+  - memory_region_set_alias_offset()
+
 === Subsections ===
 
 The use of version_id allows to be able to migrate from older versions
diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt
index e792953..b6adcad 100644
--- a/docs/specs/qcow2.txt
+++ b/docs/specs/qcow2.txt
@@ -253,7 +253,13 @@
         36 - 39:    Size of extra data in the table entry (used for future
                     extensions of the format)
 
-        variable:   Extra data for future extensions. Must be ignored.
+        variable:   Extra data for future extensions. Unknown fields must be
+                    ignored. Currently defined are (offset relative to snapshot
+                    table entry):
+
+                    Byte 40 - 47:   Size of the VM state in bytes. 0 if no VM
+                                    state is saved. If this field is present,
+                                    the 32-bit value in bytes 32-35 is ignored.
 
         variable:   Unique ID string for the snapshot (not null terminated)
 
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 1388a20..f7b1d3d 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -205,7 +205,7 @@
     bool linear_vram;  /* vga.vram mapped over cirrus_linear_io */
     MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */
     MemoryRegion low_mem;           /* always mapped, overridden by: */
-    MemoryRegion *cirrus_bank[2];   /*   aliases at 0xa0000-0xb0000  */
+    MemoryRegion cirrus_bank[2];    /*   aliases at 0xa0000-0xb0000  */
     uint32_t cirrus_addr_mask;
     uint32_t linear_mmio_mask;
     uint8_t cirrus_shadow_gr0;
@@ -2363,40 +2363,16 @@
     },
 };
 
-static void unmap_bank(CirrusVGAState *s, unsigned bank)
-{
-    if (s->cirrus_bank[bank]) {
-        memory_region_del_subregion(&s->low_mem_container,
-                                    s->cirrus_bank[bank]);
-        memory_region_destroy(s->cirrus_bank[bank]);
-        g_free(s->cirrus_bank[bank]);
-        s->cirrus_bank[bank] = NULL;
-    }
-}
-
 static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
 {
-    MemoryRegion *mr;
-    static const char *names[] = { "vga.bank0", "vga.bank1" };
-
-    if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
+    MemoryRegion *mr = &s->cirrus_bank[bank];
+    bool enabled = !(s->cirrus_srcptr != s->cirrus_srcptr_end)
         && !((s->vga.sr[0x07] & 0x01) == 0)
         && !((s->vga.gr[0x0B] & 0x14) == 0x14)
-        && !(s->vga.gr[0x0B] & 0x02)) {
+        && !(s->vga.gr[0x0B] & 0x02);
 
-        mr = g_malloc(sizeof(*mr));
-        memory_region_init_alias(mr, names[bank], &s->vga.vram,
-                                 s->cirrus_bank_base[bank], 0x8000);
-        memory_region_add_subregion_overlap(
-            &s->low_mem_container,
-            0x8000 * bank,
-            mr,
-            1);
-        unmap_bank(s, bank);
-        s->cirrus_bank[bank] = mr;
-    } else {
-        unmap_bank(s, bank);
-    }
+    memory_region_set_enabled(mr, enabled);
+    memory_region_set_alias_offset(mr, s->cirrus_bank_base[bank]);
 }
 
 static void map_linear_vram(CirrusVGAState *s)
@@ -2415,8 +2391,8 @@
         s->linear_vram = false;
         memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
     }
-    unmap_bank(s, 0);
-    unmap_bank(s, 1);
+    memory_region_set_enabled(&s->cirrus_bank[0], false);
+    memory_region_set_enabled(&s->cirrus_bank[1], false);
 }
 
 /* Compute the memory access functions */
@@ -2856,6 +2832,14 @@
     memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s,
                           "cirrus-low-memory", 0x20000);
     memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
+    for (i = 0; i < 2; ++i) {
+        static const char *names[] = { "vga.bank0", "vga.bank1" };
+        MemoryRegion *bank = &s->cirrus_bank[i];
+        memory_region_init_alias(bank, names[i], &s->vga.vram, 0, 0x8000);
+        memory_region_set_enabled(bank, false);
+        memory_region_add_subregion_overlap(&s->low_mem_container, i * 0x8000,
+                                            bank, 1);
+    }
     memory_region_add_subregion_overlap(system_memory,
                                         isa_mem_base + 0x000a0000,
                                         &s->low_mem_container,
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 8af1cfd..0adb27b 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -352,14 +352,8 @@
     s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
                                        &s->bus->dma->qiov, n * 4,
                                        ide_atapi_cmd_read_dma_cb, s);
-    if (!s->bus->dma->aiocb) {
-        /* Note: media not present is the most likely case */
-        ide_atapi_cmd_error(s, NOT_READY,
-                            ASC_MEDIUM_NOT_PRESENT);
-        goto eot;
-    }
-
     return;
+
 eot:
     bdrv_acct_done(s->bs, &s->acct);
     s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 49847bd..56b219b 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -493,7 +493,7 @@
     }
 }
 
-static void dma_buf_commit(IDEState *s, int is_write)
+static void dma_buf_commit(IDEState *s)
 {
     qemu_sglist_destroy(&s->sg);
 }
@@ -532,7 +532,7 @@
         bdrv_iostatus_set_err(s->bs, error);
     } else {
         if (op & BM_STATUS_DMA_RETRY) {
-            dma_buf_commit(s, 0);
+            dma_buf_commit(s);
             ide_dma_error(s);
         } else {
             ide_rw_error(s);
@@ -549,7 +549,6 @@
     int n;
     int64_t sector_num;
 
-handle_rw_error:
     if (ret < 0) {
         int op = BM_STATUS_DMA_RETRY;
 
@@ -566,7 +565,7 @@
     n = s->io_buffer_size >> 9;
     sector_num = ide_get_sector(s);
     if (n > 0) {
-        dma_buf_commit(s, ide_cmd_is_read(s));
+        dma_buf_commit(s);
         sector_num += n;
         ide_set_sector(s, sector_num);
         s->nsector -= n;
@@ -608,11 +607,6 @@
                                          ide_issue_trim, ide_dma_cb, s, true);
         break;
     }
-
-    if (!s->bus->dma->aiocb) {
-        ret = -1;
-        goto handle_rw_error;
-    }
     return;
 
 eot:
@@ -718,18 +712,13 @@
 
 void ide_flush_cache(IDEState *s)
 {
-    BlockDriverAIOCB *acb;
-
     if (s->bs == NULL) {
         ide_flush_cb(s, 0);
         return;
     }
 
     bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
-    acb = bdrv_aio_flush(s->bs, ide_flush_cb, s);
-    if (acb == NULL) {
-        ide_flush_cb(s, -EIO);
-    }
+    bdrv_aio_flush(s->bs, ide_flush_cb, s);
 }
 
 static void ide_cfata_metadata_inquiry(IDEState *s)
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index c09d2e0..abbc41b 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -84,13 +84,6 @@
     m->aiocb = dma_bdrv_read(s->bs, &s->sg,
                              (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9),
                              pmac_ide_atapi_transfer_cb, io);
-    if (!m->aiocb) {
-        qemu_sglist_destroy(&s->sg);
-        /* Note: media not present is the most likely case */
-        ide_atapi_cmd_error(s, NOT_READY,
-                            ASC_MEDIUM_NOT_PRESENT);
-        goto done;
-    }
     return;
 
 done:
@@ -159,10 +152,8 @@
                                ide_issue_trim, pmac_ide_transfer_cb, s, true);
         break;
     }
-
-    if (!m->aiocb)
-        pmac_ide_transfer_cb(io, -1);
     return;
+
 done:
     if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
         bdrv_acct_done(s->bs, &s->acct);
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 166c2fc..b9bb09d 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -321,6 +321,14 @@
     .is_default = 1,
 };
 
+static QEMUMachine pc_machine_v0_15 = {
+    .name = "pc-0.15",
+    .desc = "Standard PC",
+    .init = pc_init_pci,
+    .max_cpus = 255,
+    .is_default = 1,
+};
+
 static QEMUMachine pc_machine_v0_14 = {
     .name = "pc-0.14",
     .desc = "Standard PC",
@@ -335,6 +343,22 @@
             .driver   = "qxl-vga",
             .property = "revision",
             .value    = stringify(2),
+        },{
+            .driver   = "virtio-blk-pci",
+            .property = "event_idx",
+            .value    = "off",
+        },{
+            .driver   = "virtio-serial-pci",
+            .property = "event_idx",
+            .value    = "off",
+        },{
+            .driver   = "virtio-net-pci",
+            .property = "event_idx",
+            .value    = "off",
+        },{
+            .driver   = "virtio-balloon-pci",
+            .property = "event_idx",
+            .value    = "off",
         },
         { /* end of list */ }
     },
@@ -375,6 +399,10 @@
             .property = "event_idx",
             .value    = "off",
         },{
+            .driver   = "virtio-balloon-pci",
+            .property = "event_idx",
+            .value    = "off",
+        },{
             .driver   = "AC97",
             .property = "use_broken_id",
             .value    = stringify(1),
@@ -422,6 +450,10 @@
             .property = "event_idx",
             .value    = "off",
         },{
+            .driver   = "virtio-balloon-pci",
+            .property = "event_idx",
+            .value    = "off",
+        },{
             .driver   = "AC97",
             .property = "use_broken_id",
             .value    = stringify(1),
@@ -477,6 +509,10 @@
             .property = "event_idx",
             .value    = "off",
         },{
+            .driver   = "virtio-balloon-pci",
+            .property = "event_idx",
+            .value    = "off",
+        },{
             .driver   = "AC97",
             .property = "use_broken_id",
             .value    = stringify(1),
@@ -544,6 +580,10 @@
             .property = "event_idx",
             .value    = "off",
         },{
+            .driver   = "virtio-balloon-pci",
+            .property = "event_idx",
+            .value    = "off",
+        },{
             .driver   = "AC97",
             .property = "use_broken_id",
             .value    = stringify(1),
@@ -572,6 +612,7 @@
 static void pc_machine_init(void)
 {
     qemu_register_machine(&pc_machine_v1_0);
+    qemu_register_machine(&pc_machine_v0_15);
     qemu_register_machine(&pc_machine_v0_14);
     qemu_register_machine(&pc_machine_v0_13);
     qemu_register_machine(&pc_machine_v0_12);
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index d785d4b..43c85aa 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -81,7 +81,6 @@
     PAMMemoryRegion pam_regions[13];
     MemoryRegion smram_region;
     uint8_t smm_enabled;
-    bool smram_enabled;
     PIIX3State *piix3;
 };
 
@@ -141,6 +140,7 @@
 {
     int i, r;
     uint32_t smram;
+    bool smram_enabled;
 
     memory_region_transaction_begin();
     update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3,
@@ -151,18 +151,8 @@
                    &d->pam_regions[i+1]);
     }
     smram = d->dev.config[I440FX_SMRAM];
-    if ((d->smm_enabled && (smram & 0x08)) || (smram & 0x40)) {
-        if (!d->smram_enabled) {
-            memory_region_del_subregion(d->system_memory, &d->smram_region);
-            d->smram_enabled = true;
-        }
-    } else {
-        if (d->smram_enabled) {
-            memory_region_add_subregion_overlap(d->system_memory, 0xa0000,
-                                                &d->smram_region, 1);
-            d->smram_enabled = false;
-        }
-    }
+    smram_enabled = (d->smm_enabled && (smram & 0x08)) || (smram & 0x40);
+    memory_region_set_enabled(&d->smram_region, !smram_enabled);
     memory_region_transaction_commit();
 }
 
@@ -308,7 +298,9 @@
     }
     memory_region_init_alias(&f->smram_region, "smram-region",
                              f->pci_address_space, 0xa0000, 0x20000);
-    f->smram_enabled = true;
+    memory_region_add_subregion_overlap(f->system_memory, 0xa0000,
+                                        &f->smram_region, 1);
+    memory_region_set_enabled(&f->smram_region, false);
 
     /* Xen supports additional interrupt routes from the PCI devices to
      * the IOAPIC: the four pins of each PCI device on the bus are also
@@ -324,9 +316,8 @@
                 pci_create_simple_multifunction(b, -1, true, "PIIX3"));
         pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
                 PIIX_NUM_PIRQS);
-
-        qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL);
     }
+    qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL);
     piix3->pic = pic;
 
     (*pi440fx_state)->piix3 = piix3;
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 673948c..505accd 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -217,9 +217,6 @@
     bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
     r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n,
                               scsi_read_complete, r);
-    if (r->req.aiocb == NULL) {
-        scsi_read_complete(r, -EIO);
-    }
 }
 
 /*
@@ -327,9 +324,6 @@
         bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
         r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n,
                                        scsi_write_complete, r);
-        if (r->req.aiocb == NULL) {
-            scsi_write_complete(r, -ENOMEM);
-        }
     } else {
         /* Called for the first time.  Ask the driver to send us more data.  */
         scsi_write_complete(r, 0);
@@ -1332,9 +1326,6 @@
         scsi_req_ref(&r->req);
         bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
         r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_flush_complete, r);
-        if (r->req.aiocb == NULL) {
-            scsi_flush_complete(r, -EIO);
-        }
         return 0;
     case READ_6:
     case READ_10:
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index e62044f..6f7d3db 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -152,10 +152,6 @@
     r->io_header.flags |= SG_FLAG_DIRECT_IO;
 
     r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
-    if (r->req.aiocb == NULL) {
-        BADF("execute_command: read failed !\n");
-        return -ENOMEM;
-    }
 
     return 0;
 }
diff --git a/hw/stellaris.c b/hw/stellaris.c
index ce62a98..7a73074 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -621,6 +621,7 @@
     s->rcgc[0] = 1;
     s->scgc[0] = 1;
     s->dcgc[0] = 1;
+    ssys_calculate_system_clock(s);
 }
 
 static int stellaris_sys_post_load(void *opaque, int version_id)
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 4b0d113..ef27421 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -288,19 +288,13 @@
 
 static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 {
-    BlockDriverAIOCB *acb;
-
     bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH);
 
     /*
      * Make sure all outstanding writes are posted to the backing device.
      */
     virtio_submit_multiwrite(req->dev->bs, mrb);
-
-    acb = bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req);
-    if (!acb) {
-        virtio_blk_flush_complete(req, -EIO);
-    }
+    bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req);
 }
 
 static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
@@ -340,7 +334,6 @@
 
 static void virtio_blk_handle_read(VirtIOBlockReq *req)
 {
-    BlockDriverAIOCB *acb;
     uint64_t sector;
 
     sector = ldq_p(&req->out->sector);
@@ -355,13 +348,9 @@
         virtio_blk_rw_complete(req, -EIO);
         return;
     }
-
-    acb = bdrv_aio_readv(req->dev->bs, sector, &req->qiov,
-                         req->qiov.size / BDRV_SECTOR_SIZE,
-                         virtio_blk_rw_complete, req);
-    if (!acb) {
-        virtio_blk_rw_complete(req, -EIO);
-    }
+    bdrv_aio_readv(req->dev->bs, sector, &req->qiov,
+                   req->qiov.size / BDRV_SECTOR_SIZE,
+                   virtio_blk_rw_complete, req);
 }
 
 static void virtio_blk_handle_request(VirtIOBlockReq *req,
diff --git a/kvm-all.c b/kvm-all.c
index 4c466d6..ac048bc 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -977,7 +977,8 @@
                 ret = EXCP_INTERRUPT;
                 break;
             }
-            DPRINTF("kvm run failed %s\n", strerror(-run_ret));
+            fprintf(stderr, "error: kvm run failed %s\n",
+                    strerror(-run_ret));
             abort();
         }
 
diff --git a/linux-aio.c b/linux-aio.c
index 1c635ef..d2fc2e7 100644
--- a/linux-aio.c
+++ b/linux-aio.c
@@ -166,8 +166,6 @@
     off_t offset = sector_num * 512;
 
     laiocb = qemu_aio_get(&laio_pool, bs, cb, opaque);
-    if (!laiocb)
-        return NULL;
     laiocb->nbytes = nb_sectors * 512;
     laiocb->ctx = s;
     laiocb->ret = -EINPROGRESS;
diff --git a/memory.c b/memory.c
index cbd6988..a7e615a 100644
--- a/memory.c
+++ b/memory.c
@@ -22,6 +22,7 @@
 #include "exec-obsolete.h"
 
 unsigned memory_region_transaction_depth = 0;
+static bool memory_region_update_pending = false;
 
 typedef struct AddrRange AddrRange;
 
@@ -531,6 +532,10 @@
     FlatRange fr;
     AddrRange tmp;
 
+    if (!mr->enabled) {
+        return;
+    }
+
     int128_addto(&base, int128_make64(mr->addr));
     readonly |= mr->readonly;
 
@@ -753,9 +758,14 @@
     address_space_update_ioeventfds(as);
 }
 
-static void memory_region_update_topology(void)
+static void memory_region_update_topology(MemoryRegion *mr)
 {
     if (memory_region_transaction_depth) {
+        memory_region_update_pending |= !mr || mr->enabled;
+        return;
+    }
+
+    if (mr && !mr->enabled) {
         return;
     }
 
@@ -765,6 +775,8 @@
     if (address_space_io.root) {
         address_space_update_topology(&address_space_io);
     }
+
+    memory_region_update_pending = false;
 }
 
 void memory_region_transaction_begin(void)
@@ -776,7 +788,9 @@
 {
     assert(memory_region_transaction_depth);
     --memory_region_transaction_depth;
-    memory_region_update_topology();
+    if (!memory_region_transaction_depth && memory_region_update_pending) {
+        memory_region_update_topology(NULL);
+    }
 }
 
 static void memory_region_destructor_none(MemoryRegion *mr)
@@ -816,6 +830,7 @@
     }
     mr->addr = 0;
     mr->offset = 0;
+    mr->enabled = true;
     mr->terminates = false;
     mr->readable = true;
     mr->readonly = false;
@@ -1061,7 +1076,7 @@
     uint8_t mask = 1 << client;
 
     mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
-    memory_region_update_topology();
+    memory_region_update_topology(mr);
 }
 
 bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
@@ -1093,7 +1108,7 @@
 {
     if (mr->readonly != readonly) {
         mr->readonly = readonly;
-        memory_region_update_topology();
+        memory_region_update_topology(mr);
     }
 }
 
@@ -1101,7 +1116,7 @@
 {
     if (mr->readable != readable) {
         mr->readable = readable;
-        memory_region_update_topology();
+        memory_region_update_topology(mr);
     }
 }
 
@@ -1206,7 +1221,7 @@
     memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i],
             sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i));
     mr->ioeventfds[i] = mrfd;
-    memory_region_update_topology();
+    memory_region_update_topology(mr);
 }
 
 void memory_region_del_eventfd(MemoryRegion *mr,
@@ -1236,7 +1251,7 @@
     --mr->ioeventfd_nb;
     mr->ioeventfds = g_realloc(mr->ioeventfds,
                                   sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);
-    memory_region_update_topology();
+    memory_region_update_topology(mr);
 }
 
 static void memory_region_add_subregion_common(MemoryRegion *mr,
@@ -1277,7 +1292,7 @@
     }
     QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link);
 done:
-    memory_region_update_topology();
+    memory_region_update_topology(mr);
 }
 
 
@@ -1306,19 +1321,63 @@
     assert(subregion->parent == mr);
     subregion->parent = NULL;
     QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
-    memory_region_update_topology();
+    memory_region_update_topology(mr);
+}
+
+void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
+{
+    if (enabled == mr->enabled) {
+        return;
+    }
+    mr->enabled = enabled;
+    memory_region_update_topology(NULL);
+}
+
+void memory_region_set_address(MemoryRegion *mr, target_phys_addr_t addr)
+{
+    MemoryRegion *parent = mr->parent;
+    unsigned priority = mr->priority;
+    bool may_overlap = mr->may_overlap;
+
+    if (addr == mr->addr || !parent) {
+        mr->addr = addr;
+        return;
+    }
+
+    memory_region_transaction_begin();
+    memory_region_del_subregion(parent, mr);
+    if (may_overlap) {
+        memory_region_add_subregion_overlap(parent, addr, mr, priority);
+    } else {
+        memory_region_add_subregion(parent, addr, mr);
+    }
+    memory_region_transaction_commit();
+}
+
+void memory_region_set_alias_offset(MemoryRegion *mr, target_phys_addr_t offset)
+{
+    target_phys_addr_t old_offset = mr->alias_offset;
+
+    assert(mr->alias);
+    mr->alias_offset = offset;
+
+    if (offset == old_offset || !mr->parent) {
+        return;
+    }
+
+    memory_region_update_topology(mr);
 }
 
 void set_system_memory_map(MemoryRegion *mr)
 {
     address_space_memory.root = mr;
-    memory_region_update_topology();
+    memory_region_update_topology(NULL);
 }
 
 void set_system_io_map(MemoryRegion *mr)
 {
     address_space_io.root = mr;
-    memory_region_update_topology();
+    memory_region_update_topology(NULL);
 }
 
 typedef struct MemoryRegionList MemoryRegionList;
diff --git a/memory.h b/memory.h
index beae127..fe643ff 100644
--- a/memory.h
+++ b/memory.h
@@ -123,6 +123,7 @@
     bool terminates;
     bool readable;
     bool readonly; /* For RAM regions */
+    bool enabled;
     MemoryRegion *alias;
     target_phys_addr_t alias_offset;
     unsigned priority;
@@ -501,6 +502,44 @@
 void memory_region_del_subregion(MemoryRegion *mr,
                                  MemoryRegion *subregion);
 
+/*
+ * memory_region_set_enabled: dynamically enable or disable a region
+ *
+ * Enables or disables a memory region.  A disabled memory region
+ * ignores all accesses to itself and its subregions.  It does not
+ * obscure sibling subregions with lower priority - it simply behaves as
+ * if it was removed from the hierarchy.
+ *
+ * Regions default to being enabled.
+ *
+ * @mr: the region to be updated
+ * @enabled: whether to enable or disable the region
+ */
+void memory_region_set_enabled(MemoryRegion *mr, bool enabled);
+
+/*
+ * memory_region_set_address: dynamically update the address of a region
+ *
+ * Dynamically updates the address of a region, relative to its parent.
+ * May be used on regions are currently part of a memory hierarchy.
+ *
+ * @mr: the region to be updated
+ * @addr: new address, relative to parent region
+ */
+void memory_region_set_address(MemoryRegion *mr, target_phys_addr_t addr);
+
+/*
+ * memory_region_set_alias_offset: dynamically update a memory alias's offset
+ *
+ * Dynamically updates the offset into the target region that an alias points
+ * to, as if the fourth argument to memory_region_init_alias() has changed.
+ *
+ * @mr: the #MemoryRegion to be updated; should be an alias.
+ * @offset: the new offset into the target memory region
+ */
+void memory_region_set_alias_offset(MemoryRegion *mr,
+                                    target_phys_addr_t offset);
+
 /**
  * memory_region_transaction_begin: Start a transaction.
  *
diff --git a/net/slirp.c b/net/slirp.c
index 6646ecb..18e07ba 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -351,7 +351,7 @@
                                host_addr, host_port);
 
     monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,
-                   err ? "removed" : "not found");
+                   err ? "not found" : "removed");
     return;
 
  fail_syntax:
diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index c380ec1..cccb673 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -611,8 +611,6 @@
     struct qemu_paiocb *acb;
 
     acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque);
-    if (!acb)
-        return NULL;
     acb->aio_type = type;
     acb->aio_fildes = fd;
 
@@ -638,8 +636,6 @@
     struct qemu_paiocb *acb;
 
     acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque);
-    if (!acb)
-        return NULL;
     acb->aio_type = QEMU_AIO_IOCTL;
     acb->aio_fildes = fd;
     acb->aio_offset = 0;
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 4be00a5..49dce7c 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -24,13 +24,13 @@
 DEF("commit", img_commit,
     "commit [-f fmt] [-t cache] filename")
 STEXI
-@item commit [-f @var{fmt}] @var{filename}
+@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename}
 ETEXI
 
 DEF("convert", img_convert,
     "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename")
 STEXI
-@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
 DEF("info", img_info,
@@ -48,7 +48,7 @@
 DEF("rebase", img_rebase,
     "rebase [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
 STEXI
-@item rebase [-f @var{fmt}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
+@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
 ETEXI
 
 DEF("resize", img_resize,
diff --git a/qemu-img.c b/qemu-img.c
index 8bdae66..01cc0d3 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1420,6 +1420,8 @@
      */
     if (!unsafe) {
         uint64_t num_sectors;
+        uint64_t old_backing_num_sectors;
+        uint64_t new_backing_num_sectors;
         uint64_t sector;
         int n;
         uint8_t * buf_old;
@@ -1430,6 +1432,8 @@
         buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
 
         bdrv_get_geometry(bs, &num_sectors);
+        bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
+        bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
 
         local_progress = (float)100 /
             (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
@@ -1448,16 +1452,36 @@
                 continue;
             }
 
-            /* Read old and new backing file */
-            ret = bdrv_read(bs_old_backing, sector, buf_old, n);
-            if (ret < 0) {
-                error_report("error while reading from old backing file");
-                goto out;
+            /*
+             * Read old and new backing file and take into consideration that
+             * backing files may be smaller than the COW image.
+             */
+            if (sector >= old_backing_num_sectors) {
+                memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
+            } else {
+                if (sector + n > old_backing_num_sectors) {
+                    n = old_backing_num_sectors - sector;
+                }
+
+                ret = bdrv_read(bs_old_backing, sector, buf_old, n);
+                if (ret < 0) {
+                    error_report("error while reading from old backing file");
+                    goto out;
+                }
             }
-            ret = bdrv_read(bs_new_backing, sector, buf_new, n);
-            if (ret < 0) {
-                error_report("error while reading from new backing file");
-                goto out;
+
+            if (sector >= new_backing_num_sectors) {
+                memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
+            } else {
+                if (sector + n > new_backing_num_sectors) {
+                    n = new_backing_num_sectors - sector;
+                }
+
+                ret = bdrv_read(bs_new_backing, sector, buf_new, n);
+                if (ret < 0) {
+                    error_report("error while reading from new backing file");
+                    goto out;
+                }
             }
 
             /* If they differ, we need to write to the COW file */
diff --git a/qemu-img.texi b/qemu-img.texi
index 70fa321..b2ca3a5 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -45,6 +45,10 @@
 for qemu-img to create a sparse image during conversion. This value is rounded
 down to the nearest 512 bytes. You may use the common size suffixes like
 @code{k} for kilobytes.
+@item -t @var{cache}
+specifies the cache mode that should be used with the (destination) file. See
+the documentation of the emulator's @code{-drive cache=...} option for allowed
+values.
 @end table
 
 Parameters to snapshot subcommand:
@@ -87,11 +91,11 @@
 The size can also be specified using the @var{size} option with @code{-o},
 it doesn't need to be specified separately in this case.
 
-@item commit [-f @var{fmt}] @var{filename}
+@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename}
 
 Commit the changes recorded in @var{filename} in its base image.
 
-@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 
 Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename}
 using format @var{output_fmt}. It can be optionally compressed (@code{-c}
@@ -121,7 +125,7 @@
 
 List, apply, create or delete snapshots in image @var{filename}.
 
-@item rebase [-f @var{fmt}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
+@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
 
 Changes the backing file of an image. Only the formats @code{qcow2} and
 @code{qed} support changing the backing file.
diff --git a/qemu-io.c b/qemu-io.c
index 622debc..ffa62fb 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -244,14 +244,10 @@
 
 static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
 {
-    BlockDriverAIOCB *acb;
     int async_ret = NOT_DONE;
 
-    acb = bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
-                         aio_rw_done, &async_ret);
-    if (!acb) {
-        return -EIO;
-    }
+    bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
+                   aio_rw_done, &async_ret);
     while (async_ret == NOT_DONE) {
         qemu_aio_wait();
     }
@@ -262,15 +258,10 @@
 
 static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total)
 {
-    BlockDriverAIOCB *acb;
     int async_ret = NOT_DONE;
 
-    acb = bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
-                          aio_rw_done, &async_ret);
-    if (!acb) {
-        return -EIO;
-    }
-
+    bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
+                    aio_rw_done, &async_ret);
     while (async_ret == NOT_DONE) {
         qemu_aio_wait();
     }
@@ -1151,7 +1142,6 @@
 {
     int nr_iov, c;
     struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
-    BlockDriverAIOCB *acb;
 
     while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
         switch (c) {
@@ -1206,14 +1196,8 @@
     }
 
     gettimeofday(&ctx->t1, NULL);
-    acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
-                         ctx->qiov.size >> 9, aio_read_done, ctx);
-    if (!acb) {
-        free(ctx->buf);
-        free(ctx);
-        return -EIO;
-    }
-
+    bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
+                   ctx->qiov.size >> 9, aio_read_done, ctx);
     return 0;
 }
 
@@ -1254,7 +1238,6 @@
     int nr_iov, c;
     int pattern = 0xcd;
     struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
-    BlockDriverAIOCB *acb;
 
     while ((c = getopt(argc, argv, "CqP:")) != EOF) {
         switch (c) {
@@ -1305,14 +1288,8 @@
     }
 
     gettimeofday(&ctx->t1, NULL);
-    acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
-                          ctx->qiov.size >> 9, aio_write_done, ctx);
-    if (!acb) {
-        free(ctx->buf);
-        free(ctx);
-        return -EIO;
-    }
-
+    bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
+                    ctx->qiov.size >> 9, aio_write_done, ctx);
     return 0;
 }
 
diff --git a/savevm.c b/savevm.c
index b72f6c0..f153c25 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2002,7 +2002,7 @@
     int ret;
     QEMUFile *f;
     int saved_vm_running;
-    uint32_t vm_state_size;
+    uint64_t vm_state_size;
 #ifdef _WIN32
     struct _timeb tb;
     struct tm *ptm;
diff --git a/trace-events b/trace-events
index bf1cf57..514849a 100644
--- a/trace-events
+++ b/trace-events
@@ -59,8 +59,6 @@
 bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags %#x format_name \"%s\""
 multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
 bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
-bdrv_aio_multiwrite_earlyfail(void *mcb) "mcb %p"
-bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d"
 bdrv_aio_discard(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
 bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
 bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"