diff --git a/Revert-file-posix-Remove-unused-s-discard_zeroes.patch b/Revert-file-posix-Remove-unused-s-discard_zeroes.patch new file mode 100644 index 0000000000000000000000000000000000000000..bad52a205a9db5a1555133fd6e81a3c67841105f --- /dev/null +++ b/Revert-file-posix-Remove-unused-s-discard_zeroes.patch @@ -0,0 +1,53 @@ +From db37bc0d85e141a666dd287cdc562a47f29b4343 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Mon, 18 Mar 2024 10:01:28 +0800 +Subject: [PATCH] Revert "file-posix: Remove unused s->discard_zeroes" + +This reverts commit a7ca2eb488ff149c898f43abe103f8bd8e3ca3c4. +--- + block/file-posix.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/block/file-posix.c b/block/file-posix.c +index b862406c71..01ae5fd88c 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -158,6 +158,7 @@ typedef struct BDRVRawState { + + bool has_discard:1; + bool has_write_zeroes:1; ++ bool discard_zeroes:1; + bool use_linux_aio:1; + bool use_linux_io_uring:1; + int page_cache_inconsistent; /* errno from fdatasync failure */ +@@ -765,6 +766,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, + ret = -EINVAL; + goto fail; + } else { ++ s->discard_zeroes = true; + s->has_fallocate = true; + } + } else { +@@ -790,12 +792,19 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, + #endif + + if (S_ISBLK(st.st_mode)) { ++#ifdef BLKDISCARDZEROES ++ unsigned int arg; ++ if (ioctl(s->fd, BLKDISCARDZEROES, &arg) == 0 && arg) { ++ s->discard_zeroes = true; ++ } ++#endif + #ifdef __linux__ + /* On Linux 3.10, BLKDISCARD leaves stale data in the page cache. Do + * not rely on the contents of discarded blocks unless using O_DIRECT. + * Same for BLKZEROOUT. + */ + if (!(bs->open_flags & BDRV_O_NOCACHE)) { ++ s->discard_zeroes = false; + s->has_write_zeroes = false; + } + #endif +-- +2.27.0 + diff --git a/blkio-Respect-memory-alignment-for-bounce-buffer-all.patch b/blkio-Respect-memory-alignment-for-bounce-buffer-all.patch new file mode 100644 index 0000000000000000000000000000000000000000..3acc7ea338d5f9b2baa6298881417ec07f2cfcec --- /dev/null +++ b/blkio-Respect-memory-alignment-for-bounce-buffer-all.patch @@ -0,0 +1,47 @@ +From c93d512dddb00e3eed2ce9484c55f5f1fbb54c8b Mon Sep 17 00:00:00 2001 +From: dinglimin +Date: Tue, 27 Feb 2024 19:02:52 +0800 +Subject: [PATCH] blkio: Respect memory-alignment for bounce buffer allocations + +cheery-pick from 10b2393e5e7f4c1d633f1ac8578465681c333efb + +blkio_alloc_mem_region() requires that the requested buffer size is a +multiple of the memory-alignment property. If it isn't, the allocation +fails with a return value of -EINVAL. + +Fix the call in blkio_resize_bounce_pool() to make sure the requested +size is properly aligned. + +I observed this problem with vhost-vdpa, which requires page aligned +memory. As the virtio-blk device behind it still had 512 byte blocks, we +got bs->bl.request_alignment = 512, but actually any request that needed +a bounce buffer and was not aligned to 4k would fail without this fix. + +Suggested-by: Stefano Garzarella +Signed-off-by: Kevin Wolf +Message-ID: <20240131173140.42398-1-kwolf@redhat.com> +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Stefano Garzarella +Signed-off-by: Kevin Wolf +Signed-off-by: dinglimin +--- + block/blkio.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/block/blkio.c b/block/blkio.c +index 0a0a6c0f5f..b989617608 100644 +--- a/block/blkio.c ++++ b/block/blkio.c +@@ -89,6 +89,9 @@ static int blkio_resize_bounce_pool(BDRVBlkioState *s, int64_t bytes) + /* Pad size to reduce frequency of resize calls */ + bytes += 128 * 1024; + ++ /* Align the pool size to avoid blkio_alloc_mem_region() failure */ ++ bytes = QEMU_ALIGN_UP(bytes, s->mem_region_alignment); ++ + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + int ret; + +-- +2.27.0 + diff --git a/block-Add-error-retry-param-setting.patch b/block-Add-error-retry-param-setting.patch new file mode 100644 index 0000000000000000000000000000000000000000..6399cd5072dc92a60ba03eacafd83500c7b7efe8 --- /dev/null +++ b/block-Add-error-retry-param-setting.patch @@ -0,0 +1,232 @@ +From d777d1585603aa7599ae8bac4492fafdf1e4b109 Mon Sep 17 00:00:00 2001 +From: yexiao +Date: Thu, 21 Jan 2021 15:46:50 +0800 +Subject: [PATCH] block: Add error retry param setting + +Add "retry_interval" and "retry_timeout" parameter for drive and device +option. These parameter are valid only when werror/rerror=retry. + +eg. -device device_name,drive=drive_id,rerror=retry,retry_interval=1000,retry_timeout=5000 + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 13 ++++-- + blockdev.c | 50 +++++++++++++++++++++ + hw/block/block.c | 10 +++++ + include/hw/block/block.h | 7 ++- + include/sysemu/block-backend-common.h | 3 ++ + include/sysemu/block-backend-global-state.h | 2 + + 6 files changed, 81 insertions(+), 4 deletions(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 919699bb70..85d732de7e 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -33,9 +33,6 @@ + + #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ + +-/* block backend default retry interval */ +-#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 +- + typedef struct BlockBackendAioNotifier { + void (*attached_aio_context)(AioContext *new_context, void *opaque); + void (*detach_aio_context)(void *opaque); +@@ -2149,6 +2146,16 @@ void blk_drain_all(void) + bdrv_drain_all_end(); + } + ++void blk_set_on_error_retry_interval(BlockBackend *blk, int64_t interval) ++{ ++ blk->retry_interval = interval; ++} ++ ++void blk_set_on_error_retry_timeout(BlockBackend *blk, int64_t timeout) ++{ ++ blk->retry_timeout = timeout; ++} ++ + static bool blk_error_retry_timeout(BlockBackend *blk) + { + /* No timeout set, infinite retries. */ +diff --git a/blockdev.c b/blockdev.c +index 2817f73fad..6a229e77a5 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -484,6 +484,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + const char *buf; + int bdrv_flags = 0; + int on_read_error, on_write_error; ++ int64_t retry_interval, retry_timeout; + OnOffAuto account_invalid, account_failed; + bool writethrough, read_only; + BlockBackend *blk; +@@ -576,6 +577,10 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + } + } + ++ retry_interval = qemu_opt_get_number(opts, "retry_interval", ++ BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL); ++ retry_timeout = qemu_opt_get_number(opts, "retry_timeout", 0); ++ + if (snapshot) { + bdrv_flags |= BDRV_O_SNAPSHOT; + } +@@ -639,6 +644,11 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + + blk_set_enable_write_cache(blk, !writethrough); + blk_set_on_error(blk, on_read_error, on_write_error); ++ if (on_read_error == BLOCKDEV_ON_ERROR_RETRY || ++ on_write_error == BLOCKDEV_ON_ERROR_RETRY) { ++ blk_set_on_error_retry_interval(blk, retry_interval); ++ blk_set_on_error_retry_timeout(blk, retry_timeout); ++ } + + if (!monitor_add_blk(blk, id, errp)) { + blk_unref(blk); +@@ -773,6 +783,14 @@ QemuOptsList qemu_legacy_drive_opts = { + .name = "werror", + .type = QEMU_OPT_STRING, + .help = "write error action", ++ },{ ++ .name = "retry_interval", ++ .type = QEMU_OPT_NUMBER, ++ .help = "interval for retry action in millisecond", ++ },{ ++ .name = "retry_timeout", ++ .type = QEMU_OPT_NUMBER, ++ .help = "timeout for retry action in millisecond", + },{ + .name = "copy-on-read", + .type = QEMU_OPT_BOOL, +@@ -795,6 +813,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type, + BlockInterfaceType type; + int max_devs, bus_id, unit_id, index; + const char *werror, *rerror; ++ int64_t retry_interval, retry_timeout; + bool read_only = false; + bool copy_on_read; + const char *filename; +@@ -1013,6 +1032,29 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type, + qdict_put_str(bs_opts, "rerror", rerror); + } + ++ if (qemu_opt_find(legacy_opts, "retry_interval")) { ++ if ((werror == NULL || strcmp(werror, "retry")) && ++ (rerror == NULL || strcmp(rerror, "retry"))) { ++ error_setg(errp, "retry_interval is only supported " ++ "by werror/rerror=retry"); ++ goto fail; ++ } ++ retry_interval = qemu_opt_get_number(legacy_opts, "retry_interval", ++ BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL); ++ qdict_put_int(bs_opts, "retry_interval", retry_interval); ++ } ++ ++ if (qemu_opt_find(legacy_opts, "retry_timeout")) { ++ if ((werror == NULL || strcmp(werror, "retry")) && ++ (rerror == NULL || strcmp(rerror, "retry"))) { ++ error_setg(errp, "retry_timeout is only supported " ++ "by werror/rerror=retry"); ++ goto fail; ++ } ++ retry_timeout = qemu_opt_get_number(legacy_opts, "retry_timeout", 0); ++ qdict_put_int(bs_opts, "retry_timeout", retry_timeout); ++ } ++ + /* Actual block device init: Functionality shared with blockdev-add */ + blk = blockdev_init(filename, bs_opts, errp); + bs_opts = NULL; +@@ -3794,6 +3836,14 @@ QemuOptsList qemu_common_drive_opts = { + .name = "werror", + .type = QEMU_OPT_STRING, + .help = "write error action", ++ },{ ++ .name = "retry_interval", ++ .type = QEMU_OPT_NUMBER, ++ .help = "interval for retry action in millisecond", ++ },{ ++ .name = "retry_timeout", ++ .type = QEMU_OPT_NUMBER, ++ .help = "timeout for retry action in millisecond", + },{ + .name = BDRV_OPT_READ_ONLY, + .type = QEMU_OPT_BOOL, +diff --git a/hw/block/block.c b/hw/block/block.c +index 9f52ee6e72..6bece87709 100644 +--- a/hw/block/block.c ++++ b/hw/block/block.c +@@ -239,6 +239,16 @@ bool blkconf_apply_backend_options(BlockConf *conf, bool readonly, + blk_set_enable_write_cache(blk, wce); + blk_set_on_error(blk, rerror, werror); + ++ if (rerror == BLOCKDEV_ON_ERROR_RETRY || ++ werror == BLOCKDEV_ON_ERROR_RETRY) { ++ if (conf->retry_interval >= 0) { ++ blk_set_on_error_retry_interval(blk, conf->retry_interval); ++ } ++ if (conf->retry_timeout >= 0) { ++ blk_set_on_error_retry_timeout(blk, conf->retry_timeout); ++ } ++ } ++ + block_acct_setup(blk_get_stats(blk), conf->account_invalid, + conf->account_failed); + return true; +diff --git a/include/hw/block/block.h b/include/hw/block/block.h +index 15fff66435..fb8c0df4a5 100644 +--- a/include/hw/block/block.h ++++ b/include/hw/block/block.h +@@ -34,6 +34,8 @@ typedef struct BlockConf { + OnOffAuto account_invalid, account_failed; + BlockdevOnError rerror; + BlockdevOnError werror; ++ int64_t retry_interval; ++ int64_t retry_timeout; + } BlockConf; + + static inline unsigned int get_physical_block_exp(BlockConf *conf) +@@ -84,7 +86,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) + DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror, \ + BLOCKDEV_ON_ERROR_AUTO), \ + DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \ +- BLOCKDEV_ON_ERROR_AUTO) ++ BLOCKDEV_ON_ERROR_AUTO), \ ++ DEFINE_PROP_INT64("retry_interval", _state, _conf.retry_interval, \ ++ -1), \ ++ DEFINE_PROP_INT64("retry_timeout", _state, _conf.retry_timeout, -1) + + /* Backend access helpers */ + +diff --git a/include/sysemu/block-backend-common.h b/include/sysemu/block-backend-common.h +index b76df8834a..5a1cdac9c4 100644 +--- a/include/sysemu/block-backend-common.h ++++ b/include/sysemu/block-backend-common.h +@@ -16,6 +16,9 @@ + #include "qemu/iov.h" + #include "block/throttle-groups.h" + ++/* block backend default retry interval */ ++#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 ++ + /* + * TODO Have to include block/block.h for a bunch of block layer + * types. Unfortunately, this pulls in the whole BlockDriverState +diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h +index 7f59fd411d..d56592c22e 100644 +--- a/include/sysemu/block-backend-global-state.h ++++ b/include/sysemu/block-backend-global-state.h +@@ -84,6 +84,8 @@ int blk_commit_all(void); + bool blk_in_drain(BlockBackend *blk); + void blk_drain(BlockBackend *blk); + void blk_drain_all(void); ++void blk_set_on_error_retry_interval(BlockBackend *blk, int64_t interval); ++void blk_set_on_error_retry_timeout(BlockBackend *blk, int64_t timeout); + void blk_error_retry_reset_timeout(BlockBackend *blk); + void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, + BlockdevOnError on_write_error); +-- +2.27.0 + diff --git a/block-Add-sanity-check-when-setting-retry-parameters.patch b/block-Add-sanity-check-when-setting-retry-parameters.patch new file mode 100644 index 0000000000000000000000000000000000000000..27c253e367c4ff62202478dc4b5a3460e11f0ef3 --- /dev/null +++ b/block-Add-sanity-check-when-setting-retry-parameters.patch @@ -0,0 +1,156 @@ +From e880fc334edb8d07593679cf0c6a9af810c51d0d Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 18 Mar 2021 19:45:11 +0800 +Subject: [PATCH] block: Add sanity check when setting retry parameters + +Add sanity check when setting retry parameters to avoid invalid retry +configuration. + +Signed-off-by: Jiahui Cen +Signed-off-by: Alex Chen +--- + hw/core/qdev-prop-internal.h | 2 ++ + hw/core/qdev-properties-system.c | 45 +++++++++++++++++++++++++++++ + hw/core/qdev-properties.c | 4 +-- + include/hw/block/block.h | 7 +++-- + include/hw/qdev-properties-system.h | 8 +++++ + 5 files changed, 61 insertions(+), 5 deletions(-) + +diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h +index d7b77844fe..68b1b9d10c 100644 +--- a/hw/core/qdev-prop-internal.h ++++ b/hw/core/qdev-prop-internal.h +@@ -22,6 +22,8 @@ void qdev_propinfo_set_default_value_uint(ObjectProperty *op, + + void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp); ++void qdev_propinfo_get_int64(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp); + void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp); + +diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c +index 1473ab3d5e..f2e2718c74 100644 +--- a/hw/core/qdev-properties-system.c ++++ b/hw/core/qdev-properties-system.c +@@ -635,6 +635,51 @@ const PropertyInfo qdev_prop_blockdev_on_error = { + .set_default_value = qdev_propinfo_set_default_value_enum, + }; + ++static void set_retry_time(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ DeviceState *dev = DEVICE(obj); ++ Property *prop = opaque; ++ int64_t value, *ptr = object_field_prop_ptr(obj, prop); ++ Error *local_err = NULL; ++ ++ if (dev->realized) { ++ qdev_prop_set_after_realize(dev, name, errp); ++ return; ++ } ++ ++ visit_type_int64(v, name, &value, &local_err); ++ if (local_err) { ++ error_propagate(errp, local_err); ++ return; ++ } ++ ++ /* value should not be negative */ ++ if (value < 0) { ++ error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, ++ dev->id ? : "", name, (int64_t)value, 0L, LONG_MAX); ++ return; ++ } ++ ++ *ptr = value; ++} ++ ++const PropertyInfo qdev_prop_blockdev_retry_interval = { ++ .name = "BlockdevRetryInterval", ++ .description = "Interval for retry error handling policy", ++ .get = qdev_propinfo_get_int64, ++ .set = set_retry_time, ++ .set_default_value = qdev_propinfo_set_default_value_int, ++}; ++ ++const PropertyInfo qdev_prop_blockdev_retry_timeout = { ++ .name = "BlockdevRetryTimeout", ++ .description = "Timeout for retry error handling policy", ++ .get = qdev_propinfo_get_int64, ++ .set = set_retry_time, ++ .set_default_value = qdev_propinfo_set_default_value_int, ++}; ++ + /* --- BIOS CHS translation */ + + QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int)); +diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c +index 840006e953..19b7450b4d 100644 +--- a/hw/core/qdev-properties.c ++++ b/hw/core/qdev-properties.c +@@ -398,7 +398,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name, + visit_type_uint64(v, name, ptr, errp); + } + +-static void get_int64(Object *obj, Visitor *v, const char *name, ++void qdev_propinfo_get_int64(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) + { + Property *prop = opaque; +@@ -425,7 +425,7 @@ const PropertyInfo qdev_prop_uint64 = { + + const PropertyInfo qdev_prop_int64 = { + .name = "int64", +- .get = get_int64, ++ .get = qdev_propinfo_get_int64, + .set = set_int64, + .set_default_value = qdev_propinfo_set_default_value_int, + }; +diff --git a/include/hw/block/block.h b/include/hw/block/block.h +index fb8c0df4a5..844e87495a 100644 +--- a/include/hw/block/block.h ++++ b/include/hw/block/block.h +@@ -87,9 +87,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) + BLOCKDEV_ON_ERROR_AUTO), \ + DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \ + BLOCKDEV_ON_ERROR_AUTO), \ +- DEFINE_PROP_INT64("retry_interval", _state, _conf.retry_interval, \ +- -1), \ +- DEFINE_PROP_INT64("retry_timeout", _state, _conf.retry_timeout, -1) ++ DEFINE_PROP_BLOCKDEV_RETRY_INTERVAL("retry_interval", _state, \ ++ _conf.retry_interval, 1000), \ ++ DEFINE_PROP_BLOCKDEV_RETRY_TIMEOUT("retry_timeout", _state, \ ++ _conf.retry_timeout, 0) + + /* Backend access helpers */ + +diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h +index 91f7a2452d..7cf27e51b9 100644 +--- a/include/hw/qdev-properties-system.h ++++ b/include/hw/qdev-properties-system.h +@@ -10,6 +10,8 @@ extern const PropertyInfo qdev_prop_multifd_compression; + extern const PropertyInfo qdev_prop_mig_mode; + extern const PropertyInfo qdev_prop_losttickpolicy; + extern const PropertyInfo qdev_prop_blockdev_on_error; ++extern const PropertyInfo qdev_prop_blockdev_retry_interval; ++extern const PropertyInfo qdev_prop_blockdev_retry_timeout; + extern const PropertyInfo qdev_prop_bios_chs_trans; + extern const PropertyInfo qdev_prop_fdc_drive_type; + extern const PropertyInfo qdev_prop_drive; +@@ -52,6 +54,12 @@ extern const PropertyInfo qdev_prop_cpus390entitlement; + #define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \ + BlockdevOnError) ++#define DEFINE_PROP_BLOCKDEV_RETRY_INTERVAL(_n, _s, _f, _d) \ ++ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_retry_interval, \ ++ int64_t) ++#define DEFINE_PROP_BLOCKDEV_RETRY_TIMEOUT(_n, _s, _f, _d) \ ++ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_retry_timeout, \ ++ int64_t) + #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int) + #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \ +-- +2.27.0 + diff --git a/block-backend-Add-device-specific-retry-callback.patch b/block-backend-Add-device-specific-retry-callback.patch new file mode 100644 index 0000000000000000000000000000000000000000..c912ea20e8d1f2bcce46d2719232aff75456b9e4 --- /dev/null +++ b/block-backend-Add-device-specific-retry-callback.patch @@ -0,0 +1,54 @@ +From 94580294f0fda3c715caa19f4b33718212c9c531 Mon Sep 17 00:00:00 2001 +From: yexiao +Date: Thu, 21 Jan 2021 15:46:47 +0800 +Subject: [PATCH] block-backend: Add device specific retry callback + +Add retry_request_cb in BlockDevOps to do device specific retry action. +Backend's timer would be registered only when the backend is set 'retry' +on errors and the device supports retry action. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 8 ++++++++ + include/sysemu/block-backend-common.h | 4 ++++ + 2 files changed, 12 insertions(+) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 2f56cc8382..7e25d5a058 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -1123,6 +1123,14 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, + blk->dev_ops = ops; + blk->dev_opaque = opaque; + ++ if ((blk->on_read_error == BLOCKDEV_ON_ERROR_RETRY || ++ blk->on_write_error == BLOCKDEV_ON_ERROR_RETRY) && ++ ops->retry_request_cb) { ++ blk->retry_timer = aio_timer_new(blk->ctx, QEMU_CLOCK_REALTIME, ++ SCALE_MS, ops->retry_request_cb, ++ opaque); ++ } ++ + /* Are we currently quiesced? Should we enforce this right now? */ + if (qatomic_read(&blk->quiesce_counter) && ops && ops->drained_begin) { + ops->drained_begin(opaque); +diff --git a/include/sysemu/block-backend-common.h b/include/sysemu/block-backend-common.h +index 780cea7305..b76df8834a 100644 +--- a/include/sysemu/block-backend-common.h ++++ b/include/sysemu/block-backend-common.h +@@ -71,6 +71,10 @@ typedef struct BlockDevOps { + * Is the device still busy? + */ + bool (*drained_poll)(void *opaque); ++ /* ++ * Runs when retrying failed requests. ++ */ ++ void (*retry_request_cb)(void *opaque); + + /* + * I/O API functions. These functions are thread-safe. +-- +2.27.0 + diff --git a/block-backend-Add-timeout-support-for-retry.patch b/block-backend-Add-timeout-support-for-retry.patch new file mode 100644 index 0000000000000000000000000000000000000000..8a35cd27449e352d4d4edc0280ae3edee484b2c8 --- /dev/null +++ b/block-backend-Add-timeout-support-for-retry.patch @@ -0,0 +1,75 @@ +From b4bb154e6587b6d3fef819efcced803e309c4e05 Mon Sep 17 00:00:00 2001 +From: yexiao +Date: Thu, 21 Jan 2021 15:46:49 +0800 +Subject: [PATCH] block-backend: Add timeout support for retry + +Retry should only be triggered when timeout is not reached, so let's check +timeout before retry. Device should also reset retry_start_time after +successful retry. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 25 ++++++++++++++++++++- + include/sysemu/block-backend-global-state.h | 1 + + 2 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index e62808fc03..919699bb70 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -2149,6 +2149,29 @@ void blk_drain_all(void) + bdrv_drain_all_end(); + } + ++static bool blk_error_retry_timeout(BlockBackend *blk) ++{ ++ /* No timeout set, infinite retries. */ ++ if (!blk->retry_timeout) { ++ return false; ++ } ++ ++ /* The first time an error occurs. */ ++ if (!blk->retry_start_time) { ++ blk->retry_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); ++ return false; ++ } ++ ++ return qemu_clock_get_ms(QEMU_CLOCK_REALTIME) > (blk->retry_start_time + ++ blk->retry_timeout); ++} ++ ++void blk_error_retry_reset_timeout(BlockBackend *blk) ++{ ++ if (blk->retry_timer && blk->retry_start_time) ++ blk->retry_start_time = 0; ++} ++ + void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, + BlockdevOnError on_write_error) + { +@@ -2180,7 +2203,7 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, + case BLOCKDEV_ON_ERROR_IGNORE: + return BLOCK_ERROR_ACTION_IGNORE; + case BLOCKDEV_ON_ERROR_RETRY: +- return (blk->retry_timer) ? ++ return (blk->retry_timer && !blk_error_retry_timeout(blk)) ? + BLOCK_ERROR_ACTION_RETRY : BLOCK_ERROR_ACTION_REPORT; + case BLOCKDEV_ON_ERROR_AUTO: + default: +diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h +index 49c12b0fa9..7f59fd411d 100644 +--- a/include/sysemu/block-backend-global-state.h ++++ b/include/sysemu/block-backend-global-state.h +@@ -84,6 +84,7 @@ int blk_commit_all(void); + bool blk_in_drain(BlockBackend *blk); + void blk_drain(BlockBackend *blk); + void blk_drain_all(void); ++void blk_error_retry_reset_timeout(BlockBackend *blk); + void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, + BlockdevOnError on_write_error); + bool blk_supports_write_perm(BlockBackend *blk); +-- +2.27.0 + diff --git a/block-backend-Enable-retry-action-on-errors.patch b/block-backend-Enable-retry-action-on-errors.patch new file mode 100644 index 0000000000000000000000000000000000000000..6581ac1b362f71773e5dae8806fd73e00ee2289f --- /dev/null +++ b/block-backend-Enable-retry-action-on-errors.patch @@ -0,0 +1,43 @@ +From 7bcf4385f518580509990ff71c8209505c887abc Mon Sep 17 00:00:00 2001 +From: yexiao +Date: Thu, 21 Jan 2021 15:46:48 +0800 +Subject: [PATCH] block-backend: Enable retry action on errors + +Enable retry action when backend's retry timer is available. It would +trigger the timer to do device specific retry action. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 7e25d5a058..e62808fc03 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -2179,6 +2179,9 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, + return BLOCK_ERROR_ACTION_REPORT; + case BLOCKDEV_ON_ERROR_IGNORE: + return BLOCK_ERROR_ACTION_IGNORE; ++ case BLOCKDEV_ON_ERROR_RETRY: ++ return (blk->retry_timer) ? ++ BLOCK_ERROR_ACTION_RETRY : BLOCK_ERROR_ACTION_REPORT; + case BLOCKDEV_ON_ERROR_AUTO: + default: + abort(); +@@ -2227,6 +2230,10 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action, + qemu_system_vmstop_request_prepare(); + send_qmp_error_event(blk, action, is_read, error); + qemu_system_vmstop_request(RUN_STATE_IO_ERROR); ++ } else if (action == BLOCK_ERROR_ACTION_RETRY) { ++ timer_mod(blk->retry_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ++ blk->retry_interval); ++ send_qmp_error_event(blk, action, is_read, error); + } else { + send_qmp_error_event(blk, action, is_read, error); + } +-- +2.27.0 + diff --git a/block-backend-Introduce-retry-timer.patch b/block-backend-Introduce-retry-timer.patch new file mode 100644 index 0000000000000000000000000000000000000000..e085a3eb1cbd90656a2ba816a17ae48ed693cefc --- /dev/null +++ b/block-backend-Introduce-retry-timer.patch @@ -0,0 +1,70 @@ +From 9567fce96050342f393f546d3c5131118c3cad7c Mon Sep 17 00:00:00 2001 +From: yexiao +Date: Thu, 21 Jan 2021 15:46:46 +0800 +Subject: [PATCH] block-backend: Introduce retry timer + +Add a timer to regularly trigger retry on errors. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/block/block-backend.c b/block/block-backend.c +index ec21148806..2f56cc8382 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -33,6 +33,9 @@ + + #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ + ++/* block backend default retry interval */ ++#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 ++ + typedef struct BlockBackendAioNotifier { + void (*attached_aio_context)(AioContext *new_context, void *opaque); + void (*detach_aio_context)(void *opaque); +@@ -92,6 +95,15 @@ struct BlockBackend { + * Accessed with atomic ops. + */ + unsigned int in_flight; ++ ++ /* Timer for retry on errors. */ ++ QEMUTimer *retry_timer; ++ /* Interval in ms to trigger next retry. */ ++ int64_t retry_interval; ++ /* Start time of the first error. Used to check timeout. */ ++ int64_t retry_start_time; ++ /* Retry timeout. 0 represents infinite retry. */ ++ int64_t retry_timeout; + }; + + typedef struct BlockBackendAIOCB { +@@ -368,6 +380,11 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm) + blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT; + blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; + ++ blk->retry_timer = NULL; ++ blk->retry_interval = BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL; ++ blk->retry_start_time = 0; ++ blk->retry_timeout = 0; ++ + block_acct_init(&blk->stats); + + qemu_mutex_init(&blk->queued_requests_lock); +@@ -508,6 +525,10 @@ static void blk_delete(BlockBackend *blk) + QTAILQ_REMOVE(&block_backends, blk, link); + drive_info_del(blk->legacy_dinfo); + block_acct_cleanup(&blk->stats); ++ if (blk->retry_timer) { ++ timer_del(blk->retry_timer); ++ timer_free(blk->retry_timer); ++ } + g_free(blk); + } + +-- +2.27.0 + diff --git a/block-backend-Stop-retrying-when-draining.patch b/block-backend-Stop-retrying-when-draining.patch new file mode 100644 index 0000000000000000000000000000000000000000..d2996b16ade4968d08bf9ee2cedb690aed5e48ce --- /dev/null +++ b/block-backend-Stop-retrying-when-draining.patch @@ -0,0 +1,38 @@ +From bbac66be575c76216c18d68c558e0dc80a078f68 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 25 Feb 2021 18:03:57 +0800 +Subject: [PATCH] block-backend: Stop retrying when draining + +Retrying failed requests when draining would make the draining hung. So it +is better not to trigger the retry timer when draining. And after the +virtual devices go back to work, they would retry those queued requests. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 85d732de7e..bfbbb18af1 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -2261,9 +2261,11 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action, + send_qmp_error_event(blk, action, is_read, error); + qemu_system_vmstop_request(RUN_STATE_IO_ERROR); + } else if (action == BLOCK_ERROR_ACTION_RETRY) { +- timer_mod(blk->retry_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + +- blk->retry_interval); +- send_qmp_error_event(blk, action, is_read, error); ++ if (!blk->quiesce_counter) { ++ timer_mod(blk->retry_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ++ blk->retry_interval); ++ send_qmp_error_event(blk, action, is_read, error); ++ } + } else { + send_qmp_error_event(blk, action, is_read, error); + } +-- +2.27.0 + diff --git a/block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch b/block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch new file mode 100644 index 0000000000000000000000000000000000000000..d082d283e83399d2d8655fc9c2137f2f329ad56c --- /dev/null +++ b/block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch @@ -0,0 +1,33 @@ +From ea0feb8a262383582416283ad1af1819c1e0e22a Mon Sep 17 00:00:00 2001 +From: WangJian +Date: Wed, 9 Feb 2022 16:10:22 +0800 +Subject: [PATCH] block: bugfix: Don't pause vm when NOSPACE EIO happened + +When backend disk is FULL and disk IO type is 'dataplane', +QEMU will pause the vm, and this may cause endless-loop in +QEMU main thread if we do the snapshot merge now. + +When backend disk is FULL, only reporting an error rather +than pausing the virtual machine. + +Signed-off-by: wangjian161 +--- + blockdev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/blockdev.c b/blockdev.c +index bc2099e9da..455ae8606d 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -557,7 +557,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + qdict_put_str(bs_opts, "driver", buf); + } + +- on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; ++ on_write_error = BLOCKDEV_ON_ERROR_REPORT; + if ((buf = qemu_opt_get(opts, "werror")) != NULL) { + on_write_error = parse_block_error_action(buf, 0, &error); + if (error) { +-- +2.27.0 + diff --git a/block-enable-cache-mode-of-empty-cdrom.patch b/block-enable-cache-mode-of-empty-cdrom.patch new file mode 100644 index 0000000000000000000000000000000000000000..d7aae757e53e7c9f84a576ccf2dfd1476bab2acb --- /dev/null +++ b/block-enable-cache-mode-of-empty-cdrom.patch @@ -0,0 +1,49 @@ +From 652325f9a04143ffabf5e9a418253a05e927ec37 Mon Sep 17 00:00:00 2001 +From: WangJian +Date: Wed, 9 Feb 2022 11:18:21 +0800 +Subject: [PATCH] block: enable cache mode of empty cdrom + +enable cache mode even if cdrom is empty + +Signed-off-by: wangjian161 +--- + blockdev.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/blockdev.c b/blockdev.c +index c91f49e7b6..bc2099e9da 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -493,6 +493,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + QDict *interval_dict = NULL; + QList *interval_list = NULL; + const char *id; ++ const char *cache; + BlockdevDetectZeroesOptions detect_zeroes = + BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF; + const char *throttling_group = NULL; +@@ -580,6 +581,21 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + + read_only = qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false); + ++ if (!file || !*file) { ++ cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH); ++ if (cache && !strcmp(cache, "on")) { ++ bdrv_flags |= BDRV_O_NO_FLUSH; ++ } ++ ++ cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_DIRECT); ++ if (cache && !strcmp(cache, "on")) { ++ bdrv_flags |= BDRV_O_NOCACHE; ++ } ++ ++ qdict_del(bs_opts, BDRV_OPT_CACHE_NO_FLUSH); ++ qdict_del(bs_opts, BDRV_OPT_CACHE_DIRECT); ++ } ++ + /* init */ + if ((!file || !*file) && !qdict_size(bs_opts)) { + BlockBackendRootState *blk_rs; +-- +2.27.0 + diff --git a/block-mirror-fix-file-system-went-to-read-only-after.patch b/block-mirror-fix-file-system-went-to-read-only-after.patch new file mode 100644 index 0000000000000000000000000000000000000000..b36f8cd870663ea2bb2c4a84d4d70f0527915ee5 --- /dev/null +++ b/block-mirror-fix-file-system-went-to-read-only-after.patch @@ -0,0 +1,32 @@ +From 6203b11d2a900c60d2ee3c3a980d2c385050eb62 Mon Sep 17 00:00:00 2001 +From: yexiao +Date: Thu, 10 Feb 2022 21:37:49 +0800 +Subject: [PATCH] block/mirror: fix file-system went to read-only after + block-mirror + +config vm disk with prdm, keep the disk writing data continuously +during block-mirror, the file-system will went to read-only after +block-mirror, fix it. + +Signed-off-by: caojinhua +Signed-off-by: jiangdongxu +--- + block/mirror.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block/mirror.c b/block/mirror.c +index cd9d3ad4a8..20b3e8e5d8 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -1774,7 +1774,7 @@ static BlockJob *mirror_start_job( + * reads on the top, while disabling it in the intermediate nodes, and make + * the backing chain writable. */ + mirror_top_bs = bdrv_new_open_driver(&bdrv_mirror_top, filter_node_name, +- BDRV_O_RDWR, errp); ++ BDRV_O_RDWR | BDRV_O_NOCACHE, errp); + if (mirror_top_bs == NULL) { + return NULL; + } +-- +2.27.0 + diff --git a/bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch b/bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch new file mode 100644 index 0000000000000000000000000000000000000000..1160489609bce25c0fceffb2c8d98c04ba2283a3 --- /dev/null +++ b/bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch @@ -0,0 +1,49 @@ +From 6588c017de54bab8a11509d43e2ddabf065cfa50 Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Thu, 10 Feb 2022 21:50:28 +0800 +Subject: [PATCH] bugfix: fix eventfds may double free when vm_id reused in + ivshmem + +As the ivshmem Server-Client Protol describes, when a +client disconnects from the server, server sends disconnect +notifications to the other clients. And the other clients +will free the eventfds of the disconnected client according +to the client ID. If the client ID is reused, the eventfds +may be double freed. + +It will be solved by setting eventfds to NULL after freeing +and allocating memory for it when it's used. + +Signed-off-by: Peng Liang +Signed-off-by: jiangdongxu +Signed-off-by: Adttil +--- + hw/misc/ivshmem.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c +index 0447888029..ad9a3c546e 100644 +--- a/hw/misc/ivshmem.c ++++ b/hw/misc/ivshmem.c +@@ -400,6 +400,7 @@ static void close_peer_eventfds(IVShmemState *s, int posn) + } + + g_free(s->peers[posn].eventfds); ++ s->peers[posn].eventfds = NULL; + s->peers[posn].nb_eventfds = 0; + } + +@@ -533,6 +534,10 @@ static void process_msg_connect(IVShmemState *s, uint16_t posn, int fd, + close(fd); + return; + } ++ if (peer->eventfds == NULL) { ++ peer->eventfds = g_new0(EventNotifier, s->vectors); ++ peer->nb_eventfds = 0; ++ } + vector = peer->nb_eventfds++; + + IVSHMEM_DPRINTF("eventfds[%d][%d] = %d\n", posn, vector, fd); +-- +2.27.0 + diff --git a/bugfix-fix-possible-memory-leak.patch b/bugfix-fix-possible-memory-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..34d88766ee9e88a8345ff2c247e51e7045a3e159 --- /dev/null +++ b/bugfix-fix-possible-memory-leak.patch @@ -0,0 +1,98 @@ +From e6a20580801314e9d47682d7b8d8161c030eab04 Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Thu, 10 Feb 2022 22:12:50 +0800 +Subject: [PATCH] bugfix: fix possible memory leak + +Signed-off-by: caojinhua +Signed-off-by: jiangdongxu +Signed-off-by: Adttil +--- + migration/savevm.c | 2 ++ + qga/main.c | 18 +++++++++++++----- + 2 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/migration/savevm.c b/migration/savevm.c +index eec5503a42..477a19719f 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -1553,6 +1553,7 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, + ret = vmstate_save(f, se, vmdesc); + if (ret) { + qemu_file_set_error(f, ret); ++ json_writer_free(vmdesc); + return ret; + } + +@@ -1572,6 +1573,7 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, + migrate_set_error(ms, local_err); + error_report_err(local_err); + qemu_file_set_error(f, ret); ++ json_writer_free(vmdesc); + return ret; + } + } +diff --git a/qga/main.c b/qga/main.c +index 8668b9f3d3..c4dcbb86be 100644 +--- a/qga/main.c ++++ b/qga/main.c +@@ -1399,7 +1399,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) + if (g_mkdir_with_parents(config->state_dir, S_IRWXU) == -1) { + g_critical("unable to create (an ancestor of) the state directory" + " '%s': %s", config->state_dir, strerror(errno)); +- return NULL; ++ goto failed; + } + #endif + +@@ -1424,7 +1424,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) + if (!log_file) { + g_critical("unable to open specified log file: %s", + strerror(errno)); +- return NULL; ++ goto failed; + } + s->log_file = log_file; + } +@@ -1435,7 +1435,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) + s->pstate_filepath, + ga_is_frozen(s))) { + g_critical("failed to load persistent state"); +- return NULL; ++ goto failed; + } + + if (config->allowedrpcs) { +@@ -1465,7 +1465,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) + #ifndef _WIN32 + if (!register_signal_handlers()) { + g_critical("failed to register signal handlers"); +- return NULL; ++ goto failed; + } + #endif + +@@ -1478,12 +1478,20 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) + s->wakeup_event = CreateEvent(NULL, TRUE, FALSE, TEXT("WakeUp")); + if (s->wakeup_event == NULL) { + g_critical("CreateEvent failed"); +- return NULL; ++ goto failed; + } + #endif + + ga_state = s; + return s; ++failed: ++ g_free(s->pstate_filepath); ++ g_free(s->state_filepath_isfrozen); ++ if (s->log_file) { ++ fclose(s->log_file); ++ } ++ g_free(s); ++ return NULL; + } + + static void cleanup_agent(GAState *s) +-- +2.27.0 + diff --git a/bugfix-fix-some-illegal-memory-access-and-memory-lea.patch b/bugfix-fix-some-illegal-memory-access-and-memory-lea.patch new file mode 100644 index 0000000000000000000000000000000000000000..18c983974ba07088dcb79920b2b84926f35bef45 --- /dev/null +++ b/bugfix-fix-some-illegal-memory-access-and-memory-lea.patch @@ -0,0 +1,27 @@ +From 35054aa25a0d7758a35d75e3298555b502e37b0f Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Thu, 10 Feb 2022 21:32:37 +0800 +Subject: [PATCH] bugfix: fix some illegal memory access and memory leak + +Signed-off-by: yuxiating +Signed-off-by: jiangdongxu +Signed-off-by: Adttil +--- + util/range.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/util/range.c b/util/range.c +index f3f40098d5..2ea640662b 100644 +--- a/util/range.c ++++ b/util/range.c +@@ -61,6 +61,7 @@ GList *range_list_insert(GList *list, Range *data) + range_extend(l->data, l->next->data); + g_free(l->next->data); + new_l = g_list_delete_link(list, l->next); ++ l->next = NULL; + assert(new_l == list); + } + +-- +2.27.0 + diff --git a/chardev-char-socket-Fix-TLS-io-channels-sending-too-.patch b/chardev-char-socket-Fix-TLS-io-channels-sending-too-.patch new file mode 100644 index 0000000000000000000000000000000000000000..f494ea7f0f43d02b856ea9f1b3d7836a40e7d202 --- /dev/null +++ b/chardev-char-socket-Fix-TLS-io-channels-sending-too-.patch @@ -0,0 +1,91 @@ +From 2d0d05b7d5925f71d7ddd4df9f1ac12add453298 Mon Sep 17 00:00:00 2001 +From: qihao +Date: Thu, 7 Mar 2024 10:39:23 +0800 +Subject: [PATCH] chardev/char-socket: Fix TLS io channels sending too much + data to the backend +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from 462945cd22d2bcd233401ed3aa167d83a8e35b05 + +Commit ffda5db65a ("io/channel-tls: fix handling of bigger read buffers") +changed the behavior of the TLS io channels to schedule a second reading +attempt if there is still incoming data pending. This caused a regression +with backends like the sclpconsole that check in their read function that +the sender does not try to write more bytes to it than the device can +currently handle. + +The problem can be reproduced like this: + + 1) In one terminal, do this: + + mkdir qemu-pki + cd qemu-pki + openssl genrsa 2048 > ca-key.pem + openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem + # enter some dummy value for the cert + openssl genrsa 2048 > server-key.pem + openssl req -new -x509 -nodes -days 365000 -key server-key.pem \ + -out server-cert.pem + # enter some other dummy values for the cert + + gnutls-serv --echo --x509cafile ca-cert.pem --x509keyfile server-key.pem \ + --x509certfile server-cert.pem -p 8338 + + 2) In another terminal, do this: + + wget https://download.fedoraproject.org/pub/fedora-secondary/releases/39/Cloud/s390x/images/Fedora-Cloud-Base-39-1.5.s390x.qcow2 + + qemu-system-s390x -nographic -nodefaults \ + -hda Fedora-Cloud-Base-39-1.5.s390x.qcow2 \ + -object tls-creds-x509,id=tls0,endpoint=client,verify-peer=false,dir=$PWD/qemu-pki \ + -chardev socket,id=tls_chardev,host=localhost,port=8338,tls-creds=tls0 \ + -device sclpconsole,chardev=tls_chardev,id=tls_serial + +QEMU then aborts after a second or two with: + + qemu-system-s390x: ../hw/char/sclpconsole.c:73: chr_read: Assertion + `size <= SIZE_BUFFER_VT220 - scon->iov_data_len' failed. + Aborted (core dumped) + +It looks like the second read does not trigger the chr_can_read() function +to be called before the second read, which should normally always be done +before sending bytes to a character device to see how much it can handle, +so the s->max_size in tcp_chr_read() still contains the old value from the +previous read. Let's make sure that we use the up-to-date value by calling +tcp_chr_read_poll() again here. + +Fixes: ffda5db65a ("io/channel-tls: fix handling of bigger read buffers") +Buglink: https://issues.redhat.com/browse/RHEL-24614 +Reviewed-by: "Daniel P. Berrangé" +Message-ID: <20240229104339.42574-1-thuth@redhat.com> +Reviewed-by: Antoine Damhet +Tested-by: Antoine Damhet +Reviewed-by: Marc-André Lureau +Signed-off-by: Thomas Huth +Signed-off-by: qihao_yewu +--- + chardev/char-socket.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/chardev/char-socket.c b/chardev/char-socket.c +index 73947da188..034840593d 100644 +--- a/chardev/char-socket.c ++++ b/chardev/char-socket.c +@@ -492,9 +492,9 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) + s->max_size <= 0) { + return TRUE; + } +- len = sizeof(buf); +- if (len > s->max_size) { +- len = s->max_size; ++ len = tcp_chr_read_poll(opaque); ++ if (len > sizeof(buf)) { ++ len = sizeof(buf); + } + size = tcp_chr_recv(chr, (void *)buf, len); + if (size == 0 || (size == -1 && errno != EAGAIN)) { +-- +2.27.0 + diff --git a/hw-acpi-cpu-Use-CPUState-typedef.patch b/hw-acpi-cpu-Use-CPUState-typedef.patch new file mode 100644 index 0000000000000000000000000000000000000000..06f9df398f89a68317504335a9e84d38859724ff --- /dev/null +++ b/hw-acpi-cpu-Use-CPUState-typedef.patch @@ -0,0 +1,34 @@ +From 105ea4d8301791bbb5a76df1f527fb5df439c565 Mon Sep 17 00:00:00 2001 +From: dinglimin +Date: Tue, 27 Feb 2024 16:01:50 +0800 +Subject: [PATCH] hw/acpi/cpu: Use CPUState typedef +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from b8492bd430ecc1ceb80cac19b46870d423f1e854 +QEMU coding style recommend using structure typedefs: +https://www.qemu.org/docs/master/devel/style.html#typedefs + +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: dinglimin +--- + include/hw/acpi/cpu.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h +index bc901660fb..209e1773f8 100644 +--- a/include/hw/acpi/cpu.h ++++ b/include/hw/acpi/cpu.h +@@ -19,7 +19,7 @@ + #include "hw/hotplug.h" + + typedef struct AcpiCpuStatus { +- struct CPUState *cpu; ++ CPUState *cpu; + uint64_t arch_id; + bool is_inserting; + bool is_removing; +-- +2.27.0 + diff --git a/hw-cxl-cxl-host-Fix-missing-ERRP_GUARD-in-cxl_fixed_.patch b/hw-cxl-cxl-host-Fix-missing-ERRP_GUARD-in-cxl_fixed_.patch new file mode 100644 index 0000000000000000000000000000000000000000..ceb933b88035c1b6fca5c3128fc46223e139dc6b --- /dev/null +++ b/hw-cxl-cxl-host-Fix-missing-ERRP_GUARD-in-cxl_fixed_.patch @@ -0,0 +1,79 @@ +From 66d91f8cb6c9668744cf0acda4402f75c5e533e0 Mon Sep 17 00:00:00 2001 +From: qihao +Date: Tue, 19 Mar 2024 14:36:46 +0800 +Subject: [PATCH] hw/cxl/cxl-host: Fix missing ERRP_GUARD() in + cxl_fixed_memory_window_config() + +cheery-pick from 2a0e0a35002db7ac64f4e82ea2a4ad2fb6d934b0 + +As the comment in qapi/error, dereferencing @errp requires +ERRP_GUARD(): + +* = Why, when and how to use ERRP_GUARD() = +* +* Without ERRP_GUARD(), use of the @errp parameter is restricted: +* - It must not be dereferenced, because it may be null. +... +* ERRP_GUARD() lifts these restrictions. +* +* To use ERRP_GUARD(), add it right at the beginning of the function. +* @errp can then be used without worrying about the argument being +* NULL or &error_fatal. +* +* Using it when it's not needed is safe, but please avoid cluttering +* the source with useless code. + +But in cxl_fixed_memory_window_config(), @errp is dereferenced in 2 +places without ERRP_GUARD(): + +fw->enc_int_ways = cxl_interleave_ways_enc(fw->num_targets, errp); +if (*errp) { + return; +} + +and + +fw->enc_int_gran = + cxl_interleave_granularity_enc(object->interleave_granularity, + errp); +if (*errp) { + return; +} + +For the above 2 places, we check "*errp", because neither function +returns a suitable error code. And since machine_set_cfmw() - the caller +of cxl_fixed_memory_window_config() - doesn't get the NULL @errp +parameter as the "set" method of object property, +cxl_fixed_memory_window_config() hasn't triggered the bug that +dereferencing the NULL @errp. + +To follow the requirement of @errp, add missing ERRP_GUARD() in +cxl_fixed_memory_window_config(). + +Suggested-by: Markus Armbruster +Signed-off-by: Zhao Liu +Reviewed-by: Markus Armbruster +Message-Id: <20240223085653.1255438-2-zhao1.liu@linux.intel.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Acked-by: Jonathan Cameron +Signed-off-by: qihao_yewu +--- + hw/cxl/cxl-host.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c +index 2aa776c79c..c5f5fcfd64 100644 +--- a/hw/cxl/cxl-host.c ++++ b/hw/cxl/cxl-host.c +@@ -26,6 +26,7 @@ static void cxl_fixed_memory_window_config(CXLState *cxl_state, + CXLFixedMemoryWindowOptions *object, + Error **errp) + { ++ ERRP_GUARD(); + g_autofree CXLFixedWindow *fw = g_malloc0(sizeof(*fw)); + strList *target; + int i; +-- +2.27.0 + diff --git a/hw-display-macfb-Fix-missing-ERRP_GUARD-in-macfb_nub.patch b/hw-display-macfb-Fix-missing-ERRP_GUARD-in-macfb_nub.patch new file mode 100644 index 0000000000000000000000000000000000000000..ba043b631bb37466c47d20e091ce68c900cdafb3 --- /dev/null +++ b/hw-display-macfb-Fix-missing-ERRP_GUARD-in-macfb_nub.patch @@ -0,0 +1,68 @@ +From c9ee283913cc9df8998a21544a68ac1d2f86aa49 Mon Sep 17 00:00:00 2001 +From: qihao +Date: Tue, 19 Mar 2024 15:07:51 +0800 +Subject: [PATCH] hw/display/macfb: Fix missing ERRP_GUARD() in + macfb_nubus_realize() + +cheery-pick from 5aa4a6417b0f7acbfd7f4c21dca26293bc3d9348 + +As the comment in qapi/error, dereferencing @errp requires +ERRP_GUARD(): + +* = Why, when and how to use ERRP_GUARD() = +* +* Without ERRP_GUARD(), use of the @errp parameter is restricted: +* - It must not be dereferenced, because it may be null. +... +* ERRP_GUARD() lifts these restrictions. +* +* To use ERRP_GUARD(), add it right at the beginning of the function. +* @errp can then be used without worrying about the argument being +* NULL or &error_fatal. +* +* Using it when it's not needed is safe, but please avoid cluttering +* the source with useless code. + +But in macfb_nubus_realize(), @errp is dereferenced without +ERRP_GUARD(): + +ndc->parent_realize(dev, errp); +if (*errp) { + return; +} + +Here we check *errp, because the ndc->parent_realize(), as a +DeviceClass.realize() callback, returns void. And since +macfb_nubus_realize(), also as a DeviceClass.realize(), doesn't get the +NULL @errp parameter, it hasn't triggered the bug that dereferencing the +NULL @errp. + +To follow the requirement of @errp, add missing ERRP_GUARD() in +macfb_nubus_realize(). + +Suggested-by: Markus Armbruster +Signed-off-by: Zhao Liu +Reviewed-by: Markus Armbruster +Message-Id: <20240223085653.1255438-3-zhao1.liu@linux.intel.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: qihao_yewu +--- + hw/display/macfb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/display/macfb.c b/hw/display/macfb.c +index d61541ccb5..170da35757 100644 +--- a/hw/display/macfb.c ++++ b/hw/display/macfb.c +@@ -714,6 +714,7 @@ static void macfb_nubus_set_irq(void *opaque, int n, int level) + + static void macfb_nubus_realize(DeviceState *dev, Error **errp) + { ++ ERRP_GUARD(); + NubusDevice *nd = NUBUS_DEVICE(dev); + MacfbNubusState *s = NUBUS_MACFB(dev); + MacfbNubusDeviceClass *ndc = NUBUS_MACFB_GET_CLASS(dev); +-- +2.27.0 + diff --git a/hw-i2c-smbus_slave-Add-object-path-on-error-prints.patch b/hw-i2c-smbus_slave-Add-object-path-on-error-prints.patch new file mode 100644 index 0000000000000000000000000000000000000000..aa63deb3fd944ed52bfc5e662c862ca45868ddd7 --- /dev/null +++ b/hw-i2c-smbus_slave-Add-object-path-on-error-prints.patch @@ -0,0 +1,49 @@ +From f8ed9dd954fbd558d549c7c2e2ab7322107218a1 Mon Sep 17 00:00:00 2001 +From: dinglimin +Date: Tue, 27 Feb 2024 17:40:21 +0800 +Subject: [PATCH] hw/i2c/smbus_slave: Add object path on error prints +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from fcc8299e29816c9b6f8d9766254fce6e8a50ee52 + +The current logging doesn't tell us which specific smbus device is an +error state. + +Signed-off-by: Joe Komlodi +Reviewed-by: Peter Maydell +Reviewed-by: Philippe Mathieu-Daudé +Message-ID: <20240202204847.2062798-3-komlodi@google.com> +Signed-off-by: Philippe Mathieu-Daudé + +Signed-off-by: dinglimin +--- + hw/i2c/smbus_slave.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c +index 2ef2c7c5f6..b35516a404 100644 +--- a/hw/i2c/smbus_slave.c ++++ b/hw/i2c/smbus_slave.c +@@ -25,11 +25,15 @@ + #define DPRINTF(fmt, ...) \ + do { printf("smbus(%02x): " fmt , dev->i2c.address, ## __VA_ARGS__); } while (0) + #define BADF(fmt, ...) \ +-do { fprintf(stderr, "smbus: error: " fmt , ## __VA_ARGS__); exit(1);} while (0) ++do { g_autofree char *qom_path = object_get_canonical_path(OBJECT(dev)); \ ++ fprintf(stderr, "%s: smbus: error: " fmt , qom_path, ## __VA_ARGS__); \ ++ exit(1); } while (0) + #else + #define DPRINTF(fmt, ...) do {} while(0) + #define BADF(fmt, ...) \ +-do { fprintf(stderr, "smbus: error: " fmt , ## __VA_ARGS__);} while (0) ++do { g_autofree char *qom_path = object_get_canonical_path(OBJECT(dev)); \ ++ fprintf(stderr, "%s: smbus: error: " fmt , qom_path, ## __VA_ARGS__); \ ++ } while (0) + #endif + + enum { +-- +2.27.0 + diff --git a/hw-nvme-Use-pcie_sriov_num_vfs-CVE-2024-26328.patch b/hw-nvme-Use-pcie_sriov_num_vfs-CVE-2024-26328.patch new file mode 100644 index 0000000000000000000000000000000000000000..7f546cd40b083c26f25eb974614a24e3c989ab35 --- /dev/null +++ b/hw-nvme-Use-pcie_sriov_num_vfs-CVE-2024-26328.patch @@ -0,0 +1,85 @@ +From 6a32c9764439093fe4b53f87059c35761d711e39 Mon Sep 17 00:00:00 2001 +From: Akihiko Odaki +Date: Wed, 28 Feb 2024 20:33:12 +0900 +Subject: [PATCH] hw/nvme: Use pcie_sriov_num_vfs() (CVE-2024-26328) + +nvme_sriov_pre_write_ctrl() used to directly inspect SR-IOV +configurations to know the number of VFs being disabled due to SR-IOV +configuration writes, but the logic was flawed and resulted in +out-of-bound memory access. + +It assumed PCI_SRIOV_NUM_VF always has the number of currently enabled +VFs, but it actually doesn't in the following cases: +- PCI_SRIOV_NUM_VF has been set but PCI_SRIOV_CTRL_VFE has never been. +- PCI_SRIOV_NUM_VF was written after PCI_SRIOV_CTRL_VFE was set. +- VFs were only partially enabled because of realization failure. + +It is a responsibility of pcie_sriov to interpret SR-IOV configurations +and pcie_sriov does it correctly, so use pcie_sriov_num_vfs(), which it +provides, to get the number of enabled VFs before and after SR-IOV +configuration writes. + +Cc: qemu-stable@nongnu.org +Fixes: CVE-2024-26328 +Fixes: 11871f53ef8e ("hw/nvme: Add support for the Virtualization Management command") +Suggested-by: Michael S. Tsirkin +Signed-off-by: Akihiko Odaki +Message-Id: <20240228-reuse-v8-1-282660281e60@daynix.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +--- + hw/nvme/ctrl.c | 26 ++++++++------------------ + 1 file changed, 8 insertions(+), 18 deletions(-) + +diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c +index f026245d1e..7a56e7b79b 100644 +--- a/hw/nvme/ctrl.c ++++ b/hw/nvme/ctrl.c +@@ -8466,36 +8466,26 @@ static void nvme_pci_reset(DeviceState *qdev) + nvme_ctrl_reset(n, NVME_RESET_FUNCTION); + } + +-static void nvme_sriov_pre_write_ctrl(PCIDevice *dev, uint32_t address, +- uint32_t val, int len) ++static void nvme_sriov_post_write_config(PCIDevice *dev, uint16_t old_num_vfs) + { + NvmeCtrl *n = NVME(dev); + NvmeSecCtrlEntry *sctrl; +- uint16_t sriov_cap = dev->exp.sriov_cap; +- uint32_t off = address - sriov_cap; +- int i, num_vfs; ++ int i; + +- if (!sriov_cap) { +- return; +- } +- +- if (range_covers_byte(off, len, PCI_SRIOV_CTRL)) { +- if (!(val & PCI_SRIOV_CTRL_VFE)) { +- num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF); +- for (i = 0; i < num_vfs; i++) { +- sctrl = &n->sec_ctrl_list.sec[i]; +- nvme_virt_set_state(n, le16_to_cpu(sctrl->scid), false); +- } +- } ++ for (i = pcie_sriov_num_vfs(dev); i < old_num_vfs; i++) { ++ sctrl = &n->sec_ctrl_list.sec[i]; ++ nvme_virt_set_state(n, le16_to_cpu(sctrl->scid), false); + } + } + + static void nvme_pci_write_config(PCIDevice *dev, uint32_t address, + uint32_t val, int len) + { +- nvme_sriov_pre_write_ctrl(dev, address, val, len); ++ uint16_t old_num_vfs = pcie_sriov_num_vfs(dev); ++ + pci_default_write_config(dev, address, val, len); + pcie_cap_flr_write_config(dev, address, val, len); ++ nvme_sriov_post_write_config(dev, old_num_vfs); + } + + static const VMStateDescription nvme_vmstate = { +-- +2.27.0 + diff --git a/hw-usb-Style-cleanup.patch b/hw-usb-Style-cleanup.patch new file mode 100644 index 0000000000000000000000000000000000000000..e2c333b373d8dea2b293fd4e8de1764e8ed3d1a2 --- /dev/null +++ b/hw-usb-Style-cleanup.patch @@ -0,0 +1,66 @@ +From f06b930da5d2acf70d142f1212ef4ee09d643b21 Mon Sep 17 00:00:00 2001 +From: dinglimin +Date: Tue, 27 Feb 2024 16:18:43 +0800 +Subject: [PATCH] hw/usb: Style cleanup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from 455177ffc457098b0103d2a09cb7ba5e260dfcdd + +We are going to modify these lines, fix their style +in order to avoid checkpatch.pl warning. + +Signed-off-by: Philippe Mathieu-Daudé +Reviewed-by: Richard Henderson +Signed-off-by: Michael Tokarev +Signed-off-by: dinglimin +--- + hw/usb/hcd-ehci.c | 3 ++- + hw/usb/hcd-uhci.c | 6 ++++-- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c +index 19b4534c20..7b093acd98 100644 +--- a/hw/usb/hcd-ehci.c ++++ b/hw/usb/hcd-ehci.c +@@ -1086,8 +1086,9 @@ static void ehci_opreg_write(void *ptr, hwaddr addr, + case CONFIGFLAG: + val &= 0x1; + if (val) { +- for(i = 0; i < NB_PORTS; i++) ++ for (i = 0; i < NB_PORTS; i++) { + handle_port_owner_write(s, i, 0); ++ } + } + break; + +diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c +index 77baaa7a6b..6975966c3f 100644 +--- a/hw/usb/hcd-uhci.c ++++ b/hw/usb/hcd-uhci.c +@@ -457,8 +457,9 @@ static void uhci_port_write(void *opaque, hwaddr addr, + int n; + + n = (addr >> 1) & 7; +- if (n >= NB_PORTS) ++ if (n >= NB_PORTS) { + return; ++ } + port = &s->ports[n]; + dev = port->port.dev; + if (dev && dev->attached) { +@@ -513,8 +514,9 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, unsigned size) + UHCIPort *port; + int n; + n = (addr >> 1) & 7; +- if (n >= NB_PORTS) ++ if (n >= NB_PORTS) { + goto read_default; ++ } + port = &s->ports[n]; + val = port->ctrl; + } +-- +2.27.0 + diff --git a/i386-cpu-Clear-FEAT_XSAVE_XSS_LO-HI-leafs-when-CPUID.patch b/i386-cpu-Clear-FEAT_XSAVE_XSS_LO-HI-leafs-when-CPUID.patch new file mode 100644 index 0000000000000000000000000000000000000000..8549070247aefc0f6091388411438386d580b2ec --- /dev/null +++ b/i386-cpu-Clear-FEAT_XSAVE_XSS_LO-HI-leafs-when-CPUID.patch @@ -0,0 +1,38 @@ +From c952c9acfab98a83122b4e6d406f4a7a0dfe871f Mon Sep 17 00:00:00 2001 +From: Xiaoyao Li +Date: Mon, 15 Jan 2024 04:13:24 -0500 +Subject: [PATCH] i386/cpu: Clear FEAT_XSAVE_XSS_LO/HI leafs when + CPUID_EXT_XSAVE is not available + +commit 81f5cad3858f27623b1b14467926032d229b76cc upstream. + +Leaf FEAT_XSAVE_XSS_LO and FEAT_XSAVE_XSS_HI also need to be cleared +when CPUID_EXT_XSAVE is not set. + +Fixes: 301e90675c3f ("target/i386: Enable support for XSAVES based features") +Signed-off-by: Xiaoyao Li +Reviewed-by: Yang Weijiang +Message-ID: <20240115091325.1904229-2-xiaoyao.li@intel.com> +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Jason Zeng +--- + target/i386/cpu.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index cd16cb893d..8b9ef218d3 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6927,6 +6927,8 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) + if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) { + env->features[FEAT_XSAVE_XCR0_LO] = 0; + env->features[FEAT_XSAVE_XCR0_HI] = 0; ++ env->features[FEAT_XSAVE_XSS_LO] = 0; ++ env->features[FEAT_XSAVE_XSS_HI] = 0; + return; + } + +-- +2.27.0 + diff --git a/i386-cpu-Mask-with-XCR0-XSS-mask-for-FEAT_XSAVE_XCR0.patch b/i386-cpu-Mask-with-XCR0-XSS-mask-for-FEAT_XSAVE_XCR0.patch new file mode 100644 index 0000000000000000000000000000000000000000..612d46547a6e221c90f8f826f78226593f529373 --- /dev/null +++ b/i386-cpu-Mask-with-XCR0-XSS-mask-for-FEAT_XSAVE_XCR0.patch @@ -0,0 +1,42 @@ +From 26ddb3428182503b28ac87cad7543eb241a9d353 Mon Sep 17 00:00:00 2001 +From: Xiaoyao Li +Date: Mon, 15 Jan 2024 04:13:25 -0500 +Subject: [PATCH] i386/cpu: Mask with XCR0/XSS mask for FEAT_XSAVE_XCR0_HI and + FEAT_XSAVE_XSS_HI leafs + +commit a11a365159b944e05be76f3ec3b98c8b38cb70fd upstream. + +The value of FEAT_XSAVE_XCR0_HI leaf and FEAT_XSAVE_XSS_HI leaf also +need to be masked by XCR0 and XSS mask respectively, to make it +logically correct. + +Fixes: 301e90675c3f ("target/i386: Enable support for XSAVES based features") +Signed-off-by: Xiaoyao Li +Reviewed-by: Yang Weijiang +Message-ID: <20240115091325.1904229-3-xiaoyao.li@intel.com> +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Jason Zeng +--- + target/i386/cpu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 8b9ef218d3..a66e5a357b 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6947,9 +6947,9 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) + } + + env->features[FEAT_XSAVE_XCR0_LO] = mask & CPUID_XSTATE_XCR0_MASK; +- env->features[FEAT_XSAVE_XCR0_HI] = mask >> 32; ++ env->features[FEAT_XSAVE_XCR0_HI] = (mask & CPUID_XSTATE_XCR0_MASK) >> 32; + env->features[FEAT_XSAVE_XSS_LO] = mask & CPUID_XSTATE_XSS_MASK; +- env->features[FEAT_XSAVE_XSS_HI] = mask >> 32; ++ env->features[FEAT_XSAVE_XSS_HI] = (mask & CPUID_XSTATE_XSS_MASK) >> 32; + } + + /***** Steps involved on loading and filtering CPUID data +-- +2.27.0 + diff --git a/i386-cpuid-Decrease-cpuid_i-when-skipping-CPUID-leaf.patch b/i386-cpuid-Decrease-cpuid_i-when-skipping-CPUID-leaf.patch new file mode 100644 index 0000000000000000000000000000000000000000..37ee5b31f618e36974d8a9a7efd8e0d928eada52 --- /dev/null +++ b/i386-cpuid-Decrease-cpuid_i-when-skipping-CPUID-leaf.patch @@ -0,0 +1,38 @@ +From 576170252c3cbd79ed918f688d088f1ccd15602a Mon Sep 17 00:00:00 2001 +From: Xiaoyao Li +Date: Wed, 24 Jan 2024 21:40:14 -0500 +Subject: [PATCH] i386/cpuid: Decrease cpuid_i when skipping CPUID leaf 1F + +commit 10f92799af8ba3c3cef2352adcd4780f13fbab31 upstream. + +Existing code misses a decrement of cpuid_i when skip leaf 0x1F. +There's a blank CPUID entry(with leaf, subleaf as 0, and all fields +stuffed 0s) left in the CPUID array. + +It conflicts with correct CPUID leaf 0. + +Signed-off-by: Xiaoyao Li +Reviewed-by:Yang Weijiang +Message-ID: <20240125024016.2521244-2-xiaoyao.li@intel.com> +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Jason Zeng +--- + target/i386/kvm/kvm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 4ce80555b4..e68eb8f5e6 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -1914,6 +1914,7 @@ int kvm_arch_init_vcpu(CPUState *cs) + } + case 0x1f: + if (env->nr_dies < 2) { ++ cpuid_i--; + break; + } + /* fallthrough */ +-- +2.27.0 + diff --git a/i386-cpuid-Move-leaf-7-to-correct-group.patch b/i386-cpuid-Move-leaf-7-to-correct-group.patch new file mode 100644 index 0000000000000000000000000000000000000000..fd217f55e0aae3a2a205dd6523a336e7b70cf453 --- /dev/null +++ b/i386-cpuid-Move-leaf-7-to-correct-group.patch @@ -0,0 +1,50 @@ +From bf3d3ecf9ff5808d1f03e83a363c8295f7abad76 Mon Sep 17 00:00:00 2001 +From: Xiaoyao Li +Date: Wed, 24 Jan 2024 21:40:16 -0500 +Subject: [PATCH] i386/cpuid: Move leaf 7 to correct group + +commit 0729857c707535847d7fe31d3d91eb8b2a118e3c upstream. + +CPUID leaf 7 was grouped together with SGX leaf 0x12 by commit +b9edbadefb9e ("i386: Propagate SGX CPUID sub-leafs to KVM") by mistake. + +SGX leaf 0x12 has its specific logic to check if subleaf (starting from 2) +is valid or not by checking the bit 0:3 of corresponding EAX is 1 or +not. + +Leaf 7 follows the logic that EAX of subleaf 0 enumerates the maximum +valid subleaf. + +Fixes: b9edbadefb9e ("i386: Propagate SGX CPUID sub-leafs to KVM") +Signed-off-by: Xiaoyao Li +Message-ID: <20240125024016.2521244-4-xiaoyao.li@intel.com> +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Jason Zeng +--- + target/i386/kvm/kvm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index e68eb8f5e6..a0bc9ea7b1 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -1955,7 +1955,6 @@ int kvm_arch_init_vcpu(CPUState *cs) + c = &cpuid_data.entries[cpuid_i++]; + } + break; +- case 0x7: + case 0x12: + for (j = 0; ; j++) { + c->function = i; +@@ -1975,6 +1974,7 @@ int kvm_arch_init_vcpu(CPUState *cs) + c = &cpuid_data.entries[cpuid_i++]; + } + break; ++ case 0x7: + case 0x14: + case 0x1d: + case 0x1e: { +-- +2.27.0 + diff --git a/log-Add-some-logs-on-VM-runtime-path.patch b/log-Add-some-logs-on-VM-runtime-path.patch new file mode 100644 index 0000000000000000000000000000000000000000..b72b9bd9a8ec1fa44eab197f4a5864c0b93e5e40 --- /dev/null +++ b/log-Add-some-logs-on-VM-runtime-path.patch @@ -0,0 +1,171 @@ +From 9d683f1ea8961d89cececf1fdc3345663744067f Mon Sep 17 00:00:00 2001 +From: Yan Wang +Date: Tue, 8 Feb 2022 15:48:01 +0800 +Subject: [PATCH] log: Add some logs on VM runtime path + +Add logs on VM runtime path, to make it easier to do trouble shooting. + +Signed-off-by: Ying Fang +Signed-off-by: Yan Wang +Signed-off-by: Adttil +--- + hw/virtio/virtio-pci.c | 2 ++ + hw/virtio/virtio.c | 14 ++++++++++++-- + monitor/monitor.c | 9 +++++++++ + qapi/qmp-dispatch.c | 15 +++++++++++++++ + system/qdev-monitor.c | 4 +++- + 5 files changed, 41 insertions(+), 3 deletions(-) + +diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c +index e433879542..134a8eaef6 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -2082,7 +2082,9 @@ static void virtio_pci_device_unplugged(DeviceState *d) + VirtIOPCIProxy *proxy = VIRTIO_PCI(d); + bool modern = virtio_pci_modern(proxy); + bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + ++ qemu_log("unplug device name: %s\n", !vdev ? "NULL" : vdev->name); + virtio_pci_stop_ioeventfd(proxy); + + if (modern) { +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 3a160f86ed..a9aa0c4f66 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2048,7 +2048,14 @@ int virtio_set_status(VirtIODevice *vdev, uint8_t val) + k->set_status(vdev, val); + } + vdev->status = val; +- ++ if (val) { ++ qemu_log("%s device status is %d that means %s\n", ++ vdev->name, val, ++ (val & VIRTIO_CONFIG_S_DRIVER_OK) ? "DRIVER OK" : ++ (val & VIRTIO_CONFIG_S_DRIVER) ? "DRIVER" : ++ (val & VIRTIO_CONFIG_S_ACKNOWLEDGE) ? "ACKNOWLEDGE" : ++ (val & VIRTIO_CONFIG_S_FAILED) ? "FAILED" : "UNKNOWN"); ++ } + return 0; + } + +@@ -2326,8 +2333,11 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, + break; + } + +- if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) ++ if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) { ++ qemu_log("unacceptable queue_size (%d) or num (%d)\n", ++ queue_size, i); + abort(); ++ } + + vdev->vq[i].vring.num = queue_size; + vdev->vq[i].vring.num_default = queue_size; +diff --git a/monitor/monitor.c b/monitor/monitor.c +index 01ede1babd..e540c1334a 100644 +--- a/monitor/monitor.c ++++ b/monitor/monitor.c +@@ -29,6 +29,7 @@ + #include "qapi/qapi-emit-events.h" + #include "qapi/qapi-visit-control.h" + #include "qapi/qmp/qdict.h" ++#include "qapi/qmp/qjson.h" + #include "qemu/error-report.h" + #include "qemu/option.h" + #include "sysemu/qtest.h" +@@ -338,6 +339,7 @@ static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict) + { + Monitor *mon; + MonitorQMP *qmp_mon; ++ GString *json; + + trace_monitor_protocol_event_emit(event, qdict); + QTAILQ_FOREACH(mon, &mon_list, entry) { +@@ -348,6 +350,13 @@ static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict) + qmp_mon = container_of(mon, MonitorQMP, common); + if (qmp_mon->commands != &qmp_cap_negotiation_commands) { + qmp_send_response(qmp_mon, qdict); ++ json = qobject_to_json(QOBJECT(qdict)); ++ if (json) { ++ if (!strstr(json->str, "RTC_CHANGE")) { ++ qemu_log("%s\n", json->str); ++ } ++ g_string_free(json, true); ++ } + } + } + } +diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c +index 555528b6bb..7a215cbfd7 100644 +--- a/qapi/qmp-dispatch.c ++++ b/qapi/qmp-dispatch.c +@@ -24,6 +24,7 @@ + #include "qapi/qmp/qbool.h" + #include "qemu/coroutine.h" + #include "qemu/main-loop.h" ++#include "qemu/log.h" + + Visitor *qobject_input_visitor_new_qmp(QObject *obj) + { +@@ -146,6 +147,7 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ + QObject *id; + QObject *ret = NULL; + QDict *rsp = NULL; ++ GString *json; + + dict = qobject_to(QDict, request); + if (!dict) { +@@ -203,6 +205,19 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ + qobject_ref(args); + } + ++ json = qobject_to_json(QOBJECT(args)); ++ if (json) { ++ if ((strcmp(command, "query-block-jobs") != 0) ++ && (strcmp(command, "query-migrate") != 0) ++ && (strcmp(command, "query-blockstats") != 0) ++ && (strcmp(command, "query-balloon") != 0) ++ && (strcmp(command, "set_password") != 0)) { ++ qemu_log("qmp_cmd_name: %s, arguments: %s\n", ++ command, json->str); ++ } ++ g_string_free(json, true); ++ } ++ + assert(!(oob && qemu_in_coroutine())); + assert(monitor_cur() == NULL); + if (!!(cmd->options & QCO_COROUTINE) == qemu_in_coroutine()) { +diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c +index a13db763e5..c885175b66 100644 +--- a/system/qdev-monitor.c ++++ b/system/qdev-monitor.c +@@ -36,6 +36,7 @@ + #include "qemu/option.h" + #include "qemu/qemu-print.h" + #include "qemu/option_int.h" ++#include "qemu/log.h" + #include "sysemu/block-backend.h" + #include "migration/misc.h" + #include "migration/migration.h" +@@ -643,6 +644,7 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, + if (path != NULL) { + bus = qbus_find(path, errp); + if (!bus) { ++ error_setg(errp, "can not find bus for %s", driver); + return NULL; + } + if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) { +@@ -715,7 +717,7 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, + if (*errp) { + goto err_del_dev; + } +- ++ qemu_log("add qdev %s:%s success\n", driver, dev->id ? dev->id : "none"); + if (!qdev_realize(dev, bus, errp)) { + goto err_del_dev; + } +-- +2.27.0 + diff --git a/pcie_sriov-Validate-NumVFs-CVE-2024-26327.patch b/pcie_sriov-Validate-NumVFs-CVE-2024-26327.patch new file mode 100644 index 0000000000000000000000000000000000000000..015ba30eb31cfadfcbd25abccb7a00172f29dabe --- /dev/null +++ b/pcie_sriov-Validate-NumVFs-CVE-2024-26327.patch @@ -0,0 +1,37 @@ +From 632ec38ed57b76baf3e499d1789aeea0f74df0a5 Mon Sep 17 00:00:00 2001 +From: Akihiko Odaki +Date: Wed, 28 Feb 2024 20:33:13 +0900 +Subject: [PATCH] pcie_sriov: Validate NumVFs (CVE-2024-26327) + +The guest may write NumVFs greater than TotalVFs and that can lead +to buffer overflow in VF implementations. + +Cc: qemu-stable@nongnu.org +Fixes: CVE-2024-26327 +Fixes: 7c0fa8dff811 ("pcie: Add support for Single Root I/O Virtualization (SR/IOV)") +Signed-off-by: Akihiko Odaki +Message-Id: <20240228-reuse-v8-2-282660281e60@daynix.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Sriram Yagnaraman +--- + hw/pci/pcie_sriov.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c +index a1fe65f5d8..da209b7f47 100644 +--- a/hw/pci/pcie_sriov.c ++++ b/hw/pci/pcie_sriov.c +@@ -176,6 +176,9 @@ static void register_vfs(PCIDevice *dev) + + assert(sriov_cap > 0); + num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF); ++ if (num_vfs > pci_get_word(dev->config + sriov_cap + PCI_SRIOV_TOTAL_VF)) { ++ return; ++ } + + dev->exp.sriov_pf.vf = g_new(PCIDevice *, num_vfs); + +-- +2.27.0 + diff --git a/qapi-block-core-Add-retry-option-for-error-action.patch b/qapi-block-core-Add-retry-option-for-error-action.patch new file mode 100644 index 0000000000000000000000000000000000000000..43154aecf644f1c2e98b9cbe795ab335488d3724 --- /dev/null +++ b/qapi-block-core-Add-retry-option-for-error-action.patch @@ -0,0 +1,63 @@ +From cfc15dc456126a6fb811f0c51af8d8ce5c4a4a1b Mon Sep 17 00:00:00 2001 +From: yexiao +Date: Thu, 21 Jan 2021 15:46:45 +0800 +Subject: [PATCH] qapi/block-core: Add retry option for error action + +Add a new error action 'retry' to support retry on errors. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + blockdev.c | 2 ++ + qapi/block-core.json | 8 ++++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/blockdev.c b/blockdev.c +index c91f49e7b6..2817f73fad 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -326,6 +326,8 @@ static int parse_block_error_action(const char *buf, bool is_read, Error **errp) + return BLOCKDEV_ON_ERROR_STOP; + } else if (!strcmp(buf, "report")) { + return BLOCKDEV_ON_ERROR_REPORT; ++ } else if (!strcmp(buf, "retry")) { ++ return BLOCKDEV_ON_ERROR_RETRY; + } else { + error_setg(errp, "'%s' invalid %s error action", + buf, is_read ? "read" : "write"); +diff --git a/qapi/block-core.json b/qapi/block-core.json +index 1444624590..ded6f0f6d2 100644 +--- a/qapi/block-core.json ++++ b/qapi/block-core.json +@@ -1286,10 +1286,12 @@ + # + # @auto: inherit the error handling policy of the backend (since: 2.7) + # ++# @retry: retrying IO with errors ++# + # Since: 1.3 + ## + { 'enum': 'BlockdevOnError', +- 'data': ['report', 'ignore', 'enospc', 'stop', 'auto'] } ++ 'data': ['report', 'ignore', 'enospc', 'stop', 'auto', 'retry'] } + + ## + # @MirrorSyncMode: +@@ -5480,10 +5482,12 @@ + # + # @stop: error caused VM to be stopped + # ++# @retry: retry IO with errors ++# + # Since: 2.1 + ## + { 'enum': 'BlockErrorAction', +- 'data': [ 'ignore', 'report', 'stop' ] } ++ 'data': [ 'ignore', 'report', 'stop', 'retry' ] } + + ## + # @BLOCK_IMAGE_CORRUPTED: +-- +2.27.0 + diff --git a/qemu-img-add-qemu-img-direct-create.patch b/qemu-img-add-qemu-img-direct-create.patch new file mode 100644 index 0000000000000000000000000000000000000000..74fcf3bf7c9b41789da4d4d6c06fcd059e4272ec --- /dev/null +++ b/qemu-img-add-qemu-img-direct-create.patch @@ -0,0 +1,534 @@ +From 422ac7d67a7ced985b1beef4b33cc43b48d1f240 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Mon, 18 Mar 2024 10:18:07 +0800 +Subject: [PATCH] qemu-img: add qemu-img direct create + +Introdue buffer_size while creating raw file, then we +can controll the speed of direct write by: + qemu-img create -t 'cache' -o buffer_size='num' + +Signed-off-by: Jinhua Cao +--- + block/file-posix.c | 65 ++++++++++++++++++-- + include/block/block_int-common.h | 2 + + qapi/block-core.json | 6 +- + qemu-img-cmds.hx | 4 +- + qemu-img.c | 14 ++++- + tests/qemu-iotests/049.out | 102 +++++++++++++++---------------- + tests/qemu-iotests/099.out | 2 +- + 7 files changed, 134 insertions(+), 61 deletions(-) + +diff --git a/block/file-posix.c b/block/file-posix.c +index 4782aba59f..4ac8f684f1 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -128,6 +128,10 @@ + #define FTYPE_CD 1 + + #define MAX_BLOCKSIZE 4096 ++#define DEFAULT_BUFFER_SIZE 65536 ++#define BUFFER_ALIGN_SIZE 65536 ++#define MIN_BUFFER_SIZE 65536 ++#define MAX_BUFFER_SIZE 16777216 + + /* Posix file locking bytes. Libvirt takes byte 0, we start from higher bytes, + * leaving a few more bytes for its future use. */ +@@ -203,6 +207,8 @@ typedef struct RawPosixAIOData { + off_t aio_offset; + uint64_t aio_nbytes; + ++ size_t buffer_size; ++ + union { + struct { + struct iovec *iov; +@@ -2630,7 +2636,8 @@ static void raw_close(BlockDriverState *bs) + */ + static int coroutine_fn + raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset, +- PreallocMode prealloc, Error **errp) ++ PreallocMode prealloc, size_t buffer_size, ++ Error **errp) + { + RawPosixAIOData acb; + +@@ -2639,6 +2646,7 @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset, + .aio_fildes = fd, + .aio_type = QEMU_AIO_TRUNCATE, + .aio_offset = offset, ++ .buffer_size = buffer_size, + .truncate = { + .prealloc = prealloc, + .errp = errp, +@@ -2664,7 +2672,8 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset, + + if (S_ISREG(st.st_mode)) { + /* Always resizes to the exact @offset */ +- return raw_regular_truncate(bs, s->fd, offset, prealloc, errp); ++ return raw_regular_truncate(bs, s->fd, offset, prealloc, ++ DEFAULT_BUFFER_SIZE, errp); + } + + if (prealloc != PREALLOC_MODE_OFF) { +@@ -2882,6 +2891,8 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) + int fd; + uint64_t perm, shared; + int result = 0; ++ int flags = O_RDWR | O_BINARY; ++ size_t buffer_size = DEFAULT_BUFFER_SIZE; + + /* Validate options and set default values */ + assert(options->driver == BLOCKDEV_DRIVER_FILE); +@@ -2901,9 +2912,19 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) + error_setg(errp, "Extent size hint is too large"); + goto out; + } ++ if (!file_opts->cache) { ++ file_opts->cache = g_strdup("writeback"); ++ } ++ if (file_opts->preallocation == PREALLOC_MODE_FULL && ++ !strcmp(file_opts->cache, "none")) { ++ flags |= O_DIRECT; ++ } ++ if (file_opts->has_buffersize) { ++ buffer_size = file_opts->buffersize; ++ } + + /* Create file */ +- fd = qemu_create(file_opts->filename, O_RDWR | O_BINARY, 0644, errp); ++ fd = qemu_create(file_opts->filename, flags, 0644, errp); + if (fd < 0) { + result = -errno; + goto out; +@@ -2938,7 +2959,8 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) + } + + /* Clear the file by truncating it to 0 */ +- result = raw_regular_truncate(NULL, fd, 0, PREALLOC_MODE_OFF, errp); ++ result = raw_regular_truncate(NULL, fd, 0, PREALLOC_MODE_OFF, ++ buffer_size, errp); + if (result < 0) { + goto out_unlock; + } +@@ -2982,7 +3004,8 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) + /* Resize and potentially preallocate the file to the desired + * final size */ + result = raw_regular_truncate(NULL, fd, file_opts->size, +- file_opts->preallocation, errp); ++ file_opts->preallocation, ++ buffer_size, errp); + if (result < 0) { + goto out_unlock; + } +@@ -3003,6 +3026,8 @@ out_close: + error_setg_errno(errp, -result, "Could not close the new file"); + } + out: ++ g_free(file_opts->cache); ++ file_opts->cache = NULL; + return result; + } + +@@ -3018,6 +3043,8 @@ raw_co_create_opts(BlockDriver *drv, const char *filename, + PreallocMode prealloc; + char *buf = NULL; + Error *local_err = NULL; ++ size_t buffersize = DEFAULT_BUFFER_SIZE; ++ char *cache = NULL; + + /* Skip file: protocol prefix */ + strstart(filename, "file:", &filename); +@@ -3040,6 +3067,21 @@ raw_co_create_opts(BlockDriver *drv, const char *filename, + return -EINVAL; + } + ++ buffersize = qemu_opt_get_size_del(opts, BLOCK_OPT_BUFFER_SIZE, ++ DEFAULT_BUFFER_SIZE); ++ if (buffersize < MIN_BUFFER_SIZE || buffersize > MAX_BUFFER_SIZE) { ++ error_setg_errno(errp, EINVAL, "Buffer size must be between %d " ++ "and %d", MIN_BUFFER_SIZE, MAX_BUFFER_SIZE); ++ return -EINVAL; ++ } ++ ++ cache = qemu_opt_get_del(opts, BLOCK_OPT_CACHE); ++ if (!cache) { ++ cache = g_strdup("writeback"); ++ } ++ ++ buffersize = ROUND_UP(buffersize, BUFFER_ALIGN_SIZE); ++ + options = (BlockdevCreateOptions) { + .driver = BLOCKDEV_DRIVER_FILE, + .u.file = { +@@ -3051,6 +3093,9 @@ raw_co_create_opts(BlockDriver *drv, const char *filename, + .nocow = nocow, + .has_extent_size_hint = has_extent_size_hint, + .extent_size_hint = extent_size_hint, ++ .has_buffersize = true, ++ .buffersize = buffersize, ++ .cache = cache, + }, + }; + return raw_co_create(&options, errp); +@@ -3741,6 +3786,16 @@ static QemuOptsList raw_create_opts = { + .type = QEMU_OPT_SIZE, + .help = "Extent size hint for the image file, 0 to disable" + }, ++ { ++ .name = BLOCK_OPT_CACHE, ++ .type = QEMU_OPT_STRING, ++ .help = "Cache mode (allowed values: writeback, none)" ++ }, ++ { ++ .name = BLOCK_OPT_BUFFER_SIZE, ++ .type = QEMU_OPT_SIZE, ++ .help = "write buffer size" ++ }, + { /* end of list */ } + } + }; +diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h +index 4e31d161c5..a6e2436524 100644 +--- a/include/block/block_int-common.h ++++ b/include/block/block_int-common.h +@@ -57,6 +57,8 @@ + #define BLOCK_OPT_DATA_FILE_RAW "data_file_raw" + #define BLOCK_OPT_COMPRESSION_TYPE "compression_type" + #define BLOCK_OPT_EXTL2 "extended_l2" ++#define BLOCK_OPT_CACHE "cache" ++#define BLOCK_OPT_BUFFER_SIZE "buffer_size" + + #define BLOCK_PROBE_BUF_SIZE 512 + +diff --git a/qapi/block-core.json b/qapi/block-core.json +index ca390c5700..1444624590 100644 +--- a/qapi/block-core.json ++++ b/qapi/block-core.json +@@ -4906,6 +4906,8 @@ + # + # @extent-size-hint: Extent size hint to add to the image file; 0 for + # not adding an extent size hint (default: 1 MB, since 5.1) ++# @cache: Cache mode used to write the output disk image ++# @buffersize: Buffer size for creating image + # + # Since: 2.12 + ## +@@ -4914,7 +4916,9 @@ + 'size': 'size', + '*preallocation': 'PreallocMode', + '*nocow': 'bool', +- '*extent-size-hint': 'size'} } ++ '*extent-size-hint': 'size', ++ '*cache': 'str', ++ '*buffersize': 'size'} } + + ## + # @BlockdevCreateOptionsGluster: +diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx +index 068692d13e..20bdcd7b82 100644 +--- a/qemu-img-cmds.hx ++++ b/qemu-img-cmds.hx +@@ -52,9 +52,9 @@ SRST + ERST + + DEF("create", img_create, +- "create [--object objectdef] [-q] [-f fmt] [-b backing_file [-F backing_fmt]] [-u] [-o options] filename [size]") ++ "create [--object objectdef] [-q] [-f fmt] [-b backing_file [-F backing_fmt]] [-u] [-t cache] [-o options] filename [size]") + SRST +-.. option:: create [--object OBJECTDEF] [-q] [-f FMT] [-b BACKING_FILE [-F BACKING_FMT]] [-u] [-o OPTIONS] FILENAME [SIZE] ++.. option:: create [--object OBJECTDEF] [-q] [-f FMT] [-b BACKING_FILE [-F BACKING_FMT]] [-u] [-t CACHE] [-o OPTIONS] FILENAME [SIZE] + ERST + + DEF("dd", img_dd, +diff --git a/qemu-img.c b/qemu-img.c +index 5a77f67719..80adee2620 100644 +--- a/qemu-img.c ++++ b/qemu-img.c +@@ -516,6 +516,7 @@ static int img_create(int argc, char **argv) + const char *base_fmt = NULL; + const char *filename; + const char *base_filename = NULL; ++ const char *cache = BDRV_DEFAULT_CACHE; + char *options = NULL; + Error *local_err = NULL; + bool quiet = false; +@@ -527,7 +528,7 @@ static int img_create(int argc, char **argv) + {"object", required_argument, 0, OPTION_OBJECT}, + {0, 0, 0, 0} + }; +- c = getopt_long(argc, argv, ":F:b:f:ho:qu", ++ c = getopt_long(argc, argv, ":F:b:f:t:ho:qu", + long_options, NULL); + if (c == -1) { + break; +@@ -551,6 +552,9 @@ static int img_create(int argc, char **argv) + case 'f': + fmt = optarg; + break; ++ case 't': ++ cache = optarg; ++ break; + case 'o': + if (accumulate_options(&options, optarg) < 0) { + goto fail; +@@ -594,6 +598,14 @@ static int img_create(int argc, char **argv) + error_exit("Unexpected argument: %s", argv[optind]); + } + ++ if (!options) { ++ options = g_strdup_printf(BLOCK_OPT_CACHE"=%s", cache); ++ } else { ++ char *old_options = options; ++ options = g_strdup_printf("%s,"BLOCK_OPT_CACHE"=%s", options, cache); ++ g_free(old_options); ++ } ++ + bdrv_img_create(filename, fmt, base_filename, base_fmt, + options, img_size, flags, quiet, &local_err); + if (local_err) { +diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out +index 34e1b452e6..b4a9705ec2 100644 +--- a/tests/qemu-iotests/049.out ++++ b/tests/qemu-iotests/049.out +@@ -4,90 +4,90 @@ QA output created by 049 + == 1. Traditional size parameter == + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024b +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1k +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1K +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1G +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1T +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0b +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5k +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5K +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5G +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5T +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16 cache=writeback + + == 2. Specifying size via -o == + + qemu-img create -f qcow2 -o size=1024 TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1024b TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1k TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1K TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1M TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1G TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1T TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1024.0 TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1024.0b TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1.5k TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1.5K TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1.5M TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1.5G TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o size=1.5T TEST_DIR/t.qcow2 +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16 cache=writeback + + == 3. Invalid sizes == + +@@ -132,84 +132,84 @@ qemu-img: TEST_DIR/t.qcow2: The image size must be specified only once + == Check correct interpretation of suffixes for cluster size == + + qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o cluster_size=1024b TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o cluster_size=1k TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o cluster_size=1K TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o cluster_size=1M TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1048576 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1048576 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o cluster_size=1024.0 TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o cluster_size=1024.0b TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o cluster_size=0.5k TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o cluster_size=0.5K TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o cluster_size=0.5M TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=524288 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=524288 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + == Check compat level option == + + qemu-img create -f qcow2 -o compat=0.10 TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.42 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.42 lazy_refcounts=off refcount_bits=16 cache=writeback + qemu-img: TEST_DIR/t.qcow2: Parameter 'version' does not accept value '0.42' + + qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=foobar lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=foobar lazy_refcounts=off refcount_bits=16 cache=writeback + qemu-img: TEST_DIR/t.qcow2: Parameter 'version' does not accept value 'foobar' + + == Check preallocation option == + + qemu-img create -f qcow2 -o preallocation=off TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=metadata compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=metadata compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=1234 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=1234 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + qemu-img: TEST_DIR/t.qcow2: Parameter 'preallocation' does not accept value '1234' + + == Check encryption option == + + qemu-img create -f qcow2 -o encryption=off TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=off cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=off cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=on encrypt.key-secret=sec0 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=on encrypt.key-secret=sec0 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback + + == Check lazy_refcounts option (only with v3) == + + qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=off TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=on TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=on refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=on refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16 cache=writeback + + qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M +-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=on refcount_bits=16 ++Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=on refcount_bits=16 cache=writeback + qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater) + + == Expect error when backing file name is empty string == +diff --git a/tests/qemu-iotests/099.out b/tests/qemu-iotests/099.out +index 8cce627529..f6f8f25957 100644 +--- a/tests/qemu-iotests/099.out ++++ b/tests/qemu-iotests/099.out +@@ -1,6 +1,6 @@ + QA output created by 099 + Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 +-Formatting 'TEST_DIR/t.IMGFMT.compare', fmt=raw size=131072 ++Formatting 'TEST_DIR/t.IMGFMT.compare', fmt=raw size=131072 cache=writeback + + === Testing simple filename for blkverify === + +-- +2.27.0 + diff --git a/qemu-img-block-set-zero-flags-only-when-discard_zero.patch b/qemu-img-block-set-zero-flags-only-when-discard_zero.patch new file mode 100644 index 0000000000000000000000000000000000000000..ba0731826712ba76c9e5310686060f4c03334b12 --- /dev/null +++ b/qemu-img-block-set-zero-flags-only-when-discard_zero.patch @@ -0,0 +1,33 @@ +From 48c792a802c8cb0ab670ddf92920e2e5e96747a4 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Mon, 18 Mar 2024 10:04:42 +0800 +Subject: [PATCH] qemu-img block: set zero flags only when discard_zeros of the + block supported + +zero flags set for block discard_zeros, only when the block support +discard_zeros need set these flags. + +old commit info: + qemu-img: block: dont blk_make_zero if discard_zeroes false + +Signed-off-by: Jinhua Cao +--- + block/file-posix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block/file-posix.c b/block/file-posix.c +index 01ae5fd88c..4782aba59f 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -822,7 +822,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, + #endif + s->needs_alignment = raw_needs_alignment(bs); + +- bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK; ++ bs->supported_zero_flags = s->discard_zeroes ? (BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) : 0; + if (S_ISREG(st.st_mode)) { + /* When extending regular files, we get zeros from the OS */ + bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE; +-- +2.27.0 + diff --git a/qemu-img-create-cache-paramter-only-use-for-reg-file.patch b/qemu-img-create-cache-paramter-only-use-for-reg-file.patch new file mode 100644 index 0000000000000000000000000000000000000000..6ff2ad0369356c14587fdcebd0fd89379f14a03e --- /dev/null +++ b/qemu-img-create-cache-paramter-only-use-for-reg-file.patch @@ -0,0 +1,66 @@ +From 9ca9391acb780f15a6d8769339e7cd0edf457529 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 24 Mar 2022 17:12:49 +0800 +Subject: [PATCH] qemu-img create: 'cache' paramter only use for reg file image + +The paramter 'cache' is invalid for host device(/dev/xxx). If +'qemu-img create' operator performed on host device, the host +device not support 'cache' would result 'qemu-img create' execute +failed. + +Signed-off-by: Jinhua Cao +--- + qemu-img.c | 30 ++++++++++++++++++++++++------ + 1 file changed, 24 insertions(+), 6 deletions(-) + +diff --git a/qemu-img.c b/qemu-img.c +index 80adee2620..49d914c9c4 100644 +--- a/qemu-img.c ++++ b/qemu-img.c +@@ -508,6 +508,22 @@ static int64_t cvtnum(const char *name, const char *value) + return cvtnum_full(name, value, 0, INT64_MAX); + } + ++static bool is_reg_file(const char *filename) ++{ ++ struct stat st; ++ ++ /* file not exist, file will be create later, so it's a reg file */ ++ if (access(filename, F_OK) == -1) { ++ return true; ++ } ++ ++ /* file exist, check file type */ ++ if (stat(filename, &st) >= 0 && S_ISREG(st.st_mode)) { ++ return true; ++ } ++ return false; ++} ++ + static int img_create(int argc, char **argv) + { + int c; +@@ -598,12 +614,14 @@ static int img_create(int argc, char **argv) + error_exit("Unexpected argument: %s", argv[optind]); + } + +- if (!options) { +- options = g_strdup_printf(BLOCK_OPT_CACHE"=%s", cache); +- } else { +- char *old_options = options; +- options = g_strdup_printf("%s,"BLOCK_OPT_CACHE"=%s", options, cache); +- g_free(old_options); ++ if (is_reg_file(filename)) { ++ if (!options) { ++ options = g_strdup_printf(BLOCK_OPT_CACHE"=%s", cache); ++ } else { ++ char *old_options = options; ++ options = g_strdup_printf("%s,"BLOCK_OPT_CACHE"=%s", options, cache); ++ g_free(old_options); ++ } + } + + bdrv_img_create(filename, fmt, base_filename, base_fmt, +-- +2.27.0 + diff --git a/qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch b/qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch new file mode 100644 index 0000000000000000000000000000000000000000..0d5329a2c14576a2a4c1b42e169641606e07c01d --- /dev/null +++ b/qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch @@ -0,0 +1,37 @@ +From 48f32788794e061ab0b359fe194c964849bb3040 Mon Sep 17 00:00:00 2001 +From: WangJian +Date: Wed, 9 Feb 2022 11:10:42 +0800 +Subject: [PATCH] qemu-pr: fixed ioctl failed for multipath disk + +We use ioctl to detect multipath devices. However, we only set flags in +struct dm_ioctl (the argument to ioctl) and left other fields in random, +which may cause the failure of calling ioctl. Hence, we set other +fields to 0 to avoid the failure. + +Signed-off-by: wangjian161 +Signed-off-by: shaodenghui +--- + scsi/qemu-pr-helper.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c +index c6c6347e9b..655404fd07 100644 +--- a/scsi/qemu-pr-helper.c ++++ b/scsi/qemu-pr-helper.c +@@ -285,9 +285,12 @@ static void multipath_pr_init(void) + + static int is_mpath(int fd) + { +- struct dm_ioctl dm = { .flags = DM_NOFLUSH_FLAG }; ++ struct dm_ioctl dm; + struct dm_target_spec *tgt; + ++ memset(&dm, 0, sizeof(struct dm_ioctl)); ++ dm.flags = DM_NOFLUSH_FLAG; ++ + tgt = dm_dev_ioctl(fd, DM_TABLE_STATUS, &dm); + if (!tgt) { + if (errno == ENXIO) { +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index f9825b33c91c5c7e83f0ee24000055abb538e090..477aa56303c4704084b4ae28262f51571c22f231 100644 --- a/qemu.spec +++ b/qemu.spec @@ -3,7 +3,7 @@ Name: qemu Version: 8.2.0 -Release: 1 +Release: 2 Epoch: 11 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -14,6 +14,57 @@ Source2: 99-qemu-guest-agent.rules Source3: bridge.conf Source4: BinDir.tar.gz +Patch0001: tests-qemu-iotests-resolved-the-problem-that-the-108.patch +Patch0002: hw-usb-Style-cleanup.patch +Patch0003: virtio-gpu-Correct-virgl_renderer_resource_get_info-.patch +Patch0004: blkio-Respect-memory-alignment-for-bounce-buffer-all.patch +Patch0005: i386-cpu-Clear-FEAT_XSAVE_XSS_LO-HI-leafs-when-CPUID.patch +Patch0006: i386-cpu-Mask-with-XCR0-XSS-mask-for-FEAT_XSAVE_XCR0.patch +Patch0007: i386-cpuid-Decrease-cpuid_i-when-skipping-CPUID-leaf.patch +Patch0008: i386-cpuid-Move-leaf-7-to-correct-group.patch +Patch0009: chardev-char-socket-Fix-TLS-io-channels-sending-too-.patch +Patch0010: vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch +Patch0011: vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch +Patch0012: vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch +Patch0013: vfio-pci-Ascend710-change-to-bar2-quirk.patch +Patch0014: hw-i2c-smbus_slave-Add-object-path-on-error-prints.patch +Patch0015: virtio-gpu-remove-needless-condition.patch +Patch0016: target-i386-sev-Fix-missing-ERRP_GUARD-for-error_pre.patch +Patch0017: hw-acpi-cpu-Use-CPUState-typedef.patch +Patch0018: hw-nvme-Use-pcie_sriov_num_vfs-CVE-2024-26328.patch +Patch0019: pcie_sriov-Validate-NumVFs-CVE-2024-26327.patch +Patch0020: Revert-file-posix-Remove-unused-s-discard_zeroes.patch +Patch0021: qemu-img-block-set-zero-flags-only-when-discard_zero.patch +Patch0022: qemu-img-add-qemu-img-direct-create.patch +Patch0023: qemu-img-create-cache-paramter-only-use-for-reg-file.patch +Patch0024: hw-cxl-cxl-host-Fix-missing-ERRP_GUARD-in-cxl_fixed_.patch +Patch0025: hw-display-macfb-Fix-missing-ERRP_GUARD-in-macfb_nub.patch +Patch0026: bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch +Patch0027: log-Add-some-logs-on-VM-runtime-path.patch +Patch0028: util-log-add-CONFIG_DISABLE_QEMU_LOG-macro.patch +Patch0029: bugfix-fix-some-illegal-memory-access-and-memory-lea.patch +Patch0030: bugfix-fix-possible-memory-leak.patch +Patch0031: scsi-disk-define-props-in-scsi_block_disk-to-avoid-m.patch +Patch0032: qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch +Patch0033: scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch +Patch0034: scsi-bugfix-fix-division-by-zero.patch +Patch0035: qapi-block-core-Add-retry-option-for-error-action.patch +Patch0036: block-backend-Introduce-retry-timer.patch +Patch0037: block-backend-Add-device-specific-retry-callback.patch +Patch0038: block-backend-Enable-retry-action-on-errors.patch +Patch0039: block-backend-Add-timeout-support-for-retry.patch +Patch0040: block-Add-error-retry-param-setting.patch +Patch0041: virtio_blk-Add-support-for-retry-on-errors.patch +Patch0042: scsi-bus-Refactor-the-code-that-retries-requests.patch +Patch0043: scsi-disk-Add-support-for-retry-on-errors.patch +Patch0044: block-backend-Stop-retrying-when-draining.patch +Patch0045: block-Add-sanity-check-when-setting-retry-parameters.patch +Patch0046: scsi-bus-fix-unmatched-object_unref.patch +Patch0047: scsi-bus-fix-incorrect-call-for-blk_error_retry_rese.patch +Patch0048: block-mirror-fix-file-system-went-to-read-only-after.patch +Patch0049: block-enable-cache-mode-of-empty-cdrom.patch +Patch0050: block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch + BuildRequires: flex BuildRequires: gcc BuildRequires: make @@ -610,5 +661,57 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Sat Mar 27 2024 Jiabo Feng - 11:8.2.0-2 +- block: bugfix: Don't pause vm when NOSPACE EIO happened +- block: enable cache mode of empty cdrom +- block/mirror: fix file-system went to read-only after block-mirror +- scsi-bus: fix incorrect call for blk_error_retry_reset_timeout() +- scsi-bus: fix unmatched object_unref() +- block: Add sanity check when setting retry parameters +- block-backend: Stop retrying when draining +- scsi-disk: Add support for retry on errors +- scsi-bus: Refactor the code that retries requests +- virtio_blk: Add support for retry on errors +- block: Add error retry param setting +- block-backend: Add timeout support for retry +- block-backend: Enable retry action on errors +- block-backend: Add device specific retry callback +- block-backend: Introduce retry timer +- qapi/block-core: Add retry option for error action +- scsi: bugfix: fix division by zero +- scsi: cdrom: Fix crash after remote cdrom detached +- qemu-pr: fixed ioctl failed for multipath disk +- scsi-disk: define props in scsi_block_disk to avoid memleaks +- bugfix: fix possible memory leak +- bugfix: fix some illegal memory access and memory leak +- util/log: add CONFIG_DISABLE_QEMU_LOG macro +- log: Add some logs on VM runtime path +- bugfix: fix eventfds may double free when vm_id reused in ivshmem +- hw/display/macfb: Fix missing ERRP_GUARD() in macfb_nubus_realize() +- hw/cxl/cxl-host: Fix missing ERRP_GUARD() in cxl_fixed_memory_window_config() +- qemu-img create: 'cache' paramter only use for reg file image +- qemu-img: add qemu-img direct create +- qemu-img block: set zero flags only when discard_zeros of the block supported +- Revert "file-posix: Remove unused s->discard_zeroes" +- pcie_sriov: Validate NumVFs (CVE-2024-26327) +- hw/nvme: Use pcie_sriov_num_vfs() (CVE-2024-26328) +- hw/acpi/cpu: Use CPUState typedef +- target/i386/sev: Fix missing ERRP_GUARD() for error_prepend() +- virtio-gpu: remove needless condition +- hw/i2c/smbus_slave: Add object path on error prints +- vfio/pci: Ascend710 change to bar2 quirk +- vfio/pci: Ascend910 need 4Bytes quirk in bar0 +- vfio/pci: Ascend710 need 4Bytes quirk in bar0 +- vfio/pci: Ascend310 need 4Bytes quirk in bar4 +- chardev/char-socket: Fix TLS io channels sending too much data to the backend +- i386/cpuid: Move leaf 7 to correct group +- i386/cpuid: Decrease cpuid_i when skipping CPUID leaf 1F +- i386/cpu: Mask with XCR0/XSS mask for FEAT_XSAVE_XCR0_HI and FEAT_XSAVE_XSS_HI leafs +- i386/cpu: Clear FEAT_XSAVE_XSS_LO/HI leafs when CPUID_EXT_XSAVE is not available +- blkio: Respect memory-alignment for bounce buffer allocations +- virtio-gpu: Correct virgl_renderer_resource_get_info() error check +- hw/usb: Style cleanup +- tests/qemu-iotests: resolved the problem that the 108 test cases in the container fail + * Thu Feb 29 2024 Tao Yang - 11:8.2.0-1 - Package init diff --git a/scsi-bugfix-fix-division-by-zero.patch b/scsi-bugfix-fix-division-by-zero.patch new file mode 100644 index 0000000000000000000000000000000000000000..4d6d18bb9d106aed5ccd724667f19a187bf41f1a --- /dev/null +++ b/scsi-bugfix-fix-division-by-zero.patch @@ -0,0 +1,58 @@ +From f2837d186532fb82ed01dbe32bdcf9dda6b06258 Mon Sep 17 00:00:00 2001 +From: WangJian +Date: Wed, 9 Feb 2022 16:34:05 +0800 +Subject: [PATCH] scsi: bugfix: fix division by zero + +Error of PRDM disk may cause divide by zero in +scsi_read_complete(), so add LOG and assert(). + +Signed-off-by: wangjian161 +Signed-off-by: shaodenghui +--- + hw/scsi/scsi-generic.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c +index 2417f0ad84..22efcd09a6 100644 +--- a/hw/scsi/scsi-generic.c ++++ b/hw/scsi/scsi-generic.c +@@ -192,6 +192,10 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len) + (r->req.cmd.buf[1] & 0x01)) { + page = r->req.cmd.buf[2]; + if (page == 0xb0 && r->buflen >= 8) { ++ if (s->blocksize == 0) { ++ qemu_log("device blocksize is 0!\n"); ++ abort(); ++ } + uint8_t buf[16] = {}; + uint8_t buf_used = MIN(r->buflen, 16); + uint64_t max_transfer = calculate_max_transfer(s); +@@ -326,11 +330,23 @@ static void scsi_read_complete(void * opaque, int ret) + /* Snoop READ CAPACITY output to set the blocksize. */ + if (r->req.cmd.buf[0] == READ_CAPACITY_10 && + (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) { +- s->blocksize = ldl_be_p(&r->buf[4]); ++ int new_blocksize = ldl_be_p(&r->buf[4]); ++ if (s->blocksize != new_blocksize) { ++ qemu_log("device id=%s type=%d: blocksize %d change to %d\n", ++ s->qdev.id ? s->qdev.id : "null", s->type, ++ s->blocksize, new_blocksize); ++ } ++ s->blocksize = new_blocksize; + s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL; + } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 && + (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) { +- s->blocksize = ldl_be_p(&r->buf[8]); ++ int new_blocksize = ldl_be_p(&r->buf[8]); ++ if (s->blocksize != new_blocksize) { ++ qemu_log("device id=%s type=%d: blocksize %d change to %d\n", ++ s->qdev.id ? s->qdev.id : "null", s->type, ++ s->blocksize, new_blocksize); ++ } ++ s->blocksize = new_blocksize; + s->max_lba = ldq_be_p(&r->buf[0]); + } + +-- +2.27.0 + diff --git a/scsi-bus-Refactor-the-code-that-retries-requests.patch b/scsi-bus-Refactor-the-code-that-retries-requests.patch new file mode 100644 index 0000000000000000000000000000000000000000..0226238a63c083bbab32c94ccc1033fec91bb3f2 --- /dev/null +++ b/scsi-bus-Refactor-the-code-that-retries-requests.patch @@ -0,0 +1,69 @@ +From d69428c793ca7311c55d0efdaa82100247e35dcc Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:54 +0800 +Subject: [PATCH] scsi-bus: Refactor the code that retries requests + +Move the code that retries requests from scsi_dma_restart_bh() to its own, +non-static, function. This will allow us to call it from the +retry_request_cb() of scsi-disk in a future patch. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + hw/scsi/scsi-bus.c | 16 +++++++++++----- + include/hw/scsi/scsi.h | 1 + + 2 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c +index fc4b77fdb0..cecb02ae7e 100644 +--- a/hw/scsi/scsi-bus.c ++++ b/hw/scsi/scsi-bus.c +@@ -144,14 +144,10 @@ void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host, + qbus_set_bus_hotplug_handler(BUS(bus)); + } + +-static void scsi_dma_restart_bh(void *opaque) ++void scsi_retry_requests(SCSIDevice *s) + { +- SCSIDevice *s = opaque; + SCSIRequest *req, *next; + +- qemu_bh_delete(s->bh); +- s->bh = NULL; +- + aio_context_acquire(blk_get_aio_context(s->conf.blk)); + QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) { + scsi_req_ref(req); +@@ -175,6 +171,16 @@ static void scsi_dma_restart_bh(void *opaque) + object_unref(OBJECT(s)); + } + ++static void scsi_dma_restart_bh(void *opaque) ++{ ++ SCSIDevice *s = opaque; ++ ++ qemu_bh_delete(s->bh); ++ s->bh = NULL; ++ ++ scsi_retry_requests(s); ++} ++ + void scsi_req_retry(SCSIRequest *req) + { + /* No need to save a reference, because scsi_dma_restart_bh just +diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h +index 3692ca82f3..6ec18bf12b 100644 +--- a/include/hw/scsi/scsi.h ++++ b/include/hw/scsi/scsi.h +@@ -226,6 +226,7 @@ void scsi_req_cancel_complete(SCSIRequest *req); + void scsi_req_cancel(SCSIRequest *req); + void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier); + void scsi_req_retry(SCSIRequest *req); ++void scsi_retry_requests(SCSIDevice *s); + void scsi_device_drained_begin(SCSIDevice *sdev); + void scsi_device_drained_end(SCSIDevice *sdev); + void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense); +-- +2.27.0 + diff --git a/scsi-bus-fix-incorrect-call-for-blk_error_retry_rese.patch b/scsi-bus-fix-incorrect-call-for-blk_error_retry_rese.patch new file mode 100644 index 0000000000000000000000000000000000000000..e6a960a3e62698688b1227110eccb7bef0b582f8 --- /dev/null +++ b/scsi-bus-fix-incorrect-call-for-blk_error_retry_rese.patch @@ -0,0 +1,81 @@ +From 60181b02c77f533105f904ab9e023bc22f65ad48 Mon Sep 17 00:00:00 2001 +From: Yan Wang +Date: Tue, 29 Mar 2022 12:05:56 +0800 +Subject: [PATCH] scsi-bus: fix incorrect call for + blk_error_retry_reset_timeout() + +Fix commit 52115ca0("scsi-disk: Add support for retry on errors"). +Call Stack: + ... + scsi_read_data() + scsi_do_read(r, 0) + scsi_disk_req_check_error() + blk_error_retry_reset_timeout() + blk->retry_start_time = 0; + +It will cause IO hang when storage network disconnected. Before the +storage network recovered, the upper call stack will reset the +retry_start_time, and cause the next IO operation not returned immediately. + +Signed-off-by: Yan Wang +Signed-off-by: shaodenghui +--- + hw/scsi/scsi-disk.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index 97d8c5bb30..845a2a7d5d 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -258,10 +258,8 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) + } + } + +-static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) ++static bool scsi_disk_req_handle_error(SCSIDiskReq *r, int ret, bool acct_failed) + { +- SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); +- + if (r->req.io_canceled) { + scsi_req_cancel_complete(&r->req); + return true; +@@ -271,6 +269,17 @@ static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) + return scsi_handle_rw_error(r, ret, acct_failed); + } + ++ return false; ++} ++ ++static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) ++{ ++ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); ++ ++ if (r->req.io_canceled || ret < 0) { ++ return scsi_disk_req_handle_error(r, ret, acct_failed); ++ } ++ + blk_error_retry_reset_timeout(s->qdev.conf.blk); + return false; + } +@@ -423,7 +432,7 @@ static void scsi_do_read(SCSIDiskReq *r, int ret) + SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s)); + + assert (r->req.aiocb == NULL); +- if (scsi_disk_req_check_error(r, ret, false)) { ++ if (scsi_disk_req_handle_error(r, ret, false)) { + goto done; + } + +@@ -464,6 +473,9 @@ static void scsi_do_read_cb(void *opaque, int ret) + block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); + } else { + block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); ++ if (!r->req.io_canceled) { ++ blk_error_retry_reset_timeout(s->qdev.conf.blk); ++ } + } + scsi_do_read(opaque, ret); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); +-- +2.27.0 + diff --git a/scsi-bus-fix-unmatched-object_unref.patch b/scsi-bus-fix-unmatched-object_unref.patch new file mode 100644 index 0000000000000000000000000000000000000000..006400c59b478b8ba5290cda83355f557053bce2 --- /dev/null +++ b/scsi-bus-fix-unmatched-object_unref.patch @@ -0,0 +1,43 @@ +From c2f55f210d4e021121865ea31037d2751188befd Mon Sep 17 00:00:00 2001 +From: Yan Wang +Date: Tue, 1 Mar 2022 20:12:12 +0800 +Subject: [PATCH] scsi-bus: fix unmatched object_unref() + +Fix commit 391dd8f1("scsi-bus: Refactor the code that retries requests"), +which split scsi_dma_restart_bh(), but the object_unref() belongs to +scsi_dma_restart_bh(). +So, we should mv object_unref() from scsi_retry_requests() to +scsi_dma_restart_bh(). + +Signed-off-by: Yan Wang +Signed-off-by: shaodenghui +--- + hw/scsi/scsi-bus.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c +index cecb02ae7e..7b60ac11f5 100644 +--- a/hw/scsi/scsi-bus.c ++++ b/hw/scsi/scsi-bus.c +@@ -167,8 +167,6 @@ void scsi_retry_requests(SCSIDevice *s) + scsi_req_unref(req); + } + aio_context_release(blk_get_aio_context(s->conf.blk)); +- /* Drop the reference that was acquired in scsi_dma_restart_cb */ +- object_unref(OBJECT(s)); + } + + static void scsi_dma_restart_bh(void *opaque) +@@ -179,6 +177,9 @@ static void scsi_dma_restart_bh(void *opaque) + s->bh = NULL; + + scsi_retry_requests(s); ++ ++ /* Drop the reference that was acquired in scsi_dma_restart_cb */ ++ object_unref(OBJECT(s)); + } + + void scsi_req_retry(SCSIRequest *req) +-- +2.27.0 + diff --git a/scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch b/scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch new file mode 100644 index 0000000000000000000000000000000000000000..70ec66267d03822265d6cabde1a71b1c845e34f1 --- /dev/null +++ b/scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch @@ -0,0 +1,36 @@ +From aac11bd40369aa31c9b3efb701242cc307ce5645 Mon Sep 17 00:00:00 2001 +From: WangJian +Date: Wed, 9 Feb 2022 11:42:47 +0800 +Subject: [PATCH] scsi: cdrom: Fix crash after remote cdrom detached + +There is a small window between the twice blk_is_available in +scsi_disk_emulate_command which would cause crash due to the later +assertion if the remote cdrom is detached in this window. + +So this patch replaces assertions with return to avoid qemu crash. + +Signed-off-by: wangjian161 +Signed-off-by: shaodenghui +--- + hw/scsi/scsi-disk.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index f638854ebf..7f581efce8 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -2021,7 +2021,10 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) + memset(outbuf, 0, r->buflen); + switch (req->cmd.buf[0]) { + case TEST_UNIT_READY: +- assert(blk_is_available(s->qdev.conf.blk)); ++ if (!blk_is_available(s->qdev.conf.blk)) { ++ scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); ++ return 0; ++ } + break; + case INQUIRY: + buflen = scsi_disk_emulate_inquiry(req, outbuf); +-- +2.27.0 + diff --git a/scsi-disk-Add-support-for-retry-on-errors.patch b/scsi-disk-Add-support-for-retry-on-errors.patch new file mode 100644 index 0000000000000000000000000000000000000000..29fbc7e5e56ecf1f121f4488f63990afa1f8aba9 --- /dev/null +++ b/scsi-disk-Add-support-for-retry-on-errors.patch @@ -0,0 +1,79 @@ +From 6100f909506025563ecec29b25f64cce75fc2353 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:55 +0800 +Subject: [PATCH] scsi-disk: Add support for retry on errors + +Mark failed requests as to be retried and implement retry_request_cb to +handle these requests. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + hw/scsi/scsi-disk.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index 6691f5edb8..97d8c5bb30 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -249,6 +249,10 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) + scsi_req_retry(&r->req); + return true; + ++ case BLOCK_ERROR_ACTION_RETRY: ++ scsi_req_retry(&r->req); ++ return true; ++ + default: + g_assert_not_reached(); + } +@@ -256,6 +260,8 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) + + static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) + { ++ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); ++ + if (r->req.io_canceled) { + scsi_req_cancel_complete(&r->req); + return true; +@@ -265,6 +271,7 @@ static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) + return scsi_handle_rw_error(r, ret, acct_failed); + } + ++ blk_error_retry_reset_timeout(s->qdev.conf.blk); + return false; + } + +@@ -2391,6 +2398,13 @@ static void scsi_disk_resize_cb(void *opaque) + } + } + ++static void scsi_disk_retry_request(void *opaque) ++{ ++ SCSIDiskState *s = opaque; ++ ++ scsi_retry_requests(&s->qdev); ++} ++ + static void scsi_cd_change_media_cb(void *opaque, bool load, Error **errp) + { + SCSIDiskState *s = opaque; +@@ -2440,12 +2454,14 @@ static const BlockDevOps scsi_disk_removable_block_ops = { + .is_medium_locked = scsi_cd_is_medium_locked, + .is_tray_open = scsi_cd_is_tray_open, + .resize_cb = scsi_disk_resize_cb, ++ .retry_request_cb = scsi_disk_retry_request, + }; + + static const BlockDevOps scsi_disk_block_ops = { + .drained_begin = scsi_disk_drained_begin, + .drained_end = scsi_disk_drained_end, + .resize_cb = scsi_disk_resize_cb, ++ .retry_request_cb = scsi_disk_retry_request, + }; + + static void scsi_disk_unit_attention_reported(SCSIDevice *dev) +-- +2.27.0 + diff --git a/scsi-disk-define-props-in-scsi_block_disk-to-avoid-m.patch b/scsi-disk-define-props-in-scsi_block_disk-to-avoid-m.patch new file mode 100644 index 0000000000000000000000000000000000000000..36e16d60cd4f5c37103032ccc77144d7b6d90d38 --- /dev/null +++ b/scsi-disk-define-props-in-scsi_block_disk-to-avoid-m.patch @@ -0,0 +1,36 @@ +From 85307e997e4ee7a50a87ac2ac218911c0058d8e3 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Mon, 13 Jan 2020 15:53:32 +0800 +Subject: [PATCH] scsi-disk: define props in scsi_block_disk to avoid memleaks + +scsi_block_realize() use scsi_realize() to init some props, but +these props is not defined in scsi_block_properties, so they will +not be freed. + +This patch defines these prop in scsi_block_disk_properties to avoid memleaks. + +Signed-off-by: Pan Nengyuan +Signed-off-by: Yan Wang +Signed-off-by: shaodenghui +--- + hw/scsi/scsi-disk.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index 6691f5edb8..f638854ebf 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -3241,9 +3241,7 @@ static const TypeInfo scsi_cd_info = { + + #ifdef __linux__ + static Property scsi_block_properties[] = { +- DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), +- DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk), +- DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false), ++ DEFINE_SCSI_DISK_PROPERTIES(), + DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), + DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size, + DEFAULT_MAX_UNMAP_SIZE), +-- +2.27.0 + diff --git a/target-i386-sev-Fix-missing-ERRP_GUARD-for-error_pre.patch b/target-i386-sev-Fix-missing-ERRP_GUARD-for-error_pre.patch new file mode 100644 index 0000000000000000000000000000000000000000..c3cffaa94a06016242e9cd7e2147676da7622321 --- /dev/null +++ b/target-i386-sev-Fix-missing-ERRP_GUARD-for-error_pre.patch @@ -0,0 +1,63 @@ +From 5a4e9ad98edc1ba5c1e93f0e24753c1a8355ffce Mon Sep 17 00:00:00 2001 +From: dinglimin +Date: Wed, 13 Mar 2024 13:49:37 +0800 +Subject: [PATCH] target/i386/sev: Fix missing ERRP_GUARD() for error_prepend() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from f55cceac8c03e639711490f08996c32861591435 +As the comment in qapi/error, passing @errp to error_prepend() requires ERRP_GUARD(): + +* = Why, when and how to use ERRP_GUARD() = +* +* Without ERRP_GUARD(), use of the @errp parameter is restricted: +... +* - It should not be passed to error_prepend(), error_vprepend() or +* error_append_hint(), because that doesn't work with &error_fatal. +* ERRP_GUARD() lifts these restrictions. +* +* To use ERRP_GUARD(), add it right at the beginning of the function. +* @errp can then be used without worrying about the argument being +* NULL or &error_fatal. + +ERRP_GUARD() could avoid the case when @errp is the pointer of +error_fatal, the user can't see this additional information, because +exit() happens in error_setg earlier than information is added [1]. + +The sev_inject_launch_secret() passes @errp to error_prepend(), and as +an APIs defined in target/i386/sev.h, it is necessary to protect its +@errp with ERRP_GUARD(). + +To avoid the issue like [1] said, add missing ERRP_GUARD() at the +beginning of this function. + +[1]: Issue description in the commit message of commit ae7c80a7bd73 + ("error: New macro ERRP_GUARD()"). + +Cc: Paolo Bonzini +Cc: Marcelo Tosatti +Signed-off-by: Zhao Liu +Reviewed-by: Thomas Huth +Message-ID: <20240229143914.1977550-17-zhao1.liu@linux.intel.com> +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: dinglimin +--- + target/i386/sev.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 9a71246682..1a9d1db7a8 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -1044,6 +1044,7 @@ sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp) + int sev_inject_launch_secret(const char *packet_hdr, const char *secret, + uint64_t gpa, Error **errp) + { ++ ERRP_GUARD(); + struct kvm_sev_launch_secret input; + g_autofree guchar *data = NULL, *hdr = NULL; + int error, ret = 1; +-- +2.27.0 + diff --git a/tests-qemu-iotests-resolved-the-problem-that-the-108.patch b/tests-qemu-iotests-resolved-the-problem-that-the-108.patch new file mode 100644 index 0000000000000000000000000000000000000000..f4a3c54f52e349b6d5cb2fd66b8af8dd0387e8ce --- /dev/null +++ b/tests-qemu-iotests-resolved-the-problem-that-the-108.patch @@ -0,0 +1,31 @@ +From d95cbdd8738d61b8bc7c9a1541dade42c1f48314 Mon Sep 17 00:00:00 2001 +From: adttil <2429917001@qq.com> +Date: Thu, 1 Feb 2024 21:53:58 +0800 +Subject: [PATCH] tests/qemu-iotests: resolved the problem that the 108 test + cases in the container fail + +The loop device cannot be created in the compilation environment of the +container. Therefore, a judgment condition is added to the +initialization variable loopdev to check whether loop-control exists. + +Signed-off-by: Adttil <2429917001@qq.com> +--- + tests/qemu-iotests/108 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/qemu-iotests/108 b/tests/qemu-iotests/108 +index 54e935acf2..a6fe261265 100755 +--- a/tests/qemu-iotests/108 ++++ b/tests/qemu-iotests/108 +@@ -55,7 +55,7 @@ _supported_os Linux + _unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file + + # This test either needs sudo -n losetup or FUSE exports to work +-if sudo -n losetup &>/dev/null; then ++if test -c "/dev/loop-control" && sudo -n losetup &>/dev/null; then + loopdev=true + else + loopdev=false +-- +2.27.0 + diff --git a/util-log-add-CONFIG_DISABLE_QEMU_LOG-macro.patch b/util-log-add-CONFIG_DISABLE_QEMU_LOG-macro.patch new file mode 100644 index 0000000000000000000000000000000000000000..82e2884cba6131390119bf688ee0452887236b86 --- /dev/null +++ b/util-log-add-CONFIG_DISABLE_QEMU_LOG-macro.patch @@ -0,0 +1,42 @@ +From 28763d8df34c20cab60baec8f4f5615cbea8c0df Mon Sep 17 00:00:00 2001 +From: Yan Wang +Date: Fri, 11 Feb 2022 18:20:59 +0800 +Subject: [PATCH] util/log: add CONFIG_DISABLE_QEMU_LOG macro + +Using CONFIG_DISABLE_QEMU_LOG macro to control +qemu_log function. + +Signed-off-by: Yan Wang +Signed-off-by: Adttil +--- + util/log.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/util/log.c b/util/log.c +index d36c98da0b..78b6cf225f 100644 +--- a/util/log.c ++++ b/util/log.c +@@ -143,6 +143,12 @@ void qemu_log_unlock(FILE *logfile) + } + } + ++#ifdef CONFIG_DISABLE_QEMU_LOG ++void qemu_log(const char *fmt, ...) ++{ ++ return; ++} ++#else + void qemu_log(const char *fmt, ...) + { + FILE *f = qemu_log_trylock(); +@@ -155,6 +161,7 @@ void qemu_log(const char *fmt, ...) + qemu_log_unlock(f); + } + } ++#endif + + static void __attribute__((__constructor__)) startup(void) + { +-- +2.27.0 + diff --git a/vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch b/vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch new file mode 100644 index 0000000000000000000000000000000000000000..6fb6caafbd47feb499b800928e889985a942f545 --- /dev/null +++ b/vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch @@ -0,0 +1,105 @@ +From 9558ea5d0bded6c9189adf2ce317cca205604c15 Mon Sep 17 00:00:00 2001 +From: Binfeng Wu +Date: Tue, 8 Feb 2022 17:00:39 +0800 +Subject: [PATCH] vfio/pci: Ascend310 need 4Bytes quirk in bar4 + +--- + hw/vfio/pci-quirks.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 75 insertions(+) + +diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c +index 84b1a7b948..8fb190ce3c 100644 +--- a/hw/vfio/pci-quirks.c ++++ b/hw/vfio/pci-quirks.c +@@ -1209,6 +1209,80 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, + return 0; + } + ++#define PCI_VENDOR_ID_HUAWEI 0x19e5 ++#define PCI_DEVICE_ID_ASCEND310 0xd100 ++#define ASCEND310_XLOADER_SIZE 4 ++#define ASCEND310_XLOADER_OFFSET 0x400 ++ ++typedef struct VFIOAscendBarQuirk { ++ struct VFIOPCIDevice *vdev; ++ pcibus_t offset; ++ uint8_t bar; ++ MemoryRegion *mem; ++} VFIOAscendBarQuirk; ++ ++static uint64_t vfio_ascend_quirk_read(void *opaque, ++ hwaddr addr, unsigned size) ++{ ++ VFIOAscendBarQuirk *quirk = opaque; ++ VFIOPCIDevice *vdev = quirk->vdev; ++ ++ qemu_log("read RO region! addr=0x%" HWADDR_PRIx ", size=%d\n", ++ addr + quirk->offset, size); ++ ++ return vfio_region_read(&vdev->bars[quirk->bar].region, ++ addr + quirk->offset, size); ++} ++ ++static void vfio_ascend_quirk_write(void *opaque, hwaddr addr, ++ uint64_t data, unsigned size) ++{ ++ VFIOAscendBarQuirk *quirk = opaque; ++ ++ qemu_log("modifying RO region is not allowed! addr=0x%" ++ HWADDR_PRIx ", data=0x%" PRIx64 ", size=%d\n", ++ addr + quirk->offset, data, size); ++} ++ ++static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = { ++ .read = vfio_ascend_quirk_read, ++ .write = vfio_ascend_quirk_write, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) ++{ ++ VFIOQuirk *quirk; ++ VFIOAscendBarQuirk *bar4_quirk; ++ ++ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 4 || ++ vdev->device_id != PCI_DEVICE_ID_ASCEND310) { ++ return; ++ } ++ ++ quirk = g_malloc0(sizeof(*quirk)); ++ quirk->nr_mem = 1; ++ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); ++ bar4_quirk = quirk->data = g_new0(typeof(*bar4_quirk), quirk->nr_mem); ++ bar4_quirk[0].vdev = vdev; ++ bar4_quirk[0].offset = ASCEND310_XLOADER_OFFSET; ++ bar4_quirk[0].bar = nr; ++ ++ /* ++ * intercept w/r to the xloader-updating register, ++ * so the vm can't enable xloader-updating ++ */ ++ memory_region_init_io(&quirk->mem[0], OBJECT(vdev), ++ &vfio_ascend_intercept_regs_quirk, ++ &bar4_quirk[0], ++ "vfio-ascend310-bar4-intercept-regs-quirk", ++ ASCEND310_XLOADER_SIZE); ++ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, ++ bar4_quirk[0].offset, ++ &quirk->mem[0], 1); ++ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); ++} ++ + /* + * Common quirk probe entry points. + */ +@@ -1261,6 +1335,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) + #ifdef CONFIG_VFIO_IGD + vfio_probe_igd_bar4_quirk(vdev, nr); + #endif ++ vfio_probe_ascend310_bar4_quirk(vdev, nr); + } + + void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr) +-- +2.27.0 + diff --git a/vfio-pci-Ascend710-change-to-bar2-quirk.patch b/vfio-pci-Ascend710-change-to-bar2-quirk.patch new file mode 100644 index 0000000000000000000000000000000000000000..954ced1b7f10a60b09f5b811cfefbc4d2af76485 --- /dev/null +++ b/vfio-pci-Ascend710-change-to-bar2-quirk.patch @@ -0,0 +1,125 @@ +From 782040a627d0c3a44a9259a9055610e25c1f44fe Mon Sep 17 00:00:00 2001 +From: Wu Binfeng +Date: Mon, 25 Apr 2022 15:17:48 +0800 +Subject: [PATCH] vfio/pci: Ascend710 change to bar2 quirk + +Change Ascend710's quirk regions to bar2 for internal causes. +And support Ascend710 2P format now. +--- + hw/vfio/pci-quirks.c | 64 +++++++++++++++++++++++++++++++++++--------- + 1 file changed, 51 insertions(+), 13 deletions(-) + +diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c +index ba4d8f020c..a71ebe26b4 100644 +--- a/hw/vfio/pci-quirks.c ++++ b/hw/vfio/pci-quirks.c +@@ -1213,10 +1213,17 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, + #define PCI_DEVICE_ID_ASCEND910 0xd801 + #define PCI_DEVICE_ID_ASCEND710 0xd500 + #define PCI_DEVICE_ID_ASCEND310 0xd100 ++#define PCI_SUB_DEVICE_ID_ASCEND710_1P_MIN 0x100 ++#define PCI_SUB_DEVICE_ID_ASCEND710_1P_MAX 0x10f ++#define PCI_SUB_DEVICE_ID_ASCEND710_2P_MIN 0x110 ++#define PCI_SUB_DEVICE_ID_ASCEND710_2P_MAX 0x11f + #define ASCEND910_XLOADER_SIZE 4 + #define ASCEND910_XLOADER_OFFSET 0x80400 ++#define ASCEND710_2P_BASE (128 * 1024 * 1024) ++#define ASCEND710_1P_DEVNUM 1 ++#define ASCEND710_2P_DEVNUM 2 + #define ASCEND710_XLOADER_SIZE 4 +-#define ASCEND710_XLOADER_OFFSET 0x20430 ++#define ASCEND710_XLOADER_OFFSET 0x100430 + #define ASCEND310_XLOADER_SIZE 4 + #define ASCEND310_XLOADER_OFFSET 0x400 + +@@ -1289,23 +1296,38 @@ static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr) + QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); + } + +-static void vfio_probe_ascend710_bar0_quirk(VFIOPCIDevice *vdev, int nr) ++static void vfio_probe_ascend710_bar2_quirk(VFIOPCIDevice *vdev, int nr) + { + VFIOQuirk *quirk; +- VFIOAscendBarQuirk *bar0_quirk; ++ VFIOAscendBarQuirk *bar2_quirk; ++ int sub_device_id; ++ int devnum = 0; + +- if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || ++ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || + vdev->device_id != PCI_DEVICE_ID_ASCEND710) { + return; + } + ++ sub_device_id = pci_get_word(vdev->pdev.config + PCI_SUBSYSTEM_ID); ++ if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND710_1P_MIN && ++ sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND710_1P_MAX) { ++ devnum = ASCEND710_1P_DEVNUM; ++ } else if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND710_2P_MIN && ++ sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND710_2P_MAX) { ++ devnum = ASCEND710_2P_DEVNUM; ++ } ++ ++ if (devnum != ASCEND710_1P_DEVNUM && devnum != ASCEND710_2P_DEVNUM) { ++ return; ++ } ++ + quirk = g_malloc0(sizeof(*quirk)); +- quirk->nr_mem = 1; ++ quirk->nr_mem = devnum; + quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); +- bar0_quirk = quirk->data = g_new0(typeof(*bar0_quirk), quirk->nr_mem); +- bar0_quirk[0].vdev = vdev; +- bar0_quirk[0].offset = ASCEND710_XLOADER_OFFSET; +- bar0_quirk[0].bar = nr; ++ bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); ++ bar2_quirk[0].vdev = vdev; ++ bar2_quirk[0].offset = ASCEND710_XLOADER_OFFSET; ++ bar2_quirk[0].bar = nr; + + /* + * intercept w/r to the xloader-updating register, +@@ -1313,12 +1335,28 @@ static void vfio_probe_ascend710_bar0_quirk(VFIOPCIDevice *vdev, int nr) + */ + memory_region_init_io(&quirk->mem[0], OBJECT(vdev), + &vfio_ascend_intercept_regs_quirk, +- &bar0_quirk[0], +- "vfio-ascend710-bar0-intercept-regs-quirk", ++ &bar2_quirk[0], ++ "vfio-ascend710-bar2-1p-intercept-regs-quirk", + ASCEND710_XLOADER_SIZE); + memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, +- bar0_quirk[0].offset, ++ bar2_quirk[0].offset, + &quirk->mem[0], 1); ++ ++ if (devnum == ASCEND710_2P_DEVNUM) { ++ bar2_quirk[1].vdev = vdev; ++ bar2_quirk[1].offset = (ASCEND710_2P_BASE + ASCEND710_XLOADER_OFFSET); ++ bar2_quirk[1].bar = nr; ++ ++ memory_region_init_io(&quirk->mem[1], OBJECT(vdev), ++ &vfio_ascend_intercept_regs_quirk, ++ &bar2_quirk[1], ++ "vfio-ascend710-bar2-2p-intercept-regs-quirk", ++ ASCEND710_XLOADER_SIZE); ++ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, ++ bar2_quirk[1].offset, ++ &quirk->mem[1], 1); ++ } ++ + QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); + } + +@@ -1408,7 +1446,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) + vfio_probe_igd_bar4_quirk(vdev, nr); + #endif + vfio_probe_ascend910_bar0_quirk(vdev, nr); +- vfio_probe_ascend710_bar0_quirk(vdev, nr); ++ vfio_probe_ascend710_bar2_quirk(vdev, nr); + vfio_probe_ascend310_bar4_quirk(vdev, nr); + } + +-- +2.27.0 + diff --git a/vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch b/vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch new file mode 100644 index 0000000000000000000000000000000000000000..771650754bfd6754a0e0d780d760507dcbb170a5 --- /dev/null +++ b/vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch @@ -0,0 +1,75 @@ +From f999392631e7f9fb15493f17b535a8a42ac88be2 Mon Sep 17 00:00:00 2001 +From: Binfeng Wu +Date: Tue, 8 Feb 2022 17:16:04 +0800 +Subject: [PATCH] vfio/pci: Ascend710 need 4Bytes quirk in bar0 + +--- + hw/vfio/pci-quirks.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c +index 8fb190ce3c..9ef4b63e82 100644 +--- a/hw/vfio/pci-quirks.c ++++ b/hw/vfio/pci-quirks.c +@@ -1210,7 +1210,10 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, + } + + #define PCI_VENDOR_ID_HUAWEI 0x19e5 ++#define PCI_DEVICE_ID_ASCEND710 0xd500 + #define PCI_DEVICE_ID_ASCEND310 0xd100 ++#define ASCEND710_XLOADER_SIZE 4 ++#define ASCEND710_XLOADER_OFFSET 0x20430 + #define ASCEND310_XLOADER_SIZE 4 + #define ASCEND310_XLOADER_OFFSET 0x400 + +@@ -1250,6 +1253,39 @@ static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = { + .endianness = DEVICE_LITTLE_ENDIAN, + }; + ++static void vfio_probe_ascend710_bar0_quirk(VFIOPCIDevice *vdev, int nr) ++{ ++ VFIOQuirk *quirk; ++ VFIOAscendBarQuirk *bar0_quirk; ++ ++ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || ++ vdev->device_id != PCI_DEVICE_ID_ASCEND710) { ++ return; ++ } ++ ++ quirk = g_malloc0(sizeof(*quirk)); ++ quirk->nr_mem = 1; ++ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); ++ bar0_quirk = quirk->data = g_new0(typeof(*bar0_quirk), quirk->nr_mem); ++ bar0_quirk[0].vdev = vdev; ++ bar0_quirk[0].offset = ASCEND710_XLOADER_OFFSET; ++ bar0_quirk[0].bar = nr; ++ ++ /* ++ * intercept w/r to the xloader-updating register, ++ * so the vm can't enable xloader-updating ++ */ ++ memory_region_init_io(&quirk->mem[0], OBJECT(vdev), ++ &vfio_ascend_intercept_regs_quirk, ++ &bar0_quirk[0], ++ "vfio-ascend710-bar0-intercept-regs-quirk", ++ ASCEND710_XLOADER_SIZE); ++ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, ++ bar0_quirk[0].offset, ++ &quirk->mem[0], 1); ++ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); ++} ++ + static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) + { + VFIOQuirk *quirk; +@@ -1335,6 +1371,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) + #ifdef CONFIG_VFIO_IGD + vfio_probe_igd_bar4_quirk(vdev, nr); + #endif ++ vfio_probe_ascend710_bar0_quirk(vdev, nr); + vfio_probe_ascend310_bar4_quirk(vdev, nr); + } + +-- +2.27.0 + diff --git a/vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch b/vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch new file mode 100644 index 0000000000000000000000000000000000000000..e273e233d58c24617643a0564c4a27d466bd1297 --- /dev/null +++ b/vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch @@ -0,0 +1,76 @@ +From 5b068100780cf91cc1696589d2115ba3078f9d38 Mon Sep 17 00:00:00 2001 +From: Binfeng Wu +Date: Tue, 8 Feb 2022 19:20:36 +0800 +Subject: [PATCH] vfio/pci: Ascend910 need 4Bytes quirk in bar0 + +--- + hw/vfio/pci-quirks.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c +index 9ef4b63e82..ba4d8f020c 100644 +--- a/hw/vfio/pci-quirks.c ++++ b/hw/vfio/pci-quirks.c +@@ -1210,8 +1210,11 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, + } + + #define PCI_VENDOR_ID_HUAWEI 0x19e5 ++#define PCI_DEVICE_ID_ASCEND910 0xd801 + #define PCI_DEVICE_ID_ASCEND710 0xd500 + #define PCI_DEVICE_ID_ASCEND310 0xd100 ++#define ASCEND910_XLOADER_SIZE 4 ++#define ASCEND910_XLOADER_OFFSET 0x80400 + #define ASCEND710_XLOADER_SIZE 4 + #define ASCEND710_XLOADER_OFFSET 0x20430 + #define ASCEND310_XLOADER_SIZE 4 +@@ -1253,6 +1256,39 @@ static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = { + .endianness = DEVICE_LITTLE_ENDIAN, + }; + ++static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr) ++{ ++ VFIOQuirk *quirk; ++ VFIOAscendBarQuirk *bar0_quirk; ++ ++ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || ++ vdev->device_id != PCI_DEVICE_ID_ASCEND910) { ++ return; ++ } ++ ++ quirk = g_malloc0(sizeof(*quirk)); ++ quirk->nr_mem = 1; ++ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); ++ bar0_quirk = quirk->data = g_new0(typeof(*bar0_quirk), quirk->nr_mem); ++ bar0_quirk[0].vdev = vdev; ++ bar0_quirk[0].offset = ASCEND910_XLOADER_OFFSET; ++ bar0_quirk[0].bar = nr; ++ ++ /* ++ * intercept w/r to the xloader-updating register, ++ * so the vm can't enable xloader-updating ++ */ ++ memory_region_init_io(&quirk->mem[0], OBJECT(vdev), ++ &vfio_ascend_intercept_regs_quirk, ++ &bar0_quirk[0], ++ "vfio-ascend910-bar0-intercept-regs-quirk", ++ ASCEND910_XLOADER_SIZE); ++ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, ++ bar0_quirk[0].offset, ++ &quirk->mem[0], 1); ++ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); ++} ++ + static void vfio_probe_ascend710_bar0_quirk(VFIOPCIDevice *vdev, int nr) + { + VFIOQuirk *quirk; +@@ -1371,6 +1407,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) + #ifdef CONFIG_VFIO_IGD + vfio_probe_igd_bar4_quirk(vdev, nr); + #endif ++ vfio_probe_ascend910_bar0_quirk(vdev, nr); + vfio_probe_ascend710_bar0_quirk(vdev, nr); + vfio_probe_ascend310_bar4_quirk(vdev, nr); + } +-- +2.27.0 + diff --git a/virtio-gpu-Correct-virgl_renderer_resource_get_info-.patch b/virtio-gpu-Correct-virgl_renderer_resource_get_info-.patch new file mode 100644 index 0000000000000000000000000000000000000000..fe1ade710d449101dbca7ca0d7e09e03c697500f --- /dev/null +++ b/virtio-gpu-Correct-virgl_renderer_resource_get_info-.patch @@ -0,0 +1,73 @@ +From ffb0dcccbf5f6e662e7c0b6afa4fe7308d96cc06 Mon Sep 17 00:00:00 2001 +From: dinglimin +Date: Tue, 27 Feb 2024 17:06:01 +0800 +Subject: [PATCH] virtio-gpu: Correct virgl_renderer_resource_get_info() error + check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from 574b64aa6754ba491f51024c5a823a674d48a658 + +virgl_renderer_resource_get_info() returns errno and not -1 on error. +Correct the return-value check. + +Reviewed-by: Marc-André Lureau +Signed-off-by: Dmitry Osipenko +Message-Id: <20240129073921.446869-1-dmitry.osipenko@collabora.com> +Cc: qemu-stable@nongnu.org +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: dinglimin +--- + contrib/vhost-user-gpu/virgl.c | 6 +++--- + hw/display/virtio-gpu-virgl.c | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c +index d1ccdf7d06..51da0e3667 100644 +--- a/contrib/vhost-user-gpu/virgl.c ++++ b/contrib/vhost-user-gpu/virgl.c +@@ -327,7 +327,7 @@ virgl_get_resource_info_modifiers(uint32_t resource_id, + #ifdef VIRGL_RENDERER_RESOURCE_INFO_EXT_VERSION + struct virgl_renderer_resource_info_ext info_ext; + ret = virgl_renderer_resource_get_info_ext(resource_id, &info_ext); +- if (ret < 0) { ++ if (ret) { + return ret; + } + +@@ -335,7 +335,7 @@ virgl_get_resource_info_modifiers(uint32_t resource_id, + *modifiers = info_ext.modifiers; + #else + ret = virgl_renderer_resource_get_info(resource_id, info); +- if (ret < 0) { ++ if (ret) { + return ret; + } + +@@ -372,7 +372,7 @@ virgl_cmd_set_scanout(VuGpu *g, + uint64_t modifiers = 0; + ret = virgl_get_resource_info_modifiers(ss.resource_id, &info, + &modifiers); +- if (ret == -1) { ++ if (ret) { + g_critical("%s: illegal resource specified %d\n", + __func__, ss.resource_id); + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; +diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c +index 8bb7a2c21f..9f34d0e661 100644 +--- a/hw/display/virtio-gpu-virgl.c ++++ b/hw/display/virtio-gpu-virgl.c +@@ -181,7 +181,7 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g, + memset(&info, 0, sizeof(info)); + ret = virgl_renderer_resource_get_info(ss.resource_id, &info); + #endif +- if (ret == -1) { ++ if (ret) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: illegal resource specified %d\n", + __func__, ss.resource_id); +-- +2.27.0 + diff --git a/virtio-gpu-remove-needless-condition.patch b/virtio-gpu-remove-needless-condition.patch new file mode 100644 index 0000000000000000000000000000000000000000..4930a2c5129cef2ccf57167eaba31cf43aad920d --- /dev/null +++ b/virtio-gpu-remove-needless-condition.patch @@ -0,0 +1,44 @@ +From 77b2f29dce6ddedcc13488eb80add2f9023b4b89 Mon Sep 17 00:00:00 2001 +From: dinglimin +Date: Wed, 13 Mar 2024 11:23:35 +0800 +Subject: [PATCH] virtio-gpu: remove needless condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from cab47b210598c11b76053a01316df9835b94dc09 +qemu_create_displaysurface_pixman() never returns NULL. +Signed-off-by: Marc-André Lureau +Signed-off-by: dinglimin +--- + hw/display/virtio-gpu.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c +index b016d3bac8..b02d1e3a4c 100644 +--- a/hw/display/virtio-gpu.c ++++ b/hw/display/virtio-gpu.c +@@ -679,10 +679,6 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g, + + /* realloc the surface ptr */ + scanout->ds = qemu_create_displaysurface_pixman(rect); +- if (!scanout->ds) { +- *error = VIRTIO_GPU_RESP_ERR_UNSPEC; +- return; +- } + #ifdef WIN32 + qemu_displaysurface_win32_set_handle(scanout->ds, res->handle, fb->offset); + #endif +@@ -1418,9 +1414,6 @@ static int virtio_gpu_post_load(void *opaque, int version_id) + return -EINVAL; + } + scanout->ds = qemu_create_displaysurface_pixman(res->image); +- if (!scanout->ds) { +- return -EINVAL; +- } + #ifdef WIN32 + qemu_displaysurface_win32_set_handle(scanout->ds, res->handle, 0); + #endif +-- +2.27.0 + diff --git a/virtio_blk-Add-support-for-retry-on-errors.patch b/virtio_blk-Add-support-for-retry-on-errors.patch new file mode 100644 index 0000000000000000000000000000000000000000..696bde5b607d4ca3ffe912930afcf5e854c0491f --- /dev/null +++ b/virtio_blk-Add-support-for-retry-on-errors.patch @@ -0,0 +1,118 @@ +From 0da112402efe63e09fdd6ed43aa026d5b625988f Mon Sep 17 00:00:00 2001 +From: yexiao +Date: Thu, 21 Jan 2021 15:46:53 +0800 +Subject: [PATCH] virtio_blk: Add support for retry on errors + +Insert failed requests into device's list for later retry and handle +queued requests to implement retry_request_cb. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + hw/block/virtio-blk.c | 47 ++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 44 insertions(+), 3 deletions(-) + +diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c +index a1f8e15522..1ebc9188c0 100644 +--- a/hw/block/virtio-blk.c ++++ b/hw/block/virtio-blk.c +@@ -90,6 +90,10 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, + block_acct_failed(blk_get_stats(s->blk), &req->acct); + } + virtio_blk_free_request(req); ++ } else if (action == BLOCK_ERROR_ACTION_RETRY) { ++ req->mr_next = NULL; ++ req->next = s->rq; ++ s->rq = req; + } + + blk_error_action(s->blk, action, is_read, error); +@@ -131,6 +135,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret) + } + } + ++ blk_error_retry_reset_timeout(s->blk); + virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + block_acct_done(blk_get_stats(s->blk), &req->acct); + virtio_blk_free_request(req); +@@ -150,6 +155,7 @@ static void virtio_blk_flush_complete(void *opaque, int ret) + } + } + ++ blk_error_retry_reset_timeout(s->blk); + virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + block_acct_done(blk_get_stats(s->blk), &req->acct); + virtio_blk_free_request(req); +@@ -172,6 +178,7 @@ static void virtio_blk_discard_write_zeroes_complete(void *opaque, int ret) + } + } + ++ blk_error_retry_reset_timeout(s->blk); + virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + if (is_write_zeroes) { + block_acct_done(blk_get_stats(s->blk), &req->acct); +@@ -1183,12 +1190,12 @@ static void virtio_blk_dma_restart_bh(void *opaque) + { + VirtIOBlock *s = opaque; + +- VirtIOBlockReq *req = s->rq; ++ VirtIOBlockReq *req; + MultiReqBuffer mrb = {}; + +- s->rq = NULL; +- + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); ++ req = s->rq; ++ s->rq = NULL; + while (req) { + VirtIOBlockReq *next = req->next; + if (virtio_blk_handle_request(req, &mrb)) { +@@ -1541,10 +1548,44 @@ static void virtio_blk_drained_end(void *opaque) + } + } + ++static void virtio_blk_retry_request(void *opaque) ++{ ++ VirtIOBlock *s = VIRTIO_BLK(opaque); ++ ++ VirtIOBlockReq *req; ++ MultiReqBuffer mrb = {}; ++ ++ aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); ++ req = s->rq; ++ s->rq = NULL; ++ while (req) { ++ VirtIOBlockReq *next = req->next; ++ if (virtio_blk_handle_request(req, &mrb)) { ++ /* Device is now broken and won't do any processing until it gets ++ * reset. Already queued requests will be lost: let's purge them. ++ */ ++ while (req) { ++ next = req->next; ++ virtqueue_detach_element(req->vq, &req->elem, 0); ++ virtio_blk_free_request(req); ++ req = next; ++ } ++ break; ++ } ++ req = next; ++ } ++ ++ if (mrb.num_reqs) { ++ virtio_blk_submit_multireq(s, &mrb); ++ } ++ aio_context_release(blk_get_aio_context(s->conf.conf.blk)); ++} ++ + static const BlockDevOps virtio_block_ops = { + .resize_cb = virtio_blk_resize, + .drained_begin = virtio_blk_drained_begin, + .drained_end = virtio_blk_drained_end, ++ .retry_request_cb = virtio_blk_retry_request, + }; + + static void virtio_blk_device_realize(DeviceState *dev, Error **errp) +-- +2.27.0 +