From 0dd8f840c7323b3ccface3cad5215639bb0b74a7 Mon Sep 17 00:00:00 2001 From: Jiabo Feng Date: Thu, 11 Jul 2024 14:25:27 +0800 Subject: [PATCH] QEMU update to verssion 6.2.0-96: - vdpa: Fix bug where vdpa appliance migration does not resume after rollback - block: Parse filenames only when explicitly requested (CVE-2024-4467) - block: introduce bdrv_open_file_child() helper - iotests/270: Don't store data-file with json: prefix in image (CVE-2024-4467) - iotests/244: Don't store data-file with protocol in image (CVE-2024-4467) - qcow2: Don't open data_file with BDRV_O_NO_IO (CVE-2024-4467) - qcow2: Do not reopen data_file in invalidate_cache - hw/intc/arm_gic: Fix deactivation of SPI lines chery-pick from 7175a562f157d39725ab396e39c1e8e410d206b3 - vhost-user: Skip unnecessary duplicated VHOST_USER_SET_LOG_BASE requests - target/ppc: Split off common embedded TLB init cheery-pick from 581eea5d656b73c6532109f4ced4c73fd4e5fd47` - vdpa: fix vdpa device migrate rollback wrong when suspend device failed 1. - hw/virtio/virtio-pci:Support shadow device for virtio-net/blk/scsi devices Signed-off-by: Jiabo Feng (cherry picked from commit ad45062d44e901468eeb8c4ac0729587daaa1e1f) --- ...names-only-when-explicitly-requested.patch | 229 ++++++++ ...ntroduce-bdrv_open_file_child-helper.patch | 542 ++++++++++++++++++ ...rm_gic-Fix-deactivation-of-SPI-lines.patch | 62 ++ ...-pci-Support-shadow-device-for-virti.patch | 64 +++ ...t-store-data-file-with-protocol-in-i.patch | 52 ++ ...t-store-data-file-with-json-prefix-i.patch | 54 ++ ...reopen-data_file-in-invalidate_cache.patch | 221 +++++++ ...-data_file-with-BDRV_O_NO_IO-CVE-202.patch | 108 ++++ qemu.spec | 28 +- ...c-Split-off-common-embedded-TLB-init.patch | 118 ++++ ...re-vdpa-appliance-migration-does-not.patch | 38 ++ ...vice-migrate-rollback-wrong-when-sus.patch | 140 +++++ ...unnecessary-duplicated-VHOST_USER_SE.patch | 31 + 13 files changed, 1686 insertions(+), 1 deletion(-) create mode 100644 block-Parse-filenames-only-when-explicitly-requested.patch create mode 100644 block-introduce-bdrv_open_file_child-helper.patch create mode 100644 hw-intc-arm_gic-Fix-deactivation-of-SPI-lines.patch create mode 100644 hw-virtio-virtio-pci-Support-shadow-device-for-virti.patch create mode 100644 iotests-244-Don-t-store-data-file-with-protocol-in-i.patch create mode 100644 iotests-270-Don-t-store-data-file-with-json-prefix-i.patch create mode 100644 qcow2-Do-not-reopen-data_file-in-invalidate_cache.patch create mode 100644 qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO-CVE-202.patch create mode 100644 target-ppc-Split-off-common-embedded-TLB-init.patch create mode 100644 vdpa-Fix-bug-where-vdpa-appliance-migration-does-not.patch create mode 100644 vdpa-fix-vdpa-device-migrate-rollback-wrong-when-sus.patch create mode 100644 vhost-user-Skip-unnecessary-duplicated-VHOST_USER_SE.patch diff --git a/block-Parse-filenames-only-when-explicitly-requested.patch b/block-Parse-filenames-only-when-explicitly-requested.patch new file mode 100644 index 00000000..c5aa88b6 --- /dev/null +++ b/block-Parse-filenames-only-when-explicitly-requested.patch @@ -0,0 +1,229 @@ +From effc2c56f7b5390fbe6041d3a6ecf4026371bc25 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 25 Apr 2024 14:56:02 +0200 +Subject: [PATCH] block: Parse filenames only when explicitly requested + (CVE-2024-4467) + +When handling image filenames from legacy options such as -drive or from +tools, these filenames are parsed for protocol prefixes, including for +the json:{} pseudo-protocol. + +This behaviour is intended for filenames that come directly from the +command line and for backing files, which may come from the image file +itself. Higher level management tools generally take care to verify that +untrusted images don't contain a bad (or any) backing file reference; +'qemu-img info' is a suitable tool for this. + +However, for other files that can be referenced in images, such as +qcow2 data files or VMDK extents, the string from the image file is +usually not verified by management tools - and 'qemu-img info' wouldn't +be suitable because in contrast to backing files, it already opens these +other referenced files. So here the string should be interpreted as a +literal local filename. More complex configurations need to be specified +explicitly on the command line or in QMP. + +This patch changes bdrv_open_inherit() so that it only parses filenames +if a new parameter parse_filename is true. It is set for the top level +in bdrv_open(), for the file child and for the backing file child. All +other callers pass false and disable filename parsing this way. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Hanna Czenczek +Signed-off-by: liuxiangdong +--- + block.c | 75 ++++++++++++++++++++++++++++++++++++++------------------- + 1 file changed, 50 insertions(+), 25 deletions(-) + +diff --git a/block.c b/block.c +index 7b58fe57f8..a91117abda 100644 +--- a/block.c ++++ b/block.c +@@ -85,6 +85,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, + BlockDriverState *parent, + const BdrvChildClass *child_class, + BdrvChildRole child_role, ++ bool parse_filename, + Error **errp); + + static bool bdrv_recurse_has_child(BlockDriverState *bs, +@@ -1929,7 +1930,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename, + * block driver has been specified explicitly. + */ + static int bdrv_fill_options(QDict **options, const char *filename, +- int *flags, Error **errp) ++ int *flags, bool allow_parse_filename, ++ Error **errp) + { + const char *drvname; + bool protocol = *flags & BDRV_O_PROTOCOL; +@@ -1969,7 +1971,7 @@ static int bdrv_fill_options(QDict **options, const char *filename, + if (protocol && filename) { + if (!qdict_haskey(*options, "filename")) { + qdict_put_str(*options, "filename", filename); +- parse_filename = true; ++ parse_filename = allow_parse_filename; + } else { + error_setg(errp, "Can't specify 'file' and 'filename' options at " + "the same time"); +@@ -3442,7 +3444,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, + } + + backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs, +- &child_of_bds, bdrv_backing_role(bs), errp); ++ &child_of_bds, bdrv_backing_role(bs), true, ++ errp); + if (!backing_hd) { + bs->open_flags |= BDRV_O_NO_BACKING; + error_prepend(errp, "Could not open backing file: "); +@@ -3475,7 +3478,8 @@ free_exit: + static BlockDriverState * + bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key, + BlockDriverState *parent, const BdrvChildClass *child_class, +- BdrvChildRole child_role, bool allow_none, Error **errp) ++ BdrvChildRole child_role, bool allow_none, ++ bool parse_filename, Error **errp) + { + BlockDriverState *bs = NULL; + QDict *image_options; +@@ -3506,7 +3510,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key, + } + + bs = bdrv_open_inherit(filename, reference, image_options, 0, +- parent, child_class, child_role, errp); ++ parent, child_class, child_role, parse_filename, ++ errp); + if (!bs) { + goto done; + } +@@ -3516,6 +3521,26 @@ done: + return bs; + } + ++static BdrvChild *bdrv_open_child_common(const char *filename, ++ QDict *options, const char *bdref_key, ++ BlockDriverState *parent, ++ const BdrvChildClass *child_class, ++ BdrvChildRole child_role, ++ bool allow_none, bool parse_filename, ++ Error **errp) ++{ ++ BlockDriverState *bs; ++ ++ bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class, ++ child_role, allow_none, parse_filename, errp); ++ if (bs == NULL) { ++ return NULL; ++ } ++ ++ return bdrv_attach_child(parent, bs, bdref_key, child_class, child_role, ++ errp); ++} ++ + /* + * Opens a disk image whose options are given as BlockdevRef in another block + * device's options. +@@ -3537,20 +3562,15 @@ BdrvChild *bdrv_open_child(const char *filename, + BdrvChildRole child_role, + bool allow_none, Error **errp) + { +- BlockDriverState *bs; +- +- bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class, +- child_role, allow_none, errp); +- if (bs == NULL) { +- return NULL; +- } +- +- return bdrv_attach_child(parent, bs, bdref_key, child_class, child_role, +- errp); ++ return bdrv_open_child_common(filename, options, bdref_key, parent, ++ child_class, child_role, allow_none, false, ++ errp); + } + + /* +- * Wrapper on bdrv_open_child() for most popular case: open primary child of bs. ++ * This does mostly the same as bdrv_open_child(), but for opening the primary ++ * child of a node. A notable difference from bdrv_open_child() is that it ++ * enables filename parsing for protocol names (including json:). + */ + int bdrv_open_file_child(const char *filename, + QDict *options, const char *bdref_key, +@@ -3561,8 +3581,8 @@ int bdrv_open_file_child(const char *filename, + role = parent->drv->is_filter ? + (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE; + +- parent->file = bdrv_open_child(filename, options, bdref_key, parent, +- &child_of_bds, role, false, errp); ++ parent->file = bdrv_open_child_common(filename, options, bdref_key, parent, ++ &child_of_bds, role, false, true, errp); + + return parent->file ? 0 : -EINVAL; + } +@@ -3602,7 +3622,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp) + + } + +- bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp); ++ bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, false, ++ errp); + obj = NULL; + qobject_unref(obj); + visit_free(v); +@@ -3693,6 +3714,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, + BlockDriverState *parent, + const BdrvChildClass *child_class, + BdrvChildRole child_role, ++ bool parse_filename, + Error **errp) + { + int ret; +@@ -3736,9 +3758,11 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, + } + + /* json: syntax counts as explicit options, as if in the QDict */ +- parse_json_protocol(options, &filename, &local_err); +- if (local_err) { +- goto fail; ++ if (parse_filename) { ++ parse_json_protocol(options, &filename, &local_err); ++ if (local_err) { ++ goto fail; ++ } + } + + bs->explicit_options = qdict_clone_shallow(options); +@@ -3763,7 +3787,8 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, + parent->open_flags, parent->options); + } + +- ret = bdrv_fill_options(&options, filename, &flags, &local_err); ++ ret = bdrv_fill_options(&options, filename, &flags, parse_filename, ++ &local_err); + if (ret < 0) { + goto fail; + } +@@ -3832,7 +3857,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, + + file_bs = bdrv_open_child_bs(filename, options, "file", bs, + &child_of_bds, BDRV_CHILD_IMAGE, +- true, &local_err); ++ true, true, &local_err); + if (local_err) { + goto fail; + } +@@ -3977,7 +4002,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference, + QDict *options, int flags, Error **errp) + { + return bdrv_open_inherit(filename, reference, options, flags, NULL, +- NULL, 0, errp); ++ NULL, 0, true, errp); + } + + /* Return true if the NULL-terminated @list contains @str */ +-- +2.41.0.windows.1 + diff --git a/block-introduce-bdrv_open_file_child-helper.patch b/block-introduce-bdrv_open_file_child-helper.patch new file mode 100644 index 00000000..4179b9f6 --- /dev/null +++ b/block-introduce-bdrv_open_file_child-helper.patch @@ -0,0 +1,542 @@ +From 4045020d37da7a7a70b5175b3fb7d022e0bdb47f Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 26 Jul 2022 23:11:21 +0300 +Subject: [PATCH] block: introduce bdrv_open_file_child() helper + +Almost all drivers call bdrv_open_child() similarly. Let's create a +helper for this. + +The only not updated drivers that call bdrv_open_child() to set +bs->file are raw-format and snapshot-access: + raw-format sometimes want to have filtered child but + don't set drv->is_filter to true. + snapshot-access wants only DATA | PRIMARY + +Possibly we should implement drv->is_filter_func() handler, to consider +raw-format as filter when it works as filter.. But it's another story. + +Note also, that we decrease assignments to bs->file in code: it helps +us restrict modifying this field in further commit. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Reviewed-by: Hanna Reitz +Message-Id: <20220726201134.924743-3-vsementsov@yandex-team.ru> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +Signed-off-by: liuxiangdong +--- + block.c | 18 ++++++++++++++++++ + block/blkdebug.c | 9 +++------ + block/blklogwrites.c | 7 ++----- + block/blkreplay.c | 7 ++----- + block/blkverify.c | 9 +++------ + block/bochs.c | 7 +++---- + block/cloop.c | 7 +++---- + block/copy-before-write.c | 9 ++++----- + block/copy-on-read.c | 9 ++++----- + block/crypto.c | 11 ++++++----- + block/dmg.c | 7 +++---- + block/filter-compress.c | 8 +++----- + block/parallels.c | 7 +++---- + block/preallocate.c | 9 ++++----- + block/qcow.c | 6 ++---- + block/qcow2.c | 8 ++++---- + block/qed.c | 8 ++++---- + block/replication.c | 8 +++----- + block/throttle.c | 8 +++----- + block/vdi.c | 7 +++---- + block/vhdx.c | 7 +++---- + block/vmdk.c | 7 +++---- + block/vpc.c | 7 +++---- + include/block/block.h | 3 +++ + 24 files changed, 92 insertions(+), 101 deletions(-) + +diff --git a/block.c b/block.c +index 75083139d1..7b58fe57f8 100644 +--- a/block.c ++++ b/block.c +@@ -3549,6 +3549,24 @@ BdrvChild *bdrv_open_child(const char *filename, + errp); + } + ++/* ++ * Wrapper on bdrv_open_child() for most popular case: open primary child of bs. ++ */ ++int bdrv_open_file_child(const char *filename, ++ QDict *options, const char *bdref_key, ++ BlockDriverState *parent, Error **errp) ++{ ++ BdrvChildRole role; ++ ++ role = parent->drv->is_filter ? ++ (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE; ++ ++ parent->file = bdrv_open_child(filename, options, bdref_key, parent, ++ &child_of_bds, role, false, errp); ++ ++ return parent->file ? 0 : -EINVAL; ++} ++ + /* + * TODO Future callers may need to specify parent/child_class in order for + * option inheritance to work. Existing callers use it for the root node. +diff --git a/block/blkdebug.c b/block/blkdebug.c +index bbf2948703..5fcfc8ac6f 100644 +--- a/block/blkdebug.c ++++ b/block/blkdebug.c +@@ -503,12 +503,9 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags, + } + + /* Open the image file */ +- bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image", +- bs, &child_of_bds, +- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, +- false, errp); +- if (!bs->file) { +- ret = -EINVAL; ++ ret = bdrv_open_file_child(qemu_opt_get(opts, "x-image"), options, "image", ++ bs, errp); ++ if (ret < 0) { + goto out; + } + +diff --git a/block/blklogwrites.c b/block/blklogwrites.c +index f7a251e91f..f66a617eb3 100644 +--- a/block/blklogwrites.c ++++ b/block/blklogwrites.c +@@ -155,11 +155,8 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags, + } + + /* Open the file */ +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, false, +- errp); +- if (!bs->file) { +- ret = -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { + goto fail; + } + +diff --git a/block/blkreplay.c b/block/blkreplay.c +index dcbe780ddb..76a0b8d12a 100644 +--- a/block/blkreplay.c ++++ b/block/blkreplay.c +@@ -26,11 +26,8 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags, + int ret; + + /* Open the image file */ +- bs->file = bdrv_open_child(NULL, options, "image", bs, &child_of_bds, +- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, +- false, errp); +- if (!bs->file) { +- ret = -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "image", bs, errp); ++ if (ret < 0) { + goto fail; + } + +diff --git a/block/blkverify.c b/block/blkverify.c +index d1facf5ba9..920e891684 100644 +--- a/block/blkverify.c ++++ b/block/blkverify.c +@@ -121,12 +121,9 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags, + } + + /* Open the raw file */ +- bs->file = bdrv_open_child(qemu_opt_get(opts, "x-raw"), options, "raw", +- bs, &child_of_bds, +- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, +- false, errp); +- if (!bs->file) { +- ret = -EINVAL; ++ ret = bdrv_open_file_child(qemu_opt_get(opts, "x-raw"), options, "raw", ++ bs, errp); ++ if (ret < 0) { + goto fail; + } + +diff --git a/block/bochs.c b/block/bochs.c +index 4d68658087..b2dc06bbfd 100644 +--- a/block/bochs.c ++++ b/block/bochs.c +@@ -110,10 +110,9 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags, + return ret; + } + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs)); +diff --git a/block/cloop.c b/block/cloop.c +index b8c6d0eccd..bee87da173 100644 +--- a/block/cloop.c ++++ b/block/cloop.c +@@ -71,10 +71,9 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags, + return ret; + } + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + /* read header */ +diff --git a/block/copy-before-write.c b/block/copy-before-write.c +index c30a5ff8de..8aa2cb6a85 100644 +--- a/block/copy-before-write.c ++++ b/block/copy-before-write.c +@@ -150,12 +150,11 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, + { + BDRVCopyBeforeWriteState *s = bs->opaque; + BdrvDirtyBitmap *copy_bitmap; ++ int ret; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, +- false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + s->target = bdrv_open_child(NULL, options, "target", bs, &child_of_bds, +diff --git a/block/copy-on-read.c b/block/copy-on-read.c +index 1fc7fb3333..815ac1d835 100644 +--- a/block/copy-on-read.c ++++ b/block/copy-on-read.c +@@ -41,12 +41,11 @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags, + BDRVStateCOR *state = bs->opaque; + /* Find a bottom node name, if any */ + const char *bottom_node = qdict_get_try_str(options, "bottom"); ++ int ret; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, +- false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + bs->supported_read_flags = BDRV_REQ_PREFETCH; +diff --git a/block/crypto.c b/block/crypto.c +index c8ba4681e2..abfce39230 100644 +--- a/block/crypto.c ++++ b/block/crypto.c +@@ -260,15 +260,14 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, + { + BlockCrypto *crypto = bs->opaque; + QemuOpts *opts = NULL; +- int ret = -EINVAL; ++ int ret; + QCryptoBlockOpenOptions *open_opts = NULL; + unsigned int cflags = 0; + QDict *cryptoopts = NULL; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + bs->supported_write_flags = BDRV_REQ_FUA & +@@ -276,6 +275,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, + + opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort); + if (!qemu_opts_absorb_qdict(opts, options, errp)) { ++ ret = -EINVAL; + goto cleanup; + } + +@@ -284,6 +284,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, + + open_opts = block_crypto_open_opts_init(cryptoopts, errp); + if (!open_opts) { ++ ret = -EINVAL; + goto cleanup; + } + +diff --git a/block/dmg.c b/block/dmg.c +index 447901fbb8..38c363dd39 100644 +--- a/block/dmg.c ++++ b/block/dmg.c +@@ -439,10 +439,9 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags, + return ret; + } + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + block_module_load_one("dmg-bz2"); +diff --git a/block/filter-compress.c b/block/filter-compress.c +index d5be538619..305716c86c 100644 +--- a/block/filter-compress.c ++++ b/block/filter-compress.c +@@ -30,11 +30,9 @@ + static int compress_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) + { +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, +- false, errp); +- if (!bs->file) { +- return -EINVAL; ++ int ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + if (!bs->file->bs->drv || !block_driver_can_compress(bs->file->bs->drv)) { +diff --git a/block/parallels.c b/block/parallels.c +index f3352b6aa7..ae3f324bb5 100644 +--- a/block/parallels.c ++++ b/block/parallels.c +@@ -735,10 +735,9 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, + Error *local_err = NULL; + char *buf; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph)); +diff --git a/block/preallocate.c b/block/preallocate.c +index 1d4233f730..332408bdc9 100644 +--- a/block/preallocate.c ++++ b/block/preallocate.c +@@ -134,6 +134,7 @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) + { + BDRVPreallocateState *s = bs->opaque; ++ int ret; + + /* + * s->data_end and friends should be initialized on permission update. +@@ -141,11 +142,9 @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags, + */ + s->file_end = s->zero_start = s->data_end = -EINVAL; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, +- false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + if (!preallocate_absorb_opts(&s->opts, options, bs->file->bs, errp)) { +diff --git a/block/qcow.c b/block/qcow.c +index c39940f33e..544a17261f 100644 +--- a/block/qcow.c ++++ b/block/qcow.c +@@ -120,10 +120,8 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, + qdict_extract_subqdict(options, &encryptopts, "encrypt."); + encryptfmt = qdict_get_try_str(encryptopts, "format"); + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- ret = -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { + goto fail; + } + +diff --git a/block/qcow2.c b/block/qcow2.c +index af1e94f2e2..7b1e870919 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -1910,11 +1910,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags, + .errp = errp, + .ret = -EINPROGRESS + }; ++ int ret; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + /* Initialise locks */ +diff --git a/block/qed.c b/block/qed.c +index 558d3646c4..e3b06a3d00 100644 +--- a/block/qed.c ++++ b/block/qed.c +@@ -558,11 +558,11 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags, + .errp = errp, + .ret = -EINPROGRESS + }; ++ int ret; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + bdrv_qed_init_state(bs); +diff --git a/block/replication.c b/block/replication.c +index 55c8f894aa..2f17397764 100644 +--- a/block/replication.c ++++ b/block/replication.c +@@ -88,11 +88,9 @@ static int replication_open(BlockDriverState *bs, QDict *options, + const char *mode; + const char *top_id; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, +- false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + ret = -EINVAL; +diff --git a/block/throttle.c b/block/throttle.c +index 6e8d52fa24..4fb5798c27 100644 +--- a/block/throttle.c ++++ b/block/throttle.c +@@ -78,11 +78,9 @@ static int throttle_open(BlockDriverState *bs, QDict *options, + char *group; + int ret; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, +- false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + bs->supported_write_flags = bs->file->bs->supported_write_flags | + BDRV_REQ_WRITE_UNCHANGED; +diff --git a/block/vdi.c b/block/vdi.c +index bdc58d726e..c50c0ed61f 100644 +--- a/block/vdi.c ++++ b/block/vdi.c +@@ -376,10 +376,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags, + int ret; + QemuUUID uuid_link, uuid_parent; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + logout("\n"); +diff --git a/block/vhdx.c b/block/vhdx.c +index 356ec4c455..e7d6d7509a 100644 +--- a/block/vhdx.c ++++ b/block/vhdx.c +@@ -996,10 +996,9 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags, + uint64_t signature; + Error *local_err = NULL; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + s->bat = NULL; +diff --git a/block/vmdk.c b/block/vmdk.c +index 0dfab6e941..7d7e56b36c 100644 +--- a/block/vmdk.c ++++ b/block/vmdk.c +@@ -1262,10 +1262,9 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags, + BDRVVmdkState *s = bs->opaque; + uint32_t magic; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + buf = vmdk_read_desc(bs->file, 0, errp); +diff --git a/block/vpc.c b/block/vpc.c +index 297a26262a..430cab1cbb 100644 +--- a/block/vpc.c ++++ b/block/vpc.c +@@ -232,10 +232,9 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags, + int ret; + int64_t bs_size; + +- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, +- BDRV_CHILD_IMAGE, false, errp); +- if (!bs->file) { +- return -EINVAL; ++ ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ++ if (ret < 0) { ++ return ret; + } + + opts = qemu_opts_create(&vpc_runtime_opts, NULL, 0, &error_abort); +diff --git a/include/block/block.h b/include/block/block.h +index e5dd22b034..f885f113ef 100644 +--- a/include/block/block.h ++++ b/include/block/block.h +@@ -376,6 +376,9 @@ BdrvChild *bdrv_open_child(const char *filename, + const BdrvChildClass *child_class, + BdrvChildRole child_role, + bool allow_none, Error **errp); ++int bdrv_open_file_child(const char *filename, ++ QDict *options, const char *bdref_key, ++ BlockDriverState *parent, Error **errp); + BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp); + int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, + Error **errp); +-- +2.41.0.windows.1 + diff --git a/hw-intc-arm_gic-Fix-deactivation-of-SPI-lines.patch b/hw-intc-arm_gic-Fix-deactivation-of-SPI-lines.patch new file mode 100644 index 00000000..124e06ce --- /dev/null +++ b/hw-intc-arm_gic-Fix-deactivation-of-SPI-lines.patch @@ -0,0 +1,62 @@ +From 1a52d742851a68772aeb1d6d18bb57e58d78b2d2 Mon Sep 17 00:00:00 2001 +From: guping +Date: Tue, 25 Jun 2024 11:33:54 +0000 +Subject: [PATCH] hw/intc/arm_gic: Fix deactivation of SPI lines chery-pick + from 7175a562f157d39725ab396e39c1e8e410d206b3 + +Julien reported that he has seen strange behaviour when running +Xen on QEMU using GICv2. When Xen migrates a guest's vCPU from +one pCPU to another while the vCPU is handling an interrupt, the +guest is unable to properly deactivate interrupts. + +Looking at it a little closer, our GICv2 model treats +deactivation of SPI lines as if they were PPI's, i.e banked per +CPU core. The state for active interrupts should only be banked +for PPI lines, not for SPI lines. + +Make deactivation of SPI lines unbanked, similar to how we +handle writes to GICD_ICACTIVER. + +Reported-by: default avatarJulien Grall +Signed-off-by: default avatarEdgar E. Iglesias +Message-id: 20240605143044.2029444-2-edgar.iglesias@gmail.com +Reviewed-by: default avatarPeter Maydell +Signed-off-by: default avatarPeter Maydell + +Signed-off-by: guping +--- + hw/intc/gic_internal.h | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h +index 8d29b40ca1..8ddbf554c6 100644 +--- a/hw/intc/gic_internal.h ++++ b/hw/intc/gic_internal.h +@@ -280,6 +280,8 @@ static inline void gic_set_active(GICState *s, int irq, int cpu) + + static inline void gic_clear_active(GICState *s, int irq, int cpu) + { ++ unsigned int cm; ++ + if (gic_is_vcpu(cpu)) { + uint32_t *entry = gic_get_lr_entry(s, irq, cpu); + GICH_LR_CLEAR_ACTIVE(*entry); +@@ -301,11 +303,13 @@ static inline void gic_clear_active(GICState *s, int irq, int cpu) + * the GIC is secure. + */ + if (!s->security_extn || GIC_DIST_TEST_GROUP(phys_irq, 1 << rcpu)) { +- GIC_DIST_CLEAR_ACTIVE(phys_irq, 1 << rcpu); ++ cm = phys_irq < GIC_INTERNAL ? 1 << rcpu : ALL_CPU_MASK; ++ GIC_DIST_CLEAR_ACTIVE(phys_irq, cm); + } + } + } else { +- GIC_DIST_CLEAR_ACTIVE(irq, 1 << cpu); ++ cm = irq < GIC_INTERNAL ? 1 << cpu : ALL_CPU_MASK; ++ GIC_DIST_CLEAR_ACTIVE(irq, cm); + } + } + +-- +2.41.0.windows.1 + diff --git a/hw-virtio-virtio-pci-Support-shadow-device-for-virti.patch b/hw-virtio-virtio-pci-Support-shadow-device-for-virti.patch new file mode 100644 index 00000000..59511f49 --- /dev/null +++ b/hw-virtio-virtio-pci-Support-shadow-device-for-virti.patch @@ -0,0 +1,64 @@ +From 38c0538c8d847a2e39a9bae19f5b204abcf46b3b Mon Sep 17 00:00:00 2001 +From: Yanan Wang +Date: Mon, 17 Jun 2024 20:42:22 +0800 +Subject: [PATCH] hw/virtio/virtio-pci:Support shadow device for + virtio-net/blk/scsi devices + +Currently we only support shadow device for "virtio-net", now let's +extend this feature to support "virtio-blk" and "virtio-scsi" devices. + +Signed-off-by: Yanan Wang +--- + hw/virtio/virtio-pci.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c +index 389a8db0ec..d675526016 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -886,6 +886,15 @@ int __attribute__((weak)) kvm_delete_shadow_device(PCIDevice *dev) + } + #endif + ++#ifdef __aarch64__ ++static bool shadow_device_supported(VirtIODevice *vdev) ++{ ++ return !strcmp(vdev->name, "virtio-net") || ++ !strcmp(vdev->name, "virtio-blk") || ++ !strcmp(vdev->name, "virtio-scsi"); ++} ++#endif ++ + static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs) + { + int queue_no; +@@ -893,7 +902,7 @@ static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs) + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + + #ifdef __aarch64__ +- if (!strcmp(vdev->name, "virtio-net")) { ++ if (shadow_device_supported(vdev)) { + kvm_create_shadow_device(&proxy->pci_dev); + } + #endif +@@ -906,7 +915,7 @@ static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs) + } + + #ifdef __aarch64__ +- if (!strcmp(vdev->name, "virtio-net") && ret != 0) { ++ if (shadow_device_supported(vdev) && ret != 0) { + kvm_delete_shadow_device(&proxy->pci_dev); + } + #endif +@@ -955,7 +964,7 @@ static void kvm_virtio_pci_vector_vq_release(VirtIOPCIProxy *proxy, int nvqs) + } + + #ifdef __aarch64__ +- if (!strcmp(vdev->name, "virtio-net")) { ++ if (shadow_device_supported(vdev)) { + kvm_delete_shadow_device(&proxy->pci_dev); + } + #endif +-- +2.41.0.windows.1 + diff --git a/iotests-244-Don-t-store-data-file-with-protocol-in-i.patch b/iotests-244-Don-t-store-data-file-with-protocol-in-i.patch new file mode 100644 index 00000000..787d8105 --- /dev/null +++ b/iotests-244-Don-t-store-data-file-with-protocol-in-i.patch @@ -0,0 +1,52 @@ +From e3feddf508a6c118e321b3a1c761068772487225 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 25 Apr 2024 14:49:40 +0200 +Subject: [PATCH] iotests/244: Don't store data-file with protocol in image + (CVE-2024-4467) + +We want to disable filename parsing for data files because it's too easy +to abuse in malicious image files. Make the test ready for the change by +passing the data file explicitly in command line options. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Hanna Czenczek +--- + tests/qemu-iotests/244 | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244 +index 3e61fa25bb..bb9cc6512f 100755 +--- a/tests/qemu-iotests/244 ++++ b/tests/qemu-iotests/244 +@@ -215,9 +215,22 @@ $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG" + $QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG" + + # blkdebug doesn't support copy offloading, so this tests the error path +-$QEMU_IMG amend -f $IMGFMT -o "data_file=blkdebug::$TEST_IMG.data" "$TEST_IMG" +-$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG" +-$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG" ++test_img_with_blkdebug="json:{ ++ 'driver': 'qcow2', ++ 'file': { ++ 'driver': 'file', ++ 'filename': '$TEST_IMG' ++ }, ++ 'data-file': { ++ 'driver': 'blkdebug', ++ 'image': { ++ 'driver': 'file', ++ 'filename': '$TEST_IMG.data' ++ } ++ } ++}" ++$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$test_img_with_blkdebug" ++$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$test_img_with_blkdebug" + + echo + echo "=== Flushing should flush the data file ===" +-- +2.41.0.windows.1 + diff --git a/iotests-270-Don-t-store-data-file-with-json-prefix-i.patch b/iotests-270-Don-t-store-data-file-with-json-prefix-i.patch new file mode 100644 index 00000000..0a50f70a --- /dev/null +++ b/iotests-270-Don-t-store-data-file-with-json-prefix-i.patch @@ -0,0 +1,54 @@ +From 7ee281f59878c1f7a95e0a2a3f674c252d0c9f92 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 25 Apr 2024 14:49:40 +0200 +Subject: [PATCH] iotests/270: Don't store data-file with json: prefix in image + (CVE-2024-4467) + +We want to disable filename parsing for data files because it's too easy +to abuse in malicious image files. Make the test ready for the change by +passing the data file explicitly in command line options. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Hanna Czenczek +--- + tests/qemu-iotests/270 | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/tests/qemu-iotests/270 b/tests/qemu-iotests/270 +index 74352342db..c37b674aa2 100755 +--- a/tests/qemu-iotests/270 ++++ b/tests/qemu-iotests/270 +@@ -60,8 +60,16 @@ _make_test_img -o cluster_size=2M,data_file="$TEST_IMG.orig" \ + # "write" 2G of data without using any space. + # (qemu-img create does not like it, though, because null-co does not + # support image creation.) +-$QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \ +- "$TEST_IMG" ++test_img_with_null_data="json:{ ++ 'driver': '$IMGFMT', ++ 'file': { ++ 'filename': '$TEST_IMG' ++ }, ++ 'data-file': { ++ 'driver': 'null-co', ++ 'size':'4294967296' ++ } ++}" + + # This gives us a range of: + # 2^31 - 512 + 768 - 1 = 2^31 + 255 > 2^31 +@@ -74,7 +82,7 @@ $QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \ + # on L2 boundaries, we need large L2 tables; hence the cluster size of + # 2 MB. (Anything from 256 kB should work, though, because then one L2 + # table covers 8 GB.) +-$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$TEST_IMG" | _filter_qemu_io ++$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$test_img_with_null_data" | _filter_qemu_io + + _check_test_img + +-- +2.41.0.windows.1 + diff --git a/qcow2-Do-not-reopen-data_file-in-invalidate_cache.patch b/qcow2-Do-not-reopen-data_file-in-invalidate_cache.patch new file mode 100644 index 00000000..141702f7 --- /dev/null +++ b/qcow2-Do-not-reopen-data_file-in-invalidate_cache.patch @@ -0,0 +1,221 @@ +From d21b395997737618116926cb2680e85d79e14d19 Mon Sep 17 00:00:00 2001 +From: Hanna Reitz +Date: Wed, 27 Apr 2022 13:40:55 +0200 +Subject: [PATCH] qcow2: Do not reopen data_file in invalidate_cache + +qcow2_co_invalidate_cache() closes and opens the qcow2 file, by calling +qcow2_close() and qcow2_do_open(). These two functions must thus be +usable from both a global-state and an I/O context. + +As they are, they are not safe to call in an I/O context, because they +use bdrv_unref_child() and bdrv_open_child() to close/open the data_file +child, respectively, both of which are global-state functions. When +used from qcow2_co_invalidate_cache(), we do not need to close/open the +data_file child, though (we do not do this for bs->file or bs->backing +either), and so we should skip it in the qcow2_co_invalidate_cache() +path. + +To do so, add a parameter to qcow2_do_open() and qcow2_close() to make +them skip handling s->data_file, and have qcow2_co_invalidate_cache() +exempt it from the memset() on the BDRVQcow2State. + +(Note that the QED driver similarly closes/opens the QED image by +invoking bdrv_qed_close()+bdrv_qed_do_open(), but both functions seem +safe to use in an I/O context.) + +Fixes: https://gitlab.com/qemu-project/qemu/-/issues/945 +Signed-off-by: Hanna Reitz +Message-Id: <20220427114057.36651-3-hreitz@redhat.com> +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +--- + block/qcow2.c | 104 ++++++++++++++++++++++++++++++-------------------- + 1 file changed, 62 insertions(+), 42 deletions(-) + +diff --git a/block/qcow2.c b/block/qcow2.c +index be90a898e3..4a6b0a3ea9 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -1296,7 +1296,8 @@ static int validate_compression_type(BDRVQcow2State *s, Error **errp) + + /* Called with s->lock held. */ + static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, +- int flags, Error **errp) ++ int flags, bool open_data_file, ++ Error **errp) + { + ERRP_GUARD(); + BDRVQcow2State *s = bs->opaque; +@@ -1614,50 +1615,52 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, + goto fail; + } + +- /* Open external data file */ +- s->data_file = bdrv_open_child(NULL, options, "data-file", bs, +- &child_of_bds, BDRV_CHILD_DATA, +- true, errp); +- if (*errp) { +- ret = -EINVAL; +- goto fail; +- } ++ if (open_data_file) { ++ /* Open external data file */ ++ s->data_file = bdrv_open_child(NULL, options, "data-file", bs, ++ &child_of_bds, BDRV_CHILD_DATA, ++ true, errp); ++ if (*errp) { ++ ret = -EINVAL; ++ goto fail; ++ } + +- if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) { +- if (!s->data_file && s->image_data_file) { +- s->data_file = bdrv_open_child(s->image_data_file, options, +- "data-file", bs, &child_of_bds, +- BDRV_CHILD_DATA, false, errp); ++ if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) { ++ if (!s->data_file && s->image_data_file) { ++ s->data_file = bdrv_open_child(s->image_data_file, options, ++ "data-file", bs, &child_of_bds, ++ BDRV_CHILD_DATA, false, errp); ++ if (!s->data_file) { ++ ret = -EINVAL; ++ goto fail; ++ } ++ } + if (!s->data_file) { ++ error_setg(errp, "'data-file' is required for this image"); + ret = -EINVAL; + goto fail; + } +- } +- if (!s->data_file) { +- error_setg(errp, "'data-file' is required for this image"); +- ret = -EINVAL; +- goto fail; +- } + +- /* No data here */ +- bs->file->role &= ~BDRV_CHILD_DATA; ++ /* No data here */ ++ bs->file->role &= ~BDRV_CHILD_DATA; + +- /* Must succeed because we have given up permissions if anything */ +- bdrv_child_refresh_perms(bs, bs->file, &error_abort); +- } else { +- if (s->data_file) { +- error_setg(errp, "'data-file' can only be set for images with an " +- "external data file"); +- ret = -EINVAL; +- goto fail; +- } ++ /* Must succeed because we have given up permissions if anything */ ++ bdrv_child_refresh_perms(bs, bs->file, &error_abort); ++ } else { ++ if (s->data_file) { ++ error_setg(errp, "'data-file' can only be set for images with " ++ "an external data file"); ++ ret = -EINVAL; ++ goto fail; ++ } + +- s->data_file = bs->file; ++ s->data_file = bs->file; + +- if (data_file_is_raw(bs)) { +- error_setg(errp, "data-file-raw requires a data file"); +- ret = -EINVAL; +- goto fail; ++ if (data_file_is_raw(bs)) { ++ error_setg(errp, "data-file-raw requires a data file"); ++ ret = -EINVAL; ++ goto fail; ++ } + } + } + +@@ -1839,7 +1842,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, + + fail: + g_free(s->image_data_file); +- if (has_data_file(bs)) { ++ if (open_data_file && has_data_file(bs)) { + bdrv_unref_child(bs, s->data_file); + s->data_file = NULL; + } +@@ -1876,7 +1879,8 @@ static void coroutine_fn qcow2_open_entry(void *opaque) + BDRVQcow2State *s = qoc->bs->opaque; + + qemu_co_mutex_lock(&s->lock); +- qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, qoc->errp); ++ qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, true, ++ qoc->errp); + qemu_co_mutex_unlock(&s->lock); + } + +@@ -2714,7 +2718,7 @@ static int qcow2_inactivate(BlockDriverState *bs) + return result; + } + +-static void qcow2_close(BlockDriverState *bs) ++static void qcow2_do_close(BlockDriverState *bs, bool close_data_file) + { + BDRVQcow2State *s = bs->opaque; + qemu_vfree(s->l1_table); +@@ -2740,7 +2744,7 @@ static void qcow2_close(BlockDriverState *bs) + g_free(s->image_backing_file); + g_free(s->image_backing_format); + +- if (has_data_file(bs)) { ++ if (close_data_file && has_data_file(bs)) { + bdrv_unref_child(bs, s->data_file); + s->data_file = NULL; + } +@@ -2749,11 +2753,17 @@ static void qcow2_close(BlockDriverState *bs) + qcow2_free_snapshots(bs); + } + ++static void qcow2_close(BlockDriverState *bs) ++{ ++ qcow2_do_close(bs, true); ++} ++ + static void coroutine_fn qcow2_co_invalidate_cache(BlockDriverState *bs, + Error **errp) + { + ERRP_GUARD(); + BDRVQcow2State *s = bs->opaque; ++ BdrvChild *data_file; + int flags = s->flags; + QCryptoBlock *crypto = NULL; + QDict *options; +@@ -2767,14 +2777,24 @@ static void coroutine_fn qcow2_co_invalidate_cache(BlockDriverState *bs, + crypto = s->crypto; + s->crypto = NULL; + +- qcow2_close(bs); ++ /* ++ * Do not reopen s->data_file (i.e., have qcow2_do_close() not close it, ++ * and then prevent qcow2_do_open() from opening it), because this function ++ * runs in the I/O path and as such we must not invoke global-state ++ * functions like bdrv_unref_child() and bdrv_open_child(). ++ */ + ++ qcow2_do_close(bs, false); ++ ++ data_file = s->data_file; + memset(s, 0, sizeof(BDRVQcow2State)); ++ s->data_file = data_file; ++ + options = qdict_clone_shallow(bs->options); + + flags &= ~BDRV_O_INACTIVE; + qemu_co_mutex_lock(&s->lock); +- ret = qcow2_do_open(bs, options, flags, errp); ++ ret = qcow2_do_open(bs, options, flags, false, errp); + qemu_co_mutex_unlock(&s->lock); + qobject_unref(options); + if (ret < 0) { +-- +2.41.0.windows.1 + diff --git a/qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO-CVE-202.patch b/qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO-CVE-202.patch new file mode 100644 index 00000000..a705165c --- /dev/null +++ b/qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO-CVE-202.patch @@ -0,0 +1,108 @@ +From 6dc46edd6ebe051b181e04aa6929d46b8cbc70ba Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 11 Apr 2024 15:06:01 +0200 +Subject: [PATCH] qcow2: Don't open data_file with BDRV_O_NO_IO (CVE-2024-4467) + +One use case for 'qemu-img info' is verifying that untrusted images +don't reference an unwanted external file, be it as a backing file or an +external data file. To make sure that calling 'qemu-img info' can't +already have undesired side effects with a malicious image, just don't +open the data file at all with BDRV_O_NO_IO. If nothing ever tries to do +I/O, we don't need to have it open. + +This changes the output of iotests case 061, which used 'qemu-img info' +to show that opening an image with an invalid data file fails. After +this patch, it succeeds. Replace this part of the test with a qemu-io +call, but keep the final 'qemu-img info' to show that the invalid data +file is correctly displayed in the output. + +Fixes: CVE-2024-4467 +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Hanna Czenczek +--- + block/qcow2.c | 17 ++++++++++++++++- + tests/qemu-iotests/061 | 6 ++++-- + tests/qemu-iotests/061.out | 8 ++++++-- + 3 files changed, 26 insertions(+), 5 deletions(-) + +diff --git a/block/qcow2.c b/block/qcow2.c +index 4a6b0a3ea9..af1e94f2e2 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -1615,7 +1615,22 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, + goto fail; + } + +- if (open_data_file) { ++ if (open_data_file && (flags & BDRV_O_NO_IO)) { ++ /* ++ * Don't open the data file for 'qemu-img info' so that it can be used ++ * to verify that an untrusted qcow2 image doesn't refer to external ++ * files. ++ * ++ * Note: This still makes has_data_file() return true. ++ */ ++ if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) { ++ s->data_file = NULL; ++ } else { ++ s->data_file = bs->file; ++ } ++ qdict_extract_subqdict(options, NULL, "data-file."); ++ qdict_del(options, "data-file"); ++ } else if (open_data_file) { + /* Open external data file */ + s->data_file = bdrv_open_child(NULL, options, "data-file", bs, + &child_of_bds, BDRV_CHILD_DATA, +diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061 +index 9507c223bd..6a5bd47efc 100755 +--- a/tests/qemu-iotests/061 ++++ b/tests/qemu-iotests/061 +@@ -322,12 +322,14 @@ $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG" + echo + _make_test_img -o "compat=1.1,data_file=$TEST_IMG.data" 64M + $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG" +-_img_info --format-specific ++$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt ++$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io + TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts + + echo + $QEMU_IMG amend -o "data_file=" --image-opts "data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" +-_img_info --format-specific ++$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt ++$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io + TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts + + echo +diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out +index 7ecbd4dea8..99b2307a23 100644 +--- a/tests/qemu-iotests/061.out ++++ b/tests/qemu-iotests/061.out +@@ -545,7 +545,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 + qemu-img: data-file can only be set for images that use an external data file + + Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data +-qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory ++qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open 'foo': No such file or directory ++read 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + image: TEST_DIR/t.IMGFMT + file format: IMGFMT + virtual size: 64 MiB (67108864 bytes) +@@ -560,7 +562,9 @@ Format specific information: + corrupt: false + extended l2: false + +-qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image ++qemu-io: can't open device TEST_DIR/t.IMGFMT: 'data-file' is required for this image ++read 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + image: TEST_DIR/t.IMGFMT + file format: IMGFMT + virtual size: 64 MiB (67108864 bytes) +-- +2.41.0.windows.1 + diff --git a/qemu.spec b/qemu.spec index 2aae97a5..b17d58af 100644 --- a/qemu.spec +++ b/qemu.spec @@ -3,7 +3,7 @@ Name: qemu Version: 6.2.0 -Release: 95 +Release: 96 Epoch: 10 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -970,6 +970,18 @@ Patch0955: tests-qtest-ahci-test-add-test-exposing-reset-issue-.patch Patch0956: cvm-bug-fix-for-macro-isolation.patch Patch0957: hw-arm-virt-Disable-DTB-randomness-for-confidential-.patch Patch0958: cvm-bug-fix-for-disable-DTB-randomness-for-confident.patch +Patch0959: hw-virtio-virtio-pci-Support-shadow-device-for-virti.patch +Patch0960: vdpa-fix-vdpa-device-migrate-rollback-wrong-when-sus.patch +Patch0961: target-ppc-Split-off-common-embedded-TLB-init.patch +Patch0962: vhost-user-Skip-unnecessary-duplicated-VHOST_USER_SE.patch +Patch0963: hw-intc-arm_gic-Fix-deactivation-of-SPI-lines.patch +Patch0964: qcow2-Do-not-reopen-data_file-in-invalidate_cache.patch +Patch0965: qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO-CVE-202.patch +Patch0966: iotests-244-Don-t-store-data-file-with-protocol-in-i.patch +Patch0967: iotests-270-Don-t-store-data-file-with-json-prefix-i.patch +Patch0968: block-introduce-bdrv_open_file_child-helper.patch +Patch0969: block-Parse-filenames-only-when-explicitly-requested.patch +Patch0970: vdpa-Fix-bug-where-vdpa-appliance-migration-does-not.patch BuildRequires: flex BuildRequires: gcc @@ -1568,6 +1580,20 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Thu Jul 11 2024 - 10:6.2.0-96 +- vdpa: Fix bug where vdpa appliance migration does not resume after rollback +- block: Parse filenames only when explicitly requested (CVE-2024-4467) +- block: introduce bdrv_open_file_child() helper +- iotests/270: Don't store data-file with json: prefix in image (CVE-2024-4467) +- iotests/244: Don't store data-file with protocol in image (CVE-2024-4467) +- qcow2: Don't open data_file with BDRV_O_NO_IO (CVE-2024-4467) +- qcow2: Do not reopen data_file in invalidate_cache +- hw/intc/arm_gic: Fix deactivation of SPI lines chery-pick from 7175a562f157d39725ab396e39c1e8e410d206b3 +- vhost-user: Skip unnecessary duplicated VHOST_USER_SET_LOG_BASE requests +- target/ppc: Split off common embedded TLB init cheery-pick from 581eea5d656b73c6532109f4ced4c73fd4e5fd47` +- vdpa: fix vdpa device migrate rollback wrong when suspend device failed 1. +- hw/virtio/virtio-pci:Support shadow device for virtio-net/blk/scsi devices + * Fri Jun 21 2024 - 10:6.2.0-95 - cvm: bug-fix for disable DTB randomness for confidential VMs diff --git a/target-ppc-Split-off-common-embedded-TLB-init.patch b/target-ppc-Split-off-common-embedded-TLB-init.patch new file mode 100644 index 00000000..ecccae5d --- /dev/null +++ b/target-ppc-Split-off-common-embedded-TLB-init.patch @@ -0,0 +1,118 @@ +From 9f45d0ded0694739898e2fbbb6fa08891a7de280 Mon Sep 17 00:00:00 2001 +From: dinglimin +Date: Mon, 10 Jun 2024 15:52:59 +0800 +Subject: [PATCH] target/ppc: Split off common embedded TLB init cheery-pick + from 581eea5d656b73c6532109f4ced4c73fd4e5fd47` + +Several 4xx CPUs and e200 share the same TLB settings enclosed in an +ifdef. Split it off in a common function to reduce code duplication +and the number of ifdefs. + +Reviewed-by: Nicholas Piggin +Signed-off-by: BALATON Zoltan +Signed-off-by: Nicholas Piggin + +Signed-off-by: dinglimin +--- + target/ppc/cpu_init.c | 50 +++++++++++++------------------------------ + 1 file changed, 15 insertions(+), 35 deletions(-) + +diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c +index 986d16a24d..d0dfa1aeaf 100644 +--- a/target/ppc/cpu_init.c ++++ b/target/ppc/cpu_init.c +@@ -3018,7 +3018,15 @@ POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data) + pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX | + POWERPC_FLAG_BUS_CLK; + } +- ++static void init_tlbs_emb(CPUPPCState *env) ++{ ++#if !defined(CONFIG_USER_ONLY) ++ env->nb_tlb = 64; ++ env->nb_ways = 1; ++ env->id_tlbs = 0; ++ env->tlb_type = TLB_EMB; ++#endif ++} + static void init_proc_405(CPUPPCState *env) + { + /* Time base */ +@@ -3036,13 +3044,7 @@ static void init_proc_405(CPUPPCState *env) + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +- /* Memory management */ +-#if !defined(CONFIG_USER_ONLY) +- env->nb_tlb = 64; +- env->nb_ways = 1; +- env->id_tlbs = 0; +- env->tlb_type = TLB_EMB; +-#endif ++ init_tlbs_emb(env); + init_excp_4xx_softmmu(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; +@@ -3135,13 +3137,7 @@ static void init_proc_440EP(CPUPPCState *env) + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +- /* Memory management */ +-#if !defined(CONFIG_USER_ONLY) +- env->nb_tlb = 64; +- env->nb_ways = 1; +- env->id_tlbs = 0; +- env->tlb_type = TLB_EMB; +-#endif ++ init_tlbs_emb(env); + init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; +@@ -3259,13 +3255,7 @@ static void init_proc_440GP(CPUPPCState *env) + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +- /* Memory management */ +-#if !defined(CONFIG_USER_ONLY) +- env->nb_tlb = 64; +- env->nb_ways = 1; +- env->id_tlbs = 0; +- env->tlb_type = TLB_EMB; +-#endif ++ init_tlbs_emb(env); + init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; +@@ -3443,13 +3433,7 @@ static void init_proc_440x5(CPUPPCState *env) + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +- /* Memory management */ +-#if !defined(CONFIG_USER_ONLY) +- env->nb_tlb = 64; +- env->nb_ways = 1; +- env->id_tlbs = 0; +- env->tlb_type = TLB_EMB; +-#endif ++ init_tlbs_emb(env); + init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; +@@ -3877,12 +3861,8 @@ static void init_proc_e200(CPUPPCState *env) + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +-#if !defined(CONFIG_USER_ONLY) +- env->nb_tlb = 64; +- env->nb_ways = 1; +- env->id_tlbs = 0; +- env->tlb_type = TLB_EMB; +-#endif ++ ++ init_tlbs_emb(env); + init_excp_e200(env, 0xFFFF0000UL); + env->dcache_line_size = 32; + env->icache_line_size = 32; +-- +2.41.0.windows.1 + diff --git a/vdpa-Fix-bug-where-vdpa-appliance-migration-does-not.patch b/vdpa-Fix-bug-where-vdpa-appliance-migration-does-not.patch new file mode 100644 index 00000000..b08bcaeb --- /dev/null +++ b/vdpa-Fix-bug-where-vdpa-appliance-migration-does-not.patch @@ -0,0 +1,38 @@ +From 2713ad857506ce338472e19706fbbab4ee4ba662 Mon Sep 17 00:00:00 2001 +From: Adttil <2429917001@qq.com> +Date: Mon, 8 Jul 2024 14:45:18 +0800 +Subject: [PATCH] vdpa: Fix bug where vdpa appliance migration does not resume + after rollback + +using vdpa->started to judge device started instead of vdev->vhost_started + +Signed-off-by: Adttil <2429917001@qq.com> +--- + hw/virtio/vdpa-dev-mig.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c +index 23238c9f19..c080f9d89b 100644 +--- a/hw/virtio/vdpa-dev-mig.c ++++ b/hw/virtio/vdpa-dev-mig.c +@@ -137,7 +137,7 @@ static int vhost_vdpa_device_suspend(VhostVdpaDevice *vdpa) + { + VirtIODevice *vdev = VIRTIO_DEVICE(vdpa); + +- if (!vdev->vhost_started || vdpa->suspended) { ++ if (!vdpa->started || vdpa->suspended) { + return 0; + } + +@@ -152,7 +152,7 @@ static int vhost_vdpa_device_resume(VhostVdpaDevice *vdpa) + MigrationIncomingState *mis = migration_incoming_get_current(); + int ret; + +- if (!vdev->vhost_started || ++ if (!vdpa->started || + (!vdpa->suspended && mis->state != RUN_STATE_RESTORE_VM)) { + return 0; + } +-- +2.41.0.windows.1 + diff --git a/vdpa-fix-vdpa-device-migrate-rollback-wrong-when-sus.patch b/vdpa-fix-vdpa-device-migrate-rollback-wrong-when-sus.patch new file mode 100644 index 00000000..9ebffdfc --- /dev/null +++ b/vdpa-fix-vdpa-device-migrate-rollback-wrong-when-sus.patch @@ -0,0 +1,140 @@ +From 493ef78aebf2aac04e9dbf5d1f21eb0c18763917 Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Sat, 22 Jun 2024 07:02:48 +0000 +Subject: [PATCH] vdpa: fix vdpa device migrate rollback wrong when suspend + device failed 1. set vdpa->suspended before call vhost_dev_suspend to make + sure vdpa device will resume when suspend failed. 2. using + vdpa->vhost_started to judge device started instead of vdev->started 3. using + state == RUN_STATE_FINISH_MIGRATE instead of ms->state == + MIGRATION_STATUS_ACTIVE to judge vm in migration. As migrate_fd_cancel will + change ms->state, which will result in some vdpa devices not being suspended. + +Signed-off-by: jiangdongxu +--- + hw/virtio/vdpa-dev-mig.c | 83 ++++------------------------------------ + 1 file changed, 8 insertions(+), 75 deletions(-) + +diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c +index 679d37b182..23238c9f19 100644 +--- a/hw/virtio/vdpa-dev-mig.c ++++ b/hw/virtio/vdpa-dev-mig.c +@@ -136,100 +136,33 @@ free: + static int vhost_vdpa_device_suspend(VhostVdpaDevice *vdpa) + { + VirtIODevice *vdev = VIRTIO_DEVICE(vdpa); +- BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); +- VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); +- int ret; + +- if (!vdpa->started || vdpa->suspended) { ++ if (!vdev->vhost_started || vdpa->suspended) { + return 0; + } + +- if (!k->set_guest_notifiers) { +- return -EFAULT; +- } +- +- vdpa->started = false; + vdpa->suspended = true; + +- ret = vhost_dev_suspend(&vdpa->dev, vdev, false); +- if (ret) { +- goto suspend_fail; +- } +- +- ret = k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, false); +- if (ret < 0) { +- error_report("vhost guest notifier cleanup failed: %d\n", ret); +- goto set_guest_notifiers_fail; +- } +- +- vhost_dev_disable_notifiers(&vdpa->dev, vdev); +- return ret; +- +-set_guest_notifiers_fail: +- ret = k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, true); +- if (ret) { +- error_report("vhost guest notifier restore failed: %d\n", ret); +- } +- +-suspend_fail: +- vdpa->suspended = false; +- vdpa->started = true; +- return ret; ++ return vhost_dev_suspend(&vdpa->dev, vdev, false); + } + + static int vhost_vdpa_device_resume(VhostVdpaDevice *vdpa) + { + VirtIODevice *vdev = VIRTIO_DEVICE(vdpa); +- BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); +- VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); +- int i, ret; ++ MigrationIncomingState *mis = migration_incoming_get_current(); ++ int ret; + +- if (vdpa->started || !vdpa->suspended) { ++ if (!vdev->vhost_started || ++ (!vdpa->suspended && mis->state != RUN_STATE_RESTORE_VM)) { + return 0; + } + +- if (!k->set_guest_notifiers) { +- error_report("binding does not support guest notifiers\n"); +- return -ENOSYS; +- } +- +- ret = vhost_dev_enable_notifiers(&vdpa->dev, vdev); ++ ret = vhost_dev_resume(&vdpa->dev, vdev, false); + if (ret < 0) { +- error_report("Error enabling host notifiers: %d\n", ret); + return ret; + } + +- ret = k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, true); +- if (ret < 0) { +- error_report("Error binding guest notifier: %d\n", ret); +- goto err_host_notifiers; +- } +- +- vdpa->dev.acked_features = vdev->guest_features; +- +- ret = vhost_dev_resume(&vdpa->dev, vdev, false); +- if (ret < 0) { +- error_report("Error starting vhost: %d\n", ret); +- goto err_guest_notifiers; +- } +- vdpa->started = true; + vdpa->suspended = false; +- +- /* +- * guest_notifier_mask/pending not used yet, so just unmask +- * everything here. virtio-pci will do the right thing by +- * enabling/disabling irqfd. +- */ +- for (i = 0; i < vdpa->dev.nvqs; i++) { +- vhost_virtqueue_mask(&vdpa->dev, vdev, i, false); +- } +- +- return ret; +- +-err_guest_notifiers: +- k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, false); +-err_host_notifiers: +- vhost_dev_disable_notifiers(&vdpa->dev, vdev); + return ret; + } + +@@ -254,7 +187,7 @@ static void vdpa_dev_vmstate_change(void *opaque, bool running, RunState state) + MigrationIncomingState *mis = migration_incoming_get_current(); + + if (!running) { +- if (ms->state == MIGRATION_STATUS_ACTIVE || state == RUN_STATE_PAUSED) { ++ if (state == RUN_STATE_FINISH_MIGRATE || state == RUN_STATE_PAUSED) { + ret = vhost_vdpa_device_suspend(vdpa); + if (ret) { + error_report("suspend vdpa device failed: %d\n", ret); +-- +2.41.0.windows.1 + diff --git a/vhost-user-Skip-unnecessary-duplicated-VHOST_USER_SE.patch b/vhost-user-Skip-unnecessary-duplicated-VHOST_USER_SE.patch new file mode 100644 index 00000000..1b754bfe --- /dev/null +++ b/vhost-user-Skip-unnecessary-duplicated-VHOST_USER_SE.patch @@ -0,0 +1,31 @@ +From 24e57d8013b2d039ed917676b7fb34d3736c9d8d Mon Sep 17 00:00:00 2001 +From: BillXiang <1373760142@qq.com> +Date: Wed, 19 Jun 2024 09:24:05 +0800 +Subject: [PATCH] vhost-user: Skip unnecessary duplicated + VHOST_USER_SET_LOG_BASE requests + +The VHOST_USER_SET_LOG_BASE requests should be categorized into +non-vring specific messages, and should be sent only once. +If send more than once, dpdk will munmap old log_addr which may has been used +and cause segmentation fault. + +Signed-off-by: BillXiang <1373760142@qq.com> +--- + hw/virtio/vhost-user.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c +index 937b3021e9..c97ea2544d 100644 +--- a/hw/virtio/vhost-user.c ++++ b/hw/virtio/vhost-user.c +@@ -456,6 +456,7 @@ static bool vhost_user_one_time_request(VhostUserRequest request) + case VHOST_USER_SET_MEM_TABLE: + case VHOST_USER_GET_QUEUE_NUM: + case VHOST_USER_NET_SET_MTU: ++ case VHOST_USER_SET_LOG_BASE: + return true; + default: + return false; +-- +2.41.0.windows.1 + -- Gitee