summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile11
-rw-r--r--tests/fdc-test.c181
-rw-r--r--tests/hd-geo-test.c428
-rw-r--r--tests/libqtest.c35
-rwxr-xr-xtests/qemu-iotests/03015
-rwxr-xr-xtests/qemu-iotests/03668
-rw-r--r--tests/qemu-iotests/036.out52
-rwxr-xr-xtests/qemu-iotests/037119
-rw-r--r--tests/qemu-iotests/037.out645
-rwxr-xr-xtests/qemu-iotests/038133
-rw-r--r--tests/qemu-iotests/038.out909
-rw-r--r--tests/qemu-iotests/common11
-rw-r--r--tests/qemu-iotests/common.rc10
-rw-r--r--tests/qemu-iotests/group3
-rw-r--r--tests/qemu-iotests/iotests.py4
-rwxr-xr-xtests/qemu-iotests/qcow2.py23
-rw-r--r--tests/tcg/openrisc/Makefile71
-rw-r--r--tests/tcg/openrisc/test_add.c43
-rw-r--r--tests/tcg/openrisc/test_addc.c38
-rw-r--r--tests/tcg/openrisc/test_addi.c33
-rw-r--r--tests/tcg/openrisc/test_addic.c33
-rw-r--r--tests/tcg/openrisc/test_and_or.c65
-rw-r--r--tests/tcg/openrisc/test_bf.c47
-rw-r--r--tests/tcg/openrisc/test_bnf.c51
-rw-r--r--tests/tcg/openrisc/test_div.c54
-rw-r--r--tests/tcg/openrisc/test_divu.c34
-rw-r--r--tests/tcg/openrisc/test_extx.c78
-rw-r--r--tests/tcg/openrisc/test_fx.c57
-rw-r--r--tests/tcg/openrisc/test_j.c26
-rw-r--r--tests/tcg/openrisc/test_jal.c26
-rw-r--r--tests/tcg/openrisc/test_lf_add.c39
-rw-r--r--tests/tcg/openrisc/test_lf_div.c37
-rw-r--r--tests/tcg/openrisc/test_lf_eqs.c88
-rw-r--r--tests/tcg/openrisc/test_lf_ges.c88
-rw-r--r--tests/tcg/openrisc/test_lf_gts.c86
-rw-r--r--tests/tcg/openrisc/test_lf_les.c88
-rw-r--r--tests/tcg/openrisc/test_lf_lts.c92
-rw-r--r--tests/tcg/openrisc/test_lf_mul.c22
-rw-r--r--tests/tcg/openrisc/test_lf_nes.c89
-rw-r--r--tests/tcg/openrisc/test_lf_rem.c32
-rw-r--r--tests/tcg/openrisc/test_lf_sub.c35
-rw-r--r--tests/tcg/openrisc/test_logic.c105
-rw-r--r--tests/tcg/openrisc/test_lx.c84
-rw-r--r--tests/tcg/openrisc/test_movhi.c31
-rw-r--r--tests/tcg/openrisc/test_mul.c61
-rw-r--r--tests/tcg/openrisc/test_muli.c48
-rw-r--r--tests/tcg/openrisc/test_mulu.c48
-rw-r--r--tests/tcg/openrisc/test_sfeq.c43
-rw-r--r--tests/tcg/openrisc/test_sfeqi.c39
-rw-r--r--tests/tcg/openrisc/test_sfges.c44
-rw-r--r--tests/tcg/openrisc/test_sfgesi.c40
-rw-r--r--tests/tcg/openrisc/test_sfgeu.c44
-rw-r--r--tests/tcg/openrisc/test_sfgeui.c41
-rw-r--r--tests/tcg/openrisc/test_sfgts.c45
-rw-r--r--tests/tcg/openrisc/test_sfgtsi.c41
-rw-r--r--tests/tcg/openrisc/test_sfgtu.c43
-rw-r--r--tests/tcg/openrisc/test_sfgtui.c42
-rw-r--r--tests/tcg/openrisc/test_sfles.c26
-rw-r--r--tests/tcg/openrisc/test_sflesi.c39
-rw-r--r--tests/tcg/openrisc/test_sfleu.c43
-rw-r--r--tests/tcg/openrisc/test_sfleui.c39
-rw-r--r--tests/tcg/openrisc/test_sflts.c43
-rw-r--r--tests/tcg/openrisc/test_sfltsi.c39
-rw-r--r--tests/tcg/openrisc/test_sfltu.c43
-rw-r--r--tests/tcg/openrisc/test_sfltui.c39
-rw-r--r--tests/tcg/openrisc/test_sfne.c43
-rw-r--r--tests/tcg/openrisc/test_sfnei.c39
-rw-r--r--tests/tcg/openrisc/test_sub.c35
-rw-r--r--tests/tcg/xtensa/test_mmu.S221
-rw-r--r--tests/test-iov.c260
-rw-r--r--tests/test-qmp-commands.c42
-rw-r--r--tests/test-qmp-input-visitor.c24
-rw-r--r--tests/test-string-output-visitor.c2
-rw-r--r--tests/test-visitor-serialization.c784
74 files changed, 6505 insertions, 54 deletions
diff --git a/tests/Makefile b/tests/Makefile
index ab7f667009..f3f4159c25 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -13,12 +13,15 @@ check-unit-y += tests/test-qmp-commands$(EXESUF)
 check-unit-y += tests/test-string-input-visitor$(EXESUF)
 check-unit-y += tests/test-string-output-visitor$(EXESUF)
 check-unit-y += tests/test-coroutine$(EXESUF)
+check-unit-y += tests/test-visitor-serialization$(EXESUF)
+check-unit-y += tests/test-iov$(EXESUF)
 
 check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 
 # All QTests for now are POSIX-only, but the dependencies are
 # really in libqtest, not in the testcases themselves.
 check-qtest-i386-y = tests/fdc-test$(EXESUF)
+check-qtest-i386-y += tests/hd-geo-test$(EXESUF)
 check-qtest-i386-y += tests/rtc-test$(EXESUF)
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 check-qtest-sparc-y = tests/m48t59-test$(EXESUF)
@@ -31,13 +34,12 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \
 	tests/test-coroutine.o tests/test-string-output-visitor.o \
 	tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \
 	tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \
-	tests/test-qmp-commands.o
+	tests/test-qmp-commands.o tests/test-visitor-serialization.o
 
 test-qapi-obj-y =  $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y)
 test-qapi-obj-y += tests/test-qapi-visit.o tests/test-qapi-types.o
 test-qapi-obj-y += module.o
 
-$(test-obj-y): $(GENERATED_HEADERS)
 $(test-obj-y): QEMU_INCLUDES += -Itests
 
 tests/check-qint$(EXESUF): tests/check-qint.o qint.o $(tools-obj-y)
@@ -47,6 +49,7 @@ tests/check-qlist$(EXESUF): tests/check-qlist.o qlist.o qint.o $(tools-obj-y)
 tests/check-qfloat$(EXESUF): tests/check-qfloat.o qfloat.o $(tools-obj-y)
 tests/check-qjson$(EXESUF): tests/check-qjson.o $(qobject-obj-y) $(tools-obj-y)
 tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools-obj-y)
+tests/test-iov$(EXESUF): tests/test-iov.o iov.o
 
 tests/test-qapi-types.c tests/test-qapi-types.h :\
 $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
@@ -65,10 +68,12 @@ tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-q
 tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y)
 tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y)
 tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y)
+tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y)
 
 tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y)
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y)
 tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y)
+tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o $(trace-obj-y)
 
 # QTest rules
 
@@ -142,3 +147,5 @@ check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS))
 check-unit: $(patsubst %,check-%, $(check-unit-y))
 check-block: $(patsubst %,check-%, $(check-block-y))
 check: check-unit check-qtest
+
+-include $(wildcard tests/*.d)
diff --git a/tests/fdc-test.c b/tests/fdc-test.c
index 22d24ac7dc..fa7441110d 100644
--- a/tests/fdc-test.c
+++ b/tests/fdc-test.c
@@ -47,8 +47,11 @@ enum {
 };
 
 enum {
-    CMD_SENSE_INT   = 0x08,
-    CMD_SEEK        = 0x0f,
+    CMD_SENSE_INT           = 0x08,
+    CMD_SEEK                = 0x0f,
+    CMD_READ                = 0xe6,
+    CMD_RELATIVE_SEEK_OUT   = 0x8f,
+    CMD_RELATIVE_SEEK_IN    = 0xcf,
 };
 
 enum {
@@ -90,28 +93,89 @@ static uint8_t floppy_recv(void)
     return inb(FLOPPY_BASE + reg_fifo);
 }
 
-static void ack_irq(void)
+/* pcn: Present Cylinder Number */
+static void ack_irq(uint8_t *pcn)
 {
+    uint8_t ret;
+
     g_assert(get_irq(FLOPPY_IRQ));
     floppy_send(CMD_SENSE_INT);
     floppy_recv();
-    floppy_recv();
+
+    ret = floppy_recv();
+    if (pcn != NULL) {
+        *pcn = ret;
+    }
+
+    g_assert(!get_irq(FLOPPY_IRQ));
+}
+
+static uint8_t send_read_command(void)
+{
+    uint8_t drive = 0;
+    uint8_t head = 0;
+    uint8_t cyl = 0;
+    uint8_t sect_addr = 1;
+    uint8_t sect_size = 2;
+    uint8_t eot = 1;
+    uint8_t gap = 0x1b;
+    uint8_t gpl = 0xff;
+
+    uint8_t msr = 0;
+    uint8_t st0;
+
+    uint8_t ret = 0;
+
+    floppy_send(CMD_READ);
+    floppy_send(head << 2 | drive);
     g_assert(!get_irq(FLOPPY_IRQ));
+    floppy_send(cyl);
+    floppy_send(head);
+    floppy_send(sect_addr);
+    floppy_send(sect_size);
+    floppy_send(eot);
+    floppy_send(gap);
+    floppy_send(gpl);
+
+    uint8_t i = 0;
+    uint8_t n = 2;
+    for (; i < n; i++) {
+        msr = inb(FLOPPY_BASE + reg_msr);
+        if (msr == 0xd0) {
+            break;
+        }
+        sleep(1);
+    }
+
+    if (i >= n) {
+        return 1;
+    }
+
+    st0 = floppy_recv();
+    if (st0 != 0x60) {
+        ret = 1;
+    }
+
+    floppy_recv();
+    floppy_recv();
+    floppy_recv();
+    floppy_recv();
+    floppy_recv();
+    floppy_recv();
+
+    return ret;
 }
 
-static void send_step_pulse(void)
+static void send_seek(int cyl)
 {
     int drive = 0;
     int head = 0;
-    static int cyl = 0;
 
     floppy_send(CMD_SEEK);
     floppy_send(head << 2 | drive);
     g_assert(!get_irq(FLOPPY_IRQ));
     floppy_send(cyl);
-    ack_irq();
-
-    cyl = (cyl + 1) % 4;
+    ack_irq(NULL);
 }
 
 static uint8_t cmos_read(uint8_t reg)
@@ -138,14 +202,21 @@ static void test_no_media_on_start(void)
     assert_bit_set(dir, DSKCHG);
     dir = inb(FLOPPY_BASE + reg_dir);
     assert_bit_set(dir, DSKCHG);
-    send_step_pulse();
-    send_step_pulse();
+    send_seek(1);
     dir = inb(FLOPPY_BASE + reg_dir);
     assert_bit_set(dir, DSKCHG);
     dir = inb(FLOPPY_BASE + reg_dir);
     assert_bit_set(dir, DSKCHG);
 }
 
+static void test_read_without_media(void)
+{
+    uint8_t ret;
+
+    ret = send_read_command();
+    g_assert(ret == 0);
+}
+
 static void test_media_change(void)
 {
     uint8_t dir;
@@ -162,7 +233,14 @@ static void test_media_change(void)
     dir = inb(FLOPPY_BASE + reg_dir);
     assert_bit_set(dir, DSKCHG);
 
-    send_step_pulse();
+    send_seek(0);
+    dir = inb(FLOPPY_BASE + reg_dir);
+    assert_bit_set(dir, DSKCHG);
+    dir = inb(FLOPPY_BASE + reg_dir);
+    assert_bit_set(dir, DSKCHG);
+
+    /* Step to next track should clear DSKCHG bit. */
+    send_seek(1);
     dir = inb(FLOPPY_BASE + reg_dir);
     assert_bit_clear(dir, DSKCHG);
     dir = inb(FLOPPY_BASE + reg_dir);
@@ -178,13 +256,86 @@ static void test_media_change(void)
     dir = inb(FLOPPY_BASE + reg_dir);
     assert_bit_set(dir, DSKCHG);
 
-    send_step_pulse();
+    send_seek(0);
+    dir = inb(FLOPPY_BASE + reg_dir);
+    assert_bit_set(dir, DSKCHG);
+    dir = inb(FLOPPY_BASE + reg_dir);
+    assert_bit_set(dir, DSKCHG);
+
+    send_seek(1);
     dir = inb(FLOPPY_BASE + reg_dir);
     assert_bit_set(dir, DSKCHG);
     dir = inb(FLOPPY_BASE + reg_dir);
     assert_bit_set(dir, DSKCHG);
 }
 
+static void test_sense_interrupt(void)
+{
+    int drive = 0;
+    int head = 0;
+    int cyl = 0;
+    int ret = 0;
+
+    floppy_send(CMD_SENSE_INT);
+    ret = floppy_recv();
+    g_assert(ret == 0x80);
+
+    floppy_send(CMD_SEEK);
+    floppy_send(head << 2 | drive);
+    g_assert(!get_irq(FLOPPY_IRQ));
+    floppy_send(cyl);
+
+    floppy_send(CMD_SENSE_INT);
+    ret = floppy_recv();
+    g_assert(ret == 0x20);
+    floppy_recv();
+}
+
+static void test_relative_seek(void)
+{
+    uint8_t drive = 0;
+    uint8_t head = 0;
+    uint8_t cyl = 1;
+    uint8_t pcn;
+
+    /* Send seek to track 0 */
+    send_seek(0);
+
+    /* Send relative seek to increase track by 1 */
+    floppy_send(CMD_RELATIVE_SEEK_IN);
+    floppy_send(head << 2 | drive);
+    g_assert(!get_irq(FLOPPY_IRQ));
+    floppy_send(cyl);
+
+    ack_irq(&pcn);
+    g_assert(pcn == 1);
+
+    /* Send relative seek to decrease track by 1 */
+    floppy_send(CMD_RELATIVE_SEEK_OUT);
+    floppy_send(head << 2 | drive);
+    g_assert(!get_irq(FLOPPY_IRQ));
+    floppy_send(cyl);
+
+    ack_irq(&pcn);
+    g_assert(pcn == 0);
+}
+
+/* success if no crash or abort */
+static void fuzz_registers(void)
+{
+    unsigned int i;
+
+    for (i = 0; i < 1000; i++) {
+        uint8_t reg, val;
+
+        reg = (uint8_t)g_test_rand_int_range(0, 8);
+        val = (uint8_t)g_test_rand_int_range(0, 256);
+
+        outb(FLOPPY_BASE + reg, val);
+        inb(FLOPPY_BASE + reg);
+    }
+}
+
 int main(int argc, char **argv)
 {
     const char *arch = qtest_get_arch();
@@ -214,7 +365,11 @@ int main(int argc, char **argv)
     qtest_irq_intercept_in(global_qtest, "ioapic");
     qtest_add_func("/fdc/cmos", test_cmos);
     qtest_add_func("/fdc/no_media_on_start", test_no_media_on_start);
+    qtest_add_func("/fdc/read_without_media", test_read_without_media);
     qtest_add_func("/fdc/media_change", test_media_change);
+    qtest_add_func("/fdc/sense_interrupt", test_sense_interrupt);
+    qtest_add_func("/fdc/relative_seek", test_relative_seek);
+    qtest_add_func("/fdc/fuzz-registers", fuzz_registers);
 
     ret = g_test_run();
 
diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c
new file mode 100644
index 0000000000..9a31e8587f
--- /dev/null
+++ b/tests/hd-geo-test.c
@@ -0,0 +1,428 @@
+/*
+ * Hard disk geometry test cases.
+ *
+ * Copyright (c) 2012 Red Hat Inc.
+ *
+ * Authors:
+ *  Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+/*
+ * Covers only IDE and tests only CMOS contents.  Better than nothing.
+ * Improvements welcome.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "qemu-common.h"
+#include "libqtest.h"
+
+static const char test_image[] = "/tmp/qtest.XXXXXX";
+
+static char *create_test_img(int secs)
+{
+    char *template = strdup("/tmp/qtest.XXXXXX");
+    int fd, ret;
+
+    fd = mkstemp(template);
+    g_assert(fd >= 0);
+    ret = ftruncate(fd, (off_t)secs * 512);
+    g_assert(ret == 0);
+    close(fd);
+    return template;
+}
+
+typedef struct {
+    int cyls, heads, secs, trans;
+} CHST;
+
+typedef enum {
+    mbr_blank, mbr_lba, mbr_chs,
+    mbr_last
+} MBRcontents;
+
+typedef enum {
+    /* order is relevant */
+    backend_small, backend_large, backend_empty,
+    backend_last
+} Backend;
+
+static const int img_secs[backend_last] = {
+    [backend_small] = 61440,
+    [backend_large] = 8388608,
+    [backend_empty] = -1,
+};
+
+static const CHST hd_chst[backend_last][mbr_last] = {
+    [backend_small] = {
+        [mbr_blank] = { 60, 16, 63, 0 },
+        [mbr_lba]   = { 60, 16, 63, 2 },
+        [mbr_chs]   = { 60, 16, 63, 0 }
+    },
+    [backend_large] = {
+        [mbr_blank] = { 8322, 16, 63, 1 },
+        [mbr_lba]   = { 8322, 16, 63, 1 },
+        [mbr_chs]   = { 8322, 16, 63, 0 }
+    },
+};
+
+static const char *img_file_name[backend_last];
+
+static const CHST *cur_ide[4];
+
+static bool is_hd(const CHST *expected_chst)
+{
+    return expected_chst && expected_chst->cyls;
+}
+
+static void test_cmos_byte(int reg, int expected)
+{
+    enum { cmos_base = 0x70 };
+    int actual;
+
+    outb(cmos_base + 0, reg);
+    actual = inb(cmos_base + 1);
+    g_assert(actual == expected);
+}
+
+static void test_cmos_bytes(int reg0, int n, uint8_t expected[])
+{
+    int i;
+
+    for (i = 0; i < 9; i++) {
+        test_cmos_byte(reg0 + i, expected[i]);
+    }
+}
+
+static void test_cmos_disk_data(void)
+{
+    test_cmos_byte(0x12,
+                   (is_hd(cur_ide[0]) ? 0xf0 : 0) |
+                   (is_hd(cur_ide[1]) ? 0x0f : 0));
+}
+
+static void test_cmos_drive_cyl(int reg0, const CHST *expected_chst)
+{
+    if (is_hd(expected_chst)) {
+        int c = expected_chst->cyls;
+        int h = expected_chst->heads;
+        int s = expected_chst->secs;
+        uint8_t expected_bytes[9] = {
+            c & 0xff, c >> 8, h, 0xff, 0xff, 0xc0 | ((h > 8) << 3),
+            c & 0xff, c >> 8, s
+        };
+        test_cmos_bytes(reg0, 9, expected_bytes);
+    } else {
+        int i;
+
+        for (i = 0; i < 9; i++) {
+            test_cmos_byte(reg0 + i, 0);
+        }
+    }
+}
+
+static void test_cmos_drive1(void)
+{
+    test_cmos_byte(0x19, is_hd(cur_ide[0]) ? 47 : 0);
+    test_cmos_drive_cyl(0x1b, cur_ide[0]);
+}
+
+static void test_cmos_drive2(void)
+{
+    test_cmos_byte(0x1a, is_hd(cur_ide[1]) ? 47 : 0);
+    test_cmos_drive_cyl(0x24, cur_ide[1]);
+}
+
+static void test_cmos_disktransflag(void)
+{
+    int val, i;
+
+    val = 0;
+    for (i = 0; i < ARRAY_SIZE(cur_ide); i++) {
+        if (is_hd(cur_ide[i])) {
+            val |= cur_ide[i]->trans << (2 * i);
+        }
+    }
+    test_cmos_byte(0x39, val);
+}
+
+static void test_cmos(void)
+{
+    test_cmos_disk_data();
+    test_cmos_drive1();
+    test_cmos_drive2();
+    test_cmos_disktransflag();
+}
+
+static int append_arg(int argc, char *argv[], int argv_sz, char *arg)
+{
+    g_assert(argc + 1 < argv_sz);
+    argv[argc++] = arg;
+    argv[argc] = NULL;
+    return argc;
+}
+
+static int setup_common(char *argv[], int argv_sz)
+{
+    memset(cur_ide, 0, sizeof(cur_ide));
+    return append_arg(0, argv, argv_sz,
+                      g_strdup("-nodefaults -display none"));
+}
+
+static void setup_mbr(int img_idx, MBRcontents mbr)
+{
+    static const uint8_t part_lba[16] = {
+        /* chs 0,1,1 (lba 63) to chs 0,127,63 (8001 sectors) */
+        0x80, 1, 1, 0, 6, 127, 63, 0, 63, 0, 0, 0, 0x41, 0x1F, 0, 0,
+    };
+    static const uint8_t part_chs[16] = {
+        /* chs 0,1,1 (lba 63) to chs 7,15,63 (8001 sectors) */
+        0x80, 1, 1, 0, 6,  15, 63, 7, 63, 0, 0, 0, 0x41, 0x1F, 0, 0,
+    };
+    uint8_t buf[512];
+    int fd, ret;
+
+    memset(buf, 0, sizeof(buf));
+
+    if (mbr != mbr_blank) {
+        buf[0x1fe] = 0x55;
+        buf[0x1ff] = 0xAA;
+        memcpy(buf + 0x1BE, mbr == mbr_lba ? part_lba : part_chs, 16);
+    }
+
+    fd = open(img_file_name[img_idx], O_WRONLY);
+    g_assert(fd >= 0);
+    ret = write(fd, buf, sizeof(buf));
+    g_assert(ret == sizeof(buf));
+    close(fd);
+}
+
+static int setup_ide(int argc, char *argv[], int argv_sz,
+                     int ide_idx, const char *dev, int img_idx,
+                     MBRcontents mbr, const char *opts)
+{
+    char *s1, *s2, *s3;
+
+    s1 = g_strdup_printf("-drive id=drive%d,if=%s",
+                         ide_idx, dev ? "none" : "ide");
+    s2 = dev ? g_strdup("") : g_strdup_printf(",index=%d", ide_idx);
+
+    if (img_secs[img_idx] >= 0) {
+        setup_mbr(img_idx, mbr);
+        s3 = g_strdup_printf(",file=%s", img_file_name[img_idx]);
+    } else {
+        s3 = g_strdup(",media=cdrom");
+    }
+    argc = append_arg(argc, argv, argv_sz,
+                      g_strdup_printf("%s%s%s%s", s1, s2, s3, opts));
+    g_free(s1);
+    g_free(s2);
+    g_free(s3);
+
+    if (dev) {
+        argc = append_arg(argc, argv, argv_sz,
+                          g_strdup_printf("-device %s,drive=drive%d,"
+                                          "bus=ide.%d,unit=%d",
+                                          dev, ide_idx,
+                                          ide_idx / 2, ide_idx % 2));
+    }
+    return argc;
+}
+
+/*
+ * Test case: no IDE devices
+ */
+static void test_ide_none(void)
+{
+    char *argv[256];
+
+    setup_common(argv, ARRAY_SIZE(argv));
+    qtest_start(g_strjoinv(" ", argv));
+    test_cmos();
+    qtest_quit(global_qtest);
+}
+
+static void test_ide_mbr(bool use_device, MBRcontents mbr)
+{
+    char *argv[256];
+    int argc;
+    Backend i;
+    const char *dev;
+
+    argc = setup_common(argv, ARRAY_SIZE(argv));
+    for (i = 0; i < backend_last; i++) {
+        cur_ide[i] = &hd_chst[i][mbr];
+        dev = use_device ? (is_hd(cur_ide[i]) ? "ide-hd" : "ide-cd") : NULL;
+        argc = setup_ide(argc, argv, ARRAY_SIZE(argv), i, dev, i, mbr, "");
+    }
+    qtest_start(g_strjoinv(" ", argv));
+    test_cmos();
+    qtest_quit(global_qtest);
+}
+
+/*
+ * Test case: IDE devices (if=ide) with blank MBRs
+ */
+static void test_ide_drive_mbr_blank(void)
+{
+    test_ide_mbr(false, mbr_blank);
+}
+
+/*
+ * Test case: IDE devices (if=ide) with MBRs indicating LBA is in use
+ */
+static void test_ide_drive_mbr_lba(void)
+{
+    test_ide_mbr(false, mbr_lba);
+}
+
+/*
+ * Test case: IDE devices (if=ide) with MBRs indicating CHS is in use
+ */
+static void test_ide_drive_mbr_chs(void)
+{
+    test_ide_mbr(false, mbr_chs);
+}
+
+/*
+ * Test case: IDE devices (if=none) with blank MBRs
+ */
+static void test_ide_device_mbr_blank(void)
+{
+    test_ide_mbr(true, mbr_blank);
+}
+
+/*
+ * Test case: IDE devices (if=none) with MBRs indicating LBA is in use
+ */
+static void test_ide_device_mbr_lba(void)
+{
+    test_ide_mbr(true, mbr_lba);
+}
+
+/*
+ * Test case: IDE devices (if=none) with MBRs indicating CHS is in use
+ */
+static void test_ide_device_mbr_chs(void)
+{
+    test_ide_mbr(true, mbr_chs);
+}
+
+static void test_ide_drive_user(const char *dev, bool trans)
+{
+    char *argv[256], *opts;
+    int argc;
+    int secs = img_secs[backend_small];
+    const CHST expected_chst = { secs / (4 * 32) , 4, 32, trans };
+
+    argc = setup_common(argv, ARRAY_SIZE(argv));
+    opts = g_strdup_printf("%s,%s%scyls=%d,heads=%d,secs=%d",
+                           dev ?: "",
+                           trans && dev ? "bios-chs-" : "",
+                           trans ? "trans=lba," : "",
+                           expected_chst.cyls, expected_chst.heads,
+                           expected_chst.secs);
+    cur_ide[0] = &expected_chst;
+    argc = setup_ide(argc, argv, ARRAY_SIZE(argv),
+                     0, dev ? opts : NULL, backend_small, mbr_chs,
+                     dev ? "" : opts);
+    g_free(opts);
+    qtest_start(g_strjoinv(" ", argv));
+    test_cmos();
+    qtest_quit(global_qtest);
+}
+
+/*
+ * Test case: IDE device (if=ide) with explicit CHS
+ */
+static void test_ide_drive_user_chs(void)
+{
+    test_ide_drive_user(NULL, false);
+}
+
+/*
+ * Test case: IDE device (if=ide) with explicit CHS and translation
+ */
+static void test_ide_drive_user_chst(void)
+{
+    test_ide_drive_user(NULL, true);
+}
+
+/*
+ * Test case: IDE device (if=none) with explicit CHS
+ */
+static void test_ide_device_user_chs(void)
+{
+    test_ide_drive_user("ide-hd", false);
+}
+
+/*
+ * Test case: IDE device (if=none) with explicit CHS and translation
+ */
+static void test_ide_device_user_chst(void)
+{
+    test_ide_drive_user("ide-hd", true);
+}
+
+/*
+ * Test case: IDE devices (if=ide), but use index=0 for CD-ROM
+ */
+static void test_ide_drive_cd_0(void)
+{
+    char *argv[256];
+    int argc, ide_idx;
+    Backend i;
+
+    argc = setup_common(argv, ARRAY_SIZE(argv));
+    for (i = 0; i <= backend_empty; i++) {
+        ide_idx = backend_empty - i;
+        cur_ide[ide_idx] = &hd_chst[i][mbr_blank];
+        argc = setup_ide(argc, argv, ARRAY_SIZE(argv),
+                         ide_idx, NULL, i, mbr_blank, "");
+    }
+    qtest_start(g_strjoinv(" ", argv));
+    test_cmos();
+    qtest_quit(global_qtest);
+}
+
+int main(int argc, char **argv)
+{
+    Backend i;
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+
+    for (i = 0; i < backend_last; i++) {
+        if (img_secs[i] >= 0) {
+            img_file_name[i] = create_test_img(img_secs[i]);
+        } else {
+            img_file_name[i] = NULL;
+        }
+    }
+
+    qtest_add_func("hd-geo/ide/none", test_ide_none);
+    qtest_add_func("hd-geo/ide/drive/mbr/blank", test_ide_drive_mbr_blank);
+    qtest_add_func("hd-geo/ide/drive/mbr/lba", test_ide_drive_mbr_lba);
+    qtest_add_func("hd-geo/ide/drive/mbr/chs", test_ide_drive_mbr_chs);
+    qtest_add_func("hd-geo/ide/drive/user/chs", test_ide_drive_user_chs);
+    qtest_add_func("hd-geo/ide/drive/user/chst", test_ide_drive_user_chst);
+    qtest_add_func("hd-geo/ide/drive/cd_0", test_ide_drive_cd_0);
+    qtest_add_func("hd-geo/ide/device/mbr/blank", test_ide_device_mbr_blank);
+    qtest_add_func("hd-geo/ide/device/mbr/lba", test_ide_device_mbr_lba);
+    qtest_add_func("hd-geo/ide/device/mbr/chs", test_ide_device_mbr_chs);
+    qtest_add_func("hd-geo/ide/device/user/chs", test_ide_device_user_chs);
+    qtest_add_func("hd-geo/ide/device/user/chst", test_ide_device_user_chst);
+
+    ret = g_test_run();
+
+    for (i = 0; i < backend_last; i++) {
+        unlink(img_file_name[i]);
+    }
+
+    return ret;
+}
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 6d333ef0ac..02d039218d 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -40,6 +40,7 @@ struct QTestState
     bool irq_level[MAX_IRQ];
     GString *rx;
     gchar *pid_file;
+    char *socket_path, *qmp_socket_path;
 };
 
 #define g_assert_no_errno(ret) do { \
@@ -74,6 +75,7 @@ static int socket_accept(int sock)
     socklen_t addrlen;
     int ret;
 
+    addrlen = sizeof(addr);
     do {
         ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
     } while (ret == -1 && errno == EINTR);
@@ -87,8 +89,6 @@ QTestState *qtest_init(const char *extra_args)
 {
     QTestState *s;
     int sock, qmpsock, ret, i;
-    gchar *socket_path;
-    gchar *qmp_socket_path;
     gchar *pid_file;
     gchar *command;
     const char *qemu_binary;
@@ -97,14 +97,14 @@ QTestState *qtest_init(const char *extra_args)
     qemu_binary = getenv("QTEST_QEMU_BINARY");
     g_assert(qemu_binary != NULL);
 
-    socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
-    qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
-    pid_file = g_strdup_printf("/tmp/qtest-%d.pid", getpid());
-
     s = g_malloc(sizeof(*s));
 
-    sock = init_socket(socket_path);
-    qmpsock = init_socket(qmp_socket_path);
+    s->socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
+    s->qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
+    pid_file = g_strdup_printf("/tmp/qtest-%d.pid", getpid());
+
+    sock = init_socket(s->socket_path);
+    qmpsock = init_socket(s->qmp_socket_path);
 
     pid = fork();
     if (pid == 0) {
@@ -114,8 +114,8 @@ QTestState *qtest_init(const char *extra_args)
                                   "-qmp unix:%s,nowait "
                                   "-pidfile %s "
                                   "-machine accel=qtest "
-                                  "%s", qemu_binary, socket_path,
-                                  qmp_socket_path, pid_file,
+                                  "%s", qemu_binary, s->socket_path,
+                                  s->qmp_socket_path, pid_file,
                                   extra_args ?: "");
 
         ret = system(command);
@@ -132,9 +132,6 @@ QTestState *qtest_init(const char *extra_args)
         s->irq_level[i] = false;
     }
 
-    g_free(socket_path);
-    g_free(qmp_socket_path);
-
     /* Read the QMP greeting and then do the handshake */
     qtest_qmp(s, "");
     qtest_qmp(s, "{ 'execute': 'qmp_capabilities' }");
@@ -159,6 +156,13 @@ void qtest_quit(QTestState *s)
 
         fclose(f);
     }
+
+    unlink(s->pid_file);
+    unlink(s->socket_path);
+    unlink(s->qmp_socket_path);
+    g_free(s->pid_file);
+    g_free(s->socket_path);
+    g_free(s->qmp_socket_path);
 }
 
 static void socket_sendf(int fd, const char *fmt, va_list ap)
@@ -290,6 +294,11 @@ void qtest_qmp(QTestState *s, const char *fmt, ...)
             continue;
         }
 
+        if (len == -1 || len == 0) {
+            fprintf(stderr, "Broken pipe\n");
+            exit(1);
+        }
+
         switch (c) {
         case '{':
             nesting++;
diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index eb7bf996d1..cc671dd7aa 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -21,6 +21,7 @@
 import os
 import iotests
 from iotests import qemu_img, qemu_io
+import struct
 
 backing_img = os.path.join(iotests.test_dir, 'backing.img')
 mid_img = os.path.join(iotests.test_dir, 'mid.img')
@@ -48,11 +49,21 @@ class ImageStreamingTestCase(iotests.QMPTestCase):
 
         self.assert_no_active_streams()
 
+    def create_image(self, name, size):
+        file = open(name, 'w')
+        i = 0
+        while i < size:
+            sector = struct.pack('>l504xl', i / 512, i / 512)
+            file.write(sector)
+            i = i + 512
+        file.close()
+
+
 class TestSingleDrive(ImageStreamingTestCase):
     image_len = 1 * 1024 * 1024 # MB
 
     def setUp(self):
-        qemu_img('create', backing_img, str(TestSingleDrive.image_len))
+        self.create_image(backing_img, TestSingleDrive.image_len)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
         self.vm = iotests.VM().add_drive(test_img)
@@ -136,7 +147,7 @@ class TestStreamStop(ImageStreamingTestCase):
         result = self.vm.qmp('block-stream', device='drive0')
         self.assert_qmp(result, 'return', {})
 
-        time.sleep(1)
+        time.sleep(0.1)
         events = self.vm.get_qmp_events(wait=False)
         self.assertEqual(events, [], 'unexpected QMP event: %s' % events)
 
diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036
new file mode 100755
index 0000000000..329533e9ea
--- /dev/null
+++ b/tests/qemu-iotests/036
@@ -0,0 +1,68 @@
+#!/bin/bash
+#
+# Test that qcow2 unknown autoclear feature bits are cleared
+#
+# Copyright (C) 2011 Red Hat, Inc.
+# Copyright IBM, Corp. 2010
+#
+# Based on test 031.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=stefanha@linux.vnet.ibm.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+
+_cleanup()
+{
+	_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+# This tests qcow2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+# Only qcow2v3 and later supports feature bits
+IMGOPTS="compat=1.1"
+
+echo === Create image with unknown autoclear feature bit ===
+echo
+_make_test_img 64M
+./qcow2.py $TEST_IMG set-feature-bit autoclear 63
+./qcow2.py $TEST_IMG dump-header
+
+echo
+echo === Repair image ===
+echo
+$QEMU_IMG check -r all $TEST_IMG
+./qcow2.py $TEST_IMG dump-header
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out
new file mode 100644
index 0000000000..6953e37ab6
--- /dev/null
+++ b/tests/qemu-iotests/036.out
@@ -0,0 +1,52 @@
+QA output created by 036
+=== Create image with unknown autoclear feature bit ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
+magic                     0x514649fb
+version                   3
+backing_file_offset       0x0
+backing_file_size         0x0
+cluster_bits              16
+size                      67108864
+crypt_method              0
+l1_size                   1
+l1_table_offset           0x30000
+refcount_table_offset     0x10000
+refcount_table_clusters   1
+nb_snapshots              0
+snapshot_offset           0x0
+incompatible_features     0x0
+compatible_features       0x0
+autoclear_features        0x8000000000000000
+refcount_order            4
+header_length             104
+
+
+=== Repair image ===
+
+No errors were found on the image.
+magic                     0x514649fb
+version                   3
+backing_file_offset       0x0
+backing_file_size         0x0
+cluster_bits              16
+size                      67108864
+crypt_method              0
+l1_size                   1
+l1_table_offset           0x30000
+refcount_table_offset     0x10000
+refcount_table_clusters   1
+nb_snapshots              0
+snapshot_offset           0x0
+incompatible_features     0x0
+compatible_features       0x0
+autoclear_features        0x0
+refcount_order            4
+header_length             104
+
+Header extension:
+magic                     0x6803f857
+length                    0
+data                      ''
+
+*** done
diff --git a/tests/qemu-iotests/037 b/tests/qemu-iotests/037
new file mode 100755
index 0000000000..c11460b92f
--- /dev/null
+++ b/tests/qemu-iotests/037
@@ -0,0 +1,119 @@
+#!/bin/bash
+#
+# Test COW from backing files
+#
+# Copyright (C) 2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=kwolf@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+
+_cleanup()
+{
+	_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow qcow2 vmdk qed
+_supported_proto generic
+_supported_os Linux
+
+CLUSTER_SIZE=4k
+size=128M
+
+echo
+echo "== creating backing file for COW tests =="
+
+_make_test_img $size
+
+function backing_io()
+{
+    local offset=$1
+    local sectors=$2
+    local op=$3
+    local pattern=0
+    local cur_sec=0
+
+    for i in $(seq 0 $((sectors - 1))); do
+        cur_sec=$((offset / 512 + i))
+        pattern=$(( ( (cur_sec % 256) + (cur_sec / 256)) % 256 ))
+
+        echo "$op -P $pattern $((cur_sec * 512)) 512"
+    done
+}
+
+backing_io 0 256 write | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+mv $TEST_IMG $TEST_IMG.base
+
+_make_test_img -b $TEST_IMG.base 6G
+
+echo
+echo "== COW in a single cluster =="
+$QEMU_IO -c "write -P 0x77 0 2k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x88 6k 2k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x99 9k 2k" $TEST_IMG | _filter_qemu_io
+
+$QEMU_IO -c "read -P 0x77 0 2k" $TEST_IMG | _filter_qemu_io
+backing_io $((2 * 1024)) 8 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x88 6k 2k" $TEST_IMG | _filter_qemu_io
+backing_io $((8 * 1024)) 2 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x99 9k 2k" $TEST_IMG | _filter_qemu_io
+backing_io $((11 * 1024)) 2 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+echo
+echo "== COW in two-cluster allocations =="
+$QEMU_IO -c "write -P 0x77 16k 6k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x88 26k 6k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x99 33k 5k" $TEST_IMG | _filter_qemu_io
+
+$QEMU_IO -c "read -P 0x77 16k 6k" $TEST_IMG | _filter_qemu_io
+backing_io $((22 * 1024)) 8 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x88 26k 6k" $TEST_IMG | _filter_qemu_io
+backing_io $((32 * 1024)) 2 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x99 33k 5k" $TEST_IMG | _filter_qemu_io
+backing_io $((38 * 1024)) 4 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+echo
+echo "== COW in multi-cluster allocations =="
+$QEMU_IO -c "write -P 0x77 48k 15k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x88 66k 14k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x99 83k 15k" $TEST_IMG | _filter_qemu_io
+
+$QEMU_IO -c "read -P 0x77 48k 15k" $TEST_IMG | _filter_qemu_io
+backing_io $((63 * 1024)) 6 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x88 66k 14k" $TEST_IMG | _filter_qemu_io
+backing_io $((80 * 1024)) 6 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x99 83k 15k" $TEST_IMG | _filter_qemu_io
+backing_io $((98 * 1024)) 4 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+_check_test_img
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/037.out b/tests/qemu-iotests/037.out
new file mode 100644
index 0000000000..deb8a3be43
--- /dev/null
+++ b/tests/qemu-iotests/037.out
@@ -0,0 +1,645 @@
+QA output created by 037
+
+== creating backing file for COW tests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
+qemu-io> wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 1024
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 1536
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 2048
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 2560
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 3072
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 3584
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 4096
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 4608
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 5120
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 5632
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 6144
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 6656
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 7168
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 7680
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 8192
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 8704
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 9216
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 9728
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 10240
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 10752
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 11264
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 11776
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 12288
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 12800
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 13312
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 13824
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 14336
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 14848
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 15360
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 15872
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 16384
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 16896
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 17408
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 17920
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 18432
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 18944
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 19456
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 19968
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 20480
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 20992
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 21504
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 22016
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 22528
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 23040
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 23552
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 24064
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 24576
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 25088
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 25600
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 26112
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 26624
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 27136
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 27648
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 28160
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 28672
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 29184
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 29696
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 30208
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 30720
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 31232
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 31744
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 32256
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 32768
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 33280
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 33792
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 34304
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 34816
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 35328
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 35840
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 36352
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 36864
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 37376
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 37888
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 38400
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 38912
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 39424
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 39936
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 40448
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 40960
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 41472
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 41984
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 42496
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 43008
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 43520
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 44032
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 44544
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 45056
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 45568
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 46080
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 46592
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 47104
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 47616
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 48128
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 48640
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 49152
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 49664
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 50176
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 50688
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 51200
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 51712
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 52224
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 52736
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 53248
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 53760
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 54272
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 54784
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 55296
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 55808
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 56320
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 56832
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 57344
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 57856
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 58368
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 58880
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 59392
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 59904
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 60416
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 60928
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 61440
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 61952
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 62464
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 62976
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 63488
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 64000
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 64512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 65024
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 65536
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 66048
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 66560
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 67072
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 67584
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 68096
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 68608
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 69120
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 69632
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 70144
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 70656
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 71168
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 71680
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 72192
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 72704
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 73216
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 73728
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 74240
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 74752
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 75264
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 75776
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 76288
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 76800
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 77312
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 77824
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 78336
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 78848
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 79360
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 79872
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 80384
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 80896
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 81408
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 81920
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 82432
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 82944
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 83456
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 83968
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 84480
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 84992
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 85504
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 86016
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 86528
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 87040
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 87552
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 88064
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 88576
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 89088
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 89600
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 90112
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 90624
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 91136
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 91648
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 92160
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 92672
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 93184
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 93696
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 94208
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 94720
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 95232
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 95744
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 96256
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 96768
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 97280
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 97792
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 98304
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 98816
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 99328
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 99840
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 100352
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 100864
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 101376
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 101888
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 102400
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 102912
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 103424
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 103936
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 104448
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 104960
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 105472
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 105984
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 106496
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 107008
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 107520
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 108032
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 108544
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 109056
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 109568
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 110080
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 110592
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 111104
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 111616
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 112128
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 112640
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 113152
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 113664
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 114176
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 114688
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 115200
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 115712
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 116224
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 116736
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 117248
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 117760
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 118272
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 118784
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 119296
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 119808
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 120320
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 120832
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 121344
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 121856
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 122368
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 122880
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 123392
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 123904
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 124416
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 124928
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 125440
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 125952
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 126464
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 126976
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 127488
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 128000
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 128512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 129024
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 129536
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 130048
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 130560
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' 
+
+== COW in a single cluster ==
+wrote 2048/2048 bytes at offset 0
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 2048/2048 bytes at offset 6144
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 2048/2048 bytes at offset 9216
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 2048/2048 bytes at offset 0
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 2048
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 2560
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 3072
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 3584
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 4096
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 4608
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 5120
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 5632
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 2048/2048 bytes at offset 6144
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 8192
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 8704
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 2048/2048 bytes at offset 9216
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 11264
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 11776
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> 
+== COW in two-cluster allocations ==
+wrote 6144/6144 bytes at offset 16384
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 6144/6144 bytes at offset 26624
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 5120/5120 bytes at offset 33792
+5 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 6144/6144 bytes at offset 16384
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 22528
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 23040
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 23552
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 24064
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 24576
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 25088
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 25600
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 26112
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 6144/6144 bytes at offset 26624
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 32768
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 33280
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 5120/5120 bytes at offset 33792
+5 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 38912
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 39424
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 39936
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 40448
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> 
+== COW in multi-cluster allocations ==
+wrote 15360/15360 bytes at offset 49152
+15 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 14336/14336 bytes at offset 67584
+14 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 15360/15360 bytes at offset 84992
+15 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 15360/15360 bytes at offset 49152
+15 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 64512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 65024
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 65536
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 66048
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 66560
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 67072
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 14336/14336 bytes at offset 67584
+14 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 81920
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 82432
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 82944
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 83456
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 83968
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 84480
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 15360/15360 bytes at offset 84992
+15 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 100352
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 100864
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 101376
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 101888
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> No errors were found on the image.
+*** done
diff --git a/tests/qemu-iotests/038 b/tests/qemu-iotests/038
new file mode 100755
index 0000000000..36125eab1e
--- /dev/null
+++ b/tests/qemu-iotests/038
@@ -0,0 +1,133 @@
+#!/bin/bash
+#
+# Test COW from backing files with AIO
+#
+# Copyright (C) 2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=kwolf@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+
+_cleanup()
+{
+	_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2 qed
+_supported_proto generic
+_supported_os Linux
+
+CLUSTER_SIZE=2M
+size=128M
+
+echo
+echo "== creating backing file for COW tests =="
+
+_make_test_img $size
+
+function backing_io()
+{
+    local offset=$1
+    local sectors=$2
+    local op=$3
+    local pattern=0
+    local cur_sec=0
+
+    for i in $(seq 0 $((sectors - 1))); do
+        cur_sec=$((offset / 65536 + i))
+        pattern=$(( ( (cur_sec % 128) + (cur_sec / 128)) % 128 ))
+
+        echo "$op -P $pattern $((cur_sec * 64))k 64k"
+    done
+}
+
+backing_io 0 256 write | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+mv $TEST_IMG $TEST_IMG.base
+
+_make_test_img -b $TEST_IMG.base 6G
+
+echo
+echo "== Some concurrent requests touching the same cluster =="
+
+function overlay_io()
+{
+    # Start with a request touching two clusters
+    echo aio_write -P 0x80 2020k 80k
+
+    # Then add some requests all over the place
+    for i in $(seq 0 15; seq 17 31; seq 33 47); do
+        echo aio_write -P $((0x81 + i)) $((i * 128))k 64k
+    done
+
+    # Then backwards overwriting part of them
+    for i in $( (seq 0 15; seq 17 31; seq 33 47) | tac); do
+        echo aio_write -P $((0x81 + i)) $((i * 128 + 32))k 64k
+    done
+
+    # And finally crossing the next cluster boundary
+    echo aio_write -P 0x90 4080k 80k
+}
+
+overlay_io | $QEMU_IO $TEST_IMG | _filter_qemu_io |\
+	sed -e 's/bytes at offset [0-9]*/bytes at offset XXX/g'
+
+echo
+echo "== Verify image content =="
+
+function verify_io()
+{
+    echo read -P 31 2016k 4k
+    echo read -P 0x80 2020k 80k
+    echo read -P 32 2100k 12k
+    echo read -P 33 2112k 64k
+
+    echo read -P 63 4064k 16k
+    echo read -P 0x90 4080k 80k
+    echo read -P 65 4160k 64k
+
+    for i in $(seq 0 15; seq 17 31; seq 33 47); do
+        echo read -P $((0x81 + i)) $((i * 128))k 96k
+    done
+
+    for i in $(seq 0 14; seq 16 30; seq 32 47); do
+        local cur_sec=$(( i * 2 + 1 ))
+        local pattern=$(( ( (cur_sec % 128) + (cur_sec / 128)) % 128 ))
+
+        echo read -P $pattern $((i * 128 + 96))k 32k
+    done
+}
+
+verify_io | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+_check_test_img
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/038.out b/tests/qemu-iotests/038.out
new file mode 100644
index 0000000000..acc7629267
--- /dev/null
+++ b/tests/qemu-iotests/038.out
@@ -0,0 +1,909 @@
+QA output created by 038
+
+== creating backing file for COW tests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
+qemu-io> wrote 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 131072
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 196608
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 262144
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 327680
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 393216
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 458752
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 524288
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 589824
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 655360
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 720896
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 786432
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 851968
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 917504
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 983040
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1048576
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1114112
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1179648
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1245184
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1310720
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1376256
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1441792
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1507328
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1572864
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1638400
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1703936
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1769472
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1835008
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1900544
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1966080
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2031616
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2097152
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2162688
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2228224
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2293760
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2359296
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2424832
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2490368
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2555904
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2621440
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2686976
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2752512
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2818048
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2883584
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2949120
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3014656
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3080192
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3145728
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3211264
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3276800
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3342336
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3407872
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3473408
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3538944
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3604480
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3670016
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3735552
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3801088
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3866624
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3932160
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3997696
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4063232
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4128768
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4194304
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4259840
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4325376
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4390912
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4456448
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4521984
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4587520
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4653056
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4718592
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4784128
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4849664
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4915200
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4980736
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5046272
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5111808
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5177344
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5242880
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5308416
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5373952
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5439488
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5505024
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5570560
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5636096
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5701632
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5767168
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5832704
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5898240
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5963776
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6029312
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6094848
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6160384
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6225920
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6291456
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6356992
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6422528
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6488064
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6553600
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6619136
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6684672
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6750208
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6815744
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6881280
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6946816
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7012352
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7077888
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7143424
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7208960
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7274496
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7340032
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7405568
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7471104
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7536640
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7602176
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7667712
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7733248
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7798784
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7864320
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7929856
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7995392
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8060928
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8126464
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8192000
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8257536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8323072
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8388608
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8454144
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8519680
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8585216
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8650752
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8716288
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8781824
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8847360
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8912896
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8978432
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9043968
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9109504
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9175040
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9240576
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9306112
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9371648
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9437184
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9502720
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9568256
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9633792
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9699328
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9764864
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9830400
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9895936
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9961472
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10027008
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10092544
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10158080
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10223616
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10289152
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10354688
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10420224
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10485760
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10551296
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10616832
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10682368
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10747904
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10813440
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10878976
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10944512
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11010048
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11075584
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11141120
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11206656
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11272192
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11337728
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11403264
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11468800
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11534336
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11599872
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11665408
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11730944
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11796480
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11862016
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11927552
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11993088
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12058624
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12124160
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12189696
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12255232
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12320768
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12386304
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12451840
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12517376
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12582912
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12648448
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12713984
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12779520
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12845056
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12910592
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12976128
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13041664
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13107200
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13172736
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13238272
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13303808
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13369344
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13434880
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13500416
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13565952
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13631488
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13697024
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13762560
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13828096
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13893632
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13959168
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14024704
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14090240
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14155776
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14221312
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14286848
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14352384
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14417920
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14483456
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14548992
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14614528
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14680064
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14745600
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14811136
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14876672
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14942208
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15007744
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15073280
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15138816
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15204352
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15269888
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15335424
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15400960
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15466496
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15532032
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15597568
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15663104
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15728640
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15794176
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15859712
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15925248
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15990784
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16056320
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16121856
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16187392
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16252928
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16318464
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16384000
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16449536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16515072
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16580608
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16646144
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16711680
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' 
+
+== Some concurrent requests touching the same cluster ==
+qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> wrote 81920/81920 bytes at offset XXX
+80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 81920/81920 bytes at offset XXX
+80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Verify image content ==
+qemu-io> read 4096/4096 bytes at offset 2064384
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 81920/81920 bytes at offset 2068480
+80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 12288/12288 bytes at offset 2150400
+12 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 65536/65536 bytes at offset 2162688
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 16384/16384 bytes at offset 4161536
+16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 81920/81920 bytes at offset 4177920
+80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 65536/65536 bytes at offset 4259840
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 0
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 131072
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 262144
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 393216
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 524288
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 655360
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 786432
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 917504
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1048576
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1179648
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1310720
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1441792
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1572864
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1703936
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1835008
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1966080
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2228224
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2359296
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2490368
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2621440
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2752512
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2883584
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3014656
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3145728
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3276800
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3407872
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3538944
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3670016
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3801088
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3932160
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4063232
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4325376
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4456448
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4587520
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4718592
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4849664
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4980736
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5111808
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5242880
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5373952
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5505024
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5636096
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5767168
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5898240
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 6029312
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 6160384
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 98304
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 229376
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 360448
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 491520
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 622592
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 753664
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 884736
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1015808
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1146880
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1277952
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1409024
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1540096
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1671168
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1802240
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1933312
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2195456
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2326528
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2457600
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2588672
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2719744
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2850816
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2981888
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3112960
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3244032
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3375104
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3506176
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3637248
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3768320
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3899392
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4030464
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4292608
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4423680
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4554752
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4685824
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4816896
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4947968
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5079040
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5210112
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5341184
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5472256
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5603328
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5734400
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5865472
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5996544
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 6127616
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 6258688
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> No errors were found on the image.
+*** done
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
index eeb70cbcdc..1f6fdf5c56 100644
--- a/tests/qemu-iotests/common
+++ b/tests/qemu-iotests/common
@@ -41,6 +41,7 @@ sortme=false
 expunge=true
 have_test_arg=false
 randomize=false
+valgrind=false
 rm -f $tmp.list $tmp.tmp $tmp.sed
 
 export IMGFMT=raw
@@ -212,6 +213,11 @@ testlist options
 	    xpand=false
 	    ;;
 
+    -valgrind)
+        valgrind=true
+	    xpand=false
+        ;;
+
 	-g)	# -g group ... pick from group file
 	    group=true
 	    xpand=false
@@ -345,3 +351,8 @@ fi
 [ "$QEMU" = "" ] && _fatal "qemu not found"
 [ "$QEMU_IMG" = "" ] && _fatal "qemu-img not found"
 [ "$QEMU_IO" = "" ] && _fatal "qemu-img not found"
+
+if $valgrind; then
+    export REAL_QEMU_IO="$QEMU_IO_PROG"
+    export QEMU_IO_PROG=valgrind_qemu_io
+fi
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index e535874e4c..5e3a524bc8 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -53,6 +53,16 @@ else
     TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
 fi
 
+function valgrind_qemu_io()
+{
+    valgrind --log-file=/tmp/$$.valgrind --error-exitcode=99 $REAL_QEMU_IO "$@"
+    if [ $? != 0 ]; then
+        cat /tmp/$$.valgrind
+    fi
+    rm -f /tmp/$$.valgrind
+}
+
+
 _optstr_add()
 {
     if [ -n "$1" ]; then
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 36ebf1a7f4..7a2c92b6e9 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -42,3 +42,6 @@
 033 rw auto
 034 rw auto backing
 035 rw auto quick
+036 rw auto quick
+037 rw auto backing
+038 rw auto backing
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index e27b40e289..e05b1d640b 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -54,7 +54,9 @@ class VM(object):
         self._qemu_log_path = os.path.join(test_dir, 'qemu-log.%d' % os.getpid())
         self._args = qemu_args + ['-chardev',
                      'socket,id=mon,path=' + self._monitor_path,
-                     '-mon', 'chardev=mon,mode=control', '-nographic']
+                     '-mon', 'chardev=mon,mode=control',
+                     '-qtest', 'stdio', '-machine', 'accel=qtest',
+                     '-display', 'none', '-vga', 'none']
         self._num_drives = 0
 
     def add_drive(self, path, opts=''):
diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py
index e27196aa26..97f37707bc 100755
--- a/tests/qemu-iotests/qcow2.py
+++ b/tests/qemu-iotests/qcow2.py
@@ -181,10 +181,33 @@ def cmd_del_header_ext(fd, magic):
 
     h.update(fd)
 
+def cmd_set_feature_bit(fd, group, bit):
+    try:
+        bit = int(bit, 0)
+        if bit < 0 or bit >= 64:
+            raise ValueError
+    except:
+        print "'%s' is not a valid bit number in range [0, 64)" % bit
+        sys.exit(1)
+
+    h = QcowHeader(fd)
+    if group == 'incompatible':
+        h.incompatible_features |= 1 << bit
+    elif group == 'compatible':
+        h.compatible_features |= 1 << bit
+    elif group == 'autoclear':
+        h.autoclear_features |= 1 << bit
+    else:
+        print "'%s' is not a valid group, try 'incompatible', 'compatible', or 'autoclear'" % group
+        sys.exit(1)
+
+    h.update(fd)
+
 cmds = [
     [ 'dump-header',    cmd_dump_header,    0, 'Dump image header and header extensions' ],
     [ 'add-header-ext', cmd_add_header_ext, 2, 'Add a header extension' ],
     [ 'del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension' ],
+    [ 'set-feature-bit', cmd_set_feature_bit, 2, 'Set a feature bit'],
 ]
 
 def main(filename, cmd, args):
diff --git a/tests/tcg/openrisc/Makefile b/tests/tcg/openrisc/Makefile
new file mode 100644
index 0000000000..7e65888761
--- /dev/null
+++ b/tests/tcg/openrisc/Makefile
@@ -0,0 +1,71 @@
+-include ../../config-host.mak
+
+CROSS = or32-linux-
+
+SIM = qemu-or32
+
+CC = $(CROSS)gcc
+
+TESTCASES = test_add.tst
+TESTCASES += test_sub.tst
+TESTCASES += test_addc.tst
+TESTCASES += test_addi.tst
+TESTCASES += test_addic.tst
+TESTCASES += test_and_or.tst
+TESTCASES += test_bf.tst
+TESTCASES += test_bnf.tst
+TESTCASES += test_div.tst
+TESTCASES += test_divu.tst
+TESTCASES += test_extx.tst
+TESTCASES += test_fx.tst
+TESTCASES += test_jal.tst
+TESTCASES += test_j.tst
+TESTCASES += test_lf_div.tst
+TESTCASES += test_lf_eqs.tst
+TESTCASES += test_lf_ges.tst
+TESTCASES += test_lf_gts.tst
+TESTCASES += test_lf_les.tst
+TESTCASES += test_lf_lts.tst
+TESTCASES += test_lf_mul.tst
+TESTCASES += test_lf_nes.tst
+TESTCASES += test_lf_rem.tst
+TESTCASES += test_lf_sub.tst
+TESTCASES += test_lf_add.tst
+TESTCASES += test_logic.tst
+TESTCASES += test_lx.tst
+TESTCASES += test_movhi.tst
+TESTCASES += test_mul.tst
+TESTCASES += test_mulu.tst
+TESTCASES += test_muli.tst
+TESTCASES += test_sfeq.tst
+TESTCASES += test_sfeqi.tst
+TESTCASES += test_sfges.tst
+TESTCASES += test_sfgesi.tst
+TESTCASES += test_sfgeu.tst
+TESTCASES += test_sfgeui.tst
+TESTCASES += test_sfgts.tst
+TESTCASES += test_sfgtsi.tst
+TESTCASES += test_sfgtu.tst
+TESTCASES += test_sfgtui.tst
+TESTCASES += test_sfles.tst
+TESTCASES += test_sflesi.tst
+TESTCASES += test_sfleu.tst
+TESTCASES += test_sfleui.tst
+TESTCASES += test_sflts.tst
+TESTCASES += test_sfltsi.tst
+TESTCASES += test_sfltu.tst
+TESTCASES += test_sfltui.tst
+TESTCASES += test_sfne.tst
+TESTCASES += test_sfnei.tst
+
+all: $(TESTCASES)
+
+%.tst: %.c
+	$(CC) -static $< -o $@
+
+
+check: $(TESTCASES)
+	@for case in $(TESTCASES); do $(SIM) $$case; echo $$case pass!; sleep 0.2; done
+
+clean:
+	$(RM) -rf $(TESTCASES)
diff --git a/tests/tcg/openrisc/test_add.c b/tests/tcg/openrisc/test_add.c
new file mode 100644
index 0000000000..3d23592e76
--- /dev/null
+++ b/tests/tcg/openrisc/test_add.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, d;
+    int result;
+
+    a = 0x100;
+    b = 0x100;
+    result = 0x200;
+    __asm
+    ("l.add %0, %0, %1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("add error\n");
+        return -1;
+    }
+
+    a = 0xffff;
+    b = 0x1;
+    result = 0x10000;
+    __asm
+    ("l.add %0, %0, %1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("add error\n");
+        return -1;
+    }
+
+    a = 0x7fffffff;
+    b = 0x1;
+    __asm
+    ("l.add %0, %1, %2\n\t"
+     : "=r"(d)
+     : "r"(b), "r"(a)
+    );
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_addc.c b/tests/tcg/openrisc/test_addc.c
new file mode 100644
index 0000000000..05d18f8ce5
--- /dev/null
+++ b/tests/tcg/openrisc/test_addc.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x01;
+    c = 0xffffffff;
+    result = 1;
+    __asm
+    ("l.addc   %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("first addc error\n");
+        return -1;
+    }
+
+    b = 0x01;
+    c = 0xffffffff;
+    result = 0x80000001;
+    __asm
+    ("l.addc   %0, %1, %2\n\t"
+     "l.movhi  %2, 0x7fff\n\t"
+     "l.ori    %2, %2, 0xffff\n\t"
+     "l.addc   %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("addc error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_addi.c b/tests/tcg/openrisc/test_addi.c
new file mode 100644
index 0000000000..bbf5a5ffab
--- /dev/null
+++ b/tests/tcg/openrisc/test_addi.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    b = 0x01;
+    result = 0x00;
+    __asm
+    ("l.addi  %0, %1, 0xffff\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("addi error\n\t");
+        return -1;
+    }
+
+    b = 0x010000;
+    result = 0xffff;
+    __asm
+    ("l.addi  %0, %1, 0xffff\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("addi error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_addic.c b/tests/tcg/openrisc/test_addic.c
new file mode 100644
index 0000000000..4ba7432521
--- /dev/null
+++ b/tests/tcg/openrisc/test_addic.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 1;
+    result = 0x1;
+    __asm
+    ("l.addic %0, %0, 0xffff\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("first addic error\n");
+        return -1;
+   }
+
+    a = 0x1;
+    result = 0x201;
+    __asm
+    ("l.addic %0, %0, 0xffff\n\t"
+     "l.ori   %0, r0, 0x100\n\t"
+     "l.addic %0, %0, 0x100\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("second addic error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_and_or.c b/tests/tcg/openrisc/test_and_or.c
new file mode 100644
index 0000000000..810d868c7b
--- /dev/null
+++ b/tests/tcg/openrisc/test_and_or.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x2;
+    c = 0x1;
+    result = 0;
+    __asm
+    ("l.and  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("and error\n");
+        return -1;
+    }
+
+    result = 0x2;
+    __asm
+    ("l.andi  %0, %1, 0x3\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("andi error %x\n", a);
+        return -1;
+    }
+
+    result = 0x3;
+    __asm
+    ("l.or   %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("or error\n");
+        return -1;
+    }
+
+    result = 0x3;
+    __asm
+    ("l.xor  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("xor error\n");
+        return -1;
+    }
+
+    __asm
+    ("l.xori  %0, %1, 0x1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("xori error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_bf.c b/tests/tcg/openrisc/test_bf.c
new file mode 100644
index 0000000000..79f3fb99aa
--- /dev/null
+++ b/tests/tcg/openrisc/test_bf.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 0;
+    b = 10;
+    c = 11;
+    result = 0x2;
+    __asm
+    ("1:\n\t"
+     "l.addi %1, %1, 0x01\n\t"
+     "l.addi %0, %0, 0x01\n\t"
+     "l.sfeq %1, %2\n\t"
+     "l.bf   1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfeq error\n");
+        return -1;
+    }
+
+    a = 0x00;
+    b = 0x11;
+    c = 0x11;
+    result = 0x01;
+    __asm
+    ("1:\n\t"
+     "l.addi %1, %1, 0x01\n\t"
+     "l.addi %0, %0, 0x01\n\t"
+     "l.sfeq %1, %2\n\t"
+     "l.bf   1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfeq error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_bnf.c b/tests/tcg/openrisc/test_bnf.c
new file mode 100644
index 0000000000..f716215f10
--- /dev/null
+++ b/tests/tcg/openrisc/test_bnf.c
@@ -0,0 +1,51 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 0;
+    result = 0x3;
+    __asm
+    ("l.sfeqi %1, 0x0\n\t"
+     "l.bnf 1f\n\t"
+     "l.nop\n\t"
+     "\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     "\n\t"
+     "1:\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("l.bnf error\n");
+        return -1;
+    }
+
+    a = 0;
+    b = 0;
+    result = 1;
+    __asm
+    ("l.sfeqi %1, 0x1\n\t"
+     "l.bnf 1f\n\t"
+     "l.nop\n\t"
+     "\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     "\n\t"
+     "1:\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("l.bnf error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_div.c b/tests/tcg/openrisc/test_div.c
new file mode 100644
index 0000000000..9b65f6e673
--- /dev/null
+++ b/tests/tcg/openrisc/test_div.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x120;
+    c = 0x4;
+    result = 0x48;
+    __asm
+    ("l.div  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("div error\n");
+        return -1;
+    }
+
+    result = 0x4;
+    __asm
+    ("l.div %0, %1, %0\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("div error\n");
+        return -1;
+    }
+
+    b = 0xffffffff;
+    c = 0x80000000;
+    result = 0;
+    __asm
+    ("l.div %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("div error\n");
+        return -1;
+    }
+
+    b = 0x80000000;
+    c = 0xffffffff;
+    __asm
+    ("l.div %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_divu.c b/tests/tcg/openrisc/test_divu.c
new file mode 100644
index 0000000000..bff9e3ea59
--- /dev/null
+++ b/tests/tcg/openrisc/test_divu.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x120;
+    c = 0x4;
+    result = 0x48;
+
+    __asm
+    ("l.divu  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("divu error\n");
+        return -1;
+    }
+
+    result = 0x4;
+    __asm
+    ("l.divu %0, %1, %0\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("divu error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_extx.c b/tests/tcg/openrisc/test_extx.c
new file mode 100644
index 0000000000..09221484a6
--- /dev/null
+++ b/tests/tcg/openrisc/test_extx.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    b = 0x83;
+    result = 0xffffff83;
+    __asm
+    ("l.extbs  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("extbs error\n");
+        return -1;
+    }
+
+    result = 0x83;
+    __asm
+    ("l.extbz  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("extbz error\n");
+        return -1;
+    }
+
+    b = 0x8083;
+    result = 0xffff8083;
+    __asm
+    ("l.exths  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("exths error\n");
+        return -1;
+    }
+
+    result = 0x8083;
+    __asm
+    ("l.exthz  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("exthz error\n");
+        return -1;
+    }
+
+    b = 0x11;
+    result = 0x11;
+    __asm
+    ("l.extws  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+
+    if (a != result) {
+        printf("extws error\n");
+        return -1;
+    }
+
+    __asm
+    ("l.extwz  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("extwz error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_fx.c b/tests/tcg/openrisc/test_fx.c
new file mode 100644
index 0000000000..df86000d90
--- /dev/null
+++ b/tests/tcg/openrisc/test_fx.c
@@ -0,0 +1,57 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    b = 0x123;
+    result = 1;
+    __asm
+    ("l.ff1 %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("ff1 error\n");
+        return -1;
+    }
+
+    b = 0x0;
+    result = 0;
+    __asm
+    ("l.ff1 %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("ff1 error\n");
+        return -1;
+    }
+
+    b = 0x123;
+    result = 9;
+    __asm
+    ("l.fl1 %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("fl1 error\n");
+        return -1;
+    }
+
+    b = 0x0;
+    result = 0;
+    __asm
+    ("l.fl1 %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("fl1 error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_j.c b/tests/tcg/openrisc/test_j.c
new file mode 100644
index 0000000000..9ddf8bfbb5
--- /dev/null
+++ b/tests/tcg/openrisc/test_j.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 2;
+    __asm
+    ("l.addi %0, %0, 1\n\t"
+     "l.j j\n\t"
+     "l.nop\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.nop\n\t"
+     "j:\n\t"
+     "l.addi %0, %0, 1\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("j error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_jal.c b/tests/tcg/openrisc/test_jal.c
new file mode 100644
index 0000000000..7e2da40163
--- /dev/null
+++ b/tests/tcg/openrisc/test_jal.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 2;
+    __asm
+    ("l.addi %0, %0, 1\n\t"
+     "l.jal jal\n\t"
+     "l.nop\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.nop\n\t"
+     "jal:\n\t"
+     "l.addi %0, %0, 1\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("jal error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_add.c b/tests/tcg/openrisc/test_lf_add.c
new file mode 100644
index 0000000000..e00212dad6
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_add.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    float a, b;
+    float res2;
+
+    a = 1.5;
+    b = 2.5;
+    res2 = 4.0;
+    __asm
+    ("lf.add.s  %0, %0, %1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != res2) {
+        printf("lf.add.s error, %f\n", a);
+        return -1;
+    }
+
+/*    double c, d;
+    double res1;
+
+    c = 1.5;
+    d = 1.5;
+    res1 = 3.00;
+    __asm
+    ("lf.add.d  %0, %1, %2\n\t"
+     : "+r"(c)
+     : "r"(d)
+    );
+
+    if ((e - res1) > 0.002) {
+        printf("lf.add.d error, %f\n", e - res1);
+        return -1;
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_div.c b/tests/tcg/openrisc/test_lf_div.c
new file mode 100644
index 0000000000..70b5d1c17b
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_div.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+
+int main(void)
+{
+    float a, b, c;
+    float result;
+
+    b = 1.5;
+    c = 0.5;
+    result = 3.0;
+    __asm
+    ("lf.div.s    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.div.s error\n");
+        return -1;
+    }
+
+/*    double a, b, c, res;
+
+    b = 0x80000000;
+    c = 0x40;
+    result = 0x2000000;
+    __asm
+    ("lf.div.d    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.div.d error\n");
+        return -1;
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_eqs.c b/tests/tcg/openrisc/test_lf_eqs.c
new file mode 100644
index 0000000000..a176bd6fe0
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_eqs.c
@@ -0,0 +1,88 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, result;
+    float b, c;
+
+    a = 0x1;
+    b = 122.5;
+    c = 123.5;
+    result = 0x3;
+    __asm
+    ("lfeqd:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfeq.s %1, %2\n\t"
+     "l.bf      lfeqd\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfeq.s error\n");
+        return -1;
+    }
+
+    b = 13.5;
+    c = 13.5;
+    result = 0x3;
+    __asm
+    ("lf.sfeq.s %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    r4, r4, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfeq.s error\n");
+        return -1;
+    }
+
+/*    double b, c;
+    double result;
+    int a;
+
+    a = 0x1;
+    b = 122.5;
+    c = 133.5;
+    result = 0x3;
+
+    __asm
+    ("lfeqd:\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     "lf.sfeq.d %1, %2\n\t"
+     "l.bf      lfeqd\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfeq.d error\n");
+        return -1;
+    }
+
+    double c, d, res;
+    int e = 0;
+    c = 11.5;
+    d = 11.5;
+    res = 1;
+    __asm
+    ("lf.sfeq.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(e)
+     : "r"(c), "r"(d)
+    );
+    if (e != res) {
+        printf("lf.sfeq.d error\n");
+        return -1;
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_ges.c b/tests/tcg/openrisc/test_lf_ges.c
new file mode 100644
index 0000000000..98e7f50b6e
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_ges.c
@@ -0,0 +1,88 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, result;
+    float b, c;
+
+    a = 0;
+    b = 122.5;
+    c = 123.5;
+    result = 0x1;
+    __asm
+    ("lfges:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfge.s %1, %2\n\t"
+     "l.bf      lfges\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfge.s error\n");
+        return -1;
+    }
+
+    b = 133.5;
+    c = 13.5;
+    result = 0x3;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfge.s %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfge.s error\n");
+        return -1;
+    }
+
+/*    int a, result;
+    double b, c;
+
+    a = 0x1;
+    b = 122.5;
+    c = 123.5;
+    result = 0x2;
+    __asm
+    ("lfged:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfge.d %1, %2\n\t"
+     "l.bf      lfged\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfge.d error\n");
+        return -1;
+    }
+
+    b = 133.5;
+    c = 13.5;
+    result = 0x4;
+    __asm
+    ("lf.sfge.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfge.d error\n");
+        return -1;
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_gts.c b/tests/tcg/openrisc/test_lf_gts.c
new file mode 100644
index 0000000000..f3df27958e
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_gts.c
@@ -0,0 +1,86 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, result;
+    float b, c;
+
+    a = 0;
+    b = 122.5;
+    c = 123.5;
+    result = 0x1;
+    __asm
+    ("lfgts:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfgt.s %1, %2\n\t"
+     "l.bf      lfgts\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfgt.s error\n");
+        return -1;
+    }
+
+    b = 133.5;
+    c = 13.5;
+    result = 0x1;
+    __asm
+    ("lf.sfgt.s %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfgt.s error\n");
+        return -1;
+    }
+
+/*    int a, result;
+    double b, c;
+
+    a = 0;
+    b = 122.5;
+    c = 123.5;
+    result = 0x1;
+    __asm
+    ("lfgtd:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfgt.d %1, %2\n\t"
+     "l.bf      lfgtd\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfgt.d error\n");
+        return -1;
+    }
+
+    b = 133.5;
+    c = 13.5;
+    result = 0x3;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfgt.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfgt.d error, %x\n", a);
+        return -1;
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_les.c b/tests/tcg/openrisc/test_lf_les.c
new file mode 100644
index 0000000000..046c511d93
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_les.c
@@ -0,0 +1,88 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    float b, c;
+    int result;
+
+    a = 0;
+    b = 1234.2;
+    c = 12.4;
+    result = 0x1;
+    __asm
+    ("lfles:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfle.s %1, %2\n\t"
+     "l.bf      lfles\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfle.s error\n");
+        return -1;
+    }
+
+    b = 1.1;
+    c = 19.4;
+    result = 0x3;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfle.s %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfle.s error\n");
+        return -1;
+    }
+
+/*    int a;
+    double b, c;
+    int result;
+
+    a = 0;
+    b = 1212.5;
+    c = 123.5;
+    result = 0x1;
+    __asm
+    ("lfled:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfle.d %1, %2\n\t"
+     "l.bf      lfled\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfle.d error\n");
+        return -1;
+    }
+
+    b = 13.5;
+    c = 113.5;
+    result = 0x2;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "lf.sfle.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfle.d error\n");
+        return -1;
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_lts.c b/tests/tcg/openrisc/test_lf_lts.c
new file mode 100644
index 0000000000..fa56721dfa
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_lts.c
@@ -0,0 +1,92 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    float b, c, d;
+    int result;
+
+    a = 0;
+    b = 124.5;
+    c = 1.4;
+    result = 1;
+    __asm
+    ("lfltd:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sflt.s %1, %2\n\t"
+     "l.bf      lfltd\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sflt.s error\n");
+        return -1;
+    }
+
+    a = 0;
+    b = 11.1;
+    c = 13.1;
+    d = 1.0;
+    result = 2;
+    __asm
+    ("1:\n\t"
+     "lf.add.s  %1, %1, %3\n\t"
+     "l.addi    %0, %0, 1\n\t"
+     "lf.sflt.s %1, %2\n\t"
+     "l.bf      1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c), "r"(d)
+    );
+    if (a != result) {
+        printf("lf.sflt.s error\n");
+        return -1;
+    }
+
+/*    int a;
+    double b, c;
+    int result;
+
+    a = 0;
+    b = 1432.1;
+    c = 2.4;
+    result = 0x1;
+    __asm
+    ("lfltd:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sflt.d %1, %2\n\t"
+     "l.bf      lfltd\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sflt.d error\n");
+        return -1;
+    }
+
+    a = 0;
+    b = 1.1;
+    c = 19.7;
+    result = 2;
+    __asm
+    ("lf.sflt.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "1:\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.addi %0, %0, 1\n\t"
+     : "+r"(a), "+r"(b)
+     : "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sflt.d error\n");
+        return -1;
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_mul.c b/tests/tcg/openrisc/test_lf_mul.c
new file mode 100644
index 0000000000..bc8ad800c7
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_mul.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+int main(void)
+{
+    float a, b, c;
+    float result;
+
+    b = 1.5;
+    c = 4.0;
+    result = 6.0;
+    __asm
+    ("lf.mul.s   %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.mul.s error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_nes.c b/tests/tcg/openrisc/test_lf_nes.c
new file mode 100644
index 0000000000..613631005b
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_nes.c
@@ -0,0 +1,89 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    float b, c;
+    int result;
+
+    a = 0;
+    b = 23.1;
+    c = 23.1;
+    result = 0x1;
+    __asm
+    ("lfnes:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfne.s %1, %2\n\t"
+     "l.bf      lfnes\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfne.s error");
+        return -1;
+    }
+
+    b = 12.4;
+    c = 7.8;
+    result = 0x3;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfne.s %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfne.s error\n");
+        return -1;
+    }
+/*    int a;
+    double b, c;
+    int result;
+
+    a = 0;
+    b = 124.3;
+    c = 124.3;
+    result = 0x1;
+    __asm
+    ("lfned:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfne.d %1, %2\n\t"
+     "l.bf      lfned\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfne.d error\n");
+        return -1;
+    }
+
+    b = 11.5;
+    c = 16.7;
+    result = 0x3;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfne.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    r4, r4, 0x1\n\t"
+     "l.addi    r4, r4, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfne.d error\n");
+        return -1;
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_rem.c b/tests/tcg/openrisc/test_lf_rem.c
new file mode 100644
index 0000000000..bd6090d694
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_rem.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+
+int main(void)
+{
+    float a, b, c;
+    float result;
+
+    b = 101.5;
+    c = 10;
+    result = 1.5;
+/*    __asm
+    ("lf.rem.d      %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.rem.d error\n");
+        return -1;
+    }*/
+
+    __asm
+    ("lf.rem.s      %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.rem.s error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_sub.c b/tests/tcg/openrisc/test_lf_sub.c
new file mode 100644
index 0000000000..5ee9b03910
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_sub.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+
+int main(void)
+{
+    float a, b, c;
+    float result;
+
+    b = 10.5;
+    c = 1.5;
+    result = 9.0;
+    __asm
+    ("lf.sub.s  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sub.s error\n");
+        return -1;
+    }
+
+/*    b = 0x999;
+    c = 0x654;
+    result = 0x345;
+    __asm
+    ("lf.sub.d  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sub.d error\n");
+        return -1;
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_logic.c b/tests/tcg/openrisc/test_logic.c
new file mode 100644
index 0000000000..46d173f481
--- /dev/null
+++ b/tests/tcg/openrisc/test_logic.c
@@ -0,0 +1,105 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x9743;
+    c = 0x2;
+    result = 0x25d0c;
+    __asm
+    ("l.sll    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sll error\n");
+        return -1;
+    }
+
+    b = 0x9743;
+    result = 0x25d0c;
+    __asm
+    ("l.slli   %0, %1, 0x2\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("slli error\n");
+        return -1;
+    }
+
+    b = 0x7654;
+    c = 0x03;
+    result = 0xeca;
+    __asm
+    ("l.srl    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+
+    b = 0x7654;
+    result = 0xeca;
+    __asm
+    ("l.srli   %0, %1, 0x3\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("srli error\n");
+        return -1;
+    }
+
+    b = 0x80000001;
+    c = 0x4;
+    result = 0x18000000;
+    __asm
+    ("l.ror    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("ror error\n");
+        return -1;
+    }
+
+    b = 0x80000001;
+    result = 0x18000000;
+    __asm
+    ("l.rori   %0, %1, 0x4\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("rori error\n");
+        return -1;
+    }
+
+    b = 0x80000001;
+    c = 0x03;
+    result = 0xf0000000;
+    __asm
+    ("l.sra    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sra error\n");
+        return -1;
+    }
+
+    b = 0x80000001;
+    result = 0xf0000000;
+    __asm
+    ("l.srai   %0, %1, 0x3\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("srai error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lx.c b/tests/tcg/openrisc/test_lx.c
new file mode 100644
index 0000000000..792e3d5c7f
--- /dev/null
+++ b/tests/tcg/openrisc/test_lx.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int p[50];
+    int result;
+
+    result = 0x23;
+    __asm
+    ("l.ori r8, r0, 0x123\n\t"
+     "l.sb  0x4 + %1, r8\n\t"
+     "\n\t"
+     "l.lbz %0, 0x4 + %1\n\t"
+     : "=r"(a), "+m"(*p)
+    );
+    if (a != result) {
+        printf("lbz error, %x\n", a);
+        return -1;
+    }
+
+    result = 0x23;
+    __asm
+    ("l.lbs %0, 0x4 + %1\n\t"
+     : "=r"(a)
+     : "m"(*p)
+    );
+    if (a != result) {
+        printf("lbs error\n");
+        return -1;
+    }
+
+    result = 0x1111;
+    __asm
+    ("l.ori r8, r0, 0x1111\n\t"
+     "l.sh  0x20 + %1, r8\n\t"
+     "\n\t"
+     "l.lhs %0, 0x20 + %1\n\t"
+     : "=r"(a), "=m"(*p)
+    );
+    if (a != result) {
+        printf("lhs error, %x\n", a);
+        return -1;
+    }
+
+    result = 0x1111;
+    __asm
+    ("l.lhz %0, 0x20 + %1\n\t"
+     : "=r"(a)
+     : "m"(*p)
+    );
+    if (a != result) {
+        printf("lhz error\n");
+        return -1;
+    }
+
+    result = 0x1111233;
+    __asm
+    ("l.ori r8, r0, 0x1233\n\t"
+     "l.movhi r1, 0x111\n\t"
+     "l.or  r8, r8, r1\n\t"
+     "l.sw  0x123 + %1, r8\n\t"
+     "\n\t"
+     "l.lws %0, 0x123 + %1\n\t"
+     : "=r"(a), "+m"(*p)
+    );
+    if (a != result) {
+        printf("lws error, %x\n", a);
+        return -1;
+    }
+
+    result = 0x1111233;
+    __asm
+    ("l.lwz %0, 0x123 + %1\n\t"
+     : "=r"(a)
+     : "m"(*p)
+    );
+    if (a != result) {
+        printf("lwz error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_movhi.c b/tests/tcg/openrisc/test_movhi.c
new file mode 100644
index 0000000000..737f75b9fd
--- /dev/null
+++ b/tests/tcg/openrisc/test_movhi.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    result = 0x1222;
+    __asm
+    ("l.movhi r3, 0x1222\n\t"
+     "l.srli   %0, r3, 16\n\t"
+     : "=r"(a)
+    );
+    if (a != result) {
+        printf("movhi error\n");
+        return -1;
+    }
+
+    result = 0x1111;
+    __asm
+    ("l.movhi r8, 0x1111\n\t"
+     "l.srli   %0, r8, 16\n\t"
+     : "=r"(a)
+    );
+    if (a != result) {
+        printf("movhi error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_mul.c b/tests/tcg/openrisc/test_mul.c
new file mode 100644
index 0000000000..130101fdee
--- /dev/null
+++ b/tests/tcg/openrisc/test_mul.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x4;
+    c = 0x1;
+    result = 0x4;
+    __asm
+    ("l.mul    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mul error\n");
+        return -1;
+    }
+
+    b = 0x1;
+    c = 0x0;
+    result = 0x0;
+    __asm
+    ("l.mul    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mul error\n");
+        return -1;
+    }
+
+    b = 0x1;
+    c = 0xff;
+    result = 0xff;
+    __asm
+    ("l.mul    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mul error\n");
+        return -1;
+    }
+
+    b = 0x7fffffff;
+    c = 0x2;
+    result = 0xfffffffe;
+    __asm
+    ("l.mul    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mul error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_muli.c b/tests/tcg/openrisc/test_muli.c
new file mode 100644
index 0000000000..f1042e98de
--- /dev/null
+++ b/tests/tcg/openrisc/test_muli.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x4;
+    c = 0x1;
+    result = 0x4;
+    __asm
+    ("l.muli    %0, %1, 0x1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("muli error\n");
+        return -1;
+    }
+
+    b = 0x1;
+    c = 0x0;
+    result = 0x0;
+    __asm
+    ("l.muli    %0, %1, 0x0\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("muli error\n");
+        return -1;
+    }
+
+    b = 0x1;
+    c = 0xff;
+    result = 0xff;
+    __asm
+    ("l.muli    %0, %1, 0xff\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("muli error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_mulu.c b/tests/tcg/openrisc/test_mulu.c
new file mode 100644
index 0000000000..2d1e97d16e
--- /dev/null
+++ b/tests/tcg/openrisc/test_mulu.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x4;
+    c = 0x1;
+    result = 0x4;
+    __asm
+    ("l.mulu    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mulu error\n");
+        return -1;
+    }
+
+    b = 0x1;
+    c = 0x0;
+    result = 0x0;
+    __asm
+    ("l.mulu    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mulu error\n");
+        return -1;
+    }
+
+    b = 0x1;
+    c = 0xff;
+    result = 0xff;
+    __asm
+    ("l.mulu    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mulu error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfeq.c b/tests/tcg/openrisc/test_sfeq.c
new file mode 100644
index 0000000000..bd7f875b71
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfeq.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0x1;
+    b = 0x80;
+    result = 0x2;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 0x1\n\t"
+     "l.sfeq   %0, %1\n\t"
+     "l.bf     1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfeq error\n");
+        return -1;
+    }
+
+    a = 0x7f;
+    b = 0x80;
+    result = 0x81;
+    __asm
+    ("2:\n\t"
+     "l.addi   %0, %0, 0x1\n\t"
+     "l.sfeq   %0, %1\n\t"
+     "l.bf     2b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfeq error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfeqi.c b/tests/tcg/openrisc/test_sfeqi.c
new file mode 100644
index 0000000000..574261321b
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfeqi.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 1;
+    result = 2;
+    __asm
+    ("1:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.sfeqi   %0, 0x80\n\t"
+     "l.bf      1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfeqi error\n");
+        return -1;
+    }
+
+    a = 0x7f;
+    result = 0x81;
+    __asm
+    ("2:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.sfeqi   %0, 0x80\n\t"
+     "l.bf      2b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfeqi error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfges.c b/tests/tcg/openrisc/test_sfges.c
new file mode 100644
index 0000000000..23761d7f5a
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfges.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 1;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfges  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfges error\n");
+        return -1;
+    }
+
+    a = 0xff;
+    b = 3;
+    c = 0x1;
+    result = 2;
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %2\n\t"
+     "l.sfges  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfges error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgesi.c b/tests/tcg/openrisc/test_sfgesi.c
new file mode 100644
index 0000000000..54a2d51cd5
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgesi.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    result = 1;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgesi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfgesi error\n");
+        return -1;
+    }
+
+    a = 0xff;
+    b = 1;
+    result = 2;
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %1\n\t"
+     "l.sfgesi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgesi error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgeu.c b/tests/tcg/openrisc/test_sfgeu.c
new file mode 100644
index 0000000000..2a491d91ea
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgeu.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 1;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgeu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgeu error\n");
+        return -1;
+    }
+
+    a = 0xff;
+    b = 3;
+    c = 1;
+    result = 2;
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %2\n\t"
+     "l.sfgeu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfgeu error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgeui.c b/tests/tcg/openrisc/test_sfgeui.c
new file mode 100644
index 0000000000..40af35c68f
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgeui.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    result = 1;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgeui %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfgeui error\n");
+        return -1;
+    }
+
+    a = 0xff;
+    b = 1;
+    result = 2;
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %1\n\t"
+     "l.sfgeui %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgeui error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgts.c b/tests/tcg/openrisc/test_sfgts.c
new file mode 100644
index 0000000000..4481a9cc3d
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgts.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 1;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgts  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgts error\n");
+        return -1;
+    }
+
+
+    a = 0xff;
+    b = 3;
+    c = 1;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %2\n\t"
+     "l.sfgts  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfgts error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgtsi.c b/tests/tcg/openrisc/test_sfgtsi.c
new file mode 100644
index 0000000000..7366e1292c
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgtsi.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    result = 1;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgtsi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfgtsi error\n");
+        return -1;
+    }
+
+    a = 0xff;
+    b = 1;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %1\n\t"
+     "l.sfgtsi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgtsi error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgtu.c b/tests/tcg/openrisc/test_sfgtu.c
new file mode 100644
index 0000000000..da2868916d
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgtu.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 1;
+    __asm
+    ("1:\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.sfgtu %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgtu error\n");
+        return -1;
+    }
+
+    a = 0xff;
+    b = 3;
+    c = 1;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %2\n\t"
+     "l.sfgtu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfgtu error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgtui.c b/tests/tcg/openrisc/test_sfgtui.c
new file mode 100644
index 0000000000..565d44f112
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgtui.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    result = 1;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgtui %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfgtui error\n");
+        return -1;
+    }
+
+
+    a = 0xff;
+    b = 1;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.sub     %0, %0, %1\n\t"
+     "l.sfgtui  %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgtui error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfles.c b/tests/tcg/openrisc/test_sfles.c
new file mode 100644
index 0000000000..f5735228fe
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfles.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfles  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfles error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sflesi.c b/tests/tcg/openrisc/test_sflesi.c
new file mode 100644
index 0000000000..16fe6053e5
--- /dev/null
+++ b/tests/tcg/openrisc/test_sflesi.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sflesi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sflesi error\n");
+        return -1;
+    }
+
+    a = 0;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sflesi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sflesi error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfleu.c b/tests/tcg/openrisc/test_sfleu.c
new file mode 100644
index 0000000000..be0a3c3f48
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfleu.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfleu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfleu error\n");
+        return -1;
+    }
+
+    a = 0;
+    b = 3;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfleu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfleu error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfleui.c b/tests/tcg/openrisc/test_sfleui.c
new file mode 100644
index 0000000000..38d3c89709
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfleui.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfleui %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfleui error\n");
+        return -1;
+    }
+
+    a = 0;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfleui %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfleui error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sflts.c b/tests/tcg/openrisc/test_sflts.c
new file mode 100644
index 0000000000..7deeb48d09
--- /dev/null
+++ b/tests/tcg/openrisc/test_sflts.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sflts  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sflts error\n");
+        return -1;
+    }
+
+    a = 0;
+    b = 3;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.addi    %0, %0, 1\n\t"
+     "l.sflts   %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sflts error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfltsi.c b/tests/tcg/openrisc/test_sfltsi.c
new file mode 100644
index 0000000000..3cb1f02857
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfltsi.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfltsi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfltsi error\n");
+        return -1;
+    }
+
+    a = 0;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.addi    %0, %0, 1\n\t"
+     "l.sfltsi  %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfltsi error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfltu.c b/tests/tcg/openrisc/test_sfltu.c
new file mode 100644
index 0000000000..7ed3b26858
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfltu.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfltu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfltu error\n");
+        return -1;
+    }
+
+    a = 0;
+    b = 3;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.addi    %0, %0, 1\n\t"
+     "l.sfltu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfltu error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfltui.c b/tests/tcg/openrisc/test_sfltui.c
new file mode 100644
index 0000000000..a5cb9f6a97
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfltui.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfltsi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfltui error\n");
+        return -1;
+    }
+
+    a = 0;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.addi    %0, %0, 1\n\t"
+     "l.sfltsi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfltui error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfne.c b/tests/tcg/openrisc/test_sfne.c
new file mode 100644
index 0000000000..b33a35cf96
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfne.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 3\n\t"
+     "l.sfne   %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfne error\n");
+        return -1;
+    }
+
+    a = 0;
+    b = 3;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfne   %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfne error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfnei.c b/tests/tcg/openrisc/test_sfnei.c
new file mode 100644
index 0000000000..d311c9e660
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfnei.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 3\n\t"
+     "l.sfnei  %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfnei error\n");
+        return -1;
+    }
+
+    a = 0;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfnei  %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfnei error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sub.c b/tests/tcg/openrisc/test_sub.c
new file mode 100644
index 0000000000..474ec6055b
--- /dev/null
+++ b/tests/tcg/openrisc/test_sub.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0x100;
+    b = 0x100;
+    result = 0x0;
+    __asm
+    ("l.sub %0, %0, %1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sub error\n");
+        return -1;
+    }
+
+    a = 0xffff;
+    b = 0x1;
+    result = 0xfffe;
+    __asm
+    ("l.sub %0, %0, %1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sub error\n");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/xtensa/test_mmu.S b/tests/tcg/xtensa/test_mmu.S
index 52d5774212..5d87fbb703 100644
--- a/tests/tcg/xtensa/test_mmu.S
+++ b/tests/tcg/xtensa/test_mmu.S
@@ -293,26 +293,219 @@ test store_prohibited
     assert  eq, a2, a3
 test_end
 
-test dtlb_autoload
-    set_vector kernel, 0
-
-    movi    a2, 0xd4000000
+/* Set up page table entry vaddr->paddr, ring=pte_ring, attr=pte_attr
+ * and DTLB way 7 to cover this PTE, ring=pt_ring, attr=pt_attr
+ */
+.macro pt_setup pt_ring, pt_attr, pte_ring, vaddr, paddr, pte_attr
+    movi    a2, 0x80000000
     wsr     a2, ptevaddr
-    movi    a3, 0x00001013
-    s32i    a3, a2, 4
+
+    movi    a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */
+    movi    a4, 0x04000003 | ((\pt_ring) << 4) /* PADDR 64M */
+    wdtlb   a4, a3
+    isync
+
+    movi    a3, ((\paddr) & 0xfffff000) | ((\pte_ring) << 4) | (\pte_attr)
+    movi    a1, ((\vaddr) >> 12) << 2
+    add     a2, a1, a2
+    s32i    a3, a2, 0
+
+    movi    a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */
+    movi    a4, 0x04000000 | ((\pt_ring) << 4) | (\pt_attr) /* PADDR 64M */
+    wdtlb   a4, a3
+    isync
+
+    movi    a3, (\vaddr)
+.endm
+
+/* out: PS.RING=ring, PS.EXCM=excm, a3=vaddr */
+.macro go_ring ring, excm, vaddr
+    movi    a3, 10f
+    pitlb   a3, a3
+    ritlb1  a2, a3
+    movi    a1, 0x10
+    or      a2, a2, a1
+    movi    a1, 0x000ff000
+    and     a3, a3, a1
+    movi    a1, 4
+    or      a3, a3, a1
+    witlb   a2, a3
+    movi    a3, 10f
+    movi    a1, 0x000fffff
+    and     a1, a3, a1
+
+    movi    a2, 0
+    wsr     a2, excvaddr
+
+    movi    a3, \vaddr
+    movi    a2, 0x4000f | ((\ring) << 6) | ((\excm) << 4)
+    jx      a1
+10:
+    wsr     a2, ps
+    isync
+.endm
+
+/* in: a3 -- virtual address to test */
+.macro assert_auto_tlb
+    movi    a2, 0x4000f
+    wsr     a2, ps
+    isync
+    pdtlb   a2, a3
+    movi    a1, 0xfffff01f
+    and     a2, a2, a1
+    movi    a1, 0xfffff000
+    and     a1, a1, a3
+    xor     a1, a1, a2
+    assert  gei, a1, 0x10
+    movi    a2, 0x14
+    assert  lt, a1, a2
+.endm
+
+/* in: a3 -- virtual address to test */
+.macro assert_no_auto_tlb
+    movi    a2, 0x4000f
+    wsr     a2, ps
+    isync
     pdtlb   a2, a3
     movi    a1, 0x10
     and     a1, a1, a2
     assert  eqi, a1, 0
-    l8ui    a1, a3, 0
-    pdtlb   a2, a3
-    movi    a1, 0xfffff010
-    and     a1, a1, a2
-    movi    a3, 0x00001010
-    assert  eq, a1, a3
-    movi    a1, 0xf
+.endm
+
+.macro assert_sr sr, v
+    rsr     a2, \sr
+    movi    a1, (\v)
+    assert  eq, a1, a2
+.endm
+
+.macro assert_epc1_1m vaddr
+    movi    a2, (\vaddr)
+    movi    a1, 0xfffff
     and     a1, a1, a2
-    assert  lti, a1, 4
+    rsr     a2, epc1
+    assert  eq, a1, a2
+.endm
+
+test dtlb_autoload
+    set_vector kernel, 0
+
+    pt_setup    0, 3, 1, 0x1000, 0x1000, 3
+    assert_no_auto_tlb
+
+    l8ui    a1, a3, 0
+
+    rsr     a2, excvaddr
+    assert  eq, a2, a3
+
+    assert_auto_tlb
+test_end
+
+test autoload_load_store_privilege
+    set_vector kernel, 0
+    set_vector double, 2f
+
+    pt_setup    0, 3, 0, 0x2000, 0x2000, 3
+    movi    a3, 0x2004
+    assert_no_auto_tlb
+
+    movi    a2, 0x4005f    /* ring 1 + excm => cring == 0 */
+    wsr     a2, ps
+    isync
+1:
+    l32e    a2, a3, -4     /* ring used */
+    test_fail
+2:
+    rsr     a2, excvaddr
+    addi    a1, a3, -4
+    assert  eq, a1, a2
+
+    assert_auto_tlb
+    assert_sr depc, 1b
+    assert_sr exccause, 26
+test_end
+
+test autoload_pte_load_prohibited
+    set_vector kernel, 2f
+
+    pt_setup    0, 3, 0, 0x3000, 0, 0xc
+    assert_no_auto_tlb
+1:
+    l32i    a2, a3, 0
+    test_fail
+2:
+    rsr     a2, excvaddr
+    assert  eq, a2, a3
+
+    assert_auto_tlb
+    assert_sr epc1, 1b
+    assert_sr exccause, 28
+test_end
+
+test autoload_pt_load_prohibited
+    set_vector kernel, 2f
+
+    pt_setup    0, 0xc, 0, 0x4000, 0x4000, 3
+    assert_no_auto_tlb
+1:
+    l32i    a2, a3, 0
+    test_fail
+2:
+    rsr     a2, excvaddr
+    assert  eq, a2, a3
+
+    assert_no_auto_tlb
+    assert_sr epc1, 1b
+    assert_sr exccause, 24
+test_end
+
+test autoload_pt_privilege
+    set_vector  kernel, 2f
+    pt_setup    0, 3, 1, 0x5000, 0, 3
+    go_ring     1, 0, 0x5001
+
+    l8ui    a2, a3, 0
+1:
+    syscall
+2:
+    rsr     a2, excvaddr
+    assert  eq, a2, a3
+
+    assert_auto_tlb
+    assert_epc1_1m 1b
+    assert_sr exccause, 1
+test_end
+
+test autoload_pte_privilege
+    set_vector  kernel, 2f
+    pt_setup    0, 3, 0, 0x6000, 0, 3
+    go_ring     1, 0, 0x6001
+1:
+    l8ui    a2, a3, 0
+    syscall
+2:
+    rsr     a2, excvaddr
+    assert  eq, a2, a3
+
+    assert_auto_tlb
+    assert_epc1_1m 1b
+    assert_sr exccause, 26
+test_end
+
+test autoload_3_level_pt
+    set_vector  kernel, 2f
+    pt_setup    1, 3, 1, 0x00400000, 0, 3
+    pt_setup    1, 3, 1, 0x80001000, 0x2000000, 3
+    go_ring     1, 0, 0x00400001
+1:
+    l8ui    a2, a3, 0
+    syscall
+2:
+    rsr     a2, excvaddr
+    assert  eq, a2, a3
+
+    assert_no_auto_tlb
+    assert_epc1_1m 1b
+    assert_sr exccause, 24
 test_end
 
 test_suite_end
diff --git a/tests/test-iov.c b/tests/test-iov.c
new file mode 100644
index 0000000000..cbe7a8955c
--- /dev/null
+++ b/tests/test-iov.c
@@ -0,0 +1,260 @@
+#include <glib.h>
+#include "qemu-common.h"
+#include "iov.h"
+#include "qemu_socket.h"
+
+/* create a randomly-sized iovec with random vectors */
+static void iov_random(struct iovec **iovp, unsigned *iov_cntp)
+{
+     unsigned niov = g_test_rand_int_range(3,8);
+     struct iovec *iov = g_malloc(niov * sizeof(*iov));
+     unsigned i;
+     for (i = 0; i < niov; ++i) {
+         iov[i].iov_len = g_test_rand_int_range(5,20);
+         iov[i].iov_base = g_malloc(iov[i].iov_len);
+     }
+     *iovp = iov;
+     *iov_cntp = niov;
+}
+
+static void iov_free(struct iovec *iov, unsigned niov)
+{
+    unsigned i;
+    for (i = 0; i < niov; ++i) {
+        g_free(iov[i].iov_base);
+    }
+    g_free(iov);
+}
+
+static void test_iov_bytes(struct iovec *iov, unsigned niov,
+                           size_t offset, size_t bytes)
+{
+    unsigned i;
+    size_t j, o;
+    unsigned char *b;
+    o = 0;
+
+    /* we walk over all elements, */
+    for (i = 0; i < niov; ++i) {
+        b = iov[i].iov_base;
+        /* over each char of each element, */
+        for (j = 0; j < iov[i].iov_len; ++j) {
+            /* counting each of them and
+             * verifying that the ones within [offset,offset+bytes)
+             * range are equal to the position number (o) */
+            if (o >= offset && o < offset + bytes) {
+                g_assert(b[j] == (o & 255));
+            } else {
+                g_assert(b[j] == 0xff);
+            }
+            ++o;
+        }
+    }
+}
+
+static void test_to_from_buf_1(void)
+{
+     unsigned niov;
+     struct iovec *iov;
+     size_t sz;
+     unsigned char *ibuf, *obuf;
+     unsigned i, j, n;
+
+     iov_random(&iov, &niov);
+
+     sz = iov_size(iov, niov);
+
+     ibuf = g_malloc(sz + 8) + 4;
+     memcpy(ibuf-4, "aaaa", 4); memcpy(ibuf + sz, "bbbb", 4);
+     obuf = g_malloc(sz + 8) + 4;
+     memcpy(obuf-4, "xxxx", 4); memcpy(obuf + sz, "yyyy", 4);
+
+     /* fill in ibuf with 0123456... */
+     for (i = 0; i < sz; ++i) {
+         ibuf[i] = i & 255;
+     }
+
+     for (i = 0; i <= sz; ++i) {
+
+         /* Test from/to buf for offset(i) in [0..sz] up to the end of buffer.
+          * For last iteration with offset == sz, the procedure should
+          * skip whole vector and process exactly 0 bytes */
+
+         /* first set bytes [i..sz) to some "random" value */
+         n = iov_memset(iov, niov, 0, 0xff, -1);
+         g_assert(n == sz);
+
+         /* next copy bytes [i..sz) from ibuf to iovec */
+         n = iov_from_buf(iov, niov, i, ibuf + i, -1);
+         g_assert(n == sz - i);
+
+         /* clear part of obuf */
+         memset(obuf + i, 0, sz - i);
+         /* and set this part of obuf to values from iovec */
+         n = iov_to_buf(iov, niov, i, obuf + i, -1);
+         g_assert(n == sz - i);
+
+         /* now compare resulting buffers */
+         g_assert(memcmp(ibuf, obuf, sz) == 0);
+
+         /* test just one char */
+         n = iov_to_buf(iov, niov, i, obuf + i, 1);
+         g_assert(n == (i < sz));
+         if (n) {
+             g_assert(obuf[i] == (i & 255));
+         }
+
+         for (j = i; j <= sz; ++j) {
+             /* now test num of bytes cap up to byte no. j,
+              * with j in [i..sz]. */
+
+             /* clear iovec */
+             n = iov_memset(iov, niov, 0, 0xff, -1);
+             g_assert(n == sz);
+
+             /* copy bytes [i..j) from ibuf to iovec */
+             n = iov_from_buf(iov, niov, i, ibuf + i, j - i);
+             g_assert(n == j - i);
+
+             /* clear part of obuf */
+             memset(obuf + i, 0, j - i);
+
+             /* copy bytes [i..j) from iovec to obuf */
+             n = iov_to_buf(iov, niov, i, obuf + i, j - i);
+             g_assert(n == j - i);
+
+             /* verify result */
+             g_assert(memcmp(ibuf, obuf, sz) == 0);
+
+             /* now actually check if the iovec contains the right data */
+             test_iov_bytes(iov, niov, i, j - i);
+         }
+    }
+    g_assert(!memcmp(ibuf-4, "aaaa", 4) && !memcmp(ibuf+sz, "bbbb", 4));
+    g_free(ibuf-4);
+    g_assert(!memcmp(obuf-4, "xxxx", 4) && !memcmp(obuf+sz, "yyyy", 4));
+    g_free(obuf-4);
+    iov_free(iov, niov);
+}
+
+static void test_to_from_buf(void)
+{
+    int x;
+    for (x = 0; x < 4; ++x) {
+        test_to_from_buf_1();
+    }
+}
+
+static void test_io(void)
+{
+#ifndef _WIN32
+/* socketpair(PF_UNIX) which does not exist on windows */
+
+    int sv[2];
+    int r;
+    unsigned i, j, k, s, t;
+    fd_set fds;
+    unsigned niov;
+    struct iovec *iov, *siov;
+    unsigned char *buf;
+    size_t sz;
+
+    iov_random(&iov, &niov);
+    sz = iov_size(iov, niov);
+    buf = g_malloc(sz);
+    for (i = 0; i < sz; ++i) {
+        buf[i] = i & 255;
+    }
+    iov_from_buf(iov, niov, 0, buf, sz);
+
+    siov = g_malloc(sizeof(*iov) * niov);
+    memcpy(siov, iov, sizeof(*iov) * niov);
+
+    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) < 0) {
+       perror("socketpair");
+       exit(1);
+    }
+
+    FD_ZERO(&fds);
+
+    t = 0;
+    if (fork() == 0) {
+       /* writer */
+
+       close(sv[0]);
+       FD_SET(sv[1], &fds);
+       fcntl(sv[1], F_SETFL, O_RDWR|O_NONBLOCK);
+       r = g_test_rand_int_range(sz / 2, sz);
+       setsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &r, sizeof(r));
+
+       for (i = 0; i <= sz; ++i) {
+           for (j = i; j <= sz; ++j) {
+               k = i;
+               do {
+                   s = g_test_rand_int_range(0, j - k + 1);
+                   r = iov_send(sv[1], iov, niov, k, s);
+                   g_assert(memcmp(iov, siov, sizeof(*iov)*niov) == 0);
+                   if (r >= 0) {
+                       k += r;
+                       t += r;
+                       usleep(g_test_rand_int_range(0, 30));
+                   } else if (errno == EAGAIN) {
+                       select(sv[1]+1, NULL, &fds, NULL, NULL);
+                       continue;
+                   } else {
+                       perror("send");
+                       exit(1);
+                   }
+               } while(k < j);
+           }
+       }
+       exit(0);
+
+    } else {
+       /* reader & verifier */
+
+       close(sv[1]);
+       FD_SET(sv[0], &fds);
+       fcntl(sv[0], F_SETFL, O_RDWR|O_NONBLOCK);
+       r = g_test_rand_int_range(sz / 2, sz);
+       setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &r, sizeof(r));
+       usleep(500000);
+
+       for (i = 0; i <= sz; ++i) {
+           for (j = i; j <= sz; ++j) {
+               k = i;
+               iov_memset(iov, niov, 0, 0xff, -1);
+               do {
+                   s = g_test_rand_int_range(0, j - k + 1);
+                   r = iov_recv(sv[0], iov, niov, k, s);
+                   g_assert(memcmp(iov, siov, sizeof(*iov)*niov) == 0);
+                   if (r > 0) {
+                       k += r;
+                       t += r;
+                   } else if (!r) {
+                       if (s) {
+                           break;
+                       }
+                   } else if (errno == EAGAIN) {
+                       select(sv[0]+1, &fds, NULL, NULL, NULL);
+                       continue;
+                   } else {
+                       perror("recv");
+                       exit(1);
+                   }
+               } while(k < j);
+               test_iov_bytes(iov, niov, i, j - i);
+           }
+        }
+     }
+#endif
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+    g_test_rand_int();
+    g_test_add_func("/basic/iov/from-to-buf", test_to_from_buf);
+    g_test_add_func("/basic/iov/io", test_io);
+    return g_test_run();
+}
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 60cbf019bb..dc3c507f2b 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -3,6 +3,9 @@
 #include "test-qmp-commands.h"
 #include "qapi/qmp-core.h"
 #include "module.h"
+#include "qapi/qmp-input-visitor.h"
+#include "tests/test-qapi-types.h"
+#include "tests/test-qapi-visit.h"
 
 void qmp_user_def_cmd(Error **errp)
 {
@@ -123,6 +126,44 @@ static void test_dealloc_types(void)
     qapi_free_UserDefOneList(ud1list);
 }
 
+/* test generated deallocation on an object whose construction was prematurely
+ * terminated due to an error */
+static void test_dealloc_partial(void)
+{
+    static const char text[] = "don't leak me";
+
+    UserDefTwo *ud2 = NULL;
+    Error *err = NULL;
+
+    /* create partial object */
+    {
+        QDict *ud2_dict;
+        QmpInputVisitor *qiv;
+
+        ud2_dict = qdict_new();
+        qdict_put_obj(ud2_dict, "string", QOBJECT(qstring_from_str(text)));
+
+        qiv = qmp_input_visitor_new(QOBJECT(ud2_dict));
+        visit_type_UserDefTwo(qmp_input_get_visitor(qiv), &ud2, NULL, &err);
+        qmp_input_visitor_cleanup(qiv);
+        QDECREF(ud2_dict);
+    }
+
+    /* verify partial success */
+    assert(ud2 != NULL);
+    assert(ud2->string != NULL);
+    assert(strcmp(ud2->string, text) == 0);
+    assert(ud2->dict.dict.userdef == NULL);
+
+    /* confirm & release construction error */
+    assert(err != NULL);
+    error_free(err);
+
+    /* tear down partial object */
+    qapi_free_UserDefTwo(ud2);
+}
+
+
 int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
@@ -131,6 +172,7 @@ int main(int argc, char **argv)
     g_test_add_func("/0.15/dispatch_cmd_error", test_dispatch_cmd_error);
     g_test_add_func("/0.15/dispatch_cmd_io", test_dispatch_cmd_io);
     g_test_add_func("/0.15/dealloc_types", test_dealloc_types);
+    g_test_add_func("/0.15/dealloc_partial", test_dealloc_partial);
 
     module_call_init(MODULE_INIT_QAPI);
     g_test_run();
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index c30fdc4e59..8f5a509582 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -151,14 +151,22 @@ typedef struct TestStruct
 static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
                                   const char *name, Error **errp)
 {
-    visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
-                       errp);
-
-    visit_type_int(v, &(*obj)->integer, "integer", errp);
-    visit_type_bool(v, &(*obj)->boolean, "boolean", errp);
-    visit_type_str(v, &(*obj)->string, "string", errp);
-
-    visit_end_struct(v, errp);
+    Error *err = NULL;
+    if (!error_is_set(errp)) {
+        visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
+                           &err);
+        if (!err) {
+            visit_type_int(v, &(*obj)->integer, "integer", &err);
+            visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
+            visit_type_str(v, &(*obj)->string, "string", &err);
+
+            /* Always call end_struct if start_struct succeeded.  */
+            error_propagate(errp, err);
+            err = NULL;
+            visit_end_struct(v, &err);
+        }
+        error_propagate(errp, err);
+    }
 }
 
 static void test_visitor_in_struct(TestInputVisitorData *data,
diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
index 22909b84ef..608f14a5de 100644
--- a/tests/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
@@ -84,7 +84,7 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
-    g_assert_cmpstr(str, ==, "3.14");
+    g_assert_cmpstr(str, ==, "3.140000");
     g_free(str);
 }
 
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
new file mode 100644
index 0000000000..b8ad16fc9e
--- /dev/null
+++ b/tests/test-visitor-serialization.c
@@ -0,0 +1,784 @@
+/*
+ * Unit-tests for visitor-based serialization
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Michael Roth <mdroth@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <float.h>
+#include "test-qapi-types.h"
+#include "test-qapi-visit.h"
+#include "qemu-objects.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/string-input-visitor.h"
+#include "qapi/string-output-visitor.h"
+
+typedef struct PrimitiveType {
+    union {
+        const char *string;
+        bool boolean;
+        double number;
+        int64_t integer;
+        uint8_t u8;
+        uint16_t u16;
+        uint32_t u32;
+        uint64_t u64;
+        int8_t s8;
+        int16_t s16;
+        int32_t s32;
+        int64_t s64;
+        intmax_t max;
+    } value;
+    enum {
+        PTYPE_STRING = 0,
+        PTYPE_BOOLEAN,
+        PTYPE_NUMBER,
+        PTYPE_INTEGER,
+        PTYPE_U8,
+        PTYPE_U16,
+        PTYPE_U32,
+        PTYPE_U64,
+        PTYPE_S8,
+        PTYPE_S16,
+        PTYPE_S32,
+        PTYPE_S64,
+        PTYPE_EOL,
+    } type;
+    const char *description;
+} PrimitiveType;
+
+/* test helpers */
+
+static void visit_primitive_type(Visitor *v, void **native, Error **errp)
+{
+    PrimitiveType *pt = *native;
+    switch(pt->type) {
+    case PTYPE_STRING:
+        visit_type_str(v, (char **)&pt->value.string, NULL, errp);
+        break;
+    case PTYPE_BOOLEAN:
+        visit_type_bool(v, &pt->value.boolean, NULL, errp);
+        break;
+    case PTYPE_NUMBER:
+        visit_type_number(v, &pt->value.number, NULL, errp);
+        break;
+    case PTYPE_INTEGER:
+        visit_type_int(v, &pt->value.integer, NULL, errp);
+        break;
+    case PTYPE_U8:
+        visit_type_uint8(v, &pt->value.u8, NULL, errp);
+        break;
+    case PTYPE_U16:
+        visit_type_uint16(v, &pt->value.u16, NULL, errp);
+        break;
+    case PTYPE_U32:
+        visit_type_uint32(v, &pt->value.u32, NULL, errp);
+        break;
+    case PTYPE_U64:
+        visit_type_uint64(v, &pt->value.u64, NULL, errp);
+        break;
+    case PTYPE_S8:
+        visit_type_int8(v, &pt->value.s8, NULL, errp);
+        break;
+    case PTYPE_S16:
+        visit_type_int16(v, &pt->value.s16, NULL, errp);
+        break;
+    case PTYPE_S32:
+        visit_type_int32(v, &pt->value.s32, NULL, errp);
+        break;
+    case PTYPE_S64:
+        visit_type_int64(v, &pt->value.s64, NULL, errp);
+        break;
+    case PTYPE_EOL:
+        g_assert(false);
+    }
+}
+
+typedef struct TestStruct
+{
+    int64_t integer;
+    bool boolean;
+    char *string;
+} TestStruct;
+
+static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
+                                  const char *name, Error **errp)
+{
+    visit_start_struct(v, (void **)obj, NULL, name, sizeof(TestStruct), errp);
+
+    visit_type_int(v, &(*obj)->integer, "integer", errp);
+    visit_type_bool(v, &(*obj)->boolean, "boolean", errp);
+    visit_type_str(v, &(*obj)->string, "string", errp);
+
+    visit_end_struct(v, errp);
+}
+
+static TestStruct *struct_create(void)
+{
+    TestStruct *ts = g_malloc0(sizeof(*ts));
+    ts->integer = -42;
+    ts->boolean = true;
+    ts->string = strdup("test string");
+    return ts;
+}
+
+static void struct_compare(TestStruct *ts1, TestStruct *ts2)
+{
+    g_assert(ts1);
+    g_assert(ts2);
+    g_assert_cmpint(ts1->integer, ==, ts2->integer);
+    g_assert(ts1->boolean == ts2->boolean);
+    g_assert_cmpstr(ts1->string, ==, ts2->string);
+}
+
+static void struct_cleanup(TestStruct *ts)
+{
+    g_free(ts->string);
+    g_free(ts);
+}
+
+static void visit_struct(Visitor *v, void **native, Error **errp)
+{
+    visit_type_TestStruct(v, (TestStruct **)native, NULL, errp);
+}
+
+static UserDefNested *nested_struct_create(void)
+{
+    UserDefNested *udnp = g_malloc0(sizeof(*udnp));
+    udnp->string0 = strdup("test_string0");
+    udnp->dict1.string1 = strdup("test_string1");
+    udnp->dict1.dict2.userdef1 = g_malloc0(sizeof(UserDefOne));
+    udnp->dict1.dict2.userdef1->integer = 42;
+    udnp->dict1.dict2.userdef1->string = strdup("test_string");
+    udnp->dict1.dict2.string2 = strdup("test_string2");
+    udnp->dict1.has_dict3 = true;
+    udnp->dict1.dict3.userdef2 = g_malloc0(sizeof(UserDefOne));
+    udnp->dict1.dict3.userdef2->integer = 43;
+    udnp->dict1.dict3.userdef2->string = strdup("test_string");
+    udnp->dict1.dict3.string3 = strdup("test_string3");
+    return udnp;
+}
+
+static void nested_struct_compare(UserDefNested *udnp1, UserDefNested *udnp2)
+{
+    g_assert(udnp1);
+    g_assert(udnp2);
+    g_assert_cmpstr(udnp1->string0, ==, udnp2->string0);
+    g_assert_cmpstr(udnp1->dict1.string1, ==, udnp2->dict1.string1);
+    g_assert_cmpint(udnp1->dict1.dict2.userdef1->integer, ==,
+                    udnp2->dict1.dict2.userdef1->integer);
+    g_assert_cmpstr(udnp1->dict1.dict2.userdef1->string, ==,
+                    udnp2->dict1.dict2.userdef1->string);
+    g_assert_cmpstr(udnp1->dict1.dict2.string2, ==, udnp2->dict1.dict2.string2);
+    g_assert(udnp1->dict1.has_dict3 == udnp2->dict1.has_dict3);
+    g_assert_cmpint(udnp1->dict1.dict3.userdef2->integer, ==,
+                    udnp2->dict1.dict3.userdef2->integer);
+    g_assert_cmpstr(udnp1->dict1.dict3.userdef2->string, ==,
+                    udnp2->dict1.dict3.userdef2->string);
+    g_assert_cmpstr(udnp1->dict1.dict3.string3, ==, udnp2->dict1.dict3.string3);
+}
+
+static void nested_struct_cleanup(UserDefNested *udnp)
+{
+    qapi_free_UserDefNested(udnp);
+}
+
+static void visit_nested_struct(Visitor *v, void **native, Error **errp)
+{
+    visit_type_UserDefNested(v, (UserDefNested **)native, NULL, errp);
+}
+
+static void visit_nested_struct_list(Visitor *v, void **native, Error **errp)
+{
+    visit_type_UserDefNestedList(v, (UserDefNestedList **)native, NULL, errp);
+}
+
+/* test cases */
+
+typedef void (*VisitorFunc)(Visitor *v, void **native, Error **errp);
+
+typedef enum VisitorCapabilities {
+    VCAP_PRIMITIVES = 1,
+    VCAP_STRUCTURES = 2,
+    VCAP_LISTS = 4,
+} VisitorCapabilities;
+
+typedef struct SerializeOps {
+    void (*serialize)(void *native_in, void **datap,
+                      VisitorFunc visit, Error **errp);
+    void (*deserialize)(void **native_out, void *datap,
+                            VisitorFunc visit, Error **errp);
+    void (*cleanup)(void *datap);
+    const char *type;
+    VisitorCapabilities caps;
+} SerializeOps;
+
+typedef struct TestArgs {
+    const SerializeOps *ops;
+    void *test_data;
+} TestArgs;
+
+#define FLOAT_STRING_PRECISION 6 /* corresponding to n in %.nf formatting */
+static gsize calc_float_string_storage(double value)
+{
+    int whole_value = value;
+    gsize i = 0;
+    do {
+        i++;
+    } while (whole_value /= 10);
+    return i + 2 + FLOAT_STRING_PRECISION;
+}
+
+static void test_primitives(gconstpointer opaque)
+{
+    TestArgs *args = (TestArgs *) opaque;
+    const SerializeOps *ops = args->ops;
+    PrimitiveType *pt = args->test_data;
+    PrimitiveType *pt_copy = g_malloc0(sizeof(*pt_copy));
+    Error *err = NULL;
+    void *serialize_data;
+    char *double1, *double2;
+
+    pt_copy->type = pt->type;
+    ops->serialize(pt, &serialize_data, visit_primitive_type, &err);
+    ops->deserialize((void **)&pt_copy, serialize_data, visit_primitive_type, &err);
+
+    g_assert(err == NULL);
+    g_assert(pt_copy != NULL);
+    if (pt->type == PTYPE_STRING) {
+        g_assert_cmpstr(pt->value.string, ==, pt_copy->value.string);
+    } else if (pt->type == PTYPE_NUMBER) {
+        /* we serialize with %f for our reference visitors, so rather than fuzzy
+         * floating math to test "equality", just compare the formatted values
+         */
+        double1 = g_malloc0(calc_float_string_storage(pt->value.number));
+        double2 = g_malloc0(calc_float_string_storage(pt_copy->value.number));
+        g_assert_cmpstr(double1, ==, double2);
+        g_free(double1);
+        g_free(double2);
+    } else if (pt->type == PTYPE_BOOLEAN) {
+        g_assert_cmpint(!!pt->value.max, ==, !!pt->value.max);
+    } else {
+        g_assert_cmpint(pt->value.max, ==, pt_copy->value.max);
+    }
+
+    ops->cleanup(serialize_data);
+    g_free(args);
+}
+
+static void test_struct(gconstpointer opaque)
+{
+    TestArgs *args = (TestArgs *) opaque;
+    const SerializeOps *ops = args->ops;
+    TestStruct *ts = struct_create();
+    TestStruct *ts_copy = NULL;
+    Error *err = NULL;
+    void *serialize_data;
+
+    ops->serialize(ts, &serialize_data, visit_struct, &err);
+    ops->deserialize((void **)&ts_copy, serialize_data, visit_struct, &err); 
+
+    g_assert(err == NULL);
+    struct_compare(ts, ts_copy);
+
+    struct_cleanup(ts);
+    struct_cleanup(ts_copy);
+
+    ops->cleanup(serialize_data);
+    g_free(args);
+}
+
+static void test_nested_struct(gconstpointer opaque)
+{
+    TestArgs *args = (TestArgs *) opaque;
+    const SerializeOps *ops = args->ops;
+    UserDefNested *udnp = nested_struct_create();
+    UserDefNested *udnp_copy = NULL;
+    Error *err = NULL;
+    void *serialize_data;
+    
+    ops->serialize(udnp, &serialize_data, visit_nested_struct, &err);
+    ops->deserialize((void **)&udnp_copy, serialize_data, visit_nested_struct, &err); 
+
+    g_assert(err == NULL);
+    nested_struct_compare(udnp, udnp_copy);
+
+    nested_struct_cleanup(udnp);
+    nested_struct_cleanup(udnp_copy);
+
+    ops->cleanup(serialize_data);
+    g_free(args);
+}
+
+static void test_nested_struct_list(gconstpointer opaque)
+{
+    TestArgs *args = (TestArgs *) opaque;
+    const SerializeOps *ops = args->ops;
+    UserDefNestedList *listp = NULL, *tmp, *tmp_copy, *listp_copy = NULL;
+    Error *err = NULL;
+    void *serialize_data;
+    int i = 0;
+
+    for (i = 0; i < 8; i++) {
+        tmp = g_malloc0(sizeof(UserDefNestedList));
+        tmp->value = nested_struct_create();
+        tmp->next = listp;
+        listp = tmp;
+    }
+    
+    ops->serialize(listp, &serialize_data, visit_nested_struct_list, &err);
+    ops->deserialize((void **)&listp_copy, serialize_data,
+                     visit_nested_struct_list, &err); 
+
+    g_assert(err == NULL);
+
+    tmp = listp;
+    tmp_copy = listp_copy;
+    while (listp_copy) {
+        g_assert(listp);
+        nested_struct_compare(listp->value, listp_copy->value);
+        listp = listp->next;
+        listp_copy = listp_copy->next;
+    }
+
+    qapi_free_UserDefNestedList(tmp);
+    qapi_free_UserDefNestedList(tmp_copy);
+
+    ops->cleanup(serialize_data);
+    g_free(args);
+}
+
+PrimitiveType pt_values[] = {
+    /* string tests */
+    {
+        .description = "string_empty",
+        .type = PTYPE_STRING,
+        .value.string = "",
+    },
+    {
+        .description = "string_whitespace",
+        .type = PTYPE_STRING,
+        .value.string = "a b  c\td",
+    },
+    {
+        .description = "string_newlines",
+        .type = PTYPE_STRING,
+        .value.string = "a\nb\n",
+    },
+    {
+        .description = "string_commas",
+        .type = PTYPE_STRING,
+        .value.string = "a,b, c,d",
+    },
+    {
+        .description = "string_single_quoted",
+        .type = PTYPE_STRING,
+        .value.string = "'a b',cd",
+    },
+    {
+        .description = "string_double_quoted",
+        .type = PTYPE_STRING,
+        .value.string = "\"a b\",cd",
+    },
+    /* boolean tests */
+    {
+        .description = "boolean_true1",
+        .type = PTYPE_BOOLEAN,
+        .value.boolean = true,
+    },
+    {
+        .description = "boolean_true2",
+        .type = PTYPE_BOOLEAN,
+        .value.boolean = 8,
+    },
+    {
+        .description = "boolean_true3",
+        .type = PTYPE_BOOLEAN,
+        .value.boolean = -1,
+    },
+    {
+        .description = "boolean_false1",
+        .type = PTYPE_BOOLEAN,
+        .value.boolean = false,
+    },
+    {
+        .description = "boolean_false2",
+        .type = PTYPE_BOOLEAN,
+        .value.boolean = 0,
+    },
+    /* number tests (double) */
+    /* note: we format these to %.6f before comparing, since that's how
+     * we serialize them and it doesn't make sense to check precision
+     * beyond that.
+     */
+    {
+        .description = "number_sanity1",
+        .type = PTYPE_NUMBER,
+        .value.number = -1,
+    },
+    {
+        .description = "number_sanity2",
+        .type = PTYPE_NUMBER,
+        .value.number = 3.14159265,
+    },
+    {
+        .description = "number_min",
+        .type = PTYPE_NUMBER,
+        .value.number = DBL_MIN,
+    },
+    {
+        .description = "number_max",
+        .type = PTYPE_NUMBER,
+        .value.number = DBL_MAX,
+    },
+    /* integer tests (int64) */
+    {
+        .description = "integer_sanity1",
+        .type = PTYPE_INTEGER,
+        .value.integer = -1,
+    },
+    {
+        .description = "integer_sanity2",
+        .type = PTYPE_INTEGER,
+        .value.integer = INT64_MAX / 2 + 1,
+    },
+    {
+        .description = "integer_min",
+        .type = PTYPE_INTEGER,
+        .value.integer = INT64_MIN,
+    },
+    {
+        .description = "integer_max",
+        .type = PTYPE_INTEGER,
+        .value.integer = INT64_MAX,
+    },
+    /* uint8 tests */
+    {
+        .description = "uint8_sanity1",
+        .type = PTYPE_U8,
+        .value.u8 = 1,
+    },
+    {
+        .description = "uint8_sanity2",
+        .type = PTYPE_U8,
+        .value.u8 = UINT8_MAX / 2 + 1,
+    },
+    {
+        .description = "uint8_min",
+        .type = PTYPE_U8,
+        .value.u8 = 0,
+    },
+    {
+        .description = "uint8_max",
+        .type = PTYPE_U8,
+        .value.u8 = UINT8_MAX,
+    },
+    /* uint16 tests */
+    {
+        .description = "uint16_sanity1",
+        .type = PTYPE_U16,
+        .value.u16 = 1,
+    },
+    {
+        .description = "uint16_sanity2",
+        .type = PTYPE_U16,
+        .value.u16 = UINT16_MAX / 2 + 1,
+    },
+    {
+        .description = "uint16_min",
+        .type = PTYPE_U16,
+        .value.u16 = 0,
+    },
+    {
+        .description = "uint16_max",
+        .type = PTYPE_U16,
+        .value.u16 = UINT16_MAX,
+    },
+    /* uint32 tests */
+    {
+        .description = "uint32_sanity1",
+        .type = PTYPE_U32,
+        .value.u32 = 1,
+    },
+    {
+        .description = "uint32_sanity2",
+        .type = PTYPE_U32,
+        .value.u32 = UINT32_MAX / 2 + 1,
+    },
+    {
+        .description = "uint32_min",
+        .type = PTYPE_U32,
+        .value.u32 = 0,
+    },
+    {
+        .description = "uint32_max",
+        .type = PTYPE_U32,
+        .value.u32 = UINT32_MAX,
+    },
+    /* uint64 tests */
+    {
+        .description = "uint64_sanity1",
+        .type = PTYPE_U64,
+        .value.u64 = 1,
+    },
+    {
+        .description = "uint64_sanity2",
+        .type = PTYPE_U64,
+        .value.u64 = UINT64_MAX / 2 + 1,
+    },
+    {
+        .description = "uint64_min",
+        .type = PTYPE_U64,
+        .value.u64 = 0,
+    },
+    {
+        .description = "uint64_max",
+        .type = PTYPE_U64,
+        .value.u64 = UINT64_MAX,
+    },
+    /* int8 tests */
+    {
+        .description = "int8_sanity1",
+        .type = PTYPE_S8,
+        .value.s8 = -1,
+    },
+    {
+        .description = "int8_sanity2",
+        .type = PTYPE_S8,
+        .value.s8 = INT8_MAX / 2 + 1,
+    },
+    {
+        .description = "int8_min",
+        .type = PTYPE_S8,
+        .value.s8 = INT8_MIN,
+    },
+    {
+        .description = "int8_max",
+        .type = PTYPE_S8,
+        .value.s8 = INT8_MAX,
+    },
+    /* int16 tests */
+    {
+        .description = "int16_sanity1",
+        .type = PTYPE_S16,
+        .value.s16 = -1,
+    },
+    {
+        .description = "int16_sanity2",
+        .type = PTYPE_S16,
+        .value.s16 = INT16_MAX / 2 + 1,
+    },
+    {
+        .description = "int16_min",
+        .type = PTYPE_S16,
+        .value.s16 = INT16_MIN,
+    },
+    {
+        .description = "int16_max",
+        .type = PTYPE_S16,
+        .value.s16 = INT16_MAX,
+    },
+    /* int32 tests */
+    {
+        .description = "int32_sanity1",
+        .type = PTYPE_S32,
+        .value.s32 = -1,
+    },
+    {
+        .description = "int32_sanity2",
+        .type = PTYPE_S32,
+        .value.s32 = INT32_MAX / 2 + 1,
+    },
+    {
+        .description = "int32_min",
+        .type = PTYPE_S32,
+        .value.s32 = INT32_MIN,
+    },
+    {
+        .description = "int32_max",
+        .type = PTYPE_S32,
+        .value.s32 = INT32_MAX,
+    },
+    /* int64 tests */
+    {
+        .description = "int64_sanity1",
+        .type = PTYPE_S64,
+        .value.s64 = -1,
+    },
+    {
+        .description = "int64_sanity2",
+        .type = PTYPE_S64,
+        .value.s64 = INT64_MAX / 2 + 1,
+    },
+    {
+        .description = "int64_min",
+        .type = PTYPE_S64,
+        .value.s64 = INT64_MIN,
+    },
+    {
+        .description = "int64_max",
+        .type = PTYPE_S64,
+        .value.s64 = INT64_MAX,
+    },
+    { .type = PTYPE_EOL }
+};
+
+/* visitor-specific op implementations */
+
+typedef struct QmpSerializeData {
+    QmpOutputVisitor *qov;
+    QmpInputVisitor *qiv;
+} QmpSerializeData;
+
+static void qmp_serialize(void *native_in, void **datap,
+                          VisitorFunc visit, Error **errp)
+{
+    QmpSerializeData *d = g_malloc0(sizeof(*d));
+
+    d->qov = qmp_output_visitor_new();
+    visit(qmp_output_get_visitor(d->qov), &native_in, errp);
+    *datap = d;
+}
+
+static void qmp_deserialize(void **native_out, void *datap,
+                            VisitorFunc visit, Error **errp)
+{
+    QmpSerializeData *d = datap;
+    QString *output_json = qobject_to_json(qmp_output_get_qobject(d->qov));
+    QObject *obj = qobject_from_json(qstring_get_str(output_json));
+
+    QDECREF(output_json);
+    d->qiv = qmp_input_visitor_new(obj);
+    visit(qmp_input_get_visitor(d->qiv), native_out, errp);
+}
+
+static void qmp_cleanup(void *datap)
+{
+    QmpSerializeData *d = datap;
+    qmp_output_visitor_cleanup(d->qov);
+    qmp_input_visitor_cleanup(d->qiv);
+}
+
+typedef struct StringSerializeData {
+    StringOutputVisitor *sov;
+    StringInputVisitor *siv;
+} StringSerializeData;
+
+static void string_serialize(void *native_in, void **datap,
+                             VisitorFunc visit, Error **errp)
+{
+    StringSerializeData *d = g_malloc0(sizeof(*d));
+
+    d->sov = string_output_visitor_new();
+    visit(string_output_get_visitor(d->sov), &native_in, errp);
+    *datap = d;
+}
+
+static void string_deserialize(void **native_out, void *datap,
+                               VisitorFunc visit, Error **errp)
+{
+    StringSerializeData *d = datap;
+
+    d->siv = string_input_visitor_new(string_output_get_string(d->sov));
+    visit(string_input_get_visitor(d->siv), native_out, errp);
+}
+
+static void string_cleanup(void *datap)
+{
+    StringSerializeData *d = datap;
+    string_output_visitor_cleanup(d->sov);
+    string_input_visitor_cleanup(d->siv);
+}
+
+/* visitor registration, test harness */
+
+/* note: to function interchangeably as a serialization mechanism your
+ * visitor test implementation should pass the test cases for all visitor
+ * capabilities: primitives, structures, and lists
+ */
+static const SerializeOps visitors[] = {
+    {
+        .type = "QMP",
+        .serialize = qmp_serialize,
+        .deserialize = qmp_deserialize,
+        .cleanup = qmp_cleanup,
+        .caps = VCAP_PRIMITIVES | VCAP_STRUCTURES | VCAP_LISTS
+    },
+    {
+        .type = "String",
+        .serialize = string_serialize,
+        .deserialize = string_deserialize,
+        .cleanup = string_cleanup,
+        .caps = VCAP_PRIMITIVES
+    },
+    { NULL }
+};
+
+static void add_visitor_type(const SerializeOps *ops)
+{
+    char testname_prefix[128];
+    char testname[128];
+    TestArgs *args;
+    int i = 0;
+
+    sprintf(testname_prefix, "/visitor/serialization/%s", ops->type);
+
+    if (ops->caps & VCAP_PRIMITIVES) {
+        while (pt_values[i].type != PTYPE_EOL) {
+            sprintf(testname, "%s/primitives/%s", testname_prefix,
+                    pt_values[i].description);
+            args = g_malloc0(sizeof(*args));
+            args->ops = ops;
+            args->test_data = &pt_values[i];
+            g_test_add_data_func(testname, args, test_primitives);
+            i++;
+        }
+    }
+
+    if (ops->caps & VCAP_STRUCTURES) {
+        sprintf(testname, "%s/struct", testname_prefix);
+        args = g_malloc0(sizeof(*args));
+        args->ops = ops;
+        args->test_data = NULL;
+        g_test_add_data_func(testname, args, test_struct);
+
+        sprintf(testname, "%s/nested_struct", testname_prefix);
+        args = g_malloc0(sizeof(*args));
+        args->ops = ops;
+        args->test_data = NULL;
+        g_test_add_data_func(testname, args, test_nested_struct);
+    }
+
+    if (ops->caps & VCAP_LISTS) {
+        sprintf(testname, "%s/nested_struct_list", testname_prefix);
+        args = g_malloc0(sizeof(*args));
+        args->ops = ops;
+        args->test_data = NULL;
+        g_test_add_data_func(testname, args, test_nested_struct_list);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    int i = 0;
+
+    g_test_init(&argc, &argv, NULL);
+
+    while (visitors[i].type != NULL) {
+        add_visitor_type(&visitors[i]);
+        i++;
+    }
+
+    g_test_run();
+
+    return 0;
+}