public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0
@ 2023-05-15 13:39 Fiona Ebner
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 1/7] d/rules: drop virtiofsd switch Fiona Ebner
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: Fiona Ebner @ 2023-05-15 13:39 UTC (permalink / raw)
  To: pve-devel

After weeks and weeks of (sometimes painful) debugging, it's finally
here. And got a load of stable fixes on top already. More testing is
always appreciated, especially backup, PBS live restore and snapshots,
which needed quite a few changes!

Changes from v1:
* Add fix for lintian overrides.
* Add patch squashing related changes (not required for 8.0 but will
make life easier going forward).

Fiona Ebner (7):
  d/rules: drop virtiofsd switch
  d/rules: set job flag for make based on DEB_BUILD_OPTIONS
  buildsys: fix lintian overrides
  update submodule and patches to QEMU 8.0.0
  add stable patches for 8.0.0
  PVE backup: don't call no_co_wrapper function from coroutine
  squash related patches

 ...d-support-for-sync-bitmap-mode-never.patch |   95 +-
 ...-support-for-conditional-and-always-.patch |   10 +-
 ...check-for-bitmap-mode-without-bitmap.patch |    6 +-
 ...-to-bdrv_dirty_bitmap_merge_internal.patch |    6 +-
 .../0006-mirror-move-some-checks-to-qmp.patch |   14 +-
 ...race-with-clients-disconnecting-earl.patch |    6 +-
 ...monize-defuse-PID-file-resolve-error.patch |   42 -
 ...memory-prevent-dma-reentracy-issues.patch} |    4 +-
 ...s-Internal-cdbs-have-16-byte-length.patch} |    0
 ...he-bitmap-index-of-the-section-offse.patch |   44 -
 ...al-deadlock-when-draining-during-tr.patch} |   10 +-
 ...he-iterator-variable-in-a-vmem-rdl_l.patch |   36 -
 ...sabling-re-entrancy-checking-per-MR.patch} |    6 +-
 ...ty-bitmap-syncing-when-vIOMMU-is-ena.patch |  141 --
 ...e-reentrancy-detection-for-script-R.patch} |    2 +-
 ...pci-fix-migration-compat-for-vectors.patch |   42 -
 ...-zeroes-with-BDRV_REQ_REGISTERED_BUF.patch |   36 -
 ...39-fix-large_send_mss-divide-by-zero.patch |   72 +
 ...-Fix-crash-when-executing-HMP-commit.patch |   48 +
 ...double-free-on-BUSY-or-similar-statu.patch |   32 -
 ...hen-getting-cursor-without-a-console.patch |   36 +
 ...our-channel-order-for-PNG-screenshot.patch |   77 ++
 ...arm-Fix-vd-vm-overlap-in-sve_ldff1_z.patch |   41 +
 ...ing-endian-conversions-for-doorbell-.patch |   67 -
 ...e-incorrect-computation-in-float32_e.patch |   56 +
 ...fix-field-corruption-in-type-4-table.patch |   50 -
 ...ge-wrong-XFRM-value-in-SGX-CPUID-lea.patch |   39 +
 ...t-assert_bdrv_graph_readable-by-defa.patch |  106 ++
 ...ix-transitional-migration-compat-for.patch |   35 -
 ...CI_ERR_UNCOR_MASK-register-for-machi.patch |  100 ++
 ...er-hpet-Fix-expiration-time-overflow.patch |   80 --
 ...after-free-in-blockdev_mark_auto_del.patch |   57 +
 ...vdpa-stop-all-svq-on-device-deletion.patch |   71 -
 ...ly-call-bdrv_activate-outside-corout.patch |   64 +
 ...tential-use-of-an-uninitialized-vari.patch |  132 --
 ...o_unref-for-calls-in-coroutine-conte.patch |  373 +++++
 ...ket-set-s-listener-NULL-in-char_sock.patch |   70 -
 ...-no_coroutine_fns-in-qmp_block_resiz.patch |   43 +
 ...il-MAP-notifier-without-caching-mode.patch |   41 -
 ...-tcg-Fix-atomic_mmu_lookup-for-reads.patch |   36 +
 ...-fail-DEVIOTLB_UNMAP-without-dt-mode.patch |   50 -
 ...uest-visible-maximum-access-size-to-.patch |  166 ---
 ...Introduce-and-use-reg_t-consistently.patch |  286 ----
 ...25-target-i386-Fix-BEXTR-instruction.patch |   97 --
 ...i386-Fix-C-flag-for-BLSI-BLSMSK-BLSR.patch |   47 -
 ...arget-i386-fix-ADOX-followed-by-ADCX.patch |  192 ---
 ...028-target-i386-Fix-BZHI-instruction.patch |   64 -
 ...k-file-change-locking-default-to-off.patch |    6 +-
 ...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 |    8 +-
 ...lock-rbd-disable-rbd_cache_writethro.patch |    4 +-
 .../0007-PVE-Up-qmp-add-get_link_status.patch |    8 +-
 ...PVE-Up-glusterfs-allow-partial-reads.patch |   14 +-
 ...return-success-on-info-without-snaps.patch |    4 +-
 ...dd-add-osize-and-read-from-to-stdin-.patch |   12 +-
 ...E-Up-qemu-img-dd-add-isize-parameter.patch |   14 +-
 ...PVE-Up-qemu-img-dd-add-n-skip_create.patch |   10 +-
 ...add-l-option-for-loading-a-snapshot.patch} |   18 +-
 ...irtio-balloon-improve-query-balloon.patch} |   95 +-
 ...0015-PVE-qapi-modify-query-machines.patch} |   14 +-
 ...=> 0016-PVE-qapi-modify-spice-query.patch} |   13 +-
 ...nel-implementation-for-savevm-async.patch} |   11 +-
 ...sync-for-background-state-snapshots.patch} |  125 +-
 ...dd-optional-buffer-size-to-QEMUFile.patch} |   10 +-
 ...dd-the-zeroinit-block-driver-filter.patch} |   30 +-
 ...Add-dummy-id-command-line-parameter.patch} |   10 +-
 ...-target-i386-disable-LINT0-after-re.patch} |    4 +-
 ...e-posix-make-locking-optiono-on-cre.patch} |   18 +-
 ...-PVE-monitor-disable-oob-capability.patch} |    0
 ...ed-balloon-qemu-4-0-config-size-fal.patch} |    4 +-
 ...-Allow-version-code-in-machine-type.patch} |   31 +-
 ...-bcs-bitmap-initialization-to-job-c.patch} |    4 +-
 ...E-Backup-add-vma-backup-format-code.patch} |  277 ++--
 ...Backup-add-backup-dump-block-driver.patch} |   39 +-
 ...-sequential-job-transaction-support.patch} |    0
 ...irty-bitmap-tracking-for-incremental.patch |  452 ------
 ...kup-Proxmox-backup-patches-for-QEMU.patch} | 1210 +++++++++++------
 ...store-new-command-to-restore-from-p.patch} |   33 +-
 .../pve/0032-PVE-various-PBS-fixes.patch      |  219 ---
 ...k-driver-to-map-backup-archives-into.patch |   92 +-
 ...dd-query_proxmox_support-QMP-command.patch |   74 -
 ...t-stderr-to-journal-when-daemonized.patch} |    8 +-
 ...grate-dirty-bitmap-state-via-savevm.patch} |   54 +-
 ...E-add-query-pbs-bitmap-info-QMP-call.patch |  441 ------
 ...irty-bitmap-migrate-other-bitmaps-e.patch} |    4 +-
 ...ll-back-to-open-iscsi-initiatorname.patch} |    4 +-
 ...-transaction-to-synchronize-job-stat.patch |  293 ----
 ...VE-block-stream-increase-chunk-size.patch} |    4 +-
 ...-block-on-finishing-and-cleanup-crea.patch |  499 -------
 ...ccept-NULL-qiov-in-bdrv_pad_request.patch} |    4 +-
 ...> 0040-block-add-alloc-track-driver.patch} |   23 +-
 ...rbd-workaround-for-ceph-issue-53784.patch} |    8 +-
 ...fix-handling-of-holes-in-.bdrv_co_b.patch} |    4 +-
 ...routine-QMP-for-backup-cancel_backup.patch |  598 --------
 ...-rbd-implement-bdrv_co_block_status.patch} |   10 +-
 .../pve/0044-PBS-add-master-key-support.patch |   98 --
 ...alloc-track-fix-deadlock-during-drop.patch |  153 +++
 ...st-path-reads-without-allocation-if-.patch |   53 -
 ...apshots-hold-the-BQL-during-setup-ca.patch |  190 +++
 ...vm-async-don-t-hold-BQL-during-setup.patch |   29 +
 ...-register-yank-before-migration_inco.patch |   35 -
 .../pve/0051-vma-allow-partial-restore.patch  |  407 ------
 .../pve/0052-pbs-namespace-support.patch      |  233 ----
 ...e-jobs-correctly-cancel-in-error-sce.patch |   60 -
 ...nsure-jobs-in-di_list-are-referenced.patch |   73 -
 ...d-segfault-issues-upon-backup-cancel.patch |  118 --
 ...support-64KiB-unaligned-input-images.patch |   57 -
 ...d-triggering-assertion-in-error-case.patch |   25 -
 ...ck-alloc-track-avoid-premature-break.patch |   36 -
 ...-passing-max-workers-performance-set.patch |  144 --
 debian/patches/series                         |  128 +-
 debian/pve-qemu-kvm.lintian-overrides         |    8 +-
 debian/rules                                  |    4 +-
 qemu                                          |    2 +-
 116 files changed, 3020 insertions(+), 6790 deletions(-)
 delete mode 100644 debian/patches/extra/0002-init-daemonize-defuse-PID-file-resolve-error.patch
 rename debian/patches/extra/{0008-memory-prevent-dma-reentracy-issues.patch => 0002-memory-prevent-dma-reentracy-issues.patch} (98%)
 rename debian/patches/extra/{0010-scsi-megasas-Internal-cdbs-have-16-byte-length.patch => 0003-scsi-megasas-Internal-cdbs-have-16-byte-length.patch} (100%)
 delete mode 100644 debian/patches/extra/0003-virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch
 rename debian/patches/extra/{0011-ide-avoid-potential-deadlock-when-draining-during-tr.patch => 0004-ide-avoid-potential-deadlock-when-draining-during-tr.patch} (93%)
 delete mode 100644 debian/patches/extra/0004-virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch
 rename debian/patches/extra/{0021-memory-Allow-disabling-re-entrancy-checking-per-MR.patch => 0005-memory-Allow-disabling-re-entrancy-checking-per-MR.patch} (91%)
 delete mode 100644 debian/patches/extra/0005-vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch
 rename debian/patches/extra/{0022-lsi53c895a-disable-reentrancy-detection-for-script-R.patch => 0006-lsi53c895a-disable-reentrancy-detection-for-script-R.patch} (97%)
 delete mode 100644 debian/patches/extra/0006-virtio-rng-pci-fix-migration-compat-for-vectors.patch
 delete mode 100644 debian/patches/extra/0007-block-fix-detect-zeroes-with-BDRV_REQ_REGISTERED_BUF.patch
 create mode 100644 debian/patches/extra/0007-rtl8139-fix-large_send_mss-divide-by-zero.patch
 create mode 100644 debian/patches/extra/0008-block-monitor-Fix-crash-when-executing-HMP-commit.patch
 delete mode 100644 debian/patches/extra/0009-block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch
 create mode 100644 debian/patches/extra/0009-ui-return-NULL-when-getting-cursor-without-a-console.patch
 create mode 100644 debian/patches/extra/0010-ui-Fix-pixel-colour-channel-order-for-PNG-screenshot.patch
 create mode 100644 debian/patches/extra/0011-target-arm-Fix-vd-vm-overlap-in-sve_ldff1_z.patch
 delete mode 100644 debian/patches/extra/0012-hw-nvme-fix-missing-endian-conversions-for-doorbell-.patch
 create mode 100644 debian/patches/extra/0012-softfloat-Fix-the-incorrect-computation-in-float32_e.patch
 delete mode 100644 debian/patches/extra/0013-hw-smbios-fix-field-corruption-in-type-4-table.patch
 create mode 100644 debian/patches/extra/0013-target-i386-Change-wrong-XFRM-value-in-SGX-CPUID-lea.patch
 create mode 100644 debian/patches/extra/0014-block-compile-out-assert_bdrv_graph_readable-by-defa.patch
 delete mode 100644 debian/patches/extra/0014-virtio-rng-pci-fix-transitional-migration-compat-for.patch
 create mode 100644 debian/patches/extra/0015-hw-pci-Disable-PCI_ERR_UNCOR_MASK-register-for-machi.patch
 delete mode 100644 debian/patches/extra/0015-hw-timer-hpet-Fix-expiration-time-overflow.patch
 create mode 100644 debian/patches/extra/0016-block-Fix-use-after-free-in-blockdev_mark_auto_del.patch
 delete mode 100644 debian/patches/extra/0016-vdpa-stop-all-svq-on-device-deletion.patch
 create mode 100644 debian/patches/extra/0017-block-Consistently-call-bdrv_activate-outside-corout.patch
 delete mode 100644 debian/patches/extra/0017-vhost-avoid-a-potential-use-of-an-uninitialized-vari.patch
 create mode 100644 debian/patches/extra/0018-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch
 delete mode 100644 debian/patches/extra/0018-chardev-char-socket-set-s-listener-NULL-in-char_sock.patch
 create mode 100644 debian/patches/extra/0019-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch
 delete mode 100644 debian/patches/extra/0019-intel-iommu-fail-MAP-notifier-without-caching-mode.patch
 create mode 100644 debian/patches/extra/0020-accel-tcg-Fix-atomic_mmu_lookup-for-reads.patch
 delete mode 100644 debian/patches/extra/0020-intel-iommu-fail-DEVIOTLB_UNMAP-without-dt-mode.patch
 delete mode 100644 debian/patches/extra/0023-acpi-cpuhp-fix-guest-visible-maximum-access-size-to-.patch
 delete mode 100644 debian/patches/extra/0024-tests-tcg-i386-Introduce-and-use-reg_t-consistently.patch
 delete mode 100644 debian/patches/extra/0025-target-i386-Fix-BEXTR-instruction.patch
 delete mode 100644 debian/patches/extra/0026-target-i386-Fix-C-flag-for-BLSI-BLSMSK-BLSR.patch
 delete mode 100644 debian/patches/extra/0027-target-i386-fix-ADOX-followed-by-ADCX.patch
 delete mode 100644 debian/patches/extra/0028-target-i386-Fix-BZHI-instruction.patch
 rename debian/patches/pve/{0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch => 0013-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch} (89%)
 rename debian/patches/pve/{0013-PVE-virtio-balloon-improve-query-balloon.patch => 0014-PVE-virtio-balloon-improve-query-balloon.patch} (90%)
 rename debian/patches/pve/{0014-PVE-qapi-modify-query-machines.patch => 0015-PVE-qapi-modify-query-machines.patch} (84%)
 rename debian/patches/pve/{0015-PVE-qapi-modify-spice-query.patch => 0016-PVE-qapi-modify-spice-query.patch} (82%)
 rename debian/patches/pve/{0016-PVE-add-IOChannel-implementation-for-savevm-async.patch => 0017-PVE-add-IOChannel-implementation-for-savevm-async.patch} (97%)
 rename debian/patches/pve/{0017-PVE-add-savevm-async-for-background-state-snapshots.patch => 0018-PVE-add-savevm-async-for-background-state-snapshots.patch} (89%)
 rename debian/patches/pve/{0018-PVE-add-optional-buffer-size-to-QEMUFile.patch => 0019-PVE-add-optional-buffer-size-to-QEMUFile.patch} (96%)
 rename debian/patches/pve/{0019-PVE-block-add-the-zeroinit-block-driver-filter.patch => 0020-PVE-block-add-the-zeroinit-block-driver-filter.patch} (89%)
 rename debian/patches/pve/{0020-PVE-Add-dummy-id-command-line-parameter.patch => 0021-PVE-Add-dummy-id-command-line-parameter.patch} (87%)
 rename debian/patches/pve/{0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch => 0022-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch} (90%)
 rename debian/patches/pve/{0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch => 0023-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch} (89%)
 rename debian/patches/pve/{0023-PVE-monitor-disable-oob-capability.patch => 0024-PVE-monitor-disable-oob-capability.patch} (100%)
 rename debian/patches/pve/{0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch => 0025-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch} (95%)
 rename debian/patches/pve/{0025-PVE-Allow-version-code-in-machine-type.patch => 0026-PVE-Allow-version-code-in-machine-type.patch} (85%)
 rename debian/patches/pve/{0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch => 0027-block-backup-move-bcs-bitmap-initialization-to-job-c.patch} (96%)
 rename debian/patches/pve/{0027-PVE-Backup-add-vma-backup-format-code.patch => 0028-PVE-Backup-add-vma-backup-format-code.patch} (91%)
 rename debian/patches/pve/{0028-PVE-Backup-add-backup-dump-block-driver.patch => 0029-PVE-Backup-add-backup-dump-block-driver.patch} (89%)
 rename debian/patches/pve/{0037-PVE-Add-sequential-job-transaction-support.patch => 0030-PVE-Add-sequential-job-transaction-support.patch} (100%)
 delete mode 100644 debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
 rename debian/patches/pve/{0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch => 0031-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch} (53%)
 rename debian/patches/pve/{0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch => 0032-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch} (89%)
 delete mode 100644 debian/patches/pve/0032-PVE-various-PBS-fixes.patch
 delete mode 100644 debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
 rename debian/patches/pve/{0036-PVE-redirect-stderr-to-journal-when-daemonized.patch => 0034-PVE-redirect-stderr-to-journal-when-daemonized.patch} (91%)
 rename debian/patches/pve/{0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch => 0035-PVE-Migrate-dirty-bitmap-state-via-savevm.patch} (83%)
 delete mode 100644 debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
 rename debian/patches/pve/{0041-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch => 0036-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch} (92%)
 rename debian/patches/pve/{0042-PVE-fall-back-to-open-iscsi-initiatorname.patch => 0037-PVE-fall-back-to-open-iscsi-initiatorname.patch} (95%)
 delete mode 100644 debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
 rename debian/patches/pve/{0046-PVE-block-stream-increase-chunk-size.patch => 0038-PVE-block-stream-increase-chunk-size.patch} (92%)
 delete mode 100644 debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
 rename debian/patches/pve/{0047-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch => 0039-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch} (90%)
 rename debian/patches/pve/{0048-block-add-alloc-track-driver.patch => 0040-block-add-alloc-track-driver.patch} (95%)
 rename debian/patches/pve/{0053-Revert-block-rbd-workaround-for-ceph-issue-53784.patch => 0041-Revert-block-rbd-workaround-for-ceph-issue-53784.patch} (92%)
 rename debian/patches/pve/{0054-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch => 0042-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch} (90%)
 delete mode 100644 debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
 rename debian/patches/pve/{0055-Revert-block-rbd-implement-bdrv_co_block_status.patch => 0043-Revert-block-rbd-implement-bdrv_co_block_status.patch} (95%)
 delete mode 100644 debian/patches/pve/0044-PBS-add-master-key-support.patch
 create mode 100644 debian/patches/pve/0044-alloc-track-fix-deadlock-during-drop.patch
 delete mode 100644 debian/patches/pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch
 create mode 100644 debian/patches/pve/0045-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
 create mode 100644 debian/patches/pve/0046-savevm-async-don-t-hold-BQL-during-setup.patch
 delete mode 100644 debian/patches/pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch
 delete mode 100644 debian/patches/pve/0051-vma-allow-partial-restore.patch
 delete mode 100644 debian/patches/pve/0052-pbs-namespace-support.patch
 delete mode 100644 debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
 delete mode 100644 debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
 delete mode 100644 debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
 delete mode 100644 debian/patches/pve/0059-vma-create-support-64KiB-unaligned-input-images.patch
 delete mode 100644 debian/patches/pve/0060-vma-create-avoid-triggering-assertion-in-error-case.patch
 delete mode 100644 debian/patches/pve/0061-block-alloc-track-avoid-premature-break.patch
 delete mode 100644 debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch

-- 
2.39.2





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

* [pve-devel] [PATCH v2 qemu 1/7] d/rules: drop virtiofsd switch
  2023-05-15 13:39 [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
@ 2023-05-15 13:39 ` Fiona Ebner
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 2/7] d/rules: set job flag for make based on DEB_BUILD_OPTIONS Fiona Ebner
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Fiona Ebner @ 2023-05-15 13:39 UTC (permalink / raw)
  To: pve-devel

virtiofsd is no longer part of QEMU 8.0. It got replaced by a separate
implementation written in Rust, which will be its own package.

See QEMU commit 0aaf44776e ("Merge tag 'pull-virtiofs-20230216b' of
https://gitlab.com/dagrh/qemu into staging").

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---

No changes in v2.

 debian/rules | 1 -
 1 file changed, 1 deletion(-)

diff --git a/debian/rules b/debian/rules
index e69ba47..33ebb69 100755
--- a/debian/rules
+++ b/debian/rules
@@ -84,7 +84,6 @@ ${BUILDDIR}/config.status: configure
 	--enable-usb-redir \
 	--enable-virglrenderer \
 	--enable-virtfs \
-	--enable-virtiofsd \
 	--enable-zstd
 
 build: build-stamp
-- 
2.39.2





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

* [pve-devel] [PATCH v2 qemu 2/7] d/rules: set job flag for make based on DEB_BUILD_OPTIONS
  2023-05-15 13:39 [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 1/7] d/rules: drop virtiofsd switch Fiona Ebner
@ 2023-05-15 13:39 ` Fiona Ebner
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 3/7] buildsys: fix lintian overrides Fiona Ebner
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Fiona Ebner @ 2023-05-15 13:39 UTC (permalink / raw)
  To: pve-devel

Copied from Debian's QEMU package's d/rules. Otherwise, ninja will end
up using only a single job (in Debian Bookworm/Proxmox VE 8).

Suggested-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---

No changes in v2.

 debian/rules | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/debian/rules b/debian/rules
index 33ebb69..b5df8b0 100755
--- a/debian/rules
+++ b/debian/rules
@@ -40,6 +40,9 @@ endif
 
 export CFLAGS
 
+# DEB_BUILD_OPTIONS=parallel=N
+MAKEFLAGS += $(subst parallel=,-j,$(filter parallel=%,${DEB_BUILD_OPTIONS}))
+
 ${BUILDDIR}/config.status: configure
 	dh_testdir
 	# Add here commands to configure the package.
-- 
2.39.2





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

* [pve-devel] [PATCH v2 qemu 3/7] buildsys: fix lintian overrides
  2023-05-15 13:39 [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 1/7] d/rules: drop virtiofsd switch Fiona Ebner
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 2/7] d/rules: set job flag for make based on DEB_BUILD_OPTIONS Fiona Ebner
@ 2023-05-15 13:39 ` Fiona Ebner
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 4/7] update submodule and patches to QEMU 8.0.0 Fiona Ebner
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Fiona Ebner @ 2023-05-15 13:39 UTC (permalink / raw)
  To: pve-devel

See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1007002 for more
information.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---

New in v2.

 debian/pve-qemu-kvm.lintian-overrides | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/debian/pve-qemu-kvm.lintian-overrides b/debian/pve-qemu-kvm.lintian-overrides
index ba50e51..523e848 100644
--- a/debian/pve-qemu-kvm.lintian-overrides
+++ b/debian/pve-qemu-kvm.lintian-overrides
@@ -1,4 +1,4 @@
-pve-qemu-kvm: arch-dependent-file-in-usr-share usr/share/kvm/hppa-firmware.img
-pve-qemu-kvm: binary-from-other-architecture usr/share/kvm/hppa-firmware.img
-pve-qemu-kvm: unstripped-binary-or-object usr/share/kvm/hppa-firmware.img
-pve-qemu-kvm: statically-linked-binary usr/share/kvm/hppa-firmware.img
+pve-qemu-kvm: arch-dependent-file-in-usr-share [usr/share/kvm/hppa-firmware.img]
+pve-qemu-kvm: binary-from-other-architecture [usr/share/kvm/hppa-firmware.img]
+pve-qemu-kvm: unstripped-binary-or-object [usr/share/kvm/hppa-firmware.img]
+pve-qemu-kvm: statically-linked-binary [usr/share/kvm/hppa-firmware.img]
-- 
2.39.2





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

* [pve-devel] [PATCH v2 qemu 4/7] update submodule and patches to QEMU 8.0.0
  2023-05-15 13:39 [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
                   ` (2 preceding siblings ...)
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 3/7] buildsys: fix lintian overrides Fiona Ebner
@ 2023-05-15 13:39 ` Fiona Ebner
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 5/7] add stable patches for 8.0.0 Fiona Ebner
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Fiona Ebner @ 2023-05-15 13:39 UTC (permalink / raw)
  To: pve-devel

Many changes were necessary this time around:

* QAPI was changed to avoid redundant has_* variables, see commit
44ea9d9be3 ("qapi: Start to elide redundant has_FOO in generated C")
for details. This affected many QMP commands added by Proxmox too.

* Pending querying for migration got split into two functions, one to
estimate, one for exact value, see commit c8df4a7aef ("migration:
Split save_live_pending() into state_pending_*") for details. Relevant
for savevm-async and PBS dirty bitmap.

* Some block (driver) functions got converted to coroutines, so the
Proxmox block drivers needed to be adapted.

* Alloc track auto-detaching during PBS live restore got broken by
AioContext-related changes resulting in a deadlock. The current, hacky
method was replaced by a simpler one. Stefan apparently ran into a
problem with that when he wrote the driver, but there were
improvements in the stream job code since then and I didn't manage to
reproduce the issue. It's a separate patch "alloc-track: fix deadlock
during drop" for now, you can find the details there.

* Async snapshot-related changes:
  - The pending querying got adapted to the above-mentioned split and
  a patch is added to optimize it/make it more similar to what
  upstream code does.
  - Added initialization of the compression counters (for
    future-proofing).
  - It's necessary the hold the BQL (big QEMU lock = iothread mutex)
  during the setup phase, because block layer functions are used there
  and not doing so leads to racy, hard-to-debug crashes or hangs. It's
  necessary to change some upstream code too for this, a version of
  the patch "migration: for snapshots, hold the BQL during setup
  callbacks" is intended to be upstreamed.
  - Need to take the bdrv graph read lock before flushing.

* hmp_info_balloon was moved to a different file.

* Needed to include a new headers from time to time to still get the
correct functions.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---

No changes in v2.

 ...d-support-for-sync-bitmap-mode-never.patch |  95 +++---
 ...-support-for-conditional-and-always-.patch |  10 +-
 ...check-for-bitmap-mode-without-bitmap.patch |   6 +-
 ...-to-bdrv_dirty_bitmap_merge_internal.patch |   6 +-
 .../0006-mirror-move-some-checks-to-qmp.patch |  14 +-
 ...race-with-clients-disconnecting-earl.patch |   6 +-
 ...monize-defuse-PID-file-resolve-error.patch |  42 ---
 ...memory-prevent-dma-reentracy-issues.patch} |   4 +-
 ...s-Internal-cdbs-have-16-byte-length.patch} |   0
 ...he-bitmap-index-of-the-section-offse.patch |  44 ---
 ...al-deadlock-when-draining-during-tr.patch} |  10 +-
 ...he-iterator-variable-in-a-vmem-rdl_l.patch |  36 ---
 ...sabling-re-entrancy-checking-per-MR.patch} |   6 +-
 ...ty-bitmap-syncing-when-vIOMMU-is-ena.patch | 141 ---------
 ...e-reentrancy-detection-for-script-R.patch} |   2 +-
 ...pci-fix-migration-compat-for-vectors.patch |  42 ---
 ...-zeroes-with-BDRV_REQ_REGISTERED_BUF.patch |  36 ---
 ...double-free-on-BUSY-or-similar-statu.patch |  32 --
 ...ing-endian-conversions-for-doorbell-.patch |  67 ----
 ...fix-field-corruption-in-type-4-table.patch |  50 ---
 ...ix-transitional-migration-compat-for.patch |  35 ---
 ...er-hpet-Fix-expiration-time-overflow.patch |  80 -----
 ...vdpa-stop-all-svq-on-device-deletion.patch |  71 -----
 ...tential-use-of-an-uninitialized-vari.patch | 132 --------
 ...ket-set-s-listener-NULL-in-char_sock.patch |  70 -----
 ...il-MAP-notifier-without-caching-mode.patch |  41 ---
 ...-fail-DEVIOTLB_UNMAP-without-dt-mode.patch |  50 ---
 ...uest-visible-maximum-access-size-to-.patch | 166 ----------
 ...Introduce-and-use-reg_t-consistently.patch | 286 ------------------
 ...25-target-i386-Fix-BEXTR-instruction.patch |  97 ------
 ...i386-Fix-C-flag-for-BLSI-BLSMSK-BLSR.patch |  47 ---
 ...arget-i386-fix-ADOX-followed-by-ADCX.patch | 192 ------------
 ...028-target-i386-Fix-BZHI-instruction.patch |  64 ----
 ...k-file-change-locking-default-to-off.patch |   6 +-
 ...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 |   8 +-
 ...lock-rbd-disable-rbd_cache_writethro.patch |   4 +-
 .../0007-PVE-Up-qmp-add-get_link_status.patch |   8 +-
 ...PVE-Up-glusterfs-allow-partial-reads.patch |  14 +-
 ...return-success-on-info-without-snaps.patch |   4 +-
 ...dd-add-osize-and-read-from-to-stdin-.patch |  12 +-
 ...E-Up-qemu-img-dd-add-isize-parameter.patch |  14 +-
 ...PVE-Up-qemu-img-dd-add-n-skip_create.patch |  10 +-
 ...virtio-balloon-improve-query-balloon.patch |  95 +++---
 .../0014-PVE-qapi-modify-query-machines.patch |  14 +-
 .../0015-PVE-qapi-modify-spice-query.patch    |  13 +-
 ...nnel-implementation-for-savevm-async.patch |  11 +-
 ...async-for-background-state-snapshots.patch | 101 ++++---
 ...add-optional-buffer-size-to-QEMUFile.patch |  10 +-
 ...add-the-zeroinit-block-driver-filter.patch |  30 +-
 ...-Add-dummy-id-command-line-parameter.patch |  10 +-
 ...t-target-i386-disable-LINT0-after-re.patch |   4 +-
 ...le-posix-make-locking-optiono-on-cre.patch |  18 +-
 ...sed-balloon-qemu-4-0-config-size-fal.patch |   4 +-
 ...E-Allow-version-code-in-machine-type.patch |  31 +-
 ...e-bcs-bitmap-initialization-to-job-c.patch |   4 +-
 ...VE-Backup-add-vma-backup-format-code.patch |  10 +-
 ...-Backup-add-backup-dump-block-driver.patch |  39 +--
 ...ckup-proxmox-backup-patches-for-qemu.patch | 153 +++++-----
 ...estore-new-command-to-restore-from-p.patch |   4 +-
 ...irty-bitmap-tracking-for-incremental.patch |  94 +++---
 .../pve/0032-PVE-various-PBS-fixes.patch      |  86 +++---
 ...k-driver-to-map-backup-archives-into.patch |  48 +--
 ...dd-query_proxmox_support-QMP-command.patch |   8 +-
 ...E-add-query-pbs-bitmap-info-QMP-call.patch |  52 ++--
 ...ct-stderr-to-journal-when-daemonized.patch |   8 +-
 ...-transaction-to-synchronize-job-stat.patch |  26 +-
 ...-block-on-finishing-and-cleanup-crea.patch |  46 +--
 ...igrate-dirty-bitmap-state-via-savevm.patch |  40 +--
 ...dirty-bitmap-migrate-other-bitmaps-e.patch |   4 +-
 ...all-back-to-open-iscsi-initiatorname.patch |   4 +-
 ...routine-QMP-for-backup-cancel_backup.patch | 167 +++++-----
 .../pve/0044-PBS-add-master-key-support.patch |  60 ++--
 ...st-path-reads-without-allocation-if-.patch |   6 +-
 ...PVE-block-stream-increase-chunk-size.patch |   4 +-
 ...accept-NULL-qiov-in-bdrv_pad_request.patch |   4 +-
 .../0048-block-add-alloc-track-driver.patch   |  17 +-
 ...-register-yank-before-migration_inco.patch |   4 +-
 ...-add-l-option-for-loading-a-snapshot.patch |  14 +-
 .../pve/0052-pbs-namespace-support.patch      |  62 ++--
 ...-rbd-workaround-for-ceph-issue-53784.patch |   8 +-
 ...-fix-handling-of-holes-in-.bdrv_co_b.patch |   4 +-
 ...k-rbd-implement-bdrv_co_block_status.patch |  10 +-
 ...e-jobs-correctly-cancel-in-error-sce.patch |   8 +-
 ...nsure-jobs-in-di_list-are-referenced.patch |   8 +-
 ...d-segfault-issues-upon-backup-cancel.patch |   6 +-
 ...ck-alloc-track-avoid-premature-break.patch |   4 +-
 ...-passing-max-workers-performance-set.patch |  34 +--
 ...alloc-track-fix-deadlock-during-drop.patch | 153 ++++++++++
 ...vevm-async-optimize-querying-pending.patch |  49 +++
 ...also-initialize-compression-counters.patch |  26 ++
 ...apshots-hold-the-BQL-during-setup-ca.patch | 190 ++++++++++++
 ...vm-async-don-t-hold-BQL-during-setup.patch |  29 ++
 debian/patches/series                         |  37 +--
 qemu                                          |   2 +-
 97 files changed, 1285 insertions(+), 2660 deletions(-)
 delete mode 100644 debian/patches/extra/0002-init-daemonize-defuse-PID-file-resolve-error.patch
 rename debian/patches/extra/{0008-memory-prevent-dma-reentracy-issues.patch => 0002-memory-prevent-dma-reentracy-issues.patch} (98%)
 rename debian/patches/extra/{0010-scsi-megasas-Internal-cdbs-have-16-byte-length.patch => 0003-scsi-megasas-Internal-cdbs-have-16-byte-length.patch} (100%)
 delete mode 100644 debian/patches/extra/0003-virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch
 rename debian/patches/extra/{0011-ide-avoid-potential-deadlock-when-draining-during-tr.patch => 0004-ide-avoid-potential-deadlock-when-draining-during-tr.patch} (93%)
 delete mode 100644 debian/patches/extra/0004-virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch
 rename debian/patches/extra/{0021-memory-Allow-disabling-re-entrancy-checking-per-MR.patch => 0005-memory-Allow-disabling-re-entrancy-checking-per-MR.patch} (91%)
 delete mode 100644 debian/patches/extra/0005-vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch
 rename debian/patches/extra/{0022-lsi53c895a-disable-reentrancy-detection-for-script-R.patch => 0006-lsi53c895a-disable-reentrancy-detection-for-script-R.patch} (97%)
 delete mode 100644 debian/patches/extra/0006-virtio-rng-pci-fix-migration-compat-for-vectors.patch
 delete mode 100644 debian/patches/extra/0007-block-fix-detect-zeroes-with-BDRV_REQ_REGISTERED_BUF.patch
 delete mode 100644 debian/patches/extra/0009-block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch
 delete mode 100644 debian/patches/extra/0012-hw-nvme-fix-missing-endian-conversions-for-doorbell-.patch
 delete mode 100644 debian/patches/extra/0013-hw-smbios-fix-field-corruption-in-type-4-table.patch
 delete mode 100644 debian/patches/extra/0014-virtio-rng-pci-fix-transitional-migration-compat-for.patch
 delete mode 100644 debian/patches/extra/0015-hw-timer-hpet-Fix-expiration-time-overflow.patch
 delete mode 100644 debian/patches/extra/0016-vdpa-stop-all-svq-on-device-deletion.patch
 delete mode 100644 debian/patches/extra/0017-vhost-avoid-a-potential-use-of-an-uninitialized-vari.patch
 delete mode 100644 debian/patches/extra/0018-chardev-char-socket-set-s-listener-NULL-in-char_sock.patch
 delete mode 100644 debian/patches/extra/0019-intel-iommu-fail-MAP-notifier-without-caching-mode.patch
 delete mode 100644 debian/patches/extra/0020-intel-iommu-fail-DEVIOTLB_UNMAP-without-dt-mode.patch
 delete mode 100644 debian/patches/extra/0023-acpi-cpuhp-fix-guest-visible-maximum-access-size-to-.patch
 delete mode 100644 debian/patches/extra/0024-tests-tcg-i386-Introduce-and-use-reg_t-consistently.patch
 delete mode 100644 debian/patches/extra/0025-target-i386-Fix-BEXTR-instruction.patch
 delete mode 100644 debian/patches/extra/0026-target-i386-Fix-C-flag-for-BLSI-BLSMSK-BLSR.patch
 delete mode 100644 debian/patches/extra/0027-target-i386-fix-ADOX-followed-by-ADCX.patch
 delete mode 100644 debian/patches/extra/0028-target-i386-Fix-BZHI-instruction.patch
 create mode 100644 debian/patches/pve/0063-alloc-track-fix-deadlock-during-drop.patch
 create mode 100644 debian/patches/pve/0064-savevm-async-optimize-querying-pending.patch
 create mode 100644 debian/patches/pve/0065-savevm-async-also-initialize-compression-counters.patch
 create mode 100644 debian/patches/pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
 create mode 100644 debian/patches/pve/0067-savevm-async-don-t-hold-BQL-during-setup.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 fcc2353..306dc3b 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,16 +27,18 @@ 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 8.0]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/mirror.c                         | 98 +++++++++++++++++++++-----
- blockdev.c                             | 39 +++++++++-
+ blockdev.c                             | 38 +++++++++-
  include/block/block_int-global-state.h |  4 +-
  qapi/block-core.json                   | 29 ++++++--
  tests/unit/test-block-iothread.c       |  4 +-
- 5 files changed, 145 insertions(+), 29 deletions(-)
+ 5 files changed, 144 insertions(+), 29 deletions(-)
 
 diff --git a/block/mirror.c b/block/mirror.c
-index 251adc5ae0..8ead5f77a0 100644
+index 663e2b7002..9099c75992 100644
 --- a/block/mirror.c
 +++ b/block/mirror.c
 @@ -51,7 +51,7 @@ typedef struct MirrorBlockJob {
@@ -57,7 +59,7 @@ index 251adc5ae0..8ead5f77a0 100644
      BdrvDirtyBitmap *dirty_bitmap;
      BdrvDirtyBitmapIter *dbi;
      uint8_t *buf;
-@@ -699,7 +701,8 @@ static int mirror_exit_common(Job *job)
+@@ -703,7 +705,8 @@ static int mirror_exit_common(Job *job)
      bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing,
                               &error_abort);
      if (!abort && s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) {
@@ -67,7 +69,7 @@ index 251adc5ae0..8ead5f77a0 100644
          BlockDriverState *unfiltered_target = bdrv_skip_filters(target_bs);
  
          if (bdrv_cow_bs(unfiltered_target) != backing) {
-@@ -797,6 +800,16 @@ static void mirror_abort(Job *job)
+@@ -801,6 +804,16 @@ static void mirror_abort(Job *job)
      assert(ret == 0);
  }
  
@@ -84,7 +86,7 @@ index 251adc5ae0..8ead5f77a0 100644
  static void coroutine_fn mirror_throttle(MirrorBlockJob *s)
  {
      int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-@@ -977,7 +990,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
+@@ -987,7 +1000,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);
@@ -94,7 +96,7 @@ index 251adc5ae0..8ead5f77a0 100644
          ret = mirror_dirty_init(s);
          if (ret < 0 || job_is_cancelled(&s->common.job)) {
              goto immediate_exit;
-@@ -1224,6 +1238,7 @@ static const BlockJobDriver mirror_job_driver = {
+@@ -1240,6 +1254,7 @@ static const BlockJobDriver mirror_job_driver = {
          .run                    = mirror_run,
          .prepare                = mirror_prepare,
          .abort                  = mirror_abort,
@@ -102,7 +104,7 @@ index 251adc5ae0..8ead5f77a0 100644
          .pause                  = mirror_pause,
          .complete               = mirror_complete,
          .cancel                 = mirror_cancel,
-@@ -1240,6 +1255,7 @@ static const BlockJobDriver commit_active_job_driver = {
+@@ -1256,6 +1271,7 @@ static const BlockJobDriver commit_active_job_driver = {
          .run                    = mirror_run,
          .prepare                = mirror_prepare,
          .abort                  = mirror_abort,
@@ -110,7 +112,7 @@ index 251adc5ae0..8ead5f77a0 100644
          .pause                  = mirror_pause,
          .complete               = mirror_complete,
          .cancel                 = commit_active_cancel,
-@@ -1627,7 +1643,10 @@ static BlockJob *mirror_start_job(
+@@ -1647,7 +1663,10 @@ static BlockJob *mirror_start_job(
                               BlockCompletionFunc *cb,
                               void *opaque,
                               const BlockJobDriver *driver,
@@ -122,7 +124,7 @@ index 251adc5ae0..8ead5f77a0 100644
                               bool auto_complete, const char *filter_node_name,
                               bool is_mirror, MirrorCopyMode copy_mode,
                               Error **errp)
-@@ -1639,10 +1658,39 @@ static BlockJob *mirror_start_job(
+@@ -1659,10 +1678,39 @@ static BlockJob *mirror_start_job(
      uint64_t target_perms, target_shared_perms;
      int ret;
  
@@ -164,7 +166,7 @@ index 251adc5ae0..8ead5f77a0 100644
      assert(is_power_of_2(granularity));
  
      if (buf_size < 0) {
-@@ -1774,7 +1822,9 @@ static BlockJob *mirror_start_job(
+@@ -1793,7 +1841,9 @@ static BlockJob *mirror_start_job(
      s->replaces = g_strdup(replaces);
      s->on_source_error = on_source_error;
      s->on_target_error = on_target_error;
@@ -175,7 +177,7 @@ index 251adc5ae0..8ead5f77a0 100644
      s->backing_mode = backing_mode;
      s->zero_target = zero_target;
      s->copy_mode = copy_mode;
-@@ -1795,6 +1845,18 @@ static BlockJob *mirror_start_job(
+@@ -1814,6 +1864,18 @@ static BlockJob *mirror_start_job(
          bdrv_disable_dirty_bitmap(s->dirty_bitmap);
      }
  
@@ -194,7 +196,7 @@ index 251adc5ae0..8ead5f77a0 100644
      ret = block_job_add_bdrv(&s->common, "source", bs, 0,
                               BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
                               BLK_PERM_CONSISTENT_READ,
-@@ -1872,6 +1934,9 @@ fail:
+@@ -1891,6 +1953,9 @@ fail:
          if (s->dirty_bitmap) {
              bdrv_release_dirty_bitmap(s->dirty_bitmap);
          }
@@ -204,7 +206,7 @@ index 251adc5ae0..8ead5f77a0 100644
          job_early_fail(&s->common.job);
      }
  
-@@ -1889,31 +1954,25 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
+@@ -1908,31 +1973,25 @@ 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,
@@ -241,7 +243,7 @@ index 251adc5ae0..8ead5f77a0 100644
  }
  
  BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
-@@ -1940,7 +1999,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
+@@ -1959,7 +2018,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
                       job_id, bs, creation_flags, base, NULL, speed, 0, 0,
                       MIRROR_LEAVE_BACKING_CHAIN, false,
                       on_error, on_error, true, cb, opaque,
@@ -252,21 +254,20 @@ index 251adc5ae0..8ead5f77a0 100644
                       errp);
      if (!job) {
 diff --git a/blockdev.c b/blockdev.c
-index 3f1dec6242..2ee30323cb 100644
+index d7b5c18f0a..6c34d9bb3a 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -2946,6 +2946,10 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2932,6 +2932,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
                                     BlockDriverState *target,
-                                    bool has_replaces, const char *replaces,
+                                    const char *replaces,
                                     enum MirrorSyncMode sync,
-+                                   bool has_bitmap,
 +                                   const char *bitmap_name,
 +                                   bool has_bitmap_mode,
 +                                   BitmapSyncMode bitmap_mode,
                                     BlockMirrorBackingMode backing_mode,
                                     bool zero_target,
                                     bool has_speed, int64_t speed,
-@@ -2965,6 +2969,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2950,6 +2953,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
  {
      BlockDriverState *unfiltered_bs;
      int job_flags = JOB_DEFAULT;
@@ -274,11 +275,11 @@ index 3f1dec6242..2ee30323cb 100644
  
      if (!has_speed) {
          speed = 0;
-@@ -3019,6 +3024,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3001,6 +3005,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
          sync = MIRROR_SYNC_MODE_FULL;
      }
  
-+    if (has_bitmap) {
++    if (bitmap) {
 +        if (granularity) {
 +            error_setg(errp, "Granularity and bitmap cannot both be set");
 +            return;
@@ -301,53 +302,53 @@ index 3f1dec6242..2ee30323cb 100644
 +        }
 +    }
 +
-     if (!has_replaces) {
+     if (!replaces) {
          /* We want to mirror from @bs, but keep implicit filters on top */
          unfiltered_bs = bdrv_skip_implicit_filters(bs);
-@@ -3065,8 +3093,8 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3046,8 +3073,8 @@ 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,
--                 has_replaces ? replaces : NULL, job_flags,
+-                 replaces, job_flags,
 -                 speed, granularity, buf_size, sync, backing_mode, zero_target,
-+                 has_replaces ? replaces : NULL, job_flags, speed, granularity,
-+                 buf_size, sync, bitmap, bitmap_mode, backing_mode, zero_target,
++                 replaces, job_flags, speed, granularity, buf_size, sync,
++                 bitmap, bitmap_mode, backing_mode, zero_target,
                   on_source_error, on_target_error, unmap, filter_node_name,
                   copy_mode, errp);
  }
-@@ -3211,6 +3239,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
+@@ -3192,6 +3219,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
  
-     blockdev_mirror_common(arg->has_job_id ? arg->job_id : NULL, bs, target_bs,
-                            arg->has_replaces, arg->replaces, arg->sync,
-+                           arg->has_bitmap, arg->bitmap,
+     blockdev_mirror_common(arg->job_id, bs, target_bs,
+                            arg->replaces, arg->sync,
++                           arg->bitmap,
 +                           arg->has_bitmap_mode, arg->bitmap_mode,
                             backing_mode, zero_target,
                             arg->has_speed, arg->speed,
                             arg->has_granularity, arg->granularity,
-@@ -3232,6 +3262,8 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
+@@ -3213,6 +3242,8 @@ void qmp_blockdev_mirror(const char *job_id,
                           const char *device, const char *target,
-                          bool has_replaces, const char *replaces,
+                          const char *replaces,
                           MirrorSyncMode sync,
-+                         bool has_bitmap, const char *bitmap,
++                         const char *bitmap,
 +                         bool has_bitmap_mode, BitmapSyncMode bitmap_mode,
                           bool has_speed, int64_t speed,
                           bool has_granularity, uint32_t granularity,
                           bool has_buf_size, int64_t buf_size,
-@@ -3281,7 +3313,8 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
+@@ -3261,7 +3292,8 @@ void qmp_blockdev_mirror(const char *job_id,
      }
  
-     blockdev_mirror_common(has_job_id ? job_id : NULL, bs, target_bs,
--                           has_replaces, replaces, sync, backing_mode,
-+                           has_replaces, replaces, sync, has_bitmap,
+     blockdev_mirror_common(job_id, bs, target_bs,
+-                           replaces, sync, backing_mode,
++                           replaces, sync,
 +                           bitmap, has_bitmap_mode, bitmap_mode, backing_mode,
                             zero_target, has_speed, speed,
                             has_granularity, granularity,
                             has_buf_size, buf_size,
 diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h
-index b49f4eb35b..9d744db618 100644
+index 902406eb99..d559be928c 100644
 --- a/include/block/block_int-global-state.h
 +++ b/include/block/block_int-global-state.h
-@@ -149,7 +149,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
+@@ -152,7 +152,9 @@ 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,
@@ -359,10 +360,10 @@ index b49f4eb35b..9d744db618 100644
                    BlockdevOnError on_source_error,
                    BlockdevOnError on_target_error,
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 95ac4fa634..7daaf545be 100644
+index c05ad0c07e..3c945c1f93 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -2000,10 +2000,19 @@
+@@ -2095,10 +2095,19 @@
  #        (all the disk, only the sectors allocated in the topmost image, or
  #        only new I/O).
  #
@@ -383,7 +384,7 @@ index 95ac4fa634..7daaf545be 100644
  #
  # @buf-size: maximum amount of data in flight from source to
  #            target (since 1.4).
-@@ -2043,7 +2052,9 @@
+@@ -2138,7 +2147,9 @@
  { 'struct': 'DriveMirror',
    'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
              '*format': 'str', '*node-name': 'str', '*replaces': 'str',
@@ -394,7 +395,7 @@ index 95ac4fa634..7daaf545be 100644
              '*speed': 'int', '*granularity': 'uint32',
              '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
              '*on-target-error': 'BlockdevOnError',
-@@ -2322,10 +2333,19 @@
+@@ -2417,10 +2428,19 @@
  #        (all the disk, only the sectors allocated in the topmost image, or
  #        only new I/O).
  #
@@ -415,7 +416,7 @@ index 95ac4fa634..7daaf545be 100644
  #
  # @buf-size: maximum amount of data in flight from source to
  #            target
-@@ -2375,7 +2395,8 @@
+@@ -2470,7 +2490,8 @@
  { 'command': 'blockdev-mirror',
    'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
              '*replaces': 'str',
@@ -426,10 +427,10 @@ index 95ac4fa634..7daaf545be 100644
              '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
              '*on-target-error': 'BlockdevOnError',
 diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
-index 8ca5adec5e..dae80e5a5f 100644
+index 3a5e1eb2c4..c1ecc49073 100644
 --- a/tests/unit/test-block-iothread.c
 +++ b/tests/unit/test-block-iothread.c
-@@ -755,8 +755,8 @@ static void test_propagate_mirror(void)
+@@ -757,8 +757,8 @@ static void test_propagate_mirror(void)
  
      /* Start a mirror job */
      mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0,
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 d8041ca..b0ade68 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 8ead5f77a0..35c1b8f25d 100644
+index 9099c75992..e2ff42067b 100644
 --- a/block/mirror.c
 +++ b/block/mirror.c
-@@ -676,8 +676,6 @@ static int mirror_exit_common(Job *job)
+@@ -680,8 +680,6 @@ static int mirror_exit_common(Job *job)
          bdrv_unfreeze_backing_chain(mirror_top_bs, target_bs);
      }
  
@@ -36,7 +36,7 @@ index 8ead5f77a0..35c1b8f25d 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);
-@@ -778,6 +776,18 @@ static int mirror_exit_common(Job *job)
+@@ -782,6 +780,18 @@ static int mirror_exit_common(Job *job)
      block_job_remove_all_bdrv(bjob);
      bdrv_replace_node(mirror_top_bs, mirror_top_bs->backing->bs, &error_abort);
  
@@ -55,7 +55,7 @@ index 8ead5f77a0..35c1b8f25d 100644
      bs_opaque->job = NULL;
  
      bdrv_drained_end(src);
-@@ -1668,10 +1678,6 @@ static BlockJob *mirror_start_job(
+@@ -1688,10 +1698,6 @@ static BlockJob *mirror_start_job(
                         " sync mode",
                         MirrorSyncMode_str(sync_mode));
              return NULL;
@@ -66,7 +66,7 @@ index 8ead5f77a0..35c1b8f25d 100644
          }
      } else if (bitmap) {
          error_setg(errp,
-@@ -1688,6 +1694,12 @@ static BlockJob *mirror_start_job(
+@@ -1708,6 +1714,12 @@ static BlockJob *mirror_start_job(
              return NULL;
          }
          granularity = bdrv_dirty_bitmap_granularity(bitmap);
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 c6a0710..3061723 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 2ee30323cb..dd1c2cdef7 100644
+index 6c34d9bb3a..24a76b451d 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3045,6 +3045,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3026,6 +3026,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
          if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
              return;
          }
@@ -28,4 +28,4 @@ index 2ee30323cb..dd1c2cdef7 100644
 +        return;
      }
  
-     if (!has_replaces) {
+     if (!replaces) {
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 11f4dc3..b954682 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 35c1b8f25d..4969c6833c 100644
+index e2ff42067b..f42953837b 100644
 --- a/block/mirror.c
 +++ b/block/mirror.c
-@@ -782,8 +782,8 @@ static int mirror_exit_common(Job *job)
+@@ -786,8 +786,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 35c1b8f25d..4969c6833c 100644
          }
      }
      bdrv_release_dirty_bitmap(s->dirty_bitmap);
-@@ -1862,11 +1862,8 @@ static BlockJob *mirror_start_job(
+@@ -1881,11 +1881,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 4771a2d..4139251 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
@@ -12,6 +12,8 @@ uniform w.r.t. backup block jobs.
 
 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[FE: rebase for 8.0]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/mirror.c             | 28 +++------------
  blockdev.c                 | 29 +++++++++++++++
@@ -19,10 +21,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  3 files changed, 70 insertions(+), 59 deletions(-)
 
 diff --git a/block/mirror.c b/block/mirror.c
-index 4969c6833c..cf85ae1074 100644
+index f42953837b..8f79efaa87 100644
 --- a/block/mirror.c
 +++ b/block/mirror.c
-@@ -1668,31 +1668,13 @@ static BlockJob *mirror_start_job(
+@@ -1688,31 +1688,13 @@ static BlockJob *mirror_start_job(
      uint64_t target_perms, target_shared_perms;
      int ret;
  
@@ -60,17 +62,17 @@ index 4969c6833c..cf85ae1074 100644
  
          if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
 diff --git a/blockdev.c b/blockdev.c
-index dd1c2cdef7..756e980889 100644
+index 24a76b451d..3917af7d02 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3024,7 +3024,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3005,7 +3005,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
          sync = MIRROR_SYNC_MODE_FULL;
      }
  
 +    if ((sync == MIRROR_SYNC_MODE_BITMAP) ||
 +        (sync == MIRROR_SYNC_MODE_INCREMENTAL)) {
 +        /* done before desugaring 'incremental' to print the right message */
-+        if (!has_bitmap) {
++        if (!bitmap) {
 +            error_setg(errp, "Must provide a valid bitmap name for "
 +                       "'%s' sync mode", MirrorSyncMode_str(sync));
 +            return;
@@ -91,7 +93,7 @@ index dd1c2cdef7..756e980889 100644
 +        bitmap_mode = BITMAP_SYNC_MODE_ON_SUCCESS;
 +    }
 +
-     if (has_bitmap) {
+     if (bitmap) {
 +        if (sync != MIRROR_SYNC_MODE_BITMAP) {
 +            error_setg(errp, "Sync mode '%s' not supported with bitmap.",
 +                       MirrorSyncMode_str(sync));
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 4796631..a7fe592 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
@@ -48,7 +48,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  6 files changed, 59 insertions(+), 5 deletions(-)
 
 diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
-index 737e750670..38804b8595 100644
+index 033390f699..ad35d4fea8 100644
 --- a/include/monitor/monitor.h
 +++ b/include/monitor/monitor.h
 @@ -16,6 +16,7 @@ extern QemuOptsList qemu_mon_opts;
@@ -60,7 +60,7 @@ index 737e750670..38804b8595 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 a2cdbbf646..b531bd50e7 100644
+index 53e3808054..a19f8cbc2b 100644
 --- a/monitor/monitor-internal.h
 +++ b/monitor/monitor-internal.h
 @@ -152,6 +152,13 @@ typedef struct {
@@ -78,7 +78,7 @@ index a2cdbbf646..b531bd50e7 100644
  
  /**
 diff --git a/monitor/monitor.c b/monitor/monitor.c
-index 86949024f6..c306cadcf4 100644
+index 8dc96f6af9..f3c38cb714 100644
 --- a/monitor/monitor.c
 +++ b/monitor/monitor.c
 @@ -135,6 +135,21 @@ bool monitor_cur_is_qmp(void)
diff --git a/debian/patches/extra/0002-init-daemonize-defuse-PID-file-resolve-error.patch b/debian/patches/extra/0002-init-daemonize-defuse-PID-file-resolve-error.patch
deleted file mode 100644
index 155d065..0000000
--- a/debian/patches/extra/0002-init-daemonize-defuse-PID-file-resolve-error.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fiona Ebner <f.ebner@proxmox.com>
-Date: Fri, 28 Oct 2022 10:09:46 +0200
-Subject: [PATCH] init: daemonize: defuse PID file resolve error
-
-When proxmox-file-restore invokes QEMU, the PID file is a (temporary)
-file that's already unlinked, so resolving the absolute path here
-failed.
-
-It should not be a critical error when the PID file unlink handler
-can't be registered, because the path can't be resolved for whatever
-reason. If the file is already gone from QEMU's perspective (i.e.
-errno is ENOENT), silently ignore the error. Otherwise, print a
-warning.
-
-Reported-by: Dominik Csapak <d.csapak@proxmox.com>
-Suggested-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- softmmu/vl.c | 9 +++++----
- 1 file changed, 5 insertions(+), 4 deletions(-)
-
-diff --git a/softmmu/vl.c b/softmmu/vl.c
-index 5115221efe..5f7f6ca981 100644
---- a/softmmu/vl.c
-+++ b/softmmu/vl.c
-@@ -2460,10 +2460,11 @@ static void qemu_maybe_daemonize(const char *pid_file)
- 
-         pid_file_realpath = g_malloc0(PATH_MAX);
-         if (!realpath(pid_file, pid_file_realpath)) {
--            error_report("cannot resolve PID file path: %s: %s",
--                         pid_file, strerror(errno));
--            unlink(pid_file);
--            exit(1);
-+            if (errno != ENOENT) {
-+                warn_report("not removing PID file on exit: cannot resolve PID "
-+                            "file path: %s: %s", pid_file, strerror(errno));
-+            }
-+            return;
-         }
- 
-         qemu_unlink_pidfile_notifier = (struct UnlinkPidfileNotifier) {
diff --git a/debian/patches/extra/0008-memory-prevent-dma-reentracy-issues.patch b/debian/patches/extra/0002-memory-prevent-dma-reentracy-issues.patch
similarity index 98%
rename from debian/patches/extra/0008-memory-prevent-dma-reentracy-issues.patch
rename to debian/patches/extra/0002-memory-prevent-dma-reentracy-issues.patch
index 4f3af9a..5be13d6 100644
--- a/debian/patches/extra/0008-memory-prevent-dma-reentracy-issues.patch
+++ b/debian/patches/extra/0002-memory-prevent-dma-reentracy-issues.patch
@@ -38,7 +38,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  3 files changed, 25 insertions(+)
 
 diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
-index 785dd5a56e..886f6bb79e 100644
+index bd50ad5ee1..7623703943 100644
 --- a/include/hw/qdev-core.h
 +++ b/include/hw/qdev-core.h
 @@ -162,6 +162,10 @@ struct NamedClockList {
@@ -63,7 +63,7 @@ index 785dd5a56e..886f6bb79e 100644
  
  struct DeviceListener {
 diff --git a/softmmu/memory.c b/softmmu/memory.c
-index bc0be3f62c..7dcb3347aa 100644
+index b1a6cae6f5..e4d2268d32 100644
 --- a/softmmu/memory.c
 +++ b/softmmu/memory.c
 @@ -533,6 +533,7 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
diff --git a/debian/patches/extra/0010-scsi-megasas-Internal-cdbs-have-16-byte-length.patch b/debian/patches/extra/0003-scsi-megasas-Internal-cdbs-have-16-byte-length.patch
similarity index 100%
rename from debian/patches/extra/0010-scsi-megasas-Internal-cdbs-have-16-byte-length.patch
rename to debian/patches/extra/0003-scsi-megasas-Internal-cdbs-have-16-byte-length.patch
diff --git a/debian/patches/extra/0003-virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch b/debian/patches/extra/0003-virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch
deleted file mode 100644
index b54c0cc..0000000
--- a/debian/patches/extra/0003-virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Chenyi Qiang <chenyi.qiang@intel.com>
-Date: Fri, 16 Dec 2022 14:22:31 +0800
-Subject: [PATCH] virtio-mem: Fix the bitmap index of the section offset
-
-vmem->bitmap indexes the memory region of the virtio-mem backend at a
-granularity of block_size. To calculate the index of target section offset,
-the block_size should be divided instead of the bitmap_size.
-
-Fixes: 2044969f0b ("virtio-mem: Implement RamDiscardManager interface")
-Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
-Message-Id: <20221216062231.11181-1-chenyi.qiang@intel.com>
-Reviewed-by: David Hildenbrand <david@redhat.com>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Cc: qemu-stable@nongnu.org
-Signed-off-by: David Hildenbrand <david@redhat.com>
-(cherry-picked from commit b11cf32e07a2f7ff0d171b89497381a04c9d07e0)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/virtio/virtio-mem.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
-index ed170def48..e19ee817fe 100644
---- a/hw/virtio/virtio-mem.c
-+++ b/hw/virtio/virtio-mem.c
-@@ -235,7 +235,7 @@ static int virtio_mem_for_each_plugged_section(const VirtIOMEM *vmem,
-     uint64_t offset, size;
-     int ret = 0;
- 
--    first_bit = s->offset_within_region / vmem->bitmap_size;
-+    first_bit = s->offset_within_region / vmem->block_size;
-     first_bit = find_next_bit(vmem->bitmap, vmem->bitmap_size, first_bit);
-     while (first_bit < vmem->bitmap_size) {
-         MemoryRegionSection tmp = *s;
-@@ -267,7 +267,7 @@ static int virtio_mem_for_each_unplugged_section(const VirtIOMEM *vmem,
-     uint64_t offset, size;
-     int ret = 0;
- 
--    first_bit = s->offset_within_region / vmem->bitmap_size;
-+    first_bit = s->offset_within_region / vmem->block_size;
-     first_bit = find_next_zero_bit(vmem->bitmap, vmem->bitmap_size, first_bit);
-     while (first_bit < vmem->bitmap_size) {
-         MemoryRegionSection tmp = *s;
diff --git a/debian/patches/extra/0011-ide-avoid-potential-deadlock-when-draining-during-tr.patch b/debian/patches/extra/0004-ide-avoid-potential-deadlock-when-draining-during-tr.patch
similarity index 93%
rename from debian/patches/extra/0011-ide-avoid-potential-deadlock-when-draining-during-tr.patch
rename to debian/patches/extra/0004-ide-avoid-potential-deadlock-when-draining-during-tr.patch
index 8ce9c79..89491a5 100644
--- a/debian/patches/extra/0011-ide-avoid-potential-deadlock-when-draining-during-tr.patch
+++ b/debian/patches/extra/0004-ide-avoid-potential-deadlock-when-draining-during-tr.patch
@@ -55,10 +55,10 @@ 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 39afdc0006..b67c1885a8 100644
+index 45d14a25e9..08e1f0c3d7 100644
 --- a/hw/ide/core.c
 +++ b/hw/ide/core.c
-@@ -443,7 +443,7 @@ static void ide_trim_bh_cb(void *opaque)
+@@ -444,7 +444,7 @@ static void ide_trim_bh_cb(void *opaque)
      iocb->bh = NULL;
      qemu_aio_unref(iocb);
  
@@ -67,7 +67,7 @@ index 39afdc0006..b67c1885a8 100644
      blk_dec_in_flight(blk);
  }
  
-@@ -503,6 +503,8 @@ static void ide_issue_trim_cb(void *opaque, int ret)
+@@ -504,6 +504,8 @@ static void ide_issue_trim_cb(void *opaque, int ret)
  done:
      iocb->aiocb = NULL;
      if (iocb->bh) {
@@ -76,7 +76,7 @@ index 39afdc0006..b67c1885a8 100644
          replay_bh_schedule_event(iocb->bh);
      }
  }
-@@ -514,9 +516,6 @@ BlockAIOCB *ide_issue_trim(
+@@ -515,9 +517,6 @@ BlockAIOCB *ide_issue_trim(
      IDEState *s = opaque;
      TrimAIOCB *iocb;
  
@@ -86,7 +86,7 @@ index 39afdc0006..b67c1885a8 100644
      iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque);
      iocb->s = s;
      iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
-@@ -739,8 +738,9 @@ void ide_cancel_dma_sync(IDEState *s)
+@@ -740,8 +739,9 @@ void ide_cancel_dma_sync(IDEState *s)
       */
      if (s->bus->dma->aiocb) {
          trace_ide_cancel_dma_sync_remaining();
diff --git a/debian/patches/extra/0004-virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch b/debian/patches/extra/0004-virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch
deleted file mode 100644
index c303094..0000000
--- a/debian/patches/extra/0004-virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Chenyi Qiang <chenyi.qiang@intel.com>
-Date: Wed, 28 Dec 2022 17:03:12 +0800
-Subject: [PATCH] virtio-mem: Fix the iterator variable in a vmem->rdl_list
- loop
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It should be the variable rdl2 to revert the already-notified listeners.
-
-Fixes: 2044969f0b ("virtio-mem: Implement RamDiscardManager interface")
-Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
-Message-Id: <20221228090312.17276-1-chenyi.qiang@intel.com>
-Cc: qemu-stable@nongnu.org
-Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
-Signed-off-by: David Hildenbrand <david@redhat.com>
-(cherry-picked from commit 29f1b328e3b767cba2661920a8470738469b9e36)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/virtio/virtio-mem.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
-index e19ee817fe..56db586c89 100644
---- a/hw/virtio/virtio-mem.c
-+++ b/hw/virtio/virtio-mem.c
-@@ -341,7 +341,7 @@ static int virtio_mem_notify_plug(VirtIOMEM *vmem, uint64_t offset,
-     if (ret) {
-         /* Notify all already-notified listeners. */
-         QLIST_FOREACH(rdl2, &vmem->rdl_list, next) {
--            MemoryRegionSection tmp = *rdl->section;
-+            MemoryRegionSection tmp = *rdl2->section;
- 
-             if (rdl2 == rdl) {
-                 break;
diff --git a/debian/patches/extra/0021-memory-Allow-disabling-re-entrancy-checking-per-MR.patch b/debian/patches/extra/0005-memory-Allow-disabling-re-entrancy-checking-per-MR.patch
similarity index 91%
rename from debian/patches/extra/0021-memory-Allow-disabling-re-entrancy-checking-per-MR.patch
rename to debian/patches/extra/0005-memory-Allow-disabling-re-entrancy-checking-per-MR.patch
index 3d5c267..47c0b80 100644
--- a/debian/patches/extra/0021-memory-Allow-disabling-re-entrancy-checking-per-MR.patch
+++ b/debian/patches/extra/0005-memory-Allow-disabling-re-entrancy-checking-per-MR.patch
@@ -10,10 +10,10 @@ Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
  2 files changed, 4 insertions(+), 1 deletion(-)
 
 diff --git a/include/exec/memory.h b/include/exec/memory.h
-index 91f8a2395a..d7268d9f39 100644
+index 15ade918ba..e6819e3c39 100644
 --- a/include/exec/memory.h
 +++ b/include/exec/memory.h
-@@ -765,6 +765,9 @@ struct MemoryRegion {
+@@ -791,6 +791,9 @@ struct MemoryRegion {
      unsigned ioeventfd_nb;
      MemoryRegionIoeventfd *ioeventfds;
      RamDiscardManager *rdm; /* Only for RAM */
@@ -24,7 +24,7 @@ index 91f8a2395a..d7268d9f39 100644
  
  struct IOMMUMemoryRegion {
 diff --git a/softmmu/memory.c b/softmmu/memory.c
-index 7dcb3347aa..2b46714191 100644
+index e4d2268d32..d88acb204b 100644
 --- a/softmmu/memory.c
 +++ b/softmmu/memory.c
 @@ -544,7 +544,7 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
diff --git a/debian/patches/extra/0005-vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch b/debian/patches/extra/0005-vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch
deleted file mode 100644
index b72b3da..0000000
--- a/debian/patches/extra/0005-vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jason Wang <jasowang@redhat.com>
-Date: Fri, 16 Dec 2022 11:35:52 +0800
-Subject: [PATCH] vhost: fix vq dirty bitmap syncing when vIOMMU is enabled
-
-When vIOMMU is enabled, the vq->used_phys is actually the IOVA not
-GPA. So we need to translate it to GPA before the syncing otherwise we
-may hit the following crash since IOVA could be out of the scope of
-the GPA log size. This could be noted when using virtio-IOMMU with
-vhost using 1G memory.
-
-Fixes: c471ad0e9bd46 ("vhost_net: device IOTLB support")
-Cc: qemu-stable@nongnu.org
-Tested-by: Lei Yang <leiyang@redhat.com>
-Reported-by: Yalan Zhang <yalzhang@redhat.com>
-Signed-off-by: Jason Wang <jasowang@redhat.com>
-Message-Id: <20221216033552.77087-1-jasowang@redhat.com>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-(cherry-picked from commit 345cc1cbcbce2bab00abc2b88338d7d89c702d6b)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/virtio/vhost.c | 84 ++++++++++++++++++++++++++++++++++++-----------
- 1 file changed, 64 insertions(+), 20 deletions(-)
-
-diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
-index 7fb008bc9e..fdcd1a8fdf 100644
---- a/hw/virtio/vhost.c
-+++ b/hw/virtio/vhost.c
-@@ -20,6 +20,7 @@
- #include "qemu/range.h"
- #include "qemu/error-report.h"
- #include "qemu/memfd.h"
-+#include "qemu/log.h"
- #include "standard-headers/linux/vhost_types.h"
- #include "hw/virtio/virtio-bus.h"
- #include "hw/virtio/virtio-access.h"
-@@ -106,6 +107,24 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
-     }
- }
- 
-+static bool vhost_dev_has_iommu(struct vhost_dev *dev)
-+{
-+    VirtIODevice *vdev = dev->vdev;
-+
-+    /*
-+     * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
-+     * incremental memory mapping API via IOTLB API. For platform that
-+     * does not have IOMMU, there's no need to enable this feature
-+     * which may cause unnecessary IOTLB miss/update transactions.
-+     */
-+    if (vdev) {
-+        return virtio_bus_device_iommu_enabled(vdev) &&
-+            virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
-+    } else {
-+        return false;
-+    }
-+}
-+
- static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
-                                    MemoryRegionSection *section,
-                                    hwaddr first,
-@@ -137,8 +156,51 @@ static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
-             continue;
-         }
- 
--        vhost_dev_sync_region(dev, section, start_addr, end_addr, vq->used_phys,
--                              range_get_last(vq->used_phys, vq->used_size));
-+        if (vhost_dev_has_iommu(dev)) {
-+            IOMMUTLBEntry iotlb;
-+            hwaddr used_phys = vq->used_phys, used_size = vq->used_size;
-+            hwaddr phys, s, offset;
-+
-+            while (used_size) {
-+                rcu_read_lock();
-+                iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
-+                                                      used_phys,
-+                                                      true,
-+                                                      MEMTXATTRS_UNSPECIFIED);
-+                rcu_read_unlock();
-+
-+                if (!iotlb.target_as) {
-+                    qemu_log_mask(LOG_GUEST_ERROR, "translation "
-+                                  "failure for used_iova %"PRIx64"\n",
-+                                  used_phys);
-+                    return -EINVAL;
-+                }
-+
-+                offset = used_phys & iotlb.addr_mask;
-+                phys = iotlb.translated_addr + offset;
-+
-+                /*
-+                 * Distance from start of used ring until last byte of
-+                 * IOMMU page.
-+                 */
-+                s = iotlb.addr_mask - offset;
-+                /*
-+                 * Size of used ring, or of the part of it until end
-+                 * of IOMMU page. To avoid zero result, do the adding
-+                 * outside of MIN().
-+                 */
-+                s = MIN(s, used_size - 1) + 1;
-+
-+                vhost_dev_sync_region(dev, section, start_addr, end_addr, phys,
-+                                      range_get_last(phys, s));
-+                used_size -= s;
-+                used_phys += s;
-+            }
-+        } else {
-+            vhost_dev_sync_region(dev, section, start_addr,
-+                                  end_addr, vq->used_phys,
-+                                  range_get_last(vq->used_phys, vq->used_size));
-+        }
-     }
-     return 0;
- }
-@@ -306,24 +368,6 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
-     dev->log_size = size;
- }
- 
--static bool vhost_dev_has_iommu(struct vhost_dev *dev)
--{
--    VirtIODevice *vdev = dev->vdev;
--
--    /*
--     * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
--     * incremental memory mapping API via IOTLB API. For platform that
--     * does not have IOMMU, there's no need to enable this feature
--     * which may cause unnecessary IOTLB miss/update transactions.
--     */
--    if (vdev) {
--        return virtio_bus_device_iommu_enabled(vdev) &&
--            virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
--    } else {
--        return false;
--    }
--}
--
- static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr,
-                               hwaddr *plen, bool is_write)
- {
diff --git a/debian/patches/extra/0022-lsi53c895a-disable-reentrancy-detection-for-script-R.patch b/debian/patches/extra/0006-lsi53c895a-disable-reentrancy-detection-for-script-R.patch
similarity index 97%
rename from debian/patches/extra/0022-lsi53c895a-disable-reentrancy-detection-for-script-R.patch
rename to debian/patches/extra/0006-lsi53c895a-disable-reentrancy-detection-for-script-R.patch
index a4ed0ee..d7c7496 100644
--- a/debian/patches/extra/0022-lsi53c895a-disable-reentrancy-detection-for-script-R.patch
+++ b/debian/patches/extra/0006-lsi53c895a-disable-reentrancy-detection-for-script-R.patch
@@ -15,7 +15,7 @@ Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
  1 file changed, 6 insertions(+)
 
 diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
-index 50979640c3..894b9311ac 100644
+index af93557a9a..db27872963 100644
 --- a/hw/scsi/lsi53c895a.c
 +++ b/hw/scsi/lsi53c895a.c
 @@ -2302,6 +2302,12 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
diff --git a/debian/patches/extra/0006-virtio-rng-pci-fix-migration-compat-for-vectors.patch b/debian/patches/extra/0006-virtio-rng-pci-fix-migration-compat-for-vectors.patch
deleted file mode 100644
index 2673dd7..0000000
--- a/debian/patches/extra/0006-virtio-rng-pci-fix-migration-compat-for-vectors.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
-Date: Mon, 9 Jan 2023 10:58:09 +0000
-Subject: [PATCH] virtio-rng-pci: fix migration compat for vectors
-
-Fixup the migration compatibility for existing machine types
-so that they do not enable msi-x.
-
-Symptom:
-
-(qemu) qemu: get_pci_config_device: Bad config data: i=0x34 read: 84 device: 98 cmask: ff wmask: 0 w1cmask:0
-qemu: Failed to load PCIDevice:config
-qemu: Failed to load virtio-rng:virtio
-qemu: error while loading state for instance 0x0 of device '0000:00:03.0/virtio-rng'
-qemu: load of migration failed: Invalid argument
-
-Note: This fix will break migration from 7.2->7.2-fixed with this patch
-
-bz: https://bugzilla.redhat.com/show_bug.cgi?id=2155749
-Fixes: 9ea02e8f1 ("virtio-rng-pci: Allow setting nvectors, so we can use MSI-X")
-
-Reviewed-by: Thomas Huth <thuth@redhat.com>
-Acked-by: David Daney <david.daney@fungible.com>
-Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
-(picked-up from https://lists.nongnu.org/archive/html/qemu-devel/2023-01/msg01319.html)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/core/machine.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/hw/core/machine.c b/hw/core/machine.c
-index 8d34caa31d..77a0a131d1 100644
---- a/hw/core/machine.c
-+++ b/hw/core/machine.c
-@@ -42,6 +42,7 @@
- 
- GlobalProperty hw_compat_7_1[] = {
-     { "virtio-device", "queue_reset", "false" },
-+    { "virtio-rng-pci", "vectors", "0" },
- };
- const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
- 
diff --git a/debian/patches/extra/0007-block-fix-detect-zeroes-with-BDRV_REQ_REGISTERED_BUF.patch b/debian/patches/extra/0007-block-fix-detect-zeroes-with-BDRV_REQ_REGISTERED_BUF.patch
deleted file mode 100644
index 7b7ea1e..0000000
--- a/debian/patches/extra/0007-block-fix-detect-zeroes-with-BDRV_REQ_REGISTERED_BUF.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Hajnoczi <stefanha@redhat.com>
-Date: Thu, 26 Jan 2023 15:13:58 -0500
-Subject: [PATCH] block: fix detect-zeroes= with BDRV_REQ_REGISTERED_BUF
-
-When a write request is converted into a write zeroes request by the
-detect-zeroes= feature, it is no longer associated with an I/O buffer.
-The BDRV_REQ_REGISTERED_BUF flag doesn't make sense without an I/O
-buffer and must be cleared because bdrv_co_do_pwrite_zeroes() fails with
--EINVAL when it's set.
-
-Fiona Ebner <f.ebner@proxmox.com> bisected and diagnosed this QEMU 7.2
-regression where writes containing zeroes to a blockdev with
-discard=unmap,detect-zeroes=unmap fail.
-
-Buglink: https://gitlab.com/qemu-project/qemu/-/issues/1404
-Fixes: e8b6535533be ("block: add BDRV_REQ_REGISTERED_BUF request flag")
-Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
----
- block/io.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/block/io.c b/block/io.c
-index b9424024f9..bbaa0d1b2d 100644
---- a/block/io.c
-+++ b/block/io.c
-@@ -2087,6 +2087,9 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
-         if (bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP) {
-             flags |= BDRV_REQ_MAY_UNMAP;
-         }
-+
-+        /* Can't use optimization hint with bufferless zero write */
-+        flags &= ~BDRV_REQ_REGISTERED_BUF;
-     }
- 
-     if (ret < 0) {
diff --git a/debian/patches/extra/0009-block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch b/debian/patches/extra/0009-block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch
deleted file mode 100644
index fe57e02..0000000
--- a/debian/patches/extra/0009-block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Tue, 10 Jan 2023 17:36:33 +0100
-Subject: [PATCH] block/iscsi: fix double-free on BUSY or similar statuses
-
-Commit 8c460269aa77 ("iscsi: base all handling of check condition on
-scsi_sense_to_errno", 2019-07-15) removed a "goto out" so that the
-same coroutine is re-entered twice; once from iscsi_co_generic_cb,
-once from the timer callback iscsi_retry_timer_expired.  This can
-cause a crash.
-
-Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1378
-Reported-by: Grzegorz Zdanowski <https://gitlab.com/kiler129>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-(cherry-picked from commit 5080152e2ef6cde7aa692e29880c62bd54acb750)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- block/iscsi.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/block/iscsi.c b/block/iscsi.c
-index 3ed4a50c0d..89cd032c3a 100644
---- a/block/iscsi.c
-+++ b/block/iscsi.c
-@@ -268,6 +268,7 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
-                 timer_mod(&iTask->retry_timer,
-                           qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + retry_time);
-                 iTask->do_retry = 1;
-+                return;
-             } else if (status == SCSI_STATUS_CHECK_CONDITION) {
-                 int error = iscsi_translate_sense(&task->sense);
-                 if (error == EAGAIN) {
diff --git a/debian/patches/extra/0012-hw-nvme-fix-missing-endian-conversions-for-doorbell-.patch b/debian/patches/extra/0012-hw-nvme-fix-missing-endian-conversions-for-doorbell-.patch
deleted file mode 100644
index aa9d0b0..0000000
--- a/debian/patches/extra/0012-hw-nvme-fix-missing-endian-conversions-for-doorbell-.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Klaus Jensen <k.jensen@samsung.com>
-Date: Wed, 8 Mar 2023 19:57:12 +0300
-Subject: [PATCH] hw/nvme: fix missing endian conversions for doorbell buffers
-
-The eventidx and doorbell value are not handling endianness correctly.
-Fix this.
-
-Fixes: 3f7fe8de3d49 ("hw/nvme: Implement shadow doorbell buffer support")
-Cc: qemu-stable@nongnu.org
-Reported-by: Guenter Roeck <linux@roeck-us.net>
-Reviewed-by: Keith Busch <kbusch@kernel.org>
-Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
-(cherry picked from commit 2fda0726e5149e032acfa5fe442db56cd6433c4c)
-Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
-Conflicts: hw/nvme/ctrl.c
-(picked up from qemu-stable mailing list)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/nvme/ctrl.c | 22 ++++++++++++++++------
- 1 file changed, 16 insertions(+), 6 deletions(-)
-
-diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
-index e54276dc1d..98d8e34109 100644
---- a/hw/nvme/ctrl.c
-+++ b/hw/nvme/ctrl.c
-@@ -1333,8 +1333,12 @@ static inline void nvme_blk_write(BlockBackend *blk, int64_t offset,
- 
- static void nvme_update_cq_head(NvmeCQueue *cq)
- {
--    pci_dma_read(&cq->ctrl->parent_obj, cq->db_addr, &cq->head,
--            sizeof(cq->head));
-+    uint32_t v;
-+
-+    pci_dma_read(&cq->ctrl->parent_obj, cq->db_addr, &v, sizeof(v));
-+
-+    cq->head = le32_to_cpu(v);
-+
-     trace_pci_nvme_shadow_doorbell_cq(cq->cqid, cq->head);
- }
- 
-@@ -6141,15 +6145,21 @@ static uint16_t nvme_admin_cmd(NvmeCtrl *n, NvmeRequest *req)
- 
- static void nvme_update_sq_eventidx(const NvmeSQueue *sq)
- {
--    pci_dma_write(&sq->ctrl->parent_obj, sq->ei_addr, &sq->tail,
--                  sizeof(sq->tail));
-+    uint32_t v = cpu_to_le32(sq->tail);
-+
-+    pci_dma_write(&sq->ctrl->parent_obj, sq->ei_addr, &v, sizeof(v));
-+
-     trace_pci_nvme_eventidx_sq(sq->sqid, sq->tail);
- }
- 
- static void nvme_update_sq_tail(NvmeSQueue *sq)
- {
--    pci_dma_read(&sq->ctrl->parent_obj, sq->db_addr, &sq->tail,
--                 sizeof(sq->tail));
-+    uint32_t v;
-+
-+    pci_dma_read(&sq->ctrl->parent_obj, sq->db_addr, &v, sizeof(v));
-+
-+    sq->tail = le32_to_cpu(v);
-+
-     trace_pci_nvme_shadow_doorbell_sq(sq->sqid, sq->tail);
- }
- 
diff --git a/debian/patches/extra/0013-hw-smbios-fix-field-corruption-in-type-4-table.patch b/debian/patches/extra/0013-hw-smbios-fix-field-corruption-in-type-4-table.patch
deleted file mode 100644
index 901dbfe..0000000
--- a/debian/patches/extra/0013-hw-smbios-fix-field-corruption-in-type-4-table.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Julia Suvorova <jusual@redhat.com>
-Date: Thu, 23 Feb 2023 13:57:47 +0100
-Subject: [PATCH] hw/smbios: fix field corruption in type 4 table
-
-Since table type 4 of SMBIOS version 2.6 is shorter than 3.0, the
-strings which follow immediately after the struct fields have been
-overwritten by unconditional filling of later fields such as core_count2.
-Make these fields dependent on the SMBIOS version.
-
-Fixes: 05e27d74c7 ("hw/smbios: add core_count2 to smbios table type 4")
-Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2169904
-
-Signed-off-by: Julia Suvorova <jusual@redhat.com>
-Message-Id: <20230223125747.254914-1-jusual@redhat.com>
-Reviewed-by: Igor Mammedov <imammedo@redhat.com>
-Reviewed-by: Ani Sinha <ani@anisinha.ca>
-Reviewed-by: Igor Mammedov <imammedo@redhat.com>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-(cherry-picked from commit 60d09b8dc7dd4256d664ad680795cb1327805b2b)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/smbios/smbios.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
-index b4243de735..66a020999b 100644
---- a/hw/smbios/smbios.c
-+++ b/hw/smbios/smbios.c
-@@ -749,14 +749,16 @@ static void smbios_build_type_4_table(MachineState *ms, unsigned instance)
-     t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores;
-     t->core_enabled = t->core_count;
- 
--    t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
--
-     t->thread_count = (ms->smp.threads > 255) ? 0xFF : ms->smp.threads;
--    t->thread_count2 = cpu_to_le16(ms->smp.threads);
- 
-     t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
-     t->processor_family2 = cpu_to_le16(0x01); /* Other */
- 
-+    if (tbl_len == SMBIOS_TYPE_4_LEN_V30) {
-+        t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
-+        t->thread_count2 = cpu_to_le16(ms->smp.threads);
-+    }
-+
-     SMBIOS_BUILD_TABLE_POST;
-     smbios_type4_count++;
- }
diff --git a/debian/patches/extra/0014-virtio-rng-pci-fix-transitional-migration-compat-for.patch b/debian/patches/extra/0014-virtio-rng-pci-fix-transitional-migration-compat-for.patch
deleted file mode 100644
index d44da6b..0000000
--- a/debian/patches/extra/0014-virtio-rng-pci-fix-transitional-migration-compat-for.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
-Date: Tue, 7 Feb 2023 17:49:44 +0000
-Subject: [PATCH] virtio-rng-pci: fix transitional migration compat for vectors
-
-In bad9c5a516 ("virtio-rng-pci: fix migration compat for vectors") I
-fixed the virtio-rng-pci migration compatibility, but it was discovered
-that we also need to fix the other aliases of the device for the
-transitional cases.
-
-Fixes: 9ea02e8f1 ('virtio-rng-pci: Allow setting nvectors, so we can use MSI-X')
-bz: https://bugzilla.redhat.com/show_bug.cgi?id=2162569
-Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
-Message-Id: <20230207174944.138255-1-dgilbert@redhat.com>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-(cherry-picked from commit 62bdb8871512076841f4464f7e26efdc7783f78d)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/core/machine.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/hw/core/machine.c b/hw/core/machine.c
-index cd84579591..4297315984 100644
---- a/hw/core/machine.c
-+++ b/hw/core/machine.c
-@@ -43,6 +43,8 @@
- GlobalProperty hw_compat_7_1[] = {
-     { "virtio-device", "queue_reset", "false" },
-     { "virtio-rng-pci", "vectors", "0" },
-+    { "virtio-rng-pci-transitional", "vectors", "0" },
-+    { "virtio-rng-pci-non-transitional", "vectors", "0" },
- };
- const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
- 
diff --git a/debian/patches/extra/0015-hw-timer-hpet-Fix-expiration-time-overflow.patch b/debian/patches/extra/0015-hw-timer-hpet-Fix-expiration-time-overflow.patch
deleted file mode 100644
index 3c30764..0000000
--- a/debian/patches/extra/0015-hw-timer-hpet-Fix-expiration-time-overflow.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Akihiko Odaki <akihiko.odaki@daynix.com>
-Date: Tue, 31 Jan 2023 12:00:37 +0900
-Subject: [PATCH] hw/timer/hpet: Fix expiration time overflow
-
-The expiration time provided for timer_mod() can overflow if a
-ridiculously large value is set to the comparator register. The
-resulting value can represent a past time after rounded, forcing the
-timer to fire immediately. If the timer is configured as periodic, it
-will rearm the timer again, and form an endless loop.
-
-Check if the expiration value will overflow, and if it will, stop the
-timer instead of rearming the timer with the overflowed time.
-
-This bug was found by Alexander Bulekov when fuzzing igb, a new
-network device emulation:
-https://patchew.org/QEMU/20230129053316.1071513-1-alxndr@bu.edu/
-
-The fixed test case is:
-fuzz/crash_2d7036941dcda1ad4380bb8a9174ed0c949bcefd
-
-Fixes: 16b29ae180 ("Add HPET emulation to qemu (Beth Kon)")
-Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
-Acked-by: Michael S. Tsirkin <mst@redhat.com>
-Message-Id: <20230131030037.18856-1-akihiko.odaki@daynix.com>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-(cherry-picked from commit 37d2bcbc2a4e9c2e9061bec72a32c7e49b9f81ec)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/timer/hpet.c | 19 +++++++++++++------
- 1 file changed, 13 insertions(+), 6 deletions(-)
-
-diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
-index 9520471be2..5f88ffdef8 100644
---- a/hw/timer/hpet.c
-+++ b/hw/timer/hpet.c
-@@ -352,6 +352,16 @@ static const VMStateDescription vmstate_hpet = {
-     }
- };
- 
-+static void hpet_arm(HPETTimer *t, uint64_t ticks)
-+{
-+    if (ticks < ns_to_ticks(INT64_MAX / 2)) {
-+        timer_mod(t->qemu_timer,
-+                  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ticks_to_ns(ticks));
-+    } else {
-+        timer_del(t->qemu_timer);
-+    }
-+}
-+
- /*
-  * timer expiration callback
-  */
-@@ -374,13 +384,11 @@ static void hpet_timer(void *opaque)
-             }
-         }
-         diff = hpet_calculate_diff(t, cur_tick);
--        timer_mod(t->qemu_timer,
--                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (int64_t)ticks_to_ns(diff));
-+        hpet_arm(t, diff);
-     } else if (t->config & HPET_TN_32BIT && !timer_is_periodic(t)) {
-         if (t->wrap_flag) {
-             diff = hpet_calculate_diff(t, cur_tick);
--            timer_mod(t->qemu_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
--                           (int64_t)ticks_to_ns(diff));
-+            hpet_arm(t, diff);
-             t->wrap_flag = 0;
-         }
-     }
-@@ -407,8 +415,7 @@ static void hpet_set_timer(HPETTimer *t)
-             t->wrap_flag = 1;
-         }
-     }
--    timer_mod(t->qemu_timer,
--                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (int64_t)ticks_to_ns(diff));
-+    hpet_arm(t, diff);
- }
- 
- static void hpet_del_timer(HPETTimer *t)
diff --git a/debian/patches/extra/0016-vdpa-stop-all-svq-on-device-deletion.patch b/debian/patches/extra/0016-vdpa-stop-all-svq-on-device-deletion.patch
deleted file mode 100644
index 07166db..0000000
--- a/debian/patches/extra/0016-vdpa-stop-all-svq-on-device-deletion.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
-Date: Thu, 9 Feb 2023 18:00:04 +0100
-Subject: [PATCH] vdpa: stop all svq on device deletion
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Not stopping them leave the device in a bad state when virtio-net
-fronted device is unplugged with device_del monitor command.
-
-This is not triggable in regular poweroff or qemu forces shutdown
-because cleanup is called right after vhost_vdpa_dev_start(false).  But
-devices hot unplug does not call vdpa device cleanups.  This lead to all
-the vhost_vdpa devices without stop the SVQ but the last.
-
-Fix it and clean the code, making it symmetric with
-vhost_vdpa_svqs_start.
-
-Fixes: dff4426fa656 ("vhost: Add Shadow VirtQueue kick forwarding capabilities")
-Reported-by: Lei Yang <leiyang@redhat.com>
-Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
-Message-Id: <20230209170004.899472-1-eperezma@redhat.com>
-Tested-by: Laurent Vivier <lvivier@redhat.com>
-Acked-by: Jason Wang <jasowang@redhat.com>
-(cherry-picked from commit 2e1a9de96b487cf818a22d681cad8d3f5d18dcca)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/virtio/vhost-vdpa.c | 17 ++---------------
- 1 file changed, 2 insertions(+), 15 deletions(-)
-
-diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
-index 7468e44b87..03c78d25d8 100644
---- a/hw/virtio/vhost-vdpa.c
-+++ b/hw/virtio/vhost-vdpa.c
-@@ -707,26 +707,11 @@ static int vhost_vdpa_get_device_id(struct vhost_dev *dev,
-     return ret;
- }
- 
--static void vhost_vdpa_reset_svq(struct vhost_vdpa *v)
--{
--    if (!v->shadow_vqs_enabled) {
--        return;
--    }
--
--    for (unsigned i = 0; i < v->shadow_vqs->len; ++i) {
--        VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
--        vhost_svq_stop(svq);
--    }
--}
--
- static int vhost_vdpa_reset_device(struct vhost_dev *dev)
- {
--    struct vhost_vdpa *v = dev->opaque;
-     int ret;
-     uint8_t status = 0;
- 
--    vhost_vdpa_reset_svq(v);
--
-     ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status);
-     trace_vhost_vdpa_reset_device(dev, status);
-     return ret;
-@@ -1088,6 +1073,8 @@ static void vhost_vdpa_svqs_stop(struct vhost_dev *dev)
- 
-     for (unsigned i = 0; i < v->shadow_vqs->len; ++i) {
-         VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
-+
-+        vhost_svq_stop(svq);
-         vhost_vdpa_svq_unmap_rings(dev, svq);
-     }
- }
diff --git a/debian/patches/extra/0017-vhost-avoid-a-potential-use-of-an-uninitialized-vari.patch b/debian/patches/extra/0017-vhost-avoid-a-potential-use-of-an-uninitialized-vari.patch
deleted file mode 100644
index 8ce1973..0000000
--- a/debian/patches/extra/0017-vhost-avoid-a-potential-use-of-an-uninitialized-vari.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Carlos=20L=C3=B3pez?= <clopez@suse.de>
-Date: Mon, 13 Feb 2023 09:57:47 +0100
-Subject: [PATCH] vhost: avoid a potential use of an uninitialized variable in
- vhost_svq_poll()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-In vhost_svq_poll(), if vhost_svq_get_buf() fails due to a device
-providing invalid descriptors, len is left uninitialized and returned
-to the caller, potentally leaking stack data or causing undefined
-behavior.
-
-Fix this by initializing len to 0.
-
-Found with GCC 13 and -fanalyzer (abridged):
-
-../hw/virtio/vhost-shadow-virtqueue.c: In function ‘vhost_svq_poll’:
-../hw/virtio/vhost-shadow-virtqueue.c:538:12: warning: use of uninitialized value ‘len’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
-  538 |     return len;
-      |            ^~~
-  ‘vhost_svq_poll’: events 1-4
-    |
-    |  522 | size_t vhost_svq_poll(VhostShadowVirtqueue *svq)
-    |      |        ^~~~~~~~~~~~~~
-    |      |        |
-    |      |        (1) entry to ‘vhost_svq_poll’
-    |......
-    |  525 |     uint32_t len;
-    |      |              ~~~
-    |      |              |
-    |      |              (2) region created on stack here
-    |      |              (3) capacity: 4 bytes
-    |......
-    |  528 |         if (vhost_svq_more_used(svq)) {
-    |      |             ~
-    |      |             |
-    |      |             (4) inlined call to ‘vhost_svq_more_used’ from ‘vhost_svq_poll’
-
-    (...)
-
-    |  528 |         if (vhost_svq_more_used(svq)) {
-    |      |            ^~~~~~~~~~~~~~~~~~~~~~~~~
-    |      |            ||
-    |      |            |(8) ...to here
-    |      |            (7) following ‘true’ branch...
-    |......
-    |  537 |     vhost_svq_get_buf(svq, &len);
-    |      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    |      |     |
-    |      |     (9) calling ‘vhost_svq_get_buf’ from ‘vhost_svq_poll’
-    |
-    +--> ‘vhost_svq_get_buf’: events 10-11
-           |
-           |  416 | static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
-           |      |                          ^~~~~~~~~~~~~~~~~
-           |      |                          |
-           |      |                          (10) entry to ‘vhost_svq_get_buf’
-           |......
-           |  423 |     if (!vhost_svq_more_used(svq)) {
-           |      |          ~
-           |      |          |
-           |      |          (11) inlined call to ‘vhost_svq_more_used’ from ‘vhost_svq_get_buf’
-           |
-
-           (...)
-
-           |
-         ‘vhost_svq_get_buf’: event 14
-           |
-           |  423 |     if (!vhost_svq_more_used(svq)) {
-           |      |        ^
-           |      |        |
-           |      |        (14) following ‘false’ branch...
-           |
-         ‘vhost_svq_get_buf’: event 15
-           |
-           |cc1:
-           | (15): ...to here
-           |
-    <------+
-    |
-  ‘vhost_svq_poll’: events 16-17
-    |
-    |  537 |     vhost_svq_get_buf(svq, &len);
-    |      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    |      |     |
-    |      |     (16) returning to ‘vhost_svq_poll’ from ‘vhost_svq_get_buf’
-    |  538 |     return len;
-    |      |            ~~~
-    |      |            |
-    |      |            (17) use of uninitialized value ‘len’ here
-
-Note by  Laurent Vivier <lvivier@redhat.com>:
-
-    The return value is only used to detect an error:
-
-    vhost_svq_poll
-        vhost_vdpa_net_cvq_add
-            vhost_vdpa_net_load_cmd
-                vhost_vdpa_net_load_mac
-                  -> a negative return is only used to detect error
-                vhost_vdpa_net_load_mq
-                  -> a negative return is only used to detect error
-            vhost_vdpa_net_handle_ctrl_avail
-              -> a negative return is only used to detect error
-
-Fixes: d368c0b052ad ("vhost: Do not depend on !NULL VirtQueueElement on vhost_svq_flush")
-Signed-off-by: Carlos López <clopez@suse.de>
-Message-Id: <20230213085747.19956-1-clopez@suse.de>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-(cherry-picked from commit e4dd39c699b7d63a06f686ec06ded8adbee989c1)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/virtio/vhost-shadow-virtqueue.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
-index 5bd14cad96..a723073747 100644
---- a/hw/virtio/vhost-shadow-virtqueue.c
-+++ b/hw/virtio/vhost-shadow-virtqueue.c
-@@ -522,7 +522,7 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq,
- size_t vhost_svq_poll(VhostShadowVirtqueue *svq)
- {
-     int64_t start_us = g_get_monotonic_time();
--    uint32_t len;
-+    uint32_t len = 0;
- 
-     do {
-         if (vhost_svq_more_used(svq)) {
diff --git a/debian/patches/extra/0018-chardev-char-socket-set-s-listener-NULL-in-char_sock.patch b/debian/patches/extra/0018-chardev-char-socket-set-s-listener-NULL-in-char_sock.patch
deleted file mode 100644
index 449bca8..0000000
--- a/debian/patches/extra/0018-chardev-char-socket-set-s-listener-NULL-in-char_sock.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yajun Wu <yajunw@nvidia.com>
-Date: Tue, 14 Feb 2023 10:14:30 +0800
-Subject: [PATCH] chardev/char-socket: set s->listener = NULL in
- char_socket_finalize
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-After live migration with virtio block device, qemu crash at:
-
-	#0  0x000055914f46f795 in object_dynamic_cast_assert (obj=0x559151b7b090, typename=0x55914f80fbc4 "qio-channel", file=0x55914f80fb90 "/images/testvfe/sw/qemu.gerrit/include/io/channel.h", line=30, func=0x55914f80fcb8 <__func__.17257> "QIO_CHANNEL") at ../qom/object.c:872
-	#1  0x000055914f480d68 in QIO_CHANNEL (obj=0x559151b7b090) at /images/testvfe/sw/qemu.gerrit/include/io/channel.h:29
-	#2  0x000055914f4812f8 in qio_net_listener_set_client_func_full (listener=0x559151b7a720, func=0x55914f580b97 <tcp_chr_accept>, data=0x5591519f4ea0, notify=0x0, context=0x0) at ../io/net-listener.c:166
-	#3  0x000055914f580059 in tcp_chr_update_read_handler (chr=0x5591519f4ea0) at ../chardev/char-socket.c:637
-	#4  0x000055914f583dca in qemu_chr_be_update_read_handlers (s=0x5591519f4ea0, context=0x0) at ../chardev/char.c:226
-	#5  0x000055914f57b7c9 in qemu_chr_fe_set_handlers_full (b=0x559152bf23a0, fd_can_read=0x0, fd_read=0x0, fd_event=0x0, be_change=0x0, opaque=0x0, context=0x0, set_open=false, sync_state=true) at ../chardev/char-fe.c:279
-	#6  0x000055914f57b86d in qemu_chr_fe_set_handlers (b=0x559152bf23a0, fd_can_read=0x0, fd_read=0x0, fd_event=0x0, be_change=0x0, opaque=0x0, context=0x0, set_open=false) at ../chardev/char-fe.c:304
-	#7  0x000055914f378caf in vhost_user_async_close (d=0x559152bf21a0, chardev=0x559152bf23a0, vhost=0x559152bf2420, cb=0x55914f2fb8c1 <vhost_user_blk_disconnect>) at ../hw/virtio/vhost-user.c:2725
-	#8  0x000055914f2fba40 in vhost_user_blk_event (opaque=0x559152bf21a0, event=CHR_EVENT_CLOSED) at ../hw/block/vhost-user-blk.c:395
-	#9  0x000055914f58388c in chr_be_event (s=0x5591519f4ea0, event=CHR_EVENT_CLOSED) at ../chardev/char.c:61
-	#10 0x000055914f583905 in qemu_chr_be_event (s=0x5591519f4ea0, event=CHR_EVENT_CLOSED) at ../chardev/char.c:81
-	#11 0x000055914f581275 in char_socket_finalize (obj=0x5591519f4ea0) at ../chardev/char-socket.c:1083
-	#12 0x000055914f46f073 in object_deinit (obj=0x5591519f4ea0, type=0x5591519055c0) at ../qom/object.c:680
-	#13 0x000055914f46f0e5 in object_finalize (data=0x5591519f4ea0) at ../qom/object.c:694
-	#14 0x000055914f46ff06 in object_unref (objptr=0x5591519f4ea0) at ../qom/object.c:1202
-	#15 0x000055914f4715a4 in object_finalize_child_property (obj=0x559151b76c50, name=0x559151b7b250 "char3", opaque=0x5591519f4ea0) at ../qom/object.c:1747
-	#16 0x000055914f46ee86 in object_property_del_all (obj=0x559151b76c50) at ../qom/object.c:632
-	#17 0x000055914f46f0d2 in object_finalize (data=0x559151b76c50) at ../qom/object.c:693
-	#18 0x000055914f46ff06 in object_unref (objptr=0x559151b76c50) at ../qom/object.c:1202
-	#19 0x000055914f4715a4 in object_finalize_child_property (obj=0x559151b6b560, name=0x559151b76630 "chardevs", opaque=0x559151b76c50) at ../qom/object.c:1747
-	#20 0x000055914f46ef67 in object_property_del_child (obj=0x559151b6b560, child=0x559151b76c50) at ../qom/object.c:654
-	#21 0x000055914f46f042 in object_unparent (obj=0x559151b76c50) at ../qom/object.c:673
-	#22 0x000055914f58632a in qemu_chr_cleanup () at ../chardev/char.c:1189
-	#23 0x000055914f16c66c in qemu_cleanup () at ../softmmu/runstate.c:830
-	#24 0x000055914eee7b9e in qemu_default_main () at ../softmmu/main.c:38
-	#25 0x000055914eee7bcc in main (argc=86, argv=0x7ffc97cb8d88) at ../softmmu/main.c:48
-
-In char_socket_finalize after s->listener freed, event callback function
-vhost_user_blk_event will be called to handle CHR_EVENT_CLOSED.
-vhost_user_blk_event is calling qio_net_listener_set_client_func_full which
-is still using s->listener.
-
-Setting s->listener = NULL after object_unref(OBJECT(s->listener)) can
-solve this issue.
-
-Signed-off-by: Yajun Wu <yajunw@nvidia.com>
-Acked-by: Jiri Pirko <jiri@nvidia.com>
-Message-Id: <20230214021430.3638579-1-yajunw@nvidia.com>
-Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-(cherry-picked from commit b8a7f51f59e28d5a8e0c07ed3919cc9695560ed2)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- chardev/char-socket.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/chardev/char-socket.c b/chardev/char-socket.c
-index 879564aa8a..b00efb1482 100644
---- a/chardev/char-socket.c
-+++ b/chardev/char-socket.c
-@@ -1065,6 +1065,7 @@ static void char_socket_finalize(Object *obj)
-         qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
-                                               NULL, chr->gcontext);
-         object_unref(OBJECT(s->listener));
-+        s->listener = NULL;
-     }
-     if (s->tls_creds) {
-         object_unref(OBJECT(s->tls_creds));
diff --git a/debian/patches/extra/0019-intel-iommu-fail-MAP-notifier-without-caching-mode.patch b/debian/patches/extra/0019-intel-iommu-fail-MAP-notifier-without-caching-mode.patch
deleted file mode 100644
index f0f2d21..0000000
--- a/debian/patches/extra/0019-intel-iommu-fail-MAP-notifier-without-caching-mode.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jason Wang <jasowang@redhat.com>
-Date: Thu, 23 Feb 2023 14:59:20 +0800
-Subject: [PATCH] intel-iommu: fail MAP notifier without caching mode
-
-Without caching mode, MAP notifier won't work correctly since guest
-won't send IOTLB update event when it establishes new mappings in the
-I/O page tables. Let's fail the IOMMU notifiers early instead of
-misbehaving silently.
-
-Reviewed-by: Eric Auger <eric.auger@redhat.com>
-Tested-by: Viktor Prutyanov <viktor@daynix.com>
-Signed-off-by: Jason Wang <jasowang@redhat.com>
-Message-Id: <20230223065924.42503-2-jasowang@redhat.com>
-Reviewed-by: Peter Xu <peterx@redhat.com>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-(cherry-picked from commit b8d78277c091f26fdd64f239bc8bb7e55d74cecf)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/i386/intel_iommu.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
-index a08ee85edf..9143376677 100644
---- a/hw/i386/intel_iommu.c
-+++ b/hw/i386/intel_iommu.c
-@@ -3186,6 +3186,13 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
-                          "Snoop Control with vhost or VFIO is not supported");
-         return -ENOTSUP;
-     }
-+    if (!s->caching_mode && (new & IOMMU_NOTIFIER_MAP)) {
-+        error_setg_errno(errp, ENOTSUP,
-+                         "device %02x.%02x.%x requires caching mode",
-+                         pci_bus_num(vtd_as->bus), PCI_SLOT(vtd_as->devfn),
-+                         PCI_FUNC(vtd_as->devfn));
-+        return -ENOTSUP;
-+    }
- 
-     /* Update per-address-space notifier flags */
-     vtd_as->notifier_flags = new;
diff --git a/debian/patches/extra/0020-intel-iommu-fail-DEVIOTLB_UNMAP-without-dt-mode.patch b/debian/patches/extra/0020-intel-iommu-fail-DEVIOTLB_UNMAP-without-dt-mode.patch
deleted file mode 100644
index ce87ea5..0000000
--- a/debian/patches/extra/0020-intel-iommu-fail-DEVIOTLB_UNMAP-without-dt-mode.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jason Wang <jasowang@redhat.com>
-Date: Thu, 23 Feb 2023 14:59:21 +0800
-Subject: [PATCH] intel-iommu: fail DEVIOTLB_UNMAP without dt mode
-
-Without dt mode, device IOTLB notifier won't work since guest won't
-send device IOTLB invalidation descriptor in this case. Let's fail
-early instead of misbehaving silently.
-
-Reviewed-by: Laurent Vivier <lvivier@redhat.com>
-Tested-by: Laurent Vivier <lvivier@redhat.com>
-Tested-by: Viktor Prutyanov <viktor@daynix.com>
-Buglink: https://bugzilla.redhat.com/2156876
-Signed-off-by: Jason Wang <jasowang@redhat.com>
-Message-Id: <20230223065924.42503-3-jasowang@redhat.com>
-Reviewed-by: Peter Xu <peterx@redhat.com>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-(cherry-picked from commit 09adb0e021207b60a0c51a68939b4539d98d3ef3)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/i386/intel_iommu.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
-index 9143376677..d025ef2873 100644
---- a/hw/i386/intel_iommu.c
-+++ b/hw/i386/intel_iommu.c
-@@ -3179,6 +3179,7 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
- {
-     VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
-     IntelIOMMUState *s = vtd_as->iommu_state;
-+    X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
- 
-     /* TODO: add support for VFIO and vhost users */
-     if (s->snoop_control) {
-@@ -3193,6 +3194,13 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
-                          PCI_FUNC(vtd_as->devfn));
-         return -ENOTSUP;
-     }
-+    if (!x86_iommu->dt_supported && (new & IOMMU_NOTIFIER_DEVIOTLB_UNMAP)) {
-+        error_setg_errno(errp, ENOTSUP,
-+                         "device %02x.%02x.%x requires device IOTLB mode",
-+                         pci_bus_num(vtd_as->bus), PCI_SLOT(vtd_as->devfn),
-+                         PCI_FUNC(vtd_as->devfn));
-+        return -ENOTSUP;
-+    }
- 
-     /* Update per-address-space notifier flags */
-     vtd_as->notifier_flags = new;
diff --git a/debian/patches/extra/0023-acpi-cpuhp-fix-guest-visible-maximum-access-size-to-.patch b/debian/patches/extra/0023-acpi-cpuhp-fix-guest-visible-maximum-access-size-to-.patch
deleted file mode 100644
index 345fc4e..0000000
--- a/debian/patches/extra/0023-acpi-cpuhp-fix-guest-visible-maximum-access-size-to-.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Laszlo Ersek <lersek@redhat.com>
-Date: Thu, 5 Jan 2023 17:18:04 +0100
-Subject: [PATCH] acpi: cpuhp: fix guest-visible maximum access size to the
- legacy reg block
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The modern ACPI CPU hotplug interface was introduced in the following
-series (aa1dd39ca307..679dd1a957df), released in v2.7.0:
-
-  1  abd49bc2ed2f docs: update ACPI CPU hotplug spec with new protocol
-  2  16bcab97eb9f pc: piix4/ich9: add 'cpu-hotplug-legacy' property
-  3  5e1b5d93887b acpi: cpuhp: add CPU devices AML with _STA method
-  4  ac35f13ba8f8 pc: acpi: introduce AcpiDeviceIfClass.madt_cpu hook
-  5  d2238cb6781d acpi: cpuhp: implement hot-add parts of CPU hotplug
-                  interface
-  6  8872c25a26cc acpi: cpuhp: implement hot-remove parts of CPU hotplug
-                  interface
-  7  76623d00ae57 acpi: cpuhp: add cpu._OST handling
-  8  679dd1a957df pc: use new CPU hotplug interface since 2.7 machine type
-
-Before patch#1, "docs/specs/acpi_cpu_hotplug.txt" only specified 1-byte
-accesses for the hotplug register block.  Patch#1 preserved the same
-restriction for the legacy register block, but:
-
-- it specified DWORD accesses for some of the modern registers,
-
-- in particular, the switch from the legacy block to the modern block
-  would require a DWORD write to the *legacy* block.
-
-The latter functionality was then implemented in cpu_status_write()
-[hw/acpi/cpu_hotplug.c], in patch#8.
-
-Unfortunately, all DWORD accesses depended on a dormant bug: the one
-introduced in earlier commit a014ed07bd5a ("memory: accept mismatching
-sizes in memory_region_access_valid", 2013-05-29); first released in
-v1.6.0.  Due to commit a014ed07bd5a, the DWORD accesses to the *legacy*
-CPU hotplug register block would work in spite of the above series *not*
-relaxing "valid.max_access_size = 1" in "hw/acpi/cpu_hotplug.c":
-
-> static const MemoryRegionOps AcpiCpuHotplug_ops = {
->     .read = cpu_status_read,
->     .write = cpu_status_write,
->     .endianness = DEVICE_LITTLE_ENDIAN,
->     .valid = {
->         .min_access_size = 1,
->         .max_access_size = 1,
->     },
-> };
-
-Later, in commits e6d0c3ce6895 ("acpi: cpuhp: introduce 'Command data 2'
-field", 2020-01-22) and ae340aa3d256 ("acpi: cpuhp: spec: add typical
-usecases", 2020-01-22), first released in v5.0.0, the modern CPU hotplug
-interface (including the documentation) was extended with another DWORD
-*read* access, namely to the "Command data 2" register, which would be
-important for the guest to confirm whether it managed to switch the
-register block from legacy to modern.
-
-This functionality too silently depended on the bug from commit
-a014ed07bd5a.
-
-In commit 5d971f9e6725 ('memory: Revert "memory: accept mismatching sizes
-in memory_region_access_valid"', 2020-06-26), first released in v5.1.0,
-the bug from commit a014ed07bd5a was fixed (the commit was reverted).
-That swiftly exposed the bug in "AcpiCpuHotplug_ops", still present from
-the v2.7.0 series quoted at the top -- namely the fact that
-"valid.max_access_size = 1" didn't match what the guest was supposed to
-do, according to the spec ("docs/specs/acpi_cpu_hotplug.txt").
-
-The symptom is that the "modern interface negotiation protocol"
-described in commit ae340aa3d256:
-
-> +      Use following steps to detect and enable modern CPU hotplug interface:
-> +        1. Store 0x0 to the 'CPU selector' register,
-> +           attempting to switch to modern mode
-> +        2. Store 0x0 to the 'CPU selector' register,
-> +           to ensure valid selector value
-> +        3. Store 0x0 to the 'Command field' register,
-> +        4. Read the 'Command data 2' register.
-> +           If read value is 0x0, the modern interface is enabled.
-> +           Otherwise legacy or no CPU hotplug interface available
-
-falls apart for the guest: steps 1 and 2 are lost, because they are DWORD
-writes; so no switching happens.  Step 3 (a single-byte write) is not
-lost, but it has no effect; see the condition in cpu_status_write() in
-patch#8.  And step 4 *misleads* the guest into thinking that the switch
-worked: the DWORD read is lost again -- it returns zero to the guest
-without ever reaching the device model, so the guest never learns the
-switch didn't work.
-
-This means that guest behavior centered on the "Command data 2" register
-worked *only* in the v5.0.0 release; it got effectively regressed in
-v5.1.0.
-
-To make things *even more* complicated, the breakage was (and remains, as
-of today) visible with TCG acceleration only.  Commit 5d971f9e6725 makes
-no difference with KVM acceleration -- the DWORD accesses still work,
-despite "valid.max_access_size = 1".
-
-As commit 5d971f9e6725 suggests, fix the problem by raising
-"valid.max_access_size" to 4 -- the spec now clearly instructs the guest
-to perform DWORD accesses to the legacy register block too, for enabling
-(and verifying!) the modern block.  In order to keep compatibility for the
-device model implementation though, set "impl.max_access_size = 1", so
-that wide accesses be split before they reach the legacy read/write
-handlers, like they always have been on KVM, and like they were on TCG
-before 5d971f9e6725 (v5.1.0).
-
-Tested with:
-
-- OVMF IA32 + qemu-system-i386, CPU hotplug/hot-unplug with SMM,
-  intermixed with ACPI S3 suspend/resume, using KVM accel
-  (regression-test);
-
-- OVMF IA32X64 + qemu-system-x86_64, CPU hotplug/hot-unplug with SMM,
-  intermixed with ACPI S3 suspend/resume, using KVM accel
-  (regression-test);
-
-- OVMF IA32 + qemu-system-i386, SMM enabled, using TCG accel; verified the
-  register block switch and the present/possible CPU counting through the
-  modern hotplug interface, during OVMF boot (bugfix test);
-
-- I do not have any testcase (guest payload) for regression-testing CPU
-  hotplug through the *legacy* CPU hotplug register block.
-
-Cc: "Michael S. Tsirkin" <mst@redhat.com>
-Cc: Ani Sinha <ani@anisinha.ca>
-Cc: Ard Biesheuvel <ardb@kernel.org>
-Cc: Igor Mammedov <imammedo@redhat.com>
-Cc: Paolo Bonzini <pbonzini@redhat.com>
-Cc: Peter Maydell <peter.maydell@linaro.org>
-Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
-Cc: qemu-stable@nongnu.org
-Ref: "IO port write width clamping differs between TCG and KVM"
-Link: http://mid.mail-archive.com/aaedee84-d3ed-a4f9-21e7-d221a28d1683@redhat.com
-Link: https://lists.gnu.org/archive/html/qemu-devel/2023-01/msg00199.html
-Reported-by: Ard Biesheuvel <ardb@kernel.org>
-Signed-off-by: Laszlo Ersek <lersek@redhat.com>
-Tested-by: Ard Biesheuvel <ardb@kernel.org>
-Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
-Tested-by: Igor Mammedov <imammedo@redhat.com>
-Message-Id: <20230105161804.82486-1-lersek@redhat.com>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-(cherry-picked from commit dab30fbef3896bb652a09d46c37d3f55657cbcbb)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- hw/acpi/cpu_hotplug.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
-index 53654f8638..ff14c3f410 100644
---- a/hw/acpi/cpu_hotplug.c
-+++ b/hw/acpi/cpu_hotplug.c
-@@ -52,6 +52,9 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
-     .endianness = DEVICE_LITTLE_ENDIAN,
-     .valid = {
-         .min_access_size = 1,
-+        .max_access_size = 4,
-+    },
-+    .impl = {
-         .max_access_size = 1,
-     },
- };
diff --git a/debian/patches/extra/0024-tests-tcg-i386-Introduce-and-use-reg_t-consistently.patch b/debian/patches/extra/0024-tests-tcg-i386-Introduce-and-use-reg_t-consistently.patch
deleted file mode 100644
index a4bcb71..0000000
--- a/debian/patches/extra/0024-tests-tcg-i386-Introduce-and-use-reg_t-consistently.patch
+++ /dev/null
@@ -1,286 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Richard Henderson <richard.henderson@linaro.org>
-Date: Sat, 14 Jan 2023 13:05:41 -1000
-Subject: [PATCH] tests/tcg/i386: Introduce and use reg_t consistently
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Define reg_t based on the actual register width.
-Define the inlines using that type.  This will allow
-input registers to 32-bit insns to be set to 64-bit
-values on x86-64, which allows testing various edge cases.
-
-Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
-Message-Id: <20230114230542.3116013-2-richard.henderson@linaro.org>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-(cherry-picked from commit 5d62d6649cd367b5b4a3676e7514d2f9ca86cb03)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- tests/tcg/i386/test-i386-bmi2.c | 182 ++++++++++++++++----------------
- 1 file changed, 93 insertions(+), 89 deletions(-)
-
-diff --git a/tests/tcg/i386/test-i386-bmi2.c b/tests/tcg/i386/test-i386-bmi2.c
-index 5fadf47510..3c3ef85513 100644
---- a/tests/tcg/i386/test-i386-bmi2.c
-+++ b/tests/tcg/i386/test-i386-bmi2.c
-@@ -3,34 +3,40 @@
- #include <stdint.h>
- #include <stdio.h>
- 
-+#ifdef __x86_64
-+typedef uint64_t reg_t;
-+#else
-+typedef uint32_t reg_t;
-+#endif
-+
- #define insn1q(name, arg0)                                                           \
--static inline uint64_t name##q(uint64_t arg0)                                        \
-+static inline reg_t name##q(reg_t arg0)                                              \
- {                                                                                    \
--    uint64_t result64;                                                               \
-+    reg_t result64;                                                                  \
-     asm volatile (#name "q   %1, %0" : "=r"(result64) : "rm"(arg0));                 \
-     return result64;                                                                 \
- }
- 
- #define insn1l(name, arg0)                                                           \
--static inline uint32_t name##l(uint32_t arg0)                                        \
-+static inline reg_t name##l(reg_t arg0)                                              \
- {                                                                                    \
--    uint32_t result32;                                                               \
-+    reg_t result32;                                                                  \
-     asm volatile (#name "l   %k1, %k0" : "=r"(result32) : "rm"(arg0));               \
-     return result32;                                                                 \
- }
- 
- #define insn2q(name, arg0, c0, arg1, c1)                                             \
--static inline uint64_t name##q(uint64_t arg0, uint64_t arg1)                         \
-+static inline reg_t name##q(reg_t arg0, reg_t arg1)                                  \
- {                                                                                    \
--    uint64_t result64;                                                               \
-+    reg_t result64;                                                                  \
-     asm volatile (#name "q   %2, %1, %0" : "=r"(result64) : c0(arg0), c1(arg1));     \
-     return result64;                                                                 \
- }
- 
- #define insn2l(name, arg0, c0, arg1, c1)                                             \
--static inline uint32_t name##l(uint32_t arg0, uint32_t arg1)                         \
-+static inline reg_t name##l(reg_t arg0, reg_t arg1)                                  \
- {                                                                                    \
--    uint32_t result32;                                                               \
-+    reg_t result32;                                                                  \
-     asm volatile (#name "l   %k2, %k1, %k0" : "=r"(result32) : c0(arg0), c1(arg1));  \
-     return result32;                                                                 \
- }
-@@ -65,130 +71,128 @@ insn1l(blsr, src)
- int main(int argc, char *argv[]) {
-     uint64_t ehlo = 0x202020204f4c4845ull;
-     uint64_t mask = 0xa080800302020001ull;
--    uint32_t result32;
-+    reg_t result;
- 
- #ifdef __x86_64
--    uint64_t result64;
--
-     /* 64 bits */
--    result64 = andnq(mask, ehlo);
--    assert(result64 == 0x002020204d4c4844);
-+    result = andnq(mask, ehlo);
-+    assert(result == 0x002020204d4c4844);
- 
--    result64 = pextq(ehlo, mask);
--    assert(result64 == 133);
-+    result = pextq(ehlo, mask);
-+    assert(result == 133);
- 
--    result64 = pdepq(result64, mask);
--    assert(result64 == (ehlo & mask));
-+    result = pdepq(result, mask);
-+    assert(result == (ehlo & mask));
- 
--    result64 = pextq(-1ull, mask);
--    assert(result64 == 511); /* mask has 9 bits set */
-+    result = pextq(-1ull, mask);
-+    assert(result == 511); /* mask has 9 bits set */
- 
--    result64 = pdepq(-1ull, mask);
--    assert(result64 == mask);
-+    result = pdepq(-1ull, mask);
-+    assert(result == mask);
- 
--    result64 = bextrq(mask, 0x3f00);
--    assert(result64 == (mask & ~INT64_MIN));
-+    result = bextrq(mask, 0x3f00);
-+    assert(result == (mask & ~INT64_MIN));
- 
--    result64 = bextrq(mask, 0x1038);
--    assert(result64 == 0xa0);
-+    result = bextrq(mask, 0x1038);
-+    assert(result == 0xa0);
- 
--    result64 = bextrq(mask, 0x10f8);
--    assert(result64 == 0);
-+    result = bextrq(mask, 0x10f8);
-+    assert(result == 0);
- 
--    result64 = blsiq(0x30);
--    assert(result64 == 0x10);
-+    result = blsiq(0x30);
-+    assert(result == 0x10);
- 
--    result64 = blsiq(0x30ull << 32);
--    assert(result64 == 0x10ull << 32);
-+    result = blsiq(0x30ull << 32);
-+    assert(result == 0x10ull << 32);
- 
--    result64 = blsmskq(0x30);
--    assert(result64 == 0x1f);
-+    result = blsmskq(0x30);
-+    assert(result == 0x1f);
- 
--    result64 = blsrq(0x30);
--    assert(result64 == 0x20);
-+    result = blsrq(0x30);
-+    assert(result == 0x20);
- 
--    result64 = blsrq(0x30ull << 32);
--    assert(result64 == 0x20ull << 32);
-+    result = blsrq(0x30ull << 32);
-+    assert(result == 0x20ull << 32);
- 
--    result64 = bzhiq(mask, 0x3f);
--    assert(result64 == (mask & ~INT64_MIN));
-+    result = bzhiq(mask, 0x3f);
-+    assert(result == (mask & ~INT64_MIN));
- 
--    result64 = bzhiq(mask, 0x1f);
--    assert(result64 == (mask & ~(-1 << 30)));
-+    result = bzhiq(mask, 0x1f);
-+    assert(result == (mask & ~(-1 << 30)));
- 
--    result64 = rorxq(0x2132435465768798, 8);
--    assert(result64 == 0x9821324354657687);
-+    result = rorxq(0x2132435465768798, 8);
-+    assert(result == 0x9821324354657687);
- 
--    result64 = sarxq(0xffeeddccbbaa9988, 8);
--    assert(result64 == 0xffffeeddccbbaa99);
-+    result = sarxq(0xffeeddccbbaa9988, 8);
-+    assert(result == 0xffffeeddccbbaa99);
- 
--    result64 = sarxq(0x77eeddccbbaa9988, 8 | 64);
--    assert(result64 == 0x0077eeddccbbaa99);
-+    result = sarxq(0x77eeddccbbaa9988, 8 | 64);
-+    assert(result == 0x0077eeddccbbaa99);
- 
--    result64 = shrxq(0xffeeddccbbaa9988, 8);
--    assert(result64 == 0x00ffeeddccbbaa99);
-+    result = shrxq(0xffeeddccbbaa9988, 8);
-+    assert(result == 0x00ffeeddccbbaa99);
- 
--    result64 = shrxq(0x77eeddccbbaa9988, 8 | 192);
--    assert(result64 == 0x0077eeddccbbaa99);
-+    result = shrxq(0x77eeddccbbaa9988, 8 | 192);
-+    assert(result == 0x0077eeddccbbaa99);
- 
--    result64 = shlxq(0xffeeddccbbaa9988, 8);
--    assert(result64 == 0xeeddccbbaa998800);
-+    result = shlxq(0xffeeddccbbaa9988, 8);
-+    assert(result == 0xeeddccbbaa998800);
- #endif
- 
-     /* 32 bits */
--    result32 = andnl(mask, ehlo);
--    assert(result32 == 0x04d4c4844);
-+    result = andnl(mask, ehlo);
-+    assert(result == 0x04d4c4844);
- 
--    result32 = pextl((uint32_t) ehlo, mask);
--    assert(result32 == 5);
-+    result = pextl((uint32_t) ehlo, mask);
-+    assert(result == 5);
- 
--    result32 = pdepl(result32, mask);
--    assert(result32 == (uint32_t)(ehlo & mask));
-+    result = pdepl(result, mask);
-+    assert(result == (uint32_t)(ehlo & mask));
- 
--    result32 = pextl(-1u, mask);
--    assert(result32 == 7); /* mask has 3 bits set */
-+    result = pextl(-1u, mask);
-+    assert(result == 7); /* mask has 3 bits set */
- 
--    result32 = pdepl(-1u, mask);
--    assert(result32 == (uint32_t)mask);
-+    result = pdepl(-1u, mask);
-+    assert(result == (uint32_t)mask);
- 
--    result32 = bextrl(mask, 0x1f00);
--    assert(result32 == (mask & ~INT32_MIN));
-+    result = bextrl(mask, 0x1f00);
-+    assert(result == (mask & ~INT32_MIN));
- 
--    result32 = bextrl(ehlo, 0x1018);
--    assert(result32 == 0x4f);
-+    result = bextrl(ehlo, 0x1018);
-+    assert(result == 0x4f);
- 
--    result32 = bextrl(mask, 0x1038);
--    assert(result32 == 0);
-+    result = bextrl(mask, 0x1038);
-+    assert(result == 0);
- 
--    result32 = blsil(0xffff);
--    assert(result32 == 1);
-+    result = blsil(0xffff);
-+    assert(result == 1);
- 
--    result32 = blsmskl(0x300);
--    assert(result32 == 0x1ff);
-+    result = blsmskl(0x300);
-+    assert(result == 0x1ff);
- 
--    result32 = blsrl(0xffc);
--    assert(result32 == 0xff8);
-+    result = blsrl(0xffc);
-+    assert(result == 0xff8);
- 
--    result32 = bzhil(mask, 0xf);
--    assert(result32 == 1);
-+    result = bzhil(mask, 0xf);
-+    assert(result == 1);
- 
--    result32 = rorxl(0x65768798, 8);
--    assert(result32 == 0x98657687);
-+    result = rorxl(0x65768798, 8);
-+    assert(result == 0x98657687);
- 
--    result32 = sarxl(0xffeeddcc, 8);
--    assert(result32 == 0xffffeedd);
-+    result = sarxl(0xffeeddcc, 8);
-+    assert(result == 0xffffeedd);
- 
--    result32 = sarxl(0x77eeddcc, 8 | 32);
--    assert(result32 == 0x0077eedd);
-+    result = sarxl(0x77eeddcc, 8 | 32);
-+    assert(result == 0x0077eedd);
- 
--    result32 = shrxl(0xffeeddcc, 8);
--    assert(result32 == 0x00ffeedd);
-+    result = shrxl(0xffeeddcc, 8);
-+    assert(result == 0x00ffeedd);
- 
--    result32 = shrxl(0x77eeddcc, 8 | 128);
--    assert(result32 == 0x0077eedd);
-+    result = shrxl(0x77eeddcc, 8 | 128);
-+    assert(result == 0x0077eedd);
- 
--    result32 = shlxl(0xffeeddcc, 8);
--    assert(result32 == 0xeeddcc00);
-+    result = shlxl(0xffeeddcc, 8);
-+    assert(result == 0xeeddcc00);
- 
-     return 0;
- }
diff --git a/debian/patches/extra/0025-target-i386-Fix-BEXTR-instruction.patch b/debian/patches/extra/0025-target-i386-Fix-BEXTR-instruction.patch
deleted file mode 100644
index 38282b2..0000000
--- a/debian/patches/extra/0025-target-i386-Fix-BEXTR-instruction.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Richard Henderson <richard.henderson@linaro.org>
-Date: Sat, 14 Jan 2023 13:05:42 -1000
-Subject: [PATCH] target/i386: Fix BEXTR instruction
-
-There were two problems here: not limiting the input to operand bits,
-and not correctly handling large extraction length.
-
-Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1372
-Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-Message-Id: <20230114230542.3116013-3-richard.henderson@linaro.org>
-Cc: qemu-stable@nongnu.org
-Fixes: 1d0b926150e5 ("target/i386: move scalar 0F 38 and 0F 3A instruction to new decoder", 2022-10-18)
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-(cherry-picked from commit b14c0098975264ed03144f145bca0179a6763a07)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- target/i386/tcg/emit.c.inc      | 22 +++++++++++-----------
- tests/tcg/i386/test-i386-bmi2.c | 12 ++++++++++++
- 2 files changed, 23 insertions(+), 11 deletions(-)
-
-diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
-index 7037ff91c6..99f6ba6e19 100644
---- a/target/i386/tcg/emit.c.inc
-+++ b/target/i386/tcg/emit.c.inc
-@@ -1078,30 +1078,30 @@ static void gen_ANDN(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
- static void gen_BEXTR(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
- {
-     MemOp ot = decode->op[0].ot;
--    TCGv bound, zero;
-+    TCGv bound = tcg_constant_tl(ot == MO_64 ? 63 : 31);
-+    TCGv zero = tcg_constant_tl(0);
-+    TCGv mone = tcg_constant_tl(-1);
- 
-     /*
-      * Extract START, and shift the operand.
-      * Shifts larger than operand size get zeros.
-      */
-     tcg_gen_ext8u_tl(s->A0, s->T1);
-+    if (TARGET_LONG_BITS == 64 && ot == MO_32) {
-+        tcg_gen_ext32u_tl(s->T0, s->T0);
-+    }
-     tcg_gen_shr_tl(s->T0, s->T0, s->A0);
- 
--    bound = tcg_constant_tl(ot == MO_64 ? 63 : 31);
--    zero = tcg_constant_tl(0);
-     tcg_gen_movcond_tl(TCG_COND_LEU, s->T0, s->A0, bound, s->T0, zero);
- 
-     /*
--     * Extract the LEN into a mask.  Lengths larger than
--     * operand size get all ones.
-+     * Extract the LEN into an inverse mask.  Lengths larger than
-+     * operand size get all zeros, length 0 gets all ones.
-      */
-     tcg_gen_extract_tl(s->A0, s->T1, 8, 8);
--    tcg_gen_movcond_tl(TCG_COND_LEU, s->A0, s->A0, bound, s->A0, bound);
--
--    tcg_gen_movi_tl(s->T1, 1);
--    tcg_gen_shl_tl(s->T1, s->T1, s->A0);
--    tcg_gen_subi_tl(s->T1, s->T1, 1);
--    tcg_gen_and_tl(s->T0, s->T0, s->T1);
-+    tcg_gen_shl_tl(s->T1, mone, s->A0);
-+    tcg_gen_movcond_tl(TCG_COND_LEU, s->T1, s->A0, bound, s->T1, zero);
-+    tcg_gen_andc_tl(s->T0, s->T0, s->T1);
- 
-     gen_op_update1_cc(s);
-     set_cc_op(s, CC_OP_LOGICB + ot);
-diff --git a/tests/tcg/i386/test-i386-bmi2.c b/tests/tcg/i386/test-i386-bmi2.c
-index 3c3ef85513..982d4abda4 100644
---- a/tests/tcg/i386/test-i386-bmi2.c
-+++ b/tests/tcg/i386/test-i386-bmi2.c
-@@ -99,6 +99,9 @@ int main(int argc, char *argv[]) {
-     result = bextrq(mask, 0x10f8);
-     assert(result == 0);
- 
-+    result = bextrq(0xfedcba9876543210ull, 0x7f00);
-+    assert(result == 0xfedcba9876543210ull);
-+
-     result = blsiq(0x30);
-     assert(result == 0x10);
- 
-@@ -164,6 +167,15 @@ int main(int argc, char *argv[]) {
-     result = bextrl(mask, 0x1038);
-     assert(result == 0);
- 
-+    result = bextrl((reg_t)0x8f635a775ad3b9b4ull, 0x3018);
-+    assert(result == 0x5a);
-+
-+    result = bextrl((reg_t)0xfedcba9876543210ull, 0x7f00);
-+    assert(result == 0x76543210u);
-+
-+    result = bextrl(-1, 0);
-+    assert(result == 0);
-+
-     result = blsil(0xffff);
-     assert(result == 1);
- 
diff --git a/debian/patches/extra/0026-target-i386-Fix-C-flag-for-BLSI-BLSMSK-BLSR.patch b/debian/patches/extra/0026-target-i386-Fix-C-flag-for-BLSI-BLSMSK-BLSR.patch
deleted file mode 100644
index c743d55..0000000
--- a/debian/patches/extra/0026-target-i386-Fix-C-flag-for-BLSI-BLSMSK-BLSR.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Richard Henderson <richard.henderson@linaro.org>
-Date: Sat, 14 Jan 2023 08:06:01 -1000
-Subject: [PATCH] target/i386: Fix C flag for BLSI, BLSMSK, BLSR
-
-We forgot to set cc_src, which is used for computing C.
-
-Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1370
-Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-Message-Id: <20230114180601.2993644-1-richard.henderson@linaro.org>
-Cc: qemu-stable@nongnu.org
-Fixes: 1d0b926150e5 ("target/i386: move scalar 0F 38 and 0F 3A instruction to new decoder", 2022-10-18)
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-(cherry-picked from commit 99282098dc74c2055bde5652bde6cf0067d0c370)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- target/i386/tcg/emit.c.inc | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
-index 99f6ba6e19..4d7702c106 100644
---- a/target/i386/tcg/emit.c.inc
-+++ b/target/i386/tcg/emit.c.inc
-@@ -1111,6 +1111,7 @@ static void gen_BLSI(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
- {
-     MemOp ot = decode->op[0].ot;
- 
-+    tcg_gen_mov_tl(cpu_cc_src, s->T0);
-     tcg_gen_neg_tl(s->T1, s->T0);
-     tcg_gen_and_tl(s->T0, s->T0, s->T1);
-     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
-@@ -1121,6 +1122,7 @@ static void gen_BLSMSK(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode
- {
-     MemOp ot = decode->op[0].ot;
- 
-+    tcg_gen_mov_tl(cpu_cc_src, s->T0);
-     tcg_gen_subi_tl(s->T1, s->T0, 1);
-     tcg_gen_xor_tl(s->T0, s->T0, s->T1);
-     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
-@@ -1131,6 +1133,7 @@ static void gen_BLSR(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
- {
-     MemOp ot = decode->op[0].ot;
- 
-+    tcg_gen_mov_tl(cpu_cc_src, s->T0);
-     tcg_gen_subi_tl(s->T1, s->T0, 1);
-     tcg_gen_and_tl(s->T0, s->T0, s->T1);
-     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
diff --git a/debian/patches/extra/0027-target-i386-fix-ADOX-followed-by-ADCX.patch b/debian/patches/extra/0027-target-i386-fix-ADOX-followed-by-ADCX.patch
deleted file mode 100644
index bb108e5..0000000
--- a/debian/patches/extra/0027-target-i386-fix-ADOX-followed-by-ADCX.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Tue, 31 Jan 2023 09:48:03 +0100
-Subject: [PATCH] target/i386: fix ADOX followed by ADCX
-
-When ADCX is followed by ADOX or vice versa, the second instruction's
-carry comes from EFLAGS and the condition codes use the CC_OP_ADCOX
-operation.  Retrieving the carry from EFLAGS is handled by this bit
-of gen_ADCOX:
-
-        tcg_gen_extract_tl(carry_in, cpu_cc_src,
-            ctz32(cc_op == CC_OP_ADCX ? CC_C : CC_O), 1);
-
-Unfortunately, in this case cc_op has been overwritten by the previous
-"if" statement to CC_OP_ADCOX.  This works by chance when the first
-instruction is ADCX; however, if the first instruction is ADOX,
-ADCX will incorrectly take its carry from OF instead of CF.
-
-Fix by moving the computation of the new cc_op at the end of the function.
-The included exhaustive test case fails without this patch and passes
-afterwards.
-
-Because ADCX/ADOX need not be invoked through the VEX prefix, this
-regression bisects to commit 16fc5726a6e2 ("target/i386: reimplement
-0x0f 0x38, add AVX", 2022-10-18).  However, the mistake happened a
-little earlier, when BMI instructions were rewritten using the new
-decoder framework.
-
-Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1471
-Reported-by: Paul Jolly <https://gitlab.com/myitcv>
-Fixes: 1d0b926150e5 ("target/i386: move scalar 0F 38 and 0F 3A instruction to new decoder", 2022-10-18)
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-(cherry-picked from commit 60c7dd22e1383754d5f150bc9f7c2785c662a7b6)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- target/i386/tcg/emit.c.inc       | 20 +++++----
- tests/tcg/i386/Makefile.target   |  6 ++-
- tests/tcg/i386/test-i386-adcox.c | 75 ++++++++++++++++++++++++++++++++
- 3 files changed, 91 insertions(+), 10 deletions(-)
- create mode 100644 tests/tcg/i386/test-i386-adcox.c
-
-diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
-index 4d7702c106..0d7c6e80ae 100644
---- a/target/i386/tcg/emit.c.inc
-+++ b/target/i386/tcg/emit.c.inc
-@@ -1015,6 +1015,7 @@ VSIB_AVX(VPGATHERQ, vpgatherq)
- 
- static void gen_ADCOX(DisasContext *s, CPUX86State *env, MemOp ot, int cc_op)
- {
-+    int opposite_cc_op;
-     TCGv carry_in = NULL;
-     TCGv carry_out = (cc_op == CC_OP_ADCX ? cpu_cc_dst : cpu_cc_src2);
-     TCGv zero;
-@@ -1022,14 +1023,8 @@ static void gen_ADCOX(DisasContext *s, CPUX86State *env, MemOp ot, int cc_op)
-     if (cc_op == s->cc_op || s->cc_op == CC_OP_ADCOX) {
-         /* Re-use the carry-out from a previous round.  */
-         carry_in = carry_out;
--        cc_op = s->cc_op;
--    } else if (s->cc_op == CC_OP_ADCX || s->cc_op == CC_OP_ADOX) {
--        /* Merge with the carry-out from the opposite instruction.  */
--        cc_op = CC_OP_ADCOX;
--    }
--
--    /* If we don't have a carry-in, get it out of EFLAGS.  */
--    if (!carry_in) {
-+    } else {
-+        /* We don't have a carry-in, get it out of EFLAGS.  */
-         if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
-             gen_compute_eflags(s);
-         }
-@@ -1053,7 +1048,14 @@ static void gen_ADCOX(DisasContext *s, CPUX86State *env, MemOp ot, int cc_op)
-         tcg_gen_add2_tl(s->T0, carry_out, s->T0, carry_out, s->T1, zero);
-         break;
-     }
--    set_cc_op(s, cc_op);
-+
-+    opposite_cc_op = cc_op == CC_OP_ADCX ? CC_OP_ADOX : CC_OP_ADCX;
-+    if (s->cc_op == CC_OP_ADCOX || s->cc_op == opposite_cc_op) {
-+        /* Merge with the carry-out from the opposite instruction.  */
-+        set_cc_op(s, CC_OP_ADCOX);
-+    } else {
-+        set_cc_op(s, cc_op);
-+    }
- }
- 
- static void gen_ADCX(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
-diff --git a/tests/tcg/i386/Makefile.target b/tests/tcg/i386/Makefile.target
-index 81831cafbc..bafd8c2180 100644
---- a/tests/tcg/i386/Makefile.target
-+++ b/tests/tcg/i386/Makefile.target
-@@ -14,7 +14,7 @@ config-cc.mak: Makefile
- I386_SRCS=$(notdir $(wildcard $(I386_SRC)/*.c))
- ALL_X86_TESTS=$(I386_SRCS:.c=)
- SKIP_I386_TESTS=test-i386-ssse3 test-avx test-3dnow test-mmx
--X86_64_TESTS:=$(filter test-i386-bmi2 $(SKIP_I386_TESTS), $(ALL_X86_TESTS))
-+X86_64_TESTS:=$(filter test-i386-adcox test-i386-bmi2 $(SKIP_I386_TESTS), $(ALL_X86_TESTS))
- 
- test-i386-sse-exceptions: CFLAGS += -msse4.1 -mfpmath=sse
- run-test-i386-sse-exceptions: QEMU_OPTS += -cpu max
-@@ -28,6 +28,10 @@ test-i386-bmi2: CFLAGS=-O2
- run-test-i386-bmi2: QEMU_OPTS += -cpu max
- run-plugin-test-i386-bmi2-%: QEMU_OPTS += -cpu max
- 
-+test-i386-adcox: CFLAGS=-O2
-+run-test-i386-adcox: QEMU_OPTS += -cpu max
-+run-plugin-test-i386-adcox-%: QEMU_OPTS += -cpu max
-+
- #
- # hello-i386 is a barebones app
- #
-diff --git a/tests/tcg/i386/test-i386-adcox.c b/tests/tcg/i386/test-i386-adcox.c
-new file mode 100644
-index 0000000000..16169efff8
---- /dev/null
-+++ b/tests/tcg/i386/test-i386-adcox.c
-@@ -0,0 +1,75 @@
-+/* See if various BMI2 instructions give expected results */
-+#include <assert.h>
-+#include <stdint.h>
-+#include <stdio.h>
-+
-+#define CC_C 1
-+#define CC_O (1 << 11)
-+
-+#ifdef __x86_64__
-+#define REG uint64_t
-+#else
-+#define REG uint32_t
-+#endif
-+
-+void test_adox_adcx(uint32_t in_c, uint32_t in_o, REG adcx_operand, REG adox_operand)
-+{
-+    REG flags;
-+    REG out_adcx, out_adox;
-+
-+    asm("pushf; pop %0" : "=r"(flags));
-+    flags &= ~(CC_C | CC_O);
-+    flags |= (in_c ? CC_C : 0);
-+    flags |= (in_o ? CC_O : 0);
-+
-+    out_adcx = adcx_operand;
-+    out_adox = adox_operand;
-+    asm("push %0; popf;"
-+        "adox %3, %2;"
-+        "adcx %3, %1;"
-+        "pushf; pop %0"
-+        : "+r" (flags), "+r" (out_adcx), "+r" (out_adox)
-+        : "r" ((REG)-1), "0" (flags), "1" (out_adcx), "2" (out_adox));
-+
-+    assert(out_adcx == in_c + adcx_operand - 1);
-+    assert(out_adox == in_o + adox_operand - 1);
-+    assert(!!(flags & CC_C) == (in_c || adcx_operand));
-+    assert(!!(flags & CC_O) == (in_o || adox_operand));
-+}
-+
-+void test_adcx_adox(uint32_t in_c, uint32_t in_o, REG adcx_operand, REG adox_operand)
-+{
-+    REG flags;
-+    REG out_adcx, out_adox;
-+
-+    asm("pushf; pop %0" : "=r"(flags));
-+    flags &= ~(CC_C | CC_O);
-+    flags |= (in_c ? CC_C : 0);
-+    flags |= (in_o ? CC_O : 0);
-+
-+    out_adcx = adcx_operand;
-+    out_adox = adox_operand;
-+    asm("push %0; popf;"
-+        "adcx %3, %1;"
-+        "adox %3, %2;"
-+        "pushf; pop %0"
-+        : "+r" (flags), "+r" (out_adcx), "+r" (out_adox)
-+        : "r" ((REG)-1), "0" (flags), "1" (out_adcx), "2" (out_adox));
-+
-+    assert(out_adcx == in_c + adcx_operand - 1);
-+    assert(out_adox == in_o + adox_operand - 1);
-+    assert(!!(flags & CC_C) == (in_c || adcx_operand));
-+    assert(!!(flags & CC_O) == (in_o || adox_operand));
-+}
-+
-+int main(int argc, char *argv[]) {
-+    /* try all combinations of input CF, input OF, CF from op1+op2,  OF from op2+op1 */
-+    int i;
-+    for (i = 0; i <= 15; i++) {
-+        printf("%d\n", i);
-+        test_adcx_adox(!!(i & 1), !!(i & 2), !!(i & 4), !!(i & 8));
-+        test_adox_adcx(!!(i & 1), !!(i & 2), !!(i & 4), !!(i & 8));
-+    }
-+    return 0;
-+}
-+
diff --git a/debian/patches/extra/0028-target-i386-Fix-BZHI-instruction.patch b/debian/patches/extra/0028-target-i386-Fix-BZHI-instruction.patch
deleted file mode 100644
index 391817c..0000000
--- a/debian/patches/extra/0028-target-i386-Fix-BZHI-instruction.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Richard Henderson <richard.henderson@linaro.org>
-Date: Sat, 14 Jan 2023 13:32:06 -1000
-Subject: [PATCH] target/i386: Fix BZHI instruction
-
-We did not correctly handle N >= operand size.
-
-Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1374
-Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-Message-Id: <20230114233206.3118472-1-richard.henderson@linaro.org>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-(cherry-picked from commit 9ad2ba6e8e7fc195d0dd0b76ab38bd2fceb1bdd4)
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- target/i386/tcg/emit.c.inc      | 14 +++++++-------
- tests/tcg/i386/test-i386-bmi2.c |  3 +++
- 2 files changed, 10 insertions(+), 7 deletions(-)
-
-diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
-index 0d7c6e80ae..7296f3952c 100644
---- a/target/i386/tcg/emit.c.inc
-+++ b/target/i386/tcg/emit.c.inc
-@@ -1145,20 +1145,20 @@ static void gen_BLSR(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
- static void gen_BZHI(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
- {
-     MemOp ot = decode->op[0].ot;
--    TCGv bound;
-+    TCGv bound = tcg_constant_tl(ot == MO_64 ? 63 : 31);
-+    TCGv zero = tcg_constant_tl(0);
-+    TCGv mone = tcg_constant_tl(-1);
- 
--    tcg_gen_ext8u_tl(s->T1, cpu_regs[s->vex_v]);
--    bound = tcg_constant_tl(ot == MO_64 ? 63 : 31);
-+    tcg_gen_ext8u_tl(s->T1, s->T1);
- 
-     /*
-      * Note that since we're using BMILG (in order to get O
-      * cleared) we need to store the inverse into C.
-      */
--    tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src, s->T1, bound);
--    tcg_gen_movcond_tl(TCG_COND_GT, s->T1, s->T1, bound, bound, s->T1);
-+    tcg_gen_setcond_tl(TCG_COND_LEU, cpu_cc_src, s->T1, bound);
- 
--    tcg_gen_movi_tl(s->A0, -1);
--    tcg_gen_shl_tl(s->A0, s->A0, s->T1);
-+    tcg_gen_shl_tl(s->A0, mone, s->T1);
-+    tcg_gen_movcond_tl(TCG_COND_LEU, s->A0, s->T1, bound, s->A0, zero);
-     tcg_gen_andc_tl(s->T0, s->T0, s->A0);
- 
-     gen_op_update1_cc(s);
-diff --git a/tests/tcg/i386/test-i386-bmi2.c b/tests/tcg/i386/test-i386-bmi2.c
-index 982d4abda4..0244df7987 100644
---- a/tests/tcg/i386/test-i386-bmi2.c
-+++ b/tests/tcg/i386/test-i386-bmi2.c
-@@ -123,6 +123,9 @@ int main(int argc, char *argv[]) {
-     result = bzhiq(mask, 0x1f);
-     assert(result == (mask & ~(-1 << 30)));
- 
-+    result = bzhiq(mask, 0x40);
-+    assert(result == mask);
-+
-     result = rorxq(0x2132435465768798, 8);
-     assert(result == 0x9821324354657687);
- 
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 20c6c18..4926a64 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,10 +14,10 @@ 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 b9647c5ffc..9a16d86344 100644
+index c2dee3f056..9681bd0434 100644
 --- a/block/file-posix.c
 +++ b/block/file-posix.c
-@@ -552,7 +552,7 @@ static QemuOptsList raw_runtime_opts = {
+@@ -553,7 +553,7 @@ static QemuOptsList raw_runtime_opts = {
          {
              .name = "locking",
              .type = QEMU_OPT_STRING,
@@ -26,7 +26,7 @@ index b9647c5ffc..9a16d86344 100644
          },
          {
              .name = "pr-manager",
-@@ -652,7 +652,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
+@@ -653,7 +653,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
          s->use_lock = false;
          break;
      case ON_OFF_AUTO_AUTO:
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 d43d40a..acd23d4 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 dc20b31e9f..5ae04a8693 100644
+index 1448d00afb..d1601d32c1 100644
 --- a/include/net/net.h
 +++ b/include/net/net.h
-@@ -236,8 +236,8 @@ void netdev_add(QemuOpts *opts, Error **errp);
+@@ -258,8 +258,8 @@ void netdev_add(QemuOpts *opts, Error **errp);
  int net_hub_id_for_client(NetClientState *nc, int *id);
  NetClientState *net_hub_port_find(int hub_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 0871fc7..2827fa4 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 d4bc19577a..be7da64f38 100644
+index d243e290d3..3489b05ec4 100644
 --- a/target/i386/cpu.h
 +++ b/target/i386/cpu.h
-@@ -2174,9 +2174,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
+@@ -2203,9 +2203,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 39aedf0..6405a25 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 c3ac20ad43..37774f1c0a 100644
+index 52a59386d7..b20c25aee0 100644
 --- a/ui/spice-core.c
 +++ b/ui/spice-core.c
-@@ -689,32 +689,35 @@ static void qemu_spice_init(void)
+@@ -691,32 +691,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 6c3e281..6f3afdb 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,10 +9,10 @@ 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 7c90f7ba4b..2e03102f00 100644
+index 185a83e5e5..f11a40aa9e 100644
 --- a/block/gluster.c
 +++ b/block/gluster.c
-@@ -42,7 +42,7 @@
+@@ -43,7 +43,7 @@
  #define GLUSTER_DEBUG_DEFAULT       4
  #define GLUSTER_DEBUG_MAX           9
  #define GLUSTER_OPT_LOGFILE         "logfile"
@@ -21,7 +21,7 @@ index 7c90f7ba4b..2e03102f00 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
-@@ -424,6 +424,7 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
+@@ -425,6 +425,7 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
      int old_errno;
      SocketAddressList *server;
      unsigned long long port;
@@ -29,7 +29,7 @@ index 7c90f7ba4b..2e03102f00 100644
  
      glfs = glfs_find_preopened(gconf->volume);
      if (glfs) {
-@@ -466,9 +467,15 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
+@@ -467,9 +468,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 a87a46a..4bdb7b5 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 f826410f40..64a8d7d48b 100644
+index 978671411e..a4749f3b1b 100644
 --- a/block/rbd.c
 +++ b/block/rbd.c
-@@ -820,6 +820,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
+@@ -963,6 +963,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-qmp-add-get_link_status.patch b/debian/patches/pve/0007-PVE-Up-qmp-add-get_link_status.patch
index 22ffc63..50c66f4 100644
--- a/debian/patches/pve/0007-PVE-Up-qmp-add-get_link_status.patch
+++ b/debian/patches/pve/0007-PVE-Up-qmp-add-get_link_status.patch
@@ -13,11 +13,11 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  3 files changed, 44 insertions(+)
 
 diff --git a/net/net.c b/net/net.c
-index 840ad9dca5..28e97c5d85 100644
+index 6492ad530e..33e901cba8 100644
 --- a/net/net.c
 +++ b/net/net.c
-@@ -1372,6 +1372,33 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
-     }
+@@ -1397,6 +1397,33 @@ RxFilterInfoList *qmp_query_rx_filter(const char *name, Error **errp)
+     return filter_list;
  }
  
 +int64_t qmp_get_link_status(const char *name, Error **errp)
@@ -51,7 +51,7 @@ index 840ad9dca5..28e97c5d85 100644
  {
      NetClientState *nc;
 diff --git a/qapi/net.json b/qapi/net.json
-index 522ac582ed..327d7c5a37 100644
+index d6eb30008b..4fe71b149d 100644
 --- a/qapi/net.json
 +++ b/qapi/net.json
 @@ -36,6 +36,21 @@
diff --git a/debian/patches/pve/0008-PVE-Up-glusterfs-allow-partial-reads.patch b/debian/patches/pve/0008-PVE-Up-glusterfs-allow-partial-reads.patch
index 5c731aa..122a07d 100644
--- a/debian/patches/pve/0008-PVE-Up-glusterfs-allow-partial-reads.patch
+++ b/debian/patches/pve/0008-PVE-Up-glusterfs-allow-partial-reads.patch
@@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  1 file changed, 9 insertions(+), 1 deletion(-)
 
 diff --git a/block/gluster.c b/block/gluster.c
-index 2e03102f00..7886c5fe8c 100644
+index f11a40aa9e..6756e6b886 100644
 --- a/block/gluster.c
 +++ b/block/gluster.c
-@@ -57,6 +57,7 @@ typedef struct GlusterAIOCB {
+@@ -58,6 +58,7 @@ typedef struct GlusterAIOCB {
      int ret;
      Coroutine *coroutine;
      AioContext *aio_context;
@@ -27,7 +27,7 @@ index 2e03102f00..7886c5fe8c 100644
  } GlusterAIOCB;
  
  typedef struct BDRVGlusterState {
-@@ -752,8 +753,10 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret,
+@@ -753,8 +754,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 */
@@ -39,7 +39,7 @@ index 2e03102f00..7886c5fe8c 100644
      }
  
      aio_co_schedule(acb->aio_context, acb->coroutine);
-@@ -1022,6 +1025,7 @@ static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs,
+@@ -1021,6 +1024,7 @@ static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs,
      acb.ret = 0;
      acb.coroutine = qemu_coroutine_self();
      acb.aio_context = bdrv_get_aio_context(bs);
@@ -47,7 +47,7 @@ index 2e03102f00..7886c5fe8c 100644
  
      ret = glfs_zerofill_async(s->fd, offset, bytes, gluster_finish_aiocb, &acb);
      if (ret < 0) {
-@@ -1203,9 +1207,11 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
+@@ -1201,9 +1205,11 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
      acb.aio_context = bdrv_get_aio_context(bs);
  
      if (write) {
@@ -59,7 +59,7 @@ index 2e03102f00..7886c5fe8c 100644
          ret = glfs_preadv_async(s->fd, qiov->iov, qiov->niov, offset, 0,
                                  gluster_finish_aiocb, &acb);
      }
-@@ -1268,6 +1274,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
+@@ -1266,6 +1272,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
      acb.ret = 0;
      acb.coroutine = qemu_coroutine_self();
      acb.aio_context = bdrv_get_aio_context(bs);
@@ -67,7 +67,7 @@ index 2e03102f00..7886c5fe8c 100644
  
      ret = glfs_fsync_async(s->fd, gluster_finish_aiocb, &acb);
      if (ret < 0) {
-@@ -1316,6 +1323,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs,
+@@ -1314,6 +1321,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs,
      acb.ret = 0;
      acb.coroutine = qemu_coroutine_self();
      acb.aio_context = bdrv_get_aio_context(bs);
diff --git a/debian/patches/pve/0009-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch b/debian/patches/pve/0009-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
index 7c2e8ba..feb1ef3 100644
--- a/debian/patches/pve/0009-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
+++ b/debian/patches/pve/0009-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
@@ -9,10 +9,10 @@ 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 a9b3a8103c..0bc9f1af59 100644
+index 9aeac69fa6..0919fac1f1 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -3013,7 +3013,8 @@ static int img_info(int argc, char **argv)
+@@ -3059,7 +3059,8 @@ static int img_info(int argc, char **argv)
      list = collect_image_info_list(image_opts, filename, fmt, chain,
                                     force_share);
      if (!list) {
diff --git a/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch b/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
index fb6581b..ffc30d0 100644
--- a/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
+++ b/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
@@ -54,10 +54,10 @@ index 1b1dab5b17..d1616c045a 100644
  
  DEF("info", img_info,
 diff --git a/qemu-img.c b/qemu-img.c
-index 0bc9f1af59..221b9d6a16 100644
+index 0919fac1f1..c584de648c 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -4829,10 +4829,12 @@ static int img_bitmap(int argc, char **argv)
+@@ -4885,10 +4885,12 @@ static int img_bitmap(int argc, char **argv)
  #define C_IF      04
  #define C_OF      010
  #define C_SKIP    020
@@ -70,7 +70,7 @@ index 0bc9f1af59..221b9d6a16 100644
  };
  
  struct DdIo {
-@@ -4908,6 +4910,19 @@ static int img_dd_skip(const char *arg,
+@@ -4964,6 +4966,19 @@ static int img_dd_skip(const char *arg,
      return 0;
  }
  
@@ -90,7 +90,7 @@ index 0bc9f1af59..221b9d6a16 100644
  static int img_dd(int argc, char **argv)
  {
      int ret = 0;
-@@ -4948,6 +4963,7 @@ static int img_dd(int argc, char **argv)
+@@ -5004,6 +5019,7 @@ static int img_dd(int argc, char **argv)
          { "if", img_dd_if, C_IF },
          { "of", img_dd_of, C_OF },
          { "skip", img_dd_skip, C_SKIP },
@@ -98,7 +98,7 @@ index 0bc9f1af59..221b9d6a16 100644
          { NULL, NULL, 0 }
      };
      const struct option long_options[] = {
-@@ -5023,91 +5039,112 @@ static int img_dd(int argc, char **argv)
+@@ -5079,91 +5095,112 @@ static int img_dd(int argc, char **argv)
          arg = NULL;
      }
  
@@ -275,7 +275,7 @@ index 0bc9f1af59..221b9d6a16 100644
      }
  
      if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
-@@ -5124,20 +5161,43 @@ static int img_dd(int argc, char **argv)
+@@ -5180,20 +5217,43 @@ static int img_dd(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/0011-PVE-Up-qemu-img-dd-add-isize-parameter.patch b/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-isize-parameter.patch
index 217b83b..af21381 100644
--- a/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-isize-parameter.patch
+++ b/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-isize-parameter.patch
@@ -16,10 +16,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 221b9d6a16..c1306385a8 100644
+index c584de648c..a57ceeddfe 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -4830,11 +4830,13 @@ static int img_bitmap(int argc, char **argv)
+@@ -4886,11 +4886,13 @@ static int img_bitmap(int argc, char **argv)
  #define C_OF      010
  #define C_SKIP    020
  #define C_OSIZE   040
@@ -33,7 +33,7 @@ index 221b9d6a16..c1306385a8 100644
  };
  
  struct DdIo {
-@@ -4923,6 +4925,19 @@ static int img_dd_osize(const char *arg,
+@@ -4979,6 +4981,19 @@ static int img_dd_osize(const char *arg,
      return 0;
  }
  
@@ -53,7 +53,7 @@ index 221b9d6a16..c1306385a8 100644
  static int img_dd(int argc, char **argv)
  {
      int ret = 0;
-@@ -4937,12 +4952,14 @@ static int img_dd(int argc, char **argv)
+@@ -4993,12 +5008,14 @@ static int img_dd(int argc, char **argv)
      int c, i;
      const char *out_fmt = "raw";
      const char *fmt = NULL;
@@ -69,7 +69,7 @@ index 221b9d6a16..c1306385a8 100644
      };
      struct DdIo in = {
          .bsz = 512, /* Block size is by default 512 bytes */
-@@ -4964,6 +4981,7 @@ static int img_dd(int argc, char **argv)
+@@ -5020,6 +5037,7 @@ static int img_dd(int argc, char **argv)
          { "of", img_dd_of, C_OF },
          { "skip", img_dd_skip, C_SKIP },
          { "osize", img_dd_osize, C_OSIZE },
@@ -77,7 +77,7 @@ index 221b9d6a16..c1306385a8 100644
          { NULL, NULL, 0 }
      };
      const struct option long_options[] = {
-@@ -5160,9 +5178,10 @@ static int img_dd(int argc, char **argv)
+@@ -5216,9 +5234,10 @@ static int img_dd(int argc, char **argv)
  
      in.buf = g_new(uint8_t, in.bsz);
  
@@ -90,7 +90,7 @@ index 221b9d6a16..c1306385a8 100644
          if (blk1) {
              in_ret = blk_pread(blk1, in_pos, bytes, in.buf, 0);
              if (in_ret == 0) {
-@@ -5171,6 +5190,9 @@ static int img_dd(int argc, char **argv)
+@@ -5227,6 +5246,9 @@ static int img_dd(int argc, char **argv)
          } else {
              in_ret = read(STDIN_FILENO, in.buf, bytes);
              if (in_ret == 0) {
diff --git a/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-n-skip_create.patch b/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-n-skip_create.patch
index db8a5c5..376aa67 100644
--- a/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-n-skip_create.patch
+++ b/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-n-skip_create.patch
@@ -65,10 +65,10 @@ index d1616c045a..b5b0bb4467 100644
  
  DEF("info", img_info,
 diff --git a/qemu-img.c b/qemu-img.c
-index c1306385a8..59c403373b 100644
+index a57ceeddfe..06d814e39c 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -4954,7 +4954,7 @@ static int img_dd(int argc, char **argv)
+@@ -5010,7 +5010,7 @@ static int img_dd(int argc, char **argv)
      const char *fmt = NULL;
      int64_t size = 0, readsize = 0;
      int64_t out_pos, in_pos;
@@ -77,7 +77,7 @@ index c1306385a8..59c403373b 100644
      struct DdInfo dd = {
          .flags = 0,
          .count = 0,
-@@ -4992,7 +4992,7 @@ static int img_dd(int argc, char **argv)
+@@ -5048,7 +5048,7 @@ static int img_dd(int argc, char **argv)
          { 0, 0, 0, 0 }
      };
  
@@ -86,7 +86,7 @@ index c1306385a8..59c403373b 100644
          if (c == EOF) {
              break;
          }
-@@ -5012,6 +5012,9 @@ static int img_dd(int argc, char **argv)
+@@ -5068,6 +5068,9 @@ static int img_dd(int argc, char **argv)
          case 'h':
              help();
              break;
@@ -96,7 +96,7 @@ index c1306385a8..59c403373b 100644
          case 'U':
              force_share = true;
              break;
-@@ -5142,13 +5145,15 @@ static int img_dd(int argc, char **argv)
+@@ -5198,13 +5201,15 @@ static int img_dd(int argc, char **argv)
                                  size - in.bsz * in.offset, &error_abort);
          }
  
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 ad3eb76..183c9dc 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
@@ -7,20 +7,62 @@ Actually provide memory information via the query-balloon
 command.
 
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: add BalloonInfo to member name exceptions list]
+[FE: add BalloonInfo to member name exceptions list
+     rebase for 8.0 - moved to hw/core/machine-hmp-cmds.c]
 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
+ hw/core/machine-hmp-cmds.c | 30 +++++++++++++++++++++++++++++-
  hw/virtio/virtio-balloon.c | 33 +++++++++++++++++++++++++++++++--
- monitor/hmp-cmds.c         | 30 +++++++++++++++++++++++++++++-
  qapi/machine.json          | 22 +++++++++++++++++++++-
  qapi/pragma.json           |  1 +
  4 files changed, 82 insertions(+), 4 deletions(-)
 
+diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
+index c3e55ef9e9..0e32e6201f 100644
+--- a/hw/core/machine-hmp-cmds.c
++++ b/hw/core/machine-hmp-cmds.c
+@@ -169,7 +169,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
+         return;
+     }
+ 
+-    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
++    monitor_printf(mon, "balloon: actual=%" PRId64, info->actual >> 20);
++    monitor_printf(mon, " max_mem=%" PRId64, info->max_mem >> 20);
++    if (info->has_total_mem) {
++        monitor_printf(mon, " total_mem=%" PRId64, info->total_mem >> 20);
++    }
++    if (info->has_free_mem) {
++        monitor_printf(mon, " free_mem=%" PRId64, info->free_mem >> 20);
++    }
++
++    if (info->has_mem_swapped_in) {
++        monitor_printf(mon, " mem_swapped_in=%" PRId64, info->mem_swapped_in);
++    }
++    if (info->has_mem_swapped_out) {
++        monitor_printf(mon, " mem_swapped_out=%" PRId64, info->mem_swapped_out);
++    }
++    if (info->has_major_page_faults) {
++        monitor_printf(mon, " major_page_faults=%" PRId64,
++                       info->major_page_faults);
++    }
++    if (info->has_minor_page_faults) {
++        monitor_printf(mon, " minor_page_faults=%" PRId64,
++                       info->minor_page_faults);
++    }
++    if (info->has_last_update) {
++        monitor_printf(mon, " last_update=%" PRId64,
++                       info->last_update);
++    }
++
++    monitor_printf(mon, "\n");
+ 
+     qapi_free_BalloonInfo(info);
+ }
 diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
-index 73ac5eb675..bbfe7eca62 100644
+index 746f07c4d2..a41854b902 100644
 --- a/hw/virtio/virtio-balloon.c
 +++ b/hw/virtio/virtio-balloon.c
-@@ -806,8 +806,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
+@@ -804,8 +804,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;
@@ -60,52 +102,11 @@ index 73ac5eb675..bbfe7eca62 100644
  }
  
  static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
-diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 01b789a79e..480b798963 100644
---- a/monitor/hmp-cmds.c
-+++ b/monitor/hmp-cmds.c
-@@ -696,7 +696,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
-         return;
-     }
- 
--    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
-+    monitor_printf(mon, "balloon: actual=%" PRId64, info->actual >> 20);
-+    monitor_printf(mon, " max_mem=%" PRId64, info->max_mem >> 20);
-+    if (info->has_total_mem) {
-+        monitor_printf(mon, " total_mem=%" PRId64, info->total_mem >> 20);
-+    }
-+    if (info->has_free_mem) {
-+        monitor_printf(mon, " free_mem=%" PRId64, info->free_mem >> 20);
-+    }
-+
-+    if (info->has_mem_swapped_in) {
-+        monitor_printf(mon, " mem_swapped_in=%" PRId64, info->mem_swapped_in);
-+    }
-+    if (info->has_mem_swapped_out) {
-+        monitor_printf(mon, " mem_swapped_out=%" PRId64, info->mem_swapped_out);
-+    }
-+    if (info->has_major_page_faults) {
-+        monitor_printf(mon, " major_page_faults=%" PRId64,
-+                       info->major_page_faults);
-+    }
-+    if (info->has_minor_page_faults) {
-+        monitor_printf(mon, " minor_page_faults=%" PRId64,
-+                       info->minor_page_faults);
-+    }
-+    if (info->has_last_update) {
-+        monitor_printf(mon, " last_update=%" PRId64,
-+                       info->last_update);
-+    }
-+
-+    monitor_printf(mon, "\n");
- 
-     qapi_free_BalloonInfo(info);
- }
 diff --git a/qapi/machine.json b/qapi/machine.json
-index b9228a5e46..10e77a9af3 100644
+index 604b686e59..15f5f86683 100644
 --- a/qapi/machine.json
 +++ b/qapi/machine.json
-@@ -1054,9 +1054,29 @@
+@@ -1056,9 +1056,29 @@
  # @actual: the logical size of the VM in bytes
  #          Formula used: logical_vm_size = vm_ram_size - balloon_size
  #
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 0b7c4cf..e40d67f 100644
--- a/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch
+++ b/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch
@@ -13,13 +13,13 @@ 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 4f4ab30f8c..76fff60a6b 100644
+index b98ff15089..24595f618c 100644
 --- a/hw/core/machine-qmp-cmds.c
 +++ b/hw/core/machine-qmp-cmds.c
-@@ -99,6 +99,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
-         info->hotpluggable_cpus = mc->has_hotpluggable_cpus;
+@@ -103,6 +103,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
          info->numa_mem_supported = mc->numa_mem_supported;
          info->deprecated = !!mc->deprecation_reason;
+         info->acpi = !!object_class_property_find(OBJECT_CLASS(mc), "acpi");
 +
 +        if (strcmp(mc->name, MACHINE_GET_CLASS(current_machine)->name) == 0) {
 +            info->has_is_current = true;
@@ -28,9 +28,9 @@ index 4f4ab30f8c..76fff60a6b 100644
 +
          if (mc->default_cpu_type) {
              info->default_cpu_type = g_strdup(mc->default_cpu_type);
-             info->has_default_cpu_type = true;
+         }
 diff --git a/qapi/machine.json b/qapi/machine.json
-index 10e77a9af3..9156103c8f 100644
+index 15f5f86683..c904280085 100644
 --- a/qapi/machine.json
 +++ b/qapi/machine.json
 @@ -138,6 +138,8 @@
@@ -42,7 +42,7 @@ index 10e77a9af3..9156103c8f 100644
  # @cpu-max: maximum number of CPUs supported by the machine type
  #           (since 1.5)
  #
-@@ -159,7 +161,7 @@
+@@ -161,7 +163,7 @@
  ##
  { 'struct': 'MachineInfo',
    'data': { 'name': 'str', '*alias': 'str',
@@ -50,4 +50,4 @@ index 10e77a9af3..9156103c8f 100644
 +            '*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
              'hotpluggable-cpus': 'bool',  'numa-mem-supported': 'bool',
              'deprecated': 'bool', '*default-cpu-type': 'str',
-             '*default-ram-id': 'str' } }
+             '*default-ram-id': 'str', 'acpi': 'bool' } }
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 5e15d9e..df551da 100644
--- a/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch
+++ b/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch
@@ -6,13 +6,15 @@ Subject: [PATCH] PVE: qapi: modify spice query
 Provide the last ticket in the SpiceInfo struct optionally.
 
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[FE: adapt to QAPI change]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  qapi/ui.json    | 3 +++
- ui/spice-core.c | 5 +++++
- 2 files changed, 8 insertions(+)
+ ui/spice-core.c | 4 ++++
+ 2 files changed, 7 insertions(+)
 
 diff --git a/qapi/ui.json b/qapi/ui.json
-index 0abba3e930..bf8f441227 100644
+index 98322342f7..316d4dc933 100644
 --- a/qapi/ui.json
 +++ b/qapi/ui.json
 @@ -310,11 +310,14 @@
@@ -31,15 +33,14 @@ index 0abba3e930..bf8f441227 100644
    'if': 'CONFIG_SPICE' }
  
 diff --git a/ui/spice-core.c b/ui/spice-core.c
-index 37774f1c0a..367f77f2b4 100644
+index b20c25aee0..26baeb7846 100644
 --- a/ui/spice-core.c
 +++ b/ui/spice-core.c
-@@ -534,6 +534,11 @@ static SpiceInfo *qmp_query_spice_real(Error **errp)
+@@ -548,6 +548,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);
  
 +    if (auth_passwd) {
-+        info->has_ticket = true;
 +        info->ticket =  g_strdup(auth_passwd);
 +    }
 +
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 a1073bd..ce12543 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
@@ -15,19 +15,19 @@ Additionally, allows tracking the current position from the outside
 
 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
- migration/channel-savevm-async.c | 182 +++++++++++++++++++++++++++++++
+ migration/channel-savevm-async.c | 183 +++++++++++++++++++++++++++++++
  migration/channel-savevm-async.h |  51 +++++++++
  migration/meson.build            |   1 +
- 3 files changed, 234 insertions(+)
+ 3 files changed, 235 insertions(+)
  create mode 100644 migration/channel-savevm-async.c
  create mode 100644 migration/channel-savevm-async.h
 
 diff --git a/migration/channel-savevm-async.c b/migration/channel-savevm-async.c
 new file mode 100644
-index 0000000000..06d5484778
+index 0000000000..aab081ce07
 --- /dev/null
 +++ b/migration/channel-savevm-async.c
-@@ -0,0 +1,182 @@
+@@ -0,0 +1,183 @@
 +/*
 + * QIO Channel implementation to be used by savevm-async QMP calls
 + */
@@ -71,6 +71,7 @@ index 0000000000..06d5484778
 +                               size_t niov,
 +                               int **fds,
 +                               size_t *nfds,
++                               int flags,
 +                               Error **errp)
 +{
 +    QIOChannelSavevmAsync *saioc = QIO_CHANNEL_SAVEVM_ASYNC(ioc);
@@ -268,7 +269,7 @@ index 0000000000..17ae2cb261
 +
 +#endif /* QIO_CHANNEL_SAVEVM_ASYNC_H */
 diff --git a/migration/meson.build b/migration/meson.build
-index 690487cf1a..8cac83c06c 100644
+index 0d1bb9f96e..8a142fc7a9 100644
 --- a/migration/meson.build
 +++ b/migration/meson.build
 @@ -13,6 +13,7 @@ softmmu_ss.add(files(
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 3898bd4..7c3f2ce 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
@@ -25,7 +25,8 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 [FE: further improve aborting
      adapt to removal of QEMUFileOps
-     improve condition for entering final stage]
+     improve condition for entering final stage
+     adapt to QAPI and other changes for 8.0]
 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  hmp-commands-info.hx         |  13 +
@@ -33,17 +34,17 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  include/migration/snapshot.h |   2 +
  include/monitor/hmp.h        |   5 +
  migration/meson.build        |   1 +
- migration/savevm-async.c     | 538 +++++++++++++++++++++++++++++++++++
- monitor/hmp-cmds.c           |  57 ++++
+ migration/savevm-async.c     | 535 +++++++++++++++++++++++++++++++++++
+ monitor/hmp-cmds.c           |  58 ++++
  qapi/migration.json          |  34 +++
  qapi/misc.json               |  32 +++
  qemu-options.hx              |  12 +
  softmmu/vl.c                 |  10 +
- 11 files changed, 737 insertions(+)
+ 11 files changed, 735 insertions(+)
  create mode 100644 migration/savevm-async.c
 
 diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
-index 754b1e8408..489c524e9e 100644
+index 47d63d26db..a166bff3d5 100644
 --- a/hmp-commands-info.hx
 +++ b/hmp-commands-info.hx
 @@ -540,6 +540,19 @@ SRST
@@ -67,11 +68,11 @@ index 754b1e8408..489c524e9e 100644
          .name       = "balloon",
          .args_type  = "",
 diff --git a/hmp-commands.hx b/hmp-commands.hx
-index 673e39a697..039be0033d 100644
+index bb85ee1d26..b66d7fc4ab 100644
 --- a/hmp-commands.hx
 +++ b/hmp-commands.hx
-@@ -1815,3 +1815,36 @@ SRST
-   Dump the FDT in dtb format to *filename*.
+@@ -1846,3 +1846,36 @@ SRST
+   List event channels in the guest
  ERST
  #endif
 +
@@ -119,10 +120,10 @@ index e72083b117..c846d37806 100644
 +
  #endif
 diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
-index dfbc0c9a2f..440f86aba8 100644
+index fdb69b7f9c..c012bad741 100644
 --- a/include/monitor/hmp.h
 +++ b/include/monitor/hmp.h
-@@ -27,6 +27,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict);
+@@ -28,6 +28,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);
@@ -130,10 +131,10 @@ index dfbc0c9a2f..440f86aba8 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);
-@@ -81,6 +82,10 @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict);
- void hmp_netdev_del(Monitor *mon, const QDict *qdict);
- void hmp_getfd(Monitor *mon, const QDict *qdict);
- void hmp_closefd(Monitor *mon, const QDict *qdict);
+@@ -94,6 +95,10 @@ 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);
 +void hmp_savevm_start(Monitor *mon, const QDict *qdict);
 +void hmp_snapshot_drive(Monitor *mon, const QDict *qdict);
 +void hmp_delete_drive_snapshot(Monitor *mon, const QDict *qdict);
@@ -142,23 +143,23 @@ index dfbc0c9a2f..440f86aba8 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 8cac83c06c..0842d00cd2 100644
+index 8a142fc7a9..a7824b5266 100644
 --- a/migration/meson.build
 +++ b/migration/meson.build
-@@ -24,6 +24,7 @@ softmmu_ss.add(files(
+@@ -25,6 +25,7 @@ softmmu_ss.add(files(
    'multifd-zlib.c',
    'postcopy-ram.c',
    'savevm.c',
 +  'savevm-async.c',
    'socket.c',
    'tls.c',
- ), gnutls)
+   'threadinfo.c',
 diff --git a/migration/savevm-async.c b/migration/savevm-async.c
 new file mode 100644
-index 0000000000..dc30558713
+index 0000000000..24660af014
 --- /dev/null
 +++ b/migration/savevm-async.c
-@@ -0,0 +1,538 @@
+@@ -0,0 +1,535 @@
 +#include "qemu/osdep.h"
 +#include "migration/channel-savevm-async.h"
 +#include "migration/migration.h"
@@ -231,24 +232,20 @@ index 0000000000..dc30558713
 +        info->bytes = s->bs_pos;
 +        switch (s->state) {
 +        case SAVE_STATE_ERROR:
-+            info->has_status = true;
 +            info->status = g_strdup("failed");
 +            info->has_total_time = true;
 +            info->total_time = s->total_time;
 +            if (s->error) {
-+                info->has_error = true;
 +                info->error = g_strdup(error_get_pretty(s->error));
 +            }
 +            break;
 +        case SAVE_STATE_ACTIVE:
-+            info->has_status = true;
 +            info->status = g_strdup("active");
 +            info->has_total_time = true;
 +            info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
 +                - s->total_time;
 +            break;
 +        case SAVE_STATE_COMPLETED:
-+            info->has_status = true;
 +            info->status = g_strdup("completed");
 +            info->has_total_time = true;
 +            info->total_time = s->total_time;
@@ -405,14 +402,14 @@ index 0000000000..dc30558713
 +    }
 +
 +    while (snap_state.state == SAVE_STATE_ACTIVE) {
-+        uint64_t pending_size, pend_precopy, pend_compatible, pend_postcopy;
++        uint64_t pending_size, pend_precopy, pend_postcopy;
 +
 +        /* pending is expected to be called without iothread lock */
 +        qemu_mutex_unlock_iothread();
-+        qemu_savevm_state_pending(snap_state.file, 0, &pend_precopy, &pend_compatible, &pend_postcopy);
++        qemu_savevm_state_pending_exact(&pend_precopy, &pend_postcopy);
 +        qemu_mutex_lock_iothread();
 +
-+        pending_size = pend_precopy + pend_compatible + pend_postcopy;
++        pending_size = pend_precopy + pend_postcopy;
 +
 +        /*
 +         * A guest reaching this cutoff is dirtying lots of RAM. It should be
@@ -465,7 +462,9 @@ index 0000000000..dc30558713
 +        if (bs_ctx != qemu_get_aio_context()) {
 +            DPRINTF("savevm: async flushing drive %s\n", bs->filename);
 +            aio_co_reschedule_self(bs_ctx);
++            bdrv_graph_co_rdlock();
 +            bdrv_flush(bs);
++            bdrv_graph_co_rdunlock();
 +            aio_co_reschedule_self(qemu_get_aio_context());
 +        }
 +    }
@@ -476,7 +475,7 @@ index 0000000000..dc30558713
 +    qemu_bh_schedule(snap_state.finalize_bh);
 +}
 +
-+void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
++void qmp_savevm_start(const char *statefile, Error **errp)
 +{
 +    Error *local_err = NULL;
 +    MigrationState *ms = migrate_get_current();
@@ -513,7 +512,7 @@ index 0000000000..dc30558713
 +        snap_state.error = NULL;
 +    }
 +
-+    if (!has_statefile) {
++    if (!statefile) {
 +        vm_stop(RUN_STATE_SAVE_VM);
 +        snap_state.state = SAVE_STATE_COMPLETED;
 +        return;
@@ -643,8 +642,7 @@ index 0000000000..dc30558713
 +                               Error **errp)
 +{
 +    // Compatibility to older qemu-server.
-+    (void)qmp_blockdev_snapshot_delete_internal_sync(device, false, NULL,
-+                                                     true, name, errp);
++    (void)qmp_blockdev_snapshot_delete_internal_sync(device, NULL, name, errp);
 +}
 +
 +int load_snapshot_from_blockdev(const char *filename, Error **errp)
@@ -698,19 +696,28 @@ index 0000000000..dc30558713
 +    return ret;
 +}
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 480b798963..cfebfd1db5 100644
+index 6c559b48c8..435f9334f9 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -1906,6 +1906,63 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
-     hmp_handle_error(mon, err);
- }
+@@ -22,6 +22,7 @@
+ #include "monitor/monitor-internal.h"
+ #include "qapi/error.h"
+ #include "qapi/qapi-commands-control.h"
++#include "qapi/qapi-commands-migration.h"
+ #include "qapi/qapi-commands-misc.h"
+ #include "qapi/qmp/qdict.h"
+ #include "qapi/qmp/qerror.h"
+@@ -443,3 +444,60 @@ void hmp_info_mtree(Monitor *mon, const QDict *qdict)
  
+     mtree_info(flatview, dispatch_tree, owner, disabled);
+ }
++
 +void hmp_savevm_start(Monitor *mon, const QDict *qdict)
 +{
 +    Error *errp = NULL;
 +    const char *statefile = qdict_get_try_str(qdict, "statefile");
 +
-+    qmp_savevm_start(statefile != NULL, statefile, &errp);
++    qmp_savevm_start(statefile, &errp);
 +    hmp_handle_error(mon, errp);
 +}
 +
@@ -747,7 +754,7 @@ index 480b798963..cfebfd1db5 100644
 +    SaveVMInfo *info;
 +    info = qmp_query_savevm(NULL);
 +
-+    if (info->has_status) {
++    if (info->status) {
 +        monitor_printf(mon, "savevm status: %s\n", info->status);
 +        monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
 +                       info->total_time);
@@ -757,16 +764,12 @@ index 480b798963..cfebfd1db5 100644
 +    if (info->has_bytes) {
 +        monitor_printf(mon, "Bytes saved: %"PRIu64"\n", info->bytes);
 +    }
-+    if (info->has_error) {
++    if (info->error) {
 +        monitor_printf(mon, "Error: %s\n", info->error);
 +    }
 +}
-+
- void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
- {
-     IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
 diff --git a/qapi/migration.json b/qapi/migration.json
-index 88ecf86ac8..4435866379 100644
+index c84fa10e86..1702b92553 100644
 --- a/qapi/migration.json
 +++ b/qapi/migration.json
 @@ -261,6 +261,40 @@
@@ -811,10 +814,10 @@ index 88ecf86ac8..4435866379 100644
  # @query-migrate:
  #
 diff --git a/qapi/misc.json b/qapi/misc.json
-index 27ef5a2b20..b3ce75dcae 100644
+index 6ddd16ea28..098c9bbe93 100644
 --- a/qapi/misc.json
 +++ b/qapi/misc.json
-@@ -435,6 +435,38 @@
+@@ -469,6 +469,38 @@
  ##
  { 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
  
@@ -854,10 +857,10 @@ index 27ef5a2b20..b3ce75dcae 100644
  # @CommandLineParameterType:
  #
 diff --git a/qemu-options.hx b/qemu-options.hx
-index 7f99d15b23..54efb127c4 100644
+index 59bdf67a2c..fc6cb23dd9 100644
 --- a/qemu-options.hx
 +++ b/qemu-options.hx
-@@ -4391,6 +4391,18 @@ SRST
+@@ -4378,6 +4378,18 @@ SRST
      Start right away with a saved state (``loadvm`` in monitor)
  ERST
  
@@ -877,7 +880,7 @@ index 7f99d15b23..54efb127c4 100644
  DEF("daemonize", 0, QEMU_OPTION_daemonize, \
      "-daemonize      daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
 diff --git a/softmmu/vl.c b/softmmu/vl.c
-index 5f7f6ca981..21f067d115 100644
+index ea20b23e4c..0eabc71b68 100644
 --- a/softmmu/vl.c
 +++ b/softmmu/vl.c
 @@ -164,6 +164,7 @@ static const char *accelerators;
@@ -888,7 +891,7 @@ index 5f7f6ca981..21f067d115 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;
-@@ -2607,6 +2608,12 @@ void qmp_x_exit_preconfig(Error **errp)
+@@ -2612,6 +2613,12 @@ void qmp_x_exit_preconfig(Error **errp)
  
      if (loadvm) {
          load_snapshot(loadvm, NULL, false, NULL, &error_fatal);
@@ -901,7 +904,7 @@ index 5f7f6ca981..21f067d115 100644
      }
      if (replay_mode != REPLAY_MODE_NONE) {
          replay_vmstate_init();
-@@ -3151,6 +3158,9 @@ void qemu_init(int argc, char **argv)
+@@ -3159,6 +3166,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 3095417..e638f0e 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
@@ -19,7 +19,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  3 files changed, 38 insertions(+), 18 deletions(-)
 
 diff --git a/migration/qemu-file.c b/migration/qemu-file.c
-index 2d5f74ffc2..9fd97e6fe1 100644
+index 102ab3b439..5ced17aba4 100644
 --- a/migration/qemu-file.c
 +++ b/migration/qemu-file.c
 @@ -31,8 +31,8 @@
@@ -178,7 +178,7 @@ index 2d5f74ffc2..9fd97e6fe1 100644
      if (blen < compressBound(size)) {
          return -1;
 diff --git a/migration/qemu-file.h b/migration/qemu-file.h
-index fa13d04d78..914f1a63a8 100644
+index 9d0155a2a1..cc06240e8d 100644
 --- a/migration/qemu-file.h
 +++ b/migration/qemu-file.h
 @@ -63,7 +63,9 @@ typedef struct QEMUFileHooks {
@@ -192,10 +192,10 @@ index fa13d04d78..914f1a63a8 100644
  int qemu_fclose(QEMUFile *f);
  
 diff --git a/migration/savevm-async.c b/migration/savevm-async.c
-index dc30558713..a38e7351c1 100644
+index 24660af014..70273a2996 100644
 --- a/migration/savevm-async.c
 +++ b/migration/savevm-async.c
-@@ -374,7 +374,7 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
+@@ -372,7 +372,7 @@ void qmp_savevm_start(const char *statefile, Error **errp)
  
      QIOChannel *ioc = QIO_CHANNEL(qio_channel_savevm_async_new(snap_state.target,
                                                                 &snap_state.bs_pos));
@@ -204,7 +204,7 @@ index dc30558713..a38e7351c1 100644
  
      if (!snap_state.file) {
          error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile);
-@@ -507,7 +507,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
+@@ -504,7 +504,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
      blk_op_block_all(be, blocker);
  
      /* restore the VM state */
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 2ff4d9e..39264ee 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
@@ -4,19 +4,19 @@ Date: Mon, 6 Apr 2020 12:16:47 +0200
 Subject: [PATCH] PVE: block: add the zeroinit block driver filter
 
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[adapt to changed function signatures]
-Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
+[FE: adapt to changed function signatures]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/meson.build |   1 +
- block/zeroinit.c  | 198 ++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 199 insertions(+)
+ block/zeroinit.c  | 200 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 201 insertions(+)
  create mode 100644 block/zeroinit.c
 
 diff --git a/block/meson.build b/block/meson.build
-index b7c68b83a3..020a89ae07 100644
+index 382bec0e7d..253fe49fa2 100644
 --- a/block/meson.build
 +++ b/block/meson.build
-@@ -43,6 +43,7 @@ block_ss.add(files(
+@@ -44,6 +44,7 @@ block_ss.add(files(
    'vmdk.c',
    'vpc.c',
    'write-threshold.c',
@@ -26,10 +26,10 @@ index b7c68b83a3..020a89ae07 100644
  softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
 diff --git a/block/zeroinit.c b/block/zeroinit.c
 new file mode 100644
-index 0000000000..b60e1b84dc
+index 0000000000..1257342724
 --- /dev/null
 +++ b/block/zeroinit.c
-@@ -0,0 +1,198 @@
+@@ -0,0 +1,200 @@
 +/*
 + * Filter to fake a zero-initialized block device.
 + *
@@ -43,6 +43,7 @@ index 0000000000..b60e1b84dc
 +#include "qemu/osdep.h"
 +#include "qapi/error.h"
 +#include "block/block_int.h"
++#include "block/block-io.h"
 +#include "qapi/qmp/qdict.h"
 +#include "qapi/qmp/qstring.h"
 +#include "qemu/cutils.h"
@@ -136,9 +137,9 @@ index 0000000000..b60e1b84dc
 +    (void)s;
 +}
 +
-+static int64_t zeroinit_getlength(BlockDriverState *bs)
++static coroutine_fn int64_t zeroinit_co_getlength(BlockDriverState *bs)
 +{
-+    return bdrv_getlength(bs->file->bs);
++    return bdrv_co_getlength(bs->file->bs);
 +}
 +
 +static int coroutine_fn zeroinit_co_preadv(BlockDriverState *bs,
@@ -190,9 +191,10 @@ index 0000000000..b60e1b84dc
 +    return bdrv_co_truncate(bs->file, offset, exact, prealloc, req_flags, errp);
 +}
 +
-+static int zeroinit_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
++static coroutine_fn int zeroinit_co_get_info(BlockDriverState *bs,
++                                             BlockDriverInfo *bdi)
 +{
-+    return bdrv_get_info(bs->file->bs, bdi);
++    return bdrv_co_get_info(bs->file->bs, bdi);
 +}
 +
 +static BlockDriver bdrv_zeroinit = {
@@ -203,7 +205,7 @@ index 0000000000..b60e1b84dc
 +    .bdrv_parse_filename              = zeroinit_parse_filename,
 +    .bdrv_file_open                   = zeroinit_open,
 +    .bdrv_close                       = zeroinit_close,
-+    .bdrv_getlength                   = zeroinit_getlength,
++    .bdrv_co_getlength                = zeroinit_co_getlength,
 +    .bdrv_child_perm                  = bdrv_default_perms,
 +    .bdrv_co_flush_to_disk            = zeroinit_co_flush,
 +
@@ -219,7 +221,7 @@ index 0000000000..b60e1b84dc
 +    .bdrv_co_pdiscard                 = zeroinit_co_pdiscard,
 +
 +    .bdrv_co_truncate                 = zeroinit_co_truncate,
-+    .bdrv_get_info                    = zeroinit_get_info,
++    .bdrv_co_get_info                 = zeroinit_co_get_info,
 +};
 +
 +static void bdrv_zeroinit_init(void)
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 a3f3e04..3b79a3a 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 54efb127c4..ef456d03ec 100644
+index fc6cb23dd9..3ccedf7c45 100644
 --- a/qemu-options.hx
 +++ b/qemu-options.hx
-@@ -1147,6 +1147,9 @@ backend describes how QEMU handles the data.
+@@ -1150,6 +1150,9 @@ backend describes how QEMU handles the data.
  
  ERST
  
@@ -28,10 +28,10 @@ index 54efb127c4..ef456d03ec 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/softmmu/vl.c b/softmmu/vl.c
-index 21f067d115..9d737e7914 100644
+index 0eabc71b68..323f6a23d4 100644
 --- a/softmmu/vl.c
 +++ b/softmmu/vl.c
-@@ -2643,6 +2643,7 @@ void qemu_init(int argc, char **argv)
+@@ -2648,6 +2648,7 @@ void qemu_init(int argc, char **argv)
      MachineClass *machine_class;
      bool userconfig = true;
      FILE *vmstate_dump_file = NULL;
@@ -39,7 +39,7 @@ index 21f067d115..9d737e7914 100644
  
      qemu_add_opts(&qemu_drive_opts);
      qemu_add_drive_opts(&qemu_legacy_drive_opts);
-@@ -3263,6 +3264,13 @@ void qemu_init(int argc, char **argv)
+@@ -3271,6 +3272,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 27adb3f..3c28401 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
@@ -11,10 +11,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  1 file changed, 9 insertions(+)
 
 diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
-index 2a20982066..7968ad5a93 100644
+index 4a34f03047..59b917e50c 100644
 --- a/hw/intc/apic_common.c
 +++ b/hw/intc/apic_common.c
-@@ -278,6 +278,15 @@ static void apic_reset_common(DeviceState *dev)
+@@ -252,6 +252,15 @@ static void apic_reset_common(DeviceState *dev)
      info->vapic_base_update(s);
  
      apic_init_reset(dev);
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 c476031..e9e9f12 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, 42 insertions(+), 20 deletions(-)
 
 diff --git a/block/file-posix.c b/block/file-posix.c
-index 9a16d86344..bd68df57ad 100644
+index 9681bd0434..044890822d 100644
 --- a/block/file-posix.c
 +++ b/block/file-posix.c
-@@ -2487,6 +2487,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -2483,6 +2483,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
      int fd;
      uint64_t perm, shared;
      int result = 0;
@@ -24,7 +24,7 @@ index 9a16d86344..bd68df57ad 100644
  
      /* Validate options and set default values */
      assert(options->driver == BLOCKDEV_DRIVER_FILE);
-@@ -2527,19 +2528,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -2523,19 +2524,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 9a16d86344..bd68df57ad 100644
      }
  
      /* Clear the file by truncating it to 0 */
-@@ -2593,13 +2597,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -2589,13 +2593,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
      }
  
  out_unlock:
@@ -82,7 +82,7 @@ index 9a16d86344..bd68df57ad 100644
      }
  
  out_close:
-@@ -2624,6 +2630,7 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
+@@ -2619,6 +2625,7 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
      PreallocMode prealloc;
      char *buf = NULL;
      Error *local_err = NULL;
@@ -90,7 +90,7 @@ index 9a16d86344..bd68df57ad 100644
  
      /* Skip file: protocol prefix */
      strstart(filename, "file:", &filename);
-@@ -2646,6 +2653,18 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
+@@ -2641,6 +2648,18 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
          return -EINVAL;
      }
  
@@ -109,7 +109,7 @@ index 9a16d86344..bd68df57ad 100644
      options = (BlockdevCreateOptions) {
          .driver     = BLOCKDEV_DRIVER_FILE,
          .u.file     = {
-@@ -2657,6 +2676,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
+@@ -2652,6 +2671,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 9a16d86344..bd68df57ad 100644
      };
      return raw_co_create(&options, errp);
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 7daaf545be..9e902b96bb 100644
+index 3c945c1f93..542add004b 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -4624,7 +4624,8 @@
+@@ -4740,7 +4740,8 @@
              'size':                 'size',
              '*preallocation':       'PreallocMode',
              '*nocow':               'bool',
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 c7905be..524cdb4 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 8d34caa31d..2df9037c4e 100644
+index cd13b8b0a3..cb1d334bcb 100644
 --- a/hw/core/machine.c
 +++ b/hw/core/machine.c
-@@ -132,7 +132,8 @@ GlobalProperty hw_compat_4_0[] = {
+@@ -141,7 +141,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 2d814da..d88d1d0 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,35 +11,36 @@ 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]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
- hw/core/machine-qmp-cmds.c |  6 ++++++
+ hw/core/machine-qmp-cmds.c |  5 +++++
  include/hw/boards.h        |  2 ++
  qapi/machine.json          |  4 +++-
  softmmu/vl.c               | 25 +++++++++++++++++++++++++
- 4 files changed, 36 insertions(+), 1 deletion(-)
+ 4 files changed, 35 insertions(+), 1 deletion(-)
 
 diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
-index 76fff60a6b..ec9201fb9a 100644
+index 24595f618c..ee9cb0cd04 100644
 --- a/hw/core/machine-qmp-cmds.c
 +++ b/hw/core/machine-qmp-cmds.c
-@@ -103,6 +103,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
+@@ -107,6 +107,11 @@ MachineInfoList *qmp_query_machines(Error **errp)
          if (strcmp(mc->name, MACHINE_GET_CLASS(current_machine)->name) == 0) {
              info->has_is_current = true;
              info->is_current = true;
 +
 +            // PVE version string only exists for current machine
 +            if (mc->pve_version) {
-+                info->has_pve_version = true;
 +                info->pve_version = g_strdup(mc->pve_version);
 +            }
          }
  
          if (mc->default_cpu_type) {
 diff --git a/include/hw/boards.h b/include/hw/boards.h
-index 90f1dd3aeb..14d60520d9 100644
+index 6fbbfd56c8..61a526e97d 100644
 --- a/include/hw/boards.h
 +++ b/include/hw/boards.h
-@@ -230,6 +230,8 @@ struct MachineClass {
+@@ -232,6 +232,8 @@ struct MachineClass {
      const char *desc;
      const char *deprecation_reason;
  
@@ -49,29 +50,29 @@ index 90f1dd3aeb..14d60520d9 100644
      void (*reset)(MachineState *state, ShutdownCause reason);
      void (*wakeup)(MachineState *state);
 diff --git a/qapi/machine.json b/qapi/machine.json
-index 9156103c8f..f4fb1b2c9c 100644
+index c904280085..47f3facdb2 100644
 --- a/qapi/machine.json
 +++ b/qapi/machine.json
-@@ -157,6 +157,8 @@
+@@ -159,6 +159,8 @@
  #
- # @default-ram-id: the default ID of initial RAM memory backend (since 5.2)
+ # @acpi: machine type supports ACPI (since 8.0)
  #
 +# @pve-version: custom PVE version suffix specified as 'machine+pveN'
 +#
  # Since: 1.2
  ##
  { 'struct': 'MachineInfo',
-@@ -164,7 +166,7 @@
+@@ -166,7 +168,7 @@
              '*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
              'hotpluggable-cpus': 'bool',  'numa-mem-supported': 'bool',
              'deprecated': 'bool', '*default-cpu-type': 'str',
--            '*default-ram-id': 'str' } }
-+            '*default-ram-id': 'str', '*pve-version': 'str' } }
+-            '*default-ram-id': 'str', 'acpi': 'bool' } }
++            '*default-ram-id': 'str', 'acpi': 'bool', '*pve-version': 'str' } }
  
  ##
  # @query-machines:
 diff --git a/softmmu/vl.c b/softmmu/vl.c
-index 9d737e7914..a64eee2fad 100644
+index 323f6a23d4..25abdc9da7 100644
 --- a/softmmu/vl.c
 +++ b/softmmu/vl.c
 @@ -1578,6 +1578,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
@@ -94,7 +95,7 @@ index 9d737e7914..a64eee2fad 100644
      g_slist_free(machines);
      if (local_err) {
          error_append_hint(&local_err, "Use -machine help to list supported machines\n");
-@@ -3205,12 +3211,31 @@ void qemu_init(int argc, char **argv)
+@@ -3213,12 +3219,31 @@ void qemu_init(int argc, char **argv)
              case QEMU_OPTION_machine:
                  {
                      bool help;
diff --git a/debian/patches/pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch b/debian/patches/pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch
index 5f2638d..ef3fb89 100644
--- a/debian/patches/pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch
+++ b/debian/patches/pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch
@@ -25,7 +25,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  1 file changed, 4 insertions(+), 4 deletions(-)
 
 diff --git a/block/backup.c b/block/backup.c
-index 6a9ad97a53..9b0151c5be 100644
+index db3791f4d1..39410dcf8d 100644
 --- a/block/backup.c
 +++ b/block/backup.c
 @@ -237,8 +237,8 @@ static void backup_init_bcs_bitmap(BackupBlockJob *job)
@@ -48,7 +48,7 @@ index 6a9ad97a53..9b0151c5be 100644
      if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
          int64_t offset = 0;
          int64_t count;
-@@ -492,6 +490,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -495,6 +493,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
      block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
                         &error_abort);
  
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 7735ab9..b356f34 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
@@ -20,10 +20,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
  create mode 100644 vma.h
 
 diff --git a/block/meson.build b/block/meson.build
-index 020a89ae07..4feae20e37 100644
+index 253fe49fa2..744b698a82 100644
 --- a/block/meson.build
 +++ b/block/meson.build
-@@ -46,6 +46,8 @@ block_ss.add(files(
+@@ -47,6 +47,8 @@ block_ss.add(files(
    'zeroinit.c',
  ), zstd, zlib, gnutls)
  
@@ -33,10 +33,10 @@ index 020a89ae07..4feae20e37 100644
  softmmu_ss.add(files('block-ram-registrar.c'))
  
 diff --git a/meson.build b/meson.build
-index 5c6b5a1c75..e8cf7e3d78 100644
+index c44d05a13f..b9bc31b01c 100644
 --- a/meson.build
 +++ b/meson.build
-@@ -1525,6 +1525,8 @@ keyutils = dependency('libkeyutils', required: false,
+@@ -1527,6 +1527,8 @@ keyutils = dependency('libkeyutils', required: false,
  
  has_gettid = cc.has_function('gettid')
  
@@ -45,7 +45,7 @@ index 5c6b5a1c75..e8cf7e3d78 100644
  # libselinux
  selinux = dependency('libselinux',
                       required: get_option('selinux'),
-@@ -3596,6 +3598,9 @@ if have_tools
+@@ -3645,6 +3647,9 @@ if have_tools
                 dependencies: [blockdev, qemuutil, gnutls, 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 0d7931f..cc4a679 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
@@ -9,21 +9,23 @@ Subject: [PATCH] PVE-Backup: add backup-dump block driver
 - job.c: make job_should_pause non-static
 
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[FE: adapt to coroutine changes]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
- block/backup-dump.c              | 167 +++++++++++++++++++++++++++++++
+ block/backup-dump.c              | 168 +++++++++++++++++++++++++++++++
  block/backup.c                   |  30 ++----
  block/meson.build                |   1 +
  include/block/block_int-common.h |  35 +++++++
  job.c                            |   3 +-
- 5 files changed, 213 insertions(+), 23 deletions(-)
+ 5 files changed, 214 insertions(+), 23 deletions(-)
  create mode 100644 block/backup-dump.c
 
 diff --git a/block/backup-dump.c b/block/backup-dump.c
 new file mode 100644
-index 0000000000..04718a94e2
+index 0000000000..232a094426
 --- /dev/null
 +++ b/block/backup-dump.c
-@@ -0,0 +1,167 @@
+@@ -0,0 +1,168 @@
 +/*
 + * BlockDriver to send backup data stream to a callback function
 + *
@@ -45,7 +47,8 @@ index 0000000000..04718a94e2
 +    void           *dump_cb_data;
 +} BDRVBackupDumpState;
 +
-+static int qemu_backup_dump_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
++static coroutine_fn int qemu_backup_dump_co_get_info(BlockDriverState *bs,
++                                                     BlockDriverInfo *bdi)
 +{
 +    BDRVBackupDumpState *s = bs->opaque;
 +
@@ -86,7 +89,7 @@ index 0000000000..04718a94e2
 +    /* Nothing to do. */
 +}
 +
-+static int64_t qemu_backup_dump_getlength(BlockDriverState *bs)
++static coroutine_fn int64_t qemu_backup_dump_co_getlength(BlockDriverState *bs)
 +{
 +    BDRVBackupDumpState *s = bs->opaque;
 +
@@ -146,8 +149,8 @@ index 0000000000..04718a94e2
 +
 +    .bdrv_close                   = qemu_backup_dump_close,
 +    .bdrv_has_zero_init           = bdrv_has_zero_init_1,
-+    .bdrv_getlength               = qemu_backup_dump_getlength,
-+    .bdrv_get_info                = qemu_backup_dump_get_info,
++    .bdrv_co_getlength            = qemu_backup_dump_co_getlength,
++    .bdrv_co_get_info             = qemu_backup_dump_co_get_info,
 +
 +    .bdrv_co_writev               = qemu_backup_dump_co_writev,
 +
@@ -192,7 +195,7 @@ index 0000000000..04718a94e2
 +    return bs;
 +}
 diff --git a/block/backup.c b/block/backup.c
-index 9b0151c5be..6e8f6e67b3 100644
+index 39410dcf8d..af87fa6aa9 100644
 --- a/block/backup.c
 +++ b/block/backup.c
 @@ -29,28 +29,6 @@
@@ -224,7 +227,7 @@ index 9b0151c5be..6e8f6e67b3 100644
  static const BlockJobDriver backup_job_driver;
  
  static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
-@@ -454,6 +432,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -457,6 +435,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
      }
  
      cluster_size = block_copy_cluster_size(bcs);
@@ -240,7 +243,7 @@ index 9b0151c5be..6e8f6e67b3 100644
      if (perf->max_chunk && perf->max_chunk < cluster_size) {
          error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
 diff --git a/block/meson.build b/block/meson.build
-index 4feae20e37..0d7023fc82 100644
+index 744b698a82..f580f95395 100644
 --- a/block/meson.build
 +++ b/block/meson.build
 @@ -4,6 +4,7 @@ block_ss.add(files(
@@ -252,18 +255,18 @@ index 4feae20e37..0d7023fc82 100644
    'blkdebug.c',
    'blklogwrites.c',
 diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
-index 31ae91e56e..37b64bcd93 100644
+index f01bb8b617..d7ffd1826e 100644
 --- a/include/block/block_int-common.h
 +++ b/include/block/block_int-common.h
 @@ -26,6 +26,7 @@
  
- #include "block/accounting.h"
- #include "block/block.h"
+ #include "block/aio.h"
+ #include "block/block-common.h"
 +#include "block/block-copy.h"
- #include "block/aio-wait.h"
- #include "qemu/queue.h"
- #include "qemu/coroutine.h"
-@@ -64,6 +65,40 @@
+ #include "block/block-global-state.h"
+ #include "block/snapshot.h"
+ #include "qemu/iov.h"
+@@ -60,6 +61,40 @@
  
  #define BLOCK_PROBE_BUF_SIZE        512
  
diff --git a/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch b/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
index 36ca351..add2222 100644
--- a/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
+++ b/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
@@ -8,7 +8,8 @@ Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
 [FE: add new force parameter to job_cancel_sync calls
-     adapt for new job lock mechanism replacing AioContext locks]
+     adapt for new job lock mechanism replacing AioContext locks
+     adapt to QAPI changes]
 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/meson.build              |   5 +
@@ -18,23 +19,23 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  hmp-commands.hx                |  29 +
  include/monitor/hmp.h          |   3 +
  meson.build                    |   1 +
- monitor/hmp-cmds.c             |  44 ++
- proxmox-backup-client.c        | 176 ++++++
- proxmox-backup-client.h        |  59 ++
- pve-backup.c                   | 956 +++++++++++++++++++++++++++++++++
+ monitor/hmp-cmds.c             |  45 ++
+ proxmox-backup-client.c        | 176 +++++++
+ proxmox-backup-client.h        |  59 +++
+ pve-backup.c                   | 938 +++++++++++++++++++++++++++++++++
  qapi/block-core.json           | 109 ++++
  qapi/common.json               |  13 +
  qapi/machine.json              |  15 +-
- 14 files changed, 1445 insertions(+), 13 deletions(-)
+ 14 files changed, 1428 insertions(+), 13 deletions(-)
  create mode 100644 proxmox-backup-client.c
  create mode 100644 proxmox-backup-client.h
  create mode 100644 pve-backup.c
 
 diff --git a/block/meson.build b/block/meson.build
-index 0d7023fc82..e995ae72b9 100644
+index f580f95395..5bcebb934b 100644
 --- a/block/meson.build
 +++ b/block/meson.build
-@@ -48,6 +48,11 @@ block_ss.add(files(
+@@ -49,6 +49,11 @@ block_ss.add(files(
  ), zstd, zlib, gnutls)
  
  block_ss.add(files('../vma-writer.c'), libuuid)
@@ -47,12 +48,12 @@ index 0d7023fc82..e995ae72b9 100644
  softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
  softmmu_ss.add(files('block-ram-registrar.c'))
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index b6135e9bfe..477044c54a 100644
+index 2846083546..947d4f3df0 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1015,3 +1015,36 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
-     g_free(sn_tab);
-     g_free(global_snapshots);
+@@ -1027,3 +1027,36 @@ 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);
  }
 +
 +void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
@@ -75,32 +76,32 @@ index b6135e9bfe..477044c54a 100644
 +
 +    qmp_backup(
 +        backup_file,
-+        false, NULL, // PBS password
-+        false, NULL, // PBS keyfile
-+        false, NULL, // PBS key_password
-+        false, NULL, // PBS fingerprint
-+        false, NULL, // PBS backup-id
++        NULL, // PBS password
++        NULL, // PBS keyfile
++        NULL, // PBS key_password
++        NULL, // PBS fingerprint
++        NULL, // PBS backup-id
 +        false, 0, // PBS backup-time
 +        true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
-+        false, NULL, false, NULL, !!devlist,
++        NULL, NULL,
 +        devlist, qdict_haskey(qdict, "speed"), speed, &error);
 +
 +    hmp_handle_error(mon, error);
 +}
 diff --git a/blockdev.c b/blockdev.c
-index 756e980889..bc8d67b290 100644
+index 47c70eeb91..3b95f54b64 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -36,6 +36,7 @@
- #include "hw/block/block.h"
+@@ -37,6 +37,7 @@
  #include "block/blockjob.h"
+ #include "block/dirty-bitmap.h"
  #include "block/qdict.h"
 +#include "block/blockjob_int.h"
  #include "block/throttle-groups.h"
  #include "monitor/monitor.h"
  #include "qemu/error-report.h"
 diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
-index 489c524e9e..bc1d46d845 100644
+index a166bff3d5..4b75966c2e 100644
 --- a/hmp-commands-info.hx
 +++ b/hmp-commands-info.hx
 @@ -486,6 +486,20 @@ SRST
@@ -125,7 +126,7 @@ index 489c524e9e..bc1d46d845 100644
      {
          .name       = "usernet",
 diff --git a/hmp-commands.hx b/hmp-commands.hx
-index 039be0033d..fcf9461295 100644
+index b66d7fc4ab..9b6b8e2e9c 100644
 --- a/hmp-commands.hx
 +++ b/hmp-commands.hx
 @@ -101,6 +101,35 @@ ERST
@@ -165,10 +166,10 @@ index 039be0033d..fcf9461295 100644
  
      {
 diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
-index 440f86aba8..350527e599 100644
+index c012bad741..2e504db706 100644
 --- a/include/monitor/hmp.h
 +++ b/include/monitor/hmp.h
-@@ -31,6 +31,7 @@ void hmp_info_savevm(Monitor *mon, const QDict *qdict);
+@@ -32,6 +32,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);
@@ -176,20 +177,20 @@ index 440f86aba8..350527e599 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);
-@@ -74,6 +75,8 @@ void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict);
- void hmp_set_password(Monitor *mon, const QDict *qdict);
- void hmp_expire_password(Monitor *mon, const QDict *qdict);
- void hmp_change(Monitor *mon, const QDict *qdict);
+@@ -84,6 +85,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);
 +void hmp_backup(Monitor *mon, const QDict *qdict);
 +void hmp_backup_cancel(Monitor *mon, const QDict *qdict);
  void hmp_migrate(Monitor *mon, const QDict *qdict);
  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 e8cf7e3d78..782756162c 100644
+index b9bc31b01c..b12ef9f8d4 100644
 --- a/meson.build
 +++ b/meson.build
-@@ -1526,6 +1526,7 @@ keyutils = dependency('libkeyutils', required: false,
+@@ -1528,6 +1528,7 @@ keyutils = dependency('libkeyutils', required: false,
  has_gettid = cc.has_function('gettid')
  
  libuuid = cc.find_library('uuid', required: true)
@@ -198,11 +199,19 @@ index e8cf7e3d78..782756162c 100644
  # libselinux
  selinux = dependency('libselinux',
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index cfebfd1db5..a40b25e906 100644
+index 435f9334f9..9e1bd57aeb 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -199,6 +199,50 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
-     qapi_free_MouseInfoList(mice_list);
+@@ -21,6 +21,7 @@
+ #include "qemu/help_option.h"
+ #include "monitor/monitor-internal.h"
+ #include "qapi/error.h"
++#include "qapi/qapi-commands-block-core.h"
+ #include "qapi/qapi-commands-control.h"
+ #include "qapi/qapi-commands-migration.h"
+ #include "qapi/qapi-commands-misc.h"
+@@ -144,6 +145,50 @@ void hmp_sync_profile(Monitor *mon, const QDict *qdict)
+     }
  }
  
 +void hmp_info_backup(Monitor *mon, const QDict *qdict)
@@ -216,8 +225,8 @@ index cfebfd1db5..a40b25e906 100644
 +       return;
 +    }
 +
-+    if (info->has_status) {
-+        if (info->has_errmsg) {
++    if (info->status) {
++        if (info->errmsg) {
 +            monitor_printf(mon, "Backup status: %s - %s\n",
 +                           info->status, info->errmsg);
 +        } else {
@@ -225,7 +234,7 @@ index cfebfd1db5..a40b25e906 100644
 +        }
 +    }
 +
-+    if (info->has_backup_file) {
++    if (info->backup_file) {
 +        monitor_printf(mon, "Start time: %s", ctime(&info->start_time));
 +        if (info->end_time) {
 +            monitor_printf(mon, "End time: %s", ctime(&info->end_time));
@@ -249,9 +258,9 @@ index cfebfd1db5..a40b25e906 100644
 +    qapi_free_BackupStatus(info);
 +}
 +
- void hmp_info_migrate(Monitor *mon, const QDict *qdict)
+ void hmp_exit_preconfig(Monitor *mon, const QDict *qdict)
  {
-     MigrationInfo *info;
+     Error *err = NULL;
 diff --git a/proxmox-backup-client.c b/proxmox-backup-client.c
 new file mode 100644
 index 0000000000..a8f6653a81
@@ -501,10 +510,10 @@ index 0000000000..1dda8b7d8f
 +#endif /* PROXMOX_BACKUP_CLIENT_H */
 diff --git a/pve-backup.c b/pve-backup.c
 new file mode 100644
-index 0000000000..6af212b9b4
+index 0000000000..bb51c030bd
 --- /dev/null
 +++ b/pve-backup.c
-@@ -0,0 +1,956 @@
+@@ -0,0 +1,938 @@
 +#include "proxmox-backup-client.h"
 +#include "vma.h"
 +
@@ -512,6 +521,7 @@ index 0000000000..6af212b9b4
 +#include "qemu/module.h"
 +#include "sysemu/block-backend.h"
 +#include "sysemu/blockdev.h"
++#include "block/block_int-global-state.h"
 +#include "block/blockjob.h"
 +#include "qapi/qapi-commands-block.h"
 +#include "qapi/qmp/qerror.h"
@@ -1020,25 +1030,17 @@ index 0000000000..6af212b9b4
 +
 +typedef struct QmpBackupTask {
 +    const char *backup_file;
-+    bool has_password;
 +    const char *password;
-+    bool has_keyfile;
 +    const char *keyfile;
-+    bool has_key_password;
 +    const char *key_password;
-+    bool has_backup_id;
 +    const char *backup_id;
 +    bool has_backup_time;
 +    const char *fingerprint;
-+    bool has_fingerprint;
 +    int64_t backup_time;
 +    bool has_format;
 +    BackupFormat format;
-+    bool has_config_file;
 +    const char *config_file;
-+    bool has_firewall_file;
 +    const char *firewall_file;
-+    bool has_devlist;
 +    const char *devlist;
 +    bool has_speed;
 +    int64_t speed;
@@ -1079,7 +1081,7 @@ index 0000000000..6af212b9b4
 +    /* Todo: try to auto-detect format based on file name */
 +    BackupFormat format = task->has_format ? task->format : BACKUP_FORMAT_VMA;
 +
-+    if (task->has_devlist) {
++    if (task->devlist) {
 +        devs = g_strsplit_set(task->devlist, ",;:", -1);
 +
 +        gchar **d = devs;
@@ -1144,11 +1146,11 @@ index 0000000000..6af212b9b4
 +    uuid_generate(uuid);
 +
 +    if (format == BACKUP_FORMAT_PBS) {
-+        if (!task->has_password) {
++        if (!task->password) {
 +            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
 +            goto err;
 +        }
-+        if (!task->has_backup_id) {
++        if (!task->backup_id) {
 +            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
 +            goto err;
 +        }
@@ -1166,10 +1168,10 @@ index 0000000000..6af212b9b4
 +            task->backup_id,
 +            task->backup_time,
 +            dump_cb_block_size,
-+            task->has_password ? task->password : NULL,
-+            task->has_keyfile ? task->keyfile : NULL,
-+            task->has_key_password ? task->key_password : NULL,
-+            task->has_fingerprint ? task->fingerprint : NULL,
++            task->password,
++            task->keyfile,
++            task->key_password,
++            task->fingerprint,
 +            &pbs_err);
 +
 +        if (!pbs) {
@@ -1264,7 +1266,7 @@ index 0000000000..6af212b9b4
 +
 +
 +    /* add configuration file to archive */
-+    if (task->has_config_file) {
++    if (task->config_file) {
 +        if (pvebackup_co_add_config(task->config_file, config_name, format, backup_dir,
 +                                    vmaw, pbs, task->errp) != 0) {
 +            goto err;
@@ -1272,7 +1274,7 @@ index 0000000000..6af212b9b4
 +    }
 +
 +    /* add firewall file to archive */
-+    if (task->has_firewall_file) {
++    if (task->firewall_file) {
 +        if (pvebackup_co_add_config(task->firewall_file, firewall_name, format, backup_dir,
 +                                    vmaw, pbs, task->errp) != 0) {
 +            goto err;
@@ -1360,37 +1362,30 @@ index 0000000000..6af212b9b4
 +
 +UuidInfo *qmp_backup(
 +    const char *backup_file,
-+    bool has_password, const char *password,
-+    bool has_keyfile, const char *keyfile,
-+    bool has_key_password, const char *key_password,
-+    bool has_fingerprint, const char *fingerprint,
-+    bool has_backup_id, const char *backup_id,
++    const char *password,
++    const char *keyfile,
++    const char *key_password,
++    const char *fingerprint,
++    const char *backup_id,
 +    bool has_backup_time, int64_t backup_time,
 +    bool has_format, BackupFormat format,
-+    bool has_config_file, const char *config_file,
-+    bool has_firewall_file, const char *firewall_file,
-+    bool has_devlist, const char *devlist,
++    const char *config_file,
++    const char *firewall_file,
++    const char *devlist,
 +    bool has_speed, int64_t speed, Error **errp)
 +{
 +    QmpBackupTask task = {
 +        .backup_file = backup_file,
-+        .has_password = has_password,
 +        .password = password,
-+        .has_key_password = has_key_password,
 +        .key_password = key_password,
-+        .has_fingerprint = has_fingerprint,
 +        .fingerprint = fingerprint,
-+        .has_backup_id = has_backup_id,
 +        .backup_id = backup_id,
 +        .has_backup_time = has_backup_time,
 +        .backup_time = backup_time,
 +        .has_format = has_format,
 +        .format = format,
-+        .has_config_file = has_config_file,
 +        .config_file = config_file,
-+        .has_firewall_file = has_firewall_file,
 +        .firewall_file = firewall_file,
-+        .has_devlist = has_devlist,
 +        .devlist = devlist,
 +        .has_speed = has_speed,
 +        .speed = speed,
@@ -1424,22 +1419,18 @@ index 0000000000..6af212b9b4
 +        return info;
 +    }
 +
-+    info->has_status = true;
 +    info->has_start_time = true;
 +    info->start_time = backup_state.stat.start_time;
 +
 +    if (backup_state.stat.backup_file) {
-+        info->has_backup_file = true;
 +        info->backup_file = g_strdup(backup_state.stat.backup_file);
 +    }
 +
-+    info->has_uuid = true;
 +    info->uuid = g_strdup(backup_state.stat.uuid_str);
 +
 +    if (backup_state.stat.end_time) {
 +        if (backup_state.stat.error) {
 +            info->status = g_strdup("error");
-+            info->has_errmsg = true;
 +            info->errmsg = g_strdup(error_get_pretty(backup_state.stat.error));
 +        } else {
 +            info->status = g_strdup("done");
@@ -1462,10 +1453,10 @@ index 0000000000..6af212b9b4
 +    return info;
 +}
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 9e902b96bb..c3b6b93472 100644
+index 542add004b..16fb4c5ea0 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -740,6 +740,115 @@
+@@ -835,6 +835,115 @@
  { 'command': 'query-block', 'returns': ['BlockInfo'],
    'allow-preconfig': true }
  
@@ -1603,7 +1594,7 @@ index 356db3f670..aae8a3b682 100644
 +##
 +{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} }
 diff --git a/qapi/machine.json b/qapi/machine.json
-index f4fb1b2c9c..0d6ee836ed 100644
+index 47f3facdb2..46760978ae 100644
 --- a/qapi/machine.json
 +++ b/qapi/machine.json
 @@ -4,6 +4,8 @@
@@ -1615,7 +1606,7 @@ index f4fb1b2c9c..0d6ee836ed 100644
  ##
  # = Machines
  ##
-@@ -226,19 +228,6 @@
+@@ -228,19 +230,6 @@
  ##
  { 'command': 'query-target', 'returns': 'TargetInfo' }
  
diff --git a/debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch b/debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
index 422f840..2d29a8d 100644
--- a/debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
+++ b/debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
@@ -12,10 +12,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  create mode 100644 pbs-restore.c
 
 diff --git a/meson.build b/meson.build
-index 782756162c..63ea813a9a 100644
+index b12ef9f8d4..8ec21bba90 100644
 --- a/meson.build
 +++ b/meson.build
-@@ -3602,6 +3602,10 @@ if have_tools
+@@ -3651,6 +3651,10 @@ if have_tools
    vma = executable('vma', files('vma.c', 'vma-reader.c') + genh,
                     dependencies: [authz, block, crypto, io, qom], install: true)
  
diff --git a/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch b/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
index 6d225ba..f28236a 100644
--- a/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
+++ b/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
@@ -24,27 +24,27 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  monitor/hmp-cmds.c             |  45 ++++++++++----
  proxmox-backup-client.c        |   3 +-
  proxmox-backup-client.h        |   1 +
- pve-backup.c                   | 103 ++++++++++++++++++++++++++++++---
+ pve-backup.c                   | 104 ++++++++++++++++++++++++++++++---
  qapi/block-core.json           |  12 +++-
- 6 files changed, 142 insertions(+), 23 deletions(-)
+ 6 files changed, 143 insertions(+), 23 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 477044c54a..556af25861 100644
+index 947d4f3df0..bcba630f12 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1042,6 +1042,7 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
-         false, NULL, // PBS fingerprint
-         false, NULL, // PBS backup-id
+@@ -1054,6 +1054,7 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
+         NULL, // PBS fingerprint
+         NULL, // PBS backup-id
          false, 0, // PBS backup-time
 +        false, false, // PBS incremental
          true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
-         false, NULL, false, NULL, !!devlist,
+         NULL, NULL,
          devlist, qdict_haskey(qdict, "speed"), speed, &error);
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index a40b25e906..670f783515 100644
+index 9e1bd57aeb..087161a967 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -225,19 +225,42 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
+@@ -171,19 +171,42 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
              monitor_printf(mon, "End time: %s", ctime(&info->end_time));
          }
  
@@ -132,10 +132,18 @@ index 1dda8b7d8f..8cbf645b2c 100644
  
  
 diff --git a/pve-backup.c b/pve-backup.c
-index 3d28975eaa..abd7062afe 100644
+index bb51c030bd..cfdeb50f23 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -28,6 +28,8 @@
+@@ -7,6 +7,7 @@
+ #include "sysemu/blockdev.h"
+ #include "block/block_int-global-state.h"
+ #include "block/blockjob.h"
++#include "block/dirty-bitmap.h"
+ #include "qapi/qapi-commands-block.h"
+ #include "qapi/qmp/qerror.h"
+ 
+@@ -29,6 +30,8 @@
   *
   */
  
@@ -144,7 +152,7 @@ index 3d28975eaa..abd7062afe 100644
  static struct PVEBackupState {
      struct {
          // Everithing accessed from qmp_backup_query command is protected using lock
-@@ -39,7 +41,9 @@ static struct PVEBackupState {
+@@ -40,7 +43,9 @@ static struct PVEBackupState {
          uuid_t uuid;
          char uuid_str[37];
          size_t total;
@@ -154,7 +162,7 @@ index 3d28975eaa..abd7062afe 100644
          size_t zero_bytes;
      } stat;
      int64_t speed;
-@@ -66,6 +70,7 @@ typedef struct PVEBackupDevInfo {
+@@ -67,6 +72,7 @@ typedef struct PVEBackupDevInfo {
      uint8_t dev_id;
      bool completed;
      char targetfile[PATH_MAX];
@@ -162,7 +170,7 @@ index 3d28975eaa..abd7062afe 100644
      BlockDriverState *target;
  } PVEBackupDevInfo;
  
-@@ -107,11 +112,12 @@ static bool pvebackup_error_or_canceled(void)
+@@ -108,11 +114,12 @@ static bool pvebackup_error_or_canceled(void)
      return error_or_canceled;
  }
  
@@ -176,7 +184,7 @@ index 3d28975eaa..abd7062afe 100644
      qemu_mutex_unlock(&backup_state.stat.lock);
  }
  
-@@ -150,7 +156,8 @@ pvebackup_co_dump_pbs_cb(
+@@ -151,7 +158,8 @@ pvebackup_co_dump_pbs_cb(
          pvebackup_propagate_error(local_err);
          return pbs_res;
      } else {
@@ -186,7 +194,7 @@ index 3d28975eaa..abd7062afe 100644
      }
  
      return size;
-@@ -210,11 +217,11 @@ pvebackup_co_dump_vma_cb(
+@@ -211,11 +219,11 @@ pvebackup_co_dump_vma_cb(
          } else {
              if (remaining >= VMA_CLUSTER_SIZE) {
                  assert(ret == VMA_CLUSTER_SIZE);
@@ -200,7 +208,7 @@ index 3d28975eaa..abd7062afe 100644
                  remaining = 0;
              }
          }
-@@ -250,6 +257,18 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
+@@ -251,6 +259,18 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
              if (local_err != NULL) {
                  pvebackup_propagate_error(local_err);
              }
@@ -219,7 +227,7 @@ index 3d28975eaa..abd7062afe 100644
          }
  
          proxmox_backup_disconnect(backup_state.pbs);
-@@ -305,6 +324,12 @@ static void pvebackup_complete_cb(void *opaque, int ret)
+@@ -306,6 +326,12 @@ static void pvebackup_complete_cb(void *opaque, int ret)
      // remove self from job queue
      backup_state.di_list = g_list_remove(backup_state.di_list, di);
  
@@ -232,7 +240,7 @@ index 3d28975eaa..abd7062afe 100644
      g_free(di);
  
      qemu_mutex_unlock(&backup_state.backup_mutex);
-@@ -469,12 +494,18 @@ static bool create_backup_jobs(void) {
+@@ -470,12 +496,18 @@ static bool create_backup_jobs(void) {
  
          assert(di->target != NULL);
  
@@ -253,16 +261,16 @@ index 3d28975eaa..abd7062afe 100644
              JOB_DEFAULT, pvebackup_complete_cb, di, NULL, &local_err);
  
          aio_context_release(aio_context);
-@@ -525,6 +556,8 @@ typedef struct QmpBackupTask {
+@@ -521,6 +553,8 @@ typedef struct QmpBackupTask {
+     bool has_backup_time;
      const char *fingerprint;
-     bool has_fingerprint;
      int64_t backup_time;
 +    bool has_use_dirty_bitmap;
 +    bool use_dirty_bitmap;
      bool has_format;
      BackupFormat format;
-     bool has_config_file;
-@@ -616,6 +649,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     const char *config_file;
+@@ -609,6 +643,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      }
  
      size_t total = 0;
@@ -270,7 +278,7 @@ index 3d28975eaa..abd7062afe 100644
  
      l = di_list;
      while (l) {
-@@ -653,6 +687,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -646,6 +681,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
          int dump_cb_block_size = PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE; // Hardcoded (4M)
          firewall_name = "fw.conf";
  
@@ -279,7 +287,7 @@ index 3d28975eaa..abd7062afe 100644
          char *pbs_err = NULL;
          pbs = proxmox_backup_new(
              task->backup_file,
-@@ -672,7 +708,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -665,7 +702,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              goto err;
          }
  
@@ -289,7 +297,7 @@ index 3d28975eaa..abd7062afe 100644
              goto err;
  
          /* register all devices */
-@@ -683,9 +720,40 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -676,9 +714,40 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
  
              const char *devname = bdrv_get_device_name(di->bs);
  
@@ -332,7 +340,7 @@ index 3d28975eaa..abd7062afe 100644
  
              if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, task->errp))) {
                  goto err;
-@@ -694,6 +762,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -687,6 +756,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              di->dev_id = dev_id;
          }
      } else if (format == BACKUP_FORMAT_VMA) {
@@ -341,7 +349,7 @@ index 3d28975eaa..abd7062afe 100644
          vmaw = vma_writer_create(task->backup_file, uuid, &local_err);
          if (!vmaw) {
              if (local_err) {
-@@ -721,6 +791,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -714,6 +785,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              }
          }
      } else if (format == BACKUP_FORMAT_DIR) {
@@ -350,7 +358,7 @@ index 3d28975eaa..abd7062afe 100644
          if (mkdir(task->backup_file, 0640) != 0) {
              error_setg_errno(task->errp, errno, "can't create directory '%s'\n",
                               task->backup_file);
-@@ -793,8 +865,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -786,8 +859,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      char *uuid_str = g_strdup(backup_state.stat.uuid_str);
  
      backup_state.stat.total = total;
@@ -361,7 +369,7 @@ index 3d28975eaa..abd7062afe 100644
  
      qemu_mutex_unlock(&backup_state.stat.lock);
  
-@@ -818,6 +892,10 @@ err:
+@@ -811,6 +886,10 @@ err:
          PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
          l = g_list_next(l);
  
@@ -372,15 +380,15 @@ index 3d28975eaa..abd7062afe 100644
          if (di->target) {
              bdrv_unref(di->target);
          }
-@@ -859,6 +937,7 @@ UuidInfo *qmp_backup(
-     bool has_fingerprint, const char *fingerprint,
-     bool has_backup_id, const char *backup_id,
+@@ -852,6 +931,7 @@ UuidInfo *qmp_backup(
+     const char *fingerprint,
+     const char *backup_id,
      bool has_backup_time, int64_t backup_time,
 +    bool has_use_dirty_bitmap, bool use_dirty_bitmap,
      bool has_format, BackupFormat format,
-     bool has_config_file, const char *config_file,
-     bool has_firewall_file, const char *firewall_file,
-@@ -877,6 +956,8 @@ UuidInfo *qmp_backup(
+     const char *config_file,
+     const char *firewall_file,
+@@ -866,6 +946,8 @@ UuidInfo *qmp_backup(
          .backup_id = backup_id,
          .has_backup_time = has_backup_time,
          .backup_time = backup_time,
@@ -388,8 +396,8 @@ index 3d28975eaa..abd7062afe 100644
 +        .use_dirty_bitmap = use_dirty_bitmap,
          .has_format = has_format,
          .format = format,
-         .has_config_file = has_config_file,
-@@ -945,10 +1026,14 @@ BackupStatus *qmp_query_backup(Error **errp)
+         .config_file = config_file,
+@@ -927,10 +1009,14 @@ BackupStatus *qmp_query_backup(Error **errp)
  
      info->has_total = true;
      info->total = backup_state.stat.total;
@@ -405,10 +413,10 @@ index 3d28975eaa..abd7062afe 100644
      qemu_mutex_unlock(&backup_state.stat.lock);
  
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index c3b6b93472..992e6c1e3f 100644
+index 16fb4c5ea0..92f90a898a 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -753,8 +753,13 @@
+@@ -848,8 +848,13 @@
  #
  # @total: total amount of bytes involved in the backup process
  #
@@ -422,7 +430,7 @@ index c3b6b93472..992e6c1e3f 100644
  # @zero-bytes: amount of 'zero' bytes detected.
  #
  # @start-time: time (epoch) when backup job started.
-@@ -767,8 +772,8 @@
+@@ -862,8 +867,8 @@
  #
  ##
  { 'struct': 'BackupStatus',
@@ -433,7 +441,7 @@ index c3b6b93472..992e6c1e3f 100644
             '*start-time': 'int', '*end-time': 'int',
             '*backup-file': 'str', '*uuid': 'str' } }
  
-@@ -811,6 +816,8 @@
+@@ -906,6 +911,8 @@
  #
  # @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
  #
@@ -442,7 +450,7 @@ index c3b6b93472..992e6c1e3f 100644
  # Returns: the uuid of the backup job
  #
  ##
-@@ -821,6 +828,7 @@
+@@ -916,6 +923,7 @@
                                      '*fingerprint': 'str',
                                      '*backup-id': 'str',
                                      '*backup-time': 'int',
diff --git a/debian/patches/pve/0032-PVE-various-PBS-fixes.patch b/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
index 104e42d..f4711cd 100644
--- a/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
+++ b/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
@@ -12,40 +12,42 @@ Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 PVE: add zero block handling to PBS dump callback
 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[FE: adapt to QAPI change dropping redundant has_*]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/monitor/block-hmp-cmds.c |  4 ++-
- pve-backup.c                   | 57 +++++++++++++++++++++++++++-------
+ pve-backup.c                   | 54 +++++++++++++++++++++++++++-------
  qapi/block-core.json           |  6 ++++
- 3 files changed, 54 insertions(+), 13 deletions(-)
+ 3 files changed, 52 insertions(+), 12 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 556af25861..a09f722fea 100644
+index bcba630f12..6a6ed6d0e7 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1042,7 +1042,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
-         false, NULL, // PBS fingerprint
-         false, NULL, // PBS backup-id
+@@ -1054,7 +1054,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
+         NULL, // PBS fingerprint
+         NULL, // PBS backup-id
          false, 0, // PBS backup-time
 -        false, false, // PBS incremental
 +        false, false, // PBS use-dirty-bitmap
 +        false, false, // PBS compress
 +        false, false, // PBS encrypt
          true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
-         false, NULL, false, NULL, !!devlist,
+         NULL, NULL,
          devlist, qdict_haskey(qdict, "speed"), speed, &error);
 diff --git a/pve-backup.c b/pve-backup.c
-index abd7062afe..e113ab61b9 100644
+index cfdeb50f23..f1eacbcaf6 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -8,6 +8,7 @@
- #include "block/blockjob.h"
+@@ -10,6 +10,7 @@
+ #include "block/dirty-bitmap.h"
  #include "qapi/qapi-commands-block.h"
  #include "qapi/qmp/qerror.h"
 +#include "qemu/cutils.h"
  
  /* PVE backup state and related function */
  
-@@ -67,6 +68,7 @@ opts_init(pvebackup_init);
+@@ -69,6 +70,7 @@ opts_init(pvebackup_init);
  typedef struct PVEBackupDevInfo {
      BlockDriverState *bs;
      size_t size;
@@ -53,7 +55,7 @@ index abd7062afe..e113ab61b9 100644
      uint8_t dev_id;
      bool completed;
      char targetfile[PATH_MAX];
-@@ -137,10 +139,13 @@ pvebackup_co_dump_pbs_cb(
+@@ -139,10 +141,13 @@ pvebackup_co_dump_pbs_cb(
      PVEBackupDevInfo *di = opaque;
  
      assert(backup_state.pbs);
@@ -67,7 +69,7 @@ index abd7062afe..e113ab61b9 100644
      qemu_co_mutex_lock(&backup_state.dump_callback_mutex);
  
      // avoid deadlock if job is cancelled
-@@ -149,17 +154,29 @@ pvebackup_co_dump_pbs_cb(
+@@ -151,17 +156,29 @@ pvebackup_co_dump_pbs_cb(
          return -1;
      }
  
@@ -105,7 +107,7 @@ index abd7062afe..e113ab61b9 100644
      return size;
  }
  
-@@ -180,6 +197,7 @@ pvebackup_co_dump_vma_cb(
+@@ -182,6 +199,7 @@ pvebackup_co_dump_vma_cb(
      int ret = -1;
  
      assert(backup_state.vmaw);
@@ -113,7 +115,7 @@ index abd7062afe..e113ab61b9 100644
  
      uint64_t remaining = size;
  
-@@ -206,9 +224,7 @@ pvebackup_co_dump_vma_cb(
+@@ -208,9 +226,7 @@ pvebackup_co_dump_vma_cb(
          qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
  
          ++cluster_num;
@@ -124,9 +126,9 @@ index abd7062afe..e113ab61b9 100644
          if (ret < 0) {
              Error *local_err = NULL;
              vma_writer_error_propagate(backup_state.vmaw, &local_err);
-@@ -566,6 +582,10 @@ typedef struct QmpBackupTask {
+@@ -560,6 +576,10 @@ typedef struct QmpBackupTask {
+     const char *config_file;
      const char *firewall_file;
-     bool has_devlist;
      const char *devlist;
 +    bool has_compress;
 +    bool compress;
@@ -135,7 +137,7 @@ index abd7062afe..e113ab61b9 100644
      bool has_speed;
      int64_t speed;
      Error **errp;
-@@ -689,6 +709,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -683,6 +703,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
  
          bool use_dirty_bitmap = task->has_use_dirty_bitmap && task->use_dirty_bitmap;
  
@@ -143,19 +145,16 @@ index abd7062afe..e113ab61b9 100644
          char *pbs_err = NULL;
          pbs = proxmox_backup_new(
              task->backup_file,
-@@ -698,8 +719,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             task->has_password ? task->password : NULL,
-             task->has_keyfile ? task->keyfile : NULL,
-             task->has_key_password ? task->key_password : NULL,
+@@ -692,6 +713,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+             task->password,
+             task->keyfile,
+             task->key_password,
 +            task->has_compress ? task->compress : true,
-+            task->has_encrypt ? task->encrypt : task->has_keyfile,
-             task->has_fingerprint ? task->fingerprint : NULL,
--            &pbs_err);
-+             &pbs_err);
- 
-         if (!pbs) {
-             error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
-@@ -718,6 +741,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
++            task->has_encrypt ? task->encrypt : !!task->keyfile,
+             task->fingerprint,
+             &pbs_err);
+ 
+@@ -712,6 +735,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
              l = g_list_next(l);
  
@@ -164,25 +163,24 @@ index abd7062afe..e113ab61b9 100644
              const char *devname = bdrv_get_device_name(di->bs);
  
              BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
-@@ -938,6 +963,8 @@ UuidInfo *qmp_backup(
-     bool has_backup_id, const char *backup_id,
+@@ -932,6 +957,8 @@ UuidInfo *qmp_backup(
+     const char *backup_id,
      bool has_backup_time, int64_t backup_time,
      bool has_use_dirty_bitmap, bool use_dirty_bitmap,
 +    bool has_compress, bool compress,
 +    bool has_encrypt, bool encrypt,
      bool has_format, BackupFormat format,
-     bool has_config_file, const char *config_file,
-     bool has_firewall_file, const char *firewall_file,
-@@ -948,6 +975,8 @@ UuidInfo *qmp_backup(
+     const char *config_file,
+     const char *firewall_file,
+@@ -941,6 +968,7 @@ UuidInfo *qmp_backup(
+     QmpBackupTask task = {
          .backup_file = backup_file,
-         .has_password = has_password,
          .password = password,
-+        .has_keyfile = has_keyfile,
 +        .keyfile = keyfile,
-         .has_key_password = has_key_password,
          .key_password = key_password,
-         .has_fingerprint = has_fingerprint,
-@@ -958,6 +987,10 @@ UuidInfo *qmp_backup(
+         .fingerprint = fingerprint,
+         .backup_id = backup_id,
+@@ -948,6 +976,10 @@ UuidInfo *qmp_backup(
          .backup_time = backup_time,
          .has_use_dirty_bitmap = has_use_dirty_bitmap,
          .use_dirty_bitmap = use_dirty_bitmap,
@@ -192,12 +190,12 @@ index abd7062afe..e113ab61b9 100644
 +        .encrypt = encrypt,
          .has_format = has_format,
          .format = format,
-         .has_config_file = has_config_file,
+         .config_file = config_file,
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 992e6c1e3f..5ac6276dc1 100644
+index 92f90a898a..864b8ce97c 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -818,6 +818,10 @@
+@@ -913,6 +913,10 @@
  #
  # @use-dirty-bitmap: use dirty bitmap to detect incremental changes since last job (optional for format 'pbs')
  #
@@ -208,7 +206,7 @@ index 992e6c1e3f..5ac6276dc1 100644
  # Returns: the uuid of the backup job
  #
  ##
-@@ -829,6 +833,8 @@
+@@ -924,6 +928,8 @@
                                      '*backup-id': 'str',
                                      '*backup-time': 'int',
                                      '*use-dirty-bitmap': 'bool',
diff --git a/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch b/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
index ab28112..c78dbd7 100644
--- a/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
+++ b/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
@@ -8,23 +8,24 @@ Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
 [FE: adapt to changed function signatures
-     make pbs_co_preadv return values consistent with QEMU]
+     make pbs_co_preadv return values consistent with QEMU
+     getlength is now a coroutine function]
 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/meson.build    |   3 +
- block/pbs.c          | 276 +++++++++++++++++++++++++++++++++++++++++++
+ block/pbs.c          | 277 +++++++++++++++++++++++++++++++++++++++++++
  configure            |   9 ++
  meson.build          |   2 +-
  qapi/block-core.json |  13 ++
  qapi/pragma.json     |   1 +
- 6 files changed, 303 insertions(+), 1 deletion(-)
+ 6 files changed, 304 insertions(+), 1 deletion(-)
  create mode 100644 block/pbs.c
 
 diff --git a/block/meson.build b/block/meson.build
-index e995ae72b9..7ef2fa72d5 100644
+index 5bcebb934b..eece0d5743 100644
 --- a/block/meson.build
 +++ b/block/meson.build
-@@ -53,6 +53,9 @@ block_ss.add(files(
+@@ -54,6 +54,9 @@ block_ss.add(files(
    '../pve-backup.c',
  ), libproxmox_backup_qemu)
  
@@ -36,10 +37,10 @@ index e995ae72b9..7ef2fa72d5 100644
  softmmu_ss.add(files('block-ram-registrar.c'))
 diff --git a/block/pbs.c b/block/pbs.c
 new file mode 100644
-index 0000000000..9d1f1f39d4
+index 0000000000..43e69ada46
 --- /dev/null
 +++ b/block/pbs.c
-@@ -0,0 +1,276 @@
+@@ -0,0 +1,277 @@
 +/*
 + * Proxmox Backup Server read-only block driver
 + */
@@ -52,6 +53,7 @@ index 0000000000..9d1f1f39d4
 +#include "qemu/option.h"
 +#include "qemu/cutils.h"
 +#include "block/block_int.h"
++#include "block/block-io.h"
 +
 +#include <proxmox-backup-qemu.h>
 +
@@ -218,7 +220,7 @@ index 0000000000..9d1f1f39d4
 +    proxmox_restore_disconnect(s->conn);
 +}
 +
-+static int64_t pbs_getlength(BlockDriverState *bs)
++static coroutine_fn int64_t pbs_co_getlength(BlockDriverState *bs)
 +{
 +    BDRVPBSState *s = bs->opaque;
 +    return s->length;
@@ -301,7 +303,7 @@ index 0000000000..9d1f1f39d4
 +    .bdrv_file_open         = pbs_file_open,
 +    .bdrv_open              = pbs_open,
 +    .bdrv_close             = pbs_close,
-+    .bdrv_getlength         = pbs_getlength,
++    .bdrv_co_getlength      = pbs_co_getlength,
 +
 +    .bdrv_co_preadv         = pbs_co_preadv,
 +    .bdrv_co_pwritev        = pbs_co_pwritev,
@@ -317,10 +319,10 @@ index 0000000000..9d1f1f39d4
 +
 +block_init(bdrv_pbs_init);
 diff --git a/configure b/configure
-index 26c7bc5154..c587e986c7 100755
+index 800b5850f4..37e12a3dce 100755
 --- a/configure
 +++ b/configure
-@@ -285,6 +285,7 @@ linux_user=""
+@@ -288,6 +288,7 @@ linux_user=""
  bsd_user=""
  pie=""
  coroutine=""
@@ -328,9 +330,9 @@ index 26c7bc5154..c587e986c7 100755
  plugins="$default_feature"
  meson=""
  ninja=""
-@@ -864,6 +865,10 @@ for opt do
-   --enable-uuid|--disable-uuid)
-       echo "$0: $opt is obsolete, UUID support is always built" >&2
+@@ -872,6 +873,10 @@ for opt do
+   ;;
+   --with-coroutine=*) coroutine="$optarg"
    ;;
 +  --disable-pbs-bdrv) pbs_bdrv="no"
 +  ;;
@@ -339,15 +341,15 @@ index 26c7bc5154..c587e986c7 100755
    --with-git=*) git="$optarg"
    ;;
    --with-git-submodules=*)
-@@ -1049,6 +1054,7 @@ cat << EOF
+@@ -1048,6 +1053,7 @@ cat << EOF
    debug-info      debugging information
    safe-stack      SafeStack Stack Smash Protection. Depends on
-                   clang/llvm >= 3.7 and requires coroutine backend ucontext.
+                   clang/llvm and requires coroutine backend ucontext.
 +  pbs-bdrv        Proxmox backup server read-only block driver support
  
  NOTE: The object files are built at the place where configure is launched
  EOF
-@@ -2372,6 +2378,9 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
+@@ -2385,6 +2391,9 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
  if test "$modules" = "yes"; then
    echo "CONFIG_MODULES=y" >> $config_host_mak
  fi
@@ -358,10 +360,10 @@ index 26c7bc5154..c587e986c7 100755
  # XXX: suppress that
  if [ "$bsd" = "yes" ] ; then
 diff --git a/meson.build b/meson.build
-index 63ea813a9a..f7f5b3f253 100644
+index 8ec21bba90..419bea5cf4 100644
 --- a/meson.build
 +++ b/meson.build
-@@ -3978,7 +3978,7 @@ summary_info += {'bzip2 support':     libbzip2}
+@@ -4035,7 +4035,7 @@ summary_info += {'bzip2 support':     libbzip2}
  summary_info += {'lzfse support':     liblzfse}
  summary_info += {'zstd support':      zstd}
  summary_info += {'NUMA host support': numa}
@@ -371,10 +373,10 @@ index 63ea813a9a..f7f5b3f253 100644
  summary_info += {'libdaxctl support': libdaxctl}
  summary_info += {'libudev':           libudev}
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 5ac6276dc1..45b63dfe26 100644
+index 864b8ce97c..705a65ab1a 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -3103,6 +3103,7 @@
+@@ -3198,6 +3198,7 @@
              'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum',
              'raw', 'rbd',
              { 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
@@ -382,7 +384,7 @@ index 5ac6276dc1..45b63dfe26 100644
              'ssh', 'throttle', 'vdi', 'vhdx',
              { 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' },
              { 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' },
-@@ -3179,6 +3180,17 @@
+@@ -3274,6 +3275,17 @@
  { 'struct': 'BlockdevOptionsNull',
    'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } }
  
@@ -400,7 +402,7 @@ index 5ac6276dc1..45b63dfe26 100644
  ##
  # @BlockdevOptionsNVMe:
  #
-@@ -4531,6 +4543,7 @@
+@@ -4647,6 +4659,7 @@
        'nfs':        'BlockdevOptionsNfs',
        'null-aio':   'BlockdevOptionsNull',
        'null-co':    'BlockdevOptionsNull',
diff --git a/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch b/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
index 22ff9a6..0ceb595 100644
--- a/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
+++ b/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
@@ -16,10 +16,10 @@ Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
  2 files changed, 38 insertions(+)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index e113ab61b9..9318ca4f0c 100644
+index f1eacbcaf6..c6fee40a67 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -1072,3 +1072,12 @@ BackupStatus *qmp_query_backup(Error **errp)
+@@ -1054,3 +1054,12 @@ BackupStatus *qmp_query_backup(Error **errp)
  
      return info;
  }
@@ -33,10 +33,10 @@ index e113ab61b9..9318ca4f0c 100644
 +    return ret;
 +}
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 45b63dfe26..8b0e0d92de 100644
+index 705a65ab1a..1ac535fcf2 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -863,6 +863,35 @@
+@@ -958,6 +958,35 @@
  ##
  { 'command': 'backup-cancel' }
  
diff --git a/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch b/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
index 92a19c5..418ae1c 100644
--- a/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
+++ b/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
@@ -15,10 +15,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  3 files changed, 159 insertions(+), 42 deletions(-)
 
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 670f783515..d819e5fc36 100644
+index 087161a967..9a67e544ce 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -202,6 +202,7 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
+@@ -148,6 +148,7 @@ void hmp_sync_profile(Monitor *mon, const QDict *qdict)
  void hmp_info_backup(Monitor *mon, const QDict *qdict)
  {
      BackupStatus *info;
@@ -26,7 +26,7 @@ index 670f783515..d819e5fc36 100644
  
      info = qmp_query_backup(NULL);
  
-@@ -232,26 +233,29 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
+@@ -178,26 +179,29 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
              // this should not happen normally
              monitor_printf(mon, "Total size: %d\n", 0);
          } else {
@@ -69,10 +69,10 @@ index 670f783515..d819e5fc36 100644
                             info->zero_bytes, zero_per);
  
 diff --git a/pve-backup.c b/pve-backup.c
-index 9318ca4f0c..c85b2ecd83 100644
+index c6fee40a67..d4abe6e703 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -46,6 +46,7 @@ static struct PVEBackupState {
+@@ -48,6 +48,7 @@ static struct PVEBackupState {
          size_t transferred;
          size_t reused;
          size_t zero_bytes;
@@ -80,7 +80,7 @@ index 9318ca4f0c..c85b2ecd83 100644
      } stat;
      int64_t speed;
      VmaWriter *vmaw;
-@@ -669,7 +670,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -663,7 +664,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      }
  
      size_t total = 0;
@@ -88,7 +88,7 @@ index 9318ca4f0c..c85b2ecd83 100644
  
      l = di_list;
      while (l) {
-@@ -690,18 +690,33 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -684,18 +684,33 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
  
      uuid_generate(uuid);
  
@@ -108,12 +108,12 @@ index 9318ca4f0c..c85b2ecd83 100644
 +    }
 +
      if (format == BACKUP_FORMAT_PBS) {
-         if (!task->has_password) {
+         if (!task->password) {
              error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
 -            goto err;
 +            goto err_mutex;
          }
-         if (!task->has_backup_id) {
+         if (!task->backup_id) {
              error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
 -            goto err;
 +            goto err_mutex;
@@ -125,7 +125,7 @@ index 9318ca4f0c..c85b2ecd83 100644
          }
  
          int dump_cb_block_size = PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE; // Hardcoded (4M)
-@@ -728,12 +743,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -722,12 +737,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
                        "proxmox_backup_new failed: %s", pbs_err);
              proxmox_backup_free_error(pbs_err);
@@ -140,7 +140,7 @@ index 9318ca4f0c..c85b2ecd83 100644
  
          /* register all devices */
          l = di_list;
-@@ -744,6 +759,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -738,6 +753,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              di->block_size = dump_cb_block_size;
  
              const char *devname = bdrv_get_device_name(di->bs);
@@ -149,7 +149,7 @@ index 9318ca4f0c..c85b2ecd83 100644
  
              BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
              bool expect_only_dirty = false;
-@@ -752,49 +769,59 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -746,49 +763,59 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
                  if (bitmap == NULL) {
                      bitmap = bdrv_create_dirty_bitmap(di->bs, dump_cb_block_size, PBS_BITMAP_NAME, task->errp);
                      if (!bitmap) {
@@ -219,7 +219,7 @@ index 9318ca4f0c..c85b2ecd83 100644
          }
  
          /* register all devices for vma writer */
-@@ -804,7 +831,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -798,7 +825,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              l = g_list_next(l);
  
              if (!(di->target = bdrv_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, task->errp))) {
@@ -228,7 +228,7 @@ index 9318ca4f0c..c85b2ecd83 100644
              }
  
              const char *devname = bdrv_get_device_name(di->bs);
-@@ -812,16 +839,14 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -806,16 +833,14 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              if (di->dev_id <= 0) {
                  error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
                            "register_stream failed");
@@ -247,7 +247,7 @@ index 9318ca4f0c..c85b2ecd83 100644
          }
          backup_dir = task->backup_file;
  
-@@ -838,18 +863,18 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -832,18 +857,18 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
                              di->size, flags, false, &local_err);
              if (local_err) {
                  error_propagate(task->errp, local_err);
@@ -269,8 +269,8 @@ index 9318ca4f0c..c85b2ecd83 100644
      }
  
  
-@@ -857,7 +882,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     if (task->has_config_file) {
+@@ -851,7 +876,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     if (task->config_file) {
          if (pvebackup_co_add_config(task->config_file, config_name, format, backup_dir,
                                      vmaw, pbs, task->errp) != 0) {
 -            goto err;
@@ -278,8 +278,8 @@ index 9318ca4f0c..c85b2ecd83 100644
          }
      }
  
-@@ -865,12 +890,11 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     if (task->has_firewall_file) {
+@@ -859,12 +884,11 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     if (task->firewall_file) {
          if (pvebackup_co_add_config(task->firewall_file, firewall_name, format, backup_dir,
                                      vmaw, pbs, task->errp) != 0) {
 -            goto err;
@@ -293,7 +293,7 @@ index 9318ca4f0c..c85b2ecd83 100644
  
      if (backup_state.stat.error) {
          error_free(backup_state.stat.error);
-@@ -890,10 +914,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -884,10 +908,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      char *uuid_str = g_strdup(backup_state.stat.uuid_str);
  
      backup_state.stat.total = total;
@@ -305,7 +305,7 @@ index 9318ca4f0c..c85b2ecd83 100644
  
      qemu_mutex_unlock(&backup_state.stat.lock);
  
-@@ -910,6 +933,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -904,6 +927,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      task->result = uuid_info;
      return;
  
@@ -315,7 +315,7 @@ index 9318ca4f0c..c85b2ecd83 100644
  err:
  
      l = di_list;
-@@ -1073,11 +1099,42 @@ BackupStatus *qmp_query_backup(Error **errp)
+@@ -1055,11 +1081,42 @@ BackupStatus *qmp_query_backup(Error **errp)
      return info;
  }
  
@@ -359,10 +359,10 @@ index 9318ca4f0c..c85b2ecd83 100644
      return ret;
  }
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 8b0e0d92de..7fde927621 100644
+index 1ac535fcf2..130d5f065f 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -871,6 +871,8 @@
+@@ -966,6 +966,8 @@
  # @pbs-dirty-bitmap: True if dirty-bitmap-incremental backups to PBS are
  #                    supported.
  #
@@ -371,7 +371,7 @@ index 8b0e0d92de..7fde927621 100644
  # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
  #                           safely be set for savevm-async.
  #
-@@ -879,6 +881,7 @@
+@@ -974,6 +976,7 @@
  ##
  { 'struct': 'ProxmoxSupportStatus',
    'data': { 'pbs-dirty-bitmap': 'bool',
@@ -379,7 +379,7 @@ index 8b0e0d92de..7fde927621 100644
              'pbs-dirty-bitmap-savevm': 'bool',
              'pbs-library-version': 'str' } }
  
-@@ -892,6 +895,59 @@
+@@ -987,6 +990,59 @@
  ##
  { 'command': 'query-proxmox-support', 'returns': 'ProxmoxSupportStatus' }
  
diff --git a/debian/patches/pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch b/debian/patches/pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch
index 4a00163..7f8fe9e 100644
--- a/debian/patches/pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch
+++ b/debian/patches/pve/0036-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(+), 2 deletions(-)
 
 diff --git a/meson.build b/meson.build
-index f7f5b3f253..283b0e356e 100644
+index 419bea5cf4..c39c6054ee 100644
 --- a/meson.build
 +++ b/meson.build
-@@ -1526,6 +1526,7 @@ keyutils = dependency('libkeyutils', required: false,
+@@ -1528,6 +1528,7 @@ keyutils = dependency('libkeyutils', required: false,
  has_gettid = cc.has_function('gettid')
  
  libuuid = cc.find_library('uuid', required: true)
@@ -25,7 +25,7 @@ index f7f5b3f253..283b0e356e 100644
  libproxmox_backup_qemu = cc.find_library('proxmox_backup_qemu', required: true)
  
  # libselinux
-@@ -3096,6 +3097,7 @@ if have_block
+@@ -3143,6 +3144,7 @@ if have_block
    # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
    # os-win32.c does not
    blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
@@ -34,7 +34,7 @@ index f7f5b3f253..283b0e356e 100644
  endif
  
 diff --git a/os-posix.c b/os-posix.c
-index 4858650c3e..c5cb12226a 100644
+index 5adc69f560..80c7777f10 100644
 --- a/os-posix.c
 +++ b/os-posix.c
 @@ -28,6 +28,8 @@
diff --git a/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch b/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
index abda21b..616b170 100644
--- a/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
+++ b/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
@@ -20,10 +20,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 50 insertions(+), 113 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index c85b2ecd83..b5fb844434 100644
+index d4abe6e703..214c839c0b 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -52,6 +52,7 @@ static struct PVEBackupState {
+@@ -54,6 +54,7 @@ static struct PVEBackupState {
      VmaWriter *vmaw;
      ProxmoxBackupHandle *pbs;
      GList *di_list;
@@ -31,7 +31,7 @@ index c85b2ecd83..b5fb844434 100644
      QemuMutex backup_mutex;
      CoMutex dump_callback_mutex;
  } backup_state;
-@@ -71,34 +72,12 @@ typedef struct PVEBackupDevInfo {
+@@ -73,34 +74,12 @@ typedef struct PVEBackupDevInfo {
      size_t size;
      uint64_t block_size;
      uint8_t dev_id;
@@ -67,7 +67,7 @@ index c85b2ecd83..b5fb844434 100644
  static void pvebackup_propagate_error(Error *err)
  {
      qemu_mutex_lock(&backup_state.stat.lock);
-@@ -274,18 +253,6 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
+@@ -276,18 +255,6 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
              if (local_err != NULL) {
                  pvebackup_propagate_error(local_err);
              }
@@ -86,7 +86,7 @@ index c85b2ecd83..b5fb844434 100644
          }
  
          proxmox_backup_disconnect(backup_state.pbs);
-@@ -324,8 +291,6 @@ static void pvebackup_complete_cb(void *opaque, int ret)
+@@ -326,8 +293,6 @@ static void pvebackup_complete_cb(void *opaque, int ret)
  
      qemu_mutex_lock(&backup_state.backup_mutex);
  
@@ -95,7 +95,7 @@ index c85b2ecd83..b5fb844434 100644
      if (ret < 0) {
          Error *local_err = NULL;
          error_setg(&local_err, "job failed with err %d - %s", ret, strerror(-ret));
-@@ -338,20 +303,17 @@ static void pvebackup_complete_cb(void *opaque, int ret)
+@@ -340,20 +305,17 @@ static void pvebackup_complete_cb(void *opaque, int ret)
  
      block_on_coroutine_fn(pvebackup_complete_stream, di);
  
@@ -122,7 +122,7 @@ index c85b2ecd83..b5fb844434 100644
  }
  
  static void pvebackup_cancel(void)
-@@ -373,32 +335,28 @@ static void pvebackup_cancel(void)
+@@ -375,32 +337,28 @@ static void pvebackup_cancel(void)
          proxmox_backup_abort(backup_state.pbs, "backup canceled");
      }
  
@@ -173,7 +173,7 @@ index c85b2ecd83..b5fb844434 100644
          }
      }
  }
-@@ -458,49 +416,19 @@ static int coroutine_fn pvebackup_co_add_config(
+@@ -460,49 +418,19 @@ static int coroutine_fn pvebackup_co_add_config(
      goto out;
  }
  
@@ -230,7 +230,7 @@ index c85b2ecd83..b5fb844434 100644
      BackupPerf perf = { .max_workers = 16 };
  
      /* create and start all jobs (paused state) */
-@@ -523,7 +451,7 @@ static bool create_backup_jobs(void) {
+@@ -525,7 +453,7 @@ static bool create_backup_jobs(void) {
          BlockJob *job = backup_job_create(
              NULL, di->bs, di->target, backup_state.speed, sync_mode, di->bitmap,
              bitmap_mode, false, NULL, &perf, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
@@ -239,7 +239,7 @@ index c85b2ecd83..b5fb844434 100644
  
          aio_context_release(aio_context);
  
-@@ -535,7 +463,8 @@ static bool create_backup_jobs(void) {
+@@ -537,7 +465,8 @@ static bool create_backup_jobs(void) {
              pvebackup_propagate_error(create_job_err);
              break;
          }
@@ -249,7 +249,7 @@ index c85b2ecd83..b5fb844434 100644
  
          bdrv_unref(di->target);
          di->target = NULL;
-@@ -553,6 +482,12 @@ static bool create_backup_jobs(void) {
+@@ -555,6 +484,12 @@ static bool create_backup_jobs(void) {
                  bdrv_unref(di->target);
                  di->target = NULL;
              }
@@ -262,7 +262,7 @@ index c85b2ecd83..b5fb844434 100644
          }
      }
  
-@@ -943,10 +878,6 @@ err:
+@@ -937,10 +872,6 @@ err:
          PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
          l = g_list_next(l);
  
@@ -273,7 +273,7 @@ index c85b2ecd83..b5fb844434 100644
          if (di->target) {
              bdrv_unref(di->target);
          }
-@@ -1035,9 +966,15 @@ UuidInfo *qmp_backup(
+@@ -1021,9 +952,15 @@ UuidInfo *qmp_backup(
      block_on_coroutine_fn(pvebackup_co_prepare, &task);
  
      if (*errp == NULL) {
diff --git a/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch b/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
index e13b2d2..7cd670e 100644
--- a/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
+++ b/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
@@ -57,10 +57,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  2 files changed, 138 insertions(+), 79 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index b5fb844434..88268bb586 100644
+index 214c839c0b..1d233dac93 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -33,7 +33,9 @@ const char *PBS_BITMAP_NAME = "pbs-incremental-dirty-bitmap";
+@@ -35,7 +35,9 @@ const char *PBS_BITMAP_NAME = "pbs-incremental-dirty-bitmap";
  
  static struct PVEBackupState {
      struct {
@@ -71,7 +71,7 @@ index b5fb844434..88268bb586 100644
          QemuMutex lock;
          Error *error;
          time_t start_time;
-@@ -47,20 +49,22 @@ static struct PVEBackupState {
+@@ -49,20 +51,22 @@ static struct PVEBackupState {
          size_t reused;
          size_t zero_bytes;
          GList *bitmap_list;
@@ -96,7 +96,7 @@ index b5fb844434..88268bb586 100644
      qemu_co_mutex_init(&backup_state.dump_callback_mutex);
  }
  
-@@ -72,6 +76,7 @@ typedef struct PVEBackupDevInfo {
+@@ -74,6 +78,7 @@ typedef struct PVEBackupDevInfo {
      size_t size;
      uint64_t block_size;
      uint8_t dev_id;
@@ -104,7 +104,7 @@ index b5fb844434..88268bb586 100644
      char targetfile[PATH_MAX];
      BdrvDirtyBitmap *bitmap;
      BlockDriverState *target;
-@@ -227,12 +232,12 @@ pvebackup_co_dump_vma_cb(
+@@ -229,12 +234,12 @@ pvebackup_co_dump_vma_cb(
  }
  
  // assumes the caller holds backup_mutex
@@ -119,7 +119,7 @@ index b5fb844434..88268bb586 100644
      qemu_mutex_unlock(&backup_state.stat.lock);
  
      if (backup_state.vmaw) {
-@@ -261,35 +266,29 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
+@@ -263,35 +268,29 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
  
      g_list_free(backup_state.di_list);
      backup_state.di_list = NULL;
@@ -171,7 +171,7 @@ index b5fb844434..88268bb586 100644
  
      if (ret < 0) {
          Error *local_err = NULL;
-@@ -301,7 +300,19 @@ static void pvebackup_complete_cb(void *opaque, int ret)
+@@ -303,7 +302,19 @@ static void pvebackup_complete_cb(void *opaque, int ret)
  
      assert(di->target == NULL);
  
@@ -192,7 +192,7 @@ index b5fb844434..88268bb586 100644
  
      // remove self from job list
      backup_state.di_list = g_list_remove(backup_state.di_list, di);
-@@ -310,21 +321,46 @@ static void pvebackup_complete_cb(void *opaque, int ret)
+@@ -312,21 +323,46 @@ static void pvebackup_complete_cb(void *opaque, int ret)
  
      /* call cleanup if we're the last job */
      if (!g_list_first(backup_state.di_list)) {
@@ -244,7 +244,7 @@ index b5fb844434..88268bb586 100644
  
      if (backup_state.vmaw) {
          /* make sure vma writer does not block anymore */
-@@ -342,28 +378,22 @@ static void pvebackup_cancel(void)
+@@ -344,28 +380,22 @@ static void pvebackup_cancel(void)
          ((PVEBackupDevInfo *)bdi->data)->job :
          NULL;
  
@@ -282,7 +282,7 @@ index b5fb844434..88268bb586 100644
  }
  
  // assumes the caller holds backup_mutex
-@@ -416,10 +446,18 @@ static int coroutine_fn pvebackup_co_add_config(
+@@ -418,10 +448,18 @@ static int coroutine_fn pvebackup_co_add_config(
      goto out;
  }
  
@@ -302,7 +302,7 @@ index b5fb844434..88268bb586 100644
      Error *local_err = NULL;
  
      /* create job transaction to synchronize bitmap commit and cancel all
-@@ -455,24 +493,19 @@ static bool create_backup_jobs(void) {
+@@ -457,24 +495,19 @@ static bool create_backup_jobs(void) {
  
          aio_context_release(aio_context);
  
@@ -332,7 +332,7 @@ index b5fb844434..88268bb586 100644
          l = backup_state.di_list;
          while (l) {
              PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-@@ -485,13 +518,15 @@ static bool create_backup_jobs(void) {
+@@ -487,13 +520,15 @@ static bool create_backup_jobs(void) {
  
              if (di->job) {
                  WITH_JOB_LOCK_GUARD() {
@@ -349,7 +349,7 @@ index b5fb844434..88268bb586 100644
  }
  
  typedef struct QmpBackupTask {
-@@ -528,11 +563,12 @@ typedef struct QmpBackupTask {
+@@ -522,11 +557,12 @@ typedef struct QmpBackupTask {
      UuidInfo *result;
  } QmpBackupTask;
  
@@ -363,7 +363,7 @@ index b5fb844434..88268bb586 100644
      QmpBackupTask *task = opaque;
  
      task->result = NULL; // just to be sure
-@@ -553,8 +589,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -547,8 +583,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      const char *firewall_name = "qemu-server.fw";
  
      if (backup_state.di_list) {
@@ -374,7 +374,7 @@ index b5fb844434..88268bb586 100644
          return;
      }
  
-@@ -621,6 +658,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -615,6 +652,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
          }
          di->size = size;
          total += size;
@@ -383,7 +383,7 @@ index b5fb844434..88268bb586 100644
      }
  
      uuid_generate(uuid);
-@@ -852,6 +891,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -846,6 +885,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      backup_state.stat.dirty = total - backup_state.stat.reused;
      backup_state.stat.transferred = 0;
      backup_state.stat.zero_bytes = 0;
@@ -392,7 +392,7 @@ index b5fb844434..88268bb586 100644
  
      qemu_mutex_unlock(&backup_state.stat.lock);
  
-@@ -866,6 +907,33 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -860,6 +901,33 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      uuid_info->UUID = uuid_str;
  
      task->result = uuid_info;
@@ -426,7 +426,7 @@ index b5fb844434..88268bb586 100644
      return;
  
  err_mutex:
-@@ -888,6 +956,7 @@ err:
+@@ -882,6 +950,7 @@ err:
          g_free(di);
      }
      g_list_free(di_list);
@@ -434,7 +434,7 @@ index b5fb844434..88268bb586 100644
  
      if (devs) {
          g_strfreev(devs);
-@@ -908,6 +977,8 @@ err:
+@@ -902,6 +971,8 @@ err:
      }
  
      task->result = NULL;
@@ -443,7 +443,7 @@ index b5fb844434..88268bb586 100644
      return;
  }
  
-@@ -961,24 +1032,8 @@ UuidInfo *qmp_backup(
+@@ -947,24 +1018,8 @@ UuidInfo *qmp_backup(
          .errp = errp,
      };
  
@@ -468,7 +468,7 @@ index b5fb844434..88268bb586 100644
      return task.result;
  }
  
-@@ -1030,6 +1085,7 @@ BackupStatus *qmp_query_backup(Error **errp)
+@@ -1012,6 +1067,7 @@ BackupStatus *qmp_query_backup(Error **errp)
      info->transferred = backup_state.stat.transferred;
      info->has_reused = true;
      info->reused = backup_state.stat.reused;
@@ -477,10 +477,10 @@ index b5fb844434..88268bb586 100644
      qemu_mutex_unlock(&backup_state.stat.lock);
  
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 7fde927621..bf559c6d52 100644
+index 130d5f065f..43838212e3 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -770,12 +770,15 @@
+@@ -865,12 +865,15 @@
  #
  # @uuid: uuid for this backup job
  #
diff --git a/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch b/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
index fd338a5..b678e74 100644
--- a/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
+++ b/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
@@ -13,21 +13,23 @@ safe migration is possible and makes sense.
 
 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[FE: split up state_pending for 8.0]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  include/migration/misc.h |   3 ++
  migration/meson.build    |   2 +
  migration/migration.c    |   1 +
- migration/pbs-state.c    | 106 +++++++++++++++++++++++++++++++++++++++
+ migration/pbs-state.c    | 104 +++++++++++++++++++++++++++++++++++++++
  pve-backup.c             |   1 +
  qapi/block-core.json     |   6 +++
- 6 files changed, 119 insertions(+)
+ 6 files changed, 117 insertions(+)
  create mode 100644 migration/pbs-state.c
 
 diff --git a/include/migration/misc.h b/include/migration/misc.h
-index 465906710d..4f0aeceb6f 100644
+index 8b49841016..78f63ca400 100644
 --- a/include/migration/misc.h
 +++ b/include/migration/misc.h
-@@ -75,4 +75,7 @@ bool migration_in_bg_snapshot(void);
+@@ -77,4 +77,7 @@ bool migration_in_bg_snapshot(void);
  /* migration/block-dirty-bitmap.c */
  void dirty_bitmap_mig_init(void);
  
@@ -36,7 +38,7 @@ index 465906710d..4f0aeceb6f 100644
 +
  #endif
 diff --git a/migration/meson.build b/migration/meson.build
-index 0842d00cd2..d012f4d8d3 100644
+index a7824b5266..de6a271b58 100644
 --- a/migration/meson.build
 +++ b/migration/meson.build
 @@ -6,8 +6,10 @@ migration_files = files(
@@ -51,10 +53,10 @@ index 0842d00cd2..d012f4d8d3 100644
  softmmu_ss.add(files(
    'block-dirty-bitmap.c',
 diff --git a/migration/migration.c b/migration/migration.c
-index f485eea5fb..89b287180f 100644
+index bda4789193..c8318aa258 100644
 --- a/migration/migration.c
 +++ b/migration/migration.c
-@@ -229,6 +229,7 @@ void migration_object_init(void)
+@@ -245,6 +245,7 @@ void migration_object_init(void)
      blk_mig_init();
      ram_mig_init();
      dirty_bitmap_mig_init();
@@ -64,10 +66,10 @@ index f485eea5fb..89b287180f 100644
  void migration_cancel(const Error *error)
 diff --git a/migration/pbs-state.c b/migration/pbs-state.c
 new file mode 100644
-index 0000000000..29f2b3860d
+index 0000000000..887e998b9e
 --- /dev/null
 +++ b/migration/pbs-state.c
-@@ -0,0 +1,106 @@
+@@ -0,0 +1,104 @@
 +/*
 + * PBS (dirty-bitmap) state migration
 + */
@@ -86,11 +88,8 @@ index 0000000000..29f2b3860d
 +/* state is accessed via this static variable directly, 'opaque' is NULL */
 +static PBSState pbs_state;
 +
-+static void pbs_state_save_pending(QEMUFile *f, void *opaque,
-+                                      uint64_t max_size,
-+                                      uint64_t *res_precopy_only,
-+                                      uint64_t *res_compatible,
-+                                      uint64_t *res_postcopy_only)
++static void pbs_state_pending(void *opaque, uint64_t *must_precopy,
++                              uint64_t *can_postcopy)
 +{
 +    /* we send everything in save_setup, so nothing is ever pending */
 +}
@@ -160,7 +159,8 @@ index 0000000000..29f2b3860d
 +static SaveVMHandlers savevm_pbs_state_handlers = {
 +    .save_setup = pbs_state_save_setup,
 +    .has_postcopy = pbs_state_has_postcopy,
-+    .save_live_pending = pbs_state_save_pending,
++    .state_pending_exact = pbs_state_pending,
++    .state_pending_estimate = pbs_state_pending,
 +    .is_active_iterate = pbs_state_is_active_iterate,
 +    .load_state = pbs_state_load,
 +    .is_active = pbs_state_is_active,
@@ -175,10 +175,10 @@ index 0000000000..29f2b3860d
 +                         NULL);
 +}
 diff --git a/pve-backup.c b/pve-backup.c
-index 88268bb586..fa9c6c4493 100644
+index 1d233dac93..5c9c153e31 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -1128,6 +1128,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
+@@ -1110,6 +1110,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
      ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
      ret->pbs_dirty_bitmap = true;
      ret->pbs_dirty_bitmap_savevm = true;
@@ -187,10 +187,10 @@ index 88268bb586..fa9c6c4493 100644
      return ret;
  }
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index bf559c6d52..24f30260c8 100644
+index 43838212e3..e7412f6322 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -879,6 +879,11 @@
+@@ -974,6 +974,11 @@
  # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
  #                           safely be set for savevm-async.
  #
@@ -202,7 +202,7 @@ index bf559c6d52..24f30260c8 100644
  # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
  #
  ##
-@@ -886,6 +891,7 @@
+@@ -981,6 +986,7 @@
    'data': { 'pbs-dirty-bitmap': 'bool',
              'query-bitmap-info': 'bool',
              'pbs-dirty-bitmap-savevm': 'bool',
diff --git a/debian/patches/pve/0041-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch b/debian/patches/pve/0041-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
index 074daf7..0e3f38d 100644
--- a/debian/patches/pve/0041-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
+++ b/debian/patches/pve/0041-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
@@ -19,10 +19,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
-index 9aba7d9c22..f4ecf9c9f9 100644
+index fe73aa94b1..a6440929fa 100644
 --- a/migration/block-dirty-bitmap.c
 +++ b/migration/block-dirty-bitmap.c
-@@ -538,7 +538,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
+@@ -539,7 +539,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
  
          if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, &local_err)) {
              error_report_err(local_err);
diff --git a/debian/patches/pve/0042-PVE-fall-back-to-open-iscsi-initiatorname.patch b/debian/patches/pve/0042-PVE-fall-back-to-open-iscsi-initiatorname.patch
index afaddcf..0e50c93 100644
--- a/debian/patches/pve/0042-PVE-fall-back-to-open-iscsi-initiatorname.patch
+++ b/debian/patches/pve/0042-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 a316d46d96..3ed4a50c0d 100644
+index 9fc0bed90b..1d40933165 100644
 --- a/block/iscsi.c
 +++ b/block/iscsi.c
-@@ -1387,12 +1387,42 @@ static char *get_initiator_name(QemuOpts *opts)
+@@ -1392,12 +1392,42 @@ static char *get_initiator_name(QemuOpts *opts)
      const char *name;
      char *iscsi_name;
      UuidInfo *uuid_info;
diff --git a/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch b/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
index 18675b2..810a801 100644
--- a/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
+++ b/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
@@ -23,20 +23,23 @@ way instead)
 
 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[FE: adapt to QAPI changes
+     call coroutine version of is_inserted()]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/monitor/block-hmp-cmds.c |   4 +-
  hmp-commands.hx                |   2 +
  proxmox-backup-client.c        |  31 -----
- pve-backup.c                   | 232 ++++++++++-----------------------
+ pve-backup.c                   | 220 +++++++++++----------------------
  qapi/block-core.json           |   4 +-
- 5 files changed, 77 insertions(+), 196 deletions(-)
+ 5 files changed, 79 insertions(+), 182 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index a09f722fea..71ed202491 100644
+index 6a6ed6d0e7..bcf5849196 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1016,7 +1016,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
-     g_free(global_snapshots);
+@@ -1028,7 +1028,7 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target,
+                                !!read_only, read_only_mode, errp);
  }
  
 -void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
@@ -44,7 +47,7 @@ index a09f722fea..71ed202491 100644
  {
      Error *error = NULL;
  
-@@ -1025,7 +1025,7 @@ void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
+@@ -1037,7 +1037,7 @@ void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
      hmp_handle_error(mon, error);
  }
  
@@ -54,7 +57,7 @@ index a09f722fea..71ed202491 100644
      Error *error = NULL;
  
 diff --git a/hmp-commands.hx b/hmp-commands.hx
-index fcf9461295..5fdb198ca4 100644
+index 9b6b8e2e9c..896430dae8 100644
 --- a/hmp-commands.hx
 +++ b/hmp-commands.hx
 @@ -111,6 +111,7 @@ ERST
@@ -116,10 +119,10 @@ index 4ce7bc0b5e..0923037dec 100644
  static void proxmox_backup_schedule_wake(void *data) {
      CoCtxData *waker = (CoCtxData *)data;
 diff --git a/pve-backup.c b/pve-backup.c
-index 5662f48b72..e4fe1b601d 100644
+index 5c9c153e31..378e4a9a63 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -354,7 +354,7 @@ static void job_cancel_bh(void *opaque) {
+@@ -356,7 +356,7 @@ static void job_cancel_bh(void *opaque) {
      aio_co_enter(data->ctx, data->co);
  }
  
@@ -128,7 +131,7 @@ index 5662f48b72..e4fe1b601d 100644
  {
      Error *cancel_err = NULL;
      error_setg(&cancel_err, "backup canceled");
-@@ -391,11 +391,6 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
+@@ -393,11 +393,6 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
      qemu_co_mutex_unlock(&backup_state.backup_mutex);
  }
  
@@ -140,33 +143,25 @@ index 5662f48b72..e4fe1b601d 100644
  // assumes the caller holds backup_mutex
  static int coroutine_fn pvebackup_co_add_config(
      const char *file,
-@@ -529,50 +524,27 @@ static void create_backup_jobs_bh(void *opaque) {
+@@ -531,42 +526,27 @@ static void create_backup_jobs_bh(void *opaque) {
      aio_co_enter(data->ctx, data->co);
  }
  
 -typedef struct QmpBackupTask {
 -    const char *backup_file;
--    bool has_password;
 -    const char *password;
--    bool has_keyfile;
 -    const char *keyfile;
--    bool has_key_password;
 -    const char *key_password;
--    bool has_backup_id;
 -    const char *backup_id;
 -    bool has_backup_time;
 -    const char *fingerprint;
--    bool has_fingerprint;
 -    int64_t backup_time;
 -    bool has_use_dirty_bitmap;
 -    bool use_dirty_bitmap;
 -    bool has_format;
 -    BackupFormat format;
--    bool has_config_file;
 -    const char *config_file;
--    bool has_firewall_file;
 -    const char *firewall_file;
--    bool has_devlist;
 -    const char *devlist;
 -    bool has_compress;
 -    bool compress;
@@ -181,19 +176,19 @@ index 5662f48b72..e4fe1b601d 100644
 -static void coroutine_fn pvebackup_co_prepare(void *opaque)
 +UuidInfo coroutine_fn *qmp_backup(
 +    const char *backup_file,
-+    bool has_password, const char *password,
-+    bool has_keyfile, const char *keyfile,
-+    bool has_key_password, const char *key_password,
-+    bool has_fingerprint, const char *fingerprint,
-+    bool has_backup_id, const char *backup_id,
++    const char *password,
++    const char *keyfile,
++    const char *key_password,
++    const char *fingerprint,
++    const char *backup_id,
 +    bool has_backup_time, int64_t backup_time,
 +    bool has_use_dirty_bitmap, bool use_dirty_bitmap,
 +    bool has_compress, bool compress,
 +    bool has_encrypt, bool encrypt,
 +    bool has_format, BackupFormat format,
-+    bool has_config_file, const char *config_file,
-+    bool has_firewall_file, const char *firewall_file,
-+    bool has_devlist, const char *devlist,
++    const char *config_file,
++    const char *firewall_file,
++    const char *devlist,
 +    bool has_speed, int64_t speed, Error **errp)
  {
      assert(qemu_in_coroutine());
@@ -207,7 +202,7 @@ index 5662f48b72..e4fe1b601d 100644
      BlockBackend *blk;
      BlockDriverState *bs = NULL;
      const char *backup_dir = NULL;
-@@ -589,17 +561,17 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -583,32 +563,32 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      const char *firewall_name = "qemu-server.fw";
  
      if (backup_state.di_list) {
@@ -223,18 +218,19 @@ index 5662f48b72..e4fe1b601d 100644
 -    BackupFormat format = task->has_format ? task->format : BACKUP_FORMAT_VMA;
 +    format = has_format ? format : BACKUP_FORMAT_VMA;
  
--    if (task->has_devlist) {
+-    if (task->devlist) {
 -        devs = g_strsplit_set(task->devlist, ",;:", -1);
-+    if (has_devlist) {
++    if (devlist) {
 +        devs = g_strsplit_set(devlist, ",;:", -1);
  
          gchar **d = devs;
          while (d && *d) {
-@@ -607,14 +579,14 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+             blk = blk_by_name(*d);
              if (blk) {
                  bs = blk_bs(blk);
-                 if (!bdrv_is_inserted(bs)) {
+-                if (!bdrv_is_inserted(bs)) {
 -                    error_setg(task->errp, QERR_DEVICE_HAS_NO_MEDIUM, *d);
++                if (!bdrv_co_is_inserted(bs)) {
 +                    error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, *d);
                      goto err;
                  }
@@ -247,7 +243,16 @@ index 5662f48b72..e4fe1b601d 100644
                            "Device '%s' not found", *d);
                  goto err;
              }
-@@ -637,7 +609,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -620,7 +600,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+ 
+         bs = NULL;
+         for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+-            if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
++            if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs)) {
+                 continue;
+             }
+ 
+@@ -631,7 +611,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      }
  
      if (!di_list) {
@@ -256,7 +261,7 @@ index 5662f48b72..e4fe1b601d 100644
          goto err;
      }
  
-@@ -647,13 +619,13 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -641,13 +621,13 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      while (l) {
          PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
          l = g_list_next(l);
@@ -272,19 +277,19 @@ index 5662f48b72..e4fe1b601d 100644
              goto err;
          }
          di->size = size;
-@@ -680,47 +652,44 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -674,47 +654,44 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      }
  
      if (format == BACKUP_FORMAT_PBS) {
--        if (!task->has_password) {
+-        if (!task->password) {
 -            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
-+        if (!has_password) {
++        if (!password) {
 +            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
              goto err_mutex;
          }
--        if (!task->has_backup_id) {
+-        if (!task->backup_id) {
 -            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
-+        if (!has_backup_id) {
++        if (!backup_id) {
 +            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
              goto err_mutex;
          }
@@ -310,19 +315,19 @@ index 5662f48b72..e4fe1b601d 100644
 +            backup_id,
 +            backup_time,
              dump_cb_block_size,
--            task->has_password ? task->password : NULL,
--            task->has_keyfile ? task->keyfile : NULL,
--            task->has_key_password ? task->key_password : NULL,
+-            task->password,
+-            task->keyfile,
+-            task->key_password,
 -            task->has_compress ? task->compress : true,
--            task->has_encrypt ? task->encrypt : task->has_keyfile,
--            task->has_fingerprint ? task->fingerprint : NULL,
-+            has_password ? password : NULL,
-+            has_keyfile ? keyfile : NULL,
-+            has_key_password ? key_password : NULL,
+-            task->has_encrypt ? task->encrypt : !!task->keyfile,
+-            task->fingerprint,
++            password,
++            keyfile,
++            key_password,
 +            has_compress ? compress : true,
-+            has_encrypt ? encrypt : has_keyfile,
-+            has_fingerprint ? fingerprint : NULL,
-              &pbs_err);
++            has_encrypt ? encrypt : !!keyfile,
++            fingerprint,
+             &pbs_err);
  
          if (!pbs) {
 -            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
@@ -337,7 +342,7 @@ index 5662f48b72..e4fe1b601d 100644
          if (connect_result < 0)
              goto err_mutex;
  
-@@ -739,9 +708,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -733,9 +710,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
              bool expect_only_dirty = false;
  
@@ -349,7 +354,7 @@ index 5662f48b72..e4fe1b601d 100644
                      if (!bitmap) {
                          goto err_mutex;
                      }
-@@ -771,12 +740,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -765,12 +742,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
                  }
              }
  
@@ -364,7 +369,7 @@ index 5662f48b72..e4fe1b601d 100644
                  goto err_mutex;
              }
  
-@@ -790,10 +759,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -784,10 +761,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              backup_state.stat.bitmap_list = g_list_append(backup_state.stat.bitmap_list, info);
          }
      } else if (format == BACKUP_FORMAT_VMA) {
@@ -377,7 +382,7 @@ index 5662f48b72..e4fe1b601d 100644
              }
              goto err_mutex;
          }
-@@ -804,25 +773,25 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -798,25 +775,25 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
              l = g_list_next(l);
  
@@ -409,7 +414,7 @@ index 5662f48b72..e4fe1b601d 100644
  
          l = di_list;
          while (l) {
-@@ -836,34 +805,34 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -830,34 +807,34 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
              bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
                              di->size, flags, false, &local_err);
              if (local_err) {
@@ -433,10 +438,10 @@ index 5662f48b72..e4fe1b601d 100644
  
  
      /* add configuration file to archive */
--    if (task->has_config_file) {
+-    if (task->config_file) {
 -        if (pvebackup_co_add_config(task->config_file, config_name, format, backup_dir,
 -                                    vmaw, pbs, task->errp) != 0) {
-+    if (has_config_file) {
++    if (config_file) {
 +        if (pvebackup_co_add_config(config_file, config_name, format, backup_dir,
 +                                    vmaw, pbs, errp) != 0) {
              goto err_mutex;
@@ -444,16 +449,16 @@ index 5662f48b72..e4fe1b601d 100644
      }
  
      /* add firewall file to archive */
--    if (task->has_firewall_file) {
+-    if (task->firewall_file) {
 -        if (pvebackup_co_add_config(task->firewall_file, firewall_name, format, backup_dir,
 -                                    vmaw, pbs, task->errp) != 0) {
-+    if (has_firewall_file) {
++    if (firewall_file) {
 +        if (pvebackup_co_add_config(firewall_file, firewall_name, format, backup_dir,
 +                                    vmaw, pbs, errp) != 0) {
              goto err_mutex;
          }
      }
-@@ -881,7 +850,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -875,7 +852,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      if (backup_state.stat.backup_file) {
          g_free(backup_state.stat.backup_file);
      }
@@ -462,7 +467,7 @@ index 5662f48b72..e4fe1b601d 100644
  
      uuid_copy(backup_state.stat.uuid, uuid);
      uuid_unparse_lower(uuid, backup_state.stat.uuid_str);
-@@ -896,7 +865,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -890,7 +867,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
  
      qemu_mutex_unlock(&backup_state.stat.lock);
  
@@ -471,7 +476,7 @@ index 5662f48b72..e4fe1b601d 100644
  
      backup_state.vmaw = vmaw;
      backup_state.pbs = pbs;
-@@ -906,8 +875,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -900,8 +877,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      uuid_info = g_malloc0(sizeof(*uuid_info));
      uuid_info->UUID = uuid_str;
  
@@ -480,7 +485,7 @@ index 5662f48b72..e4fe1b601d 100644
      /* Run create_backup_jobs_bh outside of coroutine (in BH) but keep
      * backup_mutex locked. This is fine, a CoMutex can be held across yield
      * points, and we'll release it as soon as the BH reschedules us.
-@@ -921,7 +888,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -915,7 +890,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      qemu_coroutine_yield();
  
      if (local_err) {
@@ -489,7 +494,7 @@ index 5662f48b72..e4fe1b601d 100644
          goto err;
      }
  
-@@ -934,7 +901,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+@@ -928,7 +903,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
      /* start the first job in the transaction */
      job_txn_start_seq(backup_state.txn);
  
@@ -498,7 +503,7 @@ index 5662f48b72..e4fe1b601d 100644
  
  err_mutex:
      qemu_mutex_unlock(&backup_state.stat.lock);
-@@ -965,7 +932,7 @@ err:
+@@ -959,7 +934,7 @@ err:
      if (vmaw) {
          Error *err = NULL;
          vma_writer_close(vmaw, &err);
@@ -507,7 +512,7 @@ index 5662f48b72..e4fe1b601d 100644
      }
  
      if (pbs) {
-@@ -976,65 +943,8 @@ err:
+@@ -970,57 +945,8 @@ err:
          rmdir(backup_dir);
      }
  
@@ -519,32 +524,27 @@ index 5662f48b72..e4fe1b601d 100644
 -
 -UuidInfo *qmp_backup(
 -    const char *backup_file,
--    bool has_password, const char *password,
--    bool has_keyfile, const char *keyfile,
--    bool has_key_password, const char *key_password,
--    bool has_fingerprint, const char *fingerprint,
--    bool has_backup_id, const char *backup_id,
+-    const char *password,
+-    const char *keyfile,
+-    const char *key_password,
+-    const char *fingerprint,
+-    const char *backup_id,
 -    bool has_backup_time, int64_t backup_time,
 -    bool has_use_dirty_bitmap, bool use_dirty_bitmap,
 -    bool has_compress, bool compress,
 -    bool has_encrypt, bool encrypt,
 -    bool has_format, BackupFormat format,
--    bool has_config_file, const char *config_file,
--    bool has_firewall_file, const char *firewall_file,
--    bool has_devlist, const char *devlist,
+-    const char *config_file,
+-    const char *firewall_file,
+-    const char *devlist,
 -    bool has_speed, int64_t speed, Error **errp)
 -{
 -    QmpBackupTask task = {
 -        .backup_file = backup_file,
--        .has_password = has_password,
 -        .password = password,
--        .has_keyfile = has_keyfile,
 -        .keyfile = keyfile,
--        .has_key_password = has_key_password,
 -        .key_password = key_password,
--        .has_fingerprint = has_fingerprint,
 -        .fingerprint = fingerprint,
--        .has_backup_id = has_backup_id,
 -        .backup_id = backup_id,
 -        .has_backup_time = has_backup_time,
 -        .backup_time = backup_time,
@@ -556,11 +556,8 @@ index 5662f48b72..e4fe1b601d 100644
 -        .encrypt = encrypt,
 -        .has_format = has_format,
 -        .format = format,
--        .has_config_file = has_config_file,
 -        .config_file = config_file,
--        .has_firewall_file = has_firewall_file,
 -        .firewall_file = firewall_file,
--        .has_devlist = has_devlist,
 -        .devlist = devlist,
 -        .has_speed = has_speed,
 -        .speed = speed,
@@ -575,10 +572,10 @@ index 5662f48b72..e4fe1b601d 100644
  
  BackupStatus *qmp_query_backup(Error **errp)
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 24f30260c8..4e8c35a3a2 100644
+index e7412f6322..93d924ef79 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -842,7 +842,7 @@
+@@ -937,7 +937,7 @@
                                      '*config-file': 'str',
                                      '*firewall-file': 'str',
                                      '*devlist': 'str', '*speed': 'int' },
@@ -587,7 +584,7 @@ index 24f30260c8..4e8c35a3a2 100644
  
  ##
  # @query-backup:
-@@ -864,7 +864,7 @@
+@@ -959,7 +959,7 @@
  # Notes: This command succeeds even if there is no backup process running.
  #
  ##
diff --git a/debian/patches/pve/0044-PBS-add-master-key-support.patch b/debian/patches/pve/0044-PBS-add-master-key-support.patch
index 7c708d7..7a7db33 100644
--- a/debian/patches/pve/0044-PBS-add-master-key-support.patch
+++ b/debian/patches/pve/0044-PBS-add-master-key-support.patch
@@ -12,6 +12,8 @@ from the PVE side to avoid QMP calls with unsupported parameters.
 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[FE: adapt to QAPI change dropping redundant has_*]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/monitor/block-hmp-cmds.c | 1 +
  pve-backup.c                   | 3 +++
@@ -19,38 +21,38 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  3 files changed, 11 insertions(+)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 71ed202491..c7468e5d3b 100644
+index bcf5849196..fb881056e9 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1039,6 +1039,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
-         false, NULL, // PBS password
-         false, NULL, // PBS keyfile
-         false, NULL, // PBS key_password
-+        false, NULL, // PBS master_keyfile
-         false, NULL, // PBS fingerprint
-         false, NULL, // PBS backup-id
+@@ -1051,6 +1051,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
+         NULL, // PBS password
+         NULL, // PBS keyfile
+         NULL, // PBS key_password
++        NULL, // PBS master_keyfile
+         NULL, // PBS fingerprint
+         NULL, // PBS backup-id
          false, 0, // PBS backup-time
 diff --git a/pve-backup.c b/pve-backup.c
-index 109498eaf9..4b5134ed27 100644
+index 378e4a9a63..504c11657a 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -529,6 +529,7 @@ UuidInfo coroutine_fn *qmp_backup(
-     bool has_password, const char *password,
-     bool has_keyfile, const char *keyfile,
-     bool has_key_password, const char *key_password,
-+    bool has_master_keyfile, const char *master_keyfile,
-     bool has_fingerprint, const char *fingerprint,
-     bool has_backup_id, const char *backup_id,
+@@ -531,6 +531,7 @@ UuidInfo coroutine_fn *qmp_backup(
+     const char *password,
+     const char *keyfile,
+     const char *key_password,
++    const char *master_keyfile,
+     const char *fingerprint,
+     const char *backup_id,
      bool has_backup_time, int64_t backup_time,
-@@ -677,6 +678,7 @@ UuidInfo coroutine_fn *qmp_backup(
-             has_password ? password : NULL,
-             has_keyfile ? keyfile : NULL,
-             has_key_password ? key_password : NULL,
-+            has_master_keyfile ? master_keyfile : NULL,
+@@ -679,6 +680,7 @@ UuidInfo coroutine_fn *qmp_backup(
+             password,
+             keyfile,
+             key_password,
++            master_keyfile,
              has_compress ? compress : true,
-             has_encrypt ? encrypt : has_keyfile,
-             has_fingerprint ? fingerprint : NULL,
-@@ -1040,5 +1042,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
+             has_encrypt ? encrypt : !!keyfile,
+             fingerprint,
+@@ -1038,5 +1040,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
      ret->pbs_dirty_bitmap_savevm = true;
      ret->pbs_dirty_bitmap_migration = true;
      ret->query_bitmap_info = true;
@@ -58,10 +60,10 @@ index 109498eaf9..4b5134ed27 100644
      return ret;
  }
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 4e8c35a3a2..d8c7331090 100644
+index 93d924ef79..568feb63ad 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -813,6 +813,8 @@
+@@ -908,6 +908,8 @@
  #
  # @key-password: password for keyfile (optional for format 'pbs')
  #
@@ -70,7 +72,7 @@ index 4e8c35a3a2..d8c7331090 100644
  # @fingerprint: server cert fingerprint (optional for format 'pbs')
  #
  # @backup-id: backup ID (required for format 'pbs')
-@@ -832,6 +834,7 @@
+@@ -927,6 +929,7 @@
                                      '*password': 'str',
                                      '*keyfile': 'str',
                                      '*key-password': 'str',
@@ -78,7 +80,7 @@ index 4e8c35a3a2..d8c7331090 100644
                                      '*fingerprint': 'str',
                                      '*backup-id': 'str',
                                      '*backup-time': 'int',
-@@ -884,6 +887,9 @@
+@@ -979,6 +982,9 @@
  #                              migration cap if this is false/unset may lead
  #                              to crashes on migration!
  #
@@ -88,7 +90,7 @@ index 4e8c35a3a2..d8c7331090 100644
  # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
  #
  ##
-@@ -892,6 +898,7 @@
+@@ -987,6 +993,7 @@
              'query-bitmap-info': 'bool',
              'pbs-dirty-bitmap-savevm': 'bool',
              'pbs-dirty-bitmap-migration': 'bool',
diff --git a/debian/patches/pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch b/debian/patches/pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch
index 1df613d..6b18def 100644
--- a/debian/patches/pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch
+++ b/debian/patches/pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch
@@ -17,10 +17,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  1 file changed, 14 insertions(+), 3 deletions(-)
 
 diff --git a/block/pbs.c b/block/pbs.c
-index 9d1f1f39d4..ce9a870885 100644
+index 43e69ada46..5d20789084 100644
 --- a/block/pbs.c
 +++ b/block/pbs.c
-@@ -200,7 +200,16 @@ static coroutine_fn int pbs_co_preadv(BlockDriverState *bs,
+@@ -201,7 +201,16 @@ static coroutine_fn int pbs_co_preadv(BlockDriverState *bs,
      BDRVPBSState *s = bs->opaque;
      int ret;
      char *pbs_error = NULL;
@@ -38,7 +38,7 @@ index 9d1f1f39d4..ce9a870885 100644
  
      if (offset < 0 || bytes < 0) {
          fprintf(stderr, "unexpected negative 'offset' or 'bytes' value!\n");
-@@ -223,8 +232,10 @@ static coroutine_fn int pbs_co_preadv(BlockDriverState *bs,
+@@ -224,8 +233,10 @@ static coroutine_fn int pbs_co_preadv(BlockDriverState *bs,
          return -EIO;
      }
  
diff --git a/debian/patches/pve/0046-PVE-block-stream-increase-chunk-size.patch b/debian/patches/pve/0046-PVE-block-stream-increase-chunk-size.patch
index 09e8d31..5707bee 100644
--- a/debian/patches/pve/0046-PVE-block-stream-increase-chunk-size.patch
+++ b/debian/patches/pve/0046-PVE-block-stream-increase-chunk-size.patch
@@ -11,10 +11,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/block/stream.c b/block/stream.c
-index 694709bd25..e09bd5c4ef 100644
+index 7f9e1ecdbb..6a29d80398 100644
 --- a/block/stream.c
 +++ b/block/stream.c
-@@ -28,7 +28,7 @@ enum {
+@@ -27,7 +27,7 @@ enum {
       * large enough to process multiple clusters in a single call, so
       * that populating contiguous regions of the image is efficient.
       */
diff --git a/debian/patches/pve/0047-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch b/debian/patches/pve/0047-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
index 269d392..d1bd74d 100644
--- a/debian/patches/pve/0047-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
+++ b/debian/patches/pve/0047-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
@@ -17,10 +17,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  1 file changed, 4 insertions(+)
 
 diff --git a/block/io.c b/block/io.c
-index b9424024f9..01f50d28c8 100644
+index 2e267a85ab..449a44bf20 100644
 --- a/block/io.c
 +++ b/block/io.c
-@@ -1730,6 +1730,10 @@ static int bdrv_pad_request(BlockDriverState *bs,
+@@ -1576,6 +1576,10 @@ static int bdrv_pad_request(BlockDriverState *bs,
  {
      int ret;
  
diff --git a/debian/patches/pve/0048-block-add-alloc-track-driver.patch b/debian/patches/pve/0048-block-add-alloc-track-driver.patch
index 833b79a..fc724c9 100644
--- a/debian/patches/pve/0048-block-add-alloc-track-driver.patch
+++ b/debian/patches/pve/0048-block-add-alloc-track-driver.patch
@@ -28,17 +28,17 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
      make error return value consistent with QEMU]
 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
- block/alloc-track.c | 350 ++++++++++++++++++++++++++++++++++++++++++++
+ block/alloc-track.c | 351 ++++++++++++++++++++++++++++++++++++++++++++
  block/meson.build   |   1 +
- 2 files changed, 351 insertions(+)
+ 2 files changed, 352 insertions(+)
  create mode 100644 block/alloc-track.c
 
 diff --git a/block/alloc-track.c b/block/alloc-track.c
 new file mode 100644
-index 0000000000..43d40d11af
+index 0000000000..113bbd7058
 --- /dev/null
 +++ b/block/alloc-track.c
-@@ -0,0 +1,350 @@
+@@ -0,0 +1,351 @@
 +/*
 + * Node to allow backing images to be applied to any node. Assumes a blank
 + * image to begin with, only new writes are tracked as allocated, thus this
@@ -54,6 +54,7 @@ index 0000000000..43d40d11af
 +#include "qemu/osdep.h"
 +#include "qapi/error.h"
 +#include "block/block_int.h"
++#include "block/dirty-bitmap.h"
 +#include "qapi/qmp/qdict.h"
 +#include "qapi/qmp/qstring.h"
 +#include "qemu/cutils.h"
@@ -163,9 +164,9 @@ index 0000000000..43d40d11af
 +    }
 +}
 +
-+static int64_t track_getlength(BlockDriverState *bs)
++static coroutine_fn int64_t track_co_getlength(BlockDriverState *bs)
 +{
-+    return bdrv_getlength(bs->file->bs);
++    return bdrv_co_getlength(bs->file->bs);
 +}
 +
 +static int coroutine_fn track_co_preadv(BlockDriverState *bs,
@@ -365,7 +366,7 @@ index 0000000000..43d40d11af
 +
 +    .bdrv_file_open                   = track_open,
 +    .bdrv_close                       = track_close,
-+    .bdrv_getlength                   = track_getlength,
++    .bdrv_co_getlength                = track_co_getlength,
 +    .bdrv_child_perm                  = track_child_perm,
 +    .bdrv_refresh_limits              = track_refresh_limits,
 +
@@ -390,7 +391,7 @@ index 0000000000..43d40d11af
 +
 +block_init(bdrv_alloc_track_init);
 diff --git a/block/meson.build b/block/meson.build
-index 7ef2fa72d5..15352f579f 100644
+index eece0d5743..8a68162cc0 100644
 --- a/block/meson.build
 +++ b/block/meson.build
 @@ -2,6 +2,7 @@ block_ss.add(genh)
diff --git a/debian/patches/pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch b/debian/patches/pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch
index c4aae04..6646d97 100644
--- a/debian/patches/pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch
+++ b/debian/patches/pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch
@@ -11,7 +11,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  1 file changed, 5 insertions(+)
 
 diff --git a/migration/savevm-async.c b/migration/savevm-async.c
-index a38e7351c1..0b1b60c6ae 100644
+index 70273a2996..fab1dc32d2 100644
 --- a/migration/savevm-async.c
 +++ b/migration/savevm-async.c
 @@ -20,6 +20,7 @@
@@ -22,7 +22,7 @@ index a38e7351c1..0b1b60c6ae 100644
  
  /* #define DEBUG_SAVEVM_STATE */
  
-@@ -521,6 +522,10 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
+@@ -518,6 +519,10 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
      dirty_bitmap_mig_before_vm_start();
  
      qemu_fclose(f);
diff --git a/debian/patches/pve/0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch b/debian/patches/pve/0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
index ed75a35..7701b55 100644
--- a/debian/patches/pve/0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
+++ b/debian/patches/pve/0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
@@ -46,10 +46,10 @@ index b5b0bb4467..36f97e1f19 100644
  
  DEF("info", img_info,
 diff --git a/qemu-img.c b/qemu-img.c
-index 59c403373b..065a54cc42 100644
+index 06d814e39c..e2c06c496d 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -4946,6 +4946,7 @@ static int img_dd(int argc, char **argv)
+@@ -5002,6 +5002,7 @@ static int img_dd(int argc, char **argv)
      BlockDriver *drv = NULL, *proto_drv = NULL;
      BlockBackend *blk1 = NULL, *blk2 = NULL;
      QemuOpts *opts = NULL;
@@ -57,7 +57,7 @@ index 59c403373b..065a54cc42 100644
      QemuOptsList *create_opts = NULL;
      Error *local_err = NULL;
      bool image_opts = false;
-@@ -4955,6 +4956,7 @@ static int img_dd(int argc, char **argv)
+@@ -5011,6 +5012,7 @@ static int img_dd(int argc, char **argv)
      int64_t size = 0, readsize = 0;
      int64_t out_pos, in_pos;
      bool force_share = false, skip_create = false;
@@ -65,7 +65,7 @@ index 59c403373b..065a54cc42 100644
      struct DdInfo dd = {
          .flags = 0,
          .count = 0,
-@@ -4992,7 +4994,7 @@ static int img_dd(int argc, char **argv)
+@@ -5048,7 +5050,7 @@ static int img_dd(int argc, char **argv)
          { 0, 0, 0, 0 }
      };
  
@@ -74,7 +74,7 @@ index 59c403373b..065a54cc42 100644
          if (c == EOF) {
              break;
          }
-@@ -5015,6 +5017,19 @@ static int img_dd(int argc, char **argv)
+@@ -5071,6 +5073,19 @@ static int img_dd(int argc, char **argv)
          case 'n':
              skip_create = true;
              break;
@@ -94,7 +94,7 @@ index 59c403373b..065a54cc42 100644
          case 'U':
              force_share = true;
              break;
-@@ -5074,11 +5089,24 @@ static int img_dd(int argc, char **argv)
+@@ -5130,11 +5145,24 @@ static int img_dd(int argc, char **argv)
      if (dd.flags & C_IF) {
          blk1 = img_open(image_opts, in.filename, fmt, 0, false, false,
                          force_share);
@@ -120,7 +120,7 @@ index 59c403373b..065a54cc42 100644
      }
  
      if (dd.flags & C_OSIZE) {
-@@ -5233,6 +5261,7 @@ static int img_dd(int argc, char **argv)
+@@ -5289,6 +5317,7 @@ static int img_dd(int argc, char **argv)
  out:
      g_free(arg);
      qemu_opts_del(opts);
diff --git a/debian/patches/pve/0052-pbs-namespace-support.patch b/debian/patches/pve/0052-pbs-namespace-support.patch
index 2640b95..958fb5f 100644
--- a/debian/patches/pve/0052-pbs-namespace-support.patch
+++ b/debian/patches/pve/0052-pbs-namespace-support.patch
@@ -4,6 +4,8 @@ Date: Tue, 26 Apr 2022 16:06:28 +0200
 Subject: [PATCH] pbs: namespace support
 
 Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+[FE: adapt to QAPI change dropping redundant has_*]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/monitor/block-hmp-cmds.c |  1 +
  block/pbs.c                    | 25 +++++++++++++++++++++----
@@ -13,22 +15,22 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
  5 files changed, 47 insertions(+), 9 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index c7468e5d3b..57b2457f1e 100644
+index fb881056e9..25ac598980 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1041,6 +1041,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
-         false, NULL, // PBS key_password
-         false, NULL, // PBS master_keyfile
-         false, NULL, // PBS fingerprint
-+        false, NULL, // PBS backup-ns
-         false, NULL, // PBS backup-id
+@@ -1053,6 +1053,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
+         NULL, // PBS key_password
+         NULL, // PBS master_keyfile
+         NULL, // PBS fingerprint
++        NULL, // PBS backup-ns
+         NULL, // PBS backup-id
          false, 0, // PBS backup-time
          false, false, // PBS use-dirty-bitmap
 diff --git a/block/pbs.c b/block/pbs.c
-index ce9a870885..9192f3e41b 100644
+index 5d20789084..a2211e0f3b 100644
 --- a/block/pbs.c
 +++ b/block/pbs.c
-@@ -14,6 +14,7 @@
+@@ -15,6 +15,7 @@
  #include <proxmox-backup-qemu.h>
  
  #define PBS_OPT_REPOSITORY "repository"
@@ -36,7 +38,7 @@ index ce9a870885..9192f3e41b 100644
  #define PBS_OPT_SNAPSHOT "snapshot"
  #define PBS_OPT_ARCHIVE "archive"
  #define PBS_OPT_KEYFILE "keyfile"
-@@ -27,6 +28,7 @@ typedef struct {
+@@ -28,6 +29,7 @@ typedef struct {
      int64_t length;
  
      char *repository;
@@ -44,7 +46,7 @@ index ce9a870885..9192f3e41b 100644
      char *snapshot;
      char *archive;
  } BDRVPBSState;
-@@ -40,6 +42,11 @@ static QemuOptsList runtime_opts = {
+@@ -41,6 +43,11 @@ static QemuOptsList runtime_opts = {
              .type = QEMU_OPT_STRING,
              .help = "The server address and repository to connect to.",
          },
@@ -56,7 +58,7 @@ index ce9a870885..9192f3e41b 100644
          {
              .name = PBS_OPT_SNAPSHOT,
              .type = QEMU_OPT_STRING,
-@@ -76,7 +83,7 @@ static QemuOptsList runtime_opts = {
+@@ -77,7 +84,7 @@ static QemuOptsList runtime_opts = {
  
  
  // filename format:
@@ -65,7 +67,7 @@ index ce9a870885..9192f3e41b 100644
  static void pbs_parse_filename(const char *filename, QDict *options,
                                       Error **errp)
  {
-@@ -112,6 +119,7 @@ static int pbs_open(BlockDriverState *bs, QDict *options, int flags,
+@@ -113,6 +120,7 @@ static int pbs_open(BlockDriverState *bs, QDict *options, int flags,
      s->archive = g_strdup(qemu_opt_get(opts, PBS_OPT_ARCHIVE));
      const char *keyfile = qemu_opt_get(opts, PBS_OPT_KEYFILE);
      const char *password = qemu_opt_get(opts, PBS_OPT_PASSWORD);
@@ -73,7 +75,7 @@ index ce9a870885..9192f3e41b 100644
      const char *fingerprint = qemu_opt_get(opts, PBS_OPT_FINGERPRINT);
      const char *key_password = qemu_opt_get(opts, PBS_OPT_ENCRYPTION_PASSWORD);
  
-@@ -124,9 +132,12 @@ static int pbs_open(BlockDriverState *bs, QDict *options, int flags,
+@@ -125,9 +133,12 @@ static int pbs_open(BlockDriverState *bs, QDict *options, int flags,
      if (!key_password) {
          key_password = getenv("PBS_ENCRYPTION_PASSWORD");
      }
@@ -87,7 +89,7 @@ index ce9a870885..9192f3e41b 100644
          keyfile, key_password, fingerprint, &pbs_error);
  
      /* invalidates qemu_opt_get char pointers from above */
-@@ -171,6 +182,7 @@ static int pbs_file_open(BlockDriverState *bs, QDict *options, int flags,
+@@ -172,6 +183,7 @@ static int pbs_file_open(BlockDriverState *bs, QDict *options, int flags,
  static void pbs_close(BlockDriverState *bs) {
      BDRVPBSState *s = bs->opaque;
      g_free(s->repository);
@@ -95,7 +97,7 @@ index ce9a870885..9192f3e41b 100644
      g_free(s->snapshot);
      g_free(s->archive);
      proxmox_restore_disconnect(s->conn);
-@@ -252,8 +264,13 @@ static coroutine_fn int pbs_co_pwritev(BlockDriverState *bs,
+@@ -253,8 +265,13 @@ static coroutine_fn int pbs_co_pwritev(BlockDriverState *bs,
  static void pbs_refresh_filename(BlockDriverState *bs)
  {
      BDRVPBSState *s = bs->opaque;
@@ -170,10 +172,10 @@ index 2f834cf42e..f03d9bab8d 100644
          fprintf(stderr, "restore failed: %s\n", pbs_error);
          return -1;
 diff --git a/pve-backup.c b/pve-backup.c
-index 4b5134ed27..262e7d3894 100644
+index 504c11657a..809ff6d134 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -10,6 +10,8 @@
+@@ -12,6 +12,8 @@
  #include "qapi/qmp/qerror.h"
  #include "qemu/cutils.h"
  
@@ -182,30 +184,30 @@ index 4b5134ed27..262e7d3894 100644
  /* PVE backup state and related function */
  
  /*
-@@ -531,6 +533,7 @@ UuidInfo coroutine_fn *qmp_backup(
-     bool has_key_password, const char *key_password,
-     bool has_master_keyfile, const char *master_keyfile,
-     bool has_fingerprint, const char *fingerprint,
-+    bool has_backup_ns, const char *backup_ns,
-     bool has_backup_id, const char *backup_id,
+@@ -533,6 +535,7 @@ UuidInfo coroutine_fn *qmp_backup(
+     const char *key_password,
+     const char *master_keyfile,
+     const char *fingerprint,
++    const char *backup_ns,
+     const char *backup_id,
      bool has_backup_time, int64_t backup_time,
      bool has_use_dirty_bitmap, bool use_dirty_bitmap,
-@@ -670,8 +673,9 @@ UuidInfo coroutine_fn *qmp_backup(
+@@ -672,8 +675,9 @@ UuidInfo coroutine_fn *qmp_backup(
          firewall_name = "fw.conf";
  
          char *pbs_err = NULL;
 -        pbs = proxmox_backup_new(
 +        pbs = proxmox_backup_new_ns(
              backup_file,
-+            has_backup_ns ? backup_ns : NULL,
++            backup_ns,
              backup_id,
              backup_time,
              dump_cb_block_size,
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index d8c7331090..889726fc26 100644
+index 568feb63ad..9edeb33d82 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -817,6 +817,8 @@
+@@ -912,6 +912,8 @@
  #
  # @fingerprint: server cert fingerprint (optional for format 'pbs')
  #
@@ -214,7 +216,7 @@ index d8c7331090..889726fc26 100644
  # @backup-id: backup ID (required for format 'pbs')
  #
  # @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
-@@ -836,6 +838,7 @@
+@@ -931,6 +933,7 @@
                                      '*key-password': 'str',
                                      '*master-keyfile': 'str',
                                      '*fingerprint': 'str',
@@ -222,7 +224,7 @@ index d8c7331090..889726fc26 100644
                                      '*backup-id': 'str',
                                      '*backup-time': 'int',
                                      '*use-dirty-bitmap': 'bool',
-@@ -3290,7 +3293,7 @@
+@@ -3385,7 +3388,7 @@
  { 'struct': 'BlockdevOptionsPbs',
    'data': { 'repository': 'str', 'snapshot': 'str', 'archive': 'str',
              '*keyfile': 'str', '*password': 'str', '*fingerprint': 'str',
diff --git a/debian/patches/pve/0053-Revert-block-rbd-workaround-for-ceph-issue-53784.patch b/debian/patches/pve/0053-Revert-block-rbd-workaround-for-ceph-issue-53784.patch
index 9827983..e60e74f 100644
--- a/debian/patches/pve/0053-Revert-block-rbd-workaround-for-ceph-issue-53784.patch
+++ b/debian/patches/pve/0053-Revert-block-rbd-workaround-for-ceph-issue-53784.patch
@@ -12,10 +12,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
  1 file changed, 2 insertions(+), 40 deletions(-)
 
 diff --git a/block/rbd.c b/block/rbd.c
-index 64a8d7d48b..9fc6dcb957 100644
+index a4749f3b1b..53e0396b51 100644
 --- a/block/rbd.c
 +++ b/block/rbd.c
-@@ -1348,7 +1348,6 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
+@@ -1511,7 +1511,6 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
      int status, r;
      RBDDiffIterateReq req = { .offs = offset };
      uint64_t features, flags;
@@ -23,7 +23,7 @@ index 64a8d7d48b..9fc6dcb957 100644
  
      assert(offset + bytes <= s->image_size);
  
-@@ -1376,43 +1375,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
+@@ -1539,43 +1538,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
          return status;
      }
  
@@ -68,7 +68,7 @@ index 64a8d7d48b..9fc6dcb957 100644
                            qemu_rbd_diff_iterate_cb, &req);
      if (r < 0 && r != QEMU_RBD_EXIT_DIFF_ITERATE2) {
          return status;
-@@ -1431,8 +1394,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
+@@ -1594,8 +1557,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
          status = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID;
      }
  
diff --git a/debian/patches/pve/0054-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch b/debian/patches/pve/0054-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch
index 6972373..e5fad08 100644
--- a/debian/patches/pve/0054-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch
+++ b/debian/patches/pve/0054-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch
@@ -13,10 +13,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
  1 file changed, 5 insertions(+), 5 deletions(-)
 
 diff --git a/block/rbd.c b/block/rbd.c
-index 9fc6dcb957..98f4ba2620 100644
+index 53e0396b51..0913a0af39 100644
 --- a/block/rbd.c
 +++ b/block/rbd.c
-@@ -1307,11 +1307,11 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len,
+@@ -1470,11 +1470,11 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len,
      RBDDiffIterateReq *req = opaque;
  
      assert(req->offs + req->bytes <= offs);
diff --git a/debian/patches/pve/0055-Revert-block-rbd-implement-bdrv_co_block_status.patch b/debian/patches/pve/0055-Revert-block-rbd-implement-bdrv_co_block_status.patch
index f7025a3..7e1ee52 100644
--- a/debian/patches/pve/0055-Revert-block-rbd-implement-bdrv_co_block_status.patch
+++ b/debian/patches/pve/0055-Revert-block-rbd-implement-bdrv_co_block_status.patch
@@ -23,10 +23,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
  1 file changed, 112 deletions(-)
 
 diff --git a/block/rbd.c b/block/rbd.c
-index 98f4ba2620..efcbbe5949 100644
+index 0913a0af39..1dab254517 100644
 --- a/block/rbd.c
 +++ b/block/rbd.c
-@@ -97,12 +97,6 @@ typedef struct RBDTask {
+@@ -108,12 +108,6 @@ typedef struct RBDTask {
      int64_t ret;
  } RBDTask;
  
@@ -39,7 +39,7 @@ index 98f4ba2620..efcbbe5949 100644
  static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
                              BlockdevOptionsRbd *opts, bool cache,
                              const char *keypairs, const char *secretid,
-@@ -1293,111 +1287,6 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
+@@ -1456,111 +1450,6 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
      return spec_info;
  }
  
@@ -148,10 +148,10 @@ index 98f4ba2620..efcbbe5949 100644
 -    return status;
 -}
 -
- static int64_t qemu_rbd_getlength(BlockDriverState *bs)
+ static int64_t coroutine_fn qemu_rbd_co_getlength(BlockDriverState *bs)
  {
      BDRVRBDState *s = bs->opaque;
-@@ -1633,7 +1522,6 @@ static BlockDriver bdrv_rbd = {
+@@ -1796,7 +1685,6 @@ static BlockDriver bdrv_rbd = {
  #ifdef LIBRBD_SUPPORTS_WRITE_ZEROES
      .bdrv_co_pwrite_zeroes  = qemu_rbd_co_pwrite_zeroes,
  #endif
diff --git a/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch b/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
index 3598205..1b3e9ec 100644
--- a/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
+++ b/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
@@ -21,10 +21,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 8 insertions(+), 2 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 262e7d3894..fde3554133 100644
+index 809ff6d134..221e45ed0e 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -503,6 +503,11 @@ static void create_backup_jobs_bh(void *opaque) {
+@@ -505,6 +505,11 @@ static void create_backup_jobs_bh(void *opaque) {
      }
  
      if (*errp) {
@@ -36,7 +36,7 @@ index 262e7d3894..fde3554133 100644
          l = backup_state.di_list;
          while (l) {
              PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-@@ -513,11 +518,11 @@ static void create_backup_jobs_bh(void *opaque) {
+@@ -515,11 +520,11 @@ static void create_backup_jobs_bh(void *opaque) {
                  di->target = NULL;
              }
  
@@ -50,7 +50,7 @@ index 262e7d3894..fde3554133 100644
              }
          }
      }
-@@ -943,6 +948,7 @@ err:
+@@ -945,6 +950,7 @@ err:
  
      if (pbs) {
          proxmox_backup_disconnect(pbs);
diff --git a/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch b/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
index 1446569..0e66858 100644
--- a/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
+++ b/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
@@ -23,10 +23,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 19 insertions(+), 3 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index fde3554133..0cf30e1ced 100644
+index 221e45ed0e..a20fa38ee8 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -316,6 +316,13 @@ static void coroutine_fn pvebackup_co_complete_stream(void *opaque)
+@@ -318,6 +318,13 @@ static void coroutine_fn pvebackup_co_complete_stream(void *opaque)
          }
      }
  
@@ -40,7 +40,7 @@ index fde3554133..0cf30e1ced 100644
      // remove self from job list
      backup_state.di_list = g_list_remove(backup_state.di_list, di);
  
-@@ -491,6 +498,11 @@ static void create_backup_jobs_bh(void *opaque) {
+@@ -493,6 +500,11 @@ static void create_backup_jobs_bh(void *opaque) {
          aio_context_release(aio_context);
  
          di->job = job;
@@ -52,7 +52,7 @@ index fde3554133..0cf30e1ced 100644
  
          if (!job || local_err) {
              error_setg(errp, "backup_job_create failed: %s",
-@@ -518,11 +530,15 @@ static void create_backup_jobs_bh(void *opaque) {
+@@ -520,11 +532,15 @@ static void create_backup_jobs_bh(void *opaque) {
                  di->target = NULL;
              }
  
diff --git a/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch b/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
index 1fbf04a..5a9da14 100644
--- a/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
+++ b/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
@@ -39,10 +39,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 38 insertions(+), 19 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 0cf30e1ced..4067018dbe 100644
+index a20fa38ee8..3509f46ed8 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -354,12 +354,41 @@ static void pvebackup_complete_cb(void *opaque, int ret)
+@@ -356,12 +356,41 @@ static void pvebackup_complete_cb(void *opaque, int ret)
  
  /*
   * job_cancel(_sync) does not like to be called from coroutines, so defer to
@@ -87,7 +87,7 @@ index 0cf30e1ced..4067018dbe 100644
      aio_co_enter(data->ctx, data->co);
  }
  
-@@ -380,22 +409,12 @@ void coroutine_fn qmp_backup_cancel(Error **errp)
+@@ -382,22 +411,12 @@ void coroutine_fn qmp_backup_cancel(Error **errp)
          proxmox_backup_abort(backup_state.pbs, "backup canceled");
      }
  
diff --git a/debian/patches/pve/0061-block-alloc-track-avoid-premature-break.patch b/debian/patches/pve/0061-block-alloc-track-avoid-premature-break.patch
index 435326c..a1c3d11 100644
--- a/debian/patches/pve/0061-block-alloc-track-avoid-premature-break.patch
+++ b/debian/patches/pve/0061-block-alloc-track-avoid-premature-break.patch
@@ -21,10 +21,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/block/alloc-track.c b/block/alloc-track.c
-index 43d40d11af..95c9c67cd8 100644
+index 113bbd7058..b75d7c6460 100644
 --- a/block/alloc-track.c
 +++ b/block/alloc-track.c
-@@ -174,7 +174,8 @@ static int coroutine_fn track_co_preadv(BlockDriverState *bs,
+@@ -175,7 +175,8 @@ static int coroutine_fn track_co_preadv(BlockDriverState *bs,
              ret = bdrv_co_preadv(bs->backing, local_offset, local_bytes,
                                   &local_qiov, flags);
          } else {
diff --git a/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch b/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
index c22b380..43efd1d 100644
--- a/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
+++ b/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
@@ -31,13 +31,13 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  3 files changed, 23 insertions(+), 8 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 57b2457f1e..ab0c988ae9 100644
+index 25ac598980..74e43a757f 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1049,7 +1049,9 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
+@@ -1061,7 +1061,9 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
          false, false, // PBS encrypt
          true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
-         false, NULL, false, NULL, !!devlist,
+         NULL, NULL,
 -        devlist, qdict_haskey(qdict, "speed"), speed, &error);
 +        devlist, qdict_haskey(qdict, "speed"), speed,
 +        false, 0, // BackupPerf max-workers
@@ -46,10 +46,10 @@ index 57b2457f1e..ab0c988ae9 100644
      hmp_handle_error(mon, error);
  }
 diff --git a/pve-backup.c b/pve-backup.c
-index 4067018dbe..3ca4f74cb8 100644
+index 3509f46ed8..a343d63586 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -55,6 +55,7 @@ static struct PVEBackupState {
+@@ -57,6 +57,7 @@ static struct PVEBackupState {
          bool starting;
      } stat;
      int64_t speed;
@@ -57,7 +57,7 @@ index 4067018dbe..3ca4f74cb8 100644
      VmaWriter *vmaw;
      ProxmoxBackupHandle *pbs;
      GList *di_list;
-@@ -490,8 +491,6 @@ static void create_backup_jobs_bh(void *opaque) {
+@@ -492,8 +493,6 @@ static void create_backup_jobs_bh(void *opaque) {
      }
      backup_state.txn = job_txn_new_seq();
  
@@ -66,7 +66,7 @@ index 4067018dbe..3ca4f74cb8 100644
      /* create and start all jobs (paused state) */
      GList *l =  backup_state.di_list;
      while (l) {
-@@ -511,8 +510,9 @@ static void create_backup_jobs_bh(void *opaque) {
+@@ -513,8 +512,9 @@ static void create_backup_jobs_bh(void *opaque) {
  
          BlockJob *job = backup_job_create(
              NULL, di->bs, di->target, backup_state.speed, sync_mode, di->bitmap,
@@ -78,10 +78,10 @@ index 4067018dbe..3ca4f74cb8 100644
  
          aio_context_release(aio_context);
  
-@@ -583,7 +583,9 @@ UuidInfo coroutine_fn *qmp_backup(
-     bool has_config_file, const char *config_file,
-     bool has_firewall_file, const char *firewall_file,
-     bool has_devlist, const char *devlist,
+@@ -585,7 +585,9 @@ UuidInfo coroutine_fn *qmp_backup(
+     const char *config_file,
+     const char *firewall_file,
+     const char *devlist,
 -    bool has_speed, int64_t speed, Error **errp)
 +    bool has_speed, int64_t speed,
 +    bool has_max_workers, int64_t max_workers,
@@ -89,7 +89,7 @@ index 4067018dbe..3ca4f74cb8 100644
  {
      assert(qemu_in_coroutine());
  
-@@ -913,6 +915,11 @@ UuidInfo coroutine_fn *qmp_backup(
+@@ -915,6 +917,11 @@ UuidInfo coroutine_fn *qmp_backup(
  
      backup_state.speed = (has_speed && speed > 0) ? speed : 0;
  
@@ -101,7 +101,7 @@ index 4067018dbe..3ca4f74cb8 100644
      backup_state.vmaw = vmaw;
      backup_state.pbs = pbs;
  
-@@ -1088,5 +1095,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
+@@ -1086,5 +1093,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
      ret->pbs_dirty_bitmap_migration = true;
      ret->query_bitmap_info = true;
      ret->pbs_masterkey = true;
@@ -109,10 +109,10 @@ index 4067018dbe..3ca4f74cb8 100644
      return ret;
  }
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 889726fc26..65795b7204 100644
+index 9edeb33d82..809f3c61bc 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -829,6 +829,8 @@
+@@ -924,6 +924,8 @@
  #
  # @encrypt: use encryption ((optional for format 'pbs', defaults to true if there is a keyfile)
  #
@@ -121,7 +121,7 @@ index 889726fc26..65795b7204 100644
  # Returns: the uuid of the backup job
  #
  ##
-@@ -847,7 +849,9 @@
+@@ -942,7 +944,9 @@
                                      '*format': 'BackupFormat',
                                      '*config-file': 'str',
                                      '*firewall-file': 'str',
@@ -132,7 +132,7 @@ index 889726fc26..65795b7204 100644
    'returns': 'UuidInfo', 'coroutine': true }
  
  ##
-@@ -902,7 +906,8 @@
+@@ -997,7 +1001,8 @@
              'pbs-dirty-bitmap-savevm': 'bool',
              'pbs-dirty-bitmap-migration': 'bool',
              'pbs-masterkey': 'bool',
diff --git a/debian/patches/pve/0063-alloc-track-fix-deadlock-during-drop.patch b/debian/patches/pve/0063-alloc-track-fix-deadlock-during-drop.patch
new file mode 100644
index 0000000..8169445
--- /dev/null
+++ b/debian/patches/pve/0063-alloc-track-fix-deadlock-during-drop.patch
@@ -0,0 +1,153 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Fiona Ebner <f.ebner@proxmox.com>
+Date: Thu, 6 Apr 2023 14:59:31 +0200
+Subject: [PATCH] alloc-track: fix deadlock during drop
+
+by replacing the block node directly after changing the backing file
+instead of rescheduling it.
+
+With changes in QEMU 8.0, calling bdrv_get_info (and bdrv_unref)
+during drop can lead to a deadlock when using iothread (only triggered
+with multiple disks, except during debugging where it also triggered
+with one disk sometimes):
+1. job_unref_locked acquires the AioContext and calls job->driver->free
+2. track_drop gets scheduled
+3. bdrv_graph_wrlock is called and polls which leads to track_drop being
+   called
+4. track_drop acquires the AioContext recursively
+5. bdrv_get_info is a wrapped coroutine (since 8.0) and thus polls for
+   bdrv_co_get_info. This releases the AioContext, but only once! The
+   documentation for the AIO_WAIT_WHILE macro states that the
+   AioContext lock needs to be acquired exactly once, but there does
+   not seem to be a way for track_drop to know if it acquired the lock
+   recursively or not (without adding further hacks).
+6. Because the AioContext is still held by the main thread once, it can't
+   be acquired before entering bdrv_co_get_info in co_schedule_bh_cb
+   which happens in the iothread
+
+When doing the operation in change_backing_file, the AioContext has
+already been acquired by the caller, so the issue with the recursive
+lock goes away.
+
+The comment explaining why delaying the replace is necessary is
+> we need to schedule this for later however, since when this function
+> is called, the blockjob modifying us is probably not done yet and
+> has a blocker on 'bs'
+
+However, there is no check for blockers in bdrv_replace_node. It would
+need to be done by us, the caller, with check_to_replace_node.
+Furthermore, the mirror job also does its call to bdrv_replace_node
+while there is an active blocker (inserted by mirror itself) and they
+use a specialized version to check for blockers instead of
+check_to_replace_node there. Alloc-track could also do something
+similar to check for other blockers, but it should be fine to rely on
+Proxmox VE that no other operation with the blockdev is going on.
+
+Mirror also drains the target before replacing the node, but the
+target can have other users. In case of alloc-track the file child
+should not be accessible by anybody else and so there can't be an
+in-flight operation for the file child when alloc-track is drained.
+
+The rescheduling based on refcounting is a hack and it doesn't seem to
+be necessary anymore. It's not clear what the original issue from the
+comment was. Testing with older builds with track_drop done directly
+without rescheduling also didn't lead to any noticable issue for me.
+
+One issue it might have been is the one fixed by b1e1af394d
+("block/stream: Drain subtree around graph change"), where
+block-stream had a use-after-free if the base node changed at an
+inconvenient time (which alloc-track's auto-drop does).
+
+It's also not possible to just not auto-replace the alloc-track. Not
+replacing it at all leads to other operations like block resize
+hanging, and there is no good way to replace it manually via QMP
+(there is x-blockdev-change, but it is experimental and doesn't
+implement the required operation yet). Also, it's just cleaner in
+general to not leave unnecessary block nodes lying around.
+
+Suggested-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ block/alloc-track.c | 54 ++++++++++++++-------------------------------
+ 1 file changed, 16 insertions(+), 38 deletions(-)
+
+diff --git a/block/alloc-track.c b/block/alloc-track.c
+index b75d7c6460..76da140a68 100644
+--- a/block/alloc-track.c
++++ b/block/alloc-track.c
+@@ -25,7 +25,6 @@
+ 
+ typedef enum DropState {
+     DropNone,
+-    DropRequested,
+     DropInProgress,
+ } DropState;
+ 
+@@ -268,37 +267,6 @@ static void track_child_perm(BlockDriverState *bs, BdrvChild *c,
+     }
+ }
+ 
+-static void track_drop(void *opaque)
+-{
+-    BlockDriverState *bs = (BlockDriverState*)opaque;
+-    BlockDriverState *file = bs->file->bs;
+-    BDRVAllocTrackState *s = bs->opaque;
+-
+-    assert(file);
+-
+-    /* we rely on the fact that we're not used anywhere else, so let's wait
+-     * until we're only used once - in the drive connected to the guest (and one
+-     * ref is held by bdrv_ref in track_change_backing_file) */
+-    if (bs->refcnt > 2) {
+-        aio_bh_schedule_oneshot(qemu_get_aio_context(), track_drop, opaque);
+-        return;
+-    }
+-    AioContext *aio_context = bdrv_get_aio_context(bs);
+-    aio_context_acquire(aio_context);
+-
+-    bdrv_drained_begin(bs);
+-
+-    /* now that we're drained, we can safely set 'DropInProgress' */
+-    s->drop_state = DropInProgress;
+-    bdrv_child_refresh_perms(bs, bs->file, &error_abort);
+-
+-    bdrv_replace_node(bs, file, &error_abort);
+-    bdrv_set_backing_hd(bs, NULL, &error_abort);
+-    bdrv_drained_end(bs);
+-    bdrv_unref(bs);
+-    aio_context_release(aio_context);
+-}
+-
+ static int track_change_backing_file(BlockDriverState *bs,
+                                      const char *backing_file,
+                                      const char *backing_fmt)
+@@ -308,13 +276,23 @@ static int track_change_backing_file(BlockDriverState *bs,
+         backing_file == NULL && backing_fmt == NULL)
+     {
+         /* backing file has been disconnected, there's no longer any use for
+-         * this node, so let's remove ourselves from the block graph - we need
+-         * to schedule this for later however, since when this function is
+-         * called, the blockjob modifying us is probably not done yet and has a
+-         * blocker on 'bs' */
+-        s->drop_state = DropRequested;
++         * this node, so let's remove ourselves from the block graph */
++        BlockDriverState *file = bs->file->bs;
++
++        /* Just to be sure, because bdrv_replace_node unrefs it */
+         bdrv_ref(bs);
+-        aio_bh_schedule_oneshot(qemu_get_aio_context(), track_drop, (void*)bs);
++        bdrv_drained_begin(bs);
++
++        /* now that we're drained, we can safely set 'DropInProgress' */
++        s->drop_state = DropInProgress;
++
++        bdrv_child_refresh_perms(bs, bs->file, &error_abort);
++
++        bdrv_replace_node(bs, file, &error_abort);
++        bdrv_set_backing_hd(bs, NULL, &error_abort);
++
++        bdrv_drained_end(bs);
++        bdrv_unref(bs);
+     }
+ 
+     return 0;
diff --git a/debian/patches/pve/0064-savevm-async-optimize-querying-pending.patch b/debian/patches/pve/0064-savevm-async-optimize-querying-pending.patch
new file mode 100644
index 0000000..fb99782
--- /dev/null
+++ b/debian/patches/pve/0064-savevm-async-optimize-querying-pending.patch
@@ -0,0 +1,49 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Fiona Ebner <f.ebner@proxmox.com>
+Date: Fri, 31 Mar 2023 14:13:01 +0200
+Subject: [PATCH] savevm-async: optimize querying pending
+
+by using the estimate variant until the precopy estimate is below the
+threshold. This is similar to what is done in migration.c
+
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ migration/savevm-async.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/migration/savevm-async.c b/migration/savevm-async.c
+index fab1dc32d2..de91506821 100644
+--- a/migration/savevm-async.c
++++ b/migration/savevm-async.c
+@@ -242,12 +242,19 @@ static void coroutine_fn process_savevm_co(void *opaque)
+ 
+     while (snap_state.state == SAVE_STATE_ACTIVE) {
+         uint64_t pending_size, pend_precopy, pend_postcopy;
++        uint64_t threshold = 400 * 1000;
+ 
+-        /* pending is expected to be called without iothread lock */
++        /*
++         * pending_{estimate,exact} are expected to be called without iothread
++         * lock. Similar to what is done in migration.c, call the exact variant
++         * only once pend_precopy in the estimate is below the threshold.
++         */
+         qemu_mutex_unlock_iothread();
+-        qemu_savevm_state_pending_exact(&pend_precopy, &pend_postcopy);
++        qemu_savevm_state_pending_estimate(&pend_precopy, &pend_postcopy);
++        if (pend_precopy <= threshold) {
++            qemu_savevm_state_pending_exact(&pend_precopy, &pend_postcopy);
++        }
+         qemu_mutex_lock_iothread();
+-
+         pending_size = pend_precopy + pend_postcopy;
+ 
+         /*
+@@ -259,7 +266,7 @@ static void coroutine_fn process_savevm_co(void *opaque)
+         maxlen = blk_getlength(snap_state.target) - 100*1024*1024;
+ 
+         /* Note that there is no progress for pend_postcopy when iterating */
+-        if (pending_size - pend_postcopy > 400000 && snap_state.bs_pos + pending_size < maxlen) {
++        if (pend_precopy > threshold && snap_state.bs_pos + pending_size < maxlen) {
+             ret = qemu_savevm_state_iterate(snap_state.file, false);
+             if (ret < 0) {
+                 save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
diff --git a/debian/patches/pve/0065-savevm-async-also-initialize-compression-counters.patch b/debian/patches/pve/0065-savevm-async-also-initialize-compression-counters.patch
new file mode 100644
index 0000000..ae2b463
--- /dev/null
+++ b/debian/patches/pve/0065-savevm-async-also-initialize-compression-counters.patch
@@ -0,0 +1,26 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Fiona Ebner <f.ebner@proxmox.com>
+Date: Thu, 27 Apr 2023 10:28:08 +0200
+Subject: [PATCH] savevm-async: also initialize compression counters
+
+Like is done in the migration code. While the compression migration
+capability is not used by Proxmox VE currently, it's still worth to
+be prepared for the future.
+
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ migration/savevm-async.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/migration/savevm-async.c b/migration/savevm-async.c
+index de91506821..effe6d1e0d 100644
+--- a/migration/savevm-async.c
++++ b/migration/savevm-async.c
+@@ -394,6 +394,7 @@ void qmp_savevm_start(const char *statefile, Error **errp)
+      */
+     migrate_init(ms);
+     memset(&ram_counters, 0, sizeof(ram_counters));
++    memset(&compression_counters, 0, sizeof(compression_counters));
+     ms->to_dst_file = snap_state.file;
+ 
+     error_setg(&snap_state.blocker, "block device is in use by savevm");
diff --git a/debian/patches/pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch b/debian/patches/pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
new file mode 100644
index 0000000..cbc39cc
--- /dev/null
+++ b/debian/patches/pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
@@ -0,0 +1,190 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Fiona Ebner <f.ebner@proxmox.com>
+Date: Fri, 5 May 2023 13:39:53 +0200
+Subject: [PATCH] migration: for snapshots, hold the BQL during setup callbacks
+
+In spirit, this is a partial revert of commit 9b09503752 ("migration:
+run setup callbacks out of big lock"), but only for the snapshot case.
+
+For snapshots, the bdrv_writev_vmstate() function is used during setup
+(in QIOChannelBlock backing the QEMUFile), but not holding the BQL
+while calling it could lead to an assertion failure. To understand
+how, first note the following:
+
+1. Generated coroutine wrappers for block layer functions spawn the
+coroutine and use AIO_WAIT_WHILE()/aio_poll() to wait for it.
+2. If the host OS switches threads at an inconvenient time, it can
+happen that a bottom half scheduled for the main thread's AioContext
+is executed as part of a vCPU thread's aio_poll().
+
+An example leading to the assertion failure is as follows:
+
+main thread:
+1. A snapshot-save QMP command gets issued.
+2. snapshot_save_job_bh() is scheduled.
+
+vCPU thread:
+3. aio_poll() for the main thread's AioContext is called (e.g. when
+the guest writes to a pflash device, as part of blk_pwrite which is a
+generated coroutine wrapper).
+4. snapshot_save_job_bh() is executed as part of aio_poll().
+3. qemu_savevm_state() is called.
+4. qemu_mutex_unlock_iothread() is called. Now
+qemu_get_current_aio_context() returns 0x0.
+5. bdrv_writev_vmstate() is executed during the usual savevm setup.
+But this function is a generated coroutine wrapper, so it uses
+AIO_WAIT_WHILE. There, the assertion
+assert(qemu_get_current_aio_context() == qemu_get_aio_context());
+will fail.
+
+To fix it, ensure that the BQL is held during setup. To avoid changing
+the behavior for migration too, introduce conditionals for the setup
+callbacks that need the BQL and only take the lock if it's not already
+held.
+
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ include/migration/register.h   |  2 +-
+ migration/block-dirty-bitmap.c | 15 ++++++++++++---
+ migration/block.c              | 15 ++++++++++++---
+ migration/ram.c                | 16 +++++++++++++---
+ migration/savevm.c             |  2 --
+ 5 files changed, 38 insertions(+), 12 deletions(-)
+
+diff --git a/include/migration/register.h b/include/migration/register.h
+index a8dfd8fefd..fa9b0b0f10 100644
+--- a/include/migration/register.h
++++ b/include/migration/register.h
+@@ -43,9 +43,9 @@ typedef struct SaveVMHandlers {
+      * by other locks.
+      */
+     int (*save_live_iterate)(QEMUFile *f, void *opaque);
++    int (*save_setup)(QEMUFile *f, void *opaque);
+ 
+     /* This runs outside the iothread lock!  */
+-    int (*save_setup)(QEMUFile *f, void *opaque);
+     /* Note for save_live_pending:
+      * must_precopy:
+      * - must be migrated in precopy or in stopped state
+diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
+index a6440929fa..69fab3275c 100644
+--- a/migration/block-dirty-bitmap.c
++++ b/migration/block-dirty-bitmap.c
+@@ -1214,10 +1214,17 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
+ {
+     DBMSaveState *s = &((DBMState *)opaque)->save;
+     SaveBitmapState *dbms = NULL;
++    bool release_lock = false;
+ 
+-    qemu_mutex_lock_iothread();
++    /* For snapshots, the BQL is held during setup. */
++    if (!qemu_mutex_iothread_locked()) {
++        qemu_mutex_lock_iothread();
++        release_lock = true;
++    }
+     if (init_dirty_bitmap_migration(s) < 0) {
+-        qemu_mutex_unlock_iothread();
++        if (release_lock) {
++            qemu_mutex_unlock_iothread();
++        }
+         return -1;
+     }
+ 
+@@ -1225,7 +1232,9 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
+         send_bitmap_start(f, s, dbms);
+     }
+     qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
+-    qemu_mutex_unlock_iothread();
++    if (release_lock) {
++        qemu_mutex_unlock_iothread();
++    }
+     return 0;
+ }
+ 
+diff --git a/migration/block.c b/migration/block.c
+index b2497bbd32..c9d55be642 100644
+--- a/migration/block.c
++++ b/migration/block.c
+@@ -716,21 +716,30 @@ static void block_migration_cleanup(void *opaque)
+ static int block_save_setup(QEMUFile *f, void *opaque)
+ {
+     int ret;
++    bool release_lock = false;
+ 
+     trace_migration_block_save("setup", block_mig_state.submitted,
+                                block_mig_state.transferred);
+ 
+-    qemu_mutex_lock_iothread();
++    /* For snapshots, the BQL is held during setup. */
++    if (!qemu_mutex_iothread_locked()) {
++        qemu_mutex_lock_iothread();
++        release_lock = true;
++    }
+     ret = init_blk_migration(f);
+     if (ret < 0) {
+-        qemu_mutex_unlock_iothread();
++        if (release_lock) {
++            qemu_mutex_unlock_iothread();
++        }
+         return ret;
+     }
+ 
+     /* start track dirty blocks */
+     ret = set_dirty_tracking();
+ 
+-    qemu_mutex_unlock_iothread();
++    if (release_lock) {
++        qemu_mutex_unlock_iothread();
++    }
+ 
+     if (ret) {
+         return ret;
+diff --git a/migration/ram.c b/migration/ram.c
+index 79d881f735..0ecbbc3202 100644
+--- a/migration/ram.c
++++ b/migration/ram.c
+@@ -3117,8 +3117,16 @@ static void migration_bitmap_clear_discarded_pages(RAMState *rs)
+ 
+ static void ram_init_bitmaps(RAMState *rs)
+ {
+-    /* For memory_global_dirty_log_start below.  */
+-    qemu_mutex_lock_iothread();
++    bool release_lock = false;
++
++    /*
++     * For memory_global_dirty_log_start below.
++     * For snapshots, the BQL is held during setup.
++     */
++    if (!qemu_mutex_iothread_locked()) {
++        qemu_mutex_lock_iothread();
++        release_lock = true;
++    }
+     qemu_mutex_lock_ramlist();
+ 
+     WITH_RCU_READ_LOCK_GUARD() {
+@@ -3130,7 +3138,9 @@ static void ram_init_bitmaps(RAMState *rs)
+         }
+     }
+     qemu_mutex_unlock_ramlist();
+-    qemu_mutex_unlock_iothread();
++    if (release_lock) {
++        qemu_mutex_unlock_iothread();
++    }
+ 
+     /*
+      * After an eventual first bitmap sync, fixup the initial bitmap
+diff --git a/migration/savevm.c b/migration/savevm.c
+index aa54a67fda..fc6a82a555 100644
+--- a/migration/savevm.c
++++ b/migration/savevm.c
+@@ -1621,10 +1621,8 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
+     memset(&compression_counters, 0, sizeof(compression_counters));
+     ms->to_dst_file = f;
+ 
+-    qemu_mutex_unlock_iothread();
+     qemu_savevm_state_header(f);
+     qemu_savevm_state_setup(f);
+-    qemu_mutex_lock_iothread();
+ 
+     while (qemu_file_get_error(f) == 0) {
+         if (qemu_savevm_state_iterate(f, false) > 0) {
diff --git a/debian/patches/pve/0067-savevm-async-don-t-hold-BQL-during-setup.patch b/debian/patches/pve/0067-savevm-async-don-t-hold-BQL-during-setup.patch
new file mode 100644
index 0000000..ce5e14e
--- /dev/null
+++ b/debian/patches/pve/0067-savevm-async-don-t-hold-BQL-during-setup.patch
@@ -0,0 +1,29 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Fiona Ebner <f.ebner@proxmox.com>
+Date: Fri, 5 May 2023 15:30:16 +0200
+Subject: [PATCH] savevm-async: don't hold BQL during setup
+
+See commit "migration: for snapshots, hold the BQL during setup
+callbacks" for why. This is separate, because a version of that one
+will hopefully land upstream.
+
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ migration/savevm-async.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/migration/savevm-async.c b/migration/savevm-async.c
+index effe6d1e0d..f006a8e4d4 100644
+--- a/migration/savevm-async.c
++++ b/migration/savevm-async.c
+@@ -403,10 +403,8 @@ void qmp_savevm_start(const char *statefile, Error **errp)
+     snap_state.state = SAVE_STATE_ACTIVE;
+     snap_state.finalize_bh = qemu_bh_new(process_savevm_finalize, &snap_state);
+     snap_state.co = qemu_coroutine_create(&process_savevm_co, NULL);
+-    qemu_mutex_unlock_iothread();
+     qemu_savevm_state_header(snap_state.file);
+     qemu_savevm_state_setup(snap_state.file);
+-    qemu_mutex_lock_iothread();
+ 
+     /* Async processing from here on out happens in iohandler context, so let
+      * the target bdrv have its home there.
diff --git a/debian/patches/series b/debian/patches/series
index 4e8ddd6..175ec2d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,31 +1,9 @@
 extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
-extra/0002-init-daemonize-defuse-PID-file-resolve-error.patch
-extra/0003-virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch
-extra/0004-virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch
-extra/0005-vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch
-extra/0006-virtio-rng-pci-fix-migration-compat-for-vectors.patch
-extra/0007-block-fix-detect-zeroes-with-BDRV_REQ_REGISTERED_BUF.patch
-extra/0008-memory-prevent-dma-reentracy-issues.patch
-extra/0009-block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch
-extra/0010-scsi-megasas-Internal-cdbs-have-16-byte-length.patch
-extra/0011-ide-avoid-potential-deadlock-when-draining-during-tr.patch
-extra/0012-hw-nvme-fix-missing-endian-conversions-for-doorbell-.patch
-extra/0013-hw-smbios-fix-field-corruption-in-type-4-table.patch
-extra/0014-virtio-rng-pci-fix-transitional-migration-compat-for.patch
-extra/0015-hw-timer-hpet-Fix-expiration-time-overflow.patch
-extra/0016-vdpa-stop-all-svq-on-device-deletion.patch
-extra/0017-vhost-avoid-a-potential-use-of-an-uninitialized-vari.patch
-extra/0018-chardev-char-socket-set-s-listener-NULL-in-char_sock.patch
-extra/0019-intel-iommu-fail-MAP-notifier-without-caching-mode.patch
-extra/0020-intel-iommu-fail-DEVIOTLB_UNMAP-without-dt-mode.patch
-extra/0021-memory-Allow-disabling-re-entrancy-checking-per-MR.patch
-extra/0022-lsi53c895a-disable-reentrancy-detection-for-script-R.patch
-extra/0023-acpi-cpuhp-fix-guest-visible-maximum-access-size-to-.patch
-extra/0024-tests-tcg-i386-Introduce-and-use-reg_t-consistently.patch
-extra/0025-target-i386-Fix-BEXTR-instruction.patch
-extra/0026-target-i386-Fix-C-flag-for-BLSI-BLSMSK-BLSR.patch
-extra/0027-target-i386-fix-ADOX-followed-by-ADCX.patch
-extra/0028-target-i386-Fix-BZHI-instruction.patch
+extra/0002-memory-prevent-dma-reentracy-issues.patch
+extra/0003-scsi-megasas-Internal-cdbs-have-16-byte-length.patch
+extra/0004-ide-avoid-potential-deadlock-when-draining-during-tr.patch
+extra/0005-memory-Allow-disabling-re-entrancy-checking-per-MR.patch
+extra/0006-lsi53c895a-disable-reentrancy-detection-for-script-R.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
@@ -94,3 +72,8 @@ pve/0059-vma-create-support-64KiB-unaligned-input-images.patch
 pve/0060-vma-create-avoid-triggering-assertion-in-error-case.patch
 pve/0061-block-alloc-track-avoid-premature-break.patch
 pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
+pve/0063-alloc-track-fix-deadlock-during-drop.patch
+pve/0064-savevm-async-optimize-querying-pending.patch
+pve/0065-savevm-async-also-initialize-compression-counters.patch
+pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
+pve/0067-savevm-async-don-t-hold-BQL-during-setup.patch
diff --git a/qemu b/qemu
index b67b00e..c1eb2dd 160000
--- a/qemu
+++ b/qemu
@@ -1 +1 @@
-Subproject commit b67b00e6b4c7831a3f5bc684bc0df7a9bfd1bd56
+Subproject commit c1eb2ddf0f8075faddc5f7c3d39feae3e8e9d6b4
-- 
2.39.2





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

* [pve-devel] [PATCH v2 qemu 5/7] add stable patches for 8.0.0
  2023-05-15 13:39 [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
                   ` (3 preceding siblings ...)
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 4/7] update submodule and patches to QEMU 8.0.0 Fiona Ebner
@ 2023-05-15 13:39 ` Fiona Ebner
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 6/7] PVE backup: don't call no_co_wrapper function from coroutine Fiona Ebner
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Fiona Ebner @ 2023-05-15 13:39 UTC (permalink / raw)
  To: pve-devel

Changes to other patches are all just metadata/context changes except
for pvebackup_co_prepare() needing to call bdrv_co_unref() rather than
bdrv_unref(), because it is a coroutine itself. This is documented in
d6ee2e324e ("block-coroutine-wrapper: Introduce no_co_wrapper"). The
change is necessary, because one of the stable fixes converts
bdrv_unref and blk_unref into no_co_wrappers (in preparation for a
second patch to fix a hang with the block resize QMP command).

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---

No changes in v2.

 ...d-support-for-sync-bitmap-mode-never.patch |  16 +-
 ...check-for-bitmap-mode-without-bitmap.patch |   4 +-
 .../0006-mirror-move-some-checks-to-qmp.patch |   4 +-
 ...39-fix-large_send_mss-divide-by-zero.patch |  72 ++++
 ...-Fix-crash-when-executing-HMP-commit.patch |  48 +++
 ...hen-getting-cursor-without-a-console.patch |  36 ++
 ...our-channel-order-for-PNG-screenshot.patch |  77 ++++
 ...arm-Fix-vd-vm-overlap-in-sve_ldff1_z.patch |  41 ++
 ...e-incorrect-computation-in-float32_e.patch |  56 +++
 ...ge-wrong-XFRM-value-in-SGX-CPUID-lea.patch |  39 ++
 ...t-assert_bdrv_graph_readable-by-defa.patch | 106 +++++
 ...CI_ERR_UNCOR_MASK-register-for-machi.patch | 100 +++++
 ...after-free-in-blockdev_mark_auto_del.patch |  57 +++
 ...ly-call-bdrv_activate-outside-corout.patch |  64 +++
 ...o_unref-for-calls-in-coroutine-conte.patch | 373 ++++++++++++++++++
 ...-no_coroutine_fns-in-qmp_block_resiz.patch |  43 ++
 ...-tcg-Fix-atomic_mmu_lookup-for-reads.patch |  36 ++
 ...sed-balloon-qemu-4-0-config-size-fal.patch |   4 +-
 ...VE-Backup-add-vma-backup-format-code.patch |   4 +-
 ...ckup-proxmox-backup-patches-for-qemu.patch |  12 +-
 ...estore-new-command-to-restore-from-p.patch |   4 +-
 ...irty-bitmap-tracking-for-incremental.patch |   8 +-
 .../pve/0032-PVE-various-PBS-fixes.patch      |   6 +-
 ...k-driver-to-map-backup-archives-into.patch |  12 +-
 ...dd-query_proxmox_support-QMP-command.patch |   2 +-
 ...E-add-query-pbs-bitmap-info-QMP-call.patch |   2 +-
 ...ct-stderr-to-journal-when-daemonized.patch |   4 +-
 ...-transaction-to-synchronize-job-stat.patch |   4 +-
 ...-block-on-finishing-and-cleanup-crea.patch |   2 +-
 ...igrate-dirty-bitmap-state-via-savevm.patch |   2 +-
 ...routine-QMP-for-backup-cancel_backup.patch |   8 +-
 .../pve/0044-PBS-add-master-key-support.patch |   6 +-
 .../pve/0052-pbs-namespace-support.patch      |   6 +-
 ...e-jobs-correctly-cancel-in-error-sce.patch |   2 +-
 ...nsure-jobs-in-di_list-are-referenced.patch |   2 +-
 ...d-segfault-issues-upon-backup-cancel.patch |   2 +-
 ...-passing-max-workers-performance-set.patch |   6 +-
 debian/patches/series                         |  14 +
 38 files changed, 1223 insertions(+), 61 deletions(-)
 create mode 100644 debian/patches/extra/0007-rtl8139-fix-large_send_mss-divide-by-zero.patch
 create mode 100644 debian/patches/extra/0008-block-monitor-Fix-crash-when-executing-HMP-commit.patch
 create mode 100644 debian/patches/extra/0009-ui-return-NULL-when-getting-cursor-without-a-console.patch
 create mode 100644 debian/patches/extra/0010-ui-Fix-pixel-colour-channel-order-for-PNG-screenshot.patch
 create mode 100644 debian/patches/extra/0011-target-arm-Fix-vd-vm-overlap-in-sve_ldff1_z.patch
 create mode 100644 debian/patches/extra/0012-softfloat-Fix-the-incorrect-computation-in-float32_e.patch
 create mode 100644 debian/patches/extra/0013-target-i386-Change-wrong-XFRM-value-in-SGX-CPUID-lea.patch
 create mode 100644 debian/patches/extra/0014-block-compile-out-assert_bdrv_graph_readable-by-defa.patch
 create mode 100644 debian/patches/extra/0015-hw-pci-Disable-PCI_ERR_UNCOR_MASK-register-for-machi.patch
 create mode 100644 debian/patches/extra/0016-block-Fix-use-after-free-in-blockdev_mark_auto_del.patch
 create mode 100644 debian/patches/extra/0017-block-Consistently-call-bdrv_activate-outside-corout.patch
 create mode 100644 debian/patches/extra/0018-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch
 create mode 100644 debian/patches/extra/0019-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch
 create mode 100644 debian/patches/extra/0020-accel-tcg-Fix-atomic_mmu_lookup-for-reads.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 306dc3b..a45ee6e 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
@@ -254,10 +254,10 @@ index 663e2b7002..9099c75992 100644
                       errp);
      if (!job) {
 diff --git a/blockdev.c b/blockdev.c
-index d7b5c18f0a..6c34d9bb3a 100644
+index e464daea58..1010b60804 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -2932,6 +2932,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2942,6 +2942,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
                                     BlockDriverState *target,
                                     const char *replaces,
                                     enum MirrorSyncMode sync,
@@ -267,7 +267,7 @@ index d7b5c18f0a..6c34d9bb3a 100644
                                     BlockMirrorBackingMode backing_mode,
                                     bool zero_target,
                                     bool has_speed, int64_t speed,
-@@ -2950,6 +2953,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2960,6 +2963,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
  {
      BlockDriverState *unfiltered_bs;
      int job_flags = JOB_DEFAULT;
@@ -275,7 +275,7 @@ index d7b5c18f0a..6c34d9bb3a 100644
  
      if (!has_speed) {
          speed = 0;
-@@ -3001,6 +3005,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3011,6 +3015,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
          sync = MIRROR_SYNC_MODE_FULL;
      }
  
@@ -305,7 +305,7 @@ index d7b5c18f0a..6c34d9bb3a 100644
      if (!replaces) {
          /* We want to mirror from @bs, but keep implicit filters on top */
          unfiltered_bs = bdrv_skip_implicit_filters(bs);
-@@ -3046,8 +3073,8 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3056,8 +3083,8 @@ 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,
@@ -316,7 +316,7 @@ index d7b5c18f0a..6c34d9bb3a 100644
                   on_source_error, on_target_error, unmap, filter_node_name,
                   copy_mode, errp);
  }
-@@ -3192,6 +3219,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
+@@ -3202,6 +3229,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
  
      blockdev_mirror_common(arg->job_id, bs, target_bs,
                             arg->replaces, arg->sync,
@@ -325,7 +325,7 @@ index d7b5c18f0a..6c34d9bb3a 100644
                             backing_mode, zero_target,
                             arg->has_speed, arg->speed,
                             arg->has_granularity, arg->granularity,
-@@ -3213,6 +3242,8 @@ void qmp_blockdev_mirror(const char *job_id,
+@@ -3223,6 +3252,8 @@ void qmp_blockdev_mirror(const char *job_id,
                           const char *device, const char *target,
                           const char *replaces,
                           MirrorSyncMode sync,
@@ -334,7 +334,7 @@ index d7b5c18f0a..6c34d9bb3a 100644
                           bool has_speed, int64_t speed,
                           bool has_granularity, uint32_t granularity,
                           bool has_buf_size, int64_t buf_size,
-@@ -3261,7 +3292,8 @@ void qmp_blockdev_mirror(const char *job_id,
+@@ -3271,7 +3302,8 @@ void qmp_blockdev_mirror(const char *job_id,
      }
  
      blockdev_mirror_common(job_id, bs, target_bs,
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 3061723..e1cd354 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 6c34d9bb3a..24a76b451d 100644
+index 1010b60804..19f490fce7 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3026,6 +3026,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3036,6 +3036,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 4139251..7dc188b 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 f42953837b..8f79efaa87 100644
  
          if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
 diff --git a/blockdev.c b/blockdev.c
-index 24a76b451d..3917af7d02 100644
+index 19f490fce7..9a010f3a86 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3005,7 +3005,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3015,7 +3015,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
          sync = MIRROR_SYNC_MODE_FULL;
      }
  
diff --git a/debian/patches/extra/0007-rtl8139-fix-large_send_mss-divide-by-zero.patch b/debian/patches/extra/0007-rtl8139-fix-large_send_mss-divide-by-zero.patch
new file mode 100644
index 0000000..ab3db30
--- /dev/null
+++ b/debian/patches/extra/0007-rtl8139-fix-large_send_mss-divide-by-zero.patch
@@ -0,0 +1,72 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Thu, 13 Apr 2023 13:19:46 -0400
+Subject: [PATCH] rtl8139: fix large_send_mss divide-by-zero
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If the driver sets large_send_mss to 0 then a divide-by-zero occurs.
+Even if the division wasn't a problem, the for loop that emits MSS-sized
+packets would never terminate.
+
+Solve these issues by skipping offloading when large_send_mss=0.
+
+This issue was found by OSS-Fuzz as part of Alexander Bulekov's device
+fuzzing work. The reproducer is:
+
+  $ cat << EOF | ./qemu-system-i386 -display none -machine accel=qtest, -m \
+  512M,slots=1,maxmem=0xffff000000000000 -machine q35 -nodefaults -device \
+  rtl8139,netdev=net0 -netdev user,id=net0 -device \
+  pc-dimm,id=nv1,memdev=mem1,addr=0xb800a64602800000 -object \
+  memory-backend-ram,id=mem1,size=2M  -qtest stdio
+  outl 0xcf8 0x80000814
+  outl 0xcfc 0xe0000000
+  outl 0xcf8 0x80000804
+  outw 0xcfc 0x06
+  write 0xe0000037 0x1 0x04
+  write 0xe00000e0 0x2 0x01
+  write 0x1 0x1 0x04
+  write 0x3 0x1 0x98
+  write 0xa 0x1 0x8c
+  write 0xb 0x1 0x02
+  write 0xc 0x1 0x46
+  write 0xd 0x1 0xa6
+  write 0xf 0x1 0xb8
+  write 0xb800a646028c000c 0x1 0x08
+  write 0xb800a646028c000e 0x1 0x47
+  write 0xb800a646028c0010 0x1 0x02
+  write 0xb800a646028c0017 0x1 0x06
+  write 0xb800a646028c0036 0x1 0x80
+  write 0xe00000d9 0x1 0x40
+  EOF
+
+Buglink: https://gitlab.com/qemu-project/qemu/-/issues/1582
+Fixes: 6d71357a3b65 ("rtl8139: honor large send MSS value")
+Reported-by: Alexander Bulekov <alxndr@bu.edu>
+Cc: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Tested-by: Alexander Bulekov <alxndr@bu.edu>
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Acked-by: Jason Wang <jasowang@redhat.com>
+(picked up from https://patchew.org/QEMU/20230413171946.2865726-1-stefanha@redhat.com/)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/net/rtl8139.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
+index 5a5aaf868d..5f1a4d359b 100644
+--- a/hw/net/rtl8139.c
++++ b/hw/net/rtl8139.c
+@@ -2154,6 +2154,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
+ 
+                 int large_send_mss = (txdw0 >> CP_TC_LGSEN_MSS_SHIFT) &
+                                      CP_TC_LGSEN_MSS_MASK;
++                if (large_send_mss == 0) {
++                    goto skip_offload;
++                }
+ 
+                 DPRINTF("+++ C+ mode offloaded task TSO IP data %d "
+                     "frame data %d specified MSS=%d\n",
diff --git a/debian/patches/extra/0008-block-monitor-Fix-crash-when-executing-HMP-commit.patch b/debian/patches/extra/0008-block-monitor-Fix-crash-when-executing-HMP-commit.patch
new file mode 100644
index 0000000..0255bd3
--- /dev/null
+++ b/debian/patches/extra/0008-block-monitor-Fix-crash-when-executing-HMP-commit.patch
@@ -0,0 +1,48 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Wang Liang <wangliangzz@inspur.com>
+Date: Mon, 24 Apr 2023 18:39:02 +0800
+Subject: [PATCH] block/monitor: Fix crash when executing HMP commit
+
+hmp_commit() calls blk_is_available() from a non-coroutine context (and
+in the main loop). blk_is_available() is a co_wrapper_mixed_bdrv_rdlock
+function, and in the non-coroutine context it calls AIO_WAIT_WHILE(),
+which crashes if the aio_context lock is not taken before.
+
+Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1615
+Signed-off-by: Wang Liang <wangliangzz@inspur.com>
+Message-Id: <20230424103902.45265-1-wangliangzz@126.com>
+Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry-picked from commit 8c1e8fb2e7fc2cbeb57703e143965a4cd3ad301a)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ block/monitor/block-hmp-cmds.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
+index 2846083546..ca2599de44 100644
+--- a/block/monitor/block-hmp-cmds.c
++++ b/block/monitor/block-hmp-cmds.c
+@@ -214,15 +214,17 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
+             error_report("Device '%s' not found", device);
+             return;
+         }
+-        if (!blk_is_available(blk)) {
+-            error_report("Device '%s' has no medium", device);
+-            return;
+-        }
+ 
+         bs = bdrv_skip_implicit_filters(blk_bs(blk));
+         aio_context = bdrv_get_aio_context(bs);
+         aio_context_acquire(aio_context);
+ 
++        if (!blk_is_available(blk)) {
++            error_report("Device '%s' has no medium", device);
++            aio_context_release(aio_context);
++            return;
++        }
++
+         ret = bdrv_commit(bs);
+ 
+         aio_context_release(aio_context);
diff --git a/debian/patches/extra/0009-ui-return-NULL-when-getting-cursor-without-a-console.patch b/debian/patches/extra/0009-ui-return-NULL-when-getting-cursor-without-a-console.patch
new file mode 100644
index 0000000..c0368b8
--- /dev/null
+++ b/debian/patches/extra/0009-ui-return-NULL-when-getting-cursor-without-a-console.patch
@@ -0,0 +1,36 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Fri, 28 Apr 2023 19:48:06 +0400
+Subject: [PATCH] ui: return NULL when getting cursor without a console
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+VNC may try to get the current cursor even when there are no consoles
+and crashes. Simple reproducer is qemu with -nodefaults.
+
+Fixes: (again)
+https://gitlab.com/qemu-project/qemu/-/issues/1548
+
+Fixes: commit 385ac97f8 ("ui: keep current cursor with QemuConsole")
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+(picked up from https://lists.nongnu.org/archive/html/qemu-devel/2023-04/msg05598.html)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ ui/console.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ui/console.c b/ui/console.c
+index 6e8a3cdc62..594517ecdb 100644
+--- a/ui/console.c
++++ b/ui/console.c
+@@ -2306,7 +2306,7 @@ QEMUCursor *qemu_console_get_cursor(QemuConsole *con)
+     if (con == NULL) {
+         con = active_console;
+     }
+-    return con->cursor;
++    return con ? con->cursor : NULL;
+ }
+ 
+ bool qemu_console_is_visible(QemuConsole *con)
diff --git a/debian/patches/extra/0010-ui-Fix-pixel-colour-channel-order-for-PNG-screenshot.patch b/debian/patches/extra/0010-ui-Fix-pixel-colour-channel-order-for-PNG-screenshot.patch
new file mode 100644
index 0000000..d76b723
--- /dev/null
+++ b/debian/patches/extra/0010-ui-Fix-pixel-colour-channel-order-for-PNG-screenshot.patch
@@ -0,0 +1,77 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Maydell <peter.maydell@linaro.org>
+Date: Tue, 2 May 2023 14:55:48 +0100
+Subject: [PATCH] ui: Fix pixel colour channel order for PNG screenshots
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When we take a PNG screenshot the ordering of the colour channels in
+the data is not correct, resulting in the image having weird
+colouring compared to the actual display.  (Specifically, on a
+little-endian host the blue and red channels are swapped; on
+big-endian everything is wrong.)
+
+This happens because the pixman idea of the pixel data and the libpng
+idea differ.  PIXMAN_a9r8g8b8 defines that pixels are 32-bit values,
+with A in bits 24-31, R in bits 16-23, G in bits 8-15 and B in bits
+0-7.  This means that on little-endian systems the bytes in memory
+are
+   B G R A
+and on big-endian systems they are
+   A R G B
+
+libpng, on the other hand, thinks of pixels as being a series of
+values for each channel, so its format PNG_COLOR_TYPE_RGB_ALPHA
+always wants bytes in the order
+   R G B A
+
+This isn't the same as the pixman order for either big or little
+endian hosts.
+
+The alpha channel is also unnecessary bulk in the output PNG file,
+because there is no alpha information in a screenshot.
+
+To handle the endianness issue, we already define in ui/qemu-pixman.h
+various PIXMAN_BE_* and PIXMAN_LE_* values that give consistent
+byte-order pixel channel formats.  So we can use PIXMAN_BE_r8g8b8 and
+PNG_COLOR_TYPE_RGB, which both have an in-memory byte order of
+    R G B
+and 3 bytes per pixel.
+
+(PPM format screenshots get this right; they already use the
+PIXMAN_BE_r8g8b8 format.)
+
+Cc: qemu-stable@nongnu.org
+Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1622
+Fixes: 9a0a119a382867 ("Added parameter to take screenshot with screendump as PNG")
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+(picked up from https://lists.nongnu.org/archive/html/qemu-devel/2023-05/msg00229.html)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ ui/console.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ui/console.c b/ui/console.c
+index 594517ecdb..7461446e71 100644
+--- a/ui/console.c
++++ b/ui/console.c
+@@ -311,7 +311,7 @@ static bool png_save(int fd, pixman_image_t *image, Error **errp)
+     png_struct *png_ptr;
+     png_info *info_ptr;
+     g_autoptr(pixman_image_t) linebuf =
+-                            qemu_pixman_linebuf_create(PIXMAN_a8r8g8b8, width);
++        qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
+     uint8_t *buf = (uint8_t *)pixman_image_get_data(linebuf);
+     FILE *f = fdopen(fd, "wb");
+     int y;
+@@ -341,7 +341,7 @@ static bool png_save(int fd, pixman_image_t *image, Error **errp)
+     png_init_io(png_ptr, f);
+ 
+     png_set_IHDR(png_ptr, info_ptr, width, height, 8,
+-                 PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
++                 PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
+                  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+ 
+     png_write_info(png_ptr, info_ptr);
diff --git a/debian/patches/extra/0011-target-arm-Fix-vd-vm-overlap-in-sve_ldff1_z.patch b/debian/patches/extra/0011-target-arm-Fix-vd-vm-overlap-in-sve_ldff1_z.patch
new file mode 100644
index 0000000..799aa84
--- /dev/null
+++ b/debian/patches/extra/0011-target-arm-Fix-vd-vm-overlap-in-sve_ldff1_z.patch
@@ -0,0 +1,41 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <richard.henderson@linaro.org>
+Date: Thu, 4 May 2023 11:42:32 +0100
+Subject: [PATCH] target/arm: Fix vd == vm overlap in sve_ldff1_z
+
+If vd == vm, copy vm to scratch, so that we can pre-zero
+the output and still access the gather indicies.
+
+Cc: qemu-stable@nongnu.org
+Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1612
+Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
+(picked up from https://lists.nongnu.org/archive/html/qemu-devel/2023-05/msg00961.html)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ target/arm/tcg/sve_helper.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
+index ccf5e5beca..0097522470 100644
+--- a/target/arm/tcg/sve_helper.c
++++ b/target/arm/tcg/sve_helper.c
+@@ -6727,6 +6727,7 @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
+     intptr_t reg_off;
+     SVEHostPage info;
+     target_ulong addr, in_page;
++    ARMVectorReg scratch;
+ 
+     /* Skip to the first true predicate.  */
+     reg_off = find_next_active(vg, 0, reg_max, esz);
+@@ -6736,6 +6737,11 @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
+         return;
+     }
+ 
++    /* Protect against overlap between vd and vm. */
++    if (unlikely(vd == vm)) {
++        vm = memcpy(&scratch, vm, reg_max);
++    }
++
+     /*
+      * Probe the first element, allowing faults.
+      */
diff --git a/debian/patches/extra/0012-softfloat-Fix-the-incorrect-computation-in-float32_e.patch b/debian/patches/extra/0012-softfloat-Fix-the-incorrect-computation-in-float32_e.patch
new file mode 100644
index 0000000..a9cc766
--- /dev/null
+++ b/debian/patches/extra/0012-softfloat-Fix-the-incorrect-computation-in-float32_e.patch
@@ -0,0 +1,56 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Shivaprasad G Bhat <sbhat@linux.ibm.com>
+Date: Tue, 2 May 2023 20:55:30 +0530
+Subject: [PATCH] softfloat: Fix the incorrect computation in float32_exp2
+
+The float32_exp2 function is computing wrong exponent of 2.
+
+For example, with the following set of values {0.1, 2.0, 2.0, -1.0},
+the expected output would be {1.071773, 4.000000, 4.000000, 0.500000}.
+Instead, the function is computing {1.119102, 3.382044, 3.382044, -0.191022}
+
+Looking at the code, the float32_exp2() attempts to do this
+
+                  2     3     4     5           n
+  x        x     x     x     x     x           x
+ e  = 1 + --- + --- + --- + --- + --- + ... + --- + ...
+           1!    2!    3!    4!    5!          n!
+
+But because of the typo it ends up doing
+
+  x        x     x     x     x     x           x
+ e  = 1 + --- + --- + --- + --- + --- + ... + --- + ...
+           1!    2!    3!    4!    5!          n!
+
+This is because instead of the xnp which holds the numerator, parts_muladd
+is using the xp which is just 'x'.  Commit '572c4d862ff2' refactored this
+function, and mistakenly used xp instead of xnp.
+
+Cc: qemu-stable@nongnu.org
+Fixes: 572c4d862ff2 "softfloat: Convert float32_exp2 to FloatParts"
+Partially-Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1623
+Reported-By: Luca Barbato (https://gitlab.com/lu-zero)
+Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
+Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
+Message-Id: <168304110865.537992.13059030916325018670.stgit@localhost.localdomain>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
+(cherry-picked from commit 1098cc3fcf952763fc9fd72c1c8fda30a18cc8ea)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ fpu/softfloat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fpu/softfloat.c b/fpu/softfloat.c
+index c7454c3eb1..108f9cb224 100644
+--- a/fpu/softfloat.c
++++ b/fpu/softfloat.c
+@@ -5135,7 +5135,7 @@ float32 float32_exp2(float32 a, float_status *status)
+     float64_unpack_canonical(&rp, float64_one, status);
+     for (i = 0 ; i < 15 ; i++) {
+         float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status);
+-        rp = *parts_muladd(&tp, &xp, &rp, 0, status);
++        rp = *parts_muladd(&tp, &xnp, &rp, 0, status);
+         xnp = *parts_mul(&xnp, &xp, status);
+     }
+ 
diff --git a/debian/patches/extra/0013-target-i386-Change-wrong-XFRM-value-in-SGX-CPUID-lea.patch b/debian/patches/extra/0013-target-i386-Change-wrong-XFRM-value-in-SGX-CPUID-lea.patch
new file mode 100644
index 0000000..425b39d
--- /dev/null
+++ b/debian/patches/extra/0013-target-i386-Change-wrong-XFRM-value-in-SGX-CPUID-lea.patch
@@ -0,0 +1,39 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Yang Zhong <yang.zhong@linux.intel.com>
+Date: Thu, 6 Apr 2023 02:40:41 -0400
+Subject: [PATCH] target/i386: Change wrong XFRM value in SGX CPUID leaf
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The previous patch wrongly replaced FEAT_XSAVE_XCR0_{LO|HI} with
+FEAT_XSAVE_XSS_{LO|HI} in CPUID(EAX=12,ECX=1):{ECX,EDX}.  As a result,
+SGX enclaves only supported SSE and x87 feature (xfrm=0x3).
+
+Fixes: 301e90675c3f ("target/i386: Enable support for XSAVES based features")
+Signed-off-by: Yang Zhong <yang.zhong@linux.intel.com>
+Reviewed-by: Yang Weijiang <weijiang.yang@intel.com>
+Reviewed-by: Kai Huang <kai.huang@intel.com>
+Message-Id: <20230406064041.420039-1-yang.zhong@linux.intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry-picked from commit 72497cff896fecf74306ed33626c30e43633cdd6)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ target/i386/cpu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 6576287e5b..f083ff4335 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -5718,8 +5718,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
+         } else {
+             *eax &= env->features[FEAT_SGX_12_1_EAX];
+             *ebx &= 0; /* ebx reserve */
+-            *ecx &= env->features[FEAT_XSAVE_XSS_LO];
+-            *edx &= env->features[FEAT_XSAVE_XSS_HI];
++            *ecx &= env->features[FEAT_XSAVE_XCR0_LO];
++            *edx &= env->features[FEAT_XSAVE_XCR0_HI];
+ 
+             /* FP and SSE are always allowed regardless of XSAVE/XCR0. */
+             *ecx |= XSTATE_FP_MASK | XSTATE_SSE_MASK;
diff --git a/debian/patches/extra/0014-block-compile-out-assert_bdrv_graph_readable-by-defa.patch b/debian/patches/extra/0014-block-compile-out-assert_bdrv_graph_readable-by-defa.patch
new file mode 100644
index 0000000..f0534d8
--- /dev/null
+++ b/debian/patches/extra/0014-block-compile-out-assert_bdrv_graph_readable-by-defa.patch
@@ -0,0 +1,106 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Mon, 1 May 2023 13:34:43 -0400
+Subject: [PATCH] block: compile out assert_bdrv_graph_readable() by default
+
+reader_count() is a performance bottleneck because the global
+aio_context_list_lock mutex causes thread contention. Put this debugging
+assertion behind a new ./configure --enable-debug-graph-lock option and
+disable it by default.
+
+The --enable-debug-graph-lock option is also enabled by the more general
+--enable-debug option.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(picked up from https://lists.nongnu.org/archive/html/qemu-devel/2023-05/msg00058.html)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ block/graph-lock.c            | 3 +++
+ configure                     | 1 +
+ meson.build                   | 2 ++
+ meson_options.txt             | 2 ++
+ scripts/meson-buildoptions.sh | 4 ++++
+ 5 files changed, 12 insertions(+)
+
+diff --git a/block/graph-lock.c b/block/graph-lock.c
+index 454c31e691..259a7a0bde 100644
+--- a/block/graph-lock.c
++++ b/block/graph-lock.c
+@@ -265,7 +265,10 @@ void bdrv_graph_rdunlock_main_loop(void)
+ 
+ void assert_bdrv_graph_readable(void)
+ {
++    /* reader_count() is slow due to aio_context_list_lock lock contention */
++#ifdef CONFIG_DEBUG_GRAPH_LOCK
+     assert(qemu_in_main_thread() || reader_count());
++#endif
+ }
+ 
+ void assert_bdrv_graph_writable(void)
+diff --git a/configure b/configure
+index 800b5850f4..a62a3e6be9 100755
+--- a/configure
++++ b/configure
+@@ -806,6 +806,7 @@ for opt do
+   --enable-debug)
+       # Enable debugging options that aren't excessively noisy
+       debug_tcg="yes"
++      meson_option_parse --enable-debug-graph-lock ""
+       meson_option_parse --enable-debug-mutex ""
+       meson_option_add -Doptimization=0
+       fortify_source="no"
+diff --git a/meson.build b/meson.build
+index c44d05a13f..d964e741e7 100644
+--- a/meson.build
++++ b/meson.build
+@@ -1956,6 +1956,7 @@ if get_option('debug_stack_usage') and have_coroutine_pool
+   have_coroutine_pool = false
+ endif
+ config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
++config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
+ config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
+ config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
+ config_host_data.set('CONFIG_GPROF', get_option('gprof'))
+@@ -3833,6 +3834,7 @@ summary_info += {'PIE':               get_option('b_pie')}
+ summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
+ summary_info += {'malloc trim support': has_malloc_trim}
+ summary_info += {'membarrier':        have_membarrier}
++summary_info += {'debug graph lock':  get_option('debug_graph_lock')}
+ summary_info += {'debug stack usage': get_option('debug_stack_usage')}
+ summary_info += {'mutex debugging':   get_option('debug_mutex')}
+ summary_info += {'memory allocator':  get_option('malloc')}
+diff --git a/meson_options.txt b/meson_options.txt
+index fc9447d267..bc857fe68b 100644
+--- a/meson_options.txt
++++ b/meson_options.txt
+@@ -311,6 +311,8 @@ option('rng_none', type: 'boolean', value: false,
+        description: 'dummy RNG, avoid using /dev/(u)random and getrandom()')
+ option('coroutine_pool', type: 'boolean', value: true,
+        description: 'coroutine freelist (better performance)')
++option('debug_graph_lock', type: 'boolean', value: false,
++       description: 'graph lock debugging support')
+ option('debug_mutex', type: 'boolean', value: false,
+        description: 'mutex debugging support')
+ option('debug_stack_usage', type: 'boolean', value: false,
+diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
+index 009fab1515..30e1f25259 100644
+--- a/scripts/meson-buildoptions.sh
++++ b/scripts/meson-buildoptions.sh
+@@ -21,6 +21,8 @@ meson_options_help() {
+   printf "%s\n" '                           QEMU'
+   printf "%s\n" '  --enable-cfi             Control-Flow Integrity (CFI)'
+   printf "%s\n" '  --enable-cfi-debug       Verbose errors in case of CFI violation'
++  printf "%s\n" '  --enable-debug-graph-lock'
++  printf "%s\n" '                           graph lock debugging support'
+   printf "%s\n" '  --enable-debug-mutex     mutex debugging support'
+   printf "%s\n" '  --enable-debug-stack-usage'
+   printf "%s\n" '                           measure coroutine stack usage'
+@@ -249,6 +251,8 @@ _meson_option_parse() {
+     --datadir=*) quote_sh "-Ddatadir=$2" ;;
+     --enable-dbus-display) printf "%s" -Ddbus_display=enabled ;;
+     --disable-dbus-display) printf "%s" -Ddbus_display=disabled ;;
++    --enable-debug-graph-lock) printf "%s" -Ddebug_graph_lock=true ;;
++    --disable-debug-graph-lock) printf "%s" -Ddebug_graph_lock=false ;;
+     --enable-debug-mutex) printf "%s" -Ddebug_mutex=true ;;
+     --disable-debug-mutex) printf "%s" -Ddebug_mutex=false ;;
+     --enable-debug-stack-usage) printf "%s" -Ddebug_stack_usage=true ;;
diff --git a/debian/patches/extra/0015-hw-pci-Disable-PCI_ERR_UNCOR_MASK-register-for-machi.patch b/debian/patches/extra/0015-hw-pci-Disable-PCI_ERR_UNCOR_MASK-register-for-machi.patch
new file mode 100644
index 0000000..b7e45e5
--- /dev/null
+++ b/debian/patches/extra/0015-hw-pci-Disable-PCI_ERR_UNCOR_MASK-register-for-machi.patch
@@ -0,0 +1,100 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Leonardo Bras <leobras@redhat.com>
+Date: Tue, 2 May 2023 21:27:02 -0300
+Subject: [PATCH] hw/pci: Disable PCI_ERR_UNCOR_MASK register for machine type
+ < 8.0
+
+Since it's implementation on v8.0.0-rc0, having the PCI_ERR_UNCOR_MASK
+set for machine types < 8.0 will cause migration to fail if the target
+QEMU version is < 8.0.0 :
+
+qemu-system-x86_64: get_pci_config_device: Bad config data: i=0x10a read: 40 device: 0 cmask: ff wmask: 0 w1cmask:0
+qemu-system-x86_64: Failed to load PCIDevice:config
+qemu-system-x86_64: Failed to load e1000e:parent_obj
+qemu-system-x86_64: error while loading state for instance 0x0 of device '0000:00:02.0/e1000e'
+qemu-system-x86_64: load of migration failed: Invalid argument
+
+The above test migrated a 7.2 machine type from QEMU master to QEMU 7.2.0,
+with this cmdline:
+
+./qemu-system-x86_64 -M pc-q35-7.2 [-incoming XXX]
+
+In order to fix this, property x-pcie-err-unc-mask was introduced to
+control when PCI_ERR_UNCOR_MASK is enabled. This property is enabled by
+default, but is disabled if machine type <= 7.2.
+
+Fixes: 010746ae1d ("hw/pci/aer: Implement PCI_ERR_UNCOR_MASK register")
+Suggested-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Leonardo Bras <leobras@redhat.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Juan Quintela <quintela@redhat.com>
+(picked up from https://lists.nongnu.org/archive/html/qemu-devel/2023-05/msg00350.html)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/core/machine.c    |  1 +
+ hw/pci/pci.c         |  2 ++
+ hw/pci/pcie_aer.c    | 11 +++++++----
+ include/hw/pci/pci.h |  2 ++
+ 4 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/hw/core/machine.c b/hw/core/machine.c
+index cd13b8b0a3..5060119952 100644
+--- a/hw/core/machine.c
++++ b/hw/core/machine.c
+@@ -43,6 +43,7 @@ GlobalProperty hw_compat_7_2[] = {
+     { "e1000e", "migrate-timadj", "off" },
+     { "virtio-mem", "x-early-migration", "false" },
+     { "migration", "x-preempt-pre-7-2", "true" },
++    { TYPE_PCI_DEVICE, "x-pcie-err-unc-mask", "off" },
+ };
+ const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2);
+ 
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index def5000e7b..8ad4349e96 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -79,6 +79,8 @@ static Property pci_props[] = {
+     DEFINE_PROP_STRING("failover_pair_id", PCIDevice,
+                        failover_pair_id),
+     DEFINE_PROP_UINT32("acpi-index",  PCIDevice, acpi_index, 0),
++    DEFINE_PROP_BIT("x-pcie-err-unc-mask", PCIDevice, cap_present,
++                    QEMU_PCIE_ERR_UNC_MASK_BITNR, true),
+     DEFINE_PROP_END_OF_LIST()
+ };
+ 
+diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
+index 103667c368..374d593ead 100644
+--- a/hw/pci/pcie_aer.c
++++ b/hw/pci/pcie_aer.c
+@@ -112,10 +112,13 @@ int pcie_aer_init(PCIDevice *dev, uint8_t cap_ver, uint16_t offset,
+ 
+     pci_set_long(dev->w1cmask + offset + PCI_ERR_UNCOR_STATUS,
+                  PCI_ERR_UNC_SUPPORTED);
+-    pci_set_long(dev->config + offset + PCI_ERR_UNCOR_MASK,
+-                 PCI_ERR_UNC_MASK_DEFAULT);
+-    pci_set_long(dev->wmask + offset + PCI_ERR_UNCOR_MASK,
+-                 PCI_ERR_UNC_SUPPORTED);
++
++    if (dev->cap_present & QEMU_PCIE_ERR_UNC_MASK) {
++        pci_set_long(dev->config + offset + PCI_ERR_UNCOR_MASK,
++                     PCI_ERR_UNC_MASK_DEFAULT);
++        pci_set_long(dev->wmask + offset + PCI_ERR_UNCOR_MASK,
++                     PCI_ERR_UNC_SUPPORTED);
++    }
+ 
+     pci_set_long(dev->config + offset + PCI_ERR_UNCOR_SEVER,
+                  PCI_ERR_UNC_SEVERITY_DEFAULT);
+diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
+index d5a40cd058..6dc6742fc4 100644
+--- a/include/hw/pci/pci.h
++++ b/include/hw/pci/pci.h
+@@ -207,6 +207,8 @@ enum {
+     QEMU_PCIE_EXTCAP_INIT = (1 << QEMU_PCIE_EXTCAP_INIT_BITNR),
+ #define QEMU_PCIE_CXL_BITNR 10
+     QEMU_PCIE_CAP_CXL = (1 << QEMU_PCIE_CXL_BITNR),
++#define QEMU_PCIE_ERR_UNC_MASK_BITNR 11
++    QEMU_PCIE_ERR_UNC_MASK = (1 << QEMU_PCIE_ERR_UNC_MASK_BITNR),
+ };
+ 
+ typedef struct PCIINTxRoute {
diff --git a/debian/patches/extra/0016-block-Fix-use-after-free-in-blockdev_mark_auto_del.patch b/debian/patches/extra/0016-block-Fix-use-after-free-in-blockdev_mark_auto_del.patch
new file mode 100644
index 0000000..20e3e35
--- /dev/null
+++ b/debian/patches/extra/0016-block-Fix-use-after-free-in-blockdev_mark_auto_del.patch
@@ -0,0 +1,57 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 May 2023 16:01:42 +0200
+Subject: [PATCH] block: Fix use after free in blockdev_mark_auto_del()
+
+job_cancel_locked() drops the job list lock temporarily and it may call
+aio_poll(). We must assume that the list has changed after this call.
+Also, with unlucky timing, it can end up freeing the job during
+job_completed_txn_abort_locked(), making the job pointer invalid, too.
+
+For both reasons, we can't just continue at block_job_next_locked(job).
+Instead, start at the head of the list again after job_cancel_locked()
+and skip those jobs that we already cancelled (or that are completing
+anyway).
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Message-Id: <20230503140142.474404-1-kwolf@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry-picked from commit e2626874a32602d4e52971c786ef5ffb4430629d)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ blockdev.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index d7b5c18f0a..2c1752a403 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -153,12 +153,22 @@ void blockdev_mark_auto_del(BlockBackend *blk)
+ 
+     JOB_LOCK_GUARD();
+ 
+-    for (job = block_job_next_locked(NULL); job;
+-         job = block_job_next_locked(job)) {
+-        if (block_job_has_bdrv(job, blk_bs(blk))) {
++    do {
++        job = block_job_next_locked(NULL);
++        while (job && (job->job.cancelled ||
++                       job->job.deferred_to_main_loop ||
++                       !block_job_has_bdrv(job, blk_bs(blk))))
++        {
++            job = block_job_next_locked(job);
++        }
++        if (job) {
++            /*
++             * This drops the job lock temporarily and polls, so we need to
++             * restart processing the list from the start after this.
++             */
+             job_cancel_locked(&job->job, false);
+         }
+-    }
++    } while (job);
+ 
+     dinfo->auto_del = 1;
+ }
diff --git a/debian/patches/extra/0017-block-Consistently-call-bdrv_activate-outside-corout.patch b/debian/patches/extra/0017-block-Consistently-call-bdrv_activate-outside-corout.patch
new file mode 100644
index 0000000..a65c044
--- /dev/null
+++ b/debian/patches/extra/0017-block-Consistently-call-bdrv_activate-outside-corout.patch
@@ -0,0 +1,64 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Thu, 4 May 2023 13:57:32 +0200
+Subject: [PATCH] block: Consistently call bdrv_activate() outside coroutine
+
+Migration code can call bdrv_activate() in coroutine context, whereas
+other callers call it outside of coroutines. As it calls other code that
+is not supposed to run in coroutines, standardise on running outside of
+coroutines.
+
+This adds a no_co_wrapper to switch to the main loop before calling
+bdrv_activate().
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20230504115750.54437-3-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry-picked from commit da4afaff074e56b0fa0d25abf865784148018895)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ block/block-backend.c              | 10 +++++++++-
+ include/block/block-global-state.h |  6 +++++-
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index 55efc735b4..d59f759daf 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -2018,7 +2018,15 @@ void blk_activate(BlockBackend *blk, Error **errp)
+         return;
+     }
+ 
+-    bdrv_activate(bs, errp);
++    /*
++     * Migration code can call this function in coroutine context, so leave
++     * coroutine context if necessary.
++     */
++    if (qemu_in_coroutine()) {
++        bdrv_co_activate(bs, errp);
++    } else {
++        bdrv_activate(bs, errp);
++    }
+ }
+ 
+ bool coroutine_fn blk_co_is_inserted(BlockBackend *blk)
+diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
+index 399200a9a3..2c312cc774 100644
+--- a/include/block/block-global-state.h
++++ b/include/block/block-global-state.h
+@@ -166,7 +166,11 @@ int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
+ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
+                                         const char *node_name, Error **errp);
+ 
+-int bdrv_activate(BlockDriverState *bs, Error **errp);
++int no_coroutine_fn bdrv_activate(BlockDriverState *bs, Error **errp);
++
++int coroutine_fn no_co_wrapper
++bdrv_co_activate(BlockDriverState *bs, Error **errp);
++
+ void bdrv_activate_all(Error **errp);
+ int bdrv_inactivate_all(void);
+ 
diff --git a/debian/patches/extra/0018-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch b/debian/patches/extra/0018-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch
new file mode 100644
index 0000000..541e64e
--- /dev/null
+++ b/debian/patches/extra/0018-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch
@@ -0,0 +1,373 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Thu, 4 May 2023 13:57:33 +0200
+Subject: [PATCH] block: bdrv/blk_co_unref() for calls in coroutine context
+
+These functions must not be called in coroutine context, because they
+need write access to the graph.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20230504115750.54437-4-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry-picked from commit b2ab5f545fa1eaaf2955dd617bee19a8b3279786)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ block.c                                     |  2 +-
+ block/crypto.c                              |  6 +++---
+ block/parallels.c                           |  6 +++---
+ block/qcow.c                                |  6 +++---
+ block/qcow2.c                               | 14 +++++++-------
+ block/qed.c                                 |  6 +++---
+ block/vdi.c                                 |  6 +++---
+ block/vhdx.c                                |  6 +++---
+ block/vmdk.c                                | 18 +++++++++---------
+ block/vpc.c                                 |  6 +++---
+ include/block/block-global-state.h          |  3 ++-
+ include/sysemu/block-backend-global-state.h |  5 ++++-
+ 12 files changed, 44 insertions(+), 40 deletions(-)
+
+diff --git a/block.c b/block.c
+index d79a52ca74..a48112f945 100644
+--- a/block.c
++++ b/block.c
+@@ -680,7 +680,7 @@ int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
+ 
+     ret = 0;
+ out:
+-    blk_unref(blk);
++    blk_co_unref(blk);
+     return ret;
+ }
+ 
+diff --git a/block/crypto.c b/block/crypto.c
+index ca67289187..8fd3ad0054 100644
+--- a/block/crypto.c
++++ b/block/crypto.c
+@@ -355,7 +355,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
+     ret = 0;
+  cleanup:
+     qcrypto_block_free(crypto);
+-    blk_unref(blk);
++    blk_co_unref(blk);
+     return ret;
+ }
+ 
+@@ -661,7 +661,7 @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
+ 
+     ret = 0;
+ fail:
+-    bdrv_unref(bs);
++    bdrv_co_unref(bs);
+     return ret;
+ }
+ 
+@@ -730,7 +730,7 @@ fail:
+         bdrv_co_delete_file_noerr(bs);
+     }
+ 
+-    bdrv_unref(bs);
++    bdrv_co_unref(bs);
+     qapi_free_QCryptoBlockCreateOptions(create_opts);
+     qobject_unref(cryptoopts);
+     return ret;
+diff --git a/block/parallels.c b/block/parallels.c
+index 013684801a..b49c35929e 100644
+--- a/block/parallels.c
++++ b/block/parallels.c
+@@ -613,8 +613,8 @@ static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts,
+ 
+     ret = 0;
+ out:
+-    blk_unref(blk);
+-    bdrv_unref(bs);
++    blk_co_unref(blk);
++    bdrv_co_unref(bs);
+     return ret;
+ 
+ exit:
+@@ -691,7 +691,7 @@ parallels_co_create_opts(BlockDriver *drv, const char *filename,
+ 
+ done:
+     qobject_unref(qdict);
+-    bdrv_unref(bs);
++    bdrv_co_unref(bs);
+     qapi_free_BlockdevCreateOptions(create_options);
+     return ret;
+ }
+diff --git a/block/qcow.c b/block/qcow.c
+index 490e4f819e..a0c701f578 100644
+--- a/block/qcow.c
++++ b/block/qcow.c
+@@ -915,8 +915,8 @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts,
+     g_free(tmp);
+     ret = 0;
+ exit:
+-    blk_unref(qcow_blk);
+-    bdrv_unref(bs);
++    blk_co_unref(qcow_blk);
++    bdrv_co_unref(bs);
+     qcrypto_block_free(crypto);
+     return ret;
+ }
+@@ -1015,7 +1015,7 @@ qcow_co_create_opts(BlockDriver *drv, const char *filename,
+ fail:
+     g_free(backing_fmt);
+     qobject_unref(qdict);
+-    bdrv_unref(bs);
++    bdrv_co_unref(bs);
+     qapi_free_BlockdevCreateOptions(create_options);
+     return ret;
+ }
+diff --git a/block/qcow2.c b/block/qcow2.c
+index 30fd53fa64..6746763c34 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -3705,7 +3705,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
+         goto out;
+     }
+ 
+-    blk_unref(blk);
++    blk_co_unref(blk);
+     blk = NULL;
+ 
+     /*
+@@ -3785,7 +3785,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
+         }
+     }
+ 
+-    blk_unref(blk);
++    blk_co_unref(blk);
+     blk = NULL;
+ 
+     /* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning.
+@@ -3810,9 +3810,9 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
+ 
+     ret = 0;
+ out:
+-    blk_unref(blk);
+-    bdrv_unref(bs);
+-    bdrv_unref(data_bs);
++    blk_co_unref(blk);
++    bdrv_co_unref(bs);
++    bdrv_co_unref(data_bs);
+     return ret;
+ }
+ 
+@@ -3943,8 +3943,8 @@ finish:
+     }
+ 
+     qobject_unref(qdict);
+-    bdrv_unref(bs);
+-    bdrv_unref(data_bs);
++    bdrv_co_unref(bs);
++    bdrv_co_unref(data_bs);
+     qapi_free_BlockdevCreateOptions(create_options);
+     return ret;
+ }
+diff --git a/block/qed.c b/block/qed.c
+index 0705a7b4e2..aff2a2076e 100644
+--- a/block/qed.c
++++ b/block/qed.c
+@@ -748,8 +748,8 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
+     ret = 0; /* success */
+ out:
+     g_free(l1_table);
+-    blk_unref(blk);
+-    bdrv_unref(bs);
++    blk_co_unref(blk);
++    bdrv_co_unref(bs);
+     return ret;
+ }
+ 
+@@ -819,7 +819,7 @@ bdrv_qed_co_create_opts(BlockDriver *drv, const char *filename,
+ 
+ fail:
+     qobject_unref(qdict);
+-    bdrv_unref(bs);
++    bdrv_co_unref(bs);
+     qapi_free_BlockdevCreateOptions(create_options);
+     return ret;
+ }
+diff --git a/block/vdi.c b/block/vdi.c
+index f2434d6153..08331d2dd7 100644
+--- a/block/vdi.c
++++ b/block/vdi.c
+@@ -886,8 +886,8 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
+ 
+     ret = 0;
+ exit:
+-    blk_unref(blk);
+-    bdrv_unref(bs_file);
++    blk_co_unref(blk);
++    bdrv_co_unref(bs_file);
+     g_free(bmap);
+     return ret;
+ }
+@@ -975,7 +975,7 @@ vdi_co_create_opts(BlockDriver *drv, const char *filename,
+ done:
+     qobject_unref(qdict);
+     qapi_free_BlockdevCreateOptions(create_options);
+-    bdrv_unref(bs_file);
++    bdrv_co_unref(bs_file);
+     return ret;
+ }
+ 
+diff --git a/block/vhdx.c b/block/vhdx.c
+index 81420722a1..00777da91a 100644
+--- a/block/vhdx.c
++++ b/block/vhdx.c
+@@ -2053,8 +2053,8 @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
+ 
+     ret = 0;
+ delete_and_exit:
+-    blk_unref(blk);
+-    bdrv_unref(bs);
++    blk_co_unref(blk);
++    bdrv_co_unref(bs);
+     g_free(creator);
+     return ret;
+ }
+@@ -2144,7 +2144,7 @@ vhdx_co_create_opts(BlockDriver *drv, const char *filename,
+ 
+ fail:
+     qobject_unref(qdict);
+-    bdrv_unref(bs);
++    bdrv_co_unref(bs);
+     qapi_free_BlockdevCreateOptions(create_options);
+     return ret;
+ }
+diff --git a/block/vmdk.c b/block/vmdk.c
+index f5f49018fe..01ca13c82b 100644
+--- a/block/vmdk.c
++++ b/block/vmdk.c
+@@ -2306,7 +2306,7 @@ exit:
+         if (pbb) {
+             *pbb = blk;
+         } else {
+-            blk_unref(blk);
++            blk_co_unref(blk);
+             blk = NULL;
+         }
+     }
+@@ -2516,12 +2516,12 @@ vmdk_co_do_create(int64_t size,
+         if (strcmp(blk_bs(backing)->drv->format_name, "vmdk")) {
+             error_setg(errp, "Invalid backing file format: %s. Must be vmdk",
+                        blk_bs(backing)->drv->format_name);
+-            blk_unref(backing);
++            blk_co_unref(backing);
+             ret = -EINVAL;
+             goto exit;
+         }
+         ret = vmdk_read_cid(blk_bs(backing), 0, &parent_cid);
+-        blk_unref(backing);
++        blk_co_unref(backing);
+         if (ret) {
+             error_setg(errp, "Failed to read parent CID");
+             goto exit;
+@@ -2542,14 +2542,14 @@ vmdk_co_do_create(int64_t size,
+                              blk_bs(extent_blk)->filename);
+         created_size += cur_size;
+         extent_idx++;
+-        blk_unref(extent_blk);
++        blk_co_unref(extent_blk);
+     }
+ 
+     /* Check whether we got excess extents */
+     extent_blk = extent_fn(-1, extent_idx, flat, split, compress, zeroed_grain,
+                            opaque, NULL);
+     if (extent_blk) {
+-        blk_unref(extent_blk);
++        blk_co_unref(extent_blk);
+         error_setg(errp, "List of extents contains unused extents");
+         ret = -EINVAL;
+         goto exit;
+@@ -2590,7 +2590,7 @@ vmdk_co_do_create(int64_t size,
+     ret = 0;
+ exit:
+     if (blk) {
+-        blk_unref(blk);
++        blk_co_unref(blk);
+     }
+     g_free(desc);
+     g_free(parent_desc_line);
+@@ -2641,7 +2641,7 @@ vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split,
+                            errp)) {
+         goto exit;
+     }
+-    bdrv_unref(bs);
++    bdrv_co_unref(bs);
+ exit:
+     g_free(ext_filename);
+     return blk;
+@@ -2797,12 +2797,12 @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
+         return NULL;
+     }
+     blk_set_allow_write_beyond_eof(blk, true);
+-    bdrv_unref(bs);
++    bdrv_co_unref(bs);
+ 
+     if (size != -1) {
+         ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
+         if (ret) {
+-            blk_unref(blk);
++            blk_co_unref(blk);
+             blk = NULL;
+         }
+     }
+diff --git a/block/vpc.c b/block/vpc.c
+index b89b0ff8e2..07ddda5b99 100644
+--- a/block/vpc.c
++++ b/block/vpc.c
+@@ -1082,8 +1082,8 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
+     }
+ 
+ out:
+-    blk_unref(blk);
+-    bdrv_unref(bs);
++    blk_co_unref(blk);
++    bdrv_co_unref(bs);
+     return ret;
+ }
+ 
+@@ -1162,7 +1162,7 @@ vpc_co_create_opts(BlockDriver *drv, const char *filename,
+ 
+ fail:
+     qobject_unref(qdict);
+-    bdrv_unref(bs);
++    bdrv_co_unref(bs);
+     qapi_free_BlockdevCreateOptions(create_options);
+     return ret;
+ }
+diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
+index 2c312cc774..ec3ddb17a8 100644
+--- a/include/block/block-global-state.h
++++ b/include/block/block-global-state.h
+@@ -218,7 +218,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
+                      bool quiet, Error **errp);
+ 
+ void bdrv_ref(BlockDriverState *bs);
+-void bdrv_unref(BlockDriverState *bs);
++void no_coroutine_fn bdrv_unref(BlockDriverState *bs);
++void coroutine_fn no_co_wrapper bdrv_co_unref(BlockDriverState *bs);
+ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
+ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
+                              BlockDriverState *child_bs,
+diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h
+index 2b6d27db7c..fa83f9389c 100644
+--- a/include/sysemu/block-backend-global-state.h
++++ b/include/sysemu/block-backend-global-state.h
+@@ -42,7 +42,10 @@ blk_co_new_open(const char *filename, const char *reference, QDict *options,
+ 
+ int blk_get_refcnt(BlockBackend *blk);
+ void blk_ref(BlockBackend *blk);
+-void blk_unref(BlockBackend *blk);
++
++void no_coroutine_fn blk_unref(BlockBackend *blk);
++void coroutine_fn no_co_wrapper blk_co_unref(BlockBackend *blk);
++
+ void blk_remove_all_bs(void);
+ BlockBackend *blk_by_name(const char *name);
+ BlockBackend *blk_next(BlockBackend *blk);
diff --git a/debian/patches/extra/0019-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch b/debian/patches/extra/0019-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch
new file mode 100644
index 0000000..685b7a8
--- /dev/null
+++ b/debian/patches/extra/0019-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch
@@ -0,0 +1,43 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Thu, 4 May 2023 13:57:34 +0200
+Subject: [PATCH] block: Don't call no_coroutine_fns in qmp_block_resize()
+
+This QMP handler runs in a coroutine, so it must use the corresponding
+no_co_wrappers instead.
+
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2185688
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20230504115750.54437-5-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry-picked from commit 0c7d204f50c382c6baac8c94bd57af4a022b3888)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ blockdev.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index 2c1752a403..e464daea58 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -2440,7 +2440,7 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
+         return;
+     }
+ 
+-    blk = blk_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL, errp);
++    blk = blk_co_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL, errp);
+     if (!blk) {
+         return;
+     }
+@@ -2455,7 +2455,7 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
+ 
+     bdrv_co_lock(bs);
+     bdrv_drained_end(bs);
+-    blk_unref(blk);
++    blk_co_unref(blk);
+     bdrv_co_unlock(bs);
+ }
+ 
diff --git a/debian/patches/extra/0020-accel-tcg-Fix-atomic_mmu_lookup-for-reads.patch b/debian/patches/extra/0020-accel-tcg-Fix-atomic_mmu_lookup-for-reads.patch
new file mode 100644
index 0000000..e4d9946
--- /dev/null
+++ b/debian/patches/extra/0020-accel-tcg-Fix-atomic_mmu_lookup-for-reads.patch
@@ -0,0 +1,36 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <richard.henderson@linaro.org>
+Date: Fri, 5 May 2023 21:40:49 +0100
+Subject: [PATCH] accel/tcg: Fix atomic_mmu_lookup for reads
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+A copy-paste bug had us looking at the victim cache for writes.
+
+Cc: qemu-stable@nongnu.org
+Reported-by: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
+Fixes: 08dff435e2 ("tcg: Probe the proper permissions for atomic ops")
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Message-Id: <20230505204049.352469-1-richard.henderson@linaro.org>
+(cherry-picked from commit 8c313254e61ed47a1bf4a2db714b25cdd94fbcce)
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ accel/tcg/cputlb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
+index e984a98dc4..145fba45b2 100644
+--- a/accel/tcg/cputlb.c
++++ b/accel/tcg/cputlb.c
+@@ -1830,7 +1830,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
+     } else /* if (prot & PAGE_READ) */ {
+         tlb_addr = tlbe->addr_read;
+         if (!tlb_hit(tlb_addr, addr)) {
+-            if (!VICTIM_TLB_HIT(addr_write, addr)) {
++            if (!VICTIM_TLB_HIT(addr_read, addr)) {
+                 tlb_fill(env_cpu(env), addr, size,
+                          MMU_DATA_LOAD, mmu_idx, retaddr);
+                 index = tlb_index(env, mmu_idx, addr);
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 524cdb4..8c76070 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 cd13b8b0a3..cb1d334bcb 100644
+index 5060119952..9d1c358c12 100644
 --- a/hw/core/machine.c
 +++ b/hw/core/machine.c
-@@ -141,7 +141,8 @@ GlobalProperty hw_compat_4_0[] = {
+@@ -142,7 +142,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/0027-PVE-Backup-add-vma-backup-format-code.patch b/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch
index b356f34..fd0c8e6 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
@@ -33,7 +33,7 @@ index 253fe49fa2..744b698a82 100644
  softmmu_ss.add(files('block-ram-registrar.c'))
  
 diff --git a/meson.build b/meson.build
-index c44d05a13f..b9bc31b01c 100644
+index d964e741e7..603cdb97bb 100644
 --- a/meson.build
 +++ b/meson.build
 @@ -1527,6 +1527,8 @@ keyutils = dependency('libkeyutils', required: false,
@@ -45,7 +45,7 @@ index c44d05a13f..b9bc31b01c 100644
  # libselinux
  selinux = dependency('libselinux',
                       required: get_option('selinux'),
-@@ -3645,6 +3647,9 @@ if have_tools
+@@ -3646,6 +3648,9 @@ if have_tools
                 dependencies: [blockdev, qemuutil, gnutls, selinux],
                 install: true)
  
diff --git a/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch b/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
index add2222..268f13b 100644
--- a/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
+++ b/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
@@ -48,10 +48,10 @@ index f580f95395..5bcebb934b 100644
  softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
  softmmu_ss.add(files('block-ram-registrar.c'))
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 2846083546..947d4f3df0 100644
+index ca2599de44..d50e99df26 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1027,3 +1027,36 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target,
+@@ -1029,3 +1029,36 @@ 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);
  }
@@ -89,7 +89,7 @@ index 2846083546..947d4f3df0 100644
 +    hmp_handle_error(mon, error);
 +}
 diff --git a/blockdev.c b/blockdev.c
-index 47c70eeb91..3b95f54b64 100644
+index 9a010f3a86..b9505c95d3 100644
 --- a/blockdev.c
 +++ b/blockdev.c
 @@ -37,6 +37,7 @@
@@ -187,7 +187,7 @@ index c012bad741..2e504db706 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 b9bc31b01c..b12ef9f8d4 100644
+index 603cdb97bb..d307d8eabf 100644
 --- a/meson.build
 +++ b/meson.build
 @@ -1528,6 +1528,7 @@ keyutils = dependency('libkeyutils', required: false,
@@ -510,7 +510,7 @@ index 0000000000..1dda8b7d8f
 +#endif /* PROXMOX_BACKUP_CLIENT_H */
 diff --git a/pve-backup.c b/pve-backup.c
 new file mode 100644
-index 0000000000..bb51c030bd
+index 0000000000..389d6c84a0
 --- /dev/null
 +++ b/pve-backup.c
 @@ -0,0 +1,938 @@
@@ -1328,7 +1328,7 @@ index 0000000000..bb51c030bd
 +        l = g_list_next(l);
 +
 +        if (di->target) {
-+            bdrv_unref(di->target);
++            bdrv_co_unref(di->target);
 +        }
 +
 +        if (di->targetfile[0]) {
diff --git a/debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch b/debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
index 2d29a8d..4ee6100 100644
--- a/debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
+++ b/debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
@@ -12,10 +12,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  create mode 100644 pbs-restore.c
 
 diff --git a/meson.build b/meson.build
-index b12ef9f8d4..8ec21bba90 100644
+index d307d8eabf..afd105001e 100644
 --- a/meson.build
 +++ b/meson.build
-@@ -3651,6 +3651,10 @@ if have_tools
+@@ -3652,6 +3652,10 @@ if have_tools
    vma = executable('vma', files('vma.c', 'vma-reader.c') + genh,
                     dependencies: [authz, block, crypto, io, qom], install: true)
  
diff --git a/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch b/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
index f28236a..082241a 100644
--- a/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
+++ b/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
@@ -29,10 +29,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  6 files changed, 143 insertions(+), 23 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 947d4f3df0..bcba630f12 100644
+index d50e99df26..cda5de792b 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1054,6 +1054,7 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
+@@ -1056,6 +1056,7 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
          NULL, // PBS fingerprint
          NULL, // PBS backup-id
          false, 0, // PBS backup-time
@@ -132,7 +132,7 @@ index 1dda8b7d8f..8cbf645b2c 100644
  
  
 diff --git a/pve-backup.c b/pve-backup.c
-index bb51c030bd..cfdeb50f23 100644
+index 389d6c84a0..c4cbff7fb1 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -7,6 +7,7 @@
@@ -378,7 +378,7 @@ index bb51c030bd..cfdeb50f23 100644
 +        }
 +
          if (di->target) {
-             bdrv_unref(di->target);
+             bdrv_co_unref(di->target);
          }
 @@ -852,6 +931,7 @@ UuidInfo *qmp_backup(
      const char *fingerprint,
diff --git a/debian/patches/pve/0032-PVE-various-PBS-fixes.patch b/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
index f4711cd..a5d7a02 100644
--- a/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
+++ b/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
@@ -21,10 +21,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  3 files changed, 52 insertions(+), 12 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index bcba630f12..6a6ed6d0e7 100644
+index cda5de792b..ecbebd39ac 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1054,7 +1054,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
+@@ -1056,7 +1056,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
          NULL, // PBS fingerprint
          NULL, // PBS backup-id
          false, 0, // PBS backup-time
@@ -36,7 +36,7 @@ index bcba630f12..6a6ed6d0e7 100644
          NULL, NULL,
          devlist, qdict_haskey(qdict, "speed"), speed, &error);
 diff --git a/pve-backup.c b/pve-backup.c
-index cfdeb50f23..f1eacbcaf6 100644
+index c4cbff7fb1..95f742e1d1 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -10,6 +10,7 @@
diff --git a/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch b/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
index c78dbd7..d7868e1 100644
--- a/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
+++ b/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
@@ -319,7 +319,7 @@ index 0000000000..43e69ada46
 +
 +block_init(bdrv_pbs_init);
 diff --git a/configure b/configure
-index 800b5850f4..37e12a3dce 100755
+index a62a3e6be9..1ac0feb46b 100755
 --- a/configure
 +++ b/configure
 @@ -288,6 +288,7 @@ linux_user=""
@@ -330,7 +330,7 @@ index 800b5850f4..37e12a3dce 100755
  plugins="$default_feature"
  meson=""
  ninja=""
-@@ -872,6 +873,10 @@ for opt do
+@@ -873,6 +874,10 @@ for opt do
    ;;
    --with-coroutine=*) coroutine="$optarg"
    ;;
@@ -341,7 +341,7 @@ index 800b5850f4..37e12a3dce 100755
    --with-git=*) git="$optarg"
    ;;
    --with-git-submodules=*)
-@@ -1048,6 +1053,7 @@ cat << EOF
+@@ -1049,6 +1054,7 @@ cat << EOF
    debug-info      debugging information
    safe-stack      SafeStack Stack Smash Protection. Depends on
                    clang/llvm and requires coroutine backend ucontext.
@@ -349,7 +349,7 @@ index 800b5850f4..37e12a3dce 100755
  
  NOTE: The object files are built at the place where configure is launched
  EOF
-@@ -2385,6 +2391,9 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
+@@ -2386,6 +2392,9 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
  if test "$modules" = "yes"; then
    echo "CONFIG_MODULES=y" >> $config_host_mak
  fi
@@ -360,10 +360,10 @@ index 800b5850f4..37e12a3dce 100755
  # XXX: suppress that
  if [ "$bsd" = "yes" ] ; then
 diff --git a/meson.build b/meson.build
-index 8ec21bba90..419bea5cf4 100644
+index afd105001e..d01ee5d489 100644
 --- a/meson.build
 +++ b/meson.build
-@@ -4035,7 +4035,7 @@ summary_info += {'bzip2 support':     libbzip2}
+@@ -4037,7 +4037,7 @@ summary_info += {'bzip2 support':     libbzip2}
  summary_info += {'lzfse support':     liblzfse}
  summary_info += {'zstd support':      zstd}
  summary_info += {'NUMA host support': numa}
diff --git a/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch b/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
index 0ceb595..60ba5dd 100644
--- a/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
+++ b/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
@@ -16,7 +16,7 @@ Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
  2 files changed, 38 insertions(+)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index f1eacbcaf6..c6fee40a67 100644
+index 95f742e1d1..9eb8645e63 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -1054,3 +1054,12 @@ BackupStatus *qmp_query_backup(Error **errp)
diff --git a/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch b/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
index 418ae1c..cd76e86 100644
--- a/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
+++ b/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
@@ -69,7 +69,7 @@ index 087161a967..9a67e544ce 100644
                             info->zero_bytes, zero_per);
  
 diff --git a/pve-backup.c b/pve-backup.c
-index c6fee40a67..d4abe6e703 100644
+index 9eb8645e63..2db35f90e0 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -48,6 +48,7 @@ static struct PVEBackupState {
diff --git a/debian/patches/pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch b/debian/patches/pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch
index 7f8fe9e..98e02a0 100644
--- a/debian/patches/pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch
+++ b/debian/patches/pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch
@@ -14,7 +14,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
  2 files changed, 7 insertions(+), 2 deletions(-)
 
 diff --git a/meson.build b/meson.build
-index 419bea5cf4..c39c6054ee 100644
+index d01ee5d489..6129c3ce0c 100644
 --- a/meson.build
 +++ b/meson.build
 @@ -1528,6 +1528,7 @@ keyutils = dependency('libkeyutils', required: false,
@@ -25,7 +25,7 @@ index 419bea5cf4..c39c6054ee 100644
  libproxmox_backup_qemu = cc.find_library('proxmox_backup_qemu', required: true)
  
  # libselinux
-@@ -3143,6 +3144,7 @@ if have_block
+@@ -3144,6 +3145,7 @@ if have_block
    # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
    # os-win32.c does not
    blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
diff --git a/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch b/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
index 616b170..3a6b4d3 100644
--- a/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
+++ b/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
@@ -20,7 +20,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 50 insertions(+), 113 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index d4abe6e703..214c839c0b 100644
+index 2db35f90e0..b4bc2de76e 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -54,6 +54,7 @@ static struct PVEBackupState {
@@ -271,7 +271,7 @@ index d4abe6e703..214c839c0b 100644
 -        }
 -
          if (di->target) {
-             bdrv_unref(di->target);
+             bdrv_co_unref(di->target);
          }
 @@ -1021,9 +952,15 @@ UuidInfo *qmp_backup(
      block_on_coroutine_fn(pvebackup_co_prepare, &task);
diff --git a/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch b/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
index 7cd670e..7f2f945 100644
--- a/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
+++ b/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
@@ -57,7 +57,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  2 files changed, 138 insertions(+), 79 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 214c839c0b..1d233dac93 100644
+index b4bc2de76e..6d6d7708b6 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -35,7 +35,9 @@ const char *PBS_BITMAP_NAME = "pbs-incremental-dirty-bitmap";
diff --git a/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch b/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
index b678e74..2c86cb2 100644
--- a/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
+++ b/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
@@ -175,7 +175,7 @@ index 0000000000..887e998b9e
 +                         NULL);
 +}
 diff --git a/pve-backup.c b/pve-backup.c
-index 1d233dac93..5c9c153e31 100644
+index 6d6d7708b6..e9264e5025 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -1110,6 +1110,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
diff --git a/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch b/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
index 810a801..21ca3a5 100644
--- a/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
+++ b/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
@@ -35,10 +35,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  5 files changed, 79 insertions(+), 182 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 6a6ed6d0e7..bcf5849196 100644
+index ecbebd39ac..56f39b14d4 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1028,7 +1028,7 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target,
+@@ -1030,7 +1030,7 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target,
                                 !!read_only, read_only_mode, errp);
  }
  
@@ -47,7 +47,7 @@ index 6a6ed6d0e7..bcf5849196 100644
  {
      Error *error = NULL;
  
-@@ -1037,7 +1037,7 @@ void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
+@@ -1039,7 +1039,7 @@ void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
      hmp_handle_error(mon, error);
  }
  
@@ -119,7 +119,7 @@ index 4ce7bc0b5e..0923037dec 100644
  static void proxmox_backup_schedule_wake(void *data) {
      CoCtxData *waker = (CoCtxData *)data;
 diff --git a/pve-backup.c b/pve-backup.c
-index 5c9c153e31..378e4a9a63 100644
+index e9264e5025..4536650b24 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -356,7 +356,7 @@ static void job_cancel_bh(void *opaque) {
diff --git a/debian/patches/pve/0044-PBS-add-master-key-support.patch b/debian/patches/pve/0044-PBS-add-master-key-support.patch
index 7a7db33..cdcf7db 100644
--- a/debian/patches/pve/0044-PBS-add-master-key-support.patch
+++ b/debian/patches/pve/0044-PBS-add-master-key-support.patch
@@ -21,10 +21,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  3 files changed, 11 insertions(+)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index bcf5849196..fb881056e9 100644
+index 56f39b14d4..f852c70611 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1051,6 +1051,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
+@@ -1053,6 +1053,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
          NULL, // PBS password
          NULL, // PBS keyfile
          NULL, // PBS key_password
@@ -33,7 +33,7 @@ index bcf5849196..fb881056e9 100644
          NULL, // PBS backup-id
          false, 0, // PBS backup-time
 diff --git a/pve-backup.c b/pve-backup.c
-index 378e4a9a63..504c11657a 100644
+index 4536650b24..0d8bf1c332 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -531,6 +531,7 @@ UuidInfo coroutine_fn *qmp_backup(
diff --git a/debian/patches/pve/0052-pbs-namespace-support.patch b/debian/patches/pve/0052-pbs-namespace-support.patch
index 958fb5f..d8d730b 100644
--- a/debian/patches/pve/0052-pbs-namespace-support.patch
+++ b/debian/patches/pve/0052-pbs-namespace-support.patch
@@ -15,10 +15,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  5 files changed, 47 insertions(+), 9 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index fb881056e9..25ac598980 100644
+index f852c70611..ac23f21eef 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1053,6 +1053,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
+@@ -1055,6 +1055,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
          NULL, // PBS key_password
          NULL, // PBS master_keyfile
          NULL, // PBS fingerprint
@@ -172,7 +172,7 @@ index 2f834cf42e..f03d9bab8d 100644
          fprintf(stderr, "restore failed: %s\n", pbs_error);
          return -1;
 diff --git a/pve-backup.c b/pve-backup.c
-index 504c11657a..809ff6d134 100644
+index 0d8bf1c332..8a4ecba394 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -12,6 +12,8 @@
diff --git a/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch b/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
index 1b3e9ec..03f6a06 100644
--- a/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
+++ b/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
@@ -21,7 +21,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 8 insertions(+), 2 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 809ff6d134..221e45ed0e 100644
+index 8a4ecba394..5eba2abde0 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -505,6 +505,11 @@ static void create_backup_jobs_bh(void *opaque) {
diff --git a/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch b/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
index 0e66858..7addf09 100644
--- a/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
+++ b/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
@@ -23,7 +23,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 19 insertions(+), 3 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 221e45ed0e..a20fa38ee8 100644
+index 5eba2abde0..99a91f88b2 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -318,6 +318,13 @@ static void coroutine_fn pvebackup_co_complete_stream(void *opaque)
diff --git a/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch b/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
index 5a9da14..f386f72 100644
--- a/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
+++ b/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
@@ -39,7 +39,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 38 insertions(+), 19 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index a20fa38ee8..3509f46ed8 100644
+index 99a91f88b2..04c8ce0a3d 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -356,12 +356,41 @@ static void pvebackup_complete_cb(void *opaque, int ret)
diff --git a/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch b/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
index 43efd1d..1aece72 100644
--- a/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
+++ b/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
@@ -31,10 +31,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  3 files changed, 23 insertions(+), 8 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 25ac598980..74e43a757f 100644
+index ac23f21eef..636509b83e 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1061,7 +1061,9 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
+@@ -1063,7 +1063,9 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
          false, false, // PBS encrypt
          true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
          NULL, NULL,
@@ -46,7 +46,7 @@ index 25ac598980..74e43a757f 100644
      hmp_handle_error(mon, error);
  }
 diff --git a/pve-backup.c b/pve-backup.c
-index 3509f46ed8..a343d63586 100644
+index 04c8ce0a3d..56da408001 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -57,6 +57,7 @@ static struct PVEBackupState {
diff --git a/debian/patches/series b/debian/patches/series
index 175ec2d..90d7943 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,6 +4,20 @@ extra/0003-scsi-megasas-Internal-cdbs-have-16-byte-length.patch
 extra/0004-ide-avoid-potential-deadlock-when-draining-during-tr.patch
 extra/0005-memory-Allow-disabling-re-entrancy-checking-per-MR.patch
 extra/0006-lsi53c895a-disable-reentrancy-detection-for-script-R.patch
+extra/0007-rtl8139-fix-large_send_mss-divide-by-zero.patch
+extra/0008-block-monitor-Fix-crash-when-executing-HMP-commit.patch
+extra/0009-ui-return-NULL-when-getting-cursor-without-a-console.patch
+extra/0010-ui-Fix-pixel-colour-channel-order-for-PNG-screenshot.patch
+extra/0011-target-arm-Fix-vd-vm-overlap-in-sve_ldff1_z.patch
+extra/0012-softfloat-Fix-the-incorrect-computation-in-float32_e.patch
+extra/0013-target-i386-Change-wrong-XFRM-value-in-SGX-CPUID-lea.patch
+extra/0014-block-compile-out-assert_bdrv_graph_readable-by-defa.patch
+extra/0015-hw-pci-Disable-PCI_ERR_UNCOR_MASK-register-for-machi.patch
+extra/0016-block-Fix-use-after-free-in-blockdev_mark_auto_del.patch
+extra/0017-block-Consistently-call-bdrv_activate-outside-corout.patch
+extra/0018-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch
+extra/0019-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch
+extra/0020-accel-tcg-Fix-atomic_mmu_lookup-for-reads.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.39.2





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

* [pve-devel] [PATCH v2 qemu 6/7] PVE backup: don't call no_co_wrapper function from coroutine
  2023-05-15 13:39 [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
                   ` (4 preceding siblings ...)
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 5/7] add stable patches for 8.0.0 Fiona Ebner
@ 2023-05-15 13:39 ` Fiona Ebner
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 7/7] squash related patches Fiona Ebner
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Fiona Ebner @ 2023-05-15 13:39 UTC (permalink / raw)
  To: pve-devel

Namely, pvebackup_co_prepare() needs to call bdrv_co_open() rather
than bdrv_open(), because it is a coroutine itself.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---

No changes in v2.

Sorry that this is not already in the rebase patch, didn't notice
earlier, because this is only in the BACKUP_FORMAT_DIR case.

This is what I mean with there are too many backup-related patches ;)

 .../pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch | 4 ++--
 ...PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch | 2 +-
 debian/patches/pve/0032-PVE-various-PBS-fixes.patch           | 2 +-
 .../pve/0034-PVE-add-query_proxmox_support-QMP-command.patch  | 2 +-
 .../pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch     | 4 ++--
 ...PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch | 2 +-
 ...PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch | 2 +-
 .../pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch  | 2 +-
 .../0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch | 4 ++--
 debian/patches/pve/0044-PBS-add-master-key-support.patch      | 2 +-
 debian/patches/pve/0052-pbs-namespace-support.patch           | 2 +-
 ...PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch | 2 +-
 ...057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch | 2 +-
 ...-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch | 2 +-
 ...PVE-Backup-allow-passing-max-workers-performance-set.patch | 2 +-
 15 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch b/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
index 268f13b..3aae91f 100644
--- a/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
+++ b/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
@@ -510,7 +510,7 @@ index 0000000000..1dda8b7d8f
 +#endif /* PROXMOX_BACKUP_CLIENT_H */
 diff --git a/pve-backup.c b/pve-backup.c
 new file mode 100644
-index 0000000000..389d6c84a0
+index 0000000000..f77892a509
 --- /dev/null
 +++ b/pve-backup.c
 @@ -0,0 +1,938 @@
@@ -1253,7 +1253,7 @@ index 0000000000..389d6c84a0
 +                goto err;
 +            }
 +
-+            di->target = bdrv_open(di->targetfile, NULL, NULL, flags, &local_err);
++            di->target = bdrv_co_open(di->targetfile, NULL, NULL, flags, &local_err);
 +            if (!di->target) {
 +                error_propagate(task->errp, local_err);
 +                goto err;
diff --git a/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch b/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
index 082241a..1708021 100644
--- a/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
+++ b/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
@@ -132,7 +132,7 @@ index 1dda8b7d8f..8cbf645b2c 100644
  
  
 diff --git a/pve-backup.c b/pve-backup.c
-index 389d6c84a0..c4cbff7fb1 100644
+index f77892a509..d9942a14a1 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -7,6 +7,7 @@
diff --git a/debian/patches/pve/0032-PVE-various-PBS-fixes.patch b/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
index a5d7a02..c46a307 100644
--- a/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
+++ b/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
@@ -36,7 +36,7 @@ index cda5de792b..ecbebd39ac 100644
          NULL, NULL,
          devlist, qdict_haskey(qdict, "speed"), speed, &error);
 diff --git a/pve-backup.c b/pve-backup.c
-index c4cbff7fb1..95f742e1d1 100644
+index d9942a14a1..8f18145255 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -10,6 +10,7 @@
diff --git a/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch b/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
index 60ba5dd..0b14e6f 100644
--- a/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
+++ b/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
@@ -16,7 +16,7 @@ Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
  2 files changed, 38 insertions(+)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 95f742e1d1..9eb8645e63 100644
+index 8f18145255..1400c21c49 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -1054,3 +1054,12 @@ BackupStatus *qmp_query_backup(Error **errp)
diff --git a/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch b/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
index cd76e86..2e0f235 100644
--- a/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
+++ b/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
@@ -69,7 +69,7 @@ index 087161a967..9a67e544ce 100644
                             info->zero_bytes, zero_per);
  
 diff --git a/pve-backup.c b/pve-backup.c
-index 9eb8645e63..2db35f90e0 100644
+index 1400c21c49..0a0996b971 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -48,6 +48,7 @@ static struct PVEBackupState {
@@ -255,7 +255,7 @@ index 9eb8645e63..2db35f90e0 100644
 +                goto err_mutex;
              }
  
-             di->target = bdrv_open(di->targetfile, NULL, NULL, flags, &local_err);
+             di->target = bdrv_co_open(di->targetfile, NULL, NULL, flags, &local_err);
              if (!di->target) {
                  error_propagate(task->errp, local_err);
 -                goto err;
diff --git a/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch b/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
index 3a6b4d3..7a5cda5 100644
--- a/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
+++ b/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
@@ -20,7 +20,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 50 insertions(+), 113 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 2db35f90e0..b4bc2de76e 100644
+index 0a0996b971..629da3e6c7 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -54,6 +54,7 @@ static struct PVEBackupState {
diff --git a/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch b/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
index 7f2f945..15eb190 100644
--- a/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
+++ b/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
@@ -57,7 +57,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  2 files changed, 138 insertions(+), 79 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index b4bc2de76e..6d6d7708b6 100644
+index 629da3e6c7..1da9dd9edc 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -35,7 +35,9 @@ const char *PBS_BITMAP_NAME = "pbs-incremental-dirty-bitmap";
diff --git a/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch b/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
index 2c86cb2..644afc2 100644
--- a/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
+++ b/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
@@ -175,7 +175,7 @@ index 0000000000..887e998b9e
 +                         NULL);
 +}
 diff --git a/pve-backup.c b/pve-backup.c
-index 6d6d7708b6..e9264e5025 100644
+index 1da9dd9edc..e0e38063a8 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -1110,6 +1110,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
diff --git a/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch b/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
index 21ca3a5..b38c633 100644
--- a/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
+++ b/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
@@ -119,7 +119,7 @@ index 4ce7bc0b5e..0923037dec 100644
  static void proxmox_backup_schedule_wake(void *data) {
      CoCtxData *waker = (CoCtxData *)data;
 diff --git a/pve-backup.c b/pve-backup.c
-index e9264e5025..4536650b24 100644
+index e0e38063a8..88e507b3c2 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -356,7 +356,7 @@ static void job_cancel_bh(void *opaque) {
@@ -423,7 +423,7 @@ index e9264e5025..4536650b24 100644
                  goto err_mutex;
              }
  
-             di->target = bdrv_open(di->targetfile, NULL, NULL, flags, &local_err);
+             di->target = bdrv_co_open(di->targetfile, NULL, NULL, flags, &local_err);
              if (!di->target) {
 -                error_propagate(task->errp, local_err);
 +                error_propagate(errp, local_err);
diff --git a/debian/patches/pve/0044-PBS-add-master-key-support.patch b/debian/patches/pve/0044-PBS-add-master-key-support.patch
index cdcf7db..4498723 100644
--- a/debian/patches/pve/0044-PBS-add-master-key-support.patch
+++ b/debian/patches/pve/0044-PBS-add-master-key-support.patch
@@ -33,7 +33,7 @@ index 56f39b14d4..f852c70611 100644
          NULL, // PBS backup-id
          false, 0, // PBS backup-time
 diff --git a/pve-backup.c b/pve-backup.c
-index 4536650b24..0d8bf1c332 100644
+index 88e507b3c2..04c5f561cd 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -531,6 +531,7 @@ UuidInfo coroutine_fn *qmp_backup(
diff --git a/debian/patches/pve/0052-pbs-namespace-support.patch b/debian/patches/pve/0052-pbs-namespace-support.patch
index d8d730b..b0bb9a6 100644
--- a/debian/patches/pve/0052-pbs-namespace-support.patch
+++ b/debian/patches/pve/0052-pbs-namespace-support.patch
@@ -172,7 +172,7 @@ index 2f834cf42e..f03d9bab8d 100644
          fprintf(stderr, "restore failed: %s\n", pbs_error);
          return -1;
 diff --git a/pve-backup.c b/pve-backup.c
-index 0d8bf1c332..8a4ecba394 100644
+index 04c5f561cd..08dfb9cbda 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -12,6 +12,8 @@
diff --git a/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch b/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
index 03f6a06..5dee746 100644
--- a/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
+++ b/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
@@ -21,7 +21,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 8 insertions(+), 2 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 8a4ecba394..5eba2abde0 100644
+index 08dfb9cbda..79d14d6a0b 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -505,6 +505,11 @@ static void create_backup_jobs_bh(void *opaque) {
diff --git a/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch b/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
index 7addf09..4beed97 100644
--- a/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
+++ b/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
@@ -23,7 +23,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 19 insertions(+), 3 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 5eba2abde0..99a91f88b2 100644
+index 79d14d6a0b..67e2b99d74 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -318,6 +318,13 @@ static void coroutine_fn pvebackup_co_complete_stream(void *opaque)
diff --git a/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch b/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
index f386f72..68c261e 100644
--- a/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
+++ b/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
@@ -39,7 +39,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  1 file changed, 38 insertions(+), 19 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 99a91f88b2..04c8ce0a3d 100644
+index 67e2b99d74..7a8240363d 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -356,12 +356,41 @@ static void pvebackup_complete_cb(void *opaque, int ret)
diff --git a/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch b/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
index 1aece72..8fd63c0 100644
--- a/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
+++ b/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
@@ -46,7 +46,7 @@ index ac23f21eef..636509b83e 100644
      hmp_handle_error(mon, error);
  }
 diff --git a/pve-backup.c b/pve-backup.c
-index 04c8ce0a3d..56da408001 100644
+index 7a8240363d..cb5312fff3 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -57,6 +57,7 @@ static struct PVEBackupState {
-- 
2.39.2





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

* [pve-devel] [PATCH v2 qemu 7/7] squash related patches
  2023-05-15 13:39 [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
                   ` (5 preceding siblings ...)
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 6/7] PVE backup: don't call no_co_wrapper function from coroutine Fiona Ebner
@ 2023-05-15 13:39 ` Fiona Ebner
  2023-05-15 13:51 ` [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
  2023-05-23 12:31 ` [pve-devel] applied-series: " Thomas Lamprecht
  8 siblings, 0 replies; 11+ messages in thread
From: Fiona Ebner @ 2023-05-15 13:39 UTC (permalink / raw)
  To: pve-devel

where there is no good reason to keep them separate. It's a pain
during rebase if there are multiple patches changing the same code
over and over again. This was especially bad for the backup-related
patches. If the history of patches really is needed, it can be
extracted via git. Additionally, compilation with partial application
of patches was broken since a long time, because one of the master key
changes became part of an earlier patch during a past rebase.

If only the same files were changed by a subsequent patch and the
changes felt to belong together (obvious for later bug fixes, but also
done for features e.g. adding master key support for PBS), the patches
were squashed together.

The PBS namespace support patch was split into the individual parts
it changes, i.e. PBS block driver, pbs-restore binary and QMP backup
infrastructure, and squashed into the respective patches.

No code change is intended, git diff in the submodule should not show
any difference between applying all patches before this commit and
applying all patches after this commit.

The query-proxmox-support QMP function has been left as part of the
"PVE-Backup: Proxmox backup patches for QEMU" patch, because it's
currently only used there. If it ever is used elsewhere too, it can
be split out from there.

The recent alloc-track and BQL-related savevm-async changes have been
left separate for now, because it's not 100% clear they are the best
approach yet. This depends on what upstream decides about the BQL
stuff and whether and what kind of issues with the changes pop up.

The qemu-img dd snapshot patch has been re-ordered to after the other
qemu-img dd patches.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---

New in v2.

 ...add-l-option-for-loading-a-snapshot.patch} |    4 +-
 ...irtio-balloon-improve-query-balloon.patch} |    0
 ...0015-PVE-qapi-modify-query-machines.patch} |    0
 ...=> 0016-PVE-qapi-modify-spice-query.patch} |    0
 ...nel-implementation-for-savevm-async.patch} |    0
 ...sync-for-background-state-snapshots.patch} |   34 +-
 ...dd-optional-buffer-size-to-QEMUFile.patch} |    6 +-
 ...dd-the-zeroinit-block-driver-filter.patch} |    0
 ...Add-dummy-id-command-line-parameter.patch} |    0
 ...-target-i386-disable-LINT0-after-re.patch} |    0
 ...e-posix-make-locking-optiono-on-cre.patch} |    0
 ...-PVE-monitor-disable-oob-capability.patch} |    0
 ...ed-balloon-qemu-4-0-config-size-fal.patch} |    0
 ...-Allow-version-code-in-machine-type.patch} |    0
 ...-bcs-bitmap-initialization-to-job-c.patch} |    0
 ...E-Backup-add-vma-backup-format-code.patch} |  267 ++--
 ...Backup-add-backup-dump-block-driver.patch} |    0
 ...-sequential-job-transaction-support.patch} |    0
 ...irty-bitmap-tracking-for-incremental.patch |  460 -------
 ...kup-Proxmox-backup-patches-for-QEMU.patch} | 1117 +++++++++++------
 ...store-new-command-to-restore-from-p.patch} |   29 +-
 .../pve/0032-PVE-various-PBS-fixes.patch      |  217 ----
 ...k-driver-to-map-backup-archives-into.patch |   62 +-
 ...dd-query_proxmox_support-QMP-command.patch |   74 --
 ...t-stderr-to-journal-when-daemonized.patch} |    0
 ...grate-dirty-bitmap-state-via-savevm.patch} |   24 +-
 ...E-add-query-pbs-bitmap-info-QMP-call.patch |  441 -------
 ...irty-bitmap-migrate-other-bitmaps-e.patch} |    0
 ...ll-back-to-open-iscsi-initiatorname.patch} |    0
 ...-transaction-to-synchronize-job-stat.patch |  293 -----
 ...VE-block-stream-increase-chunk-size.patch} |    0
 ...-block-on-finishing-and-cleanup-crea.patch |  499 --------
 ...ccept-NULL-qiov-in-bdrv_pad_request.patch} |    0
 ...> 0040-block-add-alloc-track-driver.patch} |   14 +-
 ...rbd-workaround-for-ceph-issue-53784.patch} |    0
 ...fix-handling-of-holes-in-.bdrv_co_b.patch} |    0
 ...routine-QMP-for-backup-cancel_backup.patch |  595 ---------
 ...-rbd-implement-bdrv_co_block_status.patch} |    0
 .../pve/0044-PBS-add-master-key-support.patch |  100 --
 ...lloc-track-fix-deadlock-during-drop.patch} |    0
 ...st-path-reads-without-allocation-if-.patch |   53 -
 ...pshots-hold-the-BQL-during-setup-ca.patch} |    0
 ...m-async-don-t-hold-BQL-during-setup.patch} |    0
 ...-register-yank-before-migration_inco.patch |   35 -
 .../pve/0051-vma-allow-partial-restore.patch  |  407 ------
 .../pve/0052-pbs-namespace-support.patch      |  235 ----
 ...e-jobs-correctly-cancel-in-error-sce.patch |   60 -
 ...nsure-jobs-in-di_list-are-referenced.patch |   73 --
 ...d-segfault-issues-upon-backup-cancel.patch |  118 --
 ...support-64KiB-unaligned-input-images.patch |   57 -
 ...d-triggering-assertion-in-error-case.patch |   25 -
 ...ck-alloc-track-avoid-premature-break.patch |   36 -
 ...-passing-max-workers-performance-set.patch |  144 ---
 ...vevm-async-optimize-querying-pending.patch |   49 -
 ...also-initialize-compression-counters.patch |   26 -
 debian/patches/series                         |   87 +-
 56 files changed, 1041 insertions(+), 4600 deletions(-)
 rename debian/patches/pve/{0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch => 0013-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch} (97%)
 rename debian/patches/pve/{0013-PVE-virtio-balloon-improve-query-balloon.patch => 0014-PVE-virtio-balloon-improve-query-balloon.patch} (100%)
 rename debian/patches/pve/{0014-PVE-qapi-modify-query-machines.patch => 0015-PVE-qapi-modify-query-machines.patch} (100%)
 rename debian/patches/pve/{0015-PVE-qapi-modify-spice-query.patch => 0016-PVE-qapi-modify-spice-query.patch} (100%)
 rename debian/patches/pve/{0016-PVE-add-IOChannel-implementation-for-savevm-async.patch => 0017-PVE-add-IOChannel-implementation-for-savevm-async.patch} (100%)
 rename debian/patches/pve/{0017-PVE-add-savevm-async-for-background-state-snapshots.patch => 0018-PVE-add-savevm-async-for-background-state-snapshots.patch} (96%)
 rename debian/patches/pve/{0018-PVE-add-optional-buffer-size-to-QEMUFile.patch => 0019-PVE-add-optional-buffer-size-to-QEMUFile.patch} (97%)
 rename debian/patches/pve/{0019-PVE-block-add-the-zeroinit-block-driver-filter.patch => 0020-PVE-block-add-the-zeroinit-block-driver-filter.patch} (100%)
 rename debian/patches/pve/{0020-PVE-Add-dummy-id-command-line-parameter.patch => 0021-PVE-Add-dummy-id-command-line-parameter.patch} (100%)
 rename debian/patches/pve/{0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch => 0022-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch} (100%)
 rename debian/patches/pve/{0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch => 0023-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch} (100%)
 rename debian/patches/pve/{0023-PVE-monitor-disable-oob-capability.patch => 0024-PVE-monitor-disable-oob-capability.patch} (100%)
 rename debian/patches/pve/{0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch => 0025-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch} (100%)
 rename debian/patches/pve/{0025-PVE-Allow-version-code-in-machine-type.patch => 0026-PVE-Allow-version-code-in-machine-type.patch} (100%)
 rename debian/patches/pve/{0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch => 0027-block-backup-move-bcs-bitmap-initialization-to-job-c.patch} (100%)
 rename debian/patches/pve/{0027-PVE-Backup-add-vma-backup-format-code.patch => 0028-PVE-Backup-add-vma-backup-format-code.patch} (91%)
 rename debian/patches/pve/{0028-PVE-Backup-add-backup-dump-block-driver.patch => 0029-PVE-Backup-add-backup-dump-block-driver.patch} (100%)
 rename debian/patches/pve/{0037-PVE-Add-sequential-job-transaction-support.patch => 0030-PVE-Add-sequential-job-transaction-support.patch} (100%)
 delete mode 100644 debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
 rename debian/patches/pve/{0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch => 0031-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch} (56%)
 rename debian/patches/pve/{0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch => 0032-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch} (90%)
 delete mode 100644 debian/patches/pve/0032-PVE-various-PBS-fixes.patch
 delete mode 100644 debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
 rename debian/patches/pve/{0036-PVE-redirect-stderr-to-journal-when-daemonized.patch => 0034-PVE-redirect-stderr-to-journal-when-daemonized.patch} (100%)
 rename debian/patches/pve/{0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch => 0035-PVE-Migrate-dirty-bitmap-state-via-savevm.patch} (93%)
 delete mode 100644 debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
 rename debian/patches/pve/{0041-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch => 0036-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch} (100%)
 rename debian/patches/pve/{0042-PVE-fall-back-to-open-iscsi-initiatorname.patch => 0037-PVE-fall-back-to-open-iscsi-initiatorname.patch} (100%)
 delete mode 100644 debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
 rename debian/patches/pve/{0046-PVE-block-stream-increase-chunk-size.patch => 0038-PVE-block-stream-increase-chunk-size.patch} (100%)
 delete mode 100644 debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
 rename debian/patches/pve/{0047-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch => 0039-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch} (100%)
 rename debian/patches/pve/{0048-block-add-alloc-track-driver.patch => 0040-block-add-alloc-track-driver.patch} (97%)
 rename debian/patches/pve/{0053-Revert-block-rbd-workaround-for-ceph-issue-53784.patch => 0041-Revert-block-rbd-workaround-for-ceph-issue-53784.patch} (100%)
 rename debian/patches/pve/{0054-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch => 0042-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch} (100%)
 delete mode 100644 debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
 rename debian/patches/pve/{0055-Revert-block-rbd-implement-bdrv_co_block_status.patch => 0043-Revert-block-rbd-implement-bdrv_co_block_status.patch} (100%)
 delete mode 100644 debian/patches/pve/0044-PBS-add-master-key-support.patch
 rename debian/patches/pve/{0063-alloc-track-fix-deadlock-during-drop.patch => 0044-alloc-track-fix-deadlock-during-drop.patch} (100%)
 delete mode 100644 debian/patches/pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch
 rename debian/patches/pve/{0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch => 0045-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch} (100%)
 rename debian/patches/pve/{0067-savevm-async-don-t-hold-BQL-during-setup.patch => 0046-savevm-async-don-t-hold-BQL-during-setup.patch} (100%)
 delete mode 100644 debian/patches/pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch
 delete mode 100644 debian/patches/pve/0051-vma-allow-partial-restore.patch
 delete mode 100644 debian/patches/pve/0052-pbs-namespace-support.patch
 delete mode 100644 debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
 delete mode 100644 debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
 delete mode 100644 debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
 delete mode 100644 debian/patches/pve/0059-vma-create-support-64KiB-unaligned-input-images.patch
 delete mode 100644 debian/patches/pve/0060-vma-create-avoid-triggering-assertion-in-error-case.patch
 delete mode 100644 debian/patches/pve/0061-block-alloc-track-avoid-premature-break.patch
 delete mode 100644 debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
 delete mode 100644 debian/patches/pve/0064-savevm-async-optimize-querying-pending.patch
 delete mode 100644 debian/patches/pve/0065-savevm-async-also-initialize-compression-counters.patch

diff --git a/debian/patches/pve/0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch b/debian/patches/pve/0013-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
similarity index 97%
rename from debian/patches/pve/0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
rename to debian/patches/pve/0013-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
index 7701b55..debfc54 100644
--- a/debian/patches/pve/0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
+++ b/debian/patches/pve/0013-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
@@ -1,9 +1,9 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Fabian Ebner <f.ebner@proxmox.com>
 Date: Mon, 7 Feb 2022 14:21:01 +0100
-Subject: [PATCH] qemu-img: dd: add -l option for loading a snapshot
+Subject: [PATCH] qemu-img dd: add -l option for loading a snapshot
 
-Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
 ---
  docs/tools/qemu-img.rst |  6 +++---
diff --git a/debian/patches/pve/0013-PVE-virtio-balloon-improve-query-balloon.patch b/debian/patches/pve/0014-PVE-virtio-balloon-improve-query-balloon.patch
similarity index 100%
rename from debian/patches/pve/0013-PVE-virtio-balloon-improve-query-balloon.patch
rename to debian/patches/pve/0014-PVE-virtio-balloon-improve-query-balloon.patch
diff --git a/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch b/debian/patches/pve/0015-PVE-qapi-modify-query-machines.patch
similarity index 100%
rename from debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch
rename to debian/patches/pve/0015-PVE-qapi-modify-query-machines.patch
diff --git a/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch b/debian/patches/pve/0016-PVE-qapi-modify-spice-query.patch
similarity index 100%
rename from debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch
rename to debian/patches/pve/0016-PVE-qapi-modify-spice-query.patch
diff --git a/debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch b/debian/patches/pve/0017-PVE-add-IOChannel-implementation-for-savevm-async.patch
similarity index 100%
rename from debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch
rename to debian/patches/pve/0017-PVE-add-IOChannel-implementation-for-savevm-async.patch
diff --git a/debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch b/debian/patches/pve/0018-PVE-add-savevm-async-for-background-state-snapshots.patch
similarity index 96%
rename from debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch
rename to debian/patches/pve/0018-PVE-add-savevm-async-for-background-state-snapshots.patch
index 7c3f2ce..d42d0f0 100644
--- a/debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch
+++ b/debian/patches/pve/0018-PVE-add-savevm-async-for-background-state-snapshots.patch
@@ -21,7 +21,8 @@ still opened by QEMU.
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
 Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
 Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
-[improve aborting]
+[SR: improve aborting
+     register yank before migration_incoming_state_destroy]
 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 [FE: further improve aborting
      adapt to removal of QEMUFileOps
@@ -34,13 +35,13 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
  include/migration/snapshot.h |   2 +
  include/monitor/hmp.h        |   5 +
  migration/meson.build        |   1 +
- migration/savevm-async.c     | 535 +++++++++++++++++++++++++++++++++++
+ migration/savevm-async.c     | 548 +++++++++++++++++++++++++++++++++++
  monitor/hmp-cmds.c           |  58 ++++
  qapi/migration.json          |  34 +++
- qapi/misc.json               |  32 +++
+ qapi/misc.json               |  32 ++
  qemu-options.hx              |  12 +
  softmmu/vl.c                 |  10 +
- 11 files changed, 735 insertions(+)
+ 11 files changed, 748 insertions(+)
  create mode 100644 migration/savevm-async.c
 
 diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
@@ -156,10 +157,10 @@ index 8a142fc7a9..a7824b5266 100644
    'threadinfo.c',
 diff --git a/migration/savevm-async.c b/migration/savevm-async.c
 new file mode 100644
-index 0000000000..24660af014
+index 0000000000..c5db9e9c1e
 --- /dev/null
 +++ b/migration/savevm-async.c
-@@ -0,0 +1,535 @@
+@@ -0,0 +1,548 @@
 +#include "qemu/osdep.h"
 +#include "migration/channel-savevm-async.h"
 +#include "migration/migration.h"
@@ -182,6 +183,7 @@ index 0000000000..24660af014
 +#include "qemu/timer.h"
 +#include "qemu/main-loop.h"
 +#include "qemu/rcu.h"
++#include "qemu/yank.h"
 +
 +/* #define DEBUG_SAVEVM_STATE */
 +
@@ -403,12 +405,19 @@ index 0000000000..24660af014
 +
 +    while (snap_state.state == SAVE_STATE_ACTIVE) {
 +        uint64_t pending_size, pend_precopy, pend_postcopy;
++        uint64_t threshold = 400 * 1000;
 +
-+        /* pending is expected to be called without iothread lock */
++        /*
++         * pending_{estimate,exact} are expected to be called without iothread
++         * lock. Similar to what is done in migration.c, call the exact variant
++         * only once pend_precopy in the estimate is below the threshold.
++         */
 +        qemu_mutex_unlock_iothread();
-+        qemu_savevm_state_pending_exact(&pend_precopy, &pend_postcopy);
++        qemu_savevm_state_pending_estimate(&pend_precopy, &pend_postcopy);
++        if (pend_precopy <= threshold) {
++            qemu_savevm_state_pending_exact(&pend_precopy, &pend_postcopy);
++        }
 +        qemu_mutex_lock_iothread();
-+
 +        pending_size = pend_precopy + pend_postcopy;
 +
 +        /*
@@ -420,7 +429,7 @@ index 0000000000..24660af014
 +        maxlen = blk_getlength(snap_state.target) - 100*1024*1024;
 +
 +        /* Note that there is no progress for pend_postcopy when iterating */
-+        if (pending_size - pend_postcopy > 400000 && snap_state.bs_pos + pending_size < maxlen) {
++        if (pend_precopy > threshold && snap_state.bs_pos + pending_size < maxlen) {
 +            ret = qemu_savevm_state_iterate(snap_state.file, false);
 +            if (ret < 0) {
 +                save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
@@ -548,6 +557,7 @@ index 0000000000..24660af014
 +     */
 +    migrate_init(ms);
 +    memset(&ram_counters, 0, sizeof(ram_counters));
++    memset(&compression_counters, 0, sizeof(compression_counters));
 +    ms->to_dst_file = snap_state.file;
 +
 +    error_setg(&snap_state.blocker, "block device is in use by savevm");
@@ -679,6 +689,10 @@ index 0000000000..24660af014
 +    dirty_bitmap_mig_before_vm_start();
 +
 +    qemu_fclose(f);
++
++    /* state_destroy assumes a real migration which would have added a yank */
++    yank_register_instance(MIGRATION_YANK_INSTANCE, &error_abort);
++
 +    migration_incoming_state_destroy();
 +    if (ret < 0) {
 +        error_setg_errno(errp, -ret, "Error while loading VM state");
diff --git a/debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch b/debian/patches/pve/0019-PVE-add-optional-buffer-size-to-QEMUFile.patch
similarity index 97%
rename from debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch
rename to debian/patches/pve/0019-PVE-add-optional-buffer-size-to-QEMUFile.patch
index e638f0e..cd7b508 100644
--- a/debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch
+++ b/debian/patches/pve/0019-PVE-add-optional-buffer-size-to-QEMUFile.patch
@@ -192,10 +192,10 @@ index 9d0155a2a1..cc06240e8d 100644
  int qemu_fclose(QEMUFile *f);
  
 diff --git a/migration/savevm-async.c b/migration/savevm-async.c
-index 24660af014..70273a2996 100644
+index c5db9e9c1e..effe6d1e0d 100644
 --- a/migration/savevm-async.c
 +++ b/migration/savevm-async.c
-@@ -372,7 +372,7 @@ void qmp_savevm_start(const char *statefile, Error **errp)
+@@ -380,7 +380,7 @@ void qmp_savevm_start(const char *statefile, Error **errp)
  
      QIOChannel *ioc = QIO_CHANNEL(qio_channel_savevm_async_new(snap_state.target,
                                                                 &snap_state.bs_pos));
@@ -204,7 +204,7 @@ index 24660af014..70273a2996 100644
  
      if (!snap_state.file) {
          error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile);
-@@ -504,7 +504,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
+@@ -513,7 +513,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
      blk_op_block_all(be, blocker);
  
      /* restore the VM state */
diff --git a/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch b/debian/patches/pve/0020-PVE-block-add-the-zeroinit-block-driver-filter.patch
similarity index 100%
rename from debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
rename to debian/patches/pve/0020-PVE-block-add-the-zeroinit-block-driver-filter.patch
diff --git a/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch b/debian/patches/pve/0021-PVE-Add-dummy-id-command-line-parameter.patch
similarity index 100%
rename from debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch
rename to debian/patches/pve/0021-PVE-Add-dummy-id-command-line-parameter.patch
diff --git a/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch b/debian/patches/pve/0022-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
similarity index 100%
rename from debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
rename to debian/patches/pve/0022-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
diff --git a/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch b/debian/patches/pve/0023-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
similarity index 100%
rename from debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
rename to debian/patches/pve/0023-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
diff --git a/debian/patches/pve/0023-PVE-monitor-disable-oob-capability.patch b/debian/patches/pve/0024-PVE-monitor-disable-oob-capability.patch
similarity index 100%
rename from debian/patches/pve/0023-PVE-monitor-disable-oob-capability.patch
rename to debian/patches/pve/0024-PVE-monitor-disable-oob-capability.patch
diff --git a/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch b/debian/patches/pve/0025-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
similarity index 100%
rename from debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
rename to debian/patches/pve/0025-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
diff --git a/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch b/debian/patches/pve/0026-PVE-Allow-version-code-in-machine-type.patch
similarity index 100%
rename from debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch
rename to debian/patches/pve/0026-PVE-Allow-version-code-in-machine-type.patch
diff --git a/debian/patches/pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch b/debian/patches/pve/0027-block-backup-move-bcs-bitmap-initialization-to-job-c.patch
similarity index 100%
rename from debian/patches/pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch
rename to debian/patches/pve/0027-block-backup-move-bcs-bitmap-initialization-to-job-c.patch
diff --git a/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch b/debian/patches/pve/0028-PVE-Backup-add-vma-backup-format-code.patch
similarity index 91%
rename from debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch
rename to debian/patches/pve/0028-PVE-Backup-add-vma-backup-format-code.patch
index fd0c8e6..6a343c2 100644
--- a/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch
+++ b/debian/patches/pve/0028-PVE-Backup-add-vma-backup-format-code.patch
@@ -3,17 +3,23 @@ From: Dietmar Maurer <dietmar@proxmox.com>
 Date: Mon, 6 Apr 2020 12:16:57 +0200
 Subject: [PATCH] PVE-Backup: add vma backup format code
 
+Notes about partial restoring: skipping a certain drive is done via a
+map line of the form skip=drive-scsi0. Since in PVE, most archives are
+compressed and piped to vma for restore, it's not easily possible to
+skip reads.
+
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: create: register all streams before entering coroutines]
-Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
+[FE: improvements during create
+     allow partial restore]
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/meson.build |   2 +
  meson.build       |   5 +
- vma-reader.c      | 859 ++++++++++++++++++++++++++++++++++++++++++++++
- vma-writer.c      | 791 ++++++++++++++++++++++++++++++++++++++++++
- vma.c             | 849 +++++++++++++++++++++++++++++++++++++++++++++
+ vma-reader.c      | 867 +++++++++++++++++++++++++++++++++++++++++++++
+ vma-writer.c      | 793 +++++++++++++++++++++++++++++++++++++++++
+ vma.c             | 878 ++++++++++++++++++++++++++++++++++++++++++++++
  vma.h             | 150 ++++++++
- 6 files changed, 2656 insertions(+)
+ 6 files changed, 2695 insertions(+)
  create mode 100644 vma-reader.c
  create mode 100644 vma-writer.c
  create mode 100644 vma.c
@@ -57,10 +63,10 @@ index d964e741e7..603cdb97bb 100644
    subdir('contrib/elf2dmp')
 diff --git a/vma-reader.c b/vma-reader.c
 new file mode 100644
-index 0000000000..e65f1e8415
+index 0000000000..81a891c6b1
 --- /dev/null
 +++ b/vma-reader.c
-@@ -0,0 +1,859 @@
+@@ -0,0 +1,867 @@
 +/*
 + * VMA: Virtual Machine Archive
 + *
@@ -91,6 +97,7 @@ index 0000000000..e65f1e8415
 +    bool write_zeroes;
 +    unsigned long *bitmap;
 +    int bitmap_size;
++    bool skip;
 +}  VmaRestoreState;
 +
 +struct VmaReader {
@@ -488,13 +495,14 @@ index 0000000000..e65f1e8415
 +}
 +
 +static void allocate_rstate(VmaReader *vmar,  guint8 dev_id,
-+                            BlockBackend *target, bool write_zeroes)
++                            BlockBackend *target, bool write_zeroes, bool skip)
 +{
 +    assert(vmar);
 +    assert(dev_id);
 +
 +    vmar->rstate[dev_id].target = target;
 +    vmar->rstate[dev_id].write_zeroes = write_zeroes;
++    vmar->rstate[dev_id].skip = skip;
 +
 +    int64_t size = vmar->devinfo[dev_id].size;
 +
@@ -509,28 +517,30 @@ index 0000000000..e65f1e8415
 +}
 +
 +int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id, BlockBackend *target,
-+                           bool write_zeroes, Error **errp)
++                           bool write_zeroes, bool skip, Error **errp)
 +{
 +    assert(vmar);
-+    assert(target != NULL);
++    assert(target != NULL || skip);
 +    assert(dev_id);
-+    assert(vmar->rstate[dev_id].target == NULL);
-+
-+    int64_t size = blk_getlength(target);
-+    int64_t size_diff = size - vmar->devinfo[dev_id].size;
++    assert(vmar->rstate[dev_id].target == NULL && !vmar->rstate[dev_id].skip);
 +
-+    /* storage types can have different size restrictions, so it
-+     * is not always possible to create an image with exact size.
-+     * So we tolerate a size difference up to 4MB.
-+     */
-+    if ((size_diff < 0) || (size_diff > 4*1024*1024)) {
-+        error_setg(errp, "vma_reader_register_bs for stream %s failed - "
-+                   "unexpected size %zd != %zd", vmar->devinfo[dev_id].devname,
-+                   size, vmar->devinfo[dev_id].size);
-+        return -1;
++    if (target != NULL) {
++        int64_t size = blk_getlength(target);
++        int64_t size_diff = size - vmar->devinfo[dev_id].size;
++
++        /* storage types can have different size restrictions, so it
++         * is not always possible to create an image with exact size.
++         * So we tolerate a size difference up to 4MB.
++         */
++        if ((size_diff < 0) || (size_diff > 4*1024*1024)) {
++            error_setg(errp, "vma_reader_register_bs for stream %s failed - "
++                       "unexpected size %zd != %zd", vmar->devinfo[dev_id].devname,
++                       size, vmar->devinfo[dev_id].size);
++            return -1;
++        }
 +    }
 +
-+    allocate_rstate(vmar, dev_id, target, write_zeroes);
++    allocate_rstate(vmar, dev_id, target, write_zeroes, skip);
 +
 +    return 0;
 +}
@@ -623,19 +633,23 @@ index 0000000000..e65f1e8415
 +        VmaRestoreState *rstate = &vmar->rstate[dev_id];
 +        BlockBackend *target = NULL;
 +
++        bool skip = rstate->skip;
++
 +        if (dev_id != vmar->vmstate_stream) {
 +            target = rstate->target;
-+            if (!verify && !target) {
++            if (!verify && !target && !skip) {
 +                error_setg(errp, "got wrong dev id %d", dev_id);
 +                return -1;
 +            }
 +
-+            if (vma_reader_get_bitmap(rstate, cluster_num)) {
-+                error_setg(errp, "found duplicated cluster %zd for stream %s",
-+                          cluster_num, vmar->devinfo[dev_id].devname);
-+                return -1;
++            if (!skip) {
++                if (vma_reader_get_bitmap(rstate, cluster_num)) {
++                    error_setg(errp, "found duplicated cluster %zd for stream %s",
++                              cluster_num, vmar->devinfo[dev_id].devname);
++                    return -1;
++                }
++                vma_reader_set_bitmap(rstate, cluster_num, 1);
 +            }
-+            vma_reader_set_bitmap(rstate, cluster_num, 1);
 +
 +            max_sector = vmar->devinfo[dev_id].size/BDRV_SECTOR_SIZE;
 +        } else {
@@ -681,7 +695,7 @@ index 0000000000..e65f1e8415
 +                return -1;
 +            }
 +
-+            if (!verify) {
++            if (!verify && !skip) {
 +                int nb_sectors = end_sector - sector_num;
 +                if (restore_write_data(vmar, dev_id, target, vmstate_fd,
 +                                       buf + start, sector_num, nb_sectors,
@@ -717,7 +731,7 @@ index 0000000000..e65f1e8415
 +                        return -1;
 +                    }
 +
-+                    if (!verify) {
++                    if (!verify && !skip) {
 +                        int nb_sectors = end_sector - sector_num;
 +                        if (restore_write_data(vmar, dev_id, target, vmstate_fd,
 +                                               buf + start, sector_num,
@@ -742,7 +756,7 @@ index 0000000000..e65f1e8415
 +                            vmar->partial_zero_cluster_data += zero_size;
 +                        }
 +
-+                        if (rstate->write_zeroes && !verify) {
++                        if (rstate->write_zeroes && !verify && !skip) {
 +                            if (restore_write_data(vmar, dev_id, target, vmstate_fd,
 +                                                   zero_vma_block, sector_num,
 +                                                   nb_sectors, errp) < 0) {
@@ -913,7 +927,7 @@ index 0000000000..e65f1e8415
 +
 +    for (dev_id = 1; dev_id < 255; dev_id++) {
 +        if (vma_reader_get_device_info(vmar, dev_id)) {
-+            allocate_rstate(vmar, dev_id, NULL, false);
++            allocate_rstate(vmar, dev_id, NULL, false, false);
 +        }
 +    }
 +
@@ -922,10 +936,10 @@ index 0000000000..e65f1e8415
 +
 diff --git a/vma-writer.c b/vma-writer.c
 new file mode 100644
-index 0000000000..df4b20793d
+index 0000000000..ac7da237d0
 --- /dev/null
 +++ b/vma-writer.c
-@@ -0,0 +1,791 @@
+@@ -0,0 +1,793 @@
 +/*
 + * VMA: Virtual Machine Archive
 + *
@@ -1239,6 +1253,8 @@ index 0000000000..df4b20793d
 +        }
 +
 +        if (vmaw->fd < 0) {
++            error_free(*errp);
++            *errp = NULL;
 +            error_setg(errp, "can't open file %s - %s\n", filename,
 +                       g_strerror(errno));
 +            goto err;
@@ -1719,10 +1735,10 @@ index 0000000000..df4b20793d
 +}
 diff --git a/vma.c b/vma.c
 new file mode 100644
-index 0000000000..e8dffb43e0
+index 0000000000..304f02bc84
 --- /dev/null
 +++ b/vma.c
-@@ -0,0 +1,849 @@
+@@ -0,0 +1,878 @@
 +/*
 + * VMA: Virtual Machine Archive
 + *
@@ -1863,6 +1879,7 @@ index 0000000000..e8dffb43e0
 +    char *throttling_group;
 +    char *cache;
 +    bool write_zero;
++    bool skip;
 +} RestoreMap;
 +
 +static bool try_parse_option(char **line, const char *optname, char **out, const char *inbuf) {
@@ -1970,47 +1987,61 @@ index 0000000000..e8dffb43e0
 +            char *bps = NULL;
 +            char *group = NULL;
 +            char *cache = NULL;
++            char *devname = NULL;
++            bool skip = false;
++            uint64_t bps_value = 0;
++            const char *path = NULL;
++            bool write_zero = true;
++
 +            if (!line || line[0] == '\0' || !strcmp(line, "done\n")) {
 +                break;
 +            }
 +            int len = strlen(line);
 +            if (line[len - 1] == '\n') {
 +                line[len - 1] = '\0';
-+                if (len == 1) {
++                len = len - 1;
++                if (len == 0) {
 +                    break;
 +                }
 +            }
 +
-+            while (1) {
-+                if (!try_parse_option(&line, "format", &format, inbuf) &&
-+                    !try_parse_option(&line, "throttling.bps", &bps, inbuf) &&
-+                    !try_parse_option(&line, "throttling.group", &group, inbuf) &&
-+                    !try_parse_option(&line, "cache", &cache, inbuf))
-+                {
-+                    break;
++            if (strncmp(line, "skip", 4) == 0) {
++                if (len < 6 || line[4] != '=') {
++                    g_error("read map failed - option 'skip' has no value ('%s')",
++                            inbuf);
++                } else {
++                    devname = line + 5;
++                    skip = true;
++                }
++            } else {
++                while (1) {
++                    if (!try_parse_option(&line, "format", &format, inbuf) &&
++                        !try_parse_option(&line, "throttling.bps", &bps, inbuf) &&
++                        !try_parse_option(&line, "throttling.group", &group, inbuf) &&
++                        !try_parse_option(&line, "cache", &cache, inbuf))
++                    {
++                        break;
++                    }
 +                }
-+            }
 +
-+            uint64_t bps_value = 0;
-+            if (bps) {
-+                bps_value = verify_u64(bps);
-+                g_free(bps);
-+            }
++                if (bps) {
++                    bps_value = verify_u64(bps);
++                    g_free(bps);
++                }
 +
-+            const char *path;
-+            bool write_zero;
-+            if (line[0] == '0' && line[1] == ':') {
-+                path = line + 2;
-+                write_zero = false;
-+            } else if (line[0] == '1' && line[1] == ':') {
-+                path = line + 2;
-+                write_zero = true;
-+            } else {
-+                g_error("read map failed - parse error ('%s')", inbuf);
++                if (line[0] == '0' && line[1] == ':') {
++                    path = line + 2;
++                    write_zero = false;
++                } else if (line[0] == '1' && line[1] == ':') {
++                    path = line + 2;
++                    write_zero = true;
++                } else {
++                    g_error("read map failed - parse error ('%s')", inbuf);
++                }
++
++                path = extract_devname(path, &devname, -1);
 +            }
 +
-+            char *devname = NULL;
-+            path = extract_devname(path, &devname, -1);
 +            if (!devname) {
 +                g_error("read map failed - no dev name specified ('%s')",
 +                        inbuf);
@@ -2024,6 +2055,7 @@ index 0000000000..e8dffb43e0
 +            map->throttling_group = group;
 +            map->cache = cache;
 +            map->write_zero = write_zero;
++            map->skip = skip;
 +
 +            g_hash_table_insert(devmap, map->devname, map);
 +
@@ -2053,6 +2085,7 @@ index 0000000000..e8dffb43e0
 +            const char *cache = NULL;
 +            int flags = BDRV_O_RDWR;
 +            bool write_zero = true;
++            bool skip = false;
 +
 +            BlockBackend *blk = NULL;
 +
@@ -2068,6 +2101,7 @@ index 0000000000..e8dffb43e0
 +                throttling_group = map->throttling_group;
 +                cache = map->cache;
 +                write_zero = map->write_zero;
++                skip = map->skip;
 +            } else {
 +                devfn = g_strdup_printf("%s/tmp-disk-%s.raw",
 +                                        dirname, di->devname);
@@ -2086,57 +2120,60 @@ index 0000000000..e8dffb43e0
 +                write_zero = false;
 +            }
 +
-+	    size_t devlen = strlen(devfn);
-+	    QDict *options = NULL;
-+            bool writethrough;
-+            if (format) {
-+                /* explicit format from commandline */
-+                options = qdict_new();
-+                qdict_put_str(options, "driver", format);
-+            } else if ((devlen > 4 && strcmp(devfn+devlen-4, ".raw") == 0) ||
-+	               strncmp(devfn, "/dev/", 5) == 0)
-+	    {
-+                /* This part is now deprecated for PVE as well (just as qemu
-+                 * deprecated not specifying an explicit raw format, too.
-+                 */
-+		/* explicit raw format */
-+		options = qdict_new();
-+		qdict_put_str(options, "driver", "raw");
-+	    }
-+            if (cache && bdrv_parse_cache_mode(cache, &flags, &writethrough)) {
-+                g_error("invalid cache option: %s\n", cache);
-+            }
++            if (!skip) {
++                size_t devlen = strlen(devfn);
++                QDict *options = NULL;
++                bool writethrough;
++                if (format) {
++                    /* explicit format from commandline */
++                    options = qdict_new();
++                    qdict_put_str(options, "driver", format);
++                } else if ((devlen > 4 && strcmp(devfn+devlen-4, ".raw") == 0) ||
++                    strncmp(devfn, "/dev/", 5) == 0)
++                {
++                    /* This part is now deprecated for PVE as well (just as qemu
++                     * deprecated not specifying an explicit raw format, too.
++                     */
++                    /* explicit raw format */
++                    options = qdict_new();
++                    qdict_put_str(options, "driver", "raw");
++                }
 +
-+	    if (errp || !(blk = blk_new_open(devfn, NULL, options, flags, &errp))) {
-+                g_error("can't open file %s - %s", devfn,
-+                        error_get_pretty(errp));
-+            }
++                if (cache && bdrv_parse_cache_mode(cache, &flags, &writethrough)) {
++                    g_error("invalid cache option: %s\n", cache);
++                }
 +
-+            if (cache) {
-+                blk_set_enable_write_cache(blk, !writethrough);
-+            }
++                if (errp || !(blk = blk_new_open(devfn, NULL, options, flags, &errp))) {
++                    g_error("can't open file %s - %s", devfn,
++                            error_get_pretty(errp));
++                }
 +
-+            if (throttling_group) {
-+                blk_io_limits_enable(blk, throttling_group);
-+            }
++                if (cache) {
++                    blk_set_enable_write_cache(blk, !writethrough);
++                }
 +
-+            if (throttling_bps) {
-+                if (!throttling_group) {
-+                    blk_io_limits_enable(blk, devfn);
++                if (throttling_group) {
++                    blk_io_limits_enable(blk, throttling_group);
 +                }
 +
-+                ThrottleConfig cfg;
-+                throttle_config_init(&cfg);
-+                cfg.buckets[THROTTLE_BPS_WRITE].avg = throttling_bps;
-+                Error *err = NULL;
-+                if (!throttle_is_valid(&cfg, &err)) {
-+                    error_report_err(err);
-+                    g_error("failed to apply throttling");
++                if (throttling_bps) {
++                    if (!throttling_group) {
++                        blk_io_limits_enable(blk, devfn);
++                    }
++
++                    ThrottleConfig cfg;
++                    throttle_config_init(&cfg);
++                    cfg.buckets[THROTTLE_BPS_WRITE].avg = throttling_bps;
++                    Error *err = NULL;
++                    if (!throttle_is_valid(&cfg, &err)) {
++                        error_report_err(err);
++                        g_error("failed to apply throttling");
++                    }
++                    blk_set_io_limits(blk, &cfg);
 +                }
-+                blk_set_io_limits(blk, &cfg);
 +            }
 +
-+            if (vma_reader_register_bs(vmar, i, blk, write_zero, &errp) < 0) {
++            if (vma_reader_register_bs(vmar, i, blk, write_zero, skip, &errp) < 0) {
 +                g_error("%s", error_get_pretty(errp));
 +            }
 +
@@ -2252,7 +2289,7 @@ index 0000000000..e8dffb43e0
 +    struct iovec iov;
 +    QEMUIOVector qiov;
 +
-+    int64_t start, end;
++    int64_t start, end, readlen;
 +    int ret = 0;
 +
 +    unsigned char *buf = blk_blockalign(job->target, VMA_CLUSTER_SIZE);
@@ -2266,8 +2303,16 @@ index 0000000000..e8dffb43e0
 +        iov.iov_len = VMA_CLUSTER_SIZE;
 +        qemu_iovec_init_external(&qiov, &iov, 1);
 +
++        if (start + 1 == end) {
++            memset(buf, 0, VMA_CLUSTER_SIZE);
++            readlen = job->len - start * VMA_CLUSTER_SIZE;
++            assert(readlen > 0 && readlen <= VMA_CLUSTER_SIZE);
++        } else {
++            readlen = VMA_CLUSTER_SIZE;
++        }
++
 +        ret = blk_co_preadv(job->target, start * VMA_CLUSTER_SIZE,
-+                            VMA_CLUSTER_SIZE, &qiov, 0);
++                            readlen, &qiov, 0);
 +        if (ret < 0) {
 +            vma_writer_set_error(job->vmaw, "read error", -1);
 +            goto out;
@@ -2574,7 +2619,7 @@ index 0000000000..e8dffb43e0
 +}
 diff --git a/vma.h b/vma.h
 new file mode 100644
-index 0000000000..c895c97f6d
+index 0000000000..1b62859165
 --- /dev/null
 +++ b/vma.h
 @@ -0,0 +1,150 @@
@@ -2722,7 +2767,7 @@ index 0000000000..c895c97f6d
 +VmaDeviceInfo *vma_reader_get_device_info(VmaReader *vmar, guint8 dev_id);
 +int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id,
 +                           BlockBackend *target, bool write_zeroes,
-+                           Error **errp);
++                           bool skip, Error **errp);
 +int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
 +                       Error **errp);
 +int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp);
diff --git a/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch b/debian/patches/pve/0029-PVE-Backup-add-backup-dump-block-driver.patch
similarity index 100%
rename from debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
rename to debian/patches/pve/0029-PVE-Backup-add-backup-dump-block-driver.patch
diff --git a/debian/patches/pve/0037-PVE-Add-sequential-job-transaction-support.patch b/debian/patches/pve/0030-PVE-Add-sequential-job-transaction-support.patch
similarity index 100%
rename from debian/patches/pve/0037-PVE-Add-sequential-job-transaction-support.patch
rename to debian/patches/pve/0030-PVE-Add-sequential-job-transaction-support.patch
diff --git a/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch b/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
deleted file mode 100644
index 1708021..0000000
--- a/debian/patches/pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
+++ /dev/null
@@ -1,460 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter@proxmox.com>
-Date: Mon, 29 Jun 2020 11:06:03 +0200
-Subject: [PATCH] PVE-Backup: Add dirty-bitmap tracking for incremental backups
-
-Uses QEMU's existing MIRROR_SYNC_MODE_BITMAP and a dirty-bitmap on top
-of all backed-up drives. This will only execute the data-write callback
-for any changed chunks, the PBS rust code will reuse chunks from the
-previous index for everything it doesn't receive if reuse_index is true.
-
-On error or cancellation, remove all dirty bitmaps to ensure
-consistency.
-
-Add PBS/incremental specific information to query backup info QMP and
-HMP commands.
-
-Only supported for PBS backups.
-
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
----
- block/monitor/block-hmp-cmds.c |   1 +
- monitor/hmp-cmds.c             |  45 ++++++++++----
- proxmox-backup-client.c        |   3 +-
- proxmox-backup-client.h        |   1 +
- pve-backup.c                   | 104 ++++++++++++++++++++++++++++++---
- qapi/block-core.json           |  12 +++-
- 6 files changed, 143 insertions(+), 23 deletions(-)
-
-diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index d50e99df26..cda5de792b 100644
---- a/block/monitor/block-hmp-cmds.c
-+++ b/block/monitor/block-hmp-cmds.c
-@@ -1056,6 +1056,7 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
-         NULL, // PBS fingerprint
-         NULL, // PBS backup-id
-         false, 0, // PBS backup-time
-+        false, false, // PBS incremental
-         true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
-         NULL, NULL,
-         devlist, qdict_haskey(qdict, "speed"), speed, &error);
-diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 9e1bd57aeb..087161a967 100644
---- a/monitor/hmp-cmds.c
-+++ b/monitor/hmp-cmds.c
-@@ -171,19 +171,42 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
-             monitor_printf(mon, "End time: %s", ctime(&info->end_time));
-         }
- 
--        int per = (info->has_total && info->total &&
--            info->has_transferred && info->transferred) ?
--            (info->transferred * 100)/info->total : 0;
--        int zero_per = (info->has_total && info->total &&
--                        info->has_zero_bytes && info->zero_bytes) ?
--            (info->zero_bytes * 100)/info->total : 0;
-         monitor_printf(mon, "Backup file: %s\n", info->backup_file);
-         monitor_printf(mon, "Backup uuid: %s\n", info->uuid);
--        monitor_printf(mon, "Total size: %zd\n", info->total);
--        monitor_printf(mon, "Transferred bytes: %zd (%d%%)\n",
--                       info->transferred, per);
--        monitor_printf(mon, "Zero bytes: %zd (%d%%)\n",
--                       info->zero_bytes, zero_per);
-+
-+        if (!(info->has_total && info->total))  {
-+            // this should not happen normally
-+            monitor_printf(mon, "Total size: %d\n", 0);
-+        } else {
-+            bool incremental = false;
-+            size_t total_or_dirty = info->total;
-+            if (info->has_transferred) {
-+                if (info->has_dirty && info->dirty) {
-+                     if (info->dirty < info->total) {
-+                        total_or_dirty = info->dirty;
-+                        incremental = true;
-+                    }
-+                }
-+            }
-+
-+            int per = (info->transferred * 100)/total_or_dirty;
-+
-+            monitor_printf(mon, "Backup mode: %s\n", incremental ? "incremental" : "full");
-+
-+            int zero_per = (info->has_zero_bytes && info->zero_bytes) ?
-+                (info->zero_bytes * 100)/info->total : 0;
-+            monitor_printf(mon, "Total size: %zd\n", info->total);
-+            monitor_printf(mon, "Transferred bytes: %zd (%d%%)\n",
-+                           info->transferred, per);
-+            monitor_printf(mon, "Zero bytes: %zd (%d%%)\n",
-+                           info->zero_bytes, zero_per);
-+
-+            if (info->has_reused) {
-+                int reused_per = (info->reused * 100)/total_or_dirty;
-+                monitor_printf(mon, "Reused bytes: %zd (%d%%)\n",
-+                               info->reused, reused_per);
-+            }
-+        }
-     }
- 
-     qapi_free_BackupStatus(info);
-diff --git a/proxmox-backup-client.c b/proxmox-backup-client.c
-index a8f6653a81..4ce7bc0b5e 100644
---- a/proxmox-backup-client.c
-+++ b/proxmox-backup-client.c
-@@ -89,6 +89,7 @@ proxmox_backup_co_register_image(
-     ProxmoxBackupHandle *pbs,
-     const char *device_name,
-     uint64_t size,
-+    bool incremental,
-     Error **errp)
- {
-     Coroutine *co = qemu_coroutine_self();
-@@ -98,7 +99,7 @@ proxmox_backup_co_register_image(
-     int pbs_res = -1;
- 
-     proxmox_backup_register_image_async(
--        pbs, device_name, size ,proxmox_backup_schedule_wake, &waker, &pbs_res, &pbs_err);
-+        pbs, device_name, size, incremental, proxmox_backup_schedule_wake, &waker, &pbs_res, &pbs_err);
-     qemu_coroutine_yield();
-     if (pbs_res < 0) {
-         if (errp) error_setg(errp, "backup register image failed: %s", pbs_err ? pbs_err : "unknown error");
-diff --git a/proxmox-backup-client.h b/proxmox-backup-client.h
-index 1dda8b7d8f..8cbf645b2c 100644
---- a/proxmox-backup-client.h
-+++ b/proxmox-backup-client.h
-@@ -32,6 +32,7 @@ proxmox_backup_co_register_image(
-     ProxmoxBackupHandle *pbs,
-     const char *device_name,
-     uint64_t size,
-+    bool incremental,
-     Error **errp);
- 
- 
-diff --git a/pve-backup.c b/pve-backup.c
-index f77892a509..d9942a14a1 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -7,6 +7,7 @@
- #include "sysemu/blockdev.h"
- #include "block/block_int-global-state.h"
- #include "block/blockjob.h"
-+#include "block/dirty-bitmap.h"
- #include "qapi/qapi-commands-block.h"
- #include "qapi/qmp/qerror.h"
- 
-@@ -29,6 +30,8 @@
-  *
-  */
- 
-+const char *PBS_BITMAP_NAME = "pbs-incremental-dirty-bitmap";
-+
- static struct PVEBackupState {
-     struct {
-         // Everithing accessed from qmp_backup_query command is protected using lock
-@@ -40,7 +43,9 @@ static struct PVEBackupState {
-         uuid_t uuid;
-         char uuid_str[37];
-         size_t total;
-+        size_t dirty;
-         size_t transferred;
-+        size_t reused;
-         size_t zero_bytes;
-     } stat;
-     int64_t speed;
-@@ -67,6 +72,7 @@ typedef struct PVEBackupDevInfo {
-     uint8_t dev_id;
-     bool completed;
-     char targetfile[PATH_MAX];
-+    BdrvDirtyBitmap *bitmap;
-     BlockDriverState *target;
- } PVEBackupDevInfo;
- 
-@@ -108,11 +114,12 @@ static bool pvebackup_error_or_canceled(void)
-     return error_or_canceled;
- }
- 
--static void pvebackup_add_transfered_bytes(size_t transferred, size_t zero_bytes)
-+static void pvebackup_add_transfered_bytes(size_t transferred, size_t zero_bytes, size_t reused)
- {
-     qemu_mutex_lock(&backup_state.stat.lock);
-     backup_state.stat.zero_bytes += zero_bytes;
-     backup_state.stat.transferred += transferred;
-+    backup_state.stat.reused += reused;
-     qemu_mutex_unlock(&backup_state.stat.lock);
- }
- 
-@@ -151,7 +158,8 @@ pvebackup_co_dump_pbs_cb(
-         pvebackup_propagate_error(local_err);
-         return pbs_res;
-     } else {
--        pvebackup_add_transfered_bytes(size, !buf ? size : 0);
-+        size_t reused = (pbs_res == 0) ? size : 0;
-+        pvebackup_add_transfered_bytes(size, !buf ? size : 0, reused);
-     }
- 
-     return size;
-@@ -211,11 +219,11 @@ pvebackup_co_dump_vma_cb(
-         } else {
-             if (remaining >= VMA_CLUSTER_SIZE) {
-                 assert(ret == VMA_CLUSTER_SIZE);
--                pvebackup_add_transfered_bytes(VMA_CLUSTER_SIZE, zero_bytes);
-+                pvebackup_add_transfered_bytes(VMA_CLUSTER_SIZE, zero_bytes, 0);
-                 remaining -= VMA_CLUSTER_SIZE;
-             } else {
-                 assert(ret == remaining);
--                pvebackup_add_transfered_bytes(remaining, zero_bytes);
-+                pvebackup_add_transfered_bytes(remaining, zero_bytes, 0);
-                 remaining = 0;
-             }
-         }
-@@ -251,6 +259,18 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
-             if (local_err != NULL) {
-                 pvebackup_propagate_error(local_err);
-             }
-+        } else {
-+            // on error or cancel we cannot ensure synchronization of dirty
-+            // bitmaps with backup server, so remove all and do full backup next
-+            GList *l = backup_state.di_list;
-+            while (l) {
-+                PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-+                l = g_list_next(l);
-+
-+                if (di->bitmap) {
-+                    bdrv_release_dirty_bitmap(di->bitmap);
-+                }
-+            }
-         }
- 
-         proxmox_backup_disconnect(backup_state.pbs);
-@@ -306,6 +326,12 @@ static void pvebackup_complete_cb(void *opaque, int ret)
-     // remove self from job queue
-     backup_state.di_list = g_list_remove(backup_state.di_list, di);
- 
-+    if (di->bitmap && ret < 0) {
-+        // on error or cancel we cannot ensure synchronization of dirty
-+        // bitmaps with backup server, so remove all and do full backup next
-+        bdrv_release_dirty_bitmap(di->bitmap);
-+    }
-+
-     g_free(di);
- 
-     qemu_mutex_unlock(&backup_state.backup_mutex);
-@@ -470,12 +496,18 @@ static bool create_backup_jobs(void) {
- 
-         assert(di->target != NULL);
- 
-+        MirrorSyncMode sync_mode = MIRROR_SYNC_MODE_FULL;
-+        BitmapSyncMode bitmap_mode = BITMAP_SYNC_MODE_NEVER;
-+        if (di->bitmap) {
-+            sync_mode = MIRROR_SYNC_MODE_BITMAP;
-+            bitmap_mode = BITMAP_SYNC_MODE_ON_SUCCESS;
-+        }
-         AioContext *aio_context = bdrv_get_aio_context(di->bs);
-         aio_context_acquire(aio_context);
- 
-         BlockJob *job = backup_job_create(
--            NULL, di->bs, di->target, backup_state.speed, MIRROR_SYNC_MODE_FULL, NULL,
--            BITMAP_SYNC_MODE_NEVER, false, NULL, &perf, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
-+            NULL, di->bs, di->target, backup_state.speed, sync_mode, di->bitmap,
-+            bitmap_mode, false, NULL, &perf, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
-             JOB_DEFAULT, pvebackup_complete_cb, di, NULL, &local_err);
- 
-         aio_context_release(aio_context);
-@@ -521,6 +553,8 @@ typedef struct QmpBackupTask {
-     bool has_backup_time;
-     const char *fingerprint;
-     int64_t backup_time;
-+    bool has_use_dirty_bitmap;
-+    bool use_dirty_bitmap;
-     bool has_format;
-     BackupFormat format;
-     const char *config_file;
-@@ -609,6 +643,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     }
- 
-     size_t total = 0;
-+    size_t dirty = 0;
- 
-     l = di_list;
-     while (l) {
-@@ -646,6 +681,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-         int dump_cb_block_size = PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE; // Hardcoded (4M)
-         firewall_name = "fw.conf";
- 
-+        bool use_dirty_bitmap = task->has_use_dirty_bitmap && task->use_dirty_bitmap;
-+
-         char *pbs_err = NULL;
-         pbs = proxmox_backup_new(
-             task->backup_file,
-@@ -665,7 +702,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             goto err;
-         }
- 
--        if (proxmox_backup_co_connect(pbs, task->errp) < 0)
-+        int connect_result = proxmox_backup_co_connect(pbs, task->errp);
-+        if (connect_result < 0)
-             goto err;
- 
-         /* register all devices */
-@@ -676,9 +714,40 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
- 
-             const char *devname = bdrv_get_device_name(di->bs);
- 
--            int dev_id = proxmox_backup_co_register_image(pbs, devname, di->size, task->errp);
--            if (dev_id < 0)
-+            BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
-+            bool expect_only_dirty = false;
-+
-+            if (use_dirty_bitmap) {
-+                if (bitmap == NULL) {
-+                    bitmap = bdrv_create_dirty_bitmap(di->bs, dump_cb_block_size, PBS_BITMAP_NAME, task->errp);
-+                    if (!bitmap) {
-+                        goto err;
-+                    }
-+                } else {
-+                    expect_only_dirty = proxmox_backup_check_incremental(pbs, devname, di->size) != 0;
-+                }
-+
-+                if (expect_only_dirty) {
-+                    dirty += bdrv_get_dirty_count(bitmap);
-+                } else {
-+                    /* mark entire bitmap as dirty to make full backup */
-+                    bdrv_set_dirty_bitmap(bitmap, 0, di->size);
-+                    dirty += di->size;
-+                }
-+                di->bitmap = bitmap;
-+            } else {
-+                dirty += di->size;
-+
-+                /* after a full backup the old dirty bitmap is invalid anyway */
-+                if (bitmap != NULL) {
-+                    bdrv_release_dirty_bitmap(bitmap);
-+                }
-+            }
-+
-+            int dev_id = proxmox_backup_co_register_image(pbs, devname, di->size, expect_only_dirty, task->errp);
-+            if (dev_id < 0) {
-                 goto err;
-+            }
- 
-             if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, task->errp))) {
-                 goto err;
-@@ -687,6 +756,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             di->dev_id = dev_id;
-         }
-     } else if (format == BACKUP_FORMAT_VMA) {
-+        dirty = total;
-+
-         vmaw = vma_writer_create(task->backup_file, uuid, &local_err);
-         if (!vmaw) {
-             if (local_err) {
-@@ -714,6 +785,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             }
-         }
-     } else if (format == BACKUP_FORMAT_DIR) {
-+        dirty = total;
-+
-         if (mkdir(task->backup_file, 0640) != 0) {
-             error_setg_errno(task->errp, errno, "can't create directory '%s'\n",
-                              task->backup_file);
-@@ -786,8 +859,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     char *uuid_str = g_strdup(backup_state.stat.uuid_str);
- 
-     backup_state.stat.total = total;
-+    backup_state.stat.dirty = dirty;
-     backup_state.stat.transferred = 0;
-     backup_state.stat.zero_bytes = 0;
-+    backup_state.stat.reused = format == BACKUP_FORMAT_PBS && dirty >= total ? 0 : total - dirty;
- 
-     qemu_mutex_unlock(&backup_state.stat.lock);
- 
-@@ -811,6 +886,10 @@ err:
-         PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-         l = g_list_next(l);
- 
-+        if (di->bitmap) {
-+            bdrv_release_dirty_bitmap(di->bitmap);
-+        }
-+
-         if (di->target) {
-             bdrv_co_unref(di->target);
-         }
-@@ -852,6 +931,7 @@ UuidInfo *qmp_backup(
-     const char *fingerprint,
-     const char *backup_id,
-     bool has_backup_time, int64_t backup_time,
-+    bool has_use_dirty_bitmap, bool use_dirty_bitmap,
-     bool has_format, BackupFormat format,
-     const char *config_file,
-     const char *firewall_file,
-@@ -866,6 +946,8 @@ UuidInfo *qmp_backup(
-         .backup_id = backup_id,
-         .has_backup_time = has_backup_time,
-         .backup_time = backup_time,
-+        .has_use_dirty_bitmap = has_use_dirty_bitmap,
-+        .use_dirty_bitmap = use_dirty_bitmap,
-         .has_format = has_format,
-         .format = format,
-         .config_file = config_file,
-@@ -927,10 +1009,14 @@ BackupStatus *qmp_query_backup(Error **errp)
- 
-     info->has_total = true;
-     info->total = backup_state.stat.total;
-+    info->has_dirty = true;
-+    info->dirty = backup_state.stat.dirty;
-     info->has_zero_bytes = true;
-     info->zero_bytes = backup_state.stat.zero_bytes;
-     info->has_transferred = true;
-     info->transferred = backup_state.stat.transferred;
-+    info->has_reused = true;
-+    info->reused = backup_state.stat.reused;
- 
-     qemu_mutex_unlock(&backup_state.stat.lock);
- 
-diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 16fb4c5ea0..92f90a898a 100644
---- a/qapi/block-core.json
-+++ b/qapi/block-core.json
-@@ -848,8 +848,13 @@
- #
- # @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.
-+#
- # @transferred: amount of bytes already backed up.
- #
-+# @reused: amount of bytes reused due to deduplication.
-+#
- # @zero-bytes: amount of 'zero' bytes detected.
- #
- # @start-time: time (epoch) when backup job started.
-@@ -862,8 +867,8 @@
- #
- ##
- { 'struct': 'BackupStatus',
--  'data': {'*status': 'str', '*errmsg': 'str', '*total': 'int',
--           '*transferred': 'int', '*zero-bytes': 'int',
-+  'data': {'*status': 'str', '*errmsg': 'str', '*total': 'int', '*dirty': 'int',
-+           '*transferred': 'int', '*zero-bytes': 'int', '*reused': 'int',
-            '*start-time': 'int', '*end-time': 'int',
-            '*backup-file': 'str', '*uuid': 'str' } }
- 
-@@ -906,6 +911,8 @@
- #
- # @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')
-+#
- # Returns: the uuid of the backup job
- #
- ##
-@@ -916,6 +923,7 @@
-                                     '*fingerprint': 'str',
-                                     '*backup-id': 'str',
-                                     '*backup-time': 'int',
-+                                    '*use-dirty-bitmap': 'bool',
-                                     '*format': 'BackupFormat',
-                                     '*config-file': 'str',
-                                     '*firewall-file': 'str',
diff --git a/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch b/debian/patches/pve/0031-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch
similarity index 56%
rename from debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
rename to debian/patches/pve/0031-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch
index 3aae91f..99b2a08 100644
--- a/debian/patches/pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
+++ b/debian/patches/pve/0031-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch
@@ -1,32 +1,102 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Dietmar Maurer <dietmar@proxmox.com>
 Date: Mon, 6 Apr 2020 12:16:59 +0200
-Subject: [PATCH] PVE-Backup: proxmox backup patches for qemu
+Subject: [PATCH] PVE-Backup: Proxmox backup patches for QEMU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+For PBS, using dirty bitmaps is supported via QEMU's
+MIRROR_SYNC_MODE_BITMAP. When the feature is used, the data-write
+callback is only executed for any changed chunks, the PBS rust code
+will reuse chunks from the previous index for everything it doesn't
+receive if reuse_index is true. On error or cancellation, all dirty
+bitmaps are removed to ensure consistency.
+
+By using a JobTxn, we can sync dirty bitmaps only when *all* jobs were
+successful - meaning we don't need to remove them when the backup
+fails, since QEMU's BITMAP_SYNC_MODE_ON_SUCCESS will now handle that
+for us. A sequential transaction is used, so drives will be backed up
+one after the other.
+
+The backup and backup-cancel QMP calls are coroutines. This has the
+benefit that calls are asynchronous to the main loop, i.e. long
+running operations like connecting to a PBS server will no longer hang
+the VM.
+
+backup_job_create() and job_cancel_sync() cannot be run from a
+coroutine and requires an acuqired AioContext, so the job creation and
+canceling are extracted as bottom halves and called from the
+respective QMP coroutines.
+
+To communicate the finishing state, a dedicated property is used for
+query-backup: 'finishing'. A dedicated state is explicitly not used,
+since that would break compatibility with older qemu-server versions.
+
+The first call to job_cancel_sync() will cancel and free all jobs in
+the transaction, but it is necessary to pick a job that is:
+1. still referenced. For this, there is a job_ref directly after job
+creation paired with a job_unref in cleanup paths.
+2. not yet finalized. In job_cancel_bh(), the first job that's not
+completed yet is used. This is not necessarily the first job in the
+list, because pvebackup_co_complete_stream() might not yet have
+removed a completed job when job_cancel_bh() runs. Why even bother
+with the bottom half at all and not use job_cancel() in
+qmp_backup_cancel() directly? The reason is that qmp_backup_cancel()
+is a coroutine, so it will hang when reaching AIO_WAIT_WHILE() and
+job_cancel() might end up calling that.
+
+Regarding BackupPerf performance settings. For now, only the
+max-workers setting is exposed, because:
+1. use-copy-range would need to be implemented in backup-dump and the
+feature was actually turned off by default in QEMU itself, because it
+didn't provide the expected benefit, see commit 6a30f663d4 ("qapi:
+backup: disable copy_range by default").
+2. max-chunk: enforced to be at least the backup cluster size (4 MiB
+for PBS) and otherwise maximum of source and target cluster size.
+And block-copy has a maximum buffer size of 1 MiB, so setting a larger
+max-chunk doesn't even have an effect. To make the setting sensibly
+usable the check would need to be removed and optionally the
+block-copy max buffer size would need to be bumped. I tried doing just
+that, and tested different source/target combinations with different
+max-chunk settings, but there were no noticable improvements over the
+default "unlimited" (resulting in 1 MiB for block-copy).
 
 Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
-[PVE-Backup: avoid coroutines to fix AIO freeze, cleanups]
+[SR: Add dirty-bitmap tracking for incremental backups
+     Add query_proxmox_support and query-pbs-bitmap-info QMP calls
+     Use a transaction to synchronize job states
+     Co-routine and async-related improvements
+     Improve finishing backups/cleanups
+     Various other improvements]
 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
+[FG: add master key support]
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[WB: add PBS namespace support]
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
 [FE: add new force parameter to job_cancel_sync calls
      adapt for new job lock mechanism replacing AioContext locks
-     adapt to QAPI changes]
+     adapt to QAPI changes
+     improve canceling
+     allow passing max-workers setting]
 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
- block/meson.build              |   5 +
- block/monitor/block-hmp-cmds.c |  33 ++
- blockdev.c                     |   1 +
- hmp-commands-info.hx           |  14 +
- hmp-commands.hx                |  29 +
- include/monitor/hmp.h          |   3 +
- meson.build                    |   1 +
- monitor/hmp-cmds.c             |  45 ++
- proxmox-backup-client.c        | 176 +++++++
- proxmox-backup-client.h        |  59 +++
- pve-backup.c                   | 938 +++++++++++++++++++++++++++++++++
- qapi/block-core.json           | 109 ++++
- qapi/common.json               |  13 +
- qapi/machine.json              |  15 +-
- 14 files changed, 1428 insertions(+), 13 deletions(-)
+ block/meson.build              |    5 +
+ block/monitor/block-hmp-cmds.c |   40 ++
+ blockdev.c                     |    1 +
+ hmp-commands-info.hx           |   14 +
+ hmp-commands.hx                |   31 +
+ include/monitor/hmp.h          |    3 +
+ meson.build                    |    1 +
+ monitor/hmp-cmds.c             |   72 +++
+ proxmox-backup-client.c        |  146 +++++
+ proxmox-backup-client.h        |   60 ++
+ pve-backup.c                   | 1097 ++++++++++++++++++++++++++++++++
+ qapi/block-core.json           |  226 +++++++
+ qapi/common.json               |   13 +
+ qapi/machine.json              |   15 +-
+ 14 files changed, 1711 insertions(+), 13 deletions(-)
  create mode 100644 proxmox-backup-client.c
  create mode 100644 proxmox-backup-client.h
  create mode 100644 pve-backup.c
@@ -48,15 +118,15 @@ index f580f95395..5bcebb934b 100644
  softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
  softmmu_ss.add(files('block-ram-registrar.c'))
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index ca2599de44..d50e99df26 100644
+index ca2599de44..636509b83e 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1029,3 +1029,36 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target,
+@@ -1029,3 +1029,43 @@ 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);
  }
 +
-+void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
++void coroutine_fn hmp_backup_cancel(Monitor *mon, const QDict *qdict)
 +{
 +    Error *error = NULL;
 +
@@ -65,7 +135,7 @@ index ca2599de44..d50e99df26 100644
 +    hmp_handle_error(mon, error);
 +}
 +
-+void hmp_backup(Monitor *mon, const QDict *qdict)
++void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
 +{
 +    Error *error = NULL;
 +
@@ -79,12 +149,19 @@ index ca2599de44..d50e99df26 100644
 +        NULL, // PBS password
 +        NULL, // PBS keyfile
 +        NULL, // PBS key_password
++        NULL, // PBS master_keyfile
 +        NULL, // PBS fingerprint
++        NULL, // PBS backup-ns
 +        NULL, // PBS backup-id
 +        false, 0, // PBS backup-time
++        false, false, // PBS use-dirty-bitmap
++        false, false, // PBS compress
++        false, false, // PBS encrypt
 +        true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
 +        NULL, NULL,
-+        devlist, qdict_haskey(qdict, "speed"), speed, &error);
++        devlist, qdict_haskey(qdict, "speed"), speed,
++        false, 0, // BackupPerf max-workers
++        &error);
 +
 +    hmp_handle_error(mon, error);
 +}
@@ -126,10 +203,10 @@ index a166bff3d5..4b75966c2e 100644
      {
          .name       = "usernet",
 diff --git a/hmp-commands.hx b/hmp-commands.hx
-index b66d7fc4ab..9b6b8e2e9c 100644
+index b66d7fc4ab..896430dae8 100644
 --- a/hmp-commands.hx
 +++ b/hmp-commands.hx
-@@ -101,6 +101,35 @@ ERST
+@@ -101,6 +101,37 @@ ERST
  SRST
  ``block_stream``
    Copy data from a backing file into a block device.
@@ -143,6 +220,7 @@ index b66d7fc4ab..9b6b8e2e9c 100644
 +		    "\n\t\t\t Use -d to dump data into a directory instead"
 +		    "\n\t\t\t of using VMA format.",
 +        .cmd = hmp_backup,
++        .coroutine  = true,
 +    },
 +
 +SRST
@@ -156,6 +234,7 @@ index b66d7fc4ab..9b6b8e2e9c 100644
 +        .params     = "",
 +        .help       = "cancel the current VM backup",
 +        .cmd        = hmp_backup_cancel,
++        .coroutine  = true,
 +    },
 +
 +SRST
@@ -199,7 +278,7 @@ index 603cdb97bb..d307d8eabf 100644
  # libselinux
  selinux = dependency('libselinux',
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 435f9334f9..9e1bd57aeb 100644
+index 435f9334f9..9a67e544ce 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
 @@ -21,6 +21,7 @@
@@ -210,13 +289,14 @@ index 435f9334f9..9e1bd57aeb 100644
  #include "qapi/qapi-commands-control.h"
  #include "qapi/qapi-commands-migration.h"
  #include "qapi/qapi-commands-misc.h"
-@@ -144,6 +145,50 @@ void hmp_sync_profile(Monitor *mon, const QDict *qdict)
+@@ -144,6 +145,77 @@ void hmp_sync_profile(Monitor *mon, const QDict *qdict)
      }
  }
  
 +void hmp_info_backup(Monitor *mon, const QDict *qdict)
 +{
 +    BackupStatus *info;
++    PBSBitmapInfoList *bitmap_info;
 +
 +    info = qmp_query_backup(NULL);
 +
@@ -240,19 +320,45 @@ index 435f9334f9..9e1bd57aeb 100644
 +            monitor_printf(mon, "End time: %s", ctime(&info->end_time));
 +        }
 +
-+        int per = (info->has_total && info->total &&
-+            info->has_transferred && info->transferred) ?
-+            (info->transferred * 100)/info->total : 0;
-+        int zero_per = (info->has_total && info->total &&
-+                        info->has_zero_bytes && info->zero_bytes) ?
-+            (info->zero_bytes * 100)/info->total : 0;
 +        monitor_printf(mon, "Backup file: %s\n", info->backup_file);
 +        monitor_printf(mon, "Backup uuid: %s\n", info->uuid);
-+        monitor_printf(mon, "Total size: %zd\n", info->total);
-+        monitor_printf(mon, "Transferred bytes: %zd (%d%%)\n",
-+                       info->transferred, per);
-+        monitor_printf(mon, "Zero bytes: %zd (%d%%)\n",
-+                       info->zero_bytes, zero_per);
++
++        if (!(info->has_total && info->total))  {
++            // this should not happen normally
++            monitor_printf(mon, "Total size: %d\n", 0);
++        } else {
++            size_t total_or_dirty = info->total;
++            bitmap_info = qmp_query_pbs_bitmap_info(NULL);
++
++            while (bitmap_info) {
++                monitor_printf(mon, "Drive %s:\n",
++                        bitmap_info->value->drive);
++                monitor_printf(mon, "  bitmap action: %s\n",
++                        PBSBitmapAction_str(bitmap_info->value->action));
++                monitor_printf(mon, "  size: %zd\n",
++                        bitmap_info->value->size);
++                monitor_printf(mon, "  dirty: %zd\n",
++                        bitmap_info->value->dirty);
++                bitmap_info = bitmap_info->next;
++            }
++
++            qapi_free_PBSBitmapInfoList(bitmap_info);
++
++            int zero_per = (info->has_zero_bytes && info->zero_bytes) ?
++                (info->zero_bytes * 100)/info->total : 0;
++            monitor_printf(mon, "Total size: %zd\n", info->total);
++            int trans_per = (info->transferred * 100)/total_or_dirty;
++            monitor_printf(mon, "Transferred bytes: %zd (%d%%)\n",
++                           info->transferred, trans_per);
++            monitor_printf(mon, "Zero bytes: %zd (%d%%)\n",
++                           info->zero_bytes, zero_per);
++
++            if (info->has_reused) {
++                int reused_per = (info->reused * 100)/total_or_dirty;
++                monitor_printf(mon, "Reused bytes: %zd (%d%%)\n",
++                               info->reused, reused_per);
++            }
++        }
 +    }
 +
 +    qapi_free_BackupStatus(info);
@@ -263,10 +369,10 @@ index 435f9334f9..9e1bd57aeb 100644
      Error *err = NULL;
 diff --git a/proxmox-backup-client.c b/proxmox-backup-client.c
 new file mode 100644
-index 0000000000..a8f6653a81
+index 0000000000..0923037dec
 --- /dev/null
 +++ b/proxmox-backup-client.c
-@@ -0,0 +1,176 @@
+@@ -0,0 +1,146 @@
 +#include "proxmox-backup-client.h"
 +#include "qemu/main-loop.h"
 +#include "block/aio-wait.h"
@@ -274,37 +380,6 @@ index 0000000000..a8f6653a81
 +
 +/* Proxmox Backup Server client bindings using coroutines */
 +
-+typedef struct BlockOnCoroutineWrapper {
-+    AioContext *ctx;
-+    CoroutineEntry *entry;
-+    void *entry_arg;
-+    bool finished;
-+} BlockOnCoroutineWrapper;
-+
-+static void coroutine_fn block_on_coroutine_wrapper(void *opaque)
-+{
-+    BlockOnCoroutineWrapper *wrapper = opaque;
-+    wrapper->entry(wrapper->entry_arg);
-+    wrapper->finished = true;
-+    aio_wait_kick();
-+}
-+
-+void block_on_coroutine_fn(CoroutineEntry *entry, void *entry_arg)
-+{
-+    assert(!qemu_in_coroutine());
-+
-+    AioContext *ctx = qemu_get_current_aio_context();
-+    BlockOnCoroutineWrapper wrapper = {
-+        .finished = false,
-+        .entry = entry,
-+        .entry_arg = entry_arg,
-+        .ctx = ctx,
-+    };
-+    Coroutine *wrapper_co = qemu_coroutine_create(block_on_coroutine_wrapper, &wrapper);
-+    aio_co_enter(ctx, wrapper_co);
-+    AIO_WAIT_WHILE(ctx, !wrapper.finished);
-+}
-+
 +// This is called from another thread, so we use aio_co_schedule()
 +static void proxmox_backup_schedule_wake(void *data) {
 +    CoCtxData *waker = (CoCtxData *)data;
@@ -358,6 +433,7 @@ index 0000000000..a8f6653a81
 +    ProxmoxBackupHandle *pbs,
 +    const char *device_name,
 +    uint64_t size,
++    bool incremental,
 +    Error **errp)
 +{
 +    Coroutine *co = qemu_coroutine_self();
@@ -367,7 +443,7 @@ index 0000000000..a8f6653a81
 +    int pbs_res = -1;
 +
 +    proxmox_backup_register_image_async(
-+        pbs, device_name, size ,proxmox_backup_schedule_wake, &waker, &pbs_res, &pbs_err);
++        pbs, device_name, size, incremental, proxmox_backup_schedule_wake, &waker, &pbs_res, &pbs_err);
 +    qemu_coroutine_yield();
 +    if (pbs_res < 0) {
 +        if (errp) error_setg(errp, "backup register image failed: %s", pbs_err ? pbs_err : "unknown error");
@@ -445,10 +521,10 @@ index 0000000000..a8f6653a81
 +}
 diff --git a/proxmox-backup-client.h b/proxmox-backup-client.h
 new file mode 100644
-index 0000000000..1dda8b7d8f
+index 0000000000..8cbf645b2c
 --- /dev/null
 +++ b/proxmox-backup-client.h
-@@ -0,0 +1,59 @@
+@@ -0,0 +1,60 @@
 +#ifndef PROXMOX_BACKUP_CLIENT_H
 +#define PROXMOX_BACKUP_CLIENT_H
 +
@@ -483,6 +559,7 @@ index 0000000000..1dda8b7d8f
 +    ProxmoxBackupHandle *pbs,
 +    const char *device_name,
 +    uint64_t size,
++    bool incremental,
 +    Error **errp);
 +
 +
@@ -510,10 +587,10 @@ index 0000000000..1dda8b7d8f
 +#endif /* PROXMOX_BACKUP_CLIENT_H */
 diff --git a/pve-backup.c b/pve-backup.c
 new file mode 100644
-index 0000000000..f77892a509
+index 0000000000..dd72ee0ed6
 --- /dev/null
 +++ b/pve-backup.c
-@@ -0,0 +1,938 @@
+@@ -0,0 +1,1097 @@
 +#include "proxmox-backup-client.h"
 +#include "vma.h"
 +
@@ -523,8 +600,12 @@ index 0000000000..f77892a509
 +#include "sysemu/blockdev.h"
 +#include "block/block_int-global-state.h"
 +#include "block/blockjob.h"
++#include "block/dirty-bitmap.h"
 +#include "qapi/qapi-commands-block.h"
 +#include "qapi/qmp/qerror.h"
++#include "qemu/cutils.h"
++
++#include <proxmox-backup-qemu.h>
 +
 +/* PVE backup state and related function */
 +
@@ -545,9 +626,13 @@ index 0000000000..f77892a509
 + *
 + */
 +
++const char *PBS_BITMAP_NAME = "pbs-incremental-dirty-bitmap";
++
 +static struct PVEBackupState {
 +    struct {
-+        // Everithing accessed from qmp_backup_query command is protected using lock
++        // Everything accessed from qmp_backup_query command is protected using
++        // this lock. Do NOT hold this lock for long times, as it is sometimes
++        // acquired from coroutines, and thus any wait time may block the guest.
 +        QemuMutex lock;
 +        Error *error;
 +        time_t start_time;
@@ -556,21 +641,28 @@ index 0000000000..f77892a509
 +        uuid_t uuid;
 +        char uuid_str[37];
 +        size_t total;
++        size_t dirty;
 +        size_t transferred;
++        size_t reused;
 +        size_t zero_bytes;
++        GList *bitmap_list;
++        bool finishing;
++        bool starting;
 +    } stat;
 +    int64_t speed;
++    BackupPerf perf;
 +    VmaWriter *vmaw;
 +    ProxmoxBackupHandle *pbs;
 +    GList *di_list;
-+    QemuMutex backup_mutex;
++    JobTxn *txn;
++    CoMutex backup_mutex;
 +    CoMutex dump_callback_mutex;
 +} backup_state;
 +
 +static void pvebackup_init(void)
 +{
 +    qemu_mutex_init(&backup_state.stat.lock);
-+    qemu_mutex_init(&backup_state.backup_mutex);
++    qemu_co_mutex_init(&backup_state.backup_mutex);
 +    qemu_co_mutex_init(&backup_state.dump_callback_mutex);
 +}
 +
@@ -580,34 +672,15 @@ index 0000000000..f77892a509
 +typedef struct PVEBackupDevInfo {
 +    BlockDriverState *bs;
 +    size_t size;
++    uint64_t block_size;
 +    uint8_t dev_id;
-+    bool completed;
++    int completed_ret; // INT_MAX if not completed
 +    char targetfile[PATH_MAX];
++    BdrvDirtyBitmap *bitmap;
 +    BlockDriverState *target;
++    BlockJob *job;
 +} PVEBackupDevInfo;
 +
-+static void pvebackup_run_next_job(void);
-+
-+static BlockJob *
-+lookup_active_block_job(PVEBackupDevInfo *di)
-+{
-+    if (!di->completed && di->bs) {
-+        WITH_JOB_LOCK_GUARD() {
-+            for (BlockJob *job = block_job_next_locked(NULL); job; job = block_job_next_locked(job)) {
-+                if (job->job.driver->job_type != JOB_TYPE_BACKUP) {
-+                    continue;
-+                }
-+
-+                BackupBlockJob *bjob = container_of(job, BackupBlockJob, common);
-+                if (bjob && bjob->source_bs == di->bs) {
-+                    return job;
-+                }
-+            }
-+        }
-+    }
-+    return NULL;
-+}
-+
 +static void pvebackup_propagate_error(Error *err)
 +{
 +    qemu_mutex_lock(&backup_state.stat.lock);
@@ -624,11 +697,12 @@ index 0000000000..f77892a509
 +    return error_or_canceled;
 +}
 +
-+static void pvebackup_add_transfered_bytes(size_t transferred, size_t zero_bytes)
++static void pvebackup_add_transfered_bytes(size_t transferred, size_t zero_bytes, size_t reused)
 +{
 +    qemu_mutex_lock(&backup_state.stat.lock);
 +    backup_state.stat.zero_bytes += zero_bytes;
 +    backup_state.stat.transferred += transferred;
++    backup_state.stat.reused += reused;
 +    qemu_mutex_unlock(&backup_state.stat.lock);
 +}
 +
@@ -648,10 +722,13 @@ index 0000000000..f77892a509
 +    PVEBackupDevInfo *di = opaque;
 +
 +    assert(backup_state.pbs);
++    assert(buf);
 +
 +    Error *local_err = NULL;
 +    int pbs_res = -1;
 +
++    bool is_zero_block = size == di->block_size && buffer_is_zero(buf, size);
++
 +    qemu_co_mutex_lock(&backup_state.dump_callback_mutex);
 +
 +    // avoid deadlock if job is cancelled
@@ -660,16 +737,29 @@ index 0000000000..f77892a509
 +        return -1;
 +    }
 +
-+    pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id, buf, start, size, &local_err);
-+    qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
++    uint64_t transferred = 0;
++    uint64_t reused = 0;
++    while (transferred < size) {
++        uint64_t left = size - transferred;
++        uint64_t to_transfer = left < di->block_size ? left : di->block_size;
 +
-+    if (pbs_res < 0) {
-+        pvebackup_propagate_error(local_err);
-+        return pbs_res;
-+    } else {
-+        pvebackup_add_transfered_bytes(size, !buf ? size : 0);
++        pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id,
++            is_zero_block ? NULL : buf + transferred, start + transferred,
++            to_transfer, &local_err);
++        transferred += to_transfer;
++
++        if (pbs_res < 0) {
++            pvebackup_propagate_error(local_err);
++            qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
++            return pbs_res;
++        }
++
++        reused += pbs_res == 0 ? to_transfer : 0;
 +    }
 +
++    qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
++    pvebackup_add_transfered_bytes(size, is_zero_block ? size : 0, reused);
++
 +    return size;
 +}
 +
@@ -690,6 +780,7 @@ index 0000000000..f77892a509
 +    int ret = -1;
 +
 +    assert(backup_state.vmaw);
++    assert(buf);
 +
 +    uint64_t remaining = size;
 +
@@ -716,9 +807,7 @@ index 0000000000..f77892a509
 +        qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
 +
 +        ++cluster_num;
-+        if (buf) {
-+            buf += VMA_CLUSTER_SIZE;
-+        }
++        buf += VMA_CLUSTER_SIZE;
 +        if (ret < 0) {
 +            Error *local_err = NULL;
 +            vma_writer_error_propagate(backup_state.vmaw, &local_err);
@@ -727,11 +816,11 @@ index 0000000000..f77892a509
 +        } else {
 +            if (remaining >= VMA_CLUSTER_SIZE) {
 +                assert(ret == VMA_CLUSTER_SIZE);
-+                pvebackup_add_transfered_bytes(VMA_CLUSTER_SIZE, zero_bytes);
++                pvebackup_add_transfered_bytes(VMA_CLUSTER_SIZE, zero_bytes, 0);
 +                remaining -= VMA_CLUSTER_SIZE;
 +            } else {
 +                assert(ret == remaining);
-+                pvebackup_add_transfered_bytes(remaining, zero_bytes);
++                pvebackup_add_transfered_bytes(remaining, zero_bytes, 0);
 +                remaining = 0;
 +            }
 +        }
@@ -741,12 +830,12 @@ index 0000000000..f77892a509
 +}
 +
 +// assumes the caller holds backup_mutex
-+static void coroutine_fn pvebackup_co_cleanup(void *unused)
++static void coroutine_fn pvebackup_co_cleanup(void)
 +{
 +    assert(qemu_in_coroutine());
 +
 +    qemu_mutex_lock(&backup_state.stat.lock);
-+    backup_state.stat.end_time = time(NULL);
++    backup_state.stat.finishing = true;
 +    qemu_mutex_unlock(&backup_state.stat.lock);
 +
 +    if (backup_state.vmaw) {
@@ -775,12 +864,39 @@ index 0000000000..f77892a509
 +
 +    g_list_free(backup_state.di_list);
 +    backup_state.di_list = NULL;
++
++    qemu_mutex_lock(&backup_state.stat.lock);
++    backup_state.stat.end_time = time(NULL);
++    backup_state.stat.finishing = false;
++    qemu_mutex_unlock(&backup_state.stat.lock);
 +}
 +
-+// assumes the caller holds backup_mutex
-+static void coroutine_fn pvebackup_complete_stream(void *opaque)
++static void coroutine_fn pvebackup_co_complete_stream(void *opaque)
 +{
 +    PVEBackupDevInfo *di = opaque;
++    int ret = di->completed_ret;
++
++    qemu_mutex_lock(&backup_state.stat.lock);
++    bool starting = backup_state.stat.starting;
++    qemu_mutex_unlock(&backup_state.stat.lock);
++    if (starting) {
++        /* in 'starting' state, no tasks have been run yet, meaning we can (and
++         * must) skip all cleanup, as we don't know what has and hasn't been
++         * initialized yet. */
++        return;
++    }
++
++    qemu_co_mutex_lock(&backup_state.backup_mutex);
++
++    if (ret < 0) {
++        Error *local_err = NULL;
++        error_setg(&local_err, "job failed with err %d - %s", ret, strerror(-ret));
++        pvebackup_propagate_error(local_err);
++    }
++
++    di->bs = NULL;
++
++    assert(di->target == NULL);
 +
 +    bool error_or_canceled = pvebackup_error_or_canceled();
 +
@@ -795,49 +911,90 @@ index 0000000000..f77892a509
 +            pvebackup_propagate_error(local_err);
 +        }
 +    }
-+}
-+
-+static void pvebackup_complete_cb(void *opaque, int ret)
-+{
-+    assert(!qemu_in_coroutine());
-+
-+    PVEBackupDevInfo *di = opaque;
-+
-+    qemu_mutex_lock(&backup_state.backup_mutex);
 +
-+    di->completed = true;
-+
-+    if (ret < 0) {
-+        Error *local_err = NULL;
-+        error_setg(&local_err, "job failed with err %d - %s", ret, strerror(-ret));
-+        pvebackup_propagate_error(local_err);
++    if (di->job) {
++        WITH_JOB_LOCK_GUARD() {
++            job_unref_locked(&di->job->job);
++            di->job = NULL;
++        }
 +    }
 +
-+    di->bs = NULL;
-+
-+    assert(di->target == NULL);
-+
-+    block_on_coroutine_fn(pvebackup_complete_stream, di);
-+
-+    // remove self from job queue
++    // remove self from job list
 +    backup_state.di_list = g_list_remove(backup_state.di_list, di);
 +
 +    g_free(di);
 +
-+    qemu_mutex_unlock(&backup_state.backup_mutex);
++    /* call cleanup if we're the last job */
++    if (!g_list_first(backup_state.di_list)) {
++        pvebackup_co_cleanup();
++    }
 +
-+    pvebackup_run_next_job();
++    qemu_co_mutex_unlock(&backup_state.backup_mutex);
 +}
 +
-+static void pvebackup_cancel(void)
++static void pvebackup_complete_cb(void *opaque, int ret)
 +{
-+    assert(!qemu_in_coroutine());
++    PVEBackupDevInfo *di = opaque;
++    di->completed_ret = ret;
++
++    /*
++     * Schedule stream cleanup in async coroutine. close_image and finish might
++     * take a while, so we can't block on them here. This way it also doesn't
++     * matter if we're already running in a coroutine or not.
++     * Note: di is a pointer to an entry in the global backup_state struct, so
++     * it stays valid.
++     */
++    Coroutine *co = qemu_coroutine_create(pvebackup_co_complete_stream, di);
++    aio_co_enter(qemu_get_aio_context(), co);
++}
 +
++/*
++ * job_cancel(_sync) does not like to be called from coroutines, so defer to
++ * main loop processing via a bottom half. Assumes that caller holds
++ * backup_mutex.
++ */
++static void job_cancel_bh(void *opaque) {
++    CoCtxData *data = (CoCtxData*)opaque;
++
++    /*
++     * Be careful to pick a valid job to cancel:
++     * 1. job_cancel_sync() does not expect the job to be finalized already.
++     * 2. job_exit() might run between scheduling and running job_cancel_bh()
++     *    and pvebackup_co_complete_stream() might not have removed the job from
++     *    the list yet (in fact, cannot, because it waits for the backup_mutex).
++     * Requiring !job_is_completed() ensures that no finalized job is picked.
++     */
++    GList *bdi = g_list_first(backup_state.di_list);
++    while (bdi) {
++        if (bdi->data) {
++            BlockJob *bj = ((PVEBackupDevInfo *)bdi->data)->job;
++            if (bj) {
++                Job *job = &bj->job;
++                WITH_JOB_LOCK_GUARD() {
++                    if (!job_is_completed_locked(job)) {
++                        job_cancel_sync_locked(job, true);
++                        /*
++                         * It's enough to cancel one job in the transaction, the
++                         * rest will follow automatically.
++                         */
++                        break;
++                    }
++                }
++            }
++        }
++        bdi = g_list_next(bdi);
++    }
++
++    aio_co_enter(data->ctx, data->co);
++}
++
++void coroutine_fn qmp_backup_cancel(Error **errp)
++{
 +    Error *cancel_err = NULL;
 +    error_setg(&cancel_err, "backup canceled");
 +    pvebackup_propagate_error(cancel_err);
 +
-+    qemu_mutex_lock(&backup_state.backup_mutex);
++    qemu_co_mutex_lock(&backup_state.backup_mutex);
 +
 +    if (backup_state.vmaw) {
 +        /* make sure vma writer does not block anymore */
@@ -848,39 +1005,14 @@ index 0000000000..f77892a509
 +        proxmox_backup_abort(backup_state.pbs, "backup canceled");
 +    }
 +
-+    qemu_mutex_unlock(&backup_state.backup_mutex);
-+
-+    for(;;) {
-+
-+        BlockJob *next_job = NULL;
-+
-+        qemu_mutex_lock(&backup_state.backup_mutex);
-+
-+        GList *l = backup_state.di_list;
-+        while (l) {
-+            PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-+            l = g_list_next(l);
-+
-+            BlockJob *job = lookup_active_block_job(di);
-+            if (job != NULL) {
-+                next_job = job;
-+                break;
-+            }
-+        }
-+
-+        qemu_mutex_unlock(&backup_state.backup_mutex);
-+
-+        if (next_job) {
-+            job_cancel_sync(&next_job->job, true);
-+        } else {
-+            break;
-+        }
-+    }
-+}
++    CoCtxData data = {
++        .ctx = qemu_get_current_aio_context(),
++        .co = qemu_coroutine_self(),
++    };
++    aio_bh_schedule_oneshot(data.ctx, job_cancel_bh, &data);
++    qemu_coroutine_yield();
 +
-+void qmp_backup_cancel(Error **errp)
-+{
-+    pvebackup_cancel();
++    qemu_co_mutex_unlock(&backup_state.backup_mutex);
 +}
 +
 +// assumes the caller holds backup_mutex
@@ -933,50 +1065,26 @@ index 0000000000..f77892a509
 +    goto out;
 +}
 +
-+bool job_should_pause_locked(Job *job);
++/*
++ * backup_job_create can *not* be run from a coroutine (and requires an
++ * acquired AioContext), so this can't either.
++ * The caller is responsible that backup_mutex is held nonetheless.
++ */
++static void create_backup_jobs_bh(void *opaque) {
 +
-+static void pvebackup_run_next_job(void)
-+{
 +    assert(!qemu_in_coroutine());
 +
-+    qemu_mutex_lock(&backup_state.backup_mutex);
-+
-+    GList *l = backup_state.di_list;
-+    while (l) {
-+        PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-+        l = g_list_next(l);
-+
-+        BlockJob *job = lookup_active_block_job(di);
-+
-+        if (job) {
-+            qemu_mutex_unlock(&backup_state.backup_mutex);
-+
-+            WITH_JOB_LOCK_GUARD() {
-+                if (job_should_pause_locked(&job->job)) {
-+                    bool error_or_canceled = pvebackup_error_or_canceled();
-+                    if (error_or_canceled) {
-+                        job_cancel_sync_locked(&job->job, true);
-+                    } else {
-+                        job_resume_locked(&job->job);
-+                    }
-+                }
-+            }
-+            return;
-+        }
-+    }
-+
-+    block_on_coroutine_fn(pvebackup_co_cleanup, NULL); // no more jobs, run cleanup
-+
-+    qemu_mutex_unlock(&backup_state.backup_mutex);
-+}
-+
-+static bool create_backup_jobs(void) {
-+
-+    assert(!qemu_in_coroutine());
++    CoCtxData *data = (CoCtxData*)opaque;
++    Error **errp = (Error**)data->data;
 +
 +    Error *local_err = NULL;
 +
-+    BackupPerf perf = { .max_workers = 16 };
++    /* create job transaction to synchronize bitmap commit and cancel all
++     * jobs in case one errors */
++    if (backup_state.txn) {
++        job_txn_unref(backup_state.txn);
++    }
++    backup_state.txn = job_txn_new_seq();
 +
 +    /* create and start all jobs (paused state) */
 +    GList *l =  backup_state.di_list;
@@ -986,33 +1094,46 @@ index 0000000000..f77892a509
 +
 +        assert(di->target != NULL);
 +
++        MirrorSyncMode sync_mode = MIRROR_SYNC_MODE_FULL;
++        BitmapSyncMode bitmap_mode = BITMAP_SYNC_MODE_NEVER;
++        if (di->bitmap) {
++            sync_mode = MIRROR_SYNC_MODE_BITMAP;
++            bitmap_mode = BITMAP_SYNC_MODE_ON_SUCCESS;
++        }
 +        AioContext *aio_context = bdrv_get_aio_context(di->bs);
 +        aio_context_acquire(aio_context);
 +
 +        BlockJob *job = backup_job_create(
-+            NULL, di->bs, di->target, backup_state.speed, MIRROR_SYNC_MODE_FULL, NULL,
-+            BITMAP_SYNC_MODE_NEVER, false, NULL, &perf, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
-+            JOB_DEFAULT, pvebackup_complete_cb, di, NULL, &local_err);
++            NULL, di->bs, di->target, backup_state.speed, sync_mode, di->bitmap,
++            bitmap_mode, false, NULL, &backup_state.perf, BLOCKDEV_ON_ERROR_REPORT,
++            BLOCKDEV_ON_ERROR_REPORT, JOB_DEFAULT, pvebackup_complete_cb, di, backup_state.txn,
++            &local_err);
 +
 +        aio_context_release(aio_context);
 +
-+        if (!job || local_err != NULL) {
-+            Error *create_job_err = NULL;
-+            error_setg(&create_job_err, "backup_job_create failed: %s",
-+                       local_err ? error_get_pretty(local_err) : "null");
++        di->job = job;
++        if (job) {
++            WITH_JOB_LOCK_GUARD() {
++                job_ref_locked(&job->job);
++            }
++        }
 +
-+            pvebackup_propagate_error(create_job_err);
++        if (!job || local_err) {
++            error_setg(errp, "backup_job_create failed: %s",
++                       local_err ? error_get_pretty(local_err) : "null");
 +            break;
 +        }
-+        job_start(&job->job);
 +
 +        bdrv_unref(di->target);
 +        di->target = NULL;
 +    }
 +
-+    bool errors = pvebackup_error_or_canceled();
-+
-+    if (errors) {
++    if (*errp) {
++        /*
++         * It's enough to cancel one job in the transaction, the rest will
++         * follow automatically.
++         */
++        bool canceled = false;
 +        l = backup_state.di_list;
 +        while (l) {
 +            PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
@@ -1022,40 +1143,48 @@ index 0000000000..f77892a509
 +                bdrv_unref(di->target);
 +                di->target = NULL;
 +            }
++
++            if (di->job) {
++                WITH_JOB_LOCK_GUARD() {
++                    if (!canceled) {
++                        job_cancel_sync_locked(&di->job->job, true);
++                        canceled = true;
++                    }
++                    job_unref_locked(&di->job->job);
++                    di->job = NULL;
++                }
++            }
 +        }
 +    }
 +
-+    return errors;
++    /* return */
++    aio_co_enter(data->ctx, data->co);
 +}
 +
-+typedef struct QmpBackupTask {
-+    const char *backup_file;
-+    const char *password;
-+    const char *keyfile;
-+    const char *key_password;
-+    const char *backup_id;
-+    bool has_backup_time;
-+    const char *fingerprint;
-+    int64_t backup_time;
-+    bool has_format;
-+    BackupFormat format;
-+    const char *config_file;
-+    const char *firewall_file;
-+    const char *devlist;
-+    bool has_speed;
-+    int64_t speed;
-+    Error **errp;
-+    UuidInfo *result;
-+} QmpBackupTask;
-+
-+// assumes the caller holds backup_mutex
-+static void coroutine_fn pvebackup_co_prepare(void *opaque)
++UuidInfo coroutine_fn *qmp_backup(
++    const char *backup_file,
++    const char *password,
++    const char *keyfile,
++    const char *key_password,
++    const char *master_keyfile,
++    const char *fingerprint,
++    const char *backup_ns,
++    const char *backup_id,
++    bool has_backup_time, int64_t backup_time,
++    bool has_use_dirty_bitmap, bool use_dirty_bitmap,
++    bool has_compress, bool compress,
++    bool has_encrypt, bool encrypt,
++    bool has_format, BackupFormat format,
++    const char *config_file,
++    const char *firewall_file,
++    const char *devlist,
++    bool has_speed, int64_t speed,
++    bool has_max_workers, int64_t max_workers,
++    Error **errp)
 +{
 +    assert(qemu_in_coroutine());
 +
-+    QmpBackupTask *task = opaque;
-+
-+    task->result = NULL; // just to be sure
++    qemu_co_mutex_lock(&backup_state.backup_mutex);
 +
 +    BlockBackend *blk;
 +    BlockDriverState *bs = NULL;
@@ -1073,31 +1202,32 @@ index 0000000000..f77892a509
 +    const char *firewall_name = "qemu-server.fw";
 +
 +    if (backup_state.di_list) {
-+         error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
 +                  "previous backup not finished");
-+        return;
++        qemu_co_mutex_unlock(&backup_state.backup_mutex);
++        return NULL;
 +    }
 +
 +    /* Todo: try to auto-detect format based on file name */
-+    BackupFormat format = task->has_format ? task->format : BACKUP_FORMAT_VMA;
++    format = has_format ? format : BACKUP_FORMAT_VMA;
 +
-+    if (task->devlist) {
-+        devs = g_strsplit_set(task->devlist, ",;:", -1);
++    if (devlist) {
++        devs = g_strsplit_set(devlist, ",;:", -1);
 +
 +        gchar **d = devs;
 +        while (d && *d) {
 +            blk = blk_by_name(*d);
 +            if (blk) {
 +                bs = blk_bs(blk);
-+                if (!bdrv_is_inserted(bs)) {
-+                    error_setg(task->errp, QERR_DEVICE_HAS_NO_MEDIUM, *d);
++                if (!bdrv_co_is_inserted(bs)) {
++                    error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, *d);
 +                    goto err;
 +                }
 +                PVEBackupDevInfo *di = g_new0(PVEBackupDevInfo, 1);
 +                di->bs = bs;
 +                di_list = g_list_append(di_list, di);
 +            } else {
-+                error_set(task->errp, ERROR_CLASS_DEVICE_NOT_FOUND,
++                error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 +                          "Device '%s' not found", *d);
 +                goto err;
 +            }
@@ -1109,7 +1239,7 @@ index 0000000000..f77892a509
 +
 +        bs = NULL;
 +        for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
-+            if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
++            if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs)) {
 +                continue;
 +            }
 +
@@ -1120,7 +1250,7 @@ index 0000000000..f77892a509
 +    }
 +
 +    if (!di_list) {
-+        error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "empty device list");
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR, "empty device list");
 +        goto err;
 +    }
 +
@@ -1130,59 +1260,81 @@ index 0000000000..f77892a509
 +    while (l) {
 +        PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
 +        l = g_list_next(l);
-+        if (bdrv_op_is_blocked(di->bs, BLOCK_OP_TYPE_BACKUP_SOURCE, task->errp)) {
++        if (bdrv_op_is_blocked(di->bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
 +            goto err;
 +        }
 +
 +        ssize_t size = bdrv_getlength(di->bs);
 +        if (size < 0) {
-+            error_setg_errno(task->errp, -size, "bdrv_getlength failed");
++            error_setg_errno(errp, -size, "bdrv_getlength failed");
 +            goto err;
 +        }
 +        di->size = size;
 +        total += size;
++
++        di->completed_ret = INT_MAX;
 +    }
 +
 +    uuid_generate(uuid);
 +
++    qemu_mutex_lock(&backup_state.stat.lock);
++    backup_state.stat.reused = 0;
++
++    /* clear previous backup's bitmap_list */
++    if (backup_state.stat.bitmap_list) {
++        GList *bl = backup_state.stat.bitmap_list;
++        while (bl) {
++            g_free(((PBSBitmapInfo *)bl->data)->drive);
++            g_free(bl->data);
++            bl = g_list_next(bl);
++        }
++        g_list_free(backup_state.stat.bitmap_list);
++        backup_state.stat.bitmap_list = NULL;
++    }
++
 +    if (format == BACKUP_FORMAT_PBS) {
-+        if (!task->password) {
-+            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
-+            goto err;
++        if (!password) {
++            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
++            goto err_mutex;
 +        }
-+        if (!task->backup_id) {
-+            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
-+            goto err;
++        if (!backup_id) {
++            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
++            goto err_mutex;
 +        }
-+        if (!task->has_backup_time) {
-+            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-time'");
-+            goto err;
++        if (!has_backup_time) {
++            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-time'");
++            goto err_mutex;
 +        }
 +
 +        int dump_cb_block_size = PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE; // Hardcoded (4M)
 +        firewall_name = "fw.conf";
 +
 +        char *pbs_err = NULL;
-+        pbs = proxmox_backup_new(
-+            task->backup_file,
-+            task->backup_id,
-+            task->backup_time,
++        pbs = proxmox_backup_new_ns(
++            backup_file,
++            backup_ns,
++            backup_id,
++            backup_time,
 +            dump_cb_block_size,
-+            task->password,
-+            task->keyfile,
-+            task->key_password,
-+            task->fingerprint,
++            password,
++            keyfile,
++            key_password,
++            master_keyfile,
++            has_compress ? compress : true,
++            has_encrypt ? encrypt : !!keyfile,
++            fingerprint,
 +            &pbs_err);
 +
 +        if (!pbs) {
-+            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
++            error_set(errp, ERROR_CLASS_GENERIC_ERROR,
 +                      "proxmox_backup_new failed: %s", pbs_err);
 +            proxmox_backup_free_error(pbs_err);
-+            goto err;
++            goto err_mutex;
 +        }
 +
-+        if (proxmox_backup_co_connect(pbs, task->errp) < 0)
-+            goto err;
++        int connect_result = proxmox_backup_co_connect(pbs, errp);
++        if (connect_result < 0)
++            goto err_mutex;
 +
 +        /* register all devices */
 +        l = di_list;
@@ -1190,25 +1342,72 @@ index 0000000000..f77892a509
 +            PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
 +            l = g_list_next(l);
 +
++            di->block_size = dump_cb_block_size;
++
 +            const char *devname = bdrv_get_device_name(di->bs);
++            PBSBitmapAction action = PBS_BITMAP_ACTION_NOT_USED;
++            size_t dirty = di->size;
 +
-+            int dev_id = proxmox_backup_co_register_image(pbs, devname, di->size, task->errp);
-+            if (dev_id < 0)
-+                goto err;
++            BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
++            bool expect_only_dirty = false;
 +
-+            if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, task->errp))) {
-+                goto err;
++            if (has_use_dirty_bitmap && use_dirty_bitmap) {
++                if (bitmap == NULL) {
++                    bitmap = bdrv_create_dirty_bitmap(di->bs, dump_cb_block_size, PBS_BITMAP_NAME, errp);
++                    if (!bitmap) {
++                        goto err_mutex;
++                    }
++                    action = PBS_BITMAP_ACTION_NEW;
++                } else {
++                    expect_only_dirty = proxmox_backup_check_incremental(pbs, devname, di->size) != 0;
++                }
++
++                if (expect_only_dirty) {
++                    /* track clean chunks as reused */
++                    dirty = MIN(bdrv_get_dirty_count(bitmap), di->size);
++                    backup_state.stat.reused += di->size - dirty;
++                    action = PBS_BITMAP_ACTION_USED;
++                } else {
++                    /* mark entire bitmap as dirty to make full backup */
++                    bdrv_set_dirty_bitmap(bitmap, 0, di->size);
++                    if (action != PBS_BITMAP_ACTION_NEW) {
++                        action = PBS_BITMAP_ACTION_INVALID;
++                    }
++                }
++                di->bitmap = bitmap;
++            } else {
++                /* after a full backup the old dirty bitmap is invalid anyway */
++                if (bitmap != NULL) {
++                    bdrv_release_dirty_bitmap(bitmap);
++                    action = PBS_BITMAP_ACTION_NOT_USED_REMOVED;
++                }
++            }
++
++            int dev_id = proxmox_backup_co_register_image(pbs, devname, di->size, expect_only_dirty, errp);
++            if (dev_id < 0) {
++                goto err_mutex;
++            }
++
++            if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, errp))) {
++                goto err_mutex;
 +            }
 +
 +            di->dev_id = dev_id;
++
++            PBSBitmapInfo *info = g_malloc(sizeof(*info));
++            info->drive = g_strdup(devname);
++            info->action = action;
++            info->size = di->size;
++            info->dirty = dirty;
++            backup_state.stat.bitmap_list = g_list_append(backup_state.stat.bitmap_list, info);
 +        }
 +    } else if (format == BACKUP_FORMAT_VMA) {
-+        vmaw = vma_writer_create(task->backup_file, uuid, &local_err);
++        vmaw = vma_writer_create(backup_file, uuid, &local_err);
 +        if (!vmaw) {
 +            if (local_err) {
-+                error_propagate(task->errp, local_err);
++                error_propagate(errp, local_err);
 +            }
-+            goto err;
++            goto err_mutex;
 +        }
 +
 +        /* register all devices for vma writer */
@@ -1217,25 +1416,25 @@ index 0000000000..f77892a509
 +            PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
 +            l = g_list_next(l);
 +
-+            if (!(di->target = bdrv_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, task->errp))) {
-+                goto err;
++            if (!(di->target = bdrv_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, errp))) {
++                goto err_mutex;
 +            }
 +
 +            const char *devname = bdrv_get_device_name(di->bs);
 +            di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
 +            if (di->dev_id <= 0) {
-+                error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
++                error_set(errp, ERROR_CLASS_GENERIC_ERROR,
 +                          "register_stream failed");
-+                goto err;
++                goto err_mutex;
 +            }
 +        }
 +    } else if (format == BACKUP_FORMAT_DIR) {
-+        if (mkdir(task->backup_file, 0640) != 0) {
-+            error_setg_errno(task->errp, errno, "can't create directory '%s'\n",
-+                             task->backup_file);
-+            goto err;
++        if (mkdir(backup_file, 0640) != 0) {
++            error_setg_errno(errp, errno, "can't create directory '%s'\n",
++                             backup_file);
++            goto err_mutex;
 +        }
-+        backup_dir = task->backup_file;
++        backup_dir = backup_file;
 +
 +        l = di_list;
 +        while (l) {
@@ -1249,40 +1448,39 @@ index 0000000000..f77892a509
 +            bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
 +                            di->size, flags, false, &local_err);
 +            if (local_err) {
-+                error_propagate(task->errp, local_err);
-+                goto err;
++                error_propagate(errp, local_err);
++                goto err_mutex;
 +            }
 +
 +            di->target = bdrv_co_open(di->targetfile, NULL, NULL, flags, &local_err);
 +            if (!di->target) {
-+                error_propagate(task->errp, local_err);
-+                goto err;
++                error_propagate(errp, local_err);
++                goto err_mutex;
 +            }
 +        }
 +    } else {
-+        error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
-+        goto err;
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
++        goto err_mutex;
 +    }
 +
 +
 +    /* add configuration file to archive */
-+    if (task->config_file) {
-+        if (pvebackup_co_add_config(task->config_file, config_name, format, backup_dir,
-+                                    vmaw, pbs, task->errp) != 0) {
-+            goto err;
++    if (config_file) {
++        if (pvebackup_co_add_config(config_file, config_name, format, backup_dir,
++                                    vmaw, pbs, errp) != 0) {
++            goto err_mutex;
 +        }
 +    }
 +
 +    /* add firewall file to archive */
-+    if (task->firewall_file) {
-+        if (pvebackup_co_add_config(task->firewall_file, firewall_name, format, backup_dir,
-+                                    vmaw, pbs, task->errp) != 0) {
-+            goto err;
++    if (firewall_file) {
++        if (pvebackup_co_add_config(firewall_file, firewall_name, format, backup_dir,
++                                    vmaw, pbs, errp) != 0) {
++            goto err_mutex;
 +        }
 +    }
 +    /* initialize global backup_state now */
-+
-+    qemu_mutex_lock(&backup_state.stat.lock);
++    /* note: 'reused' and 'bitmap_list' are initialized earlier */
 +
 +    if (backup_state.stat.error) {
 +        error_free(backup_state.stat.error);
@@ -1295,19 +1493,27 @@ index 0000000000..f77892a509
 +    if (backup_state.stat.backup_file) {
 +        g_free(backup_state.stat.backup_file);
 +    }
-+    backup_state.stat.backup_file = g_strdup(task->backup_file);
++    backup_state.stat.backup_file = g_strdup(backup_file);
 +
 +    uuid_copy(backup_state.stat.uuid, uuid);
 +    uuid_unparse_lower(uuid, backup_state.stat.uuid_str);
 +    char *uuid_str = g_strdup(backup_state.stat.uuid_str);
 +
 +    backup_state.stat.total = total;
++    backup_state.stat.dirty = total - backup_state.stat.reused;
 +    backup_state.stat.transferred = 0;
 +    backup_state.stat.zero_bytes = 0;
++    backup_state.stat.finishing = false;
++    backup_state.stat.starting = true;
 +
 +    qemu_mutex_unlock(&backup_state.stat.lock);
 +
-+    backup_state.speed = (task->has_speed && task->speed > 0) ? task->speed : 0;
++    backup_state.speed = (has_speed && speed > 0) ? speed : 0;
++
++    backup_state.perf = (BackupPerf){ .max_workers = 16 };
++    if (has_max_workers) {
++        backup_state.perf.max_workers = max_workers;
++    }
 +
 +    backup_state.vmaw = vmaw;
 +    backup_state.pbs = pbs;
@@ -1317,8 +1523,36 @@ index 0000000000..f77892a509
 +    uuid_info = g_malloc0(sizeof(*uuid_info));
 +    uuid_info->UUID = uuid_str;
 +
-+    task->result = uuid_info;
-+    return;
++    /* Run create_backup_jobs_bh outside of coroutine (in BH) but keep
++    * backup_mutex locked. This is fine, a CoMutex can be held across yield
++    * points, and we'll release it as soon as the BH reschedules us.
++    */
++    CoCtxData waker = {
++        .co = qemu_coroutine_self(),
++        .ctx = qemu_get_current_aio_context(),
++        .data = &local_err,
++    };
++    aio_bh_schedule_oneshot(waker.ctx, create_backup_jobs_bh, &waker);
++    qemu_coroutine_yield();
++
++    if (local_err) {
++        error_propagate(errp, local_err);
++        goto err;
++    }
++
++    qemu_co_mutex_unlock(&backup_state.backup_mutex);
++
++    qemu_mutex_lock(&backup_state.stat.lock);
++    backup_state.stat.starting = false;
++    qemu_mutex_unlock(&backup_state.stat.lock);
++
++    /* start the first job in the transaction */
++    job_txn_start_seq(backup_state.txn);
++
++    return uuid_info;
++
++err_mutex:
++    qemu_mutex_unlock(&backup_state.stat.lock);
 +
 +err:
 +
@@ -1337,6 +1571,7 @@ index 0000000000..f77892a509
 +        g_free(di);
 +    }
 +    g_list_free(di_list);
++    backup_state.di_list = NULL;
 +
 +    if (devs) {
 +        g_strfreev(devs);
@@ -1345,66 +1580,20 @@ index 0000000000..f77892a509
 +    if (vmaw) {
 +        Error *err = NULL;
 +        vma_writer_close(vmaw, &err);
-+        unlink(task->backup_file);
++        unlink(backup_file);
 +    }
 +
 +    if (pbs) {
 +        proxmox_backup_disconnect(pbs);
++        backup_state.pbs = NULL;
 +    }
 +
 +    if (backup_dir) {
 +        rmdir(backup_dir);
 +    }
 +
-+    task->result = NULL;
-+    return;
-+}
-+
-+UuidInfo *qmp_backup(
-+    const char *backup_file,
-+    const char *password,
-+    const char *keyfile,
-+    const char *key_password,
-+    const char *fingerprint,
-+    const char *backup_id,
-+    bool has_backup_time, int64_t backup_time,
-+    bool has_format, BackupFormat format,
-+    const char *config_file,
-+    const char *firewall_file,
-+    const char *devlist,
-+    bool has_speed, int64_t speed, Error **errp)
-+{
-+    QmpBackupTask task = {
-+        .backup_file = backup_file,
-+        .password = password,
-+        .key_password = key_password,
-+        .fingerprint = fingerprint,
-+        .backup_id = backup_id,
-+        .has_backup_time = has_backup_time,
-+        .backup_time = backup_time,
-+        .has_format = has_format,
-+        .format = format,
-+        .config_file = config_file,
-+        .firewall_file = firewall_file,
-+        .devlist = devlist,
-+        .has_speed = has_speed,
-+        .speed = speed,
-+        .errp = errp,
-+    };
-+
-+    qemu_mutex_lock(&backup_state.backup_mutex);
-+
-+    block_on_coroutine_fn(pvebackup_co_prepare, &task);
-+
-+    if (*errp == NULL) {
-+        create_backup_jobs();
-+        qemu_mutex_unlock(&backup_state.backup_mutex);
-+        pvebackup_run_next_job();
-+    } else {
-+        qemu_mutex_unlock(&backup_state.backup_mutex);
-+    }
-+
-+    return task.result;
++    qemu_co_mutex_unlock(&backup_state.backup_mutex);
++    return NULL;
 +}
 +
 +BackupStatus *qmp_query_backup(Error **errp)
@@ -1443,20 +1632,67 @@ index 0000000000..f77892a509
 +
 +    info->has_total = true;
 +    info->total = backup_state.stat.total;
++    info->has_dirty = true;
++    info->dirty = backup_state.stat.dirty;
 +    info->has_zero_bytes = true;
 +    info->zero_bytes = backup_state.stat.zero_bytes;
 +    info->has_transferred = true;
 +    info->transferred = backup_state.stat.transferred;
++    info->has_reused = true;
++    info->reused = backup_state.stat.reused;
++    info->finishing = backup_state.stat.finishing;
 +
 +    qemu_mutex_unlock(&backup_state.stat.lock);
 +
 +    return info;
 +}
++
++PBSBitmapInfoList *qmp_query_pbs_bitmap_info(Error **errp)
++{
++    PBSBitmapInfoList *head = NULL, **p_next = &head;
++
++    qemu_mutex_lock(&backup_state.stat.lock);
++
++    GList *l = backup_state.stat.bitmap_list;
++    while (l) {
++        PBSBitmapInfo *info = (PBSBitmapInfo *)l->data;
++        l = g_list_next(l);
++
++        /* clone bitmap info to avoid auto free after QMP marshalling */
++        PBSBitmapInfo *info_ret = g_malloc0(sizeof(*info_ret));
++        info_ret->drive = g_strdup(info->drive);
++        info_ret->action = info->action;
++        info_ret->size = info->size;
++        info_ret->dirty = info->dirty;
++
++        PBSBitmapInfoList *info_list = g_malloc0(sizeof(*info_list));
++        info_list->value = info_ret;
++
++        *p_next = info_list;
++        p_next = &info_list->next;
++    }
++
++    qemu_mutex_unlock(&backup_state.stat.lock);
++
++    return head;
++}
++
++ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
++{
++    ProxmoxSupportStatus *ret = g_malloc0(sizeof(*ret));
++    ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
++    ret->pbs_dirty_bitmap = true;
++    ret->pbs_dirty_bitmap_savevm = true;
++    ret->query_bitmap_info = true;
++    ret->pbs_masterkey = true;
++    ret->backup_max_workers = true;
++    return ret;
++}
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 542add004b..16fb4c5ea0 100644
+index 542add004b..4ec70acf95 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -835,6 +835,115 @@
+@@ -835,6 +835,232 @@
  { 'command': 'query-block', 'returns': ['BlockInfo'],
    'allow-preconfig': true }
  
@@ -1473,8 +1709,13 @@ index 542add004b..16fb4c5ea0 100644
 +#
 +# @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.
++#
 +# @transferred: amount of bytes already backed up.
 +#
++# @reused: amount of bytes reused due to deduplication.
++#
 +# @zero-bytes: amount of 'zero' bytes detected.
 +#
 +# @start-time: time (epoch) when backup job started.
@@ -1485,12 +1726,15 @@ index 542add004b..16fb4c5ea0 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.
++#
 +##
 +{ 'struct': 'BackupStatus',
-+  'data': {'*status': 'str', '*errmsg': 'str', '*total': 'int',
-+           '*transferred': 'int', '*zero-bytes': 'int',
++  'data': {'*status': 'str', '*errmsg': 'str', '*total': 'int', '*dirty': 'int',
++           '*transferred': 'int', '*zero-bytes': 'int', '*reused': 'int',
 +           '*start-time': 'int', '*end-time': 'int',
-+           '*backup-file': 'str', '*uuid': 'str' } }
++           '*backup-file': 'str', '*uuid': 'str', 'finishing': 'bool' } }
 +
 +##
 +# @BackupFormat:
@@ -1525,12 +1769,24 @@ index 542add004b..16fb4c5ea0 100644
 +#
 +# @key-password: password for keyfile (optional for format 'pbs')
 +#
++# @master-keyfile: PEM-formatted master public keyfile (optional for format 'pbs')
++#
 +# @fingerprint: server cert fingerprint (optional for format 'pbs')
 +#
++# @backup-ns: backup namespace (required for format 'pbs')
++#
 +# @backup-id: backup ID (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')
++#
++# @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)
++#
++# @max-workers: see @BackupPerf for details. Default 16.
++#
 +# Returns: the uuid of the backup job
 +#
 +##
@@ -1538,14 +1794,21 @@ index 542add004b..16fb4c5ea0 100644
 +                                    '*password': 'str',
 +                                    '*keyfile': 'str',
 +                                    '*key-password': 'str',
++                                    '*master-keyfile': 'str',
 +                                    '*fingerprint': 'str',
++                                    '*backup-ns': 'str',
 +                                    '*backup-id': 'str',
 +                                    '*backup-time': 'int',
++                                    '*use-dirty-bitmap': 'bool',
++                                    '*compress': 'bool',
++                                    '*encrypt': 'bool',
 +                                    '*format': 'BackupFormat',
 +                                    '*config-file': 'str',
 +                                    '*firewall-file': 'str',
-+                                    '*devlist': 'str', '*speed': 'int' },
-+  'returns': 'UuidInfo' }
++                                    '*devlist': 'str',
++                                    '*speed': 'int',
++                                    '*max-workers': 'int' },
++  'returns': 'UuidInfo', 'coroutine': true }
 +
 +##
 +# @query-backup:
@@ -1567,7 +1830,97 @@ index 542add004b..16fb4c5ea0 100644
 +# Notes: This command succeeds even if there is no backup process running.
 +#
 +##
-+{ 'command': 'backup-cancel' }
++{ 'command': 'backup-cancel', 'coroutine': true }
++
++##
++# @ProxmoxSupportStatus:
++#
++# Contains info about supported features added by Proxmox.
++#
++# @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.
++#
++# @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-library-version: Running version of libproxmox-backup-qemu0 library.
++#
++##
++{ 'struct': 'ProxmoxSupportStatus',
++  'data': { 'pbs-dirty-bitmap': 'bool',
++            'query-bitmap-info': 'bool',
++            'pbs-dirty-bitmap-savevm': 'bool',
++            'pbs-masterkey': 'bool',
++            'pbs-library-version': 'str',
++            'backup-max-workers': 'bool' } }
++
++##
++# @query-proxmox-support:
++#
++# Returns information about supported features added by Proxmox.
++#
++# Returns: @ProxmoxSupportStatus
++#
++##
++{ 'command': 'query-proxmox-support', 'returns': 'ProxmoxSupportStatus' }
++
++##
++# @PBSBitmapAction:
++#
++# An action taken on a dirty-bitmap when a backup job was started.
++#
++# @not-used: Bitmap mode was not enabled.
++#
++# @not-used-removed: Bitmap mode was not enabled, but a bitmap from a
++#                    previous backup still existed and was removed.
++#
++# @new: A new bitmap was attached to the drive for this backup.
++#
++# @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.
++#
++##
++{ 'enum': 'PBSBitmapAction',
++  'data': ['not-used', 'not-used-removed', 'new', 'used', 'invalid'] }
++
++##
++# @PBSBitmapInfo:
++#
++# Contains information about dirty bitmaps used for each drive in a PBS backup.
++#
++# @drive: The underlying drive.
++#
++# @action: The action that was taken when the backup started.
++#
++# @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.
++#
++##
++{ 'struct': 'PBSBitmapInfo',
++  'data': { 'drive': 'str', 'action': 'PBSBitmapAction', 'size': 'int',
++            'dirty': 'int' } }
++
++##
++# @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: @PBSBitmapInfo
++#
++##
++{ 'command': 'query-pbs-bitmap-info', 'returns': ['PBSBitmapInfo'] }
 +
  ##
  # @BlockDeviceTimedStats:
diff --git a/debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch b/debian/patches/pve/0032-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
similarity index 90%
rename from debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
rename to debian/patches/pve/0032-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
index 4ee6100..1acb93d 100644
--- a/debian/patches/pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
+++ b/debian/patches/pve/0032-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
@@ -5,10 +5,12 @@ Subject: [PATCH] PVE-Backup: pbs-restore - new command to restore from proxmox
  backup server
 
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[WB: add namespace support]
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
 ---
  meson.build   |   4 +
- pbs-restore.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 227 insertions(+)
+ pbs-restore.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 240 insertions(+)
  create mode 100644 pbs-restore.c
 
 diff --git a/meson.build b/meson.build
@@ -28,10 +30,10 @@ index d307d8eabf..afd105001e 100644
    subdir('contrib/elf2dmp')
 diff --git a/pbs-restore.c b/pbs-restore.c
 new file mode 100644
-index 0000000000..2f834cf42e
+index 0000000000..f03d9bab8d
 --- /dev/null
 +++ b/pbs-restore.c
-@@ -0,0 +1,223 @@
+@@ -0,0 +1,236 @@
 +/*
 + * Qemu image restore helper for Proxmox Backup
 + *
@@ -63,7 +65,7 @@ index 0000000000..2f834cf42e
 +static void help(void)
 +{
 +    const char *help_msg =
-+        "usage: pbs-restore [--repository <repo>] snapshot archive-name target [command options]\n"
++        "usage: pbs-restore [--repository <repo>] [--ns namespace] snapshot archive-name target [command options]\n"
 +        ;
 +
 +    printf("%s", help_msg);
@@ -111,6 +113,7 @@ index 0000000000..2f834cf42e
 +    Error *main_loop_err = NULL;
 +    const char *format = "raw";
 +    const char *repository = NULL;
++    const char *backup_ns = NULL;
 +    const char *keyfile = NULL;
 +    int verbose = false;
 +    bool skip_zero = false;
@@ -124,6 +127,7 @@ index 0000000000..2f834cf42e
 +            {"verbose", no_argument, 0, 'v'},
 +            {"format", required_argument, 0, 'f'},
 +            {"repository", required_argument, 0, 'r'},
++            {"ns", required_argument, 0, 'n'},
 +            {"keyfile", required_argument, 0, 'k'},
 +            {0, 0, 0, 0}
 +        };
@@ -144,6 +148,9 @@ index 0000000000..2f834cf42e
 +            case 'r':
 +                repository = g_strdup(argv[optind - 1]);
 +                break;
++            case 'n':
++                backup_ns = g_strdup(argv[optind - 1]);
++                break;
 +            case 'k':
 +                keyfile = g_strdup(argv[optind - 1]);
 +                break;
@@ -194,8 +201,16 @@ index 0000000000..2f834cf42e
 +        fprintf(stderr, "connecting to repository '%s'\n", repository);
 +    }
 +    char *pbs_error = NULL;
-+    ProxmoxRestoreHandle *conn = proxmox_restore_new(
-+        repository, snapshot, password, keyfile, key_password, fingerprint, &pbs_error);
++    ProxmoxRestoreHandle *conn = proxmox_restore_new_ns(
++        repository,
++        snapshot,
++        backup_ns,
++        password,
++        keyfile,
++        key_password,
++        fingerprint,
++        &pbs_error
++    );
 +    if (conn == NULL) {
 +        fprintf(stderr, "restore failed: %s\n", pbs_error);
 +        return -1;
diff --git a/debian/patches/pve/0032-PVE-various-PBS-fixes.patch b/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
deleted file mode 100644
index c46a307..0000000
--- a/debian/patches/pve/0032-PVE-various-PBS-fixes.patch
+++ /dev/null
@@ -1,217 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dietmar Maurer <dietmar@proxmox.com>
-Date: Thu, 9 Jul 2020 12:53:08 +0200
-Subject: [PATCH] PVE: various PBS fixes
-
-pbs: fix crypt and compress parameters
-Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
-
-PVE: handle PBS write callback with big blocks correctly
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-
-PVE: add zero block handling to PBS dump callback
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: adapt to QAPI change dropping redundant has_*]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- block/monitor/block-hmp-cmds.c |  4 ++-
- pve-backup.c                   | 54 +++++++++++++++++++++++++++-------
- qapi/block-core.json           |  6 ++++
- 3 files changed, 52 insertions(+), 12 deletions(-)
-
-diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index cda5de792b..ecbebd39ac 100644
---- a/block/monitor/block-hmp-cmds.c
-+++ b/block/monitor/block-hmp-cmds.c
-@@ -1056,7 +1056,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
-         NULL, // PBS fingerprint
-         NULL, // PBS backup-id
-         false, 0, // PBS backup-time
--        false, false, // PBS incremental
-+        false, false, // PBS use-dirty-bitmap
-+        false, false, // PBS compress
-+        false, false, // PBS encrypt
-         true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
-         NULL, NULL,
-         devlist, qdict_haskey(qdict, "speed"), speed, &error);
-diff --git a/pve-backup.c b/pve-backup.c
-index d9942a14a1..8f18145255 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -10,6 +10,7 @@
- #include "block/dirty-bitmap.h"
- #include "qapi/qapi-commands-block.h"
- #include "qapi/qmp/qerror.h"
-+#include "qemu/cutils.h"
- 
- /* PVE backup state and related function */
- 
-@@ -69,6 +70,7 @@ opts_init(pvebackup_init);
- typedef struct PVEBackupDevInfo {
-     BlockDriverState *bs;
-     size_t size;
-+    uint64_t block_size;
-     uint8_t dev_id;
-     bool completed;
-     char targetfile[PATH_MAX];
-@@ -139,10 +141,13 @@ pvebackup_co_dump_pbs_cb(
-     PVEBackupDevInfo *di = opaque;
- 
-     assert(backup_state.pbs);
-+    assert(buf);
- 
-     Error *local_err = NULL;
-     int pbs_res = -1;
- 
-+    bool is_zero_block = size == di->block_size && buffer_is_zero(buf, size);
-+
-     qemu_co_mutex_lock(&backup_state.dump_callback_mutex);
- 
-     // avoid deadlock if job is cancelled
-@@ -151,17 +156,29 @@ pvebackup_co_dump_pbs_cb(
-         return -1;
-     }
- 
--    pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id, buf, start, size, &local_err);
--    qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
-+    uint64_t transferred = 0;
-+    uint64_t reused = 0;
-+    while (transferred < size) {
-+        uint64_t left = size - transferred;
-+        uint64_t to_transfer = left < di->block_size ? left : di->block_size;
- 
--    if (pbs_res < 0) {
--        pvebackup_propagate_error(local_err);
--        return pbs_res;
--    } else {
--        size_t reused = (pbs_res == 0) ? size : 0;
--        pvebackup_add_transfered_bytes(size, !buf ? size : 0, reused);
-+        pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id,
-+            is_zero_block ? NULL : buf + transferred, start + transferred,
-+            to_transfer, &local_err);
-+        transferred += to_transfer;
-+
-+        if (pbs_res < 0) {
-+            pvebackup_propagate_error(local_err);
-+            qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
-+            return pbs_res;
-+        }
-+
-+        reused += pbs_res == 0 ? to_transfer : 0;
-     }
- 
-+    qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
-+    pvebackup_add_transfered_bytes(size, is_zero_block ? size : 0, reused);
-+
-     return size;
- }
- 
-@@ -182,6 +199,7 @@ pvebackup_co_dump_vma_cb(
-     int ret = -1;
- 
-     assert(backup_state.vmaw);
-+    assert(buf);
- 
-     uint64_t remaining = size;
- 
-@@ -208,9 +226,7 @@ pvebackup_co_dump_vma_cb(
-         qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
- 
-         ++cluster_num;
--        if (buf) {
--            buf += VMA_CLUSTER_SIZE;
--        }
-+        buf += VMA_CLUSTER_SIZE;
-         if (ret < 0) {
-             Error *local_err = NULL;
-             vma_writer_error_propagate(backup_state.vmaw, &local_err);
-@@ -560,6 +576,10 @@ typedef struct QmpBackupTask {
-     const char *config_file;
-     const char *firewall_file;
-     const char *devlist;
-+    bool has_compress;
-+    bool compress;
-+    bool has_encrypt;
-+    bool encrypt;
-     bool has_speed;
-     int64_t speed;
-     Error **errp;
-@@ -683,6 +703,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
- 
-         bool use_dirty_bitmap = task->has_use_dirty_bitmap && task->use_dirty_bitmap;
- 
-+
-         char *pbs_err = NULL;
-         pbs = proxmox_backup_new(
-             task->backup_file,
-@@ -692,6 +713,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             task->password,
-             task->keyfile,
-             task->key_password,
-+            task->has_compress ? task->compress : true,
-+            task->has_encrypt ? task->encrypt : !!task->keyfile,
-             task->fingerprint,
-             &pbs_err);
- 
-@@ -712,6 +735,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-             l = g_list_next(l);
- 
-+            di->block_size = dump_cb_block_size;
-+
-             const char *devname = bdrv_get_device_name(di->bs);
- 
-             BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
-@@ -932,6 +957,8 @@ UuidInfo *qmp_backup(
-     const char *backup_id,
-     bool has_backup_time, int64_t backup_time,
-     bool has_use_dirty_bitmap, bool use_dirty_bitmap,
-+    bool has_compress, bool compress,
-+    bool has_encrypt, bool encrypt,
-     bool has_format, BackupFormat format,
-     const char *config_file,
-     const char *firewall_file,
-@@ -941,6 +968,7 @@ UuidInfo *qmp_backup(
-     QmpBackupTask task = {
-         .backup_file = backup_file,
-         .password = password,
-+        .keyfile = keyfile,
-         .key_password = key_password,
-         .fingerprint = fingerprint,
-         .backup_id = backup_id,
-@@ -948,6 +976,10 @@ UuidInfo *qmp_backup(
-         .backup_time = backup_time,
-         .has_use_dirty_bitmap = has_use_dirty_bitmap,
-         .use_dirty_bitmap = use_dirty_bitmap,
-+        .has_compress = has_compress,
-+        .compress = compress,
-+        .has_encrypt = has_encrypt,
-+        .encrypt = encrypt,
-         .has_format = has_format,
-         .format = format,
-         .config_file = config_file,
-diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 92f90a898a..864b8ce97c 100644
---- a/qapi/block-core.json
-+++ b/qapi/block-core.json
-@@ -913,6 +913,10 @@
- #
- # @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)
-+#
-+# @encrypt: use encryption ((optional for format 'pbs', defaults to true if there is a keyfile)
-+#
- # Returns: the uuid of the backup job
- #
- ##
-@@ -924,6 +928,8 @@
-                                     '*backup-id': 'str',
-                                     '*backup-time': 'int',
-                                     '*use-dirty-bitmap': 'bool',
-+                                    '*compress': 'bool',
-+                                    '*encrypt': 'bool',
-                                     '*format': 'BackupFormat',
-                                     '*config-file': 'str',
-                                     '*firewall-file': 'str',
diff --git a/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch b/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
index d7868e1..9c9dc26 100644
--- a/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
+++ b/debian/patches/pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
@@ -7,18 +7,20 @@ Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 [error cleanups, file_open implementation]
 Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[WB: add namespace support]
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
 [FE: adapt to changed function signatures
      make pbs_co_preadv return values consistent with QEMU
      getlength is now a coroutine function]
 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
  block/meson.build    |   3 +
- block/pbs.c          | 277 +++++++++++++++++++++++++++++++++++++++++++
+ block/pbs.c          | 305 +++++++++++++++++++++++++++++++++++++++++++
  configure            |   9 ++
  meson.build          |   2 +-
  qapi/block-core.json |  13 ++
  qapi/pragma.json     |   1 +
- 6 files changed, 304 insertions(+), 1 deletion(-)
+ 6 files changed, 332 insertions(+), 1 deletion(-)
  create mode 100644 block/pbs.c
 
 diff --git a/block/meson.build b/block/meson.build
@@ -37,10 +39,10 @@ index 5bcebb934b..eece0d5743 100644
  softmmu_ss.add(files('block-ram-registrar.c'))
 diff --git a/block/pbs.c b/block/pbs.c
 new file mode 100644
-index 0000000000..43e69ada46
+index 0000000000..a2211e0f3b
 --- /dev/null
 +++ b/block/pbs.c
-@@ -0,0 +1,277 @@
+@@ -0,0 +1,305 @@
 +/*
 + * Proxmox Backup Server read-only block driver
 + */
@@ -58,6 +60,7 @@ index 0000000000..43e69ada46
 +#include <proxmox-backup-qemu.h>
 +
 +#define PBS_OPT_REPOSITORY "repository"
++#define PBS_OPT_NAMESPACE "namespace"
 +#define PBS_OPT_SNAPSHOT "snapshot"
 +#define PBS_OPT_ARCHIVE "archive"
 +#define PBS_OPT_KEYFILE "keyfile"
@@ -71,6 +74,7 @@ index 0000000000..43e69ada46
 +    int64_t length;
 +
 +    char *repository;
++    char *namespace;
 +    char *snapshot;
 +    char *archive;
 +} BDRVPBSState;
@@ -85,6 +89,11 @@ index 0000000000..43e69ada46
 +            .help = "The server address and repository to connect to.",
 +        },
 +        {
++            .name = PBS_OPT_NAMESPACE,
++            .type = QEMU_OPT_STRING,
++            .help = "Optional: The snapshot's namespace.",
++        },
++        {
 +            .name = PBS_OPT_SNAPSHOT,
 +            .type = QEMU_OPT_STRING,
 +            .help = "The snapshot to read.",
@@ -120,7 +129,7 @@ index 0000000000..43e69ada46
 +
 +
 +// filename format:
-+// pbs:repository=<repo>,snapshot=<snap>,password=<pw>,key_password=<kpw>,fingerprint=<fp>,archive=<archive>
++// pbs:repository=<repo>,namespace=<ns>,snapshot=<snap>,password=<pw>,key_password=<kpw>,fingerprint=<fp>,archive=<archive>
 +static void pbs_parse_filename(const char *filename, QDict *options,
 +                                     Error **errp)
 +{
@@ -156,6 +165,7 @@ index 0000000000..43e69ada46
 +    s->archive = g_strdup(qemu_opt_get(opts, PBS_OPT_ARCHIVE));
 +    const char *keyfile = qemu_opt_get(opts, PBS_OPT_KEYFILE);
 +    const char *password = qemu_opt_get(opts, PBS_OPT_PASSWORD);
++    const char *namespace = qemu_opt_get(opts, PBS_OPT_NAMESPACE);
 +    const char *fingerprint = qemu_opt_get(opts, PBS_OPT_FINGERPRINT);
 +    const char *key_password = qemu_opt_get(opts, PBS_OPT_ENCRYPTION_PASSWORD);
 +
@@ -168,9 +178,12 @@ index 0000000000..43e69ada46
 +    if (!key_password) {
 +        key_password = getenv("PBS_ENCRYPTION_PASSWORD");
 +    }
++    if (namespace) {
++        s->namespace = g_strdup(namespace);
++    }
 +
 +    /* connect to PBS server in read mode */
-+    s->conn = proxmox_restore_new(s->repository, s->snapshot, password,
++    s->conn = proxmox_restore_new_ns(s->repository, s->snapshot, s->namespace, password,
 +        keyfile, key_password, fingerprint, &pbs_error);
 +
 +    /* invalidates qemu_opt_get char pointers from above */
@@ -215,6 +228,7 @@ index 0000000000..43e69ada46
 +static void pbs_close(BlockDriverState *bs) {
 +    BDRVPBSState *s = bs->opaque;
 +    g_free(s->repository);
++    g_free(s->namespace);
 +    g_free(s->snapshot);
 +    g_free(s->archive);
 +    proxmox_restore_disconnect(s->conn);
@@ -244,7 +258,16 @@ index 0000000000..43e69ada46
 +    BDRVPBSState *s = bs->opaque;
 +    int ret;
 +    char *pbs_error = NULL;
-+    uint8_t *buf = malloc(bytes);
++    uint8_t *buf;
++    bool inline_buf = true;
++
++    /* for single-buffer IO vectors we can fast-path the write directly to it */
++    if (qiov->niov == 1 && qiov->iov->iov_len >= bytes) {
++        buf = qiov->iov->iov_base;
++    } else {
++        inline_buf = false;
++        buf = g_malloc(bytes);
++    }
 +
 +    if (offset < 0 || bytes < 0) {
 +        fprintf(stderr, "unexpected negative 'offset' or 'bytes' value!\n");
@@ -267,8 +290,10 @@ index 0000000000..43e69ada46
 +        return -EIO;
 +    }
 +
-+    qemu_iovec_from_buf(qiov, 0, buf, bytes);
-+    free(buf);
++    if (!inline_buf) {
++        qemu_iovec_from_buf(qiov, 0, buf, bytes);
++        g_free(buf);
++    }
 +
 +    return 0;
 +}
@@ -285,8 +310,13 @@ index 0000000000..43e69ada46
 +static void pbs_refresh_filename(BlockDriverState *bs)
 +{
 +    BDRVPBSState *s = bs->opaque;
-+    snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s/%s(%s)",
-+             s->repository, s->snapshot, s->archive);
++    if (s->namespace) {
++        snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s/%s:%s(%s)",
++                 s->repository, s->namespace, s->snapshot, s->archive);
++    } else {
++        snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s/%s(%s)",
++                 s->repository, s->snapshot, s->archive);
++    }
 +}
 +
 +static const char *const pbs_strong_runtime_opts[] = {
@@ -373,10 +403,10 @@ index afd105001e..d01ee5d489 100644
  summary_info += {'libdaxctl support': libdaxctl}
  summary_info += {'libudev':           libudev}
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 864b8ce97c..705a65ab1a 100644
+index 4ec70acf95..47118bf83e 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -3198,6 +3198,7 @@
+@@ -3301,6 +3301,7 @@
              'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum',
              'raw', 'rbd',
              { 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
@@ -384,7 +414,7 @@ index 864b8ce97c..705a65ab1a 100644
              'ssh', 'throttle', 'vdi', 'vhdx',
              { 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' },
              { 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' },
-@@ -3274,6 +3275,17 @@
+@@ -3377,6 +3378,17 @@
  { 'struct': 'BlockdevOptionsNull',
    'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } }
  
@@ -397,12 +427,12 @@ index 864b8ce97c..705a65ab1a 100644
 +{ 'struct': 'BlockdevOptionsPbs',
 +  'data': { 'repository': 'str', 'snapshot': 'str', 'archive': 'str',
 +            '*keyfile': 'str', '*password': 'str', '*fingerprint': 'str',
-+            '*key_password': 'str' } }
++            '*key_password': 'str', '*namespace': 'str' } }
 +
  ##
  # @BlockdevOptionsNVMe:
  #
-@@ -4647,6 +4659,7 @@
+@@ -4750,6 +4762,7 @@
        'nfs':        'BlockdevOptionsNfs',
        'null-aio':   'BlockdevOptionsNull',
        'null-co':    'BlockdevOptionsNull',
diff --git a/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch b/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
deleted file mode 100644
index 0b14e6f..0000000
--- a/debian/patches/pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter@proxmox.com>
-Date: Wed, 8 Jul 2020 11:57:53 +0200
-Subject: [PATCH] PVE: add query_proxmox_support QMP command
-
-Generic interface for future use, currently used for PBS dirty-bitmap
-backup support.
-
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[PVE: query-proxmox-support: include library version]
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
----
- pve-backup.c         |  9 +++++++++
- qapi/block-core.json | 29 +++++++++++++++++++++++++++++
- 2 files changed, 38 insertions(+)
-
-diff --git a/pve-backup.c b/pve-backup.c
-index 8f18145255..1400c21c49 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -1054,3 +1054,12 @@ BackupStatus *qmp_query_backup(Error **errp)
- 
-     return info;
- }
-+
-+ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
-+{
-+    ProxmoxSupportStatus *ret = g_malloc0(sizeof(*ret));
-+    ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
-+    ret->pbs_dirty_bitmap = true;
-+    ret->pbs_dirty_bitmap_savevm = true;
-+    return ret;
-+}
-diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 705a65ab1a..1ac535fcf2 100644
---- a/qapi/block-core.json
-+++ b/qapi/block-core.json
-@@ -958,6 +958,35 @@
- ##
- { 'command': 'backup-cancel' }
- 
-+##
-+# @ProxmoxSupportStatus:
-+#
-+# Contains info about supported features added by Proxmox.
-+#
-+# @pbs-dirty-bitmap: True if dirty-bitmap-incremental backups to PBS are
-+#                    supported.
-+#
-+# @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
-+#                           safely be set for savevm-async.
-+#
-+# @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
-+#
-+##
-+{ 'struct': 'ProxmoxSupportStatus',
-+  'data': { 'pbs-dirty-bitmap': 'bool',
-+            'pbs-dirty-bitmap-savevm': 'bool',
-+            'pbs-library-version': 'str' } }
-+
-+##
-+# @query-proxmox-support:
-+#
-+# Returns information about supported features added by Proxmox.
-+#
-+# Returns: @ProxmoxSupportStatus
-+#
-+##
-+{ 'command': 'query-proxmox-support', 'returns': 'ProxmoxSupportStatus' }
-+
- ##
- # @BlockDeviceTimedStats:
- #
diff --git a/debian/patches/pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch b/debian/patches/pve/0034-PVE-redirect-stderr-to-journal-when-daemonized.patch
similarity index 100%
rename from debian/patches/pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch
rename to debian/patches/pve/0034-PVE-redirect-stderr-to-journal-when-daemonized.patch
diff --git a/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch b/debian/patches/pve/0035-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
similarity index 93%
rename from debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
rename to debian/patches/pve/0035-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
index 644afc2..a3d7386 100644
--- a/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
+++ b/debian/patches/pve/0035-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
@@ -175,22 +175,22 @@ index 0000000000..887e998b9e
 +                         NULL);
 +}
 diff --git a/pve-backup.c b/pve-backup.c
-index 1da9dd9edc..e0e38063a8 100644
+index dd72ee0ed6..cb5312fff3 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
-@@ -1110,6 +1110,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
+@@ -1090,6 +1090,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
      ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
      ret->pbs_dirty_bitmap = true;
      ret->pbs_dirty_bitmap_savevm = true;
 +    ret->pbs_dirty_bitmap_migration = true;
      ret->query_bitmap_info = true;
-     return ret;
- }
+     ret->pbs_masterkey = true;
+     ret->backup_max_workers = true;
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 43838212e3..e7412f6322 100644
+index 47118bf83e..809f3c61bc 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -974,6 +974,11 @@
+@@ -984,6 +984,11 @@
  # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
  #                           safely be set for savevm-async.
  #
@@ -199,14 +199,14 @@ index 43838212e3..e7412f6322 100644
 +#                              migration cap if this is false/unset may lead
 +#                              to crashes on migration!
 +#
- # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
+ # @pbs-masterkey: True if the QMP backup call supports the 'master_keyfile'
+ #                 parameter.
  #
- ##
-@@ -981,6 +986,7 @@
+@@ -994,6 +999,7 @@
    'data': { 'pbs-dirty-bitmap': 'bool',
              'query-bitmap-info': 'bool',
              'pbs-dirty-bitmap-savevm': 'bool',
 +            'pbs-dirty-bitmap-migration': 'bool',
-             'pbs-library-version': 'str' } }
- 
- ##
+             'pbs-masterkey': 'bool',
+             'pbs-library-version': 'str',
+             'backup-max-workers': 'bool' } }
diff --git a/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch b/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
deleted file mode 100644
index 2e0f235..0000000
--- a/debian/patches/pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
+++ /dev/null
@@ -1,441 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter@proxmox.com>
-Date: Wed, 19 Aug 2020 17:02:00 +0200
-Subject: [PATCH] PVE: add query-pbs-bitmap-info QMP call
-
-Returns advanced information about dirty bitmaps used (or not used) for
-the latest PBS backup.
-
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
----
- monitor/hmp-cmds.c   |  28 ++++++-----
- pve-backup.c         | 117 ++++++++++++++++++++++++++++++++-----------
- qapi/block-core.json |  56 +++++++++++++++++++++
- 3 files changed, 159 insertions(+), 42 deletions(-)
-
-diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 087161a967..9a67e544ce 100644
---- a/monitor/hmp-cmds.c
-+++ b/monitor/hmp-cmds.c
-@@ -148,6 +148,7 @@ void hmp_sync_profile(Monitor *mon, const QDict *qdict)
- void hmp_info_backup(Monitor *mon, const QDict *qdict)
- {
-     BackupStatus *info;
-+    PBSBitmapInfoList *bitmap_info;
- 
-     info = qmp_query_backup(NULL);
- 
-@@ -178,26 +179,29 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
-             // this should not happen normally
-             monitor_printf(mon, "Total size: %d\n", 0);
-         } else {
--            bool incremental = false;
-             size_t total_or_dirty = info->total;
--            if (info->has_transferred) {
--                if (info->has_dirty && info->dirty) {
--                     if (info->dirty < info->total) {
--                        total_or_dirty = info->dirty;
--                        incremental = true;
--                    }
--                }
-+            bitmap_info = qmp_query_pbs_bitmap_info(NULL);
-+
-+            while (bitmap_info) {
-+                monitor_printf(mon, "Drive %s:\n",
-+                        bitmap_info->value->drive);
-+                monitor_printf(mon, "  bitmap action: %s\n",
-+                        PBSBitmapAction_str(bitmap_info->value->action));
-+                monitor_printf(mon, "  size: %zd\n",
-+                        bitmap_info->value->size);
-+                monitor_printf(mon, "  dirty: %zd\n",
-+                        bitmap_info->value->dirty);
-+                bitmap_info = bitmap_info->next;
-             }
- 
--            int per = (info->transferred * 100)/total_or_dirty;
--
--            monitor_printf(mon, "Backup mode: %s\n", incremental ? "incremental" : "full");
-+            qapi_free_PBSBitmapInfoList(bitmap_info);
- 
-             int zero_per = (info->has_zero_bytes && info->zero_bytes) ?
-                 (info->zero_bytes * 100)/info->total : 0;
-             monitor_printf(mon, "Total size: %zd\n", info->total);
-+            int trans_per = (info->transferred * 100)/total_or_dirty;
-             monitor_printf(mon, "Transferred bytes: %zd (%d%%)\n",
--                           info->transferred, per);
-+                           info->transferred, trans_per);
-             monitor_printf(mon, "Zero bytes: %zd (%d%%)\n",
-                            info->zero_bytes, zero_per);
- 
-diff --git a/pve-backup.c b/pve-backup.c
-index 1400c21c49..0a0996b971 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -48,6 +48,7 @@ static struct PVEBackupState {
-         size_t transferred;
-         size_t reused;
-         size_t zero_bytes;
-+        GList *bitmap_list;
-     } stat;
-     int64_t speed;
-     VmaWriter *vmaw;
-@@ -663,7 +664,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     }
- 
-     size_t total = 0;
--    size_t dirty = 0;
- 
-     l = di_list;
-     while (l) {
-@@ -684,18 +684,33 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
- 
-     uuid_generate(uuid);
- 
-+    qemu_mutex_lock(&backup_state.stat.lock);
-+    backup_state.stat.reused = 0;
-+
-+    /* clear previous backup's bitmap_list */
-+    if (backup_state.stat.bitmap_list) {
-+        GList *bl = backup_state.stat.bitmap_list;
-+        while (bl) {
-+            g_free(((PBSBitmapInfo *)bl->data)->drive);
-+            g_free(bl->data);
-+            bl = g_list_next(bl);
-+        }
-+        g_list_free(backup_state.stat.bitmap_list);
-+        backup_state.stat.bitmap_list = NULL;
-+    }
-+
-     if (format == BACKUP_FORMAT_PBS) {
-         if (!task->password) {
-             error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
--            goto err;
-+            goto err_mutex;
-         }
-         if (!task->backup_id) {
-             error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
--            goto err;
-+            goto err_mutex;
-         }
-         if (!task->has_backup_time) {
-             error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-time'");
--            goto err;
-+            goto err_mutex;
-         }
- 
-         int dump_cb_block_size = PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE; // Hardcoded (4M)
-@@ -722,12 +737,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
-                       "proxmox_backup_new failed: %s", pbs_err);
-             proxmox_backup_free_error(pbs_err);
--            goto err;
-+            goto err_mutex;
-         }
- 
-         int connect_result = proxmox_backup_co_connect(pbs, task->errp);
-         if (connect_result < 0)
--            goto err;
-+            goto err_mutex;
- 
-         /* register all devices */
-         l = di_list;
-@@ -738,6 +753,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             di->block_size = dump_cb_block_size;
- 
-             const char *devname = bdrv_get_device_name(di->bs);
-+            PBSBitmapAction action = PBS_BITMAP_ACTION_NOT_USED;
-+            size_t dirty = di->size;
- 
-             BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
-             bool expect_only_dirty = false;
-@@ -746,49 +763,59 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-                 if (bitmap == NULL) {
-                     bitmap = bdrv_create_dirty_bitmap(di->bs, dump_cb_block_size, PBS_BITMAP_NAME, task->errp);
-                     if (!bitmap) {
--                        goto err;
-+                        goto err_mutex;
-                     }
-+                    action = PBS_BITMAP_ACTION_NEW;
-                 } else {
-                     expect_only_dirty = proxmox_backup_check_incremental(pbs, devname, di->size) != 0;
-                 }
- 
-                 if (expect_only_dirty) {
--                    dirty += bdrv_get_dirty_count(bitmap);
-+                    /* track clean chunks as reused */
-+                    dirty = MIN(bdrv_get_dirty_count(bitmap), di->size);
-+                    backup_state.stat.reused += di->size - dirty;
-+                    action = PBS_BITMAP_ACTION_USED;
-                 } else {
-                     /* mark entire bitmap as dirty to make full backup */
-                     bdrv_set_dirty_bitmap(bitmap, 0, di->size);
--                    dirty += di->size;
-+                    if (action != PBS_BITMAP_ACTION_NEW) {
-+                        action = PBS_BITMAP_ACTION_INVALID;
-+                    }
-                 }
-                 di->bitmap = bitmap;
-             } else {
--                dirty += di->size;
--
-                 /* after a full backup the old dirty bitmap is invalid anyway */
-                 if (bitmap != NULL) {
-                     bdrv_release_dirty_bitmap(bitmap);
-+                    action = PBS_BITMAP_ACTION_NOT_USED_REMOVED;
-                 }
-             }
- 
-             int dev_id = proxmox_backup_co_register_image(pbs, devname, di->size, expect_only_dirty, task->errp);
-             if (dev_id < 0) {
--                goto err;
-+                goto err_mutex;
-             }
- 
-             if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, task->errp))) {
--                goto err;
-+                goto err_mutex;
-             }
- 
-             di->dev_id = dev_id;
-+
-+            PBSBitmapInfo *info = g_malloc(sizeof(*info));
-+            info->drive = g_strdup(devname);
-+            info->action = action;
-+            info->size = di->size;
-+            info->dirty = dirty;
-+            backup_state.stat.bitmap_list = g_list_append(backup_state.stat.bitmap_list, info);
-         }
-     } else if (format == BACKUP_FORMAT_VMA) {
--        dirty = total;
--
-         vmaw = vma_writer_create(task->backup_file, uuid, &local_err);
-         if (!vmaw) {
-             if (local_err) {
-                 error_propagate(task->errp, local_err);
-             }
--            goto err;
-+            goto err_mutex;
-         }
- 
-         /* register all devices for vma writer */
-@@ -798,7 +825,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             l = g_list_next(l);
- 
-             if (!(di->target = bdrv_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, task->errp))) {
--                goto err;
-+                goto err_mutex;
-             }
- 
-             const char *devname = bdrv_get_device_name(di->bs);
-@@ -806,16 +833,14 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             if (di->dev_id <= 0) {
-                 error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
-                           "register_stream failed");
--                goto err;
-+                goto err_mutex;
-             }
-         }
-     } else if (format == BACKUP_FORMAT_DIR) {
--        dirty = total;
--
-         if (mkdir(task->backup_file, 0640) != 0) {
-             error_setg_errno(task->errp, errno, "can't create directory '%s'\n",
-                              task->backup_file);
--            goto err;
-+            goto err_mutex;
-         }
-         backup_dir = task->backup_file;
- 
-@@ -832,18 +857,18 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-                             di->size, flags, false, &local_err);
-             if (local_err) {
-                 error_propagate(task->errp, local_err);
--                goto err;
-+                goto err_mutex;
-             }
- 
-             di->target = bdrv_co_open(di->targetfile, NULL, NULL, flags, &local_err);
-             if (!di->target) {
-                 error_propagate(task->errp, local_err);
--                goto err;
-+                goto err_mutex;
-             }
-         }
-     } else {
-         error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
--        goto err;
-+        goto err_mutex;
-     }
- 
- 
-@@ -851,7 +876,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     if (task->config_file) {
-         if (pvebackup_co_add_config(task->config_file, config_name, format, backup_dir,
-                                     vmaw, pbs, task->errp) != 0) {
--            goto err;
-+            goto err_mutex;
-         }
-     }
- 
-@@ -859,12 +884,11 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     if (task->firewall_file) {
-         if (pvebackup_co_add_config(task->firewall_file, firewall_name, format, backup_dir,
-                                     vmaw, pbs, task->errp) != 0) {
--            goto err;
-+            goto err_mutex;
-         }
-     }
-     /* initialize global backup_state now */
--
--    qemu_mutex_lock(&backup_state.stat.lock);
-+    /* note: 'reused' and 'bitmap_list' are initialized earlier */
- 
-     if (backup_state.stat.error) {
-         error_free(backup_state.stat.error);
-@@ -884,10 +908,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     char *uuid_str = g_strdup(backup_state.stat.uuid_str);
- 
-     backup_state.stat.total = total;
--    backup_state.stat.dirty = dirty;
-+    backup_state.stat.dirty = total - backup_state.stat.reused;
-     backup_state.stat.transferred = 0;
-     backup_state.stat.zero_bytes = 0;
--    backup_state.stat.reused = format == BACKUP_FORMAT_PBS && dirty >= total ? 0 : total - dirty;
- 
-     qemu_mutex_unlock(&backup_state.stat.lock);
- 
-@@ -904,6 +927,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     task->result = uuid_info;
-     return;
- 
-+err_mutex:
-+    qemu_mutex_unlock(&backup_state.stat.lock);
-+
- err:
- 
-     l = di_list;
-@@ -1055,11 +1081,42 @@ BackupStatus *qmp_query_backup(Error **errp)
-     return info;
- }
- 
-+PBSBitmapInfoList *qmp_query_pbs_bitmap_info(Error **errp)
-+{
-+    PBSBitmapInfoList *head = NULL, **p_next = &head;
-+
-+    qemu_mutex_lock(&backup_state.stat.lock);
-+
-+    GList *l = backup_state.stat.bitmap_list;
-+    while (l) {
-+        PBSBitmapInfo *info = (PBSBitmapInfo *)l->data;
-+        l = g_list_next(l);
-+
-+        /* clone bitmap info to avoid auto free after QMP marshalling */
-+        PBSBitmapInfo *info_ret = g_malloc0(sizeof(*info_ret));
-+        info_ret->drive = g_strdup(info->drive);
-+        info_ret->action = info->action;
-+        info_ret->size = info->size;
-+        info_ret->dirty = info->dirty;
-+
-+        PBSBitmapInfoList *info_list = g_malloc0(sizeof(*info_list));
-+        info_list->value = info_ret;
-+
-+        *p_next = info_list;
-+        p_next = &info_list->next;
-+    }
-+
-+    qemu_mutex_unlock(&backup_state.stat.lock);
-+
-+    return head;
-+}
-+
- ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
- {
-     ProxmoxSupportStatus *ret = g_malloc0(sizeof(*ret));
-     ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
-     ret->pbs_dirty_bitmap = true;
-     ret->pbs_dirty_bitmap_savevm = true;
-+    ret->query_bitmap_info = true;
-     return ret;
- }
-diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 1ac535fcf2..130d5f065f 100644
---- a/qapi/block-core.json
-+++ b/qapi/block-core.json
-@@ -966,6 +966,8 @@
- # @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.
-+#
- # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
- #                           safely be set for savevm-async.
- #
-@@ -974,6 +976,7 @@
- ##
- { 'struct': 'ProxmoxSupportStatus',
-   'data': { 'pbs-dirty-bitmap': 'bool',
-+            'query-bitmap-info': 'bool',
-             'pbs-dirty-bitmap-savevm': 'bool',
-             'pbs-library-version': 'str' } }
- 
-@@ -987,6 +990,59 @@
- ##
- { 'command': 'query-proxmox-support', 'returns': 'ProxmoxSupportStatus' }
- 
-+##
-+# @PBSBitmapAction:
-+#
-+# An action taken on a dirty-bitmap when a backup job was started.
-+#
-+# @not-used: Bitmap mode was not enabled.
-+#
-+# @not-used-removed: Bitmap mode was not enabled, but a bitmap from a
-+#                    previous backup still existed and was removed.
-+#
-+# @new: A new bitmap was attached to the drive for this backup.
-+#
-+# @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.
-+#
-+##
-+{ 'enum': 'PBSBitmapAction',
-+  'data': ['not-used', 'not-used-removed', 'new', 'used', 'invalid'] }
-+
-+##
-+# @PBSBitmapInfo:
-+#
-+# Contains information about dirty bitmaps used for each drive in a PBS backup.
-+#
-+# @drive: The underlying drive.
-+#
-+# @action: The action that was taken when the backup started.
-+#
-+# @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.
-+#
-+##
-+{ 'struct': 'PBSBitmapInfo',
-+  'data': { 'drive': 'str', 'action': 'PBSBitmapAction', 'size': 'int',
-+            'dirty': 'int' } }
-+
-+##
-+# @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: @PBSBitmapInfo
-+#
-+##
-+{ 'command': 'query-pbs-bitmap-info', 'returns': ['PBSBitmapInfo'] }
-+
- ##
- # @BlockDeviceTimedStats:
- #
diff --git a/debian/patches/pve/0041-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch b/debian/patches/pve/0036-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
similarity index 100%
rename from debian/patches/pve/0041-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
rename to debian/patches/pve/0036-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
diff --git a/debian/patches/pve/0042-PVE-fall-back-to-open-iscsi-initiatorname.patch b/debian/patches/pve/0037-PVE-fall-back-to-open-iscsi-initiatorname.patch
similarity index 100%
rename from debian/patches/pve/0042-PVE-fall-back-to-open-iscsi-initiatorname.patch
rename to debian/patches/pve/0037-PVE-fall-back-to-open-iscsi-initiatorname.patch
diff --git a/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch b/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
deleted file mode 100644
index 7a5cda5..0000000
--- a/debian/patches/pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
+++ /dev/null
@@ -1,293 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter@proxmox.com>
-Date: Thu, 20 Aug 2020 14:25:00 +0200
-Subject: [PATCH] PVE-Backup: Use a transaction to synchronize job states
-
-By using a JobTxn, we can sync dirty bitmaps only when *all* jobs were
-successful - meaning we don't need to remove them when the backup fails,
-since QEMU's BITMAP_SYNC_MODE_ON_SUCCESS will now handle that for us.
-
-To keep the rate-limiting and IO impact from before, we use a sequential
-transaction, so drives will still be backed up one after the other.
-
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: add new force parameter to job_cancel_sync calls
-     adapt for new job lock mechanism replacing AioContext locks]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- pve-backup.c | 163 ++++++++++++++++-----------------------------------
- 1 file changed, 50 insertions(+), 113 deletions(-)
-
-diff --git a/pve-backup.c b/pve-backup.c
-index 0a0996b971..629da3e6c7 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -54,6 +54,7 @@ static struct PVEBackupState {
-     VmaWriter *vmaw;
-     ProxmoxBackupHandle *pbs;
-     GList *di_list;
-+    JobTxn *txn;
-     QemuMutex backup_mutex;
-     CoMutex dump_callback_mutex;
- } backup_state;
-@@ -73,34 +74,12 @@ typedef struct PVEBackupDevInfo {
-     size_t size;
-     uint64_t block_size;
-     uint8_t dev_id;
--    bool completed;
-     char targetfile[PATH_MAX];
-     BdrvDirtyBitmap *bitmap;
-     BlockDriverState *target;
-+    BlockJob *job;
- } PVEBackupDevInfo;
- 
--static void pvebackup_run_next_job(void);
--
--static BlockJob *
--lookup_active_block_job(PVEBackupDevInfo *di)
--{
--    if (!di->completed && di->bs) {
--        WITH_JOB_LOCK_GUARD() {
--            for (BlockJob *job = block_job_next_locked(NULL); job; job = block_job_next_locked(job)) {
--                if (job->job.driver->job_type != JOB_TYPE_BACKUP) {
--                    continue;
--                }
--
--                BackupBlockJob *bjob = container_of(job, BackupBlockJob, common);
--                if (bjob && bjob->source_bs == di->bs) {
--                    return job;
--                }
--            }
--        }
--    }
--    return NULL;
--}
--
- static void pvebackup_propagate_error(Error *err)
- {
-     qemu_mutex_lock(&backup_state.stat.lock);
-@@ -276,18 +255,6 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
-             if (local_err != NULL) {
-                 pvebackup_propagate_error(local_err);
-             }
--        } else {
--            // on error or cancel we cannot ensure synchronization of dirty
--            // bitmaps with backup server, so remove all and do full backup next
--            GList *l = backup_state.di_list;
--            while (l) {
--                PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
--                l = g_list_next(l);
--
--                if (di->bitmap) {
--                    bdrv_release_dirty_bitmap(di->bitmap);
--                }
--            }
-         }
- 
-         proxmox_backup_disconnect(backup_state.pbs);
-@@ -326,8 +293,6 @@ static void pvebackup_complete_cb(void *opaque, int ret)
- 
-     qemu_mutex_lock(&backup_state.backup_mutex);
- 
--    di->completed = true;
--
-     if (ret < 0) {
-         Error *local_err = NULL;
-         error_setg(&local_err, "job failed with err %d - %s", ret, strerror(-ret));
-@@ -340,20 +305,17 @@ static void pvebackup_complete_cb(void *opaque, int ret)
- 
-     block_on_coroutine_fn(pvebackup_complete_stream, di);
- 
--    // remove self from job queue
-+    // remove self from job list
-     backup_state.di_list = g_list_remove(backup_state.di_list, di);
- 
--    if (di->bitmap && ret < 0) {
--        // on error or cancel we cannot ensure synchronization of dirty
--        // bitmaps with backup server, so remove all and do full backup next
--        bdrv_release_dirty_bitmap(di->bitmap);
--    }
--
-     g_free(di);
- 
--    qemu_mutex_unlock(&backup_state.backup_mutex);
-+    /* call cleanup if we're the last job */
-+    if (!g_list_first(backup_state.di_list)) {
-+        block_on_coroutine_fn(pvebackup_co_cleanup, NULL);
-+    }
- 
--    pvebackup_run_next_job();
-+    qemu_mutex_unlock(&backup_state.backup_mutex);
- }
- 
- static void pvebackup_cancel(void)
-@@ -375,32 +337,28 @@ static void pvebackup_cancel(void)
-         proxmox_backup_abort(backup_state.pbs, "backup canceled");
-     }
- 
--    qemu_mutex_unlock(&backup_state.backup_mutex);
--
--    for(;;) {
--
--        BlockJob *next_job = NULL;
-+    /* it's enough to cancel one job in the transaction, the rest will follow
-+     * automatically */
-+    GList *bdi = g_list_first(backup_state.di_list);
-+    BlockJob *cancel_job = bdi && bdi->data ?
-+        ((PVEBackupDevInfo *)bdi->data)->job :
-+        NULL;
- 
--        qemu_mutex_lock(&backup_state.backup_mutex);
--
--        GList *l = backup_state.di_list;
--        while (l) {
--            PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
--            l = g_list_next(l);
--
--            BlockJob *job = lookup_active_block_job(di);
--            if (job != NULL) {
--                next_job = job;
--                break;
--            }
-+    /* ref the job before releasing the mutex, just to be safe */
-+    if (cancel_job) {
-+        WITH_JOB_LOCK_GUARD() {
-+            job_ref_locked(&cancel_job->job);
-         }
-+    }
- 
--        qemu_mutex_unlock(&backup_state.backup_mutex);
-+    /* job_cancel_sync may enter the job, so we need to release the
-+     * backup_mutex to avoid deadlock */
-+    qemu_mutex_unlock(&backup_state.backup_mutex);
- 
--        if (next_job) {
--            job_cancel_sync(&next_job->job, true);
--        } else {
--            break;
-+    if (cancel_job) {
-+        WITH_JOB_LOCK_GUARD() {
-+            job_cancel_sync_locked(&cancel_job->job, true);
-+            job_unref_locked(&cancel_job->job);
-         }
-     }
- }
-@@ -460,49 +418,19 @@ static int coroutine_fn pvebackup_co_add_config(
-     goto out;
- }
- 
--bool job_should_pause_locked(Job *job);
--
--static void pvebackup_run_next_job(void)
--{
--    assert(!qemu_in_coroutine());
--
--    qemu_mutex_lock(&backup_state.backup_mutex);
--
--    GList *l = backup_state.di_list;
--    while (l) {
--        PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
--        l = g_list_next(l);
--
--        BlockJob *job = lookup_active_block_job(di);
--
--        if (job) {
--            qemu_mutex_unlock(&backup_state.backup_mutex);
--
--            WITH_JOB_LOCK_GUARD() {
--                if (job_should_pause_locked(&job->job)) {
--                    bool error_or_canceled = pvebackup_error_or_canceled();
--                    if (error_or_canceled) {
--                        job_cancel_sync_locked(&job->job, true);
--                    } else {
--                        job_resume_locked(&job->job);
--                    }
--                }
--            }
--            return;
--        }
--    }
--
--    block_on_coroutine_fn(pvebackup_co_cleanup, NULL); // no more jobs, run cleanup
--
--    qemu_mutex_unlock(&backup_state.backup_mutex);
--}
--
- static bool create_backup_jobs(void) {
- 
-     assert(!qemu_in_coroutine());
- 
-     Error *local_err = NULL;
- 
-+    /* create job transaction to synchronize bitmap commit and cancel all
-+     * jobs in case one errors */
-+    if (backup_state.txn) {
-+        job_txn_unref(backup_state.txn);
-+    }
-+    backup_state.txn = job_txn_new_seq();
-+
-     BackupPerf perf = { .max_workers = 16 };
- 
-     /* create and start all jobs (paused state) */
-@@ -525,7 +453,7 @@ static bool create_backup_jobs(void) {
-         BlockJob *job = backup_job_create(
-             NULL, di->bs, di->target, backup_state.speed, sync_mode, di->bitmap,
-             bitmap_mode, false, NULL, &perf, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
--            JOB_DEFAULT, pvebackup_complete_cb, di, NULL, &local_err);
-+            JOB_DEFAULT, pvebackup_complete_cb, di, backup_state.txn, &local_err);
- 
-         aio_context_release(aio_context);
- 
-@@ -537,7 +465,8 @@ static bool create_backup_jobs(void) {
-             pvebackup_propagate_error(create_job_err);
-             break;
-         }
--        job_start(&job->job);
-+
-+        di->job = job;
- 
-         bdrv_unref(di->target);
-         di->target = NULL;
-@@ -555,6 +484,12 @@ static bool create_backup_jobs(void) {
-                 bdrv_unref(di->target);
-                 di->target = NULL;
-             }
-+
-+            if (di->job) {
-+                WITH_JOB_LOCK_GUARD() {
-+                    job_unref_locked(&di->job->job);
-+                }
-+            }
-         }
-     }
- 
-@@ -937,10 +872,6 @@ err:
-         PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-         l = g_list_next(l);
- 
--        if (di->bitmap) {
--            bdrv_release_dirty_bitmap(di->bitmap);
--        }
--
-         if (di->target) {
-             bdrv_co_unref(di->target);
-         }
-@@ -1021,9 +952,15 @@ UuidInfo *qmp_backup(
-     block_on_coroutine_fn(pvebackup_co_prepare, &task);
- 
-     if (*errp == NULL) {
--        create_backup_jobs();
-+        bool errors = create_backup_jobs();
-         qemu_mutex_unlock(&backup_state.backup_mutex);
--        pvebackup_run_next_job();
-+
-+        if (!errors) {
-+            /* start the first job in the transaction
-+             * note: this might directly enter the job, so we need to do this
-+             * after unlocking the backup_mutex */
-+            job_txn_start_seq(backup_state.txn);
-+        }
-     } else {
-         qemu_mutex_unlock(&backup_state.backup_mutex);
-     }
diff --git a/debian/patches/pve/0046-PVE-block-stream-increase-chunk-size.patch b/debian/patches/pve/0038-PVE-block-stream-increase-chunk-size.patch
similarity index 100%
rename from debian/patches/pve/0046-PVE-block-stream-increase-chunk-size.patch
rename to debian/patches/pve/0038-PVE-block-stream-increase-chunk-size.patch
diff --git a/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch b/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
deleted file mode 100644
index 15eb190..0000000
--- a/debian/patches/pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
+++ /dev/null
@@ -1,499 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter@proxmox.com>
-Date: Mon, 28 Sep 2020 13:40:51 +0200
-Subject: [PATCH] PVE-Backup: Don't block on finishing and cleanup
- create_backup_jobs
-
-proxmox_backup_co_finish is already async, but previously we would wait
-for the coroutine using block_on_coroutine_fn(). Avoid this by
-scheduling pvebackup_co_complete_stream (and thus pvebackup_co_cleanup)
-as a real coroutine when calling from pvebackup_complete_cb. This is ok,
-since complete_stream uses the backup_mutex internally to synchronize,
-and other streams can happily continue writing in the meantime anyway.
-
-To accomodate, backup_mutex is converted to a CoMutex. This means
-converting every user to a coroutine. This is not just useful here, but
-will come in handy once this series[0] is merged, and QMP calls can be
-yield-able coroutines too. Then we can also finally get rid of
-block_on_coroutine_fn.
-
-Cases of aio_context_acquire/release from within what is now a coroutine
-are changed to aio_co_reschedule_self, which works since a running
-coroutine always holds the aio lock for the context it is running in.
-
-job_cancel_sync is called from a BH since it can't be run from a
-coroutine (uses AIO_WAIT_WHILE internally).
-
-Same thing for create_backup_jobs, which is converted to a BH too.
-
-To communicate the finishing state, a new property is introduced to
-query-backup: 'finishing'. A new state is explicitly not used, since
-that would break compatibility with older qemu-server versions.
-
-Also fix create_backup_jobs:
-
-No more weird bool returns, just the standard "errp" format used
-everywhere else too. With this, if backup_job_create fails, the error
-message is actually returned over QMP and can be shown to the user.
-
-To facilitate correct cleanup on such an error, we call
-create_backup_jobs as a bottom half directly from pvebackup_co_prepare.
-This additionally allows us to actually hold the backup_mutex during
-operation.
-
-Also add a job_cancel_sync before job_unref, since a job must be in
-STATUS_NULL to be deleted by unref, which could trigger an assert
-before.
-
-[0] https://lists.gnu.org/archive/html/qemu-devel/2020-09/msg03515.html
-
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: add new force parameter to job_cancel_sync calls]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- pve-backup.c         | 212 +++++++++++++++++++++++++++----------------
- qapi/block-core.json |   5 +-
- 2 files changed, 138 insertions(+), 79 deletions(-)
-
-diff --git a/pve-backup.c b/pve-backup.c
-index 629da3e6c7..1da9dd9edc 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -35,7 +35,9 @@ const char *PBS_BITMAP_NAME = "pbs-incremental-dirty-bitmap";
- 
- static struct PVEBackupState {
-     struct {
--        // Everithing accessed from qmp_backup_query command is protected using lock
-+        // Everything accessed from qmp_backup_query command is protected using
-+        // this lock. Do NOT hold this lock for long times, as it is sometimes
-+        // acquired from coroutines, and thus any wait time may block the guest.
-         QemuMutex lock;
-         Error *error;
-         time_t start_time;
-@@ -49,20 +51,22 @@ static struct PVEBackupState {
-         size_t reused;
-         size_t zero_bytes;
-         GList *bitmap_list;
-+        bool finishing;
-+        bool starting;
-     } stat;
-     int64_t speed;
-     VmaWriter *vmaw;
-     ProxmoxBackupHandle *pbs;
-     GList *di_list;
-     JobTxn *txn;
--    QemuMutex backup_mutex;
-+    CoMutex backup_mutex;
-     CoMutex dump_callback_mutex;
- } backup_state;
- 
- static void pvebackup_init(void)
- {
-     qemu_mutex_init(&backup_state.stat.lock);
--    qemu_mutex_init(&backup_state.backup_mutex);
-+    qemu_co_mutex_init(&backup_state.backup_mutex);
-     qemu_co_mutex_init(&backup_state.dump_callback_mutex);
- }
- 
-@@ -74,6 +78,7 @@ typedef struct PVEBackupDevInfo {
-     size_t size;
-     uint64_t block_size;
-     uint8_t dev_id;
-+    int completed_ret; // INT_MAX if not completed
-     char targetfile[PATH_MAX];
-     BdrvDirtyBitmap *bitmap;
-     BlockDriverState *target;
-@@ -229,12 +234,12 @@ pvebackup_co_dump_vma_cb(
- }
- 
- // assumes the caller holds backup_mutex
--static void coroutine_fn pvebackup_co_cleanup(void *unused)
-+static void coroutine_fn pvebackup_co_cleanup(void)
- {
-     assert(qemu_in_coroutine());
- 
-     qemu_mutex_lock(&backup_state.stat.lock);
--    backup_state.stat.end_time = time(NULL);
-+    backup_state.stat.finishing = true;
-     qemu_mutex_unlock(&backup_state.stat.lock);
- 
-     if (backup_state.vmaw) {
-@@ -263,35 +268,29 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
- 
-     g_list_free(backup_state.di_list);
-     backup_state.di_list = NULL;
-+
-+    qemu_mutex_lock(&backup_state.stat.lock);
-+    backup_state.stat.end_time = time(NULL);
-+    backup_state.stat.finishing = false;
-+    qemu_mutex_unlock(&backup_state.stat.lock);
- }
- 
--// assumes the caller holds backup_mutex
--static void coroutine_fn pvebackup_complete_stream(void *opaque)
-+static void coroutine_fn pvebackup_co_complete_stream(void *opaque)
- {
-     PVEBackupDevInfo *di = opaque;
-+    int ret = di->completed_ret;
- 
--    bool error_or_canceled = pvebackup_error_or_canceled();
--
--    if (backup_state.vmaw) {
--        vma_writer_close_stream(backup_state.vmaw, di->dev_id);
-+    qemu_mutex_lock(&backup_state.stat.lock);
-+    bool starting = backup_state.stat.starting;
-+    qemu_mutex_unlock(&backup_state.stat.lock);
-+    if (starting) {
-+        /* in 'starting' state, no tasks have been run yet, meaning we can (and
-+         * must) skip all cleanup, as we don't know what has and hasn't been
-+         * initialized yet. */
-+        return;
-     }
- 
--    if (backup_state.pbs && !error_or_canceled) {
--        Error *local_err = NULL;
--        proxmox_backup_co_close_image(backup_state.pbs, di->dev_id, &local_err);
--        if (local_err != NULL) {
--            pvebackup_propagate_error(local_err);
--        }
--    }
--}
--
--static void pvebackup_complete_cb(void *opaque, int ret)
--{
--    assert(!qemu_in_coroutine());
--
--    PVEBackupDevInfo *di = opaque;
--
--    qemu_mutex_lock(&backup_state.backup_mutex);
-+    qemu_co_mutex_lock(&backup_state.backup_mutex);
- 
-     if (ret < 0) {
-         Error *local_err = NULL;
-@@ -303,7 +302,19 @@ static void pvebackup_complete_cb(void *opaque, int ret)
- 
-     assert(di->target == NULL);
- 
--    block_on_coroutine_fn(pvebackup_complete_stream, di);
-+    bool error_or_canceled = pvebackup_error_or_canceled();
-+
-+    if (backup_state.vmaw) {
-+        vma_writer_close_stream(backup_state.vmaw, di->dev_id);
-+    }
-+
-+    if (backup_state.pbs && !error_or_canceled) {
-+        Error *local_err = NULL;
-+        proxmox_backup_co_close_image(backup_state.pbs, di->dev_id, &local_err);
-+        if (local_err != NULL) {
-+            pvebackup_propagate_error(local_err);
-+        }
-+    }
- 
-     // remove self from job list
-     backup_state.di_list = g_list_remove(backup_state.di_list, di);
-@@ -312,21 +323,46 @@ static void pvebackup_complete_cb(void *opaque, int ret)
- 
-     /* call cleanup if we're the last job */
-     if (!g_list_first(backup_state.di_list)) {
--        block_on_coroutine_fn(pvebackup_co_cleanup, NULL);
-+        pvebackup_co_cleanup();
-     }
- 
--    qemu_mutex_unlock(&backup_state.backup_mutex);
-+    qemu_co_mutex_unlock(&backup_state.backup_mutex);
- }
- 
--static void pvebackup_cancel(void)
-+static void pvebackup_complete_cb(void *opaque, int ret)
- {
--    assert(!qemu_in_coroutine());
-+    PVEBackupDevInfo *di = opaque;
-+    di->completed_ret = ret;
-+
-+    /*
-+     * Schedule stream cleanup in async coroutine. close_image and finish might
-+     * take a while, so we can't block on them here. This way it also doesn't
-+     * matter if we're already running in a coroutine or not.
-+     * Note: di is a pointer to an entry in the global backup_state struct, so
-+     * it stays valid.
-+     */
-+    Coroutine *co = qemu_coroutine_create(pvebackup_co_complete_stream, di);
-+    aio_co_enter(qemu_get_aio_context(), co);
-+}
-+
-+/*
-+ * job_cancel(_sync) does not like to be called from coroutines, so defer to
-+ * main loop processing via a bottom half.
-+ */
-+static void job_cancel_bh(void *opaque) {
-+    CoCtxData *data = (CoCtxData*)opaque;
-+    Job *job = (Job*)data->data;
-+    job_cancel_sync(job, true);
-+    aio_co_enter(data->ctx, data->co);
-+}
- 
-+static void coroutine_fn pvebackup_co_cancel(void *opaque)
-+{
-     Error *cancel_err = NULL;
-     error_setg(&cancel_err, "backup canceled");
-     pvebackup_propagate_error(cancel_err);
- 
--    qemu_mutex_lock(&backup_state.backup_mutex);
-+    qemu_co_mutex_lock(&backup_state.backup_mutex);
- 
-     if (backup_state.vmaw) {
-         /* make sure vma writer does not block anymore */
-@@ -344,28 +380,22 @@ static void pvebackup_cancel(void)
-         ((PVEBackupDevInfo *)bdi->data)->job :
-         NULL;
- 
--    /* ref the job before releasing the mutex, just to be safe */
-     if (cancel_job) {
--        WITH_JOB_LOCK_GUARD() {
--            job_ref_locked(&cancel_job->job);
--        }
-+        CoCtxData data = {
-+            .ctx = qemu_get_current_aio_context(),
-+            .co = qemu_coroutine_self(),
-+            .data = &cancel_job->job,
-+        };
-+        aio_bh_schedule_oneshot(data.ctx, job_cancel_bh, &data);
-+        qemu_coroutine_yield();
-     }
- 
--    /* job_cancel_sync may enter the job, so we need to release the
--     * backup_mutex to avoid deadlock */
--    qemu_mutex_unlock(&backup_state.backup_mutex);
--
--    if (cancel_job) {
--        WITH_JOB_LOCK_GUARD() {
--            job_cancel_sync_locked(&cancel_job->job, true);
--            job_unref_locked(&cancel_job->job);
--        }
--    }
-+    qemu_co_mutex_unlock(&backup_state.backup_mutex);
- }
- 
- void qmp_backup_cancel(Error **errp)
- {
--    pvebackup_cancel();
-+    block_on_coroutine_fn(pvebackup_co_cancel, NULL);
- }
- 
- // assumes the caller holds backup_mutex
-@@ -418,10 +448,18 @@ static int coroutine_fn pvebackup_co_add_config(
-     goto out;
- }
- 
--static bool create_backup_jobs(void) {
-+/*
-+ * backup_job_create can *not* be run from a coroutine (and requires an
-+ * acquired AioContext), so this can't either.
-+ * The caller is responsible that backup_mutex is held nonetheless.
-+ */
-+static void create_backup_jobs_bh(void *opaque) {
- 
-     assert(!qemu_in_coroutine());
- 
-+    CoCtxData *data = (CoCtxData*)opaque;
-+    Error **errp = (Error**)data->data;
-+
-     Error *local_err = NULL;
- 
-     /* create job transaction to synchronize bitmap commit and cancel all
-@@ -457,24 +495,19 @@ static bool create_backup_jobs(void) {
- 
-         aio_context_release(aio_context);
- 
--        if (!job || local_err != NULL) {
--            Error *create_job_err = NULL;
--            error_setg(&create_job_err, "backup_job_create failed: %s",
--                       local_err ? error_get_pretty(local_err) : "null");
-+        di->job = job;
- 
--            pvebackup_propagate_error(create_job_err);
-+        if (!job || local_err) {
-+            error_setg(errp, "backup_job_create failed: %s",
-+                       local_err ? error_get_pretty(local_err) : "null");
-             break;
-         }
- 
--        di->job = job;
--
-         bdrv_unref(di->target);
-         di->target = NULL;
-     }
- 
--    bool errors = pvebackup_error_or_canceled();
--
--    if (errors) {
-+    if (*errp) {
-         l = backup_state.di_list;
-         while (l) {
-             PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-@@ -487,13 +520,15 @@ static bool create_backup_jobs(void) {
- 
-             if (di->job) {
-                 WITH_JOB_LOCK_GUARD() {
-+                    job_cancel_sync_locked(&di->job->job, true);
-                     job_unref_locked(&di->job->job);
-                 }
-             }
-         }
-     }
- 
--    return errors;
-+    /* return */
-+    aio_co_enter(data->ctx, data->co);
- }
- 
- typedef struct QmpBackupTask {
-@@ -522,11 +557,12 @@ typedef struct QmpBackupTask {
-     UuidInfo *result;
- } QmpBackupTask;
- 
--// assumes the caller holds backup_mutex
- static void coroutine_fn pvebackup_co_prepare(void *opaque)
- {
-     assert(qemu_in_coroutine());
- 
-+    qemu_co_mutex_lock(&backup_state.backup_mutex);
-+
-     QmpBackupTask *task = opaque;
- 
-     task->result = NULL; // just to be sure
-@@ -547,8 +583,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     const char *firewall_name = "qemu-server.fw";
- 
-     if (backup_state.di_list) {
--         error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
-+        error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
-                   "previous backup not finished");
-+        qemu_co_mutex_unlock(&backup_state.backup_mutex);
-         return;
-     }
- 
-@@ -615,6 +652,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-         }
-         di->size = size;
-         total += size;
-+
-+        di->completed_ret = INT_MAX;
-     }
- 
-     uuid_generate(uuid);
-@@ -846,6 +885,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     backup_state.stat.dirty = total - backup_state.stat.reused;
-     backup_state.stat.transferred = 0;
-     backup_state.stat.zero_bytes = 0;
-+    backup_state.stat.finishing = false;
-+    backup_state.stat.starting = true;
- 
-     qemu_mutex_unlock(&backup_state.stat.lock);
- 
-@@ -860,6 +901,33 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     uuid_info->UUID = uuid_str;
- 
-     task->result = uuid_info;
-+
-+    /* Run create_backup_jobs_bh outside of coroutine (in BH) but keep
-+    * backup_mutex locked. This is fine, a CoMutex can be held across yield
-+    * points, and we'll release it as soon as the BH reschedules us.
-+    */
-+    CoCtxData waker = {
-+        .co = qemu_coroutine_self(),
-+        .ctx = qemu_get_current_aio_context(),
-+        .data = &local_err,
-+    };
-+    aio_bh_schedule_oneshot(waker.ctx, create_backup_jobs_bh, &waker);
-+    qemu_coroutine_yield();
-+
-+    if (local_err) {
-+        error_propagate(task->errp, local_err);
-+        goto err;
-+    }
-+
-+    qemu_co_mutex_unlock(&backup_state.backup_mutex);
-+
-+    qemu_mutex_lock(&backup_state.stat.lock);
-+    backup_state.stat.starting = false;
-+    qemu_mutex_unlock(&backup_state.stat.lock);
-+
-+    /* start the first job in the transaction */
-+    job_txn_start_seq(backup_state.txn);
-+
-     return;
- 
- err_mutex:
-@@ -882,6 +950,7 @@ err:
-         g_free(di);
-     }
-     g_list_free(di_list);
-+    backup_state.di_list = NULL;
- 
-     if (devs) {
-         g_strfreev(devs);
-@@ -902,6 +971,8 @@ err:
-     }
- 
-     task->result = NULL;
-+
-+    qemu_co_mutex_unlock(&backup_state.backup_mutex);
-     return;
- }
- 
-@@ -947,24 +1018,8 @@ UuidInfo *qmp_backup(
-         .errp = errp,
-     };
- 
--    qemu_mutex_lock(&backup_state.backup_mutex);
--
-     block_on_coroutine_fn(pvebackup_co_prepare, &task);
- 
--    if (*errp == NULL) {
--        bool errors = create_backup_jobs();
--        qemu_mutex_unlock(&backup_state.backup_mutex);
--
--        if (!errors) {
--            /* start the first job in the transaction
--             * note: this might directly enter the job, so we need to do this
--             * after unlocking the backup_mutex */
--            job_txn_start_seq(backup_state.txn);
--        }
--    } else {
--        qemu_mutex_unlock(&backup_state.backup_mutex);
--    }
--
-     return task.result;
- }
- 
-@@ -1012,6 +1067,7 @@ BackupStatus *qmp_query_backup(Error **errp)
-     info->transferred = backup_state.stat.transferred;
-     info->has_reused = true;
-     info->reused = backup_state.stat.reused;
-+    info->finishing = backup_state.stat.finishing;
- 
-     qemu_mutex_unlock(&backup_state.stat.lock);
- 
-diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 130d5f065f..43838212e3 100644
---- a/qapi/block-core.json
-+++ b/qapi/block-core.json
-@@ -865,12 +865,15 @@
- #
- # @uuid: uuid for this backup job
- #
-+# @finishing: if status='active' and finishing=true, then the backup process is
-+#             waiting for the target to finish.
-+#
- ##
- { 'struct': 'BackupStatus',
-   'data': {'*status': 'str', '*errmsg': 'str', '*total': 'int', '*dirty': 'int',
-            '*transferred': 'int', '*zero-bytes': 'int', '*reused': 'int',
-            '*start-time': 'int', '*end-time': 'int',
--           '*backup-file': 'str', '*uuid': 'str' } }
-+           '*backup-file': 'str', '*uuid': 'str', 'finishing': 'bool' } }
- 
- ##
- # @BackupFormat:
diff --git a/debian/patches/pve/0047-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch b/debian/patches/pve/0039-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
similarity index 100%
rename from debian/patches/pve/0047-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
rename to debian/patches/pve/0039-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
diff --git a/debian/patches/pve/0048-block-add-alloc-track-driver.patch b/debian/patches/pve/0040-block-add-alloc-track-driver.patch
similarity index 97%
rename from debian/patches/pve/0048-block-add-alloc-track-driver.patch
rename to debian/patches/pve/0040-block-add-alloc-track-driver.patch
index fc724c9..823be87 100644
--- a/debian/patches/pve/0048-block-add-alloc-track-driver.patch
+++ b/debian/patches/pve/0040-block-add-alloc-track-driver.patch
@@ -25,20 +25,21 @@ once the backing image is removed. It will be replaced by 'file'.
 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
 [FE: adapt to changed function signatures
-     make error return value consistent with QEMU]
+     make error return value consistent with QEMU
+     avoid premature break during read]
 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 ---
- block/alloc-track.c | 351 ++++++++++++++++++++++++++++++++++++++++++++
+ block/alloc-track.c | 352 ++++++++++++++++++++++++++++++++++++++++++++
  block/meson.build   |   1 +
- 2 files changed, 352 insertions(+)
+ 2 files changed, 353 insertions(+)
  create mode 100644 block/alloc-track.c
 
 diff --git a/block/alloc-track.c b/block/alloc-track.c
 new file mode 100644
-index 0000000000..113bbd7058
+index 0000000000..b75d7c6460
 --- /dev/null
 +++ b/block/alloc-track.c
-@@ -0,0 +1,351 @@
+@@ -0,0 +1,352 @@
 +/*
 + * Node to allow backing images to be applied to any node. Assumes a blank
 + * image to begin with, only new writes are tracked as allocated, thus this
@@ -216,7 +217,8 @@ index 0000000000..113bbd7058
 +            ret = bdrv_co_preadv(bs->backing, local_offset, local_bytes,
 +                                 &local_qiov, flags);
 +        } else {
-+            ret = qemu_iovec_memset(&local_qiov, cur_offset, 0, local_bytes);
++            qemu_iovec_memset(&local_qiov, cur_offset, 0, local_bytes);
++            ret = 0;
 +        }
 +
 +        if (ret != 0) {
diff --git a/debian/patches/pve/0053-Revert-block-rbd-workaround-for-ceph-issue-53784.patch b/debian/patches/pve/0041-Revert-block-rbd-workaround-for-ceph-issue-53784.patch
similarity index 100%
rename from debian/patches/pve/0053-Revert-block-rbd-workaround-for-ceph-issue-53784.patch
rename to debian/patches/pve/0041-Revert-block-rbd-workaround-for-ceph-issue-53784.patch
diff --git a/debian/patches/pve/0054-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch b/debian/patches/pve/0042-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch
similarity index 100%
rename from debian/patches/pve/0054-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch
rename to debian/patches/pve/0042-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch
diff --git a/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch b/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
deleted file mode 100644
index b38c633..0000000
--- a/debian/patches/pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
+++ /dev/null
@@ -1,595 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter@proxmox.com>
-Date: Tue, 26 Jan 2021 15:45:30 +0100
-Subject: [PATCH] PVE: Use coroutine QMP for backup/cancel_backup
-
-Finally turn backup QMP calls into coroutines, now that it's possible.
-This has the benefit that calls are asynchronous to the main loop, i.e.
-long running operations like connecting to a PBS server will no longer
-hang the VM.
-
-Additionally, it allows us to get rid of block_on_coroutine_fn, which
-was always a hacky workaround.
-
-While we're already spring cleaning, also remove the QmpBackupTask
-struct, since we can now put the 'prepare' function directly into
-qmp_backup and thus no longer need those giant walls of text.
-
-(Note that for our patches to work with 5.2.0 this change is actually
-required, otherwise monitor_get_fd() fails as we're not in a QMP
-coroutine, but one we start ourselves - we could of course set the
-monitor for that coroutine ourselves, but let's just fix it the right
-way instead)
-
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: adapt to QAPI changes
-     call coroutine version of is_inserted()]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- block/monitor/block-hmp-cmds.c |   4 +-
- hmp-commands.hx                |   2 +
- proxmox-backup-client.c        |  31 -----
- pve-backup.c                   | 220 +++++++++++----------------------
- qapi/block-core.json           |   4 +-
- 5 files changed, 79 insertions(+), 182 deletions(-)
-
-diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index ecbebd39ac..56f39b14d4 100644
---- a/block/monitor/block-hmp-cmds.c
-+++ b/block/monitor/block-hmp-cmds.c
-@@ -1030,7 +1030,7 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target,
-                                !!read_only, read_only_mode, errp);
- }
- 
--void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
-+void coroutine_fn hmp_backup_cancel(Monitor *mon, const QDict *qdict)
- {
-     Error *error = NULL;
- 
-@@ -1039,7 +1039,7 @@ void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
-     hmp_handle_error(mon, error);
- }
- 
--void hmp_backup(Monitor *mon, const QDict *qdict)
-+void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
- {
-     Error *error = NULL;
- 
-diff --git a/hmp-commands.hx b/hmp-commands.hx
-index 9b6b8e2e9c..896430dae8 100644
---- a/hmp-commands.hx
-+++ b/hmp-commands.hx
-@@ -111,6 +111,7 @@ ERST
- 		    "\n\t\t\t Use -d to dump data into a directory instead"
- 		    "\n\t\t\t of using VMA format.",
-         .cmd = hmp_backup,
-+        .coroutine  = true,
-     },
- 
- SRST
-@@ -124,6 +125,7 @@ ERST
-         .params     = "",
-         .help       = "cancel the current VM backup",
-         .cmd        = hmp_backup_cancel,
-+        .coroutine  = true,
-     },
- 
- SRST
-diff --git a/proxmox-backup-client.c b/proxmox-backup-client.c
-index 4ce7bc0b5e..0923037dec 100644
---- a/proxmox-backup-client.c
-+++ b/proxmox-backup-client.c
-@@ -5,37 +5,6 @@
- 
- /* Proxmox Backup Server client bindings using coroutines */
- 
--typedef struct BlockOnCoroutineWrapper {
--    AioContext *ctx;
--    CoroutineEntry *entry;
--    void *entry_arg;
--    bool finished;
--} BlockOnCoroutineWrapper;
--
--static void coroutine_fn block_on_coroutine_wrapper(void *opaque)
--{
--    BlockOnCoroutineWrapper *wrapper = opaque;
--    wrapper->entry(wrapper->entry_arg);
--    wrapper->finished = true;
--    aio_wait_kick();
--}
--
--void block_on_coroutine_fn(CoroutineEntry *entry, void *entry_arg)
--{
--    assert(!qemu_in_coroutine());
--
--    AioContext *ctx = qemu_get_current_aio_context();
--    BlockOnCoroutineWrapper wrapper = {
--        .finished = false,
--        .entry = entry,
--        .entry_arg = entry_arg,
--        .ctx = ctx,
--    };
--    Coroutine *wrapper_co = qemu_coroutine_create(block_on_coroutine_wrapper, &wrapper);
--    aio_co_enter(ctx, wrapper_co);
--    AIO_WAIT_WHILE(ctx, !wrapper.finished);
--}
--
- // This is called from another thread, so we use aio_co_schedule()
- static void proxmox_backup_schedule_wake(void *data) {
-     CoCtxData *waker = (CoCtxData *)data;
-diff --git a/pve-backup.c b/pve-backup.c
-index e0e38063a8..88e507b3c2 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -356,7 +356,7 @@ static void job_cancel_bh(void *opaque) {
-     aio_co_enter(data->ctx, data->co);
- }
- 
--static void coroutine_fn pvebackup_co_cancel(void *opaque)
-+void coroutine_fn qmp_backup_cancel(Error **errp)
- {
-     Error *cancel_err = NULL;
-     error_setg(&cancel_err, "backup canceled");
-@@ -393,11 +393,6 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
-     qemu_co_mutex_unlock(&backup_state.backup_mutex);
- }
- 
--void qmp_backup_cancel(Error **errp)
--{
--    block_on_coroutine_fn(pvebackup_co_cancel, NULL);
--}
--
- // assumes the caller holds backup_mutex
- static int coroutine_fn pvebackup_co_add_config(
-     const char *file,
-@@ -531,42 +526,27 @@ static void create_backup_jobs_bh(void *opaque) {
-     aio_co_enter(data->ctx, data->co);
- }
- 
--typedef struct QmpBackupTask {
--    const char *backup_file;
--    const char *password;
--    const char *keyfile;
--    const char *key_password;
--    const char *backup_id;
--    bool has_backup_time;
--    const char *fingerprint;
--    int64_t backup_time;
--    bool has_use_dirty_bitmap;
--    bool use_dirty_bitmap;
--    bool has_format;
--    BackupFormat format;
--    const char *config_file;
--    const char *firewall_file;
--    const char *devlist;
--    bool has_compress;
--    bool compress;
--    bool has_encrypt;
--    bool encrypt;
--    bool has_speed;
--    int64_t speed;
--    Error **errp;
--    UuidInfo *result;
--} QmpBackupTask;
--
--static void coroutine_fn pvebackup_co_prepare(void *opaque)
-+UuidInfo coroutine_fn *qmp_backup(
-+    const char *backup_file,
-+    const char *password,
-+    const char *keyfile,
-+    const char *key_password,
-+    const char *fingerprint,
-+    const char *backup_id,
-+    bool has_backup_time, int64_t backup_time,
-+    bool has_use_dirty_bitmap, bool use_dirty_bitmap,
-+    bool has_compress, bool compress,
-+    bool has_encrypt, bool encrypt,
-+    bool has_format, BackupFormat format,
-+    const char *config_file,
-+    const char *firewall_file,
-+    const char *devlist,
-+    bool has_speed, int64_t speed, Error **errp)
- {
-     assert(qemu_in_coroutine());
- 
-     qemu_co_mutex_lock(&backup_state.backup_mutex);
- 
--    QmpBackupTask *task = opaque;
--
--    task->result = NULL; // just to be sure
--
-     BlockBackend *blk;
-     BlockDriverState *bs = NULL;
-     const char *backup_dir = NULL;
-@@ -583,32 +563,32 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     const char *firewall_name = "qemu-server.fw";
- 
-     if (backup_state.di_list) {
--        error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
-+        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
-                   "previous backup not finished");
-         qemu_co_mutex_unlock(&backup_state.backup_mutex);
--        return;
-+        return NULL;
-     }
- 
-     /* Todo: try to auto-detect format based on file name */
--    BackupFormat format = task->has_format ? task->format : BACKUP_FORMAT_VMA;
-+    format = has_format ? format : BACKUP_FORMAT_VMA;
- 
--    if (task->devlist) {
--        devs = g_strsplit_set(task->devlist, ",;:", -1);
-+    if (devlist) {
-+        devs = g_strsplit_set(devlist, ",;:", -1);
- 
-         gchar **d = devs;
-         while (d && *d) {
-             blk = blk_by_name(*d);
-             if (blk) {
-                 bs = blk_bs(blk);
--                if (!bdrv_is_inserted(bs)) {
--                    error_setg(task->errp, QERR_DEVICE_HAS_NO_MEDIUM, *d);
-+                if (!bdrv_co_is_inserted(bs)) {
-+                    error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, *d);
-                     goto err;
-                 }
-                 PVEBackupDevInfo *di = g_new0(PVEBackupDevInfo, 1);
-                 di->bs = bs;
-                 di_list = g_list_append(di_list, di);
-             } else {
--                error_set(task->errp, ERROR_CLASS_DEVICE_NOT_FOUND,
-+                error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
-                           "Device '%s' not found", *d);
-                 goto err;
-             }
-@@ -620,7 +600,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
- 
-         bs = NULL;
-         for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
--            if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
-+            if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs)) {
-                 continue;
-             }
- 
-@@ -631,7 +611,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     }
- 
-     if (!di_list) {
--        error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "empty device list");
-+        error_set(errp, ERROR_CLASS_GENERIC_ERROR, "empty device list");
-         goto err;
-     }
- 
-@@ -641,13 +621,13 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     while (l) {
-         PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-         l = g_list_next(l);
--        if (bdrv_op_is_blocked(di->bs, BLOCK_OP_TYPE_BACKUP_SOURCE, task->errp)) {
-+        if (bdrv_op_is_blocked(di->bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
-             goto err;
-         }
- 
-         ssize_t size = bdrv_getlength(di->bs);
-         if (size < 0) {
--            error_setg_errno(task->errp, -size, "bdrv_getlength failed");
-+            error_setg_errno(errp, -size, "bdrv_getlength failed");
-             goto err;
-         }
-         di->size = size;
-@@ -674,47 +654,44 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     }
- 
-     if (format == BACKUP_FORMAT_PBS) {
--        if (!task->password) {
--            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
-+        if (!password) {
-+            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
-             goto err_mutex;
-         }
--        if (!task->backup_id) {
--            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
-+        if (!backup_id) {
-+            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
-             goto err_mutex;
-         }
--        if (!task->has_backup_time) {
--            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-time'");
-+        if (!has_backup_time) {
-+            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-time'");
-             goto err_mutex;
-         }
- 
-         int dump_cb_block_size = PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE; // Hardcoded (4M)
-         firewall_name = "fw.conf";
- 
--        bool use_dirty_bitmap = task->has_use_dirty_bitmap && task->use_dirty_bitmap;
--
--
-         char *pbs_err = NULL;
-         pbs = proxmox_backup_new(
--            task->backup_file,
--            task->backup_id,
--            task->backup_time,
-+            backup_file,
-+            backup_id,
-+            backup_time,
-             dump_cb_block_size,
--            task->password,
--            task->keyfile,
--            task->key_password,
--            task->has_compress ? task->compress : true,
--            task->has_encrypt ? task->encrypt : !!task->keyfile,
--            task->fingerprint,
-+            password,
-+            keyfile,
-+            key_password,
-+            has_compress ? compress : true,
-+            has_encrypt ? encrypt : !!keyfile,
-+            fingerprint,
-             &pbs_err);
- 
-         if (!pbs) {
--            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
-+            error_set(errp, ERROR_CLASS_GENERIC_ERROR,
-                       "proxmox_backup_new failed: %s", pbs_err);
-             proxmox_backup_free_error(pbs_err);
-             goto err_mutex;
-         }
- 
--        int connect_result = proxmox_backup_co_connect(pbs, task->errp);
-+        int connect_result = proxmox_backup_co_connect(pbs, errp);
-         if (connect_result < 0)
-             goto err_mutex;
- 
-@@ -733,9 +710,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
-             bool expect_only_dirty = false;
- 
--            if (use_dirty_bitmap) {
-+            if (has_use_dirty_bitmap && use_dirty_bitmap) {
-                 if (bitmap == NULL) {
--                    bitmap = bdrv_create_dirty_bitmap(di->bs, dump_cb_block_size, PBS_BITMAP_NAME, task->errp);
-+                    bitmap = bdrv_create_dirty_bitmap(di->bs, dump_cb_block_size, PBS_BITMAP_NAME, errp);
-                     if (!bitmap) {
-                         goto err_mutex;
-                     }
-@@ -765,12 +742,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-                 }
-             }
- 
--            int dev_id = proxmox_backup_co_register_image(pbs, devname, di->size, expect_only_dirty, task->errp);
-+            int dev_id = proxmox_backup_co_register_image(pbs, devname, di->size, expect_only_dirty, errp);
-             if (dev_id < 0) {
-                 goto err_mutex;
-             }
- 
--            if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, task->errp))) {
-+            if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, errp))) {
-                 goto err_mutex;
-             }
- 
-@@ -784,10 +761,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             backup_state.stat.bitmap_list = g_list_append(backup_state.stat.bitmap_list, info);
-         }
-     } else if (format == BACKUP_FORMAT_VMA) {
--        vmaw = vma_writer_create(task->backup_file, uuid, &local_err);
-+        vmaw = vma_writer_create(backup_file, uuid, &local_err);
-         if (!vmaw) {
-             if (local_err) {
--                error_propagate(task->errp, local_err);
-+                error_propagate(errp, local_err);
-             }
-             goto err_mutex;
-         }
-@@ -798,25 +775,25 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-             l = g_list_next(l);
- 
--            if (!(di->target = bdrv_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, task->errp))) {
-+            if (!(di->target = bdrv_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, errp))) {
-                 goto err_mutex;
-             }
- 
-             const char *devname = bdrv_get_device_name(di->bs);
-             di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
-             if (di->dev_id <= 0) {
--                error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
-+                error_set(errp, ERROR_CLASS_GENERIC_ERROR,
-                           "register_stream failed");
-                 goto err_mutex;
-             }
-         }
-     } else if (format == BACKUP_FORMAT_DIR) {
--        if (mkdir(task->backup_file, 0640) != 0) {
--            error_setg_errno(task->errp, errno, "can't create directory '%s'\n",
--                             task->backup_file);
-+        if (mkdir(backup_file, 0640) != 0) {
-+            error_setg_errno(errp, errno, "can't create directory '%s'\n",
-+                             backup_file);
-             goto err_mutex;
-         }
--        backup_dir = task->backup_file;
-+        backup_dir = backup_file;
- 
-         l = di_list;
-         while (l) {
-@@ -830,34 +807,34 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-             bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
-                             di->size, flags, false, &local_err);
-             if (local_err) {
--                error_propagate(task->errp, local_err);
-+                error_propagate(errp, local_err);
-                 goto err_mutex;
-             }
- 
-             di->target = bdrv_co_open(di->targetfile, NULL, NULL, flags, &local_err);
-             if (!di->target) {
--                error_propagate(task->errp, local_err);
-+                error_propagate(errp, local_err);
-                 goto err_mutex;
-             }
-         }
-     } else {
--        error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
-+        error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
-         goto err_mutex;
-     }
- 
- 
-     /* add configuration file to archive */
--    if (task->config_file) {
--        if (pvebackup_co_add_config(task->config_file, config_name, format, backup_dir,
--                                    vmaw, pbs, task->errp) != 0) {
-+    if (config_file) {
-+        if (pvebackup_co_add_config(config_file, config_name, format, backup_dir,
-+                                    vmaw, pbs, errp) != 0) {
-             goto err_mutex;
-         }
-     }
- 
-     /* add firewall file to archive */
--    if (task->firewall_file) {
--        if (pvebackup_co_add_config(task->firewall_file, firewall_name, format, backup_dir,
--                                    vmaw, pbs, task->errp) != 0) {
-+    if (firewall_file) {
-+        if (pvebackup_co_add_config(firewall_file, firewall_name, format, backup_dir,
-+                                    vmaw, pbs, errp) != 0) {
-             goto err_mutex;
-         }
-     }
-@@ -875,7 +852,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     if (backup_state.stat.backup_file) {
-         g_free(backup_state.stat.backup_file);
-     }
--    backup_state.stat.backup_file = g_strdup(task->backup_file);
-+    backup_state.stat.backup_file = g_strdup(backup_file);
- 
-     uuid_copy(backup_state.stat.uuid, uuid);
-     uuid_unparse_lower(uuid, backup_state.stat.uuid_str);
-@@ -890,7 +867,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
- 
-     qemu_mutex_unlock(&backup_state.stat.lock);
- 
--    backup_state.speed = (task->has_speed && task->speed > 0) ? task->speed : 0;
-+    backup_state.speed = (has_speed && speed > 0) ? speed : 0;
- 
-     backup_state.vmaw = vmaw;
-     backup_state.pbs = pbs;
-@@ -900,8 +877,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     uuid_info = g_malloc0(sizeof(*uuid_info));
-     uuid_info->UUID = uuid_str;
- 
--    task->result = uuid_info;
--
-     /* Run create_backup_jobs_bh outside of coroutine (in BH) but keep
-     * backup_mutex locked. This is fine, a CoMutex can be held across yield
-     * points, and we'll release it as soon as the BH reschedules us.
-@@ -915,7 +890,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     qemu_coroutine_yield();
- 
-     if (local_err) {
--        error_propagate(task->errp, local_err);
-+        error_propagate(errp, local_err);
-         goto err;
-     }
- 
-@@ -928,7 +903,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
-     /* start the first job in the transaction */
-     job_txn_start_seq(backup_state.txn);
- 
--    return;
-+    return uuid_info;
- 
- err_mutex:
-     qemu_mutex_unlock(&backup_state.stat.lock);
-@@ -959,7 +934,7 @@ err:
-     if (vmaw) {
-         Error *err = NULL;
-         vma_writer_close(vmaw, &err);
--        unlink(task->backup_file);
-+        unlink(backup_file);
-     }
- 
-     if (pbs) {
-@@ -970,57 +945,8 @@ err:
-         rmdir(backup_dir);
-     }
- 
--    task->result = NULL;
--
-     qemu_co_mutex_unlock(&backup_state.backup_mutex);
--    return;
--}
--
--UuidInfo *qmp_backup(
--    const char *backup_file,
--    const char *password,
--    const char *keyfile,
--    const char *key_password,
--    const char *fingerprint,
--    const char *backup_id,
--    bool has_backup_time, int64_t backup_time,
--    bool has_use_dirty_bitmap, bool use_dirty_bitmap,
--    bool has_compress, bool compress,
--    bool has_encrypt, bool encrypt,
--    bool has_format, BackupFormat format,
--    const char *config_file,
--    const char *firewall_file,
--    const char *devlist,
--    bool has_speed, int64_t speed, Error **errp)
--{
--    QmpBackupTask task = {
--        .backup_file = backup_file,
--        .password = password,
--        .keyfile = keyfile,
--        .key_password = key_password,
--        .fingerprint = fingerprint,
--        .backup_id = backup_id,
--        .has_backup_time = has_backup_time,
--        .backup_time = backup_time,
--        .has_use_dirty_bitmap = has_use_dirty_bitmap,
--        .use_dirty_bitmap = use_dirty_bitmap,
--        .has_compress = has_compress,
--        .compress = compress,
--        .has_encrypt = has_encrypt,
--        .encrypt = encrypt,
--        .has_format = has_format,
--        .format = format,
--        .config_file = config_file,
--        .firewall_file = firewall_file,
--        .devlist = devlist,
--        .has_speed = has_speed,
--        .speed = speed,
--        .errp = errp,
--    };
--
--    block_on_coroutine_fn(pvebackup_co_prepare, &task);
--
--    return task.result;
-+    return NULL;
- }
- 
- BackupStatus *qmp_query_backup(Error **errp)
-diff --git a/qapi/block-core.json b/qapi/block-core.json
-index e7412f6322..93d924ef79 100644
---- a/qapi/block-core.json
-+++ b/qapi/block-core.json
-@@ -937,7 +937,7 @@
-                                     '*config-file': 'str',
-                                     '*firewall-file': 'str',
-                                     '*devlist': 'str', '*speed': 'int' },
--  'returns': 'UuidInfo' }
-+  'returns': 'UuidInfo', 'coroutine': true }
- 
- ##
- # @query-backup:
-@@ -959,7 +959,7 @@
- # Notes: This command succeeds even if there is no backup process running.
- #
- ##
--{ 'command': 'backup-cancel' }
-+{ 'command': 'backup-cancel', 'coroutine': true }
- 
- ##
- # @ProxmoxSupportStatus:
diff --git a/debian/patches/pve/0055-Revert-block-rbd-implement-bdrv_co_block_status.patch b/debian/patches/pve/0043-Revert-block-rbd-implement-bdrv_co_block_status.patch
similarity index 100%
rename from debian/patches/pve/0055-Revert-block-rbd-implement-bdrv_co_block_status.patch
rename to debian/patches/pve/0043-Revert-block-rbd-implement-bdrv_co_block_status.patch
diff --git a/debian/patches/pve/0044-PBS-add-master-key-support.patch b/debian/patches/pve/0044-PBS-add-master-key-support.patch
deleted file mode 100644
index 4498723..0000000
--- a/debian/patches/pve/0044-PBS-add-master-key-support.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter@proxmox.com>
-Date: Wed, 10 Feb 2021 11:07:06 +0100
-Subject: [PATCH] PBS: add master key support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-this requires a new enough libproxmox-backup-qemu0, and allows querying
-from the PVE side to avoid QMP calls with unsupported parameters.
-
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: adapt to QAPI change dropping redundant has_*]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- block/monitor/block-hmp-cmds.c | 1 +
- pve-backup.c                   | 3 +++
- qapi/block-core.json           | 7 +++++++
- 3 files changed, 11 insertions(+)
-
-diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 56f39b14d4..f852c70611 100644
---- a/block/monitor/block-hmp-cmds.c
-+++ b/block/monitor/block-hmp-cmds.c
-@@ -1053,6 +1053,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
-         NULL, // PBS password
-         NULL, // PBS keyfile
-         NULL, // PBS key_password
-+        NULL, // PBS master_keyfile
-         NULL, // PBS fingerprint
-         NULL, // PBS backup-id
-         false, 0, // PBS backup-time
-diff --git a/pve-backup.c b/pve-backup.c
-index 88e507b3c2..04c5f561cd 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -531,6 +531,7 @@ UuidInfo coroutine_fn *qmp_backup(
-     const char *password,
-     const char *keyfile,
-     const char *key_password,
-+    const char *master_keyfile,
-     const char *fingerprint,
-     const char *backup_id,
-     bool has_backup_time, int64_t backup_time,
-@@ -679,6 +680,7 @@ UuidInfo coroutine_fn *qmp_backup(
-             password,
-             keyfile,
-             key_password,
-+            master_keyfile,
-             has_compress ? compress : true,
-             has_encrypt ? encrypt : !!keyfile,
-             fingerprint,
-@@ -1038,5 +1040,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
-     ret->pbs_dirty_bitmap_savevm = true;
-     ret->pbs_dirty_bitmap_migration = true;
-     ret->query_bitmap_info = true;
-+    ret->pbs_masterkey = true;
-     return ret;
- }
-diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 93d924ef79..568feb63ad 100644
---- a/qapi/block-core.json
-+++ b/qapi/block-core.json
-@@ -908,6 +908,8 @@
- #
- # @key-password: password for keyfile (optional for format 'pbs')
- #
-+# @master-keyfile: PEM-formatted master public keyfile (optional for format 'pbs')
-+#
- # @fingerprint: server cert fingerprint (optional for format 'pbs')
- #
- # @backup-id: backup ID (required for format 'pbs')
-@@ -927,6 +929,7 @@
-                                     '*password': 'str',
-                                     '*keyfile': 'str',
-                                     '*key-password': 'str',
-+                                    '*master-keyfile': 'str',
-                                     '*fingerprint': 'str',
-                                     '*backup-id': 'str',
-                                     '*backup-time': 'int',
-@@ -979,6 +982,9 @@
- #                              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-library-version: Running version of libproxmox-backup-qemu0 library.
- #
- ##
-@@ -987,6 +993,7 @@
-             'query-bitmap-info': 'bool',
-             'pbs-dirty-bitmap-savevm': 'bool',
-             'pbs-dirty-bitmap-migration': 'bool',
-+            'pbs-masterkey': 'bool',
-             'pbs-library-version': 'str' } }
- 
- ##
diff --git a/debian/patches/pve/0063-alloc-track-fix-deadlock-during-drop.patch b/debian/patches/pve/0044-alloc-track-fix-deadlock-during-drop.patch
similarity index 100%
rename from debian/patches/pve/0063-alloc-track-fix-deadlock-during-drop.patch
rename to debian/patches/pve/0044-alloc-track-fix-deadlock-during-drop.patch
diff --git a/debian/patches/pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch b/debian/patches/pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch
deleted file mode 100644
index 6b18def..0000000
--- a/debian/patches/pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter@proxmox.com>
-Date: Wed, 9 Dec 2020 11:46:57 +0100
-Subject: [PATCH] PVE: block/pbs: fast-path reads without allocation if
- possible
-
-...and switch over to g_malloc/g_free while at it to align with other
-QEMU code.
-
-Tracing shows the fast-path is taken almost all the time, though not
-100% so the slow one is still necessary.
-
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
----
- block/pbs.c | 17 ++++++++++++++---
- 1 file changed, 14 insertions(+), 3 deletions(-)
-
-diff --git a/block/pbs.c b/block/pbs.c
-index 43e69ada46..5d20789084 100644
---- a/block/pbs.c
-+++ b/block/pbs.c
-@@ -201,7 +201,16 @@ static coroutine_fn int pbs_co_preadv(BlockDriverState *bs,
-     BDRVPBSState *s = bs->opaque;
-     int ret;
-     char *pbs_error = NULL;
--    uint8_t *buf = malloc(bytes);
-+    uint8_t *buf;
-+    bool inline_buf = true;
-+
-+    /* for single-buffer IO vectors we can fast-path the write directly to it */
-+    if (qiov->niov == 1 && qiov->iov->iov_len >= bytes) {
-+        buf = qiov->iov->iov_base;
-+    } else {
-+        inline_buf = false;
-+        buf = g_malloc(bytes);
-+    }
- 
-     if (offset < 0 || bytes < 0) {
-         fprintf(stderr, "unexpected negative 'offset' or 'bytes' value!\n");
-@@ -224,8 +233,10 @@ static coroutine_fn int pbs_co_preadv(BlockDriverState *bs,
-         return -EIO;
-     }
- 
--    qemu_iovec_from_buf(qiov, 0, buf, bytes);
--    free(buf);
-+    if (!inline_buf) {
-+        qemu_iovec_from_buf(qiov, 0, buf, bytes);
-+        g_free(buf);
-+    }
- 
-     return 0;
- }
diff --git a/debian/patches/pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch b/debian/patches/pve/0045-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
similarity index 100%
rename from debian/patches/pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
rename to debian/patches/pve/0045-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
diff --git a/debian/patches/pve/0067-savevm-async-don-t-hold-BQL-during-setup.patch b/debian/patches/pve/0046-savevm-async-don-t-hold-BQL-during-setup.patch
similarity index 100%
rename from debian/patches/pve/0067-savevm-async-don-t-hold-BQL-during-setup.patch
rename to debian/patches/pve/0046-savevm-async-don-t-hold-BQL-during-setup.patch
diff --git a/debian/patches/pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch b/debian/patches/pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch
deleted file mode 100644
index 6646d97..0000000
--- a/debian/patches/pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter@proxmox.com>
-Date: Wed, 26 May 2021 17:36:55 +0200
-Subject: [PATCH] PVE: savevm-async: register yank before
- migration_incoming_state_destroy
-
-Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
----
- migration/savevm-async.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/migration/savevm-async.c b/migration/savevm-async.c
-index 70273a2996..fab1dc32d2 100644
---- a/migration/savevm-async.c
-+++ b/migration/savevm-async.c
-@@ -20,6 +20,7 @@
- #include "qemu/timer.h"
- #include "qemu/main-loop.h"
- #include "qemu/rcu.h"
-+#include "qemu/yank.h"
- 
- /* #define DEBUG_SAVEVM_STATE */
- 
-@@ -518,6 +519,10 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
-     dirty_bitmap_mig_before_vm_start();
- 
-     qemu_fclose(f);
-+
-+    /* state_destroy assumes a real migration which would have added a yank */
-+    yank_register_instance(MIGRATION_YANK_INSTANCE, &error_abort);
-+
-     migration_incoming_state_destroy();
-     if (ret < 0) {
-         error_setg_errno(errp, -ret, "Error while loading VM state");
diff --git a/debian/patches/pve/0051-vma-allow-partial-restore.patch b/debian/patches/pve/0051-vma-allow-partial-restore.patch
deleted file mode 100644
index f1fd7cb..0000000
--- a/debian/patches/pve/0051-vma-allow-partial-restore.patch
+++ /dev/null
@@ -1,407 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fabian Ebner <f.ebner@proxmox.com>
-Date: Thu, 21 Apr 2022 13:26:48 +0200
-Subject: [PATCH] vma: allow partial restore
-
-Introduce a new map line for skipping a certain drive, of the form
-skip=drive-scsi0
-
-Since in PVE, most archives are compressed and piped to vma for
-restore, it's not easily possible to skip reads.
-
-For the reader, a new skip flag for VmaRestoreState is added and the
-target is allowed to be NULL if skip is specified when registering. If
-the skip flag is set, no writes will be made as well as no check for
-duplicate clusters. Therefore, the flag is not set for verify.
-
-Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
-Acked-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
----
- vma-reader.c |  64 ++++++++++++---------
- vma.c        | 157 +++++++++++++++++++++++++++++----------------------
- vma.h        |   2 +-
- 3 files changed, 126 insertions(+), 97 deletions(-)
-
-diff --git a/vma-reader.c b/vma-reader.c
-index e65f1e8415..81a891c6b1 100644
---- a/vma-reader.c
-+++ b/vma-reader.c
-@@ -28,6 +28,7 @@ typedef struct VmaRestoreState {
-     bool write_zeroes;
-     unsigned long *bitmap;
-     int bitmap_size;
-+    bool skip;
- }  VmaRestoreState;
- 
- struct VmaReader {
-@@ -425,13 +426,14 @@ VmaDeviceInfo *vma_reader_get_device_info(VmaReader *vmar, guint8 dev_id)
- }
- 
- static void allocate_rstate(VmaReader *vmar,  guint8 dev_id,
--                            BlockBackend *target, bool write_zeroes)
-+                            BlockBackend *target, bool write_zeroes, bool skip)
- {
-     assert(vmar);
-     assert(dev_id);
- 
-     vmar->rstate[dev_id].target = target;
-     vmar->rstate[dev_id].write_zeroes = write_zeroes;
-+    vmar->rstate[dev_id].skip = skip;
- 
-     int64_t size = vmar->devinfo[dev_id].size;
- 
-@@ -446,28 +448,30 @@ static void allocate_rstate(VmaReader *vmar,  guint8 dev_id,
- }
- 
- int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id, BlockBackend *target,
--                           bool write_zeroes, Error **errp)
-+                           bool write_zeroes, bool skip, Error **errp)
- {
-     assert(vmar);
--    assert(target != NULL);
-+    assert(target != NULL || skip);
-     assert(dev_id);
--    assert(vmar->rstate[dev_id].target == NULL);
--
--    int64_t size = blk_getlength(target);
--    int64_t size_diff = size - vmar->devinfo[dev_id].size;
--
--    /* storage types can have different size restrictions, so it
--     * is not always possible to create an image with exact size.
--     * So we tolerate a size difference up to 4MB.
--     */
--    if ((size_diff < 0) || (size_diff > 4*1024*1024)) {
--        error_setg(errp, "vma_reader_register_bs for stream %s failed - "
--                   "unexpected size %zd != %zd", vmar->devinfo[dev_id].devname,
--                   size, vmar->devinfo[dev_id].size);
--        return -1;
-+    assert(vmar->rstate[dev_id].target == NULL && !vmar->rstate[dev_id].skip);
-+
-+    if (target != NULL) {
-+        int64_t size = blk_getlength(target);
-+        int64_t size_diff = size - vmar->devinfo[dev_id].size;
-+
-+        /* storage types can have different size restrictions, so it
-+         * is not always possible to create an image with exact size.
-+         * So we tolerate a size difference up to 4MB.
-+         */
-+        if ((size_diff < 0) || (size_diff > 4*1024*1024)) {
-+            error_setg(errp, "vma_reader_register_bs for stream %s failed - "
-+                       "unexpected size %zd != %zd", vmar->devinfo[dev_id].devname,
-+                       size, vmar->devinfo[dev_id].size);
-+            return -1;
-+        }
-     }
- 
--    allocate_rstate(vmar, dev_id, target, write_zeroes);
-+    allocate_rstate(vmar, dev_id, target, write_zeroes, skip);
- 
-     return 0;
- }
-@@ -560,19 +564,23 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
-         VmaRestoreState *rstate = &vmar->rstate[dev_id];
-         BlockBackend *target = NULL;
- 
-+        bool skip = rstate->skip;
-+
-         if (dev_id != vmar->vmstate_stream) {
-             target = rstate->target;
--            if (!verify && !target) {
-+            if (!verify && !target && !skip) {
-                 error_setg(errp, "got wrong dev id %d", dev_id);
-                 return -1;
-             }
- 
--            if (vma_reader_get_bitmap(rstate, cluster_num)) {
--                error_setg(errp, "found duplicated cluster %zd for stream %s",
--                          cluster_num, vmar->devinfo[dev_id].devname);
--                return -1;
-+            if (!skip) {
-+                if (vma_reader_get_bitmap(rstate, cluster_num)) {
-+                    error_setg(errp, "found duplicated cluster %zd for stream %s",
-+                              cluster_num, vmar->devinfo[dev_id].devname);
-+                    return -1;
-+                }
-+                vma_reader_set_bitmap(rstate, cluster_num, 1);
-             }
--            vma_reader_set_bitmap(rstate, cluster_num, 1);
- 
-             max_sector = vmar->devinfo[dev_id].size/BDRV_SECTOR_SIZE;
-         } else {
-@@ -618,7 +626,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
-                 return -1;
-             }
- 
--            if (!verify) {
-+            if (!verify && !skip) {
-                 int nb_sectors = end_sector - sector_num;
-                 if (restore_write_data(vmar, dev_id, target, vmstate_fd,
-                                        buf + start, sector_num, nb_sectors,
-@@ -654,7 +662,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
-                         return -1;
-                     }
- 
--                    if (!verify) {
-+                    if (!verify && !skip) {
-                         int nb_sectors = end_sector - sector_num;
-                         if (restore_write_data(vmar, dev_id, target, vmstate_fd,
-                                                buf + start, sector_num,
-@@ -679,7 +687,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
-                             vmar->partial_zero_cluster_data += zero_size;
-                         }
- 
--                        if (rstate->write_zeroes && !verify) {
-+                        if (rstate->write_zeroes && !verify && !skip) {
-                             if (restore_write_data(vmar, dev_id, target, vmstate_fd,
-                                                    zero_vma_block, sector_num,
-                                                    nb_sectors, errp) < 0) {
-@@ -850,7 +858,7 @@ int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp)
- 
-     for (dev_id = 1; dev_id < 255; dev_id++) {
-         if (vma_reader_get_device_info(vmar, dev_id)) {
--            allocate_rstate(vmar, dev_id, NULL, false);
-+            allocate_rstate(vmar, dev_id, NULL, false, false);
-         }
-     }
- 
-diff --git a/vma.c b/vma.c
-index e8dffb43e0..e6e9ffc7fe 100644
---- a/vma.c
-+++ b/vma.c
-@@ -138,6 +138,7 @@ typedef struct RestoreMap {
-     char *throttling_group;
-     char *cache;
-     bool write_zero;
-+    bool skip;
- } RestoreMap;
- 
- static bool try_parse_option(char **line, const char *optname, char **out, const char *inbuf) {
-@@ -245,47 +246,61 @@ static int extract_content(int argc, char **argv)
-             char *bps = NULL;
-             char *group = NULL;
-             char *cache = NULL;
-+            char *devname = NULL;
-+            bool skip = false;
-+            uint64_t bps_value = 0;
-+            const char *path = NULL;
-+            bool write_zero = true;
-+
-             if (!line || line[0] == '\0' || !strcmp(line, "done\n")) {
-                 break;
-             }
-             int len = strlen(line);
-             if (line[len - 1] == '\n') {
-                 line[len - 1] = '\0';
--                if (len == 1) {
-+                len = len - 1;
-+                if (len == 0) {
-                     break;
-                 }
-             }
- 
--            while (1) {
--                if (!try_parse_option(&line, "format", &format, inbuf) &&
--                    !try_parse_option(&line, "throttling.bps", &bps, inbuf) &&
--                    !try_parse_option(&line, "throttling.group", &group, inbuf) &&
--                    !try_parse_option(&line, "cache", &cache, inbuf))
--                {
--                    break;
-+            if (strncmp(line, "skip", 4) == 0) {
-+                if (len < 6 || line[4] != '=') {
-+                    g_error("read map failed - option 'skip' has no value ('%s')",
-+                            inbuf);
-+                } else {
-+                    devname = line + 5;
-+                    skip = true;
-+                }
-+            } else {
-+                while (1) {
-+                    if (!try_parse_option(&line, "format", &format, inbuf) &&
-+                        !try_parse_option(&line, "throttling.bps", &bps, inbuf) &&
-+                        !try_parse_option(&line, "throttling.group", &group, inbuf) &&
-+                        !try_parse_option(&line, "cache", &cache, inbuf))
-+                    {
-+                        break;
-+                    }
-                 }
--            }
- 
--            uint64_t bps_value = 0;
--            if (bps) {
--                bps_value = verify_u64(bps);
--                g_free(bps);
--            }
-+                if (bps) {
-+                    bps_value = verify_u64(bps);
-+                    g_free(bps);
-+                }
- 
--            const char *path;
--            bool write_zero;
--            if (line[0] == '0' && line[1] == ':') {
--                path = line + 2;
--                write_zero = false;
--            } else if (line[0] == '1' && line[1] == ':') {
--                path = line + 2;
--                write_zero = true;
--            } else {
--                g_error("read map failed - parse error ('%s')", inbuf);
-+                if (line[0] == '0' && line[1] == ':') {
-+                    path = line + 2;
-+                    write_zero = false;
-+                } else if (line[0] == '1' && line[1] == ':') {
-+                    path = line + 2;
-+                    write_zero = true;
-+                } else {
-+                    g_error("read map failed - parse error ('%s')", inbuf);
-+                }
-+
-+                path = extract_devname(path, &devname, -1);
-             }
- 
--            char *devname = NULL;
--            path = extract_devname(path, &devname, -1);
-             if (!devname) {
-                 g_error("read map failed - no dev name specified ('%s')",
-                         inbuf);
-@@ -299,6 +314,7 @@ static int extract_content(int argc, char **argv)
-             map->throttling_group = group;
-             map->cache = cache;
-             map->write_zero = write_zero;
-+            map->skip = skip;
- 
-             g_hash_table_insert(devmap, map->devname, map);
- 
-@@ -328,6 +344,7 @@ static int extract_content(int argc, char **argv)
-             const char *cache = NULL;
-             int flags = BDRV_O_RDWR;
-             bool write_zero = true;
-+            bool skip = false;
- 
-             BlockBackend *blk = NULL;
- 
-@@ -343,6 +360,7 @@ static int extract_content(int argc, char **argv)
-                 throttling_group = map->throttling_group;
-                 cache = map->cache;
-                 write_zero = map->write_zero;
-+                skip = map->skip;
-             } else {
-                 devfn = g_strdup_printf("%s/tmp-disk-%s.raw",
-                                         dirname, di->devname);
-@@ -361,57 +379,60 @@ static int extract_content(int argc, char **argv)
-                 write_zero = false;
-             }
- 
--	    size_t devlen = strlen(devfn);
--	    QDict *options = NULL;
--            bool writethrough;
--            if (format) {
--                /* explicit format from commandline */
--                options = qdict_new();
--                qdict_put_str(options, "driver", format);
--            } else if ((devlen > 4 && strcmp(devfn+devlen-4, ".raw") == 0) ||
--	               strncmp(devfn, "/dev/", 5) == 0)
--	    {
--                /* This part is now deprecated for PVE as well (just as qemu
--                 * deprecated not specifying an explicit raw format, too.
--                 */
--		/* explicit raw format */
--		options = qdict_new();
--		qdict_put_str(options, "driver", "raw");
--	    }
--            if (cache && bdrv_parse_cache_mode(cache, &flags, &writethrough)) {
--                g_error("invalid cache option: %s\n", cache);
--            }
-+            if (!skip) {
-+                size_t devlen = strlen(devfn);
-+                QDict *options = NULL;
-+                bool writethrough;
-+                if (format) {
-+                    /* explicit format from commandline */
-+                    options = qdict_new();
-+                    qdict_put_str(options, "driver", format);
-+                } else if ((devlen > 4 && strcmp(devfn+devlen-4, ".raw") == 0) ||
-+                    strncmp(devfn, "/dev/", 5) == 0)
-+                {
-+                    /* This part is now deprecated for PVE as well (just as qemu
-+                     * deprecated not specifying an explicit raw format, too.
-+                     */
-+                    /* explicit raw format */
-+                    options = qdict_new();
-+                    qdict_put_str(options, "driver", "raw");
-+                }
- 
--	    if (errp || !(blk = blk_new_open(devfn, NULL, options, flags, &errp))) {
--                g_error("can't open file %s - %s", devfn,
--                        error_get_pretty(errp));
--            }
-+                if (cache && bdrv_parse_cache_mode(cache, &flags, &writethrough)) {
-+                    g_error("invalid cache option: %s\n", cache);
-+                }
- 
--            if (cache) {
--                blk_set_enable_write_cache(blk, !writethrough);
--            }
-+                if (errp || !(blk = blk_new_open(devfn, NULL, options, flags, &errp))) {
-+                    g_error("can't open file %s - %s", devfn,
-+                            error_get_pretty(errp));
-+                }
- 
--            if (throttling_group) {
--                blk_io_limits_enable(blk, throttling_group);
--            }
-+                if (cache) {
-+                    blk_set_enable_write_cache(blk, !writethrough);
-+                }
- 
--            if (throttling_bps) {
--                if (!throttling_group) {
--                    blk_io_limits_enable(blk, devfn);
-+                if (throttling_group) {
-+                    blk_io_limits_enable(blk, throttling_group);
-                 }
- 
--                ThrottleConfig cfg;
--                throttle_config_init(&cfg);
--                cfg.buckets[THROTTLE_BPS_WRITE].avg = throttling_bps;
--                Error *err = NULL;
--                if (!throttle_is_valid(&cfg, &err)) {
--                    error_report_err(err);
--                    g_error("failed to apply throttling");
-+                if (throttling_bps) {
-+                    if (!throttling_group) {
-+                        blk_io_limits_enable(blk, devfn);
-+                    }
-+
-+                    ThrottleConfig cfg;
-+                    throttle_config_init(&cfg);
-+                    cfg.buckets[THROTTLE_BPS_WRITE].avg = throttling_bps;
-+                    Error *err = NULL;
-+                    if (!throttle_is_valid(&cfg, &err)) {
-+                        error_report_err(err);
-+                        g_error("failed to apply throttling");
-+                    }
-+                    blk_set_io_limits(blk, &cfg);
-                 }
--                blk_set_io_limits(blk, &cfg);
-             }
- 
--            if (vma_reader_register_bs(vmar, i, blk, write_zero, &errp) < 0) {
-+            if (vma_reader_register_bs(vmar, i, blk, write_zero, skip, &errp) < 0) {
-                 g_error("%s", error_get_pretty(errp));
-             }
- 
-diff --git a/vma.h b/vma.h
-index c895c97f6d..1b62859165 100644
---- a/vma.h
-+++ b/vma.h
-@@ -142,7 +142,7 @@ GList *vma_reader_get_config_data(VmaReader *vmar);
- VmaDeviceInfo *vma_reader_get_device_info(VmaReader *vmar, guint8 dev_id);
- int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id,
-                            BlockBackend *target, bool write_zeroes,
--                           Error **errp);
-+                           bool skip, Error **errp);
- int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
-                        Error **errp);
- int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp);
diff --git a/debian/patches/pve/0052-pbs-namespace-support.patch b/debian/patches/pve/0052-pbs-namespace-support.patch
deleted file mode 100644
index b0bb9a6..0000000
--- a/debian/patches/pve/0052-pbs-namespace-support.patch
+++ /dev/null
@@ -1,235 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Wolfgang Bumiller <w.bumiller@proxmox.com>
-Date: Tue, 26 Apr 2022 16:06:28 +0200
-Subject: [PATCH] pbs: namespace support
-
-Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
-[FE: adapt to QAPI change dropping redundant has_*]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- block/monitor/block-hmp-cmds.c |  1 +
- block/pbs.c                    | 25 +++++++++++++++++++++----
- pbs-restore.c                  | 19 ++++++++++++++++---
- pve-backup.c                   |  6 +++++-
- qapi/block-core.json           |  5 ++++-
- 5 files changed, 47 insertions(+), 9 deletions(-)
-
-diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index f852c70611..ac23f21eef 100644
---- a/block/monitor/block-hmp-cmds.c
-+++ b/block/monitor/block-hmp-cmds.c
-@@ -1055,6 +1055,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
-         NULL, // PBS key_password
-         NULL, // PBS master_keyfile
-         NULL, // PBS fingerprint
-+        NULL, // PBS backup-ns
-         NULL, // PBS backup-id
-         false, 0, // PBS backup-time
-         false, false, // PBS use-dirty-bitmap
-diff --git a/block/pbs.c b/block/pbs.c
-index 5d20789084..a2211e0f3b 100644
---- a/block/pbs.c
-+++ b/block/pbs.c
-@@ -15,6 +15,7 @@
- #include <proxmox-backup-qemu.h>
- 
- #define PBS_OPT_REPOSITORY "repository"
-+#define PBS_OPT_NAMESPACE "namespace"
- #define PBS_OPT_SNAPSHOT "snapshot"
- #define PBS_OPT_ARCHIVE "archive"
- #define PBS_OPT_KEYFILE "keyfile"
-@@ -28,6 +29,7 @@ typedef struct {
-     int64_t length;
- 
-     char *repository;
-+    char *namespace;
-     char *snapshot;
-     char *archive;
- } BDRVPBSState;
-@@ -41,6 +43,11 @@ static QemuOptsList runtime_opts = {
-             .type = QEMU_OPT_STRING,
-             .help = "The server address and repository to connect to.",
-         },
-+        {
-+            .name = PBS_OPT_NAMESPACE,
-+            .type = QEMU_OPT_STRING,
-+            .help = "Optional: The snapshot's namespace.",
-+        },
-         {
-             .name = PBS_OPT_SNAPSHOT,
-             .type = QEMU_OPT_STRING,
-@@ -77,7 +84,7 @@ static QemuOptsList runtime_opts = {
- 
- 
- // filename format:
--// pbs:repository=<repo>,snapshot=<snap>,password=<pw>,key_password=<kpw>,fingerprint=<fp>,archive=<archive>
-+// pbs:repository=<repo>,namespace=<ns>,snapshot=<snap>,password=<pw>,key_password=<kpw>,fingerprint=<fp>,archive=<archive>
- static void pbs_parse_filename(const char *filename, QDict *options,
-                                      Error **errp)
- {
-@@ -113,6 +120,7 @@ static int pbs_open(BlockDriverState *bs, QDict *options, int flags,
-     s->archive = g_strdup(qemu_opt_get(opts, PBS_OPT_ARCHIVE));
-     const char *keyfile = qemu_opt_get(opts, PBS_OPT_KEYFILE);
-     const char *password = qemu_opt_get(opts, PBS_OPT_PASSWORD);
-+    const char *namespace = qemu_opt_get(opts, PBS_OPT_NAMESPACE);
-     const char *fingerprint = qemu_opt_get(opts, PBS_OPT_FINGERPRINT);
-     const char *key_password = qemu_opt_get(opts, PBS_OPT_ENCRYPTION_PASSWORD);
- 
-@@ -125,9 +133,12 @@ static int pbs_open(BlockDriverState *bs, QDict *options, int flags,
-     if (!key_password) {
-         key_password = getenv("PBS_ENCRYPTION_PASSWORD");
-     }
-+    if (namespace) {
-+        s->namespace = g_strdup(namespace);
-+    }
- 
-     /* connect to PBS server in read mode */
--    s->conn = proxmox_restore_new(s->repository, s->snapshot, password,
-+    s->conn = proxmox_restore_new_ns(s->repository, s->snapshot, s->namespace, password,
-         keyfile, key_password, fingerprint, &pbs_error);
- 
-     /* invalidates qemu_opt_get char pointers from above */
-@@ -172,6 +183,7 @@ static int pbs_file_open(BlockDriverState *bs, QDict *options, int flags,
- static void pbs_close(BlockDriverState *bs) {
-     BDRVPBSState *s = bs->opaque;
-     g_free(s->repository);
-+    g_free(s->namespace);
-     g_free(s->snapshot);
-     g_free(s->archive);
-     proxmox_restore_disconnect(s->conn);
-@@ -253,8 +265,13 @@ static coroutine_fn int pbs_co_pwritev(BlockDriverState *bs,
- static void pbs_refresh_filename(BlockDriverState *bs)
- {
-     BDRVPBSState *s = bs->opaque;
--    snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s/%s(%s)",
--             s->repository, s->snapshot, s->archive);
-+    if (s->namespace) {
-+        snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s/%s:%s(%s)",
-+                 s->repository, s->namespace, s->snapshot, s->archive);
-+    } else {
-+        snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s/%s(%s)",
-+                 s->repository, s->snapshot, s->archive);
-+    }
- }
- 
- static const char *const pbs_strong_runtime_opts[] = {
-diff --git a/pbs-restore.c b/pbs-restore.c
-index 2f834cf42e..f03d9bab8d 100644
---- a/pbs-restore.c
-+++ b/pbs-restore.c
-@@ -29,7 +29,7 @@
- static void help(void)
- {
-     const char *help_msg =
--        "usage: pbs-restore [--repository <repo>] snapshot archive-name target [command options]\n"
-+        "usage: pbs-restore [--repository <repo>] [--ns namespace] snapshot archive-name target [command options]\n"
-         ;
- 
-     printf("%s", help_msg);
-@@ -77,6 +77,7 @@ int main(int argc, char **argv)
-     Error *main_loop_err = NULL;
-     const char *format = "raw";
-     const char *repository = NULL;
-+    const char *backup_ns = NULL;
-     const char *keyfile = NULL;
-     int verbose = false;
-     bool skip_zero = false;
-@@ -90,6 +91,7 @@ int main(int argc, char **argv)
-             {"verbose", no_argument, 0, 'v'},
-             {"format", required_argument, 0, 'f'},
-             {"repository", required_argument, 0, 'r'},
-+            {"ns", required_argument, 0, 'n'},
-             {"keyfile", required_argument, 0, 'k'},
-             {0, 0, 0, 0}
-         };
-@@ -110,6 +112,9 @@ int main(int argc, char **argv)
-             case 'r':
-                 repository = g_strdup(argv[optind - 1]);
-                 break;
-+            case 'n':
-+                backup_ns = g_strdup(argv[optind - 1]);
-+                break;
-             case 'k':
-                 keyfile = g_strdup(argv[optind - 1]);
-                 break;
-@@ -160,8 +165,16 @@ int main(int argc, char **argv)
-         fprintf(stderr, "connecting to repository '%s'\n", repository);
-     }
-     char *pbs_error = NULL;
--    ProxmoxRestoreHandle *conn = proxmox_restore_new(
--        repository, snapshot, password, keyfile, key_password, fingerprint, &pbs_error);
-+    ProxmoxRestoreHandle *conn = proxmox_restore_new_ns(
-+        repository,
-+        snapshot,
-+        backup_ns,
-+        password,
-+        keyfile,
-+        key_password,
-+        fingerprint,
-+        &pbs_error
-+    );
-     if (conn == NULL) {
-         fprintf(stderr, "restore failed: %s\n", pbs_error);
-         return -1;
-diff --git a/pve-backup.c b/pve-backup.c
-index 04c5f561cd..08dfb9cbda 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -12,6 +12,8 @@
- #include "qapi/qmp/qerror.h"
- #include "qemu/cutils.h"
- 
-+#include <proxmox-backup-qemu.h>
-+
- /* PVE backup state and related function */
- 
- /*
-@@ -533,6 +535,7 @@ UuidInfo coroutine_fn *qmp_backup(
-     const char *key_password,
-     const char *master_keyfile,
-     const char *fingerprint,
-+    const char *backup_ns,
-     const char *backup_id,
-     bool has_backup_time, int64_t backup_time,
-     bool has_use_dirty_bitmap, bool use_dirty_bitmap,
-@@ -672,8 +675,9 @@ UuidInfo coroutine_fn *qmp_backup(
-         firewall_name = "fw.conf";
- 
-         char *pbs_err = NULL;
--        pbs = proxmox_backup_new(
-+        pbs = proxmox_backup_new_ns(
-             backup_file,
-+            backup_ns,
-             backup_id,
-             backup_time,
-             dump_cb_block_size,
-diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 568feb63ad..9edeb33d82 100644
---- a/qapi/block-core.json
-+++ b/qapi/block-core.json
-@@ -912,6 +912,8 @@
- #
- # @fingerprint: server cert fingerprint (optional for format 'pbs')
- #
-+# @backup-ns: backup namespace (required for format 'pbs')
-+#
- # @backup-id: backup ID (required for format 'pbs')
- #
- # @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
-@@ -931,6 +933,7 @@
-                                     '*key-password': 'str',
-                                     '*master-keyfile': 'str',
-                                     '*fingerprint': 'str',
-+                                    '*backup-ns': 'str',
-                                     '*backup-id': 'str',
-                                     '*backup-time': 'int',
-                                     '*use-dirty-bitmap': 'bool',
-@@ -3385,7 +3388,7 @@
- { 'struct': 'BlockdevOptionsPbs',
-   'data': { 'repository': 'str', 'snapshot': 'str', 'archive': 'str',
-             '*keyfile': 'str', '*password': 'str', '*fingerprint': 'str',
--            '*key_password': 'str' } }
-+            '*key_password': 'str', '*namespace': 'str' } }
- 
- ##
- # @BlockdevOptionsNVMe:
diff --git a/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch b/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
deleted file mode 100644
index 5dee746..0000000
--- a/debian/patches/pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fabian Ebner <f.ebner@proxmox.com>
-Date: Wed, 25 May 2022 13:59:37 +0200
-Subject: [PATCH] PVE-Backup: create jobs: correctly cancel in error scenario
-
-The first call to job_cancel_sync() will cancel and free all jobs in
-the transaction, so ensure that it's called only once and get rid of
-the job_unref() that would operate on freed memory.
-
-It's also necessary to NULL backup_state.pbs in the error scenario,
-because a subsequent backup_cancel QMP call (as happens in PVE when
-the backup QMP command fails) would try to call proxmox_backup_abort()
-and run into a segfault.
-
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
-Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
-[FE: adapt for new job lock mechanism replacing AioContext locks]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- pve-backup.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/pve-backup.c b/pve-backup.c
-index 08dfb9cbda..79d14d6a0b 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -505,6 +505,11 @@ static void create_backup_jobs_bh(void *opaque) {
-     }
- 
-     if (*errp) {
-+        /*
-+         * It's enough to cancel one job in the transaction, the rest will
-+         * follow automatically.
-+         */
-+        bool canceled = false;
-         l = backup_state.di_list;
-         while (l) {
-             PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-@@ -515,11 +520,11 @@ static void create_backup_jobs_bh(void *opaque) {
-                 di->target = NULL;
-             }
- 
--            if (di->job) {
-+            if (!canceled && di->job) {
-                 WITH_JOB_LOCK_GUARD() {
-                     job_cancel_sync_locked(&di->job->job, true);
--                    job_unref_locked(&di->job->job);
-                 }
-+                canceled = true;
-             }
-         }
-     }
-@@ -945,6 +950,7 @@ err:
- 
-     if (pbs) {
-         proxmox_backup_disconnect(pbs);
-+        backup_state.pbs = NULL;
-     }
- 
-     if (backup_dir) {
diff --git a/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch b/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
deleted file mode 100644
index 4beed97..0000000
--- a/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fabian Ebner <f.ebner@proxmox.com>
-Date: Wed, 25 May 2022 13:59:38 +0200
-Subject: [PATCH] PVE-Backup: ensure jobs in di_list are referenced
-
-Ensures that qmp_backup_cancel doesn't pick a job that's already been
-freed. With unlucky timings it seems possible that:
-1. job_exit -> job_completed -> job_finalize_single starts
-2. pvebackup_co_complete_stream gets spawned in completion callback
-3. job finalize_single finishes -> job's refcount hits zero -> job is
-   freed
-4. qmp_backup_cancel comes in and locks backup_state.backup_mutex
-   before pvebackup_co_complete_stream can remove the job from the
-   di_list
-5. qmp_backup_cancel will pick a job that's already been freed
-
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
-Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
-[FE: adapt for new job lock mechanism replacing AioContext locks]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- pve-backup.c | 22 +++++++++++++++++++---
- 1 file changed, 19 insertions(+), 3 deletions(-)
-
-diff --git a/pve-backup.c b/pve-backup.c
-index 79d14d6a0b..67e2b99d74 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -318,6 +318,13 @@ static void coroutine_fn pvebackup_co_complete_stream(void *opaque)
-         }
-     }
- 
-+    if (di->job) {
-+        WITH_JOB_LOCK_GUARD() {
-+            job_unref_locked(&di->job->job);
-+            di->job = NULL;
-+        }
-+    }
-+
-     // remove self from job list
-     backup_state.di_list = g_list_remove(backup_state.di_list, di);
- 
-@@ -493,6 +500,11 @@ static void create_backup_jobs_bh(void *opaque) {
-         aio_context_release(aio_context);
- 
-         di->job = job;
-+        if (job) {
-+            WITH_JOB_LOCK_GUARD() {
-+                job_ref_locked(&job->job);
-+            }
-+        }
- 
-         if (!job || local_err) {
-             error_setg(errp, "backup_job_create failed: %s",
-@@ -520,11 +532,15 @@ static void create_backup_jobs_bh(void *opaque) {
-                 di->target = NULL;
-             }
- 
--            if (!canceled && di->job) {
-+            if (di->job) {
-                 WITH_JOB_LOCK_GUARD() {
--                    job_cancel_sync_locked(&di->job->job, true);
-+                    if (!canceled) {
-+                        job_cancel_sync_locked(&di->job->job, true);
-+                        canceled = true;
-+                    }
-+                    job_unref_locked(&di->job->job);
-+                    di->job = NULL;
-                 }
--                canceled = true;
-             }
-         }
-     }
diff --git a/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch b/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
deleted file mode 100644
index 68c261e..0000000
--- a/debian/patches/pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fabian Ebner <f.ebner@proxmox.com>
-Date: Wed, 25 May 2022 13:59:39 +0200
-Subject: [PATCH] PVE-Backup: avoid segfault issues upon backup-cancel
-
-When canceling a backup in PVE via a signal it's easy to run into a
-situation where the job is already failing when the backup_cancel QMP
-command comes in. With a bit of unlucky timing on top, it can happen
-that job_exit() runs between schedulung of job_cancel_bh() and
-execution of job_cancel_bh(). But job_cancel_sync() does not expect
-that the job is already finalized (in fact, the job might've been
-freed already, but even if it isn't, job_cancel_sync() would try to
-deref job->txn which would be NULL at that point).
-
-It is not possible to simply use the job_cancel() (which is advertised
-as being async but isn't in all cases) in qmp_backup_cancel() for the
-same reason job_cancel_sync() cannot be used. Namely, because it can
-invoke job_finish_sync() (which uses AIO_WAIT_WHILE and thus hangs if
-called from a coroutine). This happens when there's multiple jobs in
-the transaction and job->deferred_to_main_loop is true (is set before
-scheduling job_exit()) or if the job was not started yet.
-
-Fix the issue by selecting the job to cancel in job_cancel_bh() itself
-using the first job that's not completed yet. This is not necessarily
-the first job in the list, because pvebackup_co_complete_stream()
-might not yet have removed a completed job when job_cancel_bh() runs.
-
-An alternative would be to continue using only the first job and
-checking against JOB_STATUS_CONCLUDED or JOB_STATUS_NULL to decide if
-it's still necessary and possible to cancel, but the approach with
-using the first non-completed job seemed more robust.
-
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
-Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
-[FE: adapt for new job lock mechanism replacing AioContext locks]
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- pve-backup.c | 57 ++++++++++++++++++++++++++++++++++------------------
- 1 file changed, 38 insertions(+), 19 deletions(-)
-
-diff --git a/pve-backup.c b/pve-backup.c
-index 67e2b99d74..7a8240363d 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -356,12 +356,41 @@ static void pvebackup_complete_cb(void *opaque, int ret)
- 
- /*
-  * job_cancel(_sync) does not like to be called from coroutines, so defer to
-- * main loop processing via a bottom half.
-+ * main loop processing via a bottom half. Assumes that caller holds
-+ * backup_mutex.
-  */
- static void job_cancel_bh(void *opaque) {
-     CoCtxData *data = (CoCtxData*)opaque;
--    Job *job = (Job*)data->data;
--    job_cancel_sync(job, true);
-+
-+    /*
-+     * Be careful to pick a valid job to cancel:
-+     * 1. job_cancel_sync() does not expect the job to be finalized already.
-+     * 2. job_exit() might run between scheduling and running job_cancel_bh()
-+     *    and pvebackup_co_complete_stream() might not have removed the job from
-+     *    the list yet (in fact, cannot, because it waits for the backup_mutex).
-+     * Requiring !job_is_completed() ensures that no finalized job is picked.
-+     */
-+    GList *bdi = g_list_first(backup_state.di_list);
-+    while (bdi) {
-+        if (bdi->data) {
-+            BlockJob *bj = ((PVEBackupDevInfo *)bdi->data)->job;
-+            if (bj) {
-+                Job *job = &bj->job;
-+                WITH_JOB_LOCK_GUARD() {
-+                    if (!job_is_completed_locked(job)) {
-+                        job_cancel_sync_locked(job, true);
-+                        /*
-+                         * It's enough to cancel one job in the transaction, the
-+                         * rest will follow automatically.
-+                         */
-+                        break;
-+                    }
-+                }
-+            }
-+        }
-+        bdi = g_list_next(bdi);
-+    }
-+
-     aio_co_enter(data->ctx, data->co);
- }
- 
-@@ -382,22 +411,12 @@ void coroutine_fn qmp_backup_cancel(Error **errp)
-         proxmox_backup_abort(backup_state.pbs, "backup canceled");
-     }
- 
--    /* it's enough to cancel one job in the transaction, the rest will follow
--     * automatically */
--    GList *bdi = g_list_first(backup_state.di_list);
--    BlockJob *cancel_job = bdi && bdi->data ?
--        ((PVEBackupDevInfo *)bdi->data)->job :
--        NULL;
--
--    if (cancel_job) {
--        CoCtxData data = {
--            .ctx = qemu_get_current_aio_context(),
--            .co = qemu_coroutine_self(),
--            .data = &cancel_job->job,
--        };
--        aio_bh_schedule_oneshot(data.ctx, job_cancel_bh, &data);
--        qemu_coroutine_yield();
--    }
-+    CoCtxData data = {
-+        .ctx = qemu_get_current_aio_context(),
-+        .co = qemu_coroutine_self(),
-+    };
-+    aio_bh_schedule_oneshot(data.ctx, job_cancel_bh, &data);
-+    qemu_coroutine_yield();
- 
-     qemu_co_mutex_unlock(&backup_state.backup_mutex);
- }
diff --git a/debian/patches/pve/0059-vma-create-support-64KiB-unaligned-input-images.patch b/debian/patches/pve/0059-vma-create-support-64KiB-unaligned-input-images.patch
deleted file mode 100644
index ffa8d0e..0000000
--- a/debian/patches/pve/0059-vma-create-support-64KiB-unaligned-input-images.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fabian Ebner <f.ebner@proxmox.com>
-Date: Wed, 22 Jun 2022 10:45:11 +0200
-Subject: [PATCH] vma: create: support 64KiB-unaligned input images
-
-which fixes backing up templates with such disks in PVE, for example
-efitype=4m EFI disks on a file-based storage (size = 540672).
-
-If there is not enough left to read, blk_co_preadv will return -EIO,
-so limit the size in the last iteration.
-
-For writing, an unaligned end is already handled correctly.
-
-The call to memset is not strictly necessary, because writing also
-checks that it doesn't write data beyond the end of the image. But
-there are two reasons to do it:
-1. It's cleaner that way.
-2. It allows detecting when the final piece is all zeroes, which might
-   not happen if the buffer still contains data from the previous
-   iteration.
-
-Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
----
- vma.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/vma.c b/vma.c
-index e6e9ffc7fe..304f02bc84 100644
---- a/vma.c
-+++ b/vma.c
-@@ -548,7 +548,7 @@ static void coroutine_fn backup_run(void *opaque)
-     struct iovec iov;
-     QEMUIOVector qiov;
- 
--    int64_t start, end;
-+    int64_t start, end, readlen;
-     int ret = 0;
- 
-     unsigned char *buf = blk_blockalign(job->target, VMA_CLUSTER_SIZE);
-@@ -562,8 +562,16 @@ static void coroutine_fn backup_run(void *opaque)
-         iov.iov_len = VMA_CLUSTER_SIZE;
-         qemu_iovec_init_external(&qiov, &iov, 1);
- 
-+        if (start + 1 == end) {
-+            memset(buf, 0, VMA_CLUSTER_SIZE);
-+            readlen = job->len - start * VMA_CLUSTER_SIZE;
-+            assert(readlen > 0 && readlen <= VMA_CLUSTER_SIZE);
-+        } else {
-+            readlen = VMA_CLUSTER_SIZE;
-+        }
-+
-         ret = blk_co_preadv(job->target, start * VMA_CLUSTER_SIZE,
--                            VMA_CLUSTER_SIZE, &qiov, 0);
-+                            readlen, &qiov, 0);
-         if (ret < 0) {
-             vma_writer_set_error(job->vmaw, "read error", -1);
-             goto out;
diff --git a/debian/patches/pve/0060-vma-create-avoid-triggering-assertion-in-error-case.patch b/debian/patches/pve/0060-vma-create-avoid-triggering-assertion-in-error-case.patch
deleted file mode 100644
index c7961ae..0000000
--- a/debian/patches/pve/0060-vma-create-avoid-triggering-assertion-in-error-case.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fabian Ebner <f.ebner@proxmox.com>
-Date: Wed, 22 Jun 2022 10:45:12 +0200
-Subject: [PATCH] vma: create: avoid triggering assertion in error case
-
-error_setg expects its argument to not be initialized yet.
-
-Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
----
- vma-writer.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/vma-writer.c b/vma-writer.c
-index df4b20793d..ac7da237d0 100644
---- a/vma-writer.c
-+++ b/vma-writer.c
-@@ -311,6 +311,8 @@ VmaWriter *vma_writer_create(const char *filename, uuid_t uuid, Error **errp)
-         }
- 
-         if (vmaw->fd < 0) {
-+            error_free(*errp);
-+            *errp = NULL;
-             error_setg(errp, "can't open file %s - %s\n", filename,
-                        g_strerror(errno));
-             goto err;
diff --git a/debian/patches/pve/0061-block-alloc-track-avoid-premature-break.patch b/debian/patches/pve/0061-block-alloc-track-avoid-premature-break.patch
deleted file mode 100644
index a1c3d11..0000000
--- a/debian/patches/pve/0061-block-alloc-track-avoid-premature-break.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fabian Ebner <f.ebner@proxmox.com>
-Date: Wed, 22 Jun 2022 10:45:13 +0200
-Subject: [PATCH] block: alloc-track: avoid premature break
-
-While the bdrv_co_preadv() calls are expected to return 0 on success,
-qemu_iovec_memset() will return the number of bytes set (will be
-local_bytes, because the slice with that size was just initialized).
-
-Don't break out of the loop after the branch with qemu_iovec_memset(),
-because there might still be work to do. Additionally, ret is an int,
-which on 64-bit platforms is too small to hold the size_t returned by
-qemu_iovec_memset().
-
-The branch seems to be difficult to reach in practice, because the
-whole point of alloc-track is to be used with a backing device.
-
-Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
----
- block/alloc-track.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/block/alloc-track.c b/block/alloc-track.c
-index 113bbd7058..b75d7c6460 100644
---- a/block/alloc-track.c
-+++ b/block/alloc-track.c
-@@ -175,7 +175,8 @@ static int coroutine_fn track_co_preadv(BlockDriverState *bs,
-             ret = bdrv_co_preadv(bs->backing, local_offset, local_bytes,
-                                  &local_qiov, flags);
-         } else {
--            ret = qemu_iovec_memset(&local_qiov, cur_offset, 0, local_bytes);
-+            qemu_iovec_memset(&local_qiov, cur_offset, 0, local_bytes);
-+            ret = 0;
-         }
- 
-         if (ret != 0) {
diff --git a/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch b/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
deleted file mode 100644
index 8fd63c0..0000000
--- a/debian/patches/pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fiona Ebner <f.ebner@proxmox.com>
-Date: Mon, 3 Oct 2022 15:52:04 +0200
-Subject: [PATCH] PVE Backup: allow passing max-workers performance setting
-
-For query-proxmox-support, add an indication that it's possible to use
-the setting.
-
-For now, the other two BackupPerf settings are not exposed:
-
-* use-copy-range: would need to be implemented by the backup-dump
-block driver first, and in fact, the default for backup was changed,
-because it wasn't as fast for backup in QEMU, see commit
-6a30f663d4c0b3c45a544d541e0c4e214b2473a1.
-
-* max-chunk: enforced to be at least the backup cluster size, which is
-4 MiB for PBS and otherwise maximum of source and target cluster size.
-And block-copy has a maximum buffer size of 1 MiB, so setting a larger
-max-chunk doesn't even have an effect. To make the setting sensibly
-usable the check would need to be removed and optionally the
-block-copy max buffer size would need to be bumped. I tried doing just
-that, and tested different source/target combinations with different
-max-chunk settings, but there were no noticable improvements over the
-default "unlimited" (resulting in 1 MiB for block-copy).
-
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- block/monitor/block-hmp-cmds.c |  4 +++-
- pve-backup.c                   | 18 +++++++++++++-----
- qapi/block-core.json           |  9 +++++++--
- 3 files changed, 23 insertions(+), 8 deletions(-)
-
-diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index ac23f21eef..636509b83e 100644
---- a/block/monitor/block-hmp-cmds.c
-+++ b/block/monitor/block-hmp-cmds.c
-@@ -1063,7 +1063,9 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
-         false, false, // PBS encrypt
-         true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
-         NULL, NULL,
--        devlist, qdict_haskey(qdict, "speed"), speed, &error);
-+        devlist, qdict_haskey(qdict, "speed"), speed,
-+        false, 0, // BackupPerf max-workers
-+        &error);
- 
-     hmp_handle_error(mon, error);
- }
-diff --git a/pve-backup.c b/pve-backup.c
-index 7a8240363d..cb5312fff3 100644
---- a/pve-backup.c
-+++ b/pve-backup.c
-@@ -57,6 +57,7 @@ static struct PVEBackupState {
-         bool starting;
-     } stat;
-     int64_t speed;
-+    BackupPerf perf;
-     VmaWriter *vmaw;
-     ProxmoxBackupHandle *pbs;
-     GList *di_list;
-@@ -492,8 +493,6 @@ static void create_backup_jobs_bh(void *opaque) {
-     }
-     backup_state.txn = job_txn_new_seq();
- 
--    BackupPerf perf = { .max_workers = 16 };
--
-     /* create and start all jobs (paused state) */
-     GList *l =  backup_state.di_list;
-     while (l) {
-@@ -513,8 +512,9 @@ static void create_backup_jobs_bh(void *opaque) {
- 
-         BlockJob *job = backup_job_create(
-             NULL, di->bs, di->target, backup_state.speed, sync_mode, di->bitmap,
--            bitmap_mode, false, NULL, &perf, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
--            JOB_DEFAULT, pvebackup_complete_cb, di, backup_state.txn, &local_err);
-+            bitmap_mode, false, NULL, &backup_state.perf, BLOCKDEV_ON_ERROR_REPORT,
-+            BLOCKDEV_ON_ERROR_REPORT, JOB_DEFAULT, pvebackup_complete_cb, di, backup_state.txn,
-+            &local_err);
- 
-         aio_context_release(aio_context);
- 
-@@ -585,7 +585,9 @@ UuidInfo coroutine_fn *qmp_backup(
-     const char *config_file,
-     const char *firewall_file,
-     const char *devlist,
--    bool has_speed, int64_t speed, Error **errp)
-+    bool has_speed, int64_t speed,
-+    bool has_max_workers, int64_t max_workers,
-+    Error **errp)
- {
-     assert(qemu_in_coroutine());
- 
-@@ -915,6 +917,11 @@ UuidInfo coroutine_fn *qmp_backup(
- 
-     backup_state.speed = (has_speed && speed > 0) ? speed : 0;
- 
-+    backup_state.perf = (BackupPerf){ .max_workers = 16 };
-+    if (has_max_workers) {
-+        backup_state.perf.max_workers = max_workers;
-+    }
-+
-     backup_state.vmaw = vmaw;
-     backup_state.pbs = pbs;
- 
-@@ -1086,5 +1093,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
-     ret->pbs_dirty_bitmap_migration = true;
-     ret->query_bitmap_info = true;
-     ret->pbs_masterkey = true;
-+    ret->backup_max_workers = true;
-     return ret;
- }
-diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 9edeb33d82..809f3c61bc 100644
---- a/qapi/block-core.json
-+++ b/qapi/block-core.json
-@@ -924,6 +924,8 @@
- #
- # @encrypt: use encryption ((optional for format 'pbs', defaults to true if there is a keyfile)
- #
-+# @max-workers: see @BackupPerf for details. Default 16.
-+#
- # Returns: the uuid of the backup job
- #
- ##
-@@ -942,7 +944,9 @@
-                                     '*format': 'BackupFormat',
-                                     '*config-file': 'str',
-                                     '*firewall-file': 'str',
--                                    '*devlist': 'str', '*speed': 'int' },
-+                                    '*devlist': 'str',
-+                                    '*speed': 'int',
-+                                    '*max-workers': 'int' },
-   'returns': 'UuidInfo', 'coroutine': true }
- 
- ##
-@@ -997,7 +1001,8 @@
-             'pbs-dirty-bitmap-savevm': 'bool',
-             'pbs-dirty-bitmap-migration': 'bool',
-             'pbs-masterkey': 'bool',
--            'pbs-library-version': 'str' } }
-+            'pbs-library-version': 'str',
-+            'backup-max-workers': 'bool' } }
- 
- ##
- # @query-proxmox-support:
diff --git a/debian/patches/pve/0064-savevm-async-optimize-querying-pending.patch b/debian/patches/pve/0064-savevm-async-optimize-querying-pending.patch
deleted file mode 100644
index fb99782..0000000
--- a/debian/patches/pve/0064-savevm-async-optimize-querying-pending.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fiona Ebner <f.ebner@proxmox.com>
-Date: Fri, 31 Mar 2023 14:13:01 +0200
-Subject: [PATCH] savevm-async: optimize querying pending
-
-by using the estimate variant until the precopy estimate is below the
-threshold. This is similar to what is done in migration.c
-
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- migration/savevm-async.c | 15 +++++++++++----
- 1 file changed, 11 insertions(+), 4 deletions(-)
-
-diff --git a/migration/savevm-async.c b/migration/savevm-async.c
-index fab1dc32d2..de91506821 100644
---- a/migration/savevm-async.c
-+++ b/migration/savevm-async.c
-@@ -242,12 +242,19 @@ static void coroutine_fn process_savevm_co(void *opaque)
- 
-     while (snap_state.state == SAVE_STATE_ACTIVE) {
-         uint64_t pending_size, pend_precopy, pend_postcopy;
-+        uint64_t threshold = 400 * 1000;
- 
--        /* pending is expected to be called without iothread lock */
-+        /*
-+         * pending_{estimate,exact} are expected to be called without iothread
-+         * lock. Similar to what is done in migration.c, call the exact variant
-+         * only once pend_precopy in the estimate is below the threshold.
-+         */
-         qemu_mutex_unlock_iothread();
--        qemu_savevm_state_pending_exact(&pend_precopy, &pend_postcopy);
-+        qemu_savevm_state_pending_estimate(&pend_precopy, &pend_postcopy);
-+        if (pend_precopy <= threshold) {
-+            qemu_savevm_state_pending_exact(&pend_precopy, &pend_postcopy);
-+        }
-         qemu_mutex_lock_iothread();
--
-         pending_size = pend_precopy + pend_postcopy;
- 
-         /*
-@@ -259,7 +266,7 @@ static void coroutine_fn process_savevm_co(void *opaque)
-         maxlen = blk_getlength(snap_state.target) - 100*1024*1024;
- 
-         /* Note that there is no progress for pend_postcopy when iterating */
--        if (pending_size - pend_postcopy > 400000 && snap_state.bs_pos + pending_size < maxlen) {
-+        if (pend_precopy > threshold && snap_state.bs_pos + pending_size < maxlen) {
-             ret = qemu_savevm_state_iterate(snap_state.file, false);
-             if (ret < 0) {
-                 save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
diff --git a/debian/patches/pve/0065-savevm-async-also-initialize-compression-counters.patch b/debian/patches/pve/0065-savevm-async-also-initialize-compression-counters.patch
deleted file mode 100644
index ae2b463..0000000
--- a/debian/patches/pve/0065-savevm-async-also-initialize-compression-counters.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fiona Ebner <f.ebner@proxmox.com>
-Date: Thu, 27 Apr 2023 10:28:08 +0200
-Subject: [PATCH] savevm-async: also initialize compression counters
-
-Like is done in the migration code. While the compression migration
-capability is not used by Proxmox VE currently, it's still worth to
-be prepared for the future.
-
-Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
----
- migration/savevm-async.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/migration/savevm-async.c b/migration/savevm-async.c
-index de91506821..effe6d1e0d 100644
---- a/migration/savevm-async.c
-+++ b/migration/savevm-async.c
-@@ -394,6 +394,7 @@ void qmp_savevm_start(const char *statefile, Error **errp)
-      */
-     migrate_init(ms);
-     memset(&ram_counters, 0, sizeof(ram_counters));
-+    memset(&compression_counters, 0, sizeof(compression_counters));
-     ms->to_dst_file = snap_state.file;
- 
-     error_setg(&snap_state.blocker, "block device is in use by savevm");
diff --git a/debian/patches/series b/debian/patches/series
index 90d7943..375b2db 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -36,58 +36,37 @@ pve/0009-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
 pve/0010-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
 pve/0011-PVE-Up-qemu-img-dd-add-isize-parameter.patch
 pve/0012-PVE-Up-qemu-img-dd-add-n-skip_create.patch
-pve/0013-PVE-virtio-balloon-improve-query-balloon.patch
-pve/0014-PVE-qapi-modify-query-machines.patch
-pve/0015-PVE-qapi-modify-spice-query.patch
-pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch
-pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch
-pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch
-pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
-pve/0020-PVE-Add-dummy-id-command-line-parameter.patch
-pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
-pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
-pve/0023-PVE-monitor-disable-oob-capability.patch
-pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
-pve/0025-PVE-Allow-version-code-in-machine-type.patch
-pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch
-pve/0027-PVE-Backup-add-vma-backup-format-code.patch
-pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
-pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
-pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
-pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
-pve/0032-PVE-various-PBS-fixes.patch
+pve/0013-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
+pve/0014-PVE-virtio-balloon-improve-query-balloon.patch
+pve/0015-PVE-qapi-modify-query-machines.patch
+pve/0016-PVE-qapi-modify-spice-query.patch
+pve/0017-PVE-add-IOChannel-implementation-for-savevm-async.patch
+pve/0018-PVE-add-savevm-async-for-background-state-snapshots.patch
+pve/0019-PVE-add-optional-buffer-size-to-QEMUFile.patch
+pve/0020-PVE-block-add-the-zeroinit-block-driver-filter.patch
+pve/0021-PVE-Add-dummy-id-command-line-parameter.patch
+pve/0022-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
+pve/0023-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
+pve/0024-PVE-monitor-disable-oob-capability.patch
+pve/0025-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
+pve/0026-PVE-Allow-version-code-in-machine-type.patch
+pve/0027-block-backup-move-bcs-bitmap-initialization-to-job-c.patch
+pve/0028-PVE-Backup-add-vma-backup-format-code.patch
+pve/0029-PVE-Backup-add-backup-dump-block-driver.patch
+pve/0030-PVE-Add-sequential-job-transaction-support.patch
+pve/0031-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch
+pve/0032-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
 pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
-pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
-pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
-pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch
-pve/0037-PVE-Add-sequential-job-transaction-support.patch
-pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
-pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
-pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
-pve/0041-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
-pve/0042-PVE-fall-back-to-open-iscsi-initiatorname.patch
-pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
-pve/0044-PBS-add-master-key-support.patch
-pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch
-pve/0046-PVE-block-stream-increase-chunk-size.patch
-pve/0047-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
-pve/0048-block-add-alloc-track-driver.patch
-pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch
-pve/0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
-pve/0051-vma-allow-partial-restore.patch
-pve/0052-pbs-namespace-support.patch
-pve/0053-Revert-block-rbd-workaround-for-ceph-issue-53784.patch
-pve/0054-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch
-pve/0055-Revert-block-rbd-implement-bdrv_co_block_status.patch
-pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
-pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
-pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
-pve/0059-vma-create-support-64KiB-unaligned-input-images.patch
-pve/0060-vma-create-avoid-triggering-assertion-in-error-case.patch
-pve/0061-block-alloc-track-avoid-premature-break.patch
-pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
-pve/0063-alloc-track-fix-deadlock-during-drop.patch
-pve/0064-savevm-async-optimize-querying-pending.patch
-pve/0065-savevm-async-also-initialize-compression-counters.patch
-pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
-pve/0067-savevm-async-don-t-hold-BQL-during-setup.patch
+pve/0034-PVE-redirect-stderr-to-journal-when-daemonized.patch
+pve/0035-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
+pve/0036-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
+pve/0037-PVE-fall-back-to-open-iscsi-initiatorname.patch
+pve/0038-PVE-block-stream-increase-chunk-size.patch
+pve/0039-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
+pve/0040-block-add-alloc-track-driver.patch
+pve/0041-Revert-block-rbd-workaround-for-ceph-issue-53784.patch
+pve/0042-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch
+pve/0043-Revert-block-rbd-implement-bdrv_co_block_status.patch
+pve/0044-alloc-track-fix-deadlock-during-drop.patch
+pve/0045-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
+pve/0046-savevm-async-don-t-hold-BQL-during-setup.patch
-- 
2.39.2





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

* Re: [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0
  2023-05-15 13:39 [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
                   ` (6 preceding siblings ...)
  2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 7/7] squash related patches Fiona Ebner
@ 2023-05-15 13:51 ` Fiona Ebner
  2023-05-16 14:04   ` Fiona Ebner
  2023-05-23 12:31 ` [pve-devel] applied-series: " Thomas Lamprecht
  8 siblings, 1 reply; 11+ messages in thread
From: Fiona Ebner @ 2023-05-15 13:51 UTC (permalink / raw)
  To: pve-devel

I should also mention that I ran into a migration issue today where a
guest crashed (inside the VM, QEMU itself seemed fine), because of I/O.
Might be related to PBS backup, local disks and/or snapshots. Will need
to debug and see if I can reproduce it. So please don't test it with
production machines yet ;)




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

* Re: [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0
  2023-05-15 13:51 ` [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
@ 2023-05-16 14:04   ` Fiona Ebner
  0 siblings, 0 replies; 11+ messages in thread
From: Fiona Ebner @ 2023-05-16 14:04 UTC (permalink / raw)
  To: pve-devel

Am 15.05.23 um 15:51 schrieb Fiona Ebner:
> I should also mention that I ran into a migration issue today where a
> guest crashed (inside the VM, QEMU itself seemed fine), because of I/O.
> Might be related to PBS backup, local disks and/or snapshots. Will need
> to debug and see if I can reproduce it. So please don't test it with
> production machines yet ;)
> 

Well, the disk of my VM was actually full. But the VM was stuck with
"Guest has not initialized the display (yet)", which is the strange
part. Maybe that can happen if the guest is migrated while
hanging/crashed. Even with trying quite a bit today, I haven't been able
to reproduce the issue a second time, so maybe it really was just that.




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

* [pve-devel] applied-series: [PATCH-SERIES v2 qemu] update to QEMU 8.0
  2023-05-15 13:39 [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
                   ` (7 preceding siblings ...)
  2023-05-15 13:51 ` [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
@ 2023-05-23 12:31 ` Thomas Lamprecht
  8 siblings, 0 replies; 11+ messages in thread
From: Thomas Lamprecht @ 2023-05-23 12:31 UTC (permalink / raw)
  To: Proxmox VE development discussion, Fiona Ebner

Am 15/05/2023 um 15:39 schrieb Fiona Ebner:
> After weeks and weeks of (sometimes painful) debugging, it's finally
> here. And got a load of stable fixes on top already. More testing is
> always appreciated, especially backup, PBS live restore and snapshots,
> which needed quite a few changes!
> 
> Changes from v1:
> * Add fix for lintian overrides.
> * Add patch squashing related changes (not required for 8.0 but will
> make life easier going forward).
> 
> Fiona Ebner (7):
>   d/rules: drop virtiofsd switch
>   d/rules: set job flag for make based on DEB_BUILD_OPTIONS
>   buildsys: fix lintian overrides
>   update submodule and patches to QEMU 8.0.0
>   add stable patches for 8.0.0
>   PVE backup: don't call no_co_wrapper function from coroutine
>   squash related patches
> 

applied, rebased onto your bookworm-build-cleanup branch with some additional
cleanups added, thanks!

Albeit I did not really test much for now, and w.r.t. packaging the switch
from manual d/rules to using dh wildcard rule is still standing out, but I
figured that's easier to do later and should not change the build result..




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

end of thread, other threads:[~2023-05-23 12:32 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-15 13:39 [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 1/7] d/rules: drop virtiofsd switch Fiona Ebner
2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 2/7] d/rules: set job flag for make based on DEB_BUILD_OPTIONS Fiona Ebner
2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 3/7] buildsys: fix lintian overrides Fiona Ebner
2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 4/7] update submodule and patches to QEMU 8.0.0 Fiona Ebner
2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 5/7] add stable patches for 8.0.0 Fiona Ebner
2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 6/7] PVE backup: don't call no_co_wrapper function from coroutine Fiona Ebner
2023-05-15 13:39 ` [pve-devel] [PATCH v2 qemu 7/7] squash related patches Fiona Ebner
2023-05-15 13:51 ` [pve-devel] [PATCH-SERIES v2 qemu] update to QEMU 8.0 Fiona Ebner
2023-05-16 14:04   ` Fiona Ebner
2023-05-23 12:31 ` [pve-devel] applied-series: " Thomas Lamprecht

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