public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH-SERIES qemu 0/2] QEMU 10.2.1
@ 2026-03-12 11:44 Fiona Ebner
  2026-03-12 11:44 ` [PATCH qemu 1/2] update submodule and patches to " Fiona Ebner
  2026-03-12 11:44 ` [PATCH qemu 2/2] stable fixes for " Fiona Ebner
  0 siblings, 2 replies; 3+ messages in thread
From: Fiona Ebner @ 2026-03-12 11:44 UTC (permalink / raw)
  To: pve-devel

See the individual patches for details.

Fiona Ebner (2):
  update submodule and patches to QEMU 10.2.1
  stable fixes for QEMU 10.2.1

 debian/cpu-models-aarch64.json                |   1 +
 ...d-support-for-sync-bitmap-mode-never.patch |  78 +++---
 ...-support-for-conditional-and-always-.patch |  10 +-
 ...check-for-bitmap-mode-without-bitmap.patch |   4 +-
 ...-to-bdrv_dirty_bitmap_merge_internal.patch |   6 +-
 .../0006-mirror-move-some-checks-to-qmp.patch |   8 +-
 ...race-with-clients-disconnecting-earl.patch |   4 +-
 ...ial-deadlock-when-draining-during-tr.patch |   2 +-
 ...k-range-when-setting-zero-bitmap-fo.patch} |   7 +-
 .../extra/0003-tcg-arm-Fix-tgen_deposit.patch |  37 ---
 ...-to-bounce-buffer-if-BLKZEROOUT-is-.patch} |   2 +-
 ...quirks-when-IGD-is-not-the-primary-d.patch |  79 ------
 ...mdk-fix-OOB-read-in-vmdk_read_extent.patch |  38 +++
 ...adlock-upon-TMF-request-cancelling-w.patch |  83 ------
 ...roups-fix-deadlock-with-iolimits-and.patch | 133 +++++++++
 ...-rename-field-to-num_initial_regions.patch | 245 -----------------
 ...-BLOCK_IO_ERROR-with-action-stop-for.patch |  88 ++++++
 ...region-info-cache-for-initial-region.patch |  75 -----
 ...d-dirty-bitmap-writes-during-startup.patch | 152 +++++++++++
 ...vdagent-fix-windows-agent-regression.patch | 105 -------
 ...six-populate-pwrite_zeroes_alignment.patch |  49 ----
 ...-Add-virtio-gpu-virgl-hostmem-region.patch | 174 ++++++++++++
 ..._zeroes_alignment-when-writing-first.patch |  86 ------
 ...e-BHs-are-invoked-only-from-main-loo.patch | 123 +++++++++
 ...void-potentially-getting-stuck-after.patch | 153 -----------
 ...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 +++++
 ...0020-virtio-snd-remove-TODO-comments.patch |  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 ++++++++
 ...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                         |  39 ++-
 qemu                                          |   2 +-
 85 files changed, 3002 insertions(+), 1291 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} (88%)
 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
 create mode 100644 debian/patches/extra/0005-block-vmdk-fix-OOB-read-in-vmdk_read_extent.patch
 delete mode 100644 debian/patches/extra/0005-hw-scsi-avoid-deadlock-upon-TMF-request-cancelling-w.patch
 create mode 100644 debian/patches/extra/0006-block-throttle-groups-fix-deadlock-with-iolimits-and.patch
 delete mode 100644 debian/patches/extra/0006-vfio-rename-field-to-num_initial_regions.patch
 create mode 100644 debian/patches/extra/0007-block-Never-drop-BLOCK_IO_ERROR-with-action-stop-for.patch
 delete mode 100644 debian/patches/extra/0007-vfio-only-check-region-info-cache-for-initial-region.patch
 create mode 100644 debian/patches/extra/0008-mirror-Fix-missed-dirty-bitmap-writes-during-startup.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
 create mode 100644 debian/patches/extra/0009-virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch
 delete mode 100644 debian/patches/extra/0010-block-use-pwrite_zeroes_alignment-when-writing-first.patch
 create mode 100644 debian/patches/extra/0010-virtio-gpu-Ensure-BHs-are-invoked-only-from-main-loo.patch
 delete mode 100644 debian/patches/extra/0011-block-io_uring-avoid-potentially-getting-stuck-after.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

-- 
2.47.3





^ permalink raw reply	[flat|nested] 3+ messages in thread

* [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
 .../extra/0003-tcg-arm-Fix-tgen_deposit.patch |  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 +++++
 ...0020-virtio-snd-remove-TODO-comments.patch |  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 = {
diff --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

end of thread, other threads:[~2026-03-12 12:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH qemu 2/2] stable fixes for " Fiona Ebner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal