all lists on 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal