summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VERSION2
-rw-r--r--aio-posix.c2
-rw-r--r--aio-win32.c4
-rw-r--r--async.c2
-rw-r--r--backends/rng-random.c6
-rw-r--r--block-migration.c10
-rw-r--r--block.c106
-rw-r--r--block/accounting.c6
-rw-r--r--block/blkdebug.c99
-rw-r--r--block/block-backend.c38
-rw-r--r--block/linux-aio.c99
-rw-r--r--block/nfs.c15
-rw-r--r--block/qapi.c32
-rw-r--r--block/qcow2-cluster.c2
-rw-r--r--block/qcow2.c33
-rw-r--r--block/raw-aio.h2
-rw-r--r--block/raw-posix.c11
-rw-r--r--block/raw-win32.c2
-rw-r--r--block/raw_bsd.c66
-rw-r--r--block/rbd.c8
-rw-r--r--block/vdi.c5
-rw-r--r--block/vhdx.c18
-rw-r--r--block/vhdx.h3
-rw-r--r--block/vmdk.c39
-rw-r--r--block/vpc.c5
-rw-r--r--block/vvfat.c6
-rw-r--r--blockdev-nbd.c15
-rw-r--r--blockdev.c149
-rwxr-xr-xconfigure2
-rw-r--r--gdbstub.c15
-rw-r--r--hmp.c221
-rw-r--r--hw/arm/boot.c4
-rw-r--r--hw/arm/pxa2xx.c6
-rw-r--r--hw/arm/realview.c3
-rw-r--r--hw/block/dataplane/virtio-blk.c6
-rw-r--r--hw/block/nvme.c1
-rw-r--r--hw/block/nvme.h2
-rw-r--r--hw/block/pflash_cfi02.c1
-rw-r--r--hw/core/qdev.c16
-rw-r--r--hw/display/cirrus_vga.c65
-rw-r--r--hw/i386/acpi-build.c22
-rw-r--r--hw/i386/pc.c22
-rw-r--r--hw/i386/pc_piix.c7
-rw-r--r--hw/i386/pc_q35.c7
-rw-r--r--hw/ide/ahci.c24
-rw-r--r--hw/ide/ahci.h5
-rw-r--r--hw/ide/qdev.c5
-rw-r--r--hw/intc/arm_gic_kvm.c20
-rw-r--r--hw/isa/vt82c686.c41
-rw-r--r--hw/net/virtio-net.c5
-rw-r--r--hw/nvram/fw_cfg.c8
-rw-r--r--hw/scsi/vhost-scsi.c1
-rw-r--r--hw/timer/hpet.c2
-rw-r--r--hw/tpm/tpm_passthrough.c4
-rw-r--r--hw/usb/host-libusb.c2
-rw-r--r--hw/virtio/vhost.c2
-rw-r--r--hw/virtio/virtio-bus.c2
-rw-r--r--hw/virtio/virtio-rng.c15
-rw-r--r--include/block/block.h5
-rw-r--r--include/block/block_int.h13
-rw-r--r--include/block/nbd.h7
-rw-r--r--include/exec/gdbstub.h6
-rw-r--r--include/hw/i386/pc.h2
-rw-r--r--include/hw/qdev-core.h2
-rw-r--r--include/hw/virtio/virtio.h3
-rw-r--r--include/qemu/option.h2
-rw-r--r--include/qemu/queue.h11
-rw-r--r--include/qemu/typedefs.h105
-rw-r--r--include/sysemu/block-backend.h12
-rw-r--r--linux-user/aarch64/target_cpu.h2
-rw-r--r--linux-user/arm/target_cpu.h2
-rw-r--r--linux-user/main.c2
-rw-r--r--monitor.c19
-rw-r--r--nbd.c63
-rw-r--r--qapi-schema.json2
-rw-r--r--qapi/block-core.json36
-rw-r--r--qapi/common.json15
-rw-r--r--qemu-char.c4
-rw-r--r--qemu-doc.texi6
-rw-r--r--qemu-img.c21
-rw-r--r--qemu-io-cmds.c46
-rw-r--r--qemu-io.c28
-rw-r--r--qemu-nbd.c12
-rw-r--r--qemu-options.hx28
-rw-r--r--qemu-timer.c9
-rw-r--r--qmp-commands.hx6
-rw-r--r--qobject/qjson.c10
-rwxr-xr-xscripts/get_maintainer.pl45
-rw-r--r--target-arm/arm-semi.c11
-rw-r--r--target-arm/cpu.c10
-rw-r--r--target-arm/cpu.h364
-rw-r--r--target-arm/helper.c677
-rw-r--r--target-arm/internals.h6
-rw-r--r--target-arm/kvm.c107
-rw-r--r--target-arm/kvm32.c100
-rw-r--r--target-arm/kvm64.c24
-rw-r--r--target-arm/kvm_arm.h22
-rw-r--r--target-arm/machine.c22
-rw-r--r--target-arm/op_helper.c4
-rw-r--r--target-arm/translate.c15
-rw-r--r--target-arm/translate.h1
-rw-r--r--target-i386/fpu_helper.c22
-rw-r--r--target-i386/translate.c16
-rw-r--r--target-s390x/helper.c6
-rw-r--r--target-s390x/kvm.c4
-rw-r--r--target-tricore/cpu.c9
-rw-r--r--target-tricore/csfr.def124
-rw-r--r--target-tricore/helper.h17
-rw-r--r--target-tricore/op_helper.c278
-rw-r--r--target-tricore/translate.c1638
-rw-r--r--target-tricore/tricore-opcodes.h17
-rw-r--r--tests/ahci-test.c3
-rw-r--r--tests/bios-tables-test.c2
-rw-r--r--tests/drive_del-test.c2
-rw-r--r--tests/fdc-test.c2
-rw-r--r--tests/hd-geo-test.c2
-rw-r--r--tests/i440fx-test.c5
-rw-r--r--tests/ide-test.c9
-rw-r--r--tests/nvme-test.c2
-rw-r--r--tests/qemu-iotests/001.out2
-rw-r--r--tests/qemu-iotests/002.out2
-rw-r--r--tests/qemu-iotests/003.out2
-rw-r--r--tests/qemu-iotests/004.out2
-rw-r--r--tests/qemu-iotests/005.out2
-rw-r--r--tests/qemu-iotests/006.out2
-rw-r--r--tests/qemu-iotests/007.out2
-rw-r--r--tests/qemu-iotests/008.out2
-rw-r--r--tests/qemu-iotests/009.out2
-rw-r--r--tests/qemu-iotests/010.out2
-rw-r--r--tests/qemu-iotests/011.out2
-rw-r--r--tests/qemu-iotests/012.out2
-rw-r--r--tests/qemu-iotests/013.out2
-rw-r--r--tests/qemu-iotests/014.out2
-rw-r--r--tests/qemu-iotests/015.out2
-rwxr-xr-xtests/qemu-iotests/01611
-rw-r--r--tests/qemu-iotests/016.out2
-rw-r--r--tests/qemu-iotests/017.out2
-rw-r--r--tests/qemu-iotests/018.out2
-rw-r--r--tests/qemu-iotests/019.out4
-rw-r--r--tests/qemu-iotests/020.out4
-rw-r--r--tests/qemu-iotests/021.out2
-rw-r--r--tests/qemu-iotests/022.out2
-rw-r--r--tests/qemu-iotests/023.out16
-rw-r--r--tests/qemu-iotests/024.out6
-rw-r--r--tests/qemu-iotests/025.out2
-rw-r--r--tests/qemu-iotests/026.out420
-rw-r--r--tests/qemu-iotests/027.out2
-rw-r--r--tests/qemu-iotests/028.out6
-rw-r--r--tests/qemu-iotests/029.out8
-rwxr-xr-xtests/qemu-iotests/03022
-rw-r--r--tests/qemu-iotests/031.out4
-rw-r--r--tests/qemu-iotests/032.out2
-rw-r--r--tests/qemu-iotests/033.out2
-rw-r--r--tests/qemu-iotests/034.out4
-rw-r--r--tests/qemu-iotests/035.out2
-rw-r--r--tests/qemu-iotests/036.out6
-rw-r--r--tests/qemu-iotests/037.out4
-rw-r--r--tests/qemu-iotests/038.out4
-rwxr-xr-xtests/qemu-iotests/03918
-rw-r--r--tests/qemu-iotests/039.out18
-rwxr-xr-xtests/qemu-iotests/04032
-rw-r--r--tests/qemu-iotests/042.out2
-rw-r--r--tests/qemu-iotests/043.out52
-rw-r--r--tests/qemu-iotests/046.out4
-rw-r--r--tests/qemu-iotests/047.out2
-rwxr-xr-xtests/qemu-iotests/0482
-rw-r--r--tests/qemu-iotests/048.out4
-rw-r--r--tests/qemu-iotests/049.out112
-rw-r--r--tests/qemu-iotests/050.out6
-rw-r--r--tests/qemu-iotests/051.out7
-rw-r--r--tests/qemu-iotests/052.out2
-rw-r--r--tests/qemu-iotests/053.out2
-rw-r--r--tests/qemu-iotests/054.out4
-rwxr-xr-xtests/qemu-iotests/05518
-rwxr-xr-xtests/qemu-iotests/05811
-rwxr-xr-xtests/qemu-iotests/05910
-rw-r--r--tests/qemu-iotests/059.out4
-rwxr-xr-xtests/qemu-iotests/0602
-rw-r--r--tests/qemu-iotests/060.out27
-rw-r--r--tests/qemu-iotests/061.out44
-rw-r--r--tests/qemu-iotests/062.out2
-rw-r--r--tests/qemu-iotests/066.out2
-rwxr-xr-xtests/qemu-iotests/0672
-rw-r--r--tests/qemu-iotests/067.out806
-rw-r--r--tests/qemu-iotests/068.out2
-rw-r--r--tests/qemu-iotests/069.out4
-rwxr-xr-xtests/qemu-iotests/07110
-rw-r--r--tests/qemu-iotests/071.out22
-rw-r--r--tests/qemu-iotests/072.out2
-rw-r--r--tests/qemu-iotests/073.out4
-rwxr-xr-xtests/qemu-iotests/0772
-rw-r--r--tests/qemu-iotests/077.out2
-rwxr-xr-xtests/qemu-iotests/0802
-rw-r--r--tests/qemu-iotests/080.out26
-rwxr-xr-xtests/qemu-iotests/0818
-rw-r--r--tests/qemu-iotests/081.out8
-rwxr-xr-xtests/qemu-iotests/08214
-rw-r--r--tests/qemu-iotests/082.out63
-rw-r--r--tests/qemu-iotests/084.out4
-rw-r--r--tests/qemu-iotests/086.out2
-rw-r--r--tests/qemu-iotests/087.out6
-rw-r--r--tests/qemu-iotests/088.out2
-rwxr-xr-xtests/qemu-iotests/0896
-rw-r--r--tests/qemu-iotests/089.out6
-rw-r--r--tests/qemu-iotests/090.out2
-rw-r--r--tests/qemu-iotests/091.out2
-rw-r--r--tests/qemu-iotests/092.out8
-rw-r--r--tests/qemu-iotests/095.out6
-rw-r--r--tests/qemu-iotests/097.out24
-rw-r--r--tests/qemu-iotests/098.out16
-rwxr-xr-xtests/qemu-iotests/09918
-rw-r--r--tests/qemu-iotests/099.out16
-rw-r--r--tests/qemu-iotests/100.out14
-rw-r--r--tests/qemu-iotests/103.out2
-rw-r--r--tests/qemu-iotests/104.out4
-rw-r--r--tests/qemu-iotests/107.out2
-rw-r--r--tests/qemu-iotests/108.out12
-rwxr-xr-xtests/qemu-iotests/109132
-rw-r--r--tests/qemu-iotests/109.out231
-rwxr-xr-xtests/qemu-iotests/11376
-rw-r--r--tests/qemu-iotests/113.out15
-rwxr-xr-xtests/qemu-iotests/11461
-rw-r--r--tests/qemu-iotests/114.out13
-rw-r--r--tests/qemu-iotests/common10
-rw-r--r--tests/qemu-iotests/common.config2
-rw-r--r--tests/qemu-iotests/common.filter6
-rw-r--r--tests/qemu-iotests/common.qemu3
-rw-r--r--tests/qemu-iotests/common.rc15
-rw-r--r--tests/qemu-iotests/group3
-rwxr-xr-xtests/qemu-iotests/qcow2.py4
-rw-r--r--tests/qemu-iotests/sample_images/grub_mbr.raw.bz2bin0 -> 552 bytes
-rw-r--r--tests/usb-hcd-uhci-test.c2
-rw-r--r--tests/usb-hcd-xhci-test.c2
-rw-r--r--tests/virtio-blk-test.c4
-rw-r--r--tests/virtio-scsi-test.c4
-rw-r--r--ui/keymaps.c196
-rw-r--r--ui/vnc-enc-tight.c2
-rw-r--r--util/hbitmap.c4
-rw-r--r--util/iov.c4
-rw-r--r--util/qemu-option.c10
-rw-r--r--util/uri.c94
-rw-r--r--vl.c65
242 files changed, 6614 insertions, 1795 deletions
diff --git a/VERSION b/VERSION
index 9be10bc08f..99572f605e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.1.93
+2.2.50
diff --git a/aio-posix.c b/aio-posix.c
index d3ac06e238..cbd4c3438c 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -73,7 +73,7 @@ void aio_set_fd_handler(AioContext *ctx,
} else {
if (node == NULL) {
/* Alloc and insert if it's not already there */
- node = g_malloc0(sizeof(AioHandler));
+ node = g_new0(AioHandler, 1);
node->pfd.fd = fd;
QLIST_INSERT_HEAD(&ctx->aio_handlers, node, node);
diff --git a/aio-win32.c b/aio-win32.c
index d81313b00b..e6f4cedf48 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -67,7 +67,7 @@ void aio_set_fd_handler(AioContext *ctx,
if (node == NULL) {
/* Alloc and insert if it's not already there */
- node = g_malloc0(sizeof(AioHandler));
+ node = g_new0(AioHandler, 1);
node->pfd.fd = fd;
QLIST_INSERT_HEAD(&ctx->aio_handlers, node, node);
}
@@ -129,7 +129,7 @@ void aio_set_event_notifier(AioContext *ctx,
} else {
if (node == NULL) {
/* Alloc and insert if it's not already there */
- node = g_malloc0(sizeof(AioHandler));
+ node = g_new0(AioHandler, 1);
node->e = e;
node->pfd.fd = (uintptr_t)event_notifier_get_handle(e);
node->pfd.events = G_IO_IN;
diff --git a/async.c b/async.c
index 6e1b282aa7..3939b795e5 100644
--- a/async.c
+++ b/async.c
@@ -44,7 +44,7 @@ struct QEMUBH {
QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
{
QEMUBH *bh;
- bh = g_malloc0(sizeof(QEMUBH));
+ bh = g_new0(QEMUBH, 1);
bh->ctx = ctx;
bh->cb = cb;
bh->opaque = opaque;
diff --git a/backends/rng-random.c b/backends/rng-random.c
index 601d9dc0c2..4f85a8ea49 100644
--- a/backends/rng-random.c
+++ b/backends/rng-random.c
@@ -88,11 +88,7 @@ static char *rng_random_get_filename(Object *obj, Error **errp)
{
RndRandom *s = RNG_RANDOM(obj);
- if (s->filename) {
- return g_strdup(s->filename);
- }
-
- return NULL;
+ return g_strdup(s->filename);
}
static void rng_random_set_filename(Object *obj, const char *filename,
diff --git a/block-migration.c b/block-migration.c
index 08db01a364..74d9eb125c 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -653,6 +653,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
{
int ret;
int64_t last_ftell = qemu_ftell(f);
+ int64_t delta_ftell;
DPRINTF("Enter save live iterate submitted %d transferred %d\n",
block_mig_state.submitted, block_mig_state.transferred);
@@ -702,7 +703,14 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
}
qemu_put_be64(f, BLK_MIG_FLAG_EOS);
- return qemu_ftell(f) - last_ftell;
+ delta_ftell = qemu_ftell(f) - last_ftell;
+ if (delta_ftell > 0) {
+ return 1;
+ } else if (delta_ftell < 0) {
+ return -1;
+ } else {
+ return 0;
+ }
}
/* Called with iothread lock taken. */
diff --git a/block.c b/block.c
index a612594db5..4165d4265c 100644
--- a/block.c
+++ b/block.c
@@ -229,7 +229,7 @@ size_t bdrv_opt_mem_align(BlockDriverState *bs)
}
/* check if the path starts with "<protocol>:" */
-static int path_has_protocol(const char *path)
+int path_has_protocol(const char *path)
{
const char *p;
@@ -629,7 +629,7 @@ BlockDriver *bdrv_find_protocol(const char *filename,
}
if (!path_has_protocol(filename) || !allow_protocol_prefix) {
- return bdrv_find_format("file");
+ return &bdrv_file;
}
p = strchr(filename, ':');
@@ -648,22 +648,49 @@ BlockDriver *bdrv_find_protocol(const char *filename,
return NULL;
}
+/*
+ * Guess image format by probing its contents.
+ * This is not a good idea when your image is raw (CVE-2008-2004), but
+ * we do it anyway for backward compatibility.
+ *
+ * @buf contains the image's first @buf_size bytes.
+ * @buf_size is the buffer size in bytes (generally BLOCK_PROBE_BUF_SIZE,
+ * but can be smaller if the image file is smaller)
+ * @filename is its filename.
+ *
+ * For all block drivers, call the bdrv_probe() method to get its
+ * probing score.
+ * Return the first block driver with the highest probing score.
+ */
+BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
+ const char *filename)
+{
+ int score_max = 0, score;
+ BlockDriver *drv = NULL, *d;
+
+ QLIST_FOREACH(d, &bdrv_drivers, list) {
+ if (d->bdrv_probe) {
+ score = d->bdrv_probe(buf, buf_size, filename);
+ if (score > score_max) {
+ score_max = score;
+ drv = d;
+ }
+ }
+ }
+
+ return drv;
+}
+
static int find_image_format(BlockDriverState *bs, const char *filename,
BlockDriver **pdrv, Error **errp)
{
- int score, score_max;
- BlockDriver *drv1, *drv;
- uint8_t buf[2048];
+ BlockDriver *drv;
+ uint8_t buf[BLOCK_PROBE_BUF_SIZE];
int ret = 0;
/* Return the raw BlockDriver * to scsi-generic devices or empty drives */
if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) {
- drv = bdrv_find_format("raw");
- if (!drv) {
- error_setg(errp, "Could not find raw image format");
- ret = -ENOENT;
- }
- *pdrv = drv;
+ *pdrv = &bdrv_raw;
return ret;
}
@@ -675,17 +702,7 @@ static int find_image_format(BlockDriverState *bs, const char *filename,
return ret;
}
- score_max = 0;
- drv = NULL;
- QLIST_FOREACH(drv1, &bdrv_drivers, list) {
- if (drv1->bdrv_probe) {
- score = drv1->bdrv_probe(buf, ret, filename);
- if (score > score_max) {
- score_max = score;
- drv = drv1;
- }
- }
- }
+ drv = bdrv_probe_all(buf, ret, filename);
if (!drv) {
error_setg(errp, "Could not determine image format: No compatible "
"driver found");
@@ -1180,7 +1197,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
{
char *backing_filename = g_malloc0(PATH_MAX);
int ret = 0;
- BlockDriver *back_drv = NULL;
BlockDriverState *backing_hd;
Error *local_err = NULL;
@@ -1213,14 +1229,14 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
backing_hd = bdrv_new();
- if (bs->backing_format[0] != '\0') {
- back_drv = bdrv_find_format(bs->backing_format);
+ if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
+ qdict_put(options, "driver", qstring_from_str(bs->backing_format));
}
assert(bs->backing_hd == NULL);
ret = bdrv_open(&backing_hd,
*backing_filename ? backing_filename : NULL, NULL, options,
- bdrv_backing_flags(bs->open_flags), back_drv, &local_err);
+ bdrv_backing_flags(bs->open_flags), NULL, &local_err);
if (ret < 0) {
bdrv_unref(backing_hd);
backing_hd = NULL;
@@ -1294,7 +1310,6 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
char *tmp_filename = g_malloc0(PATH_MAX + 1);
int64_t total_size;
- BlockDriver *bdrv_qcow2;
QemuOpts *opts = NULL;
QDict *snapshot_options;
BlockDriverState *bs_snapshot;
@@ -1319,11 +1334,10 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
goto out;
}
- bdrv_qcow2 = bdrv_find_format("qcow2");
- opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
+ opts = qemu_opts_create(bdrv_qcow2.create_opts, NULL, 0,
&error_abort);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
- ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err);
+ ret = bdrv_create(&bdrv_qcow2, tmp_filename, opts, &local_err);
qemu_opts_del(opts);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not create temporary overlay "
@@ -1343,7 +1357,7 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
bs_snapshot = bdrv_new();
ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
- flags, bdrv_qcow2, &local_err);
+ flags, &bdrv_qcow2, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
goto out;
@@ -1467,6 +1481,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
}
/* Image format probing */
+ bs->probed = !drv;
if (!drv && file) {
ret = find_image_format(file, filename, &drv, &local_err);
if (ret < 0) {
@@ -3801,6 +3816,14 @@ bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base)
return top != NULL;
}
+BlockDriverState *bdrv_next_node(BlockDriverState *bs)
+{
+ if (!bs) {
+ return QTAILQ_FIRST(&graph_bdrv_states);
+ }
+ return QTAILQ_NEXT(bs, node_list);
+}
+
BlockDriverState *bdrv_next(BlockDriverState *bs)
{
if (!bs) {
@@ -3809,6 +3832,11 @@ BlockDriverState *bdrv_next(BlockDriverState *bs)
return QTAILQ_NEXT(bs, device_list);
}
+const char *bdrv_get_node_name(const BlockDriverState *bs)
+{
+ return bs->node_name;
+}
+
/* TODO check what callers really want: bs->node_name or blk_name() */
const char *bdrv_get_device_name(const BlockDriverState *bs)
{
@@ -5541,6 +5569,18 @@ void bdrv_img_create(const char *filename, const char *fmt,
return;
}
+ if (!drv->create_opts) {
+ error_setg(errp, "Format driver '%s' does not support image creation",
+ drv->format_name);
+ return;
+ }
+
+ if (!proto_drv->create_opts) {
+ error_setg(errp, "Protocol driver '%s' does not support image creation",
+ proto_drv->format_name);
+ return;
+ }
+
create_opts = qemu_opts_append(create_opts, drv->create_opts);
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
@@ -5628,8 +5668,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
}
if (!quiet) {
- printf("Formatting '%s', fmt=%s ", filename, fmt);
- qemu_opts_print(opts);
+ printf("Formatting '%s', fmt=%s", filename, fmt);
+ qemu_opts_print(opts, " ");
puts("");
}
diff --git a/block/accounting.c b/block/accounting.c
index edbb1cc89f..18102f015d 100644
--- a/block/accounting.c
+++ b/block/accounting.c
@@ -24,6 +24,7 @@
#include "block/accounting.h"
#include "block/block_int.h"
+#include "qemu/timer.h"
void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
int64_t bytes, enum BlockAcctType type)
@@ -31,7 +32,7 @@ void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
assert(type < BLOCK_MAX_IOTYPE);
cookie->bytes = bytes;
- cookie->start_time_ns = get_clock();
+ cookie->start_time_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
cookie->type = type;
}
@@ -41,7 +42,8 @@ void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie)
stats->nr_bytes[cookie->type] += cookie->bytes;
stats->nr_ops[cookie->type]++;
- stats->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
+ stats->total_time_ns[cookie->type] +=
+ qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - cookie->start_time_ns;
}
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 862d93b59b..9ce35cd035 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -721,93 +721,50 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
static void blkdebug_refresh_filename(BlockDriverState *bs)
{
- BDRVBlkdebugState *s = bs->opaque;
- struct BlkdebugRule *rule;
QDict *opts;
- QList *inject_error_list = NULL, *set_state_list = NULL;
- QList *suspend_list = NULL;
- int event;
+ const QDictEntry *e;
+ bool force_json = false;
+
+ for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) {
+ if (strcmp(qdict_entry_key(e), "config") &&
+ strcmp(qdict_entry_key(e), "x-image") &&
+ strcmp(qdict_entry_key(e), "image") &&
+ strncmp(qdict_entry_key(e), "image.", strlen("image.")))
+ {
+ force_json = true;
+ break;
+ }
+ }
- if (!bs->file->full_open_options) {
+ if (force_json && !bs->file->full_open_options) {
/* The config file cannot be recreated, so creating a plain filename
* is impossible */
return;
}
+ if (!force_json && bs->file->exact_filename[0]) {
+ snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+ "blkdebug:%s:%s",
+ qdict_get_try_str(bs->options, "config") ?: "",
+ bs->file->exact_filename);
+ }
+
opts = qdict_new();
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkdebug")));
QINCREF(bs->file->full_open_options);
qdict_put_obj(opts, "image", QOBJECT(bs->file->full_open_options));
- for (event = 0; event < BLKDBG_EVENT_MAX; event++) {
- QLIST_FOREACH(rule, &s->rules[event], next) {
- if (rule->action == ACTION_INJECT_ERROR) {
- QDict *inject_error = qdict_new();
-
- qdict_put_obj(inject_error, "event", QOBJECT(qstring_from_str(
- BlkdebugEvent_lookup[rule->event])));
- qdict_put_obj(inject_error, "state",
- QOBJECT(qint_from_int(rule->state)));
- qdict_put_obj(inject_error, "errno", QOBJECT(qint_from_int(
- rule->options.inject.error)));
- qdict_put_obj(inject_error, "sector", QOBJECT(qint_from_int(
- rule->options.inject.sector)));
- qdict_put_obj(inject_error, "once", QOBJECT(qbool_from_int(
- rule->options.inject.once)));
- qdict_put_obj(inject_error, "immediately",
- QOBJECT(qbool_from_int(
- rule->options.inject.immediately)));
-
- if (!inject_error_list) {
- inject_error_list = qlist_new();
- }
-
- qlist_append_obj(inject_error_list, QOBJECT(inject_error));
- } else if (rule->action == ACTION_SET_STATE) {
- QDict *set_state = qdict_new();
-
- qdict_put_obj(set_state, "event", QOBJECT(qstring_from_str(
- BlkdebugEvent_lookup[rule->event])));
- qdict_put_obj(set_state, "state",
- QOBJECT(qint_from_int(rule->state)));
- qdict_put_obj(set_state, "new_state", QOBJECT(qint_from_int(
- rule->options.set_state.new_state)));
-
- if (!set_state_list) {
- set_state_list = qlist_new();
- }
-
- qlist_append_obj(set_state_list, QOBJECT(set_state));
- } else if (rule->action == ACTION_SUSPEND) {
- QDict *suspend = qdict_new();
-
- qdict_put_obj(suspend, "event", QOBJECT(qstring_from_str(
- BlkdebugEvent_lookup[rule->event])));
- qdict_put_obj(suspend, "state",
- QOBJECT(qint_from_int(rule->state)));
- qdict_put_obj(suspend, "tag", QOBJECT(qstring_from_str(
- rule->options.suspend.tag)));
-
- if (!suspend_list) {
- suspend_list = qlist_new();
- }
-
- qlist_append_obj(suspend_list, QOBJECT(suspend));
- }
+ for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) {
+ if (strcmp(qdict_entry_key(e), "x-image") &&
+ strcmp(qdict_entry_key(e), "image") &&
+ strncmp(qdict_entry_key(e), "image.", strlen("image.")))
+ {
+ qobject_incref(qdict_entry_value(e));
+ qdict_put_obj(opts, qdict_entry_key(e), qdict_entry_value(e));
}
}
- if (inject_error_list) {
- qdict_put_obj(opts, "inject-error", QOBJECT(inject_error_list));
- }
- if (set_state_list) {
- qdict_put_obj(opts, "set-state", QOBJECT(set_state_list));
- }
- if (suspend_list) {
- qdict_put_obj(opts, "suspend", QOBJECT(suspend_list));
- }
-
bs->full_open_options = opts;
}
diff --git a/block/block-backend.c b/block/block-backend.c
index d0692b18e9..ef16d7356a 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -497,6 +497,16 @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
return bdrv_aio_ioctl(blk->bs, req, buf, cb, opaque);
}
+int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
+{
+ return bdrv_co_discard(blk->bs, sector_num, nb_sectors);
+}
+
+int blk_co_flush(BlockBackend *blk)
+{
+ return bdrv_co_flush(blk->bs);
+}
+
int blk_flush(BlockBackend *blk)
{
return bdrv_flush(blk->bs);
@@ -549,6 +559,11 @@ void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
bdrv_set_enable_write_cache(blk->bs, wce);
}
+void blk_invalidate_cache(BlockBackend *blk, Error **errp)
+{
+ bdrv_invalidate_cache(blk->bs, errp);
+}
+
int blk_is_inserted(BlockBackend *blk)
{
return bdrv_is_inserted(blk->bs);
@@ -609,6 +624,29 @@ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
bdrv_set_aio_context(blk->bs, new_context);
}
+void blk_add_aio_context_notifier(BlockBackend *blk,
+ void (*attached_aio_context)(AioContext *new_context, void *opaque),
+ void (*detach_aio_context)(void *opaque), void *opaque)
+{
+ bdrv_add_aio_context_notifier(blk->bs, attached_aio_context,
+ detach_aio_context, opaque);
+}
+
+void blk_remove_aio_context_notifier(BlockBackend *blk,
+ void (*attached_aio_context)(AioContext *,
+ void *),
+ void (*detach_aio_context)(void *),
+ void *opaque)
+{
+ bdrv_remove_aio_context_notifier(blk->bs, attached_aio_context,
+ detach_aio_context, opaque);
+}
+
+void blk_add_close_notifier(BlockBackend *blk, Notifier *notify)
+{
+ bdrv_add_close_notifier(blk->bs, notify);
+}
+
void blk_io_plug(BlockBackend *blk)
{
bdrv_io_plug(blk->bs);
diff --git a/block/linux-aio.c b/block/linux-aio.c
index d92513b0f9..c991443c5d 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -35,14 +35,14 @@ struct qemu_laiocb {
size_t nbytes;
QEMUIOVector *qiov;
bool is_read;
- QLIST_ENTRY(qemu_laiocb) node;
+ QSIMPLEQ_ENTRY(qemu_laiocb) next;
};
typedef struct {
- struct iocb *iocbs[MAX_QUEUED_IO];
int plugged;
- unsigned int size;
- unsigned int idx;
+ unsigned int n;
+ bool blocked;
+ QSIMPLEQ_HEAD(, qemu_laiocb) pending;
} LaioQueue;
struct qemu_laio_state {
@@ -59,6 +59,8 @@ struct qemu_laio_state {
int event_max;
};
+static void ioq_submit(struct qemu_laio_state *s);
+
static inline ssize_t io_event_ret(struct io_event *ev)
{
return (ssize_t)(((uint64_t)ev->res2 << 32) | ev->res);
@@ -135,6 +137,10 @@ static void qemu_laio_completion_bh(void *opaque)
qemu_laio_process_completion(s, laiocb);
}
+
+ if (!s->io_q.plugged && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
+ ioq_submit(s);
+ }
}
static void qemu_laio_completion_cb(EventNotifier *e)
@@ -172,50 +178,41 @@ static const AIOCBInfo laio_aiocb_info = {
static void ioq_init(LaioQueue *io_q)
{
- io_q->size = MAX_QUEUED_IO;
- io_q->idx = 0;
+ QSIMPLEQ_INIT(&io_q->pending);
io_q->plugged = 0;
+ io_q->n = 0;
+ io_q->blocked = false;
}
-static int ioq_submit(struct qemu_laio_state *s)
+static void ioq_submit(struct qemu_laio_state *s)
{
- int ret, i = 0;
- int len = s->io_q.idx;
+ int ret, len;
+ struct qemu_laiocb *aiocb;
+ struct iocb *iocbs[MAX_QUEUED_IO];
+ QSIMPLEQ_HEAD(, qemu_laiocb) completed;
do {
- ret = io_submit(s->ctx, len, s->io_q.iocbs);
- } while (i++ < 3 && ret == -EAGAIN);
-
- /* empty io queue */
- s->io_q.idx = 0;
-
- if (ret < 0) {
- i = 0;
- } else {
- i = ret;
- }
-
- for (; i < len; i++) {
- struct qemu_laiocb *laiocb =
- container_of(s->io_q.iocbs[i], struct qemu_laiocb, iocb);
-
- laiocb->ret = (ret < 0) ? ret : -EIO;
- qemu_laio_process_completion(s, laiocb);
- }
- return ret;
-}
-
-static void ioq_enqueue(struct qemu_laio_state *s, struct iocb *iocb)
-{
- unsigned int idx = s->io_q.idx;
+ len = 0;
+ QSIMPLEQ_FOREACH(aiocb, &s->io_q.pending, next) {
+ iocbs[len++] = &aiocb->iocb;
+ if (len == MAX_QUEUED_IO) {
+ break;
+ }
+ }
- s->io_q.iocbs[idx++] = iocb;
- s->io_q.idx = idx;
+ ret = io_submit(s->ctx, len, iocbs);
+ if (ret == -EAGAIN) {
+ break;
+ }
+ if (ret < 0) {
+ abort();
+ }
- /* submit immediately if queue is full */
- if (idx == s->io_q.size) {
- ioq_submit(s);
- }
+ s->io_q.n -= ret;
+ aiocb = container_of(iocbs[ret - 1], struct qemu_laiocb, iocb);
+ QSIMPLEQ_SPLIT_AFTER(&s->io_q.pending, aiocb, next, &completed);
+ } while (ret == len && !QSIMPLEQ_EMPTY(&s->io_q.pending));
+ s->io_q.blocked = (s->io_q.n > 0);
}
void laio_io_plug(BlockDriverState *bs, void *aio_ctx)
@@ -225,22 +222,19 @@ void laio_io_plug(BlockDriverState *bs, void *aio_ctx)
s->io_q.plugged++;
}
-int laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug)
+void laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug)
{
struct qemu_laio_state *s = aio_ctx;
- int ret = 0;
assert(s->io_q.plugged > 0 || !unplug);
if (unplug && --s->io_q.plugged > 0) {
- return 0;
+ return;
}
- if (s->io_q.idx > 0) {
- ret = ioq_submit(s);
+ if (!s->io_q.blocked && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
+ ioq_submit(s);
}
-
- return ret;
}
BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
@@ -276,12 +270,11 @@ BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
}
io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
- if (!s->io_q.plugged) {
- if (io_submit(s->ctx, 1, &iocbs) < 0) {
- goto out_free_aiocb;
- }
- } else {
- ioq_enqueue(s, iocbs);
+ QSIMPLEQ_INSERT_TAIL(&s->io_q.pending, laiocb, next);
+ s->io_q.n++;
+ if (!s->io_q.blocked &&
+ (!s->io_q.plugged || s->io_q.n >= MAX_QUEUED_IO)) {
+ ioq_submit(s);
}
return &laiocb->common;
diff --git a/block/nfs.c b/block/nfs.c
index c76e368b95..ca9e24efe5 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -409,6 +409,19 @@ out:
return ret;
}
+static QemuOptsList nfs_create_opts = {
+ .name = "nfs-create-opts",
+ .head = QTAILQ_HEAD_INITIALIZER(nfs_create_opts.head),
+ .desc = {
+ {
+ .name = BLOCK_OPT_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Virtual disk size"
+ },
+ { /* end of list */ }
+ }
+};
+
static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
{
int ret = 0;
@@ -470,6 +483,8 @@ static BlockDriver bdrv_nfs = {
.instance_size = sizeof(NFSClient),
.bdrv_needs_filename = true,
+ .create_opts = &nfs_create_opts,
+
.bdrv_has_zero_init = nfs_has_zero_init,
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
.bdrv_truncate = nfs_file_truncate,
diff --git a/block/qapi.c b/block/qapi.c
index a87a34a8b4..fa68ba731f 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -40,6 +40,13 @@ BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)
info->encrypted = bs->encrypted;
info->encryption_key_missing = bdrv_key_required(bs);
+ info->cache = g_new(BlockdevCacheInfo, 1);
+ *info->cache = (BlockdevCacheInfo) {
+ .writeback = bdrv_enable_write_cache(bs),
+ .direct = !!(bs->open_flags & BDRV_O_NOCACHE),
+ .no_flush = !!(bs->open_flags & BDRV_O_NO_FLUSH),
+ };
+
if (bs->node_name[0]) {
info->has_node_name = true;
info->node_name = g_strdup(bs->node_name);
@@ -300,7 +307,8 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
qapi_free_BlockInfo(info);
}
-static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
+static BlockStats *bdrv_query_stats(const BlockDriverState *bs,
+ bool query_backing)
{
BlockStats *s;
@@ -311,6 +319,11 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
s->device = g_strdup(bdrv_get_device_name(bs));
}
+ if (bdrv_get_node_name(bs)[0]) {
+ s->has_node_name = true;
+ s->node_name = g_strdup(bdrv_get_node_name(bs));
+ }
+
s->stats = g_malloc0(sizeof(*s->stats));
s->stats->rd_bytes = bs->stats.nr_bytes[BLOCK_ACCT_READ];
s->stats->wr_bytes = bs->stats.nr_bytes[BLOCK_ACCT_WRITE];
@@ -325,12 +338,12 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
if (bs->file) {
s->has_parent = true;
- s->parent = bdrv_query_stats(bs->file);
+ s->parent = bdrv_query_stats(bs->file, query_backing);
}
- if (bs->backing_hd) {
+ if (query_backing && bs->backing_hd) {
s->has_backing = true;
- s->backing = bdrv_query_stats(bs->backing_hd);
+ s->backing = bdrv_query_stats(bs->backing_hd, query_backing);
}
return s;
@@ -361,17 +374,22 @@ BlockInfoList *qmp_query_block(Error **errp)
return NULL;
}
-BlockStatsList *qmp_query_blockstats(Error **errp)
+BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
+ bool query_nodes,
+ Error **errp)
{
BlockStatsList *head = NULL, **p_next = &head;
BlockDriverState *bs = NULL;
- while ((bs = bdrv_next(bs))) {
+ /* Just to be safe if query_nodes is not always initialized */
+ query_nodes = has_query_nodes && query_nodes;
+
+ while ((bs = query_nodes ? bdrv_next_node(bs) : bdrv_next(bs))) {
BlockStatsList *info = g_malloc0(sizeof(*info));
AioContext *ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);
- info->value = bdrv_query_stats(bs);
+ info->value = bdrv_query_stats(bs, !query_nodes);
aio_context_release(ctx);
*p_next = info;
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index df0b2c9cec..1fea5142d0 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1263,7 +1263,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
again:
start = offset;
- remaining = *num << BDRV_SECTOR_BITS;
+ remaining = (uint64_t)*num << BDRV_SECTOR_BITS;
cluster_offset = 0;
*host_offset = 0;
cur_bytes = 0;
diff --git a/block/qcow2.c b/block/qcow2.c
index d12049451a..e4e690a42b 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -117,7 +117,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
#ifdef DEBUG_EXT
printf("ext.magic = 0x%x\n", ext.magic);
#endif
- if (ext.len > end_offset - offset) {
+ if (offset > end_offset || ext.len > end_offset - offset) {
error_setg(errp, "Header extension too large");
return -EINVAL;
}
@@ -1428,10 +1428,23 @@ static void qcow2_close(BlockDriverState *bs)
s->l1_table = NULL;
if (!(bs->open_flags & BDRV_O_INCOMING)) {
- qcow2_cache_flush(bs, s->l2_table_cache);
- qcow2_cache_flush(bs, s->refcount_block_cache);
+ int ret1, ret2;
- qcow2_mark_clean(bs);
+ ret1 = qcow2_cache_flush(bs, s->l2_table_cache);
+ ret2 = qcow2_cache_flush(bs, s->refcount_block_cache);
+
+ if (ret1) {
+ error_report("Failed to flush the L2 table cache: %s",
+ strerror(-ret1));
+ }
+ if (ret2) {
+ error_report("Failed to flush the refcount block cache: %s",
+ strerror(-ret2));
+ }
+
+ if (!ret1 && !ret2) {
+ qcow2_mark_clean(bs);
+ }
}
qcow2_cache_destroy(bs, s->l2_table_cache);
@@ -1915,10 +1928,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
* refcount of the cluster that is occupied by the header and the refcount
* table)
*/
- BlockDriver* drv = bdrv_find_format("qcow2");
- assert(drv != NULL);
ret = bdrv_open(&bs, filename, NULL, NULL,
- BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv, &local_err);
+ BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH,
+ &bdrv_qcow2, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
goto out;
@@ -1970,7 +1982,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
/* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */
ret = bdrv_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING,
- drv, &local_err);
+ &bdrv_qcow2, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto out;
@@ -2150,8 +2162,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
/* align end of file to a sector boundary to ease reading with
sector based I/Os */
cluster_offset = bdrv_getlength(bs->file);
- bdrv_truncate(bs->file, cluster_offset);
- return 0;
+ return bdrv_truncate(bs->file, cluster_offset);
}
if (nb_sectors != s->cluster_sectors) {
@@ -2847,7 +2858,7 @@ static QemuOptsList qcow2_create_opts = {
}
};
-static BlockDriver bdrv_qcow2 = {
+BlockDriver bdrv_qcow2 = {
.format_name = "qcow2",
.instance_size = sizeof(BDRVQcowState),
.bdrv_probe = qcow2_probe,
diff --git a/block/raw-aio.h b/block/raw-aio.h
index 80681ce175..31d791fe67 100644
--- a/block/raw-aio.h
+++ b/block/raw-aio.h
@@ -41,7 +41,7 @@ BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
void laio_detach_aio_context(void *s, AioContext *old_context);
void laio_attach_aio_context(void *s, AioContext *new_context);
void laio_io_plug(BlockDriverState *bs, void *aio_ctx);
-int laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug);
+void laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug);
#endif
#ifdef _WIN32
diff --git a/block/raw-posix.c b/block/raw-posix.c
index b1af77e47f..e51293a455 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -446,6 +446,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
}
if (fstat(s->fd, &st) < 0) {
+ ret = -errno;
error_setg_errno(errp, errno, "Could not stat file");
goto fail;
}
@@ -1684,7 +1685,7 @@ static QemuOptsList raw_create_opts = {
}
};
-static BlockDriver bdrv_file = {
+BlockDriver bdrv_file = {
.format_name = "file",
.protocol_name = "file",
.instance_size = sizeof(BDRVRawState),
@@ -1922,7 +1923,7 @@ static int fd_open(BlockDriverState *bs)
return 0;
last_media_present = (s->fd >= 0);
if (s->fd >= 0 &&
- (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
+ (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
qemu_close(s->fd);
s->fd = -1;
#ifdef DEBUG_FLOPPY
@@ -1931,7 +1932,7 @@ static int fd_open(BlockDriverState *bs)
}
if (s->fd < 0) {
if (s->fd_got_error &&
- (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
+ (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
#ifdef DEBUG_FLOPPY
printf("No floppy (open delayed)\n");
#endif
@@ -1939,7 +1940,7 @@ static int fd_open(BlockDriverState *bs)
}
s->fd = qemu_open(bs->filename, s->open_flags & ~O_NONBLOCK);
if (s->fd < 0) {
- s->fd_error_time = get_clock();
+ s->fd_error_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
s->fd_got_error = 1;
if (last_media_present)
s->fd_media_changed = 1;
@@ -1954,7 +1955,7 @@ static int fd_open(BlockDriverState *bs)
}
if (!last_media_present)
s->fd_media_changed = 1;
- s->fd_open_time = get_clock();
+ s->fd_open_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
s->fd_got_error = 0;
return 0;
}
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 7b588815b9..06243d76df 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -540,7 +540,7 @@ static QemuOptsList raw_create_opts = {
}
};
-static BlockDriver bdrv_file = {
+BlockDriver bdrv_file = {
.format_name = "file",
.protocol_name = "file",
.instance_size = sizeof(BDRVRawState),
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 401b967e85..05b02c76d4 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -58,8 +58,58 @@ static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov)
{
+ void *buf = NULL;
+ BlockDriver *drv;
+ QEMUIOVector local_qiov;
+ int ret;
+
+ if (bs->probed && sector_num == 0) {
+ /* As long as these conditions are true, we can't get partial writes to
+ * the probe buffer and can just directly check the request. */
+ QEMU_BUILD_BUG_ON(BLOCK_PROBE_BUF_SIZE != 512);
+ QEMU_BUILD_BUG_ON(BDRV_SECTOR_SIZE != 512);
+
+ if (nb_sectors == 0) {
+ /* qemu_iovec_to_buf() would fail, but we want to return success
+ * instead of -EINVAL in this case. */
+ return 0;
+ }
+
+ buf = qemu_try_blockalign(bs->file, 512);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ ret = qemu_iovec_to_buf(qiov, 0, buf, 512);
+ if (ret != 512) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ drv = bdrv_probe_all(buf, 512, NULL);
+ if (drv != bs->drv) {
+ ret = -EPERM;
+ goto fail;
+ }
+
+ /* Use the checked buffer, a malicious guest might be overwriting its
+ * original buffer in the background. */
+ qemu_iovec_init(&local_qiov, qiov->niov + 1);
+ qemu_iovec_add(&local_qiov, buf, 512);
+ qemu_iovec_concat(&local_qiov, qiov, 512, qiov->size - 512);
+ qiov = &local_qiov;
+ }
+
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
- return bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov);
+ ret = bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov);
+
+fail:
+ if (qiov == &local_qiov) {
+ qemu_iovec_destroy(&local_qiov);
+ }
+ qemu_vfree(buf);
+ return ret;
}
static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
@@ -158,6 +208,18 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
bs->sg = bs->file->sg;
+
+ if (bs->probed && !bdrv_is_read_only(bs)) {
+ fprintf(stderr,
+ "WARNING: Image format was not specified for '%s' and probing "
+ "guessed raw.\n"
+ " Automatically detecting the format is dangerous for "
+ "raw images, write operations on block 0 will be restricted.\n"
+ " Specify the 'raw' format explicitly to remove the "
+ "restrictions.\n",
+ bs->file->filename);
+ }
+
return 0;
}
@@ -173,7 +235,7 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
return 1;
}
-static BlockDriver bdrv_raw = {
+BlockDriver bdrv_raw = {
.format_name = "raw",
.bdrv_probe = &raw_probe,
.bdrv_reopen_prepare = &raw_reopen_prepare,
diff --git a/block/rbd.c b/block/rbd.c
index 5b5a64a27a..f3ab2ddd5a 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -459,7 +459,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
r = rados_create(&s->cluster, clientname);
if (r < 0) {
- error_setg(&local_err, "error initializing");
+ error_setg(errp, "error initializing");
goto failed_opts;
}
@@ -495,19 +495,19 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
r = rados_connect(s->cluster);
if (r < 0) {
- error_setg(&local_err, "error connecting");
+ error_setg(errp, "error connecting");
goto failed_shutdown;
}
r = rados_ioctx_create(s->cluster, pool, &s->io_ctx);
if (r < 0) {
- error_setg(&local_err, "error opening pool %s", pool);
+ error_setg(errp, "error opening pool %s", pool);
goto failed_shutdown;
}
r = rbd_open(s->io_ctx, s->name, &s->image, s->snap);
if (r < 0) {
- error_setg(&local_err, "error reading header from %s", s->name);
+ error_setg(errp, "error reading header from %s", s->name);
goto failed_open;
}
diff --git a/block/vdi.c b/block/vdi.c
index 39070b75e8..74030c6e30 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -852,11 +852,6 @@ static QemuOptsList vdi_create_opts = {
.def_value_str = "off"
},
#endif
- {
- .name = BLOCK_OPT_NOCOW,
- .type = QEMU_OPT_BOOL,
- .help = "Turn off copy-on-write (valid only on btrfs)"
- },
/* TODO: An additional option to set UUID values might be useful. */
{ /* end of list */ }
}
diff --git a/block/vhdx.c b/block/vhdx.c
index 12bfe75e51..06f2b1a0cb 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -1109,8 +1109,9 @@ static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
/* check the payload block state */
switch (s->bat[sinfo.bat_idx] & VHDX_BAT_STATE_BIT_MASK) {
case PAYLOAD_BLOCK_NOT_PRESENT: /* fall through */
- case PAYLOAD_BLOCK_UNDEFINED: /* fall through */
- case PAYLOAD_BLOCK_UNMAPPED: /* fall through */
+ case PAYLOAD_BLOCK_UNDEFINED:
+ case PAYLOAD_BLOCK_UNMAPPED:
+ case PAYLOAD_BLOCK_UNMAPPED_v095:
case PAYLOAD_BLOCK_ZERO:
/* return zero */
qemu_iovec_memset(&hd_qiov, 0, 0, sinfo.bytes_avail);
@@ -1277,11 +1278,11 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
sectors_to_write += iov2.iov_len >> BDRV_SECTOR_BITS;
}
}
-
/* fall through */
case PAYLOAD_BLOCK_NOT_PRESENT: /* fall through */
- case PAYLOAD_BLOCK_UNMAPPED: /* fall through */
- case PAYLOAD_BLOCK_UNDEFINED: /* fall through */
+ case PAYLOAD_BLOCK_UNMAPPED:
+ case PAYLOAD_BLOCK_UNMAPPED_v095:
+ case PAYLOAD_BLOCK_UNDEFINED:
bat_prior_offset = sinfo.file_offset;
ret = vhdx_allocate_block(bs, s, &sinfo.file_offset);
if (ret < 0) {
@@ -1773,7 +1774,7 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
log_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_LOG_SIZE, 0);
block_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_BLOCK_SIZE, 0);
type = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
- use_zero_blocks = qemu_opt_get_bool_del(opts, VHDX_BLOCK_OPT_ZERO, false);
+ use_zero_blocks = qemu_opt_get_bool_del(opts, VHDX_BLOCK_OPT_ZERO, true);
if (image_size > VHDX_MAX_IMAGE_SIZE) {
error_setg_errno(errp, EINVAL, "Image size too large; max of 64TB");
@@ -1935,7 +1936,9 @@ static QemuOptsList vhdx_create_opts = {
{
.name = VHDX_BLOCK_OPT_ZERO,
.type = QEMU_OPT_BOOL,
- .help = "Force use of payload blocks of type 'ZERO'. Non-standard."
+ .help = "Force use of payload blocks of type 'ZERO'. "\
+ "Non-standard, but default. Do not set to 'off' when "\
+ "using 'qemu-img convert' with subformat=dynamic."
},
{ NULL }
}
@@ -1953,6 +1956,7 @@ static BlockDriver bdrv_vhdx = {
.bdrv_create = vhdx_create,
.bdrv_get_info = vhdx_get_info,
.bdrv_check = vhdx_check,
+ .bdrv_has_zero_init = bdrv_has_zero_init_1,
.create_opts = &vhdx_create_opts,
};
diff --git a/block/vhdx.h b/block/vhdx.h
index b4a12a081e..7003ab7a79 100644
--- a/block/vhdx.h
+++ b/block/vhdx.h
@@ -226,7 +226,8 @@ typedef struct QEMU_PACKED VHDXLogDataSector {
#define PAYLOAD_BLOCK_NOT_PRESENT 0
#define PAYLOAD_BLOCK_UNDEFINED 1
#define PAYLOAD_BLOCK_ZERO 2
-#define PAYLOAD_BLOCK_UNMAPPED 5
+#define PAYLOAD_BLOCK_UNMAPPED 3
+#define PAYLOAD_BLOCK_UNMAPPED_v095 5
#define PAYLOAD_BLOCK_FULLY_PRESENT 6
#define PAYLOAD_BLOCK_PARTIALLY_PRESENT 7
diff --git a/block/vmdk.c b/block/vmdk.c
index 2cbfd3e72e..bfff900ba6 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -28,6 +28,7 @@
#include "qemu/module.h"
#include "migration/migration.h"
#include <zlib.h>
+#include <glib.h>
#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
@@ -556,8 +557,16 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
return NULL;
}
- size = MIN(size, 1 << 20); /* avoid unbounded allocation */
- buf = g_malloc0(size + 1);
+ if (size < 4) {
+ /* Both descriptor file and sparse image must be much larger than 4
+ * bytes, also callers of vmdk_read_desc want to compare the first 4
+ * bytes with VMDK4_MAGIC, let's error out if less is read. */
+ error_setg(errp, "File is too small, not a valid image");
+ return NULL;
+ }
+
+ size = MIN(size, (1 << 20) - 1); /* avoid unbounded allocation */
+ buf = g_malloc(size + 1);
ret = bdrv_pread(file, desc_offset, buf, size);
if (ret < 0) {
@@ -565,6 +574,7 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
g_free(buf);
return NULL;
}
+ buf[ret] = 0;
return buf;
}
@@ -635,6 +645,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
bs->file->total_sectors * 512 - 1536,
&footer, sizeof(footer));
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to read footer");
return ret;
}
@@ -646,6 +657,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
le32_to_cpu(footer.eos_marker.size) != 0 ||
le32_to_cpu(footer.eos_marker.type) != MARKER_END_OF_STREAM)
{
+ error_setg(errp, "Invalid footer");
return -EINVAL;
}
@@ -676,6 +688,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
* le64_to_cpu(header.granularity);
if (l1_entry_sectors == 0) {
+ error_setg(errp, "L1 entry size is invalid");
return -EINVAL;
}
l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
@@ -784,10 +797,12 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
VmdkExtent *extent;
while (*p) {
- /* parse extent line:
+ /* parse extent line in one of below formats:
+ *
* RW [size in sectors] FLAT "file-name.vmdk" OFFSET
- * or
* RW [size in sectors] SPARSE "file-name.vmdk"
+ * RW [size in sectors] VMFS "file-name.vmdk"
+ * RW [size in sectors] VMFSSPARSE "file-name.vmdk"
*/
flat_offset = -1;
ret = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
@@ -818,6 +833,14 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
goto next_line;
}
+ if (!path_is_absolute(fname) && !path_has_protocol(fname) &&
+ !desc_file_path[0])
+ {
+ error_setg(errp, "Cannot use relative extent paths with VMDK "
+ "descriptor file '%s'", bs->file->filename);
+ return -EINVAL;
+ }
+
path_combine(extent_path, sizeof(extent_path),
desc_file_path, fname);
extent_file = NULL;
@@ -894,7 +917,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
}
s->create_type = g_strdup(ct);
s->desc_offset = 0;
- ret = vmdk_parse_extents(buf, bs, bs->file->filename, errp);
+ ret = vmdk_parse_extents(buf, bs, bs->file->exact_filename, errp);
exit:
return ret;
}
@@ -902,7 +925,7 @@ exit:
static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
- char *buf = NULL;
+ char *buf;
int ret;
BDRVVmdkState *s = bs->opaque;
uint32_t magic;
@@ -1538,7 +1561,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
/* update CID on the first write every time the virtual disk is
* opened */
if (!s->cid_updated) {
- ret = vmdk_write_cid(bs, time(NULL));
+ ret = vmdk_write_cid(bs, g_random_int());
if (ret < 0) {
return ret;
}
@@ -1922,7 +1945,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
}
/* generate descriptor file */
desc = g_strdup_printf(desc_template,
- (uint32_t)time(NULL),
+ g_random_int(),
parent_cid,
fmt,
parent_desc_line,
diff --git a/block/vpc.c b/block/vpc.c
index 38c4f02fff..46803b14be 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -893,11 +893,6 @@ static QemuOptsList vpc_create_opts = {
"Type of virtual hard disk format. Supported formats are "
"{dynamic (default) | fixed} "
},
- {
- .name = BLOCK_OPT_NOCOW,
- .type = QEMU_OPT_BOOL,
- .help = "Turn off copy-on-write (valid only on btrfs)"
- },
{ /* end of list */ }
}
};
diff --git a/block/vvfat.c b/block/vvfat.c
index cefe3a4f79..e34a789699 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2917,6 +2917,12 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
}
bdrv_qcow = bdrv_find_format("qcow");
+ if (!bdrv_qcow) {
+ error_setg(errp, "Failed to locate qcow driver");
+ ret = -ENOENT;
+ goto err;
+ }
+
opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 06f901ef6f..22e95d17ee 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -10,6 +10,7 @@
*/
#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "hw/block/block.h"
#include "monitor/monitor.h"
#include "qapi/qmp/qerror.h"
@@ -73,7 +74,7 @@ static void nbd_close_notifier(Notifier *n, void *data)
void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
Error **errp)
{
- BlockDriverState *bs;
+ BlockBackend *blk;
NBDExport *exp;
NBDCloseNotifier *n;
@@ -87,12 +88,12 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
return;
}
- bs = bdrv_find(device);
- if (!bs) {
+ blk = blk_by_name(device);
+ if (!blk) {
error_set(errp, QERR_DEVICE_NOT_FOUND, device);
return;
}
- if (!bdrv_is_inserted(bs)) {
+ if (!blk_is_inserted(blk)) {
error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
return;
}
@@ -100,18 +101,18 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
if (!has_writable) {
writable = false;
}
- if (bdrv_is_read_only(bs)) {
+ if (blk_is_read_only(blk)) {
writable = false;
}
- exp = nbd_export_new(bs, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY, NULL);
+ exp = nbd_export_new(blk, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY, NULL);
nbd_export_set_name(exp, device);
n = g_new0(NBDCloseNotifier, 1);
n->n.notify = nbd_close_notifier;
n->exp = exp;
- bdrv_add_close_notifier(bs, &n->n);
+ blk_add_close_notifier(blk, &n->n);
QTAILQ_INSERT_TAIL(&close_notifiers, n, next);
}
diff --git a/blockdev.c b/blockdev.c
index 57910b82c7..5651a8e140 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1105,6 +1105,7 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
Error **errp)
{
BlockDriverState *bs = bdrv_find(device);
+ AioContext *aio_context;
QEMUSnapshotInfo sn;
Error *local_err = NULL;
SnapshotInfo *info = NULL;
@@ -1128,25 +1129,34 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
return NULL;
}
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
+
+ if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE, errp)) {
+ goto out_aio_context;
+ }
+
ret = bdrv_snapshot_find_by_id_and_name(bs, id, name, &sn, &local_err);
if (local_err) {
error_propagate(errp, local_err);
- return NULL;
+ goto out_aio_context;
}
if (!ret) {
error_setg(errp,
"Snapshot with id '%s' and name '%s' does not exist on "
"device '%s'",
STR_OR_NULL(id), STR_OR_NULL(name), device);
- return NULL;
+ goto out_aio_context;
}
bdrv_snapshot_delete(bs, id, name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
- return NULL;
+ goto out_aio_context;
}
+ aio_context_release(aio_context);
+
info = g_new0(SnapshotInfo, 1);
info->id = g_strdup(sn.id_str);
info->name = g_strdup(sn.name);
@@ -1157,9 +1167,13 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
info->vm_clock_sec = sn.vm_clock_nsec / 1000000000;
return info;
+
+out_aio_context:
+ aio_context_release(aio_context);
+ return NULL;
}
-/* New and old BlockDriverState structs for group snapshots */
+/* New and old BlockDriverState structs for atomic group operations */
typedef struct BlkTransactionState BlkTransactionState;
@@ -1193,6 +1207,7 @@ struct BlkTransactionState {
typedef struct InternalSnapshotState {
BlkTransactionState common;
BlockDriverState *bs;
+ AioContext *aio_context;
QEMUSnapshotInfo sn;
} InternalSnapshotState;
@@ -1226,11 +1241,19 @@ static void internal_snapshot_prepare(BlkTransactionState *common,
return;
}
+ /* AioContext is released in .clean() */
+ state->aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(state->aio_context);
+
if (!bdrv_is_inserted(bs)) {
error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
return;
}
+ if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) {
+ return;
+ }
+
if (bdrv_is_read_only(bs)) {
error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
return;
@@ -1303,11 +1326,22 @@ static void internal_snapshot_abort(BlkTransactionState *common)
}
}
+static void internal_snapshot_clean(BlkTransactionState *common)
+{
+ InternalSnapshotState *state = DO_UPCAST(InternalSnapshotState,
+ common, common);
+
+ if (state->aio_context) {
+ aio_context_release(state->aio_context);
+ }
+}
+
/* external snapshot private data */
typedef struct ExternalSnapshotState {
BlkTransactionState common;
BlockDriverState *old_bs;
BlockDriverState *new_bs;
+ AioContext *aio_context;
} ExternalSnapshotState;
static void external_snapshot_prepare(BlkTransactionState *common,
@@ -1374,6 +1408,10 @@ static void external_snapshot_prepare(BlkTransactionState *common,
return;
}
+ /* Acquire AioContext now so any threads operating on old_bs stop */
+ state->aio_context = bdrv_get_aio_context(state->old_bs);
+ aio_context_acquire(state->aio_context);
+
if (!bdrv_is_inserted(state->old_bs)) {
error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
return;
@@ -1432,6 +1470,8 @@ static void external_snapshot_commit(BlkTransactionState *common)
ExternalSnapshotState *state =
DO_UPCAST(ExternalSnapshotState, common, common);
+ bdrv_set_aio_context(state->new_bs, state->aio_context);
+
/* This removes our old bs and adds the new bs */
bdrv_append(state->new_bs, state->old_bs);
/* We don't need (or want) to use the transactional
@@ -1439,6 +1479,8 @@ static void external_snapshot_commit(BlkTransactionState *common)
* don't want to abort all of them if one of them fails the reopen */
bdrv_reopen(state->new_bs, state->new_bs->open_flags & ~BDRV_O_RDWR,
NULL);
+
+ aio_context_release(state->aio_context);
}
static void external_snapshot_abort(BlkTransactionState *common)
@@ -1448,23 +1490,38 @@ static void external_snapshot_abort(BlkTransactionState *common)
if (state->new_bs) {
bdrv_unref(state->new_bs);
}
+ if (state->aio_context) {
+ aio_context_release(state->aio_context);
+ }
}
typedef struct DriveBackupState {
BlkTransactionState common;
BlockDriverState *bs;
+ AioContext *aio_context;
BlockJob *job;
} DriveBackupState;
static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
{
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
+ BlockDriverState *bs;
DriveBackup *backup;
Error *local_err = NULL;
assert(common->action->kind == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
backup = common->action->drive_backup;
+ bs = bdrv_find(backup->device);
+ if (!bs) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, backup->device);
+ return;
+ }
+
+ /* AioContext is released in .clean() */
+ state->aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(state->aio_context);
+
qmp_drive_backup(backup->device, backup->target,
backup->has_format, backup->format,
backup->sync,
@@ -1475,12 +1532,10 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
&local_err);
if (local_err) {
error_propagate(errp, local_err);
- state->bs = NULL;
- state->job = NULL;
return;
}
- state->bs = bdrv_find(backup->device);
+ state->bs = bs;
state->job = state->bs->job;
}
@@ -1495,6 +1550,15 @@ static void drive_backup_abort(BlkTransactionState *common)
}
}
+static void drive_backup_clean(BlkTransactionState *common)
+{
+ DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
+
+ if (state->aio_context) {
+ aio_context_release(state->aio_context);
+ }
+}
+
static void abort_prepare(BlkTransactionState *common, Error **errp)
{
error_setg(errp, "Transaction aborted using Abort action");
@@ -1516,6 +1580,7 @@ static const BdrvActionOps actions[] = {
.instance_size = sizeof(DriveBackupState),
.prepare = drive_backup_prepare,
.abort = drive_backup_abort,
+ .clean = drive_backup_clean,
},
[TRANSACTION_ACTION_KIND_ABORT] = {
.instance_size = sizeof(BlkTransactionState),
@@ -1526,13 +1591,13 @@ static const BdrvActionOps actions[] = {
.instance_size = sizeof(InternalSnapshotState),
.prepare = internal_snapshot_prepare,
.abort = internal_snapshot_abort,
+ .clean = internal_snapshot_clean,
},
};
/*
- * 'Atomic' group snapshots. The snapshots are taken as a set, and if any fail
- * then we do not pivot any of the devices in the group, and abandon the
- * snapshots
+ * 'Atomic' group operations. The operations are performed as a set, and if
+ * any fail then we roll back all operations in the group.
*/
void qmp_transaction(TransactionActionList *dev_list, Error **errp)
{
@@ -1543,10 +1608,10 @@ void qmp_transaction(TransactionActionList *dev_list, Error **errp)
QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionState) snap_bdrv_states;
QSIMPLEQ_INIT(&snap_bdrv_states);
- /* drain all i/o before any snapshots */
+ /* drain all i/o before any operations */
bdrv_drain_all();
- /* We don't do anything in this loop that commits us to the snapshot */
+ /* We don't do anything in this loop that commits us to the operations */
while (NULL != dev_entry) {
TransactionAction *dev_info = NULL;
const BdrvActionOps *ops;
@@ -1581,10 +1646,7 @@ void qmp_transaction(TransactionActionList *dev_list, Error **errp)
goto exit;
delete_and_fail:
- /*
- * failure, and it is all-or-none; abandon each new bs, and keep using
- * the original bs for all images
- */
+ /* failure, and it is all-or-none; roll back all operations */
QSIMPLEQ_FOREACH(state, &snap_bdrv_states, entry) {
if (state->ops->abort) {
state->ops->abort(state);
@@ -1603,14 +1665,18 @@ exit:
static void eject_device(BlockBackend *blk, int force, Error **errp)
{
BlockDriverState *bs = blk_bs(blk);
+ AioContext *aio_context;
+
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
- return;
+ goto out;
}
if (!blk_dev_has_removable_media(blk)) {
error_setg(errp, "Device '%s' is not removable",
bdrv_get_device_name(bs));
- return;
+ goto out;
}
if (blk_dev_is_medium_locked(blk) && !blk_dev_is_tray_open(blk)) {
@@ -1618,11 +1684,14 @@ static void eject_device(BlockBackend *blk, int force, Error **errp)
if (!force) {
error_setg(errp, "Device '%s' is locked",
bdrv_get_device_name(bs));
- return;
+ goto out;
}
}
bdrv_close(bs);
+
+out:
+ aio_context_release(aio_context);
}
void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
@@ -1644,6 +1713,7 @@ void qmp_block_passwd(bool has_device, const char *device,
{
Error *local_err = NULL;
BlockDriverState *bs;
+ AioContext *aio_context;
int err;
bs = bdrv_lookup_bs(has_device ? device : NULL,
@@ -1654,16 +1724,23 @@ void qmp_block_passwd(bool has_device, const char *device,
return;
}
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
+
err = bdrv_set_key(bs, password);
if (err == -EINVAL) {
error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
- return;
+ goto out;
} else if (err < 0) {
error_set(errp, QERR_INVALID_PASSWORD);
- return;
+ goto out;
}
+
+out:
+ aio_context_release(aio_context);
}
+/* Assumes AioContext is held */
static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
int bdrv_flags, BlockDriver *drv,
const char *password, Error **errp)
@@ -1696,6 +1773,7 @@ void qmp_change_blockdev(const char *device, const char *filename,
{
BlockBackend *blk;
BlockDriverState *bs;
+ AioContext *aio_context;
BlockDriver *drv = NULL;
int bdrv_flags;
Error *err = NULL;
@@ -1707,24 +1785,30 @@ void qmp_change_blockdev(const char *device, const char *filename,
}
bs = blk_bs(blk);
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
+
if (format) {
drv = bdrv_find_whitelisted_format(format, bs->read_only);
if (!drv) {
error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
- return;
+ goto out;
}
}
eject_device(blk, 0, &err);
if (err) {
error_propagate(errp, err);
- return;
+ goto out;
}
bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0;
qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, errp);
+
+out:
+ aio_context_release(aio_context);
}
/* throttling disk I/O limits */
@@ -2548,6 +2632,7 @@ void qmp_change_backing_file(const char *device,
Error **errp)
{
BlockDriverState *bs = NULL;
+ AioContext *aio_context;
BlockDriverState *image_bs = NULL;
Error *local_err = NULL;
bool ro;
@@ -2561,34 +2646,37 @@ void qmp_change_backing_file(const char *device,
return;
}
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
+
image_bs = bdrv_lookup_bs(NULL, image_node_name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
- return;
+ goto out;
}
if (!image_bs) {
error_setg(errp, "image file not found");
- return;
+ goto out;
}
if (bdrv_find_base(image_bs) == image_bs) {
error_setg(errp, "not allowing backing file change on an image "
"without a backing file");
- return;
+ goto out;
}
/* even though we are not necessarily operating on bs, we need it to
* determine if block ops are currently prohibited on the chain */
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_CHANGE, errp)) {
- return;
+ goto out;
}
/* final sanity check */
if (!bdrv_chain_contains(bs, image_bs)) {
error_setg(errp, "'%s' and image file are not in the same chain",
device);
- return;
+ goto out;
}
/* if not r/w, reopen to make r/w */
@@ -2599,7 +2687,7 @@ void qmp_change_backing_file(const char *device,
bdrv_reopen(image_bs, open_flags | BDRV_O_RDWR, &local_err);
if (local_err) {
error_propagate(errp, local_err);
- return;
+ goto out;
}
}
@@ -2619,6 +2707,9 @@ void qmp_change_backing_file(const char *device,
error_propagate(errp, local_err); /* will preserve prior errp */
}
}
+
+out:
+ aio_context_release(aio_context);
}
void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
diff --git a/configure b/configure
index 47048f0086..cae588c128 100755
--- a/configure
+++ b/configure
@@ -2727,7 +2727,7 @@ fi
if test "$modules" = yes; then
shacmd_probe="sha1sum sha1 shasum"
for c in $shacmd_probe; do
- if which $c >/dev/null 2>&1; then
+ if has $c; then
shacmd="$c"
break
fi
diff --git a/gdbstub.c b/gdbstub.c
index 0faca568d9..e4a1a79384 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -317,6 +317,8 @@ static GDBState *gdbserver_state;
bool gdb_has_xml;
+int semihosting_target = SEMIHOSTING_TARGET_AUTO;
+
#ifdef CONFIG_USER_ONLY
/* XXX: This is not thread safe. Do we care? */
static int gdbserver_fd = -1;
@@ -351,10 +353,19 @@ static enum {
GDB_SYS_DISABLED,
} gdb_syscall_mode;
-/* If gdb is connected when the first semihosting syscall occurs then use
- remote gdb syscalls. Otherwise use native file IO. */
+/* Decide if either remote gdb syscalls or native file IO should be used. */
int use_gdb_syscalls(void)
{
+ if (semihosting_target == SEMIHOSTING_TARGET_NATIVE) {
+ /* -semihosting-config target=native */
+ return false;
+ } else if (semihosting_target == SEMIHOSTING_TARGET_GDB) {
+ /* -semihosting-config target=gdb */
+ return true;
+ }
+
+ /* -semihosting-config target=auto */
+ /* On the first call check if gdb is connected and remember. */
if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
gdb_syscall_mode = (gdbserver_state ? GDB_SYS_ENABLED
: GDB_SYS_DISABLED);
diff --git a/hmp.c b/hmp.c
index 63d76868b9..481be8019b 100644
--- a/hmp.c
+++ b/hmp.c
@@ -290,14 +290,131 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict)
qapi_free_CpuInfoList(cpu_list);
}
+static void print_block_info(Monitor *mon, BlockInfo *info,
+ BlockDeviceInfo *inserted, bool verbose)
+{
+ ImageInfo *image_info;
+
+ assert(!info || !info->has_inserted || info->inserted == inserted);
+
+ if (info) {
+ monitor_printf(mon, "%s", info->device);
+ if (inserted && inserted->has_node_name) {
+ monitor_printf(mon, " (%s)", inserted->node_name);
+ }
+ } else {
+ assert(inserted);
+ monitor_printf(mon, "%s",
+ inserted->has_node_name
+ ? inserted->node_name
+ : "<anonymous>");
+ }
+
+ if (inserted) {
+ monitor_printf(mon, ": %s (%s%s%s)\n",
+ inserted->file,
+ inserted->drv,
+ inserted->ro ? ", read-only" : "",
+ inserted->encrypted ? ", encrypted" : "");
+ } else {
+ monitor_printf(mon, ": [not inserted]\n");
+ }
+
+ if (info) {
+ if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
+ monitor_printf(mon, " I/O status: %s\n",
+ BlockDeviceIoStatus_lookup[info->io_status]);
+ }
+
+ if (info->removable) {
+ monitor_printf(mon, " Removable device: %slocked, tray %s\n",
+ info->locked ? "" : "not ",
+ info->tray_open ? "open" : "closed");
+ }
+ }
+
+
+ if (!inserted) {
+ return;
+ }
+
+ monitor_printf(mon, " Cache mode: %s%s%s\n",
+ inserted->cache->writeback ? "writeback" : "writethrough",
+ inserted->cache->direct ? ", direct" : "",
+ inserted->cache->no_flush ? ", ignore flushes" : "");
+
+ if (inserted->has_backing_file) {
+ monitor_printf(mon,
+ " Backing file: %s "
+ "(chain depth: %" PRId64 ")\n",
+ inserted->backing_file,
+ inserted->backing_file_depth);
+ }
+
+ if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
+ monitor_printf(mon, " Detect zeroes: %s\n",
+ BlockdevDetectZeroesOptions_lookup[inserted->detect_zeroes]);
+ }
+
+ if (inserted->bps || inserted->bps_rd || inserted->bps_wr ||
+ inserted->iops || inserted->iops_rd || inserted->iops_wr)
+ {
+ monitor_printf(mon, " I/O throttling: bps=%" PRId64
+ " bps_rd=%" PRId64 " bps_wr=%" PRId64
+ " bps_max=%" PRId64
+ " bps_rd_max=%" PRId64
+ " bps_wr_max=%" PRId64
+ " iops=%" PRId64 " iops_rd=%" PRId64
+ " iops_wr=%" PRId64
+ " iops_max=%" PRId64
+ " iops_rd_max=%" PRId64
+ " iops_wr_max=%" PRId64
+ " iops_size=%" PRId64 "\n",
+ inserted->bps,
+ inserted->bps_rd,
+ inserted->bps_wr,
+ inserted->bps_max,
+ inserted->bps_rd_max,
+ inserted->bps_wr_max,
+ inserted->iops,
+ inserted->iops_rd,
+ inserted->iops_wr,
+ inserted->iops_max,
+ inserted->iops_rd_max,
+ inserted->iops_wr_max,
+ inserted->iops_size);
+ }
+
+ if (verbose) {
+ monitor_printf(mon, "\nImages:\n");
+ image_info = inserted->image;
+ while (1) {
+ bdrv_image_info_dump((fprintf_function)monitor_printf,
+ mon, image_info);
+ if (image_info->has_backing_image) {
+ image_info = image_info->backing_image;
+ } else {
+ break;
+ }
+ }
+ }
+}
+
void hmp_info_block(Monitor *mon, const QDict *qdict)
{
BlockInfoList *block_list, *info;
- ImageInfo *image_info;
+ BlockDeviceInfoList *blockdev_list, *blockdev;
const char *device = qdict_get_try_str(qdict, "device");
bool verbose = qdict_get_try_bool(qdict, "verbose", 0);
+ bool nodes = qdict_get_try_bool(qdict, "nodes", 0);
+ bool printed = false;
- block_list = qmp_query_block(NULL);
+ /* Print BlockBackend information */
+ if (!nodes) {
+ block_list = qmp_query_block(false);
+ } else {
+ block_list = NULL;
+ }
for (info = block_list; info; info = info->next) {
if (device && strcmp(device, info->value->device)) {
@@ -308,102 +425,40 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "\n");
}
- monitor_printf(mon, "%s", info->value->device);
- if (info->value->has_inserted) {
- monitor_printf(mon, ": %s (%s%s%s)\n",
- info->value->inserted->file,
- info->value->inserted->drv,
- info->value->inserted->ro ? ", read-only" : "",
- info->value->inserted->encrypted ? ", encrypted" : "");
- } else {
- monitor_printf(mon, ": [not inserted]\n");
- }
-
- if (info->value->has_io_status && info->value->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
- monitor_printf(mon, " I/O status: %s\n",
- BlockDeviceIoStatus_lookup[info->value->io_status]);
- }
+ print_block_info(mon, info->value, info->value->has_inserted
+ ? info->value->inserted : NULL,
+ verbose);
+ printed = true;
+ }
- if (info->value->removable) {
- monitor_printf(mon, " Removable device: %slocked, tray %s\n",
- info->value->locked ? "" : "not ",
- info->value->tray_open ? "open" : "closed");
- }
+ qapi_free_BlockInfoList(block_list);
+ if ((!device && !nodes) || printed) {
+ return;
+ }
- if (!info->value->has_inserted) {
+ /* Print node information */
+ blockdev_list = qmp_query_named_block_nodes(NULL);
+ for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
+ assert(blockdev->value->has_node_name);
+ if (device && strcmp(device, blockdev->value->node_name)) {
continue;
}
- if (info->value->inserted->has_backing_file) {
- monitor_printf(mon,
- " Backing file: %s "
- "(chain depth: %" PRId64 ")\n",
- info->value->inserted->backing_file,
- info->value->inserted->backing_file_depth);
- }
-
- if (info->value->inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
- monitor_printf(mon, " Detect zeroes: %s\n",
- BlockdevDetectZeroesOptions_lookup[info->value->inserted->detect_zeroes]);
- }
-
- if (info->value->inserted->bps
- || info->value->inserted->bps_rd
- || info->value->inserted->bps_wr
- || info->value->inserted->iops
- || info->value->inserted->iops_rd
- || info->value->inserted->iops_wr)
- {
- monitor_printf(mon, " I/O throttling: bps=%" PRId64
- " bps_rd=%" PRId64 " bps_wr=%" PRId64
- " bps_max=%" PRId64
- " bps_rd_max=%" PRId64
- " bps_wr_max=%" PRId64
- " iops=%" PRId64 " iops_rd=%" PRId64
- " iops_wr=%" PRId64
- " iops_max=%" PRId64
- " iops_rd_max=%" PRId64
- " iops_wr_max=%" PRId64
- " iops_size=%" PRId64 "\n",
- info->value->inserted->bps,
- info->value->inserted->bps_rd,
- info->value->inserted->bps_wr,
- info->value->inserted->bps_max,
- info->value->inserted->bps_rd_max,
- info->value->inserted->bps_wr_max,
- info->value->inserted->iops,
- info->value->inserted->iops_rd,
- info->value->inserted->iops_wr,
- info->value->inserted->iops_max,
- info->value->inserted->iops_rd_max,
- info->value->inserted->iops_wr_max,
- info->value->inserted->iops_size);
+ if (blockdev != blockdev_list) {
+ monitor_printf(mon, "\n");
}
- if (verbose) {
- monitor_printf(mon, "\nImages:\n");
- image_info = info->value->inserted->image;
- while (1) {
- bdrv_image_info_dump((fprintf_function)monitor_printf,
- mon, image_info);
- if (image_info->has_backing_image) {
- image_info = image_info->backing_image;
- } else {
- break;
- }
- }
- }
+ print_block_info(mon, NULL, blockdev->value, verbose);
}
-
- qapi_free_BlockInfoList(block_list);
+ qapi_free_BlockDeviceInfoList(blockdev_list);
}
void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
{
BlockStatsList *stats_list, *stats;
- stats_list = qmp_query_blockstats(NULL);
+ stats_list = qmp_query_blockstats(false, false, NULL);
for (stats = stats_list; stats; stats = stats->next) {
if (!stats->value->has_device) {
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 0014c34ddd..e6a3c5bcfb 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -329,6 +329,8 @@ static void set_kernel_args_old(const struct arm_boot_info *info)
* Returns: the size of the device tree image on success,
* 0 if the image size exceeds the limit,
* -1 on errors.
+ *
+ * Note: Must not be called unless have_dtb(binfo) is true.
*/
static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
hwaddr addr_limit)
@@ -352,7 +354,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
goto fail;
}
g_free(filename);
- } else if (binfo->get_dtb) {
+ } else {
fdt = binfo->get_dtb(binfo, &size);
if (!fdt) {
fprintf(stderr, "Board was unable to create a dtb blob\n");
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 693dfec9f2..8967cc4e0b 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -273,10 +273,10 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
case 3:
s->cpu->env.uncached_cpsr = ARM_CPU_MODE_SVC;
s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I;
- s->cpu->env.cp15.c1_sys = 0;
+ s->cpu->env.cp15.sctlr_ns = 0;
s->cpu->env.cp15.c1_coproc = 0;
- s->cpu->env.cp15.ttbr0_el1 = 0;
- s->cpu->env.cp15.c3 = 0;
+ s->cpu->env.cp15.ttbr0_el[1] = 0;
+ s->cpu->env.cp15.dacr_ns = 0;
s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */
s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index af65aa4082..d41ec97a23 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -52,7 +52,7 @@ static void realview_init(MachineState *machine,
CPUARMState *env;
ObjectClass *cpu_oc;
MemoryRegion *sysmem = get_system_memory();
- MemoryRegion *ram_lo = g_new(MemoryRegion, 1);
+ MemoryRegion *ram_lo;
MemoryRegion *ram_hi = g_new(MemoryRegion, 1);
MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
MemoryRegion *ram_hack = g_new(MemoryRegion, 1);
@@ -135,6 +135,7 @@ static void realview_init(MachineState *machine,
if (is_pb && ram_size > 0x20000000) {
/* Core tile RAM. */
+ ram_lo = g_new(MemoryRegion, 1);
low_ram_size = ram_size - 0x20000000;
ram_size = 0x20000000;
memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size,
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 1222a37f4f..2a28978cba 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -197,7 +197,13 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_RESIZE, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE, s->blocker);
+ blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_CHANGE, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_COMMIT, s->blocker);
+ blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_EJECT, s->blocker);
+ blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, s->blocker);
+ blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, s->blocker);
+ blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE,
+ s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_MIRROR, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_STREAM, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_REPLACE, s->blocker);
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 13276589e4..aa1ed986d2 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -811,6 +811,7 @@ static int nvme_init(PCIDevice *pci_dev)
NVME_CAP_SET_AMS(n->bar.cap, 1);
NVME_CAP_SET_TO(n->bar.cap, 0xf);
NVME_CAP_SET_CSS(n->bar.cap, 1);
+ NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
n->bar.vs = 0x00010001;
n->bar.intmc = n->bar.intms = 0;
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index 993c51131c..b6ccb655a6 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -688,7 +688,7 @@ typedef struct NvmeCtrl {
NvmeBar bar;
BlockConf conf;
- uint16_t page_size;
+ uint32_t page_size;
uint16_t page_bits;
uint16_t max_prp_ents;
uint16_t cqe_size;
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 8513a17e9f..389b4aa1f4 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -744,6 +744,7 @@ static void pflash_cfi02_class_init(ObjectClass *klass, void *data)
dc->realize = pflash_cfi02_realize;
dc->props = pflash_cfi02_properties;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo pflash_cfi02_info = {
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 413b41376f..901f289860 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -935,7 +935,7 @@ void qdev_alias_all_properties(DeviceState *target, Object *source)
} while (class != object_class_by_name(TYPE_DEVICE));
}
-int qdev_build_hotpluggable_device_list(Object *obj, void *opaque)
+static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
{
GSList **list = opaque;
DeviceState *dev = DEVICE(obj);
@@ -944,10 +944,18 @@ int qdev_build_hotpluggable_device_list(Object *obj, void *opaque)
*list = g_slist_append(*list, dev);
}
- object_child_foreach(obj, qdev_build_hotpluggable_device_list, opaque);
return 0;
}
+GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
+{
+ GSList *list = NULL;
+
+ object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
+
+ return list;
+}
+
static bool device_get_realized(Object *obj, Error **errp)
{
DeviceState *dev = DEVICE(obj);
@@ -1133,9 +1141,7 @@ static void device_finalize(Object *obj)
NamedGPIOList *ngl, *next;
DeviceState *dev = DEVICE(obj);
- if (dev->opts) {
- qemu_opts_del(dev->opts);
- }
+ qemu_opts_del(dev->opts);
QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
QLIST_REMOVE(ngl, node);
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index 8a5b76c403..27252646bc 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -173,20 +173,6 @@
#define CIRRUS_PNPMMIO_SIZE 0x1000
-#define BLTUNSAFE(s) \
- ( \
- ( /* check dst is within bounds */ \
- (s)->cirrus_blt_height * ABS((s)->cirrus_blt_dstpitch) \
- + ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \
- (s)->vga.vram_size \
- ) || \
- ( /* check src is within bounds */ \
- (s)->cirrus_blt_height * ABS((s)->cirrus_blt_srcpitch) \
- + ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \
- (s)->vga.vram_size \
- ) \
- )
-
struct CirrusVGAState;
typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
uint8_t * dst, const uint8_t * src,
@@ -279,6 +265,50 @@ static void cirrus_update_memory_access(CirrusVGAState *s);
*
***************************************/
+static bool blit_region_is_unsafe(struct CirrusVGAState *s,
+ int32_t pitch, int32_t addr)
+{
+ if (pitch < 0) {
+ int64_t min = addr
+ + ((int64_t)s->cirrus_blt_height-1) * pitch;
+ int32_t max = addr
+ + s->cirrus_blt_width;
+ if (min < 0 || max >= s->vga.vram_size) {
+ return true;
+ }
+ } else {
+ int64_t max = addr
+ + ((int64_t)s->cirrus_blt_height-1) * pitch
+ + s->cirrus_blt_width;
+ if (max >= s->vga.vram_size) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool blit_is_unsafe(struct CirrusVGAState *s)
+{
+ /* should be the case, see cirrus_bitblt_start */
+ assert(s->cirrus_blt_width > 0);
+ assert(s->cirrus_blt_height > 0);
+
+ if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) {
+ return true;
+ }
+
+ if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
+ s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) {
+ return true;
+ }
+ if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
+ s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) {
+ return true;
+ }
+
+ return false;
+}
+
static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
uint8_t *dst,const uint8_t *src,
int dstpitch,int srcpitch,
@@ -636,7 +666,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
- if (BLTUNSAFE(s))
+ if (blit_is_unsafe(s))
return 0;
(*s->cirrus_rop) (s, dst, src,
@@ -654,8 +684,9 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
{
cirrus_fill_t rop_func;
- if (BLTUNSAFE(s))
+ if (blit_is_unsafe(s)) {
return 0;
+ }
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
s->cirrus_blt_dstpitch,
@@ -752,7 +783,7 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
{
- if (BLTUNSAFE(s))
+ if (blit_is_unsafe(s))
return 0;
cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index b37a397820..a4d0c0c8bf 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -68,6 +68,14 @@
#define ACPI_BUILD_TABLE_SIZE 0x20000
+/* #define DEBUG_ACPI_BUILD */
+#ifdef DEBUG_ACPI_BUILD
+#define ACPI_BUILD_DPRINTF(fmt, ...) \
+ do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define ACPI_BUILD_DPRINTF(fmt, ...)
+#endif
+
typedef struct AcpiCpuInfo {
DECLARE_BITMAP(found_cpus, ACPI_CPU_HOTPLUG_ID_LIMIT);
} AcpiCpuInfo;
@@ -246,8 +254,6 @@ static void acpi_get_pci_info(PcPciInfo *info)
#define ACPI_BUILD_APPNAME6 "BOCHS "
#define ACPI_BUILD_APPNAME4 "BXPC"
-#define ACPI_BUILD_DPRINTF(level, fmt, ...) do {} while (0)
-
#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
#define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
#define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
@@ -273,12 +279,12 @@ build_header(GArray *linker, GArray *table_data,
static inline GArray *build_alloc_array(void)
{
- return g_array_new(false, true /* clear */, 1);
+ return g_array_new(false, true /* clear */, 1);
}
static inline void build_free_array(GArray *array)
{
- g_array_free(array, true);
+ g_array_free(array, true);
}
static inline void build_prepend_byte(GArray *array, uint8_t val)
@@ -1569,7 +1575,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
table_offsets = g_array_new(false, true /* clear */,
sizeof(uint32_t));
- ACPI_BUILD_DPRINTF(3, "init ACPI tables\n");
+ ACPI_BUILD_DPRINTF("init ACPI tables\n");
bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
64 /* Ensure FACS is aligned */,
@@ -1750,17 +1756,17 @@ void acpi_setup(PcGuestInfo *guest_info)
AcpiBuildState *build_state;
if (!guest_info->fw_cfg) {
- ACPI_BUILD_DPRINTF(3, "No fw cfg. Bailing out.\n");
+ ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
return;
}
if (!guest_info->has_acpi_build) {
- ACPI_BUILD_DPRINTF(3, "ACPI build disabled. Bailing out.\n");
+ ACPI_BUILD_DPRINTF("ACPI build disabled. Bailing out.\n");
return;
}
if (!acpi_enabled) {
- ACPI_BUILD_DPRINTF(3, "ACPI disabled. Bailing out.\n");
+ ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
return;
}
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 60c1d54b6d..c0e55a6446 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -61,6 +61,7 @@
#include "hw/mem/pc-dimm.h"
#include "trace.h"
#include "qapi/visitor.h"
+#include "qapi-visit.h"
/* debug PC/ISA interrupts */
//#define DEBUG_IRQ
@@ -1771,18 +1772,21 @@ static void pc_machine_set_max_ram_below_4g(Object *obj, Visitor *v,
pcms->max_ram_below_4g = value;
}
-static bool pc_machine_get_vmport(Object *obj, Error **errp)
+static void pc_machine_get_vmport(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
+ OnOffAuto vmport = pcms->vmport;
- return pcms->vmport;
+ visit_type_OnOffAuto(v, &vmport, name, errp);
}
-static void pc_machine_set_vmport(Object *obj, bool value, Error **errp)
+static void pc_machine_set_vmport(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
- pcms->vmport = value;
+ visit_type_OnOffAuto(v, &pcms->vmport, name, errp);
}
static bool pc_machine_get_aligned_dimm(Object *obj, Error **errp)
@@ -1805,11 +1809,11 @@ static void pc_machine_initfn(Object *obj)
pc_machine_set_max_ram_below_4g,
NULL, NULL, NULL);
- pcms->vmport = !xen_enabled();
- object_property_add_bool(obj, PC_MACHINE_VMPORT,
- pc_machine_get_vmport,
- pc_machine_set_vmport,
- NULL);
+ pcms->vmport = ON_OFF_AUTO_AUTO;
+ object_property_add(obj, PC_MACHINE_VMPORT, "OnOffAuto",
+ pc_machine_get_vmport,
+ pc_machine_set_vmport,
+ NULL, NULL, NULL);
pcms->enforce_aligned_dimm = true;
object_property_add_bool(obj, PC_MACHINE_ENFORCE_ALIGNED_DIMM,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7647e34528..220f7415fa 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -234,9 +234,14 @@ static void pc_init1(MachineState *machine,
pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
+ assert(pc_machine->vmport != ON_OFF_AUTO_MAX);
+ if (pc_machine->vmport == ON_OFF_AUTO_AUTO) {
+ pc_machine->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
+ }
+
/* init basic PC hardware */
pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy,
- !pc_machine->vmport, 0x4);
+ (pc_machine->vmport != ON_OFF_AUTO_ON), 0x4);
pc_nic_init(isa_bus, pci_bus);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 858e82889d..7ba05353aa 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -242,9 +242,14 @@ static void pc_q35_init(MachineState *machine)
pc_register_ferr_irq(gsi[13]);
+ assert(pc_machine->vmport != ON_OFF_AUTO_MAX);
+ if (pc_machine->vmport == ON_OFF_AUTO_AUTO) {
+ pc_machine->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
+ }
+
/* init basic PC hardware */
pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy,
- !pc_machine->vmport, 0xff0104);
+ (pc_machine->vmport != ON_OFF_AUTO_ON), 0xff0104);
/* connect pm stuff to lpc */
ich9_lpc_pm_init(lpc);
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 94f28e6bac..5651372be3 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -34,15 +34,15 @@
#include <hw/ide/pci.h>
#include <hw/ide/ahci.h>
-/* #define DEBUG_AHCI */
+#define DEBUG_AHCI 0
-#ifdef DEBUG_AHCI
#define DPRINTF(port, fmt, ...) \
-do { fprintf(stderr, "ahci: %s: [%d] ", __FUNCTION__, port); \
- fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(port, fmt, ...) do {} while(0)
-#endif
+do { \
+ if (DEBUG_AHCI) { \
+ fprintf(stderr, "ahci: %s: [%d] ", __func__, port); \
+ fprintf(stderr, fmt, ## __VA_ARGS__); \
+ } \
+} while (0)
static void check_cmd(AHCIState *s, int port);
static int handle_cmd(AHCIState *s,int port,int slot);
@@ -551,7 +551,7 @@ static void ahci_reset_port(AHCIState *s, int port)
static void debug_print_fis(uint8_t *fis, int cmd_len)
{
-#ifdef DEBUG_AHCI
+#if DEBUG_AHCI
int i;
fprintf(stderr, "fis:");
@@ -580,7 +580,7 @@ static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished)
sdb_fis = (SDBFIS *)&ad->res_fis[RES_FIS_SDBFIS];
ide_state = &ad->port.ifs[0];
- sdb_fis->type = 0xA1;
+ sdb_fis->type = SATA_FIS_TYPE_SDB;
/* Interrupt pending & Notification bit */
sdb_fis->flags = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
sdb_fis->status = ide_state->status & 0x77;
@@ -631,7 +631,7 @@ static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len)
pio_fis = &ad->res_fis[RES_FIS_PSFIS];
- pio_fis[0] = 0x5f;
+ pio_fis[0] = SATA_FIS_TYPE_PIO_SETUP;
pio_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
pio_fis[2] = s->status;
pio_fis[3] = s->error;
@@ -690,7 +690,7 @@ static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis)
d2h_fis = &ad->res_fis[RES_FIS_RFIS];
- d2h_fis[0] = 0x34;
+ d2h_fis[0] = SATA_FIS_TYPE_REGISTER_D2H;
d2h_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
d2h_fis[2] = s->status;
d2h_fis[3] = s->error;
@@ -1154,9 +1154,7 @@ out:
static void ahci_start_dma(IDEDMA *dma, IDEState *s,
BlockCompletionFunc *dma_cb)
{
-#ifdef DEBUG_AHCI
AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
-#endif
DPRINTF(ad->port_no, "\n");
s->io_buffer_offset = 0;
dma_cb(s, 0);
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index e0d2eb8f15..99aa0c967f 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -156,7 +156,10 @@
#define AHCI_SCR_SCTL_DET 0xf
#define SATA_FIS_TYPE_REGISTER_H2D 0x27
-#define SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER 0x80
+#define SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER 0x80
+#define SATA_FIS_TYPE_REGISTER_D2H 0x34
+#define SATA_FIS_TYPE_PIO_SETUP 0x5f
+#define SATA_FIS_TYPE_SDB 0xA1
#define AHCI_CMD_HDR_CMD_FIS_LEN 0x1f
#define AHCI_CMD_HDR_PRDT_LEN 16
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index b4f096e12e..1ebb58d36d 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -163,6 +163,11 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
return -1;
}
+ if (dev->conf.logical_block_size != 512) {
+ error_report("logical_block_size must be 512 for IDE");
+ return -1;
+ }
+
blkconf_serial(&dev->conf, &dev->serial);
if (kind != IDE_CD) {
blkconf_geometry(&dev->conf, &dev->chs_trans, 65536, 16, 255, &err);
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
index 5038885afd..1ad3eb0ff8 100644
--- a/hw/intc/arm_gic_kvm.c
+++ b/hw/intc/arm_gic_kvm.c
@@ -92,6 +92,21 @@ static bool kvm_arm_gic_can_save_restore(GICState *s)
return s->dev_fd >= 0;
}
+static bool kvm_gic_supports_attr(GICState *s, int group, int attrnum)
+{
+ struct kvm_device_attr attr = {
+ .group = group,
+ .attr = attrnum,
+ .flags = 0,
+ };
+
+ if (s->dev_fd == -1) {
+ return false;
+ }
+
+ return kvm_device_ioctl(s->dev_fd, KVM_HAS_DEVICE_ATTR, &attr) == 0;
+}
+
static void kvm_gic_access(GICState *s, int group, int offset,
int cpu, uint32_t *val, bool write)
{
@@ -553,6 +568,11 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
return;
}
+ if (kvm_gic_supports_attr(s, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0)) {
+ uint32_t numirqs = s->num_irq;
+ kvm_gic_access(s, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0, 0, &numirqs, 1);
+ }
+
/* Distributor */
memory_region_init_reservation(&s->iomem, OBJECT(s),
"kvm-gic_dist", 0x1000);
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index e0c235c3c2..223b947939 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -50,13 +50,13 @@ typedef struct VT82C686BState {
static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data,
unsigned size)
{
- int can_write;
SuperIOConfig *superio_conf = opaque;
DPRINTF("superio_ioport_writeb address 0x%x val 0x%x\n", addr, data);
if (addr == 0x3f0) {
superio_conf->index = data & 0xff;
} else {
+ bool can_write = true;
/* 0x3f1 */
switch (superio_conf->index) {
case 0x00 ... 0xdf:
@@ -68,30 +68,27 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data,
case 0xf7:
case 0xf9 ... 0xfb:
case 0xfd ... 0xff:
- can_write = 0;
+ can_write = false;
break;
- default:
- can_write = 1;
-
- if (can_write) {
- switch (superio_conf->index) {
- case 0xe7:
- if ((data & 0xff) != 0xfe) {
- DPRINTF("chage uart 1 base. unsupported yet\n");
- }
- break;
- case 0xe8:
- if ((data & 0xff) != 0xbe) {
- DPRINTF("chage uart 2 base. unsupported yet\n");
- }
- break;
-
- default:
- superio_conf->config[superio_conf->index] = data & 0xff;
- }
+ case 0xe7:
+ if ((data & 0xff) != 0xfe) {
+ DPRINTF("change uart 1 base. unsupported yet\n");
+ can_write = false;
+ }
+ break;
+ case 0xe8:
+ if ((data & 0xff) != 0xbe) {
+ DPRINTF("change uart 2 base. unsupported yet\n");
+ can_write = false;
}
+ break;
+ default:
+ break;
+
+ }
+ if (can_write) {
+ superio_conf->config[superio_conf->index] = data & 0xff;
}
- superio_conf->config[superio_conf->index] = data & 0xff;
}
}
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9b88775fac..e574bd4322 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -798,7 +798,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
VirtQueueElement elem;
size_t s;
- struct iovec *iov;
+ struct iovec *iov, *iov2;
unsigned int iov_cnt;
while (virtqueue_pop(vq, &elem)) {
@@ -808,8 +808,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
exit(1);
}
- iov = elem.out_sg;
iov_cnt = elem.out_num;
+ iov2 = iov = g_memdup(elem.out_sg, sizeof(struct iovec) * elem.out_num);
s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
if (s != sizeof(ctrl)) {
@@ -833,6 +833,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
virtqueue_push(vq, &elem, sizeof(status));
virtio_notify(vdev, vq);
+ g_free(iov2);
}
}
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index e7ed27e242..c4b78ed36c 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -523,6 +523,7 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
void *data, size_t len)
{
int i, index;
+ void *ptr = NULL;
assert(s->files);
@@ -531,8 +532,10 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
for (i = 0; i < index; i++) {
if (strcmp(filename, s->files->f[i].name) == 0) {
- return fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
- data, len);
+ ptr = fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
+ data, len);
+ s->files->f[i].size = cpu_to_be32(len);
+ return ptr;
}
}
/* add new one */
@@ -618,7 +621,6 @@ static void fw_cfg_realize(DeviceState *dev, Error **errp)
FWCfgState *s = FW_CFG(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-
if (s->ctl_iobase + 1 == s->data_iobase) {
sysbus_add_io(sbd, s->ctl_iobase, &s->comb_iomem);
} else {
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 308b393f96..dcb2bc5a6e 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -233,6 +233,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
vhost_dummy_handle_output);
if (err != NULL) {
error_propagate(errp, err);
+ close(vhostfd);
return;
}
diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index e160e8facc..d8bc231e5b 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -1,5 +1,5 @@
/*
- * High Precisition Event Timer emulation
+ * High Precision Event Timer emulation
*
* Copyright (c) 2007 Alexander Graf
* Copyright (c) 2008 IBM Corporation
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 56e9e0f8a2..2bf3c6fd61 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -400,9 +400,7 @@ static int tpm_passthrough_handle_device_opts(QemuOpts *opts, TPMBackend *tb)
const char *value;
value = qemu_opt_get(opts, "cancel-path");
- if (value) {
- tb->cancel_path = g_strdup(value);
- }
+ tb->cancel_path = g_strdup(value);
value = qemu_opt_get(opts, "path");
if (!value) {
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index a5f9dab0cd..cff4f7cd51 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1237,7 +1237,7 @@ static void usb_host_handle_control(USBDevice *udev, USBPacket *p,
/* Fix up USB-3 ep0 maxpacket size to allow superspeed connected devices
* to work redirected to a not superspeed capable hcd */
if (udev->speed == USB_SPEED_SUPER &&
- !((udev->port->speedmask & USB_SPEED_MASK_SUPER)) &&
+ !(udev->port->speedmask & USB_SPEED_MASK_SUPER) &&
request == 0x8006 && value == 0x100 && index == 0) {
r->usb3ep0quirk = true;
}
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 5d7c40ac04..5a128613bb 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -817,10 +817,12 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
int i, r;
if (vhost_set_backend_type(hdev, backend_type) < 0) {
+ close((uintptr_t)opaque);
return -1;
}
if (hdev->vhost_ops->vhost_backend_init(hdev, opaque) < 0) {
+ close((uintptr_t)opaque);
return -errno;
}
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index eb77019267..dfd2d8c772 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -58,7 +58,7 @@ void virtio_bus_reset(VirtioBusState *bus)
{
VirtIODevice *vdev = virtio_bus_get_device(bus);
- DPRINTF("%s: reset device.\n", qbus->name);
+ DPRINTF("%s: reset device.\n", BUS(bus)->name);
if (vdev != NULL) {
virtio_reset(vdev);
}
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index e85a979754..473c04410e 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -113,20 +113,22 @@ static void virtio_rng_save(QEMUFile *f, void *opaque)
static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id)
{
+ VirtIORNG *vrng = opaque;
+ int ret;
+
if (version_id != 1) {
return -EINVAL;
}
- return virtio_load(VIRTIO_DEVICE(opaque), f, version_id);
-}
+ ret = virtio_load(VIRTIO_DEVICE(vrng), f, version_id);
+ if (ret != 0) {
+ return ret;
+ }
-static int virtio_rng_load_device(VirtIODevice *vdev, QEMUFile *f,
- int version_id)
-{
/* We may have an element ready but couldn't process it due to a quota
* limit. Make sure to try again after live migration when the quota may
* have been reset.
*/
- virtio_rng_process(VIRTIO_RNG(vdev));
+ virtio_rng_process(vrng);
return 0;
}
@@ -231,7 +233,6 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data)
vdc->realize = virtio_rng_device_realize;
vdc->unrealize = virtio_rng_device_unrealize;
vdc->get_features = get_features;
- vdc->load = virtio_rng_load_device;
}
static void virtio_rng_initfn(Object *obj)
diff --git a/include/block/block.h b/include/block/block.h
index 5450610bc1..6e7275d95b 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -329,8 +329,6 @@ BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp);
void bdrv_invalidate_cache_all(Error **errp);
-void bdrv_clear_incoming_migration_all(void);
-
/* Ensure contents are flushed to disk. */
int bdrv_flush(BlockDriverState *bs);
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
@@ -374,6 +372,7 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
const char *node_name,
Error **errp);
bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
+BlockDriverState *bdrv_next_node(BlockDriverState *bs);
BlockDriverState *bdrv_next(BlockDriverState *bs);
int bdrv_is_encrypted(BlockDriverState *bs);
int bdrv_key_required(BlockDriverState *bs);
@@ -381,6 +380,7 @@ int bdrv_set_key(BlockDriverState *bs, const char *key);
int bdrv_query_missing_keys(void);
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
void *opaque);
+const char *bdrv_get_node_name(const BlockDriverState *bs);
const char *bdrv_get_device_name(const BlockDriverState *bs);
int bdrv_get_flags(BlockDriverState *bs);
int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
@@ -399,6 +399,7 @@ void bdrv_get_full_backing_filename(BlockDriverState *bs,
char *dest, size_t sz);
int bdrv_is_snapshot(BlockDriverState *bs);
+int path_has_protocol(const char *path);
int path_is_absolute(const char *path);
void path_combine(char *dest, int dest_size,
const char *base_path,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index a1c17b9578..06a21dd13d 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -57,6 +57,8 @@
#define BLOCK_OPT_REDUNDANCY "redundancy"
#define BLOCK_OPT_NOCOW "nocow"
+#define BLOCK_PROBE_BUF_SIZE 512
+
typedef struct BdrvTrackedRequest {
BlockDriverState *bs;
int64_t offset;
@@ -324,6 +326,7 @@ struct BlockDriverState {
int sg; /* if true, the device is a /dev/sg* */
int copy_on_read; /* if true, copy read backing sectors into image
note this is a reference count */
+ bool probed;
BlockDriver *drv; /* NULL means no media */
void *opaque;
@@ -411,7 +414,17 @@ struct BlockDriverState {
Error *backing_blocker;
};
+
+/* Essential block drivers which must always be statically linked into qemu, and
+ * which therefore can be accessed without using bdrv_find_format() */
+extern BlockDriver bdrv_file;
+extern BlockDriver bdrv_raw;
+extern BlockDriver bdrv_qcow2;
+
+
int get_tmp_filename(char *filename, int size);
+BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
+ const char *filename);
void bdrv_set_io_limits(BlockDriverState *bs,
ThrottleConfig *cfg);
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 9e835d2cbb..348302c90b 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -85,14 +85,13 @@ int nbd_disconnect(int fd);
typedef struct NBDExport NBDExport;
typedef struct NBDClient NBDClient;
-NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
- off_t size, uint32_t nbdflags,
- void (*close)(NBDExport *));
+NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
+ uint32_t nbdflags, void (*close)(NBDExport *));
void nbd_export_close(NBDExport *exp);
void nbd_export_get(NBDExport *exp);
void nbd_export_put(NBDExport *exp);
-BlockDriverState *nbd_export_get_blockdev(NBDExport *exp);
+BlockBackend *nbd_export_get_blockdev(NBDExport *exp);
NBDExport *nbd_export_find(const char *name);
void nbd_export_set_name(NBDExport *exp, const char *name);
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index a608a26c30..c6332489a7 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -95,4 +95,10 @@ extern bool gdb_has_xml;
/* in gdbstub-xml.c, generated by scripts/feature_to_c.sh */
extern const char *const xml_builtin[][2];
+/* Command line option defining whether semihosting should go via gdb or not */
+extern int semihosting_target;
+#define SEMIHOSTING_TARGET_AUTO 0
+#define SEMIHOSTING_TARGET_NATIVE 1
+#define SEMIHOSTING_TARGET_GDB 2
+
#endif
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 9d85b89e4f..69d9cf8e67 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -39,7 +39,7 @@ struct PCMachineState {
ISADevice *rtc;
uint64_t max_ram_below_4g;
- bool vmport;
+ OnOffAuto vmport;
bool enforce_aligned_dimm;
};
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index d3a29408d4..589bbe7360 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -365,7 +365,7 @@ extern int qdev_hotplug;
char *qdev_get_dev_path(DeviceState *dev);
-int qdev_build_hotpluggable_device_list(Object *obj, void *opaque);
+GSList *qdev_build_hotpluggable_device_list(Object *peripheral);
void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler,
Error **errp);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 0726d76f49..f24997d218 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -230,9 +230,6 @@ int virtio_set_features(VirtIODevice *vdev, uint32_t val);
/* Base devices. */
typedef struct VirtIOBlkConf VirtIOBlkConf;
struct virtio_net_conf;
-VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
- struct virtio_net_conf *net,
- uint32_t host_features);
typedef struct virtio_serial_conf virtio_serial_conf;
typedef struct VirtIOSCSIConf VirtIOSCSIConf;
typedef struct VirtIORNGConf VirtIORNGConf;
diff --git a/include/qemu/option.h b/include/qemu/option.h
index 59bea759a2..58c0157ed5 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -124,7 +124,7 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
-void qemu_opts_print(QemuOpts *opts);
+void qemu_opts_print(QemuOpts *opts, const char *sep);
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
int abort_on_failure);
void qemu_opts_print_help(QemuOptsList *list);
diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index d433b9017c..42bcadfbb1 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -268,6 +268,17 @@ struct { \
(head)->sqh_last = &(head)->sqh_first; \
} while (/*CONSTCOND*/0)
+#define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do { \
+ QSIMPLEQ_INIT(removed); \
+ if (((removed)->sqh_first = (head)->sqh_first) != NULL) { \
+ if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) { \
+ (head)->sqh_last = &(head)->sqh_first; \
+ } \
+ (removed)->sqh_last = &(elm)->field.sqe_next; \
+ (elm)->field.sqe_next = NULL; \
+ } \
+} while (/*CONSTCOND*/0)
+
#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \
if ((head)->sqh_first == (elm)) { \
QSIMPLEQ_REMOVE_HEAD((head), field); \
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 34751778a3..57ff47f284 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -3,80 +3,75 @@
/* A load of opaque types so that device init declarations don't have to
pull in all the real definitions. */
-typedef struct QEMUTimer QEMUTimer;
-typedef struct QEMUTimerListGroup QEMUTimerListGroup;
-typedef struct QEMUFile QEMUFile;
-typedef struct QEMUBH QEMUBH;
-
-typedef struct AioContext AioContext;
-
-typedef struct Visitor Visitor;
-
struct Monitor;
-typedef struct Monitor Monitor;
-typedef struct MigrationParams MigrationParams;
-
-typedef struct Property Property;
-typedef struct PropertyInfo PropertyInfo;
-typedef struct CompatProperty CompatProperty;
-typedef struct DeviceState DeviceState;
-typedef struct BusState BusState;
-typedef struct BusClass BusClass;
+/* Please keep this list in alphabetical order */
+typedef struct AdapterInfo AdapterInfo;
typedef struct AddressSpace AddressSpace;
-typedef struct MemoryRegion MemoryRegion;
-typedef struct MemoryRegionSection MemoryRegionSection;
-typedef struct MemoryListener MemoryListener;
-
-typedef struct MemoryMappingList MemoryMappingList;
-
-typedef struct QEMUMachine QEMUMachine;
-typedef struct MachineClass MachineClass;
-typedef struct MachineState MachineState;
-typedef struct NICInfo NICInfo;
-typedef struct HCIInfo HCIInfo;
+typedef struct AioContext AioContext;
typedef struct AudioState AudioState;
typedef struct BlockBackend BlockBackend;
typedef struct BlockDriverState BlockDriverState;
-typedef struct DriveInfo DriveInfo;
-typedef struct DisplayState DisplayState;
+typedef struct BusClass BusClass;
+typedef struct BusState BusState;
+typedef struct CharDriverState CharDriverState;
+typedef struct CompatProperty CompatProperty;
+typedef struct DeviceState DeviceState;
typedef struct DisplayChangeListener DisplayChangeListener;
+typedef struct DisplayState DisplayState;
typedef struct DisplaySurface DisplaySurface;
-typedef struct PixelFormat PixelFormat;
-typedef struct QemuConsole QemuConsole;
-typedef struct CharDriverState CharDriverState;
-typedef struct MACAddr MACAddr;
-typedef struct NetClientState NetClientState;
+typedef struct DriveInfo DriveInfo;
+typedef struct EventNotifier EventNotifier;
+typedef struct FWCfgState FWCfgState;
+typedef struct HCIInfo HCIInfo;
typedef struct I2CBus I2CBus;
+typedef struct I2SCodec I2SCodec;
typedef struct ISABus ISABus;
typedef struct ISADevice ISADevice;
-typedef struct SMBusDevice SMBusDevice;
-typedef struct PCIHostState PCIHostState;
-typedef struct PCIExpressHost PCIExpressHost;
+typedef struct MACAddr MACAddr;
+typedef struct MachineClass MachineClass;
+typedef struct MachineState MachineState;
+typedef struct MemoryListener MemoryListener;
+typedef struct MemoryMappingList MemoryMappingList;
+typedef struct MemoryRegion MemoryRegion;
+typedef struct MemoryRegionSection MemoryRegionSection;
+typedef struct MigrationParams MigrationParams;
+typedef struct Monitor Monitor;
+typedef struct MouseTransformInfo MouseTransformInfo;
+typedef struct MSIMessage MSIMessage;
+typedef struct NetClientState NetClientState;
+typedef struct NICInfo NICInfo;
+typedef struct PcGuestInfo PcGuestInfo;
+typedef struct PCIBridge PCIBridge;
typedef struct PCIBus PCIBus;
typedef struct PCIDevice PCIDevice;
-typedef struct PCIExpressDevice PCIExpressDevice;
-typedef struct PCIBridge PCIBridge;
-typedef struct PCIEAERMsg PCIEAERMsg;
-typedef struct PCIEAERLog PCIEAERLog;
typedef struct PCIEAERErr PCIEAERErr;
+typedef struct PCIEAERLog PCIEAERLog;
+typedef struct PCIEAERMsg PCIEAERMsg;
typedef struct PCIEPort PCIEPort;
typedef struct PCIESlot PCIESlot;
-typedef struct MSIMessage MSIMessage;
-typedef struct SerialState SerialState;
+typedef struct PCIExpressDevice PCIExpressDevice;
+typedef struct PCIExpressHost PCIExpressHost;
+typedef struct PCIHostState PCIHostState;
typedef struct PCMCIACardState PCMCIACardState;
-typedef struct MouseTransformInfo MouseTransformInfo;
-typedef struct uWireSlave uWireSlave;
-typedef struct I2SCodec I2SCodec;
-typedef struct SSIBus SSIBus;
-typedef struct EventNotifier EventNotifier;
-typedef struct VirtIODevice VirtIODevice;
+typedef struct PixelFormat PixelFormat;
+typedef struct PropertyInfo PropertyInfo;
+typedef struct Property Property;
+typedef struct QEMUBH QEMUBH;
+typedef struct QemuConsole QemuConsole;
+typedef struct QEMUFile QEMUFile;
+typedef struct QEMUMachine QEMUMachine;
typedef struct QEMUSGList QEMUSGList;
typedef struct QEMUSizedBuffer QEMUSizedBuffer;
-typedef struct SHPCDevice SHPCDevice;
-typedef struct FWCfgState FWCfgState;
-typedef struct PcGuestInfo PcGuestInfo;
+typedef struct QEMUTimerListGroup QEMUTimerListGroup;
+typedef struct QEMUTimer QEMUTimer;
typedef struct Range Range;
-typedef struct AdapterInfo AdapterInfo;
+typedef struct SerialState SerialState;
+typedef struct SHPCDevice SHPCDevice;
+typedef struct SMBusDevice SMBusDevice;
+typedef struct SSIBus SSIBus;
+typedef struct uWireSlave uWireSlave;
+typedef struct VirtIODevice VirtIODevice;
+typedef struct Visitor Visitor;
#endif /* QEMU_TYPEDEFS_H */
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 52d13c1c0e..8871a021d0 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -108,6 +108,8 @@ int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs);
int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
BlockCompletionFunc *cb, void *opaque);
+int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors);
+int blk_co_flush(BlockBackend *blk);
int blk_flush(BlockBackend *blk);
int blk_flush_all(void);
void blk_drain_all(void);
@@ -120,6 +122,7 @@ int blk_is_read_only(BlockBackend *blk);
int blk_is_sg(BlockBackend *blk);
int blk_enable_write_cache(BlockBackend *blk);
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
+void blk_invalidate_cache(BlockBackend *blk, Error **errp);
int blk_is_inserted(BlockBackend *blk);
void blk_lock_medium(BlockBackend *blk, bool locked);
void blk_eject(BlockBackend *blk, bool eject_flag);
@@ -132,6 +135,15 @@ void blk_op_block_all(BlockBackend *blk, Error *reason);
void blk_op_unblock_all(BlockBackend *blk, Error *reason);
AioContext *blk_get_aio_context(BlockBackend *blk);
void blk_set_aio_context(BlockBackend *blk, AioContext *new_context);
+void blk_add_aio_context_notifier(BlockBackend *blk,
+ void (*attached_aio_context)(AioContext *new_context, void *opaque),
+ void (*detach_aio_context)(void *opaque), void *opaque);
+void blk_remove_aio_context_notifier(BlockBackend *blk,
+ void (*attached_aio_context)(AioContext *,
+ void *),
+ void (*detach_aio_context)(void *),
+ void *opaque);
+void blk_add_close_notifier(BlockBackend *blk, Notifier *notify);
void blk_io_plug(BlockBackend *blk);
void blk_io_unplug(BlockBackend *blk);
BlockAcctStats *blk_get_stats(BlockBackend *blk);
diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h
index 21560ef832..b5593dc5ad 100644
--- a/linux-user/aarch64/target_cpu.h
+++ b/linux-user/aarch64/target_cpu.h
@@ -32,7 +32,7 @@ static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
/* Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is
* different from AArch32 Linux, which uses TPIDRRO.
*/
- env->cp15.tpidr_el0 = newtls;
+ env->cp15.tpidr_el[0] = newtls;
}
#endif
diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
index 39d65b692b..d8a534d7b1 100644
--- a/linux-user/arm/target_cpu.h
+++ b/linux-user/arm/target_cpu.h
@@ -29,7 +29,7 @@ static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
{
- env->cp15.tpidrro_el0 = newtls;
+ env->cp15.tpidrro_el[0] = newtls;
}
#endif
diff --git a/linux-user/main.c b/linux-user/main.c
index 5c14c1e874..186ee4d54f 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -564,7 +564,7 @@ do_kernel_trap(CPUARMState *env)
end_exclusive();
break;
case 0xffff0fe0: /* __kernel_get_tls */
- env->regs[0] = env->cp15.tpidrro_el0;
+ env->regs[0] = env->cp15.tpidrro_el[0];
break;
case 0xffff0f60: /* __kernel_cmpxchg64 */
arm_kernel_cmpxchg64_helper(env);
diff --git a/monitor.c b/monitor.c
index fa00594fb7..b37ddda457 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2628,10 +2628,10 @@ static mon_cmd_t info_cmds[] = {
},
{
.name = "block",
- .args_type = "verbose:-v,device:B?",
- .params = "[-v] [device]",
+ .args_type = "nodes:-n,verbose:-v,device:B?",
+ .params = "[-n] [-v] [device]",
.help = "show info of one block device or all block devices "
- "(and details of images with -v option)",
+ "(-n: show named nodes; -v: show details)",
.mhandler.cmd = hmp_info_block,
},
{
@@ -4321,17 +4321,14 @@ void object_add_completion(ReadLineState *rs, int nb_args, const char *str)
static void peripheral_device_del_completion(ReadLineState *rs,
const char *str, size_t len)
{
- Object *peripheral;
- GSList *list = NULL, *item;
+ Object *peripheral = container_get(qdev_get_machine(), "/peripheral");
+ GSList *list, *item;
- peripheral = object_resolve_path("/machine/peripheral/", NULL);
- if (peripheral == NULL) {
+ list = qdev_build_hotpluggable_device_list(peripheral);
+ if (!list) {
return;
}
- object_child_foreach(peripheral, qdev_build_hotpluggable_device_list,
- &list);
-
for (item = list; item; item = g_slist_next(item)) {
DeviceState *dev = item->data;
@@ -4698,7 +4695,7 @@ static void monitor_find_completion_by_table(Monitor *mon,
}
}
str = args[nb_args - 1];
- if (*ptype == '-' && ptype[1] != '\0') {
+ while (*ptype == '-' && ptype[1] != '\0') {
ptype = next_arg_type(ptype);
}
switch(*ptype) {
diff --git a/nbd.c b/nbd.c
index a7bce45117..53cf82be0b 100644
--- a/nbd.c
+++ b/nbd.c
@@ -17,8 +17,7 @@
*/
#include "block/nbd.h"
-#include "block/block.h"
-#include "block/block_int.h"
+#include "sysemu/block-backend.h"
#include "block/coroutine.h"
@@ -101,7 +100,7 @@ struct NBDExport {
int refcount;
void (*close)(NBDExport *exp);
- BlockDriverState *bs;
+ BlockBackend *blk;
char *name;
off_t dev_offset;
off_t size;
@@ -929,7 +928,7 @@ static void nbd_request_put(NBDRequest *req)
nbd_client_put(client);
}
-static void bs_aio_attached(AioContext *ctx, void *opaque)
+static void blk_aio_attached(AioContext *ctx, void *opaque)
{
NBDExport *exp = opaque;
NBDClient *client;
@@ -943,7 +942,7 @@ static void bs_aio_attached(AioContext *ctx, void *opaque)
}
}
-static void bs_aio_detach(void *opaque)
+static void blk_aio_detach(void *opaque)
{
NBDExport *exp = opaque;
NBDClient *client;
@@ -957,27 +956,26 @@ static void bs_aio_detach(void *opaque)
exp->ctx = NULL;
}
-NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
- off_t size, uint32_t nbdflags,
- void (*close)(NBDExport *))
+NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
+ uint32_t nbdflags, void (*close)(NBDExport *))
{
NBDExport *exp = g_malloc0(sizeof(NBDExport));
exp->refcount = 1;
QTAILQ_INIT(&exp->clients);
- exp->bs = bs;
+ exp->blk = blk;
exp->dev_offset = dev_offset;
exp->nbdflags = nbdflags;
- exp->size = size == -1 ? bdrv_getlength(bs) : size;
+ exp->size = size == -1 ? blk_getlength(blk) : size;
exp->close = close;
- exp->ctx = bdrv_get_aio_context(bs);
- bdrv_ref(bs);
- bdrv_add_aio_context_notifier(bs, bs_aio_attached, bs_aio_detach, exp);
+ exp->ctx = blk_get_aio_context(blk);
+ blk_ref(blk);
+ blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);
/*
* NBD exports are used for non-shared storage migration. Make sure
* that BDRV_O_INCOMING is cleared and the image is ready for write
* access since the export could be available before migration handover.
*/
- bdrv_invalidate_cache(bs, NULL);
+ blk_invalidate_cache(blk, NULL);
return exp;
}
@@ -1024,11 +1022,11 @@ void nbd_export_close(NBDExport *exp)
}
nbd_export_set_name(exp, NULL);
nbd_export_put(exp);
- if (exp->bs) {
- bdrv_remove_aio_context_notifier(exp->bs, bs_aio_attached,
- bs_aio_detach, exp);
- bdrv_unref(exp->bs);
- exp->bs = NULL;
+ if (exp->blk) {
+ blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,
+ blk_aio_detach, exp);
+ blk_unref(exp->blk);
+ exp->blk = NULL;
}
}
@@ -1056,9 +1054,9 @@ void nbd_export_put(NBDExport *exp)
}
}
-BlockDriverState *nbd_export_get_blockdev(NBDExport *exp)
+BlockBackend *nbd_export_get_blockdev(NBDExport *exp)
{
- return exp->bs;
+ return exp->blk;
}
void nbd_export_close_all(void)
@@ -1137,7 +1135,7 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque
command = request->type & NBD_CMD_MASK_COMMAND;
if (command == NBD_CMD_READ || command == NBD_CMD_WRITE) {
- req->data = qemu_blockalign(client->exp->bs, request->len);
+ req->data = blk_blockalign(client->exp->blk, request->len);
}
if (command == NBD_CMD_WRITE) {
TRACE("Reading %u byte(s)", request->len);
@@ -1203,7 +1201,7 @@ static void nbd_trip(void *opaque)
TRACE("Request type is READ");
if (request.type & NBD_CMD_FLAG_FUA) {
- ret = bdrv_co_flush(exp->bs);
+ ret = blk_co_flush(exp->blk);
if (ret < 0) {
LOG("flush failed");
reply.error = -ret;
@@ -1211,8 +1209,9 @@ static void nbd_trip(void *opaque)
}
}
- ret = bdrv_read(exp->bs, (request.from + exp->dev_offset) / 512,
- req->data, request.len / 512);
+ ret = blk_read(exp->blk,
+ (request.from + exp->dev_offset) / BDRV_SECTOR_SIZE,
+ req->data, request.len / BDRV_SECTOR_SIZE);
if (ret < 0) {
LOG("reading from file failed");
reply.error = -ret;
@@ -1234,8 +1233,9 @@ static void nbd_trip(void *opaque)
TRACE("Writing to device");
- ret = bdrv_write(exp->bs, (request.from + exp->dev_offset) / 512,
- req->data, request.len / 512);
+ ret = blk_write(exp->blk,
+ (request.from + exp->dev_offset) / BDRV_SECTOR_SIZE,
+ req->data, request.len / BDRV_SECTOR_SIZE);
if (ret < 0) {
LOG("writing to file failed");
reply.error = -ret;
@@ -1243,7 +1243,7 @@ static void nbd_trip(void *opaque)
}
if (request.type & NBD_CMD_FLAG_FUA) {
- ret = bdrv_co_flush(exp->bs);
+ ret = blk_co_flush(exp->blk);
if (ret < 0) {
LOG("flush failed");
reply.error = -ret;
@@ -1262,7 +1262,7 @@ static void nbd_trip(void *opaque)
case NBD_CMD_FLUSH:
TRACE("Request type is FLUSH");
- ret = bdrv_co_flush(exp->bs);
+ ret = blk_co_flush(exp->blk);
if (ret < 0) {
LOG("flush failed");
reply.error = -ret;
@@ -1273,8 +1273,9 @@ static void nbd_trip(void *opaque)
break;
case NBD_CMD_TRIM:
TRACE("Request type is TRIM");
- ret = bdrv_co_discard(exp->bs, (request.from + exp->dev_offset) / 512,
- request.len / 512);
+ ret = blk_co_discard(exp->blk, (request.from + exp->dev_offset)
+ / BDRV_SECTOR_SIZE,
+ request.len / BDRV_SECTOR_SIZE);
if (ret < 0) {
LOG("discard failed");
reply.error = -ret;
diff --git a/qapi-schema.json b/qapi-schema.json
index 9ffdcf8e85..563b4ad98a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1533,7 +1533,7 @@
#
# Change the VNC server password.
#
-# @target: the new password to use with VNC authentication
+# @password: the new password to use with VNC authentication
#
# Since: 1.1
#
diff --git a/qapi/block-core.json b/qapi/block-core.json
index a14e6ab1fd..6e8db15861 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -183,6 +183,22 @@
'*fragmented-clusters': 'int', '*compressed-clusters': 'int' } }
##
+# @BlockdevCacheInfo
+#
+# Cache mode information for a block device
+#
+# @writeback: true if writeback mode is enabled
+# @direct: true if the host page cache is bypassed (O_DIRECT)
+# @no-flush: true if flush requests are ignored for the device
+#
+# Since: 2.3
+##
+{ 'type': 'BlockdevCacheInfo',
+ 'data': { 'writeback': 'bool',
+ 'direct': 'bool',
+ 'no-flush': 'bool' } }
+
+##
# @BlockDeviceInfo:
#
# Information about the backing device for a block device.
@@ -239,6 +255,8 @@
#
# @iops_size: #optional an I/O size in bytes (Since 1.7)
#
+# @cache: the cache mode used for the block device (since: 2.3)
+#
# Since: 0.14.0
#
##
@@ -253,7 +271,7 @@
'*bps_max': 'int', '*bps_rd_max': 'int',
'*bps_wr_max': 'int', '*iops_max': 'int',
'*iops_rd_max': 'int', '*iops_wr_max': 'int',
- '*iops_size': 'int' } }
+ '*iops_size': 'int', 'cache': 'BlockdevCacheInfo' } }
##
# @BlockDeviceIoStatus:
@@ -405,6 +423,8 @@
# @device: #optional If the stats are for a virtual block device, the name
# corresponding to the virtual block device.
#
+# @device: #optional The node name of the device. (Since 2.3)
+#
# @stats: A @BlockDeviceStats for the device.
#
# @parent: #optional This describes the file block device if it has one.
@@ -415,7 +435,8 @@
# Since: 0.14.0
##
{ 'type': 'BlockStats',
- 'data': {'*device': 'str', 'stats': 'BlockDeviceStats',
+ 'data': {'*device': 'str', '*node-name': 'str',
+ 'stats': 'BlockDeviceStats',
'*parent': 'BlockStats',
'*backing': 'BlockStats'} }
@@ -424,11 +445,20 @@
#
# Query the @BlockStats for all virtual block devices.
#
+# @query-nodes: #optional If true, the command will query all the block nodes
+# that have a node name, in a list which will include "parent"
+# information, but not "backing".
+# If false or omitted, the behavior is as before - query all the
+# device backends, recursively including their "parent" and
+# "backing". (Since 2.3)
+#
# Returns: A list of @BlockStats for each virtual block devices.
#
# Since: 0.14.0
##
-{ 'command': 'query-blockstats', 'returns': ['BlockStats'] }
+{ 'command': 'query-blockstats',
+ 'data': { '*query-nodes': 'bool' },
+ 'returns': ['BlockStats'] }
##
# @BlockdevOnError:
diff --git a/qapi/common.json b/qapi/common.json
index 4e9a21f2f6..63ef3b4724 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -87,3 +87,18 @@
##
{ 'command': 'query-commands', 'returns': ['CommandInfo'] }
+##
+# @OnOffAuto
+#
+# An enumeration of three options: on, off, and auto
+#
+# @auto: QEMU selects the value between on and off
+#
+# @on: Enabled
+#
+# @off: Disabled
+#
+# Since: 2.2
+##
+{ 'enum': 'OnOffAuto',
+ 'data': [ 'auto', 'on', 'off' ] }
diff --git a/qemu-char.c b/qemu-char.c
index a8b01da3ee..ef84b53681 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3825,9 +3825,7 @@ void qemu_chr_delete(CharDriverState *chr)
}
g_free(chr->filename);
g_free(chr->label);
- if (chr->opts) {
- qemu_opts_del(chr->opts);
- }
+ qemu_opts_del(chr->opts);
g_free(chr);
}
diff --git a/qemu-doc.texi b/qemu-doc.texi
index ad418f851d..aabe8df2f3 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -698,7 +698,11 @@ Supported options:
Specifies which VHDX subformat to use. Valid options are
@code{dynamic} (default) and @code{fixed}.
@item block_state_zero
-Force use of payload blocks of type 'ZERO'.
+Force use of payload blocks of type 'ZERO'. Can be set to @code{on} (default)
+or @code{off}. When set to @code{off}, new blocks will be created as
+@code{PAYLOAD_BLOCK_NOT_PRESENT}, which means parsers are free to return
+arbitrary data for those blocks. Do not set to @code{off} when using
+@code{qemu-img convert} with @code{subformat=dynamic}.
@item block_size
Block size; min 1 MB, max 256 MB. 0 means auto-calculate based on image size.
@item log_size
diff --git a/qemu-img.c b/qemu-img.c
index a42335c632..7876258fa9 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1531,6 +1531,20 @@ static int img_convert(int argc, char **argv)
goto out;
}
+ if (!drv->create_opts) {
+ error_report("Format driver '%s' does not support image creation",
+ drv->format_name);
+ ret = -1;
+ goto out;
+ }
+
+ if (!proto_drv->create_opts) {
+ error_report("Protocol driver '%s' does not support image creation",
+ proto_drv->format_name);
+ ret = -1;
+ goto out;
+ }
+
create_opts = qemu_opts_append(create_opts, drv->create_opts);
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
@@ -2972,6 +2986,13 @@ static int img_amend(int argc, char **argv)
goto out;
}
+ if (!bs->drv->create_opts) {
+ error_report("Format driver '%s' does not support any options to amend",
+ fmt);
+ ret = -1;
+ goto out;
+ }
+
create_opts = qemu_opts_append(create_opts, bs->drv->create_opts);
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
if (options && qemu_opts_do_parse(opts, options, NULL)) {
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index d94fb1e2ea..e70855254a 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -2048,6 +2048,51 @@ static const cmdinfo_t abort_cmd = {
.oneline = "simulate a program crash using abort(3)",
};
+static void sigraise_help(void)
+{
+ printf(
+"\n"
+" raises the given signal\n"
+"\n"
+" Example:\n"
+" 'sigraise %i' - raises SIGTERM\n"
+"\n"
+" Invokes raise(signal), where \"signal\" is the mandatory integer argument\n"
+" given to sigraise.\n"
+"\n", SIGTERM);
+}
+
+static int sigraise_f(BlockDriverState *bs, int argc, char **argv);
+
+static const cmdinfo_t sigraise_cmd = {
+ .name = "sigraise",
+ .cfunc = sigraise_f,
+ .argmin = 1,
+ .argmax = 1,
+ .flags = CMD_NOFILE_OK,
+ .args = "signal",
+ .oneline = "raises a signal",
+ .help = sigraise_help,
+};
+
+static int sigraise_f(BlockDriverState *bs, int argc, char **argv)
+{
+ int sig = cvtnum(argv[1]);
+ if (sig < 0) {
+ printf("non-numeric signal number argument -- %s\n", argv[1]);
+ return 0;
+ }
+
+ /* Using raise() to kill this process does not necessarily flush all open
+ * streams. At least stdout and stderr (although the latter should be
+ * non-buffered anyway) should be flushed, though. */
+ fflush(stdout);
+ fflush(stderr);
+
+ raise(sig);
+ return 0;
+}
+
static void sleep_cb(void *opaque)
{
bool *expired = opaque;
@@ -2202,4 +2247,5 @@ static void __attribute((constructor)) init_qemuio_commands(void)
qemuio_add_command(&wait_break_cmd);
qemuio_add_command(&abort_cmd);
qemuio_add_command(&sleep_cmd);
+ qemuio_add_command(&sigraise_cmd);
}
diff --git a/qemu-io.c b/qemu-io.c
index 60f84dd72a..91a445a106 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -51,7 +51,8 @@ static const cmdinfo_t close_cmd = {
.oneline = "close the current open file",
};
-static int openfile(char *name, int flags, int growable, QDict *opts)
+static int openfile(char *name, BlockDriver *drv, int flags, int growable,
+ QDict *opts)
{
Error *local_err = NULL;
@@ -68,7 +69,7 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
flags |= BDRV_O_PROTOCOL;
}
- if (bdrv_open(&qemuio_bs, name, NULL, opts, flags, NULL, &local_err) < 0) {
+ if (bdrv_open(&qemuio_bs, name, NULL, opts, flags, drv, &local_err) < 0) {
fprintf(stderr, "%s: can't open%s%s: %s\n", progname,
name ? " device " : "", name ?: "",
error_get_pretty(local_err));
@@ -169,9 +170,9 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
qemu_opts_reset(&empty_opts);
if (optind == argc - 1) {
- return openfile(argv[optind], flags, growable, opts);
+ return openfile(argv[optind], NULL, flags, growable, opts);
} else if (optind == argc) {
- return openfile(NULL, flags, growable, opts);
+ return openfile(NULL, NULL, flags, growable, opts);
} else {
QDECREF(opts);
return qemuio_command_usage(&open_cmd);
@@ -196,11 +197,12 @@ static const cmdinfo_t quit_cmd = {
static void usage(const char *name)
{
printf(
-"Usage: %s [-h] [-V] [-rsnm] [-c STRING] ... [file]\n"
+"Usage: %s [-h] [-V] [-rsnm] [-f FMT] [-c STRING] ... [file]\n"
"QEMU Disk exerciser\n"
"\n"
" -c, --cmd STRING execute command with its arguments\n"
" from the given string\n"
+" -f, --format FMT specifies the block driver to use\n"
" -r, --read-only export read-only\n"
" -s, --snapshot use snapshot file\n"
" -n, --nocache disable host cache\n"
@@ -364,12 +366,13 @@ int main(int argc, char **argv)
{
int readonly = 0;
int growable = 0;
- const char *sopt = "hVc:d:rsnmgkt:T:";
+ const char *sopt = "hVc:d:f:rsnmgkt:T:";
const struct option lopt[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' },
{ "offset", 1, NULL, 'o' },
{ "cmd", 1, NULL, 'c' },
+ { "format", 1, NULL, 'f' },
{ "read-only", 0, NULL, 'r' },
{ "snapshot", 0, NULL, 's' },
{ "nocache", 0, NULL, 'n' },
@@ -384,6 +387,7 @@ int main(int argc, char **argv)
int c;
int opt_index = 0;
int flags = BDRV_O_UNMAP;
+ BlockDriver *drv = NULL;
Error *local_error = NULL;
#ifdef CONFIG_POSIX
@@ -393,6 +397,8 @@ int main(int argc, char **argv)
progname = basename(argv[0]);
qemu_init_exec_dir(argv[0]);
+ bdrv_init();
+
while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
switch (c) {
case 's':
@@ -407,6 +413,13 @@ int main(int argc, char **argv)
exit(1);
}
break;
+ case 'f':
+ drv = bdrv_find_format(optarg);
+ if (!drv) {
+ error_report("Invalid format '%s'", optarg);
+ exit(EXIT_FAILURE);
+ }
+ break;
case 'c':
add_user_command(optarg);
break;
@@ -455,7 +468,6 @@ int main(int argc, char **argv)
error_free(local_error);
exit(1);
}
- bdrv_init();
/* initialize commands */
qemuio_add_command(&quit_cmd);
@@ -477,7 +489,7 @@ int main(int argc, char **argv)
}
if ((argc - optind) == 1) {
- openfile(argv[optind], flags, growable, NULL);
+ openfile(argv[optind], drv, flags, growable, NULL);
}
command_loop();
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 5cd6c6d187..d222512412 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -146,7 +146,7 @@ static void read_partition(uint8_t *p, struct partition_record *r)
r->nb_sectors_abs = p[12] | p[13] << 8 | p[14] << 16 | p[15] << 24;
}
-static int find_partition(BlockDriverState *bs, int partition,
+static int find_partition(BlockBackend *blk, int partition,
off_t *offset, off_t *size)
{
struct partition_record mbr[4];
@@ -155,7 +155,7 @@ static int find_partition(BlockDriverState *bs, int partition,
int ext_partnum = 4;
int ret;
- if ((ret = bdrv_read(bs, 0, data, 1)) < 0) {
+ if ((ret = blk_read(blk, 0, data, 1)) < 0) {
errno = -ret;
err(EXIT_FAILURE, "error while reading");
}
@@ -175,7 +175,7 @@ static int find_partition(BlockDriverState *bs, int partition,
uint8_t data1[512];
int j;
- if ((ret = bdrv_read(bs, mbr[i].start_sector_abs, data1, 1)) < 0) {
+ if ((ret = blk_read(blk, mbr[i].start_sector_abs, data1, 1)) < 0) {
errno = -ret;
err(EXIT_FAILURE, "error while reading");
}
@@ -720,17 +720,17 @@ int main(int argc, char **argv)
}
bs->detect_zeroes = detect_zeroes;
- fd_size = bdrv_getlength(bs);
+ fd_size = blk_getlength(blk);
if (partition != -1) {
- ret = find_partition(bs, partition, &dev_offset, &fd_size);
+ ret = find_partition(blk, partition, &dev_offset, &fd_size);
if (ret < 0) {
errno = -ret;
err(EXIT_FAILURE, "Could not find partition %d", partition);
}
}
- exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, nbd_export_closed);
+ exp = nbd_export_new(blk, dev_offset, fd_size, nbdflags, nbd_export_closed);
if (sockpath) {
fd = unix_socket_incoming(sockpath);
diff --git a/qemu-options.hx b/qemu-options.hx
index da9851d483..10b9568815 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -33,7 +33,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" property accel=accel1[:accel2[:...]] selects accelerator\n"
" supported accelerators are kvm, xen, tcg (default: tcg)\n"
" kernel_irqchip=on|off controls accelerated irqchip support\n"
- " vmport=on|off controls emulation of vmport (default: on)\n"
+ " vmport=on|off|auto controls emulation of vmport (default: auto)\n"
" kvm_shadow_mem=size of KVM shadow MMU\n"
" dump-guest-core=on|off include guest memory in a core dump (default=on)\n"
" mem-merge=on|off controls memory merge support (default: on)\n"
@@ -52,8 +52,10 @@ than one accelerator specified, the next one is used if the previous one fails
to initialize.
@item kernel_irqchip=on|off
Enables in-kernel irqchip support for the chosen accelerator when available.
-@item vmport=on|off
-Enables emulation of VMWare IO port, for vmmouse etc. (enabled by default)
+@item vmport=on|off|auto
+Enables emulation of VMWare IO port, for vmmouse etc. auto says to select the
+value based on accel. For accel=xen the default is off otherwise the default
+is on.
@item kvm_shadow_mem=size
Defines the size of the KVM shadow MMU.
@item dump-guest-core=on|off
@@ -2788,6 +2790,14 @@ STEXI
@findex -qmp
Like -monitor but opens in 'control' mode.
ETEXI
+DEF("qmp-pretty", HAS_ARG, QEMU_OPTION_qmp_pretty, \
+ "-qmp-pretty dev like -qmp but uses pretty JSON formatting\n",
+ QEMU_ARCH_ALL)
+STEXI
+@item -qmp-pretty @var{dev}
+@findex -qmp-pretty
+Like -qmp but uses pretty JSON formatting.
+ETEXI
DEF("mon", HAS_ARG, QEMU_OPTION_mon, \
"-mon [chardev=]name[,mode=readline|control][,default]\n", QEMU_ARCH_ALL)
@@ -3216,7 +3226,17 @@ DEF("semihosting", 0, QEMU_OPTION_semihosting,
STEXI
@item -semihosting
@findex -semihosting
-Semihosting mode (ARM, M68K, Xtensa only).
+Enable semihosting mode (ARM, M68K, Xtensa only).
+ETEXI
+DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config,
+ "-semihosting-config [enable=on|off,]target=native|gdb|auto semihosting configuration\n",
+QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32)
+STEXI
+@item -semihosting-config [enable=on|off,]target=native|gdb|auto
+@findex -semihosting-config
+Enable semihosting and define where the semihosting calls will be addressed,
+to QEMU (@code{native}) or to GDB (@code{gdb}). The default is @code{auto}, which means
+@code{gdb} during debug sessions and @code{native} otherwise (ARM, M68K, Xtensa only).
ETEXI
DEF("old-param", 0, QEMU_OPTION_old_param,
"-old-param old param mode\n", QEMU_ARCH_ARM)
diff --git a/qemu-timer.c b/qemu-timer.c
index f4b4b6aa45..cb7d988b56 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -314,7 +314,14 @@ int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout)
return ppoll((struct pollfd *)fds, nfds, NULL, NULL);
} else {
struct timespec ts;
- ts.tv_sec = timeout / 1000000000LL;
+ int64_t tvsec = timeout / 1000000000LL;
+ /* Avoid possibly overflowing and specifying a negative number of
+ * seconds, which would turn a very long timeout into a busy-wait.
+ */
+ if (tvsec > (int64_t)INT32_MAX) {
+ tvsec = INT32_MAX;
+ }
+ ts.tv_sec = tvsec;
ts.tv_nsec = timeout % 1000000000LL;
return ppoll((struct pollfd *)fds, nfds, &ts, NULL);
}
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 718dd92f6a..33487820a4 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2347,7 +2347,7 @@ EQMP
{
.name = "query-blockstats",
- .args_type = "",
+ .args_type = "query-nodes:b?",
.mhandler.cmd_new = qmp_marshal_input_query_blockstats,
},
@@ -3820,13 +3820,13 @@ Press left mouse button.
-> { "execute": "x-input-send-event",
"arguments": { "console": 0,
"events": [ { "type": "btn",
- "data" : { "down": true, "button": "Left" } } } }
+ "data" : { "down": true, "button": "Left" } } ] } }
<- { "return": {} }
-> { "execute": "x-input-send-event",
"arguments": { "console": 0,
"events": [ { "type": "btn",
- "data" : { "down": false, "button": "Left" } } } }
+ "data" : { "down": false, "button": "Left" } } ] } }
<- { "return": {} }
Example (2):
diff --git a/qobject/qjson.c b/qobject/qjson.c
index 6cf2511580..12c576d548 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -86,8 +86,9 @@ static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
QString *qkey;
int j;
- if (s->count)
- qstring_append(s->str, ", ");
+ if (s->count) {
+ qstring_append(s->str, s->pretty ? "," : ", ");
+ }
if (s->pretty) {
qstring_append(s->str, "\n");
@@ -109,8 +110,9 @@ static void to_json_list_iter(QObject *obj, void *opaque)
ToJsonIterState *s = opaque;
int j;
- if (s->count)
- qstring_append(s->str, ", ");
+ if (s->count) {
+ qstring_append(s->str, s->pretty ? "," : ", ");
+ }
if (s->pretty) {
qstring_append(s->str, "\n");
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index af68c6c92d..f39630eb3d 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -23,7 +23,6 @@ my $email_usename = 1;
my $email_maintainer = 1;
my $email_list = 1;
my $email_subscriber_list = 0;
-my $email_git_penguin_chiefs = 0;
my $email_git = 0;
my $email_git_all_signature_types = 0;
my $email_git_blame = 0;
@@ -60,21 +59,6 @@ my $exit = 0;
my %commit_author_hash;
my %commit_signer_hash;
-my @penguin_chief = ();
-push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org");
-#Andrew wants in on most everything - 2009/01/14
-#push(@penguin_chief, "Andrew Morton:akpm\@linux-foundation.org");
-
-my @penguin_chief_names = ();
-foreach my $chief (@penguin_chief) {
- if ($chief =~ m/^(.*):(.*)/) {
- my $chief_name = $1;
- my $chief_addr = $2;
- push(@penguin_chief_names, $chief_name);
- }
-}
-my $penguin_chiefs = "\(" . join("|", @penguin_chief_names) . "\)";
-
# Signature types of people who are either
# a) responsible for the code in question, or
# b) familiar enough with it to give relevant feedback
@@ -187,7 +171,6 @@ if (!GetOptions(
'git-blame!' => \$email_git_blame,
'git-blame-signatures!' => \$email_git_blame_signatures,
'git-fallback!' => \$email_git_fallback,
- 'git-chief-penguins!' => \$email_git_penguin_chiefs,
'git-min-signatures=i' => \$email_git_min_signatures,
'git-max-maintainers=i' => \$email_git_max_maintainers,
'git-min-percent=i' => \$email_git_min_percent,
@@ -256,7 +239,7 @@ if ($sections) {
if ($email &&
($email_maintainer + $email_list + $email_subscriber_list +
- $email_git + $email_git_penguin_chiefs + $email_git_blame) == 0) {
+ $email_git + $email_git_blame) == 0) {
die "$P: Please select at least 1 email option\n";
}
@@ -671,19 +654,6 @@ sub get_maintainers {
}
}
- foreach my $chief (@penguin_chief) {
- if ($chief =~ m/^(.*):(.*)/) {
- my $email_address;
-
- $email_address = format_email($1, $2, $email_usename);
- if ($email_git_penguin_chiefs) {
- push(@email_to, [$email_address, 'chief penguin']);
- } else {
- @email_to = grep($_->[0] !~ /${email_address}/, @email_to);
- }
- }
- }
-
foreach my $email (@file_emails) {
my ($name, $address) = parse_email($email);
@@ -740,7 +710,6 @@ MAINTAINER field selection options:
--git-all-signature-types => include signers regardless of signature type
or use only ${signature_pattern} signers (default: $email_git_all_signature_types)
--git-fallback => use git when no exact MAINTAINERS pattern (default: $email_git_fallback)
- --git-chief-penguins => include ${penguin_chiefs}
--git-min-signatures => number of signatures required (default: $email_git_min_signatures)
--git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers)
--git-min-percent => minimum percentage of commits required (default: $email_git_min_percent)
@@ -1281,10 +1250,6 @@ sub vcs_find_signers {
save_commits_by_author(@lines) if ($interactive);
save_commits_by_signer(@lines) if ($interactive);
- if (!$email_git_penguin_chiefs) {
- @signatures = grep(!/${penguin_chiefs}/i, @signatures);
- }
-
my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures);
return ($commits, @$signers_ref);
@@ -1296,10 +1261,6 @@ sub vcs_find_author {
@lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
- if (!$email_git_penguin_chiefs) {
- @lines = grep(!/${penguin_chiefs}/i, @lines);
- }
-
return @lines if !@lines;
my @authors = ();
@@ -1925,10 +1886,6 @@ sub vcs_file_blame {
@lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
- if (!$email_git_penguin_chiefs) {
- @lines = grep(!/${penguin_chiefs}/i, @lines);
- }
-
last if !@lines;
my @authors = ();
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index ebb5235521..a8b83e6912 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -58,6 +58,10 @@
#define TARGET_SYS_HEAPINFO 0x16
#define TARGET_SYS_EXIT 0x18
+/* ADP_Stopped_ApplicationExit is used for exit(0),
+ * anything else is implemented as exit(1) */
+#define ADP_Stopped_ApplicationExit (0x20026)
+
#ifndef O_BINARY
#define O_BINARY 0
#endif
@@ -551,8 +555,11 @@ uint32_t do_arm_semihosting(CPUARMState *env)
return 0;
}
case TARGET_SYS_EXIT:
- gdb_exit(env, 0);
- exit(0);
+ /* ARM specifies only Stopped_ApplicationExit as normal
+ * exit, everything else is considered an error */
+ ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1;
+ gdb_exit(env, ret);
+ exit(ret);
default:
fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
cpu_dump_state(cs, stderr, fprintf, 0);
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 5ce7350ce6..d3db279e1b 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -109,7 +109,7 @@ static void arm_cpu_reset(CPUState *s)
#if defined(CONFIG_USER_ONLY)
env->pstate = PSTATE_MODE_EL0t;
/* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */
- env->cp15.c1_sys |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
+ env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
/* and to the FP/Neon instructions */
env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 2, 3);
#else
@@ -167,7 +167,11 @@ static void arm_cpu_reset(CPUState *s)
env->thumb = initial_pc & 1;
}
- if (env->cp15.c1_sys & SCTLR_V) {
+ /* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently
+ * executing as AArch32 then check if highvecs are enabled and
+ * adjust the PC accordingly.
+ */
+ if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
env->regs[15] = 0xFFFF0000;
}
@@ -548,7 +552,7 @@ static void arm1026_initfn(Object *obj)
ARMCPRegInfo ifar = {
.name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
.access = PL1_RW,
- .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[1]),
+ .fieldoffset = offsetof(CPUARMState, cp15.ifar_ns),
.resetvalue = 0
};
define_one_arm_cp_reg(cpu, &ifar);
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7f800908f4..7ba55f0c2e 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -120,6 +120,12 @@ typedef struct ARMGenericTimer {
#define GTIMER_VIRT 1
#define NUM_GTIMERS 2
+typedef struct {
+ uint64_t raw_tcr;
+ uint32_t mask;
+ uint32_t base_mask;
+} TCR;
+
typedef struct CPUARMState {
/* Regs for current mode. */
uint32_t regs[16];
@@ -177,28 +183,111 @@ typedef struct CPUARMState {
/* System control coprocessor (cp15) */
struct {
uint32_t c0_cpuid;
- uint64_t c0_cssel; /* Cache size selection. */
- uint64_t c1_sys; /* System control register. */
+ union { /* Cache size selection */
+ struct {
+ uint64_t _unused_csselr0;
+ uint64_t csselr_ns;
+ uint64_t _unused_csselr1;
+ uint64_t csselr_s;
+ };
+ uint64_t csselr_el[4];
+ };
+ union { /* System control register. */
+ struct {
+ uint64_t _unused_sctlr;
+ uint64_t sctlr_ns;
+ uint64_t hsctlr;
+ uint64_t sctlr_s;
+ };
+ uint64_t sctlr_el[4];
+ };
uint64_t c1_coproc; /* Coprocessor access register. */
uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */
- uint64_t ttbr0_el1; /* MMU translation table base 0. */
- uint64_t ttbr1_el1; /* MMU translation table base 1. */
- uint64_t c2_control; /* MMU translation table base control. */
- uint32_t c2_mask; /* MMU translation table base selection mask. */
- uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
+ uint64_t sder; /* Secure debug enable register. */
+ uint32_t nsacr; /* Non-secure access control register. */
+ union { /* MMU translation table base 0. */
+ struct {
+ uint64_t _unused_ttbr0_0;
+ uint64_t ttbr0_ns;
+ uint64_t _unused_ttbr0_1;
+ uint64_t ttbr0_s;
+ };
+ uint64_t ttbr0_el[4];
+ };
+ union { /* MMU translation table base 1. */
+ struct {
+ uint64_t _unused_ttbr1_0;
+ uint64_t ttbr1_ns;
+ uint64_t _unused_ttbr1_1;
+ uint64_t ttbr1_s;
+ };
+ uint64_t ttbr1_el[4];
+ };
+ /* MMU translation table base control. */
+ TCR tcr_el[4];
uint32_t c2_data; /* MPU data cachable bits. */
uint32_t c2_insn; /* MPU instruction cachable bits. */
- uint32_t c3; /* MMU domain access control register
- MPU write buffer control. */
+ union { /* MMU domain access control register
+ * MPU write buffer control.
+ */
+ struct {
+ uint64_t dacr_ns;
+ uint64_t dacr_s;
+ };
+ struct {
+ uint64_t dacr32_el2;
+ };
+ };
uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */
uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */
uint64_t hcr_el2; /* Hypervisor configuration register */
uint64_t scr_el3; /* Secure configuration register. */
- uint32_t ifsr_el2; /* Fault status registers. */
- uint64_t esr_el[4];
+ union { /* Fault status registers. */
+ struct {
+ uint64_t ifsr_ns;
+ uint64_t ifsr_s;
+ };
+ struct {
+ uint64_t ifsr32_el2;
+ };
+ };
+ union {
+ struct {
+ uint64_t _unused_dfsr;
+ uint64_t dfsr_ns;
+ uint64_t hsr;
+ uint64_t dfsr_s;
+ };
+ uint64_t esr_el[4];
+ };
uint32_t c6_region[8]; /* MPU base/size registers. */
- uint64_t far_el[4]; /* Fault address registers. */
- uint64_t par_el1; /* Translation result. */
+ union { /* Fault address registers. */
+ struct {
+ uint64_t _unused_far0;
+#ifdef HOST_WORDS_BIGENDIAN
+ uint32_t ifar_ns;
+ uint32_t dfar_ns;
+ uint32_t ifar_s;
+ uint32_t dfar_s;
+#else
+ uint32_t dfar_ns;
+ uint32_t ifar_ns;
+ uint32_t dfar_s;
+ uint32_t ifar_s;
+#endif
+ uint64_t _unused_far3;
+ };
+ uint64_t far_el[4];
+ };
+ union { /* Translation result. */
+ struct {
+ uint64_t _unused_par_0;
+ uint64_t par_ns;
+ uint64_t _unused_par_1;
+ uint64_t par_s;
+ };
+ uint64_t par_el[4];
+ };
uint32_t c9_insn; /* Cache lockdown registers. */
uint32_t c9_data;
uint64_t c9_pmcr; /* performance monitor control register */
@@ -207,13 +296,67 @@ typedef struct CPUARMState {
uint32_t c9_pmxevtyper; /* perf monitor event type */
uint32_t c9_pmuserenr; /* perf monitor user enable */
uint32_t c9_pminten; /* perf monitor interrupt enables */
- uint64_t mair_el1;
- uint64_t vbar_el[4]; /* vector base address register */
- uint32_t c13_fcse; /* FCSE PID. */
- uint64_t contextidr_el1; /* Context ID. */
- uint64_t tpidr_el0; /* User RW Thread register. */
- uint64_t tpidrro_el0; /* User RO Thread register. */
- uint64_t tpidr_el1; /* Privileged Thread register. */
+ union { /* Memory attribute redirection */
+ struct {
+#ifdef HOST_WORDS_BIGENDIAN
+ uint64_t _unused_mair_0;
+ uint32_t mair1_ns;
+ uint32_t mair0_ns;
+ uint64_t _unused_mair_1;
+ uint32_t mair1_s;
+ uint32_t mair0_s;
+#else
+ uint64_t _unused_mair_0;
+ uint32_t mair0_ns;
+ uint32_t mair1_ns;
+ uint64_t _unused_mair_1;
+ uint32_t mair0_s;
+ uint32_t mair1_s;
+#endif
+ };
+ uint64_t mair_el[4];
+ };
+ union { /* vector base address register */
+ struct {
+ uint64_t _unused_vbar;
+ uint64_t vbar_ns;
+ uint64_t hvbar;
+ uint64_t vbar_s;
+ };
+ uint64_t vbar_el[4];
+ };
+ uint32_t mvbar; /* (monitor) vector base address register */
+ struct { /* FCSE PID. */
+ uint32_t fcseidr_ns;
+ uint32_t fcseidr_s;
+ };
+ union { /* Context ID. */
+ struct {
+ uint64_t _unused_contextidr_0;
+ uint64_t contextidr_ns;
+ uint64_t _unused_contextidr_1;
+ uint64_t contextidr_s;
+ };
+ uint64_t contextidr_el[4];
+ };
+ union { /* User RW Thread register. */
+ struct {
+ uint64_t tpidrurw_ns;
+ uint64_t tpidrprw_ns;
+ uint64_t htpidr;
+ uint64_t _tpidr_el3;
+ };
+ uint64_t tpidr_el[4];
+ };
+ /* The secure banks of these registers don't map anywhere */
+ uint64_t tpidrurw_s;
+ uint64_t tpidrprw_s;
+ uint64_t tpidruro_s;
+
+ union { /* User RO Thread register. */
+ uint64_t tpidruro_ns;
+ uint64_t tpidrro_el[1];
+ };
uint64_t c14_cntfrq; /* Counter Frequency register */
uint64_t c14_cntkctl; /* Timer Control register */
ARMGenericTimer c14_timer[NUM_GTIMERS];
@@ -817,6 +960,49 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
return arm_feature(env, ARM_FEATURE_AARCH64);
}
+/* Function for determing whether guest cp register reads and writes should
+ * access the secure or non-secure bank of a cp register. When EL3 is
+ * operating in AArch32 state, the NS-bit determines whether the secure
+ * instance of a cp register should be used. When EL3 is AArch64 (or if
+ * it doesn't exist at all) then there is no register banking, and all
+ * accesses are to the non-secure version.
+ */
+static inline bool access_secure_reg(CPUARMState *env)
+{
+ bool ret = (arm_feature(env, ARM_FEATURE_EL3) &&
+ !arm_el_is_aa64(env, 3) &&
+ !(env->cp15.scr_el3 & SCR_NS));
+
+ return ret;
+}
+
+/* Macros for accessing a specified CP register bank */
+#define A32_BANKED_REG_GET(_env, _regname, _secure) \
+ ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns)
+
+#define A32_BANKED_REG_SET(_env, _regname, _secure, _val) \
+ do { \
+ if (_secure) { \
+ (_env)->cp15._regname##_s = (_val); \
+ } else { \
+ (_env)->cp15._regname##_ns = (_val); \
+ } \
+ } while (0)
+
+/* Macros for automatically accessing a specific CP register bank depending on
+ * the current secure state of the system. These macros are not intended for
+ * supporting instruction translation reads/writes as these are dependent
+ * solely on the SCR.NS bit and not the mode.
+ */
+#define A32_BANKED_CURRENT_REG_GET(_env, _regname) \
+ A32_BANKED_REG_GET((_env), _regname, \
+ ((!arm_el_is_aa64((_env), 3) && arm_is_secure(_env))))
+
+#define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val) \
+ A32_BANKED_REG_SET((_env), _regname, \
+ ((!arm_el_is_aa64((_env), 3) && arm_is_secure(_env))), \
+ (_val))
+
void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf);
unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx);
@@ -836,6 +1022,7 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
* Crn, Crm, opc1, opc2 fields
* 32 or 64 bit register (ie is it accessed via MRC/MCR
* or via MRRC/MCRR?)
+ * non-secure/secure bank (AArch32 only)
* We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
* (In this case crn and opc2 should be zero.)
* For AArch64, there is no 32/64 bit size distinction;
@@ -853,9 +1040,16 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
#define CP_REG_AA64_SHIFT 28
#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
-#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2) \
- (((cp) << 16) | ((is64) << 15) | ((crn) << 11) | \
- ((crm) << 7) | ((opc1) << 3) | (opc2))
+/* To enable banking of coprocessor registers depending on ns-bit we
+ * add a bit to distinguish between secure and non-secure cpregs in the
+ * hashtable.
+ */
+#define CP_REG_NS_SHIFT 29
+#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
+
+#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
+ ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
+ ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
(CP_REG_AA64_MASK | \
@@ -874,8 +1068,15 @@ static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
uint32_t cpregid = kvmid;
if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
cpregid |= CP_REG_AA64_MASK;
- } else if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
- cpregid |= (1 << 15);
+ } else {
+ if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
+ cpregid |= (1 << 15);
+ }
+
+ /* KVM is always non-secure so add the NS flag on AArch32 register
+ * entries.
+ */
+ cpregid |= 1 << CP_REG_NS_SHIFT;
}
return cpregid;
}
@@ -950,6 +1151,21 @@ enum {
ARM_CP_STATE_BOTH = 2,
};
+/* ARM CP register secure state flags. These flags identify security state
+ * attributes for a given CP register entry.
+ * The existence of both or neither secure and non-secure flags indicates that
+ * the register has both a secure and non-secure hash entry. A single one of
+ * these flags causes the register to only be hashed for the specified
+ * security state.
+ * Although definitions may have any combination of the S/NS bits, each
+ * registered entry will only have one to identify whether the entry is secure
+ * or non-secure.
+ */
+enum {
+ ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
+ ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
+};
+
/* Return true if cptype is a valid type field. This is used to try to
* catch errors where the sentinel has been accidentally left off the end
* of a list of registers.
@@ -1084,6 +1300,8 @@ struct ARMCPRegInfo {
int type;
/* Access rights: PL*_[RW] */
int access;
+ /* Security state: ARM_CP_SECSTATE_* bits/values */
+ int secure;
/* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
* this register was defined: can be used to hand data through to the
* register read/write functions, since they are passed the ARMCPRegInfo*.
@@ -1093,12 +1311,27 @@ struct ARMCPRegInfo {
* fieldoffset is non-zero, the reset value of the register.
*/
uint64_t resetvalue;
- /* Offset of the field in CPUARMState for this register. This is not
- * needed if either:
+ /* Offset of the field in CPUARMState for this register.
+ *
+ * This is not needed if either:
* 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
* 2. both readfn and writefn are specified
*/
ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
+
+ /* Offsets of the secure and non-secure fields in CPUARMState for the
+ * register if it is banked. These fields are only used during the static
+ * registration of a register. During hashing the bank associated
+ * with a given security state is copied to fieldoffset which is used from
+ * there on out.
+ *
+ * It is expected that register definitions use either fieldoffset or
+ * bank_fieldoffsets in the definition but not both. It is also expected
+ * that both bank offsets are set when defining a banked register. This
+ * use indicates that a register is banked.
+ */
+ ptrdiff_t bank_fieldoffsets[2];
+
/* Function for making any access checks for this register in addition to
* those specified by the 'access' permissions bits. If NULL, no extra
* checks required. The access check is performed at runtime, not at
@@ -1247,27 +1480,50 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
CPUARMState *env = cs->env_ptr;
unsigned int cur_el = arm_current_el(env);
unsigned int target_el = arm_excp_target_el(cs, excp_idx);
- /* FIXME: Use actual secure state. */
- bool secure = false;
- /* If in EL1/0, Physical IRQ routing to EL2 only happens from NS state. */
- bool irq_can_hyp = !secure && cur_el < 2 && target_el == 2;
-
- /* Don't take exceptions if they target a lower EL. */
+ bool secure = arm_is_secure(env);
+ uint32_t scr;
+ uint32_t hcr;
+ bool pstate_unmasked;
+ int8_t unmasked = 0;
+
+ /* Don't take exceptions if they target a lower EL.
+ * This check should catch any exceptions that would not be taken but left
+ * pending.
+ */
if (cur_el > target_el) {
return false;
}
switch (excp_idx) {
case EXCP_FIQ:
- if (irq_can_hyp && (env->cp15.hcr_el2 & HCR_FMO)) {
- return true;
- }
- return !(env->daif & PSTATE_F);
+ /* If FIQs are routed to EL3 or EL2 then there are cases where we
+ * override the CPSR.F in determining if the exception is masked or
+ * not. If neither of these are set then we fall back to the CPSR.F
+ * setting otherwise we further assess the state below.
+ */
+ hcr = (env->cp15.hcr_el2 & HCR_FMO);
+ scr = (env->cp15.scr_el3 & SCR_FIQ);
+
+ /* When EL3 is 32-bit, the SCR.FW bit controls whether the CPSR.F bit
+ * masks FIQ interrupts when taken in non-secure state. If SCR.FW is
+ * set then FIQs can be masked by CPSR.F when non-secure but only
+ * when FIQs are only routed to EL3.
+ */
+ scr &= !((env->cp15.scr_el3 & SCR_FW) && !hcr);
+ pstate_unmasked = !(env->daif & PSTATE_F);
+ break;
+
case EXCP_IRQ:
- if (irq_can_hyp && (env->cp15.hcr_el2 & HCR_IMO)) {
- return true;
- }
- return !(env->daif & PSTATE_I);
+ /* When EL3 execution state is 32-bit, if HCR.IMO is set then we may
+ * override the CPSR.I masking when in non-secure state. The SCR.IRQ
+ * setting has already been taken into consideration when setting the
+ * target EL, so it does not have a further affect here.
+ */
+ hcr = (env->cp15.hcr_el2 & HCR_IMO);
+ scr = false;
+ pstate_unmasked = !(env->daif & PSTATE_I);
+ break;
+
case EXCP_VFIQ:
if (secure || !(env->cp15.hcr_el2 & HCR_FMO)) {
/* VFIQs are only taken when hypervized and non-secure. */
@@ -1283,6 +1539,21 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
default:
g_assert_not_reached();
}
+
+ /* Use the target EL, current execution state and SCR/HCR settings to
+ * determine whether the corresponding CPSR bit is used to mask the
+ * interrupt.
+ */
+ if ((target_el > cur_el) && (target_el != 1)) {
+ if (arm_el_is_aa64(env, 3) || ((scr || hcr) && (!secure))) {
+ unmasked = 1;
+ }
+ }
+
+ /* The PSTATE bits only mask the interrupt if we have not overriden the
+ * ability above.
+ */
+ return unmasked || pstate_unmasked;
}
static inline CPUARMState *cpu_init(const char *cpu_model)
@@ -1402,6 +1673,12 @@ static inline bool arm_singlestep_active(CPUARMState *env)
*/
#define ARM_TBFLAG_XSCALE_CPAR_SHIFT 20
#define ARM_TBFLAG_XSCALE_CPAR_MASK (3 << ARM_TBFLAG_XSCALE_CPAR_SHIFT)
+/* Indicates whether cp register reads and writes by guest code should access
+ * the secure or nonsecure bank of banked registers; note that this is not
+ * the same thing as the current security state of the processor!
+ */
+#define ARM_TBFLAG_NS_SHIFT 22
+#define ARM_TBFLAG_NS_MASK (1 << ARM_TBFLAG_NS_SHIFT)
/* Bit usage when in AArch64 state */
#define ARM_TBFLAG_AA64_EL_SHIFT 0
@@ -1446,6 +1723,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
(((F) & ARM_TBFLAG_AA64_SS_ACTIVE_MASK) >> ARM_TBFLAG_AA64_SS_ACTIVE_SHIFT)
#define ARM_TBFLAG_AA64_PSTATE_SS(F) \
(((F) & ARM_TBFLAG_AA64_PSTATE_SS_MASK) >> ARM_TBFLAG_AA64_PSTATE_SS_SHIFT)
+#define ARM_TBFLAG_NS(F) \
+ (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
@@ -1495,6 +1774,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
if (privmode) {
*flags |= ARM_TBFLAG_PRIV_MASK;
}
+ if (!(access_secure_reg(env))) {
+ *flags |= ARM_TBFLAG_NS_MASK;
+ }
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
|| arm_el_is_aa64(env, 1)) {
*flags |= ARM_TBFLAG_VFPEN_MASK;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index b74d348a3b..96abbed935 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -136,6 +136,11 @@ static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
}
}
+static void *raw_ptr(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ return (char *)env + ri->fieldoffset;
+}
+
static uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
{
/* Raw read of a coprocessor register (as needed for migration, etc). */
@@ -419,13 +424,36 @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
}
static const ARMCPRegInfo cp_reginfo[] = {
- { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
+ /* Define the secure and non-secure FCSE identifier CP registers
+ * separately because there is no secure bank in V8 (no _EL3). This allows
+ * the secure register to be properly reset and migrated. There is also no
+ * v8 EL1 version of the register so the non-secure instance stands alone.
+ */
+ { .name = "FCSEIDR(NS)",
+ .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0,
+ .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS,
+ .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_ns),
+ .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
+ { .name = "FCSEIDR(S)",
+ .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0,
+ .access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
+ .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_s),
.resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
- { .name = "CONTEXTIDR", .state = ARM_CP_STATE_BOTH,
+ /* Define the secure and non-secure context identifier CP registers
+ * separately because there is no secure bank in V8 (no _EL3). This allows
+ * the secure register to be properly reset and migrated. In the
+ * non-secure case, the 32-bit register will have reset and migration
+ * disabled during registration as it is handled by the 64-bit instance.
+ */
+ { .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
- .access = PL1_RW,
- .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el1),
+ .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS,
+ .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]),
+ .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
+ { .name = "CONTEXTIDR(S)", .state = ARM_CP_STATE_AA32,
+ .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
+ .access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
+ .fieldoffset = offsetof(CPUARMState, cp15.contextidr_s),
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
REGINFO_SENTINEL
};
@@ -435,10 +463,12 @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
* definitions that don't use CP_ANY wildcards (mostly in v8_cp_reginfo[]).
*/
/* MMU Domain access control / MPU write buffer control */
- { .name = "DACR", .cp = 15,
- .crn = 3, .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c3),
- .resetvalue = 0, .writefn = dacr_write, .raw_writefn = raw_write, },
+ { .name = "DACR",
+ .cp = 15, .opc1 = CP_ANY, .crn = 3, .crm = CP_ANY, .opc2 = CP_ANY,
+ .access = PL1_RW, .resetvalue = 0,
+ .writefn = dacr_write, .raw_writefn = raw_write,
+ .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
+ offsetoflow32(CPUARMState, cp15.dacr_ns) } },
/* ??? This covers not just the impdef TLB lockdown registers but also
* some v7VMSA registers relating to TEX remap, so it is overly broad.
*/
@@ -552,7 +582,8 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
.access = PL0_W, .type = ARM_CP_NOP },
{ .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2,
.access = PL1_RW,
- .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[1]),
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s),
+ offsetof(CPUARMState, cp15.ifar_ns) },
.resetvalue = 0, },
/* Watchpoint Fault Address Register : should actually only be present
* for 1136, 1176, 11MPCore.
@@ -776,7 +807,14 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
ARMCPU *cpu = arm_env_get_cpu(env);
- return cpu->ccsidr[env->cp15.c0_cssel];
+
+ /* Acquire the CSSELR index from the bank corresponding to the CCSIDR
+ * bank
+ */
+ uint32_t index = A32_BANKED_REG_GET(env, csselr,
+ ri->secure & ARM_CP_SECSTATE_S);
+
+ return cpu->ccsidr[index];
}
static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -896,18 +934,17 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .writefn = vbar_write,
- .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[1]),
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
+ offsetof(CPUARMState, cp15.vbar_ns) },
.resetvalue = 0 },
- { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
- .resetvalue = 0, .writefn = scr_write },
{ .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
.access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE },
{ .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c0_cssel),
- .writefn = csselr_write, .resetvalue = 0 },
+ .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
+ offsetof(CPUARMState, cp15.csselr_ns) } },
/* Auxiliary ID register: this actually has an IMPDEF value but for now
* just RAZ for all cores:
*/
@@ -928,20 +965,26 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
*/
{ .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el1),
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
.resetvalue = 0 },
/* For non-long-descriptor page tables these are PRRR and NMRR;
* regardless they still act as reads-as-written for QEMU.
* The override is necessary because of the overly-broad TLB_LOCKDOWN
* definition.
*/
+ /* MAIR0/1 are defined seperately from their 64-bit counterpart which
+ * allows them to assign the correct fieldoffset based on the endianness
+ * handled in the field definitions.
+ */
{ .name = "MAIR0", .state = ARM_CP_STATE_AA32, .type = ARM_CP_OVERRIDE,
.cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW,
- .fieldoffset = offsetoflow32(CPUARMState, cp15.mair_el1),
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair0_s),
+ offsetof(CPUARMState, cp15.mair0_ns) },
.resetfn = arm_cp_reset_ignore },
{ .name = "MAIR1", .state = ARM_CP_STATE_AA32, .type = ARM_CP_OVERRIDE,
.cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW,
- .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el1),
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair1_s),
+ offsetof(CPUARMState, cp15.mair1_ns) },
.resetfn = arm_cp_reset_ignore },
{ .name = "ISR_EL1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0,
@@ -1017,23 +1060,31 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
{ .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0,
.access = PL0_RW,
- .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue = 0 },
+ .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .resetvalue = 0 },
{ .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
.access = PL0_RW,
- .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0),
+ .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s),
+ offsetoflow32(CPUARMState, cp15.tpidrurw_ns) },
.resetfn = arm_cp_reset_ignore },
{ .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
.access = PL0_R|PL1_W,
- .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el0), .resetvalue = 0 },
+ .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]),
+ .resetvalue = 0},
{ .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
.access = PL0_R|PL1_W,
- .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0),
+ .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
+ offsetoflow32(CPUARMState, cp15.tpidruro_ns) },
.resetfn = arm_cp_reset_ignore },
- { .name = "TPIDR_EL1", .state = ARM_CP_STATE_BOTH,
+ { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
.access = PL1_RW,
- .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el1), .resetvalue = 0 },
+ .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]), .resetvalue = 0 },
+ { .name = "TPIDRPRW", .opc1 = 0, .cp = 15, .crn = 13, .crm = 0, .opc2 = 4,
+ .access = PL1_RW,
+ .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s),
+ offsetoflow32(CPUARMState, cp15.tpidrprw_ns) },
+ .resetvalue = 0 },
REGINFO_SENTINEL
};
@@ -1391,6 +1442,7 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
int prot;
int ret, is_user = ri->opc2 & 2;
int access_type = ri->opc2 & 1;
+ uint64_t par64;
ret = get_phys_addr(env, value, access_type, is_user,
&phys_addr, &prot, &page_size);
@@ -1399,7 +1451,7 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
* translation table format, but with WnR always clear.
* Convert it to a 64-bit PAR.
*/
- uint64_t par64 = (1 << 11); /* LPAE bit always set */
+ par64 = (1 << 11); /* LPAE bit always set */
if (ret == 0) {
par64 |= phys_addr & ~0xfffULL;
/* We don't set the ATTR or SH fields in the PAR. */
@@ -1411,7 +1463,6 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
* fault.
*/
}
- env->cp15.par_el1 = par64;
} else {
/* ret is a DFSR/IFSR value for the short descriptor
* translation table format (with WnR always clear).
@@ -1421,23 +1472,25 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
/* We do not set any attribute bits in the PAR */
if (page_size == (1 << 24)
&& arm_feature(env, ARM_FEATURE_V7)) {
- env->cp15.par_el1 = (phys_addr & 0xff000000) | 1 << 1;
+ par64 = (phys_addr & 0xff000000) | (1 << 1);
} else {
- env->cp15.par_el1 = phys_addr & 0xfffff000;
+ par64 = phys_addr & 0xfffff000;
}
} else {
- env->cp15.par_el1 = ((ret & (1 << 10)) >> 5) |
- ((ret & (1 << 12)) >> 6) |
- ((ret & 0xf) << 1) | 1;
+ par64 = ((ret & (1 << 10)) >> 5) | ((ret & (1 << 12)) >> 6) |
+ ((ret & 0xf) << 1) | 1;
}
}
+
+ A32_BANKED_CURRENT_REG_SET(env, par, par64);
}
#endif
static const ARMCPRegInfo vapa_cp_reginfo[] = {
{ .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .resetvalue = 0,
- .fieldoffset = offsetoflow32(CPUARMState, cp15.par_el1),
+ .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.par_s),
+ offsetoflow32(CPUARMState, cp15.par_ns) },
.writefn = par_write },
#ifndef CONFIG_USER_ONLY
{ .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
@@ -1555,6 +1608,7 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
+ TCR *tcr = raw_ptr(env, ri);
int maskshift = extract32(value, 0, 3);
if (!arm_feature(env, ARM_FEATURE_V8)) {
@@ -1573,14 +1627,15 @@ static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
}
}
- /* Note that we always calculate c2_mask and c2_base_mask, but
+ /* Update the masks corresponding to the the TCR bank being written
+ * Note that we always calculate mask and base_mask, but
* they are only used for short-descriptor tables (ie if EAE is 0);
- * for long-descriptor tables the TTBCR fields are used differently
- * and the c2_mask and c2_base_mask values are meaningless.
+ * for long-descriptor tables the TCR fields are used differently
+ * and the mask and base_mask values are meaningless.
*/
- raw_write(env, ri, value);
- env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift);
- env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift);
+ tcr->raw_tcr = value;
+ tcr->mask = ~(((uint32_t)0xffffffffu) >> maskshift);
+ tcr->base_mask = ~((uint32_t)0x3fffu >> maskshift);
}
static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -1599,19 +1654,25 @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
{
- env->cp15.c2_base_mask = 0xffffc000u;
- raw_write(env, ri, 0);
- env->cp15.c2_mask = 0;
+ TCR *tcr = raw_ptr(env, ri);
+
+ /* Reset both the TCR as well as the masks corresponding to the bank of
+ * the TCR being reset.
+ */
+ tcr->raw_tcr = 0;
+ tcr->mask = 0;
+ tcr->base_mask = 0xffffc000u;
}
static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
ARMCPU *cpu = arm_env_get_cpu(env);
+ TCR *tcr = raw_ptr(env, ri);
/* For AArch64 the A1 bit could result in a change of ASID, so TLB flush. */
tlb_flush(CPU(cpu), 1);
- raw_write(env, ri, value);
+ tcr->raw_tcr = value;
}
static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -1631,37 +1692,45 @@ static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
static const ARMCPRegInfo vmsa_cp_reginfo[] = {
{ .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
- .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
+ .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s),
+ offsetoflow32(CPUARMState, cp15.dfsr_ns) },
.resetfn = arm_cp_reset_ignore, },
{ .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
- .access = PL1_RW,
- .fieldoffset = offsetof(CPUARMState, cp15.ifsr_el2), .resetvalue = 0, },
+ .access = PL1_RW, .resetvalue = 0,
+ .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ifsr_s),
+ offsetoflow32(CPUARMState, cp15.ifsr_ns) } },
{ .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
.access = PL1_RW,
.fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
- .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1),
- .writefn = vmsa_ttbr_write, .resetvalue = 0 },
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
+ .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
+ offsetof(CPUARMState, cp15.ttbr0_ns) } },
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
- .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1),
- .writefn = vmsa_ttbr_write, .resetvalue = 0 },
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
+ .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
+ offsetof(CPUARMState, cp15.ttbr1_ns) } },
{ .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
.access = PL1_RW, .writefn = vmsa_tcr_el1_write,
.resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
- .fieldoffset = offsetof(CPUARMState, cp15.c2_control) },
+ .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) },
{ .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
.access = PL1_RW, .type = ARM_CP_NO_MIGRATE, .writefn = vmsa_ttbcr_write,
.resetfn = arm_cp_reset_ignore, .raw_writefn = vmsa_ttbcr_raw_write,
- .fieldoffset = offsetoflow32(CPUARMState, cp15.c2_control) },
- /* 64-bit FAR; this entry also gives us the AArch32 DFAR */
- { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH,
+ .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]),
+ offsetoflow32(CPUARMState, cp15.tcr_el[1])} },
+ { .name = "FAR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
.resetvalue = 0, },
+ { .name = "DFAR", .cp = 15, .opc1 = 0, .crn = 6, .crm = 0, .opc2 = 0,
+ .access = PL1_RW, .resetvalue = 0,
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.dfar_s),
+ offsetof(CPUARMState, cp15.dfar_ns) } },
REGINFO_SENTINEL
};
@@ -1874,15 +1943,18 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
.access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_OVERRIDE,
.resetvalue = 0 },
{ .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
- .access = PL1_RW, .type = ARM_CP_64BIT,
- .fieldoffset = offsetof(CPUARMState, cp15.par_el1), .resetvalue = 0 },
+ .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
+ offsetof(CPUARMState, cp15.par_ns)} },
{ .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
.access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
- .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1),
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
+ offsetof(CPUARMState, cp15.ttbr0_ns) },
.writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore },
{ .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
.access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
- .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1),
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
+ offsetof(CPUARMState, cp15.ttbr1_ns) },
.writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore },
REGINFO_SENTINEL
};
@@ -1911,7 +1983,7 @@ static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri)
{
- if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
+ if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
return CP_ACCESS_TRAP;
}
return CP_ACCESS_OK;
@@ -1929,7 +2001,7 @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
/* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
* SCTLR_EL1.UCI is set.
*/
- if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCI)) {
+ if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCI)) {
return CP_ACCESS_TRAP;
}
return CP_ACCESS_OK;
@@ -2006,7 +2078,7 @@ static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri)
/* We don't implement EL2, so the only control on DC ZVA is the
* bit in the SCTLR which can prohibit access for EL0.
*/
- if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_DZE)) {
+ if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_DZE)) {
return CP_ACCESS_TRAP;
}
return CP_ACCESS_OK;
@@ -2045,6 +2117,24 @@ static void spsel_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
update_spsel(env, val);
}
+static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ ARMCPU *cpu = arm_env_get_cpu(env);
+
+ if (raw_read(env, ri) == value) {
+ /* Skip the TLB flush if nothing actually changed; Linux likes
+ * to do a lot of pointless SCTLR writes.
+ */
+ return;
+ }
+
+ raw_write(env, ri, value);
+ /* ??? Lots of these bits are not implemented. */
+ /* This may enable/disable the MMU, so do a TLB flush. */
+ tlb_flush(CPU(cpu), 1);
+}
+
static const ARMCPRegInfo v8_cp_reginfo[] = {
/* Minimal set of EL0-visible registers. This will need to be expanded
* significantly for system emulation of AArch64 CPUs.
@@ -2216,10 +2306,11 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
{ .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
.type = ARM_CP_NOP, .access = PL1_W },
/* MMU Domain access control / MPU write buffer control */
- { .name = "DACR", .cp = 15,
- .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c3),
- .resetvalue = 0, .writefn = dacr_write, .raw_writefn = raw_write, },
+ { .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
+ .access = PL1_RW, .resetvalue = 0,
+ .writefn = dacr_write, .raw_writefn = raw_write,
+ .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
+ offsetoflow32(CPUARMState, cp15.dacr_ns) } },
{ .name = "ELR_EL1", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_NO_MIGRATE,
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1,
@@ -2289,6 +2380,11 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
.writefn = hcr_write },
+ { .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
+ .access = PL2_RW, .resetvalue = 0,
+ .writefn = dacr_write, .raw_writefn = raw_write,
+ .fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_NO_MIGRATE,
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
@@ -2298,6 +2394,10 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
.type = ARM_CP_NO_MIGRATE,
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
+ { .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
+ .access = PL2_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
{ .name = "FAR_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
@@ -2314,6 +2414,19 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
};
static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
+ { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0,
+ .access = PL3_RW, .raw_writefn = raw_write, .writefn = sctlr_write,
+ .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]) },
+ { .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 0,
+ .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) },
+ { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2,
+ .access = PL3_RW, .writefn = vmsa_tcr_el1_write,
+ .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
+ .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[3]) },
{ .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_NO_MIGRATE,
.opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
@@ -2335,38 +2448,42 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
.access = PL3_RW, .writefn = vbar_write,
.fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]),
.resetvalue = 0 },
+ REGINFO_SENTINEL
+};
+
+static const ARMCPRegInfo el3_cp_reginfo[] = {
{ .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
- .type = ARM_CP_NO_MIGRATE,
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
- .writefn = scr_write },
+ .resetvalue = 0, .writefn = scr_write },
+ { .name = "SCR", .type = ARM_CP_NO_MIGRATE,
+ .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
+ .access = PL3_RW, .fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
+ .resetfn = arm_cp_reset_ignore, .writefn = scr_write },
+ { .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1,
+ .access = PL3_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.sder) },
+ { .name = "SDER",
+ .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 1,
+ .access = PL3_RW, .resetvalue = 0,
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.sder) },
+ /* TODO: Implement NSACR trapping of secure EL1 accesses to EL3 */
+ { .name = "NSACR", .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
+ .access = PL3_W | PL1_R, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.nsacr) },
+ { .name = "MVBAR", .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
+ .access = PL3_RW, .writefn = vbar_write, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.mvbar) },
REGINFO_SENTINEL
};
-static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- ARMCPU *cpu = arm_env_get_cpu(env);
-
- if (raw_read(env, ri) == value) {
- /* Skip the TLB flush if nothing actually changed; Linux likes
- * to do a lot of pointless SCTLR writes.
- */
- return;
- }
-
- raw_write(env, ri, value);
- /* ??? Lots of these bits are not implemented. */
- /* This may enable/disable the MMU, so do a TLB flush. */
- tlb_flush(CPU(cpu), 1);
-}
-
static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri)
{
/* Only accessible in EL0 if SCTLR.UCT is set (and only in AArch64,
* but the AArch32 CTR has its own reginfo struct)
*/
- if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCT)) {
+ if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
return CP_ACCESS_TRAP;
}
return CP_ACCESS_OK;
@@ -2960,7 +3077,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
}
}
if (arm_feature(env, ARM_FEATURE_EL3)) {
- define_arm_cp_regs(cpu, v8_el3_cp_reginfo);
+ if (arm_feature(env, ARM_FEATURE_V8)) {
+ define_arm_cp_regs(cpu, v8_el3_cp_reginfo);
+ }
+ define_arm_cp_regs(cpu, el3_cp_reginfo);
}
if (arm_feature(env, ARM_FEATURE_MPU)) {
/* These are the MPU registers prior to PMSAv6. Any new
@@ -3160,8 +3280,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{
ARMCPRegInfo sctlr = {
.name = "SCTLR", .state = ARM_CP_STATE_BOTH,
- .opc0 = 3, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_sys),
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
+ .access = PL1_RW,
+ .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
+ offsetof(CPUARMState, cp15.sctlr_ns) },
.writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
.raw_writefn = raw_write,
};
@@ -3287,7 +3409,7 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
}
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
- void *opaque, int state,
+ void *opaque, int state, int secstate,
int crm, int opc1, int opc2)
{
/* Private utility function for define_one_arm_cp_reg_with_opaque():
@@ -3296,22 +3418,59 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
uint32_t *key = g_new(uint32_t, 1);
ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
- if (r->state == ARM_CP_STATE_BOTH && state == ARM_CP_STATE_AA32) {
- /* The AArch32 view of a shared register sees the lower 32 bits
- * of a 64 bit backing field. It is not migratable as the AArch64
- * view handles that. AArch64 also handles reset.
- * We assume it is a cp15 register if the .cp field is left unset.
+ int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
+
+ /* Reset the secure state to the specific incoming state. This is
+ * necessary as the register may have been defined with both states.
+ */
+ r2->secure = secstate;
+
+ if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
+ /* Register is banked (using both entries in array).
+ * Overwriting fieldoffset as the array is only used to define
+ * banked registers but later only fieldoffset is used.
*/
- if (r2->cp == 0) {
- r2->cp = 15;
+ r2->fieldoffset = r->bank_fieldoffsets[ns];
+ }
+
+ if (state == ARM_CP_STATE_AA32) {
+ if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
+ /* If the register is banked then we don't need to migrate or
+ * reset the 32-bit instance in certain cases:
+ *
+ * 1) If the register has both 32-bit and 64-bit instances then we
+ * can count on the 64-bit instance taking care of the
+ * non-secure bank.
+ * 2) If ARMv8 is enabled then we can count on a 64-bit version
+ * taking care of the secure bank. This requires that separate
+ * 32 and 64-bit definitions are provided.
+ */
+ if ((r->state == ARM_CP_STATE_BOTH && ns) ||
+ (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
+ r2->type |= ARM_CP_NO_MIGRATE;
+ r2->resetfn = arm_cp_reset_ignore;
+ }
+ } else if ((secstate != r->secure) && !ns) {
+ /* The register is not banked so we only want to allow migration of
+ * the non-secure instance.
+ */
+ r2->type |= ARM_CP_NO_MIGRATE;
+ r2->resetfn = arm_cp_reset_ignore;
}
- r2->type |= ARM_CP_NO_MIGRATE;
- r2->resetfn = arm_cp_reset_ignore;
+
+ if (r->state == ARM_CP_STATE_BOTH) {
+ /* We assume it is a cp15 register if the .cp field is left unset.
+ */
+ if (r2->cp == 0) {
+ r2->cp = 15;
+ }
+
#ifdef HOST_WORDS_BIGENDIAN
- if (r2->fieldoffset) {
- r2->fieldoffset += sizeof(uint32_t);
- }
+ if (r2->fieldoffset) {
+ r2->fieldoffset += sizeof(uint32_t);
+ }
#endif
+ }
}
if (state == ARM_CP_STATE_AA64) {
/* To allow abbreviation of ARMCPRegInfo
@@ -3327,7 +3486,7 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
*key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
r2->opc0, opc1, opc2);
} else {
- *key = ENCODE_CP_REG(r2->cp, is64, r2->crn, crm, opc1, opc2);
+ *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
}
if (opaque) {
r2->opaque = opaque;
@@ -3460,10 +3619,14 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
*/
if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
if (r->access & PL3_R) {
- assert(r->fieldoffset || r->readfn);
+ assert((r->fieldoffset ||
+ (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
+ r->readfn);
}
if (r->access & PL3_W) {
- assert(r->fieldoffset || r->writefn);
+ assert((r->fieldoffset ||
+ (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
+ r->writefn);
}
}
/* Bad type field probably means missing sentinel at end of reg list */
@@ -3476,8 +3639,32 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
continue;
}
- add_cpreg_to_hashtable(cpu, r, opaque, state,
- crm, opc1, opc2);
+ if (state == ARM_CP_STATE_AA32) {
+ /* Under AArch32 CP registers can be common
+ * (same for secure and non-secure world) or banked.
+ */
+ switch (r->secure) {
+ case ARM_CP_SECSTATE_S:
+ case ARM_CP_SECSTATE_NS:
+ add_cpreg_to_hashtable(cpu, r, opaque, state,
+ r->secure, crm, opc1, opc2);
+ break;
+ default:
+ add_cpreg_to_hashtable(cpu, r, opaque, state,
+ ARM_CP_SECSTATE_S,
+ crm, opc1, opc2);
+ add_cpreg_to_hashtable(cpu, r, opaque, state,
+ ARM_CP_SECSTATE_NS,
+ crm, opc1, opc2);
+ break;
+ }
+ } else {
+ /* AArch64 registers get mapped to non-secure instance
+ * of AArch32 */
+ add_cpreg_to_hashtable(cpu, r, opaque, state,
+ ARM_CP_SECSTATE_NS,
+ crm, opc1, opc2);
+ }
}
}
}
@@ -3551,6 +3738,8 @@ uint32_t cpsr_read(CPUARMState *env)
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
{
+ uint32_t changed_daif;
+
if (mask & CPSR_NZCV) {
env->ZF = (~val) & CPSR_Z;
env->NF = val;
@@ -3573,6 +3762,58 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
env->GE = (val >> 16) & 0xf;
}
+ /* In a V7 implementation that includes the security extensions but does
+ * not include Virtualization Extensions the SCR.FW and SCR.AW bits control
+ * whether non-secure software is allowed to change the CPSR_F and CPSR_A
+ * bits respectively.
+ *
+ * In a V8 implementation, it is permitted for privileged software to
+ * change the CPSR A/F bits regardless of the SCR.AW/FW bits.
+ */
+ if (!arm_feature(env, ARM_FEATURE_V8) &&
+ arm_feature(env, ARM_FEATURE_EL3) &&
+ !arm_feature(env, ARM_FEATURE_EL2) &&
+ !arm_is_secure(env)) {
+
+ changed_daif = (env->daif ^ val) & mask;
+
+ if (changed_daif & CPSR_A) {
+ /* Check to see if we are allowed to change the masking of async
+ * abort exceptions from a non-secure state.
+ */
+ if (!(env->cp15.scr_el3 & SCR_AW)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Ignoring attempt to switch CPSR_A flag from "
+ "non-secure world with SCR.AW bit clear\n");
+ mask &= ~CPSR_A;
+ }
+ }
+
+ if (changed_daif & CPSR_F) {
+ /* Check to see if we are allowed to change the masking of FIQ
+ * exceptions from a non-secure state.
+ */
+ if (!(env->cp15.scr_el3 & SCR_FW)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Ignoring attempt to switch CPSR_F flag from "
+ "non-secure world with SCR.FW bit clear\n");
+ mask &= ~CPSR_F;
+ }
+
+ /* Check whether non-maskable FIQ (NMFI) support is enabled.
+ * If this bit is set software is not allowed to mask
+ * FIQs, but is allowed to set CPSR_F to 0.
+ */
+ if ((A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_NMFI) &&
+ (val & CPSR_F)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Ignoring attempt to enable CPSR_F flag "
+ "(non-maskable FIQ [NMFI] support enabled)\n");
+ mask &= ~CPSR_F;
+ }
+ }
+ }
+
env->daif &= ~(CPSR_AIF & mask);
env->daif |= val & CPSR_AIF & mask;
@@ -3761,6 +4002,101 @@ void switch_mode(CPUARMState *env, int mode)
env->spsr = env->banked_spsr[i];
}
+/* Physical Interrupt Target EL Lookup Table
+ *
+ * [ From ARM ARM section G1.13.4 (Table G1-15) ]
+ *
+ * The below multi-dimensional table is used for looking up the target
+ * exception level given numerous condition criteria. Specifically, the
+ * target EL is based on SCR and HCR routing controls as well as the
+ * currently executing EL and secure state.
+ *
+ * Dimensions:
+ * target_el_table[2][2][2][2][2][4]
+ * | | | | | +--- Current EL
+ * | | | | +------ Non-secure(0)/Secure(1)
+ * | | | +--------- HCR mask override
+ * | | +------------ SCR exec state control
+ * | +--------------- SCR mask override
+ * +------------------ 32-bit(0)/64-bit(1) EL3
+ *
+ * The table values are as such:
+ * 0-3 = EL0-EL3
+ * -1 = Cannot occur
+ *
+ * The ARM ARM target EL table includes entries indicating that an "exception
+ * is not taken". The two cases where this is applicable are:
+ * 1) An exception is taken from EL3 but the SCR does not have the exception
+ * routed to EL3.
+ * 2) An exception is taken from EL2 but the HCR does not have the exception
+ * routed to EL2.
+ * In these two cases, the below table contain a target of EL1. This value is
+ * returned as it is expected that the consumer of the table data will check
+ * for "target EL >= current EL" to ensure the exception is not taken.
+ *
+ * SCR HCR
+ * 64 EA AMO From
+ * BIT IRQ IMO Non-secure Secure
+ * EL3 FIQ RW FMO EL0 EL1 EL2 EL3 EL0 EL1 EL2 EL3
+ */
+const int8_t target_el_table[2][2][2][2][2][4] = {
+ {{{{/* 0 0 0 0 */{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },},
+ {/* 0 0 0 1 */{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},},
+ {{/* 0 0 1 0 */{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },},
+ {/* 0 0 1 1 */{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},},},
+ {{{/* 0 1 0 0 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},
+ {/* 0 1 0 1 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},
+ {{/* 0 1 1 0 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},
+ {/* 0 1 1 1 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},},},
+ {{{{/* 1 0 0 0 */{ 1, 1, 2, -1 },{ 1, 1, -1, 1 },},
+ {/* 1 0 0 1 */{ 2, 2, 2, -1 },{ 1, 1, -1, 1 },},},
+ {{/* 1 0 1 0 */{ 1, 1, 1, -1 },{ 1, 1, -1, 1 },},
+ {/* 1 0 1 1 */{ 2, 2, 2, -1 },{ 1, 1, -1, 1 },},},},
+ {{{/* 1 1 0 0 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},
+ {/* 1 1 0 1 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},},
+ {{/* 1 1 1 0 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},
+ {/* 1 1 1 1 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},},},},
+};
+
+/*
+ * Determine the target EL for physical exceptions
+ */
+static inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
+ uint32_t cur_el, bool secure)
+{
+ CPUARMState *env = cs->env_ptr;
+ int rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
+ int scr;
+ int hcr;
+ int target_el;
+ int is64 = arm_el_is_aa64(env, 3);
+
+ switch (excp_idx) {
+ case EXCP_IRQ:
+ scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
+ hcr = ((env->cp15.hcr_el2 & HCR_IMO) == HCR_IMO);
+ break;
+ case EXCP_FIQ:
+ scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
+ hcr = ((env->cp15.hcr_el2 & HCR_FMO) == HCR_FMO);
+ break;
+ default:
+ scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
+ hcr = ((env->cp15.hcr_el2 & HCR_AMO) == HCR_AMO);
+ break;
+ };
+
+ /* If HCR.TGE is set then HCR is treated as being 1 */
+ hcr |= ((env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE);
+
+ /* Perform a table-lookup for the target EL given the current state */
+ target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el];
+
+ assert(target_el > 0);
+
+ return target_el;
+}
+
/*
* Determine the target EL for a given exception type.
*/
@@ -3770,13 +4106,7 @@ unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
CPUARMState *env = &cpu->env;
unsigned int cur_el = arm_current_el(env);
unsigned int target_el;
- /* FIXME: Use actual secure state. */
- bool secure = false;
-
- if (!env->aarch64) {
- /* TODO: Add EL2 and 3 exception handling for AArch32. */
- return 1;
- }
+ bool secure = arm_is_secure(env);
switch (excp_idx) {
case EXCP_HVC:
@@ -3788,19 +4118,8 @@ unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
break;
case EXCP_FIQ:
case EXCP_IRQ:
- {
- const uint64_t hcr_mask = excp_idx == EXCP_FIQ ? HCR_FMO : HCR_IMO;
- const uint32_t scr_mask = excp_idx == EXCP_FIQ ? SCR_FIQ : SCR_IRQ;
-
- target_el = 1;
- if (!secure && (env->cp15.hcr_el2 & hcr_mask)) {
- target_el = 2;
- }
- if (env->cp15.scr_el3 & scr_mask) {
- target_el = 3;
- }
+ target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
break;
- }
case EXCP_VIRQ:
case EXCP_VFIQ:
target_el = 1;
@@ -4055,22 +4374,20 @@ void arm_cpu_do_interrupt(CPUState *cs)
env->exception.fsr = 2;
/* Fall through to prefetch abort. */
case EXCP_PREFETCH_ABORT:
- env->cp15.ifsr_el2 = env->exception.fsr;
- env->cp15.far_el[1] = deposit64(env->cp15.far_el[1], 32, 32,
- env->exception.vaddress);
+ A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr);
+ A32_BANKED_CURRENT_REG_SET(env, ifar, env->exception.vaddress);
qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
- env->cp15.ifsr_el2, (uint32_t)env->exception.vaddress);
+ env->exception.fsr, (uint32_t)env->exception.vaddress);
new_mode = ARM_CPU_MODE_ABT;
addr = 0x0c;
mask = CPSR_A | CPSR_I;
offset = 4;
break;
case EXCP_DATA_ABORT:
- env->cp15.esr_el[1] = env->exception.fsr;
- env->cp15.far_el[1] = deposit64(env->cp15.far_el[1], 0, 32,
- env->exception.vaddress);
+ A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);
+ A32_BANKED_CURRENT_REG_SET(env, dfar, env->exception.vaddress);
qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
- (uint32_t)env->cp15.esr_el[1],
+ env->exception.fsr,
(uint32_t)env->exception.vaddress);
new_mode = ARM_CPU_MODE_ABT;
addr = 0x10;
@@ -4083,12 +4400,21 @@ void arm_cpu_do_interrupt(CPUState *cs)
/* Disable IRQ and imprecise data aborts. */
mask = CPSR_A | CPSR_I;
offset = 4;
+ if (env->cp15.scr_el3 & SCR_IRQ) {
+ /* IRQ routed to monitor mode */
+ new_mode = ARM_CPU_MODE_MON;
+ mask |= CPSR_F;
+ }
break;
case EXCP_FIQ:
new_mode = ARM_CPU_MODE_FIQ;
addr = 0x1c;
/* Disable FIQ, IRQ and imprecise data aborts. */
mask = CPSR_A | CPSR_I | CPSR_F;
+ if (env->cp15.scr_el3 & SCR_FIQ) {
+ /* FIQ routed to monitor mode */
+ new_mode = ARM_CPU_MODE_MON;
+ }
offset = 4;
break;
case EXCP_SMC:
@@ -4101,19 +4427,19 @@ void arm_cpu_do_interrupt(CPUState *cs)
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
return; /* Never happens. Keep compiler happy. */
}
- /* High vectors. */
- if (env->cp15.c1_sys & SCTLR_V) {
- /* when enabled, base address cannot be remapped. */
+
+ if (new_mode == ARM_CPU_MODE_MON) {
+ addr += env->cp15.mvbar;
+ } else if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
+ /* High vectors. When enabled, base address cannot be remapped. */
addr += 0xffff0000;
} else {
/* ARM v7 architectures provide a vector base address register to remap
* the interrupt vector table.
- * This register is only followed in non-monitor mode, and has a secure
- * and un-secure copy. Since the cpu is always in a un-secure operation
- * and is never in monitor mode this feature is always active.
+ * This register is only followed in non-monitor mode, and is banked.
* Note: only bits 31:5 are valid.
*/
- addr += env->cp15.vbar_el[1];
+ addr += A32_BANKED_CURRENT_REG_GET(env, vbar);
}
if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
@@ -4134,7 +4460,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
/* this is a lie, as the was no c1_sys on V4T/V5, but who cares
* and we should just guard the thumb mode on V4 */
if (arm_feature(env, ARM_FEATURE_V4T)) {
- env->thumb = (env->cp15.c1_sys & SCTLR_TE) != 0;
+ env->thumb = (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0;
}
env->regs[14] = env->regs[15] + offset;
env->regs[15] = addr;
@@ -4165,7 +4491,7 @@ static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
}
if (access_type == 1)
return 0;
- switch (env->cp15.c1_sys & (SCTLR_S | SCTLR_R)) {
+ switch (A32_BANKED_CURRENT_REG_GET(env, sctlr) & (SCTLR_S | SCTLR_R)) {
case SCTLR_S:
return is_user ? 0 : PAGE_READ;
case SCTLR_R:
@@ -4200,18 +4526,25 @@ static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
static bool get_level1_table_address(CPUARMState *env, uint32_t *table,
uint32_t address)
{
- if (address & env->cp15.c2_mask) {
- if ((env->cp15.c2_control & TTBCR_PD1)) {
+ /* Get the TCR bank based on our security state */
+ TCR *tcr = &env->cp15.tcr_el[arm_is_secure(env) ? 3 : 1];
+
+ /* We only get here if EL1 is running in AArch32. If EL3 is running in
+ * AArch32 there is a secure and non-secure instance of the translation
+ * table registers.
+ */
+ if (address & tcr->mask) {
+ if (tcr->raw_tcr & TTBCR_PD1) {
/* Translation table walk disabled for TTBR1 */
return false;
}
- *table = env->cp15.ttbr1_el1 & 0xffffc000;
+ *table = A32_BANKED_CURRENT_REG_GET(env, ttbr1) & 0xffffc000;
} else {
- if ((env->cp15.c2_control & TTBCR_PD0)) {
+ if (tcr->raw_tcr & TTBCR_PD0) {
/* Translation table walk disabled for TTBR0 */
return false;
}
- *table = env->cp15.ttbr0_el1 & env->cp15.c2_base_mask;
+ *table = A32_BANKED_CURRENT_REG_GET(env, ttbr0) & tcr->base_mask;
}
*table |= (address >> 18) & 0x3ffc;
return true;
@@ -4241,7 +4574,7 @@ static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type,
desc = ldl_phys(cs->as, table);
type = (desc & 3);
domain = (desc >> 5) & 0x0f;
- domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
+ domain_prot = (A32_BANKED_CURRENT_REG_GET(env, dacr) >> (domain * 2)) & 3;
if (type == 0) {
/* Section translation fault. */
code = 5;
@@ -4353,7 +4686,7 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
/* Page or Section. */
domain = (desc >> 5) & 0x0f;
}
- domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
+ domain_prot = (A32_BANKED_CURRENT_REG_GET(env, dacr) >> (domain * 2)) & 3;
if (domain_prot == 0 || domain_prot == 2) {
if (type != 1) {
code = 9; /* Section domain fault. */
@@ -4414,7 +4747,8 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
goto do_fault;
/* The simplified model uses AP[0] as an access control bit. */
- if ((env->cp15.c1_sys & SCTLR_AFE) && (ap & 1) == 0) {
+ if ((A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_AFE)
+ && (ap & 1) == 0) {
/* Access flag fault. */
code = (code == 15) ? 6 : 3;
goto do_fault;
@@ -4464,13 +4798,14 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
int32_t granule_sz = 9;
int32_t va_size = 32;
int32_t tbi = 0;
+ TCR *tcr = &env->cp15.tcr_el[arm_is_secure(env) ? 3 : 1];
if (arm_el_is_aa64(env, 1)) {
va_size = 64;
if (extract64(address, 55, 1))
- tbi = extract64(env->cp15.c2_control, 38, 1);
+ tbi = extract64(tcr->raw_tcr, 38, 1);
else
- tbi = extract64(env->cp15.c2_control, 37, 1);
+ tbi = extract64(tcr->raw_tcr, 37, 1);
tbi *= 8;
}
@@ -4479,12 +4814,12 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
* This is a Non-secure PL0/1 stage 1 translation, so controlled by
* TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:
*/
- uint32_t t0sz = extract32(env->cp15.c2_control, 0, 6);
+ uint32_t t0sz = extract32(tcr->raw_tcr, 0, 6);
if (arm_el_is_aa64(env, 1)) {
t0sz = MIN(t0sz, 39);
t0sz = MAX(t0sz, 16);
}
- uint32_t t1sz = extract32(env->cp15.c2_control, 16, 6);
+ uint32_t t1sz = extract32(tcr->raw_tcr, 16, 6);
if (arm_el_is_aa64(env, 1)) {
t1sz = MIN(t1sz, 39);
t1sz = MAX(t1sz, 16);
@@ -4515,11 +4850,11 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
* we will always flush the TLB any time the ASID is changed).
*/
if (ttbr_select == 0) {
- ttbr = env->cp15.ttbr0_el1;
- epd = extract32(env->cp15.c2_control, 7, 1);
+ ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr0);
+ epd = extract32(tcr->raw_tcr, 7, 1);
tsz = t0sz;
- tg = extract32(env->cp15.c2_control, 14, 2);
+ tg = extract32(tcr->raw_tcr, 14, 2);
if (tg == 1) { /* 64KB pages */
granule_sz = 13;
}
@@ -4527,11 +4862,11 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
granule_sz = 11;
}
} else {
- ttbr = env->cp15.ttbr1_el1;
- epd = extract32(env->cp15.c2_control, 23, 1);
+ ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr1);
+ epd = extract32(tcr->raw_tcr, 23, 1);
tsz = t1sz;
- tg = extract32(env->cp15.c2_control, 30, 2);
+ tg = extract32(tcr->raw_tcr, 30, 2);
if (tg == 3) { /* 64KB pages */
granule_sz = 13;
}
@@ -4747,11 +5082,17 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address,
hwaddr *phys_ptr, int *prot,
target_ulong *page_size)
{
+ /* This is not entirely correct as get_phys_addr() can also be called
+ * from ats_write() for an address translation of a specific regime.
+ */
+ uint32_t sctlr = A32_BANKED_CURRENT_REG_GET(env, sctlr);
+
/* Fast Context Switch Extension. */
- if (address < 0x02000000)
- address += env->cp15.c13_fcse;
+ if (address < 0x02000000) {
+ address += A32_BANKED_CURRENT_REG_GET(env, fcseidr);
+ }
- if ((env->cp15.c1_sys & SCTLR_M) == 0) {
+ if ((sctlr & SCTLR_M) == 0) {
/* MMU/MPU disabled. */
*phys_ptr = address;
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
@@ -4764,7 +5105,7 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address,
} else if (extended_addresses_enabled(env)) {
return get_phys_addr_lpae(env, address, access_type, is_user, phys_ptr,
prot, page_size);
- } else if (env->cp15.c1_sys & SCTLR_XP) {
+ } else if (sctlr & SCTLR_XP) {
return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
prot, page_size);
} else {
diff --git a/target-arm/internals.h b/target-arm/internals.h
index 2dff4ffb19..bb171a73bd 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -153,9 +153,9 @@ static inline void update_spsel(CPUARMState *env, uint32_t imm)
*/
static inline bool extended_addresses_enabled(CPUARMState *env)
{
- return arm_el_is_aa64(env, 1)
- || ((arm_feature(env, ARM_FEATURE_LPAE)
- && (env->cp15.c2_control & TTBCR_EAE)));
+ TCR *tcr = &env->cp15.tcr_el[arm_is_secure(env) ? 3 : 1];
+ return arm_el_is_aa64(env, 1) ||
+ (arm_feature(env, ARM_FEATURE_LPAE) && (tcr->raw_tcr & TTBCR_EAE));
}
/* Valid Syndrome Register EC field values */
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 319784d689..4d81f3d765 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -21,6 +21,7 @@
#include "sysemu/kvm.h"
#include "kvm_arm.h"
#include "cpu.h"
+#include "internals.h"
#include "hw/arm/arm.h"
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
@@ -279,6 +280,94 @@ void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
memory_region_ref(kd->mr);
}
+static int compare_u64(const void *a, const void *b)
+{
+ if (*(uint64_t *)a > *(uint64_t *)b) {
+ return 1;
+ }
+ if (*(uint64_t *)a < *(uint64_t *)b) {
+ return -1;
+ }
+ return 0;
+}
+
+/* Initialize the CPUState's cpreg list according to the kernel's
+ * definition of what CPU registers it knows about (and throw away
+ * the previous TCG-created cpreg list).
+ */
+int kvm_arm_init_cpreg_list(ARMCPU *cpu)
+{
+ struct kvm_reg_list rl;
+ struct kvm_reg_list *rlp;
+ int i, ret, arraylen;
+ CPUState *cs = CPU(cpu);
+
+ rl.n = 0;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, &rl);
+ if (ret != -E2BIG) {
+ return ret;
+ }
+ rlp = g_malloc(sizeof(struct kvm_reg_list) + rl.n * sizeof(uint64_t));
+ rlp->n = rl.n;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, rlp);
+ if (ret) {
+ goto out;
+ }
+ /* Sort the list we get back from the kernel, since cpreg_tuples
+ * must be in strictly ascending order.
+ */
+ qsort(&rlp->reg, rlp->n, sizeof(rlp->reg[0]), compare_u64);
+
+ for (i = 0, arraylen = 0; i < rlp->n; i++) {
+ if (!kvm_arm_reg_syncs_via_cpreg_list(rlp->reg[i])) {
+ continue;
+ }
+ switch (rlp->reg[i] & KVM_REG_SIZE_MASK) {
+ case KVM_REG_SIZE_U32:
+ case KVM_REG_SIZE_U64:
+ break;
+ default:
+ fprintf(stderr, "Can't handle size of register in kernel list\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ arraylen++;
+ }
+
+ cpu->cpreg_indexes = g_renew(uint64_t, cpu->cpreg_indexes, arraylen);
+ cpu->cpreg_values = g_renew(uint64_t, cpu->cpreg_values, arraylen);
+ cpu->cpreg_vmstate_indexes = g_renew(uint64_t, cpu->cpreg_vmstate_indexes,
+ arraylen);
+ cpu->cpreg_vmstate_values = g_renew(uint64_t, cpu->cpreg_vmstate_values,
+ arraylen);
+ cpu->cpreg_array_len = arraylen;
+ cpu->cpreg_vmstate_array_len = arraylen;
+
+ for (i = 0, arraylen = 0; i < rlp->n; i++) {
+ uint64_t regidx = rlp->reg[i];
+ if (!kvm_arm_reg_syncs_via_cpreg_list(regidx)) {
+ continue;
+ }
+ cpu->cpreg_indexes[arraylen] = regidx;
+ arraylen++;
+ }
+ assert(cpu->cpreg_array_len == arraylen);
+
+ if (!write_kvmstate_to_list(cpu)) {
+ /* Shouldn't happen unless kernel is inconsistent about
+ * what registers exist.
+ */
+ fprintf(stderr, "Initial read of kernel register state failed\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+out:
+ g_free(rlp);
+ return ret;
+}
+
bool write_kvmstate_to_list(ARMCPU *cpu)
{
CPUState *cs = CPU(cpu);
@@ -351,6 +440,24 @@ bool write_list_to_kvmstate(ARMCPU *cpu)
return ok;
}
+void kvm_arm_reset_vcpu(ARMCPU *cpu)
+{
+ int ret;
+
+ /* Re-init VCPU so that all registers are set to
+ * their respective reset values.
+ */
+ ret = kvm_arm_vcpu_init(CPU(cpu));
+ if (ret < 0) {
+ fprintf(stderr, "kvm_arm_vcpu_init failed: %s\n", strerror(-ret));
+ abort();
+ }
+ if (!write_kvmstate_to_list(cpu)) {
+ fprintf(stderr, "write_kvmstate_to_list failed\n");
+ abort();
+ }
+}
+
void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
{
}
diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c
index 5ec4eb1f32..94030d1acb 100644
--- a/target-arm/kvm32.c
+++ b/target-arm/kvm32.c
@@ -51,17 +51,17 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
struct kvm_one_reg idregs[] = {
{
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
- | ENCODE_CP_REG(15, 0, 0, 0, 0, 0),
+ | ENCODE_CP_REG(15, 0, 0, 0, 0, 0, 0),
.addr = (uintptr_t)&midr,
},
{
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
- | ENCODE_CP_REG(15, 0, 0, 1, 0, 0),
+ | ENCODE_CP_REG(15, 0, 0, 0, 1, 0, 0),
.addr = (uintptr_t)&id_pfr0,
},
{
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
- | ENCODE_CP_REG(15, 0, 0, 2, 0, 0),
+ | ENCODE_CP_REG(15, 0, 0, 0, 2, 0, 0),
.addr = (uintptr_t)&id_isar0,
},
{
@@ -138,7 +138,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
return true;
}
-static bool reg_syncs_via_tuple_list(uint64_t regidx)
+bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
{
/* Return true if the regidx is a register we should synchronize
* via the cpreg_tuples array (ie is not a core reg we sync by
@@ -153,24 +153,11 @@ static bool reg_syncs_via_tuple_list(uint64_t regidx)
}
}
-static int compare_u64(const void *a, const void *b)
-{
- if (*(uint64_t *)a > *(uint64_t *)b) {
- return 1;
- }
- if (*(uint64_t *)a < *(uint64_t *)b) {
- return -1;
- }
- return 0;
-}
-
int kvm_arch_init_vcpu(CPUState *cs)
{
- int i, ret, arraylen;
+ int ret;
uint64_t v;
struct kvm_one_reg r;
- struct kvm_reg_list rl;
- struct kvm_reg_list *rlp;
ARMCPU *cpu = ARM_CPU(cs);
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
@@ -206,73 +193,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
return -EINVAL;
}
- /* Populate the cpreg list based on the kernel's idea
- * of what registers exist (and throw away the TCG-created list).
- */
- rl.n = 0;
- ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, &rl);
- if (ret != -E2BIG) {
- return ret;
- }
- rlp = g_malloc(sizeof(struct kvm_reg_list) + rl.n * sizeof(uint64_t));
- rlp->n = rl.n;
- ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, rlp);
- if (ret) {
- goto out;
- }
- /* Sort the list we get back from the kernel, since cpreg_tuples
- * must be in strictly ascending order.
- */
- qsort(&rlp->reg, rlp->n, sizeof(rlp->reg[0]), compare_u64);
-
- for (i = 0, arraylen = 0; i < rlp->n; i++) {
- if (!reg_syncs_via_tuple_list(rlp->reg[i])) {
- continue;
- }
- switch (rlp->reg[i] & KVM_REG_SIZE_MASK) {
- case KVM_REG_SIZE_U32:
- case KVM_REG_SIZE_U64:
- break;
- default:
- fprintf(stderr, "Can't handle size of register in kernel list\n");
- ret = -EINVAL;
- goto out;
- }
-
- arraylen++;
- }
-
- cpu->cpreg_indexes = g_renew(uint64_t, cpu->cpreg_indexes, arraylen);
- cpu->cpreg_values = g_renew(uint64_t, cpu->cpreg_values, arraylen);
- cpu->cpreg_vmstate_indexes = g_renew(uint64_t, cpu->cpreg_vmstate_indexes,
- arraylen);
- cpu->cpreg_vmstate_values = g_renew(uint64_t, cpu->cpreg_vmstate_values,
- arraylen);
- cpu->cpreg_array_len = arraylen;
- cpu->cpreg_vmstate_array_len = arraylen;
-
- for (i = 0, arraylen = 0; i < rlp->n; i++) {
- uint64_t regidx = rlp->reg[i];
- if (!reg_syncs_via_tuple_list(regidx)) {
- continue;
- }
- cpu->cpreg_indexes[arraylen] = regidx;
- arraylen++;
- }
- assert(cpu->cpreg_array_len == arraylen);
-
- if (!write_kvmstate_to_list(cpu)) {
- /* Shouldn't happen unless kernel is inconsistent about
- * what registers exist.
- */
- fprintf(stderr, "Initial read of kernel register state failed\n");
- ret = -EINVAL;
- goto out;
- }
-
-out:
- g_free(rlp);
- return ret;
+ return kvm_arm_init_cpreg_list(cpu);
}
typedef struct Reg {
@@ -508,12 +429,3 @@ int kvm_arch_get_registers(CPUState *cs)
return 0;
}
-
-void kvm_arm_reset_vcpu(ARMCPU *cpu)
-{
- /* Re-init VCPU so that all registers are set to
- * their respective reset values.
- */
- kvm_arm_vcpu_init(CPU(cpu));
- write_kvmstate_to_list(cpu);
-}
diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c
index c615286158..ba16821737 100644
--- a/target-arm/kvm64.c
+++ b/target-arm/kvm64.c
@@ -103,9 +103,21 @@ int kvm_arch_init_vcpu(CPUState *cs)
return ret;
}
- /* TODO : support for save/restore/reset of system regs via tuple list */
+ return kvm_arm_init_cpreg_list(cpu);
+}
- return 0;
+bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
+{
+ /* Return true if the regidx is a register we should synchronize
+ * via the cpreg_tuples array (ie is not a core reg we sync by
+ * hand in kvm_arch_get/put_registers())
+ */
+ switch (regidx & KVM_REG_ARM_COPROC_MASK) {
+ case KVM_REG_ARM_CORE:
+ return false;
+ default:
+ return true;
+ }
}
#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
@@ -260,11 +272,3 @@ int kvm_arch_get_registers(CPUState *cs)
/* TODO: other registers */
return ret;
}
-
-void kvm_arm_reset_vcpu(ARMCPU *cpu)
-{
- /* Re-init VCPU so that all registers are set to
- * their respective reset values.
- */
- kvm_arm_vcpu_init(CPU(cpu));
-}
diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h
index af93105517..455dea3f3f 100644
--- a/target-arm/kvm_arm.h
+++ b/target-arm/kvm_arm.h
@@ -47,6 +47,28 @@ void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
uint64_t attr, int dev_fd);
/**
+ * kvm_arm_init_cpreg_list:
+ * @cs: CPUState
+ *
+ * Initialize the CPUState's cpreg list according to the kernel's
+ * definition of what CPU registers it knows about (and throw away
+ * the previous TCG-created cpreg list).
+ *
+ * Returns: 0 if success, else < 0 error code
+ */
+int kvm_arm_init_cpreg_list(ARMCPU *cpu);
+
+/**
+ * kvm_arm_reg_syncs_via_cpreg_list
+ * regidx: KVM register index
+ *
+ * Return true if this KVM register should be synchronized via the
+ * cpreg list of arbitrary system registers, false if it is synchronized
+ * by hand using code in kvm_arch_get/put_registers().
+ */
+bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx);
+
+/**
* write_list_to_kvmstate:
* @cpu: ARMCPU
*
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 6437690af7..c29e7a2ac1 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -127,6 +127,13 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size)
CPUARMState *env = &cpu->env;
uint32_t val = qemu_get_be32(f);
+ env->aarch64 = ((val & PSTATE_nRW) == 0);
+
+ if (is_a64(env)) {
+ pstate_write(env, val);
+ return 0;
+ }
+
/* Avoid mode switch when restoring CPSR */
env->uncached_cpsr = val & CPSR_M;
cpsr_write(env, val, 0xffffffff);
@@ -137,8 +144,15 @@ static void put_cpsr(QEMUFile *f, void *opaque, size_t size)
{
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
+ uint32_t val;
+
+ if (is_a64(env)) {
+ val = pstate_read(env);
+ } else {
+ val = cpsr_read(env);
+ }
- qemu_put_be32(f, cpsr_read(env));
+ qemu_put_be32(f, val);
}
static const VMStateInfo vmstate_cpsr = {
@@ -222,12 +236,14 @@ static int cpu_post_load(void *opaque, int version_id)
const VMStateDescription vmstate_arm_cpu = {
.name = "cpu",
- .version_id = 21,
- .minimum_version_id = 21,
+ .version_id = 22,
+ .minimum_version_id = 22,
.pre_save = cpu_pre_save,
.post_load = cpu_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16),
+ VMSTATE_UINT64_ARRAY(env.xregs, ARMCPU, 32),
+ VMSTATE_UINT64(env.pc, ARMCPU),
{
.name = "cpsr",
.version_id = 0,
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 62012c3a6e..2bed914770 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -361,7 +361,7 @@ void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
* Note that SPSel is never OK from EL0; we rely on handle_msr_i()
* to catch that case at translate time.
*/
- if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
+ if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
raise_exception(env, EXCP_UDEF);
}
@@ -575,7 +575,7 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
* short descriptor format (in which case it holds both PROCID and ASID),
* since we don't implement the optional v7 context ID masking.
*/
- contextidr = extract64(env->cp15.contextidr_el1, 0, 32);
+ contextidr = extract64(env->cp15.contextidr_el[1], 0, 32);
switch (bt) {
case 3: /* linked context ID match */
diff --git a/target-arm/translate.c b/target-arm/translate.c
index af5156857e..b52c758698 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7091,7 +7091,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
rt = (insn >> 12) & 0xf;
ri = get_arm_cp_reginfo(s->cp_regs,
- ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
+ ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
if (ri) {
/* Check access permissions */
if (!cp_access_ok(s->current_el, ri, isread)) {
@@ -7281,12 +7281,16 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
*/
if (is64) {
qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
- "64 bit system register cp:%d opc1: %d crm:%d\n",
- isread ? "read" : "write", cpnum, opc1, crm);
+ "64 bit system register cp:%d opc1: %d crm:%d "
+ "(%s)\n",
+ isread ? "read" : "write", cpnum, opc1, crm,
+ s->ns ? "non-secure" : "secure");
} else {
qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
- "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
- isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
+ "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
+ "(%s)\n",
+ isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
+ s->ns ? "non-secure" : "secure");
}
return 1;
@@ -11031,6 +11035,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
#if !defined(CONFIG_USER_ONLY)
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
#endif
+ dc->ns = ARM_TBFLAG_NS(tb->flags);
dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
diff --git a/target-arm/translate.h b/target-arm/translate.h
index 41a907157f..f6ee7892ba 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -20,6 +20,7 @@ typedef struct DisasContext {
#if !defined(CONFIG_USER_ONLY)
int user;
#endif
+ bool ns; /* Use non-secure CPREG bank on access */
bool cpacr_fpen; /* FP enabled via CPACR.FPEN */
bool vfp_enabled; /* FP enabled via FPSCR.EN */
int vec_len;
diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c
index 1d4eee3974..30d34d5aee 100644
--- a/target-i386/fpu_helper.c
+++ b/target-i386/fpu_helper.c
@@ -251,16 +251,34 @@ int32_t helper_fist_ST0(CPUX86State *env)
int32_t helper_fistl_ST0(CPUX86State *env)
{
int32_t val;
+ signed char old_exp_flags;
+
+ old_exp_flags = get_float_exception_flags(&env->fp_status);
+ set_float_exception_flags(0, &env->fp_status);
val = floatx80_to_int32(ST0, &env->fp_status);
+ if (get_float_exception_flags(&env->fp_status) & float_flag_invalid) {
+ val = 0x80000000;
+ }
+ set_float_exception_flags(get_float_exception_flags(&env->fp_status)
+ | old_exp_flags, &env->fp_status);
return val;
}
int64_t helper_fistll_ST0(CPUX86State *env)
{
int64_t val;
+ signed char old_exp_flags;
- val = floatx80_to_int64(ST0, &env->fp_status);
+ old_exp_flags = get_float_exception_flags(&env->fp_status);
+ set_float_exception_flags(0, &env->fp_status);
+
+ val = floatx80_to_int32(ST0, &env->fp_status);
+ if (get_float_exception_flags(&env->fp_status) & float_flag_invalid) {
+ val = 0x8000000000000000ULL;
+ }
+ set_float_exception_flags(get_float_exception_flags(&env->fp_status)
+ | old_exp_flags, &env->fp_status);
return val;
}
@@ -621,7 +639,7 @@ void helper_fbld_ST0(CPUX86State *env, target_ulong ptr)
}
tmp = int64_to_floatx80(val, &env->fp_status);
if (cpu_ldub_data(env, ptr + 9) & 0x80) {
- floatx80_chs(tmp);
+ tmp = floatx80_chs(tmp);
}
fpush(env);
ST0 = tmp;
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 31a9f74467..fc75da7fc0 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -115,6 +115,7 @@ typedef struct DisasContext {
int tf; /* TF cpu flag */
int singlestep_enabled; /* "hardware" single step enabled */
int jmp_opt; /* use direct block chaining for direct jumps */
+ int repz_opt; /* optimize jumps within repz instructions */
int mem_index; /* select memory access functions */
uint64_t flags; /* all execution flags */
struct TranslationBlock *tb;
@@ -1215,7 +1216,7 @@ static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
gen_op_add_reg_im(s->aflag, R_ECX, -1); \
/* a loop would cause two single step exceptions if ECX = 1 \
before rep string_insn */ \
- if (!s->jmp_opt) \
+ if (s->repz_opt) \
gen_op_jz_ecx(s->aflag, l2); \
gen_jmp(s, cur_eip); \
}
@@ -1233,7 +1234,7 @@ static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
gen_op_add_reg_im(s->aflag, R_ECX, -1); \
gen_update_cc_op(s); \
gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
- if (!s->jmp_opt) \
+ if (s->repz_opt) \
gen_op_jz_ecx(s->aflag, l2); \
gen_jmp(s, cur_eip); \
}
@@ -7951,6 +7952,17 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
|| (flags & HF_SOFTMMU_MASK)
#endif
);
+ /* Do not optimize repz jumps at all in icount mode, because
+ rep movsS instructions are execured with different paths
+ in !repz_opt and repz_opt modes. The first one was used
+ always except single step mode. And this setting
+ disables jumps optimization and control paths become
+ equivalent in run and single step modes.
+ Now there will be no jump optimization for repz in
+ record/replay modes and there will always be an
+ additional step for ecx=0 when icount is enabled.
+ */
+ dc->repz_opt = !dc->jmp_opt && !use_icount;
#if 0
/* check addseg logic */
if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 09aec7b42e..96a4f22734 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -648,7 +648,7 @@ static void do_ext_interrupt(CPUS390XState *env)
cpu_abort(CPU(cpu), "Ext int w/o ext mask\n");
}
- if (env->ext_index < 0 || env->ext_index > MAX_EXT_QUEUE) {
+ if (env->ext_index < 0 || env->ext_index >= MAX_EXT_QUEUE) {
cpu_abort(CPU(cpu), "Ext queue overrun: %d\n", env->ext_index);
}
@@ -696,7 +696,7 @@ static void do_io_interrupt(CPUS390XState *env)
if (env->io_index[isc] < 0) {
continue;
}
- if (env->io_index[isc] > MAX_IO_QUEUE) {
+ if (env->io_index[isc] >= MAX_IO_QUEUE) {
cpu_abort(CPU(cpu), "I/O queue overrun for isc %d: %d\n",
isc, env->io_index[isc]);
}
@@ -754,7 +754,7 @@ static void do_mchk_interrupt(CPUS390XState *env)
cpu_abort(CPU(cpu), "Machine check w/o mchk mask\n");
}
- if (env->mchk_index < 0 || env->mchk_index > MAX_MCHK_QUEUE) {
+ if (env->mchk_index < 0 || env->mchk_index >= MAX_MCHK_QUEUE) {
cpu_abort(CPU(cpu), "Mchk queue overrun: %d\n", env->mchk_index);
}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 1dcdaa6662..f3f8f2c2ca 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -106,7 +106,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
static int cap_sync_regs;
static int cap_async_pf;
-static void *legacy_s390_alloc(size_t size);
+static void *legacy_s390_alloc(size_t size, uint64_t *align);
static int kvm_s390_check_clear_cmma(KVMState *s)
{
@@ -404,7 +404,7 @@ int kvm_arch_get_registers(CPUState *cs)
* to grow. We also have to use MAP parameters that avoid
* read-only mapping of guest pages.
*/
-static void *legacy_s390_alloc(size_t size, , uint64_t *align)
+static void *legacy_s390_alloc(size_t size, uint64_t *align)
{
void *mem;
diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c
index 7bf041afb9..abe16fa7e6 100644
--- a/target-tricore/cpu.c
+++ b/target-tricore/cpu.c
@@ -63,8 +63,17 @@ static bool tricore_cpu_has_work(CPUState *cs)
static void tricore_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
+ TriCoreCPU *cpu = TRICORE_CPU(dev);
TriCoreCPUClass *tcc = TRICORE_CPU_GET_CLASS(dev);
+ CPUTriCoreState *env = &cpu->env;
+ /* Some features automatically imply others */
+ if (tricore_feature(env, TRICORE_FEATURE_16)) {
+ set_feature(env, TRICORE_FEATURE_131);
+ }
+ if (tricore_feature(env, TRICORE_FEATURE_131)) {
+ set_feature(env, TRICORE_FEATURE_13);
+ }
cpu_reset(cs);
qemu_init_vcpu(cs);
diff --git a/target-tricore/csfr.def b/target-tricore/csfr.def
new file mode 100644
index 0000000000..5b219b4bf1
--- /dev/null
+++ b/target-tricore/csfr.def
@@ -0,0 +1,124 @@
+/* A(ll) access permited
+ R(ead only) access
+ E(nd init protected) access
+
+ A|R|E(offset, register, feature introducing reg)
+
+ NOTE: PSW is handled as a special case in gen_mtcr/mfcr */
+
+A(0xfe00, PCXI, TRICORE_FEATURE_13)
+A(0xfe08, PC, TRICORE_FEATURE_13)
+A(0xfe14, SYSCON, TRICORE_FEATURE_13)
+R(0xfe18, CPU_ID, TRICORE_FEATURE_13)
+E(0xfe20, BIV, TRICORE_FEATURE_13)
+E(0xfe24, BTV, TRICORE_FEATURE_13)
+E(0xfe28, ISP, TRICORE_FEATURE_13)
+A(0xfe2c, ICR, TRICORE_FEATURE_13)
+A(0xfe38, FCX, TRICORE_FEATURE_13)
+A(0xfe3c, LCX, TRICORE_FEATURE_13)
+E(0x9400, COMPAT, TRICORE_FEATURE_131)
+/* memory protection register */
+A(0xC000, DPR0_0L, TRICORE_FEATURE_13)
+A(0xC004, DPR0_0U, TRICORE_FEATURE_13)
+A(0xC008, DPR0_1L, TRICORE_FEATURE_13)
+A(0xC00C, DPR0_1U, TRICORE_FEATURE_13)
+A(0xC010, DPR0_2L, TRICORE_FEATURE_13)
+A(0xC014, DPR0_2U, TRICORE_FEATURE_13)
+A(0xC018, DPR0_3L, TRICORE_FEATURE_13)
+A(0xC01C, DPR0_3U, TRICORE_FEATURE_13)
+A(0xC400, DPR1_0L, TRICORE_FEATURE_13)
+A(0xC404, DPR1_0U, TRICORE_FEATURE_13)
+A(0xC408, DPR1_1L, TRICORE_FEATURE_13)
+A(0xC40C, DPR1_1U, TRICORE_FEATURE_13)
+A(0xC410, DPR1_2L, TRICORE_FEATURE_13)
+A(0xC414, DPR1_2U, TRICORE_FEATURE_13)
+A(0xC418, DPR1_3L, TRICORE_FEATURE_13)
+A(0xC41C, DPR1_3U, TRICORE_FEATURE_13)
+A(0xC800, DPR2_0L, TRICORE_FEATURE_13)
+A(0xC804, DPR2_0U, TRICORE_FEATURE_13)
+A(0xC808, DPR2_1L, TRICORE_FEATURE_13)
+A(0xC80C, DPR2_1U, TRICORE_FEATURE_13)
+A(0xC810, DPR2_2L, TRICORE_FEATURE_13)
+A(0xC814, DPR2_2U, TRICORE_FEATURE_13)
+A(0xC818, DPR2_3L, TRICORE_FEATURE_13)
+A(0xC81C, DPR2_3U, TRICORE_FEATURE_13)
+A(0xCC00, DPR3_0L, TRICORE_FEATURE_13)
+A(0xCC04, DPR3_0U, TRICORE_FEATURE_13)
+A(0xCC08, DPR3_1L, TRICORE_FEATURE_13)
+A(0xCC0C, DPR3_1U, TRICORE_FEATURE_13)
+A(0xCC10, DPR3_2L, TRICORE_FEATURE_13)
+A(0xCC14, DPR3_2U, TRICORE_FEATURE_13)
+A(0xCC18, DPR3_3L, TRICORE_FEATURE_13)
+A(0xCC1C, DPR3_3U, TRICORE_FEATURE_13)
+A(0xD000, CPR0_0L, TRICORE_FEATURE_13)
+A(0xD004, CPR0_0U, TRICORE_FEATURE_13)
+A(0xD008, CPR0_1L, TRICORE_FEATURE_13)
+A(0xD00C, CPR0_1U, TRICORE_FEATURE_13)
+A(0xD010, CPR0_2L, TRICORE_FEATURE_13)
+A(0xD014, CPR0_2U, TRICORE_FEATURE_13)
+A(0xD018, CPR0_3L, TRICORE_FEATURE_13)
+A(0xD01C, CPR0_3U, TRICORE_FEATURE_13)
+A(0xD400, CPR1_0L, TRICORE_FEATURE_13)
+A(0xD404, CPR1_0U, TRICORE_FEATURE_13)
+A(0xD408, CPR1_1L, TRICORE_FEATURE_13)
+A(0xD40C, CPR1_1U, TRICORE_FEATURE_13)
+A(0xD410, CPR1_2L, TRICORE_FEATURE_13)
+A(0xD414, CPR1_2U, TRICORE_FEATURE_13)
+A(0xD418, CPR1_3L, TRICORE_FEATURE_13)
+A(0xD41C, CPR1_3U, TRICORE_FEATURE_13)
+A(0xD800, CPR2_0L, TRICORE_FEATURE_13)
+A(0xD804, CPR2_0U, TRICORE_FEATURE_13)
+A(0xD808, CPR2_1L, TRICORE_FEATURE_13)
+A(0xD80C, CPR2_1U, TRICORE_FEATURE_13)
+A(0xD810, CPR2_2L, TRICORE_FEATURE_13)
+A(0xD814, CPR2_2U, TRICORE_FEATURE_13)
+A(0xD818, CPR2_3L, TRICORE_FEATURE_13)
+A(0xD81C, CPR2_3U, TRICORE_FEATURE_13)
+A(0xDC00, CPR3_0L, TRICORE_FEATURE_13)
+A(0xDC04, CPR3_0U, TRICORE_FEATURE_13)
+A(0xDC08, CPR3_1L, TRICORE_FEATURE_13)
+A(0xDC0C, CPR3_1U, TRICORE_FEATURE_13)
+A(0xDC10, CPR3_2L, TRICORE_FEATURE_13)
+A(0xDC14, CPR3_2U, TRICORE_FEATURE_13)
+A(0xDC18, CPR3_3L, TRICORE_FEATURE_13)
+A(0xDC1C, CPR3_3U, TRICORE_FEATURE_13)
+A(0xE000, DPM0, TRICORE_FEATURE_13)
+A(0xE080, DPM1, TRICORE_FEATURE_13)
+A(0xE100, DPM2, TRICORE_FEATURE_13)
+A(0xE180, DPM3, TRICORE_FEATURE_13)
+A(0xE200, CPM0, TRICORE_FEATURE_13)
+A(0xE280, CPM1, TRICORE_FEATURE_13)
+A(0xE300, CPM2, TRICORE_FEATURE_13)
+A(0xE380, CPM3, TRICORE_FEATURE_13)
+/* memory Managment Registers */
+A(0x8000, MMU_CON, TRICORE_FEATURE_13)
+A(0x8004, MMU_ASI, TRICORE_FEATURE_13)
+A(0x800C, MMU_TVA, TRICORE_FEATURE_13)
+A(0x8010, MMU_TPA, TRICORE_FEATURE_13)
+A(0x8014, MMU_TPX, TRICORE_FEATURE_13)
+A(0x8018, MMU_TFA, TRICORE_FEATURE_13)
+E(0x9004, BMACON, TRICORE_FEATURE_131)
+E(0x900C, SMACON, TRICORE_FEATURE_131)
+A(0x9020, DIEAR, TRICORE_FEATURE_131)
+A(0x9024, DIETR, TRICORE_FEATURE_131)
+A(0x9028, CCDIER, TRICORE_FEATURE_131)
+E(0x9044, MIECON, TRICORE_FEATURE_131)
+A(0x9210, PIEAR, TRICORE_FEATURE_131)
+A(0x9214, PIETR, TRICORE_FEATURE_131)
+A(0x9218, CCPIER, TRICORE_FEATURE_131)
+/* debug registers */
+A(0xFD00, DBGSR, TRICORE_FEATURE_13)
+A(0xFD08, EXEVT, TRICORE_FEATURE_13)
+A(0xFD0C, CREVT, TRICORE_FEATURE_13)
+A(0xFD10, SWEVT, TRICORE_FEATURE_13)
+A(0xFD20, TR0EVT, TRICORE_FEATURE_13)
+A(0xFD24, TR1EVT, TRICORE_FEATURE_13)
+A(0xFD40, DMS, TRICORE_FEATURE_13)
+A(0xFD44, DCX, TRICORE_FEATURE_13)
+A(0xFD48, DBGTCR, TRICORE_FEATURE_131)
+A(0xFC00, CCTRL, TRICORE_FEATURE_131)
+A(0xFC04, CCNT, TRICORE_FEATURE_131)
+A(0xFC08, ICNT, TRICORE_FEATURE_131)
+A(0xFC0C, M1CNT, TRICORE_FEATURE_131)
+A(0xFC10, M2CNT, TRICORE_FEATURE_131)
+A(0xFC14, M3CNT, TRICORE_FEATURE_131)
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index b3fc33ceae..6c07bd7f28 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -17,7 +17,21 @@
/* Arithmetic */
DEF_HELPER_3(add_ssov, i32, env, i32, i32)
+DEF_HELPER_3(add_suov, i32, env, i32, i32)
DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
+DEF_HELPER_3(sub_suov, i32, env, i32, i32)
+DEF_HELPER_3(mul_ssov, i32, env, i32, i32)
+DEF_HELPER_3(mul_suov, i32, env, i32, i32)
+DEF_HELPER_3(sha_ssov, i32, env, i32, i32)
+DEF_HELPER_3(absdif_ssov, i32, env, i32, i32)
+DEF_HELPER_4(madd32_ssov, i32, env, i32, i32, i32)
+DEF_HELPER_4(madd32_suov, i32, env, i32, i32, i32)
+DEF_HELPER_4(madd64_ssov, i64, env, i32, i64, i32)
+DEF_HELPER_4(madd64_suov, i64, env, i32, i64, i32)
+DEF_HELPER_4(msub32_ssov, i32, env, i32, i32, i32)
+DEF_HELPER_4(msub32_suov, i32, env, i32, i32, i32)
+DEF_HELPER_4(msub64_ssov, i64, env, i32, i64, i32)
+DEF_HELPER_4(msub64_suov, i64, env, i32, i64, i32)
/* CSA */
DEF_HELPER_2(call, void, env, i32)
DEF_HELPER_1(ret, void, env)
@@ -30,3 +44,6 @@ DEF_HELPER_2(stucx, void, env, i32)
/* Address mode helper */
DEF_HELPER_1(br_update, i32, i32)
DEF_HELPER_2(circ_update, i32, i32, i32)
+/* PSW cache helper */
+DEF_HELPER_2(psw_write, void, env, i32)
+DEF_HELPER_1(psw_read, i32, env)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index a36988aa1b..4da76ff232 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -77,6 +77,27 @@ uint32_t helper_circ_update(uint32_t reg, uint32_t off)
env->PSW_USB_SAV |= env->PSW_USB_AV; \
} while (0)
+#define SUOV(env, ret, arg, len) do { \
+ int64_t max_pos = UINT##len ##_MAX; \
+ if (arg > max_pos) { \
+ env->PSW_USB_V = (1 << 31); \
+ env->PSW_USB_SV = (1 << 31); \
+ ret = (target_ulong)max_pos; \
+ } else { \
+ if (arg < 0) { \
+ env->PSW_USB_V = (1 << 31); \
+ env->PSW_USB_SV = (1 << 31); \
+ ret = 0; \
+ } else { \
+ env->PSW_USB_V = 0; \
+ ret = (target_ulong)arg; \
+ } \
+ } \
+ env->PSW_USB_AV = arg ^ arg * 2u; \
+ env->PSW_USB_SAV |= env->PSW_USB_AV; \
+} while (0)
+
+
target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
target_ulong r2)
{
@@ -88,6 +109,17 @@ target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
return ret;
}
+target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = extract64(r1, 0, 32);
+ int64_t t2 = extract64(r2, 0, 32);
+ int64_t result = t1 + t2;
+ SUOV(env, ret, result, 32);
+ return ret;
+}
+
target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
target_ulong r2)
{
@@ -99,6 +131,241 @@ target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
return ret;
}
+target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = extract64(r1, 0, 32);
+ int64_t t2 = extract64(r2, 0, 32);
+ int64_t result = t1 - t2;
+ SUOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t2 = sextract64(r2, 0, 32);
+ int64_t result = t1 * t2;
+ SSOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = extract64(r1, 0, 32);
+ int64_t t2 = extract64(r2, 0, 32);
+ int64_t result = t1 * t2;
+ SUOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int32_t t2 = sextract64(r2, 0, 6);
+ int64_t result;
+ if (t2 == 0) {
+ result = t1;
+ } else if (t2 > 0) {
+ result = t1 << t2;
+ } else {
+ result = t1 >> -t2;
+ }
+ SSOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t2 = sextract64(r2, 0, 32);
+ int64_t result;
+
+ if (t1 > t2) {
+ result = t1 - t2;
+ } else {
+ result = t2 - t1;
+ }
+ SSOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2, target_ulong r3)
+{
+ target_ulong ret;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t2 = sextract64(r2, 0, 32);
+ int64_t t3 = sextract64(r3, 0, 32);
+ int64_t result;
+
+ result = t2 + (t1 * t3);
+ SSOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2, target_ulong r3)
+{
+ target_ulong ret;
+ uint64_t t1 = extract64(r1, 0, 32);
+ uint64_t t2 = extract64(r2, 0, 32);
+ uint64_t t3 = extract64(r3, 0, 32);
+ int64_t result;
+
+ result = t2 + (t1 * t3);
+ SUOV(env, ret, result, 32);
+ return ret;
+}
+
+uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
+ uint64_t r2, target_ulong r3)
+{
+ uint64_t ret, ovf;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t3 = sextract64(r3, 0, 32);
+ int64_t mul;
+
+ mul = t1 * t3;
+ ret = mul + r2;
+ ovf = (ret ^ mul) & ~(mul ^ r2);
+
+ if ((int64_t)ovf < 0) {
+ env->PSW_USB_V = (1 << 31);
+ env->PSW_USB_SV = (1 << 31);
+ /* ext_ret > MAX_INT */
+ if (mul >= 0) {
+ ret = INT64_MAX;
+ /* ext_ret < MIN_INT */
+ } else {
+ ret = INT64_MIN;
+ }
+ } else {
+ env->PSW_USB_V = 0;
+ }
+ t1 = ret >> 32;
+ env->PSW_USB_AV = t1 ^ t1 * 2u;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+
+ return ret;
+}
+
+uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
+ uint64_t r2, target_ulong r3)
+{
+ uint64_t ret, mul;
+ uint64_t t1 = extract64(r1, 0, 32);
+ uint64_t t3 = extract64(r3, 0, 32);
+
+ mul = t1 * t3;
+ ret = mul + r2;
+
+ if (ret < r2) {
+ env->PSW_USB_V = (1 << 31);
+ env->PSW_USB_SV = (1 << 31);
+ /* saturate */
+ ret = UINT64_MAX;
+ } else {
+ env->PSW_USB_V = 0;
+ }
+ t1 = ret >> 32;
+ env->PSW_USB_AV = t1 ^ t1 * 2u;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+ return ret;
+}
+
+target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2, target_ulong r3)
+{
+ target_ulong ret;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t2 = sextract64(r2, 0, 32);
+ int64_t t3 = sextract64(r3, 0, 32);
+ int64_t result;
+
+ result = t2 - (t1 * t3);
+ SSOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2, target_ulong r3)
+{
+ target_ulong ret;
+ int64_t t1 = extract64(r1, 0, 32);
+ int64_t t2 = extract64(r2, 0, 32);
+ int64_t t3 = extract64(r3, 0, 32);
+ int64_t result;
+
+ result = t2 - (t1 * t3);
+ SUOV(env, ret, result, 32);
+ return ret;
+}
+
+uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
+ uint64_t r2, target_ulong r3)
+{
+ uint64_t ret, ovf;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t3 = sextract64(r3, 0, 32);
+ int64_t mul;
+
+ mul = t1 * t3;
+ ret = r2 - mul;
+ ovf = (ret ^ r2) & (mul ^ r2);
+
+ if ((int64_t)ovf < 0) {
+ env->PSW_USB_V = (1 << 31);
+ env->PSW_USB_SV = (1 << 31);
+ /* ext_ret > MAX_INT */
+ if (mul < 0) {
+ ret = INT64_MAX;
+ /* ext_ret < MIN_INT */
+ } else {
+ ret = INT64_MIN;
+ }
+ } else {
+ env->PSW_USB_V = 0;
+ }
+ t1 = ret >> 32;
+ env->PSW_USB_AV = t1 ^ t1 * 2u;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+ return ret;
+}
+
+uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
+ uint64_t r2, target_ulong r3)
+{
+ uint64_t ret, mul;
+ uint64_t t1 = extract64(r1, 0, 32);
+ uint64_t t3 = extract64(r3, 0, 32);
+
+ mul = t1 * t3;
+ ret = r2 - mul;
+
+ if (ret > r2) {
+ env->PSW_USB_V = (1 << 31);
+ env->PSW_USB_SV = (1 << 31);
+ /* saturate */
+ ret = 0;
+ } else {
+ env->PSW_USB_V = 0;
+ }
+ t1 = ret >> 32;
+ env->PSW_USB_AV = t1 ^ t1 * 2u;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+ return ret;
+}
+
/* context save area (CSA) related helpers */
static int cdc_increment(target_ulong *psw)
@@ -437,6 +704,17 @@ void helper_stucx(CPUTriCoreState *env, uint32_t ea)
save_context_upper(env, ea);
}
+void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
+{
+ psw_write(env, arg);
+}
+
+uint32_t helper_psw_read(CPUTriCoreState *env)
+{
+ return psw_read(env);
+}
+
+
static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
uint32_t exception,
int error_code,
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index d5a95969bb..65abf453f0 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -233,6 +233,63 @@ static void gen_swap(DisasContext *ctx, int reg, TCGv ea)
tcg_temp_free(temp);
}
+/* We generate loads and store to core special function register (csfr) through
+ the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3
+ makros R, A and E, which allow read-only, all and endinit protected access.
+ These makros also specify in which ISA version the csfr was introduced. */
+#define R(ADDRESS, REG, FEATURE) \
+ case ADDRESS: \
+ if (tricore_feature(env, FEATURE)) { \
+ tcg_gen_ld_tl(ret, cpu_env, offsetof(CPUTriCoreState, REG)); \
+ } \
+ break;
+#define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
+#define E(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
+static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset)
+{
+ /* since we're caching PSW make this a special case */
+ if (offset == 0xfe04) {
+ gen_helper_psw_read(ret, cpu_env);
+ } else {
+ switch (offset) {
+#include "csfr.def"
+ }
+ }
+}
+#undef R
+#undef A
+#undef E
+
+#define R(ADDRESS, REG, FEATURE) /* don't gen writes to read-only reg,
+ since no execption occurs */
+#define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) \
+ case ADDRESS: \
+ if (tricore_feature(env, FEATURE)) { \
+ tcg_gen_st_tl(r1, cpu_env, offsetof(CPUTriCoreState, REG)); \
+ } \
+ break;
+/* Endinit protected registers
+ TODO: Since the endinit bit is in a register of a not yet implemented
+ watchdog device, we handle endinit protected registers like
+ all-access registers for now. */
+#define E(ADDRESS, REG, FEATURE) A(ADDRESS, REG, FEATURE)
+static inline void gen_mtcr(CPUTriCoreState *env, DisasContext *ctx, TCGv r1,
+ int32_t offset)
+{
+ if (ctx->hflags & TRICORE_HFLAG_SM) {
+ /* since we're caching PSW make this a special case */
+ if (offset == 0xfe04) {
+ gen_helper_psw_write(cpu_env, r1);
+ } else {
+ switch (offset) {
+#include "csfr.def"
+ }
+ }
+ } else {
+ /* generate privilege trap */
+ }
+}
+
/* Functions for arithmetic instructions */
static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
@@ -259,12 +316,337 @@ static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
tcg_temp_free(t0);
}
+/* ret = r2 + (r1 * r3); */
+static inline void gen_madd32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_ext_i32_i64(t1, r1);
+ tcg_gen_ext_i32_i64(t2, r2);
+ tcg_gen_ext_i32_i64(t3, r3);
+
+ tcg_gen_mul_i64(t1, t1, t3);
+ tcg_gen_add_i64(t1, t2, t1);
+
+ tcg_gen_trunc_i64_i32(ret, t1);
+ /* calc V
+ t1 > 0x7fffffff */
+ tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
+ /* t1 < -0x80000000 */
+ tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
+ tcg_gen_or_i64(t2, t2, t3);
+ tcg_gen_trunc_i64_i32(cpu_PSW_V, t2);
+ tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+ tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t2);
+ tcg_temp_free_i64(t3);
+}
+
+static inline void gen_maddi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_madd32_d(ret, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_madd64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ TCGv r3)
+{
+ TCGv t1 = tcg_temp_new();
+ TCGv t2 = tcg_temp_new();
+ TCGv t3 = tcg_temp_new();
+ TCGv t4 = tcg_temp_new();
+
+ tcg_gen_muls2_tl(t1, t2, r1, r3);
+ /* only the add can overflow */
+ tcg_gen_add2_tl(t3, t4, r2_low, r2_high, t1, t2);
+ /* calc V bit */
+ tcg_gen_xor_tl(cpu_PSW_V, t4, r2_high);
+ tcg_gen_xor_tl(t1, r2_high, t2);
+ tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t1);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, t4, t4);
+ tcg_gen_xor_tl(cpu_PSW_AV, t4, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back the result */
+ tcg_gen_mov_tl(ret_low, t3);
+ tcg_gen_mov_tl(ret_high, t4);
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t2);
+ tcg_temp_free(t3);
+ tcg_temp_free(t4);
+}
+
+static inline void
+gen_maddu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ TCGv r3)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_extu_i32_i64(t1, r1);
+ tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
+ tcg_gen_extu_i32_i64(t3, r3);
+
+ tcg_gen_mul_i64(t1, t1, t3);
+ tcg_gen_add_i64(t2, t2, t1);
+ /* write back result */
+ tcg_gen_extr_i64_i32(ret_low, ret_high, t2);
+ /* only the add overflows, if t2 < t1
+ calc V bit */
+ tcg_gen_setcond_i64(TCG_COND_LTU, t2, t2, t1);
+ tcg_gen_trunc_i64_i32(cpu_PSW_V, t2);
+ tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+ tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t2);
+ tcg_temp_free_i64(t3);
+}
+
+static inline void
+gen_maddi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_madd64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_maddui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_maddu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+ tcg_temp_free(temp);
+}
+
+/* ret = r2 - (r1 * r3); */
+static inline void gen_msub32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_ext_i32_i64(t1, r1);
+ tcg_gen_ext_i32_i64(t2, r2);
+ tcg_gen_ext_i32_i64(t3, r3);
+
+ tcg_gen_mul_i64(t1, t1, t3);
+ tcg_gen_sub_i64(t1, t2, t1);
+
+ tcg_gen_trunc_i64_i32(ret, t1);
+ /* calc V
+ t2 > 0x7fffffff */
+ tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
+ /* result < -0x80000000 */
+ tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
+ tcg_gen_or_i64(t2, t2, t3);
+ tcg_gen_trunc_i64_i32(cpu_PSW_V, t2);
+ tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+ tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t2);
+ tcg_temp_free_i64(t3);
+}
+
+static inline void gen_msubi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_msub32_d(ret, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_msub64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ TCGv r3)
+{
+ TCGv t1 = tcg_temp_new();
+ TCGv t2 = tcg_temp_new();
+ TCGv t3 = tcg_temp_new();
+ TCGv t4 = tcg_temp_new();
+
+ tcg_gen_muls2_tl(t1, t2, r1, r3);
+ /* only the sub can overflow */
+ tcg_gen_sub2_tl(t3, t4, r2_low, r2_high, t1, t2);
+ /* calc V bit */
+ tcg_gen_xor_tl(cpu_PSW_V, t4, r2_high);
+ tcg_gen_xor_tl(t1, r2_high, t2);
+ tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, t1);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, t4, t4);
+ tcg_gen_xor_tl(cpu_PSW_AV, t4, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back the result */
+ tcg_gen_mov_tl(ret_low, t3);
+ tcg_gen_mov_tl(ret_high, t4);
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t2);
+ tcg_temp_free(t3);
+ tcg_temp_free(t4);
+}
+
+static inline void
+gen_msubi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_msub64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_msubu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ TCGv r3)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_extu_i32_i64(t1, r1);
+ tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
+ tcg_gen_extu_i32_i64(t3, r3);
+
+ tcg_gen_mul_i64(t1, t1, t3);
+ tcg_gen_sub_i64(t3, t2, t1);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, t3);
+ /* calc V bit, only the sub can overflow, if t1 > t2 */
+ tcg_gen_setcond_i64(TCG_COND_GTU, t1, t1, t2);
+ tcg_gen_trunc_i64_i32(cpu_PSW_V, t1);
+ tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+ tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t2);
+ tcg_temp_free_i64(t3);
+}
+
+static inline void
+gen_msubui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_msubu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+ tcg_temp_free(temp);
+}
+
static inline void gen_addi_d(TCGv ret, TCGv r1, target_ulong r2)
{
TCGv temp = tcg_const_i32(r2);
gen_add_d(ret, r1, temp);
tcg_temp_free(temp);
}
+/* calculate the carry bit too */
+static inline void gen_add_CC(TCGv ret, TCGv r1, TCGv r2)
+{
+ TCGv t0 = tcg_temp_new_i32();
+ TCGv result = tcg_temp_new_i32();
+
+ tcg_gen_movi_tl(t0, 0);
+ /* Addition and set C/V/SV bits */
+ tcg_gen_add2_i32(result, cpu_PSW_C, r1, t0, r2, t0);
+ /* calc V bit */
+ tcg_gen_xor_tl(cpu_PSW_V, result, r1);
+ tcg_gen_xor_tl(t0, r1, r2);
+ tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, result, result);
+ tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back result */
+ tcg_gen_mov_tl(ret, result);
+
+ tcg_temp_free(result);
+ tcg_temp_free(t0);
+}
+
+static inline void gen_addi_CC(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_add_CC(ret, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_addc_CC(TCGv ret, TCGv r1, TCGv r2)
+{
+ TCGv carry = tcg_temp_new_i32();
+ TCGv t0 = tcg_temp_new_i32();
+ TCGv result = tcg_temp_new_i32();
+
+ tcg_gen_movi_tl(t0, 0);
+ tcg_gen_setcondi_tl(TCG_COND_NE, carry, cpu_PSW_C, 0);
+ /* Addition, carry and set C/V/SV bits */
+ tcg_gen_add2_i32(result, cpu_PSW_C, r1, t0, carry, t0);
+ tcg_gen_add2_i32(result, cpu_PSW_C, result, cpu_PSW_C, r2, t0);
+ /* calc V bit */
+ tcg_gen_xor_tl(cpu_PSW_V, result, r1);
+ tcg_gen_xor_tl(t0, r1, r2);
+ tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, result, result);
+ tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back result */
+ tcg_gen_mov_tl(ret, result);
+
+ tcg_temp_free(result);
+ tcg_temp_free(t0);
+ tcg_temp_free(carry);
+}
+
+static inline void gen_addci_CC(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_addc_CC(ret, r1, temp);
+ tcg_temp_free(temp);
+}
static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
TCGv r4)
@@ -337,6 +719,49 @@ static inline void gen_sub_d(TCGv ret, TCGv r1, TCGv r2)
tcg_temp_free(result);
}
+static inline void gen_absdif(TCGv ret, TCGv r1, TCGv r2)
+{
+ TCGv temp = tcg_temp_new_i32();
+ TCGv result = tcg_temp_new_i32();
+
+ tcg_gen_sub_tl(result, r1, r2);
+ tcg_gen_sub_tl(temp, r2, r1);
+ tcg_gen_movcond_tl(TCG_COND_GT, result, r1, r2, result, temp);
+
+ /* calc V bit */
+ tcg_gen_xor_tl(cpu_PSW_V, result, r1);
+ tcg_gen_xor_tl(temp, result, r2);
+ tcg_gen_movcond_tl(TCG_COND_GT, cpu_PSW_V, r1, r2, cpu_PSW_V, temp);
+ tcg_gen_xor_tl(temp, r1, r2);
+ tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp);
+ /* calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV bit */
+ tcg_gen_add_tl(cpu_PSW_AV, result, result);
+ tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
+ /* calc SAV bit */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back result */
+ tcg_gen_mov_tl(ret, result);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(result);
+}
+
+static inline void gen_absdifi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_absdif(ret, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_absdifsi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_absdif_ssov(ret, cpu_env, r1, temp);
+ tcg_temp_free(temp);
+}
+
static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
{
TCGv high = tcg_temp_new();
@@ -360,6 +785,151 @@ static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
tcg_temp_free(low);
}
+static inline void gen_muli_i32s(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_mul_i32s(ret, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_mul_i64s(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2)
+{
+ tcg_gen_muls2_tl(ret_low, ret_high, r1, r2);
+ /* clear V bit */
+ tcg_gen_movi_tl(cpu_PSW_V, 0);
+ /* calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV bit */
+ tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
+ /* calc SAV bit */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+}
+
+static inline void gen_muli_i64s(TCGv ret_low, TCGv ret_high, TCGv r1,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_mul_i64s(ret_low, ret_high, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_mul_i64u(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2)
+{
+ tcg_gen_mulu2_tl(ret_low, ret_high, r1, r2);
+ /* clear V bit */
+ tcg_gen_movi_tl(cpu_PSW_V, 0);
+ /* calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV bit */
+ tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
+ /* calc SAV bit */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+}
+
+static inline void gen_muli_i64u(TCGv ret_low, TCGv ret_high, TCGv r1,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_mul_i64u(ret_low, ret_high, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_mulsi_i32(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_mul_ssov(ret, cpu_env, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_mulsui_i32(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_mul_suov(ret, cpu_env, r1, temp);
+ tcg_temp_free(temp);
+}
+/* gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9); */
+static inline void gen_maddsi_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_madd32_ssov(ret, cpu_env, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_maddsui_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_madd32_suov(ret, cpu_env, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_maddsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+ gen_helper_madd64_ssov(temp64, cpu_env, r1, temp64, temp);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+}
+
+static inline void
+gen_maddsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+ gen_helper_madd64_suov(temp64, cpu_env, r1, temp64, temp);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+}
+
+static inline void gen_msubsi_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_msub32_ssov(ret, cpu_env, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_msubsui_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_msub32_suov(ret, cpu_env, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_msubsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+ gen_helper_msub64_ssov(temp64, cpu_env, r1, temp64, temp);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+}
+
+static inline void
+gen_msubsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+ gen_helper_msub64_suov(temp64, cpu_env, r1, temp64, temp);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+}
+
static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
{
TCGv sat_neg = tcg_const_i32(low);
@@ -394,6 +964,27 @@ static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
}
}
+static void gen_sh_hi(TCGv ret, TCGv r1, int32_t shiftcount)
+{
+ TCGv temp_low, temp_high;
+
+ if (shiftcount == -16) {
+ tcg_gen_movi_tl(ret, 0);
+ } else {
+ temp_high = tcg_temp_new();
+ temp_low = tcg_temp_new();
+
+ tcg_gen_andi_tl(temp_low, r1, 0xffff);
+ tcg_gen_andi_tl(temp_high, r1, 0xffff0000);
+ gen_shi(temp_low, temp_low, shiftcount);
+ gen_shi(ret, temp_high, shiftcount);
+ tcg_gen_deposit_tl(ret, ret, temp_low, 0, 16);
+
+ tcg_temp_free(temp_low);
+ tcg_temp_free(temp_high);
+ }
+}
+
static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count)
{
uint32_t msk, msk_start;
@@ -453,16 +1044,100 @@ static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count)
tcg_temp_free(t_0);
}
+static void gen_shas(TCGv ret, TCGv r1, TCGv r2)
+{
+ gen_helper_sha_ssov(ret, cpu_env, r1, r2);
+}
+
+static void gen_shasi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_shas(ret, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static void gen_sha_hi(TCGv ret, TCGv r1, int32_t shift_count)
+{
+ TCGv low, high;
+
+ if (shift_count == 0) {
+ tcg_gen_mov_tl(ret, r1);
+ } else if (shift_count > 0) {
+ low = tcg_temp_new();
+ high = tcg_temp_new();
+
+ tcg_gen_andi_tl(high, r1, 0xffff0000);
+ tcg_gen_shli_tl(low, r1, shift_count);
+ tcg_gen_shli_tl(ret, high, shift_count);
+ tcg_gen_deposit_tl(ret, ret, low, 0, 16);
+
+ tcg_temp_free(low);
+ tcg_temp_free(high);
+ } else {
+ low = tcg_temp_new();
+ high = tcg_temp_new();
+
+ tcg_gen_ext16s_tl(low, r1);
+ tcg_gen_sari_tl(low, low, -shift_count);
+ tcg_gen_sari_tl(ret, r1, -shift_count);
+ tcg_gen_deposit_tl(ret, ret, low, 0, 16);
+
+ tcg_temp_free(low);
+ tcg_temp_free(high);
+ }
+
+}
+
+/* ret = {ret[30:0], (r1 cond r2)}; */
+static void gen_sh_cond(int cond, TCGv ret, TCGv r1, TCGv r2)
+{
+ TCGv temp = tcg_temp_new();
+ TCGv temp2 = tcg_temp_new();
+
+ tcg_gen_shli_tl(temp, ret, 1);
+ tcg_gen_setcond_tl(cond, temp2, r1, r2);
+ tcg_gen_or_tl(ret, temp, temp2);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
+
+static void gen_sh_condi(int cond, TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_sh_cond(cond, ret, r1, temp);
+ tcg_temp_free(temp);
+}
+
static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2)
{
gen_helper_add_ssov(ret, cpu_env, r1, r2);
}
+static inline void gen_addsi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_add_ssov(ret, cpu_env, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_addsui(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_add_suov(ret, cpu_env, r1, temp);
+ tcg_temp_free(temp);
+}
+
static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
{
gen_helper_sub_ssov(ret, cpu_env, r1, r2);
}
+static inline void gen_subsu(TCGv ret, TCGv r1, TCGv r2)
+{
+ gen_helper_sub_suov(ret, cpu_env, r1, r2);
+}
+
static inline void gen_bit_2op(TCGv ret, TCGv r1, TCGv r2,
int pos1, int pos2,
void(*op1)(TCGv, TCGv, TCGv),
@@ -506,6 +1181,109 @@ static inline void gen_bit_1op(TCGv ret, TCGv r1, TCGv r2,
tcg_temp_free(temp2);
}
+static inline void gen_accumulating_cond(int cond, TCGv ret, TCGv r1, TCGv r2,
+ void(*op)(TCGv, TCGv, TCGv))
+{
+ TCGv temp = tcg_temp_new();
+ TCGv temp2 = tcg_temp_new();
+ /* temp = (arg1 cond arg2 )*/
+ tcg_gen_setcond_tl(cond, temp, r1, r2);
+ /* temp2 = ret[0]*/
+ tcg_gen_andi_tl(temp2, ret, 0x1);
+ /* temp = temp insn temp2 */
+ (*op)(temp, temp, temp2);
+ /* ret = {ret[31:1], temp} */
+ tcg_gen_deposit_tl(ret, ret, temp, 0, 1);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
+
+static inline void
+gen_accumulating_condi(int cond, TCGv ret, TCGv r1, int32_t con,
+ void(*op)(TCGv, TCGv, TCGv))
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_accumulating_cond(cond, ret, r1, temp, op);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_eqany_bi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv b0 = tcg_temp_new();
+ TCGv b1 = tcg_temp_new();
+ TCGv b2 = tcg_temp_new();
+ TCGv b3 = tcg_temp_new();
+
+ /* byte 0 */
+ tcg_gen_andi_tl(b0, r1, 0xff);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, b0, b0, con & 0xff);
+
+ /* byte 1 */
+ tcg_gen_andi_tl(b1, r1, 0xff00);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, b1, b1, con & 0xff00);
+
+ /* byte 2 */
+ tcg_gen_andi_tl(b2, r1, 0xff0000);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, b2, b2, con & 0xff0000);
+
+ /* byte 3 */
+ tcg_gen_andi_tl(b3, r1, 0xff000000);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, b3, b3, con & 0xff000000);
+
+ /* combine them */
+ tcg_gen_or_tl(ret, b0, b1);
+ tcg_gen_or_tl(ret, ret, b2);
+ tcg_gen_or_tl(ret, ret, b3);
+
+ tcg_temp_free(b0);
+ tcg_temp_free(b1);
+ tcg_temp_free(b2);
+ tcg_temp_free(b3);
+}
+
+static inline void gen_eqany_hi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv h0 = tcg_temp_new();
+ TCGv h1 = tcg_temp_new();
+
+ /* halfword 0 */
+ tcg_gen_andi_tl(h0, r1, 0xffff);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, h0, h0, con & 0xffff);
+
+ /* halfword 1 */
+ tcg_gen_andi_tl(h1, r1, 0xffff0000);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, h1, h1, con & 0xffff0000);
+
+ /* combine them */
+ tcg_gen_or_tl(ret, h0, h1);
+
+ tcg_temp_free(h0);
+ tcg_temp_free(h1);
+}
+/* mask = ((1 << width) -1) << pos;
+ ret = (r1 & ~mask) | (r2 << pos) & mask); */
+static inline void gen_insert(TCGv ret, TCGv r1, TCGv r2, TCGv width, TCGv pos)
+{
+ TCGv mask = tcg_temp_new();
+ TCGv temp = tcg_temp_new();
+ TCGv temp2 = tcg_temp_new();
+
+ tcg_gen_movi_tl(mask, 1);
+ tcg_gen_shl_tl(mask, mask, width);
+ tcg_gen_subi_tl(mask, mask, 1);
+ tcg_gen_shl_tl(mask, mask, pos);
+
+ tcg_gen_shl_tl(temp, r2, pos);
+ tcg_gen_and_tl(temp, temp, mask);
+ tcg_gen_andc_tl(temp2, r1, mask);
+ tcg_gen_or_tl(ret, temp, temp2);
+
+ tcg_temp_free(mask);
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
+
/* helpers for generating program flow micro-ops */
static inline void gen_save_pc(target_ulong pc)
@@ -567,7 +1345,8 @@ static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
{
- TCGv temp;
+ TCGv temp, temp2;
+ int n;
switch (opc) {
/* SB-format jumps */
@@ -665,6 +1444,134 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
break;
+/* BOL format */
+ case OPCM_32_BRC_EQ_NEQ:
+ if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JEQ) {
+ gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], constant, offset);
+ } else {
+ gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], constant, offset);
+ }
+ break;
+ case OPCM_32_BRC_GE:
+ if (MASK_OP_BRC_OP2(ctx->opcode) == OP2_32_BRC_JGE) {
+ gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], constant, offset);
+ } else {
+ constant = MASK_OP_BRC_CONST4(ctx->opcode);
+ gen_branch_condi(ctx, TCG_COND_GEU, cpu_gpr_d[r1], constant,
+ offset);
+ }
+ break;
+ case OPCM_32_BRC_JLT:
+ if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JLT) {
+ gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], constant, offset);
+ } else {
+ constant = MASK_OP_BRC_CONST4(ctx->opcode);
+ gen_branch_condi(ctx, TCG_COND_LTU, cpu_gpr_d[r1], constant,
+ offset);
+ }
+ break;
+ case OPCM_32_BRC_JNE:
+ temp = tcg_temp_new();
+ if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JNED) {
+ tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
+ /* subi is unconditional */
+ tcg_gen_subi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
+ gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
+ } else {
+ tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
+ /* addi is unconditional */
+ tcg_gen_addi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
+ gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
+ }
+ tcg_temp_free(temp);
+ break;
+/* BRN format */
+ case OPCM_32_BRN_JTT:
+ n = MASK_OP_BRN_N(ctx->opcode);
+
+ temp = tcg_temp_new();
+ tcg_gen_andi_tl(temp, cpu_gpr_d[r1], (1 << n));
+
+ if (MASK_OP_BRN_OP2(ctx->opcode) == OPC2_32_BRN_JNZ_T) {
+ gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
+ } else {
+ gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
+ }
+ tcg_temp_free(temp);
+ break;
+/* BRR Format */
+ case OPCM_32_BRR_EQ_NEQ:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ) {
+ gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ } else {
+ gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ }
+ break;
+ case OPCM_32_BRR_ADDR_EQ_NEQ:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ_A) {
+ gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_a[r1], cpu_gpr_a[r2],
+ offset);
+ } else {
+ gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_a[r1], cpu_gpr_a[r2],
+ offset);
+ }
+ break;
+ case OPCM_32_BRR_GE:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JGE) {
+ gen_branch_cond(ctx, TCG_COND_GE, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ } else {
+ gen_branch_cond(ctx, TCG_COND_GEU, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ }
+ break;
+ case OPCM_32_BRR_JLT:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JLT) {
+ gen_branch_cond(ctx, TCG_COND_LT, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ } else {
+ gen_branch_cond(ctx, TCG_COND_LTU, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ }
+ break;
+ case OPCM_32_BRR_LOOP:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_LOOP) {
+ gen_loop(ctx, r1, offset * 2);
+ } else {
+ /* OPC2_32_BRR_LOOPU */
+ gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+ }
+ break;
+ case OPCM_32_BRR_JNE:
+ temp = tcg_temp_new();
+ temp2 = tcg_temp_new();
+ if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRR_JNED) {
+ tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
+ /* also save r2, in case of r1 == r2, so r2 is not decremented */
+ tcg_gen_mov_tl(temp2, cpu_gpr_d[r2]);
+ /* subi is unconditional */
+ tcg_gen_subi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
+ gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
+ } else {
+ tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
+ /* also save r2, in case of r1 == r2, so r2 is not decremented */
+ tcg_gen_mov_tl(temp2, cpu_gpr_d[r2]);
+ /* addi is unconditional */
+ tcg_gen_addi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
+ gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
+ }
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+ break;
+ case OPCM_32_BRR_JNZ:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JNZ_A) {
+ gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
+ } else {
+ gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
+ }
+ break;
default:
printf("Branch Error at %x\n", ctx->pc);
}
@@ -1712,17 +2619,17 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
case OPC2_32_BO_CACHEI_WI_SHORTOFF:
case OPC2_32_BO_CACHEI_W_SHORTOFF:
/* TODO: Raise illegal opcode trap,
- if tricore_feature(TRICORE_FEATURE_13) */
+ if !tricore_feature(TRICORE_FEATURE_131) */
break;
case OPC2_32_BO_CACHEI_W_POSTINC:
case OPC2_32_BO_CACHEI_WI_POSTINC:
- if (!tricore_feature(env, TRICORE_FEATURE_13)) {
+ if (tricore_feature(env, TRICORE_FEATURE_131)) {
tcg_gen_addi_tl(cpu_gpr_d[r2], cpu_gpr_d[r2], off10);
} /* TODO: else raise illegal opcode trap */
break;
case OPC2_32_BO_CACHEI_W_PREINC:
case OPC2_32_BO_CACHEI_WI_PREINC:
- if (!tricore_feature(env, TRICORE_FEATURE_13)) {
+ if (tricore_feature(env, TRICORE_FEATURE_131)) {
tcg_gen_addi_tl(cpu_gpr_d[r2], cpu_gpr_d[r2], off10);
} /* TODO: else raise illegal opcode trap */
break;
@@ -2279,17 +3186,633 @@ static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env,
tcg_temp_free(temp3);
}
+static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
+{
+ int r1, r2;
+ int32_t address;
+ TCGv temp;
+
+ r1 = MASK_OP_BOL_S1D(ctx->opcode);
+ r2 = MASK_OP_BOL_S2(ctx->opcode);
+ address = MASK_OP_BOL_OFF16_SEXT(ctx->opcode);
+
+ switch (op1) {
+ case OPC1_32_BOL_LD_A_LONGOFF:
+ temp = tcg_temp_new();
+ tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);
+ tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LEUL);
+ tcg_temp_free(temp);
+ break;
+ case OPC1_32_BOL_LD_W_LONFOFF:
+ temp = tcg_temp_new();
+ tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);
+ tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUL);
+ tcg_temp_free(temp);
+ break;
+ case OPC1_32_BOL_LEA_LONGOFF:
+ tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], address);
+ break;
+ case OPC1_32_BOL_ST_A_LONGOFF:
+ if (tricore_feature(env, TRICORE_FEATURE_16)) {
+ gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], address, MO_LEUL);
+ } else {
+ /* raise illegal opcode trap */
+ }
+ break;
+ case OPC1_32_BOL_ST_W_LONGOFF:
+ gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUL);
+ break;
+ }
+
+}
+
+/* RC format */
+static void decode_rc_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r2;
+ int32_t const9;
+ TCGv temp;
+
+ r2 = MASK_OP_RC_D(ctx->opcode);
+ r1 = MASK_OP_RC_S1(ctx->opcode);
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ op2 = MASK_OP_RC_OP2(ctx->opcode);
+
+ temp = tcg_temp_new();
+
+ switch (op2) {
+ case OPC2_32_RC_AND:
+ tcg_gen_andi_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ANDN:
+ tcg_gen_andi_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], ~const9);
+ break;
+ case OPC2_32_RC_NAND:
+ tcg_gen_movi_tl(temp, const9);
+ tcg_gen_nand_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_NOR:
+ tcg_gen_movi_tl(temp, const9);
+ tcg_gen_nor_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_OR:
+ tcg_gen_ori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ORN:
+ tcg_gen_ori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], ~const9);
+ break;
+ case OPC2_32_RC_SH:
+ const9 = sextract32(const9, 0, 6);
+ gen_shi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_H:
+ const9 = sextract32(const9, 0, 5);
+ gen_sh_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SHA:
+ const9 = sextract32(const9, 0, 6);
+ gen_shaci(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SHA_H:
+ const9 = sextract32(const9, 0, 5);
+ gen_sha_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SHAS:
+ gen_shasi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_XNOR:
+ tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ tcg_gen_not_tl(cpu_gpr_d[r2], cpu_gpr_d[r2]);
+ break;
+ case OPC2_32_RC_XOR:
+ tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ }
+ tcg_temp_free(temp);
+}
+
+static void decode_rc_accumulator(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r2;
+ int16_t const9;
+
+ TCGv temp;
+
+ r2 = MASK_OP_RC_D(ctx->opcode);
+ r1 = MASK_OP_RC_S1(ctx->opcode);
+ const9 = MASK_OP_RC_CONST9_SEXT(ctx->opcode);
+
+ op2 = MASK_OP_RC_OP2(ctx->opcode);
+
+ temp = tcg_temp_new();
+
+ switch (op2) {
+ case OPC2_32_RC_ABSDIF:
+ gen_absdifi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ABSDIFS:
+ gen_absdifsi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ADD:
+ gen_addi_d(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ADDC:
+ gen_addci_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ADDS:
+ gen_addsi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ADDS_U:
+ gen_addsui(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ADDX:
+ gen_addi_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_AND_EQ:
+ gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_AND_GE:
+ gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_AND_GE_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_AND_LT:
+ gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_AND_LT_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_AND_NE:
+ gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_EQ:
+ tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_EQANY_B:
+ gen_eqany_bi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_EQANY_H:
+ gen_eqany_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_GE:
+ tcg_gen_setcondi_tl(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_GE_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_LT:
+ tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_LT_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_MAX:
+ tcg_gen_movi_tl(temp, const9);
+ tcg_gen_movcond_tl(TCG_COND_GT, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
+ cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_MAX_U:
+ tcg_gen_movi_tl(temp, MASK_OP_RC_CONST9(ctx->opcode));
+ tcg_gen_movcond_tl(TCG_COND_GTU, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
+ cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_MIN:
+ tcg_gen_movi_tl(temp, const9);
+ tcg_gen_movcond_tl(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
+ cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_MIN_U:
+ tcg_gen_movi_tl(temp, MASK_OP_RC_CONST9(ctx->opcode));
+ tcg_gen_movcond_tl(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
+ cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_NE:
+ tcg_gen_setcondi_tl(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_OR_EQ:
+ gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_OR_GE:
+ gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_OR_GE_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_OR_LT:
+ gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_OR_LT_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_OR_NE:
+ gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_RSUB:
+ tcg_gen_movi_tl(temp, const9);
+ gen_sub_d(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
+ break;
+ case OPC2_32_RC_RSUBS:
+ tcg_gen_movi_tl(temp, const9);
+ gen_subs(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
+ break;
+ case OPC2_32_RC_RSUBS_U:
+ tcg_gen_movi_tl(temp, const9);
+ gen_subsu(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
+ break;
+ case OPC2_32_RC_SH_EQ:
+ gen_sh_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_GE:
+ gen_sh_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_GE_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_sh_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_LT:
+ gen_sh_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_LT_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_sh_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_NE:
+ gen_sh_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_XOR_EQ:
+ gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ case OPC2_32_RC_XOR_GE:
+ gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ case OPC2_32_RC_XOR_GE_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ case OPC2_32_RC_XOR_LT:
+ gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ case OPC2_32_RC_XOR_LT_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ case OPC2_32_RC_XOR_NE:
+ gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ }
+ tcg_temp_free(temp);
+}
+
+static void decode_rc_serviceroutine(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ uint32_t const9;
+
+ op2 = MASK_OP_RC_OP2(ctx->opcode);
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RC_BISR:
+ gen_helper_1arg(bisr, const9);
+ break;
+ case OPC2_32_RC_SYSCALL:
+ /* TODO: Add exception generation */
+ break;
+ }
+}
+
+static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r2;
+ int16_t const9;
+
+ r2 = MASK_OP_RC_D(ctx->opcode);
+ r1 = MASK_OP_RC_S1(ctx->opcode);
+ const9 = MASK_OP_RC_CONST9_SEXT(ctx->opcode);
+
+ op2 = MASK_OP_RC_OP2(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RC_MUL_32:
+ gen_muli_i32s(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_MUL_64:
+ gen_muli_i64s(cpu_gpr_d[r2], cpu_gpr_d[r2+1], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_MULS_32:
+ gen_mulsi_i32(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_MUL_U_64:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_muli_i64u(cpu_gpr_d[r2], cpu_gpr_d[r2+1], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_MULS_U_32:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_mulsui_i32(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ }
+}
+
+/* RCPW format */
+static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r2;
+ int32_t pos, width, const4;
+
+ TCGv temp;
+
+ op2 = MASK_OP_RCPW_OP2(ctx->opcode);
+ r1 = MASK_OP_RCPW_S1(ctx->opcode);
+ r2 = MASK_OP_RCPW_D(ctx->opcode);
+ const4 = MASK_OP_RCPW_CONST4(ctx->opcode);
+ width = MASK_OP_RCPW_WIDTH(ctx->opcode);
+ pos = MASK_OP_RCPW_POS(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RCPW_IMASK:
+ /* if pos + width > 31 undefined result */
+ if (pos + width <= 31) {
+ tcg_gen_movi_tl(cpu_gpr_d[r2+1], ((1u << width) - 1) << pos);
+ tcg_gen_movi_tl(cpu_gpr_d[r2], (const4 << pos));
+ }
+ break;
+ case OPC2_32_RCPW_INSERT:
+ /* if pos + width > 32 undefined result */
+ if (pos + width <= 32) {
+ temp = tcg_const_i32(const4);
+ tcg_gen_deposit_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp, pos, width);
+ tcg_temp_free(temp);
+ }
+ break;
+ }
+}
+
+/* RCRW format */
+
+static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r3, r4;
+ int32_t width, const4;
+
+ TCGv temp, temp2, temp3;
+
+ op2 = MASK_OP_RCRW_OP2(ctx->opcode);
+ r1 = MASK_OP_RCRW_S1(ctx->opcode);
+ r3 = MASK_OP_RCRW_S3(ctx->opcode);
+ r4 = MASK_OP_RCRW_D(ctx->opcode);
+ width = MASK_OP_RCRW_WIDTH(ctx->opcode);
+ const4 = MASK_OP_RCRW_CONST4(ctx->opcode);
+
+ temp = tcg_temp_new();
+ temp2 = tcg_temp_new();
+
+ switch (op2) {
+ case OPC2_32_RCRW_IMASK:
+ tcg_gen_andi_tl(temp, cpu_gpr_d[r4], 0x1f);
+ tcg_gen_movi_tl(temp2, (1 << width) - 1);
+ tcg_gen_shl_tl(cpu_gpr_d[r3 + 1], temp2, temp);
+ tcg_gen_movi_tl(temp2, const4);
+ tcg_gen_shl_tl(cpu_gpr_d[r3], temp2, temp);
+ break;
+ case OPC2_32_RCRW_INSERT:
+ temp3 = tcg_temp_new();
+
+ tcg_gen_movi_tl(temp, width);
+ tcg_gen_movi_tl(temp2, const4);
+ tcg_gen_andi_tl(temp3, cpu_gpr_d[r4], 0x1f);
+ gen_insert(cpu_gpr_d[r3], cpu_gpr_d[r1], temp2, temp, temp3);
+
+ tcg_temp_free(temp3);
+ break;
+ }
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
+
+/* RCR format */
+
+static void decode_rcr_cond_select(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r3, r4;
+ int32_t const9;
+
+ TCGv temp, temp2;
+
+ op2 = MASK_OP_RCR_OP2(ctx->opcode);
+ r1 = MASK_OP_RCR_S1(ctx->opcode);
+ const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
+ r3 = MASK_OP_RCR_S3(ctx->opcode);
+ r4 = MASK_OP_RCR_D(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RCR_CADD:
+ gen_condi_add(TCG_COND_NE, cpu_gpr_d[r1], const9, cpu_gpr_d[r3],
+ cpu_gpr_d[r4]);
+ break;
+ case OPC2_32_RCR_CADDN:
+ gen_condi_add(TCG_COND_EQ, cpu_gpr_d[r1], const9, cpu_gpr_d[r3],
+ cpu_gpr_d[r4]);
+ break;
+ case OPC2_32_RCR_SEL:
+ temp = tcg_const_i32(0);
+ temp2 = tcg_const_i32(const9);
+ tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r4], temp,
+ cpu_gpr_d[r1], temp2);
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+ break;
+ case OPC2_32_RCR_SELN:
+ temp = tcg_const_i32(0);
+ temp2 = tcg_const_i32(const9);
+ tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r4], temp,
+ cpu_gpr_d[r1], temp2);
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+ break;
+ }
+}
+
+static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r3, r4;
+ int32_t const9;
+
+
+ op2 = MASK_OP_RCR_OP2(ctx->opcode);
+ r1 = MASK_OP_RCR_S1(ctx->opcode);
+ const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
+ r3 = MASK_OP_RCR_S3(ctx->opcode);
+ r4 = MASK_OP_RCR_D(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RCR_MADD_32:
+ gen_maddi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MADD_64:
+ gen_maddi64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MADDS_32:
+ gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MADDS_64:
+ gen_maddsi_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MADD_U_64:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_maddui64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MADDS_U_32:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_maddsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MADDS_U_64:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_maddsui_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ }
+}
+
+static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r3, r4;
+ int32_t const9;
+
+
+ op2 = MASK_OP_RCR_OP2(ctx->opcode);
+ r1 = MASK_OP_RCR_S1(ctx->opcode);
+ const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
+ r3 = MASK_OP_RCR_S3(ctx->opcode);
+ r4 = MASK_OP_RCR_D(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RCR_MSUB_32:
+ gen_msubi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MSUB_64:
+ gen_msubi64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MSUBS_32:
+ gen_msubsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MSUBS_64:
+ gen_msubsi_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MSUB_U_64:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_msubui64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MSUBS_U_32:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_msubsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MSUBS_U_64:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_msubsui_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ }
+}
+
+/* RLC format */
+
+static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
+ uint32_t op1)
+{
+ int32_t const16;
+ int r1, r2;
+
+ const16 = MASK_OP_RLC_CONST16_SEXT(ctx->opcode);
+ r1 = MASK_OP_RLC_S1(ctx->opcode);
+ r2 = MASK_OP_RLC_D(ctx->opcode);
+
+ switch (op1) {
+ case OPC1_32_RLC_ADDI:
+ gen_addi_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const16);
+ break;
+ case OPC1_32_RLC_ADDIH:
+ gen_addi_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const16 << 16);
+ break;
+ case OPC1_32_RLC_ADDIH_A:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r1], const16 << 16);
+ break;
+ case OPC1_32_RLC_MFCR:
+ gen_mfcr(env, cpu_gpr_d[r2], const16);
+ break;
+ case OPC1_32_RLC_MOV:
+ tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
+ break;
+ case OPC1_32_RLC_MOV_U:
+ const16 = MASK_OP_RLC_CONST16(ctx->opcode);
+ tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
+ break;
+ case OPC1_32_RLC_MOV_H:
+ tcg_gen_movi_tl(cpu_gpr_d[r2], const16 << 16);
+ break;
+ case OPC1_32_RLC_MOVH_A:
+ tcg_gen_movi_tl(cpu_gpr_a[r2], const16 << 16);
+ break;
+ case OPC1_32_RLC_MTCR:
+ gen_mtcr(env, ctx, cpu_gpr_d[r2], const16);
+ break;
+ }
+}
+
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
{
int op1;
- int32_t r1;
- int32_t address;
- int8_t b;
+ int32_t r1, r2, r3;
+ int32_t address, const16;
+ int8_t b, const4;
int32_t bpos;
- TCGv temp, temp2;
+ TCGv temp, temp2, temp3;
op1 = MASK_OP_MAJOR(ctx->opcode);
+ /* handle JNZ.T opcode only being 6 bit long */
+ if (unlikely((op1 & 0x3f) == OPCM_32_BRN_JTT)) {
+ op1 = OPCM_32_BRN_JTT;
+ }
+
switch (op1) {
/* ABS-format */
case OPCM_32_ABS_LDW:
@@ -2405,6 +3928,105 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
case OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR:
decode_bo_addrmode_ldmst_bitreverse_circular(env, ctx);
break;
+/* BOL-format */
+ case OPC1_32_BOL_LD_A_LONGOFF:
+ case OPC1_32_BOL_LD_W_LONFOFF:
+ case OPC1_32_BOL_LEA_LONGOFF:
+ case OPC1_32_BOL_ST_W_LONGOFF:
+ case OPC1_32_BOL_ST_A_LONGOFF:
+ decode_bol_opc(env, ctx, op1);
+ break;
+/* BRC Format */
+ case OPCM_32_BRC_EQ_NEQ:
+ case OPCM_32_BRC_GE:
+ case OPCM_32_BRC_JLT:
+ case OPCM_32_BRC_JNE:
+ const4 = MASK_OP_BRC_CONST4_SEXT(ctx->opcode);
+ address = MASK_OP_BRC_DISP15_SEXT(ctx->opcode);
+ r1 = MASK_OP_BRC_S1(ctx->opcode);
+ gen_compute_branch(ctx, op1, r1, 0, const4, address);
+ break;
+/* BRN Format */
+ case OPCM_32_BRN_JTT:
+ address = MASK_OP_BRN_DISP15_SEXT(ctx->opcode);
+ r1 = MASK_OP_BRN_S1(ctx->opcode);
+ gen_compute_branch(ctx, op1, r1, 0, 0, address);
+ break;
+/* BRR Format */
+ case OPCM_32_BRR_EQ_NEQ:
+ case OPCM_32_BRR_ADDR_EQ_NEQ:
+ case OPCM_32_BRR_GE:
+ case OPCM_32_BRR_JLT:
+ case OPCM_32_BRR_JNE:
+ case OPCM_32_BRR_JNZ:
+ case OPCM_32_BRR_LOOP:
+ address = MASK_OP_BRR_DISP15_SEXT(ctx->opcode);
+ r2 = MASK_OP_BRR_S2(ctx->opcode);
+ r1 = MASK_OP_BRR_S1(ctx->opcode);
+ gen_compute_branch(ctx, op1, r1, r2, 0, address);
+ break;
+/* RC Format */
+ case OPCM_32_RC_LOGICAL_SHIFT:
+ decode_rc_logical_shift(env, ctx);
+ break;
+ case OPCM_32_RC_ACCUMULATOR:
+ decode_rc_accumulator(env, ctx);
+ break;
+ case OPCM_32_RC_SERVICEROUTINE:
+ decode_rc_serviceroutine(env, ctx);
+ break;
+ case OPCM_32_RC_MUL:
+ decode_rc_mul(env, ctx);
+ break;
+/* RCPW Format */
+ case OPCM_32_RCPW_MASK_INSERT:
+ decode_rcpw_insert(env, ctx);
+ break;
+/* RCRR Format */
+ case OPC1_32_RCRR_INSERT:
+ r1 = MASK_OP_RCRR_S1(ctx->opcode);
+ r2 = MASK_OP_RCRR_S3(ctx->opcode);
+ r3 = MASK_OP_RCRR_D(ctx->opcode);
+ const16 = MASK_OP_RCRR_CONST4(ctx->opcode);
+ temp = tcg_const_i32(const16);
+ temp2 = tcg_temp_new(); /* width*/
+ temp3 = tcg_temp_new(); /* pos */
+
+ tcg_gen_andi_tl(temp2, cpu_gpr_d[r3+1], 0x1f);
+ tcg_gen_andi_tl(temp3, cpu_gpr_d[r3], 0x1f);
+
+ gen_insert(cpu_gpr_d[r2], cpu_gpr_d[r1], temp, temp2, temp3);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+ tcg_temp_free(temp3);
+ break;
+/* RCRW Format */
+ case OPCM_32_RCRW_MASK_INSERT:
+ decode_rcrw_insert(env, ctx);
+ break;
+/* RCR Format */
+ case OPCM_32_RCR_COND_SELECT:
+ decode_rcr_cond_select(env, ctx);
+ break;
+ case OPCM_32_RCR_MADD:
+ decode_rcr_madd(env, ctx);
+ break;
+ case OPCM_32_RCR_MSUB:
+ decode_rcr_msub(env, ctx);
+ break;
+/* RLC Format */
+ case OPC1_32_RLC_ADDI:
+ case OPC1_32_RLC_ADDIH:
+ case OPC1_32_RLC_ADDIH_A:
+ case OPC1_32_RLC_MFCR:
+ case OPC1_32_RLC_MOV:
+ case OPC1_32_RLC_MOV_U:
+ case OPC1_32_RLC_MOV_H:
+ case OPC1_32_RLC_MOVH_A:
+ case OPC1_32_RLC_MTCR:
+ decode_rlc_opc(env, ctx, op1);
+ break;
}
}
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 7e6f33bd62..0a9122cfb9 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -115,25 +115,31 @@
#define MASK_OP_BOL_OFF16(op) ((MASK_BITS_SHIFT(op, 16, 21) + \
(MASK_BITS_SHIFT(op, 28, 31) << 6)) + \
(MASK_BITS_SHIFT(op, 22, 27) >> 10))
-
+#define MASK_OP_BOL_OFF16_SEXT(op) ((MASK_BITS_SHIFT(op, 16, 21) + \
+ (MASK_BITS_SHIFT(op, 28, 31) << 6)) + \
+ (MASK_BITS_SHIFT_SEXT(op, 22, 27) << 10))
#define MASK_OP_BOL_S2(op) MASK_BITS_SHIFT(op, 12, 15)
#define MASK_OP_BOL_S1D(op) MASK_BITS_SHIFT(op, 8, 11)
/* BRC Format */
#define MASK_OP_BRC_OP2(op) MASK_BITS_SHIFT(op, 31, 31)
#define MASK_OP_BRC_DISP15(op) MASK_BITS_SHIFT(op, 16, 30)
+#define MASK_OP_BRC_DISP15_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 16, 30)
#define MASK_OP_BRC_CONST4(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_BRC_CONST4_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 15)
#define MASK_OP_BRC_S1(op) MASK_BITS_SHIFT(op, 8, 11)
/* BRN Format */
#define MASK_OP_BRN_OP2(op) MASK_BITS_SHIFT(op, 31, 31)
#define MASK_OP_BRN_DISP15(op) MASK_BITS_SHIFT(op, 16, 30)
+#define MASK_OP_BRN_DISP15_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 16, 30)
#define MASK_OP_BRN_N(op) (MASK_BITS_SHIFT(op, 12, 15) + \
(MASK_BITS_SHIFT(op, 7, 7) << 4))
#define MASK_OP_BRN_S1(op) MASK_BITS_SHIFT(op, 8, 11)
/* BRR Format */
#define MASK_OP_BRR_OP2(op) MASK_BITS_SHIFT(op, 31, 31)
#define MASK_OP_BRR_DISP15(op) MASK_BITS_SHIFT(op, 16, 30)
+#define MASK_OP_BRR_DISP15_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 16, 30)
#define MASK_OP_BRR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
#define MASK_OP_BRR_S1(op) MASK_BITS_SHIFT(op, 8, 11)
@@ -145,6 +151,7 @@
#define MASK_OP_RC_D(op) MASK_OP_META_D(op)
#define MASK_OP_RC_OP2(op) MASK_BITS_SHIFT(op, 21, 27)
#define MASK_OP_RC_CONST9(op) MASK_BITS_SHIFT(op, 12, 20)
+#define MASK_OP_RC_CONST9_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 20)
#define MASK_OP_RC_S1(op) MASK_OP_META_S1(op)
/* RCPW Format */
@@ -162,6 +169,7 @@
#define MASK_OP_RCR_S3(op) MASK_BITS_SHIFT(op, 24, 27)
#define MASK_OP_RCR_OP2(op) MASK_BITS_SHIFT(op, 21, 23)
#define MASK_OP_RCR_CONST9(op) MASK_BITS_SHIFT(op, 12, 20)
+#define MASK_OP_RCR_CONST9_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 20)
#define MASK_OP_RCR_S1(op) MASK_OP_META_S1(op)
/* RCRR Format */
@@ -185,6 +193,7 @@
#define MASK_OP_RLC_D(op) MASK_OP_META_D(op)
#define MASK_OP_RLC_CONST16(op) MASK_BITS_SHIFT(op, 12, 27)
+#define MASK_OP_RLC_CONST16_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 27)
#define MASK_OP_RLC_S1(op) MASK_OP_META_S1(op)
/* RR Format */
@@ -763,8 +772,8 @@ enum {
};
/* OPCM_32_BRC_GE */
enum {
- OP2_BRC_JGE = 0x00,
- OPC_BRC_JGE_U = 0x01,
+ OP2_32_BRC_JGE = 0x00,
+ OPC_32_BRC_JGE_U = 0x01,
};
/* OPCM_32_BRC_JLT */
enum {
@@ -937,7 +946,7 @@ enum {
OPC2_32_RCR_MSUB_64 = 0x03,
OPC2_32_RCR_MSUBS_32 = 0x05,
OPC2_32_RCR_MSUBS_64 = 0x07,
- OPC2_32_RCR_MSUB_U_32 = 0x02,
+ OPC2_32_RCR_MSUB_U_64 = 0x02,
OPC2_32_RCR_MSUBS_U_32 = 0x04,
OPC2_32_RCR_MSUBS_U_64 = 0x06,
};
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 4c77ebec7a..e77fa3a25c 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -487,7 +487,8 @@ static void qtest_shutdown(void)
*/
static QPCIDevice *ahci_boot(void)
{
- qtest_boot("-drive if=none,id=drive0,file=%s,cache=writeback,serial=%s"
+ qtest_boot("-drive if=none,id=drive0,file=%s,cache=writeback,serial=%s,"
+ "format=raw"
" -M q35 "
"-device ide-hd,drive=drive0 "
"-global ide-hd.ver=%s",
diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
index 9e4d20592b..2519f7d0e2 100644
--- a/tests/bios-tables-test.c
+++ b/tests/bios-tables-test.c
@@ -716,7 +716,7 @@ static void test_acpi_one(const char *params, test_data *data)
int i;
args = g_strdup_printf("-net none -display none %s "
- "-drive id=hd0,if=none,file=%s "
+ "-drive id=hd0,if=none,file=%s,format=raw "
"-device ide-hd,drive=hd0 ",
params ? params : "", disk);
diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c
index 53fa969260..8951f6f610 100644
--- a/tests/drive_del-test.c
+++ b/tests/drive_del-test.c
@@ -103,7 +103,7 @@ static void test_after_failed_device_add(void)
static void test_drive_del_device_del(void)
{
/* Start with a drive used by a device that unplugs instantaneously */
- qtest_start("-drive if=none,id=drive0,file=/dev/null"
+ qtest_start("-drive if=none,id=drive0,file=/dev/null,format=raw"
" -device virtio-scsi-pci"
" -device scsi-hd,drive=drive0,id=dev0");
diff --git a/tests/fdc-test.c b/tests/fdc-test.c
index 203074cdad..3c6c83cac4 100644
--- a/tests/fdc-test.c
+++ b/tests/fdc-test.c
@@ -291,7 +291,7 @@ static void test_media_insert(void)
/* Insert media in drive. DSKCHK should not be reset until a step pulse
* is sent. */
qmp_discard_response("{'execute':'change', 'arguments':{"
- " 'device':'floppy0', 'target': %s }}",
+ " 'device':'floppy0', 'target': %s, 'arg': 'raw' }}",
test_image);
qmp_discard_response(""); /* ignore event
(FIXME open -> open transition?!) */
diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c
index c84d1e75e0..7cc8dfff16 100644
--- a/tests/hd-geo-test.c
+++ b/tests/hd-geo-test.c
@@ -208,7 +208,7 @@ static int setup_ide(int argc, char *argv[], int argv_sz,
{
char *s1, *s2, *s3;
- s1 = g_strdup_printf("-drive id=drive%d,if=%s",
+ s1 = g_strdup_printf("-drive id=drive%d,if=%s,format=raw",
ide_idx, dev ? "none" : "ide");
s2 = dev ? g_strdup("") : g_strdup_printf(",index=%d", ide_idx);
diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c
index ad232b561c..a3f72790ea 100644
--- a/tests/i440fx-test.c
+++ b/tests/i440fx-test.c
@@ -342,8 +342,9 @@ static void test_i440fx_firmware(FirmwareTestFixture *fixture,
g_assert(fw_pathname != NULL);
/* Better hope the user didn't put metacharacters in TMPDIR and co. */
- cmdline = g_strdup_printf("-S %s %s",
- fixture->is_bios ? "-bios" : "-pflash",
+ cmdline = g_strdup_printf("-S %s%s", fixture->is_bios
+ ? "-bios "
+ : "-drive if=pflash,format=raw,file=",
fw_pathname);
g_test_message("qemu cmdline: %s", cmdline);
qtest_start(cmdline);
diff --git a/tests/ide-test.c b/tests/ide-test.c
index b7a97e9362..29f4039bd5 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -385,7 +385,7 @@ static void test_bmdma_no_busmaster(void)
static void test_bmdma_setup(void)
{
ide_test_start(
- "-drive file=%s,if=ide,serial=%s,cache=writeback "
+ "-drive file=%s,if=ide,serial=%s,cache=writeback,format=raw "
"-global ide-hd.ver=%s",
tmp_path, "testdisk", "version");
}
@@ -414,7 +414,7 @@ static void test_identify(void)
int ret;
ide_test_start(
- "-drive file=%s,if=ide,serial=%s,cache=writeback "
+ "-drive file=%s,if=ide,serial=%s,cache=writeback,format=raw "
"-global ide-hd.ver=%s",
tmp_path, "testdisk", "version");
@@ -458,7 +458,7 @@ static void test_flush(void)
uint8_t data;
ide_test_start(
- "-drive file=blkdebug::%s,if=ide,cache=writeback",
+ "-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw",
tmp_path);
/* Delay the completion of the flush request until we explicitly do it */
@@ -526,7 +526,8 @@ static void test_retry_flush(void)
ide_test_start(
"-vnc none "
- "-drive file=blkdebug:%s:%s,if=ide,cache=writeback,rerror=stop,werror=stop",
+ "-drive file=blkdebug:%s:%s,if=ide,cache=writeback,format=raw,"
+ "rerror=stop,werror=stop",
debug_path, tmp_path);
/* FLUSH CACHE command on device 0*/
diff --git a/tests/nvme-test.c b/tests/nvme-test.c
index 85768e837b..ff38b5e48f 100644
--- a/tests/nvme-test.c
+++ b/tests/nvme-test.c
@@ -24,7 +24,7 @@ int main(int argc, char **argv)
g_test_init(&argc, &argv, NULL);
qtest_add_func("/nvme/nop", nop);
- qtest_start("-drive id=drv0,if=none,file=/dev/null "
+ qtest_start("-drive id=drv0,if=none,file=/dev/null,format=raw "
"-device nvme,drive=drv0,serial=foo");
ret = g_test_run();
diff --git a/tests/qemu-iotests/001.out b/tests/qemu-iotests/001.out
index 330f5c9afa..b80e098a68 100644
--- a/tests/qemu-iotests/001.out
+++ b/tests/qemu-iotests/001.out
@@ -1,5 +1,5 @@
QA output created by 001
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== reading whole image ==
read 134217728/134217728 bytes at offset 0
diff --git a/tests/qemu-iotests/002.out b/tests/qemu-iotests/002.out
index cd6aa0f9fa..1b46b34ad3 100644
--- a/tests/qemu-iotests/002.out
+++ b/tests/qemu-iotests/002.out
@@ -1,5 +1,5 @@
QA output created by 002
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== reading whole image ==
read 134217728/134217728 bytes at offset 0
diff --git a/tests/qemu-iotests/003.out b/tests/qemu-iotests/003.out
index 4942482bab..e7641230fa 100644
--- a/tests/qemu-iotests/003.out
+++ b/tests/qemu-iotests/003.out
@@ -1,5 +1,5 @@
QA output created by 003
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== reading whole image ==
read 134217728/134217728 bytes at offset 0
diff --git a/tests/qemu-iotests/004.out b/tests/qemu-iotests/004.out
index f1ed4d896a..fb8593289f 100644
--- a/tests/qemu-iotests/004.out
+++ b/tests/qemu-iotests/004.out
@@ -1,5 +1,5 @@
QA output created by 004
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
write before image boundary
wrote 1048576/1048576 bytes at offset 133169152
diff --git a/tests/qemu-iotests/005.out b/tests/qemu-iotests/005.out
index 2d3e7df25a..10044c34ae 100644
--- a/tests/qemu-iotests/005.out
+++ b/tests/qemu-iotests/005.out
@@ -1,7 +1,7 @@
QA output created by 005
creating large image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=5368709120000
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=5368709120000
small read
read 4096/4096 bytes at offset 1024
diff --git a/tests/qemu-iotests/006.out b/tests/qemu-iotests/006.out
index f82fbfbe25..d135841b70 100644
--- a/tests/qemu-iotests/006.out
+++ b/tests/qemu-iotests/006.out
@@ -2,5 +2,5 @@ QA output created by 006
creating 128GB image
qemu-img: The image size is too large for file format 'vpc'
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=137438953472
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=137438953472
*** done
diff --git a/tests/qemu-iotests/007.out b/tests/qemu-iotests/007.out
index cf3d17da27..571505368f 100644
--- a/tests/qemu-iotests/007.out
+++ b/tests/qemu-iotests/007.out
@@ -1,7 +1,7 @@
QA output created by 007
creating image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
savevm 1
savevm 2
savevm 3
diff --git a/tests/qemu-iotests/008.out b/tests/qemu-iotests/008.out
index 0acbb86ea5..08475c8a0d 100644
--- a/tests/qemu-iotests/008.out
+++ b/tests/qemu-iotests/008.out
@@ -1,5 +1,5 @@
QA output created by 008
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== reading whole image ==
read 134217728/134217728 bytes at offset 0
diff --git a/tests/qemu-iotests/009.out b/tests/qemu-iotests/009.out
index 180e451689..19e15d0c7b 100644
--- a/tests/qemu-iotests/009.out
+++ b/tests/qemu-iotests/009.out
@@ -1,7 +1,7 @@
QA output created by 009
creating image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
creating pattern
wrote 4096/4096 bytes at offset 2097152
diff --git a/tests/qemu-iotests/010.out b/tests/qemu-iotests/010.out
index cc5c9414f7..1bee037d7a 100644
--- a/tests/qemu-iotests/010.out
+++ b/tests/qemu-iotests/010.out
@@ -1,7 +1,7 @@
QA output created by 010
creating image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
creating pattern
wrote 4096/4096 bytes at offset 2097152
diff --git a/tests/qemu-iotests/011.out b/tests/qemu-iotests/011.out
index dfec17d184..65c998eaa1 100644
--- a/tests/qemu-iotests/011.out
+++ b/tests/qemu-iotests/011.out
@@ -1,7 +1,7 @@
QA output created by 011
creating image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
overlapping I/O
wrote 1048576/1048576 bytes at offset XXX
diff --git a/tests/qemu-iotests/012.out b/tests/qemu-iotests/012.out
index 5f9b9900b3..c4ffa8f608 100644
--- a/tests/qemu-iotests/012.out
+++ b/tests/qemu-iotests/012.out
@@ -1,5 +1,5 @@
QA output created by 012
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== mark image read-only
diff --git a/tests/qemu-iotests/013.out b/tests/qemu-iotests/013.out
index 43a414cbf6..317cdf4b48 100644
--- a/tests/qemu-iotests/013.out
+++ b/tests/qemu-iotests/013.out
@@ -1,5 +1,5 @@
QA output created by 013
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
Testing empty image
At offset 0:
diff --git a/tests/qemu-iotests/014.out b/tests/qemu-iotests/014.out
index 4744b4b214..f19341c87e 100644
--- a/tests/qemu-iotests/014.out
+++ b/tests/qemu-iotests/014.out
@@ -1,5 +1,5 @@
QA output created by 014
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
Testing empty image:
test2: With offset 0
=== Clusters to be compressed [1]
diff --git a/tests/qemu-iotests/015.out b/tests/qemu-iotests/015.out
index d4b961c82c..3414afd9ee 100644
--- a/tests/qemu-iotests/015.out
+++ b/tests/qemu-iotests/015.out
@@ -1,7 +1,7 @@
QA output created by 015
creating image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=37748736
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=37748736
creating first snapshot
wrote 37748736/37748736 bytes at offset 0
36 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/016 b/tests/qemu-iotests/016
index 7ea9e94b5d..52397aa80e 100755
--- a/tests/qemu-iotests/016
+++ b/tests/qemu-iotests/016
@@ -43,25 +43,28 @@ _supported_proto file sheepdog nfs
_supported_os Linux
+# No -f, use probing for the protocol driver
+QEMU_IO_PROTO="$QEMU_IO_PROG -g --cache $CACHEMODE"
+
size=128M
_make_test_img $size
echo
echo "== reading at EOF =="
-$QEMU_IO -g -c "read -P 0 $size 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO_PROTO -c "read -P 0 $size 512" "$TEST_IMG" | _filter_qemu_io
echo
echo "== reading far past EOF =="
-$QEMU_IO -g -c "read -P 0 256M 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO_PROTO -c "read -P 0 256M 512" "$TEST_IMG" | _filter_qemu_io
echo
echo "== writing at EOF =="
-$QEMU_IO -g -c "write -P 66 $size 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO_PROTO -c "write -P 66 $size 512" "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c "read -P 66 $size 512" "$TEST_IMG" | _filter_qemu_io
echo
echo "== writing far past EOF =="
-$QEMU_IO -g -c "write -P 66 256M 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO_PROTO -c "write -P 66 256M 512" "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c "read -P 66 256M 512" "$TEST_IMG" | _filter_qemu_io
# success, all done
diff --git a/tests/qemu-iotests/016.out b/tests/qemu-iotests/016.out
index 18679780d0..acbd60b4a3 100644
--- a/tests/qemu-iotests/016.out
+++ b/tests/qemu-iotests/016.out
@@ -1,5 +1,5 @@
QA output created by 016
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== reading at EOF ==
read 512/512 bytes at offset 134217728
diff --git a/tests/qemu-iotests/017.out b/tests/qemu-iotests/017.out
index 75ea61481e..7c409fc5bc 100644
--- a/tests/qemu-iotests/017.out
+++ b/tests/qemu-iotests/017.out
@@ -269,7 +269,7 @@ wrote 65536/65536 bytes at offset 4295032832
No errors were found on the image.
Creating test image with backing file
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
Filling test image
=== IO: pattern 1
diff --git a/tests/qemu-iotests/018.out b/tests/qemu-iotests/018.out
index 25e7b95708..39a6011d29 100644
--- a/tests/qemu-iotests/018.out
+++ b/tests/qemu-iotests/018.out
@@ -269,7 +269,7 @@ wrote 65536/65536 bytes at offset 4295032832
No errors were found on the image.
Creating test image with backing file
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
Filling test image
=== IO: pattern 1
diff --git a/tests/qemu-iotests/019.out b/tests/qemu-iotests/019.out
index f0c6e6375f..4695b972d5 100644
--- a/tests/qemu-iotests/019.out
+++ b/tests/qemu-iotests/019.out
@@ -1,5 +1,5 @@
QA output created by 019
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
Filling base image
=== IO: pattern 42
@@ -269,7 +269,7 @@ wrote 65536/65536 bytes at offset 4296015872
No errors were found on the image.
Creating test image with backing file
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
Filling test image
=== IO: pattern 43
diff --git a/tests/qemu-iotests/020.out b/tests/qemu-iotests/020.out
index fc9a63cf19..71aab1c747 100644
--- a/tests/qemu-iotests/020.out
+++ b/tests/qemu-iotests/020.out
@@ -1,5 +1,5 @@
QA output created by 020
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
Filling base image
=== IO: pattern 0
@@ -269,7 +269,7 @@ wrote 65536/65536 bytes at offset 4295032832
No errors were found on the image.
Creating test image with backing file
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
Filling test image
=== IO: pattern 1
diff --git a/tests/qemu-iotests/021.out b/tests/qemu-iotests/021.out
index ed4448c56b..8533f8e58a 100644
--- a/tests/qemu-iotests/021.out
+++ b/tests/qemu-iotests/021.out
@@ -1,5 +1,5 @@
QA output created by 021
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== testing writev -P -1 ==
-1 is not a valid pattern byte
diff --git a/tests/qemu-iotests/022.out b/tests/qemu-iotests/022.out
index 5a729e07e7..dbe9cdb0e7 100644
--- a/tests/qemu-iotests/022.out
+++ b/tests/qemu-iotests/022.out
@@ -1,5 +1,5 @@
QA output created by 022
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
Testing empty image
At offset 10485760:
diff --git a/tests/qemu-iotests/023.out b/tests/qemu-iotests/023.out
index ec32341e3a..d4e9be25e1 100644
--- a/tests/qemu-iotests/023.out
+++ b/tests/qemu-iotests/023.out
@@ -1,7 +1,7 @@
QA output created by 023
Creating new image; cluster size: 1024
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
Testing empty image
At offset 0:
@@ -5664,7 +5664,7 @@ read 3072/3072 bytes at offset 4295491072
No errors were found on the image.
Creating another new image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
More complex patterns
test2: With offset 0
@@ -5887,7 +5887,7 @@ read 2048/2048 bytes at offset 4295001088
No errors were found on the image.
Creating new image; cluster size: 4096
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
Testing empty image
At offset 0:
@@ -12270,7 +12270,7 @@ read 12288/12288 bytes at offset 4301256704
No errors were found on the image.
Creating another new image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
More complex patterns
test2: With offset 0
@@ -12493,7 +12493,7 @@ read 8192/8192 bytes at offset 4295102464
No errors were found on the image.
Creating new image; cluster size: 16384
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
Testing empty image
At offset 0:
@@ -18876,7 +18876,7 @@ read 49152/49152 bytes at offset 4395622400
No errors were found on the image.
Creating another new image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
More complex patterns
test2: With offset 0
@@ -19099,7 +19099,7 @@ read 32768/32768 bytes at offset 4295507968
No errors were found on the image.
Creating new image; cluster size: 65536
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
Testing empty image
At offset 0:
@@ -25482,7 +25482,7 @@ read 196608/196608 bytes at offset 5905547264
No errors were found on the image.
Creating another new image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8589934592
More complex patterns
test2: With offset 0
diff --git a/tests/qemu-iotests/024.out b/tests/qemu-iotests/024.out
index e84b9730f5..521d469425 100644
--- a/tests/qemu-iotests/024.out
+++ b/tests/qemu-iotests/024.out
@@ -1,7 +1,7 @@
QA output created by 024
Creating backing file
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
=== IO: pattern 0x11
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -21,7 +21,7 @@ wrote 65536/65536 bytes at offset 917504
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Creating new backing file
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
=== IO: pattern 0x22
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -33,7 +33,7 @@ wrote 131072/131072 bytes at offset 786432
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Creating COW image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 backing_file='TEST_DIR/t.IMGFMT.base_old'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 backing_file='TEST_DIR/t.IMGFMT.base_old'
=== IO: pattern 0x33
wrote 262144/262144 bytes at offset 0
256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/025.out b/tests/qemu-iotests/025.out
index 8c695e6394..f13fc2863c 100644
--- a/tests/qemu-iotests/025.out
+++ b/tests/qemu-iotests/025.out
@@ -1,7 +1,7 @@
QA output created by 025
=== Creating image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
=== Writing whole image
=== IO: pattern 0xc5
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
index f7c78e712a..524f7ee21c 100644
--- a/tests/qemu-iotests/026.out
+++ b/tests/qemu-iotests/026.out
@@ -1,63 +1,71 @@
QA output created by 026
Errors while writing 128 kB
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l1_update; errno: 5; imm: off; once: on; write
+Event: l1_update; errno: 5; imm: off; once: on; write
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: on; write -b
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l1_update; errno: 5; imm: off; once: off; write
+Event: l1_update; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
1 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
1 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l1_update; errno: 28; imm: off; once: on; write
+Event: l1_update; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l1_update; errno: 28; imm: off; once: off; write
+Event: l1_update; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
1 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
1 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_load; errno: 5; imm: off; once: on; write
+Event: l2_load; errno: 5; imm: off; once: on; write
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write failed: Input/output error
read failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 5; imm: off; once: on; write -b
wrote 131072/131072 bytes at offset 0
@@ -65,31 +73,39 @@ wrote 131072/131072 bytes at offset 0
write failed: Input/output error
read failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_load; errno: 5; imm: off; once: off; write
+Event: l2_load; errno: 5; imm: off; once: off; write
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
read failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 5; imm: off; once: off; write -b
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
read failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_load; errno: 28; imm: off; once: on; write
+Event: l2_load; errno: 28; imm: off; once: on; write
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write failed: No space left on device
read failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 28; imm: off; once: on; write -b
wrote 131072/131072 bytes at offset 0
@@ -97,437 +113,529 @@ wrote 131072/131072 bytes at offset 0
write failed: No space left on device
read failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_load; errno: 28; imm: off; once: off; write
+Event: l2_load; errno: 28; imm: off; once: off; write
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
read failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 28; imm: off; once: off; write -b
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
read failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_update; errno: 5; imm: off; once: on; write
+Event: l2_update; errno: 5; imm: off; once: on; write
+Failed to flush the L2 table cache: Input/output error
write failed: Input/output error
127 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 5; imm: off; once: on; write -b
+Failed to flush the L2 table cache: Input/output error
write failed: Input/output error
127 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_update; errno: 5; imm: off; once: off; write
+Event: l2_update; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
127 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
127 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_update; errno: 28; imm: off; once: on; write
+Event: l2_update; errno: 28; imm: off; once: on; write
+Failed to flush the L2 table cache: No space left on device
write failed: No space left on device
127 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 28; imm: off; once: on; write -b
+Failed to flush the L2 table cache: No space left on device
write failed: No space left on device
127 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_update; errno: 28; imm: off; once: off; write
+Event: l2_update; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
127 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
127 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_alloc.write; errno: 5; imm: off; once: on; write
+Event: l2_alloc.write; errno: 5; imm: off; once: on; write
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc.write; errno: 5; imm: off; once: on; write -b
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_alloc.write; errno: 5; imm: off; once: off; write
+Event: l2_alloc.write; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc.write; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
1 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_alloc.write; errno: 28; imm: off; once: on; write
+Event: l2_alloc.write; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc.write; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: l2_alloc.write; errno: 28; imm: off; once: off; write
+Event: l2_alloc.write; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc.write; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
1 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: write_aio; errno: 5; imm: off; once: on; write
+Event: write_aio; errno: 5; imm: off; once: on; write
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 5; imm: off; once: on; write -b
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: write_aio; errno: 5; imm: off; once: off; write
+Event: write_aio; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: write_aio; errno: 28; imm: off; once: on; write
+Event: write_aio; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: write_aio; errno: 28; imm: off; once: off; write
+Event: write_aio; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_load; errno: 5; imm: off; once: on; write
+Event: refblock_load; errno: 5; imm: off; once: on; write
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: on; write -b
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_load; errno: 5; imm: off; once: off; write
+Event: refblock_load; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_load; errno: 28; imm: off; once: on; write
+Event: refblock_load; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_load; errno: 28; imm: off; once: off; write
+Event: refblock_load; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_update_part; errno: 5; imm: off; once: on; write
+Event: refblock_update_part; errno: 5; imm: off; once: on; write
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: on; write -b
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_update_part; errno: 5; imm: off; once: off; write
+Event: refblock_update_part; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_update_part; errno: 28; imm: off; once: on; write
+Event: refblock_update_part; errno: 28; imm: off; once: on; write
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: on; write -b
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_update_part; errno: 28; imm: off; once: off; write
+Event: refblock_update_part; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc; errno: 5; imm: off; once: on; write
+Event: refblock_alloc; errno: 5; imm: off; once: on; write
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: on; write -b
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc; errno: 5; imm: off; once: off; write
+Event: refblock_alloc; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc; errno: 28; imm: off; once: on; write
+Event: refblock_alloc; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc; errno: 28; imm: off; once: off; write
+Event: refblock_alloc; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: cluster_alloc; errno: 5; imm: off; once: on; write
+Event: cluster_alloc; errno: 5; imm: off; once: on; write
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 5; imm: off; once: on; write -b
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: cluster_alloc; errno: 5; imm: off; once: off; write
+Event: cluster_alloc; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: cluster_alloc; errno: 28; imm: off; once: on; write
+Event: cluster_alloc; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: cluster_alloc; errno: 28; imm: off; once: off; write
+Event: cluster_alloc; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
=== Refcout table growth tests ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc.hookup; errno: 28; imm: off; once: on; write
+Event: refblock_alloc.hookup; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.hookup; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc.hookup; errno: 28; imm: off; once: off; write
+Event: refblock_alloc.hookup; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
55 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.hookup; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
251 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc.write; errno: 28; imm: off; once: on; write
+Event: refblock_alloc.write; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc.write; errno: 28; imm: off; once: off; write
+Event: refblock_alloc.write; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: on; write
+Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: off; write
+Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
11 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
23 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc.write_table; errno: 28; imm: off; once: on; write
+Event: refblock_alloc.write_table; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write_table; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc.write_table; errno: 28; imm: off; once: off; write
+Event: refblock_alloc.write_table; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
11 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write_table; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
23 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc.switch_table; errno: 28; imm: off; once: on; write
+Event: refblock_alloc.switch_table; errno: 28; imm: off; once: on; write
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.switch_table; errno: 28; imm: off; once: on; write -b
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Event: refblock_alloc.switch_table; errno: 28; imm: off; once: off; write
+Event: refblock_alloc.switch_table; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
11 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.switch_table; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
23 leaked clusters were found on the image.
@@ -535,66 +643,78 @@ This means waste of disk space, but no harm to data.
=== L1 growth tests ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.alloc_table; errno: 5; imm: off; once: on
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.alloc_table; errno: 5; imm: off; once: off
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.alloc_table; errno: 28; imm: off; once: on
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.alloc_table; errno: 28; imm: off; once: off
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.write_table; errno: 5; imm: off; once: on
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.write_table; errno: 5; imm: off; once: off
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.write_table; errno: 28; imm: off; once: on
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.write_table; errno: 28; imm: off; once: off
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.activate_table; errno: 5; imm: off; once: on
write failed: Input/output error
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.activate_table; errno: 5; imm: off; once: off
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
96 leaked clusters were found on the image.
This means waste of disk space, but no harm to data.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.activate_table; errno: 28; imm: off; once: on
write failed: No space left on device
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.activate_table; errno: 28; imm: off; once: off
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
96 leaked clusters were found on the image.
diff --git a/tests/qemu-iotests/027.out b/tests/qemu-iotests/027.out
index 4fcb4161da..c7bca71083 100644
--- a/tests/qemu-iotests/027.out
+++ b/tests/qemu-iotests/027.out
@@ -1,5 +1,5 @@
QA output created by 027
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== writing first cluster to populate metadata ==
wrote 65536/65536 bytes at offset 65536
diff --git a/tests/qemu-iotests/028.out b/tests/qemu-iotests/028.out
index e8d02459be..5db167ce78 100644
--- a/tests/qemu-iotests/028.out
+++ b/tests/qemu-iotests/028.out
@@ -1,5 +1,5 @@
QA output created by 028
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=3221227008
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=3221227008
Filling base image
=== IO: pattern 195
@@ -70,7 +70,7 @@ wrote 512/512 bytes at offset 3221225984
No errors were found on the image.
Creating test image with backing file
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294968832 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294968832 backing_file='TEST_DIR/t.IMGFMT.base'
Filling test image
=== IO: pattern 196
@@ -469,7 +469,7 @@ No errors were found on the image.
block-backup
Formatting 'TEST_DIR/t.IMGFMT.copy', fmt=IMGFMT size=4294968832 backing_file='TEST_DIR/t.IMGFMT.base' backing_fmt='IMGFMT'
-(qemu)
+(qemu)
(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block-info block-jinfo block-joinfo block-jobinfo block-jobs
Type backup, device disk: Completed 0 of 4294968832 bytes, speed limit 0 bytes/s
iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block-info block-jinfo block-joinfo block-jobinfo block-jobs
diff --git a/tests/qemu-iotests/029.out b/tests/qemu-iotests/029.out
index ce0e64d24a..5bc93e0451 100644
--- a/tests/qemu-iotests/029.out
+++ b/tests/qemu-iotests/029.out
@@ -3,18 +3,18 @@ QA output created by 029
Test loading internal snapshots where the L1 table of the snapshot
is smaller than the current L1 table.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
No errors were found on the image.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216
wrote 4194304/4194304 bytes at offset 0
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
No errors were found on the image.
Try using a huge VM state
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 4096/4096 bytes at offset 1099511627776
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 4096/4096 bytes at offset 1099511627776
@@ -23,5 +23,5 @@ No errors were found on the image.
qcow2_snapshot_load_tmp() should take the L1 size from the snapshot
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
*** done
diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index 8ce2373cf5..952a524ec7 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -34,7 +34,7 @@ class TestSingleDrive(iotests.QMPTestCase):
iotests.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)
- qemu_io('-c', 'write -P 0x1 0 512', backing_img)
+ qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 512', backing_img)
self.vm = iotests.VM().add_drive("blkdebug::" + test_img)
self.vm.launch()
@@ -55,8 +55,8 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_no_active_block_jobs()
self.vm.shutdown()
- self.assertEqual(qemu_io('-c', 'map', backing_img),
- qemu_io('-c', 'map', test_img),
+ self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
'image file map does not match backing file after streaming')
def test_stream_pause(self):
@@ -86,8 +86,8 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_no_active_block_jobs()
self.vm.shutdown()
- self.assertEqual(qemu_io('-c', 'map', backing_img),
- qemu_io('-c', 'map', test_img),
+ self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
'image file map does not match backing file after streaming')
def test_stream_partial(self):
@@ -101,8 +101,8 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_no_active_block_jobs()
self.vm.shutdown()
- self.assertEqual(qemu_io('-c', 'map', mid_img),
- qemu_io('-c', 'map', test_img),
+ self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', mid_img),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
'image file map does not match backing file after streaming')
def test_device_not_found(self):
@@ -359,9 +359,9 @@ class TestStreamStop(iotests.QMPTestCase):
def setUp(self):
qemu_img('create', backing_img, str(TestStreamStop.image_len))
- qemu_io('-c', 'write -P 0x1 0 32M', backing_img)
+ qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 32M', backing_img)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
- qemu_io('-c', 'write -P 0x1 32M 32M', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 32M 32M', test_img)
self.vm = iotests.VM().add_drive("blkdebug::" + test_img)
self.vm.launch()
@@ -388,9 +388,9 @@ class TestSetSpeed(iotests.QMPTestCase):
def setUp(self):
qemu_img('create', backing_img, str(TestSetSpeed.image_len))
- qemu_io('-c', 'write -P 0x1 0 32M', backing_img)
+ qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 32M', backing_img)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
- qemu_io('-c', 'write -P 0x1 32M 32M', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 32M 32M', test_img)
self.vm = iotests.VM().add_drive('blkdebug::' + test_img)
self.vm.launch()
diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out
index a94334478e..fce3ce0984 100644
--- a/tests/qemu-iotests/031.out
+++ b/tests/qemu-iotests/031.out
@@ -4,7 +4,7 @@ QA output created by 031
=== Create image with unknown header extension ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
magic 0x514649fb
version 2
backing_file_offset 0x0
@@ -105,7 +105,7 @@ data 'This is a test header extension'
=== Create image with unknown header extension ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
magic 0x514649fb
version 3
backing_file_offset 0x0
diff --git a/tests/qemu-iotests/032.out b/tests/qemu-iotests/032.out
index ca20de676d..ce27d5dfdc 100644
--- a/tests/qemu-iotests/032.out
+++ b/tests/qemu-iotests/032.out
@@ -2,7 +2,7 @@ QA output created by 032
=== Prepare image ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 65536/65536 bytes at offset 131072
diff --git a/tests/qemu-iotests/033.out b/tests/qemu-iotests/033.out
index 2fe74df763..41475eefea 100644
--- a/tests/qemu-iotests/033.out
+++ b/tests/qemu-iotests/033.out
@@ -1,5 +1,5 @@
QA output created by 033
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== preparing image ==
wrote 1024/1024 bytes at offset 512
diff --git a/tests/qemu-iotests/034.out b/tests/qemu-iotests/034.out
index e82dae55f7..d12daf206f 100644
--- a/tests/qemu-iotests/034.out
+++ b/tests/qemu-iotests/034.out
@@ -1,10 +1,10 @@
QA output created by 034
== creating backing file for COW tests ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
== zero write with backing file ==
wrote 196608/196608 bytes at offset 65536
diff --git a/tests/qemu-iotests/035.out b/tests/qemu-iotests/035.out
index cde21d8135..dd3bd201d9 100644
--- a/tests/qemu-iotests/035.out
+++ b/tests/qemu-iotests/035.out
@@ -1,7 +1,7 @@
QA output created by 035
creating image
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944
wrote 512/512 bytes at offset XXX
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset XXX
diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out
index 720bd89161..5616e37b3f 100644
--- a/tests/qemu-iotests/036.out
+++ b/tests/qemu-iotests/036.out
@@ -2,7 +2,7 @@ QA output created by 036
=== Image with unknown incompatible feature bit ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
magic 0x514649fb
version 3
backing_file_offset 0x0
@@ -27,7 +27,7 @@ qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature whic
=== Image with multiple incompatible feature bits ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Unknown incompatible feature: e000000000000000
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Test feature, Unknown incompatible feature: 6000000000000000
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Test feature, Unknown incompatible feature: c000000000000000
@@ -36,7 +36,7 @@ qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature whic
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: test2, Unknown incompatible feature: a000000000000000
=== Create image with unknown autoclear feature bit ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
magic 0x514649fb
version 3
backing_file_offset 0x0
diff --git a/tests/qemu-iotests/037.out b/tests/qemu-iotests/037.out
index 4eb84ed55a..dc40a021a4 100644
--- a/tests/qemu-iotests/037.out
+++ b/tests/qemu-iotests/037.out
@@ -1,7 +1,7 @@
QA output created by 037
== creating backing file for COW tests ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 512
@@ -514,7 +514,7 @@ wrote 512/512 bytes at offset 130048
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 130560
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+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
diff --git a/tests/qemu-iotests/038.out b/tests/qemu-iotests/038.out
index a71c3fa359..e1a7e94410 100644
--- a/tests/qemu-iotests/038.out
+++ b/tests/qemu-iotests/038.out
@@ -1,7 +1,7 @@
QA output created by 038
== creating backing file for COW tests ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 65536/65536 bytes at offset 65536
@@ -514,7 +514,7 @@ wrote 65536/65536 bytes at offset 16646144
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 65536/65536 bytes at offset 16711680
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
== Some concurrent requests touching the same cluster ==
wrote 65536/65536 bytes at offset XXX
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
index 84c9167660..859705f848 100755
--- a/tests/qemu-iotests/039
+++ b/tests/qemu-iotests/039
@@ -47,9 +47,11 @@ _supported_os Linux
_default_cache_mode "writethrough"
_supported_cache_modes "writethrough"
-_no_dump_exec()
+_subshell_exec()
{
- (ulimit -c 0; exec "$@")
+ # Executing crashing commands in a subshell prevents information like the
+ # "Killed" line from being lost
+ (exec "$@")
}
size=128M
@@ -72,7 +74,9 @@ echo "== Creating a dirty image file =="
IMGOPTS="compat=1.1,lazy_refcounts=on"
_make_test_img $size
-_no_dump_exec $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" 2>&1 | _filter_qemu_io
+_subshell_exec $QEMU_IO -c "write -P 0x5a 0 512" \
+ -c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
+ | _filter_qemu_io
# The dirty bit must be set
$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
@@ -105,7 +109,9 @@ echo "== Opening a dirty image read/write should repair it =="
IMGOPTS="compat=1.1,lazy_refcounts=on"
_make_test_img $size
-_no_dump_exec $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" 2>&1 | _filter_qemu_io
+_subshell_exec $QEMU_IO -c "write -P 0x5a 0 512" \
+ -c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
+ | _filter_qemu_io
# The dirty bit must be set
$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
@@ -121,7 +127,9 @@ echo "== Creating an image file with lazy_refcounts=off =="
IMGOPTS="compat=1.1,lazy_refcounts=off"
_make_test_img $size
-_no_dump_exec $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" 2>&1 | _filter_qemu_io
+_subshell_exec $QEMU_IO -c "write -P 0x5a 0 512" \
+ -c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
+ | _filter_qemu_io
# The dirty bit must not be set since lazy_refcounts=off
$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out
index 0adf1535ef..d09751f9c8 100644
--- a/tests/qemu-iotests/039.out
+++ b/tests/qemu-iotests/039.out
@@ -1,17 +1,17 @@
QA output created by 039
== Checking that image is clean on shutdown ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
incompatible_features 0x0
No errors were found on the image.
== Creating a dirty image file ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./039: Aborted ( ulimit -c 0; exec "$@" )
+./039: Killed ( exec "$@" )
incompatible_features 0x1
ERROR cluster 5 refcount=0 reference=1
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
@@ -43,10 +43,10 @@ read 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== Opening a dirty image read/write should repair it ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./039: Aborted ( ulimit -c 0; exec "$@" )
+./039: Killed ( exec "$@" )
incompatible_features 0x1
ERROR cluster 5 refcount=0 reference=1
Rebuilding refcount structure
@@ -57,16 +57,16 @@ wrote 512/512 bytes at offset 0
incompatible_features 0x0
== Creating an image file with lazy_refcounts=off ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./039: Aborted ( ulimit -c 0; exec "$@" )
+./039: Killed ( exec "$@" )
incompatible_features 0x0
No errors were found on the image.
== Committing to a backing file with lazy_refcounts=on ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base'
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Image committed.
diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
index 2b432ad7a1..ea2f98e51d 100755
--- a/tests/qemu-iotests/040
+++ b/tests/qemu-iotests/040
@@ -76,8 +76,8 @@ class TestSingleDrive(ImageCommitTestCase):
iotests.create_image(backing_img, self.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)
- qemu_io('-c', 'write -P 0xab 0 524288', backing_img)
- qemu_io('-c', 'write -P 0xef 524288 524288', mid_img)
+ qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', backing_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
self.vm = iotests.VM().add_drive(test_img)
self.vm.launch()
@@ -89,8 +89,8 @@ class TestSingleDrive(ImageCommitTestCase):
def test_commit(self):
self.run_commit_test(mid_img, backing_img)
- self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
- self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
+ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
+ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
def test_device_not_found(self):
result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % mid_img)
@@ -116,13 +116,13 @@ class TestSingleDrive(ImageCommitTestCase):
def test_top_is_active(self):
self.run_commit_test(test_img, backing_img, need_ready=True)
- self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
- self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
+ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
+ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
def test_top_is_default_active(self):
self.run_default_commit_test()
- self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
- self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
+ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
+ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
def test_top_and_base_reversed(self):
self.assert_no_active_block_jobs()
@@ -159,8 +159,8 @@ class TestRelativePaths(ImageCommitTestCase):
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.mid_img_abs, self.test_img)
qemu_img('rebase', '-u', '-b', self.backing_img, self.mid_img_abs)
qemu_img('rebase', '-u', '-b', self.mid_img, self.test_img)
- qemu_io('-c', 'write -P 0xab 0 524288', self.backing_img_abs)
- qemu_io('-c', 'write -P 0xef 524288 524288', self.mid_img_abs)
+ qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', self.backing_img_abs)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', self.mid_img_abs)
self.vm = iotests.VM().add_drive(self.test_img)
self.vm.launch()
@@ -179,8 +179,8 @@ class TestRelativePaths(ImageCommitTestCase):
def test_commit(self):
self.run_commit_test(self.mid_img, self.backing_img)
- self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
- self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
+ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
+ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
def test_device_not_found(self):
result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % self.mid_img)
@@ -206,8 +206,8 @@ class TestRelativePaths(ImageCommitTestCase):
def test_top_is_active(self):
self.run_commit_test(self.test_img, self.backing_img)
- self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
- self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
+ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
+ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
def test_top_and_base_reversed(self):
self.assert_no_active_block_jobs()
@@ -223,8 +223,8 @@ class TestSetSpeed(ImageCommitTestCase):
qemu_img('create', backing_img, str(TestSetSpeed.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)
- qemu_io('-c', 'write -P 0x1 0 512', test_img)
- qemu_io('-c', 'write -P 0xef 524288 524288', mid_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 0 512', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
self.vm = iotests.VM().add_drive(test_img)
self.vm.launch()
diff --git a/tests/qemu-iotests/042.out b/tests/qemu-iotests/042.out
index dc80f4b5b3..8ab1520020 100644
--- a/tests/qemu-iotests/042.out
+++ b/tests/qemu-iotests/042.out
@@ -1,7 +1,7 @@
QA output created by 042
== Creating zero size image ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
No errors were found on the image.
== Converting the image ==
diff --git a/tests/qemu-iotests/043.out b/tests/qemu-iotests/043.out
index ad23337db5..012cc008e3 100644
--- a/tests/qemu-iotests/043.out
+++ b/tests/qemu-iotests/043.out
@@ -1,23 +1,23 @@
QA output created by 043
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== backing file references self ==
qemu-img: Backing file 'TEST_DIR/t.IMGFMT' creates an infinite loop.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base'
== parent references self ==
qemu-img: Backing file 'TEST_DIR/t.IMGFMT' creates an infinite loop.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.1.base'
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.2.base'
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.3.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.1.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.2.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.3.base'
== ancestor references another ancestor ==
qemu-img: Backing file 'TEST_DIR/t.IMGFMT.2.base' creates an infinite loop.
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.1.base'
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.2.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.1.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.2.base'
== finite chain of length 3 (human) ==
image: TEST_DIR/t.IMGFMT
@@ -40,26 +40,26 @@ cluster_size: 65536
== finite chain of length 3 (json) ==
[
{
- "virtual-size": 134217728,
- "filename": "TEST_DIR/t.IMGFMT",
- "cluster-size": 65536,
- "format": "IMGFMT",
- "backing-filename": "TEST_DIR/t.IMGFMT.2.base",
+ "virtual-size": 134217728,
+ "filename": "TEST_DIR/t.IMGFMT",
+ "cluster-size": 65536,
+ "format": "IMGFMT",
+ "backing-filename": "TEST_DIR/t.IMGFMT.2.base",
"dirty-flag": false
- },
+ },
{
- "virtual-size": 134217728,
- "filename": "TEST_DIR/t.IMGFMT.2.base",
- "cluster-size": 65536,
- "format": "IMGFMT",
- "backing-filename": "TEST_DIR/t.IMGFMT.1.base",
+ "virtual-size": 134217728,
+ "filename": "TEST_DIR/t.IMGFMT.2.base",
+ "cluster-size": 65536,
+ "format": "IMGFMT",
+ "backing-filename": "TEST_DIR/t.IMGFMT.1.base",
"dirty-flag": false
- },
+ },
{
- "virtual-size": 134217728,
- "filename": "TEST_DIR/t.IMGFMT.1.base",
- "cluster-size": 65536,
- "format": "IMGFMT",
+ "virtual-size": 134217728,
+ "filename": "TEST_DIR/t.IMGFMT.1.base",
+ "cluster-size": 65536,
+ "format": "IMGFMT",
"dirty-flag": false
}
]
diff --git a/tests/qemu-iotests/046.out b/tests/qemu-iotests/046.out
index 65d584bcfe..9d18af53a1 100644
--- a/tests/qemu-iotests/046.out
+++ b/tests/qemu-iotests/046.out
@@ -1,7 +1,7 @@
QA output created by 046
== creating backing file for COW tests ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 65536/65536 bytes at offset 65536
@@ -66,7 +66,7 @@ wrote 65536/65536 bytes at offset 1966080
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 65536/65536 bytes at offset 2031616
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
== Some concurrent requests touching the same cluster ==
blkdebug: Suspended request 'A'
diff --git a/tests/qemu-iotests/047.out b/tests/qemu-iotests/047.out
index 959f2afa6c..856a2bcf87 100644
--- a/tests/qemu-iotests/047.out
+++ b/tests/qemu-iotests/047.out
@@ -1,5 +1,5 @@
QA output created by 047
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 327680/327680 bytes at offset 0
320 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 131072/131072 bytes at offset 327680
diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048
index 65da46d6f5..e1eeac2a31 100755
--- a/tests/qemu-iotests/048
+++ b/tests/qemu-iotests/048
@@ -64,7 +64,7 @@ _compare
_compare -q
# Compare images with different size
-$QEMU_IMG resize "$TEST_IMG" +512M
+$QEMU_IMG resize -f $IMGFMT "$TEST_IMG" +512M
_compare
_compare -s
diff --git a/tests/qemu-iotests/048.out b/tests/qemu-iotests/048.out
index c0f380d3a3..57100dc453 100644
--- a/tests/qemu-iotests/048.out
+++ b/tests/qemu-iotests/048.out
@@ -1,5 +1,5 @@
QA output created by 048
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
=== IO: pattern 45
wrote 4096/4096 bytes at offset 524288
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -28,7 +28,7 @@ wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Content mismatch at offset 0!
1
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
=== IO: pattern 100
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
index 09ca0aed49..b6311b01b9 100644
--- a/tests/qemu-iotests/049.out
+++ b/tests/qemu-iotests/049.out
@@ -4,90 +4,90 @@ QA output created by 049
== 1. Traditional size parameter ==
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024b
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1k
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1K
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1G
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1T
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0b
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5k
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5K
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5G
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5T
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 encryption=off cluster_size=65536 lazy_refcounts=off
== 2. Specifying size via -o ==
qemu-img create -f qcow2 -o size=1024 TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1024b TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1k TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1K TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1M TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1G TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1T TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1024.0 TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1024.0b TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1.5k TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1.5K TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1.5M TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1.5G TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o size=1.5T TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 encryption=off cluster_size=65536 lazy_refcounts=off
== 3. Invalid sizes ==
@@ -97,7 +97,7 @@ qemu-img: Image size must be less than 8 EiB!
qemu-img create -f qcow2 -o size=-1024 TEST_DIR/t.qcow2
qemu-img: qcow2 doesn't support shrinking images yet
qemu-img: TEST_DIR/t.qcow2: Could not resize image: Operation not supported
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=-1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=-1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1k
qemu-img: Image size must be less than 8 EiB!
@@ -105,17 +105,17 @@ qemu-img: Image size must be less than 8 EiB!
qemu-img create -f qcow2 -o size=-1k TEST_DIR/t.qcow2
qemu-img: qcow2 doesn't support shrinking images yet
qemu-img: TEST_DIR/t.qcow2: Could not resize image: Operation not supported
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=-1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=-1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte
-qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
+qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
qemu-img create -f qcow2 -o size=1kilobyte TEST_DIR/t.qcow2
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- foobar
-qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
+qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
qemu-img create -f qcow2 -o size=foobar TEST_DIR/t.qcow2
@@ -125,84 +125,84 @@ qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2'
== Check correct interpretation of suffixes for cluster size ==
qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
qemu-img create -f qcow2 -o cluster_size=1024b TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
qemu-img create -f qcow2 -o cluster_size=1k TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
qemu-img create -f qcow2 -o cluster_size=1K TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
qemu-img create -f qcow2 -o cluster_size=1M TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1048576 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1048576 lazy_refcounts=off
qemu-img create -f qcow2 -o cluster_size=1024.0 TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
qemu-img create -f qcow2 -o cluster_size=1024.0b TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off
qemu-img create -f qcow2 -o cluster_size=0.5k TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=512 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=512 lazy_refcounts=off
qemu-img create -f qcow2 -o cluster_size=0.5K TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=512 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=512 lazy_refcounts=off
qemu-img create -f qcow2 -o cluster_size=0.5M TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=524288 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=524288 lazy_refcounts=off
== Check compat level option ==
qemu-img create -f qcow2 -o compat=0.10 TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.10' encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.10' encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='1.1' encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='1.1' encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M
qemu-img: TEST_DIR/t.qcow2: Invalid compatibility level: '0.42'
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.42' encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.42' encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M
qemu-img: TEST_DIR/t.qcow2: Invalid compatibility level: 'foobar'
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='foobar' encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='foobar' encryption=off cluster_size=65536 lazy_refcounts=off
== Check preallocation option ==
qemu-img create -f qcow2 -o preallocation=off TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='off' lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='off' lazy_refcounts=off
qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='metadata' lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='metadata' lazy_refcounts=off
qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
qemu-img: TEST_DIR/t.qcow2: invalid parameter value: 1234
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='1234' lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='1234' lazy_refcounts=off
== Check encryption option ==
qemu-img create -f qcow2 -o encryption=off TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o encryption=on TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on cluster_size=65536 lazy_refcounts=off
== Check lazy_refcounts option (only with v3) ==
qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=off TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='1.1' encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='1.1' encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=on TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='1.1' encryption=off cluster_size=65536 lazy_refcounts=on
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='1.1' encryption=off cluster_size=65536 lazy_refcounts=on
qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off TEST_DIR/t.qcow2 64M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.10' encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.10' encryption=off cluster_size=65536 lazy_refcounts=off
qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M
qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility level 1.1 and above (use compat=1.1 or greater)
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.10' encryption=off cluster_size=65536 lazy_refcounts=on
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.10' encryption=off cluster_size=65536 lazy_refcounts=on
*** done
diff --git a/tests/qemu-iotests/050.out b/tests/qemu-iotests/050.out
index 3f5f7e1e7b..a6cb2e686d 100644
--- a/tests/qemu-iotests/050.out
+++ b/tests/qemu-iotests/050.out
@@ -1,13 +1,13 @@
QA output created by 050
== Creating images ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=10485760
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=10485760
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=10485760
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=10485760
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=10485760 backing_file='TEST_DIR/t.IMGFMT.old'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=10485760 backing_file='TEST_DIR/t.IMGFMT.old'
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index 2c7e808765..f497c5717b 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -1,6 +1,6 @@
QA output created by 051
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base'
=== Unknown option ===
@@ -50,6 +50,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DI
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
ide0-hd0: TEST_DIR/t.qcow2 (qcow2)
+ Cache mode: writeback
Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1)
(qemu) qququiquit
@@ -85,7 +86,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=foo: could n
=== With version 2 images enabling lazy refcounts must fail ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: could not open disk image TEST_DIR/t.qcow2: Lazy refcounts require a qcow2 image with at least qemu 1.1 compatibility level
diff --git a/tests/qemu-iotests/052.out b/tests/qemu-iotests/052.out
index 8617aa2a9e..9dab51c0e8 100644
--- a/tests/qemu-iotests/052.out
+++ b/tests/qemu-iotests/052.out
@@ -1,5 +1,5 @@
QA output created by 052
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== reading whole image ==
read 134217728/134217728 bytes at offset 0
diff --git a/tests/qemu-iotests/053.out b/tests/qemu-iotests/053.out
index 16464e6dde..8e793b6462 100644
--- a/tests/qemu-iotests/053.out
+++ b/tests/qemu-iotests/053.out
@@ -1,7 +1,7 @@
QA output created by 053
== Creating single sector image ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=512
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=512
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/054.out b/tests/qemu-iotests/054.out
index 7161d6e50b..e6ec430edd 100644
--- a/tests/qemu-iotests/054.out
+++ b/tests/qemu-iotests/054.out
@@ -2,9 +2,9 @@ QA output created by 054
creating too large image (1 EB)
qemu-img: TEST_DIR/t.IMGFMT: The image size is too large for file format 'IMGFMT' (try using a larger cluster size)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1152921504606846976
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1152921504606846976
creating too large image (1 EB) using qcow2.py
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296
qemu-img: Could not open 'TEST_DIR/t.qcow2': Image is too big
*** done
diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
index 451b67ddfb..0872444811 100755
--- a/tests/qemu-iotests/055
+++ b/tests/qemu-iotests/055
@@ -34,10 +34,10 @@ class TestSingleDrive(iotests.QMPTestCase):
def setUp(self):
# Write data to the image so we can compare later
qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleDrive.image_len))
- qemu_io('-c', 'write -P0x5d 0 64k', test_img)
- qemu_io('-c', 'write -P0xd5 1M 32k', test_img)
- qemu_io('-c', 'write -P0xdc 32M 124k', test_img)
- qemu_io('-c', 'write -P0xdc 67043328 64k', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 64k', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 67043328 64k', test_img)
self.vm = iotests.VM().add_drive(test_img)
self.vm.launch()
@@ -115,7 +115,7 @@ class TestSetSpeed(iotests.QMPTestCase):
def setUp(self):
qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSetSpeed.image_len))
- qemu_io('-c', 'write -P1 0 512', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P1 0 512', test_img)
self.vm = iotests.VM().add_drive(test_img)
self.vm.launch()
@@ -186,10 +186,10 @@ class TestSingleTransaction(iotests.QMPTestCase):
def setUp(self):
qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleTransaction.image_len))
- qemu_io('-c', 'write -P0x5d 0 64k', test_img)
- qemu_io('-c', 'write -P0xd5 1M 32k', test_img)
- qemu_io('-c', 'write -P0xdc 32M 124k', test_img)
- qemu_io('-c', 'write -P0xdc 67043328 64k', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 64k', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 67043328 64k', test_img)
self.vm = iotests.VM().add_drive(test_img)
self.vm.launch()
diff --git a/tests/qemu-iotests/058 b/tests/qemu-iotests/058
index 14584cdea2..2d5ca85ddc 100755
--- a/tests/qemu-iotests/058
+++ b/tests/qemu-iotests/058
@@ -89,6 +89,9 @@ _supported_fmt qcow2
_supported_proto file
_require_command QEMU_NBD
+# Use -f raw instead of -f $IMGFMT for the NBD connection
+QEMU_IO_NBD="$QEMU_IO -f raw --cache=$CACHEMODE"
+
echo
echo "== preparing image =="
_make_test_img 64M
@@ -108,15 +111,15 @@ _export_nbd_snapshot sn1
echo
echo "== verifying the exported snapshot with patterns, method 1 =="
-$QEMU_IO -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
-$QEMU_IO -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
+$QEMU_IO_NBD -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
+$QEMU_IO_NBD -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
_export_nbd_snapshot1 sn1
echo
echo "== verifying the exported snapshot with patterns, method 2 =="
-$QEMU_IO -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
-$QEMU_IO -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
+$QEMU_IO_NBD -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
+$QEMU_IO_NBD -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
$QEMU_IMG convert "$TEST_IMG" -l sn1 -O qcow2 "$converted_image"
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index 3c053c29b4..50ca5ce681 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -106,11 +106,17 @@ _img_info
echo
echo "=== Converting to streamOptimized from image with small cluster size==="
TEST_IMG="$TEST_IMG.qcow2" IMGFMT=qcow2 IMGOPTS="cluster_size=4096" _make_test_img 1G
-$QEMU_IO -c "write -P 0xa 0 512" "$TEST_IMG.qcow2" | _filter_qemu_io
-$QEMU_IO -c "write -P 0xb 10240 512" "$TEST_IMG.qcow2" | _filter_qemu_io
+$QEMU_IO -f qcow2 -c "write -P 0xa 0 512" "$TEST_IMG.qcow2" | _filter_qemu_io
+$QEMU_IO -f qcow2 -c "write -P 0xb 10240 512" "$TEST_IMG.qcow2" | _filter_qemu_io
$QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2" "$TEST_IMG" 2>&1
echo
+echo "=== Testing monolithicFlat with internally generated JSON file name ==="
+IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
+$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" 2>&1 \
+ | _filter_testdir | _filter_imgfmt
+
+echo
echo "=== Testing version 3 ==="
_use_sample_img iotest-version3.vmdk.bz2
_img_info
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 0dadba658f..cbb0de4254 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -2053,6 +2053,10 @@ wrote 512/512 bytes at offset 0
wrote 512/512 bytes at offset 10240
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+=== Testing monolithicFlat with internally generated JSON file name ===
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "read_aio"}'
+
=== Testing version 3 ===
image: TEST_DIR/iotest-version3.IMGFMT
file format: IMGFMT
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
index 9772d365ae..73863bf1f6 100755
--- a/tests/qemu-iotests/060
+++ b/tests/qemu-iotests/060
@@ -77,7 +77,7 @@ $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
# This information should be available through qemu-img info
-$QEMU_IMG info "$TEST_IMG" | _filter_testdir
+_img_info --format-specific
# Try to open the image R/W (which should fail)
$QEMU_IO -c "$OPEN_RW" -c "read 0 512" 2>&1 | _filter_qemu_io \
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
index 9419da1b41..7d493bbe61 100644
--- a/tests/qemu-iotests/060.out
+++ b/tests/qemu-iotests/060.out
@@ -2,7 +2,7 @@ QA output created by 060
=== Testing L2 reference into L1 ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
ERROR cluster 3 refcount=1 reference=3
1 errors were found on the image.
@@ -11,10 +11,9 @@ incompatible_features 0x0
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with active L1 table); further corruption events will be suppressed
write failed: Input/output error
incompatible_features 0x2
-image: TEST_DIR/t.qcow2
-file format: qcow2
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
virtual size: 64M (67108864 bytes)
-disk size: 196K
cluster_size: 65536
Format specific information:
compat: 1.1
@@ -26,7 +25,7 @@ read 512/512 bytes at offset 0
=== Testing cluster data reference into refcount block ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
ERROR refcount block 0 refcount=2
ERROR cluster 2 refcount=1 reference=2
@@ -55,7 +54,7 @@ incompatible_features 0x0
=== Testing cluster data reference into inactive L2 table ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 0
@@ -96,7 +95,7 @@ read 512/512 bytes at offset 0
=== Testing overlap while COW is in flight ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 65536/65536 bytes at offset 536870912
@@ -111,7 +110,7 @@ aio_write failed: No medium found
=== Testing unallocated image header ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with qcow2_header); further corruption events will be suppressed
@@ -119,7 +118,7 @@ write failed: Input/output error
=== Testing unaligned L1 entry ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: L2 table offset 0x42a00 unaligned (L1 index: 0); further corruption events will be suppressed
@@ -127,7 +126,7 @@ read failed: Input/output error
=== Testing unaligned L2 entry ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Data cluster offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
@@ -135,13 +134,13 @@ read failed: Input/output error
=== Testing unaligned reftable entry ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qcow2: Marking image as corrupt: Refblock offset 0x22a00 unaligned (reftable index: 0); further corruption events will be suppressed
write failed: Input/output error
=== Testing non-fatal corruption on freeing ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Image is corrupt: Cannot free unaligned cluster 0x52a00; further non-fatal corruption events will be suppressed
@@ -150,7 +149,7 @@ discard 65536/65536 bytes at offset 0
=== Testing read-only corruption report ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Image is corrupt: Data cluster offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further non-fatal corruption events will be suppressed
@@ -159,7 +158,7 @@ read failed: Input/output error
=== Testing non-fatal and then fatal corruption report ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Image is corrupt: Cannot free unaligned cluster 0x52a00; further non-fatal corruption events will be suppressed
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
index 9045544df2..e70f9834d8 100644
--- a/tests/qemu-iotests/061.out
+++ b/tests/qemu-iotests/061.out
@@ -2,7 +2,7 @@ QA output created by 061
=== Testing version downgrade with zero expansion ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
magic 0x514649fb
@@ -54,7 +54,7 @@ No errors were found on the image.
=== Testing dirty version downgrade ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
magic 0x514649fb
@@ -111,7 +111,7 @@ No errors were found on the image.
=== Testing version downgrade with unknown compat/autoclear flags ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
magic 0x514649fb
version 3
backing_file_offset 0x0
@@ -159,7 +159,7 @@ No errors were found on the image.
=== Testing version upgrade and resize ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 44040192
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
magic 0x514649fb
@@ -211,7 +211,7 @@ No errors were found on the image.
=== Testing dirty lazy_refcounts=off ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
magic 0x514649fb
@@ -268,8 +268,8 @@ No errors were found on the image.
=== Testing backing file ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 131072/131072 bytes at offset 0
@@ -280,7 +280,7 @@ No errors were found on the image.
=== Testing invalid configurations ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Lazy refcounts only supported with compatibility level 1.1 and above (use compat=1.1 or greater)
qemu-img: Error while amending options: Invalid argument
Lazy refcounts only supported with compatibility level 1.1 and above (use compat=1.1 or greater)
@@ -298,7 +298,7 @@ qemu-img: Error while amending options: Operation not supported
=== Testing correct handling of unset value ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Should work:
Should not work:
Changing the cluster size is not supported.
@@ -306,7 +306,7 @@ qemu-img: Error while amending options: Operation not supported
=== Testing zero expansion on inactive clusters ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 131072/131072 bytes at offset 0
@@ -320,7 +320,7 @@ read 131072/131072 bytes at offset 0
=== Testing zero expansion on shared L2 table ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
No errors were found on the image.
@@ -332,10 +332,10 @@ read 131072/131072 bytes at offset 0
=== Testing zero expansion on backed image ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
read 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 65536/65536 bytes at offset 0
@@ -348,10 +348,10 @@ read 65536/65536 bytes at offset 65536
=== Testing zero expansion on backed inactive clusters ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 131072/131072 bytes at offset 0
@@ -367,10 +367,10 @@ read 65536/65536 bytes at offset 65536
=== Testing zero expansion on backed image with shared L2 table ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
No errors were found on the image.
@@ -382,7 +382,7 @@ read 131072/131072 bytes at offset 0
=== Testing preallocated zero expansion on full image ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 67108864/67108864 bytes at offset 0
64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 67108864/67108864 bytes at offset 0
@@ -393,8 +393,8 @@ read 67108864/67108864 bytes at offset 0
=== Testing progress report without snapshot ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=4294967296
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=4294967296
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 backing_file='TEST_DIR/t.IMGFMT.base'
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 65536/65536 bytes at offset 1073741824
@@ -408,8 +408,8 @@ No errors were found on the image.
=== Testing progress report with snapshot ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=4294967296
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=4294967296
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 backing_file='TEST_DIR/t.IMGFMT.base'
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 65536/65536 bytes at offset 1073741824
diff --git a/tests/qemu-iotests/062.out b/tests/qemu-iotests/062.out
index 442d761959..9ddf22b43c 100644
--- a/tests/qemu-iotests/062.out
+++ b/tests/qemu-iotests/062.out
@@ -2,7 +2,7 @@ QA output created by 062
=== Testing snapshotting an image with zero clusters ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 262144/262144 bytes at offset 0
256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
No errors were found on the image.
diff --git a/tests/qemu-iotests/066.out b/tests/qemu-iotests/066.out
index 9139780f49..7bc9a107d5 100644
--- a/tests/qemu-iotests/066.out
+++ b/tests/qemu-iotests/066.out
@@ -2,7 +2,7 @@ QA output created by 066
=== Testing snapshotting an image with zero clusters ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 262144/262144 bytes at offset 0
256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 262144/262144 bytes at offset 0
diff --git a/tests/qemu-iotests/067 b/tests/qemu-iotests/067
index d025192c83..29cd6b5aff 100755
--- a/tests/qemu-iotests/067
+++ b/tests/qemu-iotests/067
@@ -39,7 +39,7 @@ _supported_os Linux
function do_run_qemu()
{
echo Testing: "$@"
- $QEMU -nographic -qmp stdio -serial none "$@"
+ $QEMU -nographic -qmp-pretty stdio -serial none "$@"
echo
}
diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out
index 0f72dcf63a..13ff3cd7aa 100644
--- a/tests/qemu-iotests/067.out
+++ b/tests/qemu-iotests/067.out
@@ -1,80 +1,770 @@
QA output created by 067
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
=== -drive/-device and device_del ===
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virtio-blk-pci,drive=disk,id=virtio0
-QMP_VERSION
-{"return": {}}
-{"return": [{"io-status": "ok", "device": "disk", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "type": "unknown"}, {"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]}
-{"return": {}}
-{"return": {}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"}
-{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]}
-{"return": {}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+{
+ QMP_VERSION
+}
+{
+ "return": {
+ }
+}
+{
+ "return": [
+ {
+ "io-status": "ok",
+ "device": "disk",
+ "locked": false,
+ "removable": false,
+ "inserted": {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "virtual-size": 134217728,
+ "filename": "TEST_DIR/t.qcow2",
+ "cluster-size": 65536,
+ "format": "qcow2",
+ "actual-size": SIZE,
+ "format-specific": {
+ "type": "qcow2",
+ "data": {
+ "compat": "1.1",
+ "lazy-refcounts": false,
+ "corrupt": false
+ }
+ },
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": false,
+ "backing_file_depth": 0,
+ "drv": "qcow2",
+ "iops": 0,
+ "bps_wr": 0,
+ "encrypted": false,
+ "bps": 0,
+ "bps_rd": 0,
+ "cache": {
+ "no-flush": false,
+ "direct": false,
+ "writeback": true
+ },
+ "file": "TEST_DIR/t.qcow2",
+ "encryption_key_missing": false
+ },
+ "type": "unknown"
+ },
+ {
+ "io-status": "ok",
+ "device": "ide1-cd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "floppy0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "sd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ }
+ ]
+}
+{
+ "return": {
+ }
+}
+{
+ "return": {
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_DELETED",
+ "data": {
+ "path": "/machine/peripheral/virtio0/virtio-backend"
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_DELETED",
+ "data": {
+ "device": "virtio0",
+ "path": "/machine/peripheral/virtio0"
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "RESET"
+}
+{
+ "return": [
+ {
+ "io-status": "ok",
+ "device": "ide1-cd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "floppy0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "sd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ }
+ ]
+}
+{
+ "return": {
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "SHUTDOWN"
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_TRAY_MOVED",
+ "data": {
+ "device": "ide1-cd0",
+ "tray-open": true
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_TRAY_MOVED",
+ "data": {
+ "device": "floppy0",
+ "tray-open": true
+ }
+}
=== -drive/device_add and device_del ===
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk
-QMP_VERSION
-{"return": {}}
-{"return": [{"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}, {"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]}
-{"return": {}}
-{"return": {}}
-{"return": {}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"}
-{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]}
-{"return": {}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+{
+ QMP_VERSION
+}
+{
+ "return": {
+ }
+}
+{
+ "return": [
+ {
+ "device": "disk",
+ "locked": false,
+ "removable": true,
+ "inserted": {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "virtual-size": 134217728,
+ "filename": "TEST_DIR/t.qcow2",
+ "cluster-size": 65536,
+ "format": "qcow2",
+ "actual-size": SIZE,
+ "format-specific": {
+ "type": "qcow2",
+ "data": {
+ "compat": "1.1",
+ "lazy-refcounts": false,
+ "corrupt": false
+ }
+ },
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": false,
+ "backing_file_depth": 0,
+ "drv": "qcow2",
+ "iops": 0,
+ "bps_wr": 0,
+ "encrypted": false,
+ "bps": 0,
+ "bps_rd": 0,
+ "cache": {
+ "no-flush": false,
+ "direct": false,
+ "writeback": true
+ },
+ "file": "TEST_DIR/t.qcow2",
+ "encryption_key_missing": false
+ },
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "io-status": "ok",
+ "device": "ide1-cd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "floppy0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "sd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ }
+ ]
+}
+{
+ "return": {
+ }
+}
+{
+ "return": {
+ }
+}
+{
+ "return": {
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_DELETED",
+ "data": {
+ "path": "/machine/peripheral/virtio0/virtio-backend"
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_DELETED",
+ "data": {
+ "device": "virtio0",
+ "path": "/machine/peripheral/virtio0"
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "RESET"
+}
+{
+ "return": [
+ {
+ "io-status": "ok",
+ "device": "ide1-cd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "floppy0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "sd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ }
+ ]
+}
+{
+ "return": {
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "SHUTDOWN"
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_TRAY_MOVED",
+ "data": {
+ "device": "ide1-cd0",
+ "tray-open": true
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_TRAY_MOVED",
+ "data": {
+ "device": "floppy0",
+ "tray-open": true
+ }
+}
=== drive_add/device_add and device_del ===
Testing:
-QMP_VERSION
-{"return": {}}
-{"return": "OK\r\n"}
-{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]}
-{"return": {}}
-{"return": {}}
-{"return": {}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"}
-{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]}
-{"return": {}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+{
+ QMP_VERSION
+}
+{
+ "return": {
+ }
+}
+{
+ "return": "OK\r\n"
+}
+{
+ "return": [
+ {
+ "io-status": "ok",
+ "device": "ide1-cd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "floppy0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "sd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "disk",
+ "locked": false,
+ "removable": true,
+ "inserted": {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "virtual-size": 134217728,
+ "filename": "TEST_DIR/t.qcow2",
+ "cluster-size": 65536,
+ "format": "qcow2",
+ "actual-size": SIZE,
+ "format-specific": {
+ "type": "qcow2",
+ "data": {
+ "compat": "1.1",
+ "lazy-refcounts": false,
+ "corrupt": false
+ }
+ },
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": false,
+ "backing_file_depth": 0,
+ "drv": "qcow2",
+ "iops": 0,
+ "bps_wr": 0,
+ "encrypted": false,
+ "bps": 0,
+ "bps_rd": 0,
+ "cache": {
+ "no-flush": false,
+ "direct": false,
+ "writeback": true
+ },
+ "file": "TEST_DIR/t.qcow2",
+ "encryption_key_missing": false
+ },
+ "tray_open": false,
+ "type": "unknown"
+ }
+ ]
+}
+{
+ "return": {
+ }
+}
+{
+ "return": {
+ }
+}
+{
+ "return": {
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_DELETED",
+ "data": {
+ "path": "/machine/peripheral/virtio0/virtio-backend"
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_DELETED",
+ "data": {
+ "device": "virtio0",
+ "path": "/machine/peripheral/virtio0"
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "RESET"
+}
+{
+ "return": [
+ {
+ "io-status": "ok",
+ "device": "ide1-cd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "floppy0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "sd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ }
+ ]
+}
+{
+ "return": {
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "SHUTDOWN"
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_TRAY_MOVED",
+ "data": {
+ "device": "ide1-cd0",
+ "tray-open": true
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_TRAY_MOVED",
+ "data": {
+ "device": "floppy0",
+ "tray-open": true
+ }
+}
=== blockdev_add/device_add and device_del ===
Testing:
-QMP_VERSION
-{"return": {}}
-{"return": {}}
-{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]}
-{"return": {}}
-{"return": {}}
-{"return": {}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"}
-{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"io-status": "ok", "device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]}
-{"return": {}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+{
+ QMP_VERSION
+}
+{
+ "return": {
+ }
+}
+{
+ "return": {
+ }
+}
+{
+ "return": [
+ {
+ "io-status": "ok",
+ "device": "ide1-cd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "floppy0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "sd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "disk",
+ "locked": false,
+ "removable": true,
+ "inserted": {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "virtual-size": 134217728,
+ "filename": "TEST_DIR/t.qcow2",
+ "cluster-size": 65536,
+ "format": "qcow2",
+ "actual-size": SIZE,
+ "format-specific": {
+ "type": "qcow2",
+ "data": {
+ "compat": "1.1",
+ "lazy-refcounts": false,
+ "corrupt": false
+ }
+ },
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": false,
+ "backing_file_depth": 0,
+ "drv": "qcow2",
+ "iops": 0,
+ "bps_wr": 0,
+ "encrypted": false,
+ "bps": 0,
+ "bps_rd": 0,
+ "cache": {
+ "no-flush": false,
+ "direct": false,
+ "writeback": true
+ },
+ "file": "TEST_DIR/t.qcow2",
+ "encryption_key_missing": false
+ },
+ "tray_open": false,
+ "type": "unknown"
+ }
+ ]
+}
+{
+ "return": {
+ }
+}
+{
+ "return": {
+ }
+}
+{
+ "return": {
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_DELETED",
+ "data": {
+ "path": "/machine/peripheral/virtio0/virtio-backend"
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_DELETED",
+ "data": {
+ "device": "virtio0",
+ "path": "/machine/peripheral/virtio0"
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "RESET"
+}
+{
+ "return": [
+ {
+ "io-status": "ok",
+ "device": "ide1-cd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "floppy0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "device": "sd0",
+ "locked": false,
+ "removable": true,
+ "tray_open": false,
+ "type": "unknown"
+ },
+ {
+ "io-status": "ok",
+ "device": "disk",
+ "locked": false,
+ "removable": true,
+ "inserted": {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "virtual-size": 134217728,
+ "filename": "TEST_DIR/t.qcow2",
+ "cluster-size": 65536,
+ "format": "qcow2",
+ "actual-size": SIZE,
+ "format-specific": {
+ "type": "qcow2",
+ "data": {
+ "compat": "1.1",
+ "lazy-refcounts": false,
+ "corrupt": false
+ }
+ },
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": false,
+ "backing_file_depth": 0,
+ "drv": "qcow2",
+ "iops": 0,
+ "bps_wr": 0,
+ "encrypted": false,
+ "bps": 0,
+ "bps_rd": 0,
+ "cache": {
+ "no-flush": false,
+ "direct": false,
+ "writeback": true
+ },
+ "file": "TEST_DIR/t.qcow2",
+ "encryption_key_missing": false
+ },
+ "tray_open": false,
+ "type": "unknown"
+ }
+ ]
+}
+{
+ "return": {
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "SHUTDOWN"
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_TRAY_MOVED",
+ "data": {
+ "device": "ide1-cd0",
+ "tray-open": true
+ }
+}
+{
+ "timestamp": {
+ "seconds": TIMESTAMP,
+ "microseconds": TIMESTAMP
+ },
+ "event": "DEVICE_TRAY_MOVED",
+ "data": {
+ "device": "floppy0",
+ "tray-open": true
+ }
+}
*** done
diff --git a/tests/qemu-iotests/068.out b/tests/qemu-iotests/068.out
index abe35a9f8c..84f19b4ffd 100644
--- a/tests/qemu-iotests/068.out
+++ b/tests/qemu-iotests/068.out
@@ -2,7 +2,7 @@ QA output created by 068
=== Saving and reloading a VM state to/from a qcow2 image ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) ssasavsavesavevsavevmsavevm savevm 0
(qemu) qququiquit
diff --git a/tests/qemu-iotests/069.out b/tests/qemu-iotests/069.out
index b48306d5ab..4d7e63cf88 100644
--- a/tests/qemu-iotests/069.out
+++ b/tests/qemu-iotests/069.out
@@ -2,7 +2,7 @@ QA output created by 069
=== Creating an image with a backing file and deleting that file ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=131072
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=131072
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file='TEST_DIR/t.IMGFMT.base'
qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open backing file: Could not open 'TEST_DIR/t.IMGFMT.base': No such file or directory
*** done
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
index 3924e51f51..5d61ef6d81 100755
--- a/tests/qemu-iotests/071
+++ b/tests/qemu-iotests/071
@@ -63,12 +63,12 @@ echo
TEST_IMG="$TEST_IMG.base" IMGOPTS="" IMGFMT="raw" _make_test_img $IMG_SIZE |\
_filter_imgfmt
_make_test_img $IMG_SIZE
-$QEMU_IO -c "open -o file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
+$QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
-c 'read 0 512' -c 'write -P 42 0x38000 512' -c 'read -P 42 0x38000 512' | _filter_qemu_io
$QEMU_IO -c 'write -P 42 0 512' "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "open -o file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
+$QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
-c 'read -P 42 0 512' | _filter_qemu_io
echo
@@ -78,12 +78,12 @@ echo
TEST_IMG="$TEST_IMG.base" IMGOPTS="" IMGFMT="raw" _make_test_img $IMG_SIZE |\
_filter_imgfmt
_make_test_img $IMG_SIZE
-$QEMU_IO -c "open -o file.driver=blkverify,file.raw.filename=$TEST_IMG.base,file.test.driver=$IMGFMT,file.test.file.filename=$TEST_IMG" \
+$QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base,file.test.driver=$IMGFMT,file.test.file.filename=$TEST_IMG" \
-c 'read 0 512' -c 'write -P 42 0x38000 512' -c 'read -P 42 0x38000 512' | _filter_qemu_io
$QEMU_IO -c 'write -P 42 0 512' "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "open -o file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
+$QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
-c 'read -P 42 0 512' | _filter_qemu_io
echo
@@ -163,7 +163,7 @@ echo
echo "=== Testing blkverify on existing raw block device ==="
echo
-run_qemu -drive "file=$TEST_IMG.base,if=none,id=drive0" <<EOF
+run_qemu -drive "file=$TEST_IMG.base,format=raw,if=none,id=drive0" <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "blockdev-add",
"arguments": {
diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out
index 5f840a9980..46484ff69c 100644
--- a/tests/qemu-iotests/071.out
+++ b/tests/qemu-iotests/071.out
@@ -2,8 +2,8 @@ QA output created by 071
=== Testing blkverify through filename ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
read 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 229376
@@ -12,12 +12,12 @@ read 512/512 bytes at offset 229376
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-blkverify: read sector_num=0 nb_sectors=4 contents mismatch in sector 0
+blkverify: read sector_num=0 nb_sectors=1 contents mismatch in sector 0
=== Testing blkverify through file blockref ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
read 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 229376
@@ -26,14 +26,18 @@ read 512/512 bytes at offset 229376
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-blkverify: read sector_num=0 nb_sectors=4 contents mismatch in sector 0
+blkverify: read sector_num=0 nb_sectors=1 contents mismatch in sector 0
=== Testing blkdebug through filename ===
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
read failed: Input/output error
=== Testing blkdebug through file blockref ===
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
read failed: Input/output error
=== Testing blkdebug on existing block device ===
@@ -48,6 +52,8 @@ read failed: Input/output error
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+qemu-system-x86_64: Failed to flush the L2 table cache: Input/output error
+qemu-system-x86_64: Failed to flush the refcount block cache: Input/output error
=== Testing blkverify on existing block device ===
@@ -61,7 +67,7 @@ blkverify: read sector_num=0 nb_sectors=1 contents mismatch in sector 0
=== Testing blkverify on existing raw block device ===
-Testing: -drive file=TEST_DIR/t.IMGFMT.base,if=none,id=drive0
+Testing: -drive file=TEST_DIR/t.IMGFMT.base,format=raw,if=none,id=drive0
QMP_VERSION
{"return": {}}
{"return": {}}
@@ -86,5 +92,7 @@ read failed: Input/output error
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+qemu-system-x86_64: Failed to flush the L2 table cache: Input/output error
+qemu-system-x86_64: Failed to flush the refcount block cache: Input/output error
*** done
diff --git a/tests/qemu-iotests/072.out b/tests/qemu-iotests/072.out
index efe577c1c0..fe949d4781 100644
--- a/tests/qemu-iotests/072.out
+++ b/tests/qemu-iotests/072.out
@@ -2,7 +2,7 @@ QA output created by 072
=== Testing nested image formats ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 512
diff --git a/tests/qemu-iotests/073.out b/tests/qemu-iotests/073.out
index c9b00763b2..733d79ca91 100644
--- a/tests/qemu-iotests/073.out
+++ b/tests/qemu-iotests/073.out
@@ -1,8 +1,8 @@
QA output created by 073
== creating backing file ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base'
wrote 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/077 b/tests/qemu-iotests/077
index 4dd1bdde20..42a90850c7 100755
--- a/tests/qemu-iotests/077
+++ b/tests/qemu-iotests/077
@@ -52,7 +52,7 @@ echo "== Some concurrent requests involving RMW =="
function test_io()
{
-echo "open -o file.align=4k blkdebug::$TEST_IMG"
+echo "open -o driver=$IMGFMT,file.align=4k blkdebug::$TEST_IMG"
# A simple RMW request
cat <<EOF
aio_write -P 10 0x200 0x200
diff --git a/tests/qemu-iotests/077.out b/tests/qemu-iotests/077.out
index ab612344d6..eab14ae2e1 100644
--- a/tests/qemu-iotests/077.out
+++ b/tests/qemu-iotests/077.out
@@ -1,5 +1,5 @@
QA output created by 077
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== Some concurrent requests involving RMW ==
wrote XXX/XXX bytes at offset XXX
diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080
index 9de337c407..73795f198f 100755
--- a/tests/qemu-iotests/080
+++ b/tests/qemu-iotests/080
@@ -78,6 +78,8 @@ poke_file "$TEST_IMG" "$offset_backing_file_offset" "\xff\xff\xff\xff\xff\xff\xf
poke_file "$TEST_IMG" "$offset_ext_magic" "\x12\x34\x56\x78"
poke_file "$TEST_IMG" "$offset_ext_size" "\x7f\xff\xff\xff"
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
+poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x$(printf %x $offset_ext_size)"
+{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x00"
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out
index f7a943c7a4..6061d84432 100644
--- a/tests/qemu-iotests/080.out
+++ b/tests/qemu-iotests/080.out
@@ -1,38 +1,40 @@
QA output created by 080
== Huge header size ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
no file open, try 'help open'
== Huge unknown header extension ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: Invalid backing file offset
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
no file open, try 'help open'
+qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
+no file open, try 'help open'
== Huge refcount table size ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: Reference count table too large
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: Reference count table too large
no file open, try 'help open'
== Misaligned refcount table ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: Invalid reference count table offset
no file open, try 'help open'
== Huge refcount offset ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: Invalid reference count table offset
no file open, try 'help open'
== Invalid snapshot table ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: Too many snapshots
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: Too many snapshots
@@ -43,13 +45,13 @@ qemu-io: can't open device TEST_DIR/t.qcow2: Invalid snapshot table offset
no file open, try 'help open'
== Hitting snapshot table size limit ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-img: Could not create snapshot 'test': -27 (File too large)
read 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== Invalid L1 table ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: Active L1 table too large
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: Active L1 table too large
@@ -60,23 +62,23 @@ qemu-io: can't open device TEST_DIR/t.qcow2: Invalid L1 table offset
no file open, try 'help open'
== Invalid L1 table (with internal snapshot in the image) ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': L1 table is too small
== Invalid backing file size ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: Backing file name too long
no file open, try 'help open'
== Invalid L2 entry (huge physical offset) ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-img: Could not create snapshot 'test': -27 (File too large)
qemu-img: Could not create snapshot 'test': -11 (Resource temporarily unavailable)
== Invalid snapshot L1 table ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-img: Failed to load snapshot: Snapshot L1 table too large
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
index ed3c29e13c..9ab93ff89e 100755
--- a/tests/qemu-iotests/081
+++ b/tests/qemu-iotests/081
@@ -59,9 +59,13 @@ function run_qemu()
test_quorum=$($QEMU_IMG --help|grep quorum)
[ "$test_quorum" = "" ] && _supported_fmt quorum
-quorum="file.driver=quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
+quorum="driver=raw,file.driver=quorum,file.vote-threshold=2"
+quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
-quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw,file.vote-threshold=2"
+quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
+quorum="$quorum,file.children.0.driver=raw"
+quorum="$quorum,file.children.1.driver=raw"
+quorum="$quorum,file.children.2.driver=raw"
echo
echo "== creating quorum files =="
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
index 073515ea50..9f57d9d3b5 100644
--- a/tests/qemu-iotests/081.out
+++ b/tests/qemu-iotests/081.out
@@ -1,9 +1,9 @@
QA output created by 081
== creating quorum files ==
-Formatting 'TEST_DIR/1.IMGFMT', fmt=IMGFMT size=10485760
-Formatting 'TEST_DIR/2.IMGFMT', fmt=IMGFMT size=10485760
-Formatting 'TEST_DIR/3.IMGFMT', fmt=IMGFMT size=10485760
+Formatting 'TEST_DIR/1.IMGFMT', fmt=IMGFMT size=10485760
+Formatting 'TEST_DIR/2.IMGFMT', fmt=IMGFMT size=10485760
+Formatting 'TEST_DIR/3.IMGFMT', fmt=IMGFMT size=10485760
== writing images ==
wrote 10485760/10485760 bytes at offset 0
@@ -55,5 +55,5 @@ wrote 10485760/10485760 bytes at offset 0
10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== checking that quorum is broken ==
-qemu-io: can't open: Could not read image for determining its format: Input/output error
+read failed: Input/output error
*** done
diff --git a/tests/qemu-iotests/082 b/tests/qemu-iotests/082
index e64de27733..c83e01e7cd 100755
--- a/tests/qemu-iotests/082
+++ b/tests/qemu-iotests/082
@@ -60,11 +60,11 @@ _img_info
# Multiple -o should be merged
run_qemu_img create -f $IMGFMT -o cluster_size=4k -o lazy_refcounts=on "$TEST_IMG" $size
-run_qemu_img info "$TEST_IMG"
+_img_info --format-specific
# If the same -o key is specified more than once, the last one wins
run_qemu_img create -f $IMGFMT -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k "$TEST_IMG" $size
-run_qemu_img info "$TEST_IMG"
+_img_info --format-specific
run_qemu_img create -f $IMGFMT -o cluster_size=4k,cluster_size=8k "$TEST_IMG" $size
_img_info
@@ -114,11 +114,11 @@ TEST_IMG="${TEST_IMG}.base" _img_info
# Multiple -o should be merged
run_qemu_img convert -O $IMGFMT -o cluster_size=4k -o lazy_refcounts=on "$TEST_IMG" "$TEST_IMG".base
-run_qemu_img info "$TEST_IMG".base
+TEST_IMG="${TEST_IMG}.base" _img_info --format-specific
# If the same -o key is specified more than once, the last one wins
run_qemu_img convert -O $IMGFMT -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k "$TEST_IMG" "$TEST_IMG".base
-run_qemu_img info "$TEST_IMG".base
+TEST_IMG="${TEST_IMG}.base" _img_info --format-specific
run_qemu_img convert -O $IMGFMT -o cluster_size=4k,cluster_size=8k "$TEST_IMG" "$TEST_IMG".base
TEST_IMG="${TEST_IMG}.base" _img_info
@@ -157,15 +157,15 @@ echo === amend: Options specified more than once ===
# Last -f should win
run_qemu_img amend -f foo -f $IMGFMT -o lazy_refcounts=on "$TEST_IMG"
-run_qemu_img info "$TEST_IMG"
+_img_info --format-specific
# Multiple -o should be merged
run_qemu_img amend -f $IMGFMT -o size=130M -o lazy_refcounts=off "$TEST_IMG"
-run_qemu_img info "$TEST_IMG"
+_img_info --format-specific
# If the same -o key is specified more than once, the last one wins
run_qemu_img amend -f $IMGFMT -o size=8M -o lazy_refcounts=on -o size=132M "$TEST_IMG"
-run_qemu_img info "$TEST_IMG"
+_img_info --format-specific
run_qemu_img amend -f $IMGFMT -o size=4M,size=148M "$TEST_IMG"
_img_info
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
index 0a3ab5ac90..d0234e6137 100644
--- a/tests/qemu-iotests/082.out
+++ b/tests/qemu-iotests/082.out
@@ -3,20 +3,17 @@ QA output created by 082
=== create: Options specified more than once ===
Testing: create -f foo -f qcow2 TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=65536 lazy_refcounts=off
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 128M (134217728 bytes)
cluster_size: 65536
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=4096 lazy_refcounts=on
-
-Testing: info TEST_DIR/t.qcow2
-image: TEST_DIR/t.qcow2
-file format: qcow2
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=4096 lazy_refcounts=on
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
virtual size: 128M (134217728 bytes)
-disk size: 16K
cluster_size: 4096
Format specific information:
compat: 1.1
@@ -24,13 +21,10 @@ Format specific information:
corrupt: false
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=on
-
-Testing: info TEST_DIR/t.qcow2
-image: TEST_DIR/t.qcow2
-file format: qcow2
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=on
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
virtual size: 128M (134217728 bytes)
-disk size: 28K
cluster_size: 8192
Format specific information:
compat: 1.1
@@ -38,7 +32,7 @@ Format specific information:
corrupt: false
Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=off
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 128M (134217728 bytes)
@@ -143,10 +137,10 @@ lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs)
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2,help' encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2,help' encryption=off cluster_size=65536 lazy_refcounts=off
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,? TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2,?' encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2,?' encryption=off cluster_size=65536 lazy_refcounts=off
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 128M
qemu-img: Invalid option list: backing_file=TEST_DIR/t.qcow2,
@@ -175,7 +169,7 @@ size Virtual disk size
=== convert: Options specified more than once ===
Testing: create -f qcow2 TEST_DIR/t.qcow2 128M
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=65536 lazy_refcounts=off
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=65536 lazy_refcounts=off
Testing: convert -f foo -f qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
image: TEST_DIR/t.IMGFMT.base
@@ -189,12 +183,9 @@ virtual size: 128M (134217728 bytes)
cluster_size: 65536
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
-
-Testing: info TEST_DIR/t.qcow2.base
-image: TEST_DIR/t.qcow2.base
-file format: qcow2
+image: TEST_DIR/t.IMGFMT.base
+file format: IMGFMT
virtual size: 128M (134217728 bytes)
-disk size: 16K
cluster_size: 4096
Format specific information:
compat: 1.1
@@ -202,12 +193,9 @@ Format specific information:
corrupt: false
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
-
-Testing: info TEST_DIR/t.qcow2.base
-image: TEST_DIR/t.qcow2.base
-file format: qcow2
+image: TEST_DIR/t.IMGFMT.base
+file format: IMGFMT
virtual size: 128M (134217728 bytes)
-disk size: 28K
cluster_size: 8192
Format specific information:
compat: 1.1
@@ -351,12 +339,9 @@ size Virtual disk size
=== amend: Options specified more than once ===
Testing: amend -f foo -f qcow2 -o lazy_refcounts=on TEST_DIR/t.qcow2
-
-Testing: info TEST_DIR/t.qcow2
-image: TEST_DIR/t.qcow2
-file format: qcow2
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
virtual size: 128M (134217728 bytes)
-disk size: 196K
cluster_size: 65536
Format specific information:
compat: 1.1
@@ -364,12 +349,9 @@ Format specific information:
corrupt: false
Testing: amend -f qcow2 -o size=130M -o lazy_refcounts=off TEST_DIR/t.qcow2
-
-Testing: info TEST_DIR/t.qcow2
-image: TEST_DIR/t.qcow2
-file format: qcow2
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
virtual size: 130M (136314880 bytes)
-disk size: 196K
cluster_size: 65536
Format specific information:
compat: 1.1
@@ -377,12 +359,9 @@ Format specific information:
corrupt: false
Testing: amend -f qcow2 -o size=8M -o lazy_refcounts=on -o size=132M TEST_DIR/t.qcow2
-
-Testing: info TEST_DIR/t.qcow2
-image: TEST_DIR/t.qcow2
-file format: qcow2
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
virtual size: 132M (138412032 bytes)
-disk size: 196K
cluster_size: 65536
Format specific information:
compat: 1.1
diff --git a/tests/qemu-iotests/084.out b/tests/qemu-iotests/084.out
index 5ece8299c8..5c5ab928c9 100644
--- a/tests/qemu-iotests/084.out
+++ b/tests/qemu-iotests/084.out
@@ -2,7 +2,7 @@ QA output created by 084
=== Statically allocated image creation ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
@@ -11,7 +11,7 @@ disk image file size in bytes: 67109888
=== Testing image size bounds ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
diff --git a/tests/qemu-iotests/086.out b/tests/qemu-iotests/086.out
index 9c0bf23718..5ff996101b 100644
--- a/tests/qemu-iotests/086.out
+++ b/tests/qemu-iotests/086.out
@@ -1,5 +1,5 @@
QA output created by 086
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 1048576/1048576 bytes at offset 2097152
diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
index e8795b3a10..7d38cc26c5 100644
--- a/tests/qemu-iotests/087.out
+++ b/tests/qemu-iotests/087.out
@@ -1,5 +1,5 @@
QA output created by 087
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
=== Missing ID ===
@@ -45,7 +45,7 @@ QMP_VERSION
=== Encrypted image ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
Testing: -S
QMP_VERSION
{"return": {}}
@@ -67,7 +67,7 @@ QMP_VERSION
=== Missing driver ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
Testing: -S
QMP_VERSION
{"return": {}}
diff --git a/tests/qemu-iotests/088.out b/tests/qemu-iotests/088.out
index d961609e49..6e6bfcaf90 100644
--- a/tests/qemu-iotests/088.out
+++ b/tests/qemu-iotests/088.out
@@ -1,7 +1,7 @@
QA output created by 088
== Invalid block size ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 0
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 0
diff --git a/tests/qemu-iotests/089 b/tests/qemu-iotests/089
index dffc977e1c..6f74cecde2 100755
--- a/tests/qemu-iotests/089
+++ b/tests/qemu-iotests/089
@@ -65,7 +65,8 @@ $QEMU_IO -c 'write -P 42 0 512' -c 'write -P 23 512 512' \
$QEMU_IMG convert -f raw -O $IMGFMT "$TEST_IMG.base" "$TEST_IMG"
-$QEMU_IO -c 'read -P 42 0 512' -c 'read -P 23 512 512' \
+$QEMU_IO_PROG --cache $CACHEMODE \
+ -c 'read -P 42 0 512' -c 'read -P 23 512 512' \
-c 'read -P 66 1024 512' "json:{
\"driver\": \"$IMGFMT\",
\"file\": {
@@ -91,7 +92,8 @@ $QEMU_IO -c 'write -P 42 0x38000 512' "$TEST_IMG" | _filter_qemu_io
# The "image.filename" part tests whether "a": { "b": "c" } and "a.b": "c" do
# the same (which they should).
-$QEMU_IO -c 'read -P 42 0x38000 512' "json:{
+$QEMU_IO_PROG --cache $CACHEMODE \
+ -c 'read -P 42 0x38000 512' "json:{
\"driver\": \"$IMGFMT\",
\"file\": {
\"driver\": \"blkdebug\",
diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out
index b2b0390818..a6d37118c7 100644
--- a/tests/qemu-iotests/089.out
+++ b/tests/qemu-iotests/089.out
@@ -2,7 +2,7 @@ QA output created by 089
=== Testing nested image formats ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 512
@@ -21,9 +21,11 @@ read 512/512 bytes at offset 0
=== Testing blkdebug ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 512/512 bytes at offset 229376
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
read failed: Input/output error
=== Testing qemu-img info output ===
diff --git a/tests/qemu-iotests/090.out b/tests/qemu-iotests/090.out
index 2df93e0d97..66ca5d58da 100644
--- a/tests/qemu-iotests/090.out
+++ b/tests/qemu-iotests/090.out
@@ -1,5 +1,5 @@
QA output created by 090
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 65536/65536 bytes at offset 65536
diff --git a/tests/qemu-iotests/091.out b/tests/qemu-iotests/091.out
index a2e0122966..5017f8c2d9 100644
--- a/tests/qemu-iotests/091.out
+++ b/tests/qemu-iotests/091.out
@@ -1,5 +1,5 @@
QA output created by 091
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
=== Starting QEMU VM1 ===
diff --git a/tests/qemu-iotests/092.out b/tests/qemu-iotests/092.out
index 496d8f0a63..c5c60f9178 100644
--- a/tests/qemu-iotests/092.out
+++ b/tests/qemu-iotests/092.out
@@ -1,7 +1,7 @@
QA output created by 092
== Invalid cluster size ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and 64k
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and 64k
@@ -12,7 +12,7 @@ qemu-io: can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and
no file open, try 'help open'
== Invalid L2 table size ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow: L2 table size must be between 512 and 64k
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow: L2 table size must be between 512 and 64k
@@ -23,14 +23,14 @@ qemu-io: can't open device TEST_DIR/t.qcow: L2 table size must be between 512 an
no file open, try 'help open'
== Invalid size ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow: Image too large
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow: Image too large
no file open, try 'help open'
== Invalid backing file length ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow: Backing file name too long
no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow: Backing file name too long
diff --git a/tests/qemu-iotests/095.out b/tests/qemu-iotests/095.out
index cc86efacc6..267c4836e5 100644
--- a/tests/qemu-iotests/095.out
+++ b/tests/qemu-iotests/095.out
@@ -1,7 +1,7 @@
QA output created by 095
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=5242880
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file='TEST_DIR/t.IMGFMT.base'
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file='TEST_DIR/t.IMGFMT.snp1'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=5242880
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file='TEST_DIR/t.IMGFMT.snp1'
=== Base image info before commit and resize ===
image: TEST_DIR/t.IMGFMT.base
diff --git a/tests/qemu-iotests/097.out b/tests/qemu-iotests/097.out
index 1cb7764fe8..81651f496c 100644
--- a/tests/qemu-iotests/097.out
+++ b/tests/qemu-iotests/097.out
@@ -2,9 +2,9 @@ QA output created by 097
=== Test pass 0 ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd'
wrote 196608/196608 bytes at offset 0
192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 131072/131072 bytes at offset 65536
@@ -31,9 +31,9 @@ Offset Length File
=== Test pass 1 ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd'
wrote 196608/196608 bytes at offset 0
192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 131072/131072 bytes at offset 65536
@@ -61,9 +61,9 @@ Offset Length File
=== Test pass 2 ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd'
wrote 196608/196608 bytes at offset 0
192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 131072/131072 bytes at offset 65536
@@ -91,9 +91,9 @@ Offset Length File
=== Test pass 3 ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd'
wrote 196608/196608 bytes at offset 0
192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 131072/131072 bytes at offset 65536
diff --git a/tests/qemu-iotests/098.out b/tests/qemu-iotests/098.out
index 586dfc809f..e08a189b4f 100644
--- a/tests/qemu-iotests/098.out
+++ b/tests/qemu-iotests/098.out
@@ -2,8 +2,8 @@ QA output created by 098
=== l1_update ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
@@ -11,8 +11,8 @@ No errors were found on the image.
=== empty_image_prepare ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
@@ -24,8 +24,8 @@ No errors were found on the image.
=== reftable_update ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
@@ -38,8 +38,8 @@ No errors were found on the image.
=== refblock_alloc ===
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
diff --git a/tests/qemu-iotests/099 b/tests/qemu-iotests/099
index ffc7ea795a..948afff28b 100755
--- a/tests/qemu-iotests/099
+++ b/tests/qemu-iotests/099
@@ -44,7 +44,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow qcow2 qed vdi vhdx vmdk vpc
_supported_proto file
_supported_os Linux
-
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
+ "subformat=twoGbMaxExtentSparse"
function do_run_qemu()
{
@@ -107,8 +108,21 @@ echo
# generate a JSON object here as well
test_qemu "file.driver=blkverify,file.raw.filename=$TEST_IMG.compare,file.test.file.driver=blkdebug,file.test.file.image.filename=$TEST_IMG,file.test.file.inject-error.0.event=l1_update"
+echo
+echo '=== Testing plain filename for blkdebug ==='
+echo
+
+touch "$TEST_DIR/blkdebug.conf"
+test_qemu "file.driver=blkdebug,file.config=$TEST_DIR/blkdebug.conf,file.image.filename=$TEST_IMG"
+
+echo
+echo '=== Testing plain filename for blkdebug without configuration file ==='
+echo
+
+test_qemu "file.driver=blkdebug,file.image.filename=$TEST_IMG"
+
-rm -f "$TEST_IMG.compare"
+rm -f "$TEST_IMG.compare" "$TEST_DIR/blkdebug.conf"
# success, all done
echo "*** done"
diff --git a/tests/qemu-iotests/099.out b/tests/qemu-iotests/099.out
index 55be4d4c56..8cce627529 100644
--- a/tests/qemu-iotests/099.out
+++ b/tests/qemu-iotests/099.out
@@ -1,6 +1,6 @@
QA output created by 099
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
-Formatting 'TEST_DIR/t.IMGFMT.compare', fmt=raw size=131072
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
+Formatting 'TEST_DIR/t.IMGFMT.compare', fmt=raw size=131072
=== Testing simple filename for blkverify ===
@@ -12,9 +12,17 @@ blkverify:TEST_DIR/t.IMGFMT.compare:TEST_DIR/t.IMGFMT
=== Testing JSON filename for blkdebug ===
-json:{"driver": "IMGFMT", "file": {"inject-error": [{"immediately": false, "once": false, "state": 0, "sector": -1, "event": "l1_update", "errno": 5}], "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug"}}
+json:{"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}
=== Testing indirectly enforced JSON filename ===
-json:{"driver": "raw", "file": {"test": {"driver": "IMGFMT", "file": {"inject-error": [{"immediately": false, "once": false, "state": 0, "sector": -1, "event": "l1_update", "errno": 5}], "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug"}}, "driver": "blkverify", "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
+json:{"driver": "raw", "file": {"test": {"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}, "driver": "blkverify", "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
+
+=== Testing plain filename for blkdebug ===
+
+blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT
+
+=== Testing plain filename for blkdebug without configuration file ===
+
+blkdebug::TEST_DIR/t.IMGFMT
*** done
diff --git a/tests/qemu-iotests/100.out b/tests/qemu-iotests/100.out
index 2d6e9f0a7d..05649038d9 100644
--- a/tests/qemu-iotests/100.out
+++ b/tests/qemu-iotests/100.out
@@ -1,7 +1,7 @@
QA output created by 100
== Single request ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -12,7 +12,7 @@ read 4096/4096 bytes at offset 4096
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== Sequential requests ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 8192/8192 bytes at offset 0
8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -25,7 +25,7 @@ read 4096/4096 bytes at offset 8192
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== Superset overlapping requests ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 6144/6144 bytes at offset 0
6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -38,7 +38,7 @@ read 4096/4096 bytes at offset 4096
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== Subset overlapping requests ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 6144/6144 bytes at offset 1024
6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -51,7 +51,7 @@ read 4096/4096 bytes at offset 4096
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== Head overlapping requests ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 6144/6144 bytes at offset 0
6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -62,7 +62,7 @@ read 4096/4096 bytes at offset 4096
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== Tail overlapping requests ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 6144/6144 bytes at offset 2048
6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -73,7 +73,7 @@ read 4096/4096 bytes at offset 4096
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== Disjoint requests ==
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 8192/8192 bytes at offset 0
8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/103.out b/tests/qemu-iotests/103.out
index ddf6b5a075..ee705b05f0 100644
--- a/tests/qemu-iotests/103.out
+++ b/tests/qemu-iotests/103.out
@@ -1,5 +1,5 @@
QA output created by 103
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/104.out b/tests/qemu-iotests/104.out
index de27852e35..ab8d892c2a 100644
--- a/tests/qemu-iotests/104.out
+++ b/tests/qemu-iotests/104.out
@@ -1,11 +1,11 @@
QA output created by 104
=== Check qemu-img info output ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 1.0K (1024 bytes)
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1234
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1234
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 1.5K (1536 bytes)
diff --git a/tests/qemu-iotests/107.out b/tests/qemu-iotests/107.out
index 93445b731f..24f85d8c56 100644
--- a/tests/qemu-iotests/107.out
+++ b/tests/qemu-iotests/107.out
@@ -2,7 +2,7 @@ QA output created by 107
=== Updates should not write random data ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 65528/65528 bytes at offset 196616
diff --git a/tests/qemu-iotests/108.out b/tests/qemu-iotests/108.out
index 824d5cf139..75bab8dc84 100644
--- a/tests/qemu-iotests/108.out
+++ b/tests/qemu-iotests/108.out
@@ -2,7 +2,7 @@ QA output created by 108
=== Repairing an image without any refcount table ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
ERROR cluster 0 refcount=0 reference=1
@@ -22,7 +22,7 @@ read 65536/65536 bytes at offset 0
=== Repairing unreferenced data cluster in new refblock area ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 111104/111104 bytes at offset 0
108.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
131072
@@ -49,7 +49,7 @@ read 512/512 bytes at offset 111104
--- Otherwise clean ---
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Repairing refcount block 1 is outside image
The following inconsistencies were found and repaired:
@@ -61,7 +61,7 @@ No errors were found on the image.
--- Refblock is unallocated ---
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Repairing refcount block 1 is outside image
ERROR cluster 16 refcount=0 reference=1
Rebuilding refcount structure
@@ -78,7 +78,7 @@ No errors were found on the image.
--- Signed overflow after the refblock ---
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Repairing refcount block 1 is outside image
ERROR could not resize image: Invalid argument
Rebuilding refcount structure
@@ -94,7 +94,7 @@ No errors were found on the image.
--- Unsigned overflow after the refblock ---
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Repairing refcount block 1 is outside image
ERROR could not resize image: Invalid argument
Rebuilding refcount structure
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
new file mode 100755
index 0000000000..0b668da850
--- /dev/null
+++ b/tests/qemu-iotests/109
@@ -0,0 +1,132 @@
+#!/bin/bash
+#
+# Test writing image headers of other formats into raw images
+#
+# Copyright (C) 2014 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()
+{
+ rm -f $TEST_IMG.src
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+_supported_fmt raw
+_supported_proto file
+_supported_os Linux
+
+qemu_comm_method=qmp
+
+function run_qemu()
+{
+ local raw_img="$1"
+ local source_img="$2"
+ local qmp_format="$3"
+ local qmp_event="$4"
+
+ _launch_qemu -drive file="${source_img}",format=raw,cache=${CACHEMODE},id=src
+ _send_qemu_cmd $QEMU_HANDLE "{ 'execute': 'qmp_capabilities' }" "return"
+
+ _send_qemu_cmd $QEMU_HANDLE \
+ "{'execute':'drive-mirror', 'arguments':{
+ 'device': 'src', 'target': '$raw_img', $qmp_format
+ 'mode': 'existing', 'sync': 'full'}}" \
+ "return"
+
+ _send_qemu_cmd $QEMU_HANDLE '' "$qmp_event"
+ _send_qemu_cmd $QEMU_HANDLE '{"execute":"query-block-jobs"}' "return"
+ _cleanup_qemu
+}
+
+for fmt in qcow qcow2 qed vdi vmdk vpc; do
+
+ echo
+ echo "=== Writing a $fmt header into raw ==="
+ echo
+
+ _make_test_img 64M
+ TEST_IMG="$TEST_IMG.src" IMGFMT=$fmt _make_test_img 64M
+
+ # This first test should fail: The image format was probed, we may not
+ # write an image header at the start of the image
+ run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR"
+ $QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
+
+
+ # When raw was explicitly specified, the same must succeed
+ run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
+ $QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
+
+done
+
+
+for sample_img in empty.bochs iotest-dirtylog-10G-4M.vhdx parallels-v1 \
+ simple-pattern.cloop; do
+
+ echo
+ echo "=== Copying sample image $sample_img into raw ==="
+ echo
+
+ # Can't use _use_sample_img because that isn't designed to be used multiple
+ # times and it overwrites $TEST_IMG (both breaks cleanup)
+ _make_test_img 64M
+ bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
+
+ run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR"
+ $QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
+
+ run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
+ # qemu-img compare can't handle unaligned file sizes
+ $QEMU_IMG resize -f raw "$TEST_IMG.src" +0
+ $QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
+done
+
+echo
+echo "=== Write legitimate MBR into raw ==="
+echo
+
+for sample_img in grub_mbr.raw; do
+ _make_test_img 64M
+ bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
+
+ run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_READY"
+ $QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
+
+ run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
+ $QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
+done
+
+
+# success, all done
+echo '*** done'
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out
new file mode 100644
index 0000000000..7db92c9ce8
--- /dev/null
+++ b/tests/qemu-iotests/109.out
@@ -0,0 +1,231 @@
+QA output created by 109
+
+=== Writing a qcow header into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"return": []}
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Warning: Image size mismatch!
+Images are identical.
+
+=== Writing a qcow2 header into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 197120, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"return": []}
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 197120, "offset": 197120, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Warning: Image size mismatch!
+Images are identical.
+
+=== Writing a qed header into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"return": []}
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Warning: Image size mismatch!
+Images are identical.
+
+=== Writing a vdi header into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"return": []}
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Warning: Image size mismatch!
+Images are identical.
+
+=== Writing a vmdk header into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"return": []}
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 65536, "offset": 65536, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Warning: Image size mismatch!
+Images are identical.
+
+=== Writing a vpc header into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"return": []}
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Warning: Image size mismatch!
+Images are identical.
+
+=== Copying sample image empty.bochs into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"return": []}
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Image resized.
+Warning: Image size mismatch!
+Images are identical.
+
+=== Copying sample image iotest-dirtylog-10G-4M.vhdx into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"return": []}
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 31457280, "offset": 31457280, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Image resized.
+Warning: Image size mismatch!
+Images are identical.
+
+=== Copying sample image parallels-v1 into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"return": []}
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Image resized.
+Warning: Image size mismatch!
+Images are identical.
+
+=== Copying sample image simple-pattern.cloop into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"return": []}
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2048, "offset": 2048, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Image resized.
+Warning: Image size mismatch!
+Images are identical.
+
+=== Write legitimate MBR into raw ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+{"return": {}}
+WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
+Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
+Specify the 'raw' format explicitly to remove the restrictions.
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Warning: Image size mismatch!
+Images are identical.
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Warning: Image size mismatch!
+Images are identical.
+*** done
diff --git a/tests/qemu-iotests/113 b/tests/qemu-iotests/113
new file mode 100755
index 0000000000..a2cd96b176
--- /dev/null
+++ b/tests/qemu-iotests/113
@@ -0,0 +1,76 @@
+#!/bin/bash
+#
+# Test case for accessing creation options on image formats and
+# protocols not supporting image creation
+#
+# Copyright (C) 2014 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=mreitz@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
+
+# We can only test one format here because we need its sample file
+_supported_fmt bochs
+_supported_proto nbd
+_supported_os Linux
+
+echo
+echo '=== Unsupported image creation in qemu-img create ==='
+echo
+
+$QEMU_IMG create -f $IMGFMT nbd://example.com 2>&1 64M | _filter_imgfmt
+
+echo
+echo '=== Unsupported image creation in qemu-img convert ==='
+echo
+
+# We could use any input image format here, but this is a bochs test, so just
+# use the bochs image
+_use_sample_img empty.bochs.bz2
+$QEMU_IMG convert -f $IMGFMT -O $IMGFMT "$TEST_IMG" nbd://example.com 2>&1 \
+ | _filter_imgfmt
+
+echo
+echo '=== Unsupported format in qemu-img amend ==='
+echo
+
+# The protocol does not matter here
+_use_sample_img empty.bochs.bz2
+$QEMU_IMG amend -f $IMGFMT -o foo=bar "$TEST_IMG" 2>&1 | _filter_imgfmt
+
+
+# success, all done
+echo
+echo '*** done'
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/113.out b/tests/qemu-iotests/113.out
new file mode 100644
index 0000000000..00bdfd6887
--- /dev/null
+++ b/tests/qemu-iotests/113.out
@@ -0,0 +1,15 @@
+QA output created by 113
+
+=== Unsupported image creation in qemu-img create ===
+
+qemu-img: nbd://example.com: Format driver 'IMGFMT' does not support image creation
+
+=== Unsupported image creation in qemu-img convert ===
+
+qemu-img: Format driver 'IMGFMT' does not support image creation
+
+=== Unsupported format in qemu-img amend ===
+
+qemu-img: Format driver 'IMGFMT' does not support any options to amend
+
+*** done
diff --git a/tests/qemu-iotests/114 b/tests/qemu-iotests/114
new file mode 100755
index 0000000000..d02e7ffbe3
--- /dev/null
+++ b/tests/qemu-iotests/114
@@ -0,0 +1,61 @@
+#!/bin/bash
+#
+# Test invalid backing file format in qcow2 images
+#
+# Copyright (C) 2014 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
+_supported_proto generic
+_supported_os Linux
+
+
+TEST_IMG="$TEST_IMG.base" _make_test_img 64M
+_make_test_img -b "$TEST_IMG.base" 64M
+
+# Set an invalid backing file format
+$PYTHON qcow2.py "$TEST_IMG" add-header-ext 0xE2792ACA "foo"
+_img_info
+
+# Try opening the image. Should fail (and not probe) in the first case, but
+# overriding the backing file format should be possible.
+$QEMU_IO -c "open $TEST_IMG" -c "read 0 4k" 2>&1 | _filter_qemu_io | _filter_testdir
+$QEMU_IO -c "open -o backing.driver=$IMGFMT $TEST_IMG" -c "read 0 4k" | _filter_qemu_io
+
+# success, all done
+echo '*** done'
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
new file mode 100644
index 0000000000..6c6b21085a
--- /dev/null
+++ b/tests/qemu-iotests/114.out
@@ -0,0 +1,13 @@
+QA output created by 114
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
+virtual size: 64M (67108864 bytes)
+cluster_size: 65536
+backing file: TEST_DIR/t.IMGFMT.base
+backing file format: foo
+qemu-io: can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
index 9e12bec2bf..1e556bbb7d 100644
--- a/tests/qemu-iotests/common
+++ b/tests/qemu-iotests/common
@@ -289,10 +289,10 @@ testlist options
if [ ! -z "$DISPLAY" ]
then
- which xdiff >/dev/null 2>&1 && diff=xdiff
- which gdiff >/dev/null 2>&1 && diff=gdiff
- which tkdiff >/dev/null 2>&1 && diff=tkdiff
- which xxdiff >/dev/null 2>&1 && diff=xxdiff
+ command -v xdiff >/dev/null 2>&1 && diff=xdiff
+ command -v gdiff >/dev/null 2>&1 && diff=gdiff
+ command -v tkdiff >/dev/null 2>&1 && diff=tkdiff
+ command -v xxdiff >/dev/null 2>&1 && diff=xxdiff
fi
;;
@@ -391,7 +391,7 @@ BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
done
# Set qemu-io cache mode with $CACHEMODE we have
-QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
+QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT --cache $CACHEMODE"
# Set default options for qemu-img create -o if they were not specified
_set_default_imgopts
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
index bd6790be63..91a5ef696b 100644
--- a/tests/qemu-iotests/common.config
+++ b/tests/qemu-iotests/common.config
@@ -47,7 +47,7 @@ export PWD=`pwd`
# $1 = prog to look for, $2* = default pathnames if not found in $PATH
set_prog_path()
{
- p=`which $1 2> /dev/null`
+ p=`command -v $1 2> /dev/null`
if [ -n "$p" -a -x "$p" ]; then
echo $p
return 0
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 3acdb307f4..6c14590594 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -150,7 +150,7 @@ _filter_win32()
_filter_qemu_io()
{
_filter_win32 | sed -e "s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/" \
- -e "s/: line [0-9][0-9]*: *[0-9][0-9]*\( Aborted\)/:\1/" \
+ -e "s/: line [0-9][0-9]*: *[0-9][0-9]*\( Aborted\| Killed\)/:\1/" \
-e "s/qemu-io> //g"
}
@@ -167,7 +167,9 @@ _filter_qmp()
{
_filter_win32 | \
sed -e 's#\("\(micro\)\?seconds": \)[0-9]\+#\1 TIMESTAMP#g' \
- -e 's#^{"QMP":.*}$#QMP_VERSION#'
+ -e 's#^{"QMP":.*}$#QMP_VERSION#' \
+ -e '/^ "QMP": {\s*$/, /^ }\s*$/ c\' \
+ -e ' QMP_VERSION'
}
# replace driver-specific options in the "Formatting..." line
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
index ee7ebb4c1d..8e618b5149 100644
--- a/tests/qemu-iotests/common.qemu
+++ b/tests/qemu-iotests/common.qemu
@@ -153,8 +153,9 @@ function _launch_qemu()
mkfifo "${fifo_out}"
mkfifo "${fifo_in}"
- "${QEMU}" -nographic -serial none ${comm} -machine accel=qtest "${@}" 2>&1 \
+ "${QEMU}" -nographic -serial none ${comm} -machine accel=qtest "${@}" \
>"${fifo_out}" \
+ 2>&1 \
<"${fifo_in}" &
QEMU_PID[${_QEMU_HANDLE}]=$!
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 9c49deb3dd..3b14053790 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -175,7 +175,9 @@ _cleanup_test_img()
case "$IMGPROTO" in
nbd)
- kill $QEMU_NBD_PID
+ if [ -n "$QEMU_NBD_PID" ]; then
+ kill $QEMU_NBD_PID
+ fi
rm -f "$TEST_IMG_FILE"
;;
file)
@@ -213,6 +215,13 @@ _check_test_img()
_img_info()
{
+ if [[ "$1" == "--format-specific" ]]; then
+ local format_specific=1
+ shift
+ else
+ local format_specific=0
+ fi
+
discard=0
regex_json_spec_start='^ *"format-specific": \{'
$QEMU_IMG info "$@" "$TEST_IMG" 2>&1 | \
@@ -222,7 +231,9 @@ _img_info()
-e "/^disk size:/ D" \
-e "/actual-size/ D" | \
while IFS='' read line; do
- if [[ $line == "Format specific information:" ]]; then
+ if [[ $format_specific == 1 ]]; then
+ discard=0
+ elif [[ $line == "Format specific information:" ]]; then
discard=1
elif [[ $line =~ $regex_json_spec_start ]]; then
discard=2
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 7dfe46940a..a4742c6d01 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -111,4 +111,7 @@
105 rw auto quick
107 rw auto quick
108 rw auto quick
+109 rw auto
111 rw auto quick
+113 rw auto quick
+114 rw auto quick
diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py
index 2058596964..9cc4cf7d08 100755
--- a/tests/qemu-iotests/qcow2.py
+++ b/tests/qemu-iotests/qcow2.py
@@ -7,6 +7,10 @@ import string
class QcowHeaderExtension:
def __init__(self, magic, length, data):
+ if length % 8 != 0:
+ padding = 8 - (length % 8)
+ data += "\0" * padding
+
self.magic = magic
self.length = length
self.data = data
diff --git a/tests/qemu-iotests/sample_images/grub_mbr.raw.bz2 b/tests/qemu-iotests/sample_images/grub_mbr.raw.bz2
new file mode 100644
index 0000000000..8585878bcd
--- /dev/null
+++ b/tests/qemu-iotests/sample_images/grub_mbr.raw.bz2
Binary files differ
diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c
index 8cf2c5bcaa..6d631cf366 100644
--- a/tests/usb-hcd-uhci-test.c
+++ b/tests/usb-hcd-uhci-test.c
@@ -87,7 +87,7 @@ int main(int argc, char **argv)
qtest_add_func("/uhci/pci/hotplug/usb-storage", test_usb_storage_hotplug);
qtest_start("-device piix3-usb-uhci,id=uhci,addr=1d.0"
- " -drive id=drive0,if=none,file=/dev/null"
+ " -drive id=drive0,if=none,file=/dev/null,format=raw"
" -device usb-tablet,bus=uhci.0,port=1");
ret = g_test_run();
qtest_end();
diff --git a/tests/usb-hcd-xhci-test.c b/tests/usb-hcd-xhci-test.c
index b1a7dec5bb..adf261e963 100644
--- a/tests/usb-hcd-xhci-test.c
+++ b/tests/usb-hcd-xhci-test.c
@@ -91,7 +91,7 @@ int main(int argc, char **argv)
qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug);
qtest_start("-device nec-usb-xhci,id=xhci"
- " -drive id=drive0,if=none,file=/dev/null");
+ " -drive id=drive0,if=none,file=/dev/null,format=raw");
ret = g_test_run();
qtest_end();
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index ead3911e28..89d7cbf919 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -68,8 +68,8 @@ static QPCIBus *test_start(void)
g_assert_cmpint(ret, ==, 0);
close(fd);
- cmdline = g_strdup_printf("-drive if=none,id=drive0,file=%s "
- "-drive if=none,id=drive1,file=/dev/null "
+ cmdline = g_strdup_printf("-drive if=none,id=drive0,file=%s,format=raw "
+ "-drive if=none,id=drive1,file=/dev/null,format=raw "
"-device virtio-blk-pci,id=drv0,drive=drive0,"
"addr=%x.%x",
tmp_path, PCI_SLOT, PCI_FN);
diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
index 41f9602e44..989f8251c4 100644
--- a/tests/virtio-scsi-test.c
+++ b/tests/virtio-scsi-test.c
@@ -52,8 +52,8 @@ int main(int argc, char **argv)
qtest_add_func("/virtio/scsi/pci/nop", pci_nop);
qtest_add_func("/virtio/scsi/pci/hotplug", hotplug);
- qtest_start("-drive id=drv0,if=none,file=/dev/null "
- "-drive id=drv1,if=none,file=/dev/null "
+ qtest_start("-drive id=drv0,if=none,file=/dev/null,format=raw "
+ "-drive id=drv1,if=none,file=/dev/null,format=raw "
"-device virtio-scsi-pci,id=vscsi0 "
"-device scsi-hd,bus=vscsi0.0,drive=drv0");
ret = g_test_run();
diff --git a/ui/keymaps.c b/ui/keymaps.c
index 80d658d907..49410ae9d1 100644
--- a/ui/keymaps.c
+++ b/ui/keymaps.c
@@ -26,18 +26,20 @@
#include "sysemu/sysemu.h"
static int get_keysym(const name2keysym_t *table,
- const char *name)
+ const char *name)
{
const name2keysym_t *p;
for(p = table; p->name != NULL; p++) {
- if (!strcmp(p->name, name))
+ if (!strcmp(p->name, name)) {
return p->keysym;
+ }
}
if (name[0] == 'U' && strlen(name) == 5) { /* try unicode Uxxxx */
char *end;
int ret = (int)strtoul(name + 1, &end, 16);
- if (*end == '\0' && ret > 0)
- return ret;
+ if (*end == '\0' && ret > 0) {
+ return ret;
+ }
}
return 0;
}
@@ -46,19 +48,20 @@ static int get_keysym(const name2keysym_t *table,
static void add_to_key_range(struct key_range **krp, int code) {
struct key_range *kr;
for (kr = *krp; kr; kr = kr->next) {
- if (code >= kr->start && code <= kr->end)
- break;
- if (code == kr->start - 1) {
- kr->start--;
- break;
- }
- if (code == kr->end + 1) {
- kr->end++;
- break;
- }
+ if (code >= kr->start && code <= kr->end) {
+ break;
+ }
+ if (code == kr->start - 1) {
+ kr->start--;
+ break;
+ }
+ if (code == kr->end + 1) {
+ kr->end++;
+ break;
+ }
}
if (kr == NULL) {
- kr = g_malloc0(sizeof(*kr));
+ kr = g_malloc0(sizeof(*kr));
kr->start = kr->end = code;
kr->next = *krp;
*krp = kr;
@@ -67,30 +70,30 @@ static void add_to_key_range(struct key_range **krp, int code) {
static void add_keysym(char *line, int keysym, int keycode, kbd_layout_t *k) {
if (keysym < MAX_NORMAL_KEYCODE) {
- //fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode);
- k->keysym2keycode[keysym] = keycode;
+ /* fprintf(stderr,"Setting keysym %s (%d) to %d\n",
+ line, keysym, keycode); */
+ k->keysym2keycode[keysym] = keycode;
} else {
- if (k->extra_count >= MAX_EXTRA_COUNT) {
- fprintf(stderr,
- "Warning: Could not assign keysym %s (0x%x) because of memory constraints.\n",
- line, keysym);
- } else {
+ if (k->extra_count >= MAX_EXTRA_COUNT) {
+ fprintf(stderr, "Warning: Could not assign keysym %s (0x%x)"
+ " because of memory constraints.\n", line, keysym);
+ } else {
#if 0
- fprintf(stderr, "Setting %d: %d,%d\n",
- k->extra_count, keysym, keycode);
+ fprintf(stderr, "Setting %d: %d,%d\n",
+ k->extra_count, keysym, keycode);
#endif
- k->keysym2keycode_extra[k->extra_count].
- keysym = keysym;
- k->keysym2keycode_extra[k->extra_count].
- keycode = keycode;
- k->extra_count++;
- }
+ k->keysym2keycode_extra[k->extra_count].
+ keysym = keysym;
+ k->keysym2keycode_extra[k->extra_count].
+ keycode = keycode;
+ k->extra_count++;
+ }
}
}
static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
- const char *language,
- kbd_layout_t * k)
+ const char *language,
+ kbd_layout_t *k)
{
FILE *f;
char * filename;
@@ -101,69 +104,78 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
f = filename ? fopen(filename, "r") : NULL;
g_free(filename);
if (!f) {
- fprintf(stderr,
- "Could not read keymap file: '%s'\n", language);
- return NULL;
+ fprintf(stderr, "Could not read keymap file: '%s'\n", language);
+ return NULL;
}
- if (!k)
- k = g_malloc0(sizeof(kbd_layout_t));
+ if (!k) {
+ k = g_malloc0(sizeof(kbd_layout_t));
+ }
for(;;) {
- if (fgets(line, 1024, f) == NULL)
+ if (fgets(line, 1024, f) == NULL) {
break;
+ }
len = strlen(line);
- if (len > 0 && line[len - 1] == '\n')
+ if (len > 0 && line[len - 1] == '\n') {
line[len - 1] = '\0';
- if (line[0] == '#')
- continue;
- if (!strncmp(line, "map ", 4))
- continue;
- if (!strncmp(line, "include ", 8)) {
- parse_keyboard_layout(table, line + 8, k);
+ }
+ if (line[0] == '#') {
+ continue;
+ }
+ if (!strncmp(line, "map ", 4)) {
+ continue;
+ }
+ if (!strncmp(line, "include ", 8)) {
+ parse_keyboard_layout(table, line + 8, k);
} else {
- char *end_of_keysym = line;
- while (*end_of_keysym != 0 && *end_of_keysym != ' ')
- end_of_keysym++;
- if (*end_of_keysym) {
- int keysym;
- *end_of_keysym = 0;
- keysym = get_keysym(table, line);
- if (keysym == 0) {
- // fprintf(stderr, "Warning: unknown keysym %s\n", line);
- } else {
- const char *rest = end_of_keysym + 1;
+ char *end_of_keysym = line;
+ while (*end_of_keysym != 0 && *end_of_keysym != ' ') {
+ end_of_keysym++;
+ }
+ if (*end_of_keysym) {
+ int keysym;
+ *end_of_keysym = 0;
+ keysym = get_keysym(table, line);
+ if (keysym == 0) {
+ /* fprintf(stderr, "Warning: unknown keysym %s\n", line);*/
+ } else {
+ const char *rest = end_of_keysym + 1;
int keycode = strtol(rest, NULL, 0);
if (strstr(rest, "numlock")) {
- add_to_key_range(&k->keypad_range, keycode);
- add_to_key_range(&k->numlock_range, keysym);
- //fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode);
- }
+ add_to_key_range(&k->keypad_range, keycode);
+ add_to_key_range(&k->numlock_range, keysym);
+ /* fprintf(stderr, "keypad keysym %04x keycode %d\n",
+ keysym, keycode); */
+ }
if (strstr(rest, "shift")) {
- keycode |= SCANCODE_SHIFT;
+ keycode |= SCANCODE_SHIFT;
}
if (strstr(rest, "altgr")) {
- keycode |= SCANCODE_ALTGR;
+ keycode |= SCANCODE_ALTGR;
}
if (strstr(rest, "ctrl")) {
- keycode |= SCANCODE_CTRL;
+ keycode |= SCANCODE_CTRL;
}
- add_keysym(line, keysym, keycode, k);
+ add_keysym(line, keysym, keycode, k);
if (strstr(rest, "addupper")) {
- char *c;
- for (c = line; *c; c++)
- *c = qemu_toupper(*c);
- keysym = get_keysym(table, line);
- if (keysym)
- add_keysym(line, keysym, keycode | SCANCODE_SHIFT, k);
- }
- }
- }
- }
+ char *c;
+ for (c = line; *c; c++) {
+ *c = qemu_toupper(*c);
+ }
+ keysym = get_keysym(table, line);
+ if (keysym) {
+ add_keysym(line, keysym,
+ keycode | SCANCODE_SHIFT, k);
+ }
+ }
+ }
+ }
+ }
}
fclose(f);
return k;
@@ -180,19 +192,23 @@ int keysym2scancode(void *kbd_layout, int keysym)
{
kbd_layout_t *k = kbd_layout;
if (keysym < MAX_NORMAL_KEYCODE) {
- if (k->keysym2keycode[keysym] == 0)
- fprintf(stderr, "Warning: no scancode found for keysym %d\n",
- keysym);
- return k->keysym2keycode[keysym];
+ if (k->keysym2keycode[keysym] == 0) {
+ fprintf(stderr, "Warning: no scancode found for keysym %d\n",
+ keysym);
+ }
+ return k->keysym2keycode[keysym];
} else {
- int i;
+ int i;
#ifdef XK_ISO_Left_Tab
- if (keysym == XK_ISO_Left_Tab)
- keysym = XK_Tab;
+ if (keysym == XK_ISO_Left_Tab) {
+ keysym = XK_Tab;
+ }
#endif
- for (i = 0; i < k->extra_count; i++)
- if (k->keysym2keycode_extra[i].keysym == keysym)
- return k->keysym2keycode_extra[i].keycode;
+ for (i = 0; i < k->extra_count; i++) {
+ if (k->keysym2keycode_extra[i].keysym == keysym) {
+ return k->keysym2keycode_extra[i].keycode;
+ }
+ }
}
return 0;
}
@@ -202,9 +218,11 @@ int keycode_is_keypad(void *kbd_layout, int keycode)
kbd_layout_t *k = kbd_layout;
struct key_range *kr;
- for (kr = k->keypad_range; kr; kr = kr->next)
- if (keycode >= kr->start && keycode <= kr->end)
+ for (kr = k->keypad_range; kr; kr = kr->next) {
+ if (keycode >= kr->start && keycode <= kr->end) {
return 1;
+ }
+ }
return 0;
}
@@ -213,8 +231,10 @@ int keysym_is_numlock(void *kbd_layout, int keysym)
kbd_layout_t *k = kbd_layout;
struct key_range *kr;
- for (kr = k->numlock_range; kr; kr = kr->next)
- if (keysym >= kr->start && keysym <= kr->end)
+ for (kr = k->numlock_range; kr; kr = kr->next) {
+ if (keysym >= kr->start && keysym <= kr->end) {
return 1;
+ }
+ }
return 0;
}
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 3d1b5cd066..9a9ddf2e3c 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -1489,7 +1489,7 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
}
#endif
- colors = tight_fill_palette(vs, x, y, w * h, &fg, &bg, &palette);
+ colors = tight_fill_palette(vs, x, y, w * h, &bg, &fg, &palette);
#ifdef CONFIG_VNC_JPEG
if (allow_jpeg && vs->tight.quality != (uint8_t)-1) {
diff --git a/util/hbitmap.c b/util/hbitmap.c
index b3060e6976..ab139717f5 100644
--- a/util/hbitmap.c
+++ b/util/hbitmap.c
@@ -373,7 +373,7 @@ void hbitmap_free(HBitmap *hb)
HBitmap *hbitmap_alloc(uint64_t size, int granularity)
{
- HBitmap *hb = g_malloc0(sizeof (struct HBitmap));
+ HBitmap *hb = g_new0(struct HBitmap, 1);
unsigned i;
assert(granularity >= 0 && granularity < 64);
@@ -384,7 +384,7 @@ HBitmap *hbitmap_alloc(uint64_t size, int granularity)
hb->granularity = granularity;
for (i = HBITMAP_LEVELS; i-- > 0; ) {
size = MAX((size + BITS_PER_LONG - 1) >> BITS_PER_LEVEL, 1);
- hb->levels[i] = g_malloc0(size * sizeof(unsigned long));
+ hb->levels[i] = g_new0(unsigned long, size);
}
/* We necessarily have free bits in level 0 due to the definition
diff --git a/util/iov.c b/util/iov.c
index 24566c8789..2fb18e6654 100644
--- a/util/iov.c
+++ b/util/iov.c
@@ -253,7 +253,7 @@ unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
{
- qiov->iov = g_malloc(alloc_hint * sizeof(struct iovec));
+ qiov->iov = g_new(struct iovec, alloc_hint);
qiov->niov = 0;
qiov->nalloc = alloc_hint;
qiov->size = 0;
@@ -277,7 +277,7 @@ void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
if (qiov->niov == qiov->nalloc) {
qiov->nalloc = 2 * qiov->nalloc + 1;
- qiov->iov = g_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec));
+ qiov->iov = g_renew(struct iovec, qiov->iov, qiov->nalloc);
}
qiov->iov[qiov->niov].iov_base = base;
qiov->iov[qiov->niov].iov_len = len;
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 5d106959ca..a708241643 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -737,14 +737,14 @@ void qemu_opts_del(QemuOpts *opts)
g_free(opts);
}
-void qemu_opts_print(QemuOpts *opts)
+void qemu_opts_print(QemuOpts *opts, const char *sep)
{
QemuOpt *opt;
QemuOptDesc *desc = opts->list->desc;
if (desc[0].name == NULL) {
QTAILQ_FOREACH(opt, &opts->head, next) {
- printf("%s=\"%s\" ", opt->name, opt->str);
+ printf("%s%s=\"%s\"", sep, opt->name, opt->str);
}
return;
}
@@ -757,12 +757,12 @@ void qemu_opts_print(QemuOpts *opts)
continue;
}
if (desc->type == QEMU_OPT_STRING) {
- printf("%s='%s' ", desc->name, value);
+ printf("%s%s='%s'", sep, desc->name, value);
} else if ((desc->type == QEMU_OPT_SIZE ||
desc->type == QEMU_OPT_NUMBER) && opt) {
- printf("%s=%" PRId64 " ", desc->name, opt->value.uint);
+ printf("%s%s=%" PRId64, sep, desc->name, opt->value.uint);
} else {
- printf("%s=%s ", desc->name, value);
+ printf("%s%s=%s", sep, desc->name, value);
}
}
}
diff --git a/util/uri.c b/util/uri.c
index e348c1768c..918d23516d 100644
--- a/util/uri.c
+++ b/util/uri.c
@@ -225,7 +225,7 @@ rfc3986_parse_scheme(URI *uri, const char **str) {
while (ISA_ALPHA(cur) || ISA_DIGIT(cur) ||
(*cur == '+') || (*cur == '-') || (*cur == '.')) cur++;
if (uri != NULL) {
- if (uri->scheme != NULL) g_free(uri->scheme);
+ g_free(uri->scheme);
uri->scheme = g_strndup(*str, cur - *str);
}
*str = cur;
@@ -262,8 +262,7 @@ rfc3986_parse_fragment(URI *uri, const char **str)
((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
NEXT(cur);
if (uri != NULL) {
- if (uri->fragment != NULL)
- g_free(uri->fragment);
+ g_free(uri->fragment);
if (uri->cleanup & 2)
uri->fragment = g_strndup(*str, cur - *str);
else
@@ -298,8 +297,7 @@ rfc3986_parse_query(URI *uri, const char **str)
((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
NEXT(cur);
if (uri != NULL) {
- if (uri->query != NULL)
- g_free (uri->query);
+ g_free(uri->query);
uri->query = g_strndup (*str, cur - *str);
}
*str = cur;
@@ -360,7 +358,7 @@ rfc3986_parse_user_info(URI *uri, const char **str)
NEXT(cur);
if (*cur == '@') {
if (uri != NULL) {
- if (uri->user != NULL) g_free(uri->user);
+ g_free(uri->user);
if (uri->cleanup & 2)
uri->user = g_strndup(*str, cur - *str);
else
@@ -473,9 +471,9 @@ not_ipv4:
NEXT(cur);
found:
if (uri != NULL) {
- if (uri->authority != NULL) g_free(uri->authority);
+ g_free(uri->authority);
uri->authority = NULL;
- if (uri->server != NULL) g_free(uri->server);
+ g_free(uri->server);
if (cur != host) {
if (uri->cleanup & 2)
uri->server = g_strndup(host, cur - host);
@@ -585,7 +583,7 @@ rfc3986_parse_path_ab_empty(URI *uri, const char **str)
if (ret != 0) return(ret);
}
if (uri != NULL) {
- if (uri->path != NULL) g_free(uri->path);
+ g_free(uri->path);
if (*str != cur) {
if (uri->cleanup & 2)
uri->path = g_strndup(*str, cur - *str);
@@ -631,7 +629,7 @@ rfc3986_parse_path_absolute(URI *uri, const char **str)
}
}
if (uri != NULL) {
- if (uri->path != NULL) g_free(uri->path);
+ g_free(uri->path);
if (cur != *str) {
if (uri->cleanup & 2)
uri->path = g_strndup(*str, cur - *str);
@@ -673,7 +671,7 @@ rfc3986_parse_path_rootless(URI *uri, const char **str)
if (ret != 0) return(ret);
}
if (uri != NULL) {
- if (uri->path != NULL) g_free(uri->path);
+ g_free(uri->path);
if (cur != *str) {
if (uri->cleanup & 2)
uri->path = g_strndup(*str, cur - *str);
@@ -715,7 +713,7 @@ rfc3986_parse_path_no_scheme(URI *uri, const char **str)
if (ret != 0) return(ret);
}
if (uri != NULL) {
- if (uri->path != NULL) g_free(uri->path);
+ g_free(uri->path);
if (cur != *str) {
if (uri->cleanup & 2)
uri->path = g_strndup(*str, cur - *str);
@@ -769,7 +767,7 @@ rfc3986_parse_hier_part(URI *uri, const char **str)
} else {
/* path-empty is effectively empty */
if (uri != NULL) {
- if (uri->path != NULL) g_free(uri->path);
+ g_free(uri->path);
uri->path = NULL;
}
}
@@ -812,7 +810,7 @@ rfc3986_parse_relative_ref(URI *uri, const char *str) {
} else {
/* path-empty is effectively empty */
if (uri != NULL) {
- if (uri->path != NULL) g_free(uri->path);
+ g_free(uri->path);
uri->path = NULL;
}
}
@@ -1006,8 +1004,7 @@ URI *
uri_new(void) {
URI *ret;
- ret = (URI *) g_malloc(sizeof(URI));
- memset(ret, 0, sizeof(URI));
+ ret = g_new0(URI, 1);
return(ret);
}
@@ -1285,21 +1282,21 @@ static void
uri_clean(URI *uri) {
if (uri == NULL) return;
- if (uri->scheme != NULL) g_free(uri->scheme);
+ g_free(uri->scheme);
uri->scheme = NULL;
- if (uri->server != NULL) g_free(uri->server);
+ g_free(uri->server);
uri->server = NULL;
- if (uri->user != NULL) g_free(uri->user);
+ g_free(uri->user);
uri->user = NULL;
- if (uri->path != NULL) g_free(uri->path);
+ g_free(uri->path);
uri->path = NULL;
- if (uri->fragment != NULL) g_free(uri->fragment);
+ g_free(uri->fragment);
uri->fragment = NULL;
- if (uri->opaque != NULL) g_free(uri->opaque);
+ g_free(uri->opaque);
uri->opaque = NULL;
- if (uri->authority != NULL) g_free(uri->authority);
+ g_free(uri->authority);
uri->authority = NULL;
- if (uri->query != NULL) g_free(uri->query);
+ g_free(uri->query);
uri->query = NULL;
}
@@ -1711,10 +1708,8 @@ uri_resolve(const char *uri, const char *base) {
/*
* the base fragment must be ignored
*/
- if (bas->fragment != NULL) {
- g_free(bas->fragment);
- bas->fragment = NULL;
- }
+ g_free(bas->fragment);
+ bas->fragment = NULL;
val = uri_to_string(bas);
goto done;
}
@@ -1736,24 +1731,21 @@ uri_resolve(const char *uri, const char *base) {
goto done;
if ((ref->scheme == NULL) && (ref->path == NULL) &&
((ref->authority == NULL) && (ref->server == NULL))) {
- if (bas->scheme != NULL)
- res->scheme = g_strdup(bas->scheme);
+ res->scheme = g_strdup(bas->scheme);
if (bas->authority != NULL)
res->authority = g_strdup(bas->authority);
else if (bas->server != NULL) {
- res->server = g_strdup(bas->server);
- if (bas->user != NULL)
- res->user = g_strdup(bas->user);
- res->port = bas->port;
+ res->server = g_strdup(bas->server);
+ res->user = g_strdup(bas->user);
+ res->port = bas->port;
}
- if (bas->path != NULL)
- res->path = g_strdup(bas->path);
- if (ref->query != NULL)
+ res->path = g_strdup(bas->path);
+ if (ref->query != NULL) {
res->query = g_strdup (ref->query);
- else if (bas->query != NULL)
- res->query = g_strdup(bas->query);
- if (ref->fragment != NULL)
- res->fragment = g_strdup(ref->fragment);
+ } else {
+ res->query = g_strdup(bas->query);
+ }
+ res->fragment = g_strdup(ref->fragment);
goto step_7;
}
@@ -1767,13 +1759,10 @@ uri_resolve(const char *uri, const char *base) {
val = uri_to_string(ref);
goto done;
}
- if (bas->scheme != NULL)
- res->scheme = g_strdup(bas->scheme);
+ res->scheme = g_strdup(bas->scheme);
- if (ref->query != NULL)
- res->query = g_strdup(ref->query);
- if (ref->fragment != NULL)
- res->fragment = g_strdup(ref->fragment);
+ res->query = g_strdup(ref->query);
+ res->fragment = g_strdup(ref->fragment);
/*
* 4) If the authority component is defined, then the reference is a
@@ -1787,20 +1776,17 @@ uri_resolve(const char *uri, const char *base) {
res->authority = g_strdup(ref->authority);
else {
res->server = g_strdup(ref->server);
- if (ref->user != NULL)
- res->user = g_strdup(ref->user);
+ res->user = g_strdup(ref->user);
res->port = ref->port;
}
- if (ref->path != NULL)
- res->path = g_strdup(ref->path);
+ res->path = g_strdup(ref->path);
goto step_7;
}
if (bas->authority != NULL)
res->authority = g_strdup(bas->authority);
else if (bas->server != NULL) {
- res->server = g_strdup(bas->server);
- if (bas->user != NULL)
- res->user = g_strdup(bas->user);
+ res->server = g_strdup(bas->server);
+ res->user = g_strdup(bas->user);
res->port = bas->port;
}
diff --git a/vl.c b/vl.c
index f4a6e5e05b..113e98e56b 100644
--- a/vl.c
+++ b/vl.c
@@ -381,7 +381,7 @@ static QemuOptsList qemu_machine_opts = {
.help = "maximum ram below the 4G boundary (32bit boundary)",
}, {
.name = PC_MACHINE_VMPORT,
- .type = QEMU_OPT_BOOL,
+ .type = QEMU_OPT_STRING,
.help = "Enable vmport (pc & q35)",
},{
.name = "iommu",
@@ -554,6 +554,22 @@ static QemuOptsList qemu_icount_opts = {
},
};
+static QemuOptsList qemu_semihosting_config_opts = {
+ .name = "semihosting-config",
+ .implied_opt_name = "enable",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_semihosting_config_opts.head),
+ .desc = {
+ {
+ .name = "enable",
+ .type = QEMU_OPT_BOOL,
+ }, {
+ .name = "target",
+ .type = QEMU_OPT_STRING,
+ },
+ { /* end of list */ }
+ },
+};
+
/**
* Get machine options
*
@@ -2284,7 +2300,7 @@ static int mon_init_func(QemuOpts *opts, void *opaque)
return 0;
}
-static void monitor_parse(const char *optarg, const char *mode)
+static void monitor_parse(const char *optarg, const char *mode, bool pretty)
{
static int monitor_device_index = 0;
QemuOpts *opts;
@@ -2314,6 +2330,7 @@ static void monitor_parse(const char *optarg, const char *mode)
}
qemu_opt_set(opts, "mode", mode);
qemu_opt_set(opts, "chardev", label);
+ qemu_opt_set_bool(opts, "pretty", pretty);
if (def)
qemu_opt_set(opts, "default", "on");
monitor_device_index++;
@@ -2811,6 +2828,7 @@ int main(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_name_opts);
qemu_add_opts(&qemu_numa_opts);
qemu_add_opts(&qemu_icount_opts);
+ qemu_add_opts(&qemu_semihosting_config_opts);
runstate_init();
@@ -3292,11 +3310,15 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_monitor:
default_monitor = 0;
if (strncmp(optarg, "none", 4)) {
- monitor_parse(optarg, "readline");
+ monitor_parse(optarg, "readline", false);
}
break;
case QEMU_OPTION_qmp:
- monitor_parse(optarg, "control");
+ monitor_parse(optarg, "control", false);
+ default_monitor = 0;
+ break;
+ case QEMU_OPTION_qmp_pretty:
+ monitor_parse(optarg, "control", true);
default_monitor = 0;
break;
case QEMU_OPTION_mon:
@@ -3618,6 +3640,37 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_semihosting:
semihosting_enabled = 1;
+ semihosting_target = SEMIHOSTING_TARGET_AUTO;
+ break;
+ case QEMU_OPTION_semihosting_config:
+ semihosting_enabled = 1;
+ opts = qemu_opts_parse(qemu_find_opts("semihosting-config"),
+ optarg, 0);
+ if (opts != NULL) {
+ semihosting_enabled = qemu_opt_get_bool(opts, "enable",
+ true);
+ const char *target = qemu_opt_get(opts, "target");
+ if (target != NULL) {
+ if (strcmp("native", target) == 0) {
+ semihosting_target = SEMIHOSTING_TARGET_NATIVE;
+ } else if (strcmp("gdb", target) == 0) {
+ semihosting_target = SEMIHOSTING_TARGET_GDB;
+ } else if (strcmp("auto", target) == 0) {
+ semihosting_target = SEMIHOSTING_TARGET_AUTO;
+ } else {
+ fprintf(stderr, "Unsupported semihosting-config"
+ " %s\n",
+ optarg);
+ exit(1);
+ }
+ } else {
+ semihosting_target = SEMIHOSTING_TARGET_AUTO;
+ }
+ } else {
+ fprintf(stderr, "Unsupported semihosting-config %s\n",
+ optarg);
+ exit(1);
+ }
break;
case QEMU_OPTION_tdf:
fprintf(stderr, "Warning: user space PIT time drift fix "
@@ -3994,7 +4047,7 @@ int main(int argc, char **argv, char **envp)
add_device_config(DEV_SCLP, "stdio");
}
if (default_monitor)
- monitor_parse("stdio", "readline");
+ monitor_parse("stdio", "readline", false);
}
} else {
if (default_serial)
@@ -4002,7 +4055,7 @@ int main(int argc, char **argv, char **envp)
if (default_parallel)
add_device_config(DEV_PARALLEL, "vc:80Cx24C");
if (default_monitor)
- monitor_parse("vc:80Cx24C", "readline");
+ monitor_parse("vc:80Cx24C", "readline", false);
if (default_virtcon)
add_device_config(DEV_VIRTCON, "vc:80Cx24C");
if (default_sclp) {