diff --git a/SOURCES/libvirt-Make-systemd-unit-ordering-more-robust.patch b/SOURCES/libvirt-Make-systemd-unit-ordering-more-robust.patch
new file mode 100644
index 0000000..be38df5
--- /dev/null
+++ b/SOURCES/libvirt-Make-systemd-unit-ordering-more-robust.patch
@@ -0,0 +1,89 @@
+From ee1ce580f5373070e4b6a50d1ae4a3218c737a72 Mon Sep 17 00:00:00 2001
+Message-Id: <ee1ce580f5373070e4b6a50d1ae4a3218c737a72@dist-git>
+From: Martin Kletzander <mkletzan@redhat.com>
+Date: Mon, 14 Feb 2022 12:37:37 +0100
+Subject: [PATCH] Make systemd unit ordering more robust
+
+Since libvirt-guests script/service can operate on various URIs and we do
+support both socket activation and traditional services, the ordering should be
+specified for all the possible sockets and services.
+
+Also remove the Wants= dependency since do not want to start any service.  We
+cannot know which one libvirt-guests is configured, so we'd have to start all
+the daemons which would break if unused colliding services are not
+masked (libvirtd.service in the modular case and all the modular daemon service
+units in the monolithic scenario).  Fortunately we can assume that the system is
+configured properly to start services/sockets that are of interest to the user.
+That also works with the setup described in https://libvirt.org/daemons.html .
+
+To make it even more robust we add the daemon service into the machine units
+created for individual domains as it was missing there.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1868537
+
+Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 4e42686adef8b9e9266f0099ddcd25bc95c4ed43)
+Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
+---
+ src/util/virsystemd.c           |  8 ++++++--
+ tools/libvirt-guests.service.in | 12 +++++++++++-
+ 2 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
+index a86d4c6bb9..f156c2f39a 100644
+--- a/src/util/virsystemd.c
++++ b/src/util/virsystemd.c
+@@ -441,8 +441,10 @@ int virSystemdCreateMachine(const char *name,
+                                                 nicindexes, nnicindexes, sizeof(int));
+         gprops = g_variant_new_parsed("[('Slice', <%s>),"
+                                       " ('After', <['libvirtd.service']>),"
++                                      " ('After', <['virt%sd.service']>),"
+                                       " ('Before', <['virt-guest-shutdown.target']>)]",
+-                                      slicename);
++                                      slicename,
++                                      drivername);
+         message = g_variant_new("(s@ayssus@ai@a(sv))",
+                                 name,
+                                 guuid,
+@@ -489,8 +491,10 @@ int virSystemdCreateMachine(const char *name,
+                                           uuid, 16, sizeof(unsigned char));
+         gprops = g_variant_new_parsed("[('Slice', <%s>),"
+                                       " ('After', <['libvirtd.service']>),"
++                                      " ('After', <['virt%sd.service']>),"
+                                       " ('Before', <['virt-guest-shutdown.target']>)]",
+-                                      slicename);
++                                      slicename,
++                                      drivername);
+         message = g_variant_new("(s@ayssus@a(sv))",
+                                 name,
+                                 guuid,
+diff --git a/tools/libvirt-guests.service.in b/tools/libvirt-guests.service.in
+index 1a9b233e11..3cf6476196 100644
+--- a/tools/libvirt-guests.service.in
++++ b/tools/libvirt-guests.service.in
+@@ -1,10 +1,20 @@
+ [Unit]
+ Description=Suspend/Resume Running libvirt Guests
+-Wants=libvirtd.service
+ Requires=virt-guest-shutdown.target
+ After=network.target
+ After=time-sync.target
++After=libvirtd.socket
++After=virtqemud.socket
++After=virtlxcd.socket
++After=virtvboxd.socket
++After=virtvzd.socket
++After=virtxend.socket
+ After=libvirtd.service
++After=virtqemud.service
++After=virtlxcd.service
++After=virtvboxd.service
++After=virtvzd.service
++After=virtxend.service
+ After=virt-guest-shutdown.target
+ Documentation=man:libvirt-guests(8)
+ Documentation=https://libvirt.org
+-- 
+2.35.1
+
diff --git a/SOURCES/libvirt-nwfilter-hold-filter-update-lock-when-creating-deleting-bindings.patch b/SOURCES/libvirt-nwfilter-hold-filter-update-lock-when-creating-deleting-bindings.patch
new file mode 100644
index 0000000..d9f6fab
--- /dev/null
+++ b/SOURCES/libvirt-nwfilter-hold-filter-update-lock-when-creating-deleting-bindings.patch
@@ -0,0 +1,77 @@
+From bbab997f4307da65856dedd3f319037ce442d17e Mon Sep 17 00:00:00 2001
+Message-Id: <bbab997f4307da65856dedd3f319037ce442d17e@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Thu, 24 Feb 2022 18:41:29 +0000
+Subject: [PATCH] nwfilter: hold filter update lock when creating/deleting
+ bindings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The nwfilter update lock is historically acquired by the virt
+drivers in order to achieve serialization between nwfilter
+define/undefine, and instantiation/teardown of filters.
+
+When running in the modular daemons, however, the mutex that
+the virt drivers are locking is in a completely different
+process from the mutex that the nwfilter driver is locking.
+
+Serialization is lost and thus call from the virt driver to
+virNWFilterBindingCreateXML can deadlock with a concurrent
+call to the virNWFilterDefineXML method.
+
+The solution is surprisingly easy, the update lock simply
+needs acquiring in the virNWFilterBindingCreateXML method
+and virNWFilterBindingUndefine method instead of in the
+virt drivers.
+
+The only semantic difference here is that when a virtual
+machine has multiple NICs, the instantiation and teardown
+of filters is no longer serialized for the whole VM, but
+rather for each NIC. This should not be a problem since
+the virt drivers already need to cope with tearing down
+a partially created VM where only some of the NICs are
+setup.
+
+Reviewed-by: Laine Stump <laine@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 65dc79f50b96b34b2253601b8972d5ca90658f33)
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2044379
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/nwfilter/nwfilter_driver.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
+index 200451d6b1..a4479fc9fe 100644
+--- a/src/nwfilter/nwfilter_driver.c
++++ b/src/nwfilter/nwfilter_driver.c
+@@ -760,12 +760,15 @@ nwfilterBindingCreateXML(virConnectPtr conn,
+     if (!(ret = virGetNWFilterBinding(conn, def->portdevname, def->filter)))
+         goto cleanup;
+ 
++    virNWFilterReadLockFilterUpdates();
+     if (virNWFilterInstantiateFilter(driver, def) < 0) {
++        virNWFilterUnlockFilterUpdates();
+         virNWFilterBindingObjListRemove(driver->bindings, obj);
+         virObjectUnref(ret);
+         ret = NULL;
+         goto cleanup;
+     }
++    virNWFilterUnlockFilterUpdates();
+     virNWFilterBindingObjSave(obj, driver->bindingDir);
+ 
+  cleanup:
+@@ -802,7 +805,9 @@ nwfilterBindingDelete(virNWFilterBindingPtr binding)
+     if (virNWFilterBindingDeleteEnsureACL(binding->conn, def) < 0)
+         goto cleanup;
+ 
++    virNWFilterReadLockFilterUpdates();
+     virNWFilterTeardownFilter(def);
++    virNWFilterUnlockFilterUpdates();
+     virNWFilterBindingObjDelete(obj, driver->bindingDir);
+     virNWFilterBindingObjListRemove(driver->bindings, obj);
+ 
+-- 
+2.35.1
+
diff --git a/SOURCES/libvirt-qemu-lxc-remove-use-to-nwfilter-update-lock.patch b/SOURCES/libvirt-qemu-lxc-remove-use-to-nwfilter-update-lock.patch
new file mode 100644
index 0000000..6699b1c
--- /dev/null
+++ b/SOURCES/libvirt-qemu-lxc-remove-use-to-nwfilter-update-lock.patch
@@ -0,0 +1,222 @@
+From 7bcd75ca73d8eda05fafa8342309a8fd058cd326 Mon Sep 17 00:00:00 2001
+Message-Id: <7bcd75ca73d8eda05fafa8342309a8fd058cd326@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Thu, 24 Feb 2022 19:02:32 +0000
+Subject: [PATCH] qemu,lxc: remove use to nwfilter update lock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Now that the virNWFilterBinding APIs are using the nwfilter
+update lock directly, there is no need for the virt drivers
+to do it themselves.
+
+Reviewed-by: Laine Stump <laine@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 5f8b090f421cd6a6c46f44905431491e2d3cf8f5)
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2044379
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/lxc/lxc_driver.c      |  6 ------
+ src/qemu/qemu_driver.c    | 18 ------------------
+ src/qemu/qemu_migration.c |  3 ---
+ src/qemu/qemu_process.c   |  4 ----
+ 4 files changed, 31 deletions(-)
+
+diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
+index 7bc39120ee..e581c62668 100644
+--- a/src/lxc/lxc_driver.c
++++ b/src/lxc/lxc_driver.c
+@@ -971,8 +971,6 @@ static int lxcDomainCreateWithFiles(virDomainPtr dom,
+ 
+     virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, -1);
+ 
+-    virNWFilterReadLockFilterUpdates();
+-
+     if (!(vm = lxcDomObjFromDomain(dom)))
+         goto cleanup;
+ 
+@@ -1014,7 +1012,6 @@ static int lxcDomainCreateWithFiles(virDomainPtr dom,
+  cleanup:
+     virDomainObjEndAPI(&vm);
+     virObjectEventStateQueue(driver->domainEventState, event);
+-    virNWFilterUnlockFilterUpdates();
+     return ret;
+ }
+ 
+@@ -1080,8 +1077,6 @@ lxcDomainCreateXMLWithFiles(virConnectPtr conn,
+     if (flags & VIR_DOMAIN_START_VALIDATE)
+         parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA;
+ 
+-    virNWFilterReadLockFilterUpdates();
+-
+     if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+         goto cleanup;
+ 
+@@ -1138,7 +1133,6 @@ lxcDomainCreateXMLWithFiles(virConnectPtr conn,
+  cleanup:
+     virDomainObjEndAPI(&vm);
+     virObjectEventStateQueue(driver->domainEventState, event);
+-    virNWFilterUnlockFilterUpdates();
+     return dom;
+ }
+ 
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index d3d76c003f..00a86b6c7c 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -1603,8 +1603,6 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
+     if (flags & VIR_DOMAIN_START_AUTODESTROY)
+         start_flags |= VIR_QEMU_PROCESS_START_AUTODESTROY;
+ 
+-    virNWFilterReadLockFilterUpdates();
+-
+     if (!(def = virDomainDefParseString(xml, driver->xmlopt,
+                                         NULL, parse_flags)))
+         goto cleanup;
+@@ -1658,7 +1656,6 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
+     virDomainObjEndAPI(&vm);
+     virObjectEventStateQueue(driver->domainEventState, event);
+     virObjectEventStateQueue(driver->domainEventState, event2);
+-    virNWFilterUnlockFilterUpdates();
+     return dom;
+ }
+ 
+@@ -5773,8 +5770,6 @@ qemuDomainRestoreFlags(virConnectPtr conn,
+                   VIR_DOMAIN_SAVE_PAUSED, -1);
+ 
+ 
+-    virNWFilterReadLockFilterUpdates();
+-
+     fd = qemuSaveImageOpen(driver, NULL, path, &def, &data,
+                            (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
+                            &wrapperFd, false, false);
+@@ -5846,7 +5841,6 @@ qemuDomainRestoreFlags(virConnectPtr conn,
+     if (vm && ret < 0)
+         qemuDomainRemoveInactiveJob(driver, vm);
+     virDomainObjEndAPI(&vm);
+-    virNWFilterUnlockFilterUpdates();
+     return ret;
+ }
+ 
+@@ -6395,8 +6389,6 @@ qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
+                   VIR_DOMAIN_START_BYPASS_CACHE |
+                   VIR_DOMAIN_START_FORCE_BOOT, -1);
+ 
+-    virNWFilterReadLockFilterUpdates();
+-
+     if (!(vm = qemuDomainObjFromDomain(dom)))
+         goto cleanup;
+ 
+@@ -6425,7 +6417,6 @@ qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
+ 
+  cleanup:
+     virDomainObjEndAPI(&vm);
+-    virNWFilterUnlockFilterUpdates();
+     return ret;
+ }
+ 
+@@ -7811,8 +7802,6 @@ qemuDomainAttachDeviceFlags(virDomainPtr dom,
+     virDomainObj *vm = NULL;
+     int ret = -1;
+ 
+-    virNWFilterReadLockFilterUpdates();
+-
+     if (!(vm = qemuDomainObjFromDomain(dom)))
+         goto cleanup;
+ 
+@@ -7835,7 +7824,6 @@ qemuDomainAttachDeviceFlags(virDomainPtr dom,
+ 
+  cleanup:
+     virDomainObjEndAPI(&vm);
+-    virNWFilterUnlockFilterUpdates();
+     return ret;
+ }
+ 
+@@ -7865,8 +7853,6 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
+                   VIR_DOMAIN_AFFECT_CONFIG |
+                   VIR_DOMAIN_DEVICE_MODIFY_FORCE, -1);
+ 
+-    virNWFilterReadLockFilterUpdates();
+-
+     cfg = virQEMUDriverGetConfig(driver);
+ 
+     if (!(vm = qemuDomainObjFromDomain(dom)))
+@@ -7943,7 +7929,6 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
+     if (dev != dev_copy)
+         virDomainDeviceDefFree(dev_copy);
+     virDomainObjEndAPI(&vm);
+-    virNWFilterUnlockFilterUpdates();
+     return ret;
+ }
+ 
+@@ -13644,8 +13629,6 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
+     virDomainObj *vm = NULL;
+     int ret = -1;
+ 
+-    virNWFilterReadLockFilterUpdates();
+-
+     if (!(vm = qemuDomObjFromSnapshot(snapshot)))
+         goto cleanup;
+ 
+@@ -13656,7 +13639,6 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
+ 
+  cleanup:
+     virDomainObjEndAPI(&vm);
+-    virNWFilterUnlockFilterUpdates();
+     return ret;
+ }
+ 
+diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
+index 2635ef1162..358cb9c3b5 100644
+--- a/src/qemu/qemu_migration.c
++++ b/src/qemu/qemu_migration.c
+@@ -2779,8 +2779,6 @@ qemuMigrationDstPrepareAny(virQEMUDriver *driver,
+     int rv;
+     g_autofree char *tlsAlias = NULL;
+ 
+-    virNWFilterReadLockFilterUpdates();
+-
+     if (flags & VIR_MIGRATE_OFFLINE) {
+         if (flags & (VIR_MIGRATE_NON_SHARED_DISK |
+                      VIR_MIGRATE_NON_SHARED_INC)) {
+@@ -3101,7 +3099,6 @@ qemuMigrationDstPrepareAny(virQEMUDriver *driver,
+     virDomainObjEndAPI(&vm);
+     virObjectEventStateQueue(driver->domainEventState, event);
+     qemuMigrationCookieFree(mig);
+-    virNWFilterUnlockFilterUpdates();
+     virErrorRestore(&origErr);
+     return ret;
+ 
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 5c6657a876..914f9bef8b 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -8986,7 +8986,6 @@ qemuProcessReconnect(void *opaque)
+             qemuDomainRemoveInactiveJob(driver, obj);
+     }
+     virDomainObjEndAPI(&obj);
+-    virNWFilterUnlockFilterUpdates();
+     virIdentitySetCurrent(NULL);
+     return;
+ 
+@@ -9038,8 +9037,6 @@ qemuProcessReconnectHelper(virDomainObj *obj,
+     data->obj = obj;
+     data->identity = virIdentityGetCurrent();
+ 
+-    virNWFilterReadLockFilterUpdates();
+-
+     /* this lock and reference will be eventually transferred to the thread
+      * that handles the reconnect */
+     virObjectLock(obj);
+@@ -9062,7 +9059,6 @@ qemuProcessReconnectHelper(virDomainObj *obj,
+         qemuDomainRemoveInactiveJobLocked(src->driver, obj);
+ 
+         virDomainObjEndAPI(&obj);
+-        virNWFilterUnlockFilterUpdates();
+         g_clear_object(&data->identity);
+         VIR_FREE(data);
+         return -1;
+-- 
+2.35.1
+
diff --git a/SOURCES/libvirt-qemu-support-firmware-descriptor-flash-mode-for-optional-NVRAM.patch b/SOURCES/libvirt-qemu-support-firmware-descriptor-flash-mode-for-optional-NVRAM.patch
new file mode 100644
index 0000000..822b859
--- /dev/null
+++ b/SOURCES/libvirt-qemu-support-firmware-descriptor-flash-mode-for-optional-NVRAM.patch
@@ -0,0 +1,471 @@
+From 3cde498c98be902fc8fe87c895dfeaaa95352b38 Mon Sep 17 00:00:00 2001
+Message-Id: <3cde498c98be902fc8fe87c895dfeaaa95352b38@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Thu, 3 Feb 2022 13:43:18 +0000
+Subject: [PATCH] qemu: support firmware descriptor flash 'mode' for optional
+ NVRAM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Currently the 'nvram_template' entry is mandatory when parsing the
+firmware descriptor based on flash. QEMU is extending the firmware
+descriptor spec to make the 'nvram_template' optional, depending
+on the value of a new 'mode' field:
+
+  - "split"
+      * "executable" contains read-only CODE
+      * "nvram_template" contains read-write VARS
+
+  - "combined"
+      * "executable" contains read-write CODE and VARs
+      * "nvram_template" not present
+
+  - "stateless"
+      * "executable" contains read-only CODE and VARs
+      * "nvram_template" not present
+
+In the latter case, the guest OS can write vars but the
+firmware will make no attempt to persist them, so any changes
+will be lost at poweroff.
+
+For now we parse this new 'mode' but discard any firmware
+which is not 'mode=split' when matching for a domain.
+
+In the tests we have a mixture of files with and without the
+mode attribute.
+
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 32b9d8b0ae00669555f01f91ee11612a636c4b69)
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2057769
+---
+ src/qemu/qemu_firmware.c                      | 79 ++++++++++++++++---
+ .../share/qemu/firmware/50-ovmf-sb-keys.json  | 33 ++++++++
+ .../out/usr/share/qemu/firmware/61-ovmf.json  | 31 ++++++++
+ .../out/usr/share/qemu/firmware/70-aavmf.json | 28 +++++++
+ .../qemu/firmware/45-ovmf-sev-stateless.json  | 31 ++++++++
+ .../qemu/firmware/55-ovmf-sb-combined.json    | 33 ++++++++
+ .../usr/share/qemu/firmware/60-ovmf-sb.json   |  1 +
+ tests/qemufirmwaretest.c                      | 31 ++++++--
+ 8 files changed, 246 insertions(+), 21 deletions(-)
+ create mode 100644 tests/qemufirmwaredata/out/usr/share/qemu/firmware/50-ovmf-sb-keys.json
+ create mode 100644 tests/qemufirmwaredata/out/usr/share/qemu/firmware/61-ovmf.json
+ create mode 100644 tests/qemufirmwaredata/out/usr/share/qemu/firmware/70-aavmf.json
+ create mode 100644 tests/qemufirmwaredata/usr/share/qemu/firmware/45-ovmf-sev-stateless.json
+ create mode 100644 tests/qemufirmwaredata/usr/share/qemu/firmware/55-ovmf-sb-combined.json
+
+diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
+index 529ab8d68e..7911d45aa0 100644
+--- a/src/qemu/qemu_firmware.c
++++ b/src/qemu/qemu_firmware.c
+@@ -59,6 +59,22 @@ VIR_ENUM_IMPL(qemuFirmwareOSInterface,
+ );
+ 
+ 
++typedef enum {
++    QEMU_FIRMWARE_FLASH_MODE_SPLIT,
++    QEMU_FIRMWARE_FLASH_MODE_COMBINED,
++    QEMU_FIRMWARE_FLASH_MODE_STATELESS,
++
++    QEMU_FIRMWARE_FLASH_MODE_LAST,
++} qemuFirmwareFlashMode;
++
++VIR_ENUM_DECL(qemuFirmwareFlashMode);
++VIR_ENUM_IMPL(qemuFirmwareFlashMode,
++              QEMU_FIRMWARE_FLASH_MODE_LAST,
++              "split",
++              "combined",
++              "stateless",
++);
++
+ typedef struct _qemuFirmwareFlashFile qemuFirmwareFlashFile;
+ struct _qemuFirmwareFlashFile {
+     char *filename;
+@@ -68,6 +84,7 @@ struct _qemuFirmwareFlashFile {
+ 
+ typedef struct _qemuFirmwareMappingFlash qemuFirmwareMappingFlash;
+ struct _qemuFirmwareMappingFlash {
++    qemuFirmwareFlashMode mode;
+     qemuFirmwareFlashFile executable;
+     qemuFirmwareFlashFile nvram_template;
+ };
+@@ -359,9 +376,31 @@ qemuFirmwareMappingFlashParse(const char *path,
+                               virJSONValue *doc,
+                               qemuFirmwareMappingFlash *flash)
+ {
++    virJSONValue *mode;
+     virJSONValue *executable;
+     virJSONValue *nvram_template;
+ 
++    if (!(mode = virJSONValueObjectGet(doc, "mode"))) {
++        /* Historical default */
++        flash->mode = QEMU_FIRMWARE_FLASH_MODE_SPLIT;
++    } else {
++        const char *modestr = virJSONValueGetString(mode);
++        int modeval;
++        if (!modestr) {
++            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                           _("Firmware flash mode value was malformed"));
++            return -1;
++        }
++        modeval = qemuFirmwareFlashModeTypeFromString(modestr);
++        if (modeval < 0) {
++            virReportError(VIR_ERR_INTERNAL_ERROR,
++                           _("Firmware flash mode value '%s' unexpected"),
++                           modestr);
++            return -1;
++        }
++        flash->mode = modeval;
++    }
++
+     if (!(executable = virJSONValueObjectGet(doc, "executable"))) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("missing 'executable' in '%s'"),
+@@ -372,15 +411,17 @@ qemuFirmwareMappingFlashParse(const char *path,
+     if (qemuFirmwareFlashFileParse(path, executable, &flash->executable) < 0)
+         return -1;
+ 
+-    if (!(nvram_template = virJSONValueObjectGet(doc, "nvram-template"))) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       _("missing 'nvram-template' in '%s'"),
+-                       path);
+-        return -1;
+-    }
++    if (flash->mode == QEMU_FIRMWARE_FLASH_MODE_SPLIT) {
++        if (!(nvram_template = virJSONValueObjectGet(doc, "nvram-template"))) {
++            virReportError(VIR_ERR_INTERNAL_ERROR,
++                           _("missing 'nvram-template' in '%s'"),
++                           path);
++            return -1;
++        }
+ 
+-    if (qemuFirmwareFlashFileParse(path, nvram_template, &flash->nvram_template) < 0)
+-        return -1;
++        if (qemuFirmwareFlashFileParse(path, nvram_template, &flash->nvram_template) < 0)
++            return -1;
++    }
+ 
+     return 0;
+ }
+@@ -693,10 +734,12 @@ qemuFirmwareMappingFlashFormat(virJSONValue *mapping,
+     g_autoptr(virJSONValue) executable = NULL;
+     g_autoptr(virJSONValue) nvram_template = NULL;
+ 
+-    if (!(executable = qemuFirmwareFlashFileFormat(flash->executable)))
++    if (virJSONValueObjectAppendString(mapping,
++                                       "mode",
++                                       qemuFirmwareFlashModeTypeToString(flash->mode)) < 0)
+         return -1;
+ 
+-    if (!(nvram_template = qemuFirmwareFlashFileFormat(flash->nvram_template)))
++    if (!(executable = qemuFirmwareFlashFileFormat(flash->executable)))
+         return -1;
+ 
+     if (virJSONValueObjectAppend(mapping,
+@@ -704,11 +747,15 @@ qemuFirmwareMappingFlashFormat(virJSONValue *mapping,
+                                  &executable) < 0)
+         return -1;
+ 
++    if (flash->mode == QEMU_FIRMWARE_FLASH_MODE_SPLIT) {
++        if (!(nvram_template = qemuFirmwareFlashFileFormat(flash->nvram_template)))
++            return -1;
+ 
+-    if (virJSONValueObjectAppend(mapping,
++        if (virJSONValueObjectAppend(mapping,
+                                  "nvram-template",
+-                                 &nvram_template) < 0)
+-        return -1;
++                                     &nvram_template) < 0)
++            return -1;
++    }
+ 
+     return 0;
+ }
+@@ -1053,6 +1100,12 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
+         return false;
+     }
+ 
++    if (fw->mapping.device == QEMU_FIRMWARE_DEVICE_FLASH &&
++        fw->mapping.data.flash.mode != QEMU_FIRMWARE_FLASH_MODE_SPLIT) {
++        VIR_DEBUG("Discarding loader without split flash");
++        return false;
++    }
++
+     if (def->sec) {
+         switch ((virDomainLaunchSecurity) def->sec->sectype) {
+         case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
+diff --git a/tests/qemufirmwaredata/out/usr/share/qemu/firmware/50-ovmf-sb-keys.json b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/50-ovmf-sb-keys.json
+new file mode 100644
+index 0000000000..c251682cd9
+--- /dev/null
++++ b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/50-ovmf-sb-keys.json
+@@ -0,0 +1,33 @@
++{
++    "interface-types": [
++        "uefi"
++    ],
++    "mapping": {
++        "device": "flash",
++        "mode": "split",
++        "executable": {
++            "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
++            "format": "raw"
++        },
++        "nvram-template": {
++            "filename": "/usr/share/OVMF/OVMF_VARS.secboot.fd",
++            "format": "raw"
++        }
++    },
++    "targets": [
++        {
++            "architecture": "x86_64",
++            "machines": [
++                "pc-q35-*"
++            ]
++        }
++    ],
++    "features": [
++        "acpi-s3",
++        "amd-sev",
++        "enrolled-keys",
++        "requires-smm",
++        "secure-boot",
++        "verbose-dynamic"
++    ]
++}
+diff --git a/tests/qemufirmwaredata/out/usr/share/qemu/firmware/61-ovmf.json b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/61-ovmf.json
+new file mode 100644
+index 0000000000..2a9aa23efb
+--- /dev/null
++++ b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/61-ovmf.json
+@@ -0,0 +1,31 @@
++{
++    "interface-types": [
++        "uefi"
++    ],
++    "mapping": {
++        "device": "flash",
++        "mode": "split",
++        "executable": {
++            "filename": "/usr/share/OVMF/OVMF_CODE.fd",
++            "format": "raw"
++        },
++        "nvram-template": {
++            "filename": "/usr/share/OVMF/OVMF_VARS.fd",
++            "format": "raw"
++        }
++    },
++    "targets": [
++        {
++            "architecture": "x86_64",
++            "machines": [
++                "pc-i440fx-*",
++                "pc-q35-*"
++            ]
++        }
++    ],
++    "features": [
++        "acpi-s3",
++        "amd-sev",
++        "verbose-dynamic"
++    ]
++}
+diff --git a/tests/qemufirmwaredata/out/usr/share/qemu/firmware/70-aavmf.json b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/70-aavmf.json
+new file mode 100644
+index 0000000000..9bd5ac2868
+--- /dev/null
++++ b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/70-aavmf.json
+@@ -0,0 +1,28 @@
++{
++    "interface-types": [
++        "uefi"
++    ],
++    "mapping": {
++        "device": "flash",
++        "mode": "split",
++        "executable": {
++            "filename": "/usr/share/AAVMF/AAVMF_CODE.fd",
++            "format": "raw"
++        },
++        "nvram-template": {
++            "filename": "/usr/share/AAVMF/AAVMF_VARS.fd",
++            "format": "raw"
++        }
++    },
++    "targets": [
++        {
++            "architecture": "aarch64",
++            "machines": [
++                "virt-*"
++            ]
++        }
++    ],
++    "features": [
++
++    ]
++}
+diff --git a/tests/qemufirmwaredata/usr/share/qemu/firmware/45-ovmf-sev-stateless.json b/tests/qemufirmwaredata/usr/share/qemu/firmware/45-ovmf-sev-stateless.json
+new file mode 100644
+index 0000000000..5a619f3ab0
+--- /dev/null
++++ b/tests/qemufirmwaredata/usr/share/qemu/firmware/45-ovmf-sev-stateless.json
+@@ -0,0 +1,31 @@
++{
++    "description": "OVMF for x86_64, with SEV, without SB, without SMM, with NO varstore",
++    "interface-types": [
++        "uefi"
++    ],
++    "mapping": {
++        "device": "flash",
++        "mode": "stateless",
++        "executable": {
++            "filename": "/usr/share/OVMF/OVMF.sev.fd",
++            "format": "raw"
++        }
++    },
++    "targets": [
++        {
++            "architecture": "x86_64",
++            "machines": [
++                "pc-q35-*"
++            ]
++        }
++    ],
++    "features": [
++        "acpi-s3",
++        "amd-sev",
++        "amd-sev-es",
++        "verbose-dynamic"
++    ],
++    "tags": [
++
++    ]
++}
+diff --git a/tests/qemufirmwaredata/usr/share/qemu/firmware/55-ovmf-sb-combined.json b/tests/qemufirmwaredata/usr/share/qemu/firmware/55-ovmf-sb-combined.json
+new file mode 100644
+index 0000000000..eb3332e4ab
+--- /dev/null
++++ b/tests/qemufirmwaredata/usr/share/qemu/firmware/55-ovmf-sb-combined.json
+@@ -0,0 +1,33 @@
++{
++    "description": "OVMF with SB+SMM, SB enabled, MS certs enrolled",
++    "interface-types": [
++        "uefi"
++    ],
++    "mapping": {
++        "device": "flash",
++	"mode": "combined",
++        "executable": {
++            "filename": "/usr/share/OVMF/OVMF.secboot.fd",
++            "format": "raw"
++        }
++    },
++    "targets": [
++        {
++            "architecture": "x86_64",
++            "machines": [
++                "pc-q35-*"
++            ]
++        }
++    ],
++    "features": [
++        "acpi-s3",
++        "amd-sev",
++        "enrolled-keys",
++        "requires-smm",
++        "secure-boot",
++        "verbose-dynamic"
++    ],
++    "tags": [
++
++    ]
++}
+diff --git a/tests/qemufirmwaredata/usr/share/qemu/firmware/60-ovmf-sb.json b/tests/qemufirmwaredata/usr/share/qemu/firmware/60-ovmf-sb.json
+index 5e8a94ae78..a5273a5e8b 100644
+--- a/tests/qemufirmwaredata/usr/share/qemu/firmware/60-ovmf-sb.json
++++ b/tests/qemufirmwaredata/usr/share/qemu/firmware/60-ovmf-sb.json
+@@ -5,6 +5,7 @@
+     ],
+     "mapping": {
+         "device": "flash",
++        "mode": "split",
+         "executable": {
+             "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
+             "format": "raw"
+diff --git a/tests/qemufirmwaretest.c b/tests/qemufirmwaretest.c
+index cad4b6d383..fc3416b2ae 100644
+--- a/tests/qemufirmwaretest.c
++++ b/tests/qemufirmwaretest.c
+@@ -17,22 +17,31 @@ static int
+ testParseFormatFW(const void *opaque)
+ {
+     const char *filename = opaque;
+-    g_autofree char *path = NULL;
++    g_autofree char *inpath = NULL;
++    g_autofree char *outpath = NULL;
+     g_autoptr(qemuFirmware) fw = NULL;
+-    g_autofree char *buf = NULL;
+     g_autoptr(virJSONValue) json = NULL;
+     g_autofree char *expected = NULL;
+     g_autofree char *actual = NULL;
++    g_autofree char *buf = NULL;
+ 
+-    path = g_strdup_printf("%s/qemufirmwaredata/%s", abs_srcdir, filename);
++    inpath = g_strdup_printf("%s/qemufirmwaredata/%s", abs_srcdir, filename);
++    outpath = g_strdup_printf("%s/qemufirmwaredata/out/%s", abs_srcdir, filename);
+ 
+-    if (!(fw = qemuFirmwareParse(path)))
++    if (!(fw = qemuFirmwareParse(inpath)))
+         return -1;
+ 
+-    if (virFileReadAll(path,
+-                       1024 * 1024, /* 1MiB */
+-                       &buf) < 0)
+-        return -1;
++    if (virFileExists(outpath)) {
++        if (virFileReadAll(outpath,
++                           1024 * 1024, /* 1MiB */
++                           &buf) < 0)
++            return -1;
++    } else {
++        if (virFileReadAll(inpath,
++                           1024 * 1024, /* 1MiB */
++                           &buf) < 0)
++            return -1;
++    }
+ 
+     if (!(json = virJSONValueFromString(buf)))
+         return -1;
+@@ -60,7 +69,9 @@ testFWPrecedence(const void *opaque G_GNUC_UNUSED)
+     const char *expected[] = {
+         PREFIX "/share/qemu/firmware/40-bios.json",
+         SYSCONFDIR "/qemu/firmware/40-ovmf-sb-keys.json",
++        PREFIX "/share/qemu/firmware/45-ovmf-sev-stateless.json",
+         PREFIX "/share/qemu/firmware/50-ovmf-sb-keys.json",
++        PREFIX "/share/qemu/firmware/55-ovmf-sb-combined.json",
+         PREFIX "/share/qemu/firmware/61-ovmf.json",
+         PREFIX "/share/qemu/firmware/70-aavmf.json",
+         NULL
+@@ -218,7 +229,9 @@ mymain(void)
+     } while (0)
+ 
+     DO_PARSE_TEST("usr/share/qemu/firmware/40-bios.json");
++    DO_PARSE_TEST("usr/share/qemu/firmware/45-ovmf-sev-stateless.json");
+     DO_PARSE_TEST("usr/share/qemu/firmware/50-ovmf-sb-keys.json");
++    DO_PARSE_TEST("usr/share/qemu/firmware/55-ovmf-sb-combined.json");
+     DO_PARSE_TEST("usr/share/qemu/firmware/60-ovmf-sb.json");
+     DO_PARSE_TEST("usr/share/qemu/firmware/61-ovmf.json");
+     DO_PARSE_TEST("usr/share/qemu/firmware/70-aavmf.json");
+@@ -250,6 +263,8 @@ mymain(void)
+     DO_SUPPORTED_TEST("pc-q35-3.1", VIR_ARCH_X86_64, true,
+                       "/usr/share/seabios/bios-256k.bin:NULL:"
+                       "/usr/share/OVMF/OVMF_CODE.secboot.fd:/usr/share/OVMF/OVMF_VARS.secboot.fd:"
++                      "/usr/share/OVMF/OVMF.sev.fd:NULL:"
++                      "/usr/share/OVMF/OVMF.secboot.fd:NULL:"
+                       "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd",
+                       VIR_DOMAIN_OS_DEF_FIRMWARE_BIOS,
+                       VIR_DOMAIN_OS_DEF_FIRMWARE_EFI);
+-- 
+2.35.1
+
diff --git a/SOURCES/libvirt-qemu-support-multiqueue-for-vdpa-net-device.patch b/SOURCES/libvirt-qemu-support-multiqueue-for-vdpa-net-device.patch
new file mode 100644
index 0000000..83d9be3
--- /dev/null
+++ b/SOURCES/libvirt-qemu-support-multiqueue-for-vdpa-net-device.patch
@@ -0,0 +1,186 @@
+From 563e17f59f088d4ba76e7a95ea8958792ae165e2 Mon Sep 17 00:00:00 2001
+Message-Id: <563e17f59f088d4ba76e7a95ea8958792ae165e2@dist-git>
+From: Jonathon Jongsma <jjongsma@redhat.com>
+Date: Tue, 1 Mar 2022 16:55:21 -0600
+Subject: [PATCH] qemu: support multiqueue for vdpa net device
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2024406
+
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
+
+(cherry picked from commit a5e659f071ae5f5fc9aadb46ad7c31736425f8cf)
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+---
+ src/qemu/qemu_domain.c                        |  3 +-
+ .../net-vdpa-multiqueue.x86_64-latest.args    | 36 +++++++++++++++++++
+ .../qemuxml2argvdata/net-vdpa-multiqueue.xml  | 30 ++++++++++++++++
+ tests/qemuxml2argvtest.c                      |  1 +
+ .../net-vdpa-multiqueue.xml                   | 36 +++++++++++++++++++
+ tests/qemuxml2xmltest.c                       |  1 +
+ 6 files changed, 106 insertions(+), 1 deletion(-)
+ create mode 100644 tests/qemuxml2argvdata/net-vdpa-multiqueue.x86_64-latest.args
+ create mode 100644 tests/qemuxml2argvdata/net-vdpa-multiqueue.xml
+ create mode 100644 tests/qemuxml2xmloutdata/net-vdpa-multiqueue.xml
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index a8401bac30..68052769af 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -4511,7 +4511,8 @@ qemuDomainValidateActualNetDef(const virDomainNetDef *net,
+               actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+               actualType == VIR_DOMAIN_NET_TYPE_DIRECT ||
+               actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
+-              actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)) {
++              actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER ||
++              actualType == VIR_DOMAIN_NET_TYPE_VDPA)) {
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("interface %s - multiqueue is not supported for network interfaces of type %s"),
+                            macstr, virDomainNetTypeToString(actualType));
+diff --git a/tests/qemuxml2argvdata/net-vdpa-multiqueue.x86_64-latest.args b/tests/qemuxml2argvdata/net-vdpa-multiqueue.x86_64-latest.args
+new file mode 100644
+index 0000000000..61ba85a847
+--- /dev/null
++++ b/tests/qemuxml2argvdata/net-vdpa-multiqueue.x86_64-latest.args
+@@ -0,0 +1,36 @@
++LC_ALL=C \
++PATH=/bin \
++HOME=/tmp/lib/domain--1-QEMUGuest1 \
++USER=test \
++LOGNAME=test \
++XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
++XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
++XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
++/usr/bin/qemu-system-x86_64 \
++-name guest=QEMUGuest1,debug-threads=on \
++-S \
++-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \
++-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram \
++-accel tcg \
++-cpu qemu64 \
++-m 214 \
++-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
++-overcommit mem-lock=off \
++-smp 1,sockets=1,cores=1,threads=1 \
++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
++-display none \
++-no-user-config \
++-nodefaults \
++-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
++-mon chardev=charmonitor,id=monitor,mode=control \
++-rtc base=utc \
++-no-shutdown \
++-no-acpi \
++-boot strict=on \
++-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
++-add-fd set=0,fd=1732,opaque=/dev/vhost-vdpa-0 \
++-netdev vhost-vdpa,vhostdev=/dev/fdset/0,id=hostnet0 \
++-device virtio-net-pci,mq=on,vectors=6,netdev=hostnet0,id=net0,mac=52:54:00:95:db:c0,bus=pci.0,addr=0x2 \
++-audiodev '{"id":"audio1","driver":"none"}' \
++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
++-msg timestamp=on
+diff --git a/tests/qemuxml2argvdata/net-vdpa-multiqueue.xml b/tests/qemuxml2argvdata/net-vdpa-multiqueue.xml
+new file mode 100644
+index 0000000000..6e369c1916
+--- /dev/null
++++ b/tests/qemuxml2argvdata/net-vdpa-multiqueue.xml
+@@ -0,0 +1,30 @@
++<domain type='qemu'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219136</memory>
++  <currentMemory unit='KiB'>219136</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-x86_64</emulator>
++    <controller type='usb' index='0'/>
++    <controller type='ide' index='0'/>
++    <controller type='pci' index='0' model='pci-root'/>
++    <interface type='vdpa'>
++      <mac address='52:54:00:95:db:c0'/>
++      <source dev='/dev/vhost-vdpa-0'/>
++      <model type='virtio'/>
++      <driver queues='2'/>
++    </interface>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='none'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index cc67d806e4..1abb5d0124 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -1652,6 +1652,7 @@ mymain(void)
+     DO_TEST_FAILURE("net-hostdev-fail",
+                     QEMU_CAPS_DEVICE_VFIO_PCI);
+     DO_TEST_CAPS_LATEST("net-vdpa");
++    DO_TEST_CAPS_LATEST("net-vdpa-multiqueue");
+ 
+     DO_TEST("hostdev-pci-multifunction",
+             QEMU_CAPS_KVM,
+diff --git a/tests/qemuxml2xmloutdata/net-vdpa-multiqueue.xml b/tests/qemuxml2xmloutdata/net-vdpa-multiqueue.xml
+new file mode 100644
+index 0000000000..0876d5df62
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/net-vdpa-multiqueue.xml
+@@ -0,0 +1,36 @@
++<domain type='qemu'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219136</memory>
++  <currentMemory unit='KiB'>219136</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-x86_64</emulator>
++    <controller type='usb' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='ide' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'/>
++    <interface type='vdpa'>
++      <mac address='52:54:00:95:db:c0'/>
++      <source dev='/dev/vhost-vdpa-0'/>
++      <model type='virtio'/>
++      <driver queues='2'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
++    </interface>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <audio id='1' type='none'/>
++    <memballoon model='none'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index fb438269b9..772586cf19 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -461,6 +461,7 @@ mymain(void)
+     DO_TEST_NOCAPS("net-coalesce");
+     DO_TEST_NOCAPS("net-many-models");
+     DO_TEST("net-vdpa", QEMU_CAPS_NETDEV_VHOST_VDPA);
++    DO_TEST("net-vdpa-multiqueue", QEMU_CAPS_NETDEV_VHOST_VDPA);
+ 
+     DO_TEST_NOCAPS("serial-tcp-tlsx509-chardev");
+     DO_TEST_NOCAPS("serial-tcp-tlsx509-chardev-notls");
+-- 
+2.35.1
+
diff --git a/SOURCES/libvirt-util-Fix-machined-servicename.patch b/SOURCES/libvirt-util-Fix-machined-servicename.patch
new file mode 100644
index 0000000..bdab8fb
--- /dev/null
+++ b/SOURCES/libvirt-util-Fix-machined-servicename.patch
@@ -0,0 +1,71 @@
+From f38b129e38b73cb20a2d858de7b593d09380e548 Mon Sep 17 00:00:00 2001
+Message-Id: <f38b129e38b73cb20a2d858de7b593d09380e548@dist-git>
+From: Martin Kletzander <mkletzan@redhat.com>
+Date: Wed, 23 Feb 2022 10:45:28 +0100
+Subject: [PATCH] util: Fix machined servicename
+
+Commit 4e42686adef8 wrongly assumed how g_variant_new_parsed() works and broke
+starting of domains on systems with systemd (machined).
+
+Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit a64e666a112d4d6299d1b73704d176283bc42b19)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1868537
+
+Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
+---
+ src/util/virsystemd.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
+index f156c2f39a..a8af80c495 100644
+--- a/src/util/virsystemd.c
++++ b/src/util/virsystemd.c
+@@ -360,6 +360,7 @@ int virSystemdCreateMachine(const char *name,
+     g_autofree char *creatorname = NULL;
+     g_autofree char *slicename = NULL;
+     g_autofree char *scopename = NULL;
++    g_autofree char *servicename = NULL;
+     static int hasCreateWithNetwork = 1;
+ 
+     if ((rc = virSystemdHasMachined()) < 0)
+@@ -369,6 +370,7 @@ int virSystemdCreateMachine(const char *name,
+         return -1;
+ 
+     creatorname = g_strdup_printf("libvirt-%s", drivername);
++    servicename = g_strdup_printf("virt%sd.service", drivername);
+ 
+     if (partition) {
+         if (!(slicename = virSystemdMakeSliceName(partition)))
+@@ -440,11 +442,10 @@ int virSystemdCreateMachine(const char *name,
+         gnicindexes = g_variant_new_fixed_array(G_VARIANT_TYPE("i"),
+                                                 nicindexes, nnicindexes, sizeof(int));
+         gprops = g_variant_new_parsed("[('Slice', <%s>),"
+-                                      " ('After', <['libvirtd.service']>),"
+-                                      " ('After', <['virt%sd.service']>),"
++                                      " ('After', <['libvirtd.service', %s]>),"
+                                       " ('Before', <['virt-guest-shutdown.target']>)]",
+                                       slicename,
+-                                      drivername);
++                                      servicename);
+         message = g_variant_new("(s@ayssus@ai@a(sv))",
+                                 name,
+                                 guuid,
+@@ -490,11 +491,10 @@ int virSystemdCreateMachine(const char *name,
+         guuid = g_variant_new_fixed_array(G_VARIANT_TYPE("y"),
+                                           uuid, 16, sizeof(unsigned char));
+         gprops = g_variant_new_parsed("[('Slice', <%s>),"
+-                                      " ('After', <['libvirtd.service']>),"
+-                                      " ('After', <['virt%sd.service']>),"
++                                      " ('After', <['libvirtd.service', %s]>),"
+                                       " ('Before', <['virt-guest-shutdown.target']>)]",
+                                       slicename,
+-                                      drivername);
++                                      servicename);
+         message = g_variant_new("(s@ayssus@a(sv))",
+                                 name,
+                                 guuid,
+-- 
+2.35.1
+
diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec
index e75e261..3650782 100644
--- a/SPECS/libvirt.spec
+++ b/SPECS/libvirt.spec
@@ -228,7 +228,7 @@
 Summary: Library providing a simple virtualization API
 Name: libvirt
 Version: 8.0.0
-Release: 4%{?dist}%{?extra_release}
+Release: 7%{?dist}%{?extra_release}
 License: LGPLv2+
 URL: https://libvirt.org/
 
@@ -247,6 +247,12 @@ Patch6: libvirt-Revert-report-error-when-virProcessGetStatInfo-is-unable-to-pars
 Patch7: libvirt-qemuDomainSetupDisk-Initialize-targetPaths.patch
 Patch8: libvirt-qemu_command-Generate-memory-only-after-controllers.patch
 Patch9: libvirt-qemu-Validate-domain-definition-even-on-migration.patch
+Patch10: libvirt-Make-systemd-unit-ordering-more-robust.patch
+Patch11: libvirt-util-Fix-machined-servicename.patch
+Patch12: libvirt-qemu-support-firmware-descriptor-flash-mode-for-optional-NVRAM.patch
+Patch13: libvirt-nwfilter-hold-filter-update-lock-when-creating-deleting-bindings.patch
+Patch14: libvirt-qemu-lxc-remove-use-to-nwfilter-update-lock.patch
+Patch15: libvirt-qemu-support-multiqueue-for-vdpa-net-device.patch
 
 Requires: libvirt-daemon = %{version}-%{release}
 Requires: libvirt-daemon-config-network = %{version}-%{release}
@@ -2138,6 +2144,18 @@ exit 0
 
 
 %changelog
+* Fri Mar 18 2022 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-7
+- nwfilter: hold filter update lock when creating/deleting bindings (rhbz#2044379)
+- qemu,lxc: remove use to nwfilter update lock (rhbz#2044379)
+- qemu: support multiqueue for vdpa net device (rhbz#2024406)
+
+* Thu Mar  3 2022 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-6
+- qemu: support firmware descriptor flash 'mode' for optional NVRAM (rhbz#2057769)
+
+* Thu Feb 24 2022 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-5
+- Make systemd unit ordering more robust (rhbz#1868537)
+- util: Fix machined servicename (rhbz#1868537)
+
 * Thu Feb 10 2022 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-4
 - qemu_command: Generate memory only after controllers (rhbz#2047271)
 - qemu: Validate domain definition even on migration (rhbz#2048435)