Merge remote branch 'qmp/for-anthony' into staging
diff --git a/Makefile b/Makefile
index 106a401..3df202c 100644
--- a/Makefile
+++ b/Makefile
@@ -129,11 +129,11 @@
 qemu-img.o: qemu-img-cmds.h
 qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
 
-qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
-qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
-qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
 qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
 	$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@,"  GEN   $@")
diff --git a/Makefile.objs b/Makefile.objs
index 6e6f60a..f07fb01 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -127,7 +127,7 @@
 common-obj-$(CONFIG_THREAD) += qemu-thread.o
 common-obj-$(CONFIG_IOTHREAD) += compatfd.o
 common-obj-y += notify.o event_notifier.o
-common-obj-y += qemu-timer.o
+common-obj-y += qemu-timer.o qemu-timer-common.o
 
 slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
 slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
@@ -278,6 +278,7 @@
 trace-obj-y = trace.o
 ifeq ($(TRACE_BACKEND),simple)
 trace-obj-y += simpletrace.o
+user-obj-y += qemu-timer-common.o
 endif
 
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/block.c b/block.c
index a19374d..985d0b7 100644
--- a/block.c
+++ b/block.c
@@ -1899,6 +1899,22 @@
     return -ENOTSUP;
 }
 
+int bdrv_snapshot_load_tmp(BlockDriverState *bs,
+        const char *snapshot_name)
+{
+    BlockDriver *drv = bs->drv;
+    if (!drv) {
+        return -ENOMEDIUM;
+    }
+    if (!bs->read_only) {
+        return -EINVAL;
+    }
+    if (drv->bdrv_snapshot_load_tmp) {
+        return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
+    }
+    return -ENOTSUP;
+}
+
 #define NB_SUFFIXES 4
 
 char *get_human_readable_size(char *buf, int buf_size, int64_t size)
diff --git a/block.h b/block.h
index 5f64380..a4facf2 100644
--- a/block.h
+++ b/block.h
@@ -211,6 +211,8 @@
 int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
 int bdrv_snapshot_list(BlockDriverState *bs,
                        QEMUSnapshotInfo **psn_info);
+int bdrv_snapshot_load_tmp(BlockDriverState *bs,
+                           const char *snapshot_name);
 char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
 
 char *get_human_readable_size(char *buf, int buf_size, int64_t size);
diff --git a/block/blkverify.c b/block/blkverify.c
index 8083464..b2a12fe 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -53,7 +53,8 @@
     .cancel             = blkverify_aio_cancel,
 };
 
-static void blkverify_err(BlkverifyAIOCB *acb, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3) blkverify_err(BlkverifyAIOCB *acb,
+                                             const char *fmt, ...)
 {
     va_list ap;
 
@@ -299,7 +300,7 @@
 {
     ssize_t offset = blkverify_iovec_compare(acb->qiov, &acb->raw_qiov);
     if (offset != -1) {
-        blkverify_err(acb, "contents mismatch in sector %ld",
+        blkverify_err(acb, "contents mismatch in sector %lld",
                       acb->sector_num + (offset / BDRV_SECTOR_SIZE));
     }
 }
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index fb4224a..4f7dc59 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -28,7 +28,7 @@
 #include "block_int.h"
 #include "block/qcow2.h"
 
-int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
+int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
 {
     BDRVQcowState *s = bs->opaque;
     int new_l1_size, new_l1_size2, ret, i;
@@ -36,15 +36,22 @@
     int64_t new_l1_table_offset;
     uint8_t data[12];
 
-    new_l1_size = s->l1_size;
-    if (min_size <= new_l1_size)
+    if (min_size <= s->l1_size)
         return 0;
-    if (new_l1_size == 0) {
-        new_l1_size = 1;
+
+    if (exact_size) {
+        new_l1_size = min_size;
+    } else {
+        /* Bump size up to reduce the number of times we have to grow */
+        new_l1_size = s->l1_size;
+        if (new_l1_size == 0) {
+            new_l1_size = 1;
+        }
+        while (min_size > new_l1_size) {
+            new_l1_size = (new_l1_size * 3 + 1) / 2;
+        }
     }
-    while (min_size > new_l1_size) {
-        new_l1_size = (new_l1_size * 3 + 1) / 2;
-    }
+
 #ifdef DEBUG_ALLOC2
     printf("grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
 #endif
@@ -550,7 +557,7 @@
 
     l1_index = offset >> (s->l2_bits + s->cluster_bits);
     if (l1_index >= s->l1_size) {
-        ret = qcow2_grow_l1_table(bs, l1_index + 1);
+        ret = qcow2_grow_l1_table(bs, l1_index + 1, false);
         if (ret < 0) {
             return ret;
         }
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index bbfcaaa..aacf357 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -327,7 +327,7 @@
     if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, -1) < 0)
         goto fail;
 
-    if (qcow2_grow_l1_table(bs, sn->l1_size) < 0)
+    if (qcow2_grow_l1_table(bs, sn->l1_size, true) < 0)
         goto fail;
 
     s->l1_size = sn->l1_size;
@@ -418,3 +418,34 @@
     return s->nb_snapshots;
 }
 
+int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name)
+{
+    int i, snapshot_index, l1_size2;
+    BDRVQcowState *s = bs->opaque;
+    QCowSnapshot *sn;
+
+    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_name);
+    if (snapshot_index < 0) {
+        return -ENOENT;
+    }
+
+    sn = &s->snapshots[snapshot_index];
+    s->l1_size = sn->l1_size;
+    l1_size2 = s->l1_size * sizeof(uint64_t);
+    if (s->l1_table != NULL) {
+        qemu_free(s->l1_table);
+    }
+
+    s->l1_table_offset = sn->l1_table_offset;
+    s->l1_table = qemu_mallocz(align_offset(l1_size2, 512));
+
+    if (bdrv_pread(bs->file, sn->l1_table_offset,
+                   s->l1_table, l1_size2) != l1_size2) {
+        return -1;
+    }
+
+    for(i = 0;i < s->l1_size; i++) {
+        be64_to_cpus(&s->l1_table[i]);
+    }
+    return 0;
+}
diff --git a/block/qcow2.c b/block/qcow2.c
index ee3481b..b816d87 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -27,6 +27,7 @@
 #include <zlib.h>
 #include "aes.h"
 #include "block/qcow2.h"
+#include "qemu-error.h"
 
 /*
   Differences with QCOW:
@@ -794,28 +795,6 @@
     return qcow2_update_ext_header(bs, backing_file, backing_fmt);
 }
 
-static int get_bits_from_size(size_t size)
-{
-    int res = 0;
-
-    if (size == 0) {
-        return -1;
-    }
-
-    while (size != 1) {
-        /* Not a power of two */
-        if (size & 1) {
-            return -1;
-        }
-
-        size >>= 1;
-        res++;
-    }
-
-    return res;
-}
-
-
 static int preallocate(BlockDriverState *bs)
 {
     uint64_t nb_sectors;
@@ -871,199 +850,127 @@
 
 static int qcow_create2(const char *filename, int64_t total_size,
                         const char *backing_file, const char *backing_format,
-                        int flags, size_t cluster_size, int prealloc)
+                        int flags, size_t cluster_size, int prealloc,
+                        QEMUOptionParameter *options)
 {
+    /* Calulate cluster_bits */
+    int cluster_bits;
+    cluster_bits = ffs(cluster_size) - 1;
+    if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS ||
+        (1 << cluster_bits) != cluster_size)
+    {
+        error_report(
+            "Cluster size must be a power of two between %d and %dk\n",
+            1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
+        return -EINVAL;
+    }
 
-    int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
-    int ref_clusters, reftable_clusters, backing_format_len = 0;
-    int rounded_ext_bf_len = 0;
+    /*
+     * Open the image file and write a minimal qcow2 header.
+     *
+     * We keep things simple and start with a zero-sized image. We also
+     * do without refcount blocks or a L1 table for now. We'll fix the
+     * inconsistency later.
+     *
+     * We do need a refcount table because growing the refcount table means
+     * allocating two new refcount blocks - the seconds of which would be at
+     * 2 GB for 64k clusters, and we don't want to have a 2 GB initial file
+     * size for any qcow2 image.
+     */
+    BlockDriverState* bs;
     QCowHeader header;
-    uint64_t tmp, offset;
-    uint64_t old_ref_clusters;
-    QCowCreateState s1, *s = &s1;
-    QCowExtension ext_bf = {0, 0};
+    uint8_t* refcount_table;
     int ret;
 
-    memset(s, 0, sizeof(*s));
+    ret = bdrv_create_file(filename, options);
+    if (ret < 0) {
+        return ret;
+    }
 
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
-    if (fd < 0)
-        return -errno;
+    ret = bdrv_file_open(&bs, filename, BDRV_O_RDWR);
+    if (ret < 0) {
+        return ret;
+    }
+
+    /* Write the header */
     memset(&header, 0, sizeof(header));
     header.magic = cpu_to_be32(QCOW_MAGIC);
     header.version = cpu_to_be32(QCOW_VERSION);
-    header.size = cpu_to_be64(total_size * 512);
-    header_size = sizeof(header);
-    backing_filename_len = 0;
-    if (backing_file) {
-        if (backing_format) {
-            ext_bf.magic = QCOW_EXT_MAGIC_BACKING_FORMAT;
-            backing_format_len = strlen(backing_format);
-            ext_bf.len = backing_format_len;
-            rounded_ext_bf_len = (sizeof(ext_bf) + ext_bf.len + 7) & ~7;
-            header_size += rounded_ext_bf_len;
-        }
-        header.backing_file_offset = cpu_to_be64(header_size);
-        backing_filename_len = strlen(backing_file);
-        header.backing_file_size = cpu_to_be32(backing_filename_len);
-        header_size += backing_filename_len;
-    }
+    header.cluster_bits = cpu_to_be32(cluster_bits);
+    header.size = cpu_to_be64(0);
+    header.l1_table_offset = cpu_to_be64(0);
+    header.l1_size = cpu_to_be32(0);
+    header.refcount_table_offset = cpu_to_be64(cluster_size);
+    header.refcount_table_clusters = cpu_to_be32(1);
 
-    /* Cluster size */
-    s->cluster_bits = get_bits_from_size(cluster_size);
-    if (s->cluster_bits < MIN_CLUSTER_BITS ||
-        s->cluster_bits > MAX_CLUSTER_BITS)
-    {
-        fprintf(stderr, "Cluster size must be a power of two between "
-            "%d and %dk\n",
-            1 << MIN_CLUSTER_BITS,
-            1 << (MAX_CLUSTER_BITS - 10));
-        return -EINVAL;
-    }
-    s->cluster_size = 1 << s->cluster_bits;
-
-    header.cluster_bits = cpu_to_be32(s->cluster_bits);
-    header_size = (header_size + 7) & ~7;
     if (flags & BLOCK_FLAG_ENCRYPT) {
         header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
     } else {
         header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
     }
-    l2_bits = s->cluster_bits - 3;
-    shift = s->cluster_bits + l2_bits;
-    l1_size = (((total_size * 512) + (1LL << shift) - 1) >> shift);
-    offset = align_offset(header_size, s->cluster_size);
-    s->l1_table_offset = offset;
-    header.l1_table_offset = cpu_to_be64(s->l1_table_offset);
-    header.l1_size = cpu_to_be32(l1_size);
-    offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size);
 
-    /* count how many refcount blocks needed */
-
-#define NUM_CLUSTERS(bytes) \
-    (((bytes) + (s->cluster_size) - 1) / (s->cluster_size))
-
-    ref_clusters = NUM_CLUSTERS(NUM_CLUSTERS(offset) * sizeof(uint16_t));
-
-    do {
-        uint64_t image_clusters;
-        old_ref_clusters = ref_clusters;
-
-        /* Number of clusters used for the refcount table */
-        reftable_clusters = NUM_CLUSTERS(ref_clusters * sizeof(uint64_t));
-
-        /* Number of clusters that the whole image will have */
-        image_clusters = NUM_CLUSTERS(offset) + ref_clusters
-            + reftable_clusters;
-
-        /* Number of refcount blocks needed for the image */
-        ref_clusters = NUM_CLUSTERS(image_clusters * sizeof(uint16_t));
-
-    } while (ref_clusters != old_ref_clusters);
-
-    s->refcount_table = qemu_mallocz(reftable_clusters * s->cluster_size);
-
-    s->refcount_table_offset = offset;
-    header.refcount_table_offset = cpu_to_be64(offset);
-    header.refcount_table_clusters = cpu_to_be32(reftable_clusters);
-    offset += (reftable_clusters * s->cluster_size);
-    s->refcount_block_offset = offset;
-
-    for (i=0; i < ref_clusters; i++) {
-        s->refcount_table[i] = cpu_to_be64(offset);
-        offset += s->cluster_size;
+    ret = bdrv_pwrite(bs, 0, &header, sizeof(header));
+    if (ret < 0) {
+        goto out;
     }
 
-    s->refcount_block = qemu_mallocz(ref_clusters * s->cluster_size);
+    /* Write an empty refcount table */
+    refcount_table = qemu_mallocz(cluster_size);
+    ret = bdrv_pwrite(bs, cluster_size, refcount_table, cluster_size);
+    qemu_free(refcount_table);
 
-    /* update refcounts */
-    qcow2_create_refcount_update(s, 0, header_size);
-    qcow2_create_refcount_update(s, s->l1_table_offset,
-        l1_size * sizeof(uint64_t));
-    qcow2_create_refcount_update(s, s->refcount_table_offset,
-        reftable_clusters * s->cluster_size);
-    qcow2_create_refcount_update(s, s->refcount_block_offset,
-        ref_clusters * s->cluster_size);
-
-    /* write all the data */
-    ret = qemu_write_full(fd, &header, sizeof(header));
-    if (ret != sizeof(header)) {
-        ret = -errno;
-        goto exit;
+    if (ret < 0) {
+        goto out;
     }
+
+    bdrv_close(bs);
+
+    /*
+     * And now open the image and make it consistent first (i.e. increase the
+     * refcount of the cluster that is occupied by the header and the refcount
+     * table)
+     */
+    BlockDriver* drv = bdrv_find_format("qcow2");
+    assert(drv != NULL);
+    ret = bdrv_open(bs, filename, BDRV_O_RDWR | BDRV_O_NO_FLUSH, drv);
+    if (ret < 0) {
+        goto out;
+    }
+
+    ret = qcow2_alloc_clusters(bs, 2 * cluster_size);
+    if (ret < 0) {
+        goto out;
+
+    } else if (ret != 0) {
+        error_report("Huh, first cluster in empty image is already in use?");
+        abort();
+    }
+
+    /* Okay, now that we have a valid image, let's give it the right size */
+    ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE);
+    if (ret < 0) {
+        goto out;
+    }
+
+    /* Want a backing file? There you go.*/
     if (backing_file) {
-        if (backing_format_len) {
-            char zero[16];
-            int padding = rounded_ext_bf_len - (ext_bf.len + sizeof(ext_bf));
-
-            memset(zero, 0, sizeof(zero));
-            cpu_to_be32s(&ext_bf.magic);
-            cpu_to_be32s(&ext_bf.len);
-            ret = qemu_write_full(fd, &ext_bf, sizeof(ext_bf));
-            if (ret != sizeof(ext_bf)) {
-                ret = -errno;
-                goto exit;
-            }
-            ret = qemu_write_full(fd, backing_format, backing_format_len);
-            if (ret != backing_format_len) {
-                ret = -errno;
-                goto exit;
-            }
-            if (padding > 0) {
-                ret = qemu_write_full(fd, zero, padding);
-                if (ret != padding) {
-                    ret = -errno;
-                    goto exit;
-                }
-            }
+        ret = bdrv_change_backing_file(bs, backing_file, backing_format);
+        if (ret < 0) {
+            goto out;
         }
-        ret = qemu_write_full(fd, backing_file, backing_filename_len);
-        if (ret != backing_filename_len) {
-            ret = -errno;
-            goto exit;
-        }
-    }
-    lseek(fd, s->l1_table_offset, SEEK_SET);
-    tmp = 0;
-    for(i = 0;i < l1_size; i++) {
-        ret = qemu_write_full(fd, &tmp, sizeof(tmp));
-        if (ret != sizeof(tmp)) {
-            ret = -errno;
-            goto exit;
-        }
-    }
-    lseek(fd, s->refcount_table_offset, SEEK_SET);
-    ret = qemu_write_full(fd, s->refcount_table,
-        reftable_clusters * s->cluster_size);
-    if (ret != reftable_clusters * s->cluster_size) {
-        ret = -errno;
-        goto exit;
     }
 
-    lseek(fd, s->refcount_block_offset, SEEK_SET);
-    ret = qemu_write_full(fd, s->refcount_block,
-		    ref_clusters * s->cluster_size);
-    if (ret != ref_clusters * s->cluster_size) {
-        ret = -errno;
-        goto exit;
+    /* And if we're supposed to preallocate metadata, do that now */
+    if (prealloc) {
+        ret = preallocate(bs);
+        if (ret < 0) {
+            goto out;
+        }
     }
 
     ret = 0;
-exit:
-    qemu_free(s->refcount_table);
-    qemu_free(s->refcount_block);
-    close(fd);
-
-    /* Preallocate metadata */
-    if (ret == 0 && prealloc) {
-        BlockDriverState *bs;
-        BlockDriver *drv = bdrv_find_format("qcow2");
-        bs = bdrv_new("");
-        bdrv_open(bs, filename, BDRV_O_CACHE_WB | BDRV_O_RDWR, drv);
-        ret = preallocate(bs);
-        bdrv_close(bs);
-    }
-
+out:
+    bdrv_delete(bs);
     return ret;
 }
 
@@ -1111,7 +1018,7 @@
     }
 
     return qcow_create2(filename, sectors, backing_file, backing_fmt, flags,
-        cluster_size, prealloc);
+        cluster_size, prealloc, options);
 }
 
 static int qcow_make_empty(BlockDriverState *bs)
@@ -1154,7 +1061,7 @@
     }
 
     new_l1_size = size_to_l1(s, offset);
-    ret = qcow2_grow_l1_table(bs, new_l1_size);
+    ret = qcow2_grow_l1_table(bs, new_l1_size, true);
     if (ret < 0) {
         return ret;
     }
@@ -1379,6 +1286,7 @@
     .bdrv_snapshot_goto     = qcow2_snapshot_goto,
     .bdrv_snapshot_delete   = qcow2_snapshot_delete,
     .bdrv_snapshot_list     = qcow2_snapshot_list,
+    .bdrv_snapshot_load_tmp     = qcow2_snapshot_load_tmp,
     .bdrv_get_info	= qcow_get_info,
 
     .bdrv_save_vmstate    = qcow_save_vmstate,
diff --git a/block/qcow2.h b/block/qcow2.h
index 356a34a..2d22e5e 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -188,7 +188,7 @@
 int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res);
 
 /* qcow2-cluster.c functions */
-int qcow2_grow_l1_table(BlockDriverState *bs, int min_size);
+int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size);
 void qcow2_l2_cache_reset(BlockDriverState *bs);
 int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
 void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
@@ -211,6 +211,7 @@
 int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id);
 int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
 int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab);
+int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name);
 
 void qcow2_free_snapshots(BlockDriverState *bs);
 int qcow2_read_snapshots(BlockDriverState *bs);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index a5cbb7e..d0393e0 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -97,9 +97,9 @@
 #define FTYPE_CD     1
 #define FTYPE_FD     2
 
-/* if the FD is not accessed during that time (in ms), we try to
+/* if the FD is not accessed during that time (in ns), we try to
    reopen it to see if the disk has been changed */
-#define FD_OPEN_TIMEOUT 1000
+#define FD_OPEN_TIMEOUT (1000000000)
 
 #define MAX_BLOCKSIZE	4096
 
@@ -908,7 +908,7 @@
         return 0;
     last_media_present = (s->fd >= 0);
     if (s->fd >= 0 &&
-        (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
+        (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
         close(s->fd);
         s->fd = -1;
 #ifdef DEBUG_FLOPPY
@@ -917,7 +917,7 @@
     }
     if (s->fd < 0) {
         if (s->fd_got_error &&
-            (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
+            (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
 #ifdef DEBUG_FLOPPY
             printf("No floppy (open delayed)\n");
 #endif
@@ -925,7 +925,7 @@
         }
         s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
         if (s->fd < 0) {
-            s->fd_error_time = qemu_get_clock(rt_clock);
+            s->fd_error_time = get_clock();
             s->fd_got_error = 1;
             if (last_media_present)
                 s->fd_media_changed = 1;
@@ -940,7 +940,7 @@
     }
     if (!last_media_present)
         s->fd_media_changed = 1;
-    s->fd_open_time = qemu_get_clock(rt_clock);
+    s->fd_open_time = get_clock();
     s->fd_got_error = 0;
     return 0;
 }
diff --git a/block_int.h b/block_int.h
index e8e7156..87e60b8 100644
--- a/block_int.h
+++ b/block_int.h
@@ -93,6 +93,8 @@
     int (*bdrv_snapshot_delete)(BlockDriverState *bs, const char *snapshot_id);
     int (*bdrv_snapshot_list)(BlockDriverState *bs,
                               QEMUSnapshotInfo **psn_info);
+    int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs,
+                                  const char *snapshot_name);
     int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
 
     int (*bdrv_save_vmstate)(BlockDriverState *bs, const uint8_t *buf,
diff --git a/configure b/configure
index 9ed05de..f62c1fe 100755
--- a/configure
+++ b/configure
@@ -92,6 +92,7 @@
 libs_tools=""
 audio_pt_int=""
 audio_win_int=""
+cc_i386=i386-pc-linux-gnu-gcc
 
 # parse CC options first
 for opt do
@@ -789,12 +790,14 @@
     i386)
            QEMU_CFLAGS="-m32 $QEMU_CFLAGS"
            LDFLAGS="-m32 $LDFLAGS"
+           cc_i386='$(CC) -m32'
            helper_cflags="-fomit-frame-pointer"
            host_guest_base="yes"
            ;;
     x86_64)
            QEMU_CFLAGS="-m64 $QEMU_CFLAGS"
            LDFLAGS="-m64 $LDFLAGS"
+           cc_i386='$(CC) -m32'
            host_guest_base="yes"
            ;;
     arm*)
@@ -2348,6 +2351,7 @@
 printf " '%s'" "$0" "$@" >> $config_host_mak
 echo >> $config_host_mak
 
+echo all: >> $config_host_mak
 echo "prefix=$prefix" >> $config_host_mak
 echo "bindir=$bindir" >> $config_host_mak
 echo "mandir=$mandir" >> $config_host_mak
@@ -2639,6 +2643,7 @@
 echo "INSTALL_DATA=$install -m0644 -p" >> $config_host_mak
 echo "INSTALL_PROG=$install -m0755 -p" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
+echo "CC_I386=$cc_i386" >> $config_host_mak
 echo "HOST_CC=$host_cc" >> $config_host_mak
 if test "$sparse" = "yes" ; then
   echo "CC      := REAL_CC=\"\$(CC)\" cgcc"       >> $config_host_mak
diff --git a/cpu-all.h b/cpu-all.h
index 67a3266..11edddc 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -773,7 +773,7 @@
                           int flags);
 
 void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
-    __attribute__ ((__format__ (__printf__, 2, 3)));
+    GCC_FMT_ATTR(2, 3);
 extern CPUState *first_cpu;
 extern CPUState *cpu_single_env;
 
diff --git a/cris-dis.c b/cris-dis.c
index 455ba8a..afd775c 100644
--- a/cris-dis.c
+++ b/cris-dis.c
@@ -18,13 +18,11 @@
    You should have received a copy of the GNU General Public License
    along with this program; if not, see <http://www.gnu.org/licenses/>. */
 
+#include "qemu-common.h"
 #include "dis-asm.h"
 //#include "sysdep.h"
 #include "target-cris/opcode-cris.h"
 //#include "libiberty.h"
-
-
-void *qemu_malloc(size_t len); /* can't include qemu-common.h here */
 
 #define CONST_STRNEQ(STR1,STR2) (strncmp ((STR1), (STR2), sizeof (STR2) - 1) == 0)
 
diff --git a/disas.h b/disas.h
index 6a9332d..f9287f7 100644
--- a/disas.h
+++ b/disas.h
@@ -8,11 +8,8 @@
 void disas(FILE *out, void *code, unsigned long size);
 void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
 
-/* The usual mess... FIXME: Remove this condition once dyngen-exec.h is gone */
-#ifndef __DYNGEN_EXEC_H__
 void monitor_disas(Monitor *mon, CPUState *env,
                    target_ulong pc, int nb_insn, int is_physical, int flags);
-#endif
 
 /* Look up symbol for debugging purpose.  Returns "" if unknown. */
 const char *lookup_symbol(target_ulong orig_addr);
diff --git a/dyngen-exec.h b/dyngen-exec.h
index 5bfef3f..db00fba 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -19,19 +19,7 @@
 #if !defined(__DYNGEN_EXEC_H__)
 #define __DYNGEN_EXEC_H__
 
-/* prevent Solaris from trying to typedef FILE in gcc's
-   include/floatingpoint.h which will conflict with the
-   definition down below */
-#ifdef __sun__
-#define _FILEDEFED
-#endif
-
-/* NOTE: standard headers should be used with special care at this
-   point because host CPU registers are used as global variables. Some
-   host headers do not allow that. */
-#include <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
+#include "qemu-common.h"
 
 #ifdef __OpenBSD__
 #include <sys/types.h>
@@ -40,15 +28,6 @@
 /* XXX: This may be wrong for 64-bit ILP32 hosts.  */
 typedef void * host_reg_t;
 
-#ifdef CONFIG_BSD
-typedef struct __sFILE FILE;
-#else
-typedef struct FILE FILE;
-#endif
-extern int fprintf(FILE *, const char *, ...);
-extern int fputs(const char *, FILE *);
-extern int printf(const char *, ...);
-
 #if defined(__i386__)
 #define AREG0 "ebp"
 #elif defined(__x86_64__)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 06b6e14..bc3e916 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -65,6 +65,7 @@
 static void ide_dma_restart(IDEState *s, int is_read);
 static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
 static int ide_handle_rw_error(IDEState *s, int error, int op);
+static void ide_flush_cache(IDEState *s);
 
 static void padstr(char *str, const char *src, int len)
 {
@@ -146,8 +147,8 @@
     put_le16(p + 68, 120);
     put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
     put_le16(p + 81, 0x16); /* conforms to ata5 */
-    /* 14=NOP supported, 0=SMART supported */
-    put_le16(p + 82, (1 << 14) | 1);
+    /* 14=NOP supported, 5=WCACHE supported, 0=SMART supported */
+    put_le16(p + 82, (1 << 14) | (1 << 5) | 1);
     /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
     put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
     /* 14=set to 1, 1=SMART self test, 0=SMART error logging */
@@ -688,6 +689,8 @@
         } else {
             ide_sector_write(bmdma_active_if(bm));
         }
+    } else if (bm->status & BM_STATUS_RETRY_FLUSH) {
+        ide_flush_cache(bmdma_active_if(bm));
     }
 }
 
@@ -795,12 +798,26 @@
 {
     IDEState *s = opaque;
 
-    /* XXX: how do we signal I/O errors here? */
+    if (ret < 0) {
+        /* XXX: What sector number to set here? */
+        if (ide_handle_rw_error(s, -ret, BM_STATUS_RETRY_FLUSH)) {
+            return;
+        }
+    }
 
     s->status = READY_STAT | SEEK_STAT;
     ide_set_irq(s->bus);
 }
 
+static void ide_flush_cache(IDEState *s)
+{
+    if (s->bs) {
+        bdrv_aio_flush(s->bs, ide_flush_cb, s);
+    } else {
+        ide_flush_cb(s, 0);
+    }
+}
+
 static inline void cpu_to_ube16(uint8_t *buf, int val)
 {
     buf[0] = val >> 8;
@@ -2031,10 +2048,7 @@
             break;
         case WIN_FLUSH_CACHE:
         case WIN_FLUSH_CACHE_EXT:
-            if (s->bs)
-                bdrv_aio_flush(s->bs, ide_flush_cb, s);
-            else
-                ide_flush_cb(s, 0);
+            ide_flush_cache(s);
             break;
         case WIN_STANDBY:
         case WIN_STANDBY2:
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 4165543..d652e06 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -472,7 +472,8 @@
 #define BM_STATUS_INT    0x04
 #define BM_STATUS_DMA_RETRY  0x08
 #define BM_STATUS_PIO_RETRY  0x10
-#define BM_STATUS_RETRY_READ 0x20
+#define BM_STATUS_RETRY_READ  0x20
+#define BM_STATUS_RETRY_FLUSH 0x40
 
 #define BM_CMD_START     0x01
 #define BM_CMD_READ      0x08
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index f9723f5..07eb9ee 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -295,7 +295,7 @@
     ram_offset = qemu_ram_alloc(NULL, "fulong2e.ram", ram_size);
     bios_offset = qemu_ram_alloc(NULL, "fulong2e.bios", bios_size);
 
-    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+    cpu_register_physical_memory(0, ram_size, ram_offset);
     cpu_register_physical_memory(0x1fc00000LL,
 					   bios_size, bios_offset | IO_MEM_ROM);
 
diff --git a/hw/omap_clk.c b/hw/omap_clk.c
index 6bcabef..10c9c43 100644
--- a/hw/omap_clk.c
+++ b/hw/omap_clk.c
@@ -20,6 +20,7 @@
  */
 #include "hw.h"
 #include "omap.h"
+#include "qemu-timer.h" /* for muldiv64() */
 
 struct clk {
     const char *name;
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index a1df26d..dbe20707 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -106,7 +106,13 @@
 {
     VirtIOBlockReq *req = opaque;
 
-    virtio_blk_req_complete(req, ret ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK);
+    if (ret) {
+        if (virtio_blk_handle_rw_error(req, -ret, 0)) {
+            return;
+        }
+    }
+
+    virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
 }
 
 static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index d0d4b6a..f79c342 100644
--- a/pc-bios/bios.bin
+++ b/pc-bios/bios.bin
Binary files differ
diff --git a/qemu-common.h b/qemu-common.h
index 81aafa0..2fbc27f 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -18,11 +18,6 @@
 typedef struct QEMUBH QEMUBH;
 typedef struct DeviceState DeviceState;
 
-/* Hack around the mess dyngen-exec.h causes: We need QEMU_NORETURN in files that
-   cannot include the following headers without conflicts. This condition has
-   to be removed once dyngen is gone. */
-#ifndef __DYNGEN_EXEC_H__
-
 /* we put basic includes here to avoid repeating them in device drivers */
 #include <stdlib.h>
 #include <stdio.h>
@@ -138,8 +133,6 @@
 int qemu_bh_poll(void);
 void qemu_bh_update_timeout(int *timeout);
 
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
-
 void qemu_get_timedate(struct tm *tm, int offset);
 int qemu_timedate_diff(struct tm *tm);
 
@@ -318,6 +311,4 @@
 
 #include "module.h"
 
-#endif /* dyngen-exec.h hack */
-
 #endif
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 6d3e5f8..6c7176f 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -28,9 +28,9 @@
 ETEXI
 
 DEF("convert", img_convert,
-    "convert [-c] [-f fmt] [-O output_fmt] [-o options] filename [filename2 [...]] output_filename")
+    "convert [-c] [-f fmt] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
 STEXI
-@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 578b8eb..2864cb8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -645,14 +645,16 @@
     const uint8_t *buf1;
     BlockDriverInfo bdi;
     QEMUOptionParameter *param = NULL, *create_options = NULL;
+    QEMUOptionParameter *out_baseimg_param;
     char *options = NULL;
+    const char *snapshot_name = NULL;
 
     fmt = NULL;
     out_fmt = "raw";
     out_baseimg = NULL;
     flags = 0;
     for(;;) {
-        c = getopt(argc, argv, "f:O:B:hce6o:");
+        c = getopt(argc, argv, "f:O:B:s:hce6o:");
         if (c == -1)
             break;
         switch(c) {
@@ -680,6 +682,9 @@
         case 'o':
             options = optarg;
             break;
+        case 's':
+            snapshot_name = optarg;
+            break;
         }
     }
 
@@ -711,6 +716,19 @@
         total_sectors += bs_sectors;
     }
 
+    if (snapshot_name != NULL) {
+        if (bs_n > 1) {
+            error("No support for concatenating multiple snapshot\n");
+            ret = -1;
+            goto out;
+        }
+        if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
+            error("Failed to load snapshot\n");
+            ret = -1;
+            goto out;
+        }
+    }
+
     /* Find driver and parse its options */
     drv = bdrv_find_format(out_fmt);
     if (!drv) {
@@ -752,6 +770,12 @@
         goto out;
     }
 
+    /* Get backing file name if -o backing_file was used */
+    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
+    if (out_baseimg_param) {
+        out_baseimg = out_baseimg_param->value.s;
+    }
+
     /* Check if compression is supported */
     if (flags & BLOCK_FLAG_COMPRESS) {
         QEMUOptionParameter *encryption =
diff --git a/qemu-img.texi b/qemu-img.texi
index c1b1f27..1b90ddb 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -77,9 +77,9 @@
 
 Commit the changes recorded in @var{filename} in its base image.
 
-@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 
-Convert the disk image @var{filename} to disk image @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}
 option) or use any format specific options like encryption (@code{-o} option).
 
diff --git a/qemu-io.c b/qemu-io.c
index b4e5cc8..ff353eb 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -1443,6 +1443,44 @@
 };
 
 static int
+map_f(int argc, char **argv)
+{
+	int64_t offset;
+	int64_t nb_sectors;
+	char s1[64];
+	int num, num_checked;
+	int ret;
+	const char *retstr;
+
+	offset = 0;
+	nb_sectors = bs->total_sectors;
+
+	do {
+		num_checked = MIN(nb_sectors, INT_MAX);
+		ret = bdrv_is_allocated(bs, offset, num_checked, &num);
+		retstr = ret ? "    allocated" : "not allocated";
+		cvtstr(offset << 9ULL, s1, sizeof(s1));
+		printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
+				offset << 9ULL, num, num_checked, retstr, s1, ret);
+
+		offset += num;
+		nb_sectors -= num;
+	} while(offset < bs->total_sectors);
+
+	return 0;
+}
+
+static const cmdinfo_t map_cmd = {
+       .name           = "map",
+       .argmin         = 0,
+       .argmax         = 0,
+       .cfunc          = map_f,
+       .args           = "",
+       .oneline        = "prints the allocated areas of a file",
+};
+
+
+static int
 close_f(int argc, char **argv)
 {
 	bdrv_close(bs);
@@ -1680,6 +1718,7 @@
 	add_command(&length_cmd);
 	add_command(&info_cmd);
 	add_command(&alloc_cmd);
+	add_command(&map_cmd);
 
 	add_args_command(init_args_command);
 	add_check_command(init_check_command);
diff --git a/qemu-timer-common.c b/qemu-timer-common.c
new file mode 100644
index 0000000..fff4399
--- /dev/null
+++ b/qemu-timer-common.c
@@ -0,0 +1,62 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu-timer.h"
+
+/***********************************************************/
+/* real time host monotonic timer */
+
+#ifdef _WIN32
+
+int64_t clock_freq;
+
+static void __attribute__((constructor)) init_get_clock(void)
+{
+    LARGE_INTEGER freq;
+    int ret;
+    ret = QueryPerformanceFrequency(&freq);
+    if (ret == 0) {
+        fprintf(stderr, "Could not calibrate ticks\n");
+        exit(1);
+    }
+    clock_freq = freq.QuadPart;
+}
+
+#else
+
+int use_rt_clock;
+
+static void __attribute__((constructor)) init_get_clock(void)
+{
+    use_rt_clock = 0;
+#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
+    || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+    {
+        struct timespec ts;
+        if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+            use_rt_clock = 1;
+        }
+    }
+#endif
+}
+#endif
diff --git a/qemu-timer.c b/qemu-timer.c
index bc5f207..95814af 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -64,78 +64,6 @@
 static QEMUTimer *icount_rt_timer;
 static QEMUTimer *icount_vm_timer;
 
-
-/***********************************************************/
-/* real time host monotonic timer */
-
-
-static int64_t get_clock_realtime(void)
-{
-    struct timeval tv;
-
-    gettimeofday(&tv, NULL);
-    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
-}
-
-#ifdef WIN32
-
-static int64_t clock_freq;
-
-static void init_get_clock(void)
-{
-    LARGE_INTEGER freq;
-    int ret;
-    ret = QueryPerformanceFrequency(&freq);
-    if (ret == 0) {
-        fprintf(stderr, "Could not calibrate ticks\n");
-        exit(1);
-    }
-    clock_freq = freq.QuadPart;
-}
-
-static int64_t get_clock(void)
-{
-    LARGE_INTEGER ti;
-    QueryPerformanceCounter(&ti);
-    return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
-}
-
-#else
-
-static int use_rt_clock;
-
-static void init_get_clock(void)
-{
-    use_rt_clock = 0;
-#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
-    || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
-    {
-        struct timespec ts;
-        if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
-            use_rt_clock = 1;
-        }
-    }
-#endif
-}
-
-static int64_t get_clock(void)
-{
-#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
-	|| defined(__DragonFly__) || defined(__FreeBSD_kernel__)
-    if (use_rt_clock) {
-        struct timespec ts;
-        clock_gettime(CLOCK_MONOTONIC, &ts);
-        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
-    } else
-#endif
-    {
-        /* XXX: using gettimeofday leads to problems if the date
-           changes, so it should be avoided. */
-        return get_clock_realtime();
-    }
-}
-#endif
-
 /***********************************************************/
 /* guest cycle counter */
 
@@ -614,7 +542,6 @@
 
 void init_clocks(void)
 {
-    init_get_clock();
     rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
     vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
     host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
diff --git a/qemu-timer.h b/qemu-timer.h
index 1494f79..299e387 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -2,6 +2,13 @@
 #define QEMU_TIMER_H
 
 #include "qemu-common.h"
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <mmsystem.h>
+#endif
 
 /* timers */
 
@@ -52,6 +59,73 @@
     return 1000000000LL;
 }
 
+/* compute with 96 bit intermediate result: (a*b)/c */
+static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+{
+    union {
+        uint64_t ll;
+        struct {
+#ifdef HOST_WORDS_BIGENDIAN
+            uint32_t high, low;
+#else
+            uint32_t low, high;
+#endif
+        } l;
+    } u, res;
+    uint64_t rl, rh;
+
+    u.ll = a;
+    rl = (uint64_t)u.l.low * (uint64_t)b;
+    rh = (uint64_t)u.l.high * (uint64_t)b;
+    rh += (rl >> 32);
+    res.l.high = rh / c;
+    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+    return res.ll;
+}
+
+/* real time host monotonic timer */
+static inline int64_t get_clock_realtime(void)
+{
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
+}
+
+/* Warning: don't insert tracepoints into these functions, they are
+   also used by simpletrace backend and tracepoints would cause
+   an infinite recursion! */
+#ifdef _WIN32
+extern int64_t clock_freq;
+
+static inline int64_t get_clock(void)
+{
+    LARGE_INTEGER ti;
+    QueryPerformanceCounter(&ti);
+    return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
+}
+
+#else
+
+extern int use_rt_clock;
+
+static inline int64_t get_clock(void)
+{
+#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
+    || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+    if (use_rt_clock) {
+        struct timespec ts;
+        clock_gettime(CLOCK_MONOTONIC, &ts);
+        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
+    } else
+#endif
+    {
+        /* XXX: using gettimeofday leads to problems if the date
+           changes, so it should be avoided. */
+        return get_clock_realtime();
+    }
+}
+#endif
 
 void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
 void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
diff --git a/qemu-tool.c b/qemu-tool.c
index b39af86..9ccca65 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -110,10 +110,3 @@
 {
     return 0;
 }
-
-int64_t qemu_get_clock(QEMUClock *clock)
-{
-    qemu_timeval tv;
-    qemu_gettimeofday(&tv);
-    return (tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000)) / 1000000;
-}
diff --git a/roms/seabios b/roms/seabios
index 17d3e46..0ff9051 160000
--- a/roms/seabios
+++ b/roms/seabios
@@ -1 +1 @@
-Subproject commit 17d3e46511aeedc9f09a8216d194d749187b80aa
+Subproject commit 0ff9051f756ba739bc2edca77925191c3c6cbc2f
diff --git a/rules.mak b/rules.mak
index c843a13..6dac777 100644
--- a/rules.mak
+++ b/rules.mak
@@ -42,6 +42,15 @@
 VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.texi
 set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1)))
 
+# find-in-path
+# Usage: $(call find-in-path, prog)
+# Looks in the PATH if the argument contains no slash, else only considers one
+# specific directory.  Returns an # empty string if the program doesn't exist
+# there.
+find-in-path = $(if $(find-string /, $1), \
+        $(wildcard $1), \
+        $(wildcard $(patsubst %, %/$1, $(subst :, ,$(PATH)))))
+
 # Generate timestamp files for .h include files
 
 %.h: %.h-timestamp
diff --git a/simpletrace.c b/simpletrace.c
index b488d51..9ea0d1f 100644
--- a/simpletrace.c
+++ b/simpletrace.c
@@ -12,6 +12,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <time.h>
+#include "qemu-timer.h"
 #include "trace.h"
 
 /** Trace file header event ID */
@@ -140,20 +141,13 @@
                   uint64_t x4, uint64_t x5, uint64_t x6)
 {
     TraceRecord *rec = &trace_buf[trace_idx];
-    struct timespec ts;
-
-    /* TODO Windows?  It would be good to use qemu-timer here but that isn't
-     * linked into qemu-tools.  Also we should avoid recursion in the tracing
-     * code, therefore it is useful to be self-contained.
-     */
-    clock_gettime(CLOCK_MONOTONIC, &ts);
 
     if (!trace_list[event].state) {
         return;
     }
 
     rec->event = event;
-    rec->timestamp_ns = ts.tv_sec * 1000000000LL + ts.tv_nsec;
+    rec->timestamp_ns = get_clock();
     rec->x1 = x1;
     rec->x2 = x2;
     rec->x3 = x3;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 512d533..ae0a034 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -15,6 +15,7 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
+#include <sys/utsname.h>
 
 #include <linux/kvm.h>
 
@@ -53,6 +54,8 @@
 #define BUS_MCEERR_AO 5
 #endif
 
+static int lm_capable_kernel;
+
 #ifdef KVM_CAP_EXT_CPUID
 
 static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
@@ -239,12 +242,16 @@
     struct kvm_x86_mce_data *data = _data;
     int r;
 
-    /* If there is an MCE excpetion being processed, ignore this SRAO MCE */
-    r = kvm_mce_in_exception(data->env);
-    if (r == -1)
-        fprintf(stderr, "Failed to get MCE status\n");
-    else if (r && !(data->mce->status & MCI_STATUS_AR))
-        return;
+    /* If there is an MCE exception being processed, ignore this SRAO MCE */
+    if ((data->env->mcg_cap & MCG_SER_P) &&
+        !(data->mce->status & MCI_STATUS_AR)) {
+        r = kvm_mce_in_exception(data->env);
+        if (r == -1) {
+            fprintf(stderr, "Failed to get MCE status\n");
+        } else if (r) {
+            return;
+        }
+    }
 
     r = kvm_set_mce(data->env, data->mce);
     if (r < 0) {
@@ -434,23 +441,26 @@
     }
 }
 
-static int kvm_has_msr_star(CPUState *env)
+int has_msr_star;
+int has_msr_hsave_pa;
+
+static void kvm_supported_msrs(CPUState *env)
 {
-    static int has_msr_star;
+    static int kvm_supported_msrs;
     int ret;
 
     /* first time */
-    if (has_msr_star == 0) {        
+    if (kvm_supported_msrs == 0) {
         struct kvm_msr_list msr_list, *kvm_msr_list;
 
-        has_msr_star = -1;
+        kvm_supported_msrs = -1;
 
         /* Obtain MSR list from KVM.  These are the MSRs that we must
          * save/restore */
         msr_list.nmsrs = 0;
         ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list);
         if (ret < 0 && ret != -E2BIG) {
-            return 0;
+            return;
         }
         /* Old kernel modules had a bug and could write beyond the provided
            memory. Allocate at least a safe amount of 1K. */
@@ -466,7 +476,11 @@
             for (i = 0; i < kvm_msr_list->nmsrs; i++) {
                 if (kvm_msr_list->indices[i] == MSR_STAR) {
                     has_msr_star = 1;
-                    break;
+                    continue;
+                }
+                if (kvm_msr_list->indices[i] == MSR_VM_HSAVE_PA) {
+                    has_msr_hsave_pa = 1;
+                    continue;
                 }
             }
         }
@@ -474,9 +488,19 @@
         free(kvm_msr_list);
     }
 
-    if (has_msr_star == 1)
-        return 1;
-    return 0;
+    return;
+}
+
+static int kvm_has_msr_hsave_pa(CPUState *env)
+{
+    kvm_supported_msrs(env);
+    return has_msr_hsave_pa;
+}
+
+static int kvm_has_msr_star(CPUState *env)
+{
+    kvm_supported_msrs(env);
+    return has_msr_star;
 }
 
 static int kvm_init_identity_map_page(KVMState *s)
@@ -502,6 +526,11 @@
 {
     int ret;
 
+    struct utsname utsname;
+
+    uname(&utsname);
+    lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;
+
     /* create vm86 tss.  KVM uses vm86 mode to emulate 16-bit code
      * directly.  In order to use vm86 mode, a TSS is needed.  Since this
      * must be part of guest physical memory, we need to allocate it.  Older
@@ -779,28 +808,40 @@
         struct kvm_msr_entry entries[100];
     } msr_data;
     struct kvm_msr_entry *msrs = msr_data.entries;
-    int i, n = 0;
+    int n = 0;
 
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
     if (kvm_has_msr_star(env))
 	kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star);
+    if (kvm_has_msr_hsave_pa(env))
+        kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave);
 #ifdef TARGET_X86_64
-    /* FIXME if lm capable */
-    kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
-    kvm_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase);
-    kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
-    kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
+    if (lm_capable_kernel) {
+        kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
+        kvm_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase);
+        kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
+        kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
+    }
 #endif
     if (level == KVM_PUT_FULL_STATE) {
-        kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
+        /*
+         * KVM is yet unable to synchronize TSC values of multiple VCPUs on
+         * writeback. Until this is fixed, we only write the offset to SMP
+         * guests after migration, desynchronizing the VCPUs, but avoiding
+         * huge jump-backs that would occur without any writeback at all.
+         */
+        if (smp_cpus == 1 || env->tsc != 0) {
+            kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
+        }
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME,
                           env->system_time_msr);
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
     }
 #ifdef KVM_CAP_MCE
     if (env->mcg_cap) {
+        int i;
         if (level == KVM_PUT_RESET_STATE)
             kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status);
         else if (level == KVM_PUT_FULL_STATE) {
@@ -1010,13 +1051,16 @@
     msrs[n++].index = MSR_IA32_SYSENTER_EIP;
     if (kvm_has_msr_star(env))
 	msrs[n++].index = MSR_STAR;
+    if (kvm_has_msr_hsave_pa(env))
+        msrs[n++].index = MSR_VM_HSAVE_PA;
     msrs[n++].index = MSR_IA32_TSC;
 #ifdef TARGET_X86_64
-    /* FIXME lm_capable_kernel */
-    msrs[n++].index = MSR_CSTAR;
-    msrs[n++].index = MSR_KERNELGSBASE;
-    msrs[n++].index = MSR_FMASK;
-    msrs[n++].index = MSR_LSTAR;
+    if (lm_capable_kernel) {
+        msrs[n++].index = MSR_CSTAR;
+        msrs[n++].index = MSR_KERNELGSBASE;
+        msrs[n++].index = MSR_FMASK;
+        msrs[n++].index = MSR_LSTAR;
+    }
 #endif
     msrs[n++].index = MSR_KVM_SYSTEM_TIME;
     msrs[n++].index = MSR_KVM_WALL_CLOCK;
@@ -1066,6 +1110,9 @@
         case MSR_IA32_TSC:
             env->tsc = msrs[i].data;
             break;
+        case MSR_VM_HSAVE_PA:
+            env->vm_hsave = msrs[i].data;
+            break;
         case MSR_KVM_SYSTEM_TIME:
             env->system_time_msr = msrs[i].data;
             break;
@@ -1085,9 +1132,9 @@
             if (msrs[i].index >= MSR_MC0_CTL &&
                 msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
                 env->mce_banks[msrs[i].index - MSR_MC0_CTL] = msrs[i].data;
-                break;
             }
 #endif
+            break;
         }
     }
 
@@ -1632,6 +1679,28 @@
     exit(1);
 }
 
+#ifdef KVM_CAP_MCE
+static void kvm_mce_broadcast_rest(CPUState *env)
+{
+    CPUState *cenv;
+    int family, model, cpuver = env->cpuid_version;
+
+    family = (cpuver >> 8) & 0xf;
+    model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0xf);
+
+    /* Broadcast MCA signal for processor version 06H_EH and above */
+    if ((family == 6 && model >= 14) || family > 6) {
+        for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
+            if (cenv == env) {
+                continue;
+            }
+            kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
+                               MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1);
+        }
+    }
+}
+#endif
+
 int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
 {
 #if defined(KVM_CAP_MCE)
@@ -1689,6 +1758,7 @@
             fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
             abort();
         }
+        kvm_mce_broadcast_rest(env);
     } else
 #endif
     {
@@ -1711,7 +1781,6 @@
         void *vaddr;
         ram_addr_t ram_addr;
         target_phys_addr_t paddr;
-        CPUState *cenv;
 
         /* Hope we are lucky for AO MCE */
         vaddr = addr;
@@ -1727,10 +1796,7 @@
         kvm_inject_x86_mce(first_cpu, 9, status,
                            MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
                            (MCM_ADDR_PHYS << 6) | 0xc, 1);
-        for (cenv = first_cpu->next_cpu; cenv != NULL; cenv = cenv->next_cpu) {
-            kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
-                               MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1);
-        }
+        kvm_mce_broadcast_rest(first_cpu);
     } else
 #endif
     {
diff --git a/tests/Makefile b/tests/Makefile
index ff7f787..e43ec70 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,83 +1,120 @@
 -include ../config-host.mak
+-include $(SRC_PATH)/rules.mak
 
 $(call set-vpath, $(SRC_PATH)/tests)
 
-CFLAGS=-Wall -O2 -g -fno-strict-aliasing
+QEMU=../i386-linux-user/qemu-i386
+QEMU_X86_64=../x86_64-linux-user/qemu-x86_64
+CC_X86_64=$(CC_I386) -m64
+
+CFLAGS=-Wall -O2 -g -fno-strict-aliasing -I..
 #CFLAGS+=-msse2
 LDFLAGS=
 
-ifeq ($(ARCH),i386)
-TESTS=linux-test testthread sha1-i386 test-i386
+# TODO: automatically detect ARM and MIPS compilers, and run those too
+
+# runcom maps page 0, so it requires root privileges
+# also, pi_10.com runs indefinitely
+
+I386_TESTS=hello-i386 \
+	   linux-test \
+	   testthread \
+	   sha1-i386 \
+	   test-i386 \
+	   test-mmap \
+	   # runcom
+
+# native i386 compilers sometimes are not biarch.  assume cross-compilers are
+ifneq ($(ARCH),i386)
+I386_TESTS+=run-test-x86_64
 endif
-ifeq ($(ARCH),x86_64)
-TESTS=test-x86_64
+
+TESTS = test_path
+ifneq ($(call find-in-path, $(CC_I386)),)
+TESTS += $(I386_TESTS)
 endif
-TESTS+=sha1# test_path
-#TESTS+=test_path
-#TESTS+=runcom
 
-QEMU=../i386-linux-user/qemu-i386
+all: $(patsubst %,run-%,$(TESTS))
 
-all: $(TESTS)
+# rules to run tests
 
-hello-i386: hello-i386.c
-	$(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
-	strip $@
+.PHONY: $(patsubst %,run-%,$(TESTS))
 
-testthread: testthread.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread
+run-%: %
+	-$(QEMU) ./$*
 
-test_path: test_path.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
-	./$@ || { rm $@; exit 1; }
+run-hello-i386: hello-i386
+run-linux-test: linux-test
+run-testthread: testthread
+run-sha1-i386: sha1-i386
 
-# i386/x86_64 emulation test (test various opcodes) */
-test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
-           test-i386.h test-i386-shift.h test-i386-muldiv.h
-	$(CC) -m32 $(CFLAGS) $(LDFLAGS) -static -o $@ \
-              $(<D)/test-i386.c $(<D)/test-i386-code16.S $(<D)/test-i386-vm86.S -lm
-
-test-x86_64: test-i386.c \
-           test-i386.h test-i386-shift.h test-i386-muldiv.h
-	$(CC) -m64 $(CFLAGS) $(LDFLAGS) -static -o $@ $(<D)/test-i386.c -lm
-
-ifeq ($(ARCH),i386)
-test: test-i386
+run-test-i386: test-i386
 	./test-i386 > test-i386.ref
-else
-test:
-endif
-	$(QEMU) test-i386 > test-i386.out
+	-$(QEMU) test-i386 > test-i386.out
 	@if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
 
-.PHONY: test-mmap
-test-mmap: test-mmap.c
-	$(CC) $(CFLAGS) -Wall -static -O2 $(LDFLAGS) -o $@ $<
-	-./test-mmap
+run-test-x86_64: test-x86_64
+	./test-x86_64 > test-x86_64.ref
+	-$(QEMU_X86_64) test-x86_64 > test-x86_64.out
+	@if diff -u test-x86_64.ref test-x86_64.out ; then echo "Auto Test OK"; fi
+
+run-test-mmap: test-mmap
 	-$(QEMU) ./test-mmap
 	-$(QEMU) -p 8192 ./test-mmap 8192
 	-$(QEMU) -p 16384 ./test-mmap 16384
 	-$(QEMU) -p 32768 ./test-mmap 32768
 
+run-runcom: runcom
+	-$(QEMU) ./runcom $(SRC_PATH)/tests/pi_10.com
+
+run-test_path: test_path
+	./test_path
+
+# rules to compile tests
+
+test_path: test_path.o
+test_path.o: test_path.c
+
+hello-i386: hello-i386.c
+	$(CC_I386) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
+	strip $@
+
+testthread: testthread.c
+	$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread
+
+# i386/x86_64 emulation test (test various opcodes) */
+test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
+           test-i386.h test-i386-shift.h test-i386-muldiv.h
+	$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ \
+              $(<D)/test-i386.c $(<D)/test-i386-code16.S $(<D)/test-i386-vm86.S -lm
+
+test-x86_64: test-i386.c \
+           test-i386.h test-i386-shift.h test-i386-muldiv.h
+	$(CC_X86_64) $(CFLAGS) $(LDFLAGS) -o $@ $(<D)/test-i386.c -lm
+
 # generic Linux and CPU test
 linux-test: linux-test.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm
+	$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm
+
+# vm86 test
+runcom: runcom.c
+	$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $<
+
+test-mmap: test-mmap.c
+	$(CC_I386) -m32 $(CFLAGS) -Wall -O2 $(LDFLAGS) -o $@ $<
 
 # speed test
 sha1-i386: sha1.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+	$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $<
 
 sha1: sha1.c
-	$(HOST_CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
 
 speed: sha1 sha1-i386
 	time ./sha1
 	time $(QEMU) ./sha1-i386
 
-# vm86 test
-runcom: runcom.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
-
+# broken test
 # NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu
 qruncom: qruncom.c ../ioport-user.c ../i386-user/libqemu.a
 	$(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user -I../fpu \
diff --git a/tests/runcom.c b/tests/runcom.c
index 6380566..d60342b 100644
--- a/tests/runcom.c
+++ b/tests/runcom.c
@@ -13,16 +13,13 @@
 #include <linux/unistd.h>
 #include <asm/vm86.h>
 
+extern int vm86 (unsigned long int subfunction,
+		 struct vm86plus_struct *info);
+
+#define VIF_MASK                0x00080000
+
 //#define SIGTEST
 
-#undef __syscall_return
-#define __syscall_return(type, res) \
-do { \
-	return (type) (res); \
-} while (0)
-
-_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
-
 #define COM_BASE_ADDR    0x10100
 
 static void usage(void)
diff --git a/tests/test-i386.c b/tests/test-i386.c
index b28b257..8f481c7 100644
--- a/tests/test-i386.c
+++ b/tests/test-i386.c
@@ -2047,6 +2047,10 @@
 #define RBP "%%ebp"
 #endif
 
+#if !defined(__x86_64__)
+/* causes an infinite loop, disable it for now.  */
+#define TEST_ENTER(size, stack_type, level)
+#else
 #define TEST_ENTER(size, stack_type, level)\
 {\
     long esp_save, esp_val, ebp_val, ebp_save, i;\
@@ -2078,6 +2082,7 @@
     for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
         printf(FMTLX "\n", (long)ptr[0]);\
 }
+#endif
 
 static void test_enter(void)
 {
diff --git a/tests/test_path.c b/tests/test_path.c
index def7441..234ed97 100644
--- a/tests/test_path.c
+++ b/tests/test_path.c
@@ -1,12 +1,21 @@
 /* Test path override code */
-#define _GNU_SOURCE
+#include "../config-host.h"
+#include "../qemu-malloc.c"
+#include "../cutils.c"
 #include "../path.c"
+#include "../trace.c"
+#ifdef CONFIG_SIMPLE_TRACE
+#include "../simpletrace.c"
+#endif
+
 #include <stdarg.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 
+void qemu_log(const char *fmt, ...);
+
 /* Any log message kills the test. */
-void gemu_log(const char *fmt, ...)
+void qemu_log(const char *fmt, ...)
 {
     va_list ap;
 
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 6702dfd..7b4f5c1 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -29,8 +29,7 @@
 
 static int debug = 0;
 
-static void __attribute__((format(printf,2,3)))
-dprint(int level, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3) dprint(int level, const char *fmt, ...)
 {
     va_list args;
 
diff --git a/vl.c b/vl.c
index df414ef..7038952 100644
--- a/vl.c
+++ b/vl.c
@@ -289,30 +289,6 @@
 /***********************************************************/
 /* real time host monotonic timer */
 
-/* compute with 96 bit intermediate result: (a*b)/c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
-    union {
-        uint64_t ll;
-        struct {
-#ifdef HOST_WORDS_BIGENDIAN
-            uint32_t high, low;
-#else
-            uint32_t low, high;
-#endif
-        } l;
-    } u, res;
-    uint64_t rl, rh;
-
-    u.ll = a;
-    rl = (uint64_t)u.l.low * (uint64_t)b;
-    rh = (uint64_t)u.l.high * (uint64_t)b;
-    rh += (rl >> 32);
-    res.l.high = rh / c;
-    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
-    return res.ll;
-}
-
 /***********************************************************/
 /* host time/date access */
 void qemu_get_timedate(struct tm *tm, int offset)