From 8d2da0bba74e96737435f524dd5750902ca774e1 Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Fri, 6 Mar 2026 17:41:54 +0100 Subject: [PATCH] libvirt-11.10.0-11.el10 - qemu_firmware: Drop support for kernel descriptors (RHEL-82645) - qemu_firmware: Drop 'nvram' local variable (RHEL-82645) - qemu_firmware: Move format=raw compat exception (RHEL-82645) - qemu_firmware: Move copying of nvram.format to loader.format (RHEL-82645) - tests: Add firmware-manual-efi-rw-nvram (RHEL-82645) - domain_validate: Reject NVRAM with read/write firmware (RHEL-82645) - tests: Add firmware-auto-bios-rw (RHEL-82645) - tests: Add firmware-manual-bios-rw (RHEL-82645) - domain_validate: Reject read/write ROMs (RHEL-82645) - tests: Add firmware-auto-efi-format-loader-qcow2-rom (RHEL-82645) - domain_validate: Reject ROMs with format other than raw (RHEL-82645) - qemu_firmware: Ignore stateless/combined when NVRAM is configured (RHEL-82645) - qemu_firmware: Drop fallback for absent nvramTemplateFormat (RHEL-82645) - schemas: Allow templateFormat without template path (RHEL-82645) - tests: Add firmware-manual-efi-nvram-template-nonstandard-format (RHEL-82645) - tests: Add firmware-manual-efi-nvram-template-nonstandard-legacy-paths (RHEL-82645) - tests: Add firmware-auto-efi-format-nvram-raw (RHEL-82645) - tests: Add firmware-auto-efi-format-nvram-raw-loader-path (RHEL-82645) - tests: Add firmware-auto-efi-format-nvram-raw-nvramtemplate-path (RHEL-82645) - tests: Add firmware-auto-efi-format-nvramtemplate-qcow2 (RHEL-82645) - tests: Add firmware-auto-efi-format-mismatch-nvramtemplate (RHEL-82645) - qemu_firmware: Introduce qemuFirmwareFillDomainCustom() (RHEL-82645) - qemu_firmware: Set templateFormat for custom paths (RHEL-82645) - qemu_firmware: Simplify handling of legacy paths (RHEL-82645) - qemu_firmware: Refactor setting NVRAM format (RHEL-82645) - qemu_firmware: Prefer template format to loader format (RHEL-82645) - qemu_firmware: Retain user-specified NVRAM format (RHEL-82645) - qemu_firmware: Take templateFormat into account when matching (RHEL-82645) - qemu_firmware: Take NVRAM format into account when matching (RHEL-82645) - qemu_firmware: Remove NVRAM to loader format copy hack (RHEL-82645) - tests: Add firmware-manual-efi-sev-snp (RHEL-82645) - tests: Add firmware-manual-efi-tdx (RHEL-82645) - qemu_firmware: ROM firmware is always in raw format (RHEL-82645) - qemu_firmware: Don't skip autoselection for ROM (RHEL-82645) - qemu_firmware: Allow matching both UEFI and BIOS for ROM loader (RHEL-82645) - schema: Add firmwareFeatures element for domaincaps (RHEL-82645) - conf: Add firmwareFeatures element for domaincaps (RHEL-82645) - qemu: Fill in firmwareFeature element for domaincaps (RHEL-82645) - docs: Document firmwareFeature element for domaincaps (RHEL-82645) - docs: Rename "BIOS bootloader" section to "guest firmware" (RHEL-82645) - docs: Improvement related to firmware selection (RHEL-82645) - qemu_firmware: Only set format for custom loader if path is present (RHEL-82645) - conf: Move type=rom default for loader to drivers (RHEL-82645) - tests: Rename custom JSON firmware descriptors (RHEL-82645) - schema: Introduce osnvram define (RHEL-82645) - conf: Parse and format varstore element (RHEL-82645) - conf: Update validation to consider varstore element (RHEL-82645) - qemu_capabilities: Introduce QEMU_CAPS_DEVICE_UEFI_VARS (RHEL-82645) - qemu: Validate presence of uefi-vars device (RHEL-82645) - tests: Add firmware-manual-efi-varstore-q35 (RHEL-82645) - tests: Add firmware-manual-efi-varstore-aarch64 (RHEL-82645) - tests: Add firmware-auto-efi-varstore-q35 (RHEL-82645) - tests: Add firmware-auto-efi-varstore-aarch64 (RHEL-82645) - tests: Add firmware-auto-efi-enrolled-keys-aarch64 (RHEL-82645) - qemu_firmware: Parse host-uefi-vars firmware feature (RHEL-82645) - qemu_firmware: Split sanity check (RHEL-82645) - qemu_firmware: Consider host-uefi-vars feature in sanity check (RHEL-82645) - qemu_firmware: Support extended syntax for ROM firmware descriptors (RHEL-82645) - qemu_firmware: Report NVRAM template path for ROMs (RHEL-82645) - conf: Include varstore element in domcaps (RHEL-82645) - qemu: Fill in varstore element in domcaps (RHEL-82645) - qemu_firmware: Use of NVRAM implies stateful firmware (RHEL-82645) - qemu_firmware: Allow matching stateful ROMs (RHEL-82645) - qemu_firmware: Fill in varstore information (RHEL-82645) - qemu: Introduce varstoreDir (RHEL-82645) - qemu_firmware: Generate varstore path when necessary (RHEL-82645) - qemu: Introduce qemuPrepareNVRAMFileCommon() (RHEL-82645) - qemu: Create and delete varstore file (RHEL-82645) - security: Mark ROMs as read only when using AppArmor (RHEL-82645) - security: Handle varstore file (RHEL-82645) - tests: Add firmware descriptors for uefi-vars builds (RHEL-82645) - qemu_command: Use uefi-vars device where appropriate (RHEL-82645) - include: Mention varstore where applicable (RHEL-82645) - virsh: Update for varstore handling (RHEL-82645) - domain_conf: initialize network hostdev private data (RHEL-151916) - qemu_hotplug: enter monitor in order to rollback passed FD (RHEL-151916) Resolves: RHEL-151916, RHEL-82645 --- ...mwareFeatures-element-for-domaincaps.patch | 85 + ...-Include-varstore-element-in-domcaps.patch | 140 ++ ...pe-rom-default-for-loader-to-drivers.patch | 104 + ...nf-Parse-and-format-varstore-element.patch | 385 ++++ ...idation-to-consider-varstore-element.patch | 378 ++++ ...rmwareFeature-element-for-domaincaps.patch | 88 + ...vement-related-to-firmware-selection.patch | 109 ++ ...bootloader-section-to-guest-firmware.patch | 159 ++ ...tialize-network-hostdev-private-data.patch | 94 + ...eject-NVRAM-with-read-write-firmware.patch | 165 ++ ...ject-ROMs-with-format-other-than-raw.patch | 157 ++ ...main_validate-Reject-read-write-ROMs.patch | 140 ++ ...de-Mention-varstore-where-applicable.patch | 69 + ...qemu-Create-and-delete-varstore-file.patch | 118 ++ ...rmwareFeature-element-for-domaincaps.patch | 1675 +++++++++++++++++ ...-Fill-in-varstore-element-in-domcaps.patch | 1232 ++++++++++++ ...Introduce-qemuPrepareNVRAMFileCommon.patch | 123 ++ libvirt-qemu-Introduce-varstoreDir.patch | 135 ++ ...alidate-presence-of-uefi-vars-device.patch | 65 + ...Introduce-QEMU_CAPS_DEVICE_UEFI_VARS.patch | 172 ++ ...e-uefi-vars-device-where-appropriate.patch | 154 ++ ...ng-both-UEFI-and-BIOS-for-ROM-loader.patch | 131 ++ ...irmware-Allow-matching-stateful-ROMs.patch | 259 +++ ...st-uefi-vars-feature-in-sanity-check.patch | 83 + ...are-Don-t-skip-autoselection-for-ROM.patch | 64 + ...lback-for-absent-nvramTemplateFormat.patch | 44 + ...u_firmware-Drop-nvram-local-variable.patch | 58 + ...-Drop-support-for-kernel-descriptors.patch | 232 +++ ...irmware-Fill-in-varstore-information.patch | 61 + ...enerate-varstore-path-when-necessary.patch | 86 + ...ss-combined-when-NVRAM-is-configured.patch | 72 + ...troduce-qemuFirmwareFillDomainCustom.patch | 80 + ...ing-of-nvram.format-to-loader.format.patch | 90 + ...are-Move-format-raw-compat-exception.patch | 86 + ...for-custom-loader-if-path-is-present.patch | 45 + ...arse-host-uefi-vars-firmware-feature.patch | 80 + ...fer-template-format-to-loader-format.patch | 39 + ...ROM-firmware-is-always-in-raw-format.patch | 33 + ...rmware-Refactor-setting-NVRAM-format.patch | 53 + ...ove-NVRAM-to-loader-format-copy-hack.patch | 331 ++++ ...-Report-NVRAM-template-path-for-ROMs.patch | 49 + ...e-Retain-user-specified-NVRAM-format.patch | 108 ++ ...-Set-templateFormat-for-custom-paths.patch | 65 + ...re-Simplify-handling-of-legacy-paths.patch | 132 ++ ...irt-qemu_firmware-Split-sanity-check.patch | 66 + ...-syntax-for-ROM-firmware-descriptors.patch | 99 + ...AM-format-into-account-when-matching.patch | 66 + ...ateFormat-into-account-when-matching.patch | 231 +++ ...e-of-NVRAM-implies-stateful-firmware.patch | 54 + ...nitor-in-order-to-rollback-passed-FD.patch | 46 + ...mwareFeatures-element-for-domaincaps.patch | 49 + libvirt-schema-Introduce-osnvram-define.patch | 100 + ...templateFormat-without-template-path.patch | 44 + libvirt-security-Handle-varstore-file.patch | 221 +++ ...OMs-as-read-only-when-using-AppArmor.patch | 47 + libvirt-tests-Add-firmware-auto-bios-rw.patch | 115 ++ ...mware-auto-efi-enrolled-keys-aarch64.patch | 181 ++ ...are-auto-efi-format-loader-qcow2-rom.patch | 154 ++ ...to-efi-format-mismatch-nvramtemplate.patch | 165 ++ ...uto-efi-format-nvram-raw-loader-path.patch | 124 ++ ...-format-nvram-raw-nvramtemplate-path.patch | 120 ++ ...d-firmware-auto-efi-format-nvram-raw.patch | 251 +++ ...-auto-efi-format-nvramtemplate-qcow2.patch | 161 ++ ...d-firmware-auto-efi-varstore-aarch64.patch | 84 + ...s-Add-firmware-auto-efi-varstore-q35.patch | 84 + ...are-descriptors-for-uefi-vars-builds.patch | 815 ++++++++ ...rt-tests-Add-firmware-manual-bios-rw.patch | 138 ++ ...fi-nvram-template-nonstandard-format.patch | 152 ++ ...am-template-nonstandard-legacy-paths.patch | 155 ++ ...sts-Add-firmware-manual-efi-rw-nvram.patch | 160 ++ ...ests-Add-firmware-manual-efi-sev-snp.patch | 162 ++ ...rt-tests-Add-firmware-manual-efi-tdx.patch | 164 ++ ...firmware-manual-efi-varstore-aarch64.patch | 89 + ...Add-firmware-manual-efi-varstore-q35.patch | 168 ++ ...ame-custom-JSON-firmware-descriptors.patch | 151 ++ ...t-virsh-Update-for-varstore-handling.patch | 150 ++ libvirt.spec | 157 +- 77 files changed, 12950 insertions(+), 1 deletion(-) create mode 100644 libvirt-conf-Add-firmwareFeatures-element-for-domaincaps.patch create mode 100644 libvirt-conf-Include-varstore-element-in-domcaps.patch create mode 100644 libvirt-conf-Move-type-rom-default-for-loader-to-drivers.patch create mode 100644 libvirt-conf-Parse-and-format-varstore-element.patch create mode 100644 libvirt-conf-Update-validation-to-consider-varstore-element.patch create mode 100644 libvirt-docs-Document-firmwareFeature-element-for-domaincaps.patch create mode 100644 libvirt-docs-Improvement-related-to-firmware-selection.patch create mode 100644 libvirt-docs-Rename-BIOS-bootloader-section-to-guest-firmware.patch create mode 100644 libvirt-domain_conf-initialize-network-hostdev-private-data.patch create mode 100644 libvirt-domain_validate-Reject-NVRAM-with-read-write-firmware.patch create mode 100644 libvirt-domain_validate-Reject-ROMs-with-format-other-than-raw.patch create mode 100644 libvirt-domain_validate-Reject-read-write-ROMs.patch create mode 100644 libvirt-include-Mention-varstore-where-applicable.patch create mode 100644 libvirt-qemu-Create-and-delete-varstore-file.patch create mode 100644 libvirt-qemu-Fill-in-firmwareFeature-element-for-domaincaps.patch create mode 100644 libvirt-qemu-Fill-in-varstore-element-in-domcaps.patch create mode 100644 libvirt-qemu-Introduce-qemuPrepareNVRAMFileCommon.patch create mode 100644 libvirt-qemu-Introduce-varstoreDir.patch create mode 100644 libvirt-qemu-Validate-presence-of-uefi-vars-device.patch create mode 100644 libvirt-qemu_capabilities-Introduce-QEMU_CAPS_DEVICE_UEFI_VARS.patch create mode 100644 libvirt-qemu_command-Use-uefi-vars-device-where-appropriate.patch create mode 100644 libvirt-qemu_firmware-Allow-matching-both-UEFI-and-BIOS-for-ROM-loader.patch create mode 100644 libvirt-qemu_firmware-Allow-matching-stateful-ROMs.patch create mode 100644 libvirt-qemu_firmware-Consider-host-uefi-vars-feature-in-sanity-check.patch create mode 100644 libvirt-qemu_firmware-Don-t-skip-autoselection-for-ROM.patch create mode 100644 libvirt-qemu_firmware-Drop-fallback-for-absent-nvramTemplateFormat.patch create mode 100644 libvirt-qemu_firmware-Drop-nvram-local-variable.patch create mode 100644 libvirt-qemu_firmware-Drop-support-for-kernel-descriptors.patch create mode 100644 libvirt-qemu_firmware-Fill-in-varstore-information.patch create mode 100644 libvirt-qemu_firmware-Generate-varstore-path-when-necessary.patch create mode 100644 libvirt-qemu_firmware-Ignore-stateless-combined-when-NVRAM-is-configured.patch create mode 100644 libvirt-qemu_firmware-Introduce-qemuFirmwareFillDomainCustom.patch create mode 100644 libvirt-qemu_firmware-Move-copying-of-nvram.format-to-loader.format.patch create mode 100644 libvirt-qemu_firmware-Move-format-raw-compat-exception.patch create mode 100644 libvirt-qemu_firmware-Only-set-format-for-custom-loader-if-path-is-present.patch create mode 100644 libvirt-qemu_firmware-Parse-host-uefi-vars-firmware-feature.patch create mode 100644 libvirt-qemu_firmware-Prefer-template-format-to-loader-format.patch create mode 100644 libvirt-qemu_firmware-ROM-firmware-is-always-in-raw-format.patch create mode 100644 libvirt-qemu_firmware-Refactor-setting-NVRAM-format.patch create mode 100644 libvirt-qemu_firmware-Remove-NVRAM-to-loader-format-copy-hack.patch create mode 100644 libvirt-qemu_firmware-Report-NVRAM-template-path-for-ROMs.patch create mode 100644 libvirt-qemu_firmware-Retain-user-specified-NVRAM-format.patch create mode 100644 libvirt-qemu_firmware-Set-templateFormat-for-custom-paths.patch create mode 100644 libvirt-qemu_firmware-Simplify-handling-of-legacy-paths.patch create mode 100644 libvirt-qemu_firmware-Split-sanity-check.patch create mode 100644 libvirt-qemu_firmware-Support-extended-syntax-for-ROM-firmware-descriptors.patch create mode 100644 libvirt-qemu_firmware-Take-NVRAM-format-into-account-when-matching.patch create mode 100644 libvirt-qemu_firmware-Take-templateFormat-into-account-when-matching.patch create mode 100644 libvirt-qemu_firmware-Use-of-NVRAM-implies-stateful-firmware.patch create mode 100644 libvirt-qemu_hotplug-enter-monitor-in-order-to-rollback-passed-FD.patch create mode 100644 libvirt-schema-Add-firmwareFeatures-element-for-domaincaps.patch create mode 100644 libvirt-schema-Introduce-osnvram-define.patch create mode 100644 libvirt-schemas-Allow-templateFormat-without-template-path.patch create mode 100644 libvirt-security-Handle-varstore-file.patch create mode 100644 libvirt-security-Mark-ROMs-as-read-only-when-using-AppArmor.patch create mode 100644 libvirt-tests-Add-firmware-auto-bios-rw.patch create mode 100644 libvirt-tests-Add-firmware-auto-efi-enrolled-keys-aarch64.patch create mode 100644 libvirt-tests-Add-firmware-auto-efi-format-loader-qcow2-rom.patch create mode 100644 libvirt-tests-Add-firmware-auto-efi-format-mismatch-nvramtemplate.patch create mode 100644 libvirt-tests-Add-firmware-auto-efi-format-nvram-raw-loader-path.patch create mode 100644 libvirt-tests-Add-firmware-auto-efi-format-nvram-raw-nvramtemplate-path.patch create mode 100644 libvirt-tests-Add-firmware-auto-efi-format-nvram-raw.patch create mode 100644 libvirt-tests-Add-firmware-auto-efi-format-nvramtemplate-qcow2.patch create mode 100644 libvirt-tests-Add-firmware-auto-efi-varstore-aarch64.patch create mode 100644 libvirt-tests-Add-firmware-auto-efi-varstore-q35.patch create mode 100644 libvirt-tests-Add-firmware-descriptors-for-uefi-vars-builds.patch create mode 100644 libvirt-tests-Add-firmware-manual-bios-rw.patch create mode 100644 libvirt-tests-Add-firmware-manual-efi-nvram-template-nonstandard-format.patch create mode 100644 libvirt-tests-Add-firmware-manual-efi-nvram-template-nonstandard-legacy-paths.patch create mode 100644 libvirt-tests-Add-firmware-manual-efi-rw-nvram.patch create mode 100644 libvirt-tests-Add-firmware-manual-efi-sev-snp.patch create mode 100644 libvirt-tests-Add-firmware-manual-efi-tdx.patch create mode 100644 libvirt-tests-Add-firmware-manual-efi-varstore-aarch64.patch create mode 100644 libvirt-tests-Add-firmware-manual-efi-varstore-q35.patch create mode 100644 libvirt-tests-Rename-custom-JSON-firmware-descriptors.patch create mode 100644 libvirt-virsh-Update-for-varstore-handling.patch diff --git a/libvirt-conf-Add-firmwareFeatures-element-for-domaincaps.patch b/libvirt-conf-Add-firmwareFeatures-element-for-domaincaps.patch new file mode 100644 index 0000000..8896e29 --- /dev/null +++ b/libvirt-conf-Add-firmwareFeatures-element-for-domaincaps.patch @@ -0,0 +1,85 @@ +From 271cfe0d7954d5398af307b24fc5b601977975b8 Mon Sep 17 00:00:00 2001 +Message-ID: <271cfe0d7954d5398af307b24fc5b601977975b8.1772815313.git.jdenemar@redhat.com> +From: Andrea Bolognani +Date: Mon, 9 Feb 2026 21:28:50 +0100 +Subject: [PATCH] conf: Add firmwareFeatures element for domaincaps + +Signed-off-by: Andrea Bolognani +Reviewed-by: Michal Privoznik +(cherry picked from commit 928bdc3e67b29ff2314ff538905703e299b1e47e) + +https://issues.redhat.com/browse/RHEL-82645 + +Signed-off-by: Andrea Bolognani +--- + src/conf/domain_capabilities.c | 15 +++++++++++++++ + src/conf/domain_capabilities.h | 8 ++++++++ + 2 files changed, 23 insertions(+) + +diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c +index 49179b97ab..9b3577cd08 100644 +--- a/src/conf/domain_capabilities.c ++++ b/src/conf/domain_capabilities.c +@@ -422,6 +422,19 @@ virDomainCapsFeatureFormatSimple(virBuffer *buf, + } + + ++static void ++virDomainCapsFirmwareFeaturesFormat(virBuffer *buf, ++ const virDomainCapsFirmwareFeatures *firmwareFeatures) ++{ ++ FORMAT_PROLOGUE(firmwareFeatures); ++ ++ ENUM_PROCESS(firmwareFeatures, secureBoot, virTristateBoolTypeToString); ++ ENUM_PROCESS(firmwareFeatures, enrolledKeys, virTristateBoolTypeToString); ++ ++ FORMAT_EPILOGUE(firmwareFeatures); ++} ++ ++ + static void + virDomainCapsLoaderFormat(virBuffer *buf, + const virDomainCapsLoader *loader) +@@ -440,12 +453,14 @@ static void + virDomainCapsOSFormat(virBuffer *buf, + const virDomainCapsOS *os) + { ++ const virDomainCapsFirmwareFeatures *firmwareFeatures = &os->firmwareFeatures; + const virDomainCapsLoader *loader = &os->loader; + + FORMAT_PROLOGUE(os); + + ENUM_PROCESS(os, firmware, virDomainOsDefFirmwareTypeToString); + ++ virDomainCapsFirmwareFeaturesFormat(&childBuf, firmwareFeatures); + virDomainCapsLoaderFormat(&childBuf, loader); + + FORMAT_EPILOGUE(os); +diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h +index b10370db8f..a68fafe235 100644 +--- a/src/conf/domain_capabilities.h ++++ b/src/conf/domain_capabilities.h +@@ -43,6 +43,13 @@ struct _virDomainCapsStringValues { + size_t nvalues; /* number of strings */ + }; + ++typedef struct _virDomainCapsFirmwareFeatures virDomainCapsFirmwareFeatures; ++struct _virDomainCapsFirmwareFeatures { ++ virTristateBool supported; ++ virDomainCapsEnum secureBoot; ++ virDomainCapsEnum enrolledKeys; ++}; ++ + STATIC_ASSERT_ENUM(VIR_DOMAIN_LOADER_TYPE_LAST); + STATIC_ASSERT_ENUM(VIR_TRISTATE_BOOL_LAST); + typedef struct _virDomainCapsLoader virDomainCapsLoader; +@@ -59,6 +66,7 @@ typedef struct _virDomainCapsOS virDomainCapsOS; + struct _virDomainCapsOS { + virTristateBool supported; + virDomainCapsEnum firmware; /* Info about virDomainOsDefFirmware */ ++ virDomainCapsFirmwareFeatures firmwareFeatures; + virDomainCapsLoader loader; /* Info about virDomainLoaderDef */ + }; + +-- +2.53.0 diff --git a/libvirt-conf-Include-varstore-element-in-domcaps.patch b/libvirt-conf-Include-varstore-element-in-domcaps.patch new file mode 100644 index 0000000..f254bed --- /dev/null +++ b/libvirt-conf-Include-varstore-element-in-domcaps.patch @@ -0,0 +1,140 @@ +From af94300604718604a70a5d587e56187ffe5e6557 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Andrea Bolognani +Date: Fri, 30 Jan 2026 17:46:30 +0100 +Subject: [PATCH] conf: Include varstore element in domcaps +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We want to advertise whether the element is usable when +defining new domains. + +Signed-off-by: Andrea Bolognani +Reviewed-by: Michal Privoznik +Acked-by: Gerd Hoffmann +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 3d6987914bb10beb11b9eb5e83ec2194dfab1659) + +https://issues.redhat.com/browse/RHEL-82645 + +Signed-off-by: Andrea Bolognani +--- + docs/formatdomaincaps.rst | 7 +++++++ + src/conf/domain_capabilities.c | 10 ++++++++++ + src/conf/domain_capabilities.h | 6 ++++++ + src/conf/schemas/domaincaps.rng | 9 +++++++++ + 4 files changed, 32 insertions(+) + +diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst +index 3426b7c9cd..5a1d3f2670 100644 +--- a/docs/formatdomaincaps.rst ++++ b/docs/formatdomaincaps.rst +@@ -141,6 +141,7 @@ domains. + no + + ++ + + ... + +@@ -227,6 +228,12 @@ are the following: + possible to enforce Secure Boot, look at the ``enrolledKeys`` enum inside + the ```` element instead. + ++The ```` element :since:`(since 12.1.0)` indicates whether UEFI ++variable storage backed by the ``uefi-vars`` QEMU device can be used as an ++alternative to pflash-based NVRAM storage. This is the only type of variable ++storage compatible with Secure Boot on non-x86 architectures, but it can be ++used on x86 too. ++ + CPU configuration + ~~~~~~~~~~~~~~~~~ + +diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c +index 9b3577cd08..78b8e6e6e1 100644 +--- a/src/conf/domain_capabilities.c ++++ b/src/conf/domain_capabilities.c +@@ -449,12 +449,21 @@ virDomainCapsLoaderFormat(virBuffer *buf, + FORMAT_EPILOGUE(loader); + } + ++static void ++virDomainCapsVarstoreFormat(virBuffer *buf, ++ const virDomainCapsVarstore *varstore) ++{ ++ FORMAT_PROLOGUE(varstore); ++ FORMAT_EPILOGUE(varstore); ++} ++ + static void + virDomainCapsOSFormat(virBuffer *buf, + const virDomainCapsOS *os) + { + const virDomainCapsFirmwareFeatures *firmwareFeatures = &os->firmwareFeatures; + const virDomainCapsLoader *loader = &os->loader; ++ const virDomainCapsVarstore *varstore = &os->varstore; + + FORMAT_PROLOGUE(os); + +@@ -462,6 +471,7 @@ virDomainCapsOSFormat(virBuffer *buf, + + virDomainCapsFirmwareFeaturesFormat(&childBuf, firmwareFeatures); + virDomainCapsLoaderFormat(&childBuf, loader); ++ virDomainCapsVarstoreFormat(&childBuf, varstore); + + FORMAT_EPILOGUE(os); + } +diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h +index a68fafe235..02344fd9b6 100644 +--- a/src/conf/domain_capabilities.h ++++ b/src/conf/domain_capabilities.h +@@ -61,6 +61,11 @@ struct _virDomainCapsLoader { + virDomainCapsEnum secure; /* Info about secure:virTristateBool */ + }; + ++typedef struct _virDomainCapsVarstore virDomainCapsVarstore; ++struct _virDomainCapsVarstore { ++ virTristateBool supported; ++}; ++ + STATIC_ASSERT_ENUM(VIR_DOMAIN_OS_DEF_FIRMWARE_LAST); + typedef struct _virDomainCapsOS virDomainCapsOS; + struct _virDomainCapsOS { +@@ -68,6 +73,7 @@ struct _virDomainCapsOS { + virDomainCapsEnum firmware; /* Info about virDomainOsDefFirmware */ + virDomainCapsFirmwareFeatures firmwareFeatures; + virDomainCapsLoader loader; /* Info about virDomainLoaderDef */ ++ virDomainCapsVarstore varstore; + }; + + STATIC_ASSERT_ENUM(VIR_DOMAIN_MEMORY_SOURCE_LAST); +diff --git a/src/conf/schemas/domaincaps.rng b/src/conf/schemas/domaincaps.rng +index 3b24caeca6..4682abbf41 100644 +--- a/src/conf/schemas/domaincaps.rng ++++ b/src/conf/schemas/domaincaps.rng +@@ -87,6 +87,12 @@ + + + ++ ++ ++ ++ ++ ++ + + + +@@ -98,6 +104,9 @@ + + + ++ ++ ++ + + + +-- +2.53.0 diff --git a/libvirt-conf-Move-type-rom-default-for-loader-to-drivers.patch b/libvirt-conf-Move-type-rom-default-for-loader-to-drivers.patch new file mode 100644 index 0000000..96b68cb --- /dev/null +++ b/libvirt-conf-Move-type-rom-default-for-loader-to-drivers.patch @@ -0,0 +1,104 @@ +From 08ff36546b810ae14135c19c99fb1dc1aa5fcbb2 Mon Sep 17 00:00:00 2001 +Message-ID: <08ff36546b810ae14135c19c99fb1dc1aa5fcbb2.1772815313.git.jdenemar@redhat.com> +From: Andrea Bolognani +Date: Tue, 3 Feb 2026 15:18:39 +0100 +Subject: [PATCH] conf: Move type=rom default for loader to drivers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Right now we set this default in the common parsing code, which +is not a big problem per se but would get in the way of some +upcoming changes. + +Leave this choice to individual drivers instead. Only the QEMU +and Xen drivers use the value for anything, so we can limit the +amount of code duplication this change causes. + +Signed-off-by: Andrea Bolognani +Reviewed-by: Michal Privoznik +Acked-by: Gerd Hoffmann +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 1504b7f687bdfc679377e605d076776b18533468) + +https://issues.redhat.com/browse/RHEL-82645 + +Signed-off-by: Andrea Bolognani +--- + src/conf/domain_postparse.c | 19 ------------------- + src/libxl/libxl_domain.c | 6 ++++++ + src/qemu/qemu_firmware.c | 5 +++++ + 3 files changed, 11 insertions(+), 19 deletions(-) + +diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c +index 38e731348d..cbaae75c02 100644 +--- a/src/conf/domain_postparse.c ++++ b/src/conf/domain_postparse.c +@@ -89,22 +89,6 @@ virDomainDefPostParseMemory(virDomainDef *def, + } + + +-static int +-virDomainDefPostParseOs(virDomainDef *def) +-{ +- if (!def->os.loader) +- return 0; +- +- if (def->os.loader->path && +- def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_NONE) { +- /* By default, loader is type of 'rom' */ +- def->os.loader->type = VIR_DOMAIN_LOADER_TYPE_ROM; +- } +- +- return 0; +-} +- +- + static void + virDomainDefPostParseMemtune(virDomainDef *def) + { +@@ -1251,9 +1235,6 @@ virDomainDefPostParseCommon(virDomainDef *def, + if (virDomainDefPostParseMemory(def, data->parseFlags) < 0) + return -1; + +- if (virDomainDefPostParseOs(def) < 0) +- return -1; +- + virDomainDefPostParseMemtune(def); + + if (virDomainDefRejectDuplicateControllers(def) < 0) +diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c +index 9842d6fece..c6717e31cf 100644 +--- a/src/libxl/libxl_domain.c ++++ b/src/libxl/libxl_domain.c +@@ -279,6 +279,12 @@ libxlDomainDefPostParse(virDomainDef *def, + def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_TRISTATE_SWITCH_ON; + } + ++ if (def->os.loader && ++ def->os.loader->path && ++ !def->os.loader->type) { ++ def->os.loader->type = VIR_DOMAIN_LOADER_TYPE_ROM; ++ } ++ + /* add implicit balloon device */ + if (def->memballoon == NULL) { + virDomainMemballoonDef *memballoon; +diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c +index 519828f6f9..6a074055ca 100644 +--- a/src/qemu/qemu_firmware.c ++++ b/src/qemu/qemu_firmware.c +@@ -1662,6 +1662,11 @@ qemuFirmwareFillDomainCustom(virDomainDef *def) + if (!loader) + return; + ++ if (loader->path && ++ !loader->type) { ++ loader->type = VIR_DOMAIN_LOADER_TYPE_ROM; ++ } ++ + if (loader->path && + !loader->format) { + loader->format = VIR_STORAGE_FILE_RAW; +-- +2.53.0 diff --git a/libvirt-conf-Parse-and-format-varstore-element.patch b/libvirt-conf-Parse-and-format-varstore-element.patch new file mode 100644 index 0000000..477d66e --- /dev/null +++ b/libvirt-conf-Parse-and-format-varstore-element.patch @@ -0,0 +1,385 @@ +From 50a7a37ea4d6c8ffab8110a58db1b16b9d1d7b84 Mon Sep 17 00:00:00 2001 +Message-ID: <50a7a37ea4d6c8ffab8110a58db1b16b9d1d7b84.1772815313.git.jdenemar@redhat.com> +From: Andrea Bolognani +Date: Mon, 19 Jan 2026 14:20:06 +0100 +Subject: [PATCH] conf: Parse and format varstore element +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This will be used to configure the backing storage used by the +uefi-vars QEMU device. + +Dealing with the element itself is trivial, however we have to +refactor the existing code which deals with the loader and nvram +elements slightly: in particular, we can no longer perform an +early exit if those elements are absent. + +Signed-off-by: Andrea Bolognani +Reviewed-by: Michal Privoznik +Acked-by: Gerd Hoffmann +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 3feee6d0aba5abf5e69d69b0022c08ea6bd5af3e) + +https://issues.redhat.com/browse/RHEL-82645 + +Signed-off-by: Andrea Bolognani +--- + docs/formatdomain.rst | 23 +++++++-- + docs/kbase/secureboot.rst | 46 ++++++++++++------ + src/conf/domain_conf.c | 81 ++++++++++++++++++++++++++++--- + src/conf/domain_conf.h | 9 ++++ + src/conf/schemas/domaincommon.rng | 22 ++++++++- + src/conf/virconftypes.h | 2 + + src/libvirt_private.syms | 2 + + 7 files changed, 157 insertions(+), 28 deletions(-) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 152fd7f530..7d6cc45efd 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -196,9 +196,9 @@ harddisk, cdrom, network) determining where to obtain/find the boot image. + + ``firmware`` + The ``firmware`` attribute allows management applications to automatically +- fill ```` and ```` elements and possibly enable some +- features required by selected firmware. Accepted values are ``bios`` and +- ``efi``. ++ fill ```` and ```` or ```` elements and possibly ++ enable some features required by selected firmware. Accepted values are ++ ``bios`` and ``efi``. + The selection process scans for files describing installed firmware images in + specified location and uses the most specific one which fulfills domain + requirements. The locations in order of preference (from generic to most +@@ -311,6 +311,23 @@ harddisk, cdrom, network) determining where to obtain/find the boot image. + It is not valid to provide this element if the loader is marked as + stateless. + ++``varstore`` ++ This works much the same way as the ```` element described above, ++ except that variable storage is handled by the ``uefi-vars`` QEMU device ++ instead of being backed by a pflash device. :since:`Since 12.1.0 (QEMU only)` ++ ++ The ``path`` attribute contains the path of the domain-specific file where ++ variables are stored, while the ``template`` attribute points to a template ++ that the domain-specific file can be (re)generated from. Assuming that the ++ necessary JSON firmware descriptor files are present, both attributes will ++ be filled in automatically by libvirt. ++ ++ Using ```` instead of ```` is particularly useful on ++ non-x86 architectures such as aarch64, where it represents the only way to ++ get Secure Boot working. It can be used on x86 too, and doing so will make ++ it possible to keep UEFI authenticated variables safe from tampering without ++ requiring the use of SMM emulation. ++ + ``boot`` + The ``dev`` attribute takes one of the values "fd", "hd", "cdrom" or + "network" and is used to specify the next boot device to consider. The +diff --git a/docs/kbase/secureboot.rst b/docs/kbase/secureboot.rst +index 6c22b08d22..b411b65f00 100644 +--- a/docs/kbase/secureboot.rst ++++ b/docs/kbase/secureboot.rst +@@ -74,8 +74,8 @@ Changing an existing VM + + When a VM is defined, libvirt will pick the firmware that best + satisfies the provided criteria and record this information for use +-on subsequent boots. The resulting XML configuration will look like +-this: ++on subsequent boots. The resulting XML configuration will look either ++like this: + + :: + +@@ -88,14 +88,28 @@ this: + /var/lib/libvirt/qemu/nvram/vm_VARS.fd + + ++or like this: ++ ++:: ++ ++ ++ ++ ++ ++ ++ /usr/share/edk2/aarch64/QEMU_EFI.qemuvars.fd ++ ++ ++ + In order to force libvirt to repeat the firmware autoselection +-process, it's necessary to remove the ```` and ```` +-elements. Failure to do so will likely result in an error. ++process, it's necessary to remove the ```` as well as the ++```` or ```` elements, depending on what's ++applicable. Failure to do so will likely result in an error. + + Note that updating the XML configuration as described above is +-**not** enough to change the Secure Boot status: the NVRAM file +-associated with the VM has to be regenerated from its template as +-well. ++**not** enough to change the Secure Boot status: the NVRAM/varstore ++file associated with the VM has to be regenerated from its template ++as well. + + In order to do that, update the XML and then start the VM with + +@@ -107,9 +121,9 @@ This option is only available starting with libvirt 8.1.0, so if your + version of libvirt is older than that you will have to delete the + NVRAM file manually before starting the VM. + +-Most guest operating systems will be able to cope with the NVRAM file +-being reinitialized, but in some cases the VM will be unable to boot +-after the change. ++Most guest operating systems will be able to cope with the ++NVRAM/varstore file being reinitialized, but in some cases the VM ++will be unable to boot after the change. + + + Additional information +@@ -126,15 +140,15 @@ can be used to validate the operating system signature need to be + provided as well. + + Asking for the ``enrolled-keys`` firmware feature to be enabled will +-cause libvirt to initialize the NVRAM file associated with the VM +-from a template that contains a suitable set of keys. These keys +-being present will cause the firmware to enforce the Secure Boot ++cause libvirt to initialize the NVRAM/varstore file associated with ++the VM from a template that contains a suitable set of keys. These ++keys being present will cause the firmware to enforce the Secure Boot + signing requirements. + + The opposite configuration, where the feature is explicitly disabled, +-will result in no keys being present in the NVRAM file. Unable to +-verify signatures, the firmware will allow even unsigned operating +-systems to run. ++will result in no keys being present in the NVRAM/varstore file. ++Unable to verify signatures, the firmware will allow even unsigned ++operating systems to run. + + If running unsigned code is desired, it's also possible to ask for + the ``secure-boot`` feature to be disabled, which will cause libvirt +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index e72cda0048..16ea9f0b2e 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -3932,6 +3932,27 @@ virDomainLoaderDefFree(virDomainLoaderDef *loader) + g_free(loader); + } + ++virDomainVarstoreDef * ++virDomainVarstoreDefNew(void) ++{ ++ virDomainVarstoreDef *def = NULL; ++ ++ def = g_new0(virDomainVarstoreDef, 1); ++ ++ return def; ++} ++ ++void ++virDomainVarstoreDefFree(virDomainVarstoreDef *varstore) ++{ ++ if (!varstore) ++ return; ++ ++ g_free(varstore->path); ++ g_free(varstore->template); ++ g_free(varstore); ++} ++ + + static void + virDomainResctrlMonDefFree(virDomainResctrlMonDef *domresmon) +@@ -4034,6 +4055,7 @@ virDomainOSDefClear(virDomainOSDef *os) + virDomainOSACPITableDefFree(os->acpiTables[i]); + g_free(os->acpiTables); + virDomainLoaderDefFree(os->loader); ++ virDomainVarstoreDefFree(os->varstore); + g_free(os->bootloader); + g_free(os->bootloaderArgs); + } +@@ -17983,6 +18005,17 @@ virDomainLoaderDefParseXMLLoader(virDomainLoaderDef *loader, + } + + ++static int ++virDomainVarstoreDefParseXML(virDomainVarstoreDef *varstore, ++ xmlNodePtr varstoreNode) ++{ ++ varstore->path = virXMLPropString(varstoreNode, "path"); ++ varstore->template = virXMLPropString(varstoreNode, "template"); ++ ++ return 0; ++} ++ ++ + static int + virDomainLoaderDefParseXML(virDomainLoaderDef *loader, + xmlNodePtr loaderNode, +@@ -18430,16 +18463,29 @@ virDomainDefParseBootLoaderOptions(virDomainDef *def, + xmlNodePtr loaderNode = virXPathNode("./os/loader[1]", ctxt); + xmlNodePtr nvramNode = virXPathNode("./os/nvram[1]", ctxt); + xmlNodePtr nvramSourceNode = virXPathNode("./os/nvram/source[1]", ctxt); ++ xmlNodePtr varstoreNode = virXPathNode("./os/varstore[1]", ctxt); + +- if (!loaderNode && !nvramNode) +- return 0; +- +- def->os.loader = virDomainLoaderDefNew(); +- +- if (virDomainLoaderDefParseXML(def->os.loader, +- loaderNode, nvramNode, nvramSourceNode, +- ctxt, xmlopt, flags) < 0) ++ if (nvramNode && varstoreNode) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Cannot have both and ")); + return -1; ++ } ++ ++ if (loaderNode || nvramNode) { ++ def->os.loader = virDomainLoaderDefNew(); ++ ++ if (virDomainLoaderDefParseXML(def->os.loader, ++ loaderNode, nvramNode, nvramSourceNode, ++ ctxt, xmlopt, flags) < 0) ++ return -1; ++ } ++ ++ if (varstoreNode) { ++ def->os.varstore = virDomainVarstoreDefNew(); ++ ++ if (virDomainVarstoreDefParseXML(def->os.varstore, varstoreNode) < 0) ++ return -1; ++ } + + return 0; + } +@@ -28062,6 +28108,20 @@ virDomainLoaderDefFormat(virBuffer *buf, + return 0; + } + ++static int ++virDomainVarstoreDefFormat(virBuffer *buf, ++ virDomainVarstoreDef *varstore) ++{ ++ g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; ++ ++ virBufferEscapeString(&attrBuf, " template='%s'", varstore->template); ++ virBufferEscapeString(&attrBuf, " path='%s'", varstore->path); ++ ++ virXMLFormatElementEmpty(buf, "varstore", &attrBuf, NULL); ++ ++ return 0; ++} ++ + static void + virDomainKeyWrapDefFormat(virBuffer *buf, virDomainKeyWrapDef *keywrap) + { +@@ -29523,6 +29583,11 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def, + if (def->os.loader && + virDomainLoaderDefFormat(buf, def->os.loader, xmlopt, flags) < 0) + return -1; ++ ++ if (def->os.varstore && ++ virDomainVarstoreDefFormat(buf, def->os.varstore) < 0) ++ return -1; ++ + virBufferEscapeString(buf, "%s\n", + def->os.kernel); + virBufferEscapeString(buf, "%s\n", +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 69a8e79c6d..ead3b07475 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2420,6 +2420,14 @@ struct _virDomainLoaderDef { + virDomainLoaderDef *virDomainLoaderDefNew(void); + void virDomainLoaderDefFree(virDomainLoaderDef *loader); + ++struct _virDomainVarstoreDef { ++ char *path; ++ char *template; ++}; ++ ++virDomainVarstoreDef *virDomainVarstoreDefNew(void); ++void virDomainVarstoreDefFree(virDomainVarstoreDef *varstore); ++ + typedef enum { + VIR_DOMAIN_IOAPIC_NONE = 0, + VIR_DOMAIN_IOAPIC_QEMU, +@@ -2573,6 +2581,7 @@ struct _virDomainOSDef { + size_t nacpiTables; + virDomainOSACPITableDef **acpiTables; + virDomainLoaderDef *loader; ++ virDomainVarstoreDef *varstore; + char *bootloader; + char *bootloaderArgs; + int smbios_mode; +diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng +index 92f82c8fbf..7215db3fc1 100644 +--- a/src/conf/schemas/domaincommon.rng ++++ b/src/conf/schemas/domaincommon.rng +@@ -349,7 +349,10 @@ + + + +- ++ ++ ++ ++ + + + +@@ -456,6 +459,23 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h +index 6e2573035a..0596791a4d 100644 +--- a/src/conf/virconftypes.h ++++ b/src/conf/virconftypes.h +@@ -164,6 +164,8 @@ typedef struct _virDomainLeaseDef virDomainLeaseDef; + + typedef struct _virDomainLoaderDef virDomainLoaderDef; + ++typedef struct _virDomainVarstoreDef virDomainVarstoreDef; ++ + typedef struct _virDomainMemballoonDef virDomainMemballoonDef; + + typedef struct _virDomainMemoryDef virDomainMemoryDef; +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index effe44fe57..1308fa2e51 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -718,6 +718,8 @@ virDomainTPMProfileRemoveDisabledTypeToString; + virDomainTPMVersionTypeFromString; + virDomainTPMVersionTypeToString; + virDomainUSBDeviceDefForeach; ++virDomainVarstoreDefFree; ++virDomainVarstoreDefNew; + virDomainVideoDefaultRAM; + virDomainVideoDefClear; + virDomainVideoDefFree; +-- +2.53.0 diff --git a/libvirt-conf-Update-validation-to-consider-varstore-element.patch b/libvirt-conf-Update-validation-to-consider-varstore-element.patch new file mode 100644 index 0000000..c48c277 --- /dev/null +++ b/libvirt-conf-Update-validation-to-consider-varstore-element.patch @@ -0,0 +1,378 @@ +From f47031d4e6439d1daf5711d4117c0fa647196944 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Andrea Bolognani +Date: Thu, 22 Jan 2026 19:27:03 +0100 +Subject: [PATCH] conf: Update validation to consider varstore element +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The code is reworked quite significantly, but most of the +existing checks are preserved. Those that aren't, notably the +one that allowed pflash as the only acceptable non-stateless +firmware type, are intentionally removed because they will no +longer reflect reality once support for the uefi-vars QEMU +device is introduced. + +As a side effect, reworking the function in this fashion +resolves a subtle bug: due to the early exits that were being +performed when the loader element was missing, the checks at +the bottom of the function (related to the shim and kernel +elements) were effectively never performed. This is no longer +the case. + +Signed-off-by: Andrea Bolognani +Reviewed-by: Michal Privoznik +Acked-by: Gerd Hoffmann +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 1c2dbdf3ac5bed84caeacf585d5143dcf32df75e) + +https://issues.redhat.com/browse/RHEL-82645 + +Signed-off-by: Andrea Bolognani +--- + src/conf/domain_validate.c | 100 +++++++----------- + ...-auto-bios-not-stateless.x86_64-latest.err | 2 +- + ...-auto-bios-not-stateless.x86_64-latest.xml | 35 ++++++ + ...firmware-auto-bios-nvram.x86_64-latest.err | 2 +- + ...nual-bios-not-stateless.x86_64-latest.args | 32 ++++++ + ...anual-bios-not-stateless.x86_64-latest.err | 1 - + ...anual-bios-not-stateless.x86_64-latest.xml | 28 +++++ + ...nual-efi-nvram-stateless.x86_64-latest.err | 2 +- + ...nvram-template-stateless.x86_64-latest.err | 2 +- + ...ware-manual-efi-rw-nvram.x86_64-latest.err | 2 +- + tests/qemuxmlconftest.c | 7 +- + 11 files changed, 144 insertions(+), 69 deletions(-) + create mode 100644 tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml + create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.args + delete mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.err + create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.xml + +diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c +index 7346a61731..163095d55c 100644 +--- a/src/conf/domain_validate.c ++++ b/src/conf/domain_validate.c +@@ -1723,95 +1723,46 @@ virDomainDefOSValidate(const virDomainDef *def, + virDomainXMLOption *xmlopt) + { + virDomainLoaderDef *loader = def->os.loader; ++ virDomainVarstoreDef *varstore = def->os.varstore; ++ virDomainOsDefFirmware firmware = def->os.firmware; ++ int *firmwareFeatures = def->os.firmwareFeatures; ++ bool usesNvram = loader && (loader->nvram || loader->nvramTemplate || loader->nvramTemplateFormat); + +- if (def->os.firmware) { ++ if (firmware) { + if (xmlopt && !(xmlopt->config.features & VIR_DOMAIN_DEF_FEATURE_FW_AUTOSELECT)) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("firmware auto selection not implemented for this driver")); + return -1; + } + +- if (def->os.firmwareFeatures && +- def->os.firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_ENROLLED_KEYS] == VIR_TRISTATE_BOOL_YES && +- def->os.firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_SECURE_BOOT] == VIR_TRISTATE_BOOL_NO) { ++ if (firmwareFeatures && ++ firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_ENROLLED_KEYS] == VIR_TRISTATE_BOOL_YES && ++ firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_SECURE_BOOT] == VIR_TRISTATE_BOOL_NO) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("firmware feature 'enrolled-keys' cannot be enabled when firmware feature 'secure-boot' is disabled")); + return -1; + } +- +- if (!loader) +- return 0; +- +- if (loader->nvram && def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) { +- virReportError(VIR_ERR_XML_DETAIL, +- _("firmware type '%1$s' does not support nvram"), +- virDomainOsDefFirmwareTypeToString(def->os.firmware)); +- return -1; +- } + } else { +- if (def->os.firmwareFeatures) { ++ if (firmwareFeatures) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("cannot use feature-based firmware autoselection when firmware autoselection is disabled")); + return -1; + } + +- if (!loader) +- return 0; +- +- if (!loader->path) { ++ if (loader && !loader->path) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("no loader path specified and firmware auto selection disabled")); + return -1; + } + } + +- if (loader->readonly == VIR_TRISTATE_BOOL_NO) { +- if (loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) { ++ if (loader && loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) { ++ if (loader->readonly == VIR_TRISTATE_BOOL_NO) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("ROM loader type cannot be used as read/write")); + return -1; + } + +- if (loader->nvramTemplate) { +- virReportError(VIR_ERR_XML_DETAIL, "%s", +- _("NVRAM template is not permitted when loader is read/write")); +- return -1; +- } +- +- if (loader->nvram) { +- virReportError(VIR_ERR_XML_DETAIL, "%s", +- _("NVRAM is not permitted when loader is read/write")); +- return -1; +- } +- } +- +- if (loader->stateless == VIR_TRISTATE_BOOL_YES) { +- if (loader->nvramTemplate) { +- virReportError(VIR_ERR_XML_DETAIL, "%s", +- _("NVRAM template is not permitted when loader is stateless")); +- return -1; +- } +- +- if (loader->nvram) { +- virReportError(VIR_ERR_XML_DETAIL, "%s", +- _("NVRAM is not permitted when loader is stateless")); +- return -1; +- } +- } else if (loader->stateless == VIR_TRISTATE_BOOL_NO) { +- if (def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) { +- if (def->os.loader->type != VIR_DOMAIN_LOADER_TYPE_PFLASH) { +- virReportError(VIR_ERR_XML_DETAIL, "%s", +- _("Only pflash loader type permits NVRAM")); +- return -1; +- } +- } else if (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) { +- virReportError(VIR_ERR_XML_DETAIL, "%s", +- _("Only EFI firmware permits NVRAM")); +- return -1; +- } +- } +- +- if (loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) { + if (loader->format && + loader->format != VIR_STORAGE_FILE_RAW) { + virReportError(VIR_ERR_XML_DETAIL, +@@ -1821,6 +1772,33 @@ virDomainDefOSValidate(const virDomainDef *def, + } + } + ++ if (usesNvram && varstore) { ++ virReportError(VIR_ERR_XML_DETAIL, "%s", ++ _("Only one of NVRAM/varstore can be used")); ++ return -1; ++ } ++ ++ if (usesNvram || varstore) { ++ if (firmware && firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) { ++ virReportError(VIR_ERR_XML_DETAIL, ++ _("Firmware type '%1$s' does not support variable storage (NVRAM/varstore)"), ++ virDomainOsDefFirmwareTypeToString(firmware)); ++ return -1; ++ } ++ ++ if (loader && loader->stateless == VIR_TRISTATE_BOOL_YES) { ++ virReportError(VIR_ERR_XML_DETAIL, "%s", ++ _("Variable storage (NVRAM/varstore) is not permitted when loader is stateless")); ++ return -1; ++ } ++ ++ if (loader && loader->readonly == VIR_TRISTATE_BOOL_NO) { ++ virReportError(VIR_ERR_XML_DETAIL, "%s", ++ _("Variable storage (NVRAM/varstore) is not permitted when loader is read/write")); ++ return -1; ++ } ++ } ++ + if (def->os.shim && !def->os.kernel) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("shim only allowed with kernel option")); +diff --git a/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err +index b058f970a4..743fe27a97 100644 +--- a/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err ++++ b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err +@@ -1 +1 @@ +-Only EFI firmware permits NVRAM ++operation failed: Unable to find 'bios' firmware that is compatible with the current configuration +diff --git a/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml +new file mode 100644 +index 0000000000..062835e351 +--- /dev/null ++++ b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml +@@ -0,0 +1,35 @@ ++ ++ guest ++ 63840878-0deb-4095-97e6-fc444d9bc9fa ++ 1048576 ++ 1048576 ++ 1 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ ++ qemu64 ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++
++ ++ ++ ++ ++