diff options
168 files changed, 1489 insertions, 735 deletions
@@ -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), @@ -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; } @@ -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 @@ -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, |