diff options
425 files changed, 3180 insertions, 1078 deletions
diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml index 95dfc39224..7ae0f966f1 100644 --- a/.gitlab-ci.d/crossbuilds.yml +++ b/.gitlab-ci.d/crossbuilds.yml @@ -61,7 +61,7 @@ cross-i686-tci: variables: IMAGE: debian-i686-cross ACCEL: tcg-interpreter - EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user --disable-plugins --disable-kvm + EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,arm-softmmu,arm-linux-user,ppc-softmmu,ppc-linux-user --disable-plugins --disable-kvm # Force tests to run with reduced parallelism, to see whether this # reduces the flakiness of this CI job. The CI # environment by default shows us 8 CPUs and so we diff --git a/MAINTAINERS b/MAINTAINERS index aac7404473..842bac8a7f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3235,8 +3235,6 @@ S: Supported F: qapi/ X: qapi/*.json F: include/qapi/ -X: include/qapi/qmp/ -F: include/qapi/qmp/dispatch.h F: tests/qapi-schema/ F: tests/unit/test-*-visitor.c F: tests/unit/test-qapi-*.c @@ -3260,8 +3258,7 @@ QObject M: Markus Armbruster <armbru@redhat.com> S: Supported F: qobject/ -F: include/qapi/qmp/ -X: include/qapi/qmp/dispatch.h +F: include/qobject/ F: scripts/coccinelle/qobject.cocci F: tests/unit/check-qdict.c F: tests/unit/check-qjson.c diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build index aef80de967..69f4808ac4 100644 --- a/accel/tcg/meson.build +++ b/accel/tcg/meson.build @@ -21,16 +21,13 @@ specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_specific_ss) specific_ss.add(when: ['CONFIG_SYSTEM_ONLY', 'CONFIG_TCG'], if_true: files( 'cputlb.c', 'watchpoint.c', + 'tcg-accel-ops.c', + 'tcg-accel-ops-mttcg.c', + 'tcg-accel-ops-icount.c', + 'tcg-accel-ops-rr.c', )) system_ss.add(when: ['CONFIG_TCG'], if_true: files( 'icount-common.c', 'monitor.c', )) - -tcg_module_ss.add(when: ['CONFIG_SYSTEM_ONLY', 'CONFIG_TCG'], if_true: files( - 'tcg-accel-ops.c', - 'tcg-accel-ops-mttcg.c', - 'tcg-accel-ops-icount.c', - 'tcg-accel-ops-rr.c', -)) diff --git a/audio/audio-hmp-cmds.c b/audio/audio-hmp-cmds.c index c9608b715b..8774c09f18 100644 --- a/audio/audio-hmp-cmds.c +++ b/audio/audio-hmp-cmds.c @@ -27,7 +27,7 @@ #include "monitor/hmp.h" #include "monitor/monitor.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" static QLIST_HEAD (capture_list_head, CaptureState) capture_head; diff --git a/audio/audio.c b/audio/audio.c index 87b4e9b6f2..41ee11aaad 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -32,7 +32,7 @@ #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-audio.h" #include "qapi/qapi-commands-audio.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/cutils.h" #include "qemu/error-report.h" #include "qemu/log.h" diff --git a/authz/listfile.c b/authz/listfile.c index 45a60e987d..d31d9103f7 100644 --- a/authz/listfile.c +++ b/authz/listfile.c @@ -28,8 +28,8 @@ #include "qemu/filemonitor.h" #include "qom/object_interfaces.h" #include "qapi/qapi-visit-authz.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qobject.h" +#include "qobject/qjson.h" +#include "qobject/qobject.h" #include "qapi/qobject-input-visitor.h" diff --git a/backends/cryptodev-hmp-cmds.c b/backends/cryptodev-hmp-cmds.c index 4f7220bb13..01396d227c 100644 --- a/backends/cryptodev-hmp-cmds.c +++ b/backends/cryptodev-hmp-cmds.c @@ -14,7 +14,7 @@ #include "monitor/hmp.h" #include "monitor/monitor.h" #include "qapi/qapi-commands-cryptodev.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" void hmp_info_cryptodev(Monitor *mon, const QDict *qdict) diff --git a/block.c b/block.c index f60606f242..0ece805e41 100644 --- a/block.c +++ b/block.c @@ -36,10 +36,10 @@ #include "qemu/main-loop.h" #include "qemu/module.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qnull.h" +#include "qobject/qstring.h" #include "qapi/qobject-output-visitor.h" #include "qapi/qapi-visit-block-core.h" #include "system/block-backend.h" @@ -1573,6 +1573,10 @@ static void update_flags_from_options(int *flags, QemuOpts *opts) if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) { *flags |= BDRV_O_AUTO_RDONLY; } + + if (!qemu_opt_get_bool_del(opts, BDRV_OPT_ACTIVE, true)) { + *flags |= BDRV_O_INACTIVE; + } } static void update_options_from_flags(QDict *options, int flags) @@ -1800,6 +1804,11 @@ QemuOptsList bdrv_runtime_opts = { .help = "Ignore flush requests", }, { + .name = BDRV_OPT_ACTIVE, + .type = QEMU_OPT_BOOL, + .help = "Node is activated", + }, + { .name = BDRV_OPT_READ_ONLY, .type = QEMU_OPT_BOOL, .help = "Node is opened in read-only mode", @@ -3077,6 +3086,13 @@ bdrv_attach_child_common(BlockDriverState *child_bs, assert(child_class->get_parent_desc); GLOBAL_STATE_CODE(); + if (bdrv_is_inactive(child_bs) && (perm & ~BLK_PERM_CONSISTENT_READ)) { + g_autofree char *perm_names = bdrv_perm_names(perm); + error_setg(errp, "Permission '%s' unavailable on inactive node", + perm_names); + return NULL; + } + new_child = g_new(BdrvChild, 1); *new_child = (BdrvChild) { .bs = NULL, @@ -3183,6 +3199,11 @@ bdrv_attach_child_noperm(BlockDriverState *parent_bs, child_bs->node_name, child_name, parent_bs->node_name); return NULL; } + if (bdrv_is_inactive(child_bs) && !bdrv_is_inactive(parent_bs)) { + error_setg(errp, "Inactive '%s' can't be a %s child of active '%s'", + child_bs->node_name, child_name, parent_bs->node_name); + return NULL; + } bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm); bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL, @@ -6824,6 +6845,10 @@ void bdrv_init_with_whitelist(void) bdrv_init(); } +bool bdrv_is_inactive(BlockDriverState *bs) { + return bs->open_flags & BDRV_O_INACTIVE; +} + int bdrv_activate(BlockDriverState *bs, Error **errp) { BdrvChild *child, *parent; @@ -6955,7 +6980,8 @@ bdrv_has_bds_parent(BlockDriverState *bs, bool only_active) return false; } -static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs) +static int GRAPH_RDLOCK +bdrv_inactivate_recurse(BlockDriverState *bs, bool top_level) { BdrvChild *child, *parent; int ret; @@ -6973,7 +6999,14 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs) return 0; } - assert(!(bs->open_flags & BDRV_O_INACTIVE)); + /* + * Inactivating an already inactive node on user request is harmless, but if + * a child is already inactive before its parent, that's bad. + */ + if (bs->open_flags & BDRV_O_INACTIVE) { + assert(top_level); + return 0; + } /* Inactivate this node */ if (bs->drv->bdrv_inactivate) { @@ -6999,7 +7032,9 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs) return -EPERM; } + bdrv_drained_begin(bs); bs->open_flags |= BDRV_O_INACTIVE; + bdrv_drained_end(bs); /* * Update permissions, they may differ for inactive nodes. @@ -7010,7 +7045,7 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs) /* Recursively inactivate children */ QLIST_FOREACH(child, &bs->children, next) { - ret = bdrv_inactivate_recurse(child->bs); + ret = bdrv_inactivate_recurse(child->bs, false); if (ret < 0) { return ret; } @@ -7019,6 +7054,27 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs) return 0; } +int bdrv_inactivate(BlockDriverState *bs, Error **errp) +{ + int ret; + + GLOBAL_STATE_CODE(); + GRAPH_RDLOCK_GUARD_MAINLOOP(); + + if (bdrv_has_bds_parent(bs, true)) { + error_setg(errp, "Node has active parent node"); + return -EPERM; + } + + ret = bdrv_inactivate_recurse(bs, true); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to inactivate node"); + return ret; + } + + return 0; +} + int bdrv_inactivate_all(void) { BlockDriverState *bs = NULL; @@ -7035,7 +7091,7 @@ int bdrv_inactivate_all(void) if (bdrv_has_bds_parent(bs, false)) { continue; } - ret = bdrv_inactivate_recurse(bs); + ret = bdrv_inactivate_recurse(bs, true); if (ret < 0) { bdrv_next_cleanup(&it); break; diff --git a/block/blkdebug.c b/block/blkdebug.c index f500824608..1c1967f8e0 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -33,9 +33,9 @@ #include "qemu/module.h" #include "qemu/option.h" #include "qapi/qapi-visit-block-core.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qstring.h" #include "qapi/qobject-input-visitor.h" #include "system/qtest.h" diff --git a/block/blkio.c b/block/blkio.c index 003cb63832..5f4fce2b1b 100644 --- a/block/blkio.c +++ b/block/blkio.c @@ -16,7 +16,7 @@ #include "qemu/defer-call.h" #include "qapi/error.h" #include "qemu/error-report.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/module.h" #include "system/block-backend.h" #include "exec/memory.h" /* for ram_block_discard_disable() */ diff --git a/block/blklogwrites.c b/block/blklogwrites.c index ed38a93f21..b0f78c4bc7 100644 --- a/block/blklogwrites.c +++ b/block/blklogwrites.c @@ -14,8 +14,8 @@ #include "qemu/sockets.h" /* for EINPROGRESS on Windows */ #include "block/block-io.h" #include "block/block_int.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qemu/cutils.h" #include "qemu/module.h" #include "qemu/option.h" diff --git a/block/blkverify.c b/block/blkverify.c index 5a9bf674d9..db79a36681 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -12,8 +12,8 @@ #include "qemu/sockets.h" /* for EINPROGRESS on Windows */ #include "block/block-io.h" #include "block/block_int.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qemu/cutils.h" #include "qemu/module.h" #include "qemu/option.h" diff --git a/block/block-backend.c b/block/block-backend.c index c93a7525ad..9288f7e1c6 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -253,7 +253,7 @@ static bool blk_can_inactivate(BlockBackend *blk) * guest. For block job BBs that satisfy this, we can just allow * it. This is the case for mirror job source, which is required * by libvirt non-shared block migration. */ - if (!(blk->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED))) { + if (!(blk->perm & ~BLK_PERM_CONSISTENT_READ)) { return true; } @@ -900,14 +900,24 @@ void blk_remove_bs(BlockBackend *blk) int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp) { ThrottleGroupMember *tgm = &blk->public.throttle_group_member; + uint64_t perm, shared_perm; GLOBAL_STATE_CODE(); bdrv_ref(bs); bdrv_graph_wrlock(); + + if ((bs->open_flags & BDRV_O_INACTIVE) && blk_can_inactivate(blk)) { + blk->disable_perm = true; + perm = 0; + shared_perm = BLK_PERM_ALL; + } else { + perm = blk->perm; + shared_perm = blk->shared_perm; + } + blk->root = bdrv_root_attach_child(bs, "root", &child_root, BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - blk->perm, blk->shared_perm, - blk, errp); + perm, shared_perm, blk, errp); bdrv_graph_wrunlock(); if (blk->root == NULL) { return -EPERM; @@ -1019,6 +1029,10 @@ DeviceState *blk_get_attached_dev(BlockBackend *blk) return blk->dev; } +/* + * The caller is responsible for releasing the value returned + * with g_free() after use. + */ static char *blk_get_attached_dev_id_or_path(BlockBackend *blk, bool want_id) { DeviceState *dev = blk->dev; @@ -1033,15 +1047,15 @@ static char *blk_get_attached_dev_id_or_path(BlockBackend *blk, bool want_id) return object_get_canonical_path(OBJECT(dev)) ?: g_strdup(""); } -/* - * Return the qdev ID, or if no ID is assigned the QOM path, of the block - * device attached to the BlockBackend. - */ char *blk_get_attached_dev_id(BlockBackend *blk) { return blk_get_attached_dev_id_or_path(blk, true); } +/* + * The caller is responsible for releasing the value returned + * with g_free() after use. + */ static char *blk_get_attached_dev_path(BlockBackend *blk) { return blk_get_attached_dev_id_or_path(blk, false); @@ -2134,10 +2148,10 @@ static void send_qmp_error_event(BlockBackend *blk, { IoOperationType optype; BlockDriverState *bs = blk_bs(blk); + g_autofree char *path = blk_get_attached_dev_path(blk); optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE; - qapi_event_send_block_io_error(blk_name(blk), - blk_get_attached_dev_path(blk), + qapi_event_send_block_io_error(path, blk_name(blk), bs ? bdrv_get_node_name(bs) : NULL, optype, action, blk_iostatus_is_enabled(blk), error == ENOSPC, strerror(error)); diff --git a/block/copy-before-write.c b/block/copy-before-write.c index c00bc2351b..fd470f5f92 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c @@ -24,7 +24,7 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qjson.h" #include "system/block-backend.h" #include "qemu/cutils.h" diff --git a/block/copy-on-read.c b/block/copy-on-read.c index c36f253d16..accf1402f0 100644 --- a/block/copy-on-read.c +++ b/block/copy-on-read.c @@ -25,7 +25,7 @@ #include "block/block_int.h" #include "qemu/module.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "block/copy-on-read.h" diff --git a/block/curl.c b/block/curl.c index 0fdb6d39ac..5467678024 100644 --- a/block/curl.c +++ b/block/curl.c @@ -29,8 +29,8 @@ #include "qemu/option.h" #include "block/block-io.h" #include "block/block_int.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "crypto/secret.h" #include <curl/curl.h> #include "qemu/cutils.h" diff --git a/block/export/export.c b/block/export/export.c index 79c71ee245..f3bbf11070 100644 --- a/block/export/export.c +++ b/block/export/export.c @@ -75,6 +75,7 @@ static const BlockExportDriver *blk_exp_find_driver(BlockExportType type) BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) { bool fixed_iothread = export->has_fixed_iothread && export->fixed_iothread; + bool allow_inactive = export->has_allow_inactive && export->allow_inactive; const BlockExportDriver *drv; BlockExport *exp = NULL; BlockDriverState *bs; @@ -138,14 +139,25 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) } } - /* - * Block exports are used for non-shared storage migration. Make sure - * that BDRV_O_INACTIVE is cleared and the image is ready for write - * access since the export could be available before migration handover. - * ctx was acquired in the caller. - */ bdrv_graph_rdlock_main_loop(); - bdrv_activate(bs, NULL); + if (allow_inactive) { + if (!drv->supports_inactive) { + error_setg(errp, "Export type does not support inactive exports"); + bdrv_graph_rdunlock_main_loop(); + goto fail; + } + } else { + /* + * Block exports are used for non-shared storage migration. Make sure + * that BDRV_O_INACTIVE is cleared and the image is ready for write + * access since the export could be available before migration handover. + */ + ret = bdrv_activate(bs, errp); + if (ret < 0) { + bdrv_graph_rdunlock_main_loop(); + goto fail; + } + } bdrv_graph_rdunlock_main_loop(); perm = BLK_PERM_CONSISTENT_READ; @@ -158,6 +170,9 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) if (!fixed_iothread) { blk_set_allow_aio_context_change(blk, true); } + if (allow_inactive) { + blk_set_force_allow_inactivate(blk); + } ret = blk_insert_bs(blk, bs, errp); if (ret < 0) { diff --git a/block/file-posix.c b/block/file-posix.c index 90fa54352c..44e16dda87 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -36,8 +36,8 @@ #include "block/thread-pool.h" #include "qemu/iov.h" #include "block/raw-aio.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "scsi/pr-manager.h" #include "scsi/constants.h" diff --git a/block/file-win32.c b/block/file-win32.c index 7e1baa1ece..af9aea631c 100644 --- a/block/file-win32.c +++ b/block/file-win32.c @@ -33,8 +33,8 @@ #include "trace.h" #include "block/thread-pool.h" #include "qemu/iov.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include <windows.h> #include <winioctl.h> diff --git a/block/gluster.c b/block/gluster.c index e9c038042b..c6d25ae733 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -15,7 +15,7 @@ #include "block/block_int.h" #include "block/qdict.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qmp/qerror.h" #include "qemu/error-report.h" #include "qemu/module.h" diff --git a/block/iscsi.c b/block/iscsi.c index a5f8921426..2f0f4dac09 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -44,8 +44,8 @@ #include "system/replay.h" #include "qapi/error.h" #include "qapi/qapi-commands-machine.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "crypto/secret.h" #include "scsi/utils.h" #include "trace.h" diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c index 1d312513fc..ad7dc1de45 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c @@ -41,7 +41,7 @@ #include "system/blockdev.h" #include "qapi/qapi-commands-block.h" #include "qapi/qapi-commands-block-export.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "qemu/config-file.h" @@ -630,11 +630,12 @@ static void print_block_info(Monitor *mon, BlockInfo *info, } if (inserted) { - monitor_printf(mon, ": %s (%s%s%s)\n", + monitor_printf(mon, ": %s (%s%s%s%s)\n", inserted->file, inserted->drv, inserted->ro ? ", read-only" : "", - inserted->encrypted ? ", encrypted" : ""); + inserted->encrypted ? ", encrypted" : "", + inserted->active ? "" : ", inactive"); } else { monitor_printf(mon, ": [not inserted]\n"); } diff --git a/block/nbd.c b/block/nbd.c index d464315766..887841bc81 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -36,7 +36,7 @@ #include "qemu/main-loop.h" #include "qapi/qapi-visit-sockets.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qstring.h" #include "qapi/clone-visitor.h" #include "block/qdict.h" diff --git a/block/nfs.c b/block/nfs.c index 7d34b58750..0a7d38db09 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -41,8 +41,8 @@ #include "qemu/cutils.h" #include "system/replay.h" #include "qapi/qapi-visit-block-core.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" #include <nfsc/libnfs.h> diff --git a/block/null.c b/block/null.c index 8135055834..dc0b1fdbd9 100644 --- a/block/null.c +++ b/block/null.c @@ -12,8 +12,8 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qemu/module.h" #include "qemu/option.h" #include "block/block-io.h" diff --git a/block/nvme.c b/block/nvme.c index 5ba6a0c9c9..bbf7c23dcd 100644 --- a/block/nvme.c +++ b/block/nvme.c @@ -14,8 +14,8 @@ #include "qemu/osdep.h" #include <linux/vfio.h> #include "qapi/error.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qemu/defer-call.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" diff --git a/block/parallels.c b/block/parallels.c index d4bfc44e64..347ca127f3 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -36,7 +36,7 @@ #include "system/block-backend.h" #include "qemu/module.h" #include "qemu/option.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-block-core.h" #include "qemu/bswap.h" diff --git a/block/qapi-system.c b/block/qapi-system.c index 3277f37fd0..54b7409b2b 100644 --- a/block/qapi-system.c +++ b/block/qapi-system.c @@ -35,7 +35,7 @@ #include "block/block_int.h" #include "qapi/error.h" #include "qapi/qapi-commands-block.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "system/block-backend.h" #include "system/blockdev.h" diff --git a/block/qapi.c b/block/qapi.c index 902ecb08e0..2c50a6bf3b 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -33,11 +33,11 @@ #include "qapi/qapi-commands-block-core.h" #include "qapi/qobject-output-visitor.h" #include "qapi/qapi-visit-block-core.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qemu/qemu-print.h" #include "system/block-backend.h" @@ -63,6 +63,7 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, info->file = g_strdup(bs->filename); info->ro = bdrv_is_read_only(bs); info->drv = g_strdup(bs->drv->format_name); + info->active = !bdrv_is_inactive(bs); info->encrypted = bs->encrypted; info->cache = g_new(BlockdevCacheInfo, 1); diff --git a/block/qcow.c b/block/qcow.c index 37be7e7cb4..da8ad4d243 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -34,8 +34,8 @@ #include "qemu/cutils.h" #include "qemu/memalign.h" #include <zlib.h> -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-block-core.h" #include "crypto/block.h" diff --git a/block/qcow2.c b/block/qcow2.c index d732162391..dd6bcafbd8 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -32,8 +32,8 @@ #include "qemu/error-report.h" #include "qapi/error.h" #include "qapi/qapi-events-block-core.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "trace.h" #include "qemu/option_int.h" #include "qemu/cutils.h" diff --git a/block/qed.c b/block/qed.c index 8b33594546..382c9e5335 100644 --- a/block/qed.c +++ b/block/qed.c @@ -24,7 +24,7 @@ #include "trace.h" #include "qed.h" #include "system/block-backend.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-block-core.h" diff --git a/block/quorum.c b/block/quorum.c index 46be65a95f..30747a6df9 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -23,10 +23,10 @@ #include "block/qdict.h" #include "qapi/error.h" #include "qapi/qapi-events-block.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qlist.h" +#include "qobject/qstring.h" #include "crypto/hash.h" #define HASH_LENGTH 32 diff --git a/block/rbd.c b/block/rbd.c index e814856609..af984fb7db 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -24,10 +24,10 @@ #include "crypto/secret.h" #include "qemu/cutils.h" #include "system/replay.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qlist.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-block-core.h" diff --git a/block/replication.c b/block/replication.c index 2ce16f0589..0020f33843 100644 --- a/block/replication.c +++ b/block/replication.c @@ -21,7 +21,7 @@ #include "block/block_backup.h" #include "system/block-backend.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "block/replication.h" typedef enum { @@ -576,7 +576,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, return; } bdrv_op_block_all(top_bs, s->blocker); - bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker); bdrv_graph_wrunlock(); diff --git a/block/snapshot.c b/block/snapshot.c index d27afe7c0e..9c44780e96 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -27,8 +27,8 @@ #include "block/block_int.h" #include "block/qdict.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qemu/option.h" #include "system/block-backend.h" diff --git a/block/ssh.c b/block/ssh.c index b9f33ec739..70fe7cf86e 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -39,8 +39,8 @@ #include "qemu/sockets.h" #include "qapi/qapi-visit-sockets.h" #include "qapi/qapi-visit-block-core.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" #include "trace.h" diff --git a/block/stream.c b/block/stream.c index 9a06c0decb..999d9e56d4 100644 --- a/block/stream.c +++ b/block/stream.c @@ -16,7 +16,7 @@ #include "block/block_int.h" #include "block/blockjob_int.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/ratelimit.h" #include "system/block-backend.h" #include "block/copy-on-read.h" diff --git a/block/vhdx.c b/block/vhdx.c index 42c919f51a..b2a4b813a0 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -29,7 +29,7 @@ #include "vhdx.h" #include "migration/blocker.h" #include "qemu/uuid.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-block-core.h" diff --git a/block/vmdk.c b/block/vmdk.c index 6ef266df87..2adec49912 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -27,7 +27,7 @@ #include "qapi/error.h" #include "block/block_int.h" #include "system/block-backend.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/error-report.h" #include "qemu/module.h" #include "qemu/option.h" diff --git a/block/vpc.c b/block/vpc.c index 6489ee756a..0309e319f6 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -34,7 +34,7 @@ #include "qemu/bswap.h" #include "qemu/uuid.h" #include "qemu/memalign.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-block-core.h" @@ -216,6 +216,39 @@ static void vpc_parse_options(BlockDriverState *bs, QemuOpts *opts, } } +/* + * Microsoft Virtual PC and Microsoft Hyper-V produce and read + * VHD image sizes differently. VPC will rely on CHS geometry, + * while Hyper-V and disk2vhd use the size specified in the footer. + * + * We use a couple of approaches to try and determine the correct method: + * look at the Creator App field, and look for images that have CHS + * geometry that is the maximum value. + * + * If the CHS geometry is the maximum CHS geometry, then we assume that + * the size is the footer->current_size to avoid truncation. Otherwise, + * we follow the table based on footer->creator_app: + * + * Known creator apps: + * 'vpc ' : CHS Virtual PC (uses disk geometry) + * 'qemu' : CHS QEMU (uses disk geometry) + * 'qem2' : current_size QEMU (uses current_size) + * 'win ' : current_size Hyper-V + * 'd2v ' : current_size Disk2vhd + * 'tap\0' : current_size XenServer + * 'CTXS' : current_size XenConverter + * 'wa\0\0': current_size Azure + * + * The user can override the table values via drive options, however + * even with an override we will still use current_size for images + * that have CHS geometry of the maximum size. + */ +static bool vpc_ignore_current_size(VHDFooter *footer) +{ + return !strncmp(footer->creator_app, "vpc ", 4) || + !strncmp(footer->creator_app, "qemu", 4); +} + static int vpc_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { @@ -304,36 +337,8 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags, bs->total_sectors = (int64_t) be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl; - /* Microsoft Virtual PC and Microsoft Hyper-V produce and read - * VHD image sizes differently. VPC will rely on CHS geometry, - * while Hyper-V and disk2vhd use the size specified in the footer. - * - * We use a couple of approaches to try and determine the correct method: - * look at the Creator App field, and look for images that have CHS - * geometry that is the maximum value. - * - * If the CHS geometry is the maximum CHS geometry, then we assume that - * the size is the footer->current_size to avoid truncation. Otherwise, - * we follow the table based on footer->creator_app: - * - * Known creator apps: - * 'vpc ' : CHS Virtual PC (uses disk geometry) - * 'qemu' : CHS QEMU (uses disk geometry) - * 'qem2' : current_size QEMU (uses current_size) - * 'win ' : current_size Hyper-V - * 'd2v ' : current_size Disk2vhd - * 'tap\0' : current_size XenServer - * 'CTXS' : current_size XenConverter - * - * The user can override the table values via drive options, however - * even with an override we will still use current_size for images - * that have CHS geometry of the maximum size. - */ - use_chs = (!!strncmp(footer->creator_app, "win ", 4) && - !!strncmp(footer->creator_app, "qem2", 4) && - !!strncmp(footer->creator_app, "d2v ", 4) && - !!strncmp(footer->creator_app, "CTXS", 4) && - !!memcmp(footer->creator_app, "tap", 4)) || s->force_use_chs; + /* Use CHS or current_size to determine the image size. */ + use_chs = vpc_ignore_current_size(footer) || s->force_use_chs; if (!use_chs || bs->total_sectors == VHD_MAX_GEOMETRY || s->force_use_sz) { bs->total_sectors = be64_to_cpu(footer->current_size) / diff --git a/block/vvfat.c b/block/vvfat.c index bfbcc5562c..91d69b3cc8 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -34,8 +34,8 @@ #include "qemu/option.h" #include "qemu/bswap.h" #include "migration/blocker.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qemu/ctype.h" #include "qemu/cutils.h" #include "qemu/error-report.h" diff --git a/blockdev.c b/blockdev.c index 218024497b..1d1f27cfff 100644 --- a/blockdev.c +++ b/blockdev.c @@ -46,12 +46,12 @@ #include "qapi/qapi-commands-block.h" #include "qapi/qapi-commands-transaction.h" #include "qapi/qapi-visit-block-core.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qapi/qobject-output-visitor.h" #include "system/system.h" #include "system/iothread.h" @@ -1497,6 +1497,22 @@ static void external_snapshot_action(TransactionAction *action, return; } + /* + * Older QEMU versions have allowed adding an active parent node to an + * inactive child node. This is unsafe in the general case, but there is an + * important use case, which is taking a VM snapshot with migration to file + * and then adding an external snapshot while the VM is still stopped and + * images are inactive. Requiring the user to explicitly create the overlay + * as inactive would break compatibility, so just do it automatically here + * to keep this working. + */ + if (bdrv_is_inactive(state->old_bs) && !bdrv_is_inactive(state->new_bs)) { + ret = bdrv_inactivate(state->new_bs, errp); + if (ret < 0) { + return; + } + } + ret = bdrv_append(state->new_bs, state->old_bs, errp); if (ret < 0) { return; @@ -3455,6 +3471,38 @@ void qmp_blockdev_del(const char *node_name, Error **errp) bdrv_unref(bs); } +void qmp_blockdev_set_active(const char *node_name, bool active, Error **errp) +{ + int ret; + + GLOBAL_STATE_CODE(); + GRAPH_RDLOCK_GUARD_MAINLOOP(); + + if (!node_name) { + if (active) { + bdrv_activate_all(errp); + } else { + ret = bdrv_inactivate_all(); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to inactivate all nodes"); + } + } + } else { + BlockDriverState *bs = bdrv_find_node(node_name); + if (!bs) { + error_setg(errp, "Failed to find node with node-name='%s'", + node_name); + return; + } + + if (active) { + bdrv_activate(bs, errp); + } else { + bdrv_inactivate(bs, errp); + } + } +} + static BdrvChild * GRAPH_RDLOCK bdrv_find_child(BlockDriverState *parent_bs, const char *child_name) { diff --git a/blockjob.c b/blockjob.c index e94a840d7f..32007f31a9 100644 --- a/blockjob.c +++ b/blockjob.c @@ -539,8 +539,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, goto fail; } - bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker); - if (!block_job_set_speed(job, speed, errp)) { goto fail; } diff --git a/chardev/char-hmp-cmds.c b/chardev/char-hmp-cmds.c index 287c2b1bcd..8e9e1c1c02 100644 --- a/chardev/char-hmp-cmds.c +++ b/chardev/char-hmp-cmds.c @@ -19,7 +19,7 @@ #include "monitor/monitor.h" #include "qapi/error.h" #include "qapi/qapi-commands-char.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/config-file.h" #include "qemu/option.h" diff --git a/configs/targets/aarch64-bsd-user.mak b/configs/targets/aarch64-bsd-user.mak index 8aaa5d8c80..f99c73377a 100644 --- a/configs/targets/aarch64-bsd-user.mak +++ b/configs/targets/aarch64-bsd-user.mak @@ -1,3 +1,4 @@ TARGET_ARCH=aarch64 TARGET_BASE_ARCH=arm TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml +TARGET_LONG_BITS=64 diff --git a/configs/targets/aarch64-linux-user.mak b/configs/targets/aarch64-linux-user.mak index 4c6570f56a..b779ac3b4a 100644 --- a/configs/targets/aarch64-linux-user.mak +++ b/configs/targets/aarch64-linux-user.mak @@ -6,3 +6,4 @@ CONFIG_SEMIHOSTING=y CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y TARGET_SYSTBL_ABI=common,64,renameat,rlimit,memfd_secret TARGET_SYSTBL=syscall_64.tbl +TARGET_LONG_BITS=64 diff --git a/configs/targets/aarch64-softmmu.mak b/configs/targets/aarch64-softmmu.mak index 84cb32dc2f..82cb72cb83 100644 --- a/configs/targets/aarch64-softmmu.mak +++ b/configs/targets/aarch64-softmmu.mak @@ -5,3 +5,4 @@ TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml gdb-xml/aarch64-pauth.xml # needed by boot.c TARGET_NEED_FDT=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/aarch64_be-linux-user.mak b/configs/targets/aarch64_be-linux-user.mak index dcef597a80..ef9be02290 100644 --- a/configs/targets/aarch64_be-linux-user.mak +++ b/configs/targets/aarch64_be-linux-user.mak @@ -7,3 +7,4 @@ CONFIG_SEMIHOSTING=y CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y TARGET_SYSTBL_ABI=common,64,renameat,rlimit,memfd_secret TARGET_SYSTBL=syscall_64.tbl +TARGET_LONG_BITS=64 diff --git a/configs/targets/alpha-linux-user.mak b/configs/targets/alpha-linux-user.mak index f7d3fb4afa..ef8e365b09 100644 --- a/configs/targets/alpha-linux-user.mak +++ b/configs/targets/alpha-linux-user.mak @@ -1,3 +1,4 @@ TARGET_ARCH=alpha TARGET_SYSTBL_ABI=common TARGET_SYSTBL=syscall.tbl +TARGET_LONG_BITS=64 diff --git a/configs/targets/alpha-softmmu.mak b/configs/targets/alpha-softmmu.mak index 9dbe160740..89f3517aca 100644 --- a/configs/targets/alpha-softmmu.mak +++ b/configs/targets/alpha-softmmu.mak @@ -1,2 +1,3 @@ TARGET_ARCH=alpha TARGET_SUPPORTS_MTTCG=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/arm-bsd-user.mak b/configs/targets/arm-bsd-user.mak index cb143e6426..472a4f9fb1 100644 --- a/configs/targets/arm-bsd-user.mak +++ b/configs/targets/arm-bsd-user.mak @@ -1,2 +1,3 @@ TARGET_ARCH=arm TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml +TARGET_LONG_BITS=32 diff --git a/configs/targets/arm-linux-user.mak b/configs/targets/arm-linux-user.mak index 7f5d65794c..bf35ded7fe 100644 --- a/configs/targets/arm-linux-user.mak +++ b/configs/targets/arm-linux-user.mak @@ -5,3 +5,4 @@ TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml TARGET_HAS_BFLT=y CONFIG_SEMIHOSTING=y CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/arm-softmmu.mak b/configs/targets/arm-softmmu.mak index bf390b7a8d..afc64f5927 100644 --- a/configs/targets/arm-softmmu.mak +++ b/configs/targets/arm-softmmu.mak @@ -3,3 +3,4 @@ TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml # needed by boot.c TARGET_NEED_FDT=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/armeb-linux-user.mak b/configs/targets/armeb-linux-user.mak index 943d0d87bf..35fa4d91b3 100644 --- a/configs/targets/armeb-linux-user.mak +++ b/configs/targets/armeb-linux-user.mak @@ -6,3 +6,4 @@ TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml TARGET_HAS_BFLT=y CONFIG_SEMIHOSTING=y CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/avr-softmmu.mak b/configs/targets/avr-softmmu.mak index e3f921c019..b6157fc465 100644 --- a/configs/targets/avr-softmmu.mak +++ b/configs/targets/avr-softmmu.mak @@ -1,2 +1,3 @@ TARGET_ARCH=avr TARGET_XML_FILES= gdb-xml/avr-cpu.xml +TARGET_LONG_BITS=32 diff --git a/configs/targets/hexagon-linux-user.mak b/configs/targets/hexagon-linux-user.mak index b912045bd3..aec1a04d1b 100644 --- a/configs/targets/hexagon-linux-user.mak +++ b/configs/targets/hexagon-linux-user.mak @@ -2,3 +2,4 @@ TARGET_ARCH=hexagon TARGET_XML_FILES=gdb-xml/hexagon-core.xml gdb-xml/hexagon-hvx.xml TARGET_SYSTBL=syscall.tbl TARGET_SYSTBL_ABI=common,32,hexagon,time32,stat64,rlimit,renameat +TARGET_LONG_BITS=32 diff --git a/configs/targets/hppa-linux-user.mak b/configs/targets/hppa-linux-user.mak index 8e0a80492f..59190f6335 100644 --- a/configs/targets/hppa-linux-user.mak +++ b/configs/targets/hppa-linux-user.mak @@ -3,3 +3,5 @@ TARGET_ABI32=y TARGET_SYSTBL_ABI=common,32 TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y +# Compromise to ease maintenance vs system mode +TARGET_LONG_BITS=64 diff --git a/configs/targets/hppa-softmmu.mak b/configs/targets/hppa-softmmu.mak index a41662aa99..63ca74ed5e 100644 --- a/configs/targets/hppa-softmmu.mak +++ b/configs/targets/hppa-softmmu.mak @@ -1,3 +1,4 @@ TARGET_ARCH=hppa TARGET_BIG_ENDIAN=y TARGET_SUPPORTS_MTTCG=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/i386-bsd-user.mak b/configs/targets/i386-bsd-user.mak index 0283bb62a0..70e098da49 100644 --- a/configs/targets/i386-bsd-user.mak +++ b/configs/targets/i386-bsd-user.mak @@ -1,2 +1,3 @@ TARGET_ARCH=i386 TARGET_XML_FILES= gdb-xml/i386-32bit.xml +TARGET_LONG_BITS=32 diff --git a/configs/targets/i386-linux-user.mak b/configs/targets/i386-linux-user.mak index b72a156473..ea68a266fc 100644 --- a/configs/targets/i386-linux-user.mak +++ b/configs/targets/i386-linux-user.mak @@ -2,3 +2,4 @@ TARGET_ARCH=i386 TARGET_SYSTBL_ABI=i386 TARGET_SYSTBL=syscall_32.tbl TARGET_XML_FILES= gdb-xml/i386-32bit.xml gdb-xml/i386-32bit-linux.xml +TARGET_LONG_BITS=32 diff --git a/configs/targets/i386-softmmu.mak b/configs/targets/i386-softmmu.mak index 2eb0e86250..5dd8921756 100644 --- a/configs/targets/i386-softmmu.mak +++ b/configs/targets/i386-softmmu.mak @@ -3,3 +3,4 @@ TARGET_SUPPORTS_MTTCG=y TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_KVM_HAVE_RESET_PARKED_VCPU=y TARGET_XML_FILES= gdb-xml/i386-32bit.xml +TARGET_LONG_BITS=32 diff --git a/configs/targets/loongarch64-linux-user.mak b/configs/targets/loongarch64-linux-user.mak index dfded79dfa..249a26a798 100644 --- a/configs/targets/loongarch64-linux-user.mak +++ b/configs/targets/loongarch64-linux-user.mak @@ -4,3 +4,4 @@ TARGET_BASE_ARCH=loongarch TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml TARGET_SYSTBL=syscall.tbl TARGET_SYSTBL_ABI=common,64 +TARGET_LONG_BITS=64 diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak index ce19ab6a16..351341132f 100644 --- a/configs/targets/loongarch64-softmmu.mak +++ b/configs/targets/loongarch64-softmmu.mak @@ -5,3 +5,4 @@ TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml # all boards require libfdt TARGET_NEED_FDT=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/m68k-linux-user.mak b/configs/targets/m68k-linux-user.mak index 579b5d299c..2d9bae2270 100644 --- a/configs/targets/m68k-linux-user.mak +++ b/configs/targets/m68k-linux-user.mak @@ -4,3 +4,4 @@ TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y TARGET_XML_FILES= gdb-xml/cf-core.xml gdb-xml/cf-fp.xml gdb-xml/m68k-core.xml gdb-xml/m68k-fp.xml TARGET_HAS_BFLT=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/m68k-softmmu.mak b/configs/targets/m68k-softmmu.mak index bbcd0bada6..bacc52e96a 100644 --- a/configs/targets/m68k-softmmu.mak +++ b/configs/targets/m68k-softmmu.mak @@ -1,3 +1,4 @@ TARGET_ARCH=m68k TARGET_BIG_ENDIAN=y TARGET_XML_FILES= gdb-xml/cf-core.xml gdb-xml/cf-fp.xml gdb-xml/m68k-core.xml gdb-xml/m68k-fp.xml +TARGET_LONG_BITS=32 diff --git a/configs/targets/microblaze-linux-user.mak b/configs/targets/microblaze-linux-user.mak index 0a2322c249..3772779769 100644 --- a/configs/targets/microblaze-linux-user.mak +++ b/configs/targets/microblaze-linux-user.mak @@ -4,3 +4,4 @@ TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y TARGET_HAS_BFLT=y TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml +TARGET_LONG_BITS=32 diff --git a/configs/targets/microblaze-softmmu.mak b/configs/targets/microblaze-softmmu.mak index eea266d4f3..99a33ed44a 100644 --- a/configs/targets/microblaze-softmmu.mak +++ b/configs/targets/microblaze-softmmu.mak @@ -4,3 +4,6 @@ TARGET_SUPPORTS_MTTCG=y # needed by boot.c TARGET_NEED_FDT=y TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml +# System mode can address up to 64 bits via lea/sea instructions. +# TODO: These bypass the mmu, so we could emulate these differently. +TARGET_LONG_BITS=64 diff --git a/configs/targets/microblazeel-linux-user.mak b/configs/targets/microblazeel-linux-user.mak index 270743156a..a51a05488d 100644 --- a/configs/targets/microblazeel-linux-user.mak +++ b/configs/targets/microblazeel-linux-user.mak @@ -3,3 +3,4 @@ TARGET_SYSTBL_ABI=common TARGET_SYSTBL=syscall.tbl TARGET_HAS_BFLT=y TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml +TARGET_LONG_BITS=32 diff --git a/configs/targets/microblazeel-softmmu.mak b/configs/targets/microblazeel-softmmu.mak index 77b968acad..52cdeae1a2 100644 --- a/configs/targets/microblazeel-softmmu.mak +++ b/configs/targets/microblazeel-softmmu.mak @@ -3,3 +3,6 @@ TARGET_SUPPORTS_MTTCG=y # needed by boot.c TARGET_NEED_FDT=y TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml +# System mode can address up to 64 bits via lea/sea instructions. +# TODO: These bypass the mmu, so we could emulate these differently. +TARGET_LONG_BITS=64 diff --git a/configs/targets/mips-linux-user.mak b/configs/targets/mips-linux-user.mak index b4569a9893..69bdc459b6 100644 --- a/configs/targets/mips-linux-user.mak +++ b/configs/targets/mips-linux-user.mak @@ -3,3 +3,4 @@ TARGET_ABI_MIPSO32=y TARGET_SYSTBL_ABI=o32 TARGET_SYSTBL=syscall_o32.tbl TARGET_BIG_ENDIAN=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/mips-softmmu.mak b/configs/targets/mips-softmmu.mak index d34b4083fc..b62a088249 100644 --- a/configs/targets/mips-softmmu.mak +++ b/configs/targets/mips-softmmu.mak @@ -1,3 +1,4 @@ TARGET_ARCH=mips TARGET_BIG_ENDIAN=y TARGET_SUPPORTS_MTTCG=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/mips64-linux-user.mak b/configs/targets/mips64-linux-user.mak index d2ff509a11..04e82b3ab1 100644 --- a/configs/targets/mips64-linux-user.mak +++ b/configs/targets/mips64-linux-user.mak @@ -4,3 +4,4 @@ TARGET_BASE_ARCH=mips TARGET_SYSTBL_ABI=n64 TARGET_SYSTBL=syscall_n64.tbl TARGET_BIG_ENDIAN=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/mips64-softmmu.mak b/configs/targets/mips64-softmmu.mak index 12d9483bf0..7202655fca 100644 --- a/configs/targets/mips64-softmmu.mak +++ b/configs/targets/mips64-softmmu.mak @@ -1,3 +1,4 @@ TARGET_ARCH=mips64 TARGET_BASE_ARCH=mips TARGET_BIG_ENDIAN=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/mips64el-linux-user.mak b/configs/targets/mips64el-linux-user.mak index f9efeec8ea..27f4169426 100644 --- a/configs/targets/mips64el-linux-user.mak +++ b/configs/targets/mips64el-linux-user.mak @@ -3,3 +3,4 @@ TARGET_ABI_MIPSN64=y TARGET_BASE_ARCH=mips TARGET_SYSTBL_ABI=n64 TARGET_SYSTBL=syscall_n64.tbl +TARGET_LONG_BITS=64 diff --git a/configs/targets/mips64el-softmmu.mak b/configs/targets/mips64el-softmmu.mak index 3864daa736..3ebeadb29e 100644 --- a/configs/targets/mips64el-softmmu.mak +++ b/configs/targets/mips64el-softmmu.mak @@ -1,2 +1,3 @@ TARGET_ARCH=mips64 TARGET_BASE_ARCH=mips +TARGET_LONG_BITS=64 diff --git a/configs/targets/mipsel-linux-user.mak b/configs/targets/mipsel-linux-user.mak index e8d7241d31..8b7e86ab28 100644 --- a/configs/targets/mipsel-linux-user.mak +++ b/configs/targets/mipsel-linux-user.mak @@ -2,3 +2,4 @@ TARGET_ARCH=mips TARGET_ABI_MIPSO32=y TARGET_SYSTBL_ABI=o32 TARGET_SYSTBL=syscall_o32.tbl +TARGET_LONG_BITS=32 diff --git a/configs/targets/mipsel-softmmu.mak b/configs/targets/mipsel-softmmu.mak index 0829659fc2..620ec68178 100644 --- a/configs/targets/mipsel-softmmu.mak +++ b/configs/targets/mipsel-softmmu.mak @@ -1,2 +1,3 @@ TARGET_ARCH=mips TARGET_SUPPORTS_MTTCG=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/mipsn32-linux-user.mak b/configs/targets/mipsn32-linux-user.mak index 206095da64..39ae214633 100644 --- a/configs/targets/mipsn32-linux-user.mak +++ b/configs/targets/mipsn32-linux-user.mak @@ -5,3 +5,4 @@ TARGET_BASE_ARCH=mips TARGET_SYSTBL_ABI=n32 TARGET_SYSTBL=syscall_n32.tbl TARGET_BIG_ENDIAN=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/mipsn32el-linux-user.mak b/configs/targets/mipsn32el-linux-user.mak index ca2a3ed753..d9b61d6990 100644 --- a/configs/targets/mipsn32el-linux-user.mak +++ b/configs/targets/mipsn32el-linux-user.mak @@ -4,3 +4,4 @@ TARGET_ABI32=y TARGET_BASE_ARCH=mips TARGET_SYSTBL_ABI=n32 TARGET_SYSTBL=syscall_n32.tbl +TARGET_LONG_BITS=64 diff --git a/configs/targets/or1k-linux-user.mak b/configs/targets/or1k-linux-user.mak index eecb1e2241..810567a98f 100644 --- a/configs/targets/or1k-linux-user.mak +++ b/configs/targets/or1k-linux-user.mak @@ -2,3 +2,4 @@ TARGET_ARCH=openrisc TARGET_BIG_ENDIAN=y TARGET_SYSTBL_ABI=common,32,or1k,time32,stat64,rlimit,renameat TARGET_SYSTBL=syscall.tbl +TARGET_LONG_BITS=32 diff --git a/configs/targets/or1k-softmmu.mak b/configs/targets/or1k-softmmu.mak index 0341cb2a6b..adfddb1a8a 100644 --- a/configs/targets/or1k-softmmu.mak +++ b/configs/targets/or1k-softmmu.mak @@ -3,3 +3,4 @@ TARGET_SUPPORTS_MTTCG=y TARGET_BIG_ENDIAN=y # needed by boot.c and all boards TARGET_NEED_FDT=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/ppc-linux-user.mak b/configs/targets/ppc-linux-user.mak index cc0439a528..970d04a5ba 100644 --- a/configs/targets/ppc-linux-user.mak +++ b/configs/targets/ppc-linux-user.mak @@ -3,3 +3,4 @@ TARGET_SYSTBL_ABI=common,nospu,32 TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y TARGET_XML_FILES= gdb-xml/power-core.xml gdb-xml/power-fpu.xml gdb-xml/power-altivec.xml gdb-xml/power-spe.xml +TARGET_LONG_BITS=32 diff --git a/configs/targets/ppc-softmmu.mak b/configs/targets/ppc-softmmu.mak index 53120dab41..9bfa7df6c3 100644 --- a/configs/targets/ppc-softmmu.mak +++ b/configs/targets/ppc-softmmu.mak @@ -2,3 +2,4 @@ TARGET_ARCH=ppc TARGET_BIG_ENDIAN=y TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_XML_FILES= gdb-xml/power-core.xml gdb-xml/power-fpu.xml gdb-xml/power-altivec.xml gdb-xml/power-spe.xml +TARGET_LONG_BITS=32 diff --git a/configs/targets/ppc64-linux-user.mak b/configs/targets/ppc64-linux-user.mak index 4d81969f4a..461f1c67d1 100644 --- a/configs/targets/ppc64-linux-user.mak +++ b/configs/targets/ppc64-linux-user.mak @@ -5,3 +5,4 @@ TARGET_SYSTBL_ABI=common,nospu,64 TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y TARGET_XML_FILES= gdb-xml/power64-core.xml gdb-xml/power-fpu.xml gdb-xml/power-altivec.xml gdb-xml/power-spe.xml gdb-xml/power-vsx.xml +TARGET_LONG_BITS=64 diff --git a/configs/targets/ppc64-softmmu.mak b/configs/targets/ppc64-softmmu.mak index 40881d9396..7cee0e97f4 100644 --- a/configs/targets/ppc64-softmmu.mak +++ b/configs/targets/ppc64-softmmu.mak @@ -6,3 +6,4 @@ TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_XML_FILES= gdb-xml/power64-core.xml gdb-xml/power-fpu.xml gdb-xml/power-altivec.xml gdb-xml/power-spe.xml gdb-xml/power-vsx.xml # all boards require libfdt TARGET_NEED_FDT=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/ppc64le-linux-user.mak b/configs/targets/ppc64le-linux-user.mak index 426d5a28d6..cf9d8a400d 100644 --- a/configs/targets/ppc64le-linux-user.mak +++ b/configs/targets/ppc64le-linux-user.mak @@ -4,3 +4,4 @@ TARGET_ABI_DIR=ppc TARGET_SYSTBL_ABI=common,nospu,64 TARGET_SYSTBL=syscall.tbl TARGET_XML_FILES= gdb-xml/power64-core.xml gdb-xml/power-fpu.xml gdb-xml/power-altivec.xml gdb-xml/power-spe.xml gdb-xml/power-vsx.xml +TARGET_LONG_BITS=64 diff --git a/configs/targets/riscv32-linux-user.mak b/configs/targets/riscv32-linux-user.mak index 0dbaf5210a..a0ef03c0c3 100644 --- a/configs/targets/riscv32-linux-user.mak +++ b/configs/targets/riscv32-linux-user.mak @@ -7,3 +7,4 @@ CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y TARGET_SYSTBL_ABI=32 TARGET_SYSTBL_ABI=common,32,riscv,memfd_secret TARGET_SYSTBL=syscall.tbl +TARGET_LONG_BITS=32 diff --git a/configs/targets/riscv32-softmmu.mak b/configs/targets/riscv32-softmmu.mak index 338182d5b8..c828066ce6 100644 --- a/configs/targets/riscv32-softmmu.mak +++ b/configs/targets/riscv32-softmmu.mak @@ -4,3 +4,4 @@ TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-virtual.xml # needed by boot.c TARGET_NEED_FDT=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/riscv64-bsd-user.mak b/configs/targets/riscv64-bsd-user.mak index 191c2c483f..c6348a7962 100644 --- a/configs/targets/riscv64-bsd-user.mak +++ b/configs/targets/riscv64-bsd-user.mak @@ -2,3 +2,4 @@ TARGET_ARCH=riscv64 TARGET_BASE_ARCH=riscv TARGET_ABI_DIR=riscv TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-virtual.xml +TARGET_LONG_BITS=64 diff --git a/configs/targets/riscv64-linux-user.mak b/configs/targets/riscv64-linux-user.mak index 477cd4523e..aac7568305 100644 --- a/configs/targets/riscv64-linux-user.mak +++ b/configs/targets/riscv64-linux-user.mak @@ -7,3 +7,4 @@ CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y TARGET_SYSTBL_ABI=64 TARGET_SYSTBL_ABI=common,64,riscv,rlimit,memfd_secret TARGET_SYSTBL=syscall.tbl +TARGET_LONG_BITS=64 diff --git a/configs/targets/riscv64-softmmu.mak b/configs/targets/riscv64-softmmu.mak index 6c5de72e03..09f613d24a 100644 --- a/configs/targets/riscv64-softmmu.mak +++ b/configs/targets/riscv64-softmmu.mak @@ -5,3 +5,4 @@ TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-virtual.xml gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-virtual.xml # needed by boot.c TARGET_NEED_FDT=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/rx-softmmu.mak b/configs/targets/rx-softmmu.mak index 706bbe6062..1c250a6450 100644 --- a/configs/targets/rx-softmmu.mak +++ b/configs/targets/rx-softmmu.mak @@ -2,3 +2,4 @@ TARGET_ARCH=rx TARGET_XML_FILES= gdb-xml/rx-core.xml # all boards require libfdt TARGET_NEED_FDT=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/s390x-linux-user.mak b/configs/targets/s390x-linux-user.mak index 24c04c8589..68c2f28872 100644 --- a/configs/targets/s390x-linux-user.mak +++ b/configs/targets/s390x-linux-user.mak @@ -3,3 +3,4 @@ TARGET_SYSTBL_ABI=common,64 TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y TARGET_XML_FILES= gdb-xml/s390x-core64.xml gdb-xml/s390-acr.xml gdb-xml/s390-fpr.xml gdb-xml/s390-vx.xml gdb-xml/s390-cr.xml gdb-xml/s390-virt.xml gdb-xml/s390-virt-kvm.xml gdb-xml/s390-gs.xml +TARGET_LONG_BITS=64 diff --git a/configs/targets/s390x-softmmu.mak b/configs/targets/s390x-softmmu.mak index b22218aacc..5242ebe7c2 100644 --- a/configs/targets/s390x-softmmu.mak +++ b/configs/targets/s390x-softmmu.mak @@ -3,3 +3,4 @@ TARGET_BIG_ENDIAN=y TARGET_SUPPORTS_MTTCG=y TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_XML_FILES= gdb-xml/s390x-core64.xml gdb-xml/s390-acr.xml gdb-xml/s390-fpr.xml gdb-xml/s390-vx.xml gdb-xml/s390-cr.xml gdb-xml/s390-virt.xml gdb-xml/s390-virt-kvm.xml gdb-xml/s390-gs.xml +TARGET_LONG_BITS=64 diff --git a/configs/targets/sh4-linux-user.mak b/configs/targets/sh4-linux-user.mak index 9908887566..d58c5471b7 100644 --- a/configs/targets/sh4-linux-user.mak +++ b/configs/targets/sh4-linux-user.mak @@ -2,3 +2,4 @@ TARGET_ARCH=sh4 TARGET_SYSTBL_ABI=common TARGET_SYSTBL=syscall.tbl TARGET_HAS_BFLT=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/sh4-softmmu.mak b/configs/targets/sh4-softmmu.mak index f9d62d91e4..787d349b50 100644 --- a/configs/targets/sh4-softmmu.mak +++ b/configs/targets/sh4-softmmu.mak @@ -1 +1,2 @@ TARGET_ARCH=sh4 +TARGET_LONG_BITS=32 diff --git a/configs/targets/sh4eb-linux-user.mak b/configs/targets/sh4eb-linux-user.mak index 9db6b3609c..99007f0f2d 100644 --- a/configs/targets/sh4eb-linux-user.mak +++ b/configs/targets/sh4eb-linux-user.mak @@ -3,3 +3,4 @@ TARGET_SYSTBL_ABI=common TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y TARGET_HAS_BFLT=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/sh4eb-softmmu.mak b/configs/targets/sh4eb-softmmu.mak index 226b1fc698..cdea2c61c5 100644 --- a/configs/targets/sh4eb-softmmu.mak +++ b/configs/targets/sh4eb-softmmu.mak @@ -1,2 +1,3 @@ TARGET_ARCH=sh4 TARGET_BIG_ENDIAN=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/sparc-linux-user.mak b/configs/targets/sparc-linux-user.mak index abcfb8fc62..4ff4b7287d 100644 --- a/configs/targets/sparc-linux-user.mak +++ b/configs/targets/sparc-linux-user.mak @@ -2,3 +2,4 @@ TARGET_ARCH=sparc TARGET_SYSTBL_ABI=common,32 TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/sparc-softmmu.mak b/configs/targets/sparc-softmmu.mak index a5d9200382..78c2e25bd1 100644 --- a/configs/targets/sparc-softmmu.mak +++ b/configs/targets/sparc-softmmu.mak @@ -1,3 +1,4 @@ TARGET_ARCH=sparc TARGET_BIG_ENDIAN=y TARGET_SUPPORTS_MTTCG=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/sparc32plus-linux-user.mak b/configs/targets/sparc32plus-linux-user.mak index 6cc8fa516b..7a16934fd1 100644 --- a/configs/targets/sparc32plus-linux-user.mak +++ b/configs/targets/sparc32plus-linux-user.mak @@ -5,3 +5,4 @@ TARGET_ABI_DIR=sparc TARGET_SYSTBL_ABI=common,32 TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/sparc64-linux-user.mak b/configs/targets/sparc64-linux-user.mak index 52f05ec000..64ea04e3e2 100644 --- a/configs/targets/sparc64-linux-user.mak +++ b/configs/targets/sparc64-linux-user.mak @@ -4,3 +4,4 @@ TARGET_ABI_DIR=sparc TARGET_SYSTBL_ABI=common,64 TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/sparc64-softmmu.mak b/configs/targets/sparc64-softmmu.mak index 36ca64ec41..f7bab97a00 100644 --- a/configs/targets/sparc64-softmmu.mak +++ b/configs/targets/sparc64-softmmu.mak @@ -2,3 +2,4 @@ TARGET_ARCH=sparc64 TARGET_BASE_ARCH=sparc TARGET_BIG_ENDIAN=y TARGET_SUPPORTS_MTTCG=y +TARGET_LONG_BITS=64 diff --git a/configs/targets/tricore-softmmu.mak b/configs/targets/tricore-softmmu.mak index 96b10af853..781ce49a62 100644 --- a/configs/targets/tricore-softmmu.mak +++ b/configs/targets/tricore-softmmu.mak @@ -1 +1,2 @@ TARGET_ARCH=tricore +TARGET_LONG_BITS=32 diff --git a/configs/targets/x86_64-bsd-user.mak b/configs/targets/x86_64-bsd-user.mak index 799cd4acd4..d62d656f2c 100644 --- a/configs/targets/x86_64-bsd-user.mak +++ b/configs/targets/x86_64-bsd-user.mak @@ -1,3 +1,4 @@ TARGET_ARCH=x86_64 TARGET_BASE_ARCH=i386 TARGET_XML_FILES= gdb-xml/i386-64bit.xml +TARGET_LONG_BITS=64 diff --git a/configs/targets/x86_64-linux-user.mak b/configs/targets/x86_64-linux-user.mak index 86042814d3..b093ab5a16 100644 --- a/configs/targets/x86_64-linux-user.mak +++ b/configs/targets/x86_64-linux-user.mak @@ -3,3 +3,4 @@ TARGET_BASE_ARCH=i386 TARGET_SYSTBL_ABI=common,64 TARGET_SYSTBL=syscall_64.tbl TARGET_XML_FILES= gdb-xml/i386-64bit.xml gdb-xml/i386-64bit-linux.xml +TARGET_LONG_BITS=64 diff --git a/configs/targets/x86_64-softmmu.mak b/configs/targets/x86_64-softmmu.mak index 920e9a4200..1ceefde131 100644 --- a/configs/targets/x86_64-softmmu.mak +++ b/configs/targets/x86_64-softmmu.mak @@ -4,3 +4,4 @@ TARGET_SUPPORTS_MTTCG=y TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_KVM_HAVE_RESET_PARKED_VCPU=y TARGET_XML_FILES= gdb-xml/i386-64bit.xml +TARGET_LONG_BITS=64 diff --git a/configs/targets/xtensa-linux-user.mak b/configs/targets/xtensa-linux-user.mak index 420b30a68d..cbec6e368a 100644 --- a/configs/targets/xtensa-linux-user.mak +++ b/configs/targets/xtensa-linux-user.mak @@ -2,3 +2,4 @@ TARGET_ARCH=xtensa TARGET_SYSTBL_ABI=common TARGET_SYSTBL=syscall.tbl TARGET_HAS_BFLT=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/xtensa-softmmu.mak b/configs/targets/xtensa-softmmu.mak index f075557bfa..65845df4ff 100644 --- a/configs/targets/xtensa-softmmu.mak +++ b/configs/targets/xtensa-softmmu.mak @@ -1,2 +1,3 @@ TARGET_ARCH=xtensa TARGET_SUPPORTS_MTTCG=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/xtensaeb-linux-user.mak b/configs/targets/xtensaeb-linux-user.mak index bce2d1d65d..f455b1c780 100644 --- a/configs/targets/xtensaeb-linux-user.mak +++ b/configs/targets/xtensaeb-linux-user.mak @@ -3,3 +3,4 @@ TARGET_SYSTBL_ABI=common TARGET_SYSTBL=syscall.tbl TARGET_BIG_ENDIAN=y TARGET_HAS_BFLT=y +TARGET_LONG_BITS=32 diff --git a/configs/targets/xtensaeb-softmmu.mak b/configs/targets/xtensaeb-softmmu.mak index b02e11b820..f1f789d697 100644 --- a/configs/targets/xtensaeb-softmmu.mak +++ b/configs/targets/xtensaeb-softmmu.mak @@ -1,3 +1,4 @@ TARGET_ARCH=xtensa TARGET_BIG_ENDIAN=y TARGET_SUPPORTS_MTTCG=y +TARGET_LONG_BITS=32 diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index 4a3c302962..4c86620f6d 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -68,6 +68,19 @@ configurations (e.g. -smp drawers=1,books=1,clusters=1 for x86 PC machine) is marked deprecated since 9.0, users have to ensure that all the topology members described with -smp are supported by the target machine. +``-old-param`` option for booting Arm kernels via param_struct (since 10.0) +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +The ``-old-param`` command line option is specific to Arm targets: +it is used when directly booting a guest kernel to pass it the +command line and other information via the old ``param_struct`` ABI, +rather than the newer ATAGS or DTB mechanisms. This option was only +ever needed to support ancient kernels on some old board types +like the ``akita`` or ``terrier``; it has been deprecated in the +kernel since 2001. None of the board types QEMU supports need +``param_struct`` support, so this option has been deprecated and will +be removed in a future QEMU version. + User-mode emulator command line arguments ----------------------------------------- @@ -204,6 +217,34 @@ is going to be so much slower it wouldn't make sense for any serious instrumentation. Due to implementation differences there will also be anomalies in things like memory instrumentation. +32-bit host operating systems (since 10.0) +'''''''''''''''''''''''''''''''''''''''''' + +Keeping 32-bit host support alive is a substantial burden for the +QEMU project. Thus QEMU will in future drop the support for all +32-bit host systems. + +linux-user mode CPUs +-------------------- + +iwMMXt emulation and the ``pxa`` CPUs (since 10.0) +'''''''''''''''''''''''''''''''''''''''''''''''''' + +The ``pxa`` CPU family (``pxa250``, ``pxa255``, ``pxa260``, +``pxa261``, ``pxa262``, ``pxa270-a0``, ``pxa270-a1``, ``pxa270``, +``pxa270-b0``, ``pxa270-b1``, ``pxa270-c0``, ``pxa270-c5``) are no +longer used in system emulation, because all the machine types which +used these CPUs were removed in the QEMU 9.2 release. These CPUs can +now only be used in linux-user mode, and to do that you would have to +explicitly select one of these CPUs with the ``-cpu`` command line +option or the ``QEMU_CPU`` environment variable. + +We don't believe that anybody is using the iwMMXt emulation, and we do +not have any tests to validate it or any real hardware or similar +known-good implementation to test against. GCC is in the process of +dropping their support for iwMMXt codegen. These CPU types are +therefore deprecated in QEMU, and will be removed in a future release. + System emulator CPUs -------------------- diff --git a/docs/devel/index-process.rst b/docs/devel/index-process.rst index 362f97ee30..cb7c6640fd 100644 --- a/docs/devel/index-process.rst +++ b/docs/devel/index-process.rst @@ -17,3 +17,4 @@ Notes about how to interact with the community and how and where to submit patch stable-process submitting-a-pull-request secure-coding-practices + rust diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst index 3e26d2d104..9fa94251b0 100644 --- a/docs/devel/qapi-code-gen.rst +++ b/docs/devel/qapi-code-gen.rst @@ -1855,7 +1855,7 @@ Example:: #ifndef EXAMPLE_QAPI_INIT_COMMANDS_H #define EXAMPLE_QAPI_INIT_COMMANDS_H - #include "qapi/qmp/dispatch.h" + #include "qapi/qmp-registry.h" void example_qmp_init_marshal(QmpCommandList *cmds); @@ -1986,7 +1986,7 @@ Example:: #ifndef EXAMPLE_QAPI_INTROSPECT_H #define EXAMPLE_QAPI_INTROSPECT_H - #include "qapi/qmp/qlit.h" + #include "qobject/qlit.h" extern const QLitObject example_qmp_schema_qlit; diff --git a/docs/devel/rust.rst b/docs/devel/rust.rst new file mode 100644 index 0000000000..390aae4386 --- /dev/null +++ b/docs/devel/rust.rst @@ -0,0 +1,430 @@ +.. |msrv| replace:: 1.63.0 + +Rust in QEMU +============ + +Rust in QEMU is a project to enable using the Rust programming language +to add new functionality to QEMU. + +Right now, the focus is on making it possible to write devices that inherit +from ``SysBusDevice`` in `*safe*`__ Rust. Later, it may become possible +to write other kinds of devices (e.g. PCI devices that can do DMA), +complete boards, or backends (e.g. block device formats). + +__ https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html + +Building the Rust in QEMU code +------------------------------ + +The Rust in QEMU code is included in the emulators via Meson. Meson +invokes rustc directly, building static libraries that are then linked +together with the C code. This is completely automatic when you run +``make`` or ``ninja``. + +However, QEMU's build system also tries to be easy to use for people who +are accustomed to the more "normal" Cargo-based development workflow. +In particular: + +* the set of warnings and lints that are used to build QEMU always + comes from the ``rust/Cargo.toml`` workspace file + +* it is also possible to use ``cargo`` for common Rust-specific coding + tasks, in particular to invoke ``clippy``, ``rustfmt`` and ``rustdoc``. + +To this end, QEMU includes a ``build.rs`` build script that picks up +generated sources from QEMU's build directory and puts it in Cargo's +output directory (typically ``rust/target/``). A vanilla invocation +of Cargo will complain that it cannot find the generated sources, +which can be fixed in different ways: + +* by using special shorthand targets in the QEMU build directory:: + + make clippy + make rustfmt + make rustdoc + +* by invoking ``cargo`` through the Meson `development environment`__ + feature:: + + pyvenv/bin/meson devenv -w ../rust cargo clippy --tests + pyvenv/bin/meson devenv -w ../rust cargo fmt + + If you are going to use ``cargo`` repeatedly, ``pyvenv/bin/meson devenv`` + will enter a shell where commands like ``cargo clippy`` just work. + +__ https://mesonbuild.com/Commands.html#devenv + +* by pointing the ``MESON_BUILD_ROOT`` to the top of your QEMU build + tree. This third method is useful if you are using ``rust-analyzer``; + you can set the environment variable through the + ``rust-analyzer.cargo.extraEnv`` setting. + +As shown above, you can use the ``--tests`` option as usual to operate on test +code. Note however that you cannot *build* or run tests via ``cargo``, because +they need support C code from QEMU that Cargo does not know about. Tests can +be run via ``meson test`` or ``make``:: + + make check-rust + +Building Rust code with ``--enable-modules`` is not supported yet. + +Supported tools +''''''''''''''' + +QEMU supports rustc version 1.63.0 and newer. Notably, the following features +are missing: + +* ``core::ffi`` (1.64.0). Use ``std::os::raw`` and ``std::ffi`` instead. + +* ``cast_mut()``/``cast_const()`` (1.65.0). Use ``as`` instead. + +* "let ... else" (1.65.0). Use ``if let`` instead. This is currently patched + in QEMU's vendored copy of the bilge crate. + +* Generic Associated Types (1.65.0) + +* ``CStr::from_bytes_with_nul()`` as a ``const`` function (1.72.0). + +* "Return position ``impl Trait`` in Traits" (1.75.0, blocker for including + the pinned-init create). + +* ``MaybeUninit::zeroed()`` as a ``const`` function (1.75.0). QEMU's + ``Zeroable`` trait can be implemented without ``MaybeUninit::zeroed()``, + so this would be just a cleanup. + +* ``c"" literals`` (stable in 1.77.0). QEMU provides a ``c_str!()`` macro + to define ``CStr`` constants easily + +* ``offset_of!`` (stable in 1.77.0). QEMU uses ``offset_of!()`` heavily; it + provides a replacement in the ``qemu_api`` crate, but it does not support + lifetime parameters and therefore ``&'a Something`` fields in the struct + may have to be replaced by ``NonNull<Something>``. *Nested* ``offset_of!`` + was only stabilized in Rust 1.82.0, but it is not used. + +* inline const expression (stable in 1.79.0), currently worked around with + associated constants in the ``FnCall`` trait. + +* associated constants have to be explicitly marked ``'static`` (`changed in + 1.81.0`__) + +* ``&raw`` (stable in 1.82.0). Use ``addr_of!`` and ``addr_of_mut!`` instead, + though hopefully the need for raw pointers will go down over time. + +* ``new_uninit`` (stable in 1.82.0). This is used internally by the ``pinned_init`` + crate, which is planned for inclusion in QEMU, but it can be easily patched + out. + +* referencing statics in constants (stable in 1.83.0). For now use a const + function; this is an important limitation for QEMU's migration stream + architecture (VMState). Right now, VMState lacks type safety because + it is hard to place the ``VMStateField`` definitions in traits. + +* associated const equality would be nice to have for some users of + ``callbacks::FnCall``, but is still experimental. ``ASSERT_IS_SOME`` + replaces it. + +__ https://github.com/rust-lang/rust/pull/125258 + +It is expected that QEMU will advance its minimum supported version of +rustc to 1.77.0 as soon as possible; as of January 2025, blockers +for that right now are Debian bookworm and 32-bit MIPS processors. +This unfortunately means that references to statics in constants will +remain an issue. + +QEMU also supports version 0.60.x of bindgen, which is missing option +``--generate-cstr``. This option requires version 0.66.x and will +be adopted as soon as supporting these older versions is not necessary +anymore. + +Writing Rust code in QEMU +------------------------- + +Right now QEMU includes three crates: + +* ``qemu_api`` for bindings to C code and useful functionality + +* ``qemu_api_macros`` defines several procedural macros that are useful when + writing C code + +* ``pl011`` (under ``rust/hw/char/pl011``) is the sample device that is being + used to further develop ``qemu_api`` and ``qemu_api_macros``. It is a functional + replacement for the ``hw/char/pl011.c`` file. + +This section explains how to work with them. + +Status +'''''' + +Modules of ``qemu_api`` can be defined as: + +- *complete*: ready for use in new devices; if applicable, the API supports the + full functionality available in C + +- *stable*: ready for production use, the API is safe and should not undergo + major changes + +- *proof of concept*: the API is subject to change but allows working with safe + Rust + +- *initial*: the API is in its initial stages; it requires large amount of + unsafe code; it might have soundness or type-safety issues + +The status of the modules is as follows: + +================ ====================== +module status +================ ====================== +``assertions`` stable +``bitops`` complete +``callbacks`` complete +``cell`` stable +``c_str`` complete +``irq`` complete +``module`` complete +``offset_of`` stable +``qdev`` stable +``qom`` stable +``sysbus`` stable +``vmstate`` proof of concept +``zeroable`` stable +================ ====================== + +.. note:: + API stability is not a promise, if anything because the C APIs are not a stable + interface either. Also, ``unsafe`` interfaces may be replaced by safe interfaces + later. + +Common pitfalls +''''''''''''''' + +Rust has very strict rules with respect to how you get an exclusive (``&mut``) +reference; failure to respect those rules is a source of undefined behavior. +In particular, even if a value is loaded from a raw mutable pointer (``*mut``), +it *cannot* be casted to ``&mut`` unless the value was stored to the ``*mut`` +from a mutable reference. Furthermore, it is undefined behavior if any +shared reference was created between the store to the ``*mut`` and the load:: + + let mut p: u32 = 42; + let p_mut = &mut p; // 1 + let p_raw = p_mut as *mut u32; // 2 + + // p_raw keeps the mutable reference "alive" + + let p_shared = &p; // 3 + println!("access from &u32: {}", *p_shared); + + // Bring back the mutable reference, its lifetime overlaps + // with that of a shared reference. + let p_mut = unsafe { &mut *p_raw }; // 4 + println!("access from &mut 32: {}", *p_mut); + + println!("access from &u32: {}", *p_shared); // 5 + +These rules can be tested with `MIRI`__, for example. + +__ https://github.com/rust-lang/miri + +Almost all Rust code in QEMU will involve QOM objects, and pointers to these +objects are *shared*, for example because they are part of the QOM composition +tree. This creates exactly the above scenario: + +1. a QOM object is created + +2. a ``*mut`` is created, for example as the opaque value for a ``MemoryRegion`` + +3. the QOM object is placed in the composition tree + +4. a memory access dereferences the opaque value to a ``&mut`` + +5. but the shared reference is still present in the composition tree + +Because of this, QOM objects should almost always use ``&self`` instead +of ``&mut self``; access to internal fields must use *interior mutability* +to go from a shared reference to a ``&mut``. + +Whenever C code provides you with an opaque ``void *``, avoid converting it +to a Rust mutable reference, and use a shared reference instead. Rust code +will then have to use QEMU's ``BqlRefCell`` and ``BqlCell`` type, which +enforce that locking rules for the "Big QEMU Lock" are respected. These cell +types are also known to the ``vmstate`` crate, which is able to "look inside" +them when building an in-memory representation of a ``struct``s layout. +Note that the same is not true of a ``RefCell`` or ``Mutex``. + +In the future, similar cell types might also be provided for ``AioContext``-based +locking as well. + +Writing bindings to C code +'''''''''''''''''''''''''' + +Here are some things to keep in mind when working on the ``qemu_api`` crate. + +**Look at existing code** + Very often, similar idioms in C code correspond to similar tricks in + Rust bindings. If the C code uses ``offsetof``, look at qdev properties + or ``vmstate``. If the C code has a complex const struct, look at + ``MemoryRegion``. Reuse existing patterns for handling lifetimes; + for example use ``&T`` for QOM objects that do not need a reference + count (including those that can be embedded in other objects) and + ``Owned<T>`` for those that need it. + +**Use the type system** + Bindings often will need access information that is specific to a type + (either a builtin one or a user-defined one) in order to pass it to C + functions. Put them in a trait and access it through generic parameters. + The ``vmstate`` module has examples of how to retrieve type information + for the fields of a Rust ``struct``. + +**Prefer unsafe traits to unsafe functions** + Unsafe traits are much easier to prove correct than unsafe functions. + They are an excellent place to store metadata that can later be accessed + by generic functions. C code usually places metadata in global variables; + in Rust, they can be stored in traits and then turned into ``static`` + variables. Often, unsafe traits can be generated by procedural macros. + +**Document limitations due to old Rust versions** + If you need to settle for an inferior solution because of the currently + supported set of Rust versions, document it in the source and in this + file. This ensures that it can be fixed when the minimum supported + version is bumped. + +**Keep locking in mind**. + When marking a type ``Sync``, be careful of whether it needs the big + QEMU lock. Use ``BqlCell`` and ``BqlRefCell`` for interior data, + or assert ``bql_locked()``. + +**Don't be afraid of complexity, but document and isolate it** + It's okay to be tricky; device code is written more often than bindings + code and it's important that it is idiomatic. However, you should strive + to isolate any tricks in a place (for example a ``struct``, a trait + or a macro) where it can be documented and tested. If needed, include + toy versions of the code in the documentation. + +Writing procedural macros +''''''''''''''''''''''''' + +By conventions, procedural macros are split in two functions, one +returning ``Result<proc_macro2::TokenStream, MacroError>` with the body of +the procedural macro, and the second returning ``proc_macro::TokenStream`` +which is the actual procedural macro. The former's name is the same as +the latter with the ``_or_error`` suffix. The code for the latter is more +or less fixed; it follows the following template, which is fixed apart +from the type after ``as`` in the invocation of ``parse_macro_input!``:: + + #[proc_macro_derive(Object)] + pub fn derive_object(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let expanded = derive_object_or_error(input).unwrap_or_else(Into::into); + + TokenStream::from(expanded) + } + +The ``qemu_api_macros`` crate has utility functions to examine a +``DeriveInput`` and perform common checks (e.g. looking for a struct +with named fields). These functions return ``Result<..., MacroError>`` +and can be used easily in the procedural macro function:: + + fn derive_object_or_error(input: DeriveInput) -> + Result<proc_macro2::TokenStream, MacroError> + { + is_c_repr(&input, "#[derive(Object)]")?; + + let name = &input.ident; + let parent = &get_fields(&input, "#[derive(Object)]")?[0].ident; + ... + } + +Use procedural macros with care. They are mostly useful for two purposes: + +* Performing consistency checks; for example ``#[derive(Object)]`` checks + that the structure has ``#[repr[C])`` and that the type of the first field + is consistent with the ``ObjectType`` declaration. + +* Extracting information from Rust source code into traits, typically based + on types and attributes. For example, ``#[derive(TryInto)]`` builds an + implementation of ``TryFrom``, and it uses the ``#[repr(...)]`` attribute + as the ``TryFrom`` source and error types. + +Procedural macros can be hard to debug and test; if the code generation +exceeds a few lines of code, it may be worthwhile to delegate work to +"regular" declarative (``macro_rules!``) macros and write unit tests for +those instead. + + +Coding style +'''''''''''' + +Code should pass clippy and be formatted with rustfmt. + +Right now, only the nightly version of ``rustfmt`` is supported. This +might change in the future. While CI checks for correct formatting via +``cargo fmt --check``, maintainers can fix this for you when applying patches. + +It is expected that ``qemu_api`` provides full ``rustdoc`` documentation for +bindings that are in their final shape or close. + +Adding dependencies +------------------- + +Generally, the set of dependent crates is kept small. Think twice before +adding a new external crate, especially if it comes with a large set of +dependencies itself. Sometimes QEMU only needs a small subset of the +functionality; see for example QEMU's ``assertions`` or ``c_str`` modules. + +On top of this recommendation, adding external crates to QEMU is a +slightly complicated process, mostly due to the need to teach Meson how +to build them. While Meson has initial support for parsing ``Cargo.lock`` +files, it is still highly experimental and is therefore not used. + +Therefore, external crates must be added as subprojects for Meson to +learn how to build them, as well as to the relevant ``Cargo.toml`` files. +The versions specified in ``rust/Cargo.lock`` must be the same as the +subprojects; note that the ``rust/`` directory forms a Cargo `workspace`__, +and therefore there is a single lock file for the whole build. + +__ https://doc.rust-lang.org/cargo/reference/workspaces.html#virtual-workspace + +Choose a version of the crate that works with QEMU's minimum supported +Rust version (|msrv|). + +Second, a new ``wrap`` file must be added to teach Meson how to download the +crate. The wrap file must be named ``NAME-SEMVER-rs.wrap``, where ``NAME`` +is the name of the crate and ``SEMVER`` is the version up to and including the +first non-zero number. For example, a crate with version ``0.2.3`` will use +``0.2`` for its ``SEMVER``, while a crate with version ``1.0.84`` will use ``1``. + +Third, the Meson rules to build the crate must be added at +``subprojects/NAME-SEMVER-rs/meson.build``. Generally this includes: + +* ``subproject`` and ``dependency`` lines for all dependent crates + +* a ``static_library`` or ``rust.proc_macro`` line to perform the actual build + +* ``declare_dependency`` and a ``meson.override_dependency`` lines to expose + the result to QEMU and to other subprojects + +Remember to add ``native: true`` to ``dependency``, ``static_library`` and +``meson.override_dependency`` for dependencies of procedural macros. +If a crate is needed in both procedural macros and QEMU binaries, everything +apart from ``subproject`` must be duplicated to build both native and +non-native versions of the crate. + +It's important to specify the right compiler options. These include: + +* the language edition (which can be found in the ``Cargo.toml`` file) + +* the ``--cfg`` (which have to be "reverse engineered" from the ``build.rs`` + file of the crate). + +* usually, a ``--cap-lints allow`` argument to hide warnings from rustc + or clippy. + +After every change to the ``meson.build`` file you have to update the patched +version with ``meson subprojects update --reset ``NAME-SEMVER-rs``. This might +be automated in the future. + +Also, after every change to the ``meson.build`` file it is strongly suggested to +do a dummy change to the ``.wrap`` file (for example adding a comment like +``# version 2``), which will help Meson notice that the subproject is out of date. + +As a last step, add the new subproject to ``scripts/archive-source.sh``, +``scripts/make-release`` and ``subprojects/.gitignore``. diff --git a/dump/dump-hmp-cmds.c b/dump/dump-hmp-cmds.c index d9340427c3..21023db6fd 100644 --- a/dump/dump-hmp-cmds.c +++ b/dump/dump-hmp-cmds.c @@ -10,7 +10,7 @@ #include "monitor/monitor.h" #include "qapi/error.h" #include "qapi/qapi-commands-dump.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict) { diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index fee05d0a86..73621f4a97 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -126,7 +126,8 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b, float_raise(float_flag_invalid | float_flag_invalid_snan, s); } - if (infzero) { + if (infzero && + !(s->float_infzeronan_rule & float_infzeronan_suppress_invalid)) { /* This is (0 * inf) + NaN or (inf * 0) + NaN */ float_raise(float_flag_invalid | float_flag_invalid_imz, s); } @@ -144,7 +145,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b, * Inf * 0 + NaN -- some implementations return the * default NaN here, and some return the input NaN. */ - switch (s->float_infzeronan_rule) { + switch (s->float_infzeronan_rule & ~float_infzeronan_suppress_invalid) { case float_infzeronan_dnan_never: break; case float_infzeronan_dnan_always: diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index 4114e15ddd..2d0c99f159 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c @@ -20,7 +20,7 @@ #include "net/net.h" #include "system/system.h" #include "hw/intc/arm_gicv3.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qemu/log.h" static const hwaddr aspeed_soc_ast2700_memmap[] = { diff --git a/hw/arm/boot.c b/hw/arm/boot.c index cbc24356fc..42c18355e8 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -432,13 +432,12 @@ out: return ret; } -static void fdt_add_psci_node(void *fdt) +static void fdt_add_psci_node(void *fdt, ARMCPU *armcpu) { uint32_t cpu_suspend_fn; uint32_t cpu_off_fn; uint32_t cpu_on_fn; uint32_t migrate_fn; - ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0)); const char *psci_method; int64_t psci_conduit; int rc; @@ -512,7 +511,8 @@ static void fdt_add_psci_node(void *fdt) } int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, - hwaddr addr_limit, AddressSpace *as, MachineState *ms) + hwaddr addr_limit, AddressSpace *as, MachineState *ms, + ARMCPU *cpu) { void *fdt = NULL; int size, rc, n = 0; @@ -655,7 +655,7 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, } } - fdt_add_psci_node(fdt); + fdt_add_psci_node(fdt, cpu); if (binfo->modify_dtb) { binfo->modify_dtb(binfo, fdt); @@ -1327,7 +1327,8 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) * decided whether to enable PSCI and set the psci-conduit CPU properties. */ if (!info->skip_dtb_autoload && have_dtb(info)) { - if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms) < 0) { + if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, + as, ms, cpu) < 0) { exit(1); } } diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c index 88b9ccff49..dc86338b3a 100644 --- a/hw/arm/fsl-imx6.c +++ b/hw/arm/fsl-imx6.c @@ -117,6 +117,8 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) uint16_t i; qemu_irq irq; unsigned int smp_cpus = ms->smp.cpus; + DeviceState *mpcore = DEVICE(&s->a9mpcore); + DeviceState *gic; if (smp_cpus > FSL_IMX6_NUM_CPUS) { error_setg(errp, "%s: Only %d CPUs are supported (%d requested)", @@ -143,21 +145,21 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) } } - object_property_set_int(OBJECT(&s->a9mpcore), "num-cpu", smp_cpus, - &error_abort); + object_property_set_int(OBJECT(mpcore), "num-cpu", smp_cpus, &error_abort); - object_property_set_int(OBJECT(&s->a9mpcore), "num-irq", + object_property_set_int(OBJECT(mpcore), "num-irq", FSL_IMX6_MAX_IRQ + GIC_INTERNAL, &error_abort); - if (!sysbus_realize(SYS_BUS_DEVICE(&s->a9mpcore), errp)) { + if (!sysbus_realize(SYS_BUS_DEVICE(mpcore), errp)) { return; } - sysbus_mmio_map(SYS_BUS_DEVICE(&s->a9mpcore), 0, FSL_IMX6_A9MPCORE_ADDR); + sysbus_mmio_map(SYS_BUS_DEVICE(mpcore), 0, FSL_IMX6_A9MPCORE_ADDR); + gic = mpcore; for (i = 0; i < smp_cpus; i++) { - sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i, + sysbus_connect_irq(SYS_BUS_DEVICE(gic), i, qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_IRQ)); - sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i + smp_cpus, + sysbus_connect_irq(SYS_BUS_DEVICE(gic), i + smp_cpus, qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_FIQ)); } @@ -195,8 +197,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - serial_table[i].irq)); + qdev_get_gpio_in(gic, serial_table[i].irq)); } s->gpt.ccm = IMX_CCM(&s->ccm); @@ -207,8 +208,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt), 0, FSL_IMX6_GPT_ADDR); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), 0, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - FSL_IMX6_GPT_IRQ)); + qdev_get_gpio_in(gic, FSL_IMX6_GPT_IRQ)); /* Initialize all EPIT timers */ for (i = 0; i < FSL_IMX6_NUM_EPITS; i++) { @@ -228,8 +228,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - epit_table[i].irq)); + qdev_get_gpio_in(gic, epit_table[i].irq)); } /* Initialize all I2C */ @@ -249,8 +248,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - i2c_table[i].irq)); + qdev_get_gpio_in(gic, i2c_table[i].irq)); } /* Initialize all GPIOs */ @@ -307,11 +305,9 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - gpio_table[i].irq_low)); + qdev_get_gpio_in(gic, gpio_table[i].irq_low)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - gpio_table[i].irq_high)); + qdev_get_gpio_in(gic, gpio_table[i].irq_high)); } /* Initialize all SDHC */ @@ -338,8 +334,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) } sysbus_mmio_map(SYS_BUS_DEVICE(&s->esdhc[i]), 0, esdhc_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->esdhc[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - esdhc_table[i].irq)); + qdev_get_gpio_in(gic, esdhc_table[i].irq)); } /* USB */ @@ -360,8 +355,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0, FSL_IMX6_USBOH3_USB_ADDR + i * 0x200); sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - FSL_IMX6_USBn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6_USBn_IRQ[i])); } /* Initialize all ECSPI */ @@ -384,8 +378,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - spi_table[i].irq)); + qdev_get_gpio_in(gic, spi_table[i].irq)); } object_property_set_uint(OBJECT(&s->eth), "phy-num", s->phy_num, @@ -396,11 +389,9 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) } sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth), 0, FSL_IMX6_ENET_ADDR); sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth), 0, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - FSL_IMX6_ENET_MAC_IRQ)); + qdev_get_gpio_in(gic, FSL_IMX6_ENET_MAC_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth), 1, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - FSL_IMX6_ENET_MAC_1588_IRQ)); + qdev_get_gpio_in(gic, FSL_IMX6_ENET_MAC_1588_IRQ)); /* * SNVS @@ -427,8 +418,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX6_WDOGn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a9mpcore), - FSL_IMX6_WDOGn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6_WDOGn_IRQ[i])); } /* diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c index 79e4847953..34c4aa15cd 100644 --- a/hw/arm/fsl-imx6ul.c +++ b/hw/arm/fsl-imx6ul.c @@ -157,10 +157,12 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) { MachineState *ms = MACHINE(qdev_get_machine()); FslIMX6ULState *s = FSL_IMX6UL(dev); + DeviceState *mpcore = DEVICE(&s->a7mpcore); int i; char name[NAME_SIZE]; - SysBusDevice *sbd; - DeviceState *d; + DeviceState *gic; + SysBusDevice *gicsbd; + DeviceState *cpu; if (ms->smp.cpus > 1) { error_setg(errp, "%s: Only a single CPU is supported (%d requested)", @@ -173,19 +175,19 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) /* * A7MPCORE */ - object_property_set_int(OBJECT(&s->a7mpcore), "num-cpu", 1, &error_abort); - object_property_set_int(OBJECT(&s->a7mpcore), "num-irq", + object_property_set_int(OBJECT(mpcore), "num-cpu", 1, &error_abort); + object_property_set_int(OBJECT(mpcore), "num-irq", FSL_IMX6UL_MAX_IRQ + GIC_INTERNAL, &error_abort); - sysbus_realize(SYS_BUS_DEVICE(&s->a7mpcore), &error_abort); - sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR); + sysbus_realize(SYS_BUS_DEVICE(mpcore), &error_abort); + sysbus_mmio_map(SYS_BUS_DEVICE(mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR); - sbd = SYS_BUS_DEVICE(&s->a7mpcore); - d = DEVICE(&s->cpu); - - sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(d, ARM_CPU_IRQ)); - sysbus_connect_irq(sbd, 1, qdev_get_gpio_in(d, ARM_CPU_FIQ)); - sysbus_connect_irq(sbd, 2, qdev_get_gpio_in(d, ARM_CPU_VIRQ)); - sysbus_connect_irq(sbd, 3, qdev_get_gpio_in(d, ARM_CPU_VFIQ)); + gic = mpcore; + gicsbd = SYS_BUS_DEVICE(gic); + cpu = DEVICE(&s->cpu); + sysbus_connect_irq(gicsbd, 0, qdev_get_gpio_in(cpu, ARM_CPU_IRQ)); + sysbus_connect_irq(gicsbd, 1, qdev_get_gpio_in(cpu, ARM_CPU_FIQ)); + sysbus_connect_irq(gicsbd, 2, qdev_get_gpio_in(cpu, ARM_CPU_VIRQ)); + sysbus_connect_irq(gicsbd, 3, qdev_get_gpio_in(cpu, ARM_CPU_VFIQ)); /* * A7MPCORE DAP @@ -244,8 +246,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) FSL_IMX6UL_GPTn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_GPTn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_GPTn_IRQ[i])); } /* @@ -269,8 +270,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) FSL_IMX6UL_EPITn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_EPITn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_EPITn_IRQ[i])); } /* @@ -307,12 +307,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) FSL_IMX6UL_GPIOn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_GPIOn_LOW_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_GPIOn_LOW_IRQ[i])); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_GPIOn_HIGH_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_GPIOn_HIGH_IRQ[i])); } /* @@ -366,8 +364,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) FSL_IMX6UL_SPIn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_SPIn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_SPIn_IRQ[i])); } /* @@ -392,8 +389,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX6UL_I2Cn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_I2Cn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_I2Cn_IRQ[i])); } /* @@ -430,8 +426,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) FSL_IMX6UL_UARTn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_UARTn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_UARTn_IRQ[i])); } /* @@ -480,12 +475,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) FSL_IMX6UL_ENETn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_ENETn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_ENETn_IRQ[i])); sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_ENETn_TIMER_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_ENETn_TIMER_IRQ[i])); } /* @@ -521,8 +514,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0, FSL_IMX6UL_USB02_USBn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_USBn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_USBn_IRQ[i])); } /* @@ -547,8 +539,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) FSL_IMX6UL_USDHCn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_USDHCn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_USDHCn_IRQ[i])); } /* @@ -580,8 +571,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX6UL_WDOGn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX6UL_WDOGn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX6UL_WDOGn_IRQ[i])); } /* diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c index 004bf49937..3374018cde 100644 --- a/hw/arm/fsl-imx7.c +++ b/hw/arm/fsl-imx7.c @@ -166,7 +166,8 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) { MachineState *ms = MACHINE(qdev_get_machine()); FslIMX7State *s = FSL_IMX7(dev); - Object *o; + DeviceState *mpcore = DEVICE(&s->a7mpcore); + DeviceState *gic; int i; qemu_irq irq; char name[NAME_SIZE]; @@ -182,7 +183,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) * CPUs */ for (i = 0; i < smp_cpus; i++) { - o = OBJECT(&s->cpu[i]); + Object *o = OBJECT(&s->cpu[i]); /* On uniprocessor, the CBAR is set to 0 */ if (smp_cpus > 1) { @@ -205,16 +206,15 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) /* * A7MPCORE */ - object_property_set_int(OBJECT(&s->a7mpcore), "num-cpu", smp_cpus, - &error_abort); - object_property_set_int(OBJECT(&s->a7mpcore), "num-irq", + object_property_set_int(OBJECT(mpcore), "num-cpu", smp_cpus, &error_abort); + object_property_set_int(OBJECT(mpcore), "num-irq", FSL_IMX7_MAX_IRQ + GIC_INTERNAL, &error_abort); + sysbus_realize(SYS_BUS_DEVICE(mpcore), &error_abort); + sysbus_mmio_map(SYS_BUS_DEVICE(mpcore), 0, FSL_IMX7_A7MPCORE_ADDR); - sysbus_realize(SYS_BUS_DEVICE(&s->a7mpcore), &error_abort); - sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX7_A7MPCORE_ADDR); - + gic = mpcore; for (i = 0; i < smp_cpus; i++) { - SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore); + SysBusDevice *sbd = SYS_BUS_DEVICE(gic); DeviceState *d = DEVICE(qemu_get_cpu(i)); irq = qdev_get_gpio_in(d, ARM_CPU_IRQ); @@ -255,8 +255,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), &error_abort); sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, FSL_IMX7_GPTn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX7_GPTn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX7_GPTn_IRQ[i])); } /* @@ -298,12 +297,10 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) FSL_IMX7_GPIOn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX7_GPIOn_LOW_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX7_GPIOn_LOW_IRQ[i])); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX7_GPIOn_HIGH_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX7_GPIOn_HIGH_IRQ[i])); } /* @@ -355,8 +352,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, FSL_IMX7_SPIn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX7_SPIn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX7_SPIn_IRQ[i])); } /* @@ -381,8 +377,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX7_I2Cn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX7_I2Cn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX7_I2Cn_IRQ[i])); } /* @@ -416,7 +411,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, FSL_IMX7_UARTn_ADDR[i]); - irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_UARTn_IRQ[i]); + irq = qdev_get_gpio_in(gic, FSL_IMX7_UARTn_IRQ[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, irq); } @@ -454,9 +449,9 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0, FSL_IMX7_ENETn_ADDR[i]); - irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 0)); + irq = qdev_get_gpio_in(gic, FSL_IMX7_ENET_IRQ(i, 0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0, irq); - irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 3)); + irq = qdev_get_gpio_in(gic, FSL_IMX7_ENET_IRQ(i, 3)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1, irq); } @@ -483,7 +478,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0, FSL_IMX7_USDHCn_ADDR[i]); - irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USDHCn_IRQ[i]); + irq = qdev_get_gpio_in(gic, FSL_IMX7_USDHCn_IRQ[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, irq); } @@ -522,8 +517,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX7_WDOGn_ADDR[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0, - qdev_get_gpio_in(DEVICE(&s->a7mpcore), - FSL_IMX7_WDOGn_IRQ[i])); + qdev_get_gpio_in(gic, FSL_IMX7_WDOGn_IRQ[i])); } /* @@ -606,11 +600,11 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_MSI_IRQ); qdev_connect_gpio_out(DEVICE(&s->pcie4_msi_irq), 0, irq); - irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ); + irq = qdev_get_gpio_in(gic, FSL_IMX7_PCI_INTA_IRQ); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq); - irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ); + irq = qdev_get_gpio_in(gic, FSL_IMX7_PCI_INTB_IRQ); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq); - irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ); + irq = qdev_get_gpio_in(gic, FSL_IMX7_PCI_INTC_IRQ); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq); irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 0); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq); @@ -643,7 +637,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0, FSL_IMX7_USBn_ADDR[i]); - irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USBn_IRQ[i]); + irq = qdev_get_gpio_in(gic, FSL_IMX7_USBn_IRQ[i]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0, irq); snprintf(name, NAME_SIZE, "usbmisc%d", i); diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index d3a9f1b03a..13ed868b6b 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -48,7 +48,7 @@ #include "qemu/units.h" #include "qemu/cutils.h" #include "qapi/error.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qemu/error-report.h" #include "hw/arm/boot.h" #include "hw/arm/armv7m.h" diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c index 56b2af40f1..3f8db0cab6 100644 --- a/hw/arm/mps2.c +++ b/hw/arm/mps2.c @@ -48,7 +48,7 @@ #include "net/net.h" #include "hw/watchdog/cmsdk-apb-watchdog.h" #include "hw/qdev-clock.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qom/object.h" typedef enum MPS2FPGAType { diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c index 2b104671db..1bddb5e822 100644 --- a/hw/arm/mps3r.c +++ b/hw/arm/mps3r.c @@ -27,7 +27,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qapi/error.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "exec/address-spaces.h" #include "cpu.h" #include "system/system.h" diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 6183111f2d..e720de3064 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -48,7 +48,7 @@ #include "hw/char/pl011.h" #include "hw/watchdog/sbsa_gwdt.h" #include "net/net.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qom/object.h" #include "target/arm/cpu-qom.h" #include "target/arm/gtimer.h" diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index c3c3fd0410..47c1cfa048 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -32,7 +32,7 @@ #include "hw/timer/stellaris-gptm.h" #include "hw/qdev-clock.h" #include "qom/object.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "ui/input.h" #define GPIO_A 0 diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 42c6703406..b886d16c02 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -42,7 +42,7 @@ #include "hw/cpu/a15mpcore.h" #include "hw/i2c/arm_sbcon_i2c.h" #include "hw/sd/sd.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qom/object.h" #include "audio/audio.h" #include "target/arm/cpu-qom.h" diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 99e0a68b6c..4a5a9666e9 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -70,7 +70,7 @@ #include "hw/firmware/smbios.h" #include "qapi/visitor.h" #include "qapi/qapi-visit-common.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "standard-headers/linux/input.h" #include "hw/arm/smmuv3.h" #include "hw/acpi/acpi.h" @@ -1746,7 +1746,7 @@ void virt_machine_done(Notifier *notifier, void *data) vms->memmap[VIRT_PLATFORM_BUS].size, vms->irqmap[VIRT_PLATFORM_BUS]); } - if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms) < 0) { + if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms, cpu) < 0) { exit(1); } diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index cccdd99fcc..278545a3f7 100644 --- a/hw/arm/xlnx-versal.c +++ b/hw/arm/xlnx-versal.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qapi/error.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qemu/module.h" #include "hw/sysbus.h" #include "net/net.h" diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index e0acce89e1..a1829e3abd 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1562,15 +1562,6 @@ static bool virtio_blk_vq_aio_context_init(VirtIOBlock *s, Error **errp) error_setg(errp, "ioeventfd is required for iothread"); return false; } - - /* - * If ioeventfd is (re-)enabled while the guest is running there could - * be block jobs that can conflict. - */ - if (blk_op_is_blocked(conf->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { - error_prepend(errp, "cannot start virtio-blk ioeventfd: "); - return false; - } } s->vq_aio_context = g_new(AioContext *, conf->num_queues); diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index 034a18b70e..6c26052561 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -16,8 +16,8 @@ #include "qapi/qapi-visit-block-core.h" #include "qapi/qobject-input-visitor.h" #include "qapi/visitor.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qom/object_interfaces.h" #include "hw/block/xen_blkif.h" #include "hw/qdev-properties.h" diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c index 916727961c..c6325cdcaa 100644 --- a/hw/core/machine-hmp-cmds.c +++ b/hw/core/machine-hmp-cmds.c @@ -19,7 +19,7 @@ #include "qapi/error.h" #include "qapi/qapi-builtin-visit.h" #include "qapi/qapi-commands-machine.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/string-output-visitor.h" #include "qemu/error-report.h" #include "system/numa.h" diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index 4eefe6ba86..3130c5cd45 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -15,7 +15,7 @@ #include "qapi/error.h" #include "qapi/qapi-builtin-visit.h" #include "qapi/qapi-commands-machine.h" -#include "qapi/qmp/qobject.h" +#include "qobject/qobject.h" #include "qapi/qobject-input-visitor.h" #include "qapi/type-helpers.h" #include "qemu/uuid.h" diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 434a76f503..0b52aad555 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -2,7 +2,7 @@ #include "hw/qdev-properties.h" #include "qapi/error.h" #include "qapi/qapi-types-misc.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qemu/ctype.h" #include "qemu/error-report.h" #include "qapi/visitor.h" diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 82bbdcb654..2745b5e092 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -28,7 +28,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/qapi-events-qdev.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/visitor.h" #include "qemu/error-report.h" #include "qemu/option.h" diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c index 3b0897e54e..d24ab0a6ab 100644 --- a/hw/cpu/a15mpcore.c +++ b/hw/cpu/a15mpcore.c @@ -164,17 +164,14 @@ static void a15mp_priv_class_init(ObjectClass *klass, void *data) /* We currently have no saveable state */ } -static const TypeInfo a15mp_priv_info = { - .name = TYPE_A15MPCORE_PRIV, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(A15MPPrivState), - .instance_init = a15mp_priv_initfn, - .class_init = a15mp_priv_class_init, +static const TypeInfo a15mp_types[] = { + { + .name = TYPE_A15MPCORE_PRIV, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(A15MPPrivState), + .instance_init = a15mp_priv_initfn, + .class_init = a15mp_priv_class_init, + }, }; -static void a15mp_register_types(void) -{ - type_register_static(&a15mp_priv_info); -} - -type_init(a15mp_register_types) +DEFINE_TYPES(a15mp_types) diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c index 9671585b5f..25416c5032 100644 --- a/hw/cpu/a9mpcore.c +++ b/hw/cpu/a9mpcore.c @@ -177,17 +177,14 @@ static void a9mp_priv_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, a9mp_priv_properties); } -static const TypeInfo a9mp_priv_info = { - .name = TYPE_A9MPCORE_PRIV, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(A9MPPrivState), - .instance_init = a9mp_priv_initfn, - .class_init = a9mp_priv_class_init, +static const TypeInfo a9mp_types[] = { + { + .name = TYPE_A9MPCORE_PRIV, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(A9MPPrivState), + .instance_init = a9mp_priv_initfn, + .class_init = a9mp_priv_class_init, + }, }; -static void a9mp_register_types(void) -{ - type_register_static(&a9mp_priv_info); -} - -type_init(a9mp_register_types) +DEFINE_TYPES(a9mp_types) diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c index 94861a06d9..b56bee6d54 100644 --- a/hw/cpu/arm11mpcore.c +++ b/hw/cpu/arm11mpcore.c @@ -152,17 +152,14 @@ static void mpcore_priv_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, mpcore_priv_properties); } -static const TypeInfo mpcore_priv_info = { - .name = TYPE_ARM11MPCORE_PRIV, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(ARM11MPCorePriveState), - .instance_init = mpcore_priv_initfn, - .class_init = mpcore_priv_class_init, +static const TypeInfo arm11mp_types[] = { + { + .name = TYPE_ARM11MPCORE_PRIV, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(ARM11MPCorePriveState), + .instance_init = mpcore_priv_initfn, + .class_init = mpcore_priv_class_init, + }, }; -static void arm11mpcore_register_types(void) -{ - type_register_static(&mpcore_priv_info); -} - -type_init(arm11mpcore_register_types) +DEFINE_TYPES(arm11mp_types) diff --git a/hw/cpu/realview_mpcore.c b/hw/cpu/realview_mpcore.c index 4268735e3a..b140888618 100644 --- a/hw/cpu/realview_mpcore.c +++ b/hw/cpu/realview_mpcore.c @@ -14,7 +14,6 @@ #include "hw/cpu/arm11mpcore.h" #include "hw/intc/realview_gic.h" #include "hw/irq.h" -#include "hw/qdev-properties.h" #include "qom/object.h" #define TYPE_REALVIEW_MPCORE_RIRQ "realview_mpcore" @@ -68,7 +67,6 @@ static void realview_mpcore_realize(DeviceState *dev, Error **errp) int n; int i; - qdev_prop_set_uint32(priv, "num-cpu", s->num_cpu); if (!sysbus_realize(SYS_BUS_DEVICE(&s->priv), errp)) { return; } @@ -100,6 +98,7 @@ static void mpcore_rirq_init(Object *obj) int i; object_initialize_child(obj, "a11priv", &s->priv, TYPE_ARM11MPCORE_PRIV); + object_property_add_alias(obj, "num-cpu", OBJECT(&s->priv), "num-cpu"); privbusdev = SYS_BUS_DEVICE(&s->priv); sysbus_init_mmio(sbd, sysbus_mmio_get_region(privbusdev, 0)); @@ -108,29 +107,21 @@ static void mpcore_rirq_init(Object *obj) } } -static const Property mpcore_rirq_properties[] = { - DEFINE_PROP_UINT32("num-cpu", mpcore_rirq_state, num_cpu, 1), -}; - static void mpcore_rirq_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = realview_mpcore_realize; - device_class_set_props(dc, mpcore_rirq_properties); } -static const TypeInfo mpcore_rirq_info = { - .name = TYPE_REALVIEW_MPCORE_RIRQ, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(mpcore_rirq_state), - .instance_init = mpcore_rirq_init, - .class_init = mpcore_rirq_class_init, +static const TypeInfo realview_mpcore_types[] = { + { + .name = TYPE_REALVIEW_MPCORE_RIRQ, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(mpcore_rirq_state), + .instance_init = mpcore_rirq_init, + .class_init = mpcore_rirq_class_init, + }, }; -static void realview_mpcore_register_types(void) -{ - type_register_static(&mpcore_rirq_info); -} - -type_init(realview_mpcore_register_types) +DEFINE_TYPES(realview_mpcore_types) diff --git a/hw/hyperv/hv-balloon.c b/hw/hyperv/hv-balloon.c index e21fc675a6..6f33c3e741 100644 --- a/hw/hyperv/hv-balloon.c +++ b/hw/hyperv/hv-balloon.c @@ -26,7 +26,7 @@ #include "qapi/qapi-commands-machine.h" #include "qapi/qapi-events-machine.h" #include "qapi/qapi-types-machine.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/visitor.h" #include "qemu/error-report.h" #include "qemu/module.h" diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 53b7306b43..3fffa4a332 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -22,7 +22,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qnum.h" #include "acpi-build.h" #include "acpi-common.h" #include "qemu/bitmap.h" diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 58484f308e..9b8b092bc2 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -20,7 +20,7 @@ #include "monitor/hmp.h" #include "qapi/error.h" #include "qapi/qapi-commands-misc-target.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qom/object.h" #include "exec/target_page.h" #include "exec/address-spaces.h" diff --git a/hw/i386/monitor.c b/hw/i386/monitor.c index 1ebd3564bf..1921e4d52e 100644 --- a/hw/i386/monitor.c +++ b/hw/i386/monitor.c @@ -24,7 +24,7 @@ #include "qemu/osdep.h" #include "monitor/monitor.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/error.h" #include "qapi/qapi-commands-misc-target.h" #include "hw/i386/x86.h" diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b46975c8a4..0eb52d315b 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -44,7 +44,7 @@ #include "system/reset.h" #include "kvm/kvm_i386.h" #include "hw/xen/xen.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qemu/error-report.h" #include "hw/acpi/cpu_hotplug.h" #include "acpi-build.h" diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index f744054a6d..80fbbacc1e 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -909,8 +909,8 @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr, /* Compare A, B, C */ for (j = 0; j < 3; j++) { - uint32_t cr0, cr1, mask, compare; - uint16_t rx_cmp; + uint32_t cr0, cr1, mask, compare, disable_mask; + uint32_t rx_cmp; int offset; int cr_idx = extract32(reg, R_SCREENING_TYPE2_REG0_COMPARE_A_SHIFT + j * 6, R_SCREENING_TYPE2_REG0_COMPARE_A_LENGTH); @@ -946,9 +946,25 @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr, break; } - rx_cmp = rxbuf_ptr[offset] << 8 | rxbuf_ptr[offset]; - mask = FIELD_EX32(cr0, TYPE2_COMPARE_0_WORD_0, MASK_VALUE); - compare = FIELD_EX32(cr0, TYPE2_COMPARE_0_WORD_0, COMPARE_VALUE); + disable_mask = + FIELD_EX32(cr1, TYPE2_COMPARE_0_WORD_1, DISABLE_MASK); + if (disable_mask) { + /* + * If disable_mask is set, mask_value is used as an + * additional 2 byte Compare Value; that is equivalent + * to using the whole cr0 register as the comparison value. + * Load 32 bits of data from rx_buf, and set mask to + * all-ones so we compare all 32 bits. + */ + rx_cmp = ldl_le_p(rxbuf_ptr + offset); + mask = 0xFFFFFFFF; + compare = cr0; + } else { + rx_cmp = lduw_le_p(rxbuf_ptr + offset); + mask = FIELD_EX32(cr0, TYPE2_COMPARE_0_WORD_0, MASK_VALUE); + compare = + FIELD_EX32(cr0, TYPE2_COMPARE_0_WORD_0, COMPARE_VALUE); + } if ((rx_cmp & mask) == (compare & mask)) { matched = true; diff --git a/hw/net/rocker/rocker-hmp-cmds.c b/hw/net/rocker/rocker-hmp-cmds.c index 197c6e28dc..df40991f6d 100644 --- a/hw/net/rocker/rocker-hmp-cmds.c +++ b/hw/net/rocker/rocker-hmp-cmds.c @@ -18,7 +18,7 @@ #include "monitor/monitor.h" #include "net/eth.h" #include "qapi/qapi-commands-rocker.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" void hmp_rocker(Monitor *mon, const QDict *qdict) { diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 85e14b788c..d847429b1c 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -26,7 +26,7 @@ #include "qemu/option.h" #include "qemu/option_int.h" #include "qemu/config-file.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "hw/virtio/virtio-net.h" #include "net/vhost_net.h" #include "net/announce.h" diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 5410039490..c48691207d 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -24,7 +24,7 @@ #include "qemu/cutils.h" #include "qemu/log.h" #include "qemu/qemu-print.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/error.h" #include <sys/socket.h> diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c index fdfe44435c..a5f6483cc3 100644 --- a/hw/pci/pci-hmp-cmds.c +++ b/hw/pci/pci-hmp-cmds.c @@ -20,7 +20,7 @@ #include "monitor/monitor.h" #include "pci-internal.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qapi-commands-pci.h" #include "qemu/cutils.h" diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 0364243f4f..b057672e82 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -33,7 +33,7 @@ #include "kvm_ppc.h" #include "exec/address-spaces.h" #include "qom/qom-qobject.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "trace.h" #include "qemu/datadir.h" #include "system/device_tree.h" diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 2435397e94..549b652c20 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/qnull.h" +#include "qobject/qnull.h" #include "qemu/cutils.h" #include "hw/ppc/spapr_drc.h" #include "qom/object.h" diff --git a/hw/rx/rx62n.c b/hw/rx/rx62n.c index 8c1d1023ed..e6bac4f053 100644 --- a/hw/rx/rx62n.c +++ b/hw/rx/rx62n.c @@ -29,7 +29,7 @@ #include "hw/sysbus.h" #include "hw/qdev-properties.h" #include "system/system.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qom/object.h" /* diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c index 995817f4a3..811d892122 100644 --- a/hw/s390x/s390-skeys.c +++ b/hw/s390x/s390-skeys.c @@ -16,7 +16,7 @@ #include "hw/s390x/storage-keys.h" #include "qapi/error.h" #include "qapi/qapi-commands-misc-target.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/error-report.h" #include "system/memory_mapping.h" #include "exec/address-spaces.h" diff --git a/hw/s390x/s390-stattrib.c b/hw/s390x/s390-stattrib.c index 8e07acbddc..be07c28c6e 100644 --- a/hw/s390x/s390-stattrib.c +++ b/hw/s390x/s390-stattrib.c @@ -18,7 +18,7 @@ #include "qemu/error-report.h" #include "exec/ram_addr.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "cpu.h" /* 512KiB cover 2GB of guest memory */ diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 23516995dc..7d094e1881 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -1065,9 +1065,6 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, int ret; if (s->ctx && !s->dataplane_fenced) { - if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { - return; - } ret = blk_set_aio_context(sd->conf.blk, s->ctx, errp); if (ret < 0) { return; diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c index 13901625c0..13b065b0fa 100644 --- a/hw/usb/xen-usb.c +++ b/hw/usb/xen-usb.c @@ -30,8 +30,8 @@ #include "hw/xen/xen-legacy-backend.h" #include "monitor/qdev.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "hw/xen/interface/io/usbif.h" diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index ab17a98ee5..9a55e7b773 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -30,7 +30,7 @@ #include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" #include "migration/vmstate.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "qemu/module.h" diff --git a/hw/virtio/virtio-hmp-cmds.c b/hw/virtio/virtio-hmp-cmds.c index 477c97dea2..7d8677bcf0 100644 --- a/hw/virtio/virtio-hmp-cmds.c +++ b/hw/virtio/virtio-hmp-cmds.c @@ -9,7 +9,7 @@ #include "monitor/hmp.h" #include "monitor/monitor.h" #include "qapi/qapi-commands-virtio.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" static void hmp_virtio_dump_protocols(Monitor *mon, diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c index 8a32a3b105..3b6377cf0d 100644 --- a/hw/virtio/virtio-qmp.c +++ b/hw/virtio/virtio-qmp.c @@ -15,8 +15,8 @@ #include "qapi/error.h" #include "qapi/qapi-commands-virtio.h" #include "qapi/qapi-commands-qom.h" -#include "qapi/qmp/qobject.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qobject.h" +#include "qobject/qjson.h" #include "hw/virtio/vhost-user.h" #include "standard-headers/linux/virtio_ids.h" diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index feeb612681..8260f1e1bb 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -18,7 +18,7 @@ #include "hw/xen/xen-bus-helper.h" #include "monitor/monitor.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "system/system.h" #include "net/net.h" #include "trace.h" diff --git a/include/block/block-common.h b/include/block/block-common.h index 338fe5ff7a..0b831ef87b 100644 --- a/include/block/block-common.h +++ b/include/block/block-common.h @@ -257,6 +257,7 @@ typedef enum { #define BDRV_OPT_AUTO_READ_ONLY "auto-read-only" #define BDRV_OPT_DISCARD "discard" #define BDRV_OPT_FORCE_SHARE "force-share" +#define BDRV_OPT_ACTIVE "active" #define BDRV_SECTOR_BITS 9 @@ -355,7 +356,6 @@ typedef enum BlockOpType { BLOCK_OP_TYPE_CHANGE, BLOCK_OP_TYPE_COMMIT_SOURCE, BLOCK_OP_TYPE_COMMIT_TARGET, - BLOCK_OP_TYPE_DATAPLANE, BLOCK_OP_TYPE_DRIVE_DEL, BLOCK_OP_TYPE_EJECT, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index bd7cecd1cf..9be34b3c99 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -175,12 +175,18 @@ BlockDriverState * GRAPH_RDLOCK check_to_replace_node(BlockDriverState *parent_bs, const char *node_name, Error **errp); + +bool GRAPH_RDLOCK bdrv_is_inactive(BlockDriverState *bs); + int no_coroutine_fn GRAPH_RDLOCK bdrv_activate(BlockDriverState *bs, Error **errp); int coroutine_fn no_co_wrapper_bdrv_rdlock bdrv_co_activate(BlockDriverState *bs, Error **errp); +int no_coroutine_fn +bdrv_inactivate(BlockDriverState *bs, Error **errp); + void bdrv_activate_all(Error **errp); int bdrv_inactivate_all(void); diff --git a/include/block/export.h b/include/block/export.h index f2fe0f8078..4bd9531d4d 100644 --- a/include/block/export.h +++ b/include/block/export.h @@ -29,6 +29,9 @@ typedef struct BlockExportDriver { */ size_t instance_size; + /* True if the export type supports running on an inactive node */ + bool supports_inactive; + /* Creates and starts a new block export */ int (*create)(BlockExport *, BlockExportOptions *, Error **); diff --git a/include/block/qdict.h b/include/block/qdict.h index b4c28d96a9..53c4df4cb2 100644 --- a/include/block/qdict.h +++ b/include/block/qdict.h @@ -10,7 +10,7 @@ #ifndef BLOCK_QDICT_H #define BLOCK_QDICT_H -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" QObject *qdict_crumple(const QDict *src, Error **errp); void qdict_flatten(QDict *qdict); diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h index 616c290145..2e43d1dd9e 100644 --- a/include/fpu/softfloat-types.h +++ b/include/fpu/softfloat-types.h @@ -280,11 +280,21 @@ typedef enum __attribute__((__packed__)) { /* No propagation rule specified */ float_infzeronan_none = 0, /* Result is never the default NaN (so always the input NaN) */ - float_infzeronan_dnan_never, + float_infzeronan_dnan_never = 1, /* Result is always the default NaN */ - float_infzeronan_dnan_always, + float_infzeronan_dnan_always = 2, /* Result is the default NaN if the input NaN is quiet */ - float_infzeronan_dnan_if_qnan, + float_infzeronan_dnan_if_qnan = 3, + /* + * Don't raise Invalid for 0 * Inf + NaN. Default is to raise. + * IEEE 754-2008 section 7.2 makes it implementation defined whether + * 0 * Inf + QNaN raises Invalid or not. Note that 0 * Inf + SNaN will + * raise the Invalid flag for the SNaN anyway. + * + * This is a flag which can be ORed in with any of the above + * DNaN behaviour options. + */ + float_infzeronan_suppress_invalid = (1 << 7), } FloatInfZeroNaNRule; /* diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index 80c492d742..b12bf61ca8 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -160,6 +160,7 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu, * @binfo: struct describing the boot environment * @addr_limit: upper limit of the available memory area at @addr * @as: address space to load image to + * @cpu: ARM CPU object * * Load a device tree supplied by the machine or by the user with the * '-dtb' command line option, and put it at offset @addr in target @@ -176,7 +177,8 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu, * Note: Must not be called unless have_dtb(binfo) is true. */ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, - hwaddr addr_limit, AddressSpace *as, MachineState *ms); + hwaddr addr_limit, AddressSpace *as, MachineState *ms, + ARMCPU *cpu); /* Write a secure board setup routine with a dummy handler for SMCs */ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu, diff --git a/include/qapi/compat-policy.h b/include/qapi/compat-policy.h index 8b7b25c0b5..ea65e10744 100644 --- a/include/qapi/compat-policy.h +++ b/include/qapi/compat-policy.h @@ -18,7 +18,7 @@ extern CompatPolicy compat_policy; -bool compat_policy_input_ok(unsigned special_features, +bool compat_policy_input_ok(uint64_t features, const CompatPolicy *policy, ErrorClass error_class, const char *kind, const char *name, diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp-registry.h index f2e956813a..e0ee1ad3ac 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp-registry.h @@ -33,7 +33,7 @@ typedef struct QmpCommand /* Runs in coroutine context if QCO_COROUTINE is set */ QmpCommandFunc *fn; QmpCommandOptions options; - unsigned special_features; + uint64_t features; QTAILQ_ENTRY(QmpCommand) node; bool enabled; const char *disable_reason; @@ -43,7 +43,7 @@ typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList; void qmp_register_command(QmpCommandList *cmds, const char *name, QmpCommandFunc *fn, QmpCommandOptions options, - unsigned special_features); + uint64_t features); const QmpCommand *qmp_find_command(const QmpCommandList *cmds, const char *name); void qmp_disable_command(QmpCommandList *cmds, const char *name, diff --git a/include/qapi/util.h b/include/qapi/util.h index b8254247b8..29bc4eb865 100644 --- a/include/qapi/util.h +++ b/include/qapi/util.h @@ -18,7 +18,7 @@ typedef enum { typedef struct QEnumLookup { const char *const *array; - const unsigned char *const special_features; + const uint64_t *const features; const int size; } QEnumLookup; diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index 2badec5ba4..7beb0dbfa5 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -115,11 +115,11 @@ struct Visitor /* Optional */ bool (*policy_reject)(Visitor *v, const char *name, - unsigned special_features, Error **errp); + uint64_t features, Error **errp); /* Optional */ bool (*policy_skip)(Visitor *v, const char *name, - unsigned special_features); + uint64_t features); /* Must be set */ VisitorType type; diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 27b85d4700..f6a9b0743f 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -463,29 +463,29 @@ bool visit_optional(Visitor *v, const char *name, bool *present); /* * Should we reject member @name due to policy? * - * @special_features is the member's special features encoded as a - * bitset of QapiSpecialFeature. + * @features is the member's special features encoded as a + * bitset of QapiFeature. * * @name must not be NULL. This function is only useful between * visit_start_struct() and visit_end_struct(), since only objects * have deprecated members. */ bool visit_policy_reject(Visitor *v, const char *name, - unsigned special_features, Error **errp); + uint64_t features, Error **errp); /* * * Should we skip member @name due to policy? * - * @special_features is the member's special features encoded as a - * bitset of QapiSpecialFeature. + * @features is the member's special features encoded as a + * bitset of QapiFeature. * * @name must not be NULL. This function is only useful between * visit_start_struct() and visit_end_struct(), since only objects * have deprecated members. */ bool visit_policy_skip(Visitor *v, const char *name, - unsigned special_features); + uint64_t features); /* * Set policy for handling deprecated management interfaces. diff --git a/include/qapi/qmp/json-parser.h b/include/qobject/json-parser.h index 7345a9bd5c..7345a9bd5c 100644 --- a/include/qapi/qmp/json-parser.h +++ b/include/qobject/json-parser.h diff --git a/include/qapi/qmp/json-writer.h b/include/qobject/json-writer.h index b70ba64077..b70ba64077 100644 --- a/include/qapi/qmp/json-writer.h +++ b/include/qobject/json-writer.h diff --git a/include/qapi/qmp/qbool.h b/include/qobject/qbool.h index 0d09726939..b348e17867 100644 --- a/include/qapi/qmp/qbool.h +++ b/include/qobject/qbool.h @@ -14,7 +14,7 @@ #ifndef QBOOL_H #define QBOOL_H -#include "qapi/qmp/qobject.h" +#include "qobject/qobject.h" struct QBool { struct QObjectBase_ base; diff --git a/include/qapi/qmp/qdict.h b/include/qobject/qdict.h index 82e90fc072..903e6e5462 100644 --- a/include/qapi/qmp/qdict.h +++ b/include/qobject/qdict.h @@ -13,7 +13,7 @@ #ifndef QDICT_H #define QDICT_H -#include "qapi/qmp/qobject.h" +#include "qobject/qobject.h" #include "qemu/queue.h" #define QDICT_BUCKET_MAX 512 diff --git a/include/qapi/qmp/qjson.h b/include/qobject/qjson.h index 7bd8d2de1b..7bd8d2de1b 100644 --- a/include/qapi/qmp/qjson.h +++ b/include/qobject/qjson.h diff --git a/include/qapi/qmp/qlist.h b/include/qobject/qlist.h index e4e985d435..0377bf824e 100644 --- a/include/qapi/qmp/qlist.h +++ b/include/qobject/qlist.h @@ -13,7 +13,7 @@ #ifndef QLIST_H #define QLIST_H -#include "qapi/qmp/qobject.h" +#include "qobject/qobject.h" #include "qemu/queue.h" typedef struct QListEntry { diff --git a/include/qapi/qmp/qlit.h b/include/qobject/qlit.h index c0676d5daf..c0676d5daf 100644 --- a/include/qapi/qmp/qlit.h +++ b/include/qobject/qlit.h diff --git a/include/qapi/qmp/qnull.h b/include/qobject/qnull.h index 7feb7c7d83..4423836a0c 100644 --- a/include/qapi/qmp/qnull.h +++ b/include/qobject/qnull.h @@ -13,7 +13,7 @@ #ifndef QNULL_H #define QNULL_H -#include "qapi/qmp/qobject.h" +#include "qobject/qobject.h" struct QNull { struct QObjectBase_ base; diff --git a/include/qapi/qmp/qnum.h b/include/qobject/qnum.h index e86788dd2e..1ce24b3668 100644 --- a/include/qapi/qmp/qnum.h +++ b/include/qobject/qnum.h @@ -15,7 +15,7 @@ #ifndef QNUM_H #define QNUM_H -#include "qapi/qmp/qobject.h" +#include "qobject/qobject.h" typedef enum { QNUM_I64, diff --git a/include/qapi/qmp/qobject.h b/include/qobject/qobject.h index 256d782688..a6244d0ce0 100644 --- a/include/qapi/qmp/qobject.h +++ b/include/qobject/qobject.h @@ -34,7 +34,7 @@ #include "qapi/qapi-builtin-types.h" -/* Not for use outside include/qapi/qmp/ */ +/* Not for use outside include/qobject/ */ struct QObjectBase_ { QType type; size_t refcnt; diff --git a/include/qapi/qmp/qstring.h b/include/qobject/qstring.h index 318d815d6a..1e2abe4032 100644 --- a/include/qapi/qmp/qstring.h +++ b/include/qobject/qstring.h @@ -13,7 +13,7 @@ #ifndef QSTRING_H #define QSTRING_H -#include "qapi/qmp/qobject.h" +#include "qobject/qobject.h" struct QString { struct QObjectBase_ base; diff --git a/include/system/block-backend-io.h b/include/system/block-backend-io.h index d174275a5c..ba8dfcc7d0 100644 --- a/include/system/block-backend-io.h +++ b/include/system/block-backend-io.h @@ -32,6 +32,13 @@ void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow); void blk_set_disable_request_queuing(BlockBackend *blk, bool disable); bool blk_iostatus_is_enabled(const BlockBackend *blk); +/* + * Return the qdev ID, or if no ID is assigned the QOM path, + * of the block device attached to the BlockBackend. + * + * The caller is responsible for releasing the value returned + * with g_free() after use. + */ char *blk_get_attached_dev_id(BlockBackend *blk); BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset, diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 90afaa4426..02ea4221c9 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -361,7 +361,8 @@ _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len, #define __NR_sys_sched_setaffinity __NR_sched_setaffinity _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len, unsigned long *, user_mask_ptr); -/* sched_attr is not defined in glibc */ +/* sched_attr is not defined in glibc < 2.41 */ +#ifndef SCHED_ATTR_SIZE_VER0 struct sched_attr { uint32_t size; uint32_t sched_policy; @@ -374,6 +375,7 @@ struct sched_attr { uint32_t sched_util_min; uint32_t sched_util_max; }; +#endif #define __NR_sys_sched_getattr __NR_sched_getattr _syscall4(int, sys_sched_getattr, pid_t, pid, struct sched_attr *, attr, unsigned int, size, unsigned int, flags); diff --git a/meson.build b/meson.build index 131b2225ab..18cf9e2913 100644 --- a/meson.build +++ b/meson.build @@ -277,30 +277,41 @@ else host_arch = cpu endif -if cpu in ['x86', 'x86_64'] +if cpu == 'x86' + kvm_targets = ['i386-softmmu'] +elif cpu == 'x86_64' kvm_targets = ['i386-softmmu', 'x86_64-softmmu'] elif cpu == 'aarch64' kvm_targets = ['aarch64-softmmu'] elif cpu == 's390x' kvm_targets = ['s390x-softmmu'] -elif cpu in ['ppc', 'ppc64'] +elif cpu == 'ppc' + kvm_targets = ['ppc-softmmu'] +elif cpu == 'ppc64' kvm_targets = ['ppc-softmmu', 'ppc64-softmmu'] -elif cpu in ['mips', 'mips64'] +elif cpu == 'mips' + kvm_targets = ['mips-softmmu', 'mipsel-softmmu'] +elif cpu == 'mips64' kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu'] -elif cpu in ['riscv32'] +elif cpu == 'riscv32' kvm_targets = ['riscv32-softmmu'] -elif cpu in ['riscv64'] +elif cpu == 'riscv64' kvm_targets = ['riscv64-softmmu'] -elif cpu in ['loongarch64'] +elif cpu == 'loongarch64' kvm_targets = ['loongarch64-softmmu'] else kvm_targets = [] endif accelerator_targets = { 'CONFIG_KVM': kvm_targets } -if cpu in ['x86', 'x86_64'] +if cpu == 'x86' + xen_targets = ['i386-softmmu'] +elif cpu == 'x86_64' xen_targets = ['i386-softmmu', 'x86_64-softmmu'] -elif cpu in ['arm', 'aarch64'] +elif cpu == 'arm' + # i386 emulator provides xenpv machine type for multiple architectures + xen_targets = ['i386-softmmu'] +elif cpu == 'aarch64' # i386 emulator provides xenpv machine type for multiple architectures xen_targets = ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu'] else @@ -308,13 +319,11 @@ else endif accelerator_targets += { 'CONFIG_XEN': xen_targets } -if cpu in ['aarch64'] +if cpu == 'aarch64' accelerator_targets += { 'CONFIG_HVF': ['aarch64-softmmu'] } -endif - -if cpu in ['x86', 'x86_64'] +elif cpu == 'x86_64' accelerator_targets += { 'CONFIG_HVF': ['x86_64-softmmu'], 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'], @@ -322,12 +331,6 @@ if cpu in ['x86', 'x86_64'] } endif -modular_tcg = [] -# Darwin does not support references to thread-local variables in modules -if host_os != 'darwin' - modular_tcg = ['i386-softmmu', 'x86_64-softmmu'] -endif - ################## # Compiler flags # ################## @@ -3182,6 +3185,9 @@ if host_os == 'windows' endif endif +# Detect host pointer size for the target configuration loop. +host_long_bits = cc.sizeof('void *') * 8 + ######################## # Target configuration # ######################## @@ -3274,16 +3280,17 @@ foreach target : target_dirs } endif + config_target += keyval.load('configs/targets' / target + '.mak') + target_kconfig = [] foreach sym: accelerators + # Disallow 64-bit on 32-bit emulation and virtualization + if host_long_bits < config_target['TARGET_LONG_BITS'].to_int() + continue + endif if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) config_target += { sym: 'y' } config_all_accel += { sym: 'y' } - if target in modular_tcg - config_target += { 'CONFIG_TCG_MODULAR': 'y' } - else - config_target += { 'CONFIG_TCG_BUILTIN': 'y' } - endif target_kconfig += [ sym + '=y' ] endif endforeach @@ -3294,9 +3301,6 @@ foreach target : target_dirs error('No accelerator available for target @0@'.format(target)) endif - config_target += keyval.load('configs/targets' / target + '.mak') - config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } - if 'TARGET_NEED_FDT' in config_target and not fdt.found() if default_targets warning('Disabling ' + target + ' due to missing libfdt') @@ -3309,6 +3313,7 @@ foreach target : target_dirs actual_target_dirs += target # Add default keys + config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } if 'TARGET_BASE_ARCH' not in config_target config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} endif @@ -3444,6 +3449,7 @@ qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', meson.current_source_dir() / 'scripts/qapi/schema.py', meson.current_source_dir() / 'scripts/qapi/source.py', meson.current_source_dir() / 'scripts/qapi/types.py', + meson.current_source_dir() / 'scripts/qapi/features.py', meson.current_source_dir() / 'scripts/qapi/visit.py', meson.current_source_dir() / 'scripts/qapi-gen.py' ] @@ -3642,7 +3648,6 @@ util_ss = ss.source_set() # accel modules qtest_module_ss = ss.source_set() -tcg_module_ss = ss.source_set() modules = {} target_modules = {} @@ -3803,11 +3808,7 @@ subdir('tests/qtest/libqos') subdir('tests/qtest/fuzz') # accel modules -tcg_real_module_ss = ss.source_set() -tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) -specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) -target_modules += { 'accel' : { 'qtest': qtest_module_ss, - 'tcg': tcg_real_module_ss }} +target_modules += { 'accel' : { 'qtest': qtest_module_ss }} ############################################## # Internal static_libraries and dependencies # @@ -4841,14 +4842,12 @@ if host_arch == 'unknown' message('configure has succeeded and you can continue to build, but') message('QEMU will use a slow interpreter to emulate the target CPU.') endif -elif host_arch == 'mips' +elif host_long_bits < 64 message() warning('DEPRECATED HOST CPU') message() - message('Support for CPU host architecture ' + cpu + ' is going to be') - message('dropped as soon as the QEMU project stops supporting Debian 12') - message('("Bookworm"). Going forward, the QEMU project will not guarantee') - message('that QEMU will compile or work on this host CPU.') + message('Support for 32-bit CPU host architecture ' + cpu + ' is going') + message('to be dropped in a future QEMU release.') endif if not supported_oses.contains(host_os) diff --git a/migration/block-active.c b/migration/block-active.c index d477cf8182..40e986aade 100644 --- a/migration/block-active.c +++ b/migration/block-active.c @@ -12,51 +12,12 @@ #include "qemu/error-report.h" #include "trace.h" -/* - * Migration-only cache to remember the block layer activation status. - * Protected by BQL. - * - * We need this because.. - * - * - Migration can fail after block devices are invalidated (during - * switchover phase). When that happens, we need to be able to recover - * the block drive status by re-activating them. - * - * - Currently bdrv_inactivate_all() is not safe to be invoked on top of - * invalidated drives (even if bdrv_activate_all() is actually safe to be - * called any time!). It means remembering this could help migration to - * make sure it won't invalidate twice in a row, crashing QEMU. It can - * happen when we migrate a PAUSED VM from host1 to host2, then migrate - * again to host3 without starting it. TODO: a cleaner solution is to - * allow safe invoke of bdrv_inactivate_all() at anytime, like - * bdrv_activate_all(). - * - * For freshly started QEMU, the flag is initialized to TRUE reflecting the - * scenario where QEMU owns block device ownerships. - * - * For incoming QEMU taking a migration stream, the flag is initialized to - * FALSE reflecting that the incoming side doesn't own the block devices, - * not until switchover happens. - */ -static bool migration_block_active; - -/* Setup the disk activation status */ -void migration_block_active_setup(bool active) -{ - migration_block_active = active; -} - bool migration_block_activate(Error **errp) { ERRP_GUARD(); assert(bql_locked()); - if (migration_block_active) { - trace_migration_block_activation("active-skipped"); - return true; - } - trace_migration_block_activation("active"); bdrv_activate_all(errp); @@ -65,7 +26,6 @@ bool migration_block_activate(Error **errp) return false; } - migration_block_active = true; return true; } @@ -75,11 +35,6 @@ bool migration_block_inactivate(void) assert(bql_locked()); - if (!migration_block_active) { - trace_migration_block_activation("inactive-skipped"); - return true; - } - trace_migration_block_activation("inactive"); ret = bdrv_inactivate_all(); @@ -89,6 +44,5 @@ bool migration_block_inactivate(void) return false; } - migration_block_active = false; return true; } diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c index 7c955894e4..4cd14779d6 100644 --- a/migration/dirtyrate.c +++ b/migration/dirtyrate.c @@ -24,7 +24,7 @@ #include "dirtyrate.h" #include "monitor/hmp.h" #include "monitor/monitor.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "system/kvm.h" #include "system/runstate.h" #include "exec/memory.h" diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c index e8527bef80..3347e34c48 100644 --- a/migration/migration-hmp-cmds.c +++ b/migration/migration-hmp-cmds.c @@ -21,7 +21,7 @@ #include "qapi/error.h" #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-visit-migration.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/string-input-visitor.h" #include "qapi/string-output-visitor.h" #include "qemu/cutils.h" diff --git a/migration/migration.c b/migration/migration.c index 74c50cc72c..396928513a 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -45,7 +45,7 @@ #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-events-migration.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qnull.h" +#include "qobject/qnull.h" #include "qemu/rcu.h" #include "postcopy-ram.h" #include "qemu/thread.h" @@ -1895,12 +1895,6 @@ void qmp_migrate_incoming(const char *uri, bool has_channels, return; } - /* - * Newly setup incoming QEMU. Mark the block active state to reflect - * that the src currently owns the disks. - */ - migration_block_active_setup(false); - once = false; } @@ -3992,8 +3986,6 @@ static void migration_instance_init(Object *obj) ms->state = MIGRATION_STATUS_NONE; ms->mbps = -1; ms->pages_per_second = -1; - /* Freshly started QEMU owns all the block devices */ - migration_block_active_setup(true); qemu_sem_init(&ms->pause_sem, 0); qemu_mutex_init(&ms->error_mutex); diff --git a/migration/migration.h b/migration/migration.h index 4c1fafc2b5..eaebcc2042 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -17,7 +17,7 @@ #include "exec/cpu-common.h" #include "hw/qdev-core.h" #include "qapi/qapi-types-migration.h" -#include "qapi/qmp/json-writer.h" +#include "qobject/json-writer.h" #include "qemu/thread.h" #include "qemu/coroutine.h" #include "io/channel.h" @@ -554,7 +554,4 @@ void migration_bitmap_sync_precopy(bool last_stage); void dirty_bitmap_mig_init(void); bool should_send_vmdesc(void); -/* migration/block-active.c */ -void migration_block_active_setup(bool active); - #endif diff --git a/migration/options.c b/migration/options.c index 1ad950e397..4db340b502 100644 --- a/migration/options.c +++ b/migration/options.c @@ -19,7 +19,7 @@ #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-visit-migration.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qnull.h" +#include "qobject/qnull.h" #include "system/runstate.h" #include "migration/colo.h" #include "migration/cpr.h" diff --git a/migration/vmstate.c b/migration/vmstate.c index 047a52af89..5feaa3244d 100644 --- a/migration/vmstate.c +++ b/migration/vmstate.c @@ -15,7 +15,7 @@ #include "migration/vmstate.h" #include "savevm.h" #include "qapi/error.h" -#include "qapi/qmp/json-writer.h" +#include "qobject/json-writer.h" #include "qemu-file.h" #include "qemu/bitops.h" #include "qemu/error-report.h" diff --git a/monitor/hmp-cmds-target.c b/monitor/hmp-cmds-target.c index 0300faa8a2..27ffe61818 100644 --- a/monitor/hmp-cmds-target.c +++ b/monitor/hmp-cmds-target.c @@ -29,7 +29,7 @@ #include "monitor/hmp-target.h" #include "monitor/monitor-internal.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "system/hw_accel.h" /* Set the current CPU defined by the user. Callers must hold BQL. */ diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 0aa22e1ae2..3825ff40a9 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -25,7 +25,7 @@ #include "qapi/qapi-commands-control.h" #include "qapi/qapi-commands-machine.h" #include "qapi/qapi-commands-misc.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/cutils.h" #include "qemu/log.h" #include "system/system.h" diff --git a/monitor/hmp.c b/monitor/hmp.c index db90360553..34e2b8f748 100644 --- a/monitor/hmp.c +++ b/monitor/hmp.c @@ -27,8 +27,8 @@ #include "hw/qdev-core.h" #include "monitor-internal.h" #include "monitor/hmp.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qdict.h" +#include "qobject/qnum.h" #include "qemu/config-file.h" #include "qemu/ctype.h" #include "qemu/cutils.h" diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index 088960a503..5676eb334e 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -28,8 +28,8 @@ #include "chardev/char-fe.h" #include "monitor/monitor.h" #include "qapi/qapi-types-control.h" -#include "qapi/qmp/dispatch.h" -#include "qapi/qmp/json-parser.h" +#include "qapi/qmp-registry.h" +#include "qobject/json-parser.h" #include "qemu/readline.h" #include "system/iothread.h" diff --git a/monitor/monitor.c b/monitor/monitor.c index 9fad61f9df..c5a5d30877 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -28,7 +28,7 @@ #include "qapi/opts-visitor.h" #include "qapi/qapi-emit-events.h" #include "qapi/qapi-visit-control.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/error-report.h" #include "qemu/option.h" #include "system/qtest.h" diff --git a/monitor/qemu-config-qmp.c b/monitor/qemu-config-qmp.c index 24477a0e44..9a3b183602 100644 --- a/monitor/qemu-config-qmp.c +++ b/monitor/qemu-config-qmp.c @@ -2,7 +2,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/qapi-commands-misc.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qemu/option.h" #include "qemu/config-file.h" #include "hw/boards.h" diff --git a/monitor/qmp.c b/monitor/qmp.c index 5e538f34c0..2f46cf9e49 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -28,9 +28,9 @@ #include "monitor-internal.h" #include "qapi/error.h" #include "qapi/qapi-commands-control.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qlist.h" #include "trace.h" /* diff --git a/nbd/server.c b/nbd/server.c index f64e47270c..2076fb2666 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -2026,6 +2026,7 @@ static void nbd_export_delete(BlockExport *blk_exp) const BlockExportDriver blk_exp_nbd = { .type = BLOCK_EXPORT_TYPE_NBD, .instance_size = sizeof(NBDExport), + .supports_inactive = true, .create = nbd_export_create, .delete = nbd_export_delete, .request_shutdown = nbd_export_request_shutdown, @@ -2920,6 +2921,22 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, NBDExport *exp = client->exp; char *msg; size_t i; + bool inactive; + + WITH_GRAPH_RDLOCK_GUARD() { + inactive = bdrv_is_inactive(blk_bs(exp->common.blk)); + if (inactive) { + switch (request->type) { + case NBD_CMD_READ: + /* These commands are allowed on inactive nodes */ + break; + default: + /* Return an error for the rest */ + return nbd_send_generic_reply(client, request, -EPERM, + "export is inactive", errp); + } + } + } switch (request->type) { case NBD_CMD_CACHE: diff --git a/net/net-hmp-cmds.c b/net/net-hmp-cmds.c index 41d326bf5f..e7c55d2787 100644 --- a/net/net-hmp-cmds.c +++ b/net/net-hmp-cmds.c @@ -22,7 +22,7 @@ #include "qapi/clone-visitor.h" #include "qapi/qapi-commands-net.h" #include "qapi/qapi-visit-net.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/config-file.h" #include "qemu/help_option.h" #include "qemu/option.h" diff --git a/net/net.c b/net/net.c index 9cded70dde..a3996d5c62 100644 --- a/net/net.c +++ b/net/net.c @@ -36,7 +36,7 @@ #include "qemu/help_option.h" #include "qapi/qapi-commands-net.h" #include "qapi/qapi-visit-net.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qmp/qerror.h" #include "qemu/error-report.h" #include "qemu/sockets.h" diff --git a/net/slirp.c b/net/slirp.c index 97d08ed1fb..9657e86a84 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -43,7 +43,7 @@ #include "system/system.h" #include "qemu/cutils.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "util.h" #include "migration/register.h" #include "migration/vmstate.h" diff --git a/qapi/block-core.json b/qapi/block-core.json index fd3bcc1c17..ee6eccc68c 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -486,6 +486,10 @@ # @backing_file_depth: number of files in the backing file chain # (since: 1.2) # +# @active: true if the backend is active; typical cases for inactive backends +# are on the migration source instance after migration completes and on the +# destination before it completes. (since: 10.0) +# # @encrypted: true if the backing device is encrypted # # @detect_zeroes: detect and optimize zero writes (Since 2.1) @@ -556,7 +560,7 @@ { 'struct': 'BlockDeviceInfo', 'data': { 'file': 'str', '*node-name': 'str', 'ro': 'bool', 'drv': 'str', '*backing_file': 'str', 'backing_file_depth': 'int', - 'encrypted': 'bool', + 'active': 'bool', 'encrypted': 'bool', 'detect_zeroes': 'BlockdevDetectZeroesOptions', 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int', 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int', @@ -4679,6 +4683,11 @@ # # @cache: cache-related options # +# @active: whether the block node should be activated (default: true). +# Having inactive block nodes is useful primarily for migration because it +# allows opening an image on the destination while the source is still +# holding locks for it. (Since 10.0) +# # @read-only: whether the block device should be read-only (default: # false). Note that some block drivers support only read-only # access, either generally or in certain configurations. In this @@ -4705,6 +4714,7 @@ '*node-name': 'str', '*discard': 'BlockdevDiscardOptions', '*cache': 'BlockdevCacheOptions', + '*active': 'bool', '*read-only': 'bool', '*auto-read-only': 'bool', '*force-share': 'bool', @@ -4936,6 +4946,38 @@ 'allow-preconfig': true } ## +# @blockdev-set-active: +# +# Activate or inactivate a block device. Use this to manage the handover of +# block devices on migration with qemu-storage-daemon. +# +# Activating a node automatically activates all of its child nodes first. +# Inactivating a node automatically inactivates any of its child nodes that are +# not in use by a still active node. +# +# @node-name: Name of the graph node to activate or inactivate. By default, all +# nodes are affected by the operation. +# +# @active: true if the nodes should be active when the command returns success, +# false if they should be inactive. +# +# Since: 10.0 +# +# .. qmp-example:: +# +# -> { "execute": "blockdev-set-active", +# "arguments": { +# "node-name": "node0", +# "active": false +# } +# } +# <- { "return": {} } +## +{ 'command': 'blockdev-set-active', + 'data': { '*node-name': 'str', 'active': 'bool' }, + 'allow-preconfig': true } + +## # @BlockdevCreateOptionsFile: # # Driver specific image creation options for file. diff --git a/qapi/block-export.json b/qapi/block-export.json index ce33fe378d..117b05d13c 100644 --- a/qapi/block-export.json +++ b/qapi/block-export.json @@ -372,6 +372,13 @@ # cannot be moved to the iothread. The default is false. # (since: 5.2) # +# @allow-inactive: If true, the export allows the exported node to be inactive. +# If it is created for an inactive block node, the node remains inactive. If +# the export type doesn't support running on an inactive node, an error is +# returned. If false, inactive block nodes are automatically activated before +# creating the export and trying to inactivate them later fails. +# (since: 10.0; default: false) +# # Since: 4.2 ## { 'union': 'BlockExportOptions', @@ -381,7 +388,8 @@ '*iothread': 'str', 'node-name': 'str', '*writable': 'bool', - '*writethrough': 'bool' }, + '*writethrough': 'bool', + '*allow-inactive': 'bool' }, 'discriminator': 'type', 'data': { 'nbd': 'BlockExportOptionsNbd', diff --git a/qapi/cxl.json b/qapi/cxl.json index 9f65589bce..dd947d3bbc 100644 --- a/qapi/cxl.json +++ b/qapi/cxl.json @@ -460,7 +460,7 @@ # # @unstable: For now this command is subject to change. # -# Since : 9.1 +# Since: 9.1 ## { 'command': 'cxl-add-dynamic-capacity', 'data': { 'path': 'str', @@ -539,7 +539,7 @@ # # @unstable: For now this command is subject to change. # -# Since : 9.1 +# Since: 9.1 ## { 'command': 'cxl-release-dynamic-capacity', 'data': { 'path': 'str', diff --git a/qapi/qapi-clone-visitor.c b/qapi/qapi-clone-visitor.c index bbf953698f..30997638de 100644 --- a/qapi/qapi-clone-visitor.c +++ b/qapi/qapi-clone-visitor.c @@ -12,7 +12,7 @@ #include "qapi/clone-visitor.h" #include "qapi/visitor-impl.h" #include "qapi/error.h" -#include "qapi/qmp/qnull.h" +#include "qobject/qnull.h" struct QapiCloneVisitor { Visitor visitor; diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c index ef283f2966..57a2c904bb 100644 --- a/qapi/qapi-dealloc-visitor.c +++ b/qapi/qapi-dealloc-visitor.c @@ -14,7 +14,7 @@ #include "qemu/osdep.h" #include "qapi/dealloc-visitor.h" -#include "qapi/qmp/qnull.h" +#include "qobject/qnull.h" #include "qapi/visitor-impl.h" struct QapiDeallocVisitor diff --git a/qapi/qapi-forward-visitor.c b/qapi/qapi-forward-visitor.c index e36d9bc9ba..d91d921bdb 100644 --- a/qapi/qapi-forward-visitor.c +++ b/qapi/qapi-forward-visitor.c @@ -14,14 +14,14 @@ #include "qapi/forward-visitor.h" #include "qapi/visitor-impl.h" #include "qemu/queue.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qlist.h" +#include "qobject/qnull.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qemu/cutils.h" struct ForwardFieldVisitor { @@ -246,7 +246,7 @@ static void forward_field_optional(Visitor *v, const char *name, bool *present) } static bool forward_field_policy_reject(Visitor *v, const char *name, - unsigned special_features, + uint64_t features, Error **errp) { ForwardFieldVisitor *ffv = to_ffv(v); @@ -254,18 +254,18 @@ static bool forward_field_policy_reject(Visitor *v, const char *name, if (!forward_field_translate_name(ffv, &name, errp)) { return true; } - return visit_policy_reject(ffv->target, name, special_features, errp); + return visit_policy_reject(ffv->target, name, features, errp); } static bool forward_field_policy_skip(Visitor *v, const char *name, - unsigned special_features) + uint64_t features) { ForwardFieldVisitor *ffv = to_ffv(v); if (!forward_field_translate_name(ffv, &name, NULL)) { return true; } - return visit_policy_skip(ffv->target, name, special_features); + return visit_policy_skip(ffv->target, name, features); } static void forward_field_complete(Visitor *v, void *opaque) diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c index 65a7d18437..3d849fe034 100644 --- a/qapi/qapi-util.c +++ b/qapi/qapi-util.c @@ -37,19 +37,19 @@ static bool compat_policy_input_ok1(const char *adjective, } } -bool compat_policy_input_ok(unsigned special_features, +bool compat_policy_input_ok(uint64_t features, const CompatPolicy *policy, ErrorClass error_class, const char *kind, const char *name, Error **errp) { - if ((special_features & 1u << QAPI_DEPRECATED) + if ((features & 1u << QAPI_DEPRECATED) && !compat_policy_input_ok1("Deprecated", policy->deprecated_input, error_class, kind, name, errp)) { return false; } - if ((special_features & (1u << QAPI_UNSTABLE)) + if ((features & (1u << QAPI_UNSTABLE)) && !compat_policy_input_ok1("Unstable", policy->unstable_input, error_class, kind, name, errp)) { diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index 6c13510a2b..706c61e026 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -141,21 +141,21 @@ bool visit_optional(Visitor *v, const char *name, bool *present) } bool visit_policy_reject(Visitor *v, const char *name, - unsigned special_features, Error **errp) + uint64_t features, Error **errp) { trace_visit_policy_reject(v, name); if (v->policy_reject) { - return v->policy_reject(v, name, special_features, errp); + return v->policy_reject(v, name, features, errp); } return false; } bool visit_policy_skip(Visitor *v, const char *name, - unsigned special_features) + uint64_t features) { trace_visit_policy_skip(v, name); if (v->policy_skip) { - return v->policy_skip(v, name, special_features); + return v->policy_skip(v, name, features); } return false; } @@ -409,8 +409,8 @@ static bool input_type_enum(Visitor *v, const char *name, int *obj, return false; } - if (lookup->special_features - && !compat_policy_input_ok(lookup->special_features[value], + if (lookup->features + && !compat_policy_input_ok(lookup->features[value], &v->compat_policy, ERROR_CLASS_GENERIC_ERROR, "value", enum_str, errp)) { diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 176b549473..e569224eae 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -16,12 +16,12 @@ #include "block/aio.h" #include "qapi/compat-policy.h" #include "qapi/error.h" -#include "qapi/qmp/dispatch.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" +#include "qapi/qmp-registry.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" -#include "qapi/qmp/qbool.h" +#include "qobject/qbool.h" #include "qemu/coroutine.h" #include "qemu/main-loop.h" @@ -173,7 +173,7 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ "The command %s has not been found", command); goto out; } - if (!compat_policy_input_ok(cmd->special_features, &compat_policy, + if (!compat_policy_input_ok(cmd->features, &compat_policy, ERROR_CLASS_COMMAND_NOT_FOUND, "command", command, &err)) { goto out; diff --git a/qapi/qmp-event.c b/qapi/qmp-event.c index 0fe0d0a5a6..11cb6ace99 100644 --- a/qapi/qmp-event.c +++ b/qapi/qmp-event.c @@ -14,9 +14,9 @@ #include "qemu/osdep.h" #include "qapi/qmp-event.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" static void timestamp_put(QDict *qdict) { diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c index 485bc5e6fc..e2623f2b78 100644 --- a/qapi/qmp-registry.c +++ b/qapi/qmp-registry.c @@ -13,11 +13,11 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/dispatch.h" +#include "qapi/qmp-registry.h" void qmp_register_command(QmpCommandList *cmds, const char *name, QmpCommandFunc *fn, QmpCommandOptions options, - unsigned special_features) + uint64_t features) { QmpCommand *cmd = g_malloc0(sizeof(*cmd)); @@ -28,7 +28,7 @@ void qmp_register_command(QmpCommandList *cmds, const char *name, cmd->fn = fn; cmd->enabled = true; cmd->options = options; - cmd->special_features = special_features; + cmd->features = features; QTAILQ_INSERT_TAIL(cmds, cmd, node); } diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c index f110a804b2..c52d36997d 100644 --- a/qapi/qobject-input-visitor.c +++ b/qapi/qobject-input-visitor.c @@ -19,14 +19,14 @@ #include "qapi/qobject-input-visitor.h" #include "qapi/visitor-impl.h" #include "qemu/queue.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qlist.h" +#include "qobject/qnull.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qemu/cutils.h" #include "qemu/keyval.h" @@ -664,10 +664,10 @@ static void qobject_input_optional(Visitor *v, const char *name, bool *present) } static bool qobject_input_policy_reject(Visitor *v, const char *name, - unsigned special_features, + uint64_t features, Error **errp) { - return !compat_policy_input_ok(special_features, &v->compat_policy, + return !compat_policy_input_ok(features, &v->compat_policy, ERROR_CLASS_GENERIC_ERROR, "parameter", name, errp); } diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c index 74770edd73..de5b36bda5 100644 --- a/qapi/qobject-output-visitor.c +++ b/qapi/qobject-output-visitor.c @@ -17,12 +17,12 @@ #include "qapi/qobject-output-visitor.h" #include "qapi/visitor-impl.h" #include "qemu/queue.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qnull.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" typedef struct QStackEntry { QObject *value; @@ -210,13 +210,13 @@ static bool qobject_output_type_null(Visitor *v, const char *name, } static bool qobject_output_policy_skip(Visitor *v, const char *name, - unsigned special_features) + uint64_t features) { CompatPolicy *pol = &v->compat_policy; - return ((special_features & 1u << QAPI_DEPRECATED) + return ((features & 1u << QAPI_DEPRECATED) && pol->deprecated_output == COMPAT_POLICY_OUTPUT_HIDE) - || ((special_features & 1u << QAPI_UNSTABLE) + || ((features & 1u << QAPI_UNSTABLE) && pol->unstable_output == COMPAT_POLICY_OUTPUT_HIDE); } diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c index 3f1b9e9b41..f4eecc73d0 100644 --- a/qapi/string-input-visitor.c +++ b/qapi/string-input-visitor.c @@ -15,7 +15,7 @@ #include "qapi/string-input-visitor.h" #include "qapi/visitor-impl.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qnull.h" +#include "qobject/qnull.h" #include "qemu/option.h" #include "qemu/cutils.h" diff --git a/qapi/ui.json b/qapi/ui.json index 460a26b981..c536d4e524 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1133,7 +1133,7 @@ # @axis: Which axis is referenced by @value. # # @value: Pointer position. For absolute coordinates the valid range -# is 0 -> 0x7ffff +# is 0 to 0x7fff. # # Since: 2.0 ## diff --git a/qemu-img.c b/qemu-img.c index 2f2fac90e8..89c93c1eb5 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -32,8 +32,8 @@ #include "qapi/qapi-commands-block-core.h" #include "qapi/qapi-visit-block-core.h" #include "qapi/qobject-output-visitor.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qdict.h" #include "qemu/cutils.h" #include "qemu/config-file.h" #include "qemu/option.h" diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index bf08dcb8f5..13e0330162 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -10,7 +10,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu-io.h" #include "system/block-backend.h" #include "block/block.h" diff --git a/qemu-io.c b/qemu-io.c index fa04695d1d..8f2de83f3c 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -27,8 +27,8 @@ #include "qemu/readline.h" #include "qemu/log.h" #include "qemu/sockets.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qstring.h" +#include "qobject/qdict.h" #include "qom/object_interfaces.h" #include "system/block-backend.h" #include "block/block_int.h" diff --git a/qemu-nbd.c b/qemu-nbd.c index e7a961a556..b30d3ab8de 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -37,8 +37,8 @@ #include "qemu/log.h" #include "qemu/systemd.h" #include "block/snapshot.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qom/object_interfaces.h" #include "io/channel-socket.h" #include "io/net-listener.h" diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h index b4e7c52c61..a536d07d0d 100644 --- a/qga/guest-agent-core.h +++ b/qga/guest-agent-core.h @@ -13,7 +13,7 @@ #ifndef GUEST_AGENT_CORE_H #define GUEST_AGENT_CORE_H -#include "qapi/qmp/dispatch.h" +#include "qapi/qmp-registry.h" #include "qga-qapi-types.h" #define QGA_READ_COUNT_DEFAULT 4096 diff --git a/qga/main.c b/qga/main.c index 4a695235f0..531853e13d 100644 --- a/qga/main.c +++ b/qga/main.c @@ -19,9 +19,9 @@ #include <sys/wait.h> #endif #include "qemu/help-texts.h" -#include "qapi/qmp/json-parser.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" +#include "qobject/json-parser.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" #include "guest-agent-core.h" #include "qga-qapi-init-commands.h" #include "qapi/error.h" diff --git a/qobject/block-qdict.c b/qobject/block-qdict.c index 4a83bda2c3..d0e1c63cf6 100644 --- a/qobject/block-qdict.c +++ b/qobject/block-qdict.c @@ -9,10 +9,10 @@ #include "qemu/osdep.h" #include "block/qdict.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qlist.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qapi/qobject-input-visitor.h" #include "qemu/cutils.h" #include "qapi/error.h" diff --git a/qobject/json-parser-int.h b/qobject/json-parser-int.h index 16a25d00bb..8c01f23627 100644 --- a/qobject/json-parser-int.h +++ b/qobject/json-parser-int.h @@ -14,7 +14,7 @@ #ifndef JSON_PARSER_INT_H #define JSON_PARSER_INT_H -#include "qapi/qmp/json-parser.h" +#include "qobject/json-parser.h" typedef enum json_token_type { JSON_ERROR = 0, /* must be zero, see json_lexer[] */ diff --git a/qobject/json-parser.c b/qobject/json-parser.c index d498db6e70..7483e582fe 100644 --- a/qobject/json-parser.c +++ b/qobject/json-parser.c @@ -16,12 +16,12 @@ #include "qemu/cutils.h" #include "qemu/unicode.h" #include "qapi/error.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qnull.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "json-parser-int.h" struct JSONToken { diff --git a/qobject/json-writer.c b/qobject/json-writer.c index 309a31d57a..aac2c6ab71 100644 --- a/qobject/json-writer.c +++ b/qobject/json-writer.c @@ -14,7 +14,7 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/json-writer.h" +#include "qobject/json-writer.h" #include "qemu/unicode.h" struct JSONWriter { diff --git a/qobject/qbool.c b/qobject/qbool.c index c7049c0c50..00d7066aae 100644 --- a/qobject/qbool.c +++ b/qobject/qbool.c @@ -12,7 +12,7 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qbool.h" +#include "qobject/qbool.h" #include "qobject-internal.h" /** diff --git a/qobject/qdict.c b/qobject/qdict.c index 8faff230d3..a90ac9ae2f 100644 --- a/qobject/qdict.c +++ b/qobject/qdict.c @@ -11,11 +11,11 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qnum.h" +#include "qobject/qdict.h" +#include "qobject/qbool.h" +#include "qobject/qnull.h" +#include "qobject/qstring.h" #include "qobject-internal.h" /** diff --git a/qobject/qjson.c b/qobject/qjson.c index 167fcb429c..c858dafb5e 100644 --- a/qobject/qjson.c +++ b/qobject/qjson.c @@ -13,14 +13,14 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/json-parser.h" -#include "qapi/qmp/json-writer.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/json-parser.h" +#include "qobject/json-writer.h" +#include "qobject/qjson.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" typedef struct JSONParsingState { JSONMessageParser parser; diff --git a/qobject/qlist.c b/qobject/qlist.c index 356ad946b0..41e6876d5b 100644 --- a/qobject/qlist.c +++ b/qobject/qlist.c @@ -11,11 +11,11 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qlist.h" +#include "qobject/qnull.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qemu/queue.h" #include "qobject-internal.h" diff --git a/qobject/qlit.c b/qobject/qlit.c index a62865b642..a44f47eaa5 100644 --- a/qobject/qlit.c +++ b/qobject/qlit.c @@ -15,13 +15,13 @@ #include "qemu/osdep.h" -#include "qapi/qmp/qlit.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qnull.h" +#include "qobject/qlit.h" +#include "qobject/qbool.h" +#include "qobject/qlist.h" +#include "qobject/qnum.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" +#include "qobject/qnull.h" static bool qlit_equal_qdict(const QLitObject *lhs, const QDict *qdict) { diff --git a/qobject/qnull.c b/qobject/qnull.c index 445a5db7f3..0fb78cbd0a 100644 --- a/qobject/qnull.c +++ b/qobject/qnull.c @@ -11,7 +11,7 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qnull.h" +#include "qobject/qnull.h" #include "qobject-internal.h" QNull qnull_ = { diff --git a/qobject/qnum.c b/qobject/qnum.c index dd8ea49565..a938b64537 100644 --- a/qobject/qnum.c +++ b/qobject/qnum.c @@ -13,7 +13,7 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qnum.h" #include "qobject-internal.h" /** diff --git a/qobject/qobject-internal.h b/qobject/qobject-internal.h index b310c8e1b5..0c7679fe98 100644 --- a/qobject/qobject-internal.h +++ b/qobject/qobject-internal.h @@ -10,7 +10,7 @@ #ifndef QOBJECT_INTERNAL_H #define QOBJECT_INTERNAL_H -#include "qapi/qmp/qobject.h" +#include "qobject/qobject.h" static inline void qobject_init(QObject *obj, QType type) { diff --git a/qobject/qobject.c b/qobject/qobject.c index d7077b8f2a..78d1e057c1 100644 --- a/qobject/qobject.c +++ b/qobject/qobject.c @@ -8,12 +8,12 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qnull.h" +#include "qobject/qnum.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qstring.h" #include "qobject-internal.h" QEMU_BUILD_BUG_MSG( diff --git a/qobject/qstring.c b/qobject/qstring.c index 794f8c9357..d316604914 100644 --- a/qobject/qstring.c +++ b/qobject/qstring.c @@ -11,7 +11,7 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qstring.h" #include "qobject-internal.h" /** diff --git a/qom/object.c b/qom/object.c index ec447f14a7..01618d06bd 100644 --- a/qom/object.c +++ b/qom/object.c @@ -23,16 +23,16 @@ #include "qapi/qobject-input-visitor.h" #include "qapi/forward-visitor.h" #include "qapi/qapi-builtin-visit.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qjson.h" #include "trace.h" /* TODO: replace QObject with a simpler visitor to avoid a dependency * of the QOM core on QObject? */ #include "qom/qom-qobject.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qlist.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qemu/error-report.h" #define MAX_INTERFACES 32 diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index 1a6f29c053..f35d331331 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -3,10 +3,10 @@ #include "qemu/cutils.h" #include "qapi/error.h" #include "qapi/qapi-visit-qom.h" -#include "qapi/qmp/qobject.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qobject.h" +#include "qobject/qdict.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qjson.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" #include "qom/object_interfaces.h" diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c index 6e3a2175a4..a00a564b1e 100644 --- a/qom/qom-hmp-cmds.c +++ b/qom/qom-hmp-cmds.c @@ -11,8 +11,8 @@ #include "monitor/monitor.h" #include "qapi/error.h" #include "qapi/qapi-commands-qom.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" #include "qemu/readline.h" #include "qom/object.h" #include "qom/object_interfaces.h" diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c index 46e4562300..e866547618 100644 --- a/qom/qom-qmp-cmds.c +++ b/qom/qom-qmp-cmds.c @@ -20,7 +20,7 @@ #include "qapi/qapi-commands-qdev.h" #include "qapi/qapi-commands-qom.h" #include "qapi/qapi-visit-qom.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qmp/qerror.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index b672ec3e3f..1105364002 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -17,7 +17,7 @@ #include "monitor/hmp.h" #include "monitor/monitor.h" #include "qapi/qapi-commands-replay.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/timer.h" #include "block/snapshot.h" #include "migration/snapshot.h" diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c index 7b7b326925..3c0a89442a 100644 --- a/replay/replay-snapshot.c +++ b/replay/replay-snapshot.c @@ -14,7 +14,7 @@ #include "system/replay.h" #include "replay-internal.h" #include "monitor/monitor.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qstring.h" #include "qemu/error-report.h" #include "migration/vmstate.h" #include "migration/snapshot.h" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 5b6b6ca438..5b0cb55928 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -52,7 +52,6 @@ empty_structs_with_brackets = "deny" ignored_unit_patterns = "deny" implicit_clone = "deny" macro_use_imports = "deny" -missing_const_for_fn = "deny" missing_safety_doc = "deny" multiple_crate_versions = "deny" mut_mut = "deny" diff --git a/rust/clippy.toml b/rust/clippy.toml new file mode 100644 index 0000000000..5d190f91de --- /dev/null +++ b/rust/clippy.toml @@ -0,0 +1,2 @@ +doc-valid-idents = ["PrimeCell", ".."] +msrv = "1.63.0" diff --git a/rust/hw/char/pl011/Cargo.toml b/rust/hw/char/pl011/Cargo.toml index 58f3e859f7..f2296cad58 100644 --- a/rust/hw/char/pl011/Cargo.toml +++ b/rust/hw/char/pl011/Cargo.toml @@ -4,14 +4,12 @@ version = "0.1.0" edition = "2021" authors = ["Manos Pitsidianakis <manos.pitsidianakis@linaro.org>"] license = "GPL-2.0-or-later" -readme = "README.md" -homepage = "https://www.qemu.org" description = "pl011 device model for QEMU" -repository = "https://gitlab.com/epilys/rust-for-qemu" resolver = "2" publish = false keywords = [] categories = [] +rust-version = "1.63.0" [lib] crate-type = ["staticlib"] diff --git a/rust/hw/char/pl011/README.md b/rust/hw/char/pl011/README.md deleted file mode 100644 index cd7dea3163..0000000000 --- a/rust/hw/char/pl011/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# PL011 QEMU Device Model - -This library implements a device model for the PrimeCell® UART (PL011) -device in QEMU. - -## Build static lib - -Host build target must be explicitly specified: - -```sh -cargo build --target x86_64-unknown-linux-gnu -``` - -Replace host target triplet if necessary. - -## Generate Rust documentation - -To generate docs for this crate, including private items: - -```sh -cargo doc --no-deps --document-private-items --target x86_64-unknown-linux-gnu -``` - -To include direct dependencies like `bilge` (bitmaps for register types): - -```sh -cargo tree --depth 1 -e normal --prefix none \ - | cut -d' ' -f1 \ - | xargs printf -- '-p %s\n' \ - | xargs cargo doc --no-deps --document-private-items --target x86_64-unknown-linux-gnu -``` diff --git a/rust/hw/char/pl011/src/device_class.rs b/rust/hw/char/pl011/src/device_class.rs index 8a157a663f..dbef93f6cb 100644 --- a/rust/hw/char/pl011/src/device_class.rs +++ b/rust/hw/char/pl011/src/device_class.rs @@ -12,7 +12,6 @@ use qemu_api::{ use crate::device::{PL011Registers, PL011State}; -#[allow(clippy::missing_const_for_fn)] extern "C" fn pl011_clock_needed(opaque: *mut c_void) -> bool { let state = NonNull::new(opaque).unwrap().cast::<PL011State>(); unsafe { state.as_ref().migrate_clock } diff --git a/rust/hw/char/pl011/src/lib.rs b/rust/hw/char/pl011/src/lib.rs index e2df4586bc..3c72f1221f 100644 --- a/rust/hw/char/pl011/src/lib.rs +++ b/rust/hw/char/pl011/src/lib.rs @@ -1,29 +1,18 @@ // Copyright 2024, Linaro Limited // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> // SPDX-License-Identifier: GPL-2.0-or-later -// -// PL011 QEMU Device Model -// -// This library implements a device model for the PrimeCell® UART (PL011) -// device in QEMU. -// -#![doc = include_str!("../README.md")] + +//! PL011 QEMU Device Model +//! +//! This library implements a device model for the PrimeCell® UART (PL011) +//! device in QEMU. +//! //! # Library crate //! //! See [`PL011State`](crate::device::PL011State) for the device model type and //! the [`registers`] module for register types. -#![deny( - clippy::correctness, - clippy::suspicious, - clippy::complexity, - clippy::perf, - clippy::cargo, - clippy::nursery, - clippy::style -)] #![allow(clippy::upper_case_acronyms)] -#![allow(clippy::result_unit_err)] use qemu_api::c_str; diff --git a/rust/qemu-api-macros/Cargo.toml b/rust/qemu-api-macros/Cargo.toml index 5a27b52ee6..89dee1cfb3 100644 --- a/rust/qemu-api-macros/Cargo.toml +++ b/rust/qemu-api-macros/Cargo.toml @@ -4,14 +4,12 @@ version = "0.1.0" edition = "2021" authors = ["Manos Pitsidianakis <manos.pitsidianakis@linaro.org>"] license = "GPL-2.0-or-later" -readme = "README.md" -homepage = "https://www.qemu.org" description = "Rust bindings for QEMU - Utility macros" -repository = "https://gitlab.com/qemu-project/qemu/" resolver = "2" publish = false keywords = [] categories = [] +rust-version = "1.63.0" [lib] proc-macro = true diff --git a/rust/qemu-api-macros/README.md b/rust/qemu-api-macros/README.md deleted file mode 100644 index f60f54ac4b..0000000000 --- a/rust/qemu-api-macros/README.md +++ /dev/null @@ -1 +0,0 @@ -# `qemu-api-macros` - Utility macros for defining QEMU devices diff --git a/rust/qemu-api/Cargo.toml b/rust/qemu-api/Cargo.toml index 4aa22f3198..a51dd14285 100644 --- a/rust/qemu-api/Cargo.toml +++ b/rust/qemu-api/Cargo.toml @@ -12,6 +12,7 @@ resolver = "2" publish = false keywords = [] categories = [] +rust-version = "1.63.0" [dependencies] qemu_api_macros = { path = "../qemu-api-macros" } diff --git a/rust/qemu-api/src/lib.rs b/rust/qemu-api/src/lib.rs index 83c6a987c0..3cf9371cff 100644 --- a/rust/qemu-api/src/lib.rs +++ b/rust/qemu-api/src/lib.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #![cfg_attr(not(MESON), doc = include_str!("../README.md"))] +#![deny(clippy::missing_const_for_fn)] #[rustfmt::skip] pub mod bindings; diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py index 79951a841f..7914227382 100644 --- a/scripts/qapi/commands.py +++ b/scripts/qapi/commands.py @@ -25,7 +25,7 @@ from .gen import ( QAPIGenC, QAPISchemaModularCVisitor, build_params, - gen_special_features, + gen_features, ifcontext, ) from .schema import ( @@ -298,7 +298,7 @@ def gen_register_command(name: str, ''', name=name, c_name=c_name(name), opts=' | '.join(options) or 0, - feats=gen_special_features(features)) + feats=gen_features(features)) return ret @@ -320,7 +320,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor): #include "qemu/osdep.h" #include "qapi/compat-policy.h" #include "qapi/visitor.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/dealloc-visitor.h" #include "qapi/error.h" #include "%(visit)s.h" @@ -330,7 +330,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor): if self._gen_tracing and commands != 'qapi-commands': self._genc.add(mcgen(''' -#include "qapi/qmp/qjson.h" +#include "qobject/qjson.h" #include "trace/trace-%(nm)s_trace_events.h" ''', nm=c_name(commands, protect=False))) @@ -346,7 +346,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor): def visit_begin(self, schema: QAPISchema) -> None: self._add_module('./init', ' * QAPI Commands initialization') self._genh.add(mcgen(''' -#include "qapi/qmp/dispatch.h" +#include "qapi/qmp-registry.h" void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds); ''', @@ -355,6 +355,7 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds); #include "qemu/osdep.h" #include "%(prefix)sqapi-commands.h" #include "%(prefix)sqapi-init-commands.h" +#include "%(prefix)sqapi-features.h" void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds) { diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py index d1f639981a..d179b0ed69 100644 --- a/scripts/qapi/events.py +++ b/scripts/qapi/events.py @@ -194,7 +194,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor): #include "%(visit)s.h" #include "qapi/compat-policy.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qmp-event.h" ''', events=events, visit=visit, diff --git a/scripts/qapi/features.py b/scripts/qapi/features.py new file mode 100644 index 0000000000..57563207a8 --- /dev/null +++ b/scripts/qapi/features.py @@ -0,0 +1,48 @@ +""" +QAPI features generator + +Copyright 2024 Red Hat + +This work is licensed under the terms of the GNU GPL, version 2. +# See the COPYING file in the top-level directory. +""" + +from typing import ValuesView + +from .common import c_enum_const, c_name +from .gen import QAPISchemaMonolithicCVisitor +from .schema import QAPISchema, QAPISchemaFeature + + +class QAPISchemaGenFeatureVisitor(QAPISchemaMonolithicCVisitor): + + def __init__(self, prefix: str): + super().__init__( + prefix, 'qapi-features', + ' * Schema-defined QAPI features', + __doc__) + + self.features: ValuesView[QAPISchemaFeature] + + def visit_begin(self, schema: QAPISchema) -> None: + self.features = schema.features() + self._genh.add("#include \"qapi/util.h\"\n\n") + + def visit_end(self) -> None: + self._genh.add("typedef enum {\n") + for f in self.features: + self._genh.add(f" {c_enum_const('qapi_feature', f.name)}") + if f.name in QAPISchemaFeature.SPECIAL_NAMES: + self._genh.add(f" = {c_enum_const('qapi', f.name)},\n") + else: + self._genh.add(",\n") + + self._genh.add("} " + c_name('QapiFeature') + ";\n") + + +def gen_features(schema: QAPISchema, + output_dir: str, + prefix: str) -> None: + vis = QAPISchemaGenFeatureVisitor(prefix) + schema.visit(vis) + vis.write(output_dir) diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py index 6a8abe0041..d3c56d45c8 100644 --- a/scripts/qapi/gen.py +++ b/scripts/qapi/gen.py @@ -24,6 +24,7 @@ from typing import ( ) from .common import ( + c_enum_const, c_fname, c_name, guardend, @@ -40,10 +41,10 @@ from .schema import ( from .source import QAPISourceInfo -def gen_special_features(features: Sequence[QAPISchemaFeature]) -> str: - special_features = [f"1u << QAPI_{feat.name.upper()}" - for feat in features if feat.is_special()] - return ' | '.join(special_features) or '0' +def gen_features(features: Sequence[QAPISchemaFeature]) -> str: + feats = [f"1u << {c_enum_const('qapi_feature', feat.name)}" + for feat in features] + return ' | '.join(feats) or '0' class QAPIGen: diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index ac14b20f30..42e5185c7c 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -197,7 +197,7 @@ class QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor): # generate C name = c_name(self._prefix, protect=False) + 'qmp_schema_qlit' self._genh.add(mcgen(''' -#include "qapi/qmp/qlit.h" +#include "qobject/qlit.h" extern const QLitObject %(c_name)s; ''', diff --git a/scripts/qapi/main.py b/scripts/qapi/main.py index 316736b6a2..324081b9fc 100644 --- a/scripts/qapi/main.py +++ b/scripts/qapi/main.py @@ -15,6 +15,7 @@ from .commands import gen_commands from .common import must_match from .error import QAPIError from .events import gen_events +from .features import gen_features from .introspect import gen_introspect from .schema import QAPISchema from .types import gen_types @@ -49,6 +50,7 @@ def generate(schema_file: str, schema = QAPISchema(schema_file) gen_types(schema, output_dir, prefix, builtins) + gen_features(schema, output_dir, prefix) gen_visit(schema, output_dir, prefix, builtins) gen_commands(schema, output_dir, prefix, gen_tracing) gen_events(schema, output_dir, prefix) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index e97c978d38..7f70969c09 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -29,6 +29,7 @@ from typing import ( List, Optional, Union, + ValuesView, cast, ) @@ -933,8 +934,11 @@ class QAPISchemaEnumMember(QAPISchemaMember): class QAPISchemaFeature(QAPISchemaMember): role = 'feature' + # Features which are standardized across all schemas + SPECIAL_NAMES = ['deprecated', 'unstable'] + def is_special(self) -> bool: - return self.name in ('deprecated', 'unstable') + return self.name in QAPISchemaFeature.SPECIAL_NAMES class QAPISchemaObjectTypeMember(QAPISchemaMember): @@ -1138,6 +1142,16 @@ class QAPISchema: self._entity_list: List[QAPISchemaEntity] = [] self._entity_dict: Dict[str, QAPISchemaDefinition] = {} self._module_dict: Dict[str, QAPISchemaModule] = OrderedDict() + # NB, values in the dict will identify the first encountered + # usage of a named feature only + self._feature_dict: Dict[str, QAPISchemaFeature] = OrderedDict() + + # All schemas get the names defined in the QapiSpecialFeature enum. + # Rely on dict iteration order matching insertion order so that + # the special names are emitted first when generating code. + for f in QAPISchemaFeature.SPECIAL_NAMES: + self._feature_dict[f] = QAPISchemaFeature(f, None) + self._schema_dir = os.path.dirname(fname) self._make_module(QAPISchemaModule.BUILTIN_MODULE_NAME) self._make_module(fname) @@ -1147,6 +1161,9 @@ class QAPISchema: self._def_exprs(exprs) self.check() + def features(self) -> ValuesView[QAPISchemaFeature]: + return self._feature_dict.values() + def _def_entity(self, ent: QAPISchemaEntity) -> None: self._entity_list.append(ent) @@ -1258,6 +1275,12 @@ class QAPISchema: ) -> List[QAPISchemaFeature]: if features is None: return [] + + for f in features: + feat = QAPISchemaFeature(f['name'], info) + if feat.name not in self._feature_dict: + self._feature_dict[feat.name] = feat + return [QAPISchemaFeature(f['name'], info, QAPISchemaIfCond(f.get('if'))) for f in features] @@ -1485,6 +1508,12 @@ class QAPISchema: for doc in self.docs: doc.check() + features = list(self._feature_dict.values()) + if len(features) > 64: + raise QAPISemError( + features[64].info, + "Maximum of 64 schema features is permitted") + def visit(self, visitor: QAPISchemaVisitor) -> None: visitor.visit_begin(self) for mod in self._module_dict.values(): diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index 0dd0b00ada..2bf7533828 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -16,11 +16,7 @@ This work is licensed under the terms of the GNU GPL, version 2. from typing import List, Optional from .common import c_enum_const, c_name, mcgen -from .gen import ( - QAPISchemaModularCVisitor, - gen_special_features, - ifcontext, -) +from .gen import QAPISchemaModularCVisitor, gen_features, ifcontext from .schema import ( QAPISchema, QAPISchemaAlternatives, @@ -61,17 +57,17 @@ const QEnumLookup %(c_name)s_lookup = { index=index, name=memb.name) ret += memb.ifcond.gen_endif() - special_features = gen_special_features(memb.features) - if special_features != '0': + features = gen_features(memb.features) + if features != '0': feats += mcgen(''' - [%(index)s] = %(special_features)s, + [%(index)s] = %(features)s, ''', - index=index, special_features=special_features) + index=index, features=features) if feats: ret += mcgen(''' }, - .special_features = (const unsigned char[%(max_index)s]) { + .features = (const uint64_t[%(max_index)s]) { ''', max_index=max_index) ret += feats @@ -308,11 +304,14 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor): #include "qapi/dealloc-visitor.h" #include "%(types)s.h" #include "%(visit)s.h" +#include "%(prefix)sqapi-features.h" ''', - types=types, visit=visit)) + types=types, visit=visit, + prefix=self._prefix)) self._genh.preamble_add(mcgen(''' #include "qapi/qapi-builtin-types.h" -''')) +''', + prefix=self._prefix)) def visit_begin(self, schema: QAPISchema) -> None: # gen_object() is recursive, ensure it doesn't visit the empty type diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index 12f92e429f..36e240967b 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -21,11 +21,7 @@ from .common import ( indent, mcgen, ) -from .gen import ( - QAPISchemaModularCVisitor, - gen_special_features, - ifcontext, -) +from .gen import QAPISchemaModularCVisitor, gen_features, ifcontext from .schema import ( QAPISchema, QAPISchemaAlternatives, @@ -103,15 +99,15 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) ''', name=memb.name, has=has) indent.increase() - special_features = gen_special_features(memb.features) - if special_features != '0': + features = gen_features(memb.features) + if features != '0': ret += mcgen(''' - if (visit_policy_reject(v, "%(name)s", %(special_features)s, errp)) { + if (visit_policy_reject(v, "%(name)s", %(features)s, errp)) { return false; } - if (!visit_policy_skip(v, "%(name)s", %(special_features)s)) { + if (!visit_policy_skip(v, "%(name)s", %(features)s)) { ''', - name=memb.name, special_features=special_features) + name=memb.name, features=features) indent.increase() ret += mcgen(''' if (!visit_type_%(c_type)s(v, "%(name)s", &obj->%(c_name)s, errp)) { @@ -120,7 +116,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) ''', c_type=memb.type.c_name(), name=memb.name, c_name=c_name(memb.name)) - if special_features != '0': + if features != '0': indent.decrease() ret += mcgen(''' } @@ -360,8 +356,9 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor): #include "qemu/osdep.h" #include "qapi/error.h" #include "%(visit)s.h" +#include "%(prefix)sqapi-features.h" ''', - visit=visit)) + visit=visit, prefix=self._prefix)) self._genh.preamble_add(mcgen(''' #include "qapi/qapi-builtin-visit.h" #include "%(types)s.h" diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py index 4d2a9f6c43..cfae94a2e9 100644 --- a/scripts/qemu-gdb.py +++ b/scripts/qemu-gdb.py @@ -45,3 +45,5 @@ coroutine.CoroutineBt() # Default to silently passing through SIGUSR1, because QEMU sends it # to itself a lot. gdb.execute('handle SIGUSR1 pass noprint nostop') +# Always print full stack for python errors, easier to debug and report issues +gdb.execute('set python print-stack full') diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py index 7db46d4b68..e98fc48a4b 100644 --- a/scripts/qemugdb/coroutine.py +++ b/scripts/qemugdb/coroutine.py @@ -13,28 +13,9 @@ import gdb VOID_PTR = gdb.lookup_type('void').pointer() -def get_fs_base(): - '''Fetch %fs base value using arch_prctl(ARCH_GET_FS). This is - pthread_self().''' - # %rsp - 120 is scratch space according to the SystemV ABI - old = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)') - gdb.execute('call (int)arch_prctl(0x1003, $rsp - 120)', False, True) - fs_base = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)') - gdb.execute('set *(uint64_t*)($rsp - 120) = %s' % old, False, True) - return fs_base - def pthread_self(): - '''Fetch pthread_self() from the glibc start_thread function.''' - f = gdb.newest_frame() - while f.name() != 'start_thread': - f = f.older() - if f is None: - return get_fs_base() - - try: - return f.read_var("arg") - except ValueError: - return get_fs_base() + '''Fetch the base address of TLS.''' + return gdb.parse_and_eval("$fs_base") def get_glibc_pointer_guard(): '''Fetch glibc pointer guard value''' @@ -65,9 +46,60 @@ def get_jmpbuf_regs(jmpbuf): 'r15': jmpbuf[JB_R15], 'rip': glibc_ptr_demangle(jmpbuf[JB_PC], pointer_guard) } -def bt_jmpbuf(jmpbuf): - '''Backtrace a jmpbuf''' - regs = get_jmpbuf_regs(jmpbuf) +def symbol_lookup(addr): + # Example: "__clone3 + 44 in section .text of /lib64/libc.so.6" + result = gdb.execute(f"info symbol {hex(addr)}", to_string=True).strip() + try: + if "+" in result: + (func, result) = result.split(" + ") + (offset, result) = result.split(" in ") + else: + offset = "0" + (func, result) = result.split(" in ") + func_str = f"{func}<+{offset}> ()" + except: + return f"??? ({result})" + + # Example: Line 321 of "../util/coroutine-ucontext.c" starts at address + # 0x55cf3894d993 <qemu_coroutine_switch+99> and ends at 0x55cf3894d9ab + # <qemu_coroutine_switch+123>. + result = gdb.execute(f"info line *{hex(addr)}", to_string=True).strip() + if not result.startswith("Line "): + return func_str + result = result[5:] + + try: + result = result.split(" starts ")[0] + (line, path) = result.split(" of ") + path = path.replace("\"", "") + except: + return func_str + + return f"{func_str} at {path}:{line}" + +def dump_backtrace(regs): + ''' + Backtrace dump with raw registers, mimic GDB command 'bt'. + ''' + # Here only rbp and rip that matter.. + rbp = regs['rbp'] + rip = regs['rip'] + i = 0 + + while rbp: + # For all return addresses on stack, we want to look up symbol/line + # on the CALL command, because the return address is the next + # instruction instead of the CALL. Here -1 would work for any + # sized CALL instruction. + print(f"#{i} {hex(rip)} in {symbol_lookup(rip if i == 0 else rip-1)}") + rip = gdb.parse_and_eval(f"*(uint64_t *)(uint64_t)({hex(rbp)} + 8)") + rbp = gdb.parse_and_eval(f"*(uint64_t *)(uint64_t)({hex(rbp)})") + i += 1 + +def dump_backtrace_live(regs): + ''' + Backtrace dump with gdb's 'bt' command, only usable in a live session. + ''' old = dict() # remember current stack frame and select the topmost @@ -88,6 +120,17 @@ def bt_jmpbuf(jmpbuf): selected_frame.select() +def bt_jmpbuf(jmpbuf): + '''Backtrace a jmpbuf''' + regs = get_jmpbuf_regs(jmpbuf) + try: + # This reuses gdb's "bt" command, which can be slightly prettier + # but only works with live sessions. + dump_backtrace_live(regs) + except: + # If above doesn't work, fallback to poor man's unwind + dump_backtrace(regs) + def co_cast(co): return co.cast(gdb.lookup_type('CoroutineUContext').pointer()) @@ -120,10 +163,15 @@ class CoroutineBt(gdb.Command): gdb.execute("bt") - if gdb.parse_and_eval("qemu_in_coroutine()") == False: - return + try: + # This only works with a live session + co_ptr = gdb.parse_and_eval("qemu_coroutine_self()") + except: + # Fallback to use hard-coded ucontext vars if it's coredump + co_ptr = gdb.parse_and_eval("co_tls_current") - co_ptr = gdb.parse_and_eval("qemu_coroutine_self()") + if co_ptr == False: + return while True: co = co_cast(co_ptr) diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c index c6c6347e9b..b69dd982d6 100644 --- a/scsi/qemu-pr-helper.c +++ b/scsi/qemu-pr-helper.c @@ -47,7 +47,7 @@ #include "qemu/log.h" #include "qemu/systemd.h" #include "qapi/util.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qstring.h" #include "io/channel-socket.h" #include "trace/control.h" #include "qemu-version.h" diff --git a/stats/stats-hmp-cmds.c b/stats/stats-hmp-cmds.c index 1f91bf8bd5..b93b471b1b 100644 --- a/stats/stats-hmp-cmds.c +++ b/stats/stats-hmp-cmds.c @@ -11,7 +11,7 @@ #include "monitor/monitor.h" #include "qemu/cutils.h" #include "hw/core/cpu.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/error.h" static void print_stats_schema_value(Monitor *mon, StatsSchemaValue *value) diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c index 325966eb9e..eb72561358 100644 --- a/storage-daemon/qemu-storage-daemon.c +++ b/storage-daemon/qemu-storage-daemon.c @@ -38,8 +38,8 @@ #include "qapi/qapi-visit-block-core.h" #include "qapi/qapi-visit-block-export.h" #include "qapi/qapi-visit-control.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qapi/qobject-input-visitor.h" #include "qemu/help-texts.h" diff --git a/stubs/qmp-command-available.c b/stubs/qmp-command-available.c index 46540af7bf..8851faced1 100644 --- a/stubs/qmp-command-available.c +++ b/stubs/qmp-command-available.c @@ -1,5 +1,5 @@ #include "qemu/osdep.h" -#include "qapi/qmp/dispatch.h" +#include "qapi/qmp-registry.h" bool qmp_command_available(const QmpCommand *cmd, Error **errp) { diff --git a/stubs/qmp-quit.c b/stubs/qmp-quit.c index a3ff47f7bd..8fb523e905 100644 --- a/stubs/qmp-quit.c +++ b/stubs/qmp-quit.c @@ -1,6 +1,6 @@ #include "qemu/osdep.h" #include "qapi/qapi-commands-control.h" -#include "qapi/qmp/dispatch.h" +#include "qapi/qmp-registry.h" void qmp_quit(Error **errp) { diff --git a/system/device_tree.c b/system/device_tree.c index 11f3178095..4bc2d61b93 100644 --- a/system/device_tree.c +++ b/system/device_tree.c @@ -28,7 +28,7 @@ #include "hw/boards.h" #include "qemu/config-file.h" #include "qapi/qapi-commands-machine.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "monitor/hmp.h" #include <libfdt.h> diff --git a/system/dirtylimit.c b/system/dirtylimit.c index 7c071248bb..7dedef8dd4 100644 --- a/system/dirtylimit.c +++ b/system/dirtylimit.c @@ -13,7 +13,7 @@ #include "qemu/osdep.h" #include "qemu/main-loop.h" #include "qapi/qapi-commands-migration.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/error.h" #include "system/dirtyrate.h" #include "system/dirtylimit.h" diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c index 861c25c855..856c9e8c32 100644 --- a/system/qdev-monitor.c +++ b/system/qdev-monitor.c @@ -26,10 +26,10 @@ #include "system/runstate.h" #include "qapi/error.h" #include "qapi/qapi-commands-qdev.h" -#include "qapi/qmp/dispatch.h" -#include "qapi/qmp/qdict.h" +#include "qapi/qmp-registry.h" +#include "qobject/qdict.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qstring.h" #include "qapi/qobject-input-visitor.h" #include "qemu/config-file.h" #include "qemu/error-report.h" diff --git a/system/runstate-hmp-cmds.c b/system/runstate-hmp-cmds.c index 2df670f0c0..be1d676992 100644 --- a/system/runstate-hmp-cmds.c +++ b/system/runstate-hmp-cmds.c @@ -19,7 +19,7 @@ #include "monitor/monitor.h" #include "qapi/error.h" #include "qapi/qapi-commands-run-state.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/accel.h" void hmp_info_status(Monitor *mon, const QDict *qdict) diff --git a/system/vl.c b/system/vl.c index db8e604eba..9c6942c6cf 100644 --- a/system/vl.c +++ b/system/vl.c @@ -31,9 +31,9 @@ #include "hw/qdev-properties.h" #include "qapi/compat-policy.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" +#include "qobject/qjson.h" #include "qemu-version.h" #include "qemu/cutils.h" #include "qemu/help_option.h" @@ -3469,6 +3469,7 @@ void qemu_init(int argc, char **argv) nb_prom_envs++; break; case QEMU_OPTION_old_param: + warn_report("-old-param is deprecated"); old_param = 1; break; case QEMU_OPTION_rtc: diff --git a/target/alpha/cpu-param.h b/target/alpha/cpu-param.h index c21ddf1afd..ff06e41497 100644 --- a/target/alpha/cpu-param.h +++ b/target/alpha/cpu-param.h @@ -8,8 +8,6 @@ #ifndef ALPHA_CPU_PARAM_H #define ALPHA_CPU_PARAM_H -#define TARGET_LONG_BITS 64 - /* ??? EV4 has 34 phys addr bits, EV5 has 40, EV6 has 44. */ #define TARGET_PHYS_ADDR_SPACE_BITS 44 diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c index 33cea080d1..883c0a0e8c 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c @@ -28,7 +28,7 @@ #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-commands-machine-target.h" #include "qapi/qapi-commands-misc-target.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qom/qom-qobject.h" static GICCapability *gic_cap_new(int version) diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h index bed29613c8..896b35bd6d 100644 --- a/target/arm/cpu-param.h +++ b/target/arm/cpu-param.h @@ -9,11 +9,9 @@ #define ARM_CPU_PARAM_H #ifdef TARGET_AARCH64 -# define TARGET_LONG_BITS 64 # define TARGET_PHYS_ADDR_SPACE_BITS 52 # define TARGET_VIRT_ADDR_SPACE_BITS 52 #else -# define TARGET_LONG_BITS 32 # define TARGET_PHYS_ADDR_SPACE_BITS 40 # define TARGET_VIRT_ADDR_SPACE_BITS 32 #endif diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 7a83b9ee34..32dc7c1e69 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2758,6 +2758,9 @@ static void cpu_register_class_init(ObjectClass *oc, void *data) acc->info = data; cc->gdb_core_xml_file = "arm-core.xml"; + if (acc->info->deprecation_note) { + cc->deprecation_note = acc->info->deprecation_note; + } } void arm_cpu_register(const ARMCPUInfo *info) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 2213c27734..c2d2d99b46 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1118,6 +1118,7 @@ struct ArchCPU { typedef struct ARMCPUInfo { const char *name; + const char *deprecation_note; void (*initfn)(Object *obj); void (*class_init)(ObjectClass *oc, void *data); } ARMCPUInfo; diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c index 2ad2182525..0f1c5bc87e 100644 --- a/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c @@ -1026,19 +1026,31 @@ static const ARMCPUInfo arm_tcg_cpus[] = { { .name = "ti925t", .initfn = ti925t_initfn }, { .name = "sa1100", .initfn = sa1100_initfn }, { .name = "sa1110", .initfn = sa1110_initfn }, - { .name = "pxa250", .initfn = pxa250_initfn }, - { .name = "pxa255", .initfn = pxa255_initfn }, - { .name = "pxa260", .initfn = pxa260_initfn }, - { .name = "pxa261", .initfn = pxa261_initfn }, - { .name = "pxa262", .initfn = pxa262_initfn }, + { .name = "pxa250", .initfn = pxa250_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, + { .name = "pxa255", .initfn = pxa255_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, + { .name = "pxa260", .initfn = pxa260_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, + { .name = "pxa261", .initfn = pxa261_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, + { .name = "pxa262", .initfn = pxa262_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, /* "pxa270" is an alias for "pxa270-a0" */ - { .name = "pxa270", .initfn = pxa270a0_initfn }, - { .name = "pxa270-a0", .initfn = pxa270a0_initfn }, - { .name = "pxa270-a1", .initfn = pxa270a1_initfn }, - { .name = "pxa270-b0", .initfn = pxa270b0_initfn }, - { .name = "pxa270-b1", .initfn = pxa270b1_initfn }, - { .name = "pxa270-c0", .initfn = pxa270c0_initfn }, - { .name = "pxa270-c5", .initfn = pxa270c5_initfn }, + { .name = "pxa270", .initfn = pxa270a0_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, + { .name = "pxa270-a0", .initfn = pxa270a0_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, + { .name = "pxa270-a1", .initfn = pxa270a1_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, + { .name = "pxa270-b0", .initfn = pxa270b0_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, + { .name = "pxa270-b1", .initfn = pxa270b1_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, + { .name = "pxa270-c0", .initfn = pxa270c0_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, + { .name = "pxa270-c5", .initfn = pxa270c5_initfn, + .deprecation_note = "iwMMXt CPUs are no longer supported", }, #ifndef TARGET_AARCH64 { .name = "max", .initfn = arm_max_initfn }, #endif diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 0b76a2cdb7..d6ac2ed418 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -75,17 +75,6 @@ static int scale_by_log2_tag_granule(DisasContext *s, int x) #include "decode-sme-fa64.c.inc" #include "decode-a64.c.inc" -/* Table based decoder typedefs - used when the relevant bits for decode - * are too awkwardly scattered across the instruction (eg SIMD). - */ -typedef void AArch64DecodeFn(DisasContext *s, uint32_t insn); - -typedef struct AArch64DecodeTable { - uint32_t pattern; - uint32_t mask; - AArch64DecodeFn *disas_fn; -} AArch64DecodeTable; - /* initialize TCG globals. */ void a64_translate_init(void) { diff --git a/target/avr/cpu-param.h b/target/avr/cpu-param.h index 93c2f470d0..81f3f49ee1 100644 --- a/target/avr/cpu-param.h +++ b/target/avr/cpu-param.h @@ -21,7 +21,6 @@ #ifndef AVR_CPU_PARAM_H #define AVR_CPU_PARAM_H -#define TARGET_LONG_BITS 32 /* * TARGET_PAGE_BITS cannot be more than 8 bits because * 1. all IO registers occupy [0x0000 .. 0x00ff] address range, and they diff --git a/target/hexagon/cpu-param.h b/target/hexagon/cpu-param.h index 71b4a9b83e..45ee7b4640 100644 --- a/target/hexagon/cpu-param.h +++ b/target/hexagon/cpu-param.h @@ -19,7 +19,6 @@ #define HEXAGON_CPU_PARAM_H #define TARGET_PAGE_BITS 16 /* 64K pages */ -#define TARGET_LONG_BITS 32 #define TARGET_PHYS_ADDR_SPACE_BITS 36 #define TARGET_VIRT_ADDR_SPACE_BITS 32 diff --git a/target/hppa/cpu-param.h b/target/hppa/cpu-param.h index ef3200f0f3..7ed6b5741e 100644 --- a/target/hppa/cpu-param.h +++ b/target/hppa/cpu-param.h @@ -8,8 +8,6 @@ #ifndef HPPA_CPU_PARAM_H #define HPPA_CPU_PARAM_H -#define TARGET_LONG_BITS 64 - #if defined(CONFIG_USER_ONLY) && defined(TARGET_ABI32) # define TARGET_PHYS_ADDR_SPACE_BITS 32 # define TARGET_VIRT_ADDR_SPACE_BITS 32 diff --git a/target/i386/cpu-apic.c b/target/i386/cpu-apic.c index dc844cae8b..c1708b04bb 100644 --- a/target/i386/cpu-apic.c +++ b/target/i386/cpu-apic.c @@ -7,7 +7,7 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/error.h" #include "monitor/monitor.h" #include "monitor/hmp-target.h" diff --git a/target/i386/cpu-param.h b/target/i386/cpu-param.h index 8c75abe141..b0e884c5d7 100644 --- a/target/i386/cpu-param.h +++ b/target/i386/cpu-param.h @@ -9,7 +9,6 @@ #define I386_CPU_PARAM_H #ifdef TARGET_X86_64 -# define TARGET_LONG_BITS 64 # define TARGET_PHYS_ADDR_SPACE_BITS 52 /* * ??? This is really 48 bits, sign-extended, but the only thing @@ -18,7 +17,6 @@ */ # define TARGET_VIRT_ADDR_SPACE_BITS 47 #else -# define TARGET_LONG_BITS 32 # define TARGET_PHYS_ADDR_SPACE_BITS 36 # define TARGET_VIRT_ADDR_SPACE_BITS 32 #endif diff --git a/target/i386/cpu-system.c b/target/i386/cpu-system.c index b56a2821af..55f192e819 100644 --- a/target/i386/cpu-system.c +++ b/target/i386/cpu-system.c @@ -21,7 +21,7 @@ #include "cpu.h" #include "qapi/error.h" #include "qapi/qapi-visit-run-state.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qom/qom-qobject.h" #include "qapi/qapi-commands-machine-target.h" diff --git a/target/i386/monitor.c b/target/i386/monitor.c index 2d766b2637..3ea92b066e 100644 --- a/target/i386/monitor.c +++ b/target/i386/monitor.c @@ -27,7 +27,7 @@ #include "monitor/monitor.h" #include "monitor/hmp-target.h" #include "monitor/hmp.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/error.h" #include "qapi/qapi-commands-misc-target.h" #include "qapi/qapi-commands-misc.h" diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c index 3d764bc138..de6d0b252e 100644 --- a/target/i386/tcg/fpu_helper.c +++ b/target/i386/tcg/fpu_helper.c @@ -178,8 +178,11 @@ void cpu_init_fp_statuses(CPUX86State *env) * "Fused-Multiply-ADD (FMA) Numeric Behavior" the NaN handling is * specified -- for 0 * inf + NaN the input NaN is selected, and if * there are multiple input NaNs they are selected in the order a, b, c. + * We also do not raise Invalid for the 0 * inf + (Q)NaN case. */ - set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status); + set_float_infzeronan_rule(float_infzeronan_dnan_never | + float_infzeronan_suppress_invalid, + &env->sse_status); set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status); /* Default NaN: sign bit set, most significant frac bit set */ set_float_default_nan_pattern(0b11000000, &env->fp_status); diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h index db5ad1c69f..52437946e5 100644 --- a/target/loongarch/cpu-param.h +++ b/target/loongarch/cpu-param.h @@ -8,7 +8,6 @@ #ifndef LOONGARCH_CPU_PARAM_H #define LOONGARCH_CPU_PARAM_H -#define TARGET_LONG_BITS 64 #define TARGET_PHYS_ADDR_SPACE_BITS 48 #define TARGET_VIRT_ADDR_SPACE_BITS 48 diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c index 782fd511fd..3fde5a5a20 100644 --- a/target/loongarch/loongarch-qmp-cmds.c +++ b/target/loongarch/loongarch-qmp-cmds.c @@ -10,7 +10,7 @@ #include "qapi/error.h" #include "qapi/qapi-commands-machine-target.h" #include "cpu.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qom/qom-qobject.h" diff --git a/target/m68k/cpu-param.h b/target/m68k/cpu-param.h index 5bbe623ba7..7afbf6d302 100644 --- a/target/m68k/cpu-param.h +++ b/target/m68k/cpu-param.h @@ -8,7 +8,6 @@ #ifndef M68K_CPU_PARAM_H #define M68K_CPU_PARAM_H -#define TARGET_LONG_BITS 32 /* * Coldfire Linux uses 8k pages * and m68k linux uses 4k pages diff --git a/target/microblaze/cpu-param.h b/target/microblaze/cpu-param.h index 00efb509e3..c866ec6c14 100644 --- a/target/microblaze/cpu-param.h +++ b/target/microblaze/cpu-param.h @@ -17,11 +17,9 @@ * of address space. */ #ifdef CONFIG_USER_ONLY -#define TARGET_LONG_BITS 32 #define TARGET_PHYS_ADDR_SPACE_BITS 32 #define TARGET_VIRT_ADDR_SPACE_BITS 32 #else -#define TARGET_LONG_BITS 64 #define TARGET_PHYS_ADDR_SPACE_BITS 64 #define TARGET_VIRT_ADDR_SPACE_BITS 64 #endif diff --git a/target/mips/cpu-param.h b/target/mips/cpu-param.h index f3a37e2dbe..11b3ac0ac6 100644 --- a/target/mips/cpu-param.h +++ b/target/mips/cpu-param.h @@ -7,11 +7,6 @@ #ifndef MIPS_CPU_PARAM_H #define MIPS_CPU_PARAM_H -#ifdef TARGET_MIPS64 -# define TARGET_LONG_BITS 64 -#else -# define TARGET_LONG_BITS 32 -#endif #ifdef TARGET_ABI_MIPSN64 #define TARGET_PHYS_ADDR_SPACE_BITS 48 #define TARGET_VIRT_ADDR_SPACE_BITS 48 diff --git a/target/openrisc/cpu-param.h b/target/openrisc/cpu-param.h index 6169ed9f55..37627f2c39 100644 --- a/target/openrisc/cpu-param.h +++ b/target/openrisc/cpu-param.h @@ -8,7 +8,6 @@ #ifndef OPENRISC_CPU_PARAM_H #define OPENRISC_CPU_PARAM_H -#define TARGET_LONG_BITS 32 #define TARGET_PAGE_BITS 13 #define TARGET_PHYS_ADDR_SPACE_BITS 32 #define TARGET_VIRT_ADDR_SPACE_BITS 32 diff --git a/target/ppc/cpu-param.h b/target/ppc/cpu-param.h index 9c481b9f6c..6c4525fdf3 100644 --- a/target/ppc/cpu-param.h +++ b/target/ppc/cpu-param.h @@ -9,7 +9,6 @@ #define PPC_CPU_PARAM_H #ifdef TARGET_PPC64 -# define TARGET_LONG_BITS 64 /* * Note that the official physical address space bits is 62-M where M * is implementation dependent. I've not looked up M for the set of @@ -27,7 +26,6 @@ # define TARGET_VIRT_ADDR_SPACE_BITS 64 # endif #else -# define TARGET_LONG_BITS 32 # define TARGET_PHYS_ADDR_SPACE_BITS 36 # define TARGET_VIRT_ADDR_SPACE_BITS 32 #endif diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index c05c2dc42d..8e49051254 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -32,7 +32,7 @@ #include "qemu/module.h" #include "qemu/qemu-print.h" #include "qapi/error.h" -#include "qapi/qmp/qnull.h" +#include "qobject/qnull.h" #include "qapi/visitor.h" #include "hw/qdev-properties.h" #include "hw/ppc/ppc.h" diff --git a/target/riscv/cpu-param.h b/target/riscv/cpu-param.h index 25686192c0..fba30e966a 100644 --- a/target/riscv/cpu-param.h +++ b/target/riscv/cpu-param.h @@ -9,11 +9,9 @@ #define RISCV_CPU_PARAM_H #if defined(TARGET_RISCV64) -# define TARGET_LONG_BITS 64 # define TARGET_PHYS_ADDR_SPACE_BITS 56 /* 44-bit PPN */ # define TARGET_VIRT_ADDR_SPACE_BITS 48 /* sv48 */ #elif defined(TARGET_RISCV32) -# define TARGET_LONG_BITS 32 # define TARGET_PHYS_ADDR_SPACE_BITS 34 /* 22-bit PPN */ # define TARGET_VIRT_ADDR_SPACE_BITS 32 /* sv32 */ #endif diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c index e945b3eb02..d0a324364d 100644 --- a/target/riscv/riscv-qmp-cmds.c +++ b/target/riscv/riscv-qmp-cmds.c @@ -26,8 +26,8 @@ #include "qapi/error.h" #include "qapi/qapi-commands-machine-target.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qapi/visitor.h" #include "qom/qom-qobject.h" diff --git a/target/rx/cpu-param.h b/target/rx/cpu-param.h index 521d669bdf..ef1970a09e 100644 --- a/target/rx/cpu-param.h +++ b/target/rx/cpu-param.h @@ -19,7 +19,6 @@ #ifndef RX_CPU_PARAM_H #define RX_CPU_PARAM_H -#define TARGET_LONG_BITS 32 #define TARGET_PAGE_BITS 12 #define TARGET_PHYS_ADDR_SPACE_BITS 32 diff --git a/target/s390x/cpu-param.h b/target/s390x/cpu-param.h index a05ffcf78d..5c331ec424 100644 --- a/target/s390x/cpu-param.h +++ b/target/s390x/cpu-param.h @@ -8,7 +8,6 @@ #ifndef S390_CPU_PARAM_H #define S390_CPU_PARAM_H -#define TARGET_LONG_BITS 64 #define TARGET_PAGE_BITS 12 #define TARGET_PHYS_ADDR_SPACE_BITS 64 #define TARGET_VIRT_ADDR_SPACE_BITS 64 diff --git a/target/s390x/cpu_models_system.c b/target/s390x/cpu_models_system.c index 6b65fa2276..4351182f72 100644 --- a/target/s390x/cpu_models_system.c +++ b/target/s390x/cpu_models_system.c @@ -18,7 +18,7 @@ #include "qapi/error.h" #include "qapi/visitor.h" #include "qapi/qobject-input-visitor.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qapi-commands-machine-target.h" static void list_add_feat(const char *name, void *opaque); diff --git a/target/sh4/cpu-param.h b/target/sh4/cpu-param.h index a30ba992b3..2b6e11dd0a 100644 --- a/target/sh4/cpu-param.h +++ b/target/sh4/cpu-param.h @@ -8,7 +8,6 @@ #ifndef SH4_CPU_PARAM_H #define SH4_CPU_PARAM_H -#define TARGET_LONG_BITS 32 #define TARGET_PAGE_BITS 12 /* 4k */ #define TARGET_PHYS_ADDR_SPACE_BITS 32 #ifdef CONFIG_USER_ONLY diff --git a/target/sparc/cpu-param.h b/target/sparc/cpu-param.h index 14105dc18b..6952ee2b82 100644 --- a/target/sparc/cpu-param.h +++ b/target/sparc/cpu-param.h @@ -8,7 +8,6 @@ #define SPARC_CPU_PARAM_H #ifdef TARGET_SPARC64 -# define TARGET_LONG_BITS 64 # define TARGET_PAGE_BITS 13 /* 8k */ # define TARGET_PHYS_ADDR_SPACE_BITS 41 # ifdef TARGET_ABI32 @@ -17,7 +16,6 @@ # define TARGET_VIRT_ADDR_SPACE_BITS 44 # endif #else -# define TARGET_LONG_BITS 32 # define TARGET_PAGE_BITS 12 /* 4k */ # define TARGET_PHYS_ADDR_SPACE_BITS 36 # define TARGET_VIRT_ADDR_SPACE_BITS 32 diff --git a/target/tricore/cpu-param.h b/target/tricore/cpu-param.h index e29d551dd6..790242ef3d 100644 --- a/target/tricore/cpu-param.h +++ b/target/tricore/cpu-param.h @@ -8,7 +8,6 @@ #ifndef TRICORE_CPU_PARAM_H #define TRICORE_CPU_PARAM_H -#define TARGET_LONG_BITS 32 #define TARGET_PAGE_BITS 14 #define TARGET_PHYS_ADDR_SPACE_BITS 32 #define TARGET_VIRT_ADDR_SPACE_BITS 32 diff --git a/target/xtensa/cpu-param.h b/target/xtensa/cpu-param.h index 0000725f2f..5e4848ad05 100644 --- a/target/xtensa/cpu-param.h +++ b/target/xtensa/cpu-param.h @@ -8,7 +8,6 @@ #ifndef XTENSA_CPU_PARAM_H #define XTENSA_CPU_PARAM_H -#define TARGET_LONG_BITS 32 #define TARGET_PAGE_BITS 12 #define TARGET_PHYS_ADDR_SPACE_BITS 32 #ifdef CONFIG_USER_ONLY diff --git a/tcg/optimize.c b/tcg/optimize.c index 8c6303e3af..bca11cc427 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -766,6 +766,7 @@ static int do_constant_folding_cond1(OptContext *ctx, TCGOp *op, TCGArg dest, TCGArg *p1, TCGArg *p2, TCGArg *pcond) { TCGCond cond; + TempOptInfo *i1; bool swap; int r; @@ -783,19 +784,21 @@ static int do_constant_folding_cond1(OptContext *ctx, TCGOp *op, TCGArg dest, return -1; } + i1 = arg_info(*p1); + /* * TSTNE x,x -> NE x,0 - * TSTNE x,-1 -> NE x,0 + * TSTNE x,i -> NE x,0 if i includes all nonzero bits of x */ - if (args_are_copies(*p1, *p2) || arg_is_const_val(*p2, -1)) { + if (args_are_copies(*p1, *p2) || + (arg_is_const(*p2) && (i1->z_mask & ~arg_info(*p2)->val) == 0)) { *p2 = arg_new_constant(ctx, 0); *pcond = tcg_tst_eqne_cond(cond); return -1; } - /* TSTNE x,sign -> LT x,0 */ - if (arg_is_const_val(*p2, (ctx->type == TCG_TYPE_I32 - ? INT32_MIN : INT64_MIN))) { + /* TSTNE x,i -> LT x,0 if i only includes sign bit copies */ + if (arg_is_const(*p2) && (arg_info(*p2)->val & ~i1->s_mask) == 0) { *p2 = arg_new_constant(ctx, 0); *pcond = tcg_tst_ltge_cond(cond); return -1; diff --git a/tests/meson.build b/tests/meson.build index f96c1be574..c59619220f 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -16,6 +16,8 @@ test_qapi_outputs = [ 'test-qapi-events-sub-sub-module.h', 'test-qapi-events.c', 'test-qapi-events.h', + 'test-qapi-features.c', + 'test-qapi-features.h', 'test-qapi-init-commands.c', 'test-qapi-init-commands.h', 'test-qapi-introspect.c', diff --git a/tests/qapi-schema/features-too-many.err b/tests/qapi-schema/features-too-many.err new file mode 100644 index 0000000000..bbbd6e5202 --- /dev/null +++ b/tests/qapi-schema/features-too-many.err @@ -0,0 +1,2 @@ +features-too-many.json: In command 'go-fish': +features-too-many.json:2: Maximum of 64 schema features is permitted diff --git a/tests/qapi-schema/features-too-many.json b/tests/qapi-schema/features-too-many.json new file mode 100644 index 0000000000..aab0a0b5f1 --- /dev/null +++ b/tests/qapi-schema/features-too-many.json @@ -0,0 +1,13 @@ +# Max 64 features, with 2 specials, so 63rd custom is invalid +{ 'command': 'go-fish', + 'features': [ + 'f00', 'f01', 'f02', 'f03', 'f04', 'f05', 'f06', 'f07', + 'f08', 'f09', 'f0a', 'f0b', 'f0c', 'f0d', 'f0e', 'f0f', + 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', + 'f18', 'f19', 'f1a', 'f1b', 'f1c', 'f1d', 'f1e', 'f1f', + 'f20', 'f21', 'f22', 'f23', 'f24', 'f25', 'f26', 'f27', + 'f28', 'f29', 'f2a', 'f2b', 'f2c', 'f2d', 'f2e', 'f2f', + 'f30', 'f31', 'f32', 'f33', 'f34', 'f35', 'f36', 'f37', + 'f38', 'f39', 'f3a', 'f3b', 'f3c', 'f3d', 'f3e' + ] +} diff --git a/tests/qapi-schema/features-too-many.out b/tests/qapi-schema/features-too-many.out new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/qapi-schema/features-too-many.out diff --git a/tests/qapi-schema/meson.build b/tests/qapi-schema/meson.build index 0f479d9317..9577178b6f 100644 --- a/tests/qapi-schema/meson.build +++ b/tests/qapi-schema/meson.build @@ -105,6 +105,7 @@ schemas = [ 'event-case.json', 'event-member-invalid-dict.json', 'event-nest-struct.json', + 'features-too-many.json', 'features-bad-type.json', 'features-deprecated-type.json', 'features-duplicate-name.json', diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index 98d17b1388..8452845f44 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -1100,10 +1100,8 @@ class TestRepairQuorum(iotests.QMPTestCase): # Check the full error message now self.vm.shutdown() - log = self.vm.get_log() - log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) + log = iotests.filter_qtest(self.vm.get_log()) log = re.sub(r'^Formatting.*\n', '', log) - log = re.sub(r'\n\[I \+\d+\.\d+\] CLOSED\n?$', '', log) log = re.sub(r'^%s: ' % os.path.basename(iotests.qemu_prog), '', log) self.assertEqual(log, diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165 index b24907a62f..b3b1709d71 100755 --- a/tests/qemu-iotests/165 +++ b/tests/qemu-iotests/165 @@ -82,9 +82,7 @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase): self.vm.shutdown() #catch 'Persistent bitmaps are lost' possible error - log = self.vm.get_log() - log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) - log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) + log = iotests.filter_qtest(self.vm.get_log()) if log: print(log) diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out index e8f631f853..52692b6b3b 100644 --- a/tests/qemu-iotests/184.out +++ b/tests/qemu-iotests/184.out @@ -26,6 +26,7 @@ Testing: { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "backing-image": { "virtual-size": 1073741824, @@ -59,6 +60,7 @@ Testing: { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 1073741824, "filename": "null-co://", diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out index c3309e4bc6..2a72ca7106 100644 --- a/tests/qemu-iotests/191.out +++ b/tests/qemu-iotests/191.out @@ -114,6 +114,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "backing-image": { "virtual-size": 67108864, @@ -155,6 +156,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 197120, "filename": "TEST_DIR/t.IMGFMT.ovl2", @@ -183,6 +185,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "backing-image": { "virtual-size": 67108864, @@ -224,6 +227,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 197120, "filename": "TEST_DIR/t.IMGFMT", @@ -252,6 +256,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "backing-image": { "virtual-size": 67108864, @@ -293,6 +298,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 393216, "filename": "TEST_DIR/t.IMGFMT.mid", @@ -321,6 +327,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 67108864, "filename": "TEST_DIR/t.IMGFMT.base", @@ -350,6 +357,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 393216, "filename": "TEST_DIR/t.IMGFMT.base", @@ -521,6 +529,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "backing-image": { "virtual-size": 67108864, @@ -562,6 +571,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 197120, "filename": "TEST_DIR/t.IMGFMT.ovl2", @@ -590,6 +600,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "backing-image": { "backing-image": { @@ -642,6 +653,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 197120, "filename": "TEST_DIR/t.IMGFMT.ovl3", @@ -670,6 +682,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 67108864, "filename": "TEST_DIR/t.IMGFMT.base", @@ -699,6 +712,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 393216, "filename": "TEST_DIR/t.IMGFMT.base", @@ -727,6 +741,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "backing-image": { "virtual-size": 67108864, @@ -768,6 +783,7 @@ wrote 65536/65536 bytes at offset 1048576 { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 197120, "filename": "TEST_DIR/t.IMGFMT", diff --git a/tests/qemu-iotests/273.out b/tests/qemu-iotests/273.out index 71843f02de..c19753c685 100644 --- a/tests/qemu-iotests/273.out +++ b/tests/qemu-iotests/273.out @@ -23,6 +23,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "backing-image": { "backing-image": { @@ -74,6 +75,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 197120, "filename": "TEST_DIR/t.IMGFMT", @@ -102,6 +104,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "backing-image": { "virtual-size": 197120, @@ -142,6 +145,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 197120, "filename": "TEST_DIR/t.IMGFMT.mid", @@ -170,6 +174,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev { "iops_rd": 0, "detect_zeroes": "off", + "active": true, "image": { "virtual-size": 197120, "filename": "TEST_DIR/t.IMGFMT.base", diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 19817c7353..7292c8b342 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -701,6 +701,10 @@ def filter_qmp_imgfmt(qmsg): def filter_nbd_exports(output: str) -> str: return re.sub(r'((min|opt|max) block): [0-9]+', r'\1: XXX', output) +def filter_qtest(output: str) -> str: + output = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', output) + output = re.sub(r'\n?\[I \+\d+\.\d+\] CLOSED\n?$', '', output) + return output Msg = TypeVar('Msg', Dict[str, Any], List[Any], str) @@ -909,6 +913,10 @@ class VM(qtest.QEMUQtestMachine): self._args.append(addr) return self + def add_paused(self): + self._args.append('-S') + return self + def hmp(self, command_line: str, use_log: bool = False) -> QMPMessage: cmd = 'human-monitor-command' kwargs: Dict[str, Any] = {'command-line': command_line} diff --git a/tests/qemu-iotests/tests/copy-before-write b/tests/qemu-iotests/tests/copy-before-write index d33bea577d..498c558008 100755 --- a/tests/qemu-iotests/tests/copy-before-write +++ b/tests/qemu-iotests/tests/copy-before-write @@ -95,8 +95,7 @@ class TestCbwError(iotests.QMPTestCase): self.vm.shutdown() log = self.vm.get_log() - log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) - log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) + log = iotests.filter_qtest(log) log = iotests.filter_qemu_io(log) return log diff --git a/tests/qemu-iotests/tests/inactive-node-nbd b/tests/qemu-iotests/tests/inactive-node-nbd new file mode 100755 index 0000000000..a95b37e796 --- /dev/null +++ b/tests/qemu-iotests/tests/inactive-node-nbd @@ -0,0 +1,303 @@ +#!/usr/bin/env python3 +# group: rw quick +# +# Copyright (C) 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: Kevin Wolf <kwolf@redhat.com> + +import iotests + +from iotests import QemuIoInteractive +from iotests import filter_qemu_io, filter_qtest, filter_qmp_testfiles + +iotests.script_initialize(supported_fmts=['generic'], + supported_protocols=['file'], + supported_platforms=['linux']) + +def get_export(node_name='disk-fmt', allow_inactive=None): + exp = { + 'id': 'exp0', + 'type': 'nbd', + 'node-name': node_name, + 'writable': True, + } + + if allow_inactive is not None: + exp['allow-inactive'] = allow_inactive + + return exp + +def node_is_active(_vm, node_name): + nodes = _vm.cmd('query-named-block-nodes', flat=True) + node = next(n for n in nodes if n['node-name'] == node_name) + return node['active'] + +with iotests.FilePath('disk.img') as path, \ + iotests.FilePath('snap.qcow2') as snap_path, \ + iotests.FilePath('snap2.qcow2') as snap2_path, \ + iotests.FilePath('target.img') as target_path, \ + iotests.FilePath('nbd.sock', base_dir=iotests.sock_dir) as nbd_sock, \ + iotests.VM() as vm: + + img_size = '10M' + + iotests.log('Preparing disk...') + iotests.qemu_img_create('-f', iotests.imgfmt, path, img_size) + iotests.qemu_img_create('-f', iotests.imgfmt, target_path, img_size) + + iotests.qemu_img_create('-f', 'qcow2', '-b', path, '-F', iotests.imgfmt, + snap_path) + iotests.qemu_img_create('-f', 'qcow2', '-b', snap_path, '-F', 'qcow2', + snap2_path) + + iotests.log('Launching VM...') + vm.add_blockdev(f'file,node-name=disk-file,filename={path}') + vm.add_blockdev(f'{iotests.imgfmt},file=disk-file,node-name=disk-fmt,' + 'active=off') + vm.add_blockdev(f'file,node-name=target-file,filename={target_path}') + vm.add_blockdev(f'{iotests.imgfmt},file=target-file,node-name=target-fmt') + vm.add_blockdev(f'file,node-name=snap-file,filename={snap_path}') + vm.add_blockdev(f'file,node-name=snap2-file,filename={snap2_path}') + + # Actually running the VM activates all images + vm.add_paused() + + vm.launch() + vm.qmp_log('nbd-server-start', + addr={'type': 'unix', 'data':{'path': nbd_sock}}, + filters=[filter_qmp_testfiles]) + + iotests.log('\n=== Creating export of inactive node ===') + + iotests.log('\nExports activate nodes without allow-inactive') + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + vm.qmp_log('block-export-add', **get_export()) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + vm.qmp_log('query-block-exports') + vm.qmp_log('block-export-del', id='exp0') + vm.event_wait('BLOCK_EXPORT_DELETED') + vm.qmp_log('query-block-exports') + + iotests.log('\nExports activate nodes with allow-inactive=false') + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + vm.qmp_log('block-export-add', **get_export(allow_inactive=False)) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + vm.qmp_log('query-block-exports') + vm.qmp_log('block-export-del', id='exp0') + vm.event_wait('BLOCK_EXPORT_DELETED') + vm.qmp_log('query-block-exports') + + iotests.log('\nExport leaves nodes inactive with allow-inactive=true') + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + vm.qmp_log('block-export-add', **get_export(allow_inactive=True)) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + vm.qmp_log('query-block-exports') + vm.qmp_log('block-export-del', id='exp0') + vm.event_wait('BLOCK_EXPORT_DELETED') + vm.qmp_log('query-block-exports') + + iotests.log('\n=== Inactivating node with existing export ===') + + iotests.log('\nInactivating nodes with an export fails without ' + 'allow-inactive') + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) + vm.qmp_log('block-export-add', **get_export(node_name='disk-fmt')) + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + vm.qmp_log('query-block-exports') + vm.qmp_log('block-export-del', id='exp0') + vm.event_wait('BLOCK_EXPORT_DELETED') + vm.qmp_log('query-block-exports') + + iotests.log('\nInactivating nodes with an export fails with ' + 'allow-inactive=false') + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) + vm.qmp_log('block-export-add', + **get_export(node_name='disk-fmt', allow_inactive=False)) + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + vm.qmp_log('query-block-exports') + vm.qmp_log('block-export-del', id='exp0') + vm.event_wait('BLOCK_EXPORT_DELETED') + vm.qmp_log('query-block-exports') + + iotests.log('\nInactivating nodes with an export works with ' + 'allow-inactive=true') + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) + vm.qmp_log('block-export-add', + **get_export(node_name='disk-fmt', allow_inactive=True)) + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + vm.qmp_log('query-block-exports') + vm.qmp_log('block-export-del', id='exp0') + vm.event_wait('BLOCK_EXPORT_DELETED') + vm.qmp_log('query-block-exports') + + iotests.log('\n=== Inactive nodes with parent ===') + + iotests.log('\nInactivating nodes with an active parent fails') + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) + vm.qmp_log('blockdev-set-active', node_name='disk-file', active=False) + iotests.log('disk-file active: %s' % node_is_active(vm, 'disk-file')) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + + iotests.log('\nInactivating nodes with an inactive parent works') + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) + vm.qmp_log('blockdev-set-active', node_name='disk-file', active=False) + iotests.log('disk-file active: %s' % node_is_active(vm, 'disk-file')) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + + iotests.log('\nCreating active parent node with an inactive child fails') + vm.qmp_log('blockdev-add', driver='raw', file='disk-fmt', + node_name='disk-filter') + vm.qmp_log('blockdev-add', driver='raw', file='disk-fmt', + node_name='disk-filter', active=True) + + iotests.log('\nCreating inactive parent node with an inactive child works') + vm.qmp_log('blockdev-add', driver='raw', file='disk-fmt', + node_name='disk-filter', active=False) + vm.qmp_log('blockdev-del', node_name='disk-filter') + + iotests.log('\n=== Resizing an inactive node ===') + vm.qmp_log('block_resize', node_name='disk-fmt', size=16*1024*1024) + + iotests.log('\n=== Taking a snapshot of an inactive node ===') + + iotests.log('\nActive overlay over inactive backing file automatically ' + 'makes both inactive for compatibility') + vm.qmp_log('blockdev-add', driver='qcow2', node_name='snap-fmt', + file='snap-file', backing=None) + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) + vm.qmp_log('blockdev-snapshot', node='disk-fmt', overlay='snap-fmt') + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) + vm.qmp_log('blockdev-del', node_name='snap-fmt') + + iotests.log('\nInactive overlay over inactive backing file just works') + vm.qmp_log('blockdev-add', driver='qcow2', node_name='snap-fmt', + file='snap-file', backing=None, active=False) + vm.qmp_log('blockdev-snapshot', node='disk-fmt', overlay='snap-fmt') + + iotests.log('\n=== Block jobs with inactive nodes ===') + + iotests.log('\nStreaming into an inactive node') + vm.qmp_log('block-stream', device='snap-fmt', + filters=[iotests.filter_qmp_generated_node_ids]) + + iotests.log('\nCommitting an inactive root node (active commit)') + vm.qmp_log('block-commit', job_id='job0', device='snap-fmt', + filters=[iotests.filter_qmp_generated_node_ids]) + + iotests.log('\nCommitting an inactive intermediate node to inactive base') + vm.qmp_log('blockdev-add', driver='qcow2', node_name='snap2-fmt', + file='snap2-file', backing='snap-fmt', active=False) + + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) + iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) + + vm.qmp_log('block-commit', job_id='job0', device='snap2-fmt', + top_node='snap-fmt', + filters=[iotests.filter_qmp_generated_node_ids]) + + iotests.log('\nCommitting an inactive intermediate node to active base') + vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) + vm.qmp_log('block-commit', job_id='job0', device='snap2-fmt', + top_node='snap-fmt', + filters=[iotests.filter_qmp_generated_node_ids]) + + iotests.log('\nMirror from inactive source to active target') + vm.qmp_log('blockdev-mirror', job_id='job0', device='snap2-fmt', + target='target-fmt', sync='full', + filters=[iotests.filter_qmp_generated_node_ids]) + + iotests.log('\nMirror from active source to inactive target') + + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) + iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) + iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) + + # Activating snap2-fmt recursively activates the whole backing chain + vm.qmp_log('blockdev-set-active', node_name='snap2-fmt', active=True) + vm.qmp_log('blockdev-set-active', node_name='target-fmt', active=False) + + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) + iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) + iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) + + vm.qmp_log('blockdev-mirror', job_id='job0', device='snap2-fmt', + target='target-fmt', sync='full', + filters=[iotests.filter_qmp_generated_node_ids]) + + iotests.log('\nBackup from active source to inactive target') + + vm.qmp_log('blockdev-backup', job_id='job0', device='snap2-fmt', + target='target-fmt', sync='full', + filters=[iotests.filter_qmp_generated_node_ids]) + + iotests.log('\nBackup from inactive source to active target') + + # Inactivating snap2-fmt recursively inactivates the whole backing chain + vm.qmp_log('blockdev-set-active', node_name='snap2-fmt', active=False) + vm.qmp_log('blockdev-set-active', node_name='target-fmt', active=True) + + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) + iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) + iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) + + vm.qmp_log('blockdev-backup', job_id='job0', device='snap2-fmt', + target='target-fmt', sync='full', + filters=[iotests.filter_qmp_generated_node_ids]) + + iotests.log('\n=== Accessing export on inactive node ===') + + # Use the target node because it has the right image format and isn't the + # (read-only) backing file of a qcow2 node + vm.qmp_log('blockdev-set-active', node_name='target-fmt', active=False) + vm.qmp_log('block-export-add', + **get_export(node_name='target-fmt', allow_inactive=True)) + + # The read should succeed, everything else should fail gracefully + qemu_io = QemuIoInteractive('-f', 'raw', + f'nbd+unix:///target-fmt?socket={nbd_sock}') + iotests.log(qemu_io.cmd('read 0 64k'), filters=[filter_qemu_io]) + iotests.log(qemu_io.cmd('write 0 64k'), filters=[filter_qemu_io]) + iotests.log(qemu_io.cmd('write -z 0 64k'), filters=[filter_qemu_io]) + iotests.log(qemu_io.cmd('write -zu 0 64k'), filters=[filter_qemu_io]) + iotests.log(qemu_io.cmd('discard 0 64k'), filters=[filter_qemu_io]) + iotests.log(qemu_io.cmd('flush'), filters=[filter_qemu_io]) + iotests.log(qemu_io.cmd('map'), filters=[filter_qemu_io]) + qemu_io.close() + + iotests.log('\n=== Resuming VM activates all images ===') + vm.qmp_log('cont') + + iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) + iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) + iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) + iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) + + iotests.log('\nShutting down...') + vm.shutdown() + log = vm.get_log() + if log: + iotests.log(log, [filter_qtest, filter_qemu_io]) diff --git a/tests/qemu-iotests/tests/inactive-node-nbd.out b/tests/qemu-iotests/tests/inactive-node-nbd.out new file mode 100644 index 0000000000..a458b4fc05 --- /dev/null +++ b/tests/qemu-iotests/tests/inactive-node-nbd.out @@ -0,0 +1,239 @@ +Preparing disk... +Launching VM... +{"execute": "nbd-server-start", "arguments": {"addr": {"data": {"path": "SOCK_DIR/PID-nbd.sock"}, "type": "unix"}}} +{"return": {}} + +=== Creating export of inactive node === + +Exports activate nodes without allow-inactive +disk-fmt active: False +{"execute": "block-export-add", "arguments": {"id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} +{"return": {}} +disk-fmt active: True +{"execute": "query-block-exports", "arguments": {}} +{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} +{"execute": "block-export-del", "arguments": {"id": "exp0"}} +{"return": {}} +{"execute": "query-block-exports", "arguments": {}} +{"return": []} + +Exports activate nodes with allow-inactive=false +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} +{"return": {}} +disk-fmt active: False +{"execute": "block-export-add", "arguments": {"allow-inactive": false, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} +{"return": {}} +disk-fmt active: True +{"execute": "query-block-exports", "arguments": {}} +{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} +{"execute": "block-export-del", "arguments": {"id": "exp0"}} +{"return": {}} +{"execute": "query-block-exports", "arguments": {}} +{"return": []} + +Export leaves nodes inactive with allow-inactive=true +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} +{"return": {}} +disk-fmt active: False +{"execute": "block-export-add", "arguments": {"allow-inactive": true, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} +{"return": {}} +disk-fmt active: False +{"execute": "query-block-exports", "arguments": {}} +{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} +{"execute": "block-export-del", "arguments": {"id": "exp0"}} +{"return": {}} +{"execute": "query-block-exports", "arguments": {}} +{"return": []} + +=== Inactivating node with existing export === + +Inactivating nodes with an export fails without allow-inactive +{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} +{"return": {}} +{"execute": "block-export-add", "arguments": {"id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} +{"return": {}} +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} +{"error": {"class": "GenericError", "desc": "Failed to inactivate node: Operation not permitted"}} +disk-fmt active: True +{"execute": "query-block-exports", "arguments": {}} +{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} +{"execute": "block-export-del", "arguments": {"id": "exp0"}} +{"return": {}} +{"execute": "query-block-exports", "arguments": {}} +{"return": []} + +Inactivating nodes with an export fails with allow-inactive=false +{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} +{"return": {}} +{"execute": "block-export-add", "arguments": {"allow-inactive": false, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} +{"return": {}} +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} +{"error": {"class": "GenericError", "desc": "Failed to inactivate node: Operation not permitted"}} +disk-fmt active: True +{"execute": "query-block-exports", "arguments": {}} +{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} +{"execute": "block-export-del", "arguments": {"id": "exp0"}} +{"return": {}} +{"execute": "query-block-exports", "arguments": {}} +{"return": []} + +Inactivating nodes with an export works with allow-inactive=true +{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} +{"return": {}} +{"execute": "block-export-add", "arguments": {"allow-inactive": true, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} +{"return": {}} +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} +{"return": {}} +disk-fmt active: False +{"execute": "query-block-exports", "arguments": {}} +{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} +{"execute": "block-export-del", "arguments": {"id": "exp0"}} +{"return": {}} +{"execute": "query-block-exports", "arguments": {}} +{"return": []} + +=== Inactive nodes with parent === + +Inactivating nodes with an active parent fails +{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} +{"return": {}} +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-file"}} +{"error": {"class": "GenericError", "desc": "Node has active parent node"}} +disk-file active: True +disk-fmt active: True + +Inactivating nodes with an inactive parent works +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} +{"return": {}} +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-file"}} +{"return": {}} +disk-file active: False +disk-fmt active: False + +Creating active parent node with an inactive child fails +{"execute": "blockdev-add", "arguments": {"driver": "raw", "file": "disk-fmt", "node-name": "disk-filter"}} +{"error": {"class": "GenericError", "desc": "Inactive 'disk-fmt' can't be a file child of active 'disk-filter'"}} +{"execute": "blockdev-add", "arguments": {"active": true, "driver": "raw", "file": "disk-fmt", "node-name": "disk-filter"}} +{"error": {"class": "GenericError", "desc": "Inactive 'disk-fmt' can't be a file child of active 'disk-filter'"}} + +Creating inactive parent node with an inactive child works +{"execute": "blockdev-add", "arguments": {"active": false, "driver": "raw", "file": "disk-fmt", "node-name": "disk-filter"}} +{"return": {}} +{"execute": "blockdev-del", "arguments": {"node-name": "disk-filter"}} +{"return": {}} + +=== Resizing an inactive node === +{"execute": "block_resize", "arguments": {"node-name": "disk-fmt", "size": 16777216}} +{"error": {"class": "GenericError", "desc": "Permission 'resize' unavailable on inactive node"}} + +=== Taking a snapshot of an inactive node === + +Active overlay over inactive backing file automatically makes both inactive for compatibility +{"execute": "blockdev-add", "arguments": {"backing": null, "driver": "qcow2", "file": "snap-file", "node-name": "snap-fmt"}} +{"return": {}} +disk-fmt active: False +snap-fmt active: True +{"execute": "blockdev-snapshot", "arguments": {"node": "disk-fmt", "overlay": "snap-fmt"}} +{"return": {}} +disk-fmt active: False +snap-fmt active: False +{"execute": "blockdev-del", "arguments": {"node-name": "snap-fmt"}} +{"return": {}} + +Inactive overlay over inactive backing file just works +{"execute": "blockdev-add", "arguments": {"active": false, "backing": null, "driver": "qcow2", "file": "snap-file", "node-name": "snap-fmt"}} +{"return": {}} +{"execute": "blockdev-snapshot", "arguments": {"node": "disk-fmt", "overlay": "snap-fmt"}} +{"return": {}} + +=== Block jobs with inactive nodes === + +Streaming into an inactive node +{"execute": "block-stream", "arguments": {"device": "snap-fmt"}} +{"error": {"class": "GenericError", "desc": "Could not create node: Inactive 'snap-fmt' can't be a file child of active 'NODE_NAME'"}} + +Committing an inactive root node (active commit) +{"execute": "block-commit", "arguments": {"device": "snap-fmt", "job-id": "job0"}} +{"error": {"class": "GenericError", "desc": "Inactive 'snap-fmt' can't be a backing child of active 'NODE_NAME'"}} + +Committing an inactive intermediate node to inactive base +{"execute": "blockdev-add", "arguments": {"active": false, "backing": "snap-fmt", "driver": "qcow2", "file": "snap2-file", "node-name": "snap2-fmt"}} +{"return": {}} +disk-fmt active: False +snap-fmt active: False +snap2-fmt active: False +{"execute": "block-commit", "arguments": {"device": "snap2-fmt", "job-id": "job0", "top-node": "snap-fmt"}} +{"error": {"class": "GenericError", "desc": "Inactive 'snap-fmt' can't be a backing child of active 'NODE_NAME'"}} + +Committing an inactive intermediate node to active base +{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} +{"return": {}} +{"execute": "block-commit", "arguments": {"device": "snap2-fmt", "job-id": "job0", "top-node": "snap-fmt"}} +{"error": {"class": "GenericError", "desc": "Inactive 'snap-fmt' can't be a backing child of active 'NODE_NAME'"}} + +Mirror from inactive source to active target +{"execute": "blockdev-mirror", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} +{"error": {"class": "GenericError", "desc": "Inactive 'snap2-fmt' can't be a backing child of active 'NODE_NAME'"}} + +Mirror from active source to inactive target +disk-fmt active: True +snap-fmt active: False +snap2-fmt active: False +target-fmt active: True +{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "snap2-fmt"}} +{"return": {}} +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "target-fmt"}} +{"return": {}} +disk-fmt active: True +snap-fmt active: True +snap2-fmt active: True +target-fmt active: False +{"execute": "blockdev-mirror", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} +{"error": {"class": "GenericError", "desc": "Permission 'write' unavailable on inactive node"}} + +Backup from active source to inactive target +{"execute": "blockdev-backup", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} +{"error": {"class": "GenericError", "desc": "Could not create node: Inactive 'target-fmt' can't be a target child of active 'NODE_NAME'"}} + +Backup from inactive source to active target +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "snap2-fmt"}} +{"return": {}} +{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "target-fmt"}} +{"return": {}} +disk-fmt active: False +snap-fmt active: False +snap2-fmt active: False +target-fmt active: True +{"execute": "blockdev-backup", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} +{"error": {"class": "GenericError", "desc": "Could not create node: Inactive 'snap2-fmt' can't be a file child of active 'NODE_NAME'"}} + +=== Accessing export on inactive node === +{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "target-fmt"}} +{"return": {}} +{"execute": "block-export-add", "arguments": {"allow-inactive": true, "id": "exp0", "node-name": "target-fmt", "type": "nbd", "writable": true}} +{"return": {}} +read 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +write failed: Operation not permitted + +write failed: Operation not permitted + +write failed: Operation not permitted + +discard failed: Operation not permitted + + +qemu-io: Failed to get allocation status: Operation not permitted + + +=== Resuming VM activates all images === +{"execute": "cont", "arguments": {}} +{"return": {}} +disk-fmt active: True +snap-fmt active: True +snap2-fmt active: True +target-fmt active: True + +Shutting down... + diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-test b/tests/qemu-iotests/tests/migrate-bitmaps-test index f98e721e97..8fb4099201 100755 --- a/tests/qemu-iotests/tests/migrate-bitmaps-test +++ b/tests/qemu-iotests/tests/migrate-bitmaps-test @@ -122,11 +122,10 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase): # catch 'Could not reopen qcow2 layer: Bitmap already exists' # possible error - log = self.vm_a.get_log() - log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) - log = re.sub(r'^(wrote .* bytes at offset .*\n.*KiB.*ops.*sec.*\n){3}', + log = iotests.filter_qtest(self.vm_a.get_log()) + log = re.sub(r'^(wrote .* bytes at offset .*\n' + r'.*KiB.*ops.*sec.*\n?){3}', '', log) - log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) self.assertEqual(log, '') # test that bitmap is still persistent diff --git a/tests/qemu-iotests/tests/qsd-migrate b/tests/qemu-iotests/tests/qsd-migrate new file mode 100755 index 0000000000..de17562cb0 --- /dev/null +++ b/tests/qemu-iotests/tests/qsd-migrate @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +# group: rw quick +# +# Copyright (C) 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: Kevin Wolf <kwolf@redhat.com> + +import iotests + +from iotests import filter_qemu_io, filter_qtest + +iotests.script_initialize(supported_fmts=['generic'], + supported_protocols=['file'], + supported_platforms=['linux']) + +with iotests.FilePath('disk.img') as path, \ + iotests.FilePath('nbd-src.sock', base_dir=iotests.sock_dir) as nbd_src, \ + iotests.FilePath('nbd-dst.sock', base_dir=iotests.sock_dir) as nbd_dst, \ + iotests.FilePath('migrate.sock', base_dir=iotests.sock_dir) as mig_sock, \ + iotests.VM(path_suffix="-src") as vm_src, \ + iotests.VM(path_suffix="-dst") as vm_dst: + + img_size = '10M' + + iotests.log('Preparing disk...') + iotests.qemu_img_create('-f', iotests.imgfmt, path, img_size) + + iotests.log('Launching source QSD...') + qsd_src = iotests.QemuStorageDaemon( + '--blockdev', f'file,node-name=disk-file,filename={path}', + '--blockdev', f'{iotests.imgfmt},file=disk-file,node-name=disk-fmt', + '--nbd-server', f'addr.type=unix,addr.path={nbd_src}', + '--export', 'nbd,id=exp0,node-name=disk-fmt,writable=true,' + 'allow-inactive=true', + qmp=True, + ) + + iotests.log('Launching source VM...') + vm_src.add_args('-blockdev', f'nbd,node-name=disk,server.type=unix,' + f'server.path={nbd_src},export=disk-fmt') + vm_src.add_args('-device', 'virtio-blk,drive=disk,id=virtio0') + vm_src.launch() + + iotests.log('Launching destination QSD...') + qsd_dst = iotests.QemuStorageDaemon( + '--blockdev', f'file,node-name=disk-file,filename={path},active=off', + '--blockdev', f'{iotests.imgfmt},file=disk-file,node-name=disk-fmt,' + f'active=off', + '--nbd-server', f'addr.type=unix,addr.path={nbd_dst}', + '--export', 'nbd,id=exp0,node-name=disk-fmt,writable=true,' + 'allow-inactive=true', + qmp=True, + instance_id='b', + ) + + iotests.log('Launching destination VM...') + vm_dst.add_args('-blockdev', f'nbd,node-name=disk,server.type=unix,' + f'server.path={nbd_dst},export=disk-fmt') + vm_dst.add_args('-device', 'virtio-blk,drive=disk,id=virtio0') + vm_dst.add_args('-incoming', f'unix:{mig_sock}') + vm_dst.launch() + + iotests.log('\nTest I/O on the source') + vm_src.hmp_qemu_io('virtio0/virtio-backend', 'write -P 0x11 0 4k', + use_log=True, qdev=True) + vm_src.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x11 0 4k', + use_log=True, qdev=True) + + iotests.log('\nStarting migration...') + + mig_caps = [ + {'capability': 'events', 'state': True}, + {'capability': 'pause-before-switchover', 'state': True}, + ] + vm_src.qmp_log('migrate-set-capabilities', capabilities=mig_caps) + vm_dst.qmp_log('migrate-set-capabilities', capabilities=mig_caps) + vm_src.qmp_log('migrate', uri=f'unix:{mig_sock}', + filters=[iotests.filter_qmp_testfiles]) + + vm_src.event_wait('MIGRATION', + match={'data': {'status': 'pre-switchover'}}) + + iotests.log('\nPre-switchover: Reconfigure QSD instances') + + iotests.log(qsd_src.qmp('blockdev-set-active', {'active': False})) + + # Reading is okay from both sides while the image is inactive. Note that + # the destination may have stale data until it activates the image, though. + vm_src.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x11 0 4k', + use_log=True, qdev=True) + vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'read 0 4k', + use_log=True, qdev=True) + + iotests.log(qsd_dst.qmp('blockdev-set-active', {'active': True})) + + iotests.log('\nCompleting migration...') + + vm_src.qmp_log('migrate-continue', state='pre-switchover') + vm_dst.event_wait('MIGRATION', match={'data': {'status': 'completed'}}) + + iotests.log('\nTest I/O on the destination') + + # Now the destination must see what the source wrote + vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x11 0 4k', + use_log=True, qdev=True) + + # And be able to overwrite it + vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'write -P 0x22 0 4k', + use_log=True, qdev=True) + vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x22 0 4k', + use_log=True, qdev=True) + + iotests.log('\nDone') + + vm_src.shutdown() + iotests.log('\n--- vm_src log ---') + log = vm_src.get_log() + if log: + iotests.log(log, [filter_qtest, filter_qemu_io]) + qsd_src.stop() + + vm_dst.shutdown() + iotests.log('\n--- vm_dst log ---') + log = vm_dst.get_log() + if log: + iotests.log(log, [filter_qtest, filter_qemu_io]) + qsd_dst.stop() diff --git a/tests/qemu-iotests/tests/qsd-migrate.out b/tests/qemu-iotests/tests/qsd-migrate.out new file mode 100644 index 0000000000..4a5241e5d4 --- /dev/null +++ b/tests/qemu-iotests/tests/qsd-migrate.out @@ -0,0 +1,59 @@ +Preparing disk... +Launching source QSD... +Launching source VM... +Launching destination QSD... +Launching destination VM... + +Test I/O on the source +{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"write -P 0x11 0 4k\""}} +{"return": ""} +{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x11 0 4k\""}} +{"return": ""} + +Starting migration... +{"execute": "migrate-set-capabilities", "arguments": {"capabilities": [{"capability": "events", "state": true}, {"capability": "pause-before-switchover", "state": true}]}} +{"return": {}} +{"execute": "migrate-set-capabilities", "arguments": {"capabilities": [{"capability": "events", "state": true}, {"capability": "pause-before-switchover", "state": true}]}} +{"return": {}} +{"execute": "migrate", "arguments": {"uri": "unix:SOCK_DIR/PID-migrate.sock"}} +{"return": {}} + +Pre-switchover: Reconfigure QSD instances +{"return": {}} +{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x11 0 4k\""}} +{"return": ""} +{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read 0 4k\""}} +{"return": ""} +{"return": {}} + +Completing migration... +{"execute": "migrate-continue", "arguments": {"state": "pre-switchover"}} +{"return": {}} + +Test I/O on the destination +{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x11 0 4k\""}} +{"return": ""} +{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"write -P 0x22 0 4k\""}} +{"return": ""} +{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x22 0 4k\""}} +{"return": ""} + +Done + +--- vm_src log --- +wrote 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +--- vm_dst log --- +read 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qtest/adm1266-test.c b/tests/qtest/adm1266-test.c index 6c312c499f..5ae8206234 100644 --- a/tests/qtest/adm1266-test.c +++ b/tests/qtest/adm1266-test.c @@ -13,8 +13,8 @@ #include "libqtest-single.h" #include "libqos/qgraph.h" #include "libqos/i2c.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qdict.h" +#include "qobject/qnum.h" #include "qemu/bitops.h" #define TEST_ID "adm1266-test" diff --git a/tests/qtest/adm1272-test.c b/tests/qtest/adm1272-test.c index 63f8514801..2abda8d5be 100644 --- a/tests/qtest/adm1272-test.c +++ b/tests/qtest/adm1272-test.c @@ -12,8 +12,8 @@ #include "libqtest-single.h" #include "libqos/qgraph.h" #include "libqos/i2c.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qdict.h" +#include "qobject/qnum.h" #include "qemu/bitops.h" #define TEST_ID "adm1272-test" diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c index 5a1923f721..88ac6c66ce 100644 --- a/tests/qtest/ahci-test.c +++ b/tests/qtest/ahci-test.c @@ -30,7 +30,7 @@ #include "libqos/ahci.h" #include "libqos/pci-pc.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/host-utils.h" #include "hw/pci/pci_ids.h" diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c index 98d6c970ea..eb8ddebffb 100644 --- a/tests/qtest/arm-cpu-features.c +++ b/tests/qtest/arm-cpu-features.c @@ -11,8 +11,8 @@ #include "qemu/osdep.h" #include "qemu/bitops.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" /* * We expect the SVE max-vq to be 16. Also it must be <= 64 diff --git a/tests/qtest/aspeed_gpio-test.c b/tests/qtest/aspeed_gpio-test.c index d38f51d719..12675d4cbb 100644 --- a/tests/qtest/aspeed_gpio-test.c +++ b/tests/qtest/aspeed_gpio-test.c @@ -25,7 +25,7 @@ #include "qemu/osdep.h" #include "qemu/bitops.h" #include "qemu/timer.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "libqtest-single.h" #define AST2600_GPIO_BASE 0x1E780000 diff --git a/tests/qtest/ast2700-gpio-test.c b/tests/qtest/ast2700-gpio-test.c index 9275845564..eeae9bf11f 100644 --- a/tests/qtest/ast2700-gpio-test.c +++ b/tests/qtest/ast2700-gpio-test.c @@ -8,7 +8,7 @@ #include "qemu/osdep.h" #include "qemu/bitops.h" #include "qemu/timer.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "libqtest-single.h" #define AST2700_GPIO_BASE 0x14C0B000 diff --git a/tests/qtest/boot-order-test.c b/tests/qtest/boot-order-test.c index 4c851c2cdb..74d6b82dd2 100644 --- a/tests/qtest/boot-order-test.c +++ b/tests/qtest/boot-order-test.c @@ -13,7 +13,7 @@ #include "qemu/osdep.h" #include "libqos/fw_cfg.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "standard-headers/linux/qemu_fw_cfg.h" typedef struct { diff --git a/tests/qtest/cdrom-test.c b/tests/qtest/cdrom-test.c index c86725a511..56e2d283a9 100644 --- a/tests/qtest/cdrom-test.c +++ b/tests/qtest/cdrom-test.c @@ -13,7 +13,7 @@ #include "qemu/osdep.h" #include "libqtest.h" #include "boot-sector.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" static char isoimage[] = "cdrom-boot-iso-XXXXXX"; diff --git a/tests/qtest/cpu-plug-test.c b/tests/qtest/cpu-plug-test.c index 7f5dd5f85a..6633abfc10 100644 --- a/tests/qtest/cpu-plug-test.c +++ b/tests/qtest/cpu-plug-test.c @@ -10,8 +10,8 @@ #include "qemu/osdep.h" #include "libqtest-single.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" struct PlugTestData { char *machine; diff --git a/tests/qtest/device-introspect-test.c b/tests/qtest/device-introspect-test.c index 587da59623..f84cec51dc 100644 --- a/tests/qtest/device-introspect-test.c +++ b/tests/qtest/device-introspect-test.c @@ -18,9 +18,9 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" #include "libqtest.h" const char common_args[] = "-nodefaults -machine none"; diff --git a/tests/qtest/device-plug-test.c b/tests/qtest/device-plug-test.c index 127a7f9efe..2707ee59f6 100644 --- a/tests/qtest/device-plug-test.c +++ b/tests/qtest/device-plug-test.c @@ -12,8 +12,8 @@ #include "qemu/osdep.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" static void wait_device_deleted_event(QTestState *qtest, const char *id) { diff --git a/tests/qtest/drive_del-test.c b/tests/qtest/drive_del-test.c index 99f6fc2de1..30d9451ddd 100644 --- a/tests/qtest/drive_del-test.c +++ b/tests/qtest/drive_del-test.c @@ -13,8 +13,8 @@ #include "qemu/osdep.h" #include "libqtest.h" #include "libqos/virtio.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" static const char *qvirtio_get_dev_type(void); diff --git a/tests/qtest/emc141x-test.c b/tests/qtest/emc141x-test.c index 8c86694091..a24103e2cd 100644 --- a/tests/qtest/emc141x-test.c +++ b/tests/qtest/emc141x-test.c @@ -10,7 +10,7 @@ #include "libqtest-single.h" #include "libqos/qgraph.h" #include "libqos/i2c.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "hw/sensor/emc141x_regs.h" #define EMC1414_TEST_ID "emc1414-test" diff --git a/tests/qtest/fdc-test.c b/tests/qtest/fdc-test.c index 8645b080f7..1b37a8a4d2 100644 --- a/tests/qtest/fdc-test.c +++ b/tests/qtest/fdc-test.c @@ -26,7 +26,7 @@ #include "libqtest-single.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #define DRIVE_FLOPPY_BLANK \ "-drive if=floppy,file=null-co://,file.read-zeroes=on,format=raw,size=1440k" diff --git a/tests/qtest/hd-geo-test.c b/tests/qtest/hd-geo-test.c index 1c73dea8f7..41481a5e09 100644 --- a/tests/qtest/hd-geo-test.c +++ b/tests/qtest/hd-geo-test.c @@ -17,7 +17,7 @@ #include "qemu/osdep.h" #include "qemu/bswap.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "libqtest.h" #include "libqos/fw_cfg.h" #include "libqos/libqos.h" diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c index 90ba6b298b..ceee444a9e 100644 --- a/tests/qtest/ide-test.c +++ b/tests/qtest/ide-test.c @@ -29,7 +29,7 @@ #include "libqos/libqos.h" #include "libqos/pci-pc.h" #include "libqos/malloc-pc.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/bswap.h" #include "hw/pci/pci_ids.h" #include "hw/pci/pci_regs.h" diff --git a/tests/qtest/isl_pmbus_vr-test.c b/tests/qtest/isl_pmbus_vr-test.c index 5553ea410a..1ff840c6b7 100644 --- a/tests/qtest/isl_pmbus_vr-test.c +++ b/tests/qtest/isl_pmbus_vr-test.c @@ -21,8 +21,8 @@ #include "libqtest-single.h" #include "libqos/qgraph.h" #include "libqos/i2c.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qdict.h" +#include "qobject/qnum.h" #include "qemu/bitops.h" #define TEST_ID "isl_pmbus_vr-test" diff --git a/tests/qtest/libqmp.c b/tests/qtest/libqmp.c index a89cab03c3..16fe546885 100644 --- a/tests/qtest/libqmp.c +++ b/tests/qtest/libqmp.c @@ -25,8 +25,8 @@ #include "qemu/cutils.h" #include "qemu/sockets.h" #include "qapi/error.h" -#include "qapi/qmp/json-parser.h" -#include "qapi/qmp/qjson.h" +#include "qobject/json-parser.h" +#include "qobject/qjson.h" #define SOCKET_MAX_FDS 16 diff --git a/tests/qtest/libqmp.h b/tests/qtest/libqmp.h index 3445b753ff..4a931c93ab 100644 --- a/tests/qtest/libqmp.h +++ b/tests/qtest/libqmp.h @@ -18,7 +18,7 @@ #ifndef LIBQMP_H #define LIBQMP_H -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" QDict *qmp_fd_receive(int fd); #ifndef _WIN32 diff --git a/tests/qtest/libqos/generic-pcihost.c b/tests/qtest/libqos/generic-pcihost.c index 3124b0e46b..4bbeb5ff50 100644 --- a/tests/qtest/libqos/generic-pcihost.c +++ b/tests/qtest/libqos/generic-pcihost.c @@ -13,7 +13,7 @@ #include "qemu/osdep.h" #include "../libqtest.h" #include "generic-pcihost.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "hw/pci/pci_regs.h" #include "qemu/host-utils.h" diff --git a/tests/qtest/libqos/libqos.c b/tests/qtest/libqos/libqos.c index 28a0901a0a..9b49d0d4dd 100644 --- a/tests/qtest/libqos/libqos.c +++ b/tests/qtest/libqos/libqos.c @@ -2,7 +2,7 @@ #include "../libqtest.h" #include "libqos.h" #include "pci.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" /*** Test Setup & Teardown ***/ diff --git a/tests/qtest/libqos/pci-pc.c b/tests/qtest/libqos/pci-pc.c index 96046287ac..147009f4f4 100644 --- a/tests/qtest/libqos/pci-pc.c +++ b/tests/qtest/libqos/pci-pc.c @@ -13,7 +13,7 @@ #include "qemu/osdep.h" #include "../libqtest.h" #include "pci-pc.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "hw/pci/pci_regs.h" #include "qemu/module.h" diff --git a/tests/qtest/libqos/qos_external.c b/tests/qtest/libqos/qos_external.c index c6bb8bff09..493ab747de 100644 --- a/tests/qtest/libqos/qos_external.c +++ b/tests/qtest/libqos/qos_external.c @@ -19,11 +19,11 @@ #include "qemu/osdep.h" #include <getopt.h> #include "../libqtest.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qbool.h" +#include "qobject/qstring.h" #include "qemu/module.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "libqos-malloc.h" #include "qgraph.h" #include "qgraph_internal.h" diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index fe8606ba6a..2750067861 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -34,11 +34,11 @@ #include "qemu/ctype.h" #include "qemu/cutils.h" #include "qemu/sockets.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qlist.h" +#include "qobject/qstring.h" +#include "qobject/qbool.h" #define MAX_IRQ 256 diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index 29f123e281..930a91dcb7 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -17,9 +17,9 @@ #ifndef LIBQTEST_H #define LIBQTEST_H -#include "qapi/qmp/qobject.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qobject.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" #include "libqmp.h" typedef struct QTestState QTestState; diff --git a/tests/qtest/lsm303dlhc-mag-test.c b/tests/qtest/lsm303dlhc-mag-test.c index 0f64e7fc67..55ef4594f9 100644 --- a/tests/qtest/lsm303dlhc-mag-test.c +++ b/tests/qtest/lsm303dlhc-mag-test.c @@ -13,7 +13,7 @@ #include "libqtest-single.h" #include "libqos/qgraph.h" #include "libqos/i2c.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #define LSM303DLHC_MAG_TEST_ID "lsm303dlhc_mag-test" #define LSM303DLHC_MAG_REG_CRA 0x00 diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c index 159b2a705a..b6a87d27ed 100644 --- a/tests/qtest/machine-none-test.c +++ b/tests/qtest/machine-none-test.c @@ -14,7 +14,7 @@ #include "qemu/cutils.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" struct arch2cpu { diff --git a/tests/qtest/max34451-test.c b/tests/qtest/max34451-test.c index dbf6ddc829..5e0878c923 100644 --- a/tests/qtest/max34451-test.c +++ b/tests/qtest/max34451-test.c @@ -11,8 +11,8 @@ #include "libqtest-single.h" #include "libqos/qgraph.h" #include "libqos/i2c.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qdict.h" +#include "qobject/qnum.h" #include "qemu/bitops.h" #define TEST_ID "max34451-test" diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c new file mode 100644 index 0000000000..b08b49bd43 --- /dev/null +++ b/tests/qtest/migration-helpers.c @@ -0,0 +1,530 @@ +/* + * QTest migration helpers + * + * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates + * based on the vhost-user-test.c that is: + * Copyright (c) 2014 Virtual Open Systems Sarl. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qemu/ctype.h" +#include "qobject/qjson.h" +#include "qapi/qapi-visit-sockets.h" +#include "qapi/qobject-input-visitor.h" +#include "qapi/error.h" +#include "qobject/qlist.h" +#include "qemu/cutils.h" +#include "qemu/memalign.h" + +#include "migration-helpers.h" + +/* + * Number of seconds we wait when looking for migration + * status changes, to avoid test suite hanging forever + * when things go wrong. Needs to be higher enough to + * avoid false positives on loaded hosts. + */ +#define MIGRATION_STATUS_WAIT_TIMEOUT 120 + +static char *SocketAddress_to_str(SocketAddress *addr) +{ + switch (addr->type) { + case SOCKET_ADDRESS_TYPE_INET: + return g_strdup_printf("tcp:%s:%s", + addr->u.inet.host, + addr->u.inet.port); + case SOCKET_ADDRESS_TYPE_UNIX: + return g_strdup_printf("unix:%s", + addr->u.q_unix.path); + case SOCKET_ADDRESS_TYPE_FD: + return g_strdup_printf("fd:%s", addr->u.fd.str); + case SOCKET_ADDRESS_TYPE_VSOCK: + return g_strdup_printf("vsock:%s:%s", + addr->u.vsock.cid, + addr->u.vsock.port); + default: + return g_strdup("unknown address type"); + } +} + +static QDict *SocketAddress_to_qdict(SocketAddress *addr) +{ + QDict *dict = qdict_new(); + + switch (addr->type) { + case SOCKET_ADDRESS_TYPE_INET: + qdict_put_str(dict, "type", "inet"); + qdict_put_str(dict, "host", addr->u.inet.host); + qdict_put_str(dict, "port", addr->u.inet.port); + break; + case SOCKET_ADDRESS_TYPE_UNIX: + qdict_put_str(dict, "type", "unix"); + qdict_put_str(dict, "path", addr->u.q_unix.path); + break; + case SOCKET_ADDRESS_TYPE_FD: + qdict_put_str(dict, "type", "fd"); + qdict_put_str(dict, "str", addr->u.fd.str); + break; + case SOCKET_ADDRESS_TYPE_VSOCK: + qdict_put_str(dict, "type", "vsock"); + qdict_put_str(dict, "cid", addr->u.vsock.cid); + qdict_put_str(dict, "port", addr->u.vsock.port); + break; + default: + g_assert_not_reached(); + } + + return dict; +} + +static SocketAddressList *migrate_get_socket_address(QTestState *who) +{ + QDict *rsp; + SocketAddressList *addrs; + Visitor *iv = NULL; + QObject *object; + + rsp = migrate_query(who); + object = qdict_get(rsp, "socket-address"); + + iv = qobject_input_visitor_new(object); + visit_type_SocketAddressList(iv, NULL, &addrs, &error_abort); + visit_free(iv); + + qobject_unref(rsp); + return addrs; +} + +static char * +migrate_get_connect_uri(QTestState *who) +{ + SocketAddressList *addrs; + char *connect_uri; + + addrs = migrate_get_socket_address(who); + connect_uri = SocketAddress_to_str(addrs->value); + + qapi_free_SocketAddressList(addrs); + return connect_uri; +} + +static QDict * +migrate_get_connect_qdict(QTestState *who) +{ + SocketAddressList *addrs; + QDict *connect_qdict; + + addrs = migrate_get_socket_address(who); + connect_qdict = SocketAddress_to_qdict(addrs->value); + + qapi_free_SocketAddressList(addrs); + return connect_qdict; +} + +static void migrate_set_ports(QTestState *to, QList *channel_list) +{ + QDict *addr; + QListEntry *entry; + const char *addr_port = NULL; + + addr = migrate_get_connect_qdict(to); + + QLIST_FOREACH_ENTRY(channel_list, entry) { + QDict *channel = qobject_to(QDict, qlist_entry_obj(entry)); + QDict *addrdict = qdict_get_qdict(channel, "addr"); + + if (qdict_haskey(addrdict, "port") && + qdict_haskey(addr, "port") && + (strcmp(qdict_get_str(addrdict, "port"), "0") == 0)) { + addr_port = qdict_get_str(addr, "port"); + qdict_put_str(addrdict, "port", addr_port); + } + } + + qobject_unref(addr); +} + +bool migrate_watch_for_events(QTestState *who, const char *name, + QDict *event, void *opaque) +{ + QTestMigrationState *state = opaque; + + if (g_str_equal(name, "STOP")) { + state->stop_seen = true; + return true; + } else if (g_str_equal(name, "SUSPEND")) { + state->suspend_seen = true; + return true; + } else if (g_str_equal(name, "RESUME")) { + state->resume_seen = true; + return true; + } + + return false; +} + +void migrate_qmp_fail(QTestState *who, const char *uri, + const char *channels, const char *fmt, ...) +{ + va_list ap; + QDict *args, *err; + + va_start(ap, fmt); + args = qdict_from_vjsonf_nofail(fmt, ap); + va_end(ap); + + g_assert(!qdict_haskey(args, "uri")); + if (uri) { + qdict_put_str(args, "uri", uri); + } + + g_assert(!qdict_haskey(args, "channels")); + if (channels) { + QObject *channels_obj = qobject_from_json(channels, &error_abort); + qdict_put_obj(args, "channels", channels_obj); + } + + err = qtest_qmp_assert_failure_ref( + who, "{ 'execute': 'migrate', 'arguments': %p}", args); + + g_assert(qdict_haskey(err, "desc")); + + qobject_unref(err); +} + +/* + * Send QMP command "migrate". + * Arguments are built from @fmt... (formatted like + * qobject_from_jsonf_nofail()) with "uri": @uri spliced in. + */ +void migrate_qmp(QTestState *who, QTestState *to, const char *uri, + const char *channels, const char *fmt, ...) +{ + va_list ap; + QDict *args; + g_autofree char *connect_uri = NULL; + + va_start(ap, fmt); + args = qdict_from_vjsonf_nofail(fmt, ap); + va_end(ap); + + g_assert(!qdict_haskey(args, "uri")); + if (uri) { + qdict_put_str(args, "uri", uri); + } else if (!channels) { + connect_uri = migrate_get_connect_uri(to); + qdict_put_str(args, "uri", connect_uri); + } + + g_assert(!qdict_haskey(args, "channels")); + if (channels) { + QObject *channels_obj = qobject_from_json(channels, &error_abort); + QList *channel_list = qobject_to(QList, channels_obj); + migrate_set_ports(to, channel_list); + qdict_put_obj(args, "channels", channels_obj); + } + + qtest_qmp_assert_success(who, + "{ 'execute': 'migrate', 'arguments': %p}", args); +} + +void migrate_set_capability(QTestState *who, const char *capability, + bool value) +{ + qtest_qmp_assert_success(who, + "{ 'execute': 'migrate-set-capabilities'," + "'arguments': { " + "'capabilities': [ { " + "'capability': %s, 'state': %i } ] } }", + capability, value); +} + +void migrate_incoming_qmp(QTestState *to, const char *uri, const char *fmt, ...) +{ + va_list ap; + QDict *args, *rsp; + + va_start(ap, fmt); + args = qdict_from_vjsonf_nofail(fmt, ap); + va_end(ap); + + g_assert(!qdict_haskey(args, "uri")); + qdict_put_str(args, "uri", uri); + + /* This function relies on the event to work, make sure it's enabled */ + migrate_set_capability(to, "events", true); + + rsp = qtest_qmp(to, "{ 'execute': 'migrate-incoming', 'arguments': %p}", + args); + + if (!qdict_haskey(rsp, "return")) { + g_autoptr(GString) s = qobject_to_json_pretty(QOBJECT(rsp), true); + g_test_message("%s", s->str); + } + + g_assert(qdict_haskey(rsp, "return")); + qobject_unref(rsp); + + migration_event_wait(to, "setup"); +} + +/* + * Note: caller is responsible to free the returned object via + * qobject_unref() after use + */ +QDict *migrate_query(QTestState *who) +{ + return qtest_qmp_assert_success_ref(who, "{ 'execute': 'query-migrate' }"); +} + +QDict *migrate_query_not_failed(QTestState *who) +{ + const char *status; + QDict *rsp = migrate_query(who); + status = qdict_get_str(rsp, "status"); + if (g_str_equal(status, "failed")) { + g_printerr("query-migrate shows failed migration: %s\n", + qdict_get_str(rsp, "error-desc")); + } + g_assert(!g_str_equal(status, "failed")); + return rsp; +} + +/* + * Note: caller is responsible to free the returned object via + * g_free() after use + */ +static gchar *migrate_query_status(QTestState *who) +{ + QDict *rsp_return = migrate_query(who); + gchar *status = g_strdup(qdict_get_str(rsp_return, "status")); + + g_assert(status); + qobject_unref(rsp_return); + + return status; +} + +static bool check_migration_status(QTestState *who, const char *goal, + const char **ungoals) +{ + bool ready; + char *current_status; + const char **ungoal; + + current_status = migrate_query_status(who); + ready = strcmp(current_status, goal) == 0; + if (!ungoals) { + g_assert_cmpstr(current_status, !=, "failed"); + /* + * If looking for a state other than completed, + * completion of migration would cause the test to + * hang. + */ + if (strcmp(goal, "completed") != 0) { + g_assert_cmpstr(current_status, !=, "completed"); + } + } else { + for (ungoal = ungoals; *ungoal; ungoal++) { + g_assert_cmpstr(current_status, !=, *ungoal); + } + } + g_free(current_status); + return ready; +} + +void wait_for_migration_status(QTestState *who, + const char *goal, const char **ungoals) +{ + g_test_timer_start(); + while (!check_migration_status(who, goal, ungoals)) { + usleep(1000); + + g_assert(g_test_timer_elapsed() < MIGRATION_STATUS_WAIT_TIMEOUT); + } +} + +void wait_for_migration_complete(QTestState *who) +{ + wait_for_migration_status(who, "completed", NULL); +} + +void wait_for_migration_fail(QTestState *from, bool allow_active) +{ + g_test_timer_start(); + QDict *rsp_return; + char *status; + bool failed; + + do { + status = migrate_query_status(from); + bool result = !strcmp(status, "setup") || !strcmp(status, "failed") || + (allow_active && !strcmp(status, "active")); + if (!result) { + fprintf(stderr, "%s: unexpected status status=%s allow_active=%d\n", + __func__, status, allow_active); + } + g_assert(result); + failed = !strcmp(status, "failed"); + g_free(status); + + g_assert(g_test_timer_elapsed() < MIGRATION_STATUS_WAIT_TIMEOUT); + } while (!failed); + + /* Is the machine currently running? */ + rsp_return = qtest_qmp_assert_success_ref(from, + "{ 'execute': 'query-status' }"); + g_assert(qdict_haskey(rsp_return, "running")); + g_assert(qdict_get_bool(rsp_return, "running")); + qobject_unref(rsp_return); +} + +char *find_common_machine_version(const char *mtype, const char *var1, + const char *var2) +{ + g_autofree char *type1 = qtest_resolve_machine_alias(var1, mtype); + g_autofree char *type2 = qtest_resolve_machine_alias(var2, mtype); + + g_assert(type1 && type2); + + if (g_str_equal(type1, type2)) { + /* either can be used */ + return g_strdup(type1); + } + + if (qtest_has_machine_with_env(var2, type1)) { + return g_strdup(type1); + } + + if (qtest_has_machine_with_env(var1, type2)) { + return g_strdup(type2); + } + + g_test_message("No common machine version for machine type '%s' between " + "binaries %s and %s", mtype, getenv(var1), getenv(var2)); + g_assert_not_reached(); +} + +char *resolve_machine_version(const char *alias, const char *var1, + const char *var2) +{ + const char *mname = g_getenv("QTEST_QEMU_MACHINE_TYPE"); + g_autofree char *machine_name = NULL; + + if (mname) { + const char *dash = strrchr(mname, '-'); + const char *dot = strrchr(mname, '.'); + + machine_name = g_strdup(mname); + + if (dash && dot) { + assert(qtest_has_machine(machine_name)); + return g_steal_pointer(&machine_name); + } + /* else: probably an alias, let it be resolved below */ + } else { + /* use the hardcoded alias */ + machine_name = g_strdup(alias); + } + + return find_common_machine_version(machine_name, var1, var2); +} + +typedef struct { + char *name; + void (*func)(void); +} MigrationTest; + +static void migration_test_destroy(gpointer data) +{ + MigrationTest *test = (MigrationTest *)data; + + g_free(test->name); + g_free(test); +} + +static void migration_test_wrapper(const void *data) +{ + MigrationTest *test = (MigrationTest *)data; + + g_test_message("Running /%s%s", qtest_get_arch(), test->name); + test->func(); +} + +void migration_test_add(const char *path, void (*fn)(void)) +{ + MigrationTest *test = g_new0(MigrationTest, 1); + + test->func = fn; + test->name = g_strdup(path); + + qtest_add_data_func_full(path, test, migration_test_wrapper, + migration_test_destroy); +} + +#ifdef O_DIRECT +/* + * Probe for O_DIRECT support on the filesystem. Since this is used + * for tests, be conservative, if anything fails, assume it's + * unsupported. + */ +bool probe_o_direct_support(const char *tmpfs) +{ + g_autofree char *filename = g_strdup_printf("%s/probe-o-direct", tmpfs); + int fd, flags = O_CREAT | O_RDWR | O_TRUNC | O_DIRECT; + void *buf; + ssize_t ret, len; + uint64_t offset; + + fd = open(filename, flags, 0660); + if (fd < 0) { + unlink(filename); + return false; + } + + /* + * Using 1MB alignment as conservative choice to satisfy any + * plausible architecture default page size, and/or filesystem + * alignment restrictions. + */ + len = 0x100000; + offset = 0x100000; + + buf = qemu_try_memalign(len, len); + g_assert(buf); + + ret = pwrite(fd, buf, len, offset); + unlink(filename); + g_free(buf); + + if (ret < 0) { + return false; + } + + return true; +} +#endif + +/* + * Wait for a "MIGRATION" event. This is what Libvirt uses to track + * migration status changes. + */ +void migration_event_wait(QTestState *s, const char *target) +{ + QDict *response, *data; + const char *status; + bool found; + + do { + response = qtest_qmp_eventwait_ref(s, "MIGRATION"); + data = qdict_get_qdict(response, "data"); + g_assert(data); + status = qdict_get_str(data, "status"); + found = (strcmp(status, target) == 0); + qobject_unref(response); + } while (!found); +} diff --git a/tests/qtest/migration/file-tests.c b/tests/qtest/migration/file-tests.c index f474b3590a..f260e2871d 100644 --- a/tests/qtest/migration/file-tests.c +++ b/tests/qtest/migration/file-tests.c @@ -15,7 +15,7 @@ #include "migration/framework.h" #include "migration/migration-qmp.h" #include "migration/migration-util.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" static char *tmpfs; diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c index de65bfe40d..10e1d04b58 100644 --- a/tests/qtest/migration/framework.c +++ b/tests/qtest/migration/framework.c @@ -19,8 +19,8 @@ #include "migration/migration-util.h" #include "ppc-util.h" #include "qapi/error.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qjson.h" +#include "qobject/qlist.h" #include "qemu/module.h" #include "qemu/option.h" #include "qemu/range.h" diff --git a/tests/qtest/migration/migration-qmp.c b/tests/qtest/migration/migration-qmp.c index 5610f6d15d..fb59741b2c 100644 --- a/tests/qtest/migration/migration-qmp.c +++ b/tests/qtest/migration/migration-qmp.c @@ -17,9 +17,9 @@ #include "qapi/error.h" #include "qapi/qapi-types-migration.h" #include "qapi/qapi-visit-migration.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qlist.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" diff --git a/tests/qtest/migration/migration-util.c b/tests/qtest/migration/migration-util.c index 0ce1413b6c..6261d80e4a 100644 --- a/tests/qtest/migration/migration-util.c +++ b/tests/qtest/migration/migration-util.c @@ -15,7 +15,7 @@ #include "qapi/qapi-visit-sockets.h" #include "qapi/qobject-input-visitor.h" #include "qapi/error.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qemu/cutils.h" #include "qemu/memalign.h" diff --git a/tests/qtest/migration/misc-tests.c b/tests/qtest/migration/misc-tests.c index d03199f3c5..2e612d9e38 100644 --- a/tests/qtest/migration/misc-tests.c +++ b/tests/qtest/migration/misc-tests.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qjson.h" #include "libqtest.h" #include "migration/framework.h" #include "migration/migration-qmp.h" diff --git a/tests/qtest/migration/postcopy-tests.c b/tests/qtest/migration/postcopy-tests.c index 7e84e60fea..982457bed1 100644 --- a/tests/qtest/migration/postcopy-tests.c +++ b/tests/qtest/migration/postcopy-tests.c @@ -14,7 +14,7 @@ #include "libqtest.h" #include "migration/framework.h" #include "migration/migration-util.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qemu/module.h" #include "qemu/option.h" #include "qemu/range.h" diff --git a/tests/qtest/migration/precopy-tests.c b/tests/qtest/migration/precopy-tests.c index b16f10e908..162fa69531 100644 --- a/tests/qtest/migration/precopy-tests.c +++ b/tests/qtest/migration/precopy-tests.c @@ -19,7 +19,7 @@ #include "migration/migration-qmp.h" #include "migration/migration-util.h" #include "ppc-util.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qlist.h" #include "qemu/module.h" #include "qemu/option.h" #include "qemu/range.h" diff --git a/tests/qtest/netdev-socket.c b/tests/qtest/netdev-socket.c index 317af03817..b731af0ad9 100644 --- a/tests/qtest/netdev-socket.c +++ b/tests/qtest/netdev-socket.c @@ -11,7 +11,7 @@ #include <glib/gstdio.h> #include "../unit/socket-helpers.h" #include "libqtest.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qstring.h" #include "qemu/sockets.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-sockets.h" diff --git a/tests/qtest/npcm7xx_adc-test.c b/tests/qtest/npcm7xx_adc-test.c index e751a72e36..8bc89b8a8b 100644 --- a/tests/qtest/npcm7xx_adc-test.c +++ b/tests/qtest/npcm7xx_adc-test.c @@ -18,7 +18,7 @@ #include "qemu/bitops.h" #include "qemu/timer.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #define REF_HZ (25000000) diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c index 2e1a1a6d70..eeedb27ee6 100644 --- a/tests/qtest/npcm7xx_emc-test.c +++ b/tests/qtest/npcm7xx_emc-test.c @@ -16,8 +16,8 @@ #include "qemu/osdep.h" #include "libqos/libqos.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qdict.h" +#include "qobject/qnum.h" #include "qemu/bitops.h" #include "qemu/iov.h" diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c index b53a43c417..052ea87662 100644 --- a/tests/qtest/npcm7xx_pwm-test.c +++ b/tests/qtest/npcm7xx_pwm-test.c @@ -17,8 +17,8 @@ #include "qemu/osdep.h" #include "qemu/bitops.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qdict.h" +#include "qobject/qnum.h" static int verbosity_level; diff --git a/tests/qtest/npcm7xx_watchdog_timer-test.c b/tests/qtest/npcm7xx_watchdog_timer-test.c index 981b853c99..521ea789f1 100644 --- a/tests/qtest/npcm7xx_watchdog_timer-test.c +++ b/tests/qtest/npcm7xx_watchdog_timer-test.c @@ -18,7 +18,7 @@ #include "qemu/timer.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #define WTCR_OFFSET 0x1c #define REF_HZ (25000000) diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c index 6d92baee86..d657f38947 100644 --- a/tests/qtest/numa-test.c +++ b/tests/qtest/numa-test.c @@ -11,8 +11,8 @@ #include "qemu/osdep.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" static char *make_cli(const GString *generic_cli, const char *test_cli) { diff --git a/tests/qtest/pvpanic-pci-test.c b/tests/qtest/pvpanic-pci-test.c index dc021c2fdf..f788a44dbe 100644 --- a/tests/qtest/pvpanic-pci-test.c +++ b/tests/qtest/pvpanic-pci-test.c @@ -13,7 +13,7 @@ #include "qemu/osdep.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "libqos/pci.h" #include "libqos/pci-pc.h" #include "hw/misc/pvpanic.h" diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c index d49d2ba931..5606baf47b 100644 --- a/tests/qtest/pvpanic-test.c +++ b/tests/qtest/pvpanic-test.c @@ -9,7 +9,7 @@ #include "qemu/osdep.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "hw/misc/pvpanic.h" static void test_panic_nopause(void) diff --git a/tests/qtest/q35-test.c b/tests/qtest/q35-test.c index 7f58fc3746..75d4078b79 100644 --- a/tests/qtest/q35-test.c +++ b/tests/qtest/q35-test.c @@ -14,7 +14,7 @@ #include "libqos/pci.h" #include "libqos/pci-pc.h" #include "hw/pci-host/q35.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #define TSEG_SIZE_TEST_GUEST_RAM_MBYTES 128 diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c index 2c15f60958..15c88248b7 100644 --- a/tests/qtest/qmp-cmd-test.c +++ b/tests/qtest/qmp-cmd-test.c @@ -14,7 +14,7 @@ #include "libqtest.h" #include "qapi/error.h" #include "qapi/qapi-visit-introspect.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qapi/qobject-input-visitor.h" const char common_args[] = "-nodefaults -machine none"; diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c index 22957fa49c..edf0886787 100644 --- a/tests/qtest/qmp-test.c +++ b/tests/qtest/qmp-test.c @@ -14,10 +14,10 @@ #include "libqtest.h" #include "qapi/error.h" #include "qapi/qapi-visit-control.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" #include "qapi/qobject-input-visitor.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qstring.h" const char common_args[] = "-nodefaults -machine none"; diff --git a/tests/qtest/qom-test.c b/tests/qtest/qom-test.c index d677f87c8e..1e30a5bfe8 100644 --- a/tests/qtest/qom-test.c +++ b/tests/qtest/qom-test.c @@ -9,8 +9,8 @@ #include "qemu/osdep.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" #include "qemu/cutils.h" #include "libqtest.h" diff --git a/tests/qtest/qos-test.c b/tests/qtest/qos-test.c index 2f7e75a339..abfd4b9512 100644 --- a/tests/qtest/qos-test.c +++ b/tests/qtest/qos-test.c @@ -20,7 +20,7 @@ #include <getopt.h> #include "libqtest-single.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/module.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-machine.h" diff --git a/tests/qtest/readconfig-test.c b/tests/qtest/readconfig-test.c index 760f974e63..c6f32a4e14 100644 --- a/tests/qtest/readconfig-test.c +++ b/tests/qtest/readconfig-test.c @@ -13,10 +13,10 @@ #include "qapi/qapi-visit-machine.h" #include "qapi/qapi-visit-qom.h" #include "qapi/qapi-visit-ui.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" #include "qapi/qobject-input-visitor.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qstring.h" #include "qemu/units.h" static QTestState *qtest_init_with_config(const char *cfgdata) diff --git a/tests/qtest/tco-test.c b/tests/qtest/tco-test.c index 0547d41173..20ccefabcb 100644 --- a/tests/qtest/tco-test.c +++ b/tests/qtest/tco-test.c @@ -12,7 +12,7 @@ #include "libqtest.h" #include "libqos/pci.h" #include "libqos/pci-pc.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "hw/pci/pci_regs.h" #include "hw/southbridge/ich9.h" #include "hw/acpi/ich9.h" diff --git a/tests/qtest/test-filter-mirror.c b/tests/qtest/test-filter-mirror.c index f3865f7519..723d2c2f29 100644 --- a/tests/qtest/test-filter-mirror.c +++ b/tests/qtest/test-filter-mirror.c @@ -10,7 +10,7 @@ #include "qemu/osdep.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/iov.h" #include "qemu/sockets.h" #include "qemu/error-report.h" diff --git a/tests/qtest/test-filter-redirector.c b/tests/qtest/test-filter-redirector.c index a77d5fd8ec..a996a80c1c 100644 --- a/tests/qtest/test-filter-redirector.c +++ b/tests/qtest/test-filter-redirector.c @@ -52,7 +52,7 @@ #include "qemu/osdep.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/iov.h" #include "qemu/sockets.h" #include "qemu/error-report.h" diff --git a/tests/qtest/test-netfilter.c b/tests/qtest/test-netfilter.c index b09ef7fae9..326d4bd85f 100644 --- a/tests/qtest/test-netfilter.c +++ b/tests/qtest/test-netfilter.c @@ -10,7 +10,7 @@ #include "qemu/osdep.h" #include "libqtest-single.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" /* add a netfilter to a netdev and then remove it */ static void add_one_netfilter(void) diff --git a/tests/qtest/test-x86-cpuid-compat.c b/tests/qtest/test-x86-cpuid-compat.c index 9cbc8b7ae9..b9603d46fa 100644 --- a/tests/qtest/test-x86-cpuid-compat.c +++ b/tests/qtest/test-x86-cpuid-compat.c @@ -1,8 +1,8 @@ #include "qemu/osdep.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qnum.h" +#include "qobject/qbool.h" #include "libqtest-single.h" static char *get_cpu0_qom_path(void) diff --git a/tests/qtest/tmp105-test.c b/tests/qtest/tmp105-test.c index 85ad4eed85..3b114a50f5 100644 --- a/tests/qtest/tmp105-test.c +++ b/tests/qtest/tmp105-test.c @@ -12,7 +12,7 @@ #include "libqtest-single.h" #include "libqos/qgraph.h" #include "libqos/i2c.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "hw/sensor/tmp105_regs.h" #define TMP105_TEST_ID "tmp105-test" diff --git a/tests/qtest/tpm-emu.c b/tests/qtest/tpm-emu.c index 2bf8ff4c86..9e4c2005d0 100644 --- a/tests/qtest/tpm-emu.c +++ b/tests/qtest/tpm-emu.c @@ -16,8 +16,8 @@ #include "backends/tpm/tpm_ioctl.h" #include "io/channel-socket.h" #include "qapi/error.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qlist.h" +#include "qobject/qstring.h" #include "tpm-emu.h" void tpm_emu_test_wait_cond(TPMTestState *s) diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c index 1c0319e6e7..2cb2dd4796 100644 --- a/tests/qtest/tpm-util.c +++ b/tests/qtest/tpm-util.c @@ -18,7 +18,7 @@ #include "hw/acpi/tpm.h" #include "libqtest.h" #include "tpm-util.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" void tpm_util_crb_transfer(QTestState *s, const unsigned char *req, size_t req_size, diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c index bd977ef28d..75cb3e44b2 100644 --- a/tests/qtest/vhost-user-test.c +++ b/tests/qtest/vhost-user-test.c @@ -12,7 +12,7 @@ #include "libqtest-single.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/config-file.h" #include "qemu/option.h" #include "qemu/range.h" diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c index f04573f98c..5baf81c3e6 100644 --- a/tests/qtest/virtio-net-failover.c +++ b/tests/qtest/virtio-net-failover.c @@ -13,9 +13,9 @@ #include "libqos/pci-pc.h" #include "migration/migration-qmp.h" #include "migration/migration-util.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qjson.h" #include "libqos/malloc-pc.h" #include "libqos/virtio-pci.h" #include "hw/pci/pci.h" diff --git a/tests/qtest/virtio-net-test.c b/tests/qtest/virtio-net-test.c index 2df75c9780..60e5229a3d 100644 --- a/tests/qtest/virtio-net-test.c +++ b/tests/qtest/virtio-net-test.c @@ -11,7 +11,7 @@ #include "libqtest-single.h" #include "qemu/iov.h" #include "qemu/module.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "hw/virtio/virtio-net.h" #include "libqos/qgraph.h" #include "libqos/virtio-net.h" diff --git a/tests/qtest/vmgenid-test.c b/tests/qtest/vmgenid-test.c index 29fee9e7c0..e613374665 100644 --- a/tests/qtest/vmgenid-test.c +++ b/tests/qtest/vmgenid-test.c @@ -15,7 +15,7 @@ #include "boot-sector.h" #include "acpi-utils.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #define VGID_GUID "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87" #define VMGENID_GUID_OFFSET 40 /* allow space for diff --git a/tests/qtest/wdt_ib700-test.c b/tests/qtest/wdt_ib700-test.c index 797288d939..1754757162 100644 --- a/tests/qtest/wdt_ib700-test.c +++ b/tests/qtest/wdt_ib700-test.c @@ -9,7 +9,7 @@ #include "qemu/osdep.h" #include "libqtest.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/timer.h" static void qmp_check_no_event(QTestState *s) diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target index 06ddf3e04f..99a953b667 100644 --- a/tests/tcg/arm/Makefile.target +++ b/tests/tcg/arm/Makefile.target @@ -20,13 +20,6 @@ ARM_TESTS = hello-arm hello-arm: CFLAGS+=-marm -ffreestanding -fno-stack-protector hello-arm: LDFLAGS+=-nostdlib -# IWMXT floating point extensions -ARM_TESTS += test-arm-iwmmxt -# Clang assembler does not support IWMXT, so use the external assembler. -test-arm-iwmmxt: CFLAGS += -marm -march=iwmmxt -mabi=aapcs -mfpu=fpv4-sp-d16 $(CROSS_CC_HAS_FNIA) -test-arm-iwmmxt: test-arm-iwmmxt.S - $(CC) $(CFLAGS) -Wa,--noexecstack $< -o $@ $(LDFLAGS) - # Float-convert Tests ARM_TESTS += fcvt fcvt: LDFLAGS += -lm diff --git a/tests/tcg/arm/README b/tests/tcg/arm/README index e6307116e2..aceccc127f 100644 --- a/tests/tcg/arm/README +++ b/tests/tcg/arm/README @@ -4,8 +4,3 @@ hello-arm --------- A very simple inline assembly, write syscall based hello world - -test-arm-iwmmxt ---------------- - -A simple test case for older iwmmxt extended ARMs diff --git a/tests/tcg/arm/test-arm-iwmmxt.S b/tests/tcg/arm/test-arm-iwmmxt.S deleted file mode 100644 index d647f9404a..0000000000 --- a/tests/tcg/arm/test-arm-iwmmxt.S +++ /dev/null @@ -1,49 +0,0 @@ -@ Checks whether iwMMXt is functional. -.code 32 -.globl main - -main: -ldr r0, =data0 -ldr r1, =data1 -ldr r2, =data2 -#ifndef FPA -wldrd wr0, [r0, #0] -wldrd wr1, [r0, #8] -wldrd wr2, [r1, #0] -wldrd wr3, [r1, #8] -wsubb wr2, wr2, wr0 -wsubb wr3, wr3, wr1 -wldrd wr0, [r2, #0] -wldrd wr1, [r2, #8] -waddb wr0, wr0, wr2 -waddb wr1, wr1, wr3 -wstrd wr0, [r2, #0] -wstrd wr1, [r2, #8] -#else -ldfe f0, [r0, #0] -ldfe f1, [r0, #8] -ldfe f2, [r1, #0] -ldfe f3, [r1, #8] -adfdp f2, f2, f0 -adfdp f3, f3, f1 -ldfe f0, [r2, #0] -ldfe f1, [r2, #8] -adfd f0, f0, f2 -adfd f1, f1, f3 -stfe f0, [r2, #0] -stfe f1, [r2, #8] -#endif -mov r0, #1 -mov r1, r2 -mov r2, #0x11 -swi #0x900004 -mov r0, #0 -swi #0x900001 - -.data -data0: -.string "aaaabbbbccccdddd" -data1: -.string "bbbbccccddddeeee" -data2: -.string "hvLLWs\x1fsdrs9\x1fNJ-\n" diff --git a/tests/tcg/x86_64/Makefile.target b/tests/tcg/x86_64/Makefile.target index d6dff559c7..be20fc64e8 100644 --- a/tests/tcg/x86_64/Makefile.target +++ b/tests/tcg/x86_64/Makefile.target @@ -18,6 +18,7 @@ X86_64_TESTS += adox X86_64_TESTS += test-1648 X86_64_TESTS += test-2175 X86_64_TESTS += cross-modifying-code +X86_64_TESTS += fma TESTS=$(MULTIARCH_TESTS) $(X86_64_TESTS) test-x86_64 else TESTS=$(MULTIARCH_TESTS) diff --git a/tests/tcg/x86_64/fma.c b/tests/tcg/x86_64/fma.c new file mode 100644 index 0000000000..09c622ebc0 --- /dev/null +++ b/tests/tcg/x86_64/fma.c @@ -0,0 +1,109 @@ +/* + * Test some fused multiply add corner cases. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <stdio.h> +#include <stdint.h> +#include <stdbool.h> +#include <inttypes.h> + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/* + * Perform one "n * m + a" operation using the vfmadd insn and return + * the result; on return *mxcsr_p is set to the bottom 6 bits of MXCSR + * (the Flag bits). If ftz is true then we set MXCSR.FTZ while doing + * the operation. + * We print the operation and its results to stdout. + */ +static uint64_t do_fmadd(uint64_t n, uint64_t m, uint64_t a, + bool ftz, uint32_t *mxcsr_p) +{ + uint64_t r; + uint32_t mxcsr = 0; + uint32_t ftz_bit = ftz ? (1 << 15) : 0; + uint32_t saved_mxcsr = 0; + + asm volatile("stmxcsr %[saved_mxcsr]\n" + "stmxcsr %[mxcsr]\n" + "andl $0xffff7fc0, %[mxcsr]\n" + "orl %[ftz_bit], %[mxcsr]\n" + "ldmxcsr %[mxcsr]\n" + "movq %[a], %%xmm0\n" + "movq %[m], %%xmm1\n" + "movq %[n], %%xmm2\n" + /* xmm0 = xmm0 + xmm2 * xmm1 */ + "vfmadd231sd %%xmm1, %%xmm2, %%xmm0\n" + "movq %%xmm0, %[r]\n" + "stmxcsr %[mxcsr]\n" + "ldmxcsr %[saved_mxcsr]\n" + : [r] "=r" (r), [mxcsr] "=m" (mxcsr), + [saved_mxcsr] "=m" (saved_mxcsr) + : [n] "r" (n), [m] "r" (m), [a] "r" (a), + [ftz_bit] "r" (ftz_bit) + : "xmm0", "xmm1", "xmm2"); + *mxcsr_p = mxcsr & 0x3f; + printf("vfmadd132sd 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 + " = 0x%" PRIx64 " MXCSR flags 0x%" PRIx32 "\n", + n, m, a, r, *mxcsr_p); + return r; +} + +typedef struct testdata { + /* Input n, m, a */ + uint64_t n; + uint64_t m; + uint64_t a; + bool ftz; + /* Expected result */ + uint64_t expected_r; + /* Expected low 6 bits of MXCSR (the Flag bits) */ + uint32_t expected_mxcsr; +} testdata; + +static testdata tests[] = { + { 0, 0x7ff0000000000000, 0x7ff000000000aaaa, false, /* 0 * Inf + SNaN */ + 0x7ff800000000aaaa, 1 }, /* Should be QNaN and does raise Invalid */ + { 0, 0x7ff0000000000000, 0x7ff800000000aaaa, false, /* 0 * Inf + QNaN */ + 0x7ff800000000aaaa, 0 }, /* Should be QNaN and does *not* raise Invalid */ + /* + * These inputs give a result which is tiny before rounding but which + * becomes non-tiny after rounding. x86 is a "detect tininess after + * rounding" architecture, so it should give a non-denormal result and + * not set the Underflow flag (only the Precision flag for an inexact + * result). + */ + { 0x3fdfffffffffffff, 0x001fffffffffffff, 0x801fffffffffffff, false, + 0x8010000000000000, 0x20 }, + /* + * Flushing of denormal outputs to zero should also happen after + * rounding, so setting FTZ should not affect the result or the flags. + * QEMU currently does not emulate this correctly because we do the + * flush-to-zero check before rounding, so we incorrectly produce a + * zero result and set Underflow as well as Precision. + */ +#ifdef ENABLE_FAILING_TESTS + { 0x3fdfffffffffffff, 0x001fffffffffffff, 0x801fffffffffffff, true, + 0x8010000000000000, 0x20 }, /* Enabling FTZ shouldn't change flags */ +#endif +}; + +int main(void) +{ + bool passed = true; + for (int i = 0; i < ARRAY_SIZE(tests); i++) { + uint32_t mxcsr; + uint64_t r = do_fmadd(tests[i].n, tests[i].m, tests[i].a, + tests[i].ftz, &mxcsr); + if (r != tests[i].expected_r) { + printf("expected result 0x%" PRIx64 "\n", tests[i].expected_r); + passed = false; + } + if (mxcsr != tests[i].expected_mxcsr) { + printf("expected MXCSR flags 0x%x\n", tests[i].expected_mxcsr); + passed = false; + } + } + return passed ? 0 : 1; +} diff --git a/tests/unit/check-block-qdict.c b/tests/unit/check-block-qdict.c index 751c58e737..0036d85cfa 100644 --- a/tests/unit/check-block-qdict.c +++ b/tests/unit/check-block-qdict.c @@ -9,8 +9,8 @@ #include "qemu/osdep.h" #include "block/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qlist.h" +#include "qobject/qnum.h" #include "qapi/error.h" static void qdict_defaults_test(void) diff --git a/tests/unit/check-qdict.c b/tests/unit/check-qdict.c index b5efa859b0..a1312be30a 100644 --- a/tests/unit/check-qdict.c +++ b/tests/unit/check-qdict.c @@ -11,9 +11,9 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" /* * Public Interface test-cases diff --git a/tests/unit/check-qjson.c b/tests/unit/check-qjson.c index a89293ce51..780a3654d0 100644 --- a/tests/unit/check-qjson.c +++ b/tests/unit/check-qjson.c @@ -14,12 +14,12 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qlit.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qjson.h" +#include "qobject/qlit.h" +#include "qobject/qnull.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qemu/unicode.h" static QString *from_json_str(const char *jstr, bool single, Error **errp) diff --git a/tests/unit/check-qlist.c b/tests/unit/check-qlist.c index 3cd0ccbf19..1388aeede3 100644 --- a/tests/unit/check-qlist.c +++ b/tests/unit/check-qlist.c @@ -11,8 +11,8 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qnum.h" +#include "qobject/qlist.h" /* * Public Interface test-cases diff --git a/tests/unit/check-qlit.c b/tests/unit/check-qlit.c index bd6798d912..ea7a0d9119 100644 --- a/tests/unit/check-qlit.c +++ b/tests/unit/check-qlit.c @@ -9,12 +9,12 @@ #include "qemu/osdep.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qlit.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qlit.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" static QLitObject qlit = QLIT_QDICT(((QLitDictEntry[]) { { "foo", QLIT_QNUM(42) }, diff --git a/tests/unit/check-qnull.c b/tests/unit/check-qnull.c index 5ceacc65d7..724a66d0bd 100644 --- a/tests/unit/check-qnull.c +++ b/tests/unit/check-qnull.c @@ -8,7 +8,7 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qnull.h" +#include "qobject/qnull.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" #include "qapi/error.h" diff --git a/tests/unit/check-qnum.c b/tests/unit/check-qnum.c index bf7fe45bac..a40120e8d3 100644 --- a/tests/unit/check-qnum.c +++ b/tests/unit/check-qnum.c @@ -14,7 +14,7 @@ #include "qemu/osdep.h" -#include "qapi/qmp/qnum.h" +#include "qobject/qnum.h" /* * Public Interface test-cases diff --git a/tests/unit/check-qobject.c b/tests/unit/check-qobject.c index 022b7c74fe..ccb25660f2 100644 --- a/tests/unit/check-qobject.c +++ b/tests/unit/check-qobject.c @@ -9,12 +9,12 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qnull.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include <math.h> diff --git a/tests/unit/check-qom-proplist.c b/tests/unit/check-qom-proplist.c index b48e890577..13d632cfed 100644 --- a/tests/unit/check-qom-proplist.c +++ b/tests/unit/check-qom-proplist.c @@ -22,8 +22,8 @@ #include "qapi/error.h" #include "qapi/qobject-input-visitor.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qobject.h" +#include "qobject/qdict.h" +#include "qobject/qobject.h" #include "qom/object.h" #include "qemu/module.h" #include "qemu/option.h" diff --git a/tests/unit/check-qstring.c b/tests/unit/check-qstring.c index bd861f4f8b..2e6a00570f 100644 --- a/tests/unit/check-qstring.c +++ b/tests/unit/check-qstring.c @@ -11,7 +11,7 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qstring.h" /* * Public Interface test-cases diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c index 1de04a8a13..7324ea4a68 100644 --- a/tests/unit/test-block-iothread.c +++ b/tests/unit/test-block-iothread.c @@ -28,7 +28,7 @@ #include "block/blockjob_int.h" #include "system/block-backend.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/clang-tsa.h" #include "qemu/main-loop.h" #include "iothread.h" diff --git a/tests/unit/test-blockjob-txn.c b/tests/unit/test-blockjob-txn.c index c7b4e55483..118503a8e8 100644 --- a/tests/unit/test-blockjob-txn.c +++ b/tests/unit/test-blockjob-txn.c @@ -15,7 +15,7 @@ #include "qemu/main-loop.h" #include "block/blockjob_int.h" #include "system/block-backend.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" typedef struct { BlockJob common; diff --git a/tests/unit/test-blockjob.c b/tests/unit/test-blockjob.c index 1df5739b13..abdbe4b835 100644 --- a/tests/unit/test-blockjob.c +++ b/tests/unit/test-blockjob.c @@ -15,7 +15,7 @@ #include "qemu/main-loop.h" #include "block/blockjob_int.h" #include "system/block-backend.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "iothread.h" static const BlockJobDriver test_block_job_driver = { diff --git a/tests/unit/test-char.c b/tests/unit/test-char.c index 85b350a9b7..60a843b79d 100644 --- a/tests/unit/test-char.c +++ b/tests/unit/test-char.c @@ -10,7 +10,7 @@ #include "system/system.h" #include "qapi/error.h" #include "qapi/qapi-commands-char.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qom/qom-qobject.h" #include "io/channel-socket.h" #include "qapi/qobject-input-visitor.h" diff --git a/tests/unit/test-forward-visitor.c b/tests/unit/test-forward-visitor.c index eea8ffc072..aad1c89f13 100644 --- a/tests/unit/test-forward-visitor.c +++ b/tests/unit/test-forward-visitor.c @@ -12,8 +12,8 @@ #include "qapi/forward-visitor.h" #include "qapi/qobject-input-visitor.h" #include "qapi/error.h" -#include "qapi/qmp/qobject.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qobject.h" +#include "qobject/qdict.h" #include "test-qapi-visit.h" #include "qemu/keyval.h" diff --git a/tests/unit/test-image-locking.c b/tests/unit/test-image-locking.c index 7ccf9567f1..019195f899 100644 --- a/tests/unit/test-image-locking.c +++ b/tests/unit/test-image-locking.c @@ -28,7 +28,7 @@ #include "block/block.h" #include "system/block-backend.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/main-loop.h" static BlockBackend *open_image(const char *path, diff --git a/tests/unit/test-keyval.c b/tests/unit/test-keyval.c index 4dc52c7a1a..c6e8f4fe37 100644 --- a/tests/unit/test-keyval.c +++ b/tests/unit/test-keyval.c @@ -13,9 +13,9 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qstring.h" #include "qapi/qobject-input-visitor.h" #include "test-qapi-visit.h" #include "qemu/cutils.h" diff --git a/tests/unit/test-qemu-opts.c b/tests/unit/test-qemu-opts.c index 828d40e928..8d03a69f7c 100644 --- a/tests/unit/test-qemu-opts.c +++ b/tests/unit/test-qemu-opts.c @@ -12,8 +12,8 @@ #include "qemu/option.h" #include "qemu/option_int.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qstring.h" #include "qemu/config-file.h" diff --git a/tests/unit/test-qga.c b/tests/unit/test-qga.c index 8cddf5dc37..541b08a5e7 100644 --- a/tests/unit/test-qga.c +++ b/tests/unit/test-qga.c @@ -5,8 +5,8 @@ #include <sys/un.h> #include "../qtest/libqtest.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" typedef struct { char *test_dir; diff --git a/tests/unit/test-qmp-cmds.c b/tests/unit/test-qmp-cmds.c index 6d52b4e5d8..ad53886886 100644 --- a/tests/unit/test-qmp-cmds.c +++ b/tests/unit/test-qmp-cmds.c @@ -1,9 +1,9 @@ #include "qemu/osdep.h" #include "qapi/compat-policy.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qapi/error.h" #include "qapi/qobject-input-visitor.h" #include "tests/test-qapi-types.h" diff --git a/tests/unit/test-qmp-event.c b/tests/unit/test-qmp-event.c index 08e95a382b..2aac27163d 100644 --- a/tests/unit/test-qmp-event.c +++ b/tests/unit/test-qmp-event.c @@ -15,11 +15,11 @@ #include "qapi/compat-policy.h" #include "qapi/error.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qapi/qmp-event.h" #include "test-qapi-events.h" #include "test-qapi-emit-events.h" diff --git a/tests/unit/test-qobject-input-visitor.c b/tests/unit/test-qobject-input-visitor.c index 5479e68237..84bdcdf702 100644 --- a/tests/unit/test-qobject-input-visitor.c +++ b/tests/unit/test-qobject-input-visitor.c @@ -17,12 +17,12 @@ #include "qapi/qapi-visit-introspect.h" #include "qapi/qobject-input-visitor.h" #include "test-qapi-visit.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qjson.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qnull.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" +#include "qobject/qjson.h" #include "test-qapi-introspect.h" #include "qapi/qapi-introspect.h" diff --git a/tests/unit/test-qobject-output-visitor.c b/tests/unit/test-qobject-output-visitor.c index 3455f3b107..407ab9ed50 100644 --- a/tests/unit/test-qobject-output-visitor.c +++ b/tests/unit/test-qobject-output-visitor.c @@ -15,12 +15,12 @@ #include "qapi/error.h" #include "qapi/qobject-output-visitor.h" #include "test-qapi-visit.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qnull.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qnull.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" typedef struct TestOutputVisitorData { Visitor *ov; diff --git a/tests/unit/test-replication.c b/tests/unit/test-replication.c index 2a60f78e0a..3aa98e6f56 100644 --- a/tests/unit/test-replication.c +++ b/tests/unit/test-replication.c @@ -11,7 +11,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/option.h" #include "qemu/main-loop.h" #include "block/replication.h" diff --git a/tests/unit/test-visitor-serialization.c b/tests/unit/test-visitor-serialization.c index c2056c3eaa..2d365999fc 100644 --- a/tests/unit/test-visitor-serialization.c +++ b/tests/unit/test-visitor-serialization.c @@ -16,8 +16,8 @@ #include "test-qapi-visit.h" #include "qapi/error.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qjson.h" +#include "qobject/qstring.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" #include "qapi/string-input-visitor.h" diff --git a/trace/trace-hmp-cmds.c b/trace/trace-hmp-cmds.c index d38dd600de..45f4335ff5 100644 --- a/trace/trace-hmp-cmds.c +++ b/trace/trace-hmp-cmds.c @@ -27,7 +27,7 @@ #include "monitor/monitor.h" #include "qapi/error.h" #include "qapi/qapi-commands-trace.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "trace/control.h" #ifdef CONFIG_TRACE_SIMPLE #include "trace/simple.h" diff --git a/ui/ui-hmp-cmds.c b/ui/ui-hmp-cmds.c index 26c8ced1f2..980a8bbc51 100644 --- a/ui/ui-hmp-cmds.c +++ b/ui/ui-hmp-cmds.c @@ -21,7 +21,7 @@ #include "monitor/monitor-internal.h" #include "qapi/error.h" #include "qapi/qapi-commands-ui.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "qemu/cutils.h" #include "ui/console.h" #include "ui/input.h" diff --git a/util/keyval.c b/util/keyval.c index 66a5b4740f..a70629a481 100644 --- a/util/keyval.c +++ b/util/keyval.c @@ -91,9 +91,9 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" +#include "qobject/qstring.h" #include "qemu/cutils.h" #include "qemu/keyval.h" #include "qemu/help_option.h" diff --git a/util/qemu-config.c b/util/qemu-config.c index a90c18dad2..d1fc49c507 100644 --- a/util/qemu-config.c +++ b/util/qemu-config.c @@ -1,8 +1,8 @@ #include "qemu/osdep.h" #include "block/qdict.h" /* for qdict_extract_subqdict() */ #include "qapi/error.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" +#include "qobject/qdict.h" +#include "qobject/qlist.h" #include "qemu/error-report.h" #include "qemu/option.h" #include "qemu/config-file.h" diff --git a/util/qemu-option.c b/util/qemu-option.c index 201f7a87f3..770300dff1 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -27,10 +27,10 @@ #include "qapi/error.h" #include "qemu/error-report.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qnum.h" -#include "qapi/qmp/qstring.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qnum.h" +#include "qobject/qstring.h" #include "qapi/qmp/qerror.h" #include "qemu/option_int.h" #include "qemu/cutils.h" |