aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block.c1
-rw-r--r--block/Makefile.objs2
-rw-r--r--block/backup.c2
-rw-r--r--block/blkdebug.c1
-rw-r--r--block/curl.c6
-rw-r--r--block/gluster.c15
-rw-r--r--block/qcow2-cache.c17
-rw-r--r--block/qcow2-cluster.c25
-rw-r--r--block/qcow2-refcount.c533
-rw-r--r--block/qcow2-snapshot.c22
-rw-r--r--block/qcow2.c83
-rw-r--r--block/qcow2.h53
-rw-r--r--block/raw_bsd.c (renamed from block/raw.c)170
-rw-r--r--blockdev.c143
-rwxr-xr-xconfigure71
-rw-r--r--docs/specs/qcow2.txt7
-rw-r--r--hw/alpha/dp264.c1
-rw-r--r--hw/arm/collie.c1
-rw-r--r--hw/arm/exynos4_boards.c2
-rw-r--r--hw/arm/gumstix.c2
-rw-r--r--hw/arm/highbank.c2
-rw-r--r--hw/arm/integratorcp.c1
-rw-r--r--hw/arm/kzm.c1
-rw-r--r--hw/arm/mainstone.c1
-rw-r--r--hw/arm/musicpal.c1
-rw-r--r--hw/arm/nseries.c6
-rw-r--r--hw/arm/omap_sx1.c2
-rw-r--r--hw/arm/palm.c1
-rw-r--r--hw/arm/realview.c4
-rw-r--r--hw/arm/spitz.c4
-rw-r--r--hw/arm/stellaris.c2
-rw-r--r--hw/arm/tosa.c1
-rw-r--r--hw/arm/versatilepb.c2
-rw-r--r--hw/arm/vexpress.c2
-rw-r--r--hw/arm/xilinx_zynq.c1
-rw-r--r--hw/arm/z2.c1
-rw-r--r--hw/audio/adlib.c2
-rw-r--r--hw/audio/intel-hda.c6
-rw-r--r--hw/audio/intel-hda.h2
-rw-r--r--hw/block/pflash_cfi02.c2
-rw-r--r--hw/char/ipack.c5
-rw-r--r--hw/char/ipack.h3
-rw-r--r--hw/char/tpci200.c2
-rw-r--r--hw/char/virtio-serial-bus.c4
-rw-r--r--hw/core/null-machine.c1
-rw-r--r--hw/core/qdev.c4
-rw-r--r--hw/core/sysbus.c4
-rw-r--r--hw/cpu/icc_bus.c3
-rw-r--r--hw/cris/axis_dev88.c1
-rw-r--r--hw/dma/xilinx_axidma.c6
-rw-r--r--hw/i386/pc_piix.c88
-rw-r--r--hw/i386/pc_q35.c27
-rw-r--r--hw/i386/xen_machine_pv.c1
-rw-r--r--hw/ide/ahci.c2
-rw-r--r--hw/ide/cmd646.c2
-rw-r--r--hw/ide/internal.h3
-rw-r--r--hw/ide/isa.c2
-rw-r--r--hw/ide/macio.c2
-rw-r--r--hw/ide/mmio.c2
-rw-r--r--hw/ide/piix.c2
-rw-r--r--hw/ide/qdev.c5
-rw-r--r--hw/ide/via.c2
-rw-r--r--hw/intc/xics.c2
-rw-r--r--hw/lm32/lm32_boards.c2
-rw-r--r--hw/lm32/milkymist.c1
-rw-r--r--hw/m68k/an5206.c1
-rw-r--r--hw/m68k/dummy_m68k.c1
-rw-r--r--hw/m68k/mcf5208.c1
-rw-r--r--hw/microblaze/petalogix_ml605_mmu.c1
-rw-r--r--hw/microblaze/petalogix_s3adsp1800_mmu.c1
-rw-r--r--hw/mips/mips_fulong2e.c1
-rw-r--r--hw/mips/mips_jazz.c2
-rw-r--r--hw/mips/mips_malta.c1
-rw-r--r--hw/mips/mips_mipssim.c1
-rw-r--r--hw/mips/mips_r4k.c1
-rw-r--r--hw/misc/macio/cuda.c4
-rw-r--r--hw/misc/macio/macio.c13
-rw-r--r--hw/net/xilinx_axienet.c6
-rw-r--r--hw/openrisc/openrisc_sim.c1
-rw-r--r--hw/pci-host/piix.c9
-rw-r--r--hw/pci-host/prep.c4
-rw-r--r--hw/pci-host/q35.c10
-rw-r--r--hw/pci-host/versatile.c4
-rw-r--r--hw/pci/pci.c28
-rw-r--r--hw/pci/pci_bridge.c3
-rw-r--r--hw/pci/pci_host.c11
-rw-r--r--hw/ppc/e500plat.c1
-rw-r--r--hw/ppc/mac_newworld.c4
-rw-r--r--hw/ppc/mac_oldworld.c4
-rw-r--r--hw/ppc/mpc8544ds.c1
-rw-r--r--hw/ppc/ppc405_boards.c2
-rw-r--r--hw/ppc/ppc440_bamboo.c1
-rw-r--r--hw/ppc/prep.c4
-rw-r--r--hw/ppc/spapr.c4
-rw-r--r--hw/ppc/virtex_ml507.c1
-rw-r--r--hw/s390x/css.c2
-rw-r--r--hw/s390x/event-facility.c4
-rw-r--r--hw/s390x/s390-virtio-bus.c24
-rw-r--r--hw/s390x/s390-virtio-ccw.c1
-rw-r--r--hw/s390x/s390-virtio.c1
-rw-r--r--hw/s390x/virtio-ccw.c26
-rw-r--r--hw/scsi/esp-pci.c2
-rw-r--r--hw/scsi/esp.c2
-rw-r--r--hw/scsi/lsi53c895a.c2
-rw-r--r--hw/scsi/megasas.c3
-rw-r--r--hw/scsi/scsi-bus.c6
-rw-r--r--hw/scsi/spapr_vscsi.c3
-rw-r--r--hw/scsi/virtio-scsi.c3
-rw-r--r--hw/scsi/vmw_pvscsi.c3
-rw-r--r--hw/sh4/r2d.c1
-rw-r--r--hw/sh4/shix.c1
-rw-r--r--hw/sparc/leon3.c1
-rw-r--r--hw/sparc/sun4m.c22
-rw-r--r--hw/sparc64/sun4u.c10
-rw-r--r--hw/timer/exynos4210_rtc.c4
-rw-r--r--hw/unicore32/puv3.c1
-rw-r--r--hw/usb/bus.c5
-rw-r--r--hw/usb/core.c7
-rw-r--r--hw/usb/dev-hid.c2
-rw-r--r--hw/usb/dev-hub.c7
-rw-r--r--hw/usb/dev-smartcard-reader.c3
-rw-r--r--hw/usb/dev-storage.c6
-rw-r--r--hw/usb/dev-uas.c18
-rw-r--r--hw/usb/hcd-ehci.c2
-rw-r--r--hw/usb/hcd-musb.c2
-rw-r--r--hw/usb/hcd-ohci.c2
-rw-r--r--hw/usb/hcd-uhci.c2
-rw-r--r--hw/usb/hcd-xhci.c72
-rw-r--r--hw/virtio/virtio-mmio.c10
-rw-r--r--hw/virtio/virtio-pci.c29
-rw-r--r--hw/xtensa/xtensa_lx60.c2
-rw-r--r--hw/xtensa/xtensa_sim.c1
-rw-r--r--include/block/block.h1
-rw-r--r--include/hw/boards.h7
-rw-r--r--include/hw/bt.h8
-rw-r--r--include/hw/i386/pc.h19
-rw-r--r--include/hw/isa/isa.h2
-rw-r--r--include/hw/pci/pci.h3
-rw-r--r--include/hw/qdev-core.h2
-rw-r--r--include/hw/scsi/scsi.h4
-rw-r--r--include/hw/usb.h3
-rw-r--r--include/monitor/monitor.h1
-rw-r--r--include/qemu/option.h1
-rw-r--r--include/qom/object.h10
-rw-r--r--libcacard/card_7816.c2
-rw-r--r--libcacard/card_7816t.h2
-rw-r--r--linux-headers/asm-powerpc/epapr_hcalls.h4
-rw-r--r--migration-rdma.c14
-rw-r--r--monitor.c1
-rw-r--r--qmp-commands.hx26
-rw-r--r--qom/object.c9
-rw-r--r--scripts/qapi-types.py19
-rw-r--r--slirp/arp_table.c4
-rw-r--r--slirp/socket.c2
-rw-r--r--target-arm/translate.c4
-rw-r--r--tcg/tci/tcg-target.c7
-rw-r--r--tests/qemu-iotests/031.out12
-rw-r--r--tests/qemu-iotests/036.out2
-rw-r--r--tests/qemu-iotests/051.out1
-rwxr-xr-xtests/qemu-iotests/060111
-rw-r--r--tests/qemu-iotests/060.out44
-rwxr-xr-xtests/qemu-iotests/06264
-rw-r--r--tests/qemu-iotests/062.out9
-rw-r--r--tests/qemu-iotests/group4
-rw-r--r--tests/test-aio.c6
-rw-r--r--trace-events8
-rw-r--r--util/qemu-option.c9
-rw-r--r--vl.c4
168 files changed, 1489 insertions, 735 deletions
diff --git a/block.c b/block.c
index a387c1ad68..26639e8b70 100644
--- a/block.c
+++ b/block.c
@@ -743,7 +743,6 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
ret = -EINVAL;
goto free_and_fail;
}
- assert(file != NULL);
bs->file = file;
ret = drv->bdrv_open(bs, options, open_flags);
}
diff --git a/block/Makefile.objs b/block/Makefile.objs
index 4cf9aa499f..3bb85b535c 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -1,4 +1,4 @@
-block-obj-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
+block-obj-y += raw_bsd.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o
block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-y += qed-check.o
diff --git a/block/backup.c b/block/backup.c
index e12b3b1461..23c7264488 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -290,7 +290,7 @@ static void coroutine_fn backup_run(void *opaque)
for (i = 0; i < BACKUP_SECTORS_PER_CLUSTER;) {
/* bdrv_co_is_allocated() only returns true/false based
- * on the first set of sectors it comes accross that
+ * on the first set of sectors it comes across that
* are are all in the same state.
* For that reason we must verify each sector in the
* backup cluster length. We end up copying more than
diff --git a/block/blkdebug.c b/block/blkdebug.c
index ccb627ad93..5d33e03608 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -168,6 +168,7 @@ static const char *event_names[BLKDBG_EVENT_MAX] = {
[BLKDBG_REFTABLE_LOAD] = "reftable_load",
[BLKDBG_REFTABLE_GROW] = "reftable_grow",
+ [BLKDBG_REFTABLE_UPDATE] = "reftable_update",
[BLKDBG_REFBLOCK_LOAD] = "refblock_load",
[BLKDBG_REFBLOCK_UPDATE] = "refblock_update",
diff --git a/block/curl.c b/block/curl.c
index e566855f76..ca2cedcec1 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -572,12 +572,6 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
acb->nb_sectors = nb_sectors;
acb->bh = qemu_bh_new(curl_readv_bh_cb, acb);
-
- if (!acb->bh) {
- DPRINTF("CURL: qemu_bh_new failed\n");
- return NULL;
- }
-
qemu_bh_schedule(acb->bh);
return &acb->common;
}
diff --git a/block/gluster.c b/block/gluster.c
index 46f36f8cd6..dbb03f4de5 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -427,20 +427,9 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
/*
* Gluster AIO callback thread failed to notify the waiting
* QEMU thread about IO completion.
- *
- * Complete this IO request and make the disk inaccessible for
- * subsequent reads and writes.
*/
- error_report("Gluster failed to notify QEMU about IO completion");
-
- qemu_mutex_lock_iothread(); /* We are in gluster thread context */
- acb->common.cb(acb->common.opaque, -EIO);
- qemu_aio_release(acb);
- close(s->fds[GLUSTER_FD_READ]);
- close(s->fds[GLUSTER_FD_WRITE]);
- qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL);
- bs->drv = NULL; /* Make the disk inaccessible */
- qemu_mutex_unlock_iothread();
+ error_report("Gluster AIO completion failed: %s", strerror(errno));
+ abort();
}
}
diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
index 2f3114ecc2..7bcae09a69 100644
--- a/block/qcow2-cache.c
+++ b/block/qcow2-cache.c
@@ -115,6 +115,23 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
}
if (c == s->refcount_block_cache) {
+ ret = qcow2_pre_write_overlap_check(bs,
+ QCOW2_OL_DEFAULT & ~QCOW2_OL_REFCOUNT_BLOCK,
+ c->entries[i].offset, s->cluster_size);
+ } else if (c == s->l2_table_cache) {
+ ret = qcow2_pre_write_overlap_check(bs,
+ QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L2,
+ c->entries[i].offset, s->cluster_size);
+ } else {
+ ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+ c->entries[i].offset, s->cluster_size);
+ }
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (c == s->refcount_block_cache) {
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART);
} else if (c == s->l2_table_cache) {
BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index cca76d4fcd..2d5aa92962 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -80,6 +80,14 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
goto fail;
}
+ /* the L1 position has not yet been updated, so these clusters must
+ * indeed be completely free */
+ ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+ new_l1_table_offset, new_l1_size2);
+ if (ret < 0) {
+ goto fail;
+ }
+
BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
for(i = 0; i < s->l1_size; i++)
new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
@@ -137,7 +145,7 @@ static int l2_load(BlockDriverState *bs, uint64_t l2_offset,
* and we really don't want bdrv_pread to perform a read-modify-write)
*/
#define L1_ENTRIES_PER_SECTOR (512 / 8)
-static int write_l1_entry(BlockDriverState *bs, int l1_index)
+int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
{
BDRVQcowState *s = bs->opaque;
uint64_t buf[L1_ENTRIES_PER_SECTOR];
@@ -149,6 +157,13 @@ static int write_l1_entry(BlockDriverState *bs, int l1_index)
buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
}
+ ret = qcow2_pre_write_overlap_check(bs,
+ QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L1,
+ s->l1_table_offset + 8 * l1_start_index, sizeof(buf));
+ if (ret < 0) {
+ return ret;
+ }
+
BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + 8 * l1_start_index,
buf, sizeof(buf));
@@ -239,7 +254,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
/* update the L1 entry */
trace_qcow2_l2_allocate_write_l1(bs, l1_index);
s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
- ret = write_l1_entry(bs, l1_index);
+ ret = qcow2_write_l1_entry(bs, l1_index);
if (ret < 0) {
goto fail;
}
@@ -368,6 +383,12 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs,
&s->aes_encrypt_key);
}
+ ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+ cluster_offset + n_start * BDRV_SECTOR_SIZE, n * BDRV_SECTOR_SIZE);
+ if (ret < 0) {
+ goto out;
+ }
+
BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + n_start, n, &qiov);
if (ret < 0) {
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 1244693f39..ba129de478 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -25,6 +25,8 @@
#include "qemu-common.h"
#include "block/block_int.h"
#include "block/qcow2.h"
+#include "qemu/range.h"
+#include "qapi/qmp/types.h"
static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size);
static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
@@ -861,11 +863,14 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
}
for(j = 0; j < s->l2_size; j++) {
+ uint64_t cluster_index;
+
offset = be64_to_cpu(l2_table[j]);
- if (offset != 0) {
- old_offset = offset;
- offset &= ~QCOW_OFLAG_COPIED;
- if (offset & QCOW_OFLAG_COMPRESSED) {
+ old_offset = offset;
+ offset &= ~QCOW_OFLAG_COPIED;
+
+ switch (qcow2_get_cluster_type(offset)) {
+ case QCOW2_CLUSTER_COMPRESSED:
nb_csectors = ((offset >> s->csize_shift) &
s->csize_mask) + 1;
if (addend != 0) {
@@ -880,8 +885,16 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
}
/* compressed clusters are never modified */
refcount = 2;
- } else {
- uint64_t cluster_index = (offset & L2E_OFFSET_MASK) >> s->cluster_bits;
+ break;
+
+ case QCOW2_CLUSTER_NORMAL:
+ case QCOW2_CLUSTER_ZERO:
+ cluster_index = (offset & L2E_OFFSET_MASK) >> s->cluster_bits;
+ if (!cluster_index) {
+ /* unallocated */
+ refcount = 0;
+ break;
+ }
if (addend != 0) {
refcount = update_cluster_refcount(bs, cluster_index, addend,
QCOW2_DISCARD_SNAPSHOT);
@@ -893,19 +906,26 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
ret = refcount;
goto fail;
}
- }
+ break;
- if (refcount == 1) {
- offset |= QCOW_OFLAG_COPIED;
- }
- if (offset != old_offset) {
- if (addend > 0) {
- qcow2_cache_set_dependency(bs, s->l2_table_cache,
- s->refcount_block_cache);
- }
- l2_table[j] = cpu_to_be64(offset);
- qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
+ case QCOW2_CLUSTER_UNALLOCATED:
+ refcount = 0;
+ break;
+
+ default:
+ abort();
+ }
+
+ if (refcount == 1) {
+ offset |= QCOW_OFLAG_COPIED;
+ }
+ if (offset != old_offset) {
+ if (addend > 0) {
+ qcow2_cache_set_dependency(bs, s->l2_table_cache,
+ s->refcount_block_cache);
}
+ l2_table[j] = cpu_to_be64(offset);
+ qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
}
}
@@ -1033,7 +1053,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
BDRVQcowState *s = bs->opaque;
uint64_t *l2_table, l2_entry;
uint64_t next_contiguous_offset = 0;
- int i, l2_size, nb_csectors, refcount;
+ int i, l2_size, nb_csectors;
/* Read L2 table from disk */
l2_size = s->l2_size * sizeof(uint64_t);
@@ -1085,23 +1105,8 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
case QCOW2_CLUSTER_NORMAL:
{
- /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
uint64_t offset = l2_entry & L2E_OFFSET_MASK;
- if (flags & CHECK_OFLAG_COPIED) {
- refcount = get_refcount(bs, offset >> s->cluster_bits);
- if (refcount < 0) {
- fprintf(stderr, "Can't get refcount for offset %"
- PRIx64 ": %s\n", l2_entry, strerror(-refcount));
- goto fail;
- }
- if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
- fprintf(stderr, "ERROR OFLAG_COPIED: offset=%"
- PRIx64 " refcount=%d\n", l2_entry, refcount);
- res->corruptions++;
- }
- }
-
if (flags & CHECK_FRAG_INFO) {
res->bfi.allocated_clusters++;
if (next_contiguous_offset &&
@@ -1158,7 +1163,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
{
BDRVQcowState *s = bs->opaque;
uint64_t *l1_table, l2_offset, l1_size2;
- int i, refcount, ret;
+ int i, ret;
l1_size2 = l1_size * sizeof(uint64_t);
@@ -1182,22 +1187,6 @@ static int check_refcounts_l1(BlockDriverState *bs,
for(i = 0; i < l1_size; i++) {
l2_offset = l1_table[i];
if (l2_offset) {
- /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
- if (flags & CHECK_OFLAG_COPIED) {
- refcount = get_refcount(bs, (l2_offset & ~QCOW_OFLAG_COPIED)
- >> s->cluster_bits);
- if (refcount < 0) {
- fprintf(stderr, "Can't get refcount for l2_offset %"
- PRIx64 ": %s\n", l2_offset, strerror(-refcount));
- goto fail;
- }
- if ((refcount == 1) != ((l2_offset & QCOW_OFLAG_COPIED) != 0)) {
- fprintf(stderr, "ERROR OFLAG_COPIED: l2_offset=%" PRIx64
- " refcount=%d\n", l2_offset, refcount);
- res->corruptions++;
- }
- }
-
/* Mark L2 table as used */
l2_offset &= L1E_OFFSET_MASK;
inc_refcounts(bs, res, refcount_table, refcount_table_size,
@@ -1229,6 +1218,241 @@ fail:
}
/*
+ * Checks the OFLAG_COPIED flag for all L1 and L2 entries.
+ *
+ * This function does not print an error message nor does it increment
+ * check_errors if get_refcount fails (this is because such an error will have
+ * been already detected and sufficiently signaled by the calling function
+ * (qcow2_check_refcounts) by the time this function is called).
+ */
+static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
+ BdrvCheckMode fix)
+{
+ BDRVQcowState *s = bs->opaque;
+ uint64_t *l2_table = qemu_blockalign(bs, s->cluster_size);
+ int ret;
+ int refcount;
+ int i, j;
+
+ for (i = 0; i < s->l1_size; i++) {
+ uint64_t l1_entry = s->l1_table[i];
+ uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK;
+ bool l2_dirty = false;
+
+ if (!l2_offset) {
+ continue;
+ }
+
+ refcount = get_refcount(bs, l2_offset >> s->cluster_bits);
+ if (refcount < 0) {
+ /* don't print message nor increment check_errors */
+ continue;
+ }
+ if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) {
+ fprintf(stderr, "%s OFLAG_COPIED L2 cluster: l1_index=%d "
+ "l1_entry=%" PRIx64 " refcount=%d\n",
+ fix & BDRV_FIX_ERRORS ? "Repairing" :
+ "ERROR",
+ i, l1_entry, refcount);
+ if (fix & BDRV_FIX_ERRORS) {
+ s->l1_table[i] = refcount == 1
+ ? l1_entry | QCOW_OFLAG_COPIED
+ : l1_entry & ~QCOW_OFLAG_COPIED;
+ ret = qcow2_write_l1_entry(bs, i);
+ if (ret < 0) {
+ res->check_errors++;
+ goto fail;
+ }
+ res->corruptions_fixed++;
+ } else {
+ res->corruptions++;
+ }
+ }
+
+ ret = bdrv_pread(bs->file, l2_offset, l2_table,
+ s->l2_size * sizeof(uint64_t));
+ if (ret < 0) {
+ fprintf(stderr, "ERROR: Could not read L2 table: %s\n",
+ strerror(-ret));
+ res->check_errors++;
+ goto fail;
+ }
+
+ for (j = 0; j < s->l2_size; j++) {
+ uint64_t l2_entry = be64_to_cpu(l2_table[j]);
+ uint64_t data_offset = l2_entry & L2E_OFFSET_MASK;
+ int cluster_type = qcow2_get_cluster_type(l2_entry);
+
+ if ((cluster_type == QCOW2_CLUSTER_NORMAL) ||
+ ((cluster_type == QCOW2_CLUSTER_ZERO) && (data_offset != 0))) {
+ refcount = get_refcount(bs, data_offset >> s->cluster_bits);
+ if (refcount < 0) {
+ /* don't print message nor increment check_errors */
+ continue;
+ }
+ if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
+ fprintf(stderr, "%s OFLAG_COPIED data cluster: "
+ "l2_entry=%" PRIx64 " refcount=%d\n",
+ fix & BDRV_FIX_ERRORS ? "Repairing" :
+ "ERROR",
+ l2_entry, refcount);
+ if (fix & BDRV_FIX_ERRORS) {
+ l2_table[j] = cpu_to_be64(refcount == 1
+ ? l2_entry | QCOW_OFLAG_COPIED
+ : l2_entry & ~QCOW_OFLAG_COPIED);
+ l2_dirty = true;
+ res->corruptions_fixed++;
+ } else {
+ res->corruptions++;
+ }
+ }
+ }
+ }
+
+ if (l2_dirty) {
+ ret = qcow2_pre_write_overlap_check(bs,
+ QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L2, l2_offset,
+ s->cluster_size);
+ if (ret < 0) {
+ fprintf(stderr, "ERROR: Could not write L2 table; metadata "
+ "overlap check failed: %s\n", strerror(-ret));
+ res->check_errors++;
+ goto fail;
+ }
+
+ ret = bdrv_pwrite(bs->file, l2_offset, l2_table, s->cluster_size);
+ if (ret < 0) {
+ fprintf(stderr, "ERROR: Could not write L2 table: %s\n",
+ strerror(-ret));
+ res->check_errors++;
+ goto fail;
+ }
+ }
+ }
+
+ ret = 0;
+
+fail:
+ qemu_vfree(l2_table);
+ return ret;
+}
+
+/*
+ * Writes one sector of the refcount table to the disk
+ */
+#define RT_ENTRIES_PER_SECTOR (512 / sizeof(uint64_t))
+static int write_reftable_entry(BlockDriverState *bs, int rt_index)
+{
+ BDRVQcowState *s = bs->opaque;
+ uint64_t buf[RT_ENTRIES_PER_SECTOR];
+ int rt_start_index;
+ int i, ret;
+
+ rt_start_index = rt_index & ~(RT_ENTRIES_PER_SECTOR - 1);
+ for (i = 0; i < RT_ENTRIES_PER_SECTOR; i++) {
+ buf[i] = cpu_to_be64(s->refcount_table[rt_start_index + i]);
+ }
+
+ ret = qcow2_pre_write_overlap_check(bs,
+ QCOW2_OL_DEFAULT & ~QCOW2_OL_REFCOUNT_TABLE,
+ s->refcount_table_offset + rt_start_index * sizeof(uint64_t),
+ sizeof(buf));
+ if (ret < 0) {
+ return ret;
+ }
+
+ BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_UPDATE);
+ ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset +
+ rt_start_index * sizeof(uint64_t), buf, sizeof(buf));
+ if (ret < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Allocates a new cluster for the given refcount block (represented by its
+ * offset in the image file) and copies the current content there. This function
+ * does _not_ decrement the reference count for the currently occupied cluster.
+ *
+ * This function prints an informative message to stderr on error (and returns
+ * -errno); on success, 0 is returned.
+ */
+static int64_t realloc_refcount_block(BlockDriverState *bs, int reftable_index,
+ uint64_t offset)
+{
+ BDRVQcowState *s = bs->opaque;
+ int64_t new_offset = 0;
+ void *refcount_block = NULL;
+ int ret;
+
+ /* allocate new refcount block */
+ new_offset = qcow2_alloc_clusters(bs, s->cluster_size);
+ if (new_offset < 0) {
+ fprintf(stderr, "Could not allocate new cluster: %s\n",
+ strerror(-new_offset));
+ ret = new_offset;
+ goto fail;
+ }
+
+ /* fetch current refcount block content */
+ ret = qcow2_cache_get(bs, s->refcount_block_cache, offset, &refcount_block);
+ if (ret < 0) {
+ fprintf(stderr, "Could not fetch refcount block: %s\n", strerror(-ret));
+ goto fail;
+ }
+
+ /* new block has not yet been entered into refcount table, therefore it is
+ * no refcount block yet (regarding this check) */
+ ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, new_offset,
+ s->cluster_size);
+ if (ret < 0) {
+ fprintf(stderr, "Could not write refcount block; metadata overlap "
+ "check failed: %s\n", strerror(-ret));
+ /* the image will be marked corrupt, so don't even attempt on freeing
+ * the cluster */
+ new_offset = 0;
+ goto fail;
+ }
+
+ /* write to new block */
+ ret = bdrv_write(bs->file, new_offset / BDRV_SECTOR_SIZE, refcount_block,
+ s->cluster_sectors);
+ if (ret < 0) {
+ fprintf(stderr, "Could not write refcount block: %s\n", strerror(-ret));
+ goto fail;
+ }
+
+ /* update refcount table */
+ assert(!(new_offset & (s->cluster_size - 1)));
+ s->refcount_table[reftable_index] = new_offset;
+ ret = write_reftable_entry(bs, reftable_index);
+ if (ret < 0) {
+ fprintf(stderr, "Could not update refcount table: %s\n",
+ strerror(-ret));
+ goto fail;
+ }
+
+fail:
+ if (new_offset && (ret < 0)) {
+ qcow2_free_clusters(bs, new_offset, s->cluster_size,
+ QCOW2_DISCARD_ALWAYS);
+ }
+ if (refcount_block) {
+ if (ret < 0) {
+ qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);
+ } else {
+ ret = qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);
+ }
+ }
+ if (ret < 0) {
+ return ret;
+ }
+ return new_offset;
+}
+
+/*
* Checks an image for refcount consistency.
*
* Returns 0 if no errors are found, the number of errors in case the image is
@@ -1304,10 +1528,39 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
inc_refcounts(bs, res, refcount_table, nb_clusters,
offset, s->cluster_size);
if (refcount_table[cluster] != 1) {
- fprintf(stderr, "ERROR refcount block %" PRId64
+ fprintf(stderr, "%s refcount block %" PRId64
" refcount=%d\n",
+ fix & BDRV_FIX_ERRORS ? "Repairing" :
+ "ERROR",
i, refcount_table[cluster]);
- res->corruptions++;
+
+ if (fix & BDRV_FIX_ERRORS) {
+ int64_t new_offset;
+
+ new_offset = realloc_refcount_block(bs, i, offset);
+ if (new_offset < 0) {
+ res->corruptions++;
+ continue;
+ }
+
+ /* update refcounts */
+ if ((new_offset >> s->cluster_bits) >= nb_clusters) {
+ /* increase refcount_table size if necessary */
+ int old_nb_clusters = nb_clusters;
+ nb_clusters = (new_offset >> s->cluster_bits) + 1;
+ refcount_table = g_realloc(refcount_table,
+ nb_clusters * sizeof(uint16_t));
+ memset(&refcount_table[old_nb_clusters], 0, (nb_clusters
+ - old_nb_clusters) * sizeof(uint16_t));
+ }
+ refcount_table[cluster]--;
+ inc_refcounts(bs, res, refcount_table, nb_clusters,
+ new_offset, s->cluster_size);
+
+ res->corruptions_fixed++;
+ } else {
+ res->corruptions++;
+ }
}
}
}
@@ -1363,6 +1616,12 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
}
}
+ /* check OFLAG_COPIED */
+ ret = check_oflag_copied(bs, res, fix);
+ if (ret < 0) {
+ goto fail;
+ }
+
res->image_end_offset = (highest_cluster + 1) * s->cluster_size;
ret = 0;
@@ -1372,3 +1631,173 @@ fail:
return ret;
}
+#define overlaps_with(ofs, sz) \
+ ranges_overlap(offset, size, ofs, sz)
+
+/*
+ * Checks if the given offset into the image file is actually free to use by
+ * looking for overlaps with important metadata sections (L1/L2 tables etc.),
+ * i.e. a sanity check without relying on the refcount tables.
+ *
+ * The chk parameter specifies exactly what checks to perform (being a bitmask
+ * of QCow2MetadataOverlap values).
+ *
+ * Returns:
+ * - 0 if writing to this offset will not affect the mentioned metadata
+ * - a positive QCow2MetadataOverlap value indicating one overlapping section
+ * - a negative value (-errno) indicating an error while performing a check,
+ * e.g. when bdrv_read failed on QCOW2_OL_INACTIVE_L2
+ */
+int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,
+ int64_t size)
+{
+ BDRVQcowState *s = bs->opaque;
+ int i, j;
+
+ if (!size) {
+ return 0;
+ }
+
+ if (chk & QCOW2_OL_MAIN_HEADER) {
+ if (offset < s->cluster_size) {
+ return QCOW2_OL_MAIN_HEADER;
+ }
+ }
+
+ /* align range to test to cluster boundaries */
+ size = align_offset(offset_into_cluster(s, offset) + size, s->cluster_size);
+ offset = start_of_cluster(s, offset);
+
+ if ((chk & QCOW2_OL_ACTIVE_L1) && s->l1_size) {
+ if (overlaps_with(s->l1_table_offset, s->l1_size * sizeof(uint64_t))) {
+ return QCOW2_OL_ACTIVE_L1;
+ }
+ }
+
+ if ((chk & QCOW2_OL_REFCOUNT_TABLE) && s->refcount_table_size) {
+ if (overlaps_with(s->refcount_table_offset,
+ s->refcount_table_size * sizeof(uint64_t))) {
+ return QCOW2_OL_REFCOUNT_TABLE;
+ }
+ }
+
+ if ((chk & QCOW2_OL_SNAPSHOT_TABLE) && s->snapshots_size) {
+ if (overlaps_with(s->snapshots_offset, s->snapshots_size)) {
+ return QCOW2_OL_SNAPSHOT_TABLE;
+ }
+ }
+
+ if ((chk & QCOW2_OL_INACTIVE_L1) && s->snapshots) {
+ for (i = 0; i < s->nb_snapshots; i++) {
+ if (s->snapshots[i].l1_size &&
+ overlaps_with(s->snapshots[i].l1_table_offset,
+ s->snapshots[i].l1_size * sizeof(uint64_t))) {
+ return QCOW2_OL_INACTIVE_L1;
+ }
+ }
+ }
+
+ if ((chk & QCOW2_OL_ACTIVE_L2) && s->l1_table) {
+ for (i = 0; i < s->l1_size; i++) {
+ if ((s->l1_table[i] & L1E_OFFSET_MASK) &&
+ overlaps_with(s->l1_table[i] & L1E_OFFSET_MASK,
+ s->cluster_size)) {
+ return QCOW2_OL_ACTIVE_L2;
+ }
+ }
+ }
+
+ if ((chk & QCOW2_OL_REFCOUNT_BLOCK) && s->refcount_table) {
+ for (i = 0; i < s->refcount_table_size; i++) {
+ if ((s->refcount_table[i] & REFT_OFFSET_MASK) &&
+ overlaps_with(s->refcount_table[i] & REFT_OFFSET_MASK,
+ s->cluster_size)) {
+ return QCOW2_OL_REFCOUNT_BLOCK;
+ }
+ }
+ }
+
+ if ((chk & QCOW2_OL_INACTIVE_L2) && s->snapshots) {
+ for (i = 0; i < s->nb_snapshots; i++) {
+ uint64_t l1_ofs = s->snapshots[i].l1_table_offset;
+ uint32_t l1_sz = s->snapshots[i].l1_size;
+ uint64_t *l1 = g_malloc(l1_sz * sizeof(uint64_t));
+ int ret;
+
+ ret = bdrv_read(bs->file, l1_ofs / BDRV_SECTOR_SIZE, (uint8_t *)l1,
+ l1_sz * sizeof(uint64_t) / BDRV_SECTOR_SIZE);
+
+ if (ret < 0) {
+ g_free(l1);
+ return ret;
+ }
+
+ for (j = 0; j < l1_sz; j++) {
+ if ((l1[j] & L1E_OFFSET_MASK) &&
+ overlaps_with(l1[j] & L1E_OFFSET_MASK, s->cluster_size)) {
+ g_free(l1);
+ return QCOW2_OL_INACTIVE_L2;
+ }
+ }
+
+ g_free(l1);
+ }
+ }
+
+ return 0;
+}
+
+static const char *metadata_ol_names[] = {
+ [QCOW2_OL_MAIN_HEADER_BITNR] = "qcow2_header",
+ [QCOW2_OL_ACTIVE_L1_BITNR] = "active L1 table",
+ [QCOW2_OL_ACTIVE_L2_BITNR] = "active L2 table",
+ [QCOW2_OL_REFCOUNT_TABLE_BITNR] = "refcount table",
+ [QCOW2_OL_REFCOUNT_BLOCK_BITNR] = "refcount block",
+ [QCOW2_OL_SNAPSHOT_TABLE_BITNR] = "snapshot table",
+ [QCOW2_OL_INACTIVE_L1_BITNR] = "inactive L1 table",
+ [QCOW2_OL_INACTIVE_L2_BITNR] = "inactive L2 table",
+};
+
+/*
+ * First performs a check for metadata overlaps (through
+ * qcow2_check_metadata_overlap); if that fails with a negative value (error
+ * while performing a check), that value is returned. If an impending overlap
+ * is detected, the BDS will be made unusable, the qcow2 file marked corrupt
+ * and -EIO returned.
+ *
+ * Returns 0 if there were neither overlaps nor errors while checking for
+ * overlaps; or a negative value (-errno) on error.
+ */
+int qcow2_pre_write_overlap_check(BlockDriverState *bs, int chk, int64_t offset,
+ int64_t size)
+{
+ int ret = qcow2_check_metadata_overlap(bs, chk, offset, size);
+
+ if (ret < 0) {
+ return ret;
+ } else if (ret > 0) {
+ int metadata_ol_bitnr = ffs(ret) - 1;
+ char *message;
+ QObject *data;
+
+ assert(metadata_ol_bitnr < QCOW2_OL_MAX_BITNR);
+
+ fprintf(stderr, "qcow2: Preventing invalid write on metadata (overlaps "
+ "with %s); image marked as corrupt.\n",
+ metadata_ol_names[metadata_ol_bitnr]);
+ message = g_strdup_printf("Prevented %s overwrite",
+ metadata_ol_names[metadata_ol_bitnr]);
+ data = qobject_from_jsonf("{ 'device': %s, 'msg': %s, 'offset': %"
+ PRId64 ", 'size': %" PRId64 " }", bs->device_name, message,
+ offset, size);
+ monitor_protocol_event(QEVENT_BLOCK_IMAGE_CORRUPTED, data);
+ g_free(message);
+ qobject_decref(data);
+
+ qcow2_mark_corrupt(bs);
+ bs->drv = NULL; /* make BDS unusable */
+ return -EIO;
+ }
+
+ return 0;
+}
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 0caac9055f..e7e601301a 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -189,6 +189,15 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
return ret;
}
+ /* The snapshot list position has not yet been updated, so these clusters
+ * must indeed be completely free */
+ ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, offset,
+ s->snapshots_size);
+ if (ret < 0) {
+ return ret;
+ }
+
+
/* Write all snapshots to the new list */
for(i = 0; i < s->nb_snapshots; i++) {
sn = s->snapshots + i;
@@ -363,6 +372,12 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
l1_table[i] = cpu_to_be64(s->l1_table[i]);
}
+ ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+ sn->l1_table_offset, s->l1_size * sizeof(uint64_t));
+ if (ret < 0) {
+ goto fail;
+ }
+
ret = bdrv_pwrite(bs->file, sn->l1_table_offset, l1_table,
s->l1_size * sizeof(uint64_t));
if (ret < 0) {
@@ -475,6 +490,13 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
goto fail;
}
+ ret = qcow2_pre_write_overlap_check(bs,
+ QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L1,
+ s->l1_table_offset, cur_l1_bytes);
+ if (ret < 0) {
+ goto fail;
+ }
+
ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset, sn_l1_table,
cur_l1_bytes);
if (ret < 0) {
diff --git a/block/qcow2.c b/block/qcow2.c
index 78097e5173..4bc679a155 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -272,6 +272,37 @@ static int qcow2_mark_clean(BlockDriverState *bs)
return 0;
}
+/*
+ * Marks the image as corrupt.
+ */
+int qcow2_mark_corrupt(BlockDriverState *bs)
+{
+ BDRVQcowState *s = bs->opaque;
+
+ s->incompatible_features |= QCOW2_INCOMPAT_CORRUPT;
+ return qcow2_update_header(bs);
+}
+
+/*
+ * Marks the image as consistent, i.e., unsets the corrupt bit, and flushes
+ * before if necessary.
+ */
+int qcow2_mark_consistent(BlockDriverState *bs)
+{
+ BDRVQcowState *s = bs->opaque;
+
+ if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) {
+ int ret = bdrv_flush(bs);
+ if (ret < 0) {
+ return ret;
+ }
+
+ s->incompatible_features &= ~QCOW2_INCOMPAT_CORRUPT;
+ return qcow2_update_header(bs);
+ }
+ return 0;
+}
+
static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix)
{
@@ -281,7 +312,11 @@ static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
}
if (fix && result->check_errors == 0 && result->corruptions == 0) {
- return qcow2_mark_clean(bs);
+ ret = qcow2_mark_clean(bs);
+ if (ret < 0) {
+ return ret;
+ }
+ return qcow2_mark_consistent(bs);
}
return ret;
}
@@ -402,6 +437,17 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
goto fail;
}
+ if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) {
+ /* Corrupt images may not be written to unless they are being repaired
+ */
+ if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) {
+ error_report("qcow2: Image is corrupt; cannot be opened "
+ "read/write.");
+ ret = -EACCES;
+ goto fail;
+ }
+ }
+
/* Check support for various header values */
if (header.refcount_order != 4) {
report_unsupported(bs, "%d bit reference counts",
@@ -582,6 +628,8 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
qcow2_free_snapshots(bs);
qcow2_refcount_close(bs);
g_free(s->l1_table);
+ /* else pre-write overlap checks in cache_destroy may crash */
+ s->l1_table = NULL;
if (s->l2_table_cache) {
qcow2_cache_destroy(bs, s->l2_table_cache);
}
@@ -881,6 +929,13 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
cur_nr_sectors * 512);
}
+ ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+ cluster_offset + index_in_cluster * BDRV_SECTOR_SIZE,
+ cur_nr_sectors * BDRV_SECTOR_SIZE);
+ if (ret < 0) {
+ goto fail;
+ }
+
qemu_co_mutex_unlock(&s->lock);
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
trace_qcow2_writev_data(qemu_coroutine_self(),
@@ -947,6 +1002,8 @@ static void qcow2_close(BlockDriverState *bs)
{
BDRVQcowState *s = bs->opaque;
g_free(s->l1_table);
+ /* else pre-write overlap checks in cache_destroy may crash */
+ s->l1_table = NULL;
qcow2_cache_flush(bs, s->l2_table_cache);
qcow2_cache_flush(bs, s->refcount_block_cache);
@@ -1130,6 +1187,11 @@ int qcow2_update_header(BlockDriverState *bs)
.name = "dirty bit",
},
{
+ .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
+ .bit = QCOW2_INCOMPAT_CORRUPT_BITNR,
+ .name = "corrupt bit",
+ },
+ {
.type = QCOW2_FEAT_TYPE_COMPATIBLE,
.bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
.name = "lazy refcounts",
@@ -1429,7 +1491,9 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
return -EINVAL;
}
} else if (!strcmp(options->name, BLOCK_OPT_COMPAT_LEVEL)) {
- if (!options->value.s || !strcmp(options->value.s, "0.10")) {
+ if (!options->value.s) {
+ /* keep the default */
+ } else if (!strcmp(options->value.s, "0.10")) {
version = 2;
} else if (!strcmp(options->value.s, "1.1")) {
version = 3;
@@ -1619,6 +1683,14 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
/* could not compress: write normal cluster */
+
+ ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+ sector_num * BDRV_SECTOR_SIZE,
+ s->cluster_sectors * BDRV_SECTOR_SIZE);
+ if (ret < 0) {
+ goto fail;
+ }
+
ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);
if (ret < 0) {
goto fail;
@@ -1631,6 +1703,13 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
goto fail;
}
cluster_offset &= s->cluster_offset_mask;
+
+ ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+ cluster_offset, out_len);
+ if (ret < 0) {
+ goto fail;
+ }
+
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
if (ret < 0) {
diff --git a/block/qcow2.h b/block/qcow2.h
index dba9771419..1000239e4c 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -40,11 +40,11 @@
#define QCOW_MAX_CRYPT_CLUSTERS 32
/* indicate that the refcount of the referenced cluster is exactly one. */
-#define QCOW_OFLAG_COPIED (1LL << 63)
+#define QCOW_OFLAG_COPIED (1ULL << 63)
/* indicate that the cluster is compressed (they never have the copied flag) */
-#define QCOW_OFLAG_COMPRESSED (1LL << 62)
+#define QCOW_OFLAG_COMPRESSED (1ULL << 62)
/* The cluster reads as all zeros */
-#define QCOW_OFLAG_ZERO (1LL << 0)
+#define QCOW_OFLAG_ZERO (1ULL << 0)
#define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */
@@ -119,9 +119,12 @@ enum {
/* Incompatible feature bits */
enum {
QCOW2_INCOMPAT_DIRTY_BITNR = 0,
+ QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
+ QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
- QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY,
+ QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
+ | QCOW2_INCOMPAT_CORRUPT,
};
/* Compatible feature bits */
@@ -286,6 +289,40 @@ enum {
QCOW2_CLUSTER_ZERO
};
+typedef enum QCow2MetadataOverlap {
+ QCOW2_OL_MAIN_HEADER_BITNR = 0,
+ QCOW2_OL_ACTIVE_L1_BITNR = 1,
+ QCOW2_OL_ACTIVE_L2_BITNR = 2,
+ QCOW2_OL_REFCOUNT_TABLE_BITNR = 3,
+ QCOW2_OL_REFCOUNT_BLOCK_BITNR = 4,
+ QCOW2_OL_SNAPSHOT_TABLE_BITNR = 5,
+ QCOW2_OL_INACTIVE_L1_BITNR = 6,
+ QCOW2_OL_INACTIVE_L2_BITNR = 7,
+
+ QCOW2_OL_MAX_BITNR = 8,
+
+ QCOW2_OL_NONE = 0,
+ QCOW2_OL_MAIN_HEADER = (1 << QCOW2_OL_MAIN_HEADER_BITNR),
+ QCOW2_OL_ACTIVE_L1 = (1 << QCOW2_OL_ACTIVE_L1_BITNR),
+ QCOW2_OL_ACTIVE_L2 = (1 << QCOW2_OL_ACTIVE_L2_BITNR),
+ QCOW2_OL_REFCOUNT_TABLE = (1 << QCOW2_OL_REFCOUNT_TABLE_BITNR),
+ QCOW2_OL_REFCOUNT_BLOCK = (1 << QCOW2_OL_REFCOUNT_BLOCK_BITNR),
+ QCOW2_OL_SNAPSHOT_TABLE = (1 << QCOW2_OL_SNAPSHOT_TABLE_BITNR),
+ QCOW2_OL_INACTIVE_L1 = (1 << QCOW2_OL_INACTIVE_L1_BITNR),
+ /* NOTE: Checking overlaps with inactive L2 tables will result in bdrv
+ * reads. */
+ QCOW2_OL_INACTIVE_L2 = (1 << QCOW2_OL_INACTIVE_L2_BITNR),
+} QCow2MetadataOverlap;
+
+/* Perform all overlap checks which don't require disk access */
+#define QCOW2_OL_CACHED \
+ (QCOW2_OL_MAIN_HEADER | QCOW2_OL_ACTIVE_L1 | QCOW2_OL_ACTIVE_L2 | \
+ QCOW2_OL_REFCOUNT_TABLE | QCOW2_OL_REFCOUNT_BLOCK | \
+ QCOW2_OL_SNAPSHOT_TABLE | QCOW2_OL_INACTIVE_L1)
+
+/* The default checks to perform */
+#define QCOW2_OL_DEFAULT QCOW2_OL_CACHED
+
#define L1E_OFFSET_MASK 0x00ffffffffffff00ULL
#define L2E_OFFSET_MASK 0x00ffffffffffff00ULL
#define L2E_COMPRESSED_OFFSET_SIZE_MASK 0x3fffffffffffffffULL
@@ -361,6 +398,8 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
int64_t sector_num, int nb_sectors);
int qcow2_mark_dirty(BlockDriverState *bs);
+int qcow2_mark_corrupt(BlockDriverState *bs);
+int qcow2_mark_consistent(BlockDriverState *bs);
int qcow2_update_header(BlockDriverState *bs);
/* qcow2-refcount.c functions */
@@ -385,9 +424,15 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
void qcow2_process_discards(BlockDriverState *bs, int ret);
+int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,
+ int64_t size);
+int qcow2_pre_write_overlap_check(BlockDriverState *bs, int chk, int64_t offset,
+ int64_t size);
+
/* qcow2-cluster.c functions */
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
bool exact_size);
+int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
void qcow2_l2_cache_reset(BlockDriverState *bs);
int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
diff --git a/block/raw.c b/block/raw_bsd.c
index 47518253fe..ab2b0fd7d2 100644
--- a/block/raw.c
+++ b/block/raw_bsd.c
@@ -1,13 +1,17 @@
-/*
- * Block driver for RAW format
+/* BlockDriver implementation for "raw"
*
- * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (C) 2010, 2013, Red Hat, Inc.
+ * Copyright (C) 2010, Blue Swirl <blauwirbel@gmail.com>
+ * Copyright (C) 2009, Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * Author:
+ * Laszlo Ersek <lersek@redhat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
@@ -15,27 +19,27 @@
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
*/
-#include "qemu-common.h"
#include "block/block_int.h"
-#include "qemu/module.h"
+#include "qemu/option.h"
-static int raw_open(BlockDriverState *bs, QDict *options, int flags)
-{
- bs->sg = bs->file->sg;
- return 0;
-}
+static QEMUOptionParameter raw_create_options[] = {
+ {
+ .name = BLOCK_OPT_SIZE,
+ .type = OPT_SIZE,
+ .help = "Virtual disk size"
+ },
+ { 0 }
+};
-/* We have nothing to do for raw reopen, stubs just return
- * success */
-static int raw_reopen_prepare(BDRVReopenState *state,
- BlockReopenQueue *queue, Error **errp)
+static int raw_reopen_prepare(BDRVReopenState *reopen_state,
+ BlockReopenQueue *queue, Error **errp)
{
return 0;
}
@@ -54,43 +58,38 @@ static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
return bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov);
}
-static void raw_close(BlockDriverState *bs)
-{
-}
-
static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
- int64_t sector_num,
- int nb_sectors, int *pnum)
+ int64_t sector_num, int nb_sectors,
+ int *pnum)
{
return bdrv_co_is_allocated(bs->file, sector_num, nb_sectors, pnum);
}
static int coroutine_fn raw_co_write_zeroes(BlockDriverState *bs,
- int64_t sector_num,
- int nb_sectors)
+ int64_t sector_num, int nb_sectors)
{
return bdrv_co_write_zeroes(bs->file, sector_num, nb_sectors);
}
-static int64_t raw_getlength(BlockDriverState *bs)
+static int coroutine_fn raw_co_discard(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors)
{
- return bdrv_getlength(bs->file);
+ return bdrv_co_discard(bs->file, sector_num, nb_sectors);
}
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
+static int64_t raw_getlength(BlockDriverState *bs)
{
- return bdrv_truncate(bs->file, offset);
+ return bdrv_getlength(bs->file);
}
-static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
+static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
{
- return 1; /* everything can be opened as raw image */
+ return bdrv_get_info(bs->file, bdi);
}
-static int coroutine_fn raw_co_discard(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors)
+static int raw_truncate(BlockDriverState *bs, int64_t offset)
{
- return bdrv_co_discard(bs->file, sector_num, nb_sectors);
+ return bdrv_truncate(bs->file, offset);
}
static int raw_is_inserted(BlockDriverState *bs)
@@ -115,14 +114,20 @@ static void raw_lock_medium(BlockDriverState *bs, bool locked)
static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
{
- return bdrv_ioctl(bs->file, req, buf);
+ return bdrv_ioctl(bs->file, req, buf);
}
static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
- unsigned long int req, void *buf,
- BlockDriverCompletionFunc *cb, void *opaque)
+ unsigned long int req, void *buf,
+ BlockDriverCompletionFunc *cb,
+ void *opaque)
+{
+ return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque);
+}
+
+static int raw_has_zero_init(BlockDriverState *bs)
{
- return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque);
+ return bdrv_has_zero_init(bs->file);
}
static int raw_create(const char *filename, QEMUOptionParameter *options)
@@ -130,58 +135,47 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
return bdrv_create_file(filename, options);
}
-static QEMUOptionParameter raw_create_options[] = {
- {
- .name = BLOCK_OPT_SIZE,
- .type = OPT_SIZE,
- .help = "Virtual disk size"
- },
- { NULL }
-};
+static int raw_open(BlockDriverState *bs, QDict *options, int flags)
+{
+ bs->sg = bs->file->sg;
+ return 0;
+}
-static int raw_has_zero_init(BlockDriverState *bs)
+static void raw_close(BlockDriverState *bs)
{
- return bdrv_has_zero_init(bs->file);
}
-static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
+static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
{
- return bdrv_get_info(bs->file, bdi);
+ /* smallest possible positive score so that raw is used if and only if no
+ * other block driver works
+ */
+ return 1;
}
static BlockDriver bdrv_raw = {
- .format_name = "raw",
-
- /* It's really 0, but we need to make g_malloc() happy */
- .instance_size = 1,
-
- .bdrv_open = raw_open,
- .bdrv_close = raw_close,
-
- .bdrv_reopen_prepare = raw_reopen_prepare,
-
- .bdrv_co_readv = raw_co_readv,
- .bdrv_co_writev = raw_co_writev,
- .bdrv_co_is_allocated = raw_co_is_allocated,
- .bdrv_co_write_zeroes = raw_co_write_zeroes,
- .bdrv_co_discard = raw_co_discard,
-
- .bdrv_probe = raw_probe,
- .bdrv_getlength = raw_getlength,
- .bdrv_get_info = raw_get_info,
- .bdrv_truncate = raw_truncate,
-
- .bdrv_is_inserted = raw_is_inserted,
- .bdrv_media_changed = raw_media_changed,
- .bdrv_eject = raw_eject,
- .bdrv_lock_medium = raw_lock_medium,
-
- .bdrv_ioctl = raw_ioctl,
- .bdrv_aio_ioctl = raw_aio_ioctl,
-
- .bdrv_create = raw_create,
- .create_options = raw_create_options,
- .bdrv_has_zero_init = raw_has_zero_init,
+ .format_name = "raw",
+ .bdrv_probe = &raw_probe,
+ .bdrv_reopen_prepare = &raw_reopen_prepare,
+ .bdrv_open = &raw_open,
+ .bdrv_close = &raw_close,
+ .bdrv_create = &raw_create,
+ .bdrv_co_readv = &raw_co_readv,
+ .bdrv_co_writev = &raw_co_writev,
+ .bdrv_co_write_zeroes = &raw_co_write_zeroes,
+ .bdrv_co_discard = &raw_co_discard,
+ .bdrv_co_is_allocated = &raw_co_is_allocated,
+ .bdrv_truncate = &raw_truncate,
+ .bdrv_getlength = &raw_getlength,
+ .bdrv_get_info = &raw_get_info,
+ .bdrv_is_inserted = &raw_is_inserted,
+ .bdrv_media_changed = &raw_media_changed,
+ .bdrv_eject = &raw_eject,
+ .bdrv_lock_medium = &raw_lock_medium,
+ .bdrv_ioctl = &raw_ioctl,
+ .bdrv_aio_ioctl = &raw_aio_ioctl,
+ .create_options = &raw_create_options[0],
+ .bdrv_has_zero_init = &raw_has_zero_init
};
static void bdrv_raw_init(void)
diff --git a/blockdev.c b/blockdev.c
index 121520ecbc..e70e16e4de 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -46,7 +46,6 @@
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
extern QemuOptsList qemu_common_drive_opts;
-extern QemuOptsList qemu_old_drive_opts;
static const char *const if_name[IF_COUNT] = {
[IF_NONE] = "none",
@@ -755,26 +754,6 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
{
const char *value;
- /*
- * Check that only old options are used by copying into a QemuOpts with
- * stricter checks. Going through a QDict seems to be the easiest way to
- * achieve this...
- */
- QemuOpts* check_opts;
- QDict *qdict;
- Error *local_err = NULL;
-
- qdict = qemu_opts_to_qdict(all_opts, NULL);
- check_opts = qemu_opts_from_qdict(&qemu_old_drive_opts, qdict, &local_err);
- QDECREF(qdict);
-
- if (error_is_set(&local_err)) {
- qerror_report_err(local_err);
- error_free(local_err);
- return NULL;
- }
- qemu_opts_del(check_opts);
-
/* Change legacy command line options into QMP ones */
qemu_opt_rename(all_opts, "iops", "throttling.iops-total");
qemu_opt_rename(all_opts, "iops_rd", "throttling.iops-read");
@@ -2001,128 +1980,6 @@ QemuOptsList qemu_common_drive_opts = {
},
};
-QemuOptsList qemu_old_drive_opts = {
- .name = "drive",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_old_drive_opts.head),
- .desc = {
- {
- .name = "bus",
- .type = QEMU_OPT_NUMBER,
- .help = "bus number",
- },{
- .name = "unit",
- .type = QEMU_OPT_NUMBER,
- .help = "unit number (i.e. lun for scsi)",
- },{
- .name = "if",
- .type = QEMU_OPT_STRING,
- .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
- },{
- .name = "index",
- .type = QEMU_OPT_NUMBER,
- .help = "index number",
- },{
- .name = "cyls",
- .type = QEMU_OPT_NUMBER,
- .help = "number of cylinders (ide disk geometry)",
- },{
- .name = "heads",
- .type = QEMU_OPT_NUMBER,
- .help = "number of heads (ide disk geometry)",
- },{
- .name = "secs",
- .type = QEMU_OPT_NUMBER,
- .help = "number of sectors (ide disk geometry)",
- },{
- .name = "trans",
- .type = QEMU_OPT_STRING,
- .help = "chs translation (auto, lba. none)",
- },{
- .name = "media",
- .type = QEMU_OPT_STRING,
- .help = "media type (disk, cdrom)",
- },{
- .name = "snapshot",
- .type = QEMU_OPT_BOOL,
- .help = "enable/disable snapshot mode",
- },{
- .name = "file",
- .type = QEMU_OPT_STRING,
- .help = "disk image",
- },{
- .name = "discard",
- .type = QEMU_OPT_STRING,
- .help = "discard operation (ignore/off, unmap/on)",
- },{
- .name = "cache",
- .type = QEMU_OPT_STRING,
- .help = "host cache usage (none, writeback, writethrough, "
- "directsync, unsafe)",
- },{
- .name = "aio",
- .type = QEMU_OPT_STRING,
- .help = "host AIO implementation (threads, native)",
- },{
- .name = "format",
- .type = QEMU_OPT_STRING,
- .help = "disk format (raw, qcow2, ...)",
- },{
- .name = "serial",
- .type = QEMU_OPT_STRING,
- .help = "disk serial number",
- },{
- .name = "rerror",
- .type = QEMU_OPT_STRING,
- .help = "read error action",
- },{
- .name = "werror",
- .type = QEMU_OPT_STRING,
- .help = "write error action",
- },{
- .name = "addr",
- .type = QEMU_OPT_STRING,
- .help = "pci address (virtio only)",
- },{
- .name = "readonly",
- .type = QEMU_OPT_BOOL,
- .help = "open drive file as read-only",
- },{
- .name = "iops",
- .type = QEMU_OPT_NUMBER,
- .help = "limit total I/O operations per second",
- },{
- .name = "iops_rd",
- .type = QEMU_OPT_NUMBER,
- .help = "limit read operations per second",
- },{
- .name = "iops_wr",
- .type = QEMU_OPT_NUMBER,
- .help = "limit write operations per second",
- },{
- .name = "bps",
- .type = QEMU_OPT_NUMBER,
- .help = "limit total bytes per second",
- },{
- .name = "bps_rd",
- .type = QEMU_OPT_NUMBER,
- .help = "limit read bytes per second",
- },{
- .name = "bps_wr",
- .type = QEMU_OPT_NUMBER,
- .help = "limit write bytes per second",
- },{
- .name = "copy-on-read",
- .type = QEMU_OPT_BOOL,
- .help = "copy read data from backing file into image file",
- },{
- .name = "boot",
- .type = QEMU_OPT_BOOL,
- .help = "(deprecated, ignored)",
- },
- { /* end of list */ }
- },
-};
-
QemuOptsList qemu_drive_opts = {
.name = "drive",
.head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
diff --git a/configure b/configure
index af6b048c6e..e989609e95 100755
--- a/configure
+++ b/configure
@@ -572,7 +572,7 @@ fi
: ${make=${MAKE-make}}
: ${install=${INSTALL-install}}
-: ${python=${PYTHON-python}}
+: ${python=${PYTHON-python -B}}
: ${smbd=${SMBD-/usr/sbin/smbd}}
# Default objcc to clang if available, otherwise use CC
@@ -1213,6 +1213,7 @@ gcc_flags="-Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers $gcc_
gcc_flags="-Wmissing-include-dirs -Wempty-body -Wnested-externs $gcc_flags"
gcc_flags="-Wendif-labels $gcc_flags"
gcc_flags="-Wno-initializer-overrides $gcc_flags"
+gcc_flags="-Wno-string-plus-int $gcc_flags"
# Note that we do not add -Werror to gcc_flags here, because that would
# enable it for all configure tests. If a configure test failed due
# to -Werror this would just silently disable some features,
@@ -1357,7 +1358,7 @@ fi
# Note that if the Python conditional here evaluates True we will exit
# with status 1 which is a shell 'false' value.
-if ! "$python" -c 'import sys; sys.exit(sys.version_info < (2,4) or sys.version_info >= (3,))'; then
+if ! $python -c 'import sys; sys.exit(sys.version_info < (2,4) or sys.version_info >= (3,))'; then
error_exit "Cannot use '$python', Python 2.4 or later is required." \
"Note that Python 3 or later is not yet supported." \
"Use --python=/path/to/python to specify a supported Python."
@@ -1478,7 +1479,7 @@ libs_softmmu="$libs_softmmu -lz"
# libseccomp check
if test "$seccomp" != "no" ; then
- if $pkg_config --atleast-version=2.1.0 libseccomp --modversion >/dev/null 2>&1; then
+ if $pkg_config --atleast-version=2.1.0 libseccomp; then
libs_softmmu="$libs_softmmu `$pkg_config --libs libseccomp`"
QEMU_CFLAGS="$QEMU_CFLAGS `$pkg_config --cflags libseccomp`"
seccomp="yes"
@@ -1712,10 +1713,10 @@ if test "$gtk" != "no"; then
fi
gtk="no"
else
- gtk_cflags=`$pkg_config --cflags $gtkpackage 2>/dev/null`
- gtk_libs=`$pkg_config --libs $gtkpackage 2>/dev/null`
- vte_cflags=`$pkg_config --cflags $vtepackage 2>/dev/null`
- vte_libs=`$pkg_config --libs $vtepackage 2>/dev/null`
+ gtk_cflags=`$pkg_config --cflags $gtkpackage`
+ gtk_libs=`$pkg_config --libs $gtkpackage`
+ vte_cflags=`$pkg_config --cflags $vtepackage`
+ vte_libs=`$pkg_config --libs $vtepackage`
libs_softmmu="$gtk_libs $vte_libs $libs_softmmu"
gtk="yes"
fi
@@ -1730,7 +1731,7 @@ if test "`basename $sdl_config`" != sdl-config && ! has ${sdl_config}; then
sdl_config=sdl-config
fi
-if $pkg_config sdl --modversion >/dev/null 2>&1; then
+if $pkg_config sdl --exists; then
sdlconfig="$pkg_config sdl"
_sdlversion=`$sdlconfig --modversion 2>/dev/null | sed 's/[^0-9]//g'`
elif has ${sdl_config}; then
@@ -1916,9 +1917,9 @@ int main(void) {
return png_ptr != 0;
}
EOF
- if $pkg_config libpng --modversion >/dev/null 2>&1; then
- vnc_png_cflags=`$pkg_config libpng --cflags 2> /dev/null`
- vnc_png_libs=`$pkg_config libpng --libs 2> /dev/null`
+ if $pkg_config libpng --exists; then
+ vnc_png_cflags=`$pkg_config libpng --cflags`
+ vnc_png_libs=`$pkg_config libpng --libs`
else
vnc_png_cflags=""
vnc_png_libs="-lpng"
@@ -2195,7 +2196,7 @@ fi
##########################################
# curl probe
if test "$curl" != "no" ; then
- if $pkg_config libcurl --modversion >/dev/null 2>&1; then
+ if $pkg_config libcurl --exists; then
curlconfig="$pkg_config libcurl"
else
curlconfig=curl-config
@@ -2247,10 +2248,9 @@ if test "$mingw32" = yes; then
else
glib_req_ver=2.12
fi
-if $pkg_config --atleast-version=$glib_req_ver gthread-2.0 > /dev/null 2>&1
-then
- glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null`
- glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null`
+if $pkg_config --atleast-version=$glib_req_ver gthread-2.0; then
+ glib_cflags=`$pkg_config --cflags gthread-2.0`
+ glib_libs=`$pkg_config --libs gthread-2.0`
LIBS="$glib_libs $LIBS"
libs_qga="$glib_libs $libs_qga"
else
@@ -2279,8 +2279,8 @@ if test "$pixman" = "none"; then
pixman_cflags=
pixman_libs=
elif test "$pixman" = "system"; then
- pixman_cflags=`$pkg_config --cflags pixman-1 2>/dev/null`
- pixman_libs=`$pkg_config --libs pixman-1 2>/dev/null`
+ pixman_cflags=`$pkg_config --cflags pixman-1`
+ pixman_libs=`$pkg_config --libs pixman-1`
else
if test ! -d ${source_path}/pixman/pixman; then
error_exit "pixman not present. Your options:" \
@@ -2379,8 +2379,7 @@ fi
# libssh2 probe
min_libssh2_version=1.2.8
if test "$libssh2" != "no" ; then
- if $pkg_config --atleast-version=$min_libssh2_version libssh2 >/dev/null 2>&1
- then
+ if $pkg_config --atleast-version=$min_libssh2_version libssh2; then
libssh2_cflags=`$pkg_config libssh2 --cflags`
libssh2_libs=`$pkg_config libssh2 --libs`
libssh2=yes
@@ -2598,14 +2597,14 @@ fi
##########################################
# glusterfs probe
if test "$glusterfs" != "no" ; then
- if $pkg_config --atleast-version=3 glusterfs-api >/dev/null 2>&1; then
+ if $pkg_config --atleast-version=3 glusterfs-api; then
glusterfs="yes"
- glusterfs_cflags=`$pkg_config --cflags glusterfs-api 2>/dev/null`
- glusterfs_libs=`$pkg_config --libs glusterfs-api 2>/dev/null`
+ glusterfs_cflags=`$pkg_config --cflags glusterfs-api`
+ glusterfs_libs=`$pkg_config --libs glusterfs-api`
CFLAGS="$CFLAGS $glusterfs_cflags"
libs_tools="$glusterfs_libs $libs_tools"
libs_softmmu="$glusterfs_libs $libs_softmmu"
- if $pkg_config --atleast-version=5 glusterfs-api >/dev/null 2>&1; then
+ if $pkg_config --atleast-version=5 glusterfs-api; then
glusterfs_discard="yes"
fi
else
@@ -2968,10 +2967,10 @@ if test "$libiscsi" != "no" ; then
#include <iscsi/iscsi.h>
int main(void) { iscsi_unmap_sync(NULL,0,0,0,NULL,0); return 0; }
EOF
- if $pkg_config --atleast-version=1.7.0 libiscsi --modversion >/dev/null 2>&1; then
+ if $pkg_config --atleast-version=1.7.0 libiscsi; then
libiscsi="yes"
- libiscsi_cflags=$($pkg_config --cflags libiscsi 2>/dev/null)
- libiscsi_libs=$($pkg_config --libs libiscsi 2>/dev/null)
+ libiscsi_cflags=$($pkg_config --cflags libiscsi)
+ libiscsi_libs=$($pkg_config --libs libiscsi)
CFLAGS="$CFLAGS $libiscsi_cflags"
LIBS="$LIBS $libiscsi_libs"
elif compile_prog "" "-liscsi" ; then
@@ -3038,8 +3037,8 @@ int main(void) { spice_server_new(); return 0; }
EOF
spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null)
spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null)
- if $pkg_config --atleast-version=0.12.0 spice-server >/dev/null 2>&1 && \
- $pkg_config --atleast-version=0.12.3 spice-protocol > /dev/null 2>&1 && \
+ if $pkg_config --atleast-version=0.12.0 spice-server && \
+ $pkg_config --atleast-version=0.12.3 spice-protocol && \
compile_prog "$spice_cflags" "$spice_libs" ; then
spice="yes"
libs_softmmu="$libs_softmmu $spice_libs"
@@ -3074,7 +3073,7 @@ EOF
test_cflags="-Werror $test_cflags"
fi
if test -n "$libtool" &&
- $pkg_config --atleast-version=3.12.8 nss >/dev/null 2>&1 && \
+ $pkg_config --atleast-version=3.12.8 nss && \
compile_prog "$test_cflags" "$libcacard_libs"; then
smartcard_nss="yes"
QEMU_CFLAGS="$QEMU_CFLAGS $libcacard_cflags"
@@ -3090,11 +3089,11 @@ fi
# check for libusb
if test "$libusb" != "no" ; then
- if $pkg_config --atleast-version=1.0.13 libusb-1.0 >/dev/null 2>&1 ; then
+ if $pkg_config --atleast-version=1.0.13 libusb-1.0; then
libusb="yes"
usb="libusb"
- libusb_cflags=$($pkg_config --cflags libusb-1.0 2>/dev/null)
- libusb_libs=$($pkg_config --libs libusb-1.0 2>/dev/null)
+ libusb_cflags=$($pkg_config --cflags libusb-1.0)
+ libusb_libs=$($pkg_config --libs libusb-1.0)
QEMU_CFLAGS="$QEMU_CFLAGS $libusb_cflags"
libs_softmmu="$libs_softmmu $libusb_libs"
else
@@ -3107,10 +3106,10 @@ fi
# check for usbredirparser for usb network redirection support
if test "$usb_redir" != "no" ; then
- if $pkg_config --atleast-version=0.6 libusbredirparser-0.5 >/dev/null 2>&1 ; then
+ if $pkg_config --atleast-version=0.6 libusbredirparser-0.5; then
usb_redir="yes"
- usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5 2>/dev/null)
- usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5 2>/dev/null)
+ usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5)
+ usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5)
QEMU_CFLAGS="$QEMU_CFLAGS $usb_redir_cflags"
libs_softmmu="$libs_softmmu $usb_redir_libs"
else
diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt
index 36a559d886..33eca360cc 100644
--- a/docs/specs/qcow2.txt
+++ b/docs/specs/qcow2.txt
@@ -80,7 +80,12 @@ in the description of a field.
tables to repair refcounts before accessing the
image.
- Bits 1-63: Reserved (set to 0)
+ Bit 1: Corrupt bit. If this bit is set then any data
+ structure may be corrupt and the image must not
+ be written to (unless for regaining
+ consistency).
+
+ Bits 2-63: Reserved (set to 0)
80 - 87: compatible_features
Bitmask of compatible features. An implementation can
diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index 95fde615be..20795ac0fd 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -173,7 +173,6 @@ static QEMUMachine clipper_machine = {
.init = clipper_init,
.max_cpus = 4,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void clipper_machine_init(void)
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index a19857aaaf..8878b0ed9a 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -62,7 +62,6 @@ static QEMUMachine collie_machine = {
.name = "collie",
.desc = "Collie PDA (SA-1110)",
.init = collie_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void collie_machine_init(void)
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index 7c90b2d782..2929f9f8ab 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -150,14 +150,12 @@ static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
.desc = "Samsung NURI board (Exynos4210)",
.init = nuri_init,
.max_cpus = EXYNOS4210_NCPUS,
- DEFAULT_MACHINE_OPTIONS,
},
[EXYNOS4_BOARD_SMDKC210] = {
.name = "smdkc210",
.desc = "Samsung SMDKC210 board (Exynos4210)",
.init = smdkc210_init,
.max_cpus = EXYNOS4210_NCPUS,
- DEFAULT_MACHINE_OPTIONS,
},
};
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index b8cab10ba6..e97fbbd231 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -122,14 +122,12 @@ static QEMUMachine connex_machine = {
.name = "connex",
.desc = "Gumstix Connex (PXA255)",
.init = connex_init,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine verdex_machine = {
.name = "verdex",
.desc = "Gumstix Verdex (PXA270)",
.init = verdex_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void gumstix_machine_init(void)
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index f733a6cba7..fe98ef10cb 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -363,7 +363,6 @@ static QEMUMachine highbank_machine = {
.init = highbank_init,
.block_default_type = IF_SCSI,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine midway_machine = {
@@ -372,7 +371,6 @@ static QEMUMachine midway_machine = {
.init = midway_init,
.block_default_type = IF_SCSI,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
};
static void calxeda_machines_init(void)
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 59c37262c3..2ef93ed8d6 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -526,7 +526,6 @@ static QEMUMachine integratorcp_machine = {
.desc = "ARM Integrator/CP (ARM926EJ-S)",
.init = integratorcp_init,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void integratorcp_machine_init(void)
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index a248bf0dc7..99d33cb9d0 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -144,7 +144,6 @@ static QEMUMachine kzm_machine = {
.name = "kzm",
.desc = "ARM KZM Emulation Baseboard (ARM1136)",
.init = kzm_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void kzm_machine_init(void)
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 8e5fc26e12..b244f7e112 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -179,7 +179,6 @@ static QEMUMachine mainstone2_machine = {
.name = "mainstone",
.desc = "Mainstone II (PXA27x)",
.init = mainstone_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void mainstone_machine_init(void)
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 4404b8dd03..023e8756e2 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1729,7 +1729,6 @@ static QEMUMachine musicpal_machine = {
.name = "musicpal",
.desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)",
.init = musicpal_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void musicpal_machine_init(void)
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index f6c9dc09ef..9ef31ca37a 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -1340,7 +1340,7 @@ static void n8x0_init(QEMUMachineInitArgs *args,
}
if (option_rom[0].name &&
- (args->boot_device[0] == 'n' || !args->kernel_filename)) {
+ (args->boot_order[0] == 'n' || !args->kernel_filename)) {
uint8_t nolo_tags[0x10000];
/* No, wait, better start at the ROM. */
s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
@@ -1396,14 +1396,14 @@ static QEMUMachine n800_machine = {
.name = "n800",
.desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
.init = n800_init,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "",
};
static QEMUMachine n810_machine = {
.name = "n810",
.desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
.init = n810_init,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "",
};
static void nseries_machine_init(void)
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index 05b035308b..b0f8664607 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -219,14 +219,12 @@ static QEMUMachine sx1_machine_v2 = {
.name = "sx1",
.desc = "Siemens SX1 (OMAP310) V2",
.init = sx1_init_v2,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine sx1_machine_v1 = {
.name = "sx1-v1",
.desc = "Siemens SX1 (OMAP310) V1",
.init = sx1_init_v1,
- DEFAULT_MACHINE_OPTIONS,
};
static void sx1_machine_init(void)
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index cdc3c3a0fe..3e390448e2 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -273,7 +273,6 @@ static QEMUMachine palmte_machine = {
.name = "cheetah",
.desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)",
.init = palmte_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void palmte_machine_init(void)
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 82ec02d118..8d845ddb73 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -369,7 +369,6 @@ static QEMUMachine realview_eb_machine = {
.desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
.init = realview_eb_init,
.block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine realview_eb_mpcore_machine = {
@@ -378,14 +377,12 @@ static QEMUMachine realview_eb_mpcore_machine = {
.init = realview_eb_mpcore_init,
.block_default_type = IF_SCSI,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine realview_pb_a8_machine = {
.name = "realview-pb-a8",
.desc = "ARM RealView Platform Baseboard for Cortex-A8",
.init = realview_pb_a8_init,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine realview_pbx_a9_machine = {
@@ -394,7 +391,6 @@ static QEMUMachine realview_pbx_a9_machine = {
.init = realview_pbx_a9_init,
.block_default_type = IF_SCSI,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
};
static void realview_machine_init(void)
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 9b9ce95c5a..ba172835eb 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -966,28 +966,24 @@ static QEMUMachine akitapda_machine = {
.name = "akita",
.desc = "Akita PDA (PXA270)",
.init = akita_init,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine spitzpda_machine = {
.name = "spitz",
.desc = "Spitz PDA (PXA270)",
.init = spitz_init,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine borzoipda_machine = {
.name = "borzoi",
.desc = "Borzoi PDA (PXA270)",
.init = borzoi_init,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine terrierpda_machine = {
.name = "terrier",
.desc = "Terrier PDA (PXA270)",
.init = terrier_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void spitz_machine_init(void)
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 3237b30260..3170d69d42 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1348,14 +1348,12 @@ static QEMUMachine lm3s811evb_machine = {
.name = "lm3s811evb",
.desc = "Stellaris LM3S811EVB",
.init = lm3s811evb_init,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine lm3s6965evb_machine = {
.name = "lm3s6965evb",
.desc = "Stellaris LM3S6965EVB",
.init = lm3s6965evb_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void stellaris_machine_init(void)
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 47d1f4ff9b..c00d8c27cc 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -251,7 +251,6 @@ static QEMUMachine tosapda_machine = {
.name = "tosa",
.desc = "Tosa PDA (PXA255)",
.init = tosa_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void tosapda_machine_init(void)
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 4a6fceeeaa..f7e8b7e8fa 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -367,7 +367,6 @@ static QEMUMachine versatilepb_machine = {
.desc = "ARM Versatile/PB (ARM926EJ-S)",
.init = vpb_init,
.block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine versatileab_machine = {
@@ -375,7 +374,6 @@ static QEMUMachine versatileab_machine = {
.desc = "ARM Versatile/AB (ARM926EJ-S)",
.init = vab_init,
.block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
};
static void versatile_machine_init(void)
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index fbd71a7b49..f48de00a1a 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -647,7 +647,6 @@ static QEMUMachine vexpress_a9_machine = {
.init = vexpress_a9_init,
.block_default_type = IF_SCSI,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine vexpress_a15_machine = {
@@ -656,7 +655,6 @@ static QEMUMachine vexpress_a15_machine = {
.init = vexpress_a15_init,
.block_default_type = IF_SCSI,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
};
static void vexpress_machine_init(void)
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 0f18c852c4..46924a0391 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -233,7 +233,6 @@ static QEMUMachine zynq_machine = {
.block_default_type = IF_SCSI,
.max_cpus = 1,
.no_sdcard = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void zynq_machine_init(void)
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 07a127b498..2e0d5d4bcc 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -373,7 +373,6 @@ static QEMUMachine z2_machine = {
.name = "z2",
.desc = "Zipit Z2 (PXA27x)",
.init = z2_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void z2_machine_init(void)
diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index 0c792475d1..bd8e9d9815 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -284,9 +284,9 @@ static void Adlib_fini (AdlibState *s)
}
static MemoryRegionPortio adlib_portio_list[] = {
- { 0x388, 4, 1, .read = adlib_read, .write = adlib_write, },
{ 0, 4, 1, .read = adlib_read, .write = adlib_write, },
{ 0, 2, 1, .read = adlib_read, .write = adlib_write, },
+ { 0x388, 4, 1, .read = adlib_read, .write = adlib_write, },
PORTIO_END_OF_LIST(),
};
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 78f9d282e0..a6666c6cdf 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -40,11 +40,11 @@ static const TypeInfo hda_codec_bus_info = {
.instance_size = sizeof(HDACodecBus),
};
-void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
+void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, size_t bus_size,
hda_codec_response_func response,
hda_codec_xfer_func xfer)
{
- qbus_create_inplace(&bus->qbus, TYPE_HDA_BUS, dev, NULL);
+ qbus_create_inplace(bus, bus_size, TYPE_HDA_BUS, dev, NULL);
bus->response = response;
bus->xfer = xfer;
}
@@ -1142,7 +1142,7 @@ static int intel_hda_init(PCIDevice *pci)
msi_init(&d->pci, 0x50, 1, true, false);
}
- hda_codec_bus_init(DEVICE(pci), &d->codecs,
+ hda_codec_bus_init(DEVICE(pci), &d->codecs, sizeof(d->codecs),
intel_hda_response, intel_hda_xfer);
return 0;
diff --git a/hw/audio/intel-hda.h b/hw/audio/intel-hda.h
index 2544f0a344..d784bcf5fc 100644
--- a/hw/audio/intel-hda.h
+++ b/hw/audio/intel-hda.h
@@ -48,7 +48,7 @@ struct HDACodecDevice {
uint32_t cad; /* codec address */
};
-void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
+void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, size_t bus_size,
hda_codec_response_func response,
hda_codec_xfer_func xfer);
HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad);
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 99445b09b9..8d4b828edf 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -47,7 +47,7 @@
#ifdef PFLASH_DEBUG
#define DPRINTF(fmt, ...) \
do { \
- fprintf(stderr "PFLASH: " fmt , ## __VA_ARGS__); \
+ fprintf(stderr, "PFLASH: " fmt , ## __VA_ARGS__); \
} while (0)
#else
#define DPRINTF(fmt, ...) do { } while (0)
diff --git a/hw/char/ipack.c b/hw/char/ipack.c
index f890471db5..b7e45bedb2 100644
--- a/hw/char/ipack.c
+++ b/hw/char/ipack.c
@@ -24,11 +24,12 @@ IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot)
return NULL;
}
-void ipack_bus_new_inplace(IPackBus *bus, DeviceState *parent,
+void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
+ DeviceState *parent,
const char *name, uint8_t n_slots,
qemu_irq_handler handler)
{
- qbus_create_inplace(&bus->qbus, TYPE_IPACK_BUS, parent, name);
+ qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, name);
bus->n_slots = n_slots;
bus->set_irq = handler;
}
diff --git a/hw/char/ipack.h b/hw/char/ipack.h
index f2b7a12e05..f8dc0f242a 100644
--- a/hw/char/ipack.h
+++ b/hw/char/ipack.h
@@ -72,7 +72,8 @@ extern const VMStateDescription vmstate_ipack_device;
VMSTATE_STRUCT(_field, _state, 1, vmstate_ipack_device, IPackDevice)
IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot);
-void ipack_bus_new_inplace(IPackBus *bus, DeviceState *parent,
+void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
+ DeviceState *parent,
const char *name, uint8_t n_slots,
qemu_irq_handler handler);
diff --git a/hw/char/tpci200.c b/hw/char/tpci200.c
index d9e17b2956..e04ff26019 100644
--- a/hw/char/tpci200.c
+++ b/hw/char/tpci200.c
@@ -607,7 +607,7 @@ static int tpci200_initfn(PCIDevice *pci_dev)
pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las2);
pci_register_bar(&s->dev, 5, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las3);
- ipack_bus_new_inplace(&s->bus, DEVICE(&s->dev), NULL,
+ ipack_bus_new_inplace(&s->bus, sizeof(s->bus), DEVICE(pci_dev), NULL,
N_MODULES, tpci200_set_irq);
return 0;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index f23f555dde..703f026370 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -911,8 +911,8 @@ static int virtio_serial_device_init(VirtIODevice *vdev)
sizeof(struct virtio_console_config));
/* Spawn a new virtio-serial bus on which the ports will ride as devices */
- qbus_create_inplace(&vser->bus.qbus, TYPE_VIRTIO_SERIAL_BUS, qdev,
- vdev->bus_name);
+ qbus_create_inplace(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
+ qdev, vdev->bus_name);
vser->bus.qbus.allow_hotplug = 1;
vser->bus.vser = vser;
QTAILQ_INIT(&vser->ports);
diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index bdf109fef1..d813c089e7 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -24,7 +24,6 @@ static QEMUMachine machine_none = {
.desc = "empty machine",
.init = machine_none_init,
.max_cpus = 0,
- DEFAULT_MACHINE_OPTIONS,
};
static void register_machines(void)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 758de9fccc..533f6dd122 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -470,10 +470,10 @@ static void bus_unparent(Object *obj)
}
}
-void qbus_create_inplace(void *bus, const char *typename,
+void qbus_create_inplace(void *bus, size_t size, const char *typename,
DeviceState *parent, const char *name)
{
- object_initialize(bus, typename);
+ object_initialize(bus, size, typename);
qbus_realize(bus, parent, name);
}
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 9004d8c543..b84cd4a16f 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -276,8 +276,8 @@ static void main_system_bus_create(void)
/* assign main_system_bus before qbus_create_inplace()
* in order to make "if (bus != sysbus_get_default())" work */
main_system_bus = g_malloc0(system_bus_info.instance_size);
- qbus_create_inplace(main_system_bus, TYPE_SYSTEM_BUS, NULL,
- "main-system-bus");
+ qbus_create_inplace(main_system_bus, system_bus_info.instance_size,
+ TYPE_SYSTEM_BUS, NULL, "main-system-bus");
OBJECT(main_system_bus)->free = g_free;
object_property_add_child(container_get(qdev_get_machine(),
"/unattached"),
diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c
index 8748cc5046..9a4ea7e2df 100644
--- a/hw/cpu/icc_bus.c
+++ b/hw/cpu/icc_bus.c
@@ -90,7 +90,8 @@ static void icc_bridge_init(Object *obj)
ICCBridgeState *s = ICC_BRIGDE(obj);
SysBusDevice *sb = SYS_BUS_DEVICE(obj);
- qbus_create_inplace(&s->icc_bus, TYPE_ICC_BUS, DEVICE(s), "icc");
+ qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS,
+ DEVICE(s), "icc");
/* Do not change order of registering regions,
* APIC must be first registered region, board maps it by 0 index
diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index 9104d6194f..03058d3bc5 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -355,7 +355,6 @@ static QEMUMachine axisdev88_machine = {
.desc = "AXIS devboard 88",
.init = axisdev88_init,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void axisdev88_machine_init(void)
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index 59e8e35a4c..d67c5f19a4 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -579,8 +579,10 @@ static void xilinx_axidma_init(Object *obj)
(Object **) &s->tx_control_dev, &errp);
assert_no_error(errp);
- object_initialize(&s->rx_data_dev, TYPE_XILINX_AXI_DMA_DATA_STREAM);
- object_initialize(&s->rx_control_dev, TYPE_XILINX_AXI_DMA_CONTROL_STREAM);
+ object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
+ TYPE_XILINX_AXI_DMA_DATA_STREAM);
+ object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),
+ TYPE_XILINX_AXI_DMA_CONTROL_STREAM);
object_property_add_child(OBJECT(s), "axistream-connected-target",
(Object *)&s->rx_data_dev, &errp);
assert_no_error(errp);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 3c36a2a1c3..275e39595d 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -204,7 +204,7 @@ static void pc_init1(QEMUMachineInitArgs *args,
}
}
- pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_device,
+ pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_order,
floppy, idebus[0], idebus[1], rtc_state);
if (pci_enabled && usb_enabled(false)) {
@@ -334,40 +334,43 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
}
#endif
+#define PC_I440FX_MACHINE_OPTIONS \
+ PC_DEFAULT_MACHINE_OPTIONS, \
+ .desc = "Standard PC (i440FX + PIIX, 1996)", \
+ .hot_add_cpu = pc_hot_add_cpu
+
+#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
+
static QEMUMachine pc_i440fx_machine_v1_6 = {
+ PC_I440FX_1_6_MACHINE_OPTIONS,
.name = "pc-i440fx-1.6",
.alias = "pc",
- .desc = "Standard PC (i440FX + PIIX, 1996)",
.init = pc_init_pci_1_6,
- .hot_add_cpu = pc_hot_add_cpu,
- .max_cpus = 255,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine pc_i440fx_machine_v1_5 = {
+ PC_I440FX_1_6_MACHINE_OPTIONS,
.name = "pc-i440fx-1.5",
- .desc = "Standard PC (i440FX + PIIX, 1996)",
.init = pc_init_pci_1_5,
- .hot_add_cpu = pc_hot_add_cpu,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_1_5,
{ /* end of list */ }
},
- DEFAULT_MACHINE_OPTIONS,
};
+#define PC_I440FX_1_4_MACHINE_OPTIONS \
+ PC_I440FX_1_6_MACHINE_OPTIONS, \
+ .hot_add_cpu = NULL
+
static QEMUMachine pc_i440fx_machine_v1_4 = {
+ PC_I440FX_1_4_MACHINE_OPTIONS,
.name = "pc-i440fx-1.4",
- .desc = "Standard PC (i440FX + PIIX, 1996)",
.init = pc_init_pci_1_4,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_1_4,
{ /* end of list */ }
},
- DEFAULT_MACHINE_OPTIONS,
};
#define PC_COMPAT_1_3 \
@@ -391,15 +394,13 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
}
static QEMUMachine pc_machine_v1_3 = {
+ PC_I440FX_1_4_MACHINE_OPTIONS,
.name = "pc-1.3",
- .desc = "Standard PC",
.init = pc_init_pci_1_3,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_1_3,
{ /* end of list */ }
},
- DEFAULT_MACHINE_OPTIONS,
};
#define PC_COMPAT_1_2 \
@@ -430,16 +431,17 @@ static QEMUMachine pc_machine_v1_3 = {
.value = "off",\
}
+#define PC_I440FX_1_2_MACHINE_OPTIONS \
+ PC_I440FX_1_4_MACHINE_OPTIONS, \
+ .init = pc_init_pci_1_2
+
static QEMUMachine pc_machine_v1_2 = {
+ PC_I440FX_1_2_MACHINE_OPTIONS,
.name = "pc-1.2",
- .desc = "Standard PC",
- .init = pc_init_pci_1_2,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_1_2,
{ /* end of list */ }
},
- DEFAULT_MACHINE_OPTIONS,
};
#define PC_COMPAT_1_1 \
@@ -475,15 +477,12 @@ static QEMUMachine pc_machine_v1_2 = {
}
static QEMUMachine pc_machine_v1_1 = {
+ PC_I440FX_1_2_MACHINE_OPTIONS,
.name = "pc-1.1",
- .desc = "Standard PC",
- .init = pc_init_pci_1_2,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_1_1,
{ /* end of list */ }
},
- DEFAULT_MACHINE_OPTIONS,
};
#define PC_COMPAT_1_0 \
@@ -507,32 +506,26 @@ static QEMUMachine pc_machine_v1_1 = {
}
static QEMUMachine pc_machine_v1_0 = {
+ PC_I440FX_1_2_MACHINE_OPTIONS,
.name = "pc-1.0",
- .desc = "Standard PC",
- .init = pc_init_pci_1_2,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_1_0,
{ /* end of list */ }
},
.hw_version = "1.0",
- DEFAULT_MACHINE_OPTIONS,
};
#define PC_COMPAT_0_15 \
PC_COMPAT_1_0
static QEMUMachine pc_machine_v0_15 = {
+ PC_I440FX_1_2_MACHINE_OPTIONS,
.name = "pc-0.15",
- .desc = "Standard PC",
- .init = pc_init_pci_1_2,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_0_15,
{ /* end of list */ }
},
.hw_version = "0.15",
- DEFAULT_MACHINE_OPTIONS,
};
#define PC_COMPAT_0_14 \
@@ -556,10 +549,8 @@ static QEMUMachine pc_machine_v0_15 = {
}
static QEMUMachine pc_machine_v0_14 = {
+ PC_I440FX_1_2_MACHINE_OPTIONS,
.name = "pc-0.14",
- .desc = "Standard PC",
- .init = pc_init_pci_1_2,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_0_14,
{
@@ -574,7 +565,6 @@ static QEMUMachine pc_machine_v0_14 = {
{ /* end of list */ }
},
.hw_version = "0.14",
- DEFAULT_MACHINE_OPTIONS,
};
#define PC_COMPAT_0_13 \
@@ -589,11 +579,13 @@ static QEMUMachine pc_machine_v0_14 = {
.value = stringify(1),\
}
+#define PC_I440FX_0_13_MACHINE_OPTIONS \
+ PC_I440FX_1_2_MACHINE_OPTIONS, \
+ .init = pc_init_pci_no_kvmclock
+
static QEMUMachine pc_machine_v0_13 = {
+ PC_I440FX_0_13_MACHINE_OPTIONS,
.name = "pc-0.13",
- .desc = "Standard PC",
- .init = pc_init_pci_no_kvmclock,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_0_13,
{
@@ -612,7 +604,6 @@ static QEMUMachine pc_machine_v0_13 = {
{ /* end of list */ }
},
.hw_version = "0.13",
- DEFAULT_MACHINE_OPTIONS,
};
#define PC_COMPAT_0_12 \
@@ -640,10 +631,8 @@ static QEMUMachine pc_machine_v0_13 = {
}
static QEMUMachine pc_machine_v0_12 = {
+ PC_I440FX_0_13_MACHINE_OPTIONS,
.name = "pc-0.12",
- .desc = "Standard PC",
- .init = pc_init_pci_no_kvmclock,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_0_12,
{
@@ -658,7 +647,6 @@ static QEMUMachine pc_machine_v0_12 = {
{ /* end of list */ }
},
.hw_version = "0.12",
- DEFAULT_MACHINE_OPTIONS,
};
#define PC_COMPAT_0_11 \
@@ -674,10 +662,8 @@ static QEMUMachine pc_machine_v0_12 = {
}
static QEMUMachine pc_machine_v0_11 = {
+ PC_I440FX_0_13_MACHINE_OPTIONS,
.name = "pc-0.11",
- .desc = "Standard PC, qemu 0.11",
- .init = pc_init_pci_no_kvmclock,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_0_11,
{
@@ -692,14 +678,11 @@ static QEMUMachine pc_machine_v0_11 = {
{ /* end of list */ }
},
.hw_version = "0.11",
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine pc_machine_v0_10 = {
+ PC_I440FX_0_13_MACHINE_OPTIONS,
.name = "pc-0.10",
- .desc = "Standard PC, qemu 0.10",
- .init = pc_init_pci_no_kvmclock,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_0_11,
{
@@ -726,10 +709,10 @@ static QEMUMachine pc_machine_v0_10 = {
{ /* end of list */ }
},
.hw_version = "0.10",
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine isapc_machine = {
+ PC_COMMON_MACHINE_OPTIONS,
.name = "isapc",
.desc = "ISA-only PC",
.init = pc_init_isa,
@@ -737,17 +720,16 @@ static QEMUMachine isapc_machine = {
.compat_props = (GlobalProperty[]) {
{ /* end of list */ }
},
- DEFAULT_MACHINE_OPTIONS,
};
#ifdef CONFIG_XEN
static QEMUMachine xenfv_machine = {
+ PC_COMMON_MACHINE_OPTIONS,
.name = "xenfv",
.desc = "Xen Fully-virtualized PC",
.init = pc_xen_hvm_init,
.max_cpus = HVM_MAX_VCPUS,
.default_machine_opts = "accel=xen",
- DEFAULT_MACHINE_OPTIONS,
};
#endif
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 198c7851b3..d7b7c3bf9a 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -200,7 +200,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
0xb100),
8, NULL, 0);
- pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_device,
+ pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_order,
floppy, idebus[0], idebus[1], rtc_state);
/* the rest devices to which pci devfn is automatically assigned */
@@ -253,39 +253,42 @@ static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
pc_q35_init(args);
}
+#define PC_Q35_MACHINE_OPTIONS \
+ PC_DEFAULT_MACHINE_OPTIONS, \
+ .desc = "Standard PC (Q35 + ICH9, 2009)", \
+ .hot_add_cpu = pc_hot_add_cpu
+
+#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
+
static QEMUMachine pc_q35_machine_v1_6 = {
+ PC_Q35_1_6_MACHINE_OPTIONS,
.name = "pc-q35-1.6",
.alias = "q35",
- .desc = "Standard PC (Q35 + ICH9, 2009)",
.init = pc_q35_init_1_6,
- .hot_add_cpu = pc_hot_add_cpu,
- .max_cpus = 255,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine pc_q35_machine_v1_5 = {
+ PC_Q35_1_6_MACHINE_OPTIONS,
.name = "pc-q35-1.5",
- .desc = "Standard PC (Q35 + ICH9, 2009)",
.init = pc_q35_init_1_5,
- .hot_add_cpu = pc_hot_add_cpu,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_1_5,
{ /* end of list */ }
},
- DEFAULT_MACHINE_OPTIONS,
};
+#define PC_Q35_1_4_MACHINE_OPTIONS \
+ PC_Q35_1_6_MACHINE_OPTIONS, \
+ .hot_add_cpu = NULL
+
static QEMUMachine pc_q35_machine_v1_4 = {
+ PC_Q35_1_4_MACHINE_OPTIONS,
.name = "pc-q35-1.4",
- .desc = "Standard PC (Q35 + ICH9, 2009)",
.init = pc_q35_init_1_4,
- .max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_1_4,
{ /* end of list */ }
},
- DEFAULT_MACHINE_OPTIONS,
};
static void pc_q35_machine_init(void)
diff --git a/hw/i386/xen_machine_pv.c b/hw/i386/xen_machine_pv.c
index 9f2e2918f0..9adb57fc14 100644
--- a/hw/i386/xen_machine_pv.c
+++ b/hw/i386/xen_machine_pv.c
@@ -99,7 +99,6 @@ static QEMUMachine xenpv_machine = {
.init = xen_init_pv,
.max_cpus = 1,
.default_machine_opts = "accel=xen",
- DEFAULT_MACHINE_OPTIONS,
};
static void xenpv_machine_init(void)
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index bba150fd74..a71a4ca47c 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1175,7 +1175,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
for (i = 0; i < s->ports; i++) {
AHCIDevice *ad = &s->dev[i];
- ide_bus_new(&ad->port, qdev, i, 1);
+ ide_bus_new(&ad->port, sizeof(ad->port), qdev, i, 1);
ide_init2(&ad->port, irqs[i]);
ad->hba = s;
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index d6ef7992d4..0500a7a1b6 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -289,7 +289,7 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
for (i = 0; i < 2; i++) {
- ide_bus_new(&d->bus[i], DEVICE(dev), i, 2);
+ ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(dev), i, 2);
ide_init2(&d->bus[i], irq[i]);
bmdma_init(&d->bus[i], &d->bmdma[i], d);
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 048a052143..5d1cf87742 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -576,7 +576,8 @@ void ide_atapi_cmd(IDEState *s);
void ide_atapi_cmd_reply_end(IDEState *s);
/* hw/ide/qdev.c */
-void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id, int max_units);
+void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
+ int bus_id, int max_units);
IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
#endif /* HW_IDE_INTERNAL_H */
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index bbc8c6b9c9..afc24d4728 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -70,7 +70,7 @@ static void isa_ide_realizefn(DeviceState *dev, Error **errp)
ISADevice *isadev = ISA_DEVICE(dev);
ISAIDEState *s = ISA_IDE(dev);
- ide_bus_new(&s->bus, dev, 0, 2);
+ ide_bus_new(&s->bus, sizeof(s->bus), dev, 0, 2);
ide_init_ioport(&s->bus, isadev, s->iobase, s->iobase2);
isa_init_irq(isadev, &s->irq, s->isairq);
ide_init2(&s->bus, s->irq);
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index ef4ba2b2c5..da94580aac 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -547,7 +547,7 @@ static void macio_ide_initfn(Object *obj)
SysBusDevice *d = SYS_BUS_DEVICE(obj);
MACIOIDEState *s = MACIO_IDE(obj);
- ide_bus_new(&s->bus, DEVICE(obj), 0, 2);
+ ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000);
sysbus_init_mmio(d, &s->mem);
sysbus_init_irq(d, &s->irq);
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
index d251ff983c..9f66a52599 100644
--- a/hw/ide/mmio.c
+++ b/hw/ide/mmio.c
@@ -137,7 +137,7 @@ static void mmio_ide_initfn(Object *obj)
SysBusDevice *d = SYS_BUS_DEVICE(obj);
MMIOState *s = MMIO_IDE(obj);
- ide_bus_new(&s->bus, DEVICE(obj), 0, 2);
+ ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
sysbus_init_irq(d, &s->irq);
}
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index e6e6c0bb7a..ab36749417 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -136,7 +136,7 @@ static void pci_piix_init_ports(PCIIDEState *d) {
int i;
for (i = 0; i < 2; i++) {
- ide_bus_new(&d->bus[i], DEVICE(d), i, 2);
+ ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
port_info[i].iobase2);
ide_init2(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 1d84e15378..18c4b7eca9 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -47,9 +47,10 @@ static const TypeInfo ide_bus_info = {
.class_init = ide_bus_class_init,
};
-void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id, int max_units)
+void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
+ int bus_id, int max_units)
{
- qbus_create_inplace(&idebus->qbus, TYPE_IDE_BUS, dev, NULL);
+ qbus_create_inplace(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
idebus->bus_id = bus_id;
idebus->max_units = max_units;
}
diff --git a/hw/ide/via.c b/hw/ide/via.c
index e5fb2970e1..99468c773e 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -159,7 +159,7 @@ static void vt82c686b_init_ports(PCIIDEState *d) {
int i;
for (i = 0; i < 2; i++) {
- ide_bus_new(&d->bus[i], DEVICE(d), i, 2);
+ ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
port_info[i].iobase2);
ide_init2(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 31868c4d18..bb018d1829 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -661,7 +661,7 @@ static void xics_realize(DeviceState *dev, Error **errp)
icp->ss = g_malloc0(icp->nr_servers*sizeof(ICPState));
for (i = 0; i < icp->nr_servers; i++) {
char buffer[32];
- object_initialize(&icp->ss[i], TYPE_ICP);
+ object_initialize(&icp->ss[i], sizeof(icp->ss[i]), TYPE_ICP);
snprintf(buffer, sizeof(buffer), "icp[%d]", i);
object_property_add_child(OBJECT(icp), buffer, OBJECT(&icp->ss[i]), NULL);
qdev_init_nofail(DEVICE(&icp->ss[i]));
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 62003b8585..c032bb8b96 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -289,7 +289,6 @@ static QEMUMachine lm32_evr_machine = {
.desc = "LatticeMico32 EVR32 eval system",
.init = lm32_evr_init,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine lm32_uclinux_machine = {
@@ -297,7 +296,6 @@ static QEMUMachine lm32_uclinux_machine = {
.desc = "lm32 platform for uClinux and u-boot by Theobroma Systems",
.init = lm32_uclinux_init,
.is_default = 0,
- DEFAULT_MACHINE_OPTIONS,
};
static void lm32_machine_init(void)
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 7ceedb814f..f1744ec07e 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -208,7 +208,6 @@ static QEMUMachine milkymist_machine = {
.desc = "Milkymist One",
.init = milkymist_init,
.is_default = 0,
- DEFAULT_MACHINE_OPTIONS,
};
static void milkymist_machine_init(void)
diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index 0c03a87abc..a8eee44e62 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -89,7 +89,6 @@ static QEMUMachine an5206_machine = {
.name = "an5206",
.desc = "Arnewsh 5206",
.init = an5206_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void an5206_machine_init(void)
diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c
index f4ed7c6cc5..86e2e6e065 100644
--- a/hw/m68k/dummy_m68k.c
+++ b/hw/m68k/dummy_m68k.c
@@ -73,7 +73,6 @@ static QEMUMachine dummy_m68k_machine = {
.name = "dummy",
.desc = "Dummy board",
.init = dummy_m68k_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void dummy_m68k_machine_init(void)
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index 9cf000f4ce..fb96fe8548 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -295,7 +295,6 @@ static QEMUMachine mcf5208evb_machine = {
.desc = "MCF5206EVB",
.init = mcf5208evb_init,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void mcf5208evb_machine_init(void)
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 989da25dec..e003c7c7b4 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -186,7 +186,6 @@ static QEMUMachine petalogix_ml605_machine = {
.desc = "PetaLogix linux refdesign for xilinx ml605 little endian",
.init = petalogix_ml605_init,
.is_default = 0,
- DEFAULT_MACHINE_OPTIONS,
};
static void petalogix_ml605_machine_init(void)
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index a461494439..00af2b5abc 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -116,7 +116,6 @@ static QEMUMachine petalogix_s3adsp1800_machine = {
.desc = "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800",
.init = petalogix_s3adsp1800_init,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void petalogix_s3adsp1800_machine_init(void)
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index e8d5dd0980..9ef3a978e2 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -403,7 +403,6 @@ static QEMUMachine mips_fulong2e_machine = {
.name = "fulong2e",
.desc = "Fulong 2e mini pc",
.init = mips_fulong2e_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void mips_fulong2e_machine_init(void)
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index d748ded7eb..49bdd024ed 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -327,7 +327,6 @@ static QEMUMachine mips_magnum_machine = {
.desc = "MIPS Magnum",
.init = mips_magnum_init,
.block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine mips_pica61_machine = {
@@ -335,7 +334,6 @@ static QEMUMachine mips_pica61_machine = {
.desc = "Acer Pica 61",
.init = mips_pica61_init,
.block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
};
static void mips_jazz_machine_init(void)
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index f8d064cec3..ae0921c6aa 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1136,7 +1136,6 @@ static QEMUMachine mips_malta_machine = {
.init = mips_malta_init,
.max_cpus = 16,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void mips_malta_register_types(void)
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 297f01e268..242bab9779 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -232,7 +232,6 @@ static QEMUMachine mips_mipssim_machine = {
.name = "mipssim",
.desc = "MIPS MIPSsim platform",
.init = mips_mipssim_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void mips_mipssim_machine_init(void)
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index 044f232de0..e94b543e80 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -306,7 +306,6 @@ static QEMUMachine mips_machine = {
.name = "mips",
.desc = "mips r4k platform",
.init = mips_r4k_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void mips_machine_init(void)
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index c811b9519b..bc71aa7ccd 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -711,8 +711,8 @@ static void cuda_initfn(Object *obj)
s->timers[i].index = i;
}
- qbus_create_inplace((BusState *)&s->adb_bus, TYPE_ADB_BUS, DEVICE(obj),
- "adb.0");
+ qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
+ DEVICE(obj), "adb.0");
}
static void cuda_class_init(ObjectClass *oc, void *data)
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index 9cc33d8f96..7f99aa0d5c 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -202,11 +202,12 @@ static int macio_oldworld_initfn(PCIDevice *d)
return 0;
}
-static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, int index)
+static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, size_t ide_size,
+ int index)
{
gchar *name;
- object_initialize(ide, TYPE_MACIO_IDE);
+ object_initialize(ide, ide_size, TYPE_MACIO_IDE);
qdev_set_parent_bus(DEVICE(ide), sysbus_get_default());
memory_region_add_subregion(&s->bar, 0x1f000 + ((index + 1) * 0x1000),
&ide->mem);
@@ -224,13 +225,13 @@ static void macio_oldworld_init(Object *obj)
qdev_init_gpio_out(DEVICE(obj), os->irqs, ARRAY_SIZE(os->irqs));
- object_initialize(&os->nvram, TYPE_MACIO_NVRAM);
+ object_initialize(&os->nvram, sizeof(os->nvram), TYPE_MACIO_NVRAM);
dev = DEVICE(&os->nvram);
qdev_prop_set_uint32(dev, "size", 0x2000);
qdev_prop_set_uint32(dev, "it_shift", 4);
for (i = 0; i < 2; i++) {
- macio_init_ide(s, &os->ide[i], i);
+ macio_init_ide(s, &os->ide[i], sizeof(os->ide[i]), i);
}
}
@@ -310,7 +311,7 @@ static void macio_newworld_init(Object *obj)
qdev_init_gpio_out(DEVICE(obj), ns->irqs, ARRAY_SIZE(ns->irqs));
for (i = 0; i < 2; i++) {
- macio_init_ide(s, &ns->ide[i], i);
+ macio_init_ide(s, &ns->ide[i], sizeof(ns->ide[i]), i);
}
}
@@ -321,7 +322,7 @@ static void macio_instance_init(Object *obj)
memory_region_init(&s->bar, NULL, "macio", 0x80000);
- object_initialize(&s->cuda, TYPE_CUDA);
+ object_initialize(&s->cuda, sizeof(s->cuda), TYPE_CUDA);
qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default());
object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL);
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index f173429ecc..3eb7715c22 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -990,8 +990,10 @@ static void xilinx_enet_init(Object *obj)
(Object **) &s->tx_control_dev, &errp);
assert_no_error(errp);
- object_initialize(&s->rx_data_dev, TYPE_XILINX_AXI_ENET_DATA_STREAM);
- object_initialize(&s->rx_control_dev, TYPE_XILINX_AXI_ENET_CONTROL_STREAM);
+ object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
+ TYPE_XILINX_AXI_ENET_DATA_STREAM);
+ object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),
+ TYPE_XILINX_AXI_ENET_CONTROL_STREAM);
object_property_add_child(OBJECT(s), "axistream-connected-target",
(Object *)&s->rx_data_dev, &errp);
assert_no_error(errp);
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 28fa41d64e..8e1af8bf2e 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -138,7 +138,6 @@ static QEMUMachine openrisc_sim_machine = {
.init = openrisc_sim_init,
.max_cpus = 1,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void openrisc_sim_machine_init(void)
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index dc1718fe30..221d82b637 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -320,6 +320,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
PCII440FXState *f;
unsigned i;
I440FXState *i440fx;
+ uint64_t pci_hole64_size;
dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE);
s = PCI_HOST_BRIDGE(dev);
@@ -351,13 +352,15 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
pci_hole_start, pci_hole_size);
memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole);
+ pci_hole64_size = pci_host_get_hole64_size(i440fx->pci_hole64_size);
+
pc_init_pci64_hole(&i440fx->pci_info, 0x100000000ULL + above_4g_mem_size,
- i440fx->pci_hole64_size);
+ pci_hole64_size);
memory_region_init_alias(&f->pci_hole_64bit, OBJECT(d), "pci-hole64",
f->pci_address_space,
i440fx->pci_info.w64.begin,
- i440fx->pci_hole64_size);
- if (i440fx->pci_hole64_size) {
+ pci_hole64_size);
+ if (pci_hole64_size) {
memory_region_add_subregion(f->system_memory,
i440fx->pci_info.w64.begin,
&f->pci_hole_64bit);
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index e120058511..0e71fdbfb1 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -155,11 +155,11 @@ static void raven_pcihost_initfn(Object *obj)
MemoryRegion *address_space_io = get_system_io();
DeviceState *pci_dev;
- pci_bus_new_inplace(&s->pci_bus, DEVICE(obj), NULL,
+ pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
address_space_mem, address_space_io, 0, TYPE_PCI_BUS);
h->bus = &s->pci_bus;
- object_initialize(&s->pci_dev, TYPE_RAVEN_PCI_DEVICE);
+ object_initialize(&s->pci_dev, sizeof(s->pci_dev), TYPE_RAVEN_PCI_DEVICE);
pci_dev = DEVICE(&s->pci_dev);
qdev_set_parent_bus(pci_dev, BUS(&s->pci_bus));
object_property_set_int(OBJECT(&s->pci_dev), PCI_DEVFN(0, 0), "addr",
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 12314d8dfe..54735043b7 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -133,7 +133,7 @@ static void q35_host_initfn(Object *obj)
memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
"pci-conf-data", 4);
- object_initialize(&s->mch, TYPE_MCH_PCI_DEVICE);
+ object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
qdev_prop_set_uint32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
@@ -320,6 +320,7 @@ static int mch_init(PCIDevice *d)
{
int i;
MCHPCIState *mch = MCH_PCI_DEVICE(d);
+ uint64_t pci_hole64_size;
/* setup pci memory regions */
memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole",
@@ -329,13 +330,14 @@ static int mch_init(PCIDevice *d)
memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size,
&mch->pci_hole);
+ pci_hole64_size = pci_host_get_hole64_size(mch->pci_hole64_size);
pc_init_pci64_hole(&mch->pci_info, 0x100000000ULL + mch->above_4g_mem_size,
- mch->pci_hole64_size);
+ pci_hole64_size);
memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64",
mch->pci_address_space,
mch->pci_info.w64.begin,
- mch->pci_hole64_size);
- if (mch->pci_hole64_size) {
+ pci_hole64_size);
+ if (pci_hole64_size) {
memory_region_add_subregion(mch->system_memory,
mch->pci_info.w64.begin,
&mch->pci_hole_64bit);
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 9238d39b00..6b28929d26 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -384,12 +384,12 @@ static void pci_vpb_init(Object *obj)
memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 1ULL << 32);
memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 1ULL << 32);
- pci_bus_new_inplace(&s->pci_bus, DEVICE(obj), "pci",
+ pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), "pci",
&s->pci_mem_space, &s->pci_io_space,
PCI_DEVFN(11, 0), TYPE_PCI_BUS);
h->bus = &s->pci_bus;
- object_initialize(&s->pci_dev, TYPE_VERSATILE_PCI_HOST);
+ object_initialize(&s->pci_dev, sizeof(s->pci_dev), TYPE_VERSATILE_PCI_HOST);
qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus));
/* Window sizes for VersatilePB; realview_pci's init will override */
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 4c004f5daa..d00682e134 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -312,13 +312,13 @@ bool pci_bus_is_root(PCIBus *bus)
return !bus->parent_dev;
}
-void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
+void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
const char *name,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io,
uint8_t devfn_min, const char *typename)
{
- qbus_create_inplace(bus, typename, parent, name);
+ qbus_create_inplace(bus, bus_size, typename, parent, name);
pci_bus_init(bus, parent, name, address_space_mem,
address_space_io, devfn_min);
}
@@ -812,12 +812,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
}
pci_dev->bus = bus;
- if (bus->iommu_fn) {
- dma_as = bus->iommu_fn(bus, bus->iommu_opaque, devfn);
- } else {
- /* FIXME: inherit memory region from bus creator */
- dma_as = &address_space_memory;
- }
+ dma_as = pci_device_iommu_address_space(pci_dev);
memory_region_init_alias(&pci_dev->bus_master_enable_region,
OBJECT(pci_dev), "bus master",
@@ -2239,6 +2234,23 @@ static void pci_device_class_init(ObjectClass *klass, void *data)
k->props = pci_props;
}
+AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
+{
+ PCIBus *bus = PCI_BUS(dev->bus);
+
+ if (bus->iommu_fn) {
+ return bus->iommu_fn(bus, bus->iommu_opaque, dev->devfn);
+ }
+
+ if (bus->parent_dev) {
+ /** We are ignoring the bus master DMA bit of the bridge
+ * as it would complicate things such as VFIO for no good reason */
+ return pci_device_iommu_address_space(bus->parent_dev);
+ }
+
+ return &address_space_memory;
+}
+
void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque)
{
bus->iommu_fn = fn;
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index a90671d2f2..e6b22b860f 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -367,7 +367,8 @@ int pci_bridge_initfn(PCIDevice *dev, const char *typename)
br->bus_name = dev->qdev.id;
}
- qbus_create_inplace(&sec_bus->qbus, typename, &dev->qdev, br->bus_name);
+ qbus_create_inplace(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev),
+ br->bus_name);
sec_bus->parent_dev = dev;
sec_bus->map_irq = br->map_irq ? br->map_irq : pci_swizzle_map_irq_fn;
sec_bus->address_space_mem = &br->address_space_mem;
diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 7dd9b25609..77c7d1f86b 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -20,6 +20,7 @@
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
+#include "trace.h"
/* debug PCI */
//#define DEBUG_PCI
@@ -51,14 +52,22 @@ void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
uint32_t limit, uint32_t val, uint32_t len)
{
assert(len <= 4);
+ trace_pci_cfg_write(pci_dev->name, PCI_SLOT(pci_dev->devfn),
+ PCI_FUNC(pci_dev->devfn), addr, val);
pci_dev->config_write(pci_dev, addr, val, MIN(len, limit - addr));
}
uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
uint32_t limit, uint32_t len)
{
+ uint32_t ret;
+
assert(len <= 4);
- return pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+ ret = pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+ trace_pci_cfg_read(pci_dev->name, PCI_SLOT(pci_dev->devfn),
+ PCI_FUNC(pci_dev->devfn), addr, ret);
+
+ return ret;
}
void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index bf65b69366..2e964b2474 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -51,7 +51,6 @@ static QEMUMachine e500plat_machine = {
.desc = "generic paravirt e500 platform",
.init = e500plat_init,
.max_cpus = 32,
- DEFAULT_MACHINE_OPTIONS,
};
static void e500plat_machine_init(void)
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 7ef806ef7f..5e79575165 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -147,7 +147,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
- const char *boot_device = args->boot_device;
+ const char *boot_device = args->boot_order;
PowerPCCPU *cpu = NULL;
CPUPPCState *env = NULL;
char *filename;
@@ -477,7 +477,7 @@ static QEMUMachine core99_machine = {
.desc = "Mac99 based PowerMAC",
.init = ppc_core99_init,
.max_cpus = MAX_CPUS,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "cd",
};
static void core99_machine_init(void)
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 42bb9d55c8..2f27754c6c 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -78,7 +78,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
- const char *boot_device = args->boot_device;
+ const char *boot_device = args->boot_order;
MemoryRegion *sysmem = get_system_memory();
PowerPCCPU *cpu = NULL;
CPUPPCState *env = NULL;
@@ -350,7 +350,7 @@ static QEMUMachine heathrow_machine = {
#ifndef TARGET_PPC64
.is_default = 1,
#endif
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "cd", /* TOFIX "cad" when Mac floppy is implemented */
};
static void heathrow_machine_init(void)
diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index 1888e75545..edcc0be5f7 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -44,7 +44,6 @@ static QEMUMachine ppce500_machine = {
.desc = "mpc8544ds",
.init = mpc8544ds_init,
.max_cpus = 15,
- DEFAULT_MACHINE_OPTIONS,
};
static void ppce500_machine_init(void)
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 75b2177c9c..f1a8f6734a 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -367,7 +367,6 @@ static QEMUMachine ref405ep_machine = {
.name = "ref405ep",
.desc = "ref405ep",
.init = ref405ep_init,
- DEFAULT_MACHINE_OPTIONS,
};
/*****************************************************************************/
@@ -655,7 +654,6 @@ static QEMUMachine taihu_machine = {
.name = "taihu",
.desc = "taihu",
.init = taihu_405ep_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void ppc405_machine_init(void)
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 369ab9e26e..655e49906d 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -296,7 +296,6 @@ static QEMUMachine bamboo_machine = {
.name = "bamboo",
.desc = "bamboo",
.init = bamboo_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void bamboo_machine_init(void)
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 7e04b1ac84..aad0f69117 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -452,7 +452,7 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
- const char *boot_device = args->boot_device;
+ const char *boot_device = args->boot_order;
MemoryRegion *sysmem = get_system_memory();
PowerPCCPU *cpu = NULL;
CPUPPCState *env = NULL;
@@ -691,7 +691,7 @@ static QEMUMachine prep_machine = {
.desc = "PowerPC PREP platform",
.init = ppc_prep_init,
.max_cpus = MAX_CPUS,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "cad",
};
static void prep_machine_init(void)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8c6e296ff0..004184d841 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1091,7 +1091,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
- const char *boot_device = args->boot_device;
+ const char *boot_device = args->boot_order;
PowerPCCPU *cpu;
CPUPPCState *env;
PCIHostState *phb;
@@ -1346,7 +1346,7 @@ static QEMUMachine spapr_machine = {
.block_default_type = IF_SCSI,
.max_cpus = MAX_CPUS,
.no_parallel = 1,
- .boot_order = NULL,
+ .default_boot_order = NULL,
};
static void spapr_machine_init(void)
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index e9468b1b25..fcfa678344 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -254,7 +254,6 @@ static QEMUMachine virtex_machine = {
.name = "virtex-ml507",
.desc = "Xilinx Virtex ML507 reference design",
.init = virtex_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void virtex_machine_init(void)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 93b0b9733b..101da63d04 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -124,7 +124,7 @@ static void sch_handle_clear_func(SubchDev *sch)
/* Path management: In our simple css, we always choose the only path. */
path = 0x80;
- /* Reset values prior to 'issueing the clear signal'. */
+ /* Reset values prior to 'issuing the clear signal'. */
p->lpum = 0;
p->pom = 0xff;
s->flags &= ~SCSW_FLAGS_MASK_PNO;
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index 0faade0766..a3aceef8f5 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -324,8 +324,8 @@ static int init_event_facility(S390SCLPDevice *sdev)
sdev->event_pending = event_pending;
/* Spawn a new sclp-events facility */
- qbus_create_inplace(&event_facility->sbus.qbus,
- TYPE_SCLP_EVENTS_BUS, (DeviceState *)sdev, NULL);
+ qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
+ TYPE_SCLP_EVENTS_BUS, DEVICE(sdev), NULL);
event_facility->sbus.qbus.allow_hotplug = 0;
event_facility->qdev = (DeviceState *) sdev;
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index f0aa9414f2..6a831114da 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -47,7 +47,8 @@
#define VIRTIO_EXT_CODE 0x2603
-static void virtio_s390_bus_new(VirtioBusState *bus, VirtIOS390Device *dev);
+static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
+ VirtIOS390Device *dev);
static const TypeInfo s390_virtio_bus_info = {
.name = TYPE_S390_VIRTIO_BUS,
@@ -170,7 +171,7 @@ static int s390_virtio_net_init(VirtIOS390Device *s390_dev)
static void s390_virtio_net_instance_init(Object *obj)
{
VirtIONetS390 *dev = VIRTIO_NET_S390(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_NET);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -189,7 +190,7 @@ static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
static void s390_virtio_blk_instance_init(Object *obj)
{
VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BLK);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -230,7 +231,7 @@ static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
static void s390_virtio_serial_instance_init(Object *obj)
{
VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SERIAL);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -262,7 +263,7 @@ static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev)
static void s390_virtio_scsi_instance_init(Object *obj)
{
VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SCSI);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -283,7 +284,7 @@ static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev)
static void s390_vhost_scsi_instance_init(Object *obj)
{
VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VHOST_SCSI);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
#endif
@@ -309,7 +310,7 @@ static int s390_virtio_rng_init(VirtIOS390Device *s390_dev)
static void s390_virtio_rng_instance_init(Object *obj)
{
VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_RNG);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng, NULL);
@@ -585,7 +586,7 @@ static int s390_virtio_busdev_init(DeviceState *dev)
VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
- virtio_s390_bus_new(&_dev->bus, _dev);
+ virtio_s390_bus_new(&_dev->bus, sizeof(_dev->bus), _dev);
return _info->init(_dev);
}
@@ -691,14 +692,15 @@ static const TypeInfo s390_virtio_bridge_info = {
/* virtio-s390-bus */
-static void virtio_s390_bus_new(VirtioBusState *bus, VirtIOS390Device *dev)
+static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
+ VirtIOS390Device *dev)
{
DeviceState *qdev = DEVICE(dev);
BusState *qbus;
char virtio_bus_name[] = "virtio-bus";
- qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_S390_BUS, qdev,
- virtio_bus_name);
+ qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_S390_BUS,
+ qdev, virtio_bus_name);
qbus = BUS(bus);
qbus->allow_hotplug = 1;
}
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 8fd46a92c9..733d988871 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -141,7 +141,6 @@ static QEMUMachine ccw_machine = {
.no_sdcard = 1,
.use_sclp = 1,
.max_cpus = 255,
- DEFAULT_MACHINE_OPTIONS,
};
static void ccw_machine_init(void)
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 439d7323ec..7adf92af51 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -293,7 +293,6 @@ static QEMUMachine s390_machine = {
.use_virtcon = 1,
.max_cpus = 255,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void s390_machine_init(void)
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 8835bd4339..cd67db5e5b 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -27,7 +27,8 @@
#include "virtio-ccw.h"
#include "trace.h"
-static void virtio_ccw_bus_new(VirtioBusState *bus, VirtioCcwDevice *dev);
+static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
+ VirtioCcwDevice *dev);
static int virtual_css_bus_reset(BusState *qbus)
{
@@ -659,7 +660,7 @@ static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
static void virtio_ccw_net_instance_init(Object *obj)
{
VirtIONetCcw *dev = VIRTIO_NET_CCW(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_NET);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -679,7 +680,7 @@ static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
static void virtio_ccw_blk_instance_init(Object *obj)
{
VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BLK);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -712,7 +713,7 @@ static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
static void virtio_ccw_serial_instance_init(Object *obj)
{
VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SERIAL);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -758,7 +759,7 @@ static void balloon_ccw_stats_set_poll_interval(Object *obj, struct Visitor *v,
static void virtio_ccw_balloon_instance_init(Object *obj)
{
VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BALLOON);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_property_add(obj, "guest-stats", "guest statistics",
@@ -798,7 +799,7 @@ static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
static void virtio_ccw_scsi_instance_init(Object *obj)
{
VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SCSI);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -819,7 +820,7 @@ static int vhost_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
static void vhost_ccw_scsi_instance_init(Object *obj)
{
VHostSCSICcw *dev = VHOST_SCSI_CCW(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VHOST_SCSI);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
#endif
@@ -1170,7 +1171,7 @@ static const TypeInfo vhost_ccw_scsi = {
static void virtio_ccw_rng_instance_init(Object *obj)
{
VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_RNG);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng, NULL);
@@ -1209,7 +1210,7 @@ static int virtio_ccw_busdev_init(DeviceState *dev)
VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
- virtio_ccw_bus_new(&_dev->bus, _dev);
+ virtio_ccw_bus_new(&_dev->bus, sizeof(_dev->bus), _dev);
return _info->init(_dev);
}
@@ -1289,14 +1290,15 @@ static const TypeInfo virtual_css_bridge_info = {
/* virtio-ccw-bus */
-static void virtio_ccw_bus_new(VirtioBusState *bus, VirtioCcwDevice *dev)
+static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
+ VirtioCcwDevice *dev)
{
DeviceState *qdev = DEVICE(dev);
BusState *qbus;
char virtio_bus_name[] = "virtio-bus";
- qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_CCW_BUS, qdev,
- virtio_bus_name);
+ qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_CCW_BUS,
+ qdev, virtio_bus_name);
qbus = BUS(bus);
qbus->allow_hotplug = 1;
}
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
index d7ec1736c0..99bf8ec446 100644
--- a/hw/scsi/esp-pci.c
+++ b/hw/scsi/esp-pci.c
@@ -363,7 +363,7 @@ static int esp_pci_scsi_init(PCIDevice *dev)
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->io);
s->irq = dev->irq[0];
- scsi_bus_new(&s->bus, d, &esp_pci_scsi_info, NULL);
+ scsi_bus_new(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info, NULL);
if (!d->hotplugged) {
scsi_bus_legacy_handle_cmdline(&s->bus, &err);
if (err != NULL) {
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 101e957d4d..2d150bfe48 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -688,7 +688,7 @@ static void sysbus_esp_realize(DeviceState *dev, Error **errp)
qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
- scsi_bus_new(&s->bus, dev, &esp_scsi_info, NULL);
+ scsi_bus_new(&s->bus, sizeof(s->bus), dev, &esp_scsi_info, NULL);
scsi_bus_legacy_handle_cmdline(&s->bus, &err);
if (err != NULL) {
error_propagate(errp, err);
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 611f2aa1b2..0c36842729 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -2117,7 +2117,7 @@ static int lsi_scsi_init(PCIDevice *dev)
pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io);
QTAILQ_INIT(&s->queue);
- scsi_bus_new(&s->bus, d, &lsi_scsi_info, NULL);
+ scsi_bus_new(&s->bus, sizeof(s->bus), d, &lsi_scsi_info, NULL);
if (!d->hotplugged) {
scsi_bus_legacy_handle_cmdline(&s->bus, &err);
if (err != NULL) {
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index a6d5285911..09b51b387b 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2171,7 +2171,8 @@ static int megasas_scsi_init(PCIDevice *dev)
s->frames[i].state = s;
}
- scsi_bus_new(&s->bus, DEVICE(dev), &megasas_scsi_info, NULL);
+ scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
+ &megasas_scsi_info, NULL);
if (!d->hotplugged) {
scsi_bus_legacy_handle_cmdline(&s->bus, &err);
if (err != NULL) {
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index fbf9173fb4..5cd6137046 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -72,10 +72,10 @@ static void scsi_device_unit_attention_reported(SCSIDevice *s)
}
/* Create a scsi bus, and attach devices to it. */
-void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info,
- const char *bus_name)
+void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
+ const SCSIBusInfo *info, const char *bus_name)
{
- qbus_create_inplace(&bus->qbus, TYPE_SCSI_BUS, host, bus_name);
+ qbus_create_inplace(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
bus->busnr = next_scsi_bus++;
bus->info = info;
bus->qbus.allow_hotplug = 1;
diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index e9090e5c72..b2fcd4b3e3 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -1020,7 +1020,8 @@ static int spapr_vscsi_init(VIOsPAPRDevice *dev)
dev->crq.SendFunc = vscsi_do_crq;
- scsi_bus_new(&s->bus, &dev->qdev, &vscsi_scsi_info, NULL);
+ scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
+ &vscsi_scsi_info, NULL);
if (!dev->qdev.hotplugged) {
scsi_bus_legacy_handle_cmdline(&s->bus, &err);
if (err != NULL) {
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 05da56bd24..3bd690d128 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -627,7 +627,8 @@ static int virtio_scsi_device_init(VirtIODevice *vdev)
return ret;
}
- scsi_bus_new(&s->bus, qdev, &virtio_scsi_scsi_info, vdev->bus_name);
+ scsi_bus_new(&s->bus, sizeof(s->bus), qdev,
+ &virtio_scsi_scsi_info, vdev->bus_name);
if (!qdev->hotplugged) {
scsi_bus_legacy_handle_cmdline(&s->bus, &err);
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index d42b35941b..819d671ba2 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1088,7 +1088,8 @@ pvscsi_init(PCIDevice *pci_dev)
return -ENOMEM;
}
- scsi_bus_new(&s->bus, &pci_dev->qdev, &pvscsi_scsi_info, NULL);
+ scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
+ &pvscsi_scsi_info, NULL);
pvscsi_reset_state(s);
return 0;
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index 98b3408f47..7b1de85835 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -356,7 +356,6 @@ static QEMUMachine r2d_machine = {
.name = "r2d",
.desc = "r2d-plus board",
.init = r2d_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void r2d_machine_init(void)
diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index 84dd666bd5..1ff37f54a0 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -96,7 +96,6 @@ static QEMUMachine shix_machine = {
.desc = "shix card",
.init = shix_init,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void shix_machine_init(void)
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index 5ef282fcda..390f3e4bda 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -216,7 +216,6 @@ static QEMUMachine leon3_generic_machine = {
.name = "leon3_generic",
.desc = "Leon-3 generic",
.init = leon3_generic_hw_init,
- DEFAULT_MACHINE_OPTIONS,
};
static void leon3_machine_init(void)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 36ef36f5fe..a0d366cbbc 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -996,7 +996,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
args->ram_size);
nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, args->kernel_cmdline,
- args->boot_device, args->ram_size, kernel_size, graphic_width,
+ args->boot_order, args->ram_size, kernel_size, graphic_width,
graphic_height, graphic_depth, hwdef->nvram_machine_id,
"Sun4m");
@@ -1027,7 +1027,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
}
fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
- fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, args->boot_device[0]);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, args->boot_order[0]);
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}
@@ -1348,7 +1348,7 @@ static QEMUMachine ss5_machine = {
.init = ss5_init,
.block_default_type = IF_SCSI,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static QEMUMachine ss10_machine = {
@@ -1357,7 +1357,7 @@ static QEMUMachine ss10_machine = {
.init = ss10_init,
.block_default_type = IF_SCSI,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static QEMUMachine ss600mp_machine = {
@@ -1366,7 +1366,7 @@ static QEMUMachine ss600mp_machine = {
.init = ss600mp_init,
.block_default_type = IF_SCSI,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static QEMUMachine ss20_machine = {
@@ -1375,7 +1375,7 @@ static QEMUMachine ss20_machine = {
.init = ss20_init,
.block_default_type = IF_SCSI,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static QEMUMachine voyager_machine = {
@@ -1383,7 +1383,7 @@ static QEMUMachine voyager_machine = {
.desc = "Sun4m platform, SPARCstation Voyager",
.init = vger_init,
.block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static QEMUMachine ss_lx_machine = {
@@ -1391,7 +1391,7 @@ static QEMUMachine ss_lx_machine = {
.desc = "Sun4m platform, SPARCstation LX",
.init = ss_lx_init,
.block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static QEMUMachine ss4_machine = {
@@ -1399,7 +1399,7 @@ static QEMUMachine ss4_machine = {
.desc = "Sun4m platform, SPARCstation 4",
.init = ss4_init,
.block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static QEMUMachine scls_machine = {
@@ -1407,7 +1407,7 @@ static QEMUMachine scls_machine = {
.desc = "Sun4m platform, SPARCClassic",
.init = scls_init,
.block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static QEMUMachine sbook_machine = {
@@ -1415,7 +1415,7 @@ static QEMUMachine sbook_machine = {
.desc = "Sun4m platform, SPARCbook",
.init = sbook_init,
.block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static void sun4m_register_types(void)
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 9da083310c..6f271d9cfc 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -881,7 +881,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
&kernel_addr, &kernel_entry);
sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", args->ram_size,
- args->boot_device,
+ args->boot_order,
kernel_addr, kernel_size,
args->kernel_cmdline,
initrd_addr, initrd_size,
@@ -906,7 +906,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
}
fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
- fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, args->boot_device[0]);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, args->boot_order[0]);
fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height);
@@ -969,7 +969,7 @@ static QEMUMachine sun4u_machine = {
.init = sun4u_init,
.max_cpus = 1, // XXX for now
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static QEMUMachine sun4v_machine = {
@@ -977,7 +977,7 @@ static QEMUMachine sun4v_machine = {
.desc = "Sun4v platform",
.init = sun4v_init,
.max_cpus = 1, // XXX for now
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static QEMUMachine niagara_machine = {
@@ -985,7 +985,7 @@ static QEMUMachine niagara_machine = {
.desc = "Sun4v platform, Niagara",
.init = niagara_init,
.max_cpus = 1, // XXX for now
- DEFAULT_MACHINE_OPTIONS,
+ .default_boot_order = "c",
};
static void sun4u_register_types(void)
diff --git a/hw/timer/exynos4210_rtc.c b/hw/timer/exynos4210_rtc.c
index 3f2c8c5578..026f81a2e3 100644
--- a/hw/timer/exynos4210_rtc.c
+++ b/hw/timer/exynos4210_rtc.c
@@ -67,7 +67,7 @@
#define CURTICNT 0x0090
#define TICK_TIMER_ENABLE 0x0100
-#define TICNT_THRESHHOLD 2
+#define TICNT_THRESHOLD 2
#define RTC_ENABLE 0x0001
@@ -429,7 +429,7 @@ static void exynos4210_rtc_write(void *opaque, hwaddr offset,
s->reg_rtccon = value;
break;
case TICCNT:
- if (value > TICNT_THRESHHOLD) {
+ if (value > TICNT_THRESHOLD) {
s->reg_ticcnt = value;
} else {
fprintf(stderr,
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index 5ff0dc9a07..a9000617b4 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -128,7 +128,6 @@ static QEMUMachine puv3_machine = {
.desc = "PKUnity Version-3 based on UniCore32",
.init = puv3_init,
.is_default = 1,
- DEFAULT_MACHINE_OPTIONS,
};
static void puv3_machine_init(void)
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index f83d1de6cd..82ca6a13e8 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -67,9 +67,10 @@ const VMStateDescription vmstate_usb_device = {
}
};
-void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host)
+void usb_bus_new(USBBus *bus, size_t bus_size,
+ USBBusOps *ops, DeviceState *host)
{
- qbus_create_inplace(&bus->qbus, TYPE_USB_BUS, host, NULL);
+ qbus_create_inplace(bus, bus_size, TYPE_USB_BUS, host, NULL);
bus->ops = ops;
bus->busnr = next_usb_bus++;
bus->qbus.allow_hotplug = 1; /* Yes, we can */
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 05948ca9a4..31960c28a8 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -403,7 +403,7 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
p->ep->halted = false;
}
- if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) {
+ if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline || p->stream) {
usb_process_one(p);
if (p->status == USB_RET_ASYNC) {
/* hcd drivers cannot handle async for isoc */
@@ -420,7 +420,8 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
* When pipelining is enabled usb-devices must always return async,
* otherwise packets can complete out of order!
*/
- assert(!p->ep->pipeline || QTAILQ_EMPTY(&p->ep->queue));
+ assert(p->stream || !p->ep->pipeline ||
+ QTAILQ_EMPTY(&p->ep->queue));
if (p->status != USB_RET_NAK) {
usb_packet_set_state(p, USB_PACKET_COMPLETE);
}
@@ -434,7 +435,7 @@ void usb_packet_complete_one(USBDevice *dev, USBPacket *p)
{
USBEndpoint *ep = p->ep;
- assert(QTAILQ_FIRST(&ep->queue) == p);
+ assert(p->stream || QTAILQ_FIRST(&ep->queue) == p);
assert(p->status != USB_RET_ASYNC && p->status != USB_RET_NAK);
if (p->status != USB_RET_SUCCESS ||
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index 66c63317d6..59567200ae 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -658,7 +658,7 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
uc->product_desc = "QEMU USB Tablet";
dc->vmsd = &vmstate_usb_ptr;
dc->props = usb_tablet_properties;
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo usb_tablet_info = {
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index e865a98751..58647b4859 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -33,7 +33,6 @@ typedef struct USBHubPort {
USBPort port;
uint16_t wPortStatus;
uint16_t wPortChange;
- uint16_t wPortChange_reported;
} USBHubPort;
typedef struct USBHubState {
@@ -468,13 +467,11 @@ static void usb_hub_handle_data(USBDevice *dev, USBPacket *p)
status = 0;
for(i = 0; i < NUM_PORTS; i++) {
port = &s->ports[i];
- if (port->wPortChange &&
- port->wPortChange_reported != port->wPortChange) {
+ if (port->wPortChange)
status |= (1 << (i + 1));
- }
- port->wPortChange_reported = port->wPortChange;
}
if (status != 0) {
+ trace_usb_hub_status_report(s->dev.addr, status);
for(i = 0; i < n; i++) {
buf[i] = status >> (8 * i);
}
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 2233c548fa..8c7a61ebe1 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1309,7 +1309,8 @@ static int ccid_initfn(USBDevice *dev)
usb_desc_create_serial(dev);
usb_desc_init(dev);
- qbus_create_inplace(&s->bus.qbus, TYPE_CCID_BUS, &dev->qdev, NULL);
+ qbus_create_inplace(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev),
+ NULL);
s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
s->bus.qbus.allow_hotplug = 1;
s->card = NULL;
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index a8dc2fa960..1d81ac2a6b 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -618,7 +618,8 @@ static int usb_msd_initfn_storage(USBDevice *dev)
usb_desc_create_serial(dev);
usb_desc_init(dev);
- scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_storage, NULL);
+ scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
+ &usb_msd_scsi_info_storage, NULL);
scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable,
s->conf.bootindex, dev->serial,
&err);
@@ -646,7 +647,8 @@ static int usb_msd_initfn_bot(USBDevice *dev)
usb_desc_create_serial(dev);
usb_desc_init(dev);
- scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_bot, NULL);
+ scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
+ &usb_msd_scsi_info_bot, NULL);
s->bus.qbus.allow_hotplug = 0;
usb_msd_handle_reset(dev);
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 63ad12ea6b..70ed2d1dbd 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -113,6 +113,9 @@ struct UASDevice {
QTAILQ_HEAD(, UASStatus) results;
QTAILQ_HEAD(, UASRequest) requests;
+ /* properties */
+ uint32_t requestlog;
+
/* usb 2.0 only */
USBPacket *status2;
UASRequest *datain2;
@@ -692,9 +695,9 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui)
req->req = scsi_req_new(req->dev, req->tag,
usb_uas_get_lun(req->lun),
ui->command.cdb, req);
-#if 1
- scsi_req_print(req->req);
-#endif
+ if (uas->requestlog) {
+ scsi_req_print(req->req);
+ }
len = scsi_req_enqueue(req->req);
if (len) {
req->data_size = len;
@@ -888,7 +891,8 @@ static int usb_uas_init(USBDevice *dev)
QTAILQ_INIT(&uas->requests);
uas->status_bh = qemu_bh_new(usb_uas_send_status_bh, uas);
- scsi_bus_new(&uas->bus, &uas->dev.qdev, &usb_uas_scsi_info, NULL);
+ scsi_bus_new(&uas->bus, sizeof(uas->bus), DEVICE(dev),
+ &usb_uas_scsi_info, NULL);
return 0;
}
@@ -902,6 +906,11 @@ static const VMStateDescription vmstate_usb_uas = {
}
};
+static Property uas_properties[] = {
+ DEFINE_PROP_UINT32("log-scsi-req", UASDevice, requestlog, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void usb_uas_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -919,6 +928,7 @@ static void usb_uas_class_initfn(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->fw_name = "storage";
dc->vmsd = &vmstate_usb_uas;
+ dc->props = uas_properties;
}
static const TypeInfo uas_info = {
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index e5523d54e0..137e200202 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2520,7 +2520,7 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
return;
}
- usb_bus_new(&s->bus, &ehci_bus_ops, dev);
+ usb_bus_new(&s->bus, sizeof(s->bus), &ehci_bus_ops, dev);
for (i = 0; i < s->portnr; i++) {
usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops,
USB_SPEED_MASK_HIGH);
diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c
index f91aa5580b..66bc61ae1e 100644
--- a/hw/usb/hcd-musb.c
+++ b/hw/usb/hcd-musb.c
@@ -383,7 +383,7 @@ struct MUSBState *musb_init(DeviceState *parent_device, int gpio_base)
musb_reset(s);
- usb_bus_new(&s->bus, &musb_bus_ops, parent_device);
+ usb_bus_new(&s->bus, sizeof(s->bus), &musb_bus_ops, parent_device);
usb_register_port(&s->bus, &s->port, s, 0, &musb_port_ops,
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 39a25a72e1..35f0878409 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1881,7 +1881,7 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
return -1;
}
} else {
- usb_bus_new(&ohci->bus, &ohci_bus_ops, dev);
+ usb_bus_new(&ohci->bus, sizeof(ohci->bus), &ohci_bus_ops, dev);
for (i = 0; i < num_ports; i++) {
usb_register_port(&ohci->bus, &ohci->rhport[i].port,
ohci, i, &ohci_port_ops,
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 578b949c92..becc7faec1 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1254,7 +1254,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
return -1;
}
} else {
- usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev);
+ usb_bus_new(&s->bus, sizeof(s->bus), &uhci_bus_ops, DEVICE(dev));
for (i = 0; i < NB_PORTS; i++) {
usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index be6b86e2ba..f02231dc87 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -355,6 +355,7 @@ typedef struct XHCITransfer {
unsigned int streamid;
bool in_xfer;
bool iso_xfer;
+ bool timed_xfer;
unsigned int trb_count;
unsigned int trb_alloced;
@@ -586,6 +587,14 @@ static const char *TRBCCode_names[] = {
[CC_SPLIT_TRANSACTION_ERROR] = "CC_SPLIT_TRANSACTION_ERROR",
};
+static const char *ep_state_names[] = {
+ [EP_DISABLED] = "disabled",
+ [EP_RUNNING] = "running",
+ [EP_HALTED] = "halted",
+ [EP_STOPPED] = "stopped",
+ [EP_ERROR] = "error",
+};
+
static const char *lookup_name(uint32_t index, const char **list, uint32_t llen)
{
if (index >= llen || list[index] == NULL) {
@@ -606,6 +615,12 @@ static const char *event_name(XHCIEvent *event)
ARRAY_SIZE(TRBCCode_names));
}
+static const char *ep_state_name(uint32_t state)
+{
+ return lookup_name(state, ep_state_names,
+ ARRAY_SIZE(ep_state_names));
+}
+
static uint64_t xhci_mfindex_get(XHCIState *xhci)
{
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -1164,8 +1179,6 @@ static XHCIStreamContext *xhci_find_stream(XHCIEPContext *epctx,
if (sctx->sct == -1) {
xhci_dma_read_u32s(epctx->xhci, sctx->pctx, ctx, sizeof(ctx));
- fprintf(stderr, "%s: init sctx #%d @ " DMA_ADDR_FMT ": %08x %08x\n",
- __func__, streamid, sctx->pctx, ctx[0], ctx[1]);
sct = (ctx[0] >> 1) & 0x07;
if (epctx->lsa && sct != 1) {
*cc_error = CC_INVALID_STREAM_TYPE_ERROR;
@@ -1205,6 +1218,11 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
}
xhci_dma_write_u32s(xhci, epctx->pctx, ctx, sizeof(ctx));
+ if (epctx->state != state) {
+ trace_usb_xhci_ep_state(epctx->slotid, epctx->epid,
+ ep_state_name(epctx->state),
+ ep_state_name(state));
+ }
epctx->state = state;
}
@@ -1257,7 +1275,7 @@ static void xhci_init_epctx(XHCIEPContext *epctx,
epctx->ring.ccs = ctx[2] & 1;
}
- epctx->interval = 1 << (ctx[0] >> 16) & 0xff;
+ epctx->interval = 1 << ((ctx[0] >> 16) & 0xff);
}
static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
@@ -1803,6 +1821,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
xfer->in_xfer = bmRequestType & USB_DIR_IN;
xfer->iso_xfer = false;
+ xfer->timed_xfer = false;
if (xhci_setup_packet(xfer) < 0) {
return -1;
@@ -1818,6 +1837,17 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
return 0;
}
+static void xhci_calc_intr_kick(XHCIState *xhci, XHCITransfer *xfer,
+ XHCIEPContext *epctx, uint64_t mfindex)
+{
+ uint64_t asap = ((mfindex + epctx->interval - 1) &
+ ~(epctx->interval-1));
+ uint64_t kick = epctx->mfindex_last + epctx->interval;
+
+ assert(epctx->interval != 0);
+ xfer->mfindex_kick = MAX(asap, kick);
+}
+
static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
XHCIEPContext *epctx, uint64_t mfindex)
{
@@ -1840,8 +1870,8 @@ static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
}
}
-static void xhci_check_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
- XHCIEPContext *epctx, uint64_t mfindex)
+static void xhci_check_intr_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
+ XHCIEPContext *epctx, uint64_t mfindex)
{
if (xfer->mfindex_kick > mfindex) {
timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
@@ -1866,18 +1896,30 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
switch(epctx->type) {
case ET_INTR_OUT:
case ET_INTR_IN:
+ xfer->pkts = 0;
+ xfer->iso_xfer = false;
+ xfer->timed_xfer = true;
+ mfindex = xhci_mfindex_get(xhci);
+ xhci_calc_intr_kick(xhci, xfer, epctx, mfindex);
+ xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex);
+ if (xfer->running_retry) {
+ return -1;
+ }
+ break;
case ET_BULK_OUT:
case ET_BULK_IN:
xfer->pkts = 0;
xfer->iso_xfer = false;
+ xfer->timed_xfer = false;
break;
case ET_ISO_OUT:
case ET_ISO_IN:
xfer->pkts = 1;
xfer->iso_xfer = true;
+ xfer->timed_xfer = true;
mfindex = xhci_mfindex_get(xhci);
xhci_calc_iso_kick(xhci, xfer, epctx, mfindex);
- xhci_check_iso_kick(xhci, xfer, epctx, mfindex);
+ xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex);
if (xfer->running_retry) {
return -1;
}
@@ -1938,13 +1980,18 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
trace_usb_xhci_xfer_retry(xfer);
assert(xfer->running_retry);
- if (xfer->iso_xfer) {
- /* retry delayed iso transfer */
+ if (xfer->timed_xfer) {
+ /* time to kick the transfer? */
mfindex = xhci_mfindex_get(xhci);
- xhci_check_iso_kick(xhci, xfer, epctx, mfindex);
+ xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex);
if (xfer->running_retry) {
return;
}
+ xfer->timed_xfer = 0;
+ xfer->running_retry = 1;
+ }
+ if (xfer->iso_xfer) {
+ /* retry iso transfer */
if (xhci_setup_packet(xfer) < 0) {
return;
}
@@ -2030,7 +2077,7 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;
ep = xfer->packet.ep;
} else {
- if (!xfer->iso_xfer) {
+ if (!xfer->timed_xfer) {
fprintf(stderr, "xhci: error firing data transfer\n");
}
}
@@ -2076,6 +2123,7 @@ static TRBCCode xhci_disable_slot(XHCIState *xhci, unsigned int slotid)
xhci->slots[slotid-1].enabled = 0;
xhci->slots[slotid-1].addressed = 0;
+ xhci->slots[slotid-1].uport = NULL;
return CC_SUCCESS;
}
@@ -2118,7 +2166,6 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
int i;
TRBCCode res;
- trace_usb_xhci_slot_address(slotid);
assert(slotid >= 1 && slotid <= xhci->numslots);
dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);
@@ -2151,6 +2198,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
fprintf(stderr, "xhci: port not found\n");
return CC_TRB_ERROR;
}
+ trace_usb_xhci_slot_address(slotid, uport->path);
dev = uport->dev;
if (!dev) {
@@ -3309,7 +3357,7 @@ static void usb_xhci_init(XHCIState *xhci)
usbports = MAX(xhci->numports_2, xhci->numports_3);
xhci->numports = xhci->numports_2 + xhci->numports_3;
- usb_bus_new(&xhci->bus, &xhci_bus_ops, dev);
+ usb_bus_new(&xhci->bus, sizeof(xhci->bus), &xhci_bus_ops, dev);
for (i = 0; i < usbports; i++) {
speedmask = 0;
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 4bd29533f3..29cf284d12 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -89,7 +89,8 @@ typedef struct {
VirtioBusState bus;
} VirtIOMMIOProxy;
-static void virtio_mmio_bus_new(VirtioBusState *bus, VirtIOMMIOProxy *dev);
+static void virtio_mmio_bus_new(VirtioBusState *bus, size_t bus_size,
+ VirtIOMMIOProxy *dev);
static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
{
@@ -360,7 +361,7 @@ static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
SysBusDevice *sbd = SYS_BUS_DEVICE(d);
- virtio_mmio_bus_new(&proxy->bus, proxy);
+ virtio_mmio_bus_new(&proxy->bus, sizeof(proxy->bus), proxy);
sysbus_init_irq(sbd, &proxy->irq);
memory_region_init_io(&proxy->iomem, OBJECT(d), &virtio_mem_ops, proxy,
TYPE_VIRTIO_MMIO, 0x200);
@@ -385,12 +386,13 @@ static const TypeInfo virtio_mmio_info = {
/* virtio-mmio-bus. */
-static void virtio_mmio_bus_new(VirtioBusState *bus, VirtIOMMIOProxy *dev)
+static void virtio_mmio_bus_new(VirtioBusState *bus, size_t bus_size,
+ VirtIOMMIOProxy *dev)
{
DeviceState *qdev = DEVICE(dev);
BusState *qbus;
- qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_MMIO_BUS, qdev, NULL);
+ qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_MMIO_BUS, qdev, NULL);
qbus = BUS(bus);
qbus->allow_hotplug = 0;
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index f2c489b66c..4825802598 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -92,7 +92,8 @@
/* HACK for virtio to determine if it's running a big endian guest */
bool virtio_is_big_endian(void);
-static void virtio_pci_bus_new(VirtioBusState *bus, VirtIOPCIProxy *dev);
+static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
+ VirtIOPCIProxy *dev);
/* virtio device */
/* DeviceState to VirtIOPCIProxy. For use off data-path. TODO: use QOM. */
@@ -799,8 +800,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
break;
}
- r = virtio_pci_set_guest_notifier(d, n, assign,
- kvm_msi_via_irqfd_enabled());
+ r = virtio_pci_set_guest_notifier(d, n, assign, with_irqfd);
if (r < 0) {
goto assign_error;
}
@@ -918,7 +918,7 @@ static void virtio_9p_pci_class_init(ObjectClass *klass, void *data)
static void virtio_9p_pci_instance_init(Object *obj)
{
V9fsPCIState *dev = VIRTIO_9P_PCI(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_9P);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_9P);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -986,7 +986,7 @@ static int virtio_pci_init(PCIDevice *pci_dev)
{
VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev);
VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
- virtio_pci_bus_new(&dev->bus, dev);
+ virtio_pci_bus_new(&dev->bus, sizeof(dev->bus), dev);
if (k->init != NULL) {
return k->init(dev);
}
@@ -1078,7 +1078,7 @@ static void virtio_blk_pci_class_init(ObjectClass *klass, void *data)
static void virtio_blk_pci_instance_init(Object *obj)
{
VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BLK);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -1148,7 +1148,7 @@ static void virtio_scsi_pci_class_init(ObjectClass *klass, void *data)
static void virtio_scsi_pci_instance_init(Object *obj)
{
VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SCSI);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -1205,7 +1205,7 @@ static void vhost_scsi_pci_class_init(ObjectClass *klass, void *data)
static void vhost_scsi_pci_instance_init(Object *obj)
{
VHostSCSIPCI *dev = VHOST_SCSI_PCI(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VHOST_SCSI);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -1286,7 +1286,7 @@ static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data)
static void virtio_balloon_pci_instance_init(Object *obj)
{
VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BALLOON);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_property_add(obj, "guest-stats", "guest statistics",
@@ -1372,7 +1372,7 @@ static void virtio_serial_pci_class_init(ObjectClass *klass, void *data)
static void virtio_serial_pci_instance_init(Object *obj)
{
VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SERIAL);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -1431,7 +1431,7 @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
static void virtio_net_pci_instance_init(Object *obj)
{
VirtIONetPCI *dev = VIRTIO_NET_PCI(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_NET);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
}
@@ -1487,7 +1487,7 @@ static void virtio_rng_pci_class_init(ObjectClass *klass, void *data)
static void virtio_rng_initfn(Object *obj)
{
VirtIORngPCI *dev = VIRTIO_RNG_PCI(obj);
- object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_RNG);
+ object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng, NULL);
@@ -1504,13 +1504,14 @@ static const TypeInfo virtio_rng_pci_info = {
/* virtio-pci-bus */
-static void virtio_pci_bus_new(VirtioBusState *bus, VirtIOPCIProxy *dev)
+static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
+ VirtIOPCIProxy *dev)
{
DeviceState *qdev = DEVICE(dev);
BusState *qbus;
char virtio_bus_name[] = "virtio-bus";
- qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_PCI_BUS, qdev,
+ qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_PCI_BUS, qdev,
virtio_bus_name);
qbus = BUS(bus);
qbus->allow_hotplug = 1;
diff --git a/hw/xtensa/xtensa_lx60.c b/hw/xtensa/xtensa_lx60.c
index 1138666ca5..22e124d9ec 100644
--- a/hw/xtensa/xtensa_lx60.c
+++ b/hw/xtensa/xtensa_lx60.c
@@ -297,7 +297,6 @@ static QEMUMachine xtensa_lx60_machine = {
.desc = "lx60 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
.init = xtensa_lx60_init,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine xtensa_lx200_machine = {
@@ -305,7 +304,6 @@ static QEMUMachine xtensa_lx200_machine = {
.desc = "lx200 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
.init = xtensa_lx200_init,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
};
static void xtensa_lx_machines_init(void)
diff --git a/hw/xtensa/xtensa_sim.c b/hw/xtensa/xtensa_sim.c
index ea91162b63..1192ce7134 100644
--- a/hw/xtensa/xtensa_sim.c
+++ b/hw/xtensa/xtensa_sim.c
@@ -108,7 +108,6 @@ static QEMUMachine xtensa_sim_machine = {
.is_default = true,
.init = xtensa_sim_init,
.max_cpus = 4,
- DEFAULT_MACHINE_OPTIONS,
};
static void xtensa_sim_machine_init(void)
diff --git a/include/block/block.h b/include/block/block.h
index 742fce5f7f..e6b391ce88 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -413,6 +413,7 @@ typedef enum {
BLKDBG_REFTABLE_LOAD,
BLKDBG_REFTABLE_GROW,
+ BLKDBG_REFTABLE_UPDATE,
BLKDBG_REFBLOCK_LOAD,
BLKDBG_REFBLOCK_UPDATE,
diff --git a/include/hw/boards.h b/include/hw/boards.h
index fb7c6f1243..5a7ae9f59b 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -6,12 +6,9 @@
#include "sysemu/blockdev.h"
#include "hw/qdev.h"
-#define DEFAULT_MACHINE_OPTIONS \
- .boot_order = "cad"
-
typedef struct QEMUMachineInitArgs {
ram_addr_t ram_size;
- const char *boot_device;
+ const char *boot_order;
const char *kernel_filename;
const char *kernel_cmdline;
const char *initrd_filename;
@@ -42,7 +39,7 @@ typedef struct QEMUMachine {
no_sdcard:1;
int is_default;
const char *default_machine_opts;
- const char *boot_order;
+ const char *default_boot_order;
GlobalProperty *compat_props;
struct QEMUMachine *next;
const char *hw_version;
diff --git a/include/hw/bt.h b/include/hw/bt.h
index 830af94735..3f365bcbcb 100644
--- a/include/hw/bt.h
+++ b/include/hw/bt.h
@@ -640,8 +640,8 @@ typedef struct {
#define OCF_SETUP_SYNC_CONN 0x0028
typedef struct {
uint16_t handle;
- uint32_t tx_bandwith;
- uint32_t rx_bandwith;
+ uint32_t tx_bandwidth;
+ uint32_t rx_bandwidth;
uint16_t max_latency;
uint16_t voice_setting;
uint8_t retrans_effort;
@@ -652,8 +652,8 @@ typedef struct {
#define OCF_ACCEPT_SYNC_CONN_REQ 0x0029
typedef struct {
bdaddr_t bdaddr;
- uint32_t tx_bandwith;
- uint32_t rx_bandwith;
+ uint32_t tx_bandwidth;
+ uint32_t rx_bandwidth;
uint16_t max_latency;
uint16_t voice_setting;
uint8_t retrans_effort;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index f79d4782c1..7fb04d8cd8 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -106,7 +106,16 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
#define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start"
#define PCI_HOST_PROP_PCI_HOLE64_END "pci-hole64-end"
#define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size"
-#define DEFAULT_PCI_HOLE64_SIZE (1ULL << 31)
+#define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
+
+static inline uint64_t pci_host_get_hole64_size(uint64_t pci_hole64_size)
+{
+ if (pci_hole64_size == DEFAULT_PCI_HOLE64_SIZE) {
+ return 1ULL << 62;
+ } else {
+ return pci_hole64_size;
+ }
+}
void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start,
uint64_t pci_hole64_size);
@@ -316,4 +325,12 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
.value = stringify(0),\
}
+#define PC_COMMON_MACHINE_OPTIONS \
+ .default_boot_order = "cad"
+
+#define PC_DEFAULT_MACHINE_OPTIONS \
+ PC_COMMON_MACHINE_OPTIONS, \
+ .hot_add_cpu = pc_hot_add_cpu, \
+ .max_cpus = 255
+
#endif
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index 495bcf3a08..fa45a5b094 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -78,7 +78,7 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start);
* @dev: the ISADevice against which these are registered; may be NULL.
* @start: the base I/O port against which the portio->offset is applied.
* @portio: the ports, sorted by offset.
- * @opaque: passed into the old_portio callbacks.
+ * @opaque: passed into the portio callbacks.
* @name: passed into memory_region_init_io.
*/
void isa_register_portio_list(ISADevice *dev, uint16_t start,
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index ccec2bac31..37979aa723 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -348,7 +348,7 @@ typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev,
bool pci_bus_is_express(PCIBus *bus);
bool pci_bus_is_root(PCIBus *bus);
-void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
+void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
const char *name,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io,
@@ -405,6 +405,7 @@ void pci_device_deassert_intx(PCIDevice *dev);
typedef AddressSpace *(*PCIIOMMUFunc)(PCIBus *, void *, int);
+AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque);
static inline void
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 46972f4961..a62f231eb9 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -264,7 +264,7 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id);
typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
-void qbus_create_inplace(void *bus, const char *typename,
+void qbus_create_inplace(void *bus, size_t size, const char *typename,
DeviceState *parent, const char *name);
BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
/* Returns > 0 if either devfn or busfn skip walk somewhere in cursion,
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 87865313eb..1b6651054a 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -152,8 +152,8 @@ struct SCSIBus {
const SCSIBusInfo *info;
};
-void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info,
- const char *bus_name);
+void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
+ const SCSIBusInfo *info, const char *bus_name);
static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
{
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 901b0da8b0..1b8acba6f6 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -496,7 +496,8 @@ struct USBBusOps {
void (*wakeup_endpoint)(USBBus *bus, USBEndpoint *ep, unsigned int stream);
};
-void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host);
+void usb_bus_new(USBBus *bus, size_t bus_size,
+ USBBusOps *ops, DeviceState *host);
USBBus *usb_bus_find(int busnr);
void usb_legacy_register(const char *typename, const char *usbdevice_name,
USBDevice *(*usbdevice_init)(USBBus *bus,
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 1942cc42fe..10fa0e390c 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -48,6 +48,7 @@ typedef enum MonitorEvent {
QEVENT_BALLOON_CHANGE,
QEVENT_SPICE_MIGRATE_COMPLETED,
QEVENT_GUEST_PANICKED,
+ QEVENT_BLOCK_IMAGE_CORRUPTED,
/* Add to 'monitor_event_names' array in monitor.c when
* defining new events here */
diff --git a/include/qemu/option.h b/include/qemu/option.h
index 7a58e477d9..63db4ccb9a 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -46,6 +46,7 @@ typedef struct QEMUOptionParameter {
char* s;
} value;
const char *help;
+ bool assigned;
} QEMUOptionParameter;
diff --git a/include/qom/object.h b/include/qom/object.h
index 9b69065b7a..1a7b71aba5 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -249,7 +249,7 @@ typedef struct InterfaceInfo InterfaceInfo;
* MyClass parent_class;
*
* MyDoSomething parent_do_something;
- * } MyClass;
+ * } DerivedClass;
*
* static void derived_do_something(MyState *obj)
* {
@@ -585,25 +585,27 @@ Object *object_new_with_type(Type type);
/**
* object_initialize_with_type:
- * @obj: A pointer to the memory to be used for the object.
+ * @data: A pointer to the memory to be used for the object.
+ * @size: The maximum size available at @data for the object.
* @type: The type of the object to instantiate.
*
* This function will initialize an object. The memory for the object should
* have already been allocated. The returned object has a reference count of 1,
* and will be finalized when the last reference is dropped.
*/
-void object_initialize_with_type(void *data, Type type);
+void object_initialize_with_type(void *data, size_t size, Type type);
/**
* object_initialize:
* @obj: A pointer to the memory to be used for the object.
+ * @size: The maximum size available at @obj for the object.
* @typename: The name of the type of the object to instantiate.
*
* This function will initialize an object. The memory for the object should
* have already been allocated. The returned object has a reference count of 1,
* and will be finalized when the last reference is dropped.
*/
-void object_initialize(void *obj, const char *typename);
+void object_initialize(void *obj, size_t size, const char *typename);
/**
* object_dynamic_cast:
diff --git a/libcacard/card_7816.c b/libcacard/card_7816.c
index 8d06326da6..c28bb60fe6 100644
--- a/libcacard/card_7816.c
+++ b/libcacard/card_7816.c
@@ -232,7 +232,7 @@ vcard_apdu_set_class(VCardAPDU *apdu) {
case 0xf0:
default:
apdu->a_gen_type =
- (apdu->a_cla == 0xff) ? VCARD_7816_PTS : VCARD_7816_PROPIETARY;
+ (apdu->a_cla == 0xff) ? VCARD_7816_PTS : VCARD_7816_PROPRIETARY;
break;
}
return VCARD7816_STATUS_SUCCESS;
diff --git a/libcacard/card_7816t.h b/libcacard/card_7816t.h
index 9333285d73..8eef0ce42c 100644
--- a/libcacard/card_7816t.h
+++ b/libcacard/card_7816t.h
@@ -43,7 +43,7 @@ typedef enum {
VCARD_7816_ISO,
VCARD_7816_RFU,
VCARD_7816_PTS,
- VCARD_7816_PROPIETARY
+ VCARD_7816_PROPRIETARY
} VCardAPDUType;
diff --git a/linux-headers/asm-powerpc/epapr_hcalls.h b/linux-headers/asm-powerpc/epapr_hcalls.h
index 06f724786a..33b3f89f55 100644
--- a/linux-headers/asm-powerpc/epapr_hcalls.h
+++ b/linux-headers/asm-powerpc/epapr_hcalls.h
@@ -78,7 +78,7 @@
#define EV_SUCCESS 0
#define EV_EPERM 1 /* Operation not permitted */
#define EV_ENOENT 2 /* Entry Not Found */
-#define EV_EIO 3 /* I/O error occured */
+#define EV_EIO 3 /* I/O error occurred */
#define EV_EAGAIN 4 /* The operation had insufficient
* resources to complete and should be
* retried
@@ -89,7 +89,7 @@
#define EV_ENODEV 7 /* No such device */
#define EV_EINVAL 8 /* An argument supplied to the hcall
was out of range or invalid */
-#define EV_INTERNAL 9 /* An internal error occured */
+#define EV_INTERNAL 9 /* An internal error occurred */
#define EV_CONFIG 10 /* A configuration error was detected */
#define EV_INVALID_STATE 11 /* The object is in an invalid state */
#define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */
diff --git a/migration-rdma.c b/migration-rdma.c
index 3d1266f40a..05a155b93d 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -756,7 +756,7 @@ static void qemu_rdma_dump_gid(const char *who, struct rdma_cm_id *id)
* connections (both IPv4 and IPv6) if the destination machine does not have
* a regular infiniband network available for use.
*
- * The only way to gaurantee that an error is thrown for broken kernels is
+ * The only way to guarantee that an error is thrown for broken kernels is
* for the management software to choose a *specific* interface at bind time
* and validate what time of hardware it is.
*
@@ -778,7 +778,7 @@ static void qemu_rdma_dump_gid(const char *who, struct rdma_cm_id *id)
* Infiniband.
*
* If we detect that we have a *pure* RoCE environment, then we can safely
- * thrown an error even if the management sofware has specified '[::]' as the
+ * thrown an error even if the management software has specified '[::]' as the
* bind address.
*
* However, if there is are multiple hetergeneous devices, then we cannot make
@@ -801,7 +801,7 @@ static int qemu_rdma_broken_ipv6_kernel(Error **errp, struct ibv_context *verbs)
* devices (non-ethernet).
*
* If not, then we can safely proceed with the migration.
- * Otherwise, there are no gaurantees until the bug is fixed in linux.
+ * Otherwise, there are no guarantees until the bug is fixed in linux.
*/
if (!verbs) {
int num_devices, x;
@@ -920,9 +920,11 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
ret = rdma_resolve_addr(rdma->cm_id, NULL, e->ai_dst_addr,
RDMA_RESOLVE_TIMEOUT_MS);
if (!ret) {
- ret = qemu_rdma_broken_ipv6_kernel(errp, rdma->cm_id->verbs);
- if (ret) {
- continue;
+ if (e->ai_family == AF_INET6) {
+ ret = qemu_rdma_broken_ipv6_kernel(errp, rdma->cm_id->verbs);
+ if (ret) {
+ continue;
+ }
}
goto route;
}
diff --git a/monitor.c b/monitor.c
index 683babf24a..74f3f1ba60 100644
--- a/monitor.c
+++ b/monitor.c
@@ -506,6 +506,7 @@ static const char *monitor_event_names[] = {
[QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE",
[QEVENT_SPICE_MIGRATE_COMPLETED] = "SPICE_MIGRATE_COMPLETED",
[QEVENT_GUEST_PANICKED] = "GUEST_PANICKED",
+ [QEVENT_BLOCK_IMAGE_CORRUPTED] = "BLOCK_IMAGE_CORRUPTED",
};
QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX)
diff --git a/qmp-commands.hx b/qmp-commands.hx
index bb09e72712..8a8f342eab 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1402,22 +1402,22 @@ Change I/O throttle limits for a block drive.
Arguments:
- "device": device name (json-string)
-- "bps": total throughput limit in bytes per second(json-int)
-- "bps_rd": read throughput limit in bytes per second(json-int)
-- "bps_wr": read throughput limit in bytes per second(json-int)
-- "iops": total I/O operations per second(json-int)
-- "iops_rd": read I/O operations per second(json-int)
-- "iops_wr": write I/O operations per second(json-int)
+- "bps": total throughput limit in bytes per second (json-int)
+- "bps_rd": read throughput limit in bytes per second (json-int)
+- "bps_wr": write throughput limit in bytes per second (json-int)
+- "iops": total I/O operations per second (json-int)
+- "iops_rd": read I/O operations per second (json-int)
+- "iops_wr": write I/O operations per second (json-int)
Example:
-> { "execute": "block_set_io_throttle", "arguments": { "device": "virtio0",
- "bps": "1000000",
- "bps_rd": "0",
- "bps_wr": "0",
- "iops": "0",
- "iops_rd": "0",
- "iops_wr": "0" } }
+ "bps": 1000000,
+ "bps_rd": 0,
+ "bps_wr": 0,
+ "iops": 0,
+ "iops_rd": 0,
+ "iops_wr": 0 } }
<- { "return": {} }
EQMP
@@ -1791,7 +1791,7 @@ Each json-object contain the following:
- "vm-state-size": size of the VM state in bytes (json-int)
- "date-sec": UTC date of the snapshot in seconds (json-int)
- "date-nsec": fractional part in nanoseconds to be used with
- date-sec(json-int)
+ date-sec (json-int)
- "vm-clock-sec": VM clock relative to boot in seconds
(json-int)
- "vm-clock-nsec": fractional part in nanoseconds to be used
diff --git a/qom/object.c b/qom/object.c
index 74fd241a02..e90e3827d9 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -311,7 +311,7 @@ static void object_post_init_with_type(Object *obj, TypeImpl *ti)
}
}
-void object_initialize_with_type(void *data, TypeImpl *type)
+void object_initialize_with_type(void *data, size_t size, TypeImpl *type)
{
Object *obj = data;
@@ -320,6 +320,7 @@ void object_initialize_with_type(void *data, TypeImpl *type)
g_assert(type->instance_size >= sizeof(Object));
g_assert(type->abstract == false);
+ g_assert(size >= type->instance_size);
memset(obj, 0, type->instance_size);
obj->class = type->class;
@@ -329,11 +330,11 @@ void object_initialize_with_type(void *data, TypeImpl *type)
object_post_init_with_type(obj, type);
}
-void object_initialize(void *data, const char *typename)
+void object_initialize(void *data, size_t size, const char *typename)
{
TypeImpl *type = type_get_by_name(typename);
- object_initialize_with_type(data, type);
+ object_initialize_with_type(data, size, type);
}
static inline bool object_property_is_child(ObjectProperty *prop)
@@ -424,7 +425,7 @@ Object *object_new_with_type(Type type)
type_initialize(type);
obj = g_malloc(type->instance_size);
- object_initialize_with_type(obj, type);
+ object_initialize_with_type(obj, type->instance_size, type);
obj->free = g_free;
return obj;
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 5ee46ea1b3..86de9800ea 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -57,12 +57,8 @@ typedef struct %(name)sList
''',
name=name)
-def generate_struct(structname, fieldname, members):
- ret = mcgen('''
-struct %(name)s
-{
-''',
- name=structname)
+def generate_struct_fields(members):
+ ret = ''
for argname, argentry, optional, structured in parse_args(members):
if optional:
@@ -80,6 +76,17 @@ struct %(name)s
''',
c_type=c_type(argentry), c_name=c_var(argname))
+ return ret
+
+def generate_struct(structname, fieldname, members):
+ ret = mcgen('''
+struct %(name)s
+{
+''',
+ name=structname)
+
+ ret += generate_struct_fields(members)
+
if len(fieldname):
fieldname = " " + fieldname
ret += mcgen('''
diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index bf698c1ac5..ecdb0baee4 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -38,7 +38,7 @@ void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
ethaddr[3], ethaddr[4], ethaddr[5]));
/* Check 0.0.0.0/8 invalid source-only addresses */
- if ((ip_addr & htonl(~(0xf << 28))) == 0) {
+ if ((ip_addr & htonl(~(0xfU << 28))) == 0) {
return;
}
@@ -74,7 +74,7 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
DEBUG_ARG("ip = 0x%x", ip_addr);
/* Check 0.0.0.0/8 invalid source-only addresses */
- assert((ip_addr & htonl(~(0xf << 28))) != 0);
+ assert((ip_addr & htonl(~(0xfU << 28))) != 0);
/* If broadcast address */
if (ip_addr == 0xffffffff || ip_addr == broadcast_addr) {
diff --git a/slirp/socket.c b/slirp/socket.c
index 8e8819cf30..25d60e7a89 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -627,7 +627,9 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
addr.sin_port = hport;
if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
+#ifndef _WIN32
(qemu_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) < 0) ||
+#endif
(bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
(listen(s,1) < 0)) {
int tmperrno = errno; /* Don't clobber the real reason we failed */
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 9160ced4fe..4f4a0a97d2 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6715,6 +6715,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
/* setend */
if (((insn >> 9) & 1) != s->bswap_code) {
/* Dynamic endianness switching not implemented. */
+ qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
goto illegal_op;
}
return;
@@ -8740,6 +8741,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
if (insn & (1 << 26)) {
/* Secure monitor call (v6Z) */
+ qemu_log_mask(LOG_UNIMP,
+ "arm: unimplemented secure monitor call\n");
goto illegal_op; /* not implemented. */
} else {
op = (insn >> 20) & 7;
@@ -9779,6 +9782,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
ARCH(6);
if (((insn >> 3) & 1) != s->bswap_code) {
/* Dynamic endianness switching not implemented. */
+ qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
goto illegal_op;
}
break;
diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
index 281d7d50f3..233ab3bf35 100644
--- a/tcg/tci/tcg-target.c
+++ b/tcg/tci/tcg-target.c
@@ -415,13 +415,6 @@ static void tcg_out_i(TCGContext *s, tcg_target_ulong v)
s->code_ptr += sizeof(tcg_target_ulong);
}
-/* Write 64 bit value. */
-static void tcg_out64(TCGContext *s, uint64_t v)
-{
- *(uint64_t *)s->code_ptr = v;
- s->code_ptr += sizeof(v);
-}
-
/* Write opcode. */
static void tcg_out_op_t(TCGContext *s, TCGOpcode op)
{
diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out
index 796c993df2..a94334478e 100644
--- a/tests/qemu-iotests/031.out
+++ b/tests/qemu-iotests/031.out
@@ -54,7 +54,7 @@ header_length 72
Header extension:
magic 0x6803f857
-length 96
+length 144
data <binary>
Header extension:
@@ -68,7 +68,7 @@ No errors were found on the image.
magic 0x514649fb
version 2
-backing_file_offset 0xf8
+backing_file_offset 0x128
backing_file_size 0x17
cluster_bits 16
size 67108864
@@ -92,7 +92,7 @@ data 'host_device'
Header extension:
magic 0x6803f857
-length 96
+length 144
data <binary>
Header extension:
@@ -155,7 +155,7 @@ header_length 104
Header extension:
magic 0x6803f857
-length 96
+length 144
data <binary>
Header extension:
@@ -169,7 +169,7 @@ No errors were found on the image.
magic 0x514649fb
version 3
-backing_file_offset 0x118
+backing_file_offset 0x148
backing_file_size 0x17
cluster_bits 16
size 67108864
@@ -193,7 +193,7 @@ data 'host_device'
Header extension:
magic 0x6803f857
-length 96
+length 144
data <binary>
Header extension:
diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out
index 063ca22d66..55a3e6e441 100644
--- a/tests/qemu-iotests/036.out
+++ b/tests/qemu-iotests/036.out
@@ -46,7 +46,7 @@ header_length 104
Header extension:
magic 0x6803f857
-length 96
+length 144
data <binary>
*** done
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index 5582ed3655..86e989cc6a 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -85,7 +85,6 @@ QEMU_PROG: -drive if=virtio: Device 'virtio-blk-pci' could not be initialized
Testing: -drive if=scsi
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
-QEMU_PROG: -drive if=scsi: Device initialization failed.
QEMU_PROG: Device initialization failed.
QEMU_PROG: Initialization of device lsi53c895a failed
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
new file mode 100755
index 0000000000..65bb09f023
--- /dev/null
+++ b/tests/qemu-iotests/060
@@ -0,0 +1,111 @@
+#!/bin/bash
+#
+# Test case for image corruption (overlapping data structures) in qcow2
+#
+# Copyright (C) 2013 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
+
+# This tests qocw2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+rt_offset=65536 # 0x10000 (XXX: just an assumption)
+rb_offset=131072 # 0x20000 (XXX: just an assumption)
+l1_offset=196608 # 0x30000 (XXX: just an assumption)
+l2_offset=262144 # 0x40000 (XXX: just an assumption)
+
+IMGOPTS="compat=1.1"
+
+echo
+echo "=== Testing L2 reference into L1 ==="
+echo
+_make_test_img 64M
+# Link first L1 entry (first L2 table) onto itself
+# (Note the MSb in the L1 entry is set, ensuring the refcount is one - else any
+# later write will result in a COW operation, effectively ruining this attempt
+# on image corruption)
+poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x03\x00\x00"
+_check_test_img
+
+# The corrupt bit should not be set anyway
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# Try to write something, thereby forcing the corrupt bit to be set
+$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
+
+# The corrupt bit must now be set
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# Try to open the image R/W (which should fail)
+$QEMU_IO -c "read 0 512" "$TEST_IMG" 2>&1 | _filter_qemu_io | sed -e "s/can't open device .*$/can't open device/"
+
+# Try to open it RO (which should succeed)
+$QEMU_IO -c "read 0 512" -r "$TEST_IMG" | _filter_qemu_io
+
+# We could now try to fix the image, but this would probably fail (how should an
+# L2 table linked onto the L1 table be fixed?)
+
+echo
+echo "=== Testing cluster data reference into refcount block ==="
+echo
+_make_test_img 64M
+# Allocate L2 table
+truncate -s "$(($l2_offset+65536))" "$TEST_IMG"
+poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x04\x00\x00"
+# Mark cluster as used
+poke_file "$TEST_IMG" "$(($rb_offset+8))" "\x00\x01"
+# Redirect new data cluster onto refcount block
+poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x02\x00\x00"
+_check_test_img
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# Try to fix it
+_check_test_img -r all
+
+# The corrupt bit should be cleared
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# Look if it's really really fixed
+$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
new file mode 100644
index 0000000000..ca4583a4a4
--- /dev/null
+++ b/tests/qemu-iotests/060.out
@@ -0,0 +1,44 @@
+QA output created by 060
+
+=== Testing L2 reference into L1 ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+ERROR cluster 3 refcount=1 reference=3
+
+1 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+incompatible_features 0x0
+qcow2: Preventing invalid write on metadata (overlaps with active L1 table); image marked as corrupt.
+write failed: Input/output error
+incompatible_features 0x2
+qcow2: Image is corrupt; cannot be opened read/write.
+qemu-io: can't open device
+no file open, try 'help open'
+read 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Testing cluster data reference into refcount block ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+ERROR refcount block 0 refcount=2
+ERROR cluster 2 refcount=1 reference=2
+
+2 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+incompatible_features 0x0
+qcow2: Preventing invalid write on metadata (overlaps with refcount block); image marked as corrupt.
+write failed: Input/output error
+incompatible_features 0x2
+Repairing refcount block 0 refcount=2
+The following inconsistencies were found and repaired:
+
+ 0 leaked clusters
+ 1 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+incompatible_features 0x0
+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
+*** done
diff --git a/tests/qemu-iotests/062 b/tests/qemu-iotests/062
new file mode 100755
index 0000000000..0511246dee
--- /dev/null
+++ b/tests/qemu-iotests/062
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# Test case for snapshotting images with unallocated zero clusters in
+# qcow2
+#
+# Copyright (C) 2013 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
+
+# This tests qocw2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+IMGOPTS="compat=1.1"
+IMG_SIZE=64M
+
+echo
+echo "=== Testing snapshotting an image with zero clusters ==="
+echo
+_make_test_img $IMG_SIZE
+# Write some zero clusters
+$QEMU_IO -c "write -z 0 256k" "$TEST_IMG" | _filter_qemu_io
+# Create a snapshot
+$QEMU_IMG snapshot -c foo "$TEST_IMG"
+# Check the image (there shouldn't be any errors or leaks)
+_check_test_img
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/062.out b/tests/qemu-iotests/062.out
new file mode 100644
index 0000000000..442d761959
--- /dev/null
+++ b/tests/qemu-iotests/062.out
@@ -0,0 +1,9 @@
+QA output created by 062
+
+=== Testing snapshotting an image with zero clusters ===
+
+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.
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 43c05d6f5c..b6962421fa 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -57,10 +57,12 @@
048 img auto quick
049 rw auto
050 rw auto backing quick
-#051 rw auto
+051 rw auto
052 rw auto backing
053 rw auto
054 rw auto
055 rw auto
056 rw auto backing
059 rw auto
+060 rw auto
+062 rw auto
diff --git a/tests/test-aio.c b/tests/test-aio.c
index 07a1f61f87..532a1de3f9 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -396,7 +396,7 @@ static void test_timer_schedule(void)
g_assert(!aio_poll(ctx, false));
g_assert_cmpint(data.n, ==, 0);
- sleep(1);
+ g_usleep(1 * G_USEC_PER_SEC);
g_assert_cmpint(data.n, ==, 0);
g_assert(aio_poll(ctx, false));
@@ -729,7 +729,7 @@ static void test_source_timer_schedule(void)
g_assert_cmpint(data.n, ==, 0);
- sleep(1);
+ g_usleep(1 * G_USEC_PER_SEC);
g_assert_cmpint(data.n, ==, 0);
g_assert(g_main_context_iteration(NULL, false));
@@ -739,7 +739,7 @@ static void test_source_timer_schedule(void)
do {
g_assert(g_main_context_iteration(NULL, true));
} while (qemu_clock_get_ns(data.clock_type) <= expiry);
- sleep(1);
+ g_usleep(1 * G_USEC_PER_SEC);
g_main_context_iteration(NULL, false);
g_assert_cmpint(data.n, ==, 2);
diff --git a/trace-events b/trace-events
index aaad3560f4..8285c5a192 100644
--- a/trace-events
+++ b/trace-events
@@ -371,7 +371,7 @@ usb_xhci_port_link(uint32_t port, uint32_t pls) "port %d, pls %d"
usb_xhci_port_notify(uint32_t port, uint32_t pls) "port %d, bits %x"
usb_xhci_slot_enable(uint32_t slotid) "slotid %d"
usb_xhci_slot_disable(uint32_t slotid) "slotid %d"
-usb_xhci_slot_address(uint32_t slotid) "slotid %d"
+usb_xhci_slot_address(uint32_t slotid, const char *port) "slotid %d, port %s"
usb_xhci_slot_configure(uint32_t slotid) "slotid %d"
usb_xhci_slot_evaluate(uint32_t slotid) "slotid %d"
usb_xhci_slot_reset(uint32_t slotid) "slotid %d"
@@ -381,6 +381,7 @@ usb_xhci_ep_set_dequeue(uint32_t slotid, uint32_t epid, uint32_t streamid, uint6
usb_xhci_ep_kick(uint32_t slotid, uint32_t epid, uint32_t streamid) "slotid %d, epid %d, streamid %d"
usb_xhci_ep_stop(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
usb_xhci_ep_reset(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
+usb_xhci_ep_state(uint32_t slotid, uint32_t epid, const char *os, const char *ns) "slotid %d, epid %d, %s -> %s"
usb_xhci_xfer_start(void *xfer, uint32_t slotid, uint32_t epid, uint32_t streamid) "%p: slotid %d, epid %d, streamid %d"
usb_xhci_xfer_async(void *xfer) "%p"
usb_xhci_xfer_nak(void *xfer) "%p"
@@ -410,6 +411,7 @@ usb_hub_set_port_feature(int addr, int nr, const char *f) "dev %d, port %d, feat
usb_hub_clear_port_feature(int addr, int nr, const char *f) "dev %d, port %d, feature %s"
usb_hub_attach(int addr, int nr) "dev %d, port %d"
usb_hub_detach(int addr, int nr) "dev %d, port %d"
+usb_hub_status_report(int addr, int status) "dev %d, status 0x%x"
# hw/usb/dev-uas.c
usb_uas_reset(int addr) "dev %d"
@@ -1181,3 +1183,7 @@ object_class_dynamic_cast_assert(const char *type, const char *target, const cha
# hw/xen/xen_pvdevice.c
xen_pv_mmio_read(uint64_t addr) "WARNING: read from Xen PV Device MMIO space (address %"PRIx64")"
xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (address %"PRIx64")"
+
+# hw/pci/pci_host.c
+pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x -> 0x%x"
+pci_cfg_write(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x <- 0x%x"
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 4ebdc4c33c..e0844a966c 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -275,6 +275,8 @@ int set_option_parameter(QEMUOptionParameter *list, const char *name,
return -1;
}
+ list->assigned = true;
+
return 0;
}
@@ -306,6 +308,8 @@ int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
return -1;
}
+ list->assigned = true;
+
return 0;
}
@@ -397,6 +401,7 @@ QEMUOptionParameter *parse_option_parameters(const char *param,
char value[256];
char *param_delim, *value_delim;
char next_delim;
+ int i;
if (list == NULL) {
return NULL;
@@ -406,6 +411,10 @@ QEMUOptionParameter *parse_option_parameters(const char *param,
dest = allocated = append_option_parameters(NULL, list);
}
+ for (i = 0; dest[i].name; i++) {
+ dest[i].assigned = false;
+ }
+
while (*param) {
// Find parameter name and value in the string
diff --git a/vl.c b/vl.c
index dfbc071eef..b4b119a885 100644
--- a/vl.c
+++ b/vl.c
@@ -4123,7 +4123,7 @@ int main(int argc, char **argv, char **envp)
kernel_cmdline = qemu_opt_get(machine_opts, "append");
if (!boot_order) {
- boot_order = machine->boot_order;
+ boot_order = machine->default_boot_order;
}
opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
if (opts) {
@@ -4311,7 +4311,7 @@ int main(int argc, char **argv, char **envp)
qdev_machine_init();
QEMUMachineInitArgs args = { .ram_size = ram_size,
- .boot_device = boot_order,
+ .boot_order = boot_order,
.kernel_filename = kernel_filename,
.kernel_cmdline = kernel_cmdline,
.initrd_filename = initrd_filename,