* [PATCH qemu 1/2] update submodule and patches to QEMU 10.2.1
2026-03-12 11:44 [PATCH-SERIES qemu 0/2] QEMU 10.2.1 Fiona Ebner
@ 2026-03-12 11:44 ` Fiona Ebner
2026-03-12 11:44 ` [PATCH qemu 2/2] stable fixes for " Fiona Ebner
1 sibling, 0 replies; 3+ messages in thread
From: Fiona Ebner @ 2026-03-12 11:44 UTC (permalink / raw)
To: pve-devel
Notable changes:
The io_uring handling was rewritten, so patch "block/io_uring: avoid
potentially getting stuck after resubmit at the end of ioq_submit()"
is not required anymore.
savevm-async needed to adapt to commit 9535435795 ("migration: push
Error **errp into qemu_loadvm_state()").
QAPI docs enforce strict formatting now, requiring quite a few
adaptations.
Add the cortex-a78ae CPU model for ARM.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
debian/cpu-models-aarch64.json | 1 +
...d-support-for-sync-bitmap-mode-never.patch | 38 +--
...check-for-bitmap-mode-without-bitmap.patch | 4 +-
.../0006-mirror-move-some-checks-to-qmp.patch | 4 +-
...race-with-clients-disconnecting-earl.patch | 4 +-
...ial-deadlock-when-draining-during-tr.patch | 2 +-
...k-range-when-setting-zero-bitmap-fo.patch} | 0
| 37 ---
...-to-bounce-buffer-if-BLKZEROOUT-is-.patch} | 2 +-
...quirks-when-IGD-is-not-the-primary-d.patch | 79 ------
...adlock-upon-TMF-request-cancelling-w.patch | 83 ------
...-rename-field-to-num_initial_regions.patch | 245 ------------------
...region-info-cache-for-initial-region.patch | 75 ------
...vdagent-fix-windows-agent-regression.patch | 105 --------
...six-populate-pwrite_zeroes_alignment.patch | 49 ----
..._zeroes_alignment-when-writing-first.patch | 86 ------
...void-potentially-getting-stuck-after.patch | 153 -----------
...k-file-change-locking-default-to-off.patch | 2 +-
...djust-network-script-path-to-etc-kvm.patch | 4 +-
...he-CPU-model-to-kvm64-32-instead-of-.patch | 4 +-
...ui-spice-default-to-pve-certificates.patch | 4 +-
...erfs-no-default-logfile-if-daemonize.patch | 6 +-
...lock-rbd-disable-rbd_cache_writethro.patch | 4 +-
...PVE-Up-glusterfs-allow-partial-reads.patch | 28 +-
...return-success-on-info-without-snaps.patch | 8 +-
...dd-add-osize-and-read-from-to-stdin-.patch | 14 +-
...E-Up-qemu-img-dd-add-isize-parameter.patch | 14 +-
...PVE-Up-qemu-img-dd-add-n-skip_create.patch | 18 +-
...-add-l-option-for-loading-a-snapshot.patch | 18 +-
...virtio-balloon-improve-query-balloon.patch | 10 +-
.../0014-PVE-qapi-modify-query-machines.patch | 6 +-
.../0015-PVE-qapi-modify-spice-query.patch | 6 +-
...nnel-implementation-for-savevm-async.patch | 4 +-
...async-for-background-state-snapshots.patch | 61 +++--
...add-optional-buffer-size-to-QEMUFile.patch | 30 +--
...add-the-zeroinit-block-driver-filter.patch | 6 +-
...-Add-dummy-id-command-line-parameter.patch | 10 +-
...t-target-i386-disable-LINT0-after-re.patch | 8 +-
...le-posix-make-locking-optiono-on-cre.patch | 20 +-
...3-PVE-monitor-disable-oob-capability.patch | 2 +-
...sed-balloon-qemu-4-0-config-size-fal.patch | 4 +-
...E-Allow-version-code-in-machine-type.patch | 24 +-
...VE-Backup-add-vma-backup-format-code.patch | 6 +-
...-Backup-add-backup-dump-block-driver.patch | 2 +-
...ckup-Proxmox-backup-patches-for-QEMU.patch | 115 ++++----
...estore-new-command-to-restore-from-p.patch | 4 +-
...k-driver-to-map-backup-archives-into.patch | 12 +-
...ct-stderr-to-journal-when-daemonized.patch | 6 +-
...igrate-dirty-bitmap-state-via-savevm.patch | 36 +--
...all-back-to-open-iscsi-initiatorname.patch | 4 +-
.../0038-block-add-alloc-track-driver.patch | 8 +-
.../0039-PVE-backup-add-fleecing-option.patch | 30 +--
...e-version-deprecation-for-Proxmox-VE.patch | 10 +-
...ment-backup-access-setup-and-teardow.patch | 76 +++---
...se-migration-blocker-check-for-snaps.patch | 18 +-
debian/patches/series | 13 +-
qemu | 2 +-
57 files changed, 364 insertions(+), 1260 deletions(-)
rename debian/patches/extra/{0012-block-mirror-check-range-when-setting-zero-bitmap-fo.patch => 0003-block-mirror-check-range-when-setting-zero-bitmap-fo.patch} (100%)
delete mode 100644 debian/patches/extra/0003-tcg-arm-Fix-tgen_deposit.patch
rename debian/patches/extra/{0013-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch => 0004-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch} (97%)
delete mode 100644 debian/patches/extra/0004-vfio-igd-Enable-quirks-when-IGD-is-not-the-primary-d.patch
delete mode 100644 debian/patches/extra/0005-hw-scsi-avoid-deadlock-upon-TMF-request-cancelling-w.patch
delete mode 100644 debian/patches/extra/0006-vfio-rename-field-to-num_initial_regions.patch
delete mode 100644 debian/patches/extra/0007-vfio-only-check-region-info-cache-for-initial-region.patch
delete mode 100644 debian/patches/extra/0008-ui-vdagent-fix-windows-agent-regression.patch
delete mode 100644 debian/patches/extra/0009-file-posix-populate-pwrite_zeroes_alignment.patch
delete mode 100644 debian/patches/extra/0010-block-use-pwrite_zeroes_alignment-when-writing-first.patch
delete mode 100644 debian/patches/extra/0011-block-io_uring-avoid-potentially-getting-stuck-after.patch
diff --git a/debian/cpu-models-aarch64.json b/debian/cpu-models-aarch64.json
index 5f1f498..5b39073 100644
--- a/debian/cpu-models-aarch64.json
+++ b/debian/cpu-models-aarch64.json
@@ -7,6 +7,7 @@
"cortex-a710" : "ARM",
"cortex-a72" : "ARM",
"cortex-a76" : "ARM",
+ "cortex-a78ae" : "ARM",
"max" : "default",
"neoverse-n1" : "ARM",
"neoverse-n2" : "ARM",
diff --git a/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch b/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
index 6e93d4f..b3906bd 100644
--- a/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
+++ b/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
@@ -229,10 +229,10 @@ index bc982cb99a..99805e7a9d 100644
base_read_only, errp);
if (!job) {
diff --git a/blockdev.c b/blockdev.c
-index b451fee6e1..5855e9cac2 100644
+index 6e86c6262f..b68dfef260 100644
--- a/blockdev.c
+++ b/blockdev.c
-@@ -2857,6 +2857,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2859,6 +2859,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
BlockDriverState *target,
const char *replaces,
enum MirrorSyncMode sync,
@@ -242,7 +242,7 @@ index b451fee6e1..5855e9cac2 100644
BlockMirrorBackingMode backing_mode,
bool target_is_zero,
bool has_speed, int64_t speed,
-@@ -2875,6 +2878,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2877,6 +2880,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
{
BlockDriverState *unfiltered_bs;
int job_flags = JOB_DEFAULT;
@@ -250,7 +250,7 @@ index b451fee6e1..5855e9cac2 100644
GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();
-@@ -2925,6 +2929,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2927,6 +2931,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
return;
}
@@ -280,7 +280,7 @@ index b451fee6e1..5855e9cac2 100644
if (!replaces) {
/* We want to mirror from @bs, but keep implicit filters on top */
unfiltered_bs = bdrv_skip_implicit_filters(bs);
-@@ -2966,7 +2993,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2968,7 +2995,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
* and will allow to check whether the node still exist at mirror completion
*/
mirror_start(job_id, bs, target, replaces, job_flags,
@@ -289,7 +289,7 @@ index b451fee6e1..5855e9cac2 100644
target_is_zero, on_source_error, on_target_error, unmap,
filter_node_name, copy_mode, errp);
}
-@@ -3109,6 +3136,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
+@@ -3111,6 +3138,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
blockdev_mirror_common(arg->job_id, bs, target_bs,
arg->replaces, arg->sync,
@@ -298,7 +298,7 @@ index b451fee6e1..5855e9cac2 100644
backing_mode, target_is_zero,
arg->has_speed, arg->speed,
arg->has_granularity, arg->granularity,
-@@ -3128,6 +3157,8 @@ void qmp_blockdev_mirror(const char *job_id,
+@@ -3130,6 +3159,8 @@ void qmp_blockdev_mirror(const char *job_id,
const char *device, const char *target,
const char *replaces,
MirrorSyncMode sync,
@@ -307,7 +307,7 @@ index b451fee6e1..5855e9cac2 100644
bool has_speed, int64_t speed,
bool has_granularity, uint32_t granularity,
bool has_buf_size, int64_t buf_size,
-@@ -3166,7 +3197,8 @@ void qmp_blockdev_mirror(const char *job_id,
+@@ -3168,7 +3199,8 @@ void qmp_blockdev_mirror(const char *job_id,
}
blockdev_mirror_common(job_id, bs, target_bs,
@@ -333,26 +333,26 @@ index e7c8f1a856..d5aa68caeb 100644
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index dc6eb4ae23..7d281ab7ae 100644
+index b82af74256..64f2befdf5 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
-@@ -2205,6 +2205,15 @@
+@@ -2275,6 +2275,15 @@
# destination (all the disk, only the sectors allocated in the
# topmost image, or only new I/O).
#
-+# @bitmap: The name of a bitmap to use for sync=bitmap mode. This
++# @bitmap: The name of a bitmap to use for sync=bitmap mode. This
+# argument must be present for bitmap mode and absent otherwise.
+# The bitmap's granularity is used instead of @granularity (Since
+# 4.1).
+#
+# @bitmap-mode: Specifies the type of data the bitmap should contain
-+# after the operation concludes. Must be present if sync is
-+# "bitmap". Must NOT be present otherwise. (Since 4.1)
++# after the operation concludes. Must be present if sync is
++# "bitmap". Must NOT be present otherwise. (Since 4.1)
+#
# @granularity: granularity of the dirty bitmap, default is 64K if the
# image format doesn't have clusters, 4K if the clusters are
# smaller than that, else the cluster size. Must be a power of 2
-@@ -2246,7 +2255,9 @@
+@@ -2316,7 +2325,9 @@
{ 'struct': 'DriveMirror',
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
'*format': 'str', '*node-name': 'str', '*replaces': 'str',
@@ -363,23 +363,23 @@ index dc6eb4ae23..7d281ab7ae 100644
'*speed': 'int', '*granularity': 'uint32',
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
'*on-target-error': 'BlockdevOnError',
-@@ -2522,6 +2533,15 @@
+@@ -2593,6 +2604,15 @@
# destination (all the disk, only the sectors allocated in the
# topmost image, or only new I/O).
#
-+# @bitmap: The name of a bitmap to use for sync=bitmap mode. This
++# @bitmap: The name of a bitmap to use for sync=bitmap mode. This
+# argument must be present for bitmap mode and absent otherwise.
+# The bitmap's granularity is used instead of @granularity (since
+# 4.1).
+#
+# @bitmap-mode: Specifies the type of data the bitmap should contain
-+# after the operation concludes. Must be present if sync is
-+# "bitmap". Must NOT be present otherwise. (Since 4.1)
++# after the operation concludes. Must be present if sync is
++# "bitmap". Must NOT be present otherwise. (Since 4.1)
+#
# @granularity: granularity of the dirty bitmap, default is 64K if the
# image format doesn't have clusters, 4K if the clusters are
# smaller than that, else the cluster size. Must be a power of 2
-@@ -2574,7 +2594,8 @@
+@@ -2645,7 +2665,8 @@
{ 'command': 'blockdev-mirror',
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
'*replaces': 'str',
diff --git a/debian/patches/bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch b/debian/patches/bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch
index c2d4d9e..dadb0e6 100644
--- a/debian/patches/bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch
+++ b/debian/patches/bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch
@@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 3 insertions(+)
diff --git a/blockdev.c b/blockdev.c
-index 5855e9cac2..f132b4985b 100644
+index b68dfef260..878e47a321 100644
--- a/blockdev.c
+++ b/blockdev.c
-@@ -2950,6 +2950,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2952,6 +2952,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
return;
}
diff --git a/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch b/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch
index 238f47b..687a256 100644
--- a/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch
+++ b/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch
@@ -62,10 +62,10 @@ index 0f96c8b5ce..5340a695b1 100644
if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
diff --git a/blockdev.c b/blockdev.c
-index f132b4985b..782cc5dd75 100644
+index 878e47a321..d9575c8367 100644
--- a/blockdev.c
+++ b/blockdev.c
-@@ -2929,7 +2929,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2931,7 +2931,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
return;
}
diff --git a/debian/patches/extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch b/debian/patches/extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
index 1029ef5..1ac5cb6 100644
--- a/debian/patches/extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
+++ b/debian/patches/extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
@@ -60,7 +60,7 @@ index c3740ec616..7f38ce6b8b 100644
void monitor_init_globals(void);
void monitor_init_globals_core(void);
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
-index 5676eb334e..4c452a6aeb 100644
+index 7735c73108..43ac8c87be 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -151,6 +151,13 @@ typedef struct {
@@ -104,7 +104,7 @@ index c5a5d30877..07775784d4 100644
* Is @mon is using readline?
* Note: not all HMP monitors use readline, e.g., gdbserver has a
diff --git a/monitor/qmp.c b/monitor/qmp.c
-index cb99a12d94..170fef4531 100644
+index 7ae070dc8d..16c20305d2 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -165,6 +165,8 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req)
diff --git a/debian/patches/extra/0002-ide-avoid-potential-deadlock-when-draining-during-tr.patch b/debian/patches/extra/0002-ide-avoid-potential-deadlock-when-draining-during-tr.patch
index aca8620..b068179 100644
--- a/debian/patches/extra/0002-ide-avoid-potential-deadlock-when-draining-during-tr.patch
+++ b/debian/patches/extra/0002-ide-avoid-potential-deadlock-when-draining-during-tr.patch
@@ -55,7 +55,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/hw/ide/core.c b/hw/ide/core.c
-index b14983ec54..41c543e627 100644
+index 8c380abf7c..054d80cce8 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -456,7 +456,7 @@ static void ide_trim_bh_cb(void *opaque)
diff --git a/debian/patches/extra/0012-block-mirror-check-range-when-setting-zero-bitmap-fo.patch b/debian/patches/extra/0003-block-mirror-check-range-when-setting-zero-bitmap-fo.patch
similarity index 100%
rename from debian/patches/extra/0012-block-mirror-check-range-when-setting-zero-bitmap-fo.patch
rename to debian/patches/extra/0003-block-mirror-check-range-when-setting-zero-bitmap-fo.patch
diff --git a/debian/patches/extra/0003-tcg-arm-Fix-tgen_deposit.patch b/debian/patches/extra/0003-tcg-arm-Fix-tgen_deposit.patch
deleted file mode 100644
index ca01088..0000000
--- a/debian/patches/extra/0003-tcg-arm-Fix-tgen_deposit.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Richard Henderson <richard.henderson@linaro.org>
-Date: Fri, 29 Aug 2025 13:49:06 +0000
-Subject: [PATCH] tcg/arm: Fix tgen_deposit
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When converting from tcg_out_deposit, the arguments were not
-shuffled properly.
-
-Cc: qemu-stable@nongnu.org
-Fixes: cf4905c03135f1181e8 ("tcg: Convert deposit to TCGOutOpDeposit")
-Reported-by: Michael Tokarev <mjt@tls.msk.ru>
-Tested-by: Michael Tokarev <mjt@tls.msk.ru>
-Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
-Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-(cherry picked from commit 27ea28a0b369b4b14a485a5d6f045e0dc1db4e38)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- tcg/arm/tcg-target.c.inc | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
-index 836894b16a..338c57b061 100644
---- a/tcg/arm/tcg-target.c.inc
-+++ b/tcg/arm/tcg-target.c.inc
-@@ -975,7 +975,8 @@ static void tgen_deposit(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1,
- TCGReg a2, unsigned ofs, unsigned len)
- {
- /* bfi/bfc */
-- tcg_out32(s, 0x07c00010 | (COND_AL << 28) | (a0 << 12) | a1
-+ tcg_debug_assert(a0 == a1);
-+ tcg_out32(s, 0x07c00010 | (COND_AL << 28) | (a0 << 12) | a2
- | (ofs << 7) | ((ofs + len - 1) << 16));
- }
-
diff --git a/debian/patches/extra/0013-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch b/debian/patches/extra/0004-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch
similarity index 97%
rename from debian/patches/extra/0013-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch
rename to debian/patches/extra/0004-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch
index f71f5d2..d9a50a8 100644
--- a/debian/patches/extra/0013-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch
+++ b/debian/patches/extra/0004-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch
@@ -21,7 +21,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/block/io.c b/block/io.c
-index 9bd8ba8431..7b1ad0996a 100644
+index c4a4301321..1865f226d5 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1917,7 +1917,8 @@ bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
diff --git a/debian/patches/extra/0004-vfio-igd-Enable-quirks-when-IGD-is-not-the-primary-d.patch b/debian/patches/extra/0004-vfio-igd-Enable-quirks-when-IGD-is-not-the-primary-d.patch
deleted file mode 100644
index 98f5e9b..0000000
--- a/debian/patches/extra/0004-vfio-igd-Enable-quirks-when-IGD-is-not-the-primary-d.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Tomita Moeko <tomitamoeko@gmail.com>
-Date: Thu, 14 Aug 2025 00:05:10 +0800
-Subject: [PATCH] vfio/igd: Enable quirks when IGD is not the primary display
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Since linux 6.15, commit 41112160ca87 ("vfio/pci: match IGD devices in
-display controller class"), IGD related regions are also exposed when
-IGD is not primary display (device class is Display controller).
-
-Allow IGD quirks to be enabled in this configuration so that guests can
-have display output on IGD when it is not the primary display.
-
-Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
-Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
-Link: https://lore.kernel.org/qemu-devel/20250813160510.23553-1-tomitamoeko@gmail.com
-Signed-off-by: Cédric Le Goater <clg@redhat.com>
-(cherry picked from commit 432ca3dfa3d57a7bf1e427576fcfca4ab0079a50)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/vfio/igd.c | 7 ++++---
- hw/vfio/pci.h | 5 +++++
- 2 files changed, 9 insertions(+), 3 deletions(-)
-
-diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
-index ee0767b0b8..f116c40ccd 100644
---- a/hw/vfio/igd.c
-+++ b/hw/vfio/igd.c
-@@ -460,7 +460,7 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
- int gen;
-
- if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
-- !vfio_is_vga(vdev) || nr != 0) {
-+ !vfio_is_base_display(vdev) || nr != 0) {
- return;
- }
-
-@@ -518,7 +518,7 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
- Error *err = NULL;
-
- if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
-- !vfio_is_vga(vdev)) {
-+ !vfio_is_base_display(vdev)) {
- return true;
- }
-
-@@ -534,12 +534,13 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
- /*
- * For backward compatibility, enable legacy mode when
- * - Device geneation is 6 to 9 (including both)
-- * - IGD claims VGA cycles on host
-+ * - IGD exposes itself as VGA controller and claims VGA cycles on host
- * - Machine type is i440fx (pc_piix)
- * - IGD device is at guest BDF 00:02.0
- * - Not manually disabled by x-igd-legacy-mode=off
- */
- if ((vdev->igd_legacy_mode != ON_OFF_AUTO_OFF) &&
-+ vfio_is_vga(vdev) &&
- (gen >= 6 && gen <= 9) &&
- !(gmch & IGD_GMCH_VGA_DISABLE) &&
- !strcmp(MACHINE_GET_CLASS(qdev_get_machine())->family, "pc_piix") &&
-diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
-index 810a842f4a..923cf9c2f7 100644
---- a/hw/vfio/pci.h
-+++ b/hw/vfio/pci.h
-@@ -203,6 +203,11 @@ static inline bool vfio_is_vga(VFIOPCIDevice *vdev)
- return (vdev->class_code >> 8) == PCI_CLASS_DISPLAY_VGA;
- }
-
-+static inline bool vfio_is_base_display(VFIOPCIDevice *vdev)
-+{
-+ return (vdev->class_code >> 16) == PCI_BASE_CLASS_DISPLAY;
-+}
-+
- /* MSI/MSI-X/INTx */
- void vfio_pci_vector_init(VFIOPCIDevice *vdev, int nr);
- void vfio_pci_add_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector,
diff --git a/debian/patches/extra/0005-hw-scsi-avoid-deadlock-upon-TMF-request-cancelling-w.patch b/debian/patches/extra/0005-hw-scsi-avoid-deadlock-upon-TMF-request-cancelling-w.patch
deleted file mode 100644
index 4c7441e..0000000
--- a/debian/patches/extra/0005-hw-scsi-avoid-deadlock-upon-TMF-request-cancelling-w.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fiona Ebner <f.ebner@proxmox.com>
-Date: Fri, 17 Oct 2025 11:43:30 +0200
-Subject: [PATCH] hw/scsi: avoid deadlock upon TMF request cancelling with
- VirtIO
-
-When scsi_req_dequeue() is reached via
-scsi_req_cancel_async()
-virtio_scsi_tmf_cancel_req()
-virtio_scsi_do_tmf_aio_context(),
-there is a deadlock when trying to acquire the SCSI device's requests
-lock, because it was already acquired in
-virtio_scsi_do_tmf_aio_context().
-
-In particular, the issue happens with a FreeBSD guest (13, 14, 15,
-maybe more), when it cancels SCSI requests, because of timeout.
-
-This is a regression caused by commit da6eebb33b ("virtio-scsi:
-perform TMFs in appropriate AioContexts") and the introduction of the
-requests_lock earlier.
-
-To fix the issue, only cancel the requests after releasing the
-requests_lock. For this, the SCSI device's requests are iterated while
-holding the requests_lock and the requests to be cancelled are
-collected in a list. Then, the collected requests are cancelled
-one by one while not holding the requests_lock. This is safe, because
-only requests from the current AioContext are collected and acted
-upon.
-
-Originally reported by Proxmox VE users:
-https://bugzilla.proxmox.com/show_bug.cgi?id=6810
-https://forum.proxmox.com/threads/173914/
-
-Fixes: da6eebb33b ("virtio-scsi: perform TMFs in appropriate AioContexts")
-Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
-Message-id: 20251017094518.328905-1-f.ebner@proxmox.com
-[Changed g_list_append() to g_list_prepend() to avoid traversing the
-list each time.
---Stefan]
-Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-(cherry picked from commit 7d80d6d82db4c73e335f9e738d7a5778124df35e
- from https://gitlab.com/stefanha/qemu/-/tree/block)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/scsi/virtio-scsi.c | 14 +++++++++++++-
- 1 file changed, 13 insertions(+), 1 deletion(-)
-
-diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
-index 34ae14f7bf..3b635053b5 100644
---- a/hw/scsi/virtio-scsi.c
-+++ b/hw/scsi/virtio-scsi.c
-@@ -343,6 +343,7 @@ static void virtio_scsi_do_tmf_aio_context(void *opaque)
- SCSIDevice *d = virtio_scsi_device_get(s, tmf->req.tmf.lun);
- SCSIRequest *r;
- bool match_tag;
-+ g_autoptr(GList) reqs = NULL;
-
- if (!d) {
- tmf->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET;
-@@ -378,10 +379,21 @@ static void virtio_scsi_do_tmf_aio_context(void *opaque)
- if (match_tag && cmd_req->req.cmd.tag != tmf->req.tmf.tag) {
- continue;
- }
-- virtio_scsi_tmf_cancel_req(tmf, r);
-+ /*
-+ * Cannot cancel directly, because scsi_req_dequeue() would deadlock
-+ * when attempting to acquire the request_lock a second time. Taking
-+ * a reference here is paired with an unref after cancelling below.
-+ */
-+ scsi_req_ref(r);
-+ reqs = g_list_prepend(reqs, r);
- }
- }
-
-+ for (GList *elem = g_list_first(reqs); elem; elem = g_list_next(elem)) {
-+ virtio_scsi_tmf_cancel_req(tmf, elem->data);
-+ scsi_req_unref(elem->data);
-+ }
-+
- /* Incremented by virtio_scsi_do_tmf() */
- virtio_scsi_tmf_dec_remaining(tmf);
-
diff --git a/debian/patches/extra/0006-vfio-rename-field-to-num_initial_regions.patch b/debian/patches/extra/0006-vfio-rename-field-to-num_initial_regions.patch
deleted file mode 100644
index 3662f1d..0000000
--- a/debian/patches/extra/0006-vfio-rename-field-to-num_initial_regions.patch
+++ /dev/null
@@ -1,245 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: John Levon <john.levon@nutanix.com>
-Date: Tue, 14 Oct 2025 17:12:26 +0200
-Subject: [PATCH] vfio: rename field to "num_initial_regions"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-We set VFIODevice::num_regions at initialization time, and do not
-otherwise refresh it. As it is valid in theory for a VFIO device to
-later increase the number of supported regions, rename the field to
-"num_initial_regions" to better reflect its semantics.
-
-Signed-off-by: John Levon <john.levon@nutanix.com>
-Reviewed-by: Cédric Le Goater <clg@redhat.com>
-Reviewed-by: Alex Williamson <alex@shazbot.org>
-Link: https://lore.kernel.org/qemu-devel/20251014151227.2298892-2-john.levon@nutanix.com
-Signed-off-by: Cédric Le Goater <clg@redhat.com>
-(cherry picked from commit d5176a39405f0e0d20dff173e58255a7d5099411
- from https://gitlab.com/legoater/qemu/-/tree/vfio-next)
-[FE: also rename in hw/vfio/platform.c and hw/core/sysbus-fdt.c
- where affected code got dropped in master, but is still in v10.1]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/core/sysbus-fdt.c | 14 +++++++-------
- hw/vfio-user/device.c | 2 +-
- hw/vfio/ccw.c | 4 ++--
- hw/vfio/device.c | 12 ++++++------
- hw/vfio/iommufd.c | 3 ++-
- hw/vfio/pci.c | 4 ++--
- hw/vfio/platform.c | 10 +++++-----
- include/hw/vfio/vfio-device.h | 2 +-
- 8 files changed, 26 insertions(+), 25 deletions(-)
-
-diff --git a/hw/core/sysbus-fdt.c b/hw/core/sysbus-fdt.c
-index c339a27875..1e1966813f 100644
---- a/hw/core/sysbus-fdt.c
-+++ b/hw/core/sysbus-fdt.c
-@@ -236,15 +236,15 @@ static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice *sbdev, void *opaque)
-
- qemu_fdt_setprop(fdt, nodename, "dma-coherent", "", 0);
-
-- reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
-- for (i = 0; i < vbasedev->num_regions; i++) {
-+ reg_attr = g_new(uint32_t, vbasedev->num_initial_regions * 2);
-+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
- mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
- reg_attr[2 * i] = cpu_to_be32(mmio_base);
- reg_attr[2 * i + 1] = cpu_to_be32(
- memory_region_size(vdev->regions[i]->mem));
- }
- qemu_fdt_setprop(fdt, nodename, "reg", reg_attr,
-- vbasedev->num_regions * 2 * sizeof(uint32_t));
-+ vbasedev->num_initial_regions * 2 * sizeof(uint32_t));
-
- irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
- for (i = 0; i < vbasedev->num_irqs; i++) {
-@@ -330,7 +330,7 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
-
- g_free(dt_name);
-
-- if (vbasedev->num_regions != 5) {
-+ if (vbasedev->num_initial_regions != 5) {
- error_report("%s Does the host dt node combine XGBE/PHY?", __func__);
- exit(1);
- }
-@@ -374,15 +374,15 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
- guest_clock_phandles[0],
- guest_clock_phandles[1]);
-
-- reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
-- for (i = 0; i < vbasedev->num_regions; i++) {
-+ reg_attr = g_new(uint32_t, vbasedev->num_initial_regions * 2);
-+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
- mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
- reg_attr[2 * i] = cpu_to_be32(mmio_base);
- reg_attr[2 * i + 1] = cpu_to_be32(
- memory_region_size(vdev->regions[i]->mem));
- }
- qemu_fdt_setprop(guest_fdt, nodename, "reg", reg_attr,
-- vbasedev->num_regions * 2 * sizeof(uint32_t));
-+ vbasedev->num_initial_regions * 2 * sizeof(uint32_t));
-
- irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
- for (i = 0; i < vbasedev->num_irqs; i++) {
-diff --git a/hw/vfio-user/device.c b/hw/vfio-user/device.c
-index 0609a7dc25..64ef35b320 100644
---- a/hw/vfio-user/device.c
-+++ b/hw/vfio-user/device.c
-@@ -134,7 +134,7 @@ static int vfio_user_device_io_get_region_info(VFIODevice *vbasedev,
- VFIOUserFDs fds = { 0, 1, fd};
- int ret;
-
-- if (info->index > vbasedev->num_regions) {
-+ if (info->index > vbasedev->num_initial_regions) {
- return -EINVAL;
- }
-
-diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
-index 9560b8d851..4d9588e7aa 100644
---- a/hw/vfio/ccw.c
-+++ b/hw/vfio/ccw.c
-@@ -484,9 +484,9 @@ static bool vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
- * We always expect at least the I/O region to be present. We also
- * may have a variable number of regions governed by capabilities.
- */
-- if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
-+ if (vdev->num_initial_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
- error_setg(errp, "vfio: too few regions (%u), expected at least %u",
-- vdev->num_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1);
-+ vdev->num_initial_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1);
- return false;
- }
-
-diff --git a/hw/vfio/device.c b/hw/vfio/device.c
-index 52a1996dc4..0b459c0f7c 100644
---- a/hw/vfio/device.c
-+++ b/hw/vfio/device.c
-@@ -257,7 +257,7 @@ int vfio_device_get_region_info_type(VFIODevice *vbasedev, uint32_t type,
- {
- int i;
-
-- for (i = 0; i < vbasedev->num_regions; i++) {
-+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
- struct vfio_info_cap_header *hdr;
- struct vfio_region_info_cap_type *cap_type;
-
-@@ -466,7 +466,7 @@ void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainerBase *bcontainer,
- int i;
-
- vbasedev->num_irqs = info->num_irqs;
-- vbasedev->num_regions = info->num_regions;
-+ vbasedev->num_initial_regions = info->num_regions;
- vbasedev->flags = info->flags;
- vbasedev->reset_works = !!(info->flags & VFIO_DEVICE_FLAGS_RESET);
-
-@@ -476,10 +476,10 @@ void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainerBase *bcontainer,
- QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next);
-
- vbasedev->reginfo = g_new0(struct vfio_region_info *,
-- vbasedev->num_regions);
-+ vbasedev->num_initial_regions);
- if (vbasedev->use_region_fds) {
-- vbasedev->region_fds = g_new0(int, vbasedev->num_regions);
-- for (i = 0; i < vbasedev->num_regions; i++) {
-+ vbasedev->region_fds = g_new0(int, vbasedev->num_initial_regions);
-+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
- vbasedev->region_fds[i] = -1;
- }
- }
-@@ -489,7 +489,7 @@ void vfio_device_unprepare(VFIODevice *vbasedev)
- {
- int i;
-
-- for (i = 0; i < vbasedev->num_regions; i++) {
-+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
- g_free(vbasedev->reginfo[i]);
- if (vbasedev->region_fds != NULL && vbasedev->region_fds[i] != -1) {
- close(vbasedev->region_fds[i]);
-diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
-index 48c590b6a9..dbcd861b27 100644
---- a/hw/vfio/iommufd.c
-+++ b/hw/vfio/iommufd.c
-@@ -668,7 +668,8 @@ found_container:
- vfio_iommufd_cpr_register_device(vbasedev);
-
- trace_iommufd_cdev_device_info(vbasedev->name, devfd, vbasedev->num_irqs,
-- vbasedev->num_regions, vbasedev->flags);
-+ vbasedev->num_initial_regions,
-+ vbasedev->flags);
- return true;
-
- err_listener_register:
-diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
-index 07257d0fa0..1e69055c7c 100644
---- a/hw/vfio/pci.c
-+++ b/hw/vfio/pci.c
-@@ -2930,9 +2930,9 @@ bool vfio_pci_populate_device(VFIOPCIDevice *vdev, Error **errp)
- return false;
- }
-
-- if (vbasedev->num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {
-+ if (vbasedev->num_initial_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {
- error_setg(errp, "unexpected number of io regions %u",
-- vbasedev->num_regions);
-+ vbasedev->num_initial_regions);
- return false;
- }
-
-diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
-index 5c1795a26f..c9349ba7b7 100644
---- a/hw/vfio/platform.c
-+++ b/hw/vfio/platform.c
-@@ -148,7 +148,7 @@ static void vfio_mmap_set_enabled(VFIOPlatformDevice *vdev, bool enabled)
- {
- int i;
-
-- for (i = 0; i < vdev->vbasedev.num_regions; i++) {
-+ for (i = 0; i < vdev->vbasedev.num_initial_regions; i++) {
- vfio_region_mmaps_set_enabled(vdev->regions[i], enabled);
- }
- }
-@@ -453,9 +453,9 @@ static bool vfio_populate_device(VFIODevice *vbasedev, Error **errp)
- return false;
- }
-
-- vdev->regions = g_new0(VFIORegion *, vbasedev->num_regions);
-+ vdev->regions = g_new0(VFIORegion *, vbasedev->num_initial_regions);
-
-- for (i = 0; i < vbasedev->num_regions; i++) {
-+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
- char *name = g_strdup_printf("VFIO %s region %d\n", vbasedev->name, i);
-
- vdev->regions[i] = g_new0(VFIORegion, 1);
-@@ -499,7 +499,7 @@ irq_err:
- g_free(intp);
- }
- reg_error:
-- for (i = 0; i < vbasedev->num_regions; i++) {
-+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
- if (vdev->regions[i]) {
- vfio_region_finalize(vdev->regions[i]);
- }
-@@ -608,7 +608,7 @@ static void vfio_platform_realize(DeviceState *dev, Error **errp)
- }
- }
-
-- for (i = 0; i < vbasedev->num_regions; i++) {
-+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
- if (vfio_region_mmap(vdev->regions[i])) {
- warn_report("%s mmap unsupported, performance may be slow",
- memory_region_name(vdev->regions[i]->mem));
-diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
-index 6e4d5ccdac..10024730a1 100644
---- a/include/hw/vfio/vfio-device.h
-+++ b/include/hw/vfio/vfio-device.h
-@@ -74,7 +74,7 @@ typedef struct VFIODevice {
- VFIODeviceOps *ops;
- VFIODeviceIOOps *io_ops;
- unsigned int num_irqs;
-- unsigned int num_regions;
-+ unsigned int num_initial_regions;
- unsigned int flags;
- VFIOMigration *migration;
- Error *migration_blocker;
diff --git a/debian/patches/extra/0007-vfio-only-check-region-info-cache-for-initial-region.patch b/debian/patches/extra/0007-vfio-only-check-region-info-cache-for-initial-region.patch
deleted file mode 100644
index b239cb4..0000000
--- a/debian/patches/extra/0007-vfio-only-check-region-info-cache-for-initial-region.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: John Levon <john.levon@nutanix.com>
-Date: Tue, 14 Oct 2025 17:12:27 +0200
-Subject: [PATCH] vfio: only check region info cache for initial regions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It is semantically valid for a VFIO device to increase the number of
-regions after initialization. In this case, we'd attempt to check for
-cached region info past the size of the ->reginfo array. Check for the
-region index and skip the cache in these cases.
-
-This also works around some VGPU use cases which appear to be a bug,
-where VFIO_DEVICE_QUERY_GFX_PLANE returns a region index beyond the
-reported ->num_regions.
-
-Fixes: 95cdb024 ("vfio: add region info cache")
-Signed-off-by: John Levon <john.levon@nutanix.com>
-Reviewed-by: Cédric Le Goater <clg@redhat.com>
-Reviewed-by: Alex Williamson <alex@shazbot.org>
-Link: https://lore.kernel.org/qemu-devel/20251014151227.2298892-3-john.levon@nutanix.com
-Signed-off-by: Cédric Le Goater <clg@redhat.com>
-(cherry picked from commit 5bdcf2df64bf7e4be58524ef1442836b6d41282e
- from https://gitlab.com/legoater/qemu/-/tree/vfio-next)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/vfio/device.c | 27 +++++++++++++++++++--------
- 1 file changed, 19 insertions(+), 8 deletions(-)
-
-diff --git a/hw/vfio/device.c b/hw/vfio/device.c
-index 0b459c0f7c..7ebf41c95e 100644
---- a/hw/vfio/device.c
-+++ b/hw/vfio/device.c
-@@ -205,10 +205,19 @@ int vfio_device_get_region_info(VFIODevice *vbasedev, int index,
- int fd = -1;
- int ret;
-
-- /* check cache */
-- if (vbasedev->reginfo[index] != NULL) {
-- *info = vbasedev->reginfo[index];
-- return 0;
-+ /*
-+ * We only set up the region info cache for the initial number of regions.
-+ *
-+ * Since a VFIO device may later increase the number of regions then use
-+ * such regions with an index past ->num_initial_regions, don't attempt to
-+ * use the info cache in those cases.
-+ */
-+ if (index < vbasedev->num_initial_regions) {
-+ /* check cache */
-+ if (vbasedev->reginfo[index] != NULL) {
-+ *info = vbasedev->reginfo[index];
-+ return 0;
-+ }
- }
-
- *info = g_malloc0(argsz);
-@@ -236,10 +245,12 @@ retry:
- goto retry;
- }
-
-- /* fill cache */
-- vbasedev->reginfo[index] = *info;
-- if (vbasedev->region_fds != NULL) {
-- vbasedev->region_fds[index] = fd;
-+ if (index < vbasedev->num_initial_regions) {
-+ /* fill cache */
-+ vbasedev->reginfo[index] = *info;
-+ if (vbasedev->region_fds != NULL) {
-+ vbasedev->region_fds[index] = fd;
-+ }
- }
-
- return 0;
diff --git a/debian/patches/extra/0008-ui-vdagent-fix-windows-agent-regression.patch b/debian/patches/extra/0008-ui-vdagent-fix-windows-agent-regression.patch
deleted file mode 100644
index dbb0141..0000000
--- a/debian/patches/extra/0008-ui-vdagent-fix-windows-agent-regression.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
-Date: Mon, 27 Oct 2025 17:07:44 +0400
-Subject: [PATCH] ui/vdagent: fix windows agent regression
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Since commit f626116f ("ui/vdagent: factor out clipboard peer
-registration"), the QEMU clipboard serial is reset whenever the vdagent
-chardev receives the guest caps. This triggers a CHR_EVENT_CLOSED which
-is handled by virtio_serial_close() to notify the guest.
-
-The "reconnection logic" is there to reset the agent when a
-client (dbus, spice etc) reconnects, or the agent is restarted.
-It is required to sync the clipboard serials and to prevent races or
-loops due to clipboard managers on both ends (but this is not
-implemented by windows vdagent).
-
-The Unix agent has been reconnecting without resending caps, thus
-working with this approach.
-
-However, the Windows agent does not seem to have a way to handle
-VIRTIO_CONSOLE_PORT_OPEN=0 event and do not receive further data...
-
-Let's not trigger this disconnection/reset logic if the agent does not
-support VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL.
-
-Fixes: f626116f ("ui/vdagent: factor out clipboard peer registration")
-Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
-Reported-by: Lucas Kornicki <lucas.kornicki@nutanix.com>
-Tested-by: Lucas Kornicki <lucas.kornicki@nutanix.com>
-Link: https://lore.kernel.org/all/20251027130744.2714610-1-marcandre.lureau@redhat.com/
-[FE: picked from qemu-devel]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- ui/vdagent.c | 20 ++++++++++++++------
- 1 file changed, 14 insertions(+), 6 deletions(-)
-
-diff --git a/ui/vdagent.c b/ui/vdagent.c
-index c0746fe5b1..a7c959e8ab 100644
---- a/ui/vdagent.c
-+++ b/ui/vdagent.c
-@@ -316,6 +316,15 @@ static bool have_selection(VDAgentChardev *vd)
- return vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_SELECTION);
- }
-
-+static bool have_clipboard_serial(VDAgentChardev *vd)
-+{
-+#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1)
-+ return vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL);
-+#else
-+ return false;
-+#endif
-+}
-+
- static uint32_t type_qemu_to_vdagent(enum QemuClipboardType type)
- {
- switch (type) {
-@@ -345,8 +354,7 @@ static void vdagent_send_clipboard_grab(VDAgentChardev *vd,
- return;
- }
-
--#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1)
-- if (vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) {
-+ if (have_clipboard_serial(vd)) {
- if (!info->has_serial) {
- /* client should win */
- info->serial = vd->last_serial[info->selection]++;
-@@ -356,7 +364,6 @@ static void vdagent_send_clipboard_grab(VDAgentChardev *vd,
- data++;
- msg->size += sizeof(uint32_t);
- }
--#endif
-
- for (q = 0; q < QEMU_CLIPBOARD_TYPE__COUNT; q++) {
- type = type_qemu_to_vdagent(q);
-@@ -464,6 +471,9 @@ static void vdagent_clipboard_reset_serial(VDAgentChardev *vd)
- {
- Chardev *chr = CHARDEV(vd);
-
-+ if (!have_clipboard_serial(vd)) {
-+ return;
-+ }
- /* reopen the agent connection to reset the serial state */
- qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
- /* OPENED again after the guest disconnected, see set_fe_open */
-@@ -518,8 +528,7 @@ static void vdagent_clipboard_recv_grab(VDAgentChardev *vd, uint8_t s, uint32_t
-
- trace_vdagent_cb_grab_selection(GET_NAME(sel_name, s));
- info = qemu_clipboard_info_new(&vd->cbpeer, s);
--#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1)
-- if (vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) {
-+ if (have_clipboard_serial(vd)) {
- if (size < sizeof(uint32_t)) {
- /* this shouldn't happen! */
- return;
-@@ -537,7 +546,6 @@ static void vdagent_clipboard_recv_grab(VDAgentChardev *vd, uint8_t s, uint32_t
- data += sizeof(uint32_t);
- size -= sizeof(uint32_t);
- }
--#endif
- if (size > sizeof(uint32_t) * 10) {
- /*
- * spice has 6 types as of 2021. Limiting to 10 entries
diff --git a/debian/patches/extra/0009-file-posix-populate-pwrite_zeroes_alignment.patch b/debian/patches/extra/0009-file-posix-populate-pwrite_zeroes_alignment.patch
deleted file mode 100644
index 7e9f4b5..0000000
--- a/debian/patches/extra/0009-file-posix-populate-pwrite_zeroes_alignment.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Hajnoczi <stefanha@redhat.com>
-Date: Tue, 7 Oct 2025 10:16:58 -0400
-Subject: [PATCH] file-posix: populate pwrite_zeroes_alignment
-
-Linux block devices require write zeroes alignment whereas files do not.
-
-It may come as a surprise that block devices opened in buffered I/O mode
-require the alignment for write zeroes requests although normal
-read/write requests do not.
-
-Therefore it is necessary to populate the pwrite_zeroes_alignment field.
-
-Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
-Link: https://lore.kernel.org/20251007141700.71891-2-stefanha@redhat.com
-[FE: picked from qemu-devel]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- block/file-posix.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
-diff --git a/block/file-posix.c b/block/file-posix.c
-index 8c738674ce..827ffa77a5 100644
---- a/block/file-posix.c
-+++ b/block/file-posix.c
-@@ -1602,6 +1602,22 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
-
- bs->bl.pdiscard_alignment = dalign;
- }
-+
-+#ifdef __linux__
-+ /*
-+ * Linux requires logical block size alignment for write zeroes even
-+ * when normal reads/writes do not require alignment.
-+ */
-+ if (!s->needs_alignment) {
-+ ret = probe_logical_blocksize(s->fd,
-+ &bs->bl.pwrite_zeroes_alignment);
-+ if (ret < 0) {
-+ error_setg_errno(errp, -ret,
-+ "Failed to probe logical block size");
-+ return;
-+ }
-+ }
-+#endif /* __linux__ */
- }
-
- raw_refresh_zoned_limits(bs, &st, errp);
diff --git a/debian/patches/extra/0010-block-use-pwrite_zeroes_alignment-when-writing-first.patch b/debian/patches/extra/0010-block-use-pwrite_zeroes_alignment-when-writing-first.patch
deleted file mode 100644
index be61982..0000000
--- a/debian/patches/extra/0010-block-use-pwrite_zeroes_alignment-when-writing-first.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Hajnoczi <stefanha@redhat.com>
-Date: Tue, 7 Oct 2025 10:16:59 -0400
-Subject: [PATCH] block: use pwrite_zeroes_alignment when writing first sector
-
-Since commit 5634622bcb33 ("file-posix: allow BLKZEROOUT with -t
-writeback"), qemu-img create errors out on a Linux loop block device
-with a 4 KB sector size:
-
- # dd if=/dev/zero of=blockfile bs=1M count=1024
- # losetup --sector-size 4096 /dev/loop0 blockfile
- # qemu-img create -f raw /dev/loop0 1G
- Formatting '/dev/loop0', fmt=raw size=1073741824
- qemu-img: /dev/loop0: Failed to clear the new image's first sector: Invalid argument
-
-Use the pwrite_zeroes_alignment block limit to avoid misaligned
-fallocate(2) or ioctl(BLKZEROOUT) in the block/file-posix.c block
-driver.
-
-Fixes: 5634622bcb33 ("file-posix: allow BLKZEROOUT with -t writeback")
-Reported-by: Jean-Louis Dupond <jean-louis@dupond.be>
-Buglink: https://gitlab.com/qemu-project/qemu/-/issues/3127
-Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
-Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-Link: https://lore.kernel.org/20251007141700.71891-3-stefanha@redhat.com
-[FE: picked from qemu-devel]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- block.c | 3 ++-
- block/block-backend.c | 11 +++++++++++
- include/system/block-backend-io.h | 1 +
- 3 files changed, 14 insertions(+), 1 deletion(-)
-
-diff --git a/block.c b/block.c
-index 8848e9a7ed..be77e03904 100644
---- a/block.c
-+++ b/block.c
-@@ -606,12 +606,13 @@ create_file_fallback_zero_first_sector(BlockBackend *blk,
- int64_t current_size,
- Error **errp)
- {
-+ uint32_t alignment = blk_get_pwrite_zeroes_alignment(blk);
- int64_t bytes_to_clear;
- int ret;
-
- GLOBAL_STATE_CODE();
-
-- bytes_to_clear = MIN(current_size, BDRV_SECTOR_SIZE);
-+ bytes_to_clear = MIN(current_size, MAX(BDRV_SECTOR_SIZE, alignment));
- if (bytes_to_clear) {
- ret = blk_co_pwrite_zeroes(blk, 0, bytes_to_clear, BDRV_REQ_MAY_UNMAP);
- if (ret < 0) {
-diff --git a/block/block-backend.c b/block/block-backend.c
-index f8d6ba65c1..239d6eca37 100644
---- a/block/block-backend.c
-+++ b/block/block-backend.c
-@@ -2305,6 +2305,17 @@ uint32_t blk_get_request_alignment(BlockBackend *blk)
- return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE;
- }
-
-+/* Returns the optimal write zeroes alignment, in bytes; guaranteed nonzero */
-+uint32_t blk_get_pwrite_zeroes_alignment(BlockBackend *blk)
-+{
-+ BlockDriverState *bs = blk_bs(blk);
-+ IO_CODE();
-+ if (!bs) {
-+ return BDRV_SECTOR_SIZE;
-+ }
-+ return bs->bl.pwrite_zeroes_alignment ?: bs->bl.request_alignment;
-+}
-+
- /* Returns the maximum hardware transfer length, in bytes; guaranteed nonzero */
- uint64_t blk_get_max_hw_transfer(BlockBackend *blk)
- {
-diff --git a/include/system/block-backend-io.h b/include/system/block-backend-io.h
-index ba8dfcc7d0..6d5ac476fc 100644
---- a/include/system/block-backend-io.h
-+++ b/include/system/block-backend-io.h
-@@ -116,6 +116,7 @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
- void *opaque, int ret);
-
- uint32_t blk_get_request_alignment(BlockBackend *blk);
-+uint32_t blk_get_pwrite_zeroes_alignment(BlockBackend *blk);
- uint32_t blk_get_max_transfer(BlockBackend *blk);
- uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
-
diff --git a/debian/patches/extra/0011-block-io_uring-avoid-potentially-getting-stuck-after.patch b/debian/patches/extra/0011-block-io_uring-avoid-potentially-getting-stuck-after.patch
deleted file mode 100644
index 372ecad..0000000
--- a/debian/patches/extra/0011-block-io_uring-avoid-potentially-getting-stuck-after.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fiona Ebner <f.ebner@proxmox.com>
-Date: Mon, 24 Nov 2025 15:28:27 +0100
-Subject: [PATCH] block/io_uring: avoid potentially getting stuck after
- resubmit at the end of ioq_submit()
-
-Note that this issue seems already fixed as a consequence of the large
-io_uring rework with 047dabef97 ("block/io_uring: use aio_add_sqe()")
-in current master, so this is purely for QEMU stable branches.
-
-At the end of ioq_submit(), there is an opportunistic call to
-luring_process_completions(). This is the single caller of
-luring_process_completions() that doesn't use the
-luring_process_completions_and_submit() wrapper.
-
-Other callers use the wrapper, because luring_process_completions()
-might require a subsequent call to ioq_submit() after resubmitting a
-request. As noted for luring_resubmit():
-
-> Resubmit a request by appending it to submit_queue. The caller must ensure
-> that ioq_submit() is called later so that submit_queue requests are started.
-
-So the caller at the end of ioq_submit() violates the contract and can
-in fact be problematic if no other requests come in later. In such a
-case, the request intended to be resubmitted will never be actually be
-submitted via io_uring_submit().
-
-A reproducer exposing this issue is [0], which is based on user
-reports from [1]. Another reproducer is iotest 109 with '-i io_uring'.
-
-I had the most success to trigger the issue with [0] when using a
-BTRFS RAID 1 storage. With tmpfs, it can take quite a few iterations,
-but also triggers eventually on my machine. With iotest 109 with '-i
-io_uring' the issue triggers reliably on my ext4 file system.
-
-Have ioq_submit() submit any resubmitted requests after calling
-luring_process_completions(). The return value from io_uring_submit()
-is checked to be non-negative before the opportunistic processing of
-completions and going for the new resubmit logic, to ensure that a
-failure of io_uring_submit() is not missed. Also note that the return
-value already was not necessarily the total number of submissions,
-since the loop might've been iterated more than once even before the
-current change.
-
-Only trigger the resubmission logic if it is actually necessary to
-avoid changing behavior more than necessary. For example iotest 109
-would produce more 'mirror ready' events if always resubmitting after
-luring_process_completions() at the end of ioq_submit().
-
-Note iotest 109 still does not pass as is when run with '-i io_uring',
-because of two offset values for BLOCK_JOB_COMPLETED events being zero
-instead of non-zero as in the expected output. Note that the two
-affected test cases are expected failures and still fail, so they just
-fail "faster". The test cases are actually not triggering the resubmit
-logic, so the reason seems to be different ordering of requests and
-completions of the current aio=io_uring implementation versus
-aio=threads.
-
-[0]:
-
-> #!/bin/bash -e
-> #file=/mnt/btrfs/disk.raw
-> file=/tmp/disk.raw
-> filesize=256
-> readsize=512
-> rm -f $file
-> truncate -s $filesize $file
-> ./qemu-system-x86_64 --trace '*uring*' --qmp stdio \
-> --blockdev raw,node-name=node0,file.driver=file,file.cache.direct=off,file.filename=$file,file.aio=io_uring \
-> <<EOF
-> {"execute": "qmp_capabilities"}
-> {"execute": "human-monitor-command", "arguments": { "command-line": "qemu-io node0 \"read 0 $readsize \"" }}
-> {"execute": "quit"}
-> EOF
-
-[1]: https://forum.proxmox.com/threads/170045/
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- block/io_uring.c | 16 +++++++++++++---
- 1 file changed, 13 insertions(+), 3 deletions(-)
-
-diff --git a/block/io_uring.c b/block/io_uring.c
-index dd4f304910..5dbafc8f7b 100644
---- a/block/io_uring.c
-+++ b/block/io_uring.c
-@@ -120,11 +120,14 @@ static void luring_resubmit_short_read(LuringState *s, LuringAIOCB *luringcb,
- * event loop. When there are no events left to complete the BH is being
- * canceled.
- *
-+ * Returns whether ioq_submit() must be called again afterwards since requests
-+ * were resubmitted via luring_resubmit().
- */
--static void luring_process_completions(LuringState *s)
-+static bool luring_process_completions(LuringState *s)
- {
- struct io_uring_cqe *cqes;
- int total_bytes;
-+ bool resubmit = false;
-
- defer_call_begin();
-
-@@ -182,6 +185,7 @@ static void luring_process_completions(LuringState *s)
- */
- if (ret == -EINTR || ret == -EAGAIN) {
- luring_resubmit(s, luringcb);
-+ resubmit = true;
- continue;
- }
- } else if (!luringcb->qiov) {
-@@ -194,6 +198,7 @@ static void luring_process_completions(LuringState *s)
- if (luringcb->is_read) {
- if (ret > 0) {
- luring_resubmit_short_read(s, luringcb, ret);
-+ resubmit = true;
- continue;
- } else {
- /* Pad with zeroes */
-@@ -224,6 +229,8 @@ end:
- qemu_bh_cancel(s->completion_bh);
-
- defer_call_end();
-+
-+ return resubmit;
- }
-
- static int ioq_submit(LuringState *s)
-@@ -231,6 +238,7 @@ static int ioq_submit(LuringState *s)
- int ret = 0;
- LuringAIOCB *luringcb, *luringcb_next;
-
-+resubmit:
- while (s->io_q.in_queue > 0) {
- /*
- * Try to fetch sqes from the ring for requests waiting in
-@@ -260,12 +268,14 @@ static int ioq_submit(LuringState *s)
- }
- s->io_q.blocked = (s->io_q.in_queue > 0);
-
-- if (s->io_q.in_flight) {
-+ if (ret >= 0 && s->io_q.in_flight) {
- /*
- * We can try to complete something just right away if there are
- * still requests in-flight.
- */
-- luring_process_completions(s);
-+ if (luring_process_completions(s)) {
-+ goto resubmit;
-+ }
- }
- return ret;
- }
diff --git a/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch b/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
index df81614..3294086 100644
--- a/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
+++ b/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
@@ -14,7 +14,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
-index 827ffa77a5..baac7653db 100644
+index 6265d2e248..41ac3f222f 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -588,7 +588,7 @@ static QemuOptsList raw_runtime_opts = {
diff --git a/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch b/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
index 9582fc1..5a51af1 100644
--- a/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
+++ b/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/net/net.h b/include/net/net.h
-index 84ee18e0f9..d42d935db5 100644
+index 72b476ee1d..f257fc7401 100644
--- a/include/net/net.h
+++ b/include/net/net.h
-@@ -311,8 +311,8 @@ void netdev_add(QemuOpts *opts, Error **errp);
+@@ -325,8 +325,8 @@ void netdev_add(QemuOpts *opts, Error **errp);
int net_hub_id_for_client(NetClientState *nc, int *id);
diff --git a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
index cd2e07a..b4e1b2f 100644
--- a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
+++ b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
@@ -10,10 +10,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
-index 42168f1d6d..4f63100453 100644
+index cee1f692a1..6f49be3796 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
-@@ -2630,9 +2630,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
+@@ -2641,9 +2641,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
#define CPU_RESOLVING_TYPE TYPE_X86_CPU
#ifdef TARGET_X86_64
diff --git a/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch b/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch
index 8fe7b5d..9c6c696 100644
--- a/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch
+++ b/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch
@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/ui/spice-core.c b/ui/spice-core.c
-index 2645e96ef6..a8b34d3bf5 100644
+index 8a6050f4ae..25e891e4ba 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
-@@ -694,32 +694,35 @@ static void qemu_spice_init(void)
+@@ -696,32 +696,35 @@ static void qemu_spice_init(void)
if (tls_port) {
x509_dir = qemu_opt_get(opts, "x509-dir");
diff --git a/debian/patches/pve/0005-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch b/debian/patches/pve/0005-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch
index aaf2050..45feb82 100644
--- a/debian/patches/pve/0005-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch
+++ b/debian/patches/pve/0005-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch
@@ -9,7 +9,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/block/gluster.c b/block/gluster.c
-index 89abd40f31..d3f2e56229 100644
+index 4fb25b2c6d..542cc8da4a 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -42,7 +42,7 @@
@@ -21,7 +21,7 @@ index 89abd40f31..d3f2e56229 100644
/*
* Several versions of GlusterFS (3.12? -> 6.0.1) fail when the transfer size
* is greater or equal to 1024 MiB, so we are limiting the transfer size to 512
-@@ -421,6 +421,7 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
+@@ -420,6 +420,7 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
int old_errno;
SocketAddressList *server;
uint64_t port;
@@ -29,7 +29,7 @@ index 89abd40f31..d3f2e56229 100644
glfs = glfs_find_preopened(gconf->volume);
if (glfs) {
-@@ -463,9 +464,15 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
+@@ -462,9 +463,15 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
}
}
diff --git a/debian/patches/pve/0006-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch b/debian/patches/pve/0006-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch
index 573d26a..7100ae1 100644
--- a/debian/patches/pve/0006-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch
+++ b/debian/patches/pve/0006-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch
@@ -18,10 +18,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+)
diff --git a/block/rbd.c b/block/rbd.c
-index 3611dc81cf..d114119671 100644
+index 2a70b5a983..c0da22ed7b 100644
--- a/block/rbd.c
+++ b/block/rbd.c
-@@ -1017,6 +1017,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
+@@ -1015,6 +1015,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
rados_conf_set(*cluster, "rbd_cache", "false");
}
diff --git a/debian/patches/pve/0007-PVE-Up-glusterfs-allow-partial-reads.patch b/debian/patches/pve/0007-PVE-Up-glusterfs-allow-partial-reads.patch
index dd3b92f..8b94617 100644
--- a/debian/patches/pve/0007-PVE-Up-glusterfs-allow-partial-reads.patch
+++ b/debian/patches/pve/0007-PVE-Up-glusterfs-allow-partial-reads.patch
@@ -11,23 +11,25 @@ treating partial reads as errors doesn't seem to make much
sense.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[FE: rebase for 10.2.0]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
block/gluster.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/block/gluster.c b/block/gluster.c
-index d3f2e56229..de0fb4cf68 100644
+index 542cc8da4a..ba0f92ce52 100644
--- a/block/gluster.c
+++ b/block/gluster.c
-@@ -57,6 +57,7 @@ typedef struct GlusterAIOCB {
+@@ -56,6 +56,7 @@ typedef struct GlusterAIOCB {
+ int64_t size;
int ret;
Coroutine *coroutine;
- AioContext *aio_context;
+ bool is_write;
} GlusterAIOCB;
typedef struct BDRVGlusterState {
-@@ -746,8 +747,10 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret,
+@@ -745,8 +746,10 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret,
acb->ret = 0; /* Success */
} else if (ret < 0) {
acb->ret = -errno; /* Read/Write failed */
@@ -38,17 +40,17 @@ index d3f2e56229..de0fb4cf68 100644
+ acb->ret = 0; /* Success */
}
- aio_co_schedule(acb->aio_context, acb->coroutine);
-@@ -1014,6 +1017,7 @@ static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs,
+ /*
+@@ -1022,6 +1025,7 @@ static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs,
+ acb.size = bytes;
acb.ret = 0;
acb.coroutine = qemu_coroutine_self();
- acb.aio_context = bdrv_get_aio_context(bs);
+ acb.is_write = true;
ret = glfs_zerofill_async(s->fd, offset, bytes, gluster_finish_aiocb, &acb);
if (ret < 0) {
-@@ -1194,9 +1198,11 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
- acb.aio_context = bdrv_get_aio_context(bs);
+@@ -1201,9 +1205,11 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
+ acb.coroutine = qemu_coroutine_self();
if (write) {
+ acb.is_write = true;
@@ -59,18 +61,18 @@ index d3f2e56229..de0fb4cf68 100644
ret = glfs_preadv_async(s->fd, qiov->iov, qiov->niov, offset, 0,
gluster_finish_aiocb, &acb);
}
-@@ -1259,6 +1265,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
+@@ -1265,6 +1271,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
+ acb.size = 0;
acb.ret = 0;
acb.coroutine = qemu_coroutine_self();
- acb.aio_context = bdrv_get_aio_context(bs);
+ acb.is_write = true;
ret = glfs_fsync_async(s->fd, gluster_finish_aiocb, &acb);
if (ret < 0) {
-@@ -1307,6 +1314,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs,
+@@ -1312,6 +1319,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs,
+ acb.size = 0;
acb.ret = 0;
acb.coroutine = qemu_coroutine_self();
- acb.aio_context = bdrv_get_aio_context(bs);
+ acb.is_write = true;
ret = glfs_discard_async(s->fd, offset, bytes, gluster_finish_aiocb, &acb);
diff --git a/debian/patches/pve/0008-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch b/debian/patches/pve/0008-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
index 7710b06..eb01c67 100644
--- a/debian/patches/pve/0008-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
+++ b/debian/patches/pve/0008-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
@@ -9,12 +9,12 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/qemu-img.c b/qemu-img.c
-index 7a162fdc08..0bed551960 100644
+index c42dd4e995..616eebc42b 100644
--- a/qemu-img.c
+++ b/qemu-img.c
-@@ -3158,7 +3158,8 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
- list = collect_image_info_list(image_opts, filename, fmt, chain,
- force_share);
+@@ -3184,7 +3184,8 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
+ list = collect_image_info_list(image_opts, filename, fmt, cache, chain,
+ limits, force_share);
if (!list) {
- return 1;
+ // return success if snapshot does not exist
diff --git a/debian/patches/pve/0009-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch b/debian/patches/pve/0009-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
index c9e1f34..7b31e4b 100644
--- a/debian/patches/pve/0009-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
+++ b/debian/patches/pve/0009-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
@@ -39,7 +39,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2 files changed, 133 insertions(+), 73 deletions(-)
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
-index 2c5a8a28f9..a6de1434a3 100644
+index 6bc8265cfb..85458ea2d8 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -60,9 +60,9 @@ SRST
@@ -55,10 +55,10 @@ index 2c5a8a28f9..a6de1434a3 100644
DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
-index 0bed551960..0a0ca0cec7 100644
+index 616eebc42b..bf7c637d48 100644
--- a/qemu-img.c
+++ b/qemu-img.c
-@@ -5253,10 +5253,12 @@ static int img_bitmap(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5279,10 +5279,12 @@ static int img_bitmap(const img_cmd_t *ccmd, int argc, char **argv)
#define C_IF 04
#define C_OF 010
#define C_SKIP 020
@@ -71,7 +71,7 @@ index 0bed551960..0a0ca0cec7 100644
};
struct DdIo {
-@@ -5332,6 +5334,19 @@ static int img_dd_skip(const char *arg,
+@@ -5358,6 +5360,19 @@ static int img_dd_skip(const char *arg,
return 0;
}
@@ -91,7 +91,7 @@ index 0bed551960..0a0ca0cec7 100644
static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
{
int ret = 0;
-@@ -5372,6 +5387,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5398,6 +5413,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
{ "if", img_dd_if, C_IF },
{ "of", img_dd_of, C_OF },
{ "skip", img_dd_skip, C_SKIP },
@@ -99,7 +99,7 @@ index 0bed551960..0a0ca0cec7 100644
{ NULL, NULL, 0 }
};
const struct option long_options[] = {
-@@ -5469,91 +5485,112 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5495,91 +5511,112 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
arg = NULL;
}
@@ -276,7 +276,7 @@ index 0bed551960..0a0ca0cec7 100644
}
if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
-@@ -5570,20 +5607,43 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5596,20 +5633,43 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
in.buf = g_new(uint8_t, in.bsz);
for (out_pos = 0; in_pos < size; ) {
diff --git a/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-isize-parameter.patch b/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-isize-parameter.patch
index fbf92a1..a6bd8d8 100644
--- a/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-isize-parameter.patch
+++ b/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-isize-parameter.patch
@@ -17,10 +17,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
-index 0a0ca0cec7..89ef74ae07 100644
+index bf7c637d48..84fd7d5470 100644
--- a/qemu-img.c
+++ b/qemu-img.c
-@@ -5254,11 +5254,13 @@ static int img_bitmap(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5280,11 +5280,13 @@ static int img_bitmap(const img_cmd_t *ccmd, int argc, char **argv)
#define C_OF 010
#define C_SKIP 020
#define C_OSIZE 040
@@ -34,7 +34,7 @@ index 0a0ca0cec7..89ef74ae07 100644
};
struct DdIo {
-@@ -5347,6 +5349,19 @@ static int img_dd_osize(const char *arg,
+@@ -5373,6 +5375,19 @@ static int img_dd_osize(const char *arg,
return 0;
}
@@ -54,7 +54,7 @@ index 0a0ca0cec7..89ef74ae07 100644
static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
{
int ret = 0;
-@@ -5361,12 +5376,14 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5387,12 +5402,14 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
int c, i;
const char *out_fmt = "raw";
const char *fmt = NULL;
@@ -70,7 +70,7 @@ index 0a0ca0cec7..89ef74ae07 100644
};
struct DdIo in = {
.bsz = 512, /* Block size is by default 512 bytes */
-@@ -5388,6 +5405,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5414,6 +5431,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
{ "of", img_dd_of, C_OF },
{ "skip", img_dd_skip, C_SKIP },
{ "osize", img_dd_osize, C_OSIZE },
@@ -78,7 +78,7 @@ index 0a0ca0cec7..89ef74ae07 100644
{ NULL, NULL, 0 }
};
const struct option long_options[] = {
-@@ -5606,9 +5624,10 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5632,9 +5650,10 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
in.buf = g_new(uint8_t, in.bsz);
@@ -91,7 +91,7 @@ index 0a0ca0cec7..89ef74ae07 100644
if (blk1) {
in_ret = blk_pread(blk1, in_pos, bytes, in.buf, 0);
if (in_ret == 0) {
-@@ -5617,6 +5636,9 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5643,6 +5662,9 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
} else {
in_ret = read(STDIN_FILENO, in.buf, bytes);
if (in_ret == 0) {
diff --git a/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-n-skip_create.patch b/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-n-skip_create.patch
index ee936c5..856505c 100644
--- a/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-n-skip_create.patch
+++ b/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-n-skip_create.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] PVE: [Up] qemu-img dd: add -n skip_create
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
[FE: fix getopt-string + add documentation
- rebase for 10.1.0]
+ rebase for 10.2.0]
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
docs/tools/qemu-img.rst | 11 ++++++++++-
@@ -14,7 +14,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
3 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
-index 5e7b85079d..6249e01da9 100644
+index 558b0eb84d..c3fefaab07 100644
--- a/docs/tools/qemu-img.rst
+++ b/docs/tools/qemu-img.rst
@@ -212,6 +212,10 @@ Parameters to convert subcommand:
@@ -46,11 +46,11 @@ index 5e7b85079d..6249e01da9 100644
+ volume has already been created with site specific options that cannot
+ be supplied through ``qemu-img``.
+
- .. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [--backing-chain] [-U] FILENAME
+ .. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [--backing-chain] [--limits] [-t CACHE] [-U] FILENAME
Give information about the disk image *FILENAME*. Use it in
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
-index a6de1434a3..d584624f8e 100644
+index 85458ea2d8..f97c2fa396 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -60,9 +60,9 @@ SRST
@@ -66,10 +66,10 @@ index a6de1434a3..d584624f8e 100644
DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
-index 89ef74ae07..6e92a70254 100644
+index 84fd7d5470..c484479fc5 100644
--- a/qemu-img.c
+++ b/qemu-img.c
-@@ -5378,7 +5378,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5404,7 +5404,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
const char *fmt = NULL;
int64_t size = 0, readsize = 0;
int64_t out_pos, in_pos;
@@ -78,7 +78,7 @@ index 89ef74ae07..6e92a70254 100644
struct DdInfo dd = {
.flags = 0,
.count = 0,
-@@ -5418,7 +5418,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5444,7 +5444,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
{ 0, 0, 0, 0 }
};
@@ -87,7 +87,7 @@ index 89ef74ae07..6e92a70254 100644
if (c == EOF) {
break;
}
-@@ -5459,6 +5459,9 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5485,6 +5485,9 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
case 'O':
out_fmt = optarg;
break;
@@ -97,7 +97,7 @@ index 89ef74ae07..6e92a70254 100644
case 'U':
force_share = true;
break;
-@@ -5588,13 +5591,15 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5614,13 +5617,15 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
size - in.bsz * in.offset, &error_abort);
}
diff --git a/debian/patches/pve/0012-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch b/debian/patches/pve/0012-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
index edea617..6b1731a 100644
--- a/debian/patches/pve/0012-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
+++ b/debian/patches/pve/0012-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
@@ -14,7 +14,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
3 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
-index 6249e01da9..0ea21e061f 100644
+index c3fefaab07..9da1e526fb 100644
--- a/docs/tools/qemu-img.rst
+++ b/docs/tools/qemu-img.rst
@@ -496,10 +496,10 @@ Command description:
@@ -32,7 +32,7 @@ index 6249e01da9..0ea21e061f 100644
The data is by default read and written using blocks of 512 bytes but can be
modified by specifying *BLOCK_SIZE*. If count=\ *BLOCKS* is specified
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
-index d584624f8e..be30905374 100644
+index f97c2fa396..206ca7381c 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -60,9 +60,9 @@ SRST
@@ -48,10 +48,10 @@ index d584624f8e..be30905374 100644
DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
-index 6e92a70254..e38317a445 100644
+index c484479fc5..d738ea5185 100644
--- a/qemu-img.c
+++ b/qemu-img.c
-@@ -5370,6 +5370,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5396,6 +5396,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
BlockDriver *drv = NULL, *proto_drv = NULL;
BlockBackend *blk1 = NULL, *blk2 = NULL;
QemuOpts *opts = NULL;
@@ -59,7 +59,7 @@ index 6e92a70254..e38317a445 100644
QemuOptsList *create_opts = NULL;
Error *local_err = NULL;
bool image_opts = false;
-@@ -5379,6 +5380,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5405,6 +5406,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
int64_t size = 0, readsize = 0;
int64_t out_pos, in_pos;
bool force_share = false, skip_create = false;
@@ -67,7 +67,7 @@ index 6e92a70254..e38317a445 100644
struct DdInfo dd = {
.flags = 0,
.count = 0,
-@@ -5418,7 +5420,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5444,7 +5446,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
{ 0, 0, 0, 0 }
};
@@ -76,7 +76,7 @@ index 6e92a70254..e38317a445 100644
if (c == EOF) {
break;
}
-@@ -5462,6 +5464,19 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5488,6 +5490,19 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
case 'n':
skip_create = true;
break;
@@ -96,7 +96,7 @@ index 6e92a70254..e38317a445 100644
case 'U':
force_share = true;
break;
-@@ -5520,11 +5535,24 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5546,11 +5561,24 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
if (dd.flags & C_IF) {
blk1 = img_open(image_opts, in.filename, fmt, 0, false, false,
force_share);
@@ -122,7 +122,7 @@ index 6e92a70254..e38317a445 100644
}
if (dd.flags & C_OSIZE) {
-@@ -5679,6 +5707,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
+@@ -5705,6 +5733,7 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
out:
g_free(arg);
qemu_opts_del(opts);
diff --git a/debian/patches/pve/0013-PVE-virtio-balloon-improve-query-balloon.patch b/debian/patches/pve/0013-PVE-virtio-balloon-improve-query-balloon.patch
index d440dbb..b098ca9 100644
--- a/debian/patches/pve/0013-PVE-virtio-balloon-improve-query-balloon.patch
+++ b/debian/patches/pve/0013-PVE-virtio-balloon-improve-query-balloon.patch
@@ -18,10 +18,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
4 files changed, 82 insertions(+), 4 deletions(-)
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
-index 3a612e2232..036d87cc90 100644
+index 74a56600be..fe4ad00c16 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
-@@ -182,7 +182,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
+@@ -200,7 +200,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
return;
}
@@ -59,10 +59,10 @@ index 3a612e2232..036d87cc90 100644
qapi_free_BalloonInfo(info);
}
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
-index db787d00b3..26ebf3a5ce 100644
+index 02cdd807d7..a49cf294e4 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
-@@ -795,8 +795,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
+@@ -796,8 +796,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
static void virtio_balloon_stat(void *opaque, BalloonInfo *info)
{
VirtIOBalloon *dev = opaque;
@@ -103,7 +103,7 @@ index db787d00b3..26ebf3a5ce 100644
static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
diff --git a/qapi/machine.json b/qapi/machine.json
-index 038eab281c..5f172ece18 100644
+index 907cb25f75..0eaf36b0fe 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1125,9 +1125,29 @@
diff --git a/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch b/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch
index a131d2b..eb13f82 100644
--- a/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch
+++ b/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch
@@ -13,10 +13,10 @@ Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
-index 6aca1a626e..934cdb886d 100644
+index 28dfd3e15b..55e4550cd4 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
-@@ -94,6 +94,12 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
+@@ -120,6 +120,12 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
info->numa_mem_supported = mc->numa_mem_supported;
info->deprecated = !!mc->deprecation_reason;
info->acpi = !!object_class_property_find(OBJECT_CLASS(mc), "acpi");
@@ -30,7 +30,7 @@ index 6aca1a626e..934cdb886d 100644
info->default_cpu_type = g_strdup(default_cpu_type);
}
diff --git a/qapi/machine.json b/qapi/machine.json
-index 5f172ece18..47ac68a3b5 100644
+index 0eaf36b0fe..e981da9fbb 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -170,6 +170,8 @@
diff --git a/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch b/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch
index 02ec05b..cf1993a 100644
--- a/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch
+++ b/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch
@@ -14,7 +14,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2 files changed, 7 insertions(+)
diff --git a/qapi/ui.json b/qapi/ui.json
-index 1b2f4a4769..c9982e1bcc 100644
+index e3da77632a..cf58718ece 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -315,11 +315,14 @@
@@ -33,10 +33,10 @@ index 1b2f4a4769..c9982e1bcc 100644
'if': 'CONFIG_SPICE' }
diff --git a/ui/spice-core.c b/ui/spice-core.c
-index a8b34d3bf5..994079ec87 100644
+index 25e891e4ba..daad8a7f1f 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
-@@ -554,6 +554,10 @@ static SpiceInfo *qmp_query_spice_real(Error **errp)
+@@ -556,6 +556,10 @@ static SpiceInfo *qmp_query_spice_real(Error **errp)
micro = SPICE_SERVER_VERSION & 0xff;
info->compiled_version = g_strdup_printf("%d.%d.%d", major, minor, micro);
diff --git a/debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch b/debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch
index 4e84027..cdc7811 100644
--- a/debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch
+++ b/debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch
@@ -271,7 +271,7 @@ index 0000000000..17ae2cb261
+
+#endif /* QIO_CHANNEL_SAVEVM_ASYNC_H */
diff --git a/migration/meson.build b/migration/meson.build
-index 276da3be5a..1d32185fff 100644
+index 16909d54c5..e79f95bb6c 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -14,6 +14,7 @@ system_ss.add(files(
@@ -281,4 +281,4 @@ index 276da3be5a..1d32185fff 100644
+ 'channel-savevm-async.c',
'cpr.c',
'cpr-transfer.c',
- 'cpu-throttle.c',
+ 'cpr-exec.c',
diff --git a/debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch b/debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch
index 9401690..7ca1e70 100644
--- a/debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch
+++ b/debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch
@@ -42,20 +42,20 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
include/migration/snapshot.h | 2 +
include/monitor/hmp.h | 3 +
migration/meson.build | 1 +
- migration/savevm-async.c | 581 +++++++++++++++++++++++++++++++++++
+ migration/savevm-async.c | 586 +++++++++++++++++++++++++++++++++++
monitor/hmp-cmds.c | 38 +++
qapi/migration.json | 34 ++
qapi/misc.json | 18 ++
qemu-options.hx | 12 +
system/vl.c | 10 +
- 11 files changed, 729 insertions(+)
+ 11 files changed, 734 insertions(+)
create mode 100644 migration/savevm-async.c
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
-index 6142f60e7b..3e15458335 100644
+index 41674dcbe1..9b6cc87127 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
-@@ -510,6 +510,19 @@ SRST
+@@ -530,6 +530,19 @@ SRST
Show current migration parameters.
ERST
@@ -76,10 +76,10 @@ index 6142f60e7b..3e15458335 100644
.name = "balloon",
.args_type = "",
diff --git a/hmp-commands.hx b/hmp-commands.hx
-index d0e4f35a30..0d9241db9e 100644
+index 5cc4788f12..eda6225ef1 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
-@@ -1862,3 +1862,20 @@ SRST
+@@ -1867,3 +1867,20 @@ SRST
List event channels in the guest
ERST
#endif
@@ -112,10 +112,10 @@ index 9e4dcaaa75..2581730d74 100644
+
#endif
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
-index ae116d9804..2596cc2426 100644
+index 83721b5ffc..f05423ceda 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
-@@ -28,6 +28,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict);
+@@ -29,6 +29,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict);
void hmp_info_uuid(Monitor *mon, const QDict *qdict);
void hmp_info_chardev(Monitor *mon, const QDict *qdict);
void hmp_info_mice(Monitor *mon, const QDict *qdict);
@@ -123,7 +123,7 @@ index ae116d9804..2596cc2426 100644
void hmp_info_migrate(Monitor *mon, const QDict *qdict);
void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
-@@ -92,6 +93,8 @@ void hmp_closefd(Monitor *mon, const QDict *qdict);
+@@ -93,6 +94,8 @@ void hmp_closefd(Monitor *mon, const QDict *qdict);
void hmp_mouse_move(Monitor *mon, const QDict *qdict);
void hmp_mouse_button(Monitor *mon, const QDict *qdict);
void hmp_mouse_set(Monitor *mon, const QDict *qdict);
@@ -133,12 +133,12 @@ index ae116d9804..2596cc2426 100644
void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict);
void hmp_chardev_add(Monitor *mon, const QDict *qdict);
diff --git a/migration/meson.build b/migration/meson.build
-index 1d32185fff..409b748980 100644
+index e79f95bb6c..140264b477 100644
--- a/migration/meson.build
+++ b/migration/meson.build
-@@ -33,6 +33,7 @@ system_ss.add(files(
- 'options.c',
+@@ -35,6 +35,7 @@ system_ss.add(files(
'postcopy-ram.c',
+ 'ram.c',
'savevm.c',
+ 'savevm-async.c',
'socket.c',
@@ -146,10 +146,10 @@ index 1d32185fff..409b748980 100644
'threadinfo.c',
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
new file mode 100644
-index 0000000000..56e0fa6c69
+index 0000000000..5c22c29b9a
--- /dev/null
+++ b/migration/savevm-async.c
-@@ -0,0 +1,581 @@
+@@ -0,0 +1,586 @@
+#include "qemu/osdep.h"
+#include "migration/channel-savevm-async.h"
+#include "migration/migration.h"
@@ -703,7 +703,7 @@ index 0000000000..56e0fa6c69
+ }
+
+ qemu_system_reset(SHUTDOWN_CAUSE_NONE);
-+ ret = qemu_loadvm_state(f);
++ ret = qemu_loadvm_state(f, &local_err);
+
+ /* dirty bitmap migration has a special case we need to trigger manually */
+ dirty_bitmap_mig_before_vm_start();
@@ -715,7 +715,12 @@ index 0000000000..56e0fa6c69
+
+ migration_incoming_state_destroy();
+ if (ret < 0) {
-+ error_setg_errno(errp, -ret, "Error while loading VM state");
++ if (local_err) {
++ error_setg_errno(errp, -ret, "Error while loading VM state - %s",
++ error_get_pretty(local_err));
++ } else {
++ error_setg_errno(errp, -ret, "Error while loading VM state");
++ }
+ goto the_end;
+ }
+
@@ -732,7 +737,7 @@ index 0000000000..56e0fa6c69
+ return ret;
+}
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 74a0f56566..1e66bff724 100644
+index 33a88ce205..7af9fed7ea 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -24,6 +24,7 @@
@@ -743,7 +748,7 @@ index 74a0f56566..1e66bff724 100644
#include "qapi/qapi-commands-misc.h"
#include "qobject/qdict.h"
#include "qemu/cutils.h"
-@@ -434,3 +435,40 @@ void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
+@@ -435,3 +436,40 @@ void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "DTB dumped to '%s'\n", filename);
}
#endif
@@ -785,10 +790,10 @@ index 74a0f56566..1e66bff724 100644
+ }
+}
diff --git a/qapi/migration.json b/qapi/migration.json
-index 2387c21e9c..c1d962b4ed 100644
+index cf023bd29d..f21d06c5a4 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
-@@ -319,6 +319,40 @@
+@@ -330,6 +330,40 @@
'*dirty-limit-throttle-time-per-round': 'uint64',
'*dirty-limit-ring-full-time': 'uint64'} }
@@ -830,7 +835,7 @@ index 2387c21e9c..c1d962b4ed 100644
# @query-migrate:
#
diff --git a/qapi/misc.json b/qapi/misc.json
-index 28c641fe2f..51d907b2b8 100644
+index 28c641fe2f..5d2f12259a 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -449,6 +449,24 @@
@@ -840,7 +845,7 @@ index 28c641fe2f..51d907b2b8 100644
+##
+# @savevm-start:
+#
-+# Prepare for snapshot and halt VM. Save VM state to statefile.
++# Prepare for snapshot and halt VM. Save VM state to statefile.
+#
+# @statefile: target file that state should be written to.
+#
@@ -859,10 +864,10 @@ index 28c641fe2f..51d907b2b8 100644
# @CommandLineParameterType:
#
diff --git a/qemu-options.hx b/qemu-options.hx
-index ab23f14d21..3ec9e52d31 100644
+index fca2b7bc74..99c04c5ab9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
-@@ -5048,6 +5048,18 @@ SRST
+@@ -5085,6 +5085,18 @@ SRST
Start right away with a saved state (``loadvm`` in monitor)
ERST
@@ -882,10 +887,10 @@ index ab23f14d21..3ec9e52d31 100644
DEF("daemonize", 0, QEMU_OPTION_daemonize, \
"-daemonize daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
diff --git a/system/vl.c b/system/vl.c
-index 3b7057e6c6..28a7d74f5b 100644
+index 5091fe52d9..ab845eb634 100644
--- a/system/vl.c
+++ b/system/vl.c
-@@ -173,6 +173,7 @@ static const char *accelerators;
+@@ -174,6 +174,7 @@ static const char *accelerators;
static bool have_custom_ram_size;
static const char *ram_memdev_id;
static QDict *machine_opts_dict;
@@ -893,7 +898,7 @@ index 3b7057e6c6..28a7d74f5b 100644
static QTAILQ_HEAD(, ObjectOption) object_opts = QTAILQ_HEAD_INITIALIZER(object_opts);
static QTAILQ_HEAD(, DeviceOption) device_opts = QTAILQ_HEAD_INITIALIZER(device_opts);
static int display_remote;
-@@ -2811,6 +2812,12 @@ void qmp_x_exit_preconfig(Error **errp)
+@@ -2817,6 +2818,12 @@ void qmp_x_exit_preconfig(Error **errp)
RunState state = autostart ? RUN_STATE_RUNNING : runstate_get();
load_snapshot(loadvm, NULL, false, NULL, &error_fatal);
load_snapshot_resume(state);
@@ -906,7 +911,7 @@ index 3b7057e6c6..28a7d74f5b 100644
}
if (replay_mode != REPLAY_MODE_NONE) {
replay_vmstate_init();
-@@ -3357,6 +3364,9 @@ void qemu_init(int argc, char **argv)
+@@ -3363,6 +3370,9 @@ void qemu_init(int argc, char **argv)
case QEMU_OPTION_loadvm:
loadvm = optarg;
break;
diff --git a/debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch b/debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch
index 9a60ee8..36b6b81 100644
--- a/debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch
+++ b/debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch
@@ -10,7 +10,7 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
[increase max IOV count in QEMUFile to actually write more data]
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: adapt to removal of QEMUFileOps]
+[FE: rebase for 10.2.0]
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
migration/qemu-file.c | 48 +++++++++++++++++++++++++++-------------
@@ -19,7 +19,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
3 files changed, 38 insertions(+), 17 deletions(-)
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
-index b6ac190034..46d899edb0 100644
+index 4b5a409a80..5e5e4627e9 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -34,8 +34,8 @@
@@ -63,7 +63,7 @@ index b6ac190034..46d899edb0 100644
return f;
}
-@@ -129,17 +134,27 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
+@@ -128,17 +133,27 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
*/
QEMUFile *qemu_file_get_return_path(QEMUFile *f)
{
@@ -94,16 +94,16 @@ index b6ac190034..46d899edb0 100644
}
/*
-@@ -339,7 +354,7 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f)
+@@ -338,7 +353,7 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f)
}
do {
- struct iovec iov = { f->buf + pending, IO_BUF_SIZE - pending };
+ struct iovec iov = { f->buf + pending, f->buf_allocated_size - pending };
- len = qio_channel_readv_full(f->ioc, &iov, 1, pfds, pnfd, 0,
+ len = qio_channel_readv_full(f->ioc, &iov, 1, pfds, pnfd,
+ QIO_CHANNEL_READ_FLAG_FD_PRESERVE_BLOCKING,
&local_error);
- if (len == QIO_CHANNEL_ERR_BLOCK) {
-@@ -443,6 +458,9 @@ int qemu_fclose(QEMUFile *f)
+@@ -435,6 +450,9 @@ int qemu_fclose(QEMUFile *f)
g_free(fde);
}
g_clear_pointer(&f->ioc, object_unref);
@@ -113,7 +113,7 @@ index b6ac190034..46d899edb0 100644
error_free(f->last_error_obj);
g_free(f);
trace_qemu_file_fclose();
-@@ -491,7 +509,7 @@ static void add_buf_to_iovec(QEMUFile *f, size_t len)
+@@ -483,7 +501,7 @@ static void add_buf_to_iovec(QEMUFile *f, size_t len)
{
if (!add_to_iovec(f, f->buf + f->buf_index, len, false)) {
f->buf_index += len;
@@ -122,7 +122,7 @@ index b6ac190034..46d899edb0 100644
qemu_fflush(f);
}
}
-@@ -516,7 +534,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size)
+@@ -508,7 +526,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size)
}
while (size > 0) {
@@ -131,7 +131,7 @@ index b6ac190034..46d899edb0 100644
if (l > size) {
l = size;
}
-@@ -660,8 +678,8 @@ size_t coroutine_mixed_fn qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t si
+@@ -652,8 +670,8 @@ size_t coroutine_mixed_fn qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t si
size_t index;
assert(!qemu_file_is_writable(f));
@@ -142,7 +142,7 @@ index b6ac190034..46d899edb0 100644
/* The 1st byte to read from */
index = f->buf_index + offset;
-@@ -711,7 +729,7 @@ size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size
+@@ -703,7 +721,7 @@ size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size
size_t res;
uint8_t *src;
@@ -151,7 +151,7 @@ index b6ac190034..46d899edb0 100644
if (res == 0) {
return done;
}
-@@ -745,7 +763,7 @@ size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size
+@@ -737,7 +755,7 @@ size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size
*/
size_t coroutine_mixed_fn qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size)
{
@@ -160,7 +160,7 @@ index b6ac190034..46d899edb0 100644
size_t res;
uint8_t *src = NULL;
-@@ -770,7 +788,7 @@ int coroutine_mixed_fn qemu_peek_byte(QEMUFile *f, int offset)
+@@ -762,7 +780,7 @@ int coroutine_mixed_fn qemu_peek_byte(QEMUFile *f, int offset)
int index = f->buf_index + offset;
assert(!qemu_file_is_writable(f));
@@ -170,7 +170,7 @@ index b6ac190034..46d899edb0 100644
if (index >= f->buf_size) {
qemu_fill_buffer(f);
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
-index f5b9f430e0..0179b90698 100644
+index c13c967167..4ab142034f 100644
--- a/migration/qemu-file.h
+++ b/migration/qemu-file.h
@@ -30,7 +30,9 @@
@@ -184,7 +184,7 @@ index f5b9f430e0..0179b90698 100644
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QEMUFile, qemu_fclose)
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
-index 56e0fa6c69..730b815494 100644
+index 5c22c29b9a..9942557455 100644
--- a/migration/savevm-async.c
+++ b/migration/savevm-async.c
@@ -409,7 +409,7 @@ void qmp_savevm_start(const char *statefile, Error **errp)
diff --git a/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch b/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
index 79bd6b1..b353177 100644
--- a/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
+++ b/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
@@ -247,10 +247,10 @@ index 0000000000..036edb17f5
+
+block_init(bdrv_zeroinit_init);
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 7d281ab7ae..aa1dba4284 100644
+index 64f2befdf5..19b60e3a96 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
-@@ -3305,7 +3305,7 @@
+@@ -3376,7 +3376,7 @@
{ 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' },
{ 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' },
{ 'name': 'virtio-blk-vhost-vdpa', 'if': 'CONFIG_BLKIO' },
@@ -259,7 +259,7 @@ index 7d281ab7ae..aa1dba4284 100644
##
# @BlockdevOptionsFile:
-@@ -4863,7 +4863,8 @@
+@@ -4934,7 +4934,8 @@
'if': 'CONFIG_BLKIO' },
'vmdk': 'BlockdevOptionsGenericCOWFormat',
'vpc': 'BlockdevOptionsGenericFormat',
diff --git a/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch b/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch
index a469996..0194a4b 100644
--- a/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch
+++ b/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch
@@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 files changed, 11 insertions(+)
diff --git a/qemu-options.hx b/qemu-options.hx
-index 3ec9e52d31..bb41239111 100644
+index 99c04c5ab9..d0799b80b3 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
-@@ -1285,6 +1285,9 @@ legacy PC, they are not recommended for modern configurations.
+@@ -1315,6 +1315,9 @@ legacy PC, they are not recommended for modern configurations.
ERST
@@ -28,10 +28,10 @@ index 3ec9e52d31..bb41239111 100644
"-fda/-fdb file use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL)
DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL)
diff --git a/system/vl.c b/system/vl.c
-index 28a7d74f5b..56f8900451 100644
+index ab845eb634..6bd8704c82 100644
--- a/system/vl.c
+++ b/system/vl.c
-@@ -2851,6 +2851,7 @@ void qemu_init(int argc, char **argv)
+@@ -2857,6 +2857,7 @@ void qemu_init(int argc, char **argv)
MachineClass *machine_class;
bool userconfig = true;
FILE *vmstate_dump_file = NULL;
@@ -39,7 +39,7 @@ index 28a7d74f5b..56f8900451 100644
qemu_add_opts(&qemu_drive_opts);
qemu_add_drive_opts(&qemu_legacy_drive_opts);
-@@ -3469,6 +3470,13 @@ void qemu_init(int argc, char **argv)
+@@ -3475,6 +3476,13 @@ void qemu_init(int argc, char **argv)
machine_parse_property_opt(qemu_find_opts("smp-opts"),
"smp", optarg);
break;
diff --git a/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch b/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
index 4316412..8c08d70 100644
--- a/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
+++ b/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
@@ -6,18 +6,20 @@ Subject: [PATCH] PVE: [Config] Revert "target-i386: disable LINT0 after reset"
This reverts commit b8eb5512fd8a115f164edbbe897cdf8884920ccb.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[FE: rebase for 10.2.0]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/intc/apic_common.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
-index 37a7a7019d..444136c665 100644
+index ec9e978b0b..f4e7072fc4 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
-@@ -263,6 +263,15 @@ static void apic_reset_common(DeviceState *dev)
+@@ -245,6 +245,15 @@ static void apic_reset_common(DeviceState *dev)
info->vapic_base_update(s);
- apic_init_reset(dev);
+ apic_init_reset(s);
+
+ if (bsp) {
+ /*
diff --git a/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch b/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
index 989695e..2f70373 100644
--- a/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
+++ b/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
@@ -13,10 +13,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 files changed, 46 insertions(+), 20 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
-index baac7653db..fc5cf223bc 100644
+index 41ac3f222f..612942a222 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
-@@ -2993,6 +2993,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -2981,6 +2981,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
int fd;
uint64_t perm, shared;
int result = 0;
@@ -24,7 +24,7 @@ index baac7653db..fc5cf223bc 100644
/* Validate options and set default values */
assert(options->driver == BLOCKDEV_DRIVER_FILE);
-@@ -3033,19 +3034,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -3021,19 +3022,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
@@ -59,7 +59,7 @@ index baac7653db..fc5cf223bc 100644
}
/* Clear the file by truncating it to 0 */
-@@ -3099,13 +3103,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -3087,13 +3091,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
}
out_unlock:
@@ -82,7 +82,7 @@ index baac7653db..fc5cf223bc 100644
}
out_close:
-@@ -3129,6 +3135,7 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
+@@ -3117,6 +3123,7 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
PreallocMode prealloc;
char *buf = NULL;
Error *local_err = NULL;
@@ -90,7 +90,7 @@ index baac7653db..fc5cf223bc 100644
/* Skip file: protocol prefix */
strstart(filename, "file:", &filename);
-@@ -3151,6 +3158,18 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
+@@ -3139,6 +3146,18 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
return -EINVAL;
}
@@ -109,7 +109,7 @@ index baac7653db..fc5cf223bc 100644
options = (BlockdevCreateOptions) {
.driver = BLOCKDEV_DRIVER_FILE,
.u.file = {
-@@ -3162,6 +3181,8 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
+@@ -3150,6 +3169,8 @@ 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,
@@ -119,10 +119,10 @@ index baac7653db..fc5cf223bc 100644
};
return raw_co_create(&options, errp);
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index aa1dba4284..e17ef6abdf 100644
+index 19b60e3a96..029b8f2b51 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
-@@ -5081,6 +5081,10 @@
+@@ -5153,6 +5153,10 @@
# @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)
#
@@ -133,7 +133,7 @@ index aa1dba4284..e17ef6abdf 100644
# Since: 2.12
##
{ 'struct': 'BlockdevCreateOptionsFile',
-@@ -5088,7 +5092,8 @@
+@@ -5160,7 +5164,8 @@
'size': 'size',
'*preallocation': 'PreallocMode',
'*nocow': 'bool',
diff --git a/debian/patches/pve/0023-PVE-monitor-disable-oob-capability.patch b/debian/patches/pve/0023-PVE-monitor-disable-oob-capability.patch
index 4830740..2595faf 100644
--- a/debian/patches/pve/0023-PVE-monitor-disable-oob-capability.patch
+++ b/debian/patches/pve/0023-PVE-monitor-disable-oob-capability.patch
@@ -18,7 +18,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/monitor/qmp.c b/monitor/qmp.c
-index 170fef4531..448403b45b 100644
+index 16c20305d2..707c9cd419 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -535,8 +535,7 @@ void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
diff --git a/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch b/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
index d59e085..376c97d 100644
--- a/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
+++ b/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
@@ -26,10 +26,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/core/machine.c b/hw/core/machine.c
-index bd47527479..e59b12d9f0 100644
+index 27372bb01e..24ac725adf 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
-@@ -201,7 +201,8 @@ GlobalProperty hw_compat_4_0[] = {
+@@ -211,7 +211,8 @@ GlobalProperty hw_compat_4_0[] = {
{ "virtio-vga", "edid", "false" },
{ "virtio-gpu-device", "edid", "false" },
{ "virtio-device", "use-started", "false" },
diff --git a/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch b/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch
index 74421a1..8d2cc03 100644
--- a/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch
+++ b/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch
@@ -11,7 +11,7 @@ and only if 'is-current').
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: adapt to QAPI changes]
+[FE: rebase for 10.2.0]
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/core/machine-qmp-cmds.c | 5 +++++
@@ -21,10 +21,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
4 files changed, 34 insertions(+)
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
-index 934cdb886d..124000b771 100644
+index 55e4550cd4..6404fba525 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
-@@ -98,6 +98,11 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
+@@ -124,6 +124,11 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
if (strcmp(mc->name, MACHINE_GET_CLASS(current_machine)->name) == 0) {
info->has_is_current = true;
info->is_current = true;
@@ -37,10 +37,10 @@ index 934cdb886d..124000b771 100644
if (default_cpu_type) {
diff --git a/include/hw/boards.h b/include/hw/boards.h
-index f94713e6e2..7a389f6998 100644
+index a48ed4f86a..dfa1dc0bb7 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
-@@ -271,6 +271,8 @@ struct MachineClass {
+@@ -273,6 +273,8 @@ struct MachineClass {
const char *desc;
const char *deprecation_reason;
@@ -50,7 +50,7 @@ index f94713e6e2..7a389f6998 100644
void (*reset)(MachineState *state, ResetType type);
void (*wakeup)(MachineState *state);
diff --git a/qapi/machine.json b/qapi/machine.json
-index 47ac68a3b5..957ff0f4dd 100644
+index e981da9fbb..992900fe77 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -192,6 +192,8 @@
@@ -71,18 +71,18 @@ index 47ac68a3b5..957ff0f4dd 100644
'features': ['unstable'] } } }
diff --git a/system/vl.c b/system/vl.c
-index 56f8900451..4d583d60b1 100644
+index 6bd8704c82..587956b30d 100644
--- a/system/vl.c
+++ b/system/vl.c
-@@ -1673,6 +1673,7 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
+@@ -1678,6 +1678,7 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
{
ERRP_GUARD();
const char *machine_type = qdict_get_try_str(qdict, "type");
+ const char *pvever = qdict_get_try_str(qdict, "pvever");
- g_autoptr(GSList) machines = object_class_get_list(TYPE_MACHINE, false);
+ g_autoptr(GSList) machines = object_class_get_list(target_machine_typename(),
+ false);
MachineClass *machine_class = NULL;
-
-@@ -1692,7 +1693,11 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
+@@ -1698,7 +1699,11 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
if (!machine_class) {
error_append_hint(errp,
"Use -machine help to list supported machines\n");
@@ -94,7 +94,7 @@ index 56f8900451..4d583d60b1 100644
return machine_class;
}
-@@ -3411,12 +3416,31 @@ void qemu_init(int argc, char **argv)
+@@ -3417,12 +3422,31 @@ void qemu_init(int argc, char **argv)
case QEMU_OPTION_machine:
{
bool help;
diff --git a/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch b/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch
index 369f5ad..60fd4d0 100644
--- a/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch
+++ b/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch
@@ -40,10 +40,10 @@ index a21d9a5411..1373612c10 100644
system_ss.add(files('block-ram-registrar.c'))
diff --git a/meson.build b/meson.build
-index b7db736bbf..fe7b7a88fd 100644
+index d9293294d8..7089bfcb54 100644
--- a/meson.build
+++ b/meson.build
-@@ -2199,6 +2199,8 @@ endif
+@@ -2160,6 +2160,8 @@ endif
has_gettid = cc.has_function('gettid')
@@ -52,7 +52,7 @@ index b7db736bbf..fe7b7a88fd 100644
# libselinux
selinux = dependency('libselinux',
required: get_option('selinux'),
-@@ -4532,6 +4534,9 @@ if have_tools
+@@ -4510,6 +4512,9 @@ if have_tools
dependencies: [blockdev, qemuutil, selinux],
install: true)
diff --git a/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch b/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
index 740e076..fa1db0b 100644
--- a/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
+++ b/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
@@ -259,7 +259,7 @@ index 1373612c10..6278c4af0f 100644
'blklogwrites.c',
'blkverify.c',
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
-index 034c0634c8..5688ced531 100644
+index cb0143ea77..a5e85cff46 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -26,6 +26,7 @@
diff --git a/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch b/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch
index 3c0e64c..a56fc83 100644
--- a/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch
+++ b/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch
@@ -96,10 +96,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
proxmox-backup-client.c | 146 +++++
proxmox-backup-client.h | 60 ++
pve-backup.c | 1096 ++++++++++++++++++++++++++++++++
- qapi/block-core.json | 233 +++++++
+ qapi/block-core.json | 242 +++++++
qapi/common.json | 14 +
qapi/machine.json | 16 +-
- 14 files changed, 1715 insertions(+), 14 deletions(-)
+ 14 files changed, 1724 insertions(+), 14 deletions(-)
create mode 100644 proxmox-backup-client.c
create mode 100644 proxmox-backup-client.h
create mode 100644 pve-backup.c
@@ -121,10 +121,10 @@ index 6278c4af0f..d1b16e40e9 100644
system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
system_ss.add(files('block-ram-registrar.c'))
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 282d1c386e..bbb08ecabd 100644
+index 3640d1f3dc..b7668139de 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
-@@ -1015,3 +1015,42 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target,
+@@ -1016,3 +1016,42 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target,
qmp_blockdev_change_medium(device, NULL, target, arg, true, force,
!!read_only, read_only_mode, errp);
}
@@ -168,7 +168,7 @@ index 282d1c386e..bbb08ecabd 100644
+ hmp_handle_error(mon, error);
+}
diff --git a/blockdev.c b/blockdev.c
-index 782cc5dd75..2505f9040a 100644
+index d9575c8367..38e24e12bd 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -37,6 +37,7 @@
@@ -180,10 +180,10 @@ index 782cc5dd75..2505f9040a 100644
#include "monitor/monitor.h"
#include "qemu/error-report.h"
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
-index 3e15458335..7dffd5f68c 100644
+index 9b6cc87127..a2944aba8d 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
-@@ -456,6 +456,20 @@ SRST
+@@ -476,6 +476,20 @@ SRST
Show the current VM UUID.
ERST
@@ -205,7 +205,7 @@ index 3e15458335..7dffd5f68c 100644
{
.name = "usernet",
diff --git a/hmp-commands.hx b/hmp-commands.hx
-index 0d9241db9e..5f88b8dfaa 100644
+index eda6225ef1..f02681a157 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -101,6 +101,35 @@ ERST
@@ -245,10 +245,10 @@ index 0d9241db9e..5f88b8dfaa 100644
{
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
-index 2596cc2426..9dda91d65a 100644
+index f05423ceda..5a4bb5dbe6 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
-@@ -32,6 +32,7 @@ void hmp_info_savevm(Monitor *mon, const QDict *qdict);
+@@ -33,6 +33,7 @@ void hmp_info_savevm(Monitor *mon, const QDict *qdict);
void hmp_info_migrate(Monitor *mon, const QDict *qdict);
void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
@@ -256,7 +256,7 @@ index 2596cc2426..9dda91d65a 100644
void hmp_info_cpus(Monitor *mon, const QDict *qdict);
void hmp_info_vnc(Monitor *mon, const QDict *qdict);
void hmp_info_spice(Monitor *mon, const QDict *qdict);
-@@ -82,6 +83,8 @@ void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
+@@ -83,6 +84,8 @@ void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
void hmp_change_medium(Monitor *mon, const char *device, const char *target,
const char *arg, const char *read_only, bool force,
Error **errp);
@@ -266,10 +266,10 @@ index 2596cc2426..9dda91d65a 100644
void hmp_device_add(Monitor *mon, const QDict *qdict);
void hmp_device_del(Monitor *mon, const QDict *qdict);
diff --git a/meson.build b/meson.build
-index fe7b7a88fd..3bb206ce4d 100644
+index 7089bfcb54..06b0312a12 100644
--- a/meson.build
+++ b/meson.build
-@@ -2200,6 +2200,7 @@ endif
+@@ -2161,6 +2161,7 @@ endif
has_gettid = cc.has_function('gettid')
libuuid = cc.find_library('uuid', required: true)
@@ -278,7 +278,7 @@ index fe7b7a88fd..3bb206ce4d 100644
# libselinux
selinux = dependency('libselinux',
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 1e66bff724..d2fc956c18 100644
+index 7af9fed7ea..6abe0f2c8e 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -22,6 +22,7 @@
@@ -1688,10 +1688,10 @@ index 0000000000..177fb851b4
+ return ret;
+}
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index e17ef6abdf..a54390d9ad 100644
+index 029b8f2b51..75406f4215 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
-@@ -879,6 +879,239 @@
+@@ -947,6 +947,248 @@
{ 'command': 'query-block', 'returns': ['BlockInfo'],
'allow-preconfig': true }
@@ -1701,15 +1701,15 @@ index e17ef6abdf..a54390d9ad 100644
+# Detailed backup status.
+#
+# @status: string describing the current backup status.
-+# This can be 'active', 'done', 'error'. If this field is not
-+# returned, no backup process has been initiated
++# This can be 'active', 'done', 'error'. If this field is
++# not returned, no backup process has been initiated
+#
+# @errmsg: error message (only returned if status is 'error')
+#
+# @total: total amount of bytes involved in the backup process
+#
-+# @dirty: with incremental mode (PBS) this is the amount of bytes involved
-+# in the backup process which are marked dirty.
++# @dirty: with incremental mode (PBS) this is the amount of bytes
++# involved in the backup process which are marked dirty.
+#
+# @transferred: amount of bytes already backed up.
+#
@@ -1725,8 +1725,8 @@ index e17ef6abdf..a54390d9ad 100644
+#
+# @uuid: uuid for this backup job
+#
-+# @finishing: if status='active' and finishing=true, then the backup process is
-+# waiting for the target to finish.
++# @finishing: if status='active' and finishing=true, then the backup
++# process is waiting for the target to finish.
+#
+##
+{ 'struct': 'BackupStatus',
@@ -1760,13 +1760,13 @@ index e17ef6abdf..a54390d9ad 100644
+# @config-file: a configuration file to include into
+# the backup archive.
+#
-+# @firewall-file: a firewall configuration file to include into the backup
-+# archive.
++# @firewall-file: a firewall configuration file to include into the
++# backup archive.
+#
+# @speed: the maximum speed, in bytes per second
+#
-+# @devlist: list of block device names (separated by ',', ';'
-+# or ':'). By default the backup includes all writable block devices.
++# @devlist: list of block device names (separated by ',', ';' or ':').
++# By default the backup includes all writable block devices.
+#
+# @password: backup server passsword (required for format 'pbs')
+#
@@ -1774,7 +1774,8 @@ index e17ef6abdf..a54390d9ad 100644
+#
+# @key-password: password for keyfile (optional for format 'pbs')
+#
-+# @master-keyfile: PEM-formatted master public keyfile (optional for format 'pbs')
++# @master-keyfile: PEM-formatted master public keyfile (optional for
++# format 'pbs')
+#
+# @fingerprint: server cert fingerprint (optional for format 'pbs')
+#
@@ -1782,15 +1783,19 @@ index e17ef6abdf..a54390d9ad 100644
+#
+# @backup-id: backup ID (required for format 'pbs')
+#
-+# @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
++# @backup-time: backup timestamp (Unix epoch, required for format
++# 'pbs')
+#
-+# @use-dirty-bitmap: use dirty bitmap to detect incremental changes since last job (optional for format 'pbs')
++# @use-dirty-bitmap: use dirty bitmap to detect incremental changes
++# since last job (optional for format 'pbs')
+#
-+# @compress: use compression (optional for format 'pbs', defaults to true)
++# @compress: use compression (optional for format 'pbs', defaults to
++# true)
+#
-+# @encrypt: use encryption ((optional for format 'pbs', defaults to true if there is a keyfile)
++# @encrypt: use encryption ((optional for format 'pbs', defaults to
++# true if there is a keyfile)
+#
-+# @max-workers: see @BackupPerf for details. Default 16.
++# @max-workers: see @BackupPerf for details. Default 16.
+#
+# Returns: the uuid of the backup job
+#
@@ -1830,7 +1835,8 @@ index e17ef6abdf..a54390d9ad 100644
+#
+# Cancel the current executing backup process.
+#
-+# .. note:: This command succeeds even if there is no backup process running.
++# .. note:: This command succeeds even if there is no backup process
++# running.
+#
+##
+{ 'command': 'backup-cancel', 'coroutine': true }
@@ -1840,21 +1846,23 @@ index e17ef6abdf..a54390d9ad 100644
+#
+# Contains info about supported features added by Proxmox.
+#
-+# @pbs-dirty-bitmap: True if dirty-bitmap-incremental backups to PBS are
-+# supported.
++# @pbs-dirty-bitmap: True if dirty-bitmap-incremental backups to PBS
++# are supported.
+#
-+# @query-bitmap-info: True if the 'query-pbs-bitmap-info' QMP call is supported.
++# @query-bitmap-info: True if the 'query-pbs-bitmap-info' QMP call is
++# supported.
+#
-+# @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
-+# safely be set for savevm-async.
++# @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration
++# capability can safely be set for savevm-async.
+#
-+# @pbs-masterkey: True if the QMP backup call supports the 'master_keyfile'
-+# parameter.
++# @pbs-masterkey: True if the QMP backup call supports the
++# 'master_keyfile' parameter.
+#
-+# @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
++# @pbs-library-version: Running version of libproxmox-backup-qemu0
++# library.
+#
-+# @backup-max-workers: Whether the 'max-workers' @BackupPerf setting is
-+# supported or not.
++# @backup-max-workers: Whether the 'max-workers' @BackupPerf setting
++# is supported or not.
+#
+##
+{ 'struct': 'ProxmoxSupportStatus',
@@ -1889,9 +1897,9 @@ index e17ef6abdf..a54390d9ad 100644
+#
+# @used: An existing bitmap will be used to only backup changed data.
+#
-+# @invalid: A bitmap existed, but had to be cleared since it's associated
-+# base snapshot did not match the base given for the current job or
-+# the crypt mode has changed.
++# @invalid: A bitmap existed, but had to be cleared since it's
++# associated base snapshot did not match the base given for the
++# current job or the crypt mode has changed.
+#
+##
+{ 'enum': 'PBSBitmapAction',
@@ -1900,7 +1908,8 @@ index e17ef6abdf..a54390d9ad 100644
+##
+# @PBSBitmapInfo:
+#
-+# Contains information about dirty bitmaps used for each drive in a PBS backup.
++# Contains information about dirty bitmaps used for each drive in a
++# PBS backup.
+#
+# @drive: The underlying drive.
+#
@@ -1908,8 +1917,8 @@ index e17ef6abdf..a54390d9ad 100644
+#
+# @size: The total size of the drive.
+#
-+# @dirty: How much of the drive is considered dirty and will be backed up,
-+# or 'size' if everything will be.
++# @dirty: How much of the drive is considered dirty and will be backed
++# up, or 'size' if everything will be.
+#
+##
+{ 'struct': 'PBSBitmapInfo',
@@ -1919,9 +1928,9 @@ index e17ef6abdf..a54390d9ad 100644
+##
+# @query-pbs-bitmap-info:
+#
-+# Returns information about dirty bitmaps used on the most recently started
-+# backup. Returns nothing when the last backup was not using PBS or if no
-+# backup occured in this session.
++# Returns information about dirty bitmaps used on the most recently
++# started backup. Returns nothing when the last backup was not using
++# PBS or if no backup occured in this session.
+#
+# Returns: @PBSBitmapInfo
+#
@@ -1954,7 +1963,7 @@ index af7e3d618a..dc9ab77310 100644
+##
+{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} }
diff --git a/qapi/machine.json b/qapi/machine.json
-index 957ff0f4dd..5628cf4be4 100644
+index 992900fe77..71c19284c7 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -4,6 +4,8 @@
diff --git a/debian/patches/pve/0031-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch b/debian/patches/pve/0031-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
index 2f63bd1..33deac2 100644
--- a/debian/patches/pve/0031-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
+++ b/debian/patches/pve/0031-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
@@ -14,10 +14,10 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
create mode 100644 pbs-restore.c
diff --git a/meson.build b/meson.build
-index 3bb206ce4d..9eba919450 100644
+index 06b0312a12..73f6e2e93b 100644
--- a/meson.build
+++ b/meson.build
-@@ -4538,6 +4538,10 @@ if have_tools
+@@ -4516,6 +4516,10 @@ if have_tools
vma = executable('vma', files('vma.c', 'vma-reader.c') + genh,
dependencies: [authz, block, crypto, io, qemuutil, qom], install: true)
diff --git a/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch b/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
index 41626ce..00fef7e 100644
--- a/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
+++ b/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
@@ -348,10 +348,10 @@ index 0000000000..3e41421716
+
+block_init(bdrv_pbs_init);
diff --git a/meson.build b/meson.build
-index 9eba919450..4861b69412 100644
+index 73f6e2e93b..b717cad2f9 100644
--- a/meson.build
+++ b/meson.build
-@@ -5011,7 +5011,7 @@ summary_info += {'Query Processing Library support': qpl}
+@@ -4986,7 +4986,7 @@ summary_info += {'Query Processing Library support': qpl}
summary_info += {'UADK Library support': uadk}
summary_info += {'qatzip support': qatzip}
summary_info += {'NUMA host support': numa}
@@ -361,10 +361,10 @@ index 9eba919450..4861b69412 100644
summary_info += {'libdaxctl support': libdaxctl}
summary_info += {'libcbor support': libcbor}
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index a54390d9ad..e6b8ba49b2 100644
+index 75406f4215..f998aafc49 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
-@@ -3534,6 +3534,7 @@
+@@ -3614,6 +3614,7 @@
'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum',
'raw', 'rbd',
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
@@ -372,7 +372,7 @@ index a54390d9ad..e6b8ba49b2 100644
'ssh', 'throttle', 'vdi', 'vhdx',
{ 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' },
{ 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' },
-@@ -3620,6 +3621,33 @@
+@@ -3700,6 +3701,33 @@
{ 'struct': 'BlockdevOptionsNull',
'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } }
@@ -406,7 +406,7 @@ index a54390d9ad..e6b8ba49b2 100644
##
# @BlockdevOptionsNVMe:
#
-@@ -5067,6 +5095,7 @@
+@@ -5147,6 +5175,7 @@
'nfs': 'BlockdevOptionsNfs',
'null-aio': 'BlockdevOptionsNull',
'null-co': 'BlockdevOptionsNull',
diff --git a/debian/patches/pve/0033-PVE-redirect-stderr-to-journal-when-daemonized.patch b/debian/patches/pve/0033-PVE-redirect-stderr-to-journal-when-daemonized.patch
index b007793..f53a108 100644
--- a/debian/patches/pve/0033-PVE-redirect-stderr-to-journal-when-daemonized.patch
+++ b/debian/patches/pve/0033-PVE-redirect-stderr-to-journal-when-daemonized.patch
@@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/meson.build b/meson.build
-index 4861b69412..7e1935d43f 100644
+index b717cad2f9..0b28d2ec39 100644
--- a/meson.build
+++ b/meson.build
-@@ -2200,6 +2200,7 @@ endif
+@@ -2161,6 +2161,7 @@ endif
has_gettid = cc.has_function('gettid')
libuuid = cc.find_library('uuid', required: true)
@@ -25,7 +25,7 @@ index 4861b69412..7e1935d43f 100644
libproxmox_backup_qemu = cc.find_library('proxmox_backup_qemu', required: true)
# libselinux
-@@ -3875,7 +3876,7 @@ if have_block
+@@ -3836,7 +3837,7 @@ if have_block
elif host_os == 'emscripten'
blockdev_ss.add(files('os-wasm.c'))
else
diff --git a/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch b/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
index c581f29..2c3c25f 100644
--- a/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
+++ b/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
@@ -26,10 +26,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
create mode 100644 migration/pbs-state.c
diff --git a/include/migration/misc.h b/include/migration/misc.h
-index a261f99d89..e8c6a87305 100644
+index e26d418a6e..551898d7bf 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
-@@ -140,4 +140,7 @@ bool multifd_device_state_save_thread_should_exit(void);
+@@ -152,4 +152,7 @@ bool multifd_device_state_save_thread_should_exit(void);
void multifd_abort_device_state_save_threads(void);
bool multifd_join_device_state_save_threads(void);
@@ -38,7 +38,7 @@ index a261f99d89..e8c6a87305 100644
+
#endif
diff --git a/migration/meson.build b/migration/meson.build
-index 409b748980..ca94e7e17b 100644
+index 140264b477..23aa5b3caa 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -8,6 +8,7 @@ migration_files = files(
@@ -49,19 +49,19 @@ index 409b748980..ca94e7e17b 100644
system_ss.add(files(
'block-dirty-bitmap.c',
-@@ -31,6 +32,7 @@ system_ss.add(files(
+@@ -32,6 +33,7 @@ system_ss.add(files(
'multifd-zlib.c',
'multifd-zero-page.c',
'options.c',
+ 'pbs-state.c',
'postcopy-ram.c',
+ 'ram.c',
'savevm.c',
- 'savevm-async.c',
diff --git a/migration/migration.c b/migration/migration.c
-index 32b8ce5613..60464d43c3 100644
+index b316ee01ab..1eae33bc73 100644
--- a/migration/migration.c
+++ b/migration/migration.c
-@@ -340,6 +340,7 @@ void migration_object_init(void)
+@@ -337,6 +337,7 @@ void migration_object_init(void)
/* Initialize cpu throttle timers */
cpu_throttle_init();
@@ -192,22 +192,22 @@ index 177fb851b4..7575abab7c 100644
ret->pbs_masterkey = true;
ret->backup_max_workers = true;
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index e6b8ba49b2..be6bf25219 100644
+index f998aafc49..5b3bb3c19e 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
-@@ -1032,6 +1032,11 @@
- # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
- # safely be set for savevm-async.
+@@ -1107,6 +1107,11 @@
+ # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration
+ # capability can safely be set for savevm-async.
#
-+# @pbs-dirty-bitmap-migration: True if safe migration of dirty-bitmaps including
-+# PBS state is supported. Enabling 'dirty-bitmaps'
-+# migration cap if this is false/unset may lead
-+# to crashes on migration!
++# @pbs-dirty-bitmap-migration: True if safe migration of dirty-bitmaps
++# including PBS state is supported. Enabling 'dirty-bitmaps'
++# migration cap if this is false/unset may lead to crashes on
++# migration!
+#
- # @pbs-masterkey: True if the QMP backup call supports the 'master_keyfile'
- # parameter.
+ # @pbs-masterkey: True if the QMP backup call supports the
+ # 'master_keyfile' parameter.
#
-@@ -1045,6 +1050,7 @@
+@@ -1121,6 +1126,7 @@
'data': { 'pbs-dirty-bitmap': 'bool',
'query-bitmap-info': 'bool',
'pbs-dirty-bitmap-savevm': 'bool',
diff --git a/debian/patches/pve/0036-PVE-fall-back-to-open-iscsi-initiatorname.patch b/debian/patches/pve/0036-PVE-fall-back-to-open-iscsi-initiatorname.patch
index a187b0d..9efe1a3 100644
--- a/debian/patches/pve/0036-PVE-fall-back-to-open-iscsi-initiatorname.patch
+++ b/debian/patches/pve/0036-PVE-fall-back-to-open-iscsi-initiatorname.patch
@@ -21,10 +21,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 30 insertions(+)
diff --git a/block/iscsi.c b/block/iscsi.c
-index 15b96ee880..5aa4b602b1 100644
+index 7d6bf185ea..e8b7671f72 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
-@@ -1392,12 +1392,42 @@ static char *get_initiator_name(QemuOpts *opts)
+@@ -1380,12 +1380,42 @@ static char *get_initiator_name(QemuOpts *opts)
const char *name;
char *iscsi_name;
UuidInfo *uuid_info;
diff --git a/debian/patches/pve/0038-block-add-alloc-track-driver.patch b/debian/patches/pve/0038-block-add-alloc-track-driver.patch
index 3ff3f6c..de886e2 100644
--- a/debian/patches/pve/0038-block-add-alloc-track-driver.patch
+++ b/debian/patches/pve/0038-block-add-alloc-track-driver.patch
@@ -449,10 +449,10 @@ index d023753091..a777c8079c 100644
out:
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index be6bf25219..cbefc6d0d3 100644
+index 5b3bb3c19e..1d98f0a406 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
-@@ -3526,7 +3526,8 @@
+@@ -3606,7 +3606,8 @@
# Since: 2.9
##
{ 'enum': 'BlockdevDriver',
@@ -462,7 +462,7 @@ index be6bf25219..cbefc6d0d3 100644
'cloop', 'compress', 'copy-before-write', 'copy-on-read', 'dmg',
'file', 'snapshot-access', 'ftp', 'ftps',
{'name': 'gluster', 'features': [ 'deprecated' ] },
-@@ -3627,6 +3628,21 @@
+@@ -3707,6 +3708,21 @@
{ 'struct': 'BlockdevOptionsNull',
'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } }
@@ -484,7 +484,7 @@ index be6bf25219..cbefc6d0d3 100644
##
# @BlockdevOptionsPbs:
#
-@@ -5073,6 +5089,7 @@
+@@ -5153,6 +5169,7 @@
'*detect-zeroes': 'BlockdevDetectZeroesOptions' },
'discriminator': 'driver',
'data': {
diff --git a/debian/patches/pve/0039-PVE-backup-add-fleecing-option.patch b/debian/patches/pve/0039-PVE-backup-add-fleecing-option.patch
index 3edb41d..50021c5 100644
--- a/debian/patches/pve/0039-PVE-backup-add-fleecing-option.patch
+++ b/debian/patches/pve/0039-PVE-backup-add-fleecing-option.patch
@@ -147,10 +147,10 @@ index eb93364e85..6a6dbf90f5 100644
#endif /* COPY_BEFORE_WRITE_H */
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index bbb08ecabd..d8771ce8fc 100644
+index b7668139de..9e84ba164d 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
-@@ -1050,6 +1050,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
+@@ -1051,6 +1051,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
NULL, NULL,
devlist, qdict_haskey(qdict, "speed"), speed,
false, 0, // BackupPerf max-workers
@@ -429,21 +429,21 @@ index 7575abab7c..8b83465ebd 100644
return ret;
}
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index cbefc6d0d3..7cafc96616 100644
+index 1d98f0a406..db0a5a1266 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
-@@ -976,6 +976,10 @@
+@@ -1049,6 +1049,10 @@
#
- # @max-workers: see @BackupPerf for details. Default 16.
+ # @max-workers: see @BackupPerf for details. Default 16.
#
-+# @fleecing: perform a backup with fleecing. For each device in @devlist, a
-+# corresponing '-fleecing' device with the same size already needs to
-+# be present.
++# @fleecing: perform a backup with fleecing. For each device in
++# @devlist, a corresponing '-fleecing' device with the same size
++# already needs to be present.
+#
# Returns: the uuid of the backup job
#
##
-@@ -996,7 +1000,8 @@
+@@ -1069,7 +1073,8 @@
'*firewall-file': 'str',
'*devlist': 'str',
'*speed': 'int',
@@ -453,16 +453,16 @@ index cbefc6d0d3..7cafc96616 100644
'returns': 'UuidInfo', 'coroutine': true }
##
-@@ -1042,6 +1047,8 @@
- #
- # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
+@@ -1118,6 +1123,8 @@
+ # @pbs-library-version: Running version of libproxmox-backup-qemu0
+ # library.
#
+# @backup-fleecing: Whether backup fleecing is supported or not.
+#
- # @backup-max-workers: Whether the 'max-workers' @BackupPerf setting is
- # supported or not.
+ # @backup-max-workers: Whether the 'max-workers' @BackupPerf setting
+ # is supported or not.
#
-@@ -1053,6 +1060,7 @@
+@@ -1129,6 +1136,7 @@
'pbs-dirty-bitmap-migration': 'bool',
'pbs-masterkey': 'bool',
'pbs-library-version': 'str',
diff --git a/debian/patches/pve/0040-adapt-machine-version-deprecation-for-Proxmox-VE.patch b/debian/patches/pve/0040-adapt-machine-version-deprecation-for-Proxmox-VE.patch
index 5701668..412fd18 100644
--- a/debian/patches/pve/0040-adapt-machine-version-deprecation-for-Proxmox-VE.patch
+++ b/debian/patches/pve/0040-adapt-machine-version-deprecation-for-Proxmox-VE.patch
@@ -22,10 +22,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
1 file changed, 58 insertions(+), 41 deletions(-)
diff --git a/include/hw/boards.h b/include/hw/boards.h
-index 7a389f6998..0595a569d2 100644
+index dfa1dc0bb7..ca5c7ed0b9 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
-@@ -636,40 +636,57 @@ struct MachineState {
+@@ -672,40 +672,57 @@ struct MachineState {
/*
@@ -106,7 +106,7 @@ index 7a389f6998..0595a569d2 100644
/*
* - The first check applies to formal releases
-@@ -684,29 +701,29 @@ struct MachineState {
+@@ -720,29 +737,29 @@ struct MachineState {
* and dev snapshots / release candidates are numbered with micro >= 50
* If this ever changes the logic below will need modifying....
*/
@@ -152,7 +152,7 @@ index 7a389f6998..0595a569d2 100644
/*
* Evaluates true when a machine type with (major, minor)
-@@ -715,7 +732,7 @@ struct MachineState {
+@@ -751,7 +768,7 @@ struct MachineState {
* lifecycle rules
*/
#define MACHINE_VER_IS_DEPRECATED(...) \
@@ -161,7 +161,7 @@ index 7a389f6998..0595a569d2 100644
/*
* Evaluates true when a machine type with (major, minor)
-@@ -724,7 +741,7 @@ struct MachineState {
+@@ -760,7 +777,7 @@ struct MachineState {
* lifecycle rules
*/
#define MACHINE_VER_SHOULD_DELETE(...) \
diff --git a/debian/patches/pve/0045-PVE-backup-implement-backup-access-setup-and-teardow.patch b/debian/patches/pve/0045-PVE-backup-implement-backup-access-setup-and-teardow.patch
index b8f3632..8bdbf11 100644
--- a/debian/patches/pve/0045-PVE-backup-implement-backup-access-setup-and-teardow.patch
+++ b/debian/patches/pve/0045-PVE-backup-implement-backup-access-setup-and-teardow.patch
@@ -84,9 +84,9 @@ Reviewed-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
---
pve-backup.c | 519 +++++++++++++++++++++++++++++++++++++++----
pve-backup.h | 16 ++
- qapi/block-core.json | 99 ++++++++-
+ qapi/block-core.json | 105 ++++++++-
system/runstate.c | 6 +
- 4 files changed, 596 insertions(+), 44 deletions(-)
+ 4 files changed, 602 insertions(+), 44 deletions(-)
create mode 100644 pve-backup.h
diff --git a/pve-backup.c b/pve-backup.c
@@ -740,20 +740,20 @@ index 0000000000..9ebeef7c8f
+
+#endif /* PVE_BACKUP_H */
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 7cafc96616..adb94bebb4 100644
+index db0a5a1266..94296c0bc9 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
-@@ -1047,6 +1047,9 @@
+@@ -1123,6 +1123,9 @@
+ # @pbs-library-version: Running version of libproxmox-backup-qemu0
+ # library.
#
- # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
- #
-+# @backup-access-api: Whether backup access API for external providers is
-+# supported or not.
++# @backup-access-api: Whether backup access API for external providers
++# is supported or not.
+#
# @backup-fleecing: Whether backup fleecing is supported or not.
#
- # @backup-max-workers: Whether the 'max-workers' @BackupPerf setting is
-@@ -1060,6 +1063,7 @@
+ # @backup-max-workers: Whether the 'max-workers' @BackupPerf setting
+@@ -1136,6 +1139,7 @@
'pbs-dirty-bitmap-migration': 'bool',
'pbs-masterkey': 'bool',
'pbs-library-version': 'str',
@@ -761,15 +761,15 @@ index 7cafc96616..adb94bebb4 100644
'backup-fleecing': 'bool',
'backup-max-workers': 'bool' } }
-@@ -1091,9 +1095,16 @@
- # base snapshot did not match the base given for the current job or
- # the crypt mode has changed.
+@@ -1167,9 +1171,16 @@
+ # associated base snapshot did not match the base given for the
+ # current job or the crypt mode has changed.
#
-+# @missing-recreated: A bitmap for incremental backup was expected to be
-+# present, but was missing and thus got recreated. For example, this can
-+# happen if the drive was re-attached or if the bitmap was deleted for some
-+# other reason. PBS does not currently keep track of this; the backup-access
-+# mechanism does.
++# @missing-recreated: A bitmap for incremental backup was expected to
++# be present, but was missing and thus got recreated. For
++# example, this can happen if the drive was re-attached or if the
++# bitmap was deleted for some other reason. PBS does not
++# currently keep track of this; the backup-access mechanism does.
+#
##
{ 'enum': 'PBSBitmapAction',
@@ -779,15 +779,15 @@ index 7cafc96616..adb94bebb4 100644
##
# @PBSBitmapInfo:
-@@ -1126,6 +1137,92 @@
+@@ -1203,6 +1214,98 @@
##
{ 'command': 'query-pbs-bitmap-info', 'returns': ['PBSBitmapInfo'] }
+##
+# @BackupAccessInfo:
+#
-+# Info associated to a snapshot access for backup. For more information about
-+# the bitmap see @BackupAccessBitmapMode.
++# Info associated to a snapshot access for backup. For more
++# information about the bitmap see @BackupAccessBitmapMode.
+#
+# @node-name: the block node name of the snapshot-access node.
+#
@@ -795,9 +795,11 @@ index 7cafc96616..adb94bebb4 100644
+#
+# @size: the size of the block device in bytes.
+#
-+# @bitmap-node-name: the block node name the dirty bitmap is associated to.
++# @bitmap-node-name: the block node name the dirty bitmap is
++# associated to.
+#
-+# @bitmap-name: the name of the dirty bitmap associated to the backup access.
++# @bitmap-name: the name of the dirty bitmap associated to the backup
++# access.
+#
+# @bitmap-action: the action taken on the dirty bitmap.
+#
@@ -815,7 +817,7 @@ index 7cafc96616..adb94bebb4 100644
+# @device: the block device name.
+#
+# @bitmap-mode: used to control whether the bitmap should be reused or
-+# recreated or not used. Default is not using a bitmap.
++# recreated or not used. Default is not using a bitmap.
+#
+##
+{ 'struct': 'BackupAccessSourceDevice',
@@ -826,11 +828,12 @@ index 7cafc96616..adb94bebb4 100644
+#
+# How to setup a bitmap for a device for @backup-access-setup.
+#
-+# @none: do not use a bitmap. Removes an existing bitmap if present.
++# @none: do not use a bitmap. Removes an existing bitmap if present.
+#
+# @new: create and use a new bitmap.
+#
-+# @use: try to re-use an existing bitmap. Create a new one if it doesn't exist.
++# @use: try to re-use an existing bitmap. Create a new one if it
++# doesn't exist.
+##
+{ 'enum': 'BackupAccessSetupBitmapMode',
+ 'data': ['none', 'new', 'use' ] }
@@ -838,15 +841,17 @@ index 7cafc96616..adb94bebb4 100644
+##
+# @backup-access-setup:
+#
-+# Set up snapshot access to VM drives for an external backup provider. No other
-+# backup or backup access can be done before tearing down the backup access.
++# Set up snapshot access to VM drives for an external backup provider.
++# No other backup or backup access can be done before tearing down the
++# backup access.
+#
+# @target-id: the unique ID of the backup target.
+#
-+# @devices: list of devices for which to create the backup access. Also
-+# controls whether to use/create a bitmap for the device. Check the
-+# @bitmap-action in the result to see what action was actually taken for the
-+# bitmap. Each target controls its own bitmaps.
++# @devices: list of devices for which to create the backup access.
++# Also controls whether to use/create a bitmap for the device.
++# Check the @bitmap-action in the result to see what action was
++# actually taken for the bitmap. Each target controls its own
++# bitmaps.
+#
+# Returns: a list of @BackupAccessInfo, one for each device.
+#
@@ -862,7 +867,8 @@ index 7cafc96616..adb94bebb4 100644
+#
+# @target-id: the ID of the backup target.
+#
-+# @success: whether the backup done by the external provider was successful.
++# @success: whether the backup done by the external provider was
++# successful.
+#
+##
+{ 'command': 'backup-access-teardown',
@@ -873,7 +879,7 @@ index 7cafc96616..adb94bebb4 100644
# @BlockDeviceTimedStats:
#
diff --git a/system/runstate.c b/system/runstate.c
-index 6178b0091a..5f370ddb60 100644
+index e3ec16ab74..d471fbece9 100644
--- a/system/runstate.c
+++ b/system/runstate.c
@@ -60,6 +60,7 @@
@@ -884,7 +890,7 @@ index 6178b0091a..5f370ddb60 100644
static NotifierList exit_notifiers =
NOTIFIER_LIST_INITIALIZER(exit_notifiers);
-@@ -991,6 +992,11 @@ void qemu_cleanup(int status)
+@@ -989,6 +990,11 @@ void qemu_cleanup(int status)
* requests happening from here on anyway.
*/
bdrv_drain_all_begin();
diff --git a/debian/patches/pve/0047-savevm-async-reuse-migration-blocker-check-for-snaps.patch b/debian/patches/pve/0047-savevm-async-reuse-migration-blocker-check-for-snaps.patch
index a269f01..18db6fa 100644
--- a/debian/patches/pve/0047-savevm-async-reuse-migration-blocker-check-for-snaps.patch
+++ b/debian/patches/pve/0047-savevm-async-reuse-migration-blocker-check-for-snaps.patch
@@ -61,7 +61,7 @@ Message-ID: <20250618102531.57444-1-f.ebner@proxmox.com>
5 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/block/vmdk.c b/block/vmdk.c
-index 7b98debc2b..2af32f3d5d 100644
+index 89e89cd10e..06df10a799 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1404,9 +1404,7 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
@@ -76,12 +76,12 @@ index 7b98debc2b..2af32f3d5d 100644
if (ret < 0) {
goto fail;
diff --git a/include/migration/blocker.h b/include/migration/blocker.h
-index a687ac0efe..f36bfb2df1 100644
+index 80b75ad5cb..f8417347a1 100644
--- a/include/migration/blocker.h
+++ b/include/migration/blocker.h
-@@ -18,6 +18,8 @@
+@@ -16,6 +16,8 @@
- #define MIG_MODE_ALL MIG_MODE__MAX
+ #include "qapi/qapi-types-migration.h"
+#define MIGRATION_BLOCKER_VMDK "The vmdk format used by a disk does not support live migration"
+
@@ -89,10 +89,10 @@ index a687ac0efe..f36bfb2df1 100644
* @migrate_add_blocker - prevent all modes of migration from proceeding
*
diff --git a/migration/migration.c b/migration/migration.c
-index 60464d43c3..998a7f87b8 100644
+index 1eae33bc73..979ebac75e 100644
--- a/migration/migration.c
+++ b/migration/migration.c
-@@ -2055,6 +2055,30 @@ bool migration_is_blocked(Error **errp)
+@@ -2063,6 +2063,30 @@ bool migration_is_blocked(Error **errp)
return false;
}
@@ -124,10 +124,10 @@ index 60464d43c3..998a7f87b8 100644
static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
{
diff --git a/migration/migration.h b/migration/migration.h
-index 01329bf824..a805e98a30 100644
+index 213b33fe6e..c95eca727e 100644
--- a/migration/migration.h
+++ b/migration/migration.h
-@@ -531,6 +531,7 @@ int migration_call_notifiers(MigrationState *s, MigrationEventType type,
+@@ -535,6 +535,7 @@ int migration_call_notifiers(MigrationState *s, MigrationEventType type,
int migrate_init(MigrationState *s, Error **errp);
bool migration_is_blocked(Error **errp);
@@ -136,7 +136,7 @@ index 01329bf824..a805e98a30 100644
bool migration_in_postcopy(void);
bool migration_postcopy_is_alive(MigrationStatus state);
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
-index 730b815494..6cb91dca27 100644
+index 9942557455..8f498151bd 100644
--- a/migration/savevm-async.c
+++ b/migration/savevm-async.c
@@ -375,7 +375,7 @@ void qmp_savevm_start(const char *statefile, Error **errp)
diff --git a/debian/patches/series b/debian/patches/series
index 88cfb9b..7c8e26c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,16 +1,7 @@
extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
extra/0002-ide-avoid-potential-deadlock-when-draining-during-tr.patch
-extra/0003-tcg-arm-Fix-tgen_deposit.patch
-extra/0004-vfio-igd-Enable-quirks-when-IGD-is-not-the-primary-d.patch
-extra/0005-hw-scsi-avoid-deadlock-upon-TMF-request-cancelling-w.patch
-extra/0006-vfio-rename-field-to-num_initial_regions.patch
-extra/0007-vfio-only-check-region-info-cache-for-initial-region.patch
-extra/0008-ui-vdagent-fix-windows-agent-regression.patch
-extra/0009-file-posix-populate-pwrite_zeroes_alignment.patch
-extra/0010-block-use-pwrite_zeroes_alignment-when-writing-first.patch
-extra/0011-block-io_uring-avoid-potentially-getting-stuck-after.patch
-extra/0012-block-mirror-check-range-when-setting-zero-bitmap-fo.patch
-extra/0013-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch
+extra/0003-block-mirror-check-range-when-setting-zero-bitmap-fo.patch
+extra/0004-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch
bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch
bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch
diff --git a/qemu b/qemu
index ccaea6b..2d3df8a 160000
--- a/qemu
+++ b/qemu
@@ -1 +1 @@
-Subproject commit ccaea6b2656ec6eab966585f7b16438208f98de7
+Subproject commit 2d3df8abca265c9bcc9e438d691d561592060998
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH qemu 2/2] stable fixes for QEMU 10.2.1
2026-03-12 11:44 [PATCH-SERIES qemu 0/2] QEMU 10.2.1 Fiona Ebner
2026-03-12 11:44 ` [PATCH qemu 1/2] update submodule and patches to " Fiona Ebner
@ 2026-03-12 11:44 ` Fiona Ebner
1 sibling, 0 replies; 3+ messages in thread
From: Fiona Ebner @ 2026-03-12 11:44 UTC (permalink / raw)
To: pve-devel
Fixes for a very bad performance regression for io_uring that could
happen in combination with 'ide-hd'.
Fix for a long-standing race in mirror startup when block allocation
status change could be missed.
Fix for an out-of-bounds read with maliciously crafted VMDK images.
Fixes for newly-in-10.2.1 regressions in CPU migration,
VirtIO-GPU-Virgl and ARM emulation.
Fixes for fuse, throttle groups and block error handling.
Note that Proxmox VE does not expose virtio-snd, but the issues look
pretty bad, so still include them for people who manually use that
via custom args.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
...d-support-for-sync-bitmap-mode-never.patch | 42 +--
...-support-for-conditional-and-always-.patch | 10 +-
...-to-bdrv_dirty_bitmap_merge_internal.patch | 6 +-
.../0006-mirror-move-some-checks-to-qmp.patch | 4 +-
...ck-range-when-setting-zero-bitmap-fo.patch | 7 +-
...mdk-fix-OOB-read-in-vmdk_read_extent.patch | 38 +++
...roups-fix-deadlock-with-iolimits-and.patch | 133 +++++++++
...-BLOCK_IO_ERROR-with-action-stop-for.patch | 88 ++++++
...d-dirty-bitmap-writes-during-startup.patch | 152 +++++++++++
...-Add-virtio-gpu-virgl-hostmem-region.patch | 174 ++++++++++++
...e-BHs-are-invoked-only-from-main-loo.patch | 123 +++++++++
...c-Fix-out-of-bounds-read-in-I2C-MMIO.patch | 136 +++++++++
...nt-for-SME-in-aarch64_sve_narrow_vq-.patch | 62 +++++
...eature-check-in-DO_SVE2_RRX-DO_SVE2_.patch | 47 ++++
...llow-SVE-RAX1-in-SME2p1-streaming-mo.patch | 44 +++
...t-arm-Don-t-let-sme-on-downgrade-SME.patch | 98 +++++++
...t-the-correct-TI-bits-for-WFIT-traps.patch | 35 +++
...otify-main-loop-when-SQEs-are-queued.patch | 119 ++++++++
...heck-CQ-ring-directly-in-gsource_che.patch | 49 ++++
...-add-compat-for-migrating-error-code.patch | 75 +++++
| 93 +++++++
...andle-5.14.6.2-for-PCM_INFO-properly.patch | 89 ++++++
...ix-max_size-bounds-check-in-input-cb.patch | 44 +++
...tio-snd-tighten-read-amount-in-in_cb.patch | 51 ++++
...l-Fix-incorrect-trace-event-in-read-.patch | 41 +++
...ate-x86_decode-Actually-use-stream-i.patch | 52 ++++
...ing-of-tasks-from-marking-them-as-co.patch | 258 ++++++++++++++++++
...or-TLS-I-O-source-data-on-cancellati.patch | 176 ++++++++++++
...or-websock-I-O-source-data-on-cancel.patch | 143 ++++++++++
..._printable_name-consistently-return-.patch | 142 ++++++++++
...-write-buffer-content-before-polling.patch | 114 ++++++++
...he-CPU-model-to-kvm64-32-instead-of-.patch | 4 +-
...add-the-zeroinit-block-driver-filter.patch | 2 +-
...le-posix-make-locking-optiono-on-cre.patch | 2 +-
...ckup-Proxmox-backup-patches-for-QEMU.patch | 2 +-
...k-driver-to-map-backup-archives-into.patch | 2 +-
...igrate-dirty-bitmap-state-via-savevm.patch | 2 +-
.../0038-block-add-alloc-track-driver.patch | 2 +-
.../0039-PVE-backup-add-fleecing-option.patch | 2 +-
...ment-backup-access-setup-and-teardow.patch | 2 +-
...se-migration-blocker-check-for-snaps.patch | 2 +-
debian/patches/series | 26 ++
42 files changed, 2650 insertions(+), 43 deletions(-)
create mode 100644 debian/patches/extra/0005-block-vmdk-fix-OOB-read-in-vmdk_read_extent.patch
create mode 100644 debian/patches/extra/0006-block-throttle-groups-fix-deadlock-with-iolimits-and.patch
create mode 100644 debian/patches/extra/0007-block-Never-drop-BLOCK_IO_ERROR-with-action-stop-for.patch
create mode 100644 debian/patches/extra/0008-mirror-Fix-missed-dirty-bitmap-writes-during-startup.patch
create mode 100644 debian/patches/extra/0009-virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch
create mode 100644 debian/patches/extra/0010-virtio-gpu-Ensure-BHs-are-invoked-only-from-main-loo.patch
create mode 100644 debian/patches/extra/0011-hw-i2c-aspeed_i2c-Fix-out-of-bounds-read-in-I2C-MMIO.patch
create mode 100644 debian/patches/extra/0012-target-arm-Account-for-SME-in-aarch64_sve_narrow_vq-.patch
create mode 100644 debian/patches/extra/0013-target-arm-Fix-feature-check-in-DO_SVE2_RRX-DO_SVE2_.patch
create mode 100644 debian/patches/extra/0014-target-arm-tcg-Allow-SVE-RAX1-in-SME2p1-streaming-mo.patch
create mode 100644 debian/patches/extra/0015-target-arm-Don-t-let-sme-on-downgrade-SME.patch
create mode 100644 debian/patches/extra/0016-target-arm-set-the-correct-TI-bits-for-WFIT-traps.patch
create mode 100644 debian/patches/extra/0017-aio-posix-notify-main-loop-when-SQEs-are-queued.patch
create mode 100644 debian/patches/extra/0018-fdmon-io_uring-check-CQ-ring-directly-in-gsource_che.patch
create mode 100644 debian/patches/extra/0019-target-i386-add-compat-for-migrating-error-code.patch
create mode 100644 debian/patches/extra/0020-virtio-snd-remove-TODO-comments.patch
create mode 100644 debian/patches/extra/0021-virtio-snd-handle-5.14.6.2-for-PCM_INFO-properly.patch
create mode 100644 debian/patches/extra/0022-virtio-snd-fix-max_size-bounds-check-in-input-cb.patch
create mode 100644 debian/patches/extra/0023-virtio-snd-tighten-read-amount-in-in_cb.patch
create mode 100644 debian/patches/extra/0024-hw-misc-virt_ctrl-Fix-incorrect-trace-event-in-read-.patch
create mode 100644 debian/patches/extra/0025-target-i386-emulate-x86_decode-Actually-use-stream-i.patch
create mode 100644 debian/patches/extra/0026-io-separate-freeing-of-tasks-from-marking-them-as-co.patch
create mode 100644 debian/patches/extra/0027-io-fix-cleanup-for-TLS-I-O-source-data-on-cancellati.patch
create mode 100644 debian/patches/extra/0028-io-fix-cleanup-for-websock-I-O-source-data-on-cancel.patch
create mode 100644 debian/patches/extra/0029-hw-Make-qdev_get_printable_name-consistently-return-.patch
create mode 100644 debian/patches/extra/0030-fuse-Copy-write-buffer-content-before-polling.patch
diff --git a/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch b/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
index b3906bd..81ca0fa 100644
--- a/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
+++ b/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
@@ -27,7 +27,7 @@ Signed-off-by: Ma Haocong <mahaocong@didichuxing.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: rebased for 10.1.0]
+[FE: rebased for 10.2.1]
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
block/mirror.c | 87 +++++++++++++++++++++-----
@@ -38,7 +38,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
5 files changed, 135 insertions(+), 21 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
-index bc982cb99a..99805e7a9d 100644
+index fa1d975eb9..d09479789f 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -74,6 +74,8 @@ typedef struct MirrorBlockJob {
@@ -50,7 +50,7 @@ index bc982cb99a..99805e7a9d 100644
BdrvDirtyBitmap *dirty_bitmap;
BdrvDirtyBitmapIter *dbi;
uint8_t *buf;
-@@ -871,6 +873,16 @@ static void mirror_abort(Job *job)
+@@ -872,6 +874,16 @@ static void mirror_abort(Job *job)
assert(ret == 0);
}
@@ -67,7 +67,7 @@ index bc982cb99a..99805e7a9d 100644
static void coroutine_fn mirror_throttle(MirrorBlockJob *s)
{
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-@@ -1110,7 +1122,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
+@@ -1111,7 +1123,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
mirror_free_init(s);
s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
@@ -77,7 +77,7 @@ index bc982cb99a..99805e7a9d 100644
ret = mirror_dirty_init(s);
if (ret < 0 || job_is_cancelled(&s->common.job)) {
goto immediate_exit;
-@@ -1400,6 +1413,7 @@ static const BlockJobDriver mirror_job_driver = {
+@@ -1401,6 +1414,7 @@ static const BlockJobDriver mirror_job_driver = {
.run = mirror_run,
.prepare = mirror_prepare,
.abort = mirror_abort,
@@ -85,7 +85,7 @@ index bc982cb99a..99805e7a9d 100644
.pause = mirror_pause,
.complete = mirror_complete,
.cancel = mirror_cancel,
-@@ -1418,6 +1432,7 @@ static const BlockJobDriver commit_active_job_driver = {
+@@ -1419,6 +1433,7 @@ static const BlockJobDriver commit_active_job_driver = {
.run = mirror_run,
.prepare = mirror_prepare,
.abort = mirror_abort,
@@ -93,7 +93,7 @@ index bc982cb99a..99805e7a9d 100644
.pause = mirror_pause,
.complete = mirror_complete,
.cancel = commit_active_cancel,
-@@ -1838,6 +1853,8 @@ static BlockJob *mirror_start_job(
+@@ -1841,6 +1856,8 @@ static BlockJob *mirror_start_job(
BlockCompletionFunc *cb,
void *opaque,
const BlockJobDriver *driver,
@@ -102,7 +102,7 @@ index bc982cb99a..99805e7a9d 100644
BlockDriverState *base,
bool auto_complete, const char *filter_node_name,
bool is_mirror, MirrorCopyMode copy_mode,
-@@ -1853,10 +1870,39 @@ static BlockJob *mirror_start_job(
+@@ -1856,10 +1873,39 @@ static BlockJob *mirror_start_job(
GLOBAL_STATE_CODE();
@@ -144,7 +144,7 @@ index bc982cb99a..99805e7a9d 100644
assert(is_power_of_2(granularity));
if (buf_size < 0) {
-@@ -1998,6 +2044,8 @@ static BlockJob *mirror_start_job(
+@@ -2023,6 +2069,8 @@ static BlockJob *mirror_start_job(
s->on_source_error = on_source_error;
s->on_target_error = on_target_error;
s->sync_mode = sync_mode;
@@ -153,9 +153,9 @@ index bc982cb99a..99805e7a9d 100644
s->backing_mode = backing_mode;
s->target_is_zero = target_is_zero;
qatomic_set(&s->copy_mode, copy_mode);
-@@ -2023,6 +2071,18 @@ static BlockJob *mirror_start_job(
- */
- bdrv_disable_dirty_bitmap(s->dirty_bitmap);
+@@ -2037,6 +2085,18 @@ static BlockJob *mirror_start_job(
+ }
+ bdrv_graph_rdunlock_main_loop();
+ if (s->sync_bitmap) {
+ bdrv_dirty_bitmap_set_busy(s->sync_bitmap, true);
@@ -172,17 +172,17 @@ index bc982cb99a..99805e7a9d 100644
bdrv_graph_wrlock_drained();
ret = block_job_add_bdrv(&s->common, "source", bs, 0,
BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
-@@ -2105,6 +2165,9 @@ fail:
- if (s->dirty_bitmap) {
- bdrv_release_dirty_bitmap(s->dirty_bitmap);
- }
+@@ -2116,6 +2176,9 @@ fail:
+ g_free(s->replaces);
+ blk_unref(s->target);
+ bs_opaque->job = NULL;
+ if (s->sync_bitmap) {
+ bdrv_dirty_bitmap_set_busy(s->sync_bitmap, false);
+ }
job_early_fail(&s->common.job);
}
-@@ -2127,7 +2190,10 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
+@@ -2139,7 +2202,10 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
BlockDriverState *target, const char *replaces,
int creation_flags, int64_t speed,
uint32_t granularity, int64_t buf_size,
@@ -194,7 +194,7 @@ index bc982cb99a..99805e7a9d 100644
bool target_is_zero,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
-@@ -2138,13 +2204,6 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
+@@ -2150,13 +2216,6 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
GLOBAL_STATE_CODE();
@@ -208,7 +208,7 @@ index bc982cb99a..99805e7a9d 100644
bdrv_graph_rdlock_main_loop();
base = mode == MIRROR_SYNC_MODE_TOP ? bdrv_backing_chain_next(bs) : NULL;
bdrv_graph_rdunlock_main_loop();
-@@ -2152,8 +2211,8 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
+@@ -2164,8 +2223,8 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
mirror_start_job(job_id, bs, creation_flags, target, replaces,
speed, granularity, buf_size, mode, backing_mode,
target_is_zero, on_source_error, on_target_error, unmap,
@@ -219,7 +219,7 @@ index bc982cb99a..99805e7a9d 100644
}
BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
-@@ -2180,7 +2239,7 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
+@@ -2192,7 +2251,7 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
job_id, bs, creation_flags, base, NULL, speed, 0, 0,
MIRROR_SYNC_MODE_TOP, MIRROR_LEAVE_BACKING_CHAIN, false,
on_error, on_error, true, cb, opaque,
@@ -333,7 +333,7 @@ index e7c8f1a856..d5aa68caeb 100644
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index b82af74256..64f2befdf5 100644
+index 4118d884f4..d4a5765dc4 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2275,6 +2275,15 @@
diff --git a/debian/patches/bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch b/debian/patches/bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch
index 8258adc..f413554 100644
--- a/debian/patches/bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch
+++ b/debian/patches/bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch
@@ -24,10 +24,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
-index 99805e7a9d..7dae4d6e8a 100644
+index d09479789f..0050d4372f 100644
--- a/block/mirror.c
+++ b/block/mirror.c
-@@ -734,8 +734,6 @@ static int mirror_exit_common(Job *job)
+@@ -735,8 +735,6 @@ static int mirror_exit_common(Job *job)
bdrv_unfreeze_backing_chain(mirror_top_bs, target_bs);
}
@@ -36,7 +36,7 @@ index 99805e7a9d..7dae4d6e8a 100644
/* Make sure that the source BDS doesn't go away during bdrv_replace_node,
* before we can call bdrv_drained_end */
bdrv_ref(src);
-@@ -851,6 +849,18 @@ static int mirror_exit_common(Job *job)
+@@ -852,6 +850,18 @@ static int mirror_exit_common(Job *job)
bdrv_drained_end(target_bs);
bdrv_unref(target_bs);
@@ -55,7 +55,7 @@ index 99805e7a9d..7dae4d6e8a 100644
bs_opaque->job = NULL;
bdrv_drained_end(src);
-@@ -1880,10 +1890,6 @@ static BlockJob *mirror_start_job(
+@@ -1883,10 +1893,6 @@ static BlockJob *mirror_start_job(
" sync mode",
MirrorSyncMode_str(sync_mode));
return NULL;
@@ -66,7 +66,7 @@ index 99805e7a9d..7dae4d6e8a 100644
}
} else if (bitmap) {
error_setg(errp,
-@@ -1900,6 +1906,12 @@ static BlockJob *mirror_start_job(
+@@ -1903,6 +1909,12 @@ static BlockJob *mirror_start_job(
return NULL;
}
granularity = bdrv_dirty_bitmap_granularity(bitmap);
diff --git a/debian/patches/bitmap-mirror/0004-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch b/debian/patches/bitmap-mirror/0004-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch
index 4f9cdbd..6023b78 100644
--- a/debian/patches/bitmap-mirror/0004-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch
+++ b/debian/patches/bitmap-mirror/0004-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch
@@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
-index 7dae4d6e8a..0f96c8b5ce 100644
+index 0050d4372f..ee745f8ec4 100644
--- a/block/mirror.c
+++ b/block/mirror.c
-@@ -855,8 +855,8 @@ static int mirror_exit_common(Job *job)
+@@ -856,8 +856,8 @@ static int mirror_exit_common(Job *job)
job->ret == 0 && ret == 0)) {
/* Success; synchronize copy back to sync. */
bdrv_clear_dirty_bitmap(s->sync_bitmap, NULL);
@@ -30,7 +30,7 @@ index 7dae4d6e8a..0f96c8b5ce 100644
}
}
bdrv_release_dirty_bitmap(s->dirty_bitmap);
-@@ -2088,11 +2088,8 @@ static BlockJob *mirror_start_job(
+@@ -2102,11 +2102,8 @@ static BlockJob *mirror_start_job(
}
if (s->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
diff --git a/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch b/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch
index 687a256..76b9d40 100644
--- a/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch
+++ b/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch
@@ -21,10 +21,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
3 files changed, 70 insertions(+), 59 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
-index 0f96c8b5ce..5340a695b1 100644
+index ee745f8ec4..e71f8f3cdf 100644
--- a/block/mirror.c
+++ b/block/mirror.c
-@@ -1880,31 +1880,13 @@ static BlockJob *mirror_start_job(
+@@ -1883,31 +1883,13 @@ static BlockJob *mirror_start_job(
GLOBAL_STATE_CODE();
diff --git a/debian/patches/extra/0003-block-mirror-check-range-when-setting-zero-bitmap-fo.patch b/debian/patches/extra/0003-block-mirror-check-range-when-setting-zero-bitmap-fo.patch
index 908d721..9af7ac5 100644
--- a/debian/patches/extra/0003-block-mirror-check-range-when-setting-zero-bitmap-fo.patch
+++ b/debian/patches/extra/0003-block-mirror-check-range-when-setting-zero-bitmap-fo.patch
@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
-Date: Mon, 12 Jan 2026 15:32:52 +0100
+Date: Mon, 12 Jan 2026 16:23:51 +0100
Subject: [PATCH] block/mirror: check range when setting zero bitmap for sync
write
@@ -32,6 +32,11 @@ bitmap too, which uses the same narrower range.
Cc: qemu-stable@nongnu.org
Fixes: 7e277545b9 ("mirror: Skip writing zeroes when target is already zero")
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+Message-ID: <20260112152544.261923-1-f.ebner@proxmox.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
+Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
+(cherry picked from commit 4a7b1bd18d2e1a6b3796e177ae5df9b198264a0b)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
block/mirror.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/debian/patches/extra/0005-block-vmdk-fix-OOB-read-in-vmdk_read_extent.patch b/debian/patches/extra/0005-block-vmdk-fix-OOB-read-in-vmdk_read_extent.patch
new file mode 100644
index 0000000..c458de4
--- /dev/null
+++ b/debian/patches/extra/0005-block-vmdk-fix-OOB-read-in-vmdk_read_extent.patch
@@ -0,0 +1,38 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Oblivionsage <cookieandcream560@gmail.com>
+Date: Tue, 10 Feb 2026 13:33:25 +0100
+Subject: [PATCH] block/vmdk: fix OOB read in vmdk_read_extent()
+
+Bounds check for marker.size doesn't account for the 12-byte marker
+header, allowing zlib to read past the allocated buffer.
+
+Move the check inside the has_marker block and subtract the marker size.
+
+Fixes: CVE-2026-2243
+Reported-by: Halil Oktay (oblivionsage) <cookieandcream560@gmail.com>
+Signed-off-by: Halil Oktay (oblivionsage) <cookieandcream560@gmail.com>
+(picked from https://lore.kernel.org/qemu-devel/CAJ9qJssSwxkmEVethg57-Ph6maEfButSaV-r07ma9_x1sp6wYg@mail.gmail.com/ )
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ block/vmdk.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/block/vmdk.c b/block/vmdk.c
+index 89e89cd10e..cd8b4ec7c8 100644
+--- a/block/vmdk.c
++++ b/block/vmdk.c
+@@ -1951,10 +1951,10 @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
+ marker = (VmdkGrainMarker *)cluster_buf;
+ compressed_data = marker->data;
+ data_len = le32_to_cpu(marker->size);
+- }
+- if (!data_len || data_len > buf_bytes) {
+- ret = -EINVAL;
+- goto out;
++ if (!data_len || data_len > buf_bytes - sizeof(VmdkGrainMarker)) {
++ ret = -EINVAL;
++ goto out;
++ }
+ }
+ ret = uncompress(uncomp_buf, &buf_len, compressed_data, data_len);
+ if (ret != Z_OK) {
diff --git a/debian/patches/extra/0006-block-throttle-groups-fix-deadlock-with-iolimits-and.patch b/debian/patches/extra/0006-block-throttle-groups-fix-deadlock-with-iolimits-and.patch
new file mode 100644
index 0000000..1485bfd
--- /dev/null
+++ b/debian/patches/extra/0006-block-throttle-groups-fix-deadlock-with-iolimits-and.patch
@@ -0,0 +1,133 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Dmitry Guryanov <dmitry.guryanov@gmail.com>
+Date: Mon, 8 Dec 2025 11:55:28 +0300
+Subject: [PATCH] block/throttle-groups: fix deadlock with iolimits and muliple
+ iothreads
+
+Details: https://gitlab.com/qemu-project/qemu/-/issues/3144
+
+The function schedule_next_request is called with tg->lock held and
+it may call throttle_group_co_restart_queue, which takes
+tgm->throttled_reqs_lock, qemu_co_mutex_lock may leave current
+coroutine if other iothread has taken the lock. If the next
+coroutine will call throttle_group_co_io_limits_intercept - it
+will try to take the mutex tg->lock which will never be released.
+
+Here is the backtrace of the iothread:
+Thread 30 (Thread 0x7f8aad1fd6c0 (LWP 24240) "IO iothread2"):
+ #0 futex_wait (futex_word=0x5611adb7d828, expected=2, private=0) at ../sysdeps/nptl/futex-internal.h:146
+ #1 __GI___lll_lock_wait (futex=futex@entry=0x5611adb7d828, private=0) at lowlevellock.c:49
+ #2 0x00007f8ab5a97501 in lll_mutex_lock_optimized (mutex=0x5611adb7d828) at pthread_mutex_lock.c:48
+ #3 ___pthread_mutex_lock (mutex=0x5611adb7d828) at pthread_mutex_lock.c:93
+ #4 0x00005611823f5482 in qemu_mutex_lock_impl (mutex=0x5611adb7d828, file=0x56118289daca "../block/throttle-groups.c", line=372) at ../util/qemu-thread-posix.c:94
+ #5 0x00005611822b0b39 in throttle_group_co_io_limits_intercept (tgm=0x5611af1bb4d8, bytes=4096, direction=THROTTLE_READ) at ../block/throttle-groups.c:372
+ #6 0x00005611822473b1 in blk_co_do_preadv_part (blk=0x5611af1bb490, offset=15972311040, bytes=4096, qiov=0x7f8aa4000f98, qiov_offset=0, flags=BDRV_REQ_REGISTERED_BUF) at ../block/block-backend.c:1354
+ #7 0x0000561182247fa0 in blk_aio_read_entry (opaque=0x7f8aa4005910) at ../block/block-backend.c:1619
+ #8 0x000056118241952e in coroutine_trampoline (i0=-1543497424, i1=32650) at ../util/coroutine-ucontext.c:175
+ #9 0x00007f8ab5a56f70 in ?? () at ../sysdeps/unix/sysv/linux/x86_64/__start_context.S:66 from target:/lib64/libc.so.6
+ #10 0x00007f8aad1ef190 in ?? ()
+ #11 0x0000000000000000 in ?? ()
+
+The lock is taken in line 386:
+(gdb) p tg.lock
+$1 = {lock = {__data = {__lock = 2, __count = 0, __owner = 24240, __nusers = 1, __kind = 0, __spins = 0, __elision = 0, __list = {__prev = 0x0, __next = 0x0}},
+ __size = "\002\000\000\000\000\000\000\000\260^\000\000\001", '\000' <repeats 26 times>, __align = 2}, file = 0x56118289daca "../block/throttle-groups.c",
+ line = 386, initialized = true}
+
+The solution is to use tg->lock to protect both ThreadGroup fields and
+ThrottleGroupMember.throttled_reqs. It doesn't seem to be possible
+to use separate locks because we need to first manipulate ThrottleGroup
+fields, then schedule next coroutine using throttled_reqs and after than
+update token field from ThrottleGroup depending on the throttled_reqs
+state.
+
+Signed-off-by: Dmitry Guryanov <dmitry.guryanov@gmail.com>
+Message-ID: <20251208085528.890098-1-dmitry.guryanov@gmail.com>
+Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+---
+ block/throttle-groups.c | 21 ++++++---------------
+ include/block/throttle-groups.h | 3 +--
+ 2 files changed, 7 insertions(+), 17 deletions(-)
+
+diff --git a/block/throttle-groups.c b/block/throttle-groups.c
+index 66fdce9a90..5329ff1fdb 100644
+--- a/block/throttle-groups.c
++++ b/block/throttle-groups.c
+@@ -295,19 +295,15 @@ static bool throttle_group_schedule_timer(ThrottleGroupMember *tgm,
+ /* Start the next pending I/O request for a ThrottleGroupMember. Return whether
+ * any request was actually pending.
+ *
++ * This assumes that tg->lock is held.
++ *
+ * @tgm: the current ThrottleGroupMember
+ * @direction: the ThrottleDirection
+ */
+ static bool coroutine_fn throttle_group_co_restart_queue(ThrottleGroupMember *tgm,
+ ThrottleDirection direction)
+ {
+- bool ret;
+-
+- qemu_co_mutex_lock(&tgm->throttled_reqs_lock);
+- ret = qemu_co_queue_next(&tgm->throttled_reqs[direction]);
+- qemu_co_mutex_unlock(&tgm->throttled_reqs_lock);
+-
+- return ret;
++ return qemu_co_queue_next(&tgm->throttled_reqs[direction]);
+ }
+
+ /* Look for the next pending I/O request and schedule it.
+@@ -378,12 +374,8 @@ void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm
+ /* Wait if there's a timer set or queued requests of this type */
+ if (must_wait || tgm->pending_reqs[direction]) {
+ tgm->pending_reqs[direction]++;
+- qemu_mutex_unlock(&tg->lock);
+- qemu_co_mutex_lock(&tgm->throttled_reqs_lock);
+ qemu_co_queue_wait(&tgm->throttled_reqs[direction],
+- &tgm->throttled_reqs_lock);
+- qemu_co_mutex_unlock(&tgm->throttled_reqs_lock);
+- qemu_mutex_lock(&tg->lock);
++ &tg->lock);
+ tgm->pending_reqs[direction]--;
+ }
+
+@@ -410,15 +402,15 @@ static void coroutine_fn throttle_group_restart_queue_entry(void *opaque)
+ ThrottleDirection direction = data->direction;
+ bool empty_queue;
+
++ qemu_mutex_lock(&tg->lock);
+ empty_queue = !throttle_group_co_restart_queue(tgm, direction);
+
+ /* If the request queue was empty then we have to take care of
+ * scheduling the next one */
+ if (empty_queue) {
+- qemu_mutex_lock(&tg->lock);
+ schedule_next_request(tgm, direction);
+- qemu_mutex_unlock(&tg->lock);
+ }
++ qemu_mutex_unlock(&tg->lock);
+
+ g_free(data);
+
+@@ -569,7 +561,6 @@ void throttle_group_register_tgm(ThrottleGroupMember *tgm,
+ read_timer_cb,
+ write_timer_cb,
+ tgm);
+- qemu_co_mutex_init(&tgm->throttled_reqs_lock);
+ }
+
+ /* Unregister a ThrottleGroupMember from its group, removing it from the list,
+diff --git a/include/block/throttle-groups.h b/include/block/throttle-groups.h
+index 2355e8d9de..7dfc81f7b5 100644
+--- a/include/block/throttle-groups.h
++++ b/include/block/throttle-groups.h
+@@ -35,8 +35,7 @@
+
+ typedef struct ThrottleGroupMember {
+ AioContext *aio_context;
+- /* throttled_reqs_lock protects the CoQueues for throttled requests. */
+- CoMutex throttled_reqs_lock;
++ /* Protected by ThrottleGroup.lock */
+ CoQueue throttled_reqs[THROTTLE_MAX];
+
+ /* Nonzero if the I/O limits are currently being ignored; generally
diff --git a/debian/patches/extra/0007-block-Never-drop-BLOCK_IO_ERROR-with-action-stop-for.patch b/debian/patches/extra/0007-block-Never-drop-BLOCK_IO_ERROR-with-action-stop-for.patch
new file mode 100644
index 0000000..b530219
--- /dev/null
+++ b/debian/patches/extra/0007-block-Never-drop-BLOCK_IO_ERROR-with-action-stop-for.patch
@@ -0,0 +1,88 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 4 Mar 2026 13:28:00 +0100
+Subject: [PATCH] block: Never drop BLOCK_IO_ERROR with action=stop for rate
+ limiting
+
+Commit 2155d2dd introduced rate limiting for BLOCK_IO_ERROR to emit an
+event only once a second. This makes sense for cases in which the guest
+keeps running and can submit more requests that would possibly also fail
+because there is a problem with the backend.
+
+However, if the error policy is configured so that the VM is stopped on
+errors, this is both unnecessary because stopping the VM means that the
+guest can't issue more requests and in fact harmful because stopping the
+VM is an important state change that management tools need to keep track
+of even if it happens more than once in a given second. If an event is
+dropped, the management tool would see a VM randomly going to paused
+state without an associated error, so it has a hard time deciding how to
+handle the situation.
+
+This patch disables rate limiting for action=stop by not relying on the
+event type alone any more in monitor_qapi_event_queue_no_reenter(), but
+checking action for BLOCK_IO_ERROR, too. If the error is reported to the
+guest or ignored, the rate limiting stays in place.
+
+Fixes: 2155d2dd7f73 ('block-backend: per-device throttling of BLOCK_IO_ERROR reports')
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Message-ID: <20260304122800.51923-1-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 544ddbb6373d61292a0e2dc269809cd6bd5edec6)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ monitor/monitor.c | 21 ++++++++++++++++++++-
+ qapi/block-core.json | 2 +-
+ 2 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/monitor/monitor.c b/monitor/monitor.c
+index 07775784d4..58ddee50d8 100644
+--- a/monitor/monitor.c
++++ b/monitor/monitor.c
+@@ -378,14 +378,33 @@ monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict *qdict)
+ {
+ MonitorQAPIEventConf *evconf;
+ MonitorQAPIEventState *evstate;
++ bool throttled;
+
+ assert(event < QAPI_EVENT__MAX);
+ evconf = &monitor_qapi_event_conf[event];
+ trace_monitor_protocol_event_queue(event, qdict, evconf->rate);
++ throttled = evconf->rate;
++
++ /*
++ * Rate limit BLOCK_IO_ERROR only for action != "stop".
++ *
++ * If the VM is stopped after an I/O error, this is important information
++ * for the management tool to keep track of the state of QEMU and we can't
++ * merge any events. At the same time, stopping the VM means that the guest
++ * can't send additional requests and the number of events is already
++ * limited, so we can do without rate limiting.
++ */
++ if (event == QAPI_EVENT_BLOCK_IO_ERROR) {
++ QDict *data = qobject_to(QDict, qdict_get(qdict, "data"));
++ const char *action = qdict_get_str(data, "action");
++ if (!strcmp(action, "stop")) {
++ throttled = false;
++ }
++ }
+
+ QEMU_LOCK_GUARD(&monitor_lock);
+
+- if (!evconf->rate) {
++ if (!throttled) {
+ /* Unthrottled event */
+ monitor_qapi_event_emit(event, qdict);
+ } else {
+diff --git a/qapi/block-core.json b/qapi/block-core.json
+index b82af74256..4118d884f4 100644
+--- a/qapi/block-core.json
++++ b/qapi/block-core.json
+@@ -5789,7 +5789,7 @@
+ # .. note:: If action is "stop", a `STOP` event will eventually follow
+ # the `BLOCK_IO_ERROR` event.
+ #
+-# .. note:: This event is rate-limited.
++# .. note:: This event is rate-limited, except if action is "stop".
+ #
+ # Since: 0.13
+ #
diff --git a/debian/patches/extra/0008-mirror-Fix-missed-dirty-bitmap-writes-during-startup.patch b/debian/patches/extra/0008-mirror-Fix-missed-dirty-bitmap-writes-during-startup.patch
new file mode 100644
index 0000000..b8ee24b
--- /dev/null
+++ b/debian/patches/extra/0008-mirror-Fix-missed-dirty-bitmap-writes-during-startup.patch
@@ -0,0 +1,152 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Thu, 19 Feb 2026 21:24:46 +0100
+Subject: [PATCH] mirror: Fix missed dirty bitmap writes during startup
+
+Currently, mirror disables the block layer's dirty bitmap before its own
+replacement is working. This means that during startup, there is a
+window in which the allocation status of blocks in the source has
+already been checked, but new writes coming in aren't tracked yet,
+resulting in a corrupted copy:
+
+1. Dirty bitmap is disabled in mirror_start_job()
+2. Some request are started in mirror_top_bs while s->job == NULL
+3. mirror_dirty_init() -> bdrv_co_is_allocated_above() runs and because
+ the request hasn't completed yet, the block isn't allocated
+4. The request completes, still sees s->job == NULL and skips the
+ bitmap, and nothing else will mark it dirty either
+
+One ingredient is that mirror_top_opaque->job is only set after the
+job is fully initialized. For the rationale, see commit 32125b1460
+("mirror: Fix access of uninitialised fields during start").
+
+Fix this by giving mirror_top_bs access to dirty_bitmap and enabling it
+to track writes from the beginning. Disabling the block layer's tracking
+and enabling the mirror_top_bs one happens in a drained section, so
+there is no danger of races with in-flight requests any more. All of
+this happens well before the block allocation status is checked, so we
+can be sure that no writes will be missed.
+
+Cc: qemu-stable@nongnu.org
+Closes: https://gitlab.com/qemu-project/qemu/-/issues/3273
+Fixes: 32125b14606a ('mirror: Fix access of uninitialised fields during start')
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Message-ID: <20260219202446.312493-1-kwolf@redhat.com>
+Reviewed-by: Fiona Ebner <f.ebner@proxmox.com>
+Tested-by: Jean-Louis Dupond <jean-louis@dupond.be>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 167ef239fbdcc4bde126e47668bfc4839b873b19)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ block/mirror.c | 52 +++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 32 insertions(+), 20 deletions(-)
+
+diff --git a/block/mirror.c b/block/mirror.c
+index bc982cb99a..fa1d975eb9 100644
+--- a/block/mirror.c
++++ b/block/mirror.c
+@@ -99,6 +99,7 @@ typedef struct MirrorBlockJob {
+
+ typedef struct MirrorBDSOpaque {
+ MirrorBlockJob *job;
++ BdrvDirtyBitmap *dirty_bitmap;
+ bool stop;
+ bool is_commit;
+ } MirrorBDSOpaque;
+@@ -1675,9 +1676,11 @@ bdrv_mirror_top_do_write(BlockDriverState *bs, MirrorMethod method,
+ abort();
+ }
+
+- if (!copy_to_target && s->job && s->job->dirty_bitmap) {
+- qatomic_set(&s->job->actively_synced, false);
+- bdrv_set_dirty_bitmap(s->job->dirty_bitmap, offset, bytes);
++ if (!copy_to_target) {
++ if (s->job) {
++ qatomic_set(&s->job->actively_synced, false);
++ }
++ bdrv_set_dirty_bitmap(s->dirty_bitmap, offset, bytes);
+ }
+
+ if (ret < 0) {
+@@ -1904,13 +1907,35 @@ static BlockJob *mirror_start_job(
+
+ bdrv_drained_begin(bs);
+ ret = bdrv_append(mirror_top_bs, bs, errp);
+- bdrv_drained_end(bs);
+-
+ if (ret < 0) {
++ bdrv_drained_end(bs);
++ bdrv_unref(mirror_top_bs);
++ return NULL;
++ }
++
++ bs_opaque->dirty_bitmap = bdrv_create_dirty_bitmap(mirror_top_bs,
++ granularity,
++ NULL, errp);
++ if (!bs_opaque->dirty_bitmap) {
++ bdrv_drained_end(bs);
+ bdrv_unref(mirror_top_bs);
+ return NULL;
+ }
+
++ /*
++ * The mirror job doesn't use the block layer's dirty tracking because it
++ * needs to be able to switch seemlessly between background copy mode (which
++ * does need dirty tracking) and write blocking mode (which doesn't) and
++ * doing that would require draining the node. Instead, mirror_top_bs takes
++ * care of updating the dirty bitmap as appropriate.
++ *
++ * Note that write blocking mode only becomes effective after mirror_run()
++ * sets mirror_top_opaque->job (see should_copy_to_target()). Until then,
++ * we're still in background copy mode irrespective of @copy_mode.
++ */
++ bdrv_disable_dirty_bitmap(bs_opaque->dirty_bitmap);
++ bdrv_drained_end(bs);
++
+ /* Make sure that the source is not resized while the job is running */
+ s = block_job_create(job_id, driver, NULL, mirror_top_bs,
+ BLK_PERM_CONSISTENT_READ,
+@@ -2005,24 +2030,13 @@ static BlockJob *mirror_start_job(
+ s->base_overlay = bdrv_find_overlay(bs, base);
+ s->granularity = granularity;
+ s->buf_size = ROUND_UP(buf_size, granularity);
++ s->dirty_bitmap = bs_opaque->dirty_bitmap;
+ s->unmap = unmap;
+ if (auto_complete) {
+ s->should_complete = true;
+ }
+ bdrv_graph_rdunlock_main_loop();
+
+- s->dirty_bitmap = bdrv_create_dirty_bitmap(s->mirror_top_bs, granularity,
+- NULL, errp);
+- if (!s->dirty_bitmap) {
+- goto fail;
+- }
+-
+- /*
+- * The dirty bitmap is set by bdrv_mirror_top_do_write() when not in active
+- * mode.
+- */
+- bdrv_disable_dirty_bitmap(s->dirty_bitmap);
+-
+ bdrv_graph_wrlock_drained();
+ ret = block_job_add_bdrv(&s->common, "source", bs, 0,
+ BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
+@@ -2102,9 +2116,6 @@ fail:
+ g_free(s->replaces);
+ blk_unref(s->target);
+ bs_opaque->job = NULL;
+- if (s->dirty_bitmap) {
+- bdrv_release_dirty_bitmap(s->dirty_bitmap);
+- }
+ job_early_fail(&s->common.job);
+ }
+
+@@ -2118,6 +2129,7 @@ fail:
+ bdrv_graph_wrunlock();
+ bdrv_drained_end(bs);
+
++ bdrv_release_dirty_bitmap(bs_opaque->dirty_bitmap);
+ bdrv_unref(mirror_top_bs);
+
+ return NULL;
diff --git a/debian/patches/extra/0009-virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch b/debian/patches/extra/0009-virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch
new file mode 100644
index 0000000..10fbda0
--- /dev/null
+++ b/debian/patches/extra/0009-virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch
@@ -0,0 +1,174 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
+Date: Sat, 14 Feb 2026 13:33:36 +0900
+Subject: [PATCH] virtio-gpu-virgl: Add virtio-gpu-virgl-hostmem-region type
+
+Commit e27194e087ae ("virtio-gpu-virgl: correct parent for blob memory
+region") made the name member of MemoryRegion unset, causing a NULL
+pointer dereference[1]:
+> Thread 2 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
+> (gdb) bt
+> #0 0x00007ffff56565e2 in __strcmp_evex () at /lib64/libc.so.6
+> #1 0x0000555555841bdb in find_fd (head=0x5555572337d0 <cpr_state>,
+> name=0x0, id=0) at ../migration/cpr.c:68
+> #2 cpr_delete_fd (name=name@entry=0x0, id=id@entry=0) at
+> ../migration/cpr.c:77
+> #3 0x000055555582290a in qemu_ram_free (block=0x7ff7e93aa7f0) at
+> ../system/physmem.c:2615
+> #4 0x000055555581ae02 in memory_region_finalize (obj=<optimized out>)
+> at ../system/memory.c:1816
+> #5 0x0000555555a70ab9 in object_deinit (obj=<optimized out>,
+> type=<optimized out>) at ../qom/object.c:715
+> #6 object_finalize (data=0x7ff7e936eff0) at ../qom/object.c:729
+> #7 object_unref (objptr=0x7ff7e936eff0) at ../qom/object.c:1232
+> #8 0x0000555555814fae in memory_region_unref (mr=<optimized out>) at
+> ../system/memory.c:1848
+> #9 flatview_destroy (view=0x555559ed6c40) at ../system/memory.c:301
+> #10 0x0000555555bfc122 in call_rcu_thread (opaque=<optimized out>) at
+> ../util/rcu.c:324
+> #11 0x0000555555bf17a7 in qemu_thread_start (args=0x555557b99520) at
+> ../util/qemu-thread-posix.c:393
+> #12 0x00007ffff556f464 in start_thread () at /lib64/libc.so.6
+> #13 0x00007ffff55f25ac in __clone3 () at /lib64/libc.so.6
+
+The intention of the aforementioned commit is to prevent a MemoryRegion
+from parenting itself while its references is counted indendependently
+of the device. To achieve the same goal, add a type of QOM objects that
+count references and parent MemoryRegions.
+
+[1] https://lore.kernel.org/qemu-devel/4eb93d7a-1fa9-4b3c-8ad7-a2eb64f025a0@collabora.com/
+
+Cc: qemu-stable@nongnu.org
+Fixes: e27194e087ae ("virtio-gpu-virgl: correct parent for blob memory region")
+Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
+Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Tested-by: Joelle van Dyne <j@getutm.app>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Message-Id: <20260214-region-v1-1-229f00ae1f38@rsg.ci.i.u-tokyo.ac.jp>
+(cherry picked from commit b2a279094c3b86667969cc645f7fb1087e08dd19)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/display/virtio-gpu-virgl.c | 54 +++++++++++++++++++++++++----------
+ 1 file changed, 39 insertions(+), 15 deletions(-)
+
+diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
+index 741728cabb..4e515c4ef6 100644
+--- a/hw/display/virtio-gpu-virgl.c
++++ b/hw/display/virtio-gpu-virgl.c
+@@ -52,11 +52,17 @@ virgl_get_egl_display(G_GNUC_UNUSED void *cookie)
+
+ #if VIRGL_VERSION_MAJOR >= 1
+ struct virtio_gpu_virgl_hostmem_region {
++ Object parent_obj;
+ MemoryRegion mr;
+ struct VirtIOGPU *g;
+ bool finish_unmapping;
+ };
+
++#define TYPE_VIRTIO_GPU_VIRGL_HOSTMEM_REGION "virtio-gpu-virgl-hostmem-region"
++
++OBJECT_DECLARE_SIMPLE_TYPE(virtio_gpu_virgl_hostmem_region,
++ VIRTIO_GPU_VIRGL_HOSTMEM_REGION)
++
+ static struct virtio_gpu_virgl_hostmem_region *
+ to_hostmem_region(MemoryRegion *mr)
+ {
+@@ -70,14 +76,22 @@ static void virtio_gpu_virgl_resume_cmdq_bh(void *opaque)
+ virtio_gpu_process_cmdq(g);
+ }
+
+-static void virtio_gpu_virgl_hostmem_region_free(void *obj)
++/*
++ * MR could outlive the resource if MR's reference is held outside of
++ * virtio-gpu. In order to prevent unmapping resource while MR is alive,
++ * and thus, making the data pointer invalid, we will block virtio-gpu
++ * command processing until MR is fully unreferenced and freed.
++ */
++static void virtio_gpu_virgl_hostmem_region_finalize(Object *obj)
+ {
+- MemoryRegion *mr = MEMORY_REGION(obj);
+- struct virtio_gpu_virgl_hostmem_region *vmr;
++ struct virtio_gpu_virgl_hostmem_region *vmr = VIRTIO_GPU_VIRGL_HOSTMEM_REGION(obj);
+ VirtIOGPUBase *b;
+ VirtIOGPUGL *gl;
+
+- vmr = to_hostmem_region(mr);
++ if (!vmr->g) {
++ return;
++ }
++
+ vmr->finish_unmapping = true;
+
+ b = VIRTIO_GPU_BASE(vmr->g);
+@@ -92,11 +106,26 @@ static void virtio_gpu_virgl_hostmem_region_free(void *obj)
+ qemu_bh_schedule(gl->cmdq_resume_bh);
+ }
+
++static const TypeInfo virtio_gpu_virgl_hostmem_region_info = {
++ .parent = TYPE_OBJECT,
++ .name = TYPE_VIRTIO_GPU_VIRGL_HOSTMEM_REGION,
++ .instance_size = sizeof(struct virtio_gpu_virgl_hostmem_region),
++ .instance_finalize = virtio_gpu_virgl_hostmem_region_finalize
++};
++
++static void virtio_gpu_virgl_types(void)
++{
++ type_register_static(&virtio_gpu_virgl_hostmem_region_info);
++}
++
++type_init(virtio_gpu_virgl_types)
++
+ static int
+ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
+ struct virtio_gpu_virgl_resource *res,
+ uint64_t offset)
+ {
++ g_autofree char *name = NULL;
+ struct virtio_gpu_virgl_hostmem_region *vmr;
+ VirtIOGPUBase *b = VIRTIO_GPU_BASE(g);
+ MemoryRegion *mr;
+@@ -117,21 +146,16 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
+ }
+
+ vmr = g_new0(struct virtio_gpu_virgl_hostmem_region, 1);
++ name = g_strdup_printf("blob[%" PRIu32 "]", res->base.resource_id);
++ object_initialize_child(OBJECT(g), name, vmr,
++ TYPE_VIRTIO_GPU_VIRGL_HOSTMEM_REGION);
+ vmr->g = g;
+
+ mr = &vmr->mr;
+- memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data);
++ memory_region_init_ram_ptr(mr, OBJECT(vmr), "mr", size, data);
+ memory_region_add_subregion(&b->hostmem, offset, mr);
+ memory_region_set_enabled(mr, true);
+
+- /*
+- * MR could outlive the resource if MR's reference is held outside of
+- * virtio-gpu. In order to prevent unmapping resource while MR is alive,
+- * and thus, making the data pointer invalid, we will block virtio-gpu
+- * command processing until MR is fully unreferenced and freed.
+- */
+- OBJECT(mr)->free = virtio_gpu_virgl_hostmem_region_free;
+-
+ res->mr = mr;
+
+ trace_virtio_gpu_cmd_res_map_blob(res->base.resource_id, vmr, mr);
+@@ -163,7 +187,7 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g,
+ * 1. Begin async unmapping with memory_region_del_subregion()
+ * and suspend/block cmd processing.
+ * 2. Wait for res->mr to be freed and cmd processing resumed
+- * asynchronously by virtio_gpu_virgl_hostmem_region_free().
++ * asynchronously by virtio_gpu_virgl_hostmem_region_finalize().
+ * 3. Finish the unmapping with final virgl_renderer_resource_unmap().
+ */
+ if (vmr->finish_unmapping) {
+@@ -186,7 +210,7 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g,
+ /* memory region owns self res->mr object and frees it by itself */
+ memory_region_set_enabled(mr, false);
+ memory_region_del_subregion(&b->hostmem, mr);
+- object_unref(OBJECT(mr));
++ object_unparent(OBJECT(vmr));
+ }
+
+ return 0;
diff --git a/debian/patches/extra/0010-virtio-gpu-Ensure-BHs-are-invoked-only-from-main-loo.patch b/debian/patches/extra/0010-virtio-gpu-Ensure-BHs-are-invoked-only-from-main-loo.patch
new file mode 100644
index 0000000..dc53ad1
--- /dev/null
+++ b/debian/patches/extra/0010-virtio-gpu-Ensure-BHs-are-invoked-only-from-main-loo.patch
@@ -0,0 +1,123 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Date: Wed, 4 Mar 2026 16:50:31 +0000
+Subject: [PATCH] virtio-gpu: Ensure BHs are invoked only from main-loop thread
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+QEMU's display GL core is tied to main-loop thread and virtio-gpu
+interacts with display while processing GPU commands. Virtio-gpu BHs
+work in generic AIO context that can be invoked on vCPU thread, while
+GL and UI toolkits are bound to the main-loop thread.
+
+Make virtio-gpu BHs use iohandler AIO context that is handled in a
+main-loop thread only.
+
+ 0 SDL_GL_MakeCurrent() (libSDL3)
+ 1 SDL_GL_MakeCurrent_REAL() (libSDL2)
+ 2 sdl2_gl_make_context_current() (ui/sdl2-gl.c:201)
+ 3 make_current() (virglrenderer.c:639)
+ 4 vrend_finish_context_switch() (vrend_renderer.c:11630)
+ 5 vrend_hw_switch_context() (vrend_renderer.c:11613)
+ 6 vrend_renderer_force_ctx_0() (vrend_renderer.c:12986)
+ 7 virgl_renderer_force_ctx_0() (virglrenderer.c:460)
+ 8 virtio_gpu_virgl_process_cmd() (virtio-gpu-virgl.c:1013)
+ 9 virtio_gpu_process_cmdq() (virtio-gpu.c:1050)
+ 10 virtio_gpu_gl_handle_ctrl() (virtio-gpu-gl.c:86)
+ 11 aio_bh_poll() (util/async.c)
+ 12 aio_poll() (util/aio-posix.c)
+ 13 blk_pwrite() (block/block-gen.c:1985)
+ 14 pflash_update() (pflash_cfi01.c:396)
+ 15 pflash_write() (pflash_cfi01.c:541)
+ 16 memory_region_dispatch_write() (system/memory.c:1554)
+ 17 flatview_write() (system/physmem.c:3333)
+ 18 address_space_write() (system/physmem.c:3453)
+ 19 kvm_cpu_exec() (accel/kvm/kall-all.c:3248)
+ 20 kvm_vcpu_thread_fn() (accel/kvm/kaccel-ops.c:53)
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Message-ID: <20260303151422.977399-8-dmitry.osipenko@collabora.com>
+Message-ID: <20260304165043.1437519-10-alex.bennee@linaro.org>
+Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
+(cherry picked from commit 235f9b36383e4cc7a790bca51eddbe38edd5438c)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/display/virtio-gpu-virgl.c | 6 +++---
+ hw/display/virtio-gpu.c | 6 +++---
+ hw/virtio/virtio.c | 10 ++++++++++
+ include/hw/virtio/virtio.h | 10 ++++++++++
+ 4 files changed, 26 insertions(+), 6 deletions(-)
+
+diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
+index 4e515c4ef6..1129301d91 100644
+--- a/hw/display/virtio-gpu-virgl.c
++++ b/hw/display/virtio-gpu-virgl.c
+@@ -1203,9 +1203,9 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
+ }
+
+ #if VIRGL_VERSION_MAJOR >= 1
+- gl->cmdq_resume_bh = aio_bh_new(qemu_get_aio_context(),
+- virtio_gpu_virgl_resume_cmdq_bh,
+- g);
++ gl->cmdq_resume_bh = virtio_bh_io_new_guarded(DEVICE(g),
++ virtio_gpu_virgl_resume_cmdq_bh,
++ g);
+ #endif
+
+ return 0;
+diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
+index 43e88a4daf..ad1ebc0fcd 100644
+--- a/hw/display/virtio-gpu.c
++++ b/hw/display/virtio-gpu.c
+@@ -1526,9 +1526,9 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
+
+ g->ctrl_vq = virtio_get_queue(vdev, 0);
+ g->cursor_vq = virtio_get_queue(vdev, 1);
+- g->ctrl_bh = virtio_bh_new_guarded(qdev, virtio_gpu_ctrl_bh, g);
+- g->cursor_bh = virtio_bh_new_guarded(qdev, virtio_gpu_cursor_bh, g);
+- g->reset_bh = qemu_bh_new(virtio_gpu_reset_bh, g);
++ g->ctrl_bh = virtio_bh_io_new_guarded(qdev, virtio_gpu_ctrl_bh, g);
++ g->cursor_bh = virtio_bh_io_new_guarded(qdev, virtio_gpu_cursor_bh, g);
++ g->reset_bh = virtio_bh_io_new_guarded(qdev, virtio_gpu_reset_bh, g);
+ qemu_cond_init(&g->reset_cond);
+ QTAILQ_INIT(&g->reslist);
+ QTAILQ_INIT(&g->cmdq);
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 257cda506a..683026adc4 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -4475,3 +4475,13 @@ QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
+ return qemu_bh_new_full(cb, opaque, name,
+ &transport->mem_reentrancy_guard);
+ }
++
++QEMUBH *virtio_bh_io_new_guarded_full(DeviceState *dev,
++ QEMUBHFunc *cb, void *opaque,
++ const char *name)
++{
++ DeviceState *transport = qdev_get_parent_bus(dev)->parent;
++
++ return aio_bh_new_full(iohandler_get_aio_context(), cb, opaque, name,
++ &transport->mem_reentrancy_guard);
++}
+diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
+index d97529c3f1..d5bd921581 100644
+--- a/include/hw/virtio/virtio.h
++++ b/include/hw/virtio/virtio.h
+@@ -547,4 +547,14 @@ QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
+ #define virtio_bh_new_guarded(dev, cb, opaque) \
+ virtio_bh_new_guarded_full((dev), (cb), (opaque), (stringify(cb)))
+
++/*
++ * The "_io" variant runs BH only on a main-loop thread, while generic BH
++ * may run on a vCPU thread.
++ */
++QEMUBH *virtio_bh_io_new_guarded_full(DeviceState *dev,
++ QEMUBHFunc *cb, void *opaque,
++ const char *name);
++#define virtio_bh_io_new_guarded(dev, cb, opaque) \
++ virtio_bh_io_new_guarded_full((dev), (cb), (opaque), (stringify(cb)))
++
+ #endif
diff --git a/debian/patches/extra/0011-hw-i2c-aspeed_i2c-Fix-out-of-bounds-read-in-I2C-MMIO.patch b/debian/patches/extra/0011-hw-i2c-aspeed_i2c-Fix-out-of-bounds-read-in-I2C-MMIO.patch
new file mode 100644
index 0000000..3fdc98c
--- /dev/null
+++ b/debian/patches/extra/0011-hw-i2c-aspeed_i2c-Fix-out-of-bounds-read-in-I2C-MMIO.patch
@@ -0,0 +1,136 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jamin Lin <jamin_lin@aspeedtech.com>
+Date: Tue, 10 Feb 2026 02:43:32 +0000
+Subject: [PATCH] hw/i2c/aspeed_i2c: Fix out-of-bounds read in I2C MMIO
+ handlers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The ASPEED I2C controller exposes a per-bus MMIO window of 0x80 bytes on
+AST2600/AST1030/AST2700, but the backing regs[] array was sized for only
+28 dwords (0x70 bytes). This allows guest reads in the range [0x70..0x7f]
+to index past the end of regs[].
+
+Fix this by:
+- Sizing ASPEED_I2C_NEW_NUM_REG to match the 0x80-byte window
+ (0x80 >> 2 = 32 dwords).
+- Avoiding an unconditional pre-read from regs[] in the legacy/new read
+ handlers. Initialize the return value to -1 and only read regs[] for
+ offsets that are explicitly handled/valid, leaving invalid offsets to
+ return -1 with a guest error log.
+
+Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
+Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3290
+Reviewed-by: Cédric Le Goater <clg@redhat.com>
+Link: https://lore.kernel.org/qemu-devel/20260210024331.3984696-2-jamin_lin@aspeedtech.com
+Signed-off-by: Cédric Le Goater <clg@redhat.com>
+(cherry picked from commit c2c5beec42bf9872b37e78b9e259132df7435cb5)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/i2c/aspeed_i2c.c | 22 ++++++++++------------
+ include/hw/i2c/aspeed_i2c.h | 3 +--
+ 2 files changed, 11 insertions(+), 14 deletions(-)
+
+diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
+index c48fa2050b..c455c3eb7c 100644
+--- a/hw/i2c/aspeed_i2c.c
++++ b/hw/i2c/aspeed_i2c.c
+@@ -94,7 +94,7 @@ static uint64_t aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,
+ unsigned size)
+ {
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
+- uint64_t value = bus->regs[offset / sizeof(*bus->regs)];
++ uint64_t value = -1;
+
+ switch (offset) {
+ case A_I2CD_FUN_CTRL:
+@@ -105,7 +105,7 @@ static uint64_t aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,
+ case A_I2CD_DEV_ADDR:
+ case A_I2CD_POOL_CTRL:
+ case A_I2CD_BYTE_BUF:
+- /* Value is already set, don't do anything. */
++ value = bus->regs[offset / sizeof(*bus->regs)];
+ break;
+ case A_I2CD_CMD:
+ value = SHARED_FIELD_DP32(value, BUS_BUSY_STS, i2c_bus_busy(bus->bus));
+@@ -113,21 +113,20 @@ static uint64_t aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,
+ case A_I2CD_DMA_ADDR:
+ if (!aic->has_dma) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
+- value = -1;
+ break;
+ }
++ value = bus->regs[offset / sizeof(*bus->regs)];
+ break;
+ case A_I2CD_DMA_LEN:
+ if (!aic->has_dma) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
+- value = -1;
++ break;
+ }
++ value = bus->regs[offset / sizeof(*bus->regs)];
+ break;
+-
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
+- value = -1;
+ break;
+ }
+
+@@ -139,7 +138,7 @@ static uint64_t aspeed_i2c_bus_new_read(AspeedI2CBus *bus, hwaddr offset,
+ unsigned size)
+ {
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
+- uint64_t value = bus->regs[offset / sizeof(*bus->regs)];
++ uint64_t value = -1;
+
+ switch (offset) {
+ case A_I2CC_FUN_CTRL:
+@@ -159,13 +158,12 @@ static uint64_t aspeed_i2c_bus_new_read(AspeedI2CBus *bus, hwaddr offset,
+ case A_I2CS_CMD:
+ case A_I2CS_INTR_CTRL:
+ case A_I2CS_DMA_LEN_STS:
+- /* Value is already set, don't do anything. */
++ case A_I2CS_INTR_STS:
++ value = bus->regs[offset / sizeof(*bus->regs)];
+ break;
+ case A_I2CC_DMA_ADDR:
+ value = extract64(bus->dma_dram_offset, 0, 32);
+ break;
+- case A_I2CS_INTR_STS:
+- break;
+ case A_I2CM_CMD:
+ value = SHARED_FIELD_DP32(value, BUS_BUSY_STS, i2c_bus_busy(bus->bus));
+ break;
+@@ -176,13 +174,13 @@ static uint64_t aspeed_i2c_bus_new_read(AspeedI2CBus *bus, hwaddr offset,
+ if (!aic->has_dma64) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA 64 bits support\n",
+ __func__);
+- value = -1;
++ break;
+ }
++ value = bus->regs[offset / sizeof(*bus->regs)];
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
+- value = -1;
+ break;
+ }
+
+diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
+index 2daacc10ce..efe8b1a0c5 100644
+--- a/include/hw/i2c/aspeed_i2c.h
++++ b/include/hw/i2c/aspeed_i2c.h
+@@ -36,8 +36,7 @@ OBJECT_DECLARE_TYPE(AspeedI2CState, AspeedI2CClass, ASPEED_I2C)
+ #define ASPEED_I2C_NR_BUSSES 16
+ #define ASPEED_I2C_SHARE_POOL_SIZE 0x800
+ #define ASPEED_I2C_BUS_POOL_SIZE 0x20
+-#define ASPEED_I2C_OLD_NUM_REG 11
+-#define ASPEED_I2C_NEW_NUM_REG 28
++#define ASPEED_I2C_NEW_NUM_REG (0x80 >> 2)
+
+ #define A_I2CD_M_STOP_CMD BIT(5)
+ #define A_I2CD_M_RX_CMD BIT(3)
diff --git a/debian/patches/extra/0012-target-arm-Account-for-SME-in-aarch64_sve_narrow_vq-.patch b/debian/patches/extra/0012-target-arm-Account-for-SME-in-aarch64_sve_narrow_vq-.patch
new file mode 100644
index 0000000..ed8c4ae
--- /dev/null
+++ b/debian/patches/extra/0012-target-arm-Account-for-SME-in-aarch64_sve_narrow_vq-.patch
@@ -0,0 +1,62 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Maydell <peter.maydell@linaro.org>
+Date: Wed, 18 Feb 2026 18:40:13 +0000
+Subject: [PATCH] target/arm: Account for SME in aarch64_sve_narrow_vq()
+ assertion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In aarch64_sve_narrow_vq() we assert that the new VQ is within
+the maximum supported range for the CPU. We forgot to update
+this to account for SME, which might have a different maximum.
+
+Update the assert to permit any VQ which is valid for either
+SVE or SME.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Message-id: 20260202133353.2231685-2-peter.maydell@linaro.org
+(cherry picked from commit 42eab40a12f12f044a5ca7b7d889d9a1f0d172ee)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ target/arm/helper.c | 2 +-
+ target/arm/internals.h | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/target/arm/helper.c b/target/arm/helper.c
+index 633d314edf..5d31c551e1 100644
+--- a/target/arm/helper.c
++++ b/target/arm/helper.c
+@@ -10058,7 +10058,7 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
+ uint64_t pmask;
+
+ assert(vq >= 1 && vq <= ARM_MAX_VQ);
+- assert(vq <= env_archcpu(env)->sve_max_vq);
++ assert(vq <= arm_max_vq(env_archcpu(env)));
+
+ /* Zap the high bits of the zregs. */
+ for (i = 0; i < 32; i++) {
+diff --git a/target/arm/internals.h b/target/arm/internals.h
+index 75677945af..d5f6d6546f 100644
+--- a/target/arm/internals.h
++++ b/target/arm/internals.h
+@@ -1807,6 +1807,15 @@ static inline uint64_t arm_mdcr_el2_eff(CPUARMState *env)
+ ((1 << (1 - 1)) | (1 << (2 - 1)) | \
+ (1 << (4 - 1)) | (1 << (8 - 1)) | (1 << (16 - 1)))
+
++/*
++ * Return the maximum SVE/SME VQ for this CPU. This defines
++ * the maximum possible size of the Zn vector registers.
++ */
++static inline int arm_max_vq(ARMCPU *cpu)
++{
++ return MAX(cpu->sve_max_vq, cpu->sme_max_vq);
++}
++
+ /*
+ * Return true if it is possible to take a fine-grained-trap to EL2.
+ */
diff --git a/debian/patches/extra/0013-target-arm-Fix-feature-check-in-DO_SVE2_RRX-DO_SVE2_.patch b/debian/patches/extra/0013-target-arm-Fix-feature-check-in-DO_SVE2_RRX-DO_SVE2_.patch
new file mode 100644
index 0000000..880965c
--- /dev/null
+++ b/debian/patches/extra/0013-target-arm-Fix-feature-check-in-DO_SVE2_RRX-DO_SVE2_.patch
@@ -0,0 +1,47 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Maydell <peter.maydell@linaro.org>
+Date: Wed, 18 Feb 2026 18:40:13 +0000
+Subject: [PATCH] target/arm: Fix feature check in DO_SVE2_RRX, DO_SVE2_RRX_TB
+
+In the macros DO_SVE2_RRX and DO_SVE2_RRX_TB we use the
+feature check aa64_sve, thus exposing this set of instructions
+in SVE as well as SVE2. Use aa64_sve2 instead, so they UNDEF
+on an SVE1-only CPU as they should.
+
+Strictly, the condition here should be "SVE2 or SME"; but we
+will correct that in a following commit with all the other
+missing "or SME" checks.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Message-id: 20260202133353.2231685-4-peter.maydell@linaro.org
+(cherry picked from commit ee5bf0962ed6e0eb42d6bc9bfb3687f2408e3580)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ target/arm/tcg/translate-sve.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
+index 07b827fa8e..d69a2f5d75 100644
+--- a/target/arm/tcg/translate-sve.c
++++ b/target/arm/tcg/translate-sve.c
+@@ -3769,7 +3769,7 @@ TRANS_FEAT(UDOT_zzxw_2s, aa64_sme2_or_sve2p1, gen_gvec_ool_arg_zzxz,
+ gen_helper_gvec_udot_idx_2h, a)
+
+ #define DO_SVE2_RRX(NAME, FUNC) \
+- TRANS_FEAT(NAME, aa64_sve, gen_gvec_ool_zzz, FUNC, \
++ TRANS_FEAT(NAME, aa64_sve2, gen_gvec_ool_zzz, FUNC, \
+ a->rd, a->rn, a->rm, a->index)
+
+ DO_SVE2_RRX(MUL_zzx_h, gen_helper_gvec_mul_idx_h)
+@@ -3787,7 +3787,7 @@ DO_SVE2_RRX(SQRDMULH_zzx_d, gen_helper_sve2_sqrdmulh_idx_d)
+ #undef DO_SVE2_RRX
+
+ #define DO_SVE2_RRX_TB(NAME, FUNC, TOP) \
+- TRANS_FEAT(NAME, aa64_sve, gen_gvec_ool_zzz, FUNC, \
++ TRANS_FEAT(NAME, aa64_sve2, gen_gvec_ool_zzz, FUNC, \
+ a->rd, a->rn, a->rm, (a->index << 1) | TOP)
+
+ DO_SVE2_RRX_TB(SQDMULLB_zzx_s, gen_helper_sve2_sqdmull_idx_s, false)
diff --git a/debian/patches/extra/0014-target-arm-tcg-Allow-SVE-RAX1-in-SME2p1-streaming-mo.patch b/debian/patches/extra/0014-target-arm-tcg-Allow-SVE-RAX1-in-SME2p1-streaming-mo.patch
new file mode 100644
index 0000000..d24758e
--- /dev/null
+++ b/debian/patches/extra/0014-target-arm-tcg-Allow-SVE-RAX1-in-SME2p1-streaming-mo.patch
@@ -0,0 +1,44 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Maydell <peter.maydell@linaro.org>
+Date: Wed, 18 Feb 2026 18:40:13 +0000
+Subject: [PATCH] target/arm/tcg: Allow SVE RAX1 in SME2p1 streaming mode
+
+The SVE RAX1 instruction is permitted in SME streaming mode starting
+from SME2p1. We forgot to allow this relaxation when we implemented
+SME2p1.
+
+Cc: qemu-stable@nongnu.org
+Fixes: 7b1613a1020d2 ("target/arm: Enable FEAT_SME2p1 on -cpu max")
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Message-id: 20260202133353.2231685-5-peter.maydell@linaro.org
+(cherry picked from commit 433097a2242120918090201129e5fbb8e16b3e34)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ target/arm/tcg/translate-sve.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
+index d69a2f5d75..76e4a6c52c 100644
+--- a/target/arm/tcg/translate-sve.c
++++ b/target/arm/tcg/translate-sve.c
+@@ -7803,8 +7803,17 @@ TRANS_FEAT_NONSTREAMING(SM4E, aa64_sve2_sm4, gen_gvec_ool_arg_zzz,
+ TRANS_FEAT_NONSTREAMING(SM4EKEY, aa64_sve2_sm4, gen_gvec_ool_arg_zzz,
+ gen_helper_crypto_sm4ekey, a, 0)
+
+-TRANS_FEAT_NONSTREAMING(RAX1, aa64_sve2_sha3, gen_gvec_fn_arg_zzz,
+- gen_gvec_rax1, a)
++static bool trans_RAX1(DisasContext *s, arg_RAX1 *a)
++{
++ if (!dc_isar_feature(aa64_sve2_sha3, s)) {
++ return false;
++ }
++ if (!dc_isar_feature(aa64_sme2p1, s)) {
++ /* SME2p1 adds this as valid in streaming SVE mode */
++ s->is_nonstreaming = true;
++ }
++ return gen_gvec_fn_arg_zzz(s, gen_gvec_rax1, a);
++}
+
+ TRANS_FEAT(FCVTNT_sh, aa64_sve2, gen_gvec_fpst_arg_zpz,
+ gen_helper_sve2_fcvtnt_sh, a, 0, FPST_A64)
diff --git a/debian/patches/extra/0015-target-arm-Don-t-let-sme-on-downgrade-SME.patch b/debian/patches/extra/0015-target-arm-Don-t-let-sme-on-downgrade-SME.patch
new file mode 100644
index 0000000..b6859b0
--- /dev/null
+++ b/debian/patches/extra/0015-target-arm-Don-t-let-sme-on-downgrade-SME.patch
@@ -0,0 +1,98 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Maydell <peter.maydell@linaro.org>
+Date: Wed, 18 Feb 2026 18:40:13 +0000
+Subject: [PATCH] target/arm: Don't let 'sme=on' downgrade SME
+
+In our handling of the boolean 'sme' CPU property, we write this 0/1
+value directly to ID_AA64PFR1_EL1.SME. This worked when the only
+valid values in that field were 0 (for no SME) and 1 (for SME1).
+However, with the addition of SME2 the SME field can now also read 2.
+This means that "-cpu max,sme=on" will result in an inconsistent set
+of ID registers, where ID_AA64PFR1_EL1.SME claims SME1 but
+ID_AA64SMFR0_EL1.SMEver claims SME2p1. This isn't a valid thing to
+report, and confuses Linux into reporting SME2 to userspace but not
+actually enabling userspace access for it.
+
+Fix this bug by having arm_cpu_sme_finalize() fix up the
+ID_AA64PFR1_EL1.SME field to match ID_AA64SMFR0.SMEver. This means
+the "sme" property's semantics are "off" for "no SME" and "on" for
+"enable at whatever the default SME version this CPU provides is".
+
+Update the documentation to clarify what 'sve=on' and 'sme=on' do.
+(We don't have the equivalent bug for 'sve=on' because
+ID_AA64PFR0_EL1.SVE only has 0 and 1 as valid values, but the
+semantics of the property are the same.)
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Message-id: 20260202133353.2231685-6-peter.maydell@linaro.org
+(cherry picked from commit aeb3c147fc4a1eb9a73f9f10923fc06def088aeb)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ docs/system/arm/cpu-features.rst | 10 ++++++++++
+ target/arm/cpu64.c | 15 +++++++++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
+index 37d5dfd15b..024119449c 100644
+--- a/docs/system/arm/cpu-features.rst
++++ b/docs/system/arm/cpu-features.rst
+@@ -318,6 +318,11 @@ SVE CPU Property Parsing Semantics
+ provided an error will be generated. To avoid this error, one must
+ enable at least one vector length prior to enabling SVE.
+
++ 10) Enabling SVE (with ``sve=on`` or by default) enables all the SVE
++ sub-features that the CPU supports (for example, it may also
++ enable SVE2). There are not generally any lower-level controls
++ for disabling specific SVE sub-features.
++
+ SVE CPU Property Examples
+ -------------------------
+
+@@ -430,6 +435,11 @@ and all vector lengths must be powers of 2. The maximum vector
+ length supported by qemu is 2048 bits. Otherwise, there are no
+ additional constraints on the set of vector lengths supported by SME.
+
++As with SVE, ``sme=on`` enables all the SME sub-features the CPU
++supports (for example, it may also enable SME2), and there are
++no lower-level controls for fine-grained disabling of specific
++SME sub-features.
++
+ SME User-mode Default Vector Length Property
+ --------------------------------------------
+
+diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
+index ae84d8e420..2082672dea 100644
+--- a/target/arm/cpu64.c
++++ b/target/arm/cpu64.c
+@@ -363,6 +363,16 @@ void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
+
+ cpu->sme_vq.map = vq_map;
+ cpu->sme_max_vq = 32 - clz32(vq_map);
++
++ /*
++ * The "sme" property setter writes a bool value into ID_AA64PFR1_EL1.SME
++ * (and at this point we know it's not 0). Correct that value to report
++ * the same SME version as ID_AA64SMFR0_EL1.SMEver.
++ */
++ if (FIELD_EX64_IDREG(&cpu->isar, ID_AA64SMFR0, SMEVER) != 0) {
++ /* SME2 or better */
++ FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR1, SME, 2);
++ }
+ }
+
+ static bool cpu_arm_get_sme(Object *obj, Error **errp)
+@@ -375,6 +385,11 @@ static void cpu_arm_set_sme(Object *obj, bool value, Error **errp)
+ {
+ ARMCPU *cpu = ARM_CPU(obj);
+
++ /*
++ * For now, write 0 for "off" and 1 for "on" into the PFR1 field.
++ * We will correct this value to report the right SME
++ * level (SME vs SME2) in arm_cpu_sme_finalize() later.
++ */
+ FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR1, SME, value);
+ }
+
diff --git a/debian/patches/extra/0016-target-arm-set-the-correct-TI-bits-for-WFIT-traps.patch b/debian/patches/extra/0016-target-arm-set-the-correct-TI-bits-for-WFIT-traps.patch
new file mode 100644
index 0000000..9b10110
--- /dev/null
+++ b/debian/patches/extra/0016-target-arm-set-the-correct-TI-bits-for-WFIT-traps.patch
@@ -0,0 +1,35 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <alex.bennee@linaro.org>
+Date: Thu, 26 Feb 2026 11:27:18 +0000
+Subject: [PATCH] target/arm: set the correct TI bits for WFIT traps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The WFIT trap should be reported as 0b10.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
+Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>
+Message-id: 20260220171945.1065102-1-alex.bennee@linaro.org
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 662fd548a027c9362df71ebfc0c9cdd7b1f349fb)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ target/arm/tcg/op_helper.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
+index 4fbd219555..9c0651f000 100644
+--- a/target/arm/tcg/op_helper.c
++++ b/target/arm/tcg/op_helper.c
+@@ -448,7 +448,7 @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
+
+ if (target_el) {
+ env->pc -= 4;
+- raise_exception(env, excp, syn_wfx(1, 0xe, 0, false), target_el);
++ raise_exception(env, excp, syn_wfx(1, 0xe, 2, false), target_el);
+ }
+
+ if (uadd64_overflow(timeout, offset, &nexttick)) {
diff --git a/debian/patches/extra/0017-aio-posix-notify-main-loop-when-SQEs-are-queued.patch b/debian/patches/extra/0017-aio-posix-notify-main-loop-when-SQEs-are-queued.patch
new file mode 100644
index 0000000..ddc6803
--- /dev/null
+++ b/debian/patches/extra/0017-aio-posix-notify-main-loop-when-SQEs-are-queued.patch
@@ -0,0 +1,119 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Wed, 18 Feb 2026 15:09:58 -0500
+Subject: [PATCH] aio-posix: notify main loop when SQEs are queued
+
+When a vCPU thread handles MMIO (holding BQL), aio_co_enter() runs the
+block I/O coroutine inline on the vCPU thread because
+qemu_get_current_aio_context() returns the main AioContext when BQL is
+held. The coroutine calls luring_co_submit() which queues an SQE via
+fdmon_io_uring_add_sqe(), but the actual io_uring_submit() only happens
+in gsource_prepare() on the main loop thread.
+
+Since the coroutine ran inline (not via aio_co_schedule()), no BH is
+scheduled and aio_notify() is never called. The main loop remains asleep
+in ppoll() with up to a 499ms timeout, leaving the SQE unsubmitted until
+the next timer fires.
+
+Fix this by calling aio_notify() after queuing the SQE. This wakes the
+main loop via the eventfd so it can run gsource_prepare() and submit the
+pending SQE promptly.
+
+This is a generic fix that benefits all devices using aio=io_uring.
+Without it, AHCI/SATA devices see MUCH worse I/O latency since they use
+MMIO (not ioeventfd like virtio) and have no other mechanism to wake the
+main loop after queuing block I/O.
+
+This is usually a bit hard to detect, as it also relies on the ppoll
+loop not waking up for other activity, and micro benchmarks tend not to
+see it because they don't have any real processing time. With a
+synthetic test case that has a few usleep() to simulate processing of
+read data, it's very noticeable. The below example reads 128MB with
+O_DIRECT in 128KB chunks in batches of 16, and has a 1ms delay before
+each batch submit, and a 1ms delay after processing each completion.
+Running it on /dev/sda yields:
+
+time sudo ./iotest /dev/sda
+
+________________________________________________________
+Executed in 25.76 secs fish external
+ usr time 6.19 millis 783.00 micros 5.41 millis
+ sys time 12.43 millis 642.00 micros 11.79 millis
+
+while on a virtio-blk or NVMe device we get:
+
+time sudo ./iotest /dev/vdb
+
+________________________________________________________
+Executed in 1.25 secs fish external
+ usr time 1.40 millis 0.30 millis 1.10 millis
+ sys time 17.61 millis 1.43 millis 16.18 millis
+
+time sudo ./iotest /dev/nvme0n1
+
+________________________________________________________
+Executed in 1.26 secs fish external
+ usr time 6.11 millis 0.52 millis 5.59 millis
+ sys time 13.94 millis 1.50 millis 12.43 millis
+
+where the latter are consistent. If we run the same test but keep the
+socket for the ssh connection active by having activity there, then
+the sda test looks as follows:
+
+time sudo ./iotest /dev/sda
+
+________________________________________________________
+Executed in 1.23 secs fish external
+ usr time 2.70 millis 39.00 micros 2.66 millis
+ sys time 4.97 millis 977.00 micros 3.99 millis
+
+as now the ppoll loop is woken all the time anyway.
+
+After this fix, on an idle system:
+
+time sudo ./iotest /dev/sda
+
+________________________________________________________
+Executed in 1.30 secs fish external
+ usr time 2.14 millis 0.14 millis 2.00 millis
+ sys time 16.93 millis 1.16 millis 15.76 millis
+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Message-Id: <07d701b9-3039-4f9b-99a2-abeae51146a5@kernel.dk>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+[Generalize the comment since this applies to all vCPU thread activity,
+not just coroutines, as suggested by Kevin Wolf <kwolf@redhat.com>.
+--Stefan]
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 2ae361ef1d7d526b07ff88d854552e2d009bfb1b)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ util/aio-posix.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/util/aio-posix.c b/util/aio-posix.c
+index e24b955fd9..488d964611 100644
+--- a/util/aio-posix.c
++++ b/util/aio-posix.c
+@@ -23,6 +23,7 @@
+ #include "qemu/rcu_queue.h"
+ #include "qemu/sockets.h"
+ #include "qemu/cutils.h"
++#include "system/iothread.h"
+ #include "trace.h"
+ #include "aio-posix.h"
+
+@@ -813,5 +814,13 @@ void aio_add_sqe(void (*prep_sqe)(struct io_uring_sqe *sqe, void *opaque),
+ {
+ AioContext *ctx = qemu_get_current_aio_context();
+ ctx->fdmon_ops->add_sqe(ctx, prep_sqe, opaque, cqe_handler);
++
++ /*
++ * Wake the main loop if it is sleeping in ppoll(). When a vCPU thread
++ * queues SQEs, the actual io_uring_submit() only happens in
++ * gsource_prepare() in the main loop thread. Without this notify, the
++ * main loop thread's ppoll() can sleep up to 499ms before submitting.
++ */
++ aio_notify(ctx);
+ }
+ #endif /* CONFIG_LINUX_IO_URING */
diff --git a/debian/patches/extra/0018-fdmon-io_uring-check-CQ-ring-directly-in-gsource_che.patch b/debian/patches/extra/0018-fdmon-io_uring-check-CQ-ring-directly-in-gsource_che.patch
new file mode 100644
index 0000000..263e145
--- /dev/null
+++ b/debian/patches/extra/0018-fdmon-io_uring-check-CQ-ring-directly-in-gsource_che.patch
@@ -0,0 +1,49 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Fri, 13 Feb 2026 07:26:37 -0700
+Subject: [PATCH] fdmon-io_uring: check CQ ring directly in gsource_check
+
+gsource_check() only looks at the ppoll revents for the io_uring fd,
+but CQEs can be posted during gsource_prepare()'s io_uring_submit()
+call via kernel task_work processing on syscall exit. These completions
+are already sitting in the CQ ring but the ring fd may not be signaled
+yet, causing gsource_check() to return false.
+
+Add a fallback io_uring_cq_ready() check so completions that arrive
+during submission are dispatched immediately rather than waiting for
+the next ppoll() cycle.
+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Message-ID: <20260213143225.161043-3-axboe@kernel.dk>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 961fcc0f22768e7c3432fc645b93dc7cd4932fae)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ util/fdmon-io_uring.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/util/fdmon-io_uring.c b/util/fdmon-io_uring.c
+index d0b56127c6..b81e412402 100644
+--- a/util/fdmon-io_uring.c
++++ b/util/fdmon-io_uring.c
+@@ -344,7 +344,19 @@ static void fdmon_io_uring_gsource_prepare(AioContext *ctx)
+ static bool fdmon_io_uring_gsource_check(AioContext *ctx)
+ {
+ gpointer tag = ctx->io_uring_fd_tag;
+- return g_source_query_unix_fd(&ctx->source, tag) & G_IO_IN;
++
++ /* Check ppoll revents (normal path) */
++ if (g_source_query_unix_fd(&ctx->source, tag) & G_IO_IN) {
++ return true;
++ }
++
++ /*
++ * Also check for CQEs that may have been posted during prepare's
++ * io_uring_submit() via task_work on syscall exit. Without this,
++ * the main loop can miss completions and sleep in ppoll() until the
++ * next timer fires.
++ */
++ return io_uring_cq_ready(&ctx->fdmon_io_uring);
+ }
+
+ /* Dispatch CQE handlers that are ready */
diff --git a/debian/patches/extra/0019-target-i386-add-compat-for-migrating-error-code.patch b/debian/patches/extra/0019-target-i386-add-compat-for-migrating-error-code.patch
new file mode 100644
index 0000000..37a1d3a
--- /dev/null
+++ b/debian/patches/extra/0019-target-i386-add-compat-for-migrating-error-code.patch
@@ -0,0 +1,75 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Fiona Ebner <f.ebner@proxmox.com>
+Date: Tue, 3 Mar 2026 15:29:22 +0100
+Subject: [PATCH] target/i386: add compat for migrating error code
+
+If cpu->env.has_error_code is true, backwards migration of a VM from
+a QEMU binary with commit 27535e9cca to a QEMU binary without commit
+27535e9cca will fail:
+
+> kvm: error while loading state for instance 0x0 of device 'cpu'
+
+In practice, wrongly setting the error code to 0 on the target is
+often unproblematic, so additionally checking error_code != 0 in
+cpu_errcode_needed() is not enough to mitigate the issue. Instead, add
+proper machine version compat handling.
+
+Cc: qemu-stable@nongnu.org
+Fixes: 27535e9cca ("target/i386: Add support for save/load of exception error code")
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/i386/pc.c | 1 +
+ target/i386/cpu.c | 1 +
+ target/i386/cpu.h | 1 +
+ target/i386/machine.c | 2 +-
+ 4 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/hw/i386/pc.c b/hw/i386/pc.c
+index f8b919cb6c..48e153c93f 100644
+--- a/hw/i386/pc.c
++++ b/hw/i386/pc.c
+@@ -83,6 +83,7 @@
+
+ GlobalProperty pc_compat_10_1[] = {
+ { "mch", "extended-tseg-mbytes", "16" },
++ { TYPE_X86_CPU, "x-migrate-error-code", "false" },
+ };
+ const size_t pc_compat_10_1_len = G_N_ELEMENTS(pc_compat_10_1);
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 6417775786..78308a82a0 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -10024,6 +10024,7 @@ static const Property x86_cpu_properties[] = {
+ DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
+ DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count,
+ true),
++ DEFINE_PROP_BOOL("x-migrate-error-code", X86CPU, migrate_error_code, true),
+ /*
+ * lecacy_cache defaults to true unless the CPU model provides its
+ * own cache information (see x86_cpu_load_def()).
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index cee1f692a1..ee3ed5ae6d 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -2211,6 +2211,7 @@ struct ArchCPU {
+ bool expose_tcg;
+ bool migratable;
+ bool migrate_smi_count;
++ bool migrate_error_code;
+ uint32_t apic_id;
+
+ /* Enables publishing of TSC increment and Local APIC bus frequencies to
+diff --git a/target/i386/machine.c b/target/i386/machine.c
+index 45b7cea80a..21531f8ba2 100644
+--- a/target/i386/machine.c
++++ b/target/i386/machine.c
+@@ -466,7 +466,7 @@ static bool cpu_errcode_needed(void *opaque)
+ {
+ X86CPU *cpu = opaque;
+
+- return cpu->env.has_error_code != 0;
++ return cpu->env.has_error_code != 0 && cpu->migrate_error_code;
+ }
+
+ static const VMStateDescription vmstate_error_code = {
--git a/debian/patches/extra/0020-virtio-snd-remove-TODO-comments.patch b/debian/patches/extra/0020-virtio-snd-remove-TODO-comments.patch
new file mode 100644
index 0000000..eddb849
--- /dev/null
+++ b/debian/patches/extra/0020-virtio-snd-remove-TODO-comments.patch
@@ -0,0 +1,93 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Date: Fri, 20 Feb 2026 11:40:13 +0200
+Subject: [PATCH] virtio-snd: remove TODO comments
+
+Replying with a VIRTIO_SND_S_BAD_MSG error does not warrant a device
+reset. Instead, a device reset happens when the driver requests it from the
+transport.
+
+Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Message-Id: <20260220-virtio-snd-series-v1-2-207c4f7200a2@linaro.org>
+(cherry picked from commit 34238f078a04f24b91199249b83846ab082b4e05)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/audio/virtio-snd.c | 21 ---------------------
+ 1 file changed, 21 deletions(-)
+
+diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
+index 9101560f38..fd03efc120 100644
+--- a/hw/audio/virtio-snd.c
++++ b/hw/audio/virtio-snd.c
+@@ -168,9 +168,6 @@ static void virtio_snd_handle_pcm_info(VirtIOSound *s,
+ sizeof(virtio_snd_query_info));
+
+ if (msg_sz != sizeof(virtio_snd_query_info)) {
+- /*
+- * TODO: do we need to set DEVICE_NEEDS_RESET?
+- */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: virtio-snd command size incorrect %zu vs \
+ %zu\n", __func__, msg_sz, sizeof(virtio_snd_query_info));
+@@ -184,9 +181,6 @@ static void virtio_snd_handle_pcm_info(VirtIOSound *s,
+
+ if (iov_size(cmd->elem->in_sg, cmd->elem->in_num) <
+ sizeof(virtio_snd_hdr) + size * count) {
+- /*
+- * TODO: do we need to set DEVICE_NEEDS_RESET?
+- */
+ error_report("pcm info: buffer too small, got: %zu, needed: %zu",
+ iov_size(cmd->elem->in_sg, cmd->elem->in_num),
+ sizeof(virtio_snd_pcm_info));
+@@ -244,9 +238,6 @@ uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
+ virtio_snd_pcm_set_params *st_params;
+
+ if (stream_id >= s->snd_conf.streams || s->pcm->pcm_params == NULL) {
+- /*
+- * TODO: do we need to set DEVICE_NEEDS_RESET?
+- */
+ virtio_error(VIRTIO_DEVICE(s), "Streams have not been initialized.\n");
+ return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
+ }
+@@ -297,9 +288,6 @@ static void virtio_snd_handle_pcm_set_params(VirtIOSound *s,
+ sizeof(virtio_snd_pcm_set_params));
+
+ if (msg_sz != sizeof(virtio_snd_pcm_set_params)) {
+- /*
+- * TODO: do we need to set DEVICE_NEEDS_RESET?
+- */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: virtio-snd command size incorrect %zu vs \
+ %zu\n", __func__, msg_sz, sizeof(virtio_snd_pcm_set_params));
+@@ -609,9 +597,6 @@ static void virtio_snd_handle_pcm_release(VirtIOSound *s,
+ sizeof(stream_id));
+
+ if (msg_sz != sizeof(stream_id)) {
+- /*
+- * TODO: do we need to set DEVICE_NEEDS_RESET?
+- */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: virtio-snd command size incorrect %zu vs \
+ %zu\n", __func__, msg_sz, sizeof(stream_id));
+@@ -623,9 +608,6 @@ static void virtio_snd_handle_pcm_release(VirtIOSound *s,
+ trace_virtio_snd_handle_pcm_release(stream_id);
+ stream = virtio_snd_pcm_get_stream(s, stream_id);
+ if (stream == NULL) {
+- /*
+- * TODO: do we need to set DEVICE_NEEDS_RESET?
+- */
+ error_report("already released stream %"PRIu32, stream_id);
+ virtio_error(VIRTIO_DEVICE(s),
+ "already released stream %"PRIu32,
+@@ -668,9 +650,6 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd)
+ sizeof(virtio_snd_hdr));
+
+ if (msg_sz != sizeof(virtio_snd_hdr)) {
+- /*
+- * TODO: do we need to set DEVICE_NEEDS_RESET?
+- */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: virtio-snd command size incorrect %zu vs \
+ %zu\n", __func__, msg_sz, sizeof(virtio_snd_hdr));
diff --git a/debian/patches/extra/0021-virtio-snd-handle-5.14.6.2-for-PCM_INFO-properly.patch b/debian/patches/extra/0021-virtio-snd-handle-5.14.6.2-for-PCM_INFO-properly.patch
new file mode 100644
index 0000000..ec9ad51
--- /dev/null
+++ b/debian/patches/extra/0021-virtio-snd-handle-5.14.6.2-for-PCM_INFO-properly.patch
@@ -0,0 +1,89 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Date: Fri, 20 Feb 2026 11:40:14 +0200
+Subject: [PATCH] virtio-snd: handle 5.14.6.2 for PCM_INFO properly
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The section 5.14.6.2 of the VIRTIO spec says:
+
+ 5.14.6.2 Driver Requirements: Item Information Request
+
+ - The driver MUST NOT set start_id and count such that start_id +
+ count is greater than the total number of particular items that is
+ indicated in the device configuration space.
+
+ - The driver MUST provide a buffer of sizeof(struct virtio_snd_hdr) +
+ count * size bytes for the response.
+
+While we performed some check for the second requirement, it failed to
+check for integer overflow.
+
+Add also a check for the first requirement, which should limit exposure
+to any overflow, since realistically the number of streams will be low
+enough in value such that overflow is improbable.
+
+Cc: qemu-stable@nongnu.org
+Reported-by: 罗铭源 <myluo24@m.fudan.edu.cn>
+Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Message-Id: <20260220-virtio-snd-series-v1-3-207c4f7200a2@linaro.org>
+(cherry picked from commit 61679d7dcfa2dffc8fb115aa19b09e0e7cf5ea5c)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/audio/virtio-snd.c | 31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
+index fd03efc120..e9c24d6795 100644
+--- a/hw/audio/virtio-snd.c
++++ b/hw/audio/virtio-snd.c
+@@ -156,7 +156,7 @@ static virtio_snd_pcm_set_params *virtio_snd_pcm_get_params(VirtIOSound *s,
+ static void virtio_snd_handle_pcm_info(VirtIOSound *s,
+ virtio_snd_ctrl_command *cmd)
+ {
+- uint32_t stream_id, start_id, count, size;
++ uint32_t stream_id, start_id, count, size, tmp;
+ virtio_snd_pcm_info val;
+ virtio_snd_query_info req;
+ VirtIOSoundPCMStream *stream = NULL;
+@@ -179,11 +179,34 @@ static void virtio_snd_handle_pcm_info(VirtIOSound *s,
+ count = le32_to_cpu(req.count);
+ size = le32_to_cpu(req.size);
+
+- if (iov_size(cmd->elem->in_sg, cmd->elem->in_num) <
+- sizeof(virtio_snd_hdr) + size * count) {
++ /*
++ * 5.14.6.2 Driver Requirements: Item Information Request
++ * "The driver MUST NOT set start_id and count such that start_id + count
++ * is greater than the total number of particular items that is indicated
++ * in the device configuration space."
++ */
++ if (start_id > s->snd_conf.streams
++ || !g_uint_checked_add(&tmp, start_id, count)
++ || start_id + count > s->snd_conf.streams) {
++ error_report("pcm info: start_id + count is greater than the total "
++ "number of streams, got: start_id = %u, count = %u",
++ start_id, count);
++ cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
++ return;
++ }
++
++ /*
++ * 5.14.6.2 Driver Requirements: Item Information Request
++ * "The driver MUST provide a buffer of sizeof(struct virtio_snd_hdr) +
++ * count * size bytes for the response."
++ */
++ if (!g_uint_checked_mul(&tmp, size, count)
++ || !g_uint_checked_add(&tmp, tmp, sizeof(virtio_snd_hdr))
++ || iov_size(cmd->elem->in_sg, cmd->elem->in_num) <
++ sizeof(virtio_snd_hdr) + size * count) {
+ error_report("pcm info: buffer too small, got: %zu, needed: %zu",
+ iov_size(cmd->elem->in_sg, cmd->elem->in_num),
+- sizeof(virtio_snd_pcm_info));
++ sizeof(virtio_snd_pcm_info) * count);
+ cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
+ return;
+ }
diff --git a/debian/patches/extra/0022-virtio-snd-fix-max_size-bounds-check-in-input-cb.patch b/debian/patches/extra/0022-virtio-snd-fix-max_size-bounds-check-in-input-cb.patch
new file mode 100644
index 0000000..e4e255a
--- /dev/null
+++ b/debian/patches/extra/0022-virtio-snd-fix-max_size-bounds-check-in-input-cb.patch
@@ -0,0 +1,44 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Date: Fri, 20 Feb 2026 11:40:15 +0200
+Subject: [PATCH] virtio-snd: fix max_size bounds check in input cb
+
+In 98e77e3d we calculated the max size and checked that each buffer is smaller than it.
+
+We neglected to subtract the size of the virtio_snd_pcm_status header
+from the max size, and max_size was thus larger than the correct value,
+leading to potential OOB writes.
+
+If the buffer cannot fit the header or can fit only the header, return
+the buffer immediately.
+
+Cc: qemu-stable@nongnu.org
+Fixes: 98e77e3dd8dd6e7aa9a7dffa60f49c8c8a49d4e3 ("virtio-snd: add max size bounds check in input cb")
+Reported-by: DARKNAVY <vr@darknavy.com>
+Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Message-Id: <20260220-virtio-snd-series-v1-4-207c4f7200a2@linaro.org>
+(cherry picked from commit bcb53328aa70023f1405fade4e253e7f77567261)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/audio/virtio-snd.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
+index e9c24d6795..3437211f79 100644
+--- a/hw/audio/virtio-snd.c
++++ b/hw/audio/virtio-snd.c
+@@ -1255,6 +1255,12 @@ static void virtio_snd_pcm_in_cb(void *data, int available)
+ }
+
+ max_size = iov_size(buffer->elem->in_sg, buffer->elem->in_num);
++ if (max_size <= sizeof(virtio_snd_pcm_status)) {
++ return_rx_buffer(stream, buffer);
++ continue;
++ }
++ max_size -= sizeof(virtio_snd_pcm_status);
++
+ for (;;) {
+ if (buffer->size >= max_size) {
+ return_rx_buffer(stream, buffer);
diff --git a/debian/patches/extra/0023-virtio-snd-tighten-read-amount-in-in_cb.patch b/debian/patches/extra/0023-virtio-snd-tighten-read-amount-in-in_cb.patch
new file mode 100644
index 0000000..00e496c
--- /dev/null
+++ b/debian/patches/extra/0023-virtio-snd-tighten-read-amount-in-in_cb.patch
@@ -0,0 +1,51 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Date: Fri, 20 Feb 2026 11:40:16 +0200
+Subject: [PATCH] virtio-snd: tighten read amount in in_cb
+
+The amount of bytes to read passed to AUD_read() should never surpass
+the maximum available buffer length. Tighten the current amount by
+MIN(<amount>, max_size - <existing size>).
+
+Cc: qemu-stable@nongnu.org
+Fixes: 98e77e3dd8dd6e7aa9a7dffa60f49c8c8a49d4e3 ("virtio-snd: add max size bounds check in input cb")
+Reported-by: DARKNAVY <vr@darknavy.com>
+Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Message-Id: <20260220-virtio-snd-series-v1-5-207c4f7200a2@linaro.org>
+(cherry picked from commit 7994203bb1b83a6604f3ab00fe9598909bb66164)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/audio/virtio-snd.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
+index 3437211f79..fc0781ae9a 100644
+--- a/hw/audio/virtio-snd.c
++++ b/hw/audio/virtio-snd.c
+@@ -1240,7 +1240,7 @@ static void virtio_snd_pcm_in_cb(void *data, int available)
+ {
+ VirtIOSoundPCMStream *stream = data;
+ VirtIOSoundPCMBuffer *buffer;
+- size_t size, max_size;
++ size_t size, max_size, to_read;
+
+ WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
+ while (!QSIMPLEQ_EMPTY(&stream->queue)) {
+@@ -1266,10 +1266,12 @@ static void virtio_snd_pcm_in_cb(void *data, int available)
+ return_rx_buffer(stream, buffer);
+ break;
+ }
++ to_read = stream->params.period_bytes - buffer->size;
++ to_read = MIN(to_read, available);
++ to_read = MIN(to_read, max_size - buffer->size);
+ size = AUD_read(stream->voice.in,
+- buffer->data + buffer->size,
+- MIN(available, (stream->params.period_bytes -
+- buffer->size)));
++ buffer->data + buffer->size,
++ to_read);
+ if (!size) {
+ available = 0;
+ break;
diff --git a/debian/patches/extra/0024-hw-misc-virt_ctrl-Fix-incorrect-trace-event-in-read-.patch b/debian/patches/extra/0024-hw-misc-virt_ctrl-Fix-incorrect-trace-event-in-read-.patch
new file mode 100644
index 0000000..fd41b73
--- /dev/null
+++ b/debian/patches/extra/0024-hw-misc-virt_ctrl-Fix-incorrect-trace-event-in-read-.patch
@@ -0,0 +1,41 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Kuan-Wei Chiu <visitorckw@gmail.com>
+Date: Sun, 11 Jan 2026 18:49:15 +0000
+Subject: [PATCH] hw/misc/virt_ctrl: Fix incorrect trace event in read
+ operation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The virt_ctrl_read() function currently invokes trace_virt_ctrl_write()
+instead of trace_virt_ctrl_read(). This results in read operations
+appearing as write operations in the trace output, which is misleading
+during debugging and analysis.
+
+Replace the incorrect trace call with the proper read-specific trace
+event to accurately reflect the hardware behavior.
+
+Fixes: 0791bc02b8fb ("m68k: add a system controller")
+Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Message-ID: <20260111184915.1363318-1-visitorckw@gmail.com>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+(cherry picked from commit 8608ed356ef90815cc5bcf04fcdbde987fd24bca)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/misc/virt_ctrl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/misc/virt_ctrl.c b/hw/misc/virt_ctrl.c
+index 9f16093ca2..7dc2fe4f94 100644
+--- a/hw/misc/virt_ctrl.c
++++ b/hw/misc/virt_ctrl.c
+@@ -43,7 +43,7 @@ static uint64_t virt_ctrl_read(void *opaque, hwaddr addr, unsigned size)
+ break;
+ }
+
+- trace_virt_ctrl_write(s, addr, size, value);
++ trace_virt_ctrl_read(s, addr, size, value);
+
+ return value;
+ }
diff --git a/debian/patches/extra/0025-target-i386-emulate-x86_decode-Actually-use-stream-i.patch b/debian/patches/extra/0025-target-i386-emulate-x86_decode-Actually-use-stream-i.patch
new file mode 100644
index 0000000..f66e6a2
--- /dev/null
+++ b/debian/patches/extra/0025-target-i386-emulate-x86_decode-Actually-use-stream-i.patch
@@ -0,0 +1,52 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Bernhard Beschow <shentey@gmail.com>
+Date: Tue, 24 Feb 2026 00:39:25 +0100
+Subject: [PATCH] target/i386/emulate/x86_decode: Actually use stream in
+ decode_instruction_stream()
+
+Compared to decode_instruction(), decode_instruction_stream() has an additional
+stream parameter which avoids some guest memory accesses during instruction
+decoding. Both functions defer the actual work to decode_opcode() which would
+set the stream pointer to zero such that decode_instruction_stream() essentially
+behaved like decode_instruction(). Given that all callers of
+decode_instruction_stream() properly zero-initialize the decode parameter, the
+memset() call can be moved into decode_instruction() which is the only other
+user of decode_opcode(). This preserves the non-zero stream pointer which
+avoids extra guest memory accesses.
+
+Fixes: 1e25327b244a ("target/i386/emulate: Allow instruction decoding from stream")
+cc: qemu-stable
+Signed-off-by: Bernhard Beschow <shentey@gmail.com>
+Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>
+Reviewed-by: Wei Liu (Microsoft) <wei.liu@kernel.org>
+Tested-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
+Link: https://lore.kernel.org/r/20260223233950.96076-4-mohamed@unpredictable.fr
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 1b93832f55927b1b76a6587ca75a5a35676188de)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ target/i386/emulate/x86_decode.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/target/i386/emulate/x86_decode.c b/target/i386/emulate/x86_decode.c
+index d037ed1142..a1122d2b27 100644
+--- a/target/i386/emulate/x86_decode.c
++++ b/target/i386/emulate/x86_decode.c
+@@ -2088,8 +2088,6 @@ static void decode_opcodes(CPUX86State *env, struct x86_decode *decode)
+
+ static uint32_t decode_opcode(CPUX86State *env, struct x86_decode *decode)
+ {
+- memset(decode, 0, sizeof(*decode));
+-
+ decode_prefix(env, decode);
+ set_addressing_size(env, decode);
+ set_operand_size(env, decode);
+@@ -2101,6 +2099,8 @@ static uint32_t decode_opcode(CPUX86State *env, struct x86_decode *decode)
+
+ uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
+ {
++ memset(decode, 0, sizeof(*decode));
++
+ return decode_opcode(env, decode);
+ }
+
diff --git a/debian/patches/extra/0026-io-separate-freeing-of-tasks-from-marking-them-as-co.patch b/debian/patches/extra/0026-io-separate-freeing-of-tasks-from-marking-them-as-co.patch
new file mode 100644
index 0000000..50ab81c
--- /dev/null
+++ b/debian/patches/extra/0026-io-separate-freeing-of-tasks-from-marking-them-as-co.patch
@@ -0,0 +1,258 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Tue, 6 Jan 2026 16:08:49 +0000
+Subject: [PATCH] io: separate freeing of tasks from marking them as complete
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The original design of QIOTask was intended to simplify lifecycle
+management by automatically freeing it when the task was marked as
+complete. This overlooked the fact that when a QIOTask is used in
+combination with a GSource, there may be times when the source
+callback is never invoked. This is typically when a GSource is
+released before any I/O event arrives. In such cases it is not
+desirable to mark a QIOTask as complete, but it still needs to be
+freed. To satisfy this, the task must be released manually.
+
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 163cd0ae1182e67509b271f244a73dfd938337b9)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ include/io/task.h | 29 +++++++++++++++++++++--------
+ io/channel-tls.c | 4 ++++
+ io/channel-websock.c | 3 +++
+ io/task.c | 8 ++++++--
+ tests/unit/test-io-task.c | 26 ++++++++++++++++++++++++++
+ 5 files changed, 60 insertions(+), 10 deletions(-)
+
+diff --git a/include/io/task.h b/include/io/task.h
+index 0b5342ee84..98847f5994 100644
+--- a/include/io/task.h
++++ b/include/io/task.h
+@@ -96,7 +96,7 @@ typedef void (*QIOTaskWorker)(QIOTask *task,
+ * 1000,
+ * myobject_operation_timer,
+ * task,
+- * NULL);
++ * qio_task_free);
+ * }
+ * </programlisting>
+ * </example>
+@@ -138,9 +138,8 @@ typedef void (*QIOTaskWorker)(QIOTask *task,
+ * the callback func 'myobject_operation_notify' shown
+ * earlier to deal with the results.
+ *
+- * Once this function returns false, object_unref will be called
+- * automatically on the task causing it to be released and the
+- * ref on QMyObject dropped too.
++ * Once this function returns FALSE, the task will be freed,
++ * causing it release the ref on QMyObject too.
+ *
+ * The QIOTask module can also be used to perform operations
+ * in a background thread context, while still reporting the
+@@ -208,8 +207,8 @@ typedef void (*QIOTaskWorker)(QIOTask *task,
+ * 'err' attribute in the task object to determine if
+ * the operation was successful or not.
+ *
+- * The returned task will be released when qio_task_complete()
+- * is invoked.
++ * The returned task must be released by calling
++ * qio_task_free() when no longer required.
+ *
+ * Returns: the task struct
+ */
+@@ -218,6 +217,19 @@ QIOTask *qio_task_new(Object *source,
+ gpointer opaque,
+ GDestroyNotify destroy);
+
++/**
++ * qio_task_free:
++ * task: the task object to free
++ *
++ * Free the resources associated with the task. Typically
++ * the qio_task_complete() method will be called immediately
++ * before this to trigger the task callback, however, it is
++ * permissible to free the task in the case of cancellation.
++ * The destroy callback will be used to release the opaque
++ * data provided to qio_task_new().
++ */
++void qio_task_free(QIOTask *task);
++
+ /**
+ * qio_task_run_in_thread:
+ * @task: the task struct
+@@ -268,8 +280,9 @@ void qio_task_wait_thread(QIOTask *task);
+ * qio_task_complete:
+ * @task: the task struct
+ *
+- * Invoke the completion callback for @task and
+- * then free its memory.
++ * Invoke the completion callback for @task. This should typically
++ * only be invoked once on a task, and then qio_task_free() used
++ * to free it.
+ */
+ void qio_task_complete(QIOTask *task);
+
+diff --git a/io/channel-tls.c b/io/channel-tls.c
+index b0cec27cb9..07274c12df 100644
+--- a/io/channel-tls.c
++++ b/io/channel-tls.c
+@@ -170,6 +170,7 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
+ trace_qio_channel_tls_handshake_fail(ioc);
+ qio_task_set_error(task, err);
+ qio_task_complete(task);
++ qio_task_free(task);
+ return;
+ }
+
+@@ -183,6 +184,7 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
+ trace_qio_channel_tls_credentials_allow(ioc);
+ }
+ qio_task_complete(task);
++ qio_task_free(task);
+ } else {
+ GIOCondition condition;
+ QIOChannelTLSData *data = g_new0(typeof(*data), 1);
+@@ -270,11 +272,13 @@ static void qio_channel_tls_bye_task(QIOChannelTLS *ioc, QIOTask *task,
+ trace_qio_channel_tls_bye_fail(ioc);
+ qio_task_set_error(task, err);
+ qio_task_complete(task);
++ qio_task_free(task);
+ return;
+ }
+
+ if (status == QCRYPTO_TLS_BYE_COMPLETE) {
+ qio_task_complete(task);
++ qio_task_free(task);
+ return;
+ }
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index cb4dafdebb..b4f96a0af4 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -545,6 +545,7 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
+ trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
+ qio_task_set_error(task, err);
+ qio_task_complete(task);
++ qio_task_free(task);
+ wioc->hs_io_tag = 0;
+ return FALSE;
+ }
+@@ -561,6 +562,7 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
+ trace_qio_channel_websock_handshake_complete(ioc);
+ qio_task_complete(task);
+ }
++ qio_task_free(task);
+ wioc->hs_io_tag = 0;
+ return FALSE;
+ }
+@@ -588,6 +590,7 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
+ trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
+ qio_task_set_error(task, err);
+ qio_task_complete(task);
++ qio_task_free(task);
+ wioc->hs_io_tag = 0;
+ return FALSE;
+ }
+diff --git a/io/task.c b/io/task.c
+index 451f26f8b4..331febd4e1 100644
+--- a/io/task.c
++++ b/io/task.c
+@@ -70,8 +70,12 @@ QIOTask *qio_task_new(Object *source,
+ return task;
+ }
+
+-static void qio_task_free(QIOTask *task)
++void qio_task_free(QIOTask *task)
+ {
++ if (!task) {
++ return;
++ }
++
+ qemu_mutex_lock(&task->thread_lock);
+ if (task->thread) {
+ if (task->thread->destroy) {
+@@ -110,6 +114,7 @@ static gboolean qio_task_thread_result(gpointer opaque)
+
+ trace_qio_task_thread_result(task);
+ qio_task_complete(task);
++ qio_task_free(task);
+
+ return FALSE;
+ }
+@@ -196,7 +201,6 @@ void qio_task_complete(QIOTask *task)
+ {
+ task->func(task, task->opaque);
+ trace_qio_task_complete(task);
+- qio_task_free(task);
+ }
+
+
+diff --git a/tests/unit/test-io-task.c b/tests/unit/test-io-task.c
+index 115dba8970..b1c8ecb7ab 100644
+--- a/tests/unit/test-io-task.c
++++ b/tests/unit/test-io-task.c
+@@ -73,6 +73,7 @@ static void test_task_complete(void)
+ src = qio_task_get_source(task);
+
+ qio_task_complete(task);
++ qio_task_free(task);
+
+ g_assert(obj == src);
+
+@@ -84,6 +85,28 @@ static void test_task_complete(void)
+ }
+
+
++static void test_task_cancel(void)
++{
++ QIOTask *task;
++ Object *obj = object_new(TYPE_DUMMY);
++ Object *src;
++ struct TestTaskData data = { NULL, NULL, false };
++
++ task = qio_task_new(obj, task_callback, &data, NULL);
++ src = qio_task_get_source(task);
++
++ qio_task_free(task);
++
++ g_assert(obj == src);
++
++ object_unref(obj);
++
++ g_assert(data.source == NULL);
++ g_assert(data.err == NULL);
++ g_assert(data.freed == false);
++}
++
++
+ static void task_data_free(gpointer opaque)
+ {
+ struct TestTaskData *data = opaque;
+@@ -101,6 +124,7 @@ static void test_task_data_free(void)
+ task = qio_task_new(obj, task_callback, &data, task_data_free);
+
+ qio_task_complete(task);
++ qio_task_free(task);
+
+ object_unref(obj);
+
+@@ -123,6 +147,7 @@ static void test_task_failure(void)
+
+ qio_task_set_error(task, err);
+ qio_task_complete(task);
++ qio_task_free(task);
+
+ object_unref(obj);
+
+@@ -260,6 +285,7 @@ int main(int argc, char **argv)
+ module_call_init(MODULE_INIT_QOM);
+ type_register_static(&dummy_info);
+ g_test_add_func("/crypto/task/complete", test_task_complete);
++ g_test_add_func("/crypto/task/cancel", test_task_cancel);
+ g_test_add_func("/crypto/task/datafree", test_task_data_free);
+ g_test_add_func("/crypto/task/failure", test_task_failure);
+ g_test_add_func("/crypto/task/thread_complete", test_task_thread_complete);
diff --git a/debian/patches/extra/0027-io-fix-cleanup-for-TLS-I-O-source-data-on-cancellati.patch b/debian/patches/extra/0027-io-fix-cleanup-for-TLS-I-O-source-data-on-cancellati.patch
new file mode 100644
index 0000000..9627d84
--- /dev/null
+++ b/debian/patches/extra/0027-io-fix-cleanup-for-TLS-I-O-source-data-on-cancellati.patch
@@ -0,0 +1,176 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Tue, 6 Jan 2026 13:45:10 +0000
+Subject: [PATCH] io: fix cleanup for TLS I/O source data on cancellation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The TLS code will create a GSource for tracking completion of the
+handshake process, passing a QIOChannelTLSData struct that contains
+various data items. The data struct is freed by the callback when
+it completes, which means when a source is cancelled, nothing is
+free'ing the data struct or its contents.
+
+Switch to provide a data free callback to the GSource, which ensures
+the QIOChannelTLSData struct is always freed even when the main event
+callback never fires.
+
+Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3114
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit d39d0f3acdd7c1bb275db7e97b511f98254ecd9f)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ io/channel-tls.c | 68 ++++++++++++++++++++++++++++++------------------
+ 1 file changed, 43 insertions(+), 25 deletions(-)
+
+diff --git a/io/channel-tls.c b/io/channel-tls.c
+index 07274c12df..940fc3c6d1 100644
+--- a/io/channel-tls.c
++++ b/io/channel-tls.c
+@@ -153,13 +153,32 @@ struct QIOChannelTLSData {
+ };
+ typedef struct QIOChannelTLSData QIOChannelTLSData;
+
++static void qio_channel_tls_io_data_free(gpointer user_data)
++{
++ QIOChannelTLSData *data = user_data;
++ /*
++ * Usually 'task' will be NULL since the GSource
++ * callback will either complete the task or pass
++ * it on to a new GSource. We'll see a non-NULL
++ * task here only if the GSource was released before
++ * its callback triggers
++ */
++ if (data->task) {
++ qio_task_free(data->task);
++ }
++ if (data->context) {
++ g_main_context_unref(data->context);
++ }
++ g_free(data);
++}
++
+ static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc,
+ GIOCondition condition,
+ gpointer user_data);
+
+-static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
+- QIOTask *task,
+- GMainContext *context)
++static gboolean qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
++ QIOTask *task,
++ GMainContext *context)
+ {
+ Error *err = NULL;
+ int status;
+@@ -170,8 +189,7 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
+ trace_qio_channel_tls_handshake_fail(ioc);
+ qio_task_set_error(task, err);
+ qio_task_complete(task);
+- qio_task_free(task);
+- return;
++ return TRUE;
+ }
+
+ if (status == QCRYPTO_TLS_HANDSHAKE_COMPLETE) {
+@@ -184,7 +202,7 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
+ trace_qio_channel_tls_credentials_allow(ioc);
+ }
+ qio_task_complete(task);
+- qio_task_free(task);
++ return TRUE;
+ } else {
+ GIOCondition condition;
+ QIOChannelTLSData *data = g_new0(typeof(*data), 1);
+@@ -208,8 +226,9 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
+ condition,
+ qio_channel_tls_handshake_io,
+ data,
+- NULL,
++ qio_channel_tls_io_data_free,
+ context);
++ return FALSE;
+ }
+ }
+
+@@ -225,11 +244,9 @@ static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc,
+ qio_task_get_source(task));
+
+ tioc->hs_ioc_tag = 0;
+- g_free(data);
+- qio_channel_tls_handshake_task(tioc, task, context);
+-
+- if (context) {
+- g_main_context_unref(context);
++ if (!qio_channel_tls_handshake_task(tioc, task, context)) {
++ /* task is kept by new GSource so must not be released yet */
++ data->task = NULL;
+ }
+
+ return FALSE;
+@@ -252,14 +269,16 @@ void qio_channel_tls_handshake(QIOChannelTLS *ioc,
+ func, opaque, destroy);
+
+ trace_qio_channel_tls_handshake_start(ioc);
+- qio_channel_tls_handshake_task(ioc, task, context);
++ if (qio_channel_tls_handshake_task(ioc, task, context)) {
++ qio_task_free(task);
++ }
+ }
+
+ static gboolean qio_channel_tls_bye_io(QIOChannel *ioc, GIOCondition condition,
+ gpointer user_data);
+
+-static void qio_channel_tls_bye_task(QIOChannelTLS *ioc, QIOTask *task,
+- GMainContext *context)
++static gboolean qio_channel_tls_bye_task(QIOChannelTLS *ioc, QIOTask *task,
++ GMainContext *context)
+ {
+ GIOCondition condition;
+ QIOChannelTLSData *data;
+@@ -272,14 +291,12 @@ static void qio_channel_tls_bye_task(QIOChannelTLS *ioc, QIOTask *task,
+ trace_qio_channel_tls_bye_fail(ioc);
+ qio_task_set_error(task, err);
+ qio_task_complete(task);
+- qio_task_free(task);
+- return;
++ return TRUE;
+ }
+
+ if (status == QCRYPTO_TLS_BYE_COMPLETE) {
+ qio_task_complete(task);
+- qio_task_free(task);
+- return;
++ return TRUE;
+ }
+
+ data = g_new0(typeof(*data), 1);
+@@ -299,7 +316,10 @@ static void qio_channel_tls_bye_task(QIOChannelTLS *ioc, QIOTask *task,
+ trace_qio_channel_tls_bye_pending(ioc, status);
+ ioc->bye_ioc_tag = qio_channel_add_watch_full(ioc->master, condition,
+ qio_channel_tls_bye_io,
+- data, NULL, context);
++ data,
++ qio_channel_tls_io_data_free,
++ context);
++ return FALSE;
+ }
+
+
+@@ -312,11 +332,9 @@ static gboolean qio_channel_tls_bye_io(QIOChannel *ioc, GIOCondition condition,
+ QIOChannelTLS *tioc = QIO_CHANNEL_TLS(qio_task_get_source(task));
+
+ tioc->bye_ioc_tag = 0;
+- g_free(data);
+- qio_channel_tls_bye_task(tioc, task, context);
+-
+- if (context) {
+- g_main_context_unref(context);
++ if (!qio_channel_tls_bye_task(tioc, task, context)) {
++ /* task is kept by new GSource so must not be released yet */
++ data->task = NULL;
+ }
+
+ return FALSE;
diff --git a/debian/patches/extra/0028-io-fix-cleanup-for-websock-I-O-source-data-on-cancel.patch b/debian/patches/extra/0028-io-fix-cleanup-for-websock-I-O-source-data-on-cancel.patch
new file mode 100644
index 0000000..2604d55
--- /dev/null
+++ b/debian/patches/extra/0028-io-fix-cleanup-for-websock-I-O-source-data-on-cancel.patch
@@ -0,0 +1,143 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Tue, 6 Jan 2026 13:45:10 +0000
+Subject: [PATCH] io: fix cleanup for websock I/O source data on cancellation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The websock code will create a GSource for tracking completion of the
+handshake process, passing a QIOTask which is freed by the callback
+when it completes, which means when a source is cancelled, nothing is
+free'ing the task.
+
+Switch to provide a data free callback to the GSource, which ensures
+the QIOTask is always freed even when the main event callback never
+fires.
+
+Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3114
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 9545c059f77e3f814fcbaba83203572ea655c50e)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ io/channel-websock.c | 49 +++++++++++++++++++++++++++++++-------------
+ 1 file changed, 35 insertions(+), 14 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index b4f96a0af4..bb10bc4f7f 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -526,11 +526,32 @@ static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc,
+ return 1;
+ }
+
++typedef struct QIOChannelWebsockData {
++ QIOTask *task;
++} QIOChannelWebsockData;
++
++static void qio_channel_websock_data_free(gpointer user_data)
++{
++ QIOChannelWebsockData *data = user_data;
++ /*
++ * Usually 'task' will be NULL since the GSource
++ * callback will either complete the task or pass
++ * it on to a new GSource. We'll see a non-NULL
++ * task here only if the GSource was released before
++ * its callback triggers
++ */
++ if (data->task) {
++ qio_task_free(data->task);
++ }
++ g_free(data);
++}
++
+ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
+ GIOCondition condition,
+ gpointer user_data)
+ {
+- QIOTask *task = user_data;
++ QIOChannelWebsockData *data = user_data;
++ QIOTask *task = data->task;
+ QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(
+ qio_task_get_source(task));
+ Error *err = NULL;
+@@ -545,7 +566,6 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
+ trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
+ qio_task_set_error(task, err);
+ qio_task_complete(task);
+- qio_task_free(task);
+ wioc->hs_io_tag = 0;
+ return FALSE;
+ }
+@@ -562,7 +582,6 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
+ trace_qio_channel_websock_handshake_complete(ioc);
+ qio_task_complete(task);
+ }
+- qio_task_free(task);
+ wioc->hs_io_tag = 0;
+ return FALSE;
+ }
+@@ -574,7 +593,8 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
+ GIOCondition condition,
+ gpointer user_data)
+ {
+- QIOTask *task = user_data;
++ QIOChannelWebsockData *data = user_data, *newdata = NULL;
++ QIOTask *task = data->task;
+ QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(
+ qio_task_get_source(task));
+ Error *err = NULL;
+@@ -590,7 +610,6 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
+ trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
+ qio_task_set_error(task, err);
+ qio_task_complete(task);
+- qio_task_free(task);
+ wioc->hs_io_tag = 0;
+ return FALSE;
+ }
+@@ -603,12 +622,14 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
+ error_propagate(&wioc->io_err, err);
+
+ trace_qio_channel_websock_handshake_reply(ioc);
++ newdata = g_new0(QIOChannelWebsockData, 1);
++ newdata->task = g_steal_pointer(&data->task);
+ wioc->hs_io_tag = qio_channel_add_watch(
+ wioc->master,
+ G_IO_OUT,
+ qio_channel_websock_handshake_send,
+- task,
+- NULL);
++ newdata,
++ qio_channel_websock_data_free);
+ return FALSE;
+ }
+
+@@ -904,12 +925,12 @@ void qio_channel_websock_handshake(QIOChannelWebsock *ioc,
+ gpointer opaque,
+ GDestroyNotify destroy)
+ {
+- QIOTask *task;
++ QIOChannelWebsockData *data = g_new0(QIOChannelWebsockData, 1);
+
+- task = qio_task_new(OBJECT(ioc),
+- func,
+- opaque,
+- destroy);
++ data->task = qio_task_new(OBJECT(ioc),
++ func,
++ opaque,
++ destroy);
+
+ trace_qio_channel_websock_handshake_start(ioc);
+ trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN);
+@@ -917,8 +938,8 @@ void qio_channel_websock_handshake(QIOChannelWebsock *ioc,
+ ioc->master,
+ G_IO_IN,
+ qio_channel_websock_handshake_io,
+- task,
+- NULL);
++ data,
++ qio_channel_websock_data_free);
+ }
+
+
diff --git a/debian/patches/extra/0029-hw-Make-qdev_get_printable_name-consistently-return-.patch b/debian/patches/extra/0029-hw-Make-qdev_get_printable_name-consistently-return-.patch
new file mode 100644
index 0000000..50438b0
--- /dev/null
+++ b/debian/patches/extra/0029-hw-Make-qdev_get_printable_name-consistently-return-.patch
@@ -0,0 +1,142 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Maydell <peter.maydell@linaro.org>
+Date: Sat, 7 Mar 2026 15:50:46 +0000
+Subject: [PATCH] hw: Make qdev_get_printable_name() consistently return
+ freeable string
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The current implementation of qdev_get_printable_name() sometimes
+returns a string that must not be freed (vdev->id or the fixed
+fallback string "<unknown device>" and sometimes returns a string
+that must be freed (the return value of qdev_get_dev_path()). This
+forces callers to leak the string in the "must be freed" case.
+
+Make the function consistent that it always returns a string that
+the caller must free, and make the three callsites free it.
+
+This fixes leaks like this that show up when running "make check"
+with the address sanitizer enabled:
+
+Direct leak of 13 byte(s) in 1 object(s) allocated from:
+ #0 0x5561de21f293 in malloc (/home/pm215/qemu/build/san/qemu-system-i386+0x1a2d293) (BuildId: 6d6fad7130fd5c8dbbc03401df554f68b8034936)
+ #1 0x767ad7a82ac9 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62ac9) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
+ #2 0x5561deaf34f2 in pcibus_get_dev_path /home/pm215/qemu/build/san/../../hw/pci/pci.c:2792:12
+ #3 0x5561df9d8830 in qdev_get_printable_name /home/pm215/qemu/build/san/../../hw/core/qdev.c:431:24
+ #4 0x5561deebdca2 in virtio_init_region_cache /home/pm215/qemu/build/san/../../hw/virtio/virtio.c:298:17
+ #5 0x5561df05f842 in memory_region_write_accessor /home/pm215/qemu/build/san/../../system/memory.c:491:5
+ #6 0x5561df05ed1b in access_with_adjusted_size /home/pm215/qemu/build/san/../../system/memory.c:567:18
+ #7 0x5561df05e3fa in memory_region_dispatch_write /home/pm215/qemu/build/san/../../system/memory.c
+ #8 0x5561df0aa805 in address_space_stm_internal /home/pm215/qemu/build/san/../../system/memory_ldst.c.inc:85:13
+ #9 0x5561df0bcad3 in qtest_process_command /home/pm215/qemu/build/san/../../system/qtest.c:480:13
+
+Cc: qemu-stable@nongnu.org
+Fixes: e209d4d7a31b9 ("virtio: improve virtqueue mapping error messages")
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Message-ID: <20260307155046.3940197-3-peter.maydell@linaro.org>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+(cherry picked from commit 1e3e1d51e20e8b38efa089bf54b5ee2cbbcca221)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/core/qdev.c | 4 ++--
+ hw/virtio/virtio.c | 12 +++++++++---
+ include/hw/qdev-core.h | 16 ++++++++++++++++
+ 3 files changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/hw/core/qdev.c b/hw/core/qdev.c
+index fab42a7270..ce0ee9fcef 100644
+--- a/hw/core/qdev.c
++++ b/hw/core/qdev.c
+@@ -420,7 +420,7 @@ const char *qdev_get_printable_name(DeviceState *vdev)
+ * names.
+ */
+ if (vdev->id) {
+- return vdev->id;
++ return g_strdup(vdev->id);
+ }
+ /*
+ * Fall back to the canonical QOM device path (eg. ID for PCI
+@@ -437,7 +437,7 @@ const char *qdev_get_printable_name(DeviceState *vdev)
+ * Final fallback: if all else fails, return a placeholder string.
+ * This ensures the error message always contains a valid string.
+ */
+- return "<unknown device>";
++ return g_strdup("<unknown device>");
+ }
+
+ void qdev_add_unplug_blocker(DeviceState *dev, Error *reason)
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 683026adc4..deb7c6695e 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -258,10 +258,12 @@ void virtio_init_region_cache(VirtIODevice *vdev, int n)
+ len = address_space_cache_init(&new->desc, vdev->dma_as,
+ addr, size, packed);
+ if (len < size) {
++ g_autofree const char *devname = qdev_get_printable_name(DEVICE(vdev));
++
+ virtio_error(vdev,
+ "Failed to map descriptor ring for device %s: "
+ "invalid guest physical address or corrupted queue setup",
+- qdev_get_printable_name(DEVICE(vdev)));
++ devname);
+ goto err_desc;
+ }
+
+@@ -269,10 +271,12 @@ void virtio_init_region_cache(VirtIODevice *vdev, int n)
+ len = address_space_cache_init(&new->used, vdev->dma_as,
+ vq->vring.used, size, true);
+ if (len < size) {
++ g_autofree const char *devname = qdev_get_printable_name(DEVICE(vdev));
++
+ virtio_error(vdev,
+ "Failed to map used ring for device %s: "
+ "possible guest misconfiguration or insufficient memory",
+- qdev_get_printable_name(DEVICE(vdev)));
++ devname);
+ goto err_used;
+ }
+
+@@ -280,10 +284,12 @@ void virtio_init_region_cache(VirtIODevice *vdev, int n)
+ len = address_space_cache_init(&new->avail, vdev->dma_as,
+ vq->vring.avail, size, false);
+ if (len < size) {
++ g_autofree const char *devname = qdev_get_printable_name(DEVICE(vdev));
++
+ virtio_error(vdev,
+ "Failed to map avalaible ring for device %s: "
+ "possible queue misconfiguration or overlapping memory region",
+- qdev_get_printable_name(DEVICE(vdev)));
++ devname);
+ goto err_avail;
+ }
+
+diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
+index 2caa0cbd26..774329bba9 100644
+--- a/include/hw/qdev-core.h
++++ b/include/hw/qdev-core.h
+@@ -1065,6 +1065,22 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp);
+ extern bool qdev_hot_removed;
+
+ char *qdev_get_dev_path(DeviceState *dev);
++
++/**
++ * qdev_get_printable_name: Return human readable name for device
++ * @dev: Device to get name of
++ *
++ * Returns: A newly allocated string containing some human
++ * readable name for the device, suitable for printing in
++ * user-facing error messages. The function will never return NULL,
++ * so the name can be used without further checking or fallbacks.
++ *
++ * If the device has an explicitly set ID (e.g. by the user on the
++ * command line via "-device thisdev,id=myid") this is preferred.
++ * Otherwise we try the canonical QOM device path (which will be
++ * the PCI ID for PCI devices, for example). If all else fails
++ * we will return the placeholder "<unknown device">.
++ */
+ const char *qdev_get_printable_name(DeviceState *dev);
+
+ void qbus_set_hotplug_handler(BusState *bus, Object *handler);
diff --git a/debian/patches/extra/0030-fuse-Copy-write-buffer-content-before-polling.patch b/debian/patches/extra/0030-fuse-Copy-write-buffer-content-before-polling.patch
new file mode 100644
index 0000000..9b760f7
--- /dev/null
+++ b/debian/patches/extra/0030-fuse-Copy-write-buffer-content-before-polling.patch
@@ -0,0 +1,114 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Hanna Czenczek <hreitz@redhat.com>
+Date: Mon, 9 Mar 2026 16:08:32 +0100
+Subject: [PATCH] fuse: Copy write buffer content before polling
+
+aio_poll() in I/O functions can lead to nested read_from_fuse_export()
+calls, overwriting the request buffer's content. The only function
+affected by this is fuse_write(), which therefore must use a bounce
+buffer or corruption may occur.
+
+Note that in addition we do not know whether libfuse-internal structures
+can cope with this nesting, and even if we did, we probably cannot rely
+on it in the future. This is the main reason why we want to remove
+libfuse from the I/O path.
+
+I do not have a good reproducer for this other than:
+
+$ dd if=/dev/urandom of=image bs=1M count=4096
+$ dd if=/dev/zero of=copy bs=1M count=4096
+$ touch fuse-export
+$ qemu-storage-daemon \
+ --blockdev file,node-name=file,filename=copy \
+ --export \
+ fuse,id=exp,node-name=file,mountpoint=fuse-export,writable=true \
+ &
+
+Other shell:
+$ qemu-img convert -p -n -f raw -O raw -t none image fuse-export
+$ killall -SIGINT qemu-storage-daemon
+$ qemu-img compare image copy
+Content mismatch at offset 0!
+
+(The -t none in qemu-img convert is important.)
+
+I tried reproducing this with throttle and small aio_write requests from
+another qemu-io instance, but for some reason all requests are perfectly
+serialized then.
+
+I think in theory we should get parallel writes only if we set
+fi->parallel_direct_writes in fuse_open(). In fact, I can confirm that
+if we do that, that throttle-based reproducer works (i.e. does get
+parallel (nested) write requests). I have no idea why we still get
+parallel requests with qemu-img convert anyway.
+
+Also, a later patch in this series will set fi->parallel_direct_writes
+and note that it makes basically no difference when running fio on the
+current libfuse-based version of our code. It does make a difference
+without libfuse. So something quite fishy is going on.
+
+I will try to investigate further what the root cause is, but I think
+for now let's assume that calling blk_pwrite() can invalidate the buffer
+contents through nested polling.
+
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
+Message-ID: <20260309150856.26800-2-hreitz@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit a3fcbca0ef643a8aecf354bdeb08b1d81e5b33e7)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ block/export/fuse.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/block/export/fuse.c b/block/export/fuse.c
+index 465cc9891d..aec4d8736d 100644
+--- a/block/export/fuse.c
++++ b/block/export/fuse.c
+@@ -301,6 +301,12 @@ static void read_from_fuse_export(void *opaque)
+ goto out;
+ }
+
++ /*
++ * Note that aio_poll() in any request-processing function can lead to a
++ * nested read_from_fuse_export() call, which will overwrite the contents of
++ * exp->fuse_buf. Anything that takes a buffer needs to take care that the
++ * content is copied before potentially polling via aio_poll().
++ */
+ fuse_session_process_buf(exp->fuse_session, &exp->fuse_buf);
+
+ out:
+@@ -624,6 +630,7 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf,
+ size_t size, off_t offset, struct fuse_file_info *fi)
+ {
+ FuseExport *exp = fuse_req_userdata(req);
++ QEMU_AUTO_VFREE void *copied = NULL;
+ int64_t length;
+ int ret;
+
+@@ -638,6 +645,14 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf,
+ return;
+ }
+
++ /*
++ * Heed the note on read_from_fuse_export(): If we call aio_poll() (which
++ * any blk_*() I/O function may do), read_from_fuse_export() may be nested,
++ * overwriting the request buffer content. Therefore, we must copy it here.
++ */
++ copied = blk_blockalign(exp->common.blk, size);
++ memcpy(copied, buf, size);
++
+ /**
+ * Clients will expect short writes at EOF, so we have to limit
+ * offset+size to the image length.
+@@ -660,7 +675,7 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf,
+ }
+ }
+
+- ret = blk_pwrite(exp->common.blk, offset, size, buf, 0);
++ ret = blk_pwrite(exp->common.blk, offset, size, copied, 0);
+ if (ret >= 0) {
+ fuse_reply_write(req, size);
+ } else {
diff --git a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
index b4e1b2f..09e94e8 100644
--- a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
+++ b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
@@ -10,10 +10,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
-index cee1f692a1..6f49be3796 100644
+index ee3ed5ae6d..9d69d76f69 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
-@@ -2641,9 +2641,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
+@@ -2642,9 +2642,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
#define CPU_RESOLVING_TYPE TYPE_X86_CPU
#ifdef TARGET_X86_64
diff --git a/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch b/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
index b353177..e3f8ab8 100644
--- a/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
+++ b/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
@@ -247,7 +247,7 @@ index 0000000000..036edb17f5
+
+block_init(bdrv_zeroinit_init);
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 64f2befdf5..19b60e3a96 100644
+index d4a5765dc4..476b9c011e 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3376,7 +3376,7 @@
diff --git a/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch b/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
index 2f70373..2cae103 100644
--- a/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
+++ b/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
@@ -119,7 +119,7 @@ index 41ac3f222f..612942a222 100644
};
return raw_co_create(&options, errp);
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 19b60e3a96..029b8f2b51 100644
+index 476b9c011e..bddc97d494 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -5153,6 +5153,10 @@
diff --git a/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch b/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch
index a56fc83..0f97bdd 100644
--- a/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch
+++ b/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch
@@ -1688,7 +1688,7 @@ index 0000000000..177fb851b4
+ return ret;
+}
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 029b8f2b51..75406f4215 100644
+index bddc97d494..693a123e94 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -947,6 +947,248 @@
diff --git a/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch b/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
index 00fef7e..8995604 100644
--- a/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
+++ b/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
@@ -361,7 +361,7 @@ index 73f6e2e93b..b717cad2f9 100644
summary_info += {'libdaxctl support': libdaxctl}
summary_info += {'libcbor support': libcbor}
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 75406f4215..f998aafc49 100644
+index 693a123e94..e0f44067e0 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3614,6 +3614,7 @@
diff --git a/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch b/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
index 2c3c25f..09565fe 100644
--- a/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
+++ b/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
@@ -192,7 +192,7 @@ index 177fb851b4..7575abab7c 100644
ret->pbs_masterkey = true;
ret->backup_max_workers = true;
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index f998aafc49..5b3bb3c19e 100644
+index e0f44067e0..f1679264bb 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1107,6 +1107,11 @@
diff --git a/debian/patches/pve/0038-block-add-alloc-track-driver.patch b/debian/patches/pve/0038-block-add-alloc-track-driver.patch
index de886e2..cb3c9ae 100644
--- a/debian/patches/pve/0038-block-add-alloc-track-driver.patch
+++ b/debian/patches/pve/0038-block-add-alloc-track-driver.patch
@@ -449,7 +449,7 @@ index d023753091..a777c8079c 100644
out:
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 5b3bb3c19e..1d98f0a406 100644
+index f1679264bb..6d8c2df22b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3606,7 +3606,8 @@
diff --git a/debian/patches/pve/0039-PVE-backup-add-fleecing-option.patch b/debian/patches/pve/0039-PVE-backup-add-fleecing-option.patch
index 50021c5..c9d4d39 100644
--- a/debian/patches/pve/0039-PVE-backup-add-fleecing-option.patch
+++ b/debian/patches/pve/0039-PVE-backup-add-fleecing-option.patch
@@ -429,7 +429,7 @@ index 7575abab7c..8b83465ebd 100644
return ret;
}
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 1d98f0a406..db0a5a1266 100644
+index 6d8c2df22b..ea73974495 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1049,6 +1049,10 @@
diff --git a/debian/patches/pve/0045-PVE-backup-implement-backup-access-setup-and-teardow.patch b/debian/patches/pve/0045-PVE-backup-implement-backup-access-setup-and-teardow.patch
index 8bdbf11..f4ec604 100644
--- a/debian/patches/pve/0045-PVE-backup-implement-backup-access-setup-and-teardow.patch
+++ b/debian/patches/pve/0045-PVE-backup-implement-backup-access-setup-and-teardow.patch
@@ -740,7 +740,7 @@ index 0000000000..9ebeef7c8f
+
+#endif /* PVE_BACKUP_H */
diff --git a/qapi/block-core.json b/qapi/block-core.json
-index db0a5a1266..94296c0bc9 100644
+index ea73974495..52b750dbb3 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1123,6 +1123,9 @@
diff --git a/debian/patches/pve/0047-savevm-async-reuse-migration-blocker-check-for-snaps.patch b/debian/patches/pve/0047-savevm-async-reuse-migration-blocker-check-for-snaps.patch
index 18db6fa..d0c7868 100644
--- a/debian/patches/pve/0047-savevm-async-reuse-migration-blocker-check-for-snaps.patch
+++ b/debian/patches/pve/0047-savevm-async-reuse-migration-blocker-check-for-snaps.patch
@@ -61,7 +61,7 @@ Message-ID: <20250618102531.57444-1-f.ebner@proxmox.com>
5 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/block/vmdk.c b/block/vmdk.c
-index 89e89cd10e..06df10a799 100644
+index cd8b4ec7c8..1f64ab1766 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1404,9 +1404,7 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
diff --git a/debian/patches/series b/debian/patches/series
index 7c8e26c..8ed0c52 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,6 +2,32 @@ extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
extra/0002-ide-avoid-potential-deadlock-when-draining-during-tr.patch
extra/0003-block-mirror-check-range-when-setting-zero-bitmap-fo.patch
extra/0004-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch
+extra/0005-block-vmdk-fix-OOB-read-in-vmdk_read_extent.patch
+extra/0006-block-throttle-groups-fix-deadlock-with-iolimits-and.patch
+extra/0007-block-Never-drop-BLOCK_IO_ERROR-with-action-stop-for.patch
+extra/0008-mirror-Fix-missed-dirty-bitmap-writes-during-startup.patch
+extra/0009-virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch
+extra/0010-virtio-gpu-Ensure-BHs-are-invoked-only-from-main-loo.patch
+extra/0011-hw-i2c-aspeed_i2c-Fix-out-of-bounds-read-in-I2C-MMIO.patch
+extra/0012-target-arm-Account-for-SME-in-aarch64_sve_narrow_vq-.patch
+extra/0013-target-arm-Fix-feature-check-in-DO_SVE2_RRX-DO_SVE2_.patch
+extra/0014-target-arm-tcg-Allow-SVE-RAX1-in-SME2p1-streaming-mo.patch
+extra/0015-target-arm-Don-t-let-sme-on-downgrade-SME.patch
+extra/0016-target-arm-set-the-correct-TI-bits-for-WFIT-traps.patch
+extra/0017-aio-posix-notify-main-loop-when-SQEs-are-queued.patch
+extra/0018-fdmon-io_uring-check-CQ-ring-directly-in-gsource_che.patch
+extra/0019-target-i386-add-compat-for-migrating-error-code.patch
+extra/0020-virtio-snd-remove-TODO-comments.patch
+extra/0021-virtio-snd-handle-5.14.6.2-for-PCM_INFO-properly.patch
+extra/0022-virtio-snd-fix-max_size-bounds-check-in-input-cb.patch
+extra/0023-virtio-snd-tighten-read-amount-in-in_cb.patch
+extra/0024-hw-misc-virt_ctrl-Fix-incorrect-trace-event-in-read-.patch
+extra/0025-target-i386-emulate-x86_decode-Actually-use-stream-i.patch
+extra/0026-io-separate-freeing-of-tasks-from-marking-them-as-co.patch
+extra/0027-io-fix-cleanup-for-TLS-I-O-source-data-on-cancellati.patch
+extra/0028-io-fix-cleanup-for-websock-I-O-source-data-on-cancel.patch
+extra/0029-hw-Make-qdev_get_printable_name-consistently-return-.patch
+extra/0030-fuse-Copy-write-buffer-content-before-polling.patch
bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch
bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread