[PATCH 00/36] qemu: Improvements and fixes to firmware selection
This series improves validation so that more nonsensical configurations are rejected, fixes a number of scenarios in which user-provided attributes were getting overwritten by the firmware selection process, and overall makes things more predictable and reliable. Notably, it addresses the inability of starting confidential VMs on aarch64, which was reported[1] some time ago. It is also a prerequisite of another series that I will post shortly, which introduces support for the uefi-vars QEMU device and thus makes it possible to use Secure Boot for aarch64 VMs. Since all these fixes and improvements make sense on their own, and there is a little bit of work still needed on the QEMU/edk2 side before the other series can be merged, I decided to post this one separately instead of lumping them together. It's not like it's not meaty enough on its own anyway :) [1] https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/D5UDR... Andrea Bolognani (36): qemu_firmware: Drop support for kernel descriptors qemu_firmware: Drop 'nvram' local variable qemu_firmware: Move format=raw compat exception qemu_firmware: Move copying of nvram.format to loader.format tests: Add firmware-manual-efi-rw-nvram domain_validate: Reject NVRAM with read/write firmware tests: Add firmware-auto-bios-rw tests: Add firmware-manual-bios-rw domain_validate: Reject read/write ROMs tests: Add firmware-auto-efi-format-loader-qcow2-rom domain_validate: Reject ROMs with format other than raw qemu_firmware: Ignore stateless/combined when NVRAM is configured qemu_firmware: Drop fallback for absent nvramTemplateFormat schemas: Allow templateFormat without template path tests: Add firmware-manual-efi-nvram-template-nonstandard-format tests: Add firmware-manual-efi-nvram-template-nonstandard-legacy-paths tests: Add firmware-auto-efi-format-nvram-raw tests: Add firmware-auto-efi-format-nvram-raw-loader-path tests: Add firmware-auto-efi-format-nvram-raw-nvramtemplate-path tests: Add firmware-auto-efi-format-nvramtemplate-qcow2 tests: Add firmware-auto-efi-format-mismatch-nvramtemplate qemu_firmware: Introduce qemuFirmwareFillDomainCustom() qemu_firmware: Set templateFormat for custom paths qemu_firmware: Simplify handling of legacy paths qemu_firmware: Refactor setting NVRAM format qemu_firmware: Prefer template format to loader format qemu_firmware: Retain user-specified NVRAM format qemu_firmware: Take templateFormat into account when matching qemu_firmware: Take NVRAM format into account when matching qemu_firmware: Remove NVRAM to loader format copy hack tests: Add firmware-manual-efi-sev-snp tests: Add firmware-manual-efi-tdx qemu_firmware: ROM firmware is always in raw format qemu_firmware: Don't skip autoselection for ROM qemu_firmware: Allow matching both UEFI and BIOS for ROM loader news: Mention improvements and fixes to firmware selection NEWS.rst | 8 + src/conf/domain_conf.c | 18 +- src/conf/domain_validate.c | 30 ++ src/conf/schemas/domaincommon.rng | 10 +- src/qemu/qemu_firmware.c | 367 ++++++++++-------- src/qemu/qemu_postparse.c | 17 - .../firmware-auto-bios-rw.x86_64-latest.err | 1 + ...> firmware-auto-bios-rw.x86_64-latest.xml} | 5 +- .../qemuxmlconfdata/firmware-auto-bios-rw.xml | 18 + ...-format-loader-qcow2-rom.x86_64-latest.err | 1 + ...mware-auto-efi-format-loader-qcow2-rom.xml | 18 + ...t-mismatch-nvramtemplate.x86_64-latest.err | 1 + ...-mismatch-nvramtemplate.x86_64-latest.xml} | 6 +- ...auto-efi-format-mismatch-nvramtemplate.xml | 19 + ...uto-efi-format-mismatch.x86_64-latest.args | 5 +- ...auto-efi-format-mismatch.x86_64-latest.xml | 2 +- ...-nvram-raw-loader-path.x86_64-latest.args} | 4 +- ...t-nvram-raw-loader-path.x86_64-latest.xml} | 4 +- ...-auto-efi-format-nvram-raw-loader-path.xml | 19 + ...raw-nvramtemplate-path.x86_64-latest.args} | 4 +- ...-raw-nvramtemplate-path.x86_64-latest.xml} | 4 +- ...fi-format-nvram-raw-nvramtemplate-path.xml | 18 + ...t-nvram-raw.x86_64-latest.abi-update.args} | 0 ...at-nvram-raw.x86_64-latest.abi-update.xml} | 0 ...o-efi-format-nvram-raw.x86_64-latest.args} | 0 ...to-efi-format-nvram-raw.x86_64-latest.xml} | 0 .../firmware-auto-efi-format-nvram-raw.xml | 18 + ...at-nvramtemplate-qcow2.x86_64-latest.args} | 9 +- ...mat-nvramtemplate-qcow2.x86_64-latest.xml} | 4 +- ...re-auto-efi-format-nvramtemplate-qcow2.xml | 18 + .../firmware-manual-bios-rw.x86_64-latest.err | 1 + .../firmware-manual-bios-rw.xml | 15 + ...-loader-path-nonstandard.x86_64-latest.xml | 2 +- ...ate-nonstandard-format.x86_64-latest.args} | 10 +- ...late-nonstandard-format.x86_64-latest.xml} | 4 +- ...-efi-nvram-template-nonstandard-format.xml | 19 + ...nstandard-legacy-paths.x86_64-latest.args} | 4 +- ...onstandard-legacy-paths.x86_64-latest.xml} | 5 +- ...vram-template-nonstandard-legacy-paths.xml | 20 + ...ram-template-nonstandard.x86_64-latest.xml | 2 +- ...ware-manual-efi-rw-nvram.x86_64-latest.err | 1 + .../firmware-manual-efi-rw-nvram.xml | 19 + ...ual-efi-sev-snp.x86_64-latest+amdsev.args} | 7 +- ...nual-efi-sev-snp.x86_64-latest+amdsev.xml} | 12 +- .../firmware-manual-efi-sev-snp.xml | 21 + ...anual-efi-tdx.x86_64-latest+inteltdx.args} | 9 +- ...manual-efi-tdx.x86_64-latest+inteltdx.xml} | 11 +- .../firmware-manual-efi-tdx.xml | 25 ++ tests/qemuxmlconftest.c | 19 + 49 files changed, 571 insertions(+), 263 deletions(-) create mode 100644 tests/qemuxmlconfdata/firmware-auto-bios-rw.x86_64-latest.err copy tests/qemuxmlconfdata/{firmware-manual-efi-nvram-template-nonstandard.x86_64-latest.xml => firmware-auto-bios-rw.x86_64-latest.xml} (83%) create mode 100644 tests/qemuxmlconfdata/firmware-auto-bios-rw.xml create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.err create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.xml create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.err copy tests/qemuxmlconfdata/{firmware-manual-efi-nvram-template-nonstandard.x86_64-latest.xml => firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.xml} (83%) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.xml copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.args => firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.args} (90%) copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.xml => firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.xml} (81%) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.xml copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.args => firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.args} (90%) copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.xml => firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.xml} (81%) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.xml copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.args => firmware-auto-efi-format-nvram-raw.x86_64-latest.abi-update.args} (100%) copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.xml => firmware-auto-efi-format-nvram-raw.x86_64-latest.abi-update.xml} (100%) copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.args => firmware-auto-efi-format-nvram-raw.x86_64-latest.args} (100%) copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.xml => firmware-auto-efi-format-nvram-raw.x86_64-latest.xml} (100%) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.xml copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.args => firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args} (77%) copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.xml => firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml} (81%) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.xml create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.err create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.xml copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.args => firmware-manual-efi-nvram-template-nonstandard-format.x86_64-latest.args} (70%) copy tests/qemuxmlconfdata/{firmware-manual-efi-nvram-template-nonstandard.x86_64-latest.xml => firmware-manual-efi-nvram-template-nonstandard-format.x86_64-latest.xml} (81%) create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.xml copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.args => firmware-manual-efi-nvram-template-nonstandard-legacy-paths.x86_64-latest.args} (89%) copy tests/qemuxmlconfdata/{firmware-manual-efi-loader-path-nonstandard.x86_64-latest.xml => firmware-manual-efi-nvram-template-nonstandard-legacy-paths.x86_64-latest.xml} (81%) create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.xml create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.xml copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.args => firmware-manual-efi-sev-snp.x86_64-latest+amdsev.args} (74%) copy tests/qemuxmlconfdata/{firmware-manual-efi-nvram-template-nonstandard.x86_64-latest.xml => firmware-manual-efi-sev-snp.x86_64-latest+amdsev.xml} (75%) create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.xml copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.args => firmware-manual-efi-tdx.x86_64-latest+inteltdx.args} (59%) copy tests/qemuxmlconfdata/{firmware-auto-efi-format-mismatch.x86_64-latest.xml => firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml} (69%) create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-tdx.xml -- 2.52.0
I have been able to find exactly zero evidence of this type of firmware descriptor actually existing in the wild, so this is essentialy dead code. Dropping it simplifies the task of further tweaking the firmware selection code. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 83 ++-------------------------------------- 1 file changed, 3 insertions(+), 80 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 5bd34ea87f..b168ec7cf7 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -92,12 +92,6 @@ struct _qemuFirmwareMappingFlash { }; -typedef struct _qemuFirmwareMappingKernel qemuFirmwareMappingKernel; -struct _qemuFirmwareMappingKernel { - char *filename; -}; - - typedef struct _qemuFirmwareMappingMemory qemuFirmwareMappingMemory; struct _qemuFirmwareMappingMemory { char *filename; @@ -107,7 +101,6 @@ struct _qemuFirmwareMappingMemory { typedef enum { QEMU_FIRMWARE_DEVICE_NONE = 0, QEMU_FIRMWARE_DEVICE_FLASH, - QEMU_FIRMWARE_DEVICE_KERNEL, QEMU_FIRMWARE_DEVICE_MEMORY, QEMU_FIRMWARE_DEVICE_LAST @@ -118,7 +111,6 @@ VIR_ENUM_IMPL(qemuFirmwareDevice, QEMU_FIRMWARE_DEVICE_LAST, "", "flash", - "kernel", "memory", ); @@ -129,7 +121,6 @@ struct _qemuFirmwareMapping { union { qemuFirmwareMappingFlash flash; - qemuFirmwareMappingKernel kernel; qemuFirmwareMappingMemory memory; } data; }; @@ -222,13 +213,6 @@ qemuFirmwareMappingFlashFreeContent(qemuFirmwareMappingFlash *flash) } -static void -qemuFirmwareMappingKernelFreeContent(qemuFirmwareMappingKernel *kernel) -{ - g_free(kernel->filename); -} - - static void qemuFirmwareMappingMemoryFreeContent(qemuFirmwareMappingMemory *memory) { @@ -243,9 +227,6 @@ qemuFirmwareMappingFreeContent(qemuFirmwareMapping *mapping) case QEMU_FIRMWARE_DEVICE_FLASH: qemuFirmwareMappingFlashFreeContent(&mapping->data.flash); break; - case QEMU_FIRMWARE_DEVICE_KERNEL: - qemuFirmwareMappingKernelFreeContent(&mapping->data.kernel); - break; case QEMU_FIRMWARE_DEVICE_MEMORY: qemuFirmwareMappingMemoryFreeContent(&mapping->data.memory); break; @@ -418,24 +399,6 @@ qemuFirmwareMappingFlashParse(const char *path, } -static int -qemuFirmwareMappingKernelParse(const char *path, - virJSONValue *doc, - qemuFirmwareMappingKernel *kernel) -{ - const char *filename; - - if (!(filename = virJSONValueObjectGetString(doc, "filename"))) { - VIR_DEBUG("missing 'filename' in '%s'", path); - return -1; - } - - kernel->filename = g_strdup(filename); - - return 0; -} - - static int qemuFirmwareMappingMemoryParse(const char *path, virJSONValue *doc, @@ -485,10 +448,6 @@ qemuFirmwareMappingParse(const char *path, if (qemuFirmwareMappingFlashParse(path, mapping, &fw->mapping.data.flash) < 0) return -1; break; - case QEMU_FIRMWARE_DEVICE_KERNEL: - if (qemuFirmwareMappingKernelParse(path, mapping, &fw->mapping.data.kernel) < 0) - return -1; - break; case QEMU_FIRMWARE_DEVICE_MEMORY: if (qemuFirmwareMappingMemoryParse(path, mapping, &fw->mapping.data.memory) < 0) return -1; @@ -732,19 +691,6 @@ qemuFirmwareMappingFlashFormat(virJSONValue *mapping, } -static int -qemuFirmwareMappingKernelFormat(virJSONValue *mapping, - qemuFirmwareMappingKernel *kernel) -{ - if (virJSONValueObjectAppendString(mapping, - "filename", - kernel->filename) < 0) - return -1; - - return 0; -} - - static int qemuFirmwareMappingMemoryFormat(virJSONValue *mapping, qemuFirmwareMappingMemory *memory) @@ -774,10 +720,6 @@ qemuFirmwareMappingFormat(virJSONValue *doc, if (qemuFirmwareMappingFlashFormat(mapping, &fw->mapping.data.flash) < 0) return -1; break; - case QEMU_FIRMWARE_DEVICE_KERNEL: - if (qemuFirmwareMappingKernelFormat(mapping, &fw->mapping.data.kernel) < 0) - return -1; - break; case QEMU_FIRMWARE_DEVICE_MEMORY: if (qemuFirmwareMappingMemoryFormat(mapping, &fw->mapping.data.memory) < 0) return -1; @@ -920,21 +862,17 @@ qemuFirmwareMatchesMachineArch(const qemuFirmware *fw, * qemuFirmwareMatchesPaths: * @fw: firmware definition * @loader: loader definition - * @kernelPath: path to kernel image * * Checks whether @fw is compatible with the information provided as * part of the domain definition. * - * Returns: true if @fw is compatible with @loader and @kernelPath, - * false otherwise + * Returns: true if @fw is compatible with @loader, false otherwise */ static bool qemuFirmwareMatchesPaths(const qemuFirmware *fw, - const virDomainLoaderDef *loader, - const char *kernelPath) + const virDomainLoaderDef *loader) { const qemuFirmwareMappingFlash *flash = &fw->mapping.data.flash; - const qemuFirmwareMappingKernel *kernel = &fw->mapping.data.kernel; const qemuFirmwareMappingMemory *memory = &fw->mapping.data.memory; switch (fw->mapping.device) { @@ -954,11 +892,6 @@ qemuFirmwareMatchesPaths(const qemuFirmware *fw, !virFileComparePaths(loader->path, memory->filename)) return false; break; - case QEMU_FIRMWARE_DEVICE_KERNEL: - if (kernelPath && - !virFileComparePaths(kernelPath, kernel->filename)) - return false; - break; case QEMU_FIRMWARE_DEVICE_NONE: case QEMU_FIRMWARE_DEVICE_LAST: return false; @@ -1183,7 +1116,7 @@ qemuFirmwareMatchDomain(const virDomainDef *def, return false; } - if (!qemuFirmwareMatchesPaths(fw, def->os.loader, def->os.kernel)) { + if (!qemuFirmwareMatchesPaths(fw, def->os.loader)) { VIR_DEBUG("No matching path in '%s'", path); return false; } @@ -1424,7 +1357,6 @@ qemuFirmwareEnableFeaturesModern(virDomainDef *def, const qemuFirmware *fw) { const qemuFirmwareMappingFlash *flash = &fw->mapping.data.flash; - const qemuFirmwareMappingKernel *kernel = &fw->mapping.data.kernel; const qemuFirmwareMappingMemory *memory = &fw->mapping.data.memory; virDomainLoaderDef *loader = NULL; virStorageFileFormat format; @@ -1482,14 +1414,6 @@ qemuFirmwareEnableFeaturesModern(virDomainDef *def, loader->path, NULLSTR(loader->nvramTemplate)); break; - case QEMU_FIRMWARE_DEVICE_KERNEL: - VIR_FREE(def->os.kernel); - def->os.kernel = g_strdup(kernel->filename); - - VIR_DEBUG("decided on kernel '%s'", - def->os.kernel); - break; - case QEMU_FIRMWARE_DEVICE_MEMORY: if (!def->os.loader) def->os.loader = virDomainLoaderDefNew(); @@ -2056,7 +1980,6 @@ qemuFirmwareGetSupported(const char *machine, fwpath = memory->filename; break; - case QEMU_FIRMWARE_DEVICE_KERNEL: case QEMU_FIRMWARE_DEVICE_NONE: case QEMU_FIRMWARE_DEVICE_LAST: break; -- 2.52.0
On Mon, Dec 29, 2025 at 12:33:37AM +0100, Andrea Bolognani via Devel wrote:
I have been able to find exactly zero evidence of this type of firmware descriptor actually existing in the wild, so this is essentialy dead code.
Upstream edk2 actually has a build configuration for aarch64 firmware images loadable via -kernel. Which is probably the reason this was added in the first place. rhel/centos/fedora do not ship such builds. I'm not aware of any advantages such a build has, and the obvious disadvantage is that direct kernel boot via -kernel can not work by design. So I do not expect this to change. If there is anything going to change in how firmware gets loaded, then this will most likely be the move to use IGVM. So no objections to drop this from my side. I think it makes sense to also remove this from the spec in qemu. take care, Gerd
We access the NVRAM information via the 'loader' local variable throughout the file, and this is the only spot where the 'nvram' local variable exists. It makes things inconsistent and opens up the possibility of the values for 'loader' and 'nvram' going out of sync, especially after a future commit will introduce the need to set the former. Just get rid of the additional variable. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index b168ec7cf7..903b0a984d 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1780,7 +1780,6 @@ qemuFirmwareFillDomain(virQEMUDriver *driver, bool abiUpdate) { virDomainLoaderDef *loader = def->os.loader; - virStorageSource *nvram = loader ? loader->nvram : NULL; bool autoSelection = (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE); int ret; @@ -1804,13 +1803,14 @@ qemuFirmwareFillDomain(virQEMUDriver *driver, virStorageFileFormatTypeToString(loader->format)); return -1; } - if (nvram && - nvram->format && - nvram->format != VIR_STORAGE_FILE_RAW && - nvram->format != VIR_STORAGE_FILE_QCOW2) { + if (loader && + loader->nvram && + loader->nvram->format && + loader->nvram->format != VIR_STORAGE_FILE_RAW && + loader->nvram->format != VIR_STORAGE_FILE_QCOW2) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported nvram format '%1$s'"), - virStorageFileFormatTypeToString(nvram->format)); + virStorageFileFormatTypeToString(loader->nvram->format)); return -1; } -- 2.52.0
We currently apply this exception, which is critical to ensure that the correct firmware is selected when working with older VMs, in the postparse callback. Move it to the firmware selection process instead, where it should have been added in the first place. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 20 ++++++++++++++++++++ src/qemu/qemu_postparse.c | 17 ----------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 903b0a984d..6c609ece6a 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1783,6 +1783,26 @@ qemuFirmwareFillDomain(virQEMUDriver *driver, bool autoSelection = (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE); int ret; + /* If we're loading an existing configuration from disk, we + * should try as hard as possible to preserve historical + * behavior. In particular, firmware autoselection being enabled + * could never have resulted, before libvirt 9.2.0, in anything + * but a raw firmware image being selected. + * + * In order to ensure that existing domains keep working even if + * a firmware descriptor for a build with a different format is + * given higher priority, explicitly add this requirement to the + * definition before performing firmware selection */ + if (!abiUpdate && autoSelection) { + if (!loader) { + def->os.loader = virDomainLoaderDefNew(); + loader = def->os.loader; + } + if (!loader->format) { + loader->format = VIR_STORAGE_FILE_RAW; + } + } + /* Start by performing a thorough validation of the input. * * We need to do this here because the firmware selection logic diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c index 840d6a1174..8940cb09b3 100644 --- a/src/qemu/qemu_postparse.c +++ b/src/qemu/qemu_postparse.c @@ -1051,23 +1051,6 @@ qemuDomainDefBootPostParse(virDomainDef *def, { bool abiUpdate = !!(parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE); - /* If we're loading an existing configuration from disk, we - * should try as hard as possible to preserve historical - * behavior. In particular, firmware autoselection being enabled - * could never have resulted, before libvirt 9.2.0, in anything - * but a raw firmware image being selected. - * - * In order to ensure that existing domains keep working even if - * a firmware descriptor for a build with a different format is - * given higher priority, explicitly add this requirement to the - * definition before performing firmware selection */ - if (!abiUpdate && def->os.firmware) { - if (!def->os.loader) - def->os.loader = virDomainLoaderDefNew(); - if (!def->os.loader->format) - def->os.loader->format = VIR_STORAGE_FILE_RAW; - } - /* Firmware selection can fail for a number of reasons, but the * most likely one is that the requested configuration contains * mistakes or includes constraints that are impossible to -- 2.52.0
As explained in the comment that comes along with it, this code ensures that the user's preference is taken into account when nvram.format is the only information that's provided. Currently it lives in the parser, but it makes more sense for it to be together with the rest of the firmware selection code instead. Note that this move is not completely seamless: once the code is moved outside of the parser, it can no longer reliably know whether the <loader> element actually existed in the domain XML. The difference is subtle enough that the test suite is completely unaffected, and we are going to rework the handling of this scenario in a way that restores the original behavior later anyway, so it ultimately doesn't matter. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/conf/domain_conf.c | 18 +----------------- src/qemu/qemu_firmware.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 541dad5bdc..25494cb01a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -17823,24 +17823,8 @@ virDomainLoaderDefParseXMLLoader(virDomainLoaderDef *loader, { unsigned int format = 0; - if (!loaderNode) { - /* If there is no <loader> element but the <nvram> element - * was present, copy the format from the latter to the - * former. - * - * This ensures that a configuration such as - * - * <os> - * <nvram format='foo'/> - * </os> - * - * behaves as expected, that is, results in a firmware build - * with format 'foo' being selected */ - if (loader->nvram) - loader->format = loader->nvram->format; - + if (!loaderNode) return 0; - } if (virXMLPropTristateBool(loaderNode, "readonly", VIR_XML_PROP_NONE, &loader->readonly) < 0) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 6c609ece6a..a22853361b 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1783,6 +1783,21 @@ qemuFirmwareFillDomain(virQEMUDriver *driver, bool autoSelection = (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE); int ret; + /* If there is no <loader> element but the <nvram> element + * was present, copy the format from the latter to the + * former. + * + * This ensures that a configuration such as + * + * <os> + * <nvram format='foo'/> + * </os> + * + * behaves as expected, that is, results in a firmware build + * with format 'foo' being selected */ + if (loader && loader->nvram && !loader->format) + loader->format = loader->nvram->format; + /* If we're loading an existing configuration from disk, we * should try as hard as possible to preserve historical * behavior. In particular, firmware autoselection being enabled -- 2.52.0
This test case demonstrates a flaw in the XML validation process. Read/write firmare images already contain an area dedicated to variable storage, which they use, so attempting to use a separate NVRAM file together with them should have resulted in the domain XML being rejected. The issue will be addressed in an upcoming commit. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...are-manual-efi-rw-nvram.x86_64-latest.args | 37 +++++++++++++++++ ...ware-manual-efi-rw-nvram.x86_64-latest.xml | 40 +++++++++++++++++++ .../firmware-manual-efi-rw-nvram.xml | 19 +++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 97 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.xml diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args new file mode 100644 index 0000000000..6b3eec0a27 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF.combined.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-blockdev '{"driver":"file","filename":"/path/to/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ +-machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-global driver=cfi.pflash01,property=secure,value=on \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml new file mode 100644 index 0000000000..f6436df80f --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml @@ -0,0 +1,40 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <firmware> + <feature enabled='yes' name='secure-boot'/> + </firmware> + <loader readonly='no' secure='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF.combined.fd</loader> + <nvram format='raw'>/path/to/guest_VARS.fd</nvram> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <smm state='on'/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.xml b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.xml new file mode 100644 index 0000000000..81884f4913 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.xml @@ -0,0 +1,19 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader readonly='no' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF.combined.fd</loader> + <nvram format='raw'>/path/to/guest_VARS.fd</nvram> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 5fd538d26a..932d7410d2 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1534,6 +1534,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-legacy-paths"); DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-modern-paths"); DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-implicit"); + DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-nvram"); DO_TEST_CAPS_LATEST("firmware-manual-efi-loader-secure"); DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-efi-loader-no-path"); DO_TEST_CAPS_LATEST("firmware-manual-efi-loader-path-nonstandard"); -- 2.52.0
The combination doesn't make sense. After this change the firmware-manual-bios-rw test cases starts failing, as it should have in the first place. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/conf/domain_validate.c | 14 +++++++ ...are-manual-efi-rw-nvram.x86_64-latest.args | 37 ----------------- ...ware-manual-efi-rw-nvram.x86_64-latest.err | 1 + ...ware-manual-efi-rw-nvram.x86_64-latest.xml | 40 ------------------- tests/qemuxmlconftest.c | 2 +- 5 files changed, 16 insertions(+), 78 deletions(-) delete mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err delete mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 4558e7b210..09c1b3f13f 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1765,6 +1765,20 @@ virDomainDefOSValidate(const virDomainDef *def, } } + if (loader->readonly == VIR_TRISTATE_BOOL_NO) { + 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", diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args deleted file mode 100644 index 6b3eec0a27..0000000000 --- a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args +++ /dev/null @@ -1,37 +0,0 @@ -LC_ALL=C \ -PATH=/bin \ -HOME=/var/lib/libvirt/qemu/domain--1-guest \ -USER=test \ -LOGNAME=test \ -XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ -XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ -XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ -/usr/bin/qemu-system-x86_64 \ --name guest=guest,debug-threads=on \ --S \ --object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ --blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF.combined.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ --blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \ --blockdev '{"driver":"file","filename":"/path/to/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ --machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ --accel kvm \ --cpu qemu64 \ --global driver=cfi.pflash01,property=secure,value=on \ --m size=1048576k \ --object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ --overcommit mem-lock=off \ --smp 1,sockets=1,cores=1,threads=1 \ --uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ --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 \ --boot strict=on \ --audiodev '{"id":"audio1","driver":"none"}' \ --global ICH9-LPC.noreboot=off \ --watchdog-action reset \ --sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ --msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err new file mode 100644 index 0000000000..d0cf62061a --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err @@ -0,0 +1 @@ +NVRAM is not permitted when loader is read/write diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml deleted file mode 100644 index f6436df80f..0000000000 --- a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml +++ /dev/null @@ -1,40 +0,0 @@ -<domain type='kvm'> - <name>guest</name> - <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> - <memory unit='KiB'>1048576</memory> - <currentMemory unit='KiB'>1048576</currentMemory> - <vcpu placement='static'>1</vcpu> - <os firmware='efi'> - <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> - <firmware> - <feature enabled='yes' name='secure-boot'/> - </firmware> - <loader readonly='no' secure='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF.combined.fd</loader> - <nvram format='raw'>/path/to/guest_VARS.fd</nvram> - <boot dev='hd'/> - </os> - <features> - <acpi/> - <smm state='on'/> - </features> - <cpu mode='custom' match='exact' check='none'> - <model fallback='forbid'>qemu64</model> - </cpu> - <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' model='none'/> - <controller type='sata' index='0'> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> - </controller> - <controller type='pci' index='0' model='pcie-root'/> - <input type='mouse' bus='ps2'/> - <input type='keyboard' bus='ps2'/> - <audio id='1' type='none'/> - <watchdog model='itco' action='reset'/> - <memballoon model='none'/> - </devices> -</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 932d7410d2..1a9dd3b153 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1534,7 +1534,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-legacy-paths"); DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-modern-paths"); DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-implicit"); - DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-nvram"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-efi-rw-nvram"); DO_TEST_CAPS_LATEST("firmware-manual-efi-loader-secure"); DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-efi-loader-no-path"); DO_TEST_CAPS_LATEST("firmware-manual-efi-loader-path-nonstandard"); -- 2.52.0
This test cases demonstrates that the firmware autoselection process is unable to find a BIOS image that is read/write. This is expected, as BIOS is loaded as ROM and is thus by definition read-only. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- .../firmware-auto-bios-rw.x86_64-latest.err | 1 + .../firmware-auto-bios-rw.x86_64-latest.xml | 35 +++++++++++++++++++ .../qemuxmlconfdata/firmware-auto-bios-rw.xml | 18 ++++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 55 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-auto-bios-rw.x86_64-latest.err create mode 100644 tests/qemuxmlconfdata/firmware-auto-bios-rw.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-auto-bios-rw.xml diff --git a/tests/qemuxmlconfdata/firmware-auto-bios-rw.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-bios-rw.x86_64-latest.err new file mode 100644 index 0000000000..743fe27a97 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-bios-rw.x86_64-latest.err @@ -0,0 +1 @@ +operation failed: Unable to find 'bios' firmware that is compatible with the current configuration diff --git a/tests/qemuxmlconfdata/firmware-auto-bios-rw.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-bios-rw.x86_64-latest.xml new file mode 100644 index 0000000000..b8916c30d9 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-bios-rw.x86_64-latest.xml @@ -0,0 +1,35 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='bios'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader readonly='no' format='raw'/> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-auto-bios-rw.xml b/tests/qemuxmlconfdata/firmware-auto-bios-rw.xml new file mode 100644 index 0000000000..444273e9bb --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-bios-rw.xml @@ -0,0 +1,18 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os firmware='bios'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader readonly='no'/> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 1a9dd3b153..37ddda56f6 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1568,6 +1568,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-auto-bios"); DO_TEST_CAPS_LATEST("firmware-auto-bios-stateless"); + DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-bios-rw"); DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-auto-bios-not-stateless"); DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-auto-bios-nvram"); DO_TEST_CAPS_LATEST("firmware-auto-efi"); -- 2.52.0
This test case demonstrates a flaw in the XML validation process. ROM images are by definition read-only, so attempting to use one as read/write should have resulted in the domain XML being rejected. The issue will be addressed in an upcoming commit. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...firmware-manual-bios-rw.x86_64-latest.args | 32 +++++++++++++++++++ .../firmware-manual-bios-rw.x86_64-latest.xml | 28 ++++++++++++++++ .../firmware-manual-bios-rw.xml | 15 +++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 76 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.xml diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args new file mode 100644 index 0000000000..969c7ad68c --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args @@ -0,0 +1,32 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-machine pc-i440fx-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ +-accel tcg \ +-cpu qemu64 \ +-bios /usr/share/seabios/bios.bin \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml new file mode 100644 index 0000000000..65bb8493c9 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml @@ -0,0 +1,28 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-i440fx-10.0'>hvm</type> + <loader readonly='no' type='rom' format='raw'>/usr/share/seabios/bios.bin</loader> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-rw.xml b/tests/qemuxmlconfdata/firmware-manual-bios-rw.xml new file mode 100644 index 0000000000..b12aa67d1a --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-bios-rw.xml @@ -0,0 +1,15 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-i440fx-10.0'>hvm</type> + <loader readonly='no'>/usr/share/seabios/bios.bin</loader> + </os> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 37ddda56f6..f7f4aae79b 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1527,6 +1527,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-manual-bios"); DO_TEST_CAPS_LATEST("firmware-manual-bios-stateless"); DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-bios-not-stateless"); + DO_TEST_CAPS_LATEST("firmware-manual-bios-rw"); DO_TEST_CAPS_LATEST("firmware-manual-efi"); DO_TEST_CAPS_LATEST("firmware-manual-efi-features"); DO_TEST_CAPS_LATEST_ABI_UPDATE_PARSE_ERROR("firmware-manual-efi-features"); -- 2.52.0
The combination doesn't make sense. After this change the firmware-manual-bios-rw test case starts failing, as it should have in the first place. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/conf/domain_validate.c | 6 ++++ ...firmware-manual-bios-rw.x86_64-latest.args | 32 ------------------- .../firmware-manual-bios-rw.x86_64-latest.err | 1 + .../firmware-manual-bios-rw.x86_64-latest.xml | 28 ---------------- tests/qemuxmlconftest.c | 2 +- 5 files changed, 8 insertions(+), 61 deletions(-) delete mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.err delete mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 09c1b3f13f..93a54f8cc7 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1766,6 +1766,12 @@ virDomainDefOSValidate(const virDomainDef *def, } if (loader->readonly == VIR_TRISTATE_BOOL_NO) { + if (loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) { + 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")); diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args deleted file mode 100644 index 969c7ad68c..0000000000 --- a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args +++ /dev/null @@ -1,32 +0,0 @@ -LC_ALL=C \ -PATH=/bin \ -HOME=/var/lib/libvirt/qemu/domain--1-guest \ -USER=test \ -LOGNAME=test \ -XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ -XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ -XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ -/usr/bin/qemu-system-x86_64 \ --name guest=guest,debug-threads=on \ --S \ --object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ --machine pc-i440fx-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ --accel tcg \ --cpu qemu64 \ --bios /usr/share/seabios/bios.bin \ --m size=1048576k \ --object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ --overcommit mem-lock=off \ --smp 1,sockets=1,cores=1,threads=1 \ --uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ --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 \ --boot strict=on \ --audiodev '{"id":"audio1","driver":"none"}' \ --sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ --msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.err new file mode 100644 index 0000000000..13e9d7c0f1 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.err @@ -0,0 +1 @@ +ROM loader type cannot be used as read/write diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml deleted file mode 100644 index 65bb8493c9..0000000000 --- a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml +++ /dev/null @@ -1,28 +0,0 @@ -<domain type='qemu'> - <name>guest</name> - <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> - <memory unit='KiB'>1048576</memory> - <currentMemory unit='KiB'>1048576</currentMemory> - <vcpu placement='static'>1</vcpu> - <os> - <type arch='x86_64' machine='pc-i440fx-10.0'>hvm</type> - <loader readonly='no' type='rom' format='raw'>/usr/share/seabios/bios.bin</loader> - <boot dev='hd'/> - </os> - <cpu mode='custom' match='exact' check='none'> - <model fallback='forbid'>qemu64</model> - </cpu> - <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' model='none'/> - <controller type='pci' index='0' model='pci-root'/> - <input type='mouse' bus='ps2'/> - <input type='keyboard' bus='ps2'/> - <audio id='1' type='none'/> - <memballoon model='none'/> - </devices> -</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index f7f4aae79b..5f3cfe23fd 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1527,7 +1527,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-manual-bios"); DO_TEST_CAPS_LATEST("firmware-manual-bios-stateless"); DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-bios-not-stateless"); - DO_TEST_CAPS_LATEST("firmware-manual-bios-rw"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-bios-rw"); DO_TEST_CAPS_LATEST("firmware-manual-efi"); DO_TEST_CAPS_LATEST("firmware-manual-efi-features"); DO_TEST_CAPS_LATEST_ABI_UPDATE_PARSE_ERROR("firmware-manual-efi-features"); -- 2.52.0
This test case demonstrates a flaw in the XML validation process. ROM images are by definition in raw format, so attempting to use any other format should have resulted in the domain XML being rejected. The issue will be addressed in an upcoming commit. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...format-loader-qcow2-rom.x86_64-latest.args | 34 ++++++++++++++++ ...-format-loader-qcow2-rom.x86_64-latest.xml | 39 +++++++++++++++++++ ...mware-auto-efi-format-loader-qcow2-rom.xml | 18 +++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 92 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.xml diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args new file mode 100644 index 0000000000..417084d45e --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-machine pc-q35-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-bios /usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml new file mode 100644 index 0000000000..862a50ddb4 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml @@ -0,0 +1,39 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <firmware> + <feature enabled='yes' name='enrolled-keys'/> + <feature enabled='yes' name='secure-boot'/> + </firmware> + <loader type='rom' format='qcow2'>/usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd</loader> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.xml new file mode 100644 index 0000000000..abc2dc6d31 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.xml @@ -0,0 +1,18 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader type='rom' format='qcow2'/> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 5f3cfe23fd..c3bb768ecb 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1601,6 +1601,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-auto-efi-nvram-network-iscsi"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-loader-qcow2"); + DO_TEST_CAPS_LATEST("firmware-auto-efi-format-loader-qcow2-rom"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-loader-qcow2-nvram-path"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2-path"); -- 2.52.0
The combination doesn't make sense. After this change the firmware-auto-efi-format-loader-qcow2-rom test case starts failing, as it should have in the first place. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/conf/domain_validate.c | 10 +++++ ...format-loader-qcow2-rom.x86_64-latest.args | 34 ---------------- ...-format-loader-qcow2-rom.x86_64-latest.err | 1 + ...-format-loader-qcow2-rom.x86_64-latest.xml | 39 ------------------- tests/qemuxmlconftest.c | 2 +- 5 files changed, 12 insertions(+), 74 deletions(-) delete mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.err delete mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 93a54f8cc7..7346a61731 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1811,6 +1811,16 @@ virDomainDefOSValidate(const virDomainDef *def, } } + if (loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) { + if (loader->format && + loader->format != VIR_STORAGE_FILE_RAW) { + virReportError(VIR_ERR_XML_DETAIL, + _("Invalid format '%1$s' for ROM loader type"), + virStorageFileFormatTypeToString(loader->format)); + 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-efi-format-loader-qcow2-rom.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args deleted file mode 100644 index 417084d45e..0000000000 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args +++ /dev/null @@ -1,34 +0,0 @@ -LC_ALL=C \ -PATH=/bin \ -HOME=/var/lib/libvirt/qemu/domain--1-guest \ -USER=test \ -LOGNAME=test \ -XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ -XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ -XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ -/usr/bin/qemu-system-x86_64 \ --name guest=guest,debug-threads=on \ --S \ --object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ --machine pc-q35-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \ --accel kvm \ --cpu qemu64 \ --bios /usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd \ --m size=1048576k \ --object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ --overcommit mem-lock=off \ --smp 1,sockets=1,cores=1,threads=1 \ --uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ --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 \ --boot strict=on \ --audiodev '{"id":"audio1","driver":"none"}' \ --global ICH9-LPC.noreboot=off \ --watchdog-action reset \ --sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ --msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.err new file mode 100644 index 0000000000..b7b1400f6a --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.err @@ -0,0 +1 @@ +Invalid format 'qcow2' for ROM loader type diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml deleted file mode 100644 index 862a50ddb4..0000000000 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml +++ /dev/null @@ -1,39 +0,0 @@ -<domain type='kvm'> - <name>guest</name> - <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> - <memory unit='KiB'>1048576</memory> - <currentMemory unit='KiB'>1048576</currentMemory> - <vcpu placement='static'>1</vcpu> - <os firmware='efi'> - <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> - <firmware> - <feature enabled='yes' name='enrolled-keys'/> - <feature enabled='yes' name='secure-boot'/> - </firmware> - <loader type='rom' format='qcow2'>/usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd</loader> - <boot dev='hd'/> - </os> - <features> - <acpi/> - </features> - <cpu mode='custom' match='exact' check='none'> - <model fallback='forbid'>qemu64</model> - </cpu> - <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' model='none'/> - <controller type='sata' index='0'> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> - </controller> - <controller type='pci' index='0' model='pcie-root'/> - <input type='mouse' bus='ps2'/> - <input type='keyboard' bus='ps2'/> - <audio id='1' type='none'/> - <watchdog model='itco' action='reset'/> - <memballoon model='none'/> - </devices> -</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index c3bb768ecb..30235b7878 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1601,7 +1601,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-auto-efi-nvram-network-iscsi"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-loader-qcow2"); - DO_TEST_CAPS_LATEST("firmware-auto-efi-format-loader-qcow2-rom"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-auto-efi-format-loader-qcow2-rom"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-loader-qcow2-nvram-path"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2-path"); -- 2.52.0
For combined firmware builds, the variable storage is part of the same image as the executable code, whereas stateless builds don't support variable storage at all. In both cases, the use of a separate NVRAM storage area is not supported, so if attributes connected to one are present in the domain XML, firmware descriptors for stateless/combined builds should be ignored. ROM firmware builds are stateless by definition, so the same handling applies to them as well. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index a22853361b..47a3987b64 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1285,6 +1285,17 @@ qemuFirmwareMatchDomain(const virDomainDef *def, flash->nvram_template.format); return false; } + } else { + if (loader && loader->nvram && + (loader->nvram->path || loader->nvram->format)) { + VIR_DEBUG("Discarding non split loader (nvram configured)"); + return false; + } + if (loader && + (loader->nvramTemplate || loader->nvramTemplateFormat)) { + VIR_DEBUG("Discarding non split loader (nvram template configured)"); + return false; + } } } else if (fw->mapping.device == QEMU_FIRMWARE_DEVICE_MEMORY) { if (loader && loader->type && @@ -1302,6 +1313,17 @@ qemuFirmwareMatchDomain(const virDomainDef *def, VIR_DEBUG("Discarding readonly loader"); return false; } + + if (loader && loader->nvram && + (loader->nvram->path || loader->nvram->format)) { + VIR_DEBUG("Discarding rom loader (nvram configured)"); + return false; + } + if (loader && + (loader->nvramTemplate || loader->nvramTemplateFormat)) { + VIR_DEBUG("Discarding rom loader (nvram template configured)"); + return false; + } } if (def->sec) { -- 2.52.0
If this information is missing, the parsing code will consider the firmware descriptor to be invalid and matching against it will not even be attempted. So we can safely drop this redundant fallback. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 47a3987b64..9dff3828a2 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1421,14 +1421,8 @@ qemuFirmwareEnableFeaturesModern(virDomainDef *def, loader->nvramTemplateFormat = VIR_STORAGE_FILE_NONE; if (!loader->nvram || virStorageSourceIsLocalStorage(loader->nvram)) { - /* validation when parsing the JSON files ensures that we get - * only 'raw' and 'qcow2' here. Fall back to sharing format with loader */ - if (flash->nvram_template.format) - loader->nvramTemplateFormat = virStorageFileFormatTypeFromString(flash->nvram_template.format); - else - loader->nvramTemplateFormat = loader->format; - loader->nvramTemplate = g_strdup(flash->nvram_template.filename); + loader->nvramTemplateFormat = virStorageFileFormatTypeFromString(flash->nvram_template.format); } } -- 2.52.0
Similarly to how we allow the format for the loader and the NVRAM file to be specified without the corresponding path being present, we should allow that to happen for the NVRAM template too. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/conf/schemas/domaincommon.rng | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 1f9ac102a0..c7346526ef 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -354,11 +354,11 @@ <attribute name="template"> <ref name="absFilePath"/> </attribute> - <optional> - <attribute name="templateFormat"> - <ref name="pflashFormatTypes"/> - </attribute> - </optional> + </optional> + <optional> + <attribute name="templateFormat"> + <ref name="pflashFormatTypes"/> + </attribute> </optional> <optional> <ref name="pflashFormat"/> -- 2.52.0
This test case demonstrates that it's possible to associate a custom NVRAM template to a well-known firmware binary, specifying its format, and libvirt will behave correctly. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...late-nonstandard-format.x86_64-latest.args | 37 +++++++++++++++++++ ...plate-nonstandard-format.x86_64-latest.xml | 36 ++++++++++++++++++ ...-efi-nvram-template-nonstandard-format.xml | 19 ++++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 93 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.xml diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.x86_64-latest.args new file mode 100644 index 0000000000..fa0626a8f3 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE_4M.qcow2","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"qcow2","file":"libvirt-pflash0-storage","backing":null}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.qcow2","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"qcow2","file":"libvirt-pflash1-storage","backing":null}' \ +-machine pc-q35-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.x86_64-latest.xml new file mode 100644 index 0000000000..fc926db62e --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.x86_64-latest.xml @@ -0,0 +1,36 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader readonly='yes' type='pflash' format='qcow2'>/usr/share/edk2/ovmf/OVMF_CODE_4M.qcow2</loader> + <nvram template='/path/to/OVMF_VARS.qcow2' templateFormat='qcow2' format='qcow2'>/var/lib/libvirt/qemu/nvram/guest_VARS.qcow2</nvram> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.xml b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.xml new file mode 100644 index 0000000000..aa150973ec --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-format.xml @@ -0,0 +1,19 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader readonly='yes' type='pflash' format='qcow2'>/usr/share/edk2/ovmf/OVMF_CODE_4M.qcow2</loader> + <nvram template='/path/to/OVMF_VARS.qcow2' templateFormat='qcow2'/> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 30235b7878..a2eb689a64 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1545,6 +1545,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-manual-efi-stateless"); DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-template"); DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-template-nonstandard"); + DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-template-nonstandard-format"); DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-efi-nvram-template-stateless"); DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-network-iscsi"); DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-network-nbd"); -- 2.52.0
This test cases demonstrates that it's possible to use a custom NVRAM template together with a standard firmware binary even when referring to the latter by its legacy path rather than its modern, canonical one. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...onstandard-legacy-paths.x86_64-latest.args | 37 +++++++++++++++++++ ...nonstandard-legacy-paths.x86_64-latest.xml | 37 +++++++++++++++++++ ...vram-template-nonstandard-legacy-paths.xml | 20 ++++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 95 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.xml diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.x86_64-latest.args new file mode 100644 index 0000000000..18ca736065 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/OVMF/OVMF_CODE.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ +-machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ +-accel tcg \ +-cpu qemu64 \ +-global driver=cfi.pflash01,property=secure,value=on \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.x86_64-latest.xml new file mode 100644 index 0000000000..8073a042f9 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.x86_64-latest.xml @@ -0,0 +1,37 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader readonly='yes' secure='yes' type='pflash' format='raw'>/usr/share/OVMF/OVMF_CODE.fd</loader> + <nvram template='/path/to/OVMF_VARS.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <smm state='on'/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.xml b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.xml new file mode 100644 index 0000000000..f32d29c6f5 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard-legacy-paths.xml @@ -0,0 +1,20 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader readonly='yes' secure='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader> + <nvram template='/path/to/OVMF_VARS.fd'/> + </os> + <features> + <acpi/> + <smm state='on'/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index a2eb689a64..a3bf82dae3 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1546,6 +1546,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-template"); DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-template-nonstandard"); DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-template-nonstandard-format"); + DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-template-nonstandard-legacy-paths"); DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-efi-nvram-template-stateless"); DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-network-iscsi"); DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-network-nbd"); -- 2.52.0
This test case demonstrates that it's possible to explicitly select the format for the NVRAM template, and usually the firmware binary itself, by using the <nvram format='foo'/> shorthand syntax. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...at-nvram-raw.x86_64-latest.abi-update.args | 37 +++++++++++++++++ ...mat-nvram-raw.x86_64-latest.abi-update.xml | 41 +++++++++++++++++++ ...to-efi-format-nvram-raw.x86_64-latest.args | 37 +++++++++++++++++ ...uto-efi-format-nvram-raw.x86_64-latest.xml | 41 +++++++++++++++++++ .../firmware-auto-efi-format-nvram-raw.xml | 18 ++++++++ tests/qemuxmlconftest.c | 2 + 6 files changed, 176 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.abi-update.args create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.abi-update.xml create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.xml diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.abi-update.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.abi-update.args new file mode 100644 index 0000000000..e7c9110c95 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.abi-update.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ +-machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-global driver=cfi.pflash01,property=secure,value=on \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.abi-update.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.abi-update.xml new file mode 100644 index 0000000000..f4df8c07ed --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.abi-update.xml @@ -0,0 +1,41 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <firmware> + <feature enabled='yes' name='enrolled-keys'/> + <feature enabled='yes' name='secure-boot'/> + </firmware> + <loader readonly='yes' secure='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader> + <nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <smm state='on'/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.args new file mode 100644 index 0000000000..e7c9110c95 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ +-machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-global driver=cfi.pflash01,property=secure,value=on \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.xml new file mode 100644 index 0000000000..f4df8c07ed --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.x86_64-latest.xml @@ -0,0 +1,41 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <firmware> + <feature enabled='yes' name='enrolled-keys'/> + <feature enabled='yes' name='secure-boot'/> + </firmware> + <loader readonly='yes' secure='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader> + <nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <smm state='on'/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.xml new file mode 100644 index 0000000000..c293d079d0 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw.xml @@ -0,0 +1,18 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <nvram format='raw'/> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index a3bf82dae3..513064a0c7 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1608,6 +1608,8 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2-path"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2-network-nbd"); + DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-raw"); + DO_TEST_CAPS_LATEST_ABI_UPDATE("firmware-auto-efi-format-nvram-raw"); DO_TEST_CAPS_ARCH_LATEST("firmware-auto-efi-format-loader-raw", "aarch64"); DO_TEST_CAPS_ARCH_LATEST_ABI_UPDATE("firmware-auto-efi-format-loader-raw", "aarch64"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-mismatch"); -- 2.52.0
This test case demonstrates an issue with the current implementation of firmware autoselection. libvirt would normally be able to find the firmware descriptor for the binary mentioned in the domain XML, but the fact that at the same time we're asking for the NVRAM file to be of a different format throws a spanner in the works. Of course there is no requirement for the format of the NVRAM file to match that of the NVRAM template, so the fact that libvirt is unable to produce a working configuration out of this input is an issues that will be addressed in an upcoming commit. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...at-nvram-raw-loader-path.x86_64-latest.err | 1 + ...at-nvram-raw-loader-path.x86_64-latest.xml | 36 +++++++++++++++++++ ...-auto-efi-format-nvram-raw-loader-path.xml | 19 ++++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 57 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.err create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.xml diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.err new file mode 100644 index 0000000000..3edb2b3451 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.err @@ -0,0 +1 @@ +operation failed: Unable to find 'efi' firmware that is compatible with the current configuration diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.xml new file mode 100644 index 0000000000..6bb1ad1507 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.xml @@ -0,0 +1,36 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2</loader> + <nvram format='raw'/> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.xml new file mode 100644 index 0000000000..66e6910fc2 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.xml @@ -0,0 +1,19 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2</loader> + <nvram format='raw'/> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 513064a0c7..4c08a77f12 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1610,6 +1610,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2-network-nbd"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-raw"); DO_TEST_CAPS_LATEST_ABI_UPDATE("firmware-auto-efi-format-nvram-raw"); + DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-nvram-raw-loader-path"); DO_TEST_CAPS_ARCH_LATEST("firmware-auto-efi-format-loader-raw", "aarch64"); DO_TEST_CAPS_ARCH_LATEST_ABI_UPDATE("firmware-auto-efi-format-loader-raw", "aarch64"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-mismatch"); -- 2.52.0
This test case demonstrates an issue with the current implementation of firmware autoselection. There is no requirement for the format of the NVRAM file (raw in this case) to match that of the NVRAM template (qcow2 in this case), and yet libvirt incorrectly rejects the configuration. The issue will be addressed in an upcoming commit. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...m-raw-nvramtemplate-path.x86_64-latest.err | 1 + ...m-raw-nvramtemplate-path.x86_64-latest.xml | 36 +++++++++++++++++++ ...fi-format-nvram-raw-nvramtemplate-path.xml | 18 ++++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 56 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.err create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.xml diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.err new file mode 100644 index 0000000000..3edb2b3451 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.err @@ -0,0 +1 @@ +operation failed: Unable to find 'efi' firmware that is compatible with the current configuration diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.xml new file mode 100644 index 0000000000..8bb8f1b26c --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.xml @@ -0,0 +1,36 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader format='raw'/> + <nvram template='/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2' format='raw'/> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.xml new file mode 100644 index 0000000000..1e1174a11a --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.xml @@ -0,0 +1,18 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <nvram template='/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2' format='raw'/> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 4c08a77f12..d061444226 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1611,6 +1611,7 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-raw"); DO_TEST_CAPS_LATEST_ABI_UPDATE("firmware-auto-efi-format-nvram-raw"); DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-nvram-raw-loader-path"); + DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-nvram-raw-nvramtemplate-path"); DO_TEST_CAPS_ARCH_LATEST("firmware-auto-efi-format-loader-raw", "aarch64"); DO_TEST_CAPS_ARCH_LATEST_ABI_UPDATE("firmware-auto-efi-format-loader-raw", "aarch64"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-mismatch"); -- 2.52.0
This test case demonstrates an issue with the current implementation of firmware autoselection. While the test case passes, the outcome is not the desired one. The domain XML explicitly requests that the NVRAM template is in qcow2 format, and yet the selected firmware build uses the raw format for the NVRAM template instead. The issue will be addressed in an upcoming commit. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...mat-nvramtemplate-qcow2.x86_64-latest.args | 37 +++++++++++++++++ ...rmat-nvramtemplate-qcow2.x86_64-latest.xml | 41 +++++++++++++++++++ ...re-auto-efi-format-nvramtemplate-qcow2.xml | 18 ++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 97 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.xml diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args new file mode 100644 index 0000000000..e7c9110c95 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ +-machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-global driver=cfi.pflash01,property=secure,value=on \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml new file mode 100644 index 0000000000..f4df8c07ed --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml @@ -0,0 +1,41 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <firmware> + <feature enabled='yes' name='enrolled-keys'/> + <feature enabled='yes' name='secure-boot'/> + </firmware> + <loader readonly='yes' secure='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader> + <nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <smm state='on'/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.xml new file mode 100644 index 0000000000..582b2636e4 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.xml @@ -0,0 +1,18 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <nvram templateFormat='qcow2'/> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index d061444226..ea61e2025d 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1614,6 +1614,7 @@ mymain(void) DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-nvram-raw-nvramtemplate-path"); DO_TEST_CAPS_ARCH_LATEST("firmware-auto-efi-format-loader-raw", "aarch64"); DO_TEST_CAPS_ARCH_LATEST_ABI_UPDATE("firmware-auto-efi-format-loader-raw", "aarch64"); + DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvramtemplate-qcow2"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-mismatch"); /* This test passes, but the outcome is not the desired one: the -- 2.52.0
This test case demonstrates an issue with the current implementation of firmware autoselection. While the test case passes, the outcome is not the desired one. The domain XML explicitly requests that the format for the firmware excutable is raw and the format for the NVRAM template is qcow2: since there are no firmware descriptors that satisfy these requirements, this should result in a failure. Instead, the second request is simply ignored and a firmware that uses raw format NVRAM template is selected. The issue will be addressed in an upcoming commit. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...-mismatch-nvramtemplate.x86_64-latest.args | 37 +++++++++++++++++ ...t-mismatch-nvramtemplate.x86_64-latest.xml | 41 +++++++++++++++++++ ...auto-efi-format-mismatch-nvramtemplate.xml | 19 +++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 98 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.xml diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.args new file mode 100644 index 0000000000..e7c9110c95 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ +-machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-global driver=cfi.pflash01,property=secure,value=on \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.xml new file mode 100644 index 0000000000..f4df8c07ed --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.xml @@ -0,0 +1,41 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <firmware> + <feature enabled='yes' name='enrolled-keys'/> + <feature enabled='yes' name='secure-boot'/> + </firmware> + <loader readonly='yes' secure='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader> + <nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <smm state='on'/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.xml new file mode 100644 index 0000000000..4dc1ffce31 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.xml @@ -0,0 +1,19 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader format='raw'/> + <nvram templateFormat='qcow2'/> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index ea61e2025d..223310e8a2 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1616,6 +1616,7 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST_ABI_UPDATE("firmware-auto-efi-format-loader-raw", "aarch64"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvramtemplate-qcow2"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-mismatch"); + DO_TEST_CAPS_LATEST("firmware-auto-efi-format-mismatch-nvramtemplate"); /* This test passes, but the outcome is not the desired one: the * generic edk2 build gets selected instead of the AMD SEV one */ -- 2.52.0
Simple helper for the case where completely custom firmware paths are in use. It's quite trivial right now, but it will be expanded slightly in an upcoming commit. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 9dff3828a2..9b6c14701f 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1601,6 +1601,32 @@ qemuFirmwareFetchParsedConfigs(bool privileged, } +/** + * qemuFirmwareFillDomainCustom: + * @def: domain definition + * + * Fill in whatever information we can when totally custom firmware + * paths are in use. + * + * Should only be used as a fallback in case looking at the firmware + * descriptors yielded no results, and neither did going through the + * legacy list of CODE:VARS pairs. + */ +static void +qemuFirmwareFillDomainCustom(virDomainDef *def) +{ + virDomainLoaderDef *loader = def->os.loader; + + if (!loader) + return; + + if (!loader->format) + loader->format = VIR_STORAGE_FILE_RAW; + + return; +} + + /** * qemuFirmwareFillDomainLegacy: * @driver: QEMU driver @@ -1890,15 +1916,11 @@ qemuFirmwareFillDomain(virQEMUDriver *driver, if ((ret = qemuFirmwareFillDomainLegacy(driver, def)) < 0) return -1; - /* If we've gotten this far without finding a match, it - * means that we're dealing with a set of completely - * custom paths. In that case, unless the user has - * specified otherwise, we have to assume that they're in - * raw format */ if (ret == 1) { - if (loader && !loader->format) { - loader->format = VIR_STORAGE_FILE_RAW; - } + /* If we've gotten this far without finding a match, + * it means that we're dealing with a set of completely + * custom paths. We can still fill in some information */ + qemuFirmwareFillDomainCustom(def); } } else { virReportError(VIR_ERR_OPERATION_FAILED, -- 2.52.0
If an NVRAM template is used, its format should be set too. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 5 +++++ ...ware-manual-efi-loader-path-nonstandard.x86_64-latest.xml | 2 +- ...e-manual-efi-nvram-template-nonstandard.x86_64-latest.xml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 9b6c14701f..2b16d66818 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1623,6 +1623,11 @@ qemuFirmwareFillDomainCustom(virDomainDef *def) if (!loader->format) loader->format = VIR_STORAGE_FILE_RAW; + if (loader->nvramTemplate && + !loader->nvramTemplateFormat) { + loader->nvramTemplateFormat = loader->format; + } + return; } diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-loader-path-nonstandard.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-efi-loader-path-nonstandard.x86_64-latest.xml index c17834b5e6..7baf6ebd40 100644 --- a/tests/qemuxmlconfdata/firmware-manual-efi-loader-path-nonstandard.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/firmware-manual-efi-loader-path-nonstandard.x86_64-latest.xml @@ -7,7 +7,7 @@ <os> <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> <loader readonly='yes' type='pflash' format='raw'>/path/to/OVMF_CODE.fd</loader> - <nvram template='/path/to/OVMF_VARS.fd' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <nvram template='/path/to/OVMF_VARS.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> <boot dev='hd'/> </os> <features> diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard.x86_64-latest.xml index cbadd0f0c8..beb146d35a 100644 --- a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-nonstandard.x86_64-latest.xml @@ -7,7 +7,7 @@ <os> <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> <loader readonly='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF_CODE.fd</loader> - <nvram template='/path/to/OVMF_VARS.fd' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <nvram template='/path/to/OVMF_VARS.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> <boot dev='hd'/> </os> <features> -- 2.52.0
Currently we're doing a weird dance to avoid overwriting the user-provided path to the NVRAM template, which might potentially be one we actually know about but just so happens not to be listed first. Explaining why we're doing things this way requires a fairly long comment. We can make things simpler: if the NVRAM template path is present in the domain XML, include it into the matching criteria. This is consistent with how we match firmware descriptors. Handling of format, both for the firmware executable and the NVRAM template, is improved too. Legacy paths were used before non-raw firmware builds existed, so we can set the format to raw unconditionally. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 65 +++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 2b16d66818..a7bb8f7e45 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1653,6 +1653,7 @@ qemuFirmwareFillDomainLegacy(virQEMUDriver *driver, { g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); virDomainLoaderDef *loader = def->os.loader; + virFirmware *theone = NULL; size_t i; if (!loader) @@ -1681,6 +1682,13 @@ qemuFirmwareFillDomainLegacy(virQEMUDriver *driver, return 1; } + if (loader->nvramTemplateFormat && + loader->nvramTemplateFormat != VIR_STORAGE_FILE_RAW) { + VIR_DEBUG("Ignoring legacy entries for loader with nvram template format '%s'", + virStorageFileFormatTypeToString(loader->nvramTemplateFormat)); + return 1; + } + for (i = 0; i < cfg->nfirmwares; i++) { virFirmware *fw = cfg->firmwares[i]; @@ -1690,47 +1698,34 @@ qemuFirmwareFillDomainLegacy(virQEMUDriver *driver, continue; } - loader->type = VIR_DOMAIN_LOADER_TYPE_PFLASH; - loader->readonly = VIR_TRISTATE_BOOL_YES; - loader->format = VIR_STORAGE_FILE_RAW; - - /* Only use the default template path if one hasn't been - * provided by the user. Assume that the template is in 'raw' format. - * - * In addition to fully-custom templates, which are a valid - * use case, we could simply be in a situation where - * qemu.conf contains - * - * nvram = [ - * "/path/to/OVMF_CODE.secboot.fd:/path/to/OVMF_VARS.fd", - * "/path/to/OVMF_CODE.secboot.fd:/path/to/OVMF_VARS.secboot.fd" - * ] - * - * and the domain has been configured as - * - * <os> - * <loader readonly='yes' type='pflash'>/path/to/OVMF_CODE.secboot.fd</loader> - * <nvram template='/path/to/OVMF/OVMF_VARS.secboot.fd'> - * </os> - * - * In this case, the global default is to have Secure Boot - * disabled, but the domain configuration explicitly enables - * it, and we shouldn't overrule this choice */ - if (!loader->nvramTemplate) { - loader->nvramTemplate = g_strdup(cfg->firmwares[i]->nvram); - loader->nvramTemplateFormat = VIR_STORAGE_FILE_RAW; + if (loader->nvramTemplate && + !virFileComparePaths(fw->nvram, loader->nvramTemplate)) { + VIR_DEBUG("Not matching nvram template path '%s' for user provided path '%s'", + fw->nvram, loader->nvramTemplate); + continue; } - if (loader->nvramTemplateFormat == VIR_STORAGE_FILE_NONE) - loader->nvramTemplateFormat = VIR_STORAGE_FILE_RAW; + theone = fw; + break; + } - VIR_DEBUG("decided on firmware '%s' template '%s'", - loader->path, NULLSTR(loader->nvramTemplate)); + if (!theone) + return 1; - return 0; + loader->type = VIR_DOMAIN_LOADER_TYPE_PFLASH; + loader->readonly = VIR_TRISTATE_BOOL_YES; + + loader->format = VIR_STORAGE_FILE_RAW; + loader->nvramTemplateFormat = VIR_STORAGE_FILE_RAW; + + if (!loader->nvramTemplate) { + loader->nvramTemplate = g_strdup(theone->nvram); } - return 1; + VIR_DEBUG("decided on firmware '%s' template '%s'", + loader->path, loader->nvramTemplate); + + return 0; } -- 2.52.0
Instead of setting the format every single time, knowing that we might throw away the entire definition immediately afterwards, and duplicating a check, only set it if we are going to perform an early return due to the rest of the definition being properly filled in already. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index a7bb8f7e45..f32e46cc8c 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -985,15 +985,16 @@ qemuFirmwareEnsureNVRAM(virDomainDef *def, if (loader->stateless == VIR_TRISTATE_BOOL_YES) return; - /* If the NVRAM format hasn't been set yet, inherit the same as - * the loader */ - if (loader->nvram && !loader->nvram->format) - loader->nvram->format = loader->format; - if (loader->nvram) { - /* Nothing to do if a proper NVRAM backend is already configured */ - if (!virStorageSourceIsEmpty(loader->nvram)) + /* If a proper NVRAM backend is already configured, we are + * done for the most part. We might still need to set the + * NVRAM format if that's missing though */ + if (!virStorageSourceIsEmpty(loader->nvram)) { + if (!loader->nvram->format) { + loader->nvram->format = loader->format; + } return; + } /* otherwise we want to reset and re-populate the definition */ virObjectUnref(loader->nvram); -- 2.52.0
In the vast majority of cases they will match, but it just makes more logical sense to copy the format from the NVRAM template to the NVRAM file itself. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index f32e46cc8c..b08fb95585 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -991,7 +991,10 @@ qemuFirmwareEnsureNVRAM(virDomainDef *def, * NVRAM format if that's missing though */ if (!virStorageSourceIsEmpty(loader->nvram)) { if (!loader->nvram->format) { - loader->nvram->format = loader->format; + if (loader->nvramTemplateFormat) + loader->nvram->format = loader->nvramTemplateFormat; + else + loader->nvram->format = loader->format; } return; } -- 2.52.0
Right now we throw the entire definition away if the path is not present, including the format. This effectively results in discarding user-provided information. This change fixes the firmware-auto-efi-format-mismatch test case. Until now, the NVRAM format ended up being raw (matching the NVRAM template) despite the user explicitly asking for it to be qcow2 instead. While this means that libvirt will no longer be able to start such a VM without user intervention, since it does not automatically perform conversion between formats, that's still preferrable to silently overriding an explicit user's request. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 18 +++++++++++++----- ...auto-efi-format-mismatch.x86_64-latest.args | 5 +++-- ...-auto-efi-format-mismatch.x86_64-latest.xml | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index b08fb95585..dca0a79868 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -971,6 +971,7 @@ qemuFirmwareEnsureNVRAM(virDomainDef *def, { g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); virDomainLoaderDef *loader = def->os.loader; + virStorageFileFormat nvramFormat = VIR_STORAGE_FILE_NONE; const char *ext = NULL; if (!loader) @@ -999,19 +1000,26 @@ qemuFirmwareEnsureNVRAM(virDomainDef *def, return; } - /* otherwise we want to reset and re-populate the definition */ + /* Otherwise we want to reset and re-populate the definition. + * In this case we still retain a single piece of information: + * the user-provided NVRAM format */ + nvramFormat = loader->nvram->format; + virObjectUnref(loader->nvram); } loader->nvram = virStorageSourceNew(); loader->nvram->type = VIR_STORAGE_TYPE_FILE; + loader->nvram->format = nvramFormat; /* The nvram template format should be always present but as a failsafe, * duplicate the loader format if it is not available. */ - if (loader->nvramTemplateFormat > VIR_STORAGE_FILE_NONE) - loader->nvram->format = loader->nvramTemplateFormat; - else - loader->nvram->format = loader->format; + if (!loader->nvram->format) { + if (loader->nvramTemplateFormat) + loader->nvram->format = loader->nvramTemplateFormat; + else + loader->nvram->format = loader->format; + } if (loader->nvram->format == VIR_STORAGE_FILE_RAW) { /* The extension used by raw edk2 builds has historically diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch.x86_64-latest.args index e7c9110c95..468d7ee048 100644 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch.x86_64-latest.args +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch.x86_64-latest.args @@ -12,8 +12,9 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ -blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ --blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ --machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.qcow2","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"qcow2","file":"libvirt-pflash1-storage","backing":null}' \ +-machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,acpi=on \ -accel kvm \ -cpu qemu64 \ -global driver=cfi.pflash01,property=secure,value=on \ diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch.x86_64-latest.xml index f4df8c07ed..3a7536db2a 100644 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch.x86_64-latest.xml @@ -11,7 +11,7 @@ <feature enabled='yes' name='secure-boot'/> </firmware> <loader readonly='yes' secure='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader> - <nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd' templateFormat='raw' format='qcow2'>/var/lib/libvirt/qemu/nvram/guest_VARS.qcow2</nvram> <boot dev='hd'/> </os> <features> -- 2.52.0
If the user has specified a desired format for the NVRAM template, we should take that information into account when looking for a suitable firmware build instead of ignoring it. Two test cases start failing as a result of this change. For firmware-auto-efi-format-nvramtemplate-qcow2, the failure is temporary and the test case will pass once again with an upcoming commit. It should be noted that, until now, the selected firmware used raw, not qcow2, as the NVRAM template format, meaning that though the test case passed the outcome was not the desired one. For firmware-auto-efi-format-mismatch-nvramtemplate, the failure is desired and the test case should not have succeeded in the first place, as there are no firmware descriptors for a build that uses raw format for the executable and qcow2 format for the NVRAM template. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 7 ++++ ...-mismatch-nvramtemplate.x86_64-latest.args | 37 ------------------- ...t-mismatch-nvramtemplate.x86_64-latest.err | 1 + ...t-mismatch-nvramtemplate.x86_64-latest.xml | 9 +---- ...mat-nvramtemplate-qcow2.x86_64-latest.args | 37 ------------------- ...rmat-nvramtemplate-qcow2.x86_64-latest.err | 1 + ...rmat-nvramtemplate-qcow2.x86_64-latest.xml | 9 +---- tests/qemuxmlconftest.c | 4 +- 8 files changed, 15 insertions(+), 90 deletions(-) delete mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.err delete mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.err diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index dca0a79868..e13cce0887 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1297,6 +1297,13 @@ qemuFirmwareMatchDomain(const virDomainDef *def, flash->nvram_template.format); return false; } + if (loader && loader->nvramTemplateFormat && + STRNEQ(flash->nvram_template.format, virStorageFileFormatTypeToString(loader->nvramTemplateFormat))) { + VIR_DEBUG("Discarding loader with mismatching nvram template format '%s' != '%s'", + flash->nvram_template.format, + virStorageFileFormatTypeToString(loader->nvramTemplateFormat)); + return false; + } } else { if (loader && loader->nvram && (loader->nvram->path || loader->nvram->format)) { diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.args deleted file mode 100644 index e7c9110c95..0000000000 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.args +++ /dev/null @@ -1,37 +0,0 @@ -LC_ALL=C \ -PATH=/bin \ -HOME=/var/lib/libvirt/qemu/domain--1-guest \ -USER=test \ -LOGNAME=test \ -XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ -XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ -XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ -/usr/bin/qemu-system-x86_64 \ --name guest=guest,debug-threads=on \ --S \ --object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ --blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ --blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ --blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ --machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ --accel kvm \ --cpu qemu64 \ --global driver=cfi.pflash01,property=secure,value=on \ --m size=1048576k \ --object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ --overcommit mem-lock=off \ --smp 1,sockets=1,cores=1,threads=1 \ --uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ --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 \ --boot strict=on \ --audiodev '{"id":"audio1","driver":"none"}' \ --global ICH9-LPC.noreboot=off \ --watchdog-action reset \ --sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ --msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.err new file mode 100644 index 0000000000..3edb2b3451 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.err @@ -0,0 +1 @@ +operation failed: Unable to find 'efi' firmware that is compatible with the current configuration diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.xml index f4df8c07ed..1f039061ba 100644 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-mismatch-nvramtemplate.x86_64-latest.xml @@ -6,17 +6,12 @@ <vcpu placement='static'>1</vcpu> <os firmware='efi'> <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> - <firmware> - <feature enabled='yes' name='enrolled-keys'/> - <feature enabled='yes' name='secure-boot'/> - </firmware> - <loader readonly='yes' secure='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader> - <nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <loader format='raw'/> + <nvram templateFormat='qcow2'/> <boot dev='hd'/> </os> <features> <acpi/> - <smm state='on'/> </features> <cpu mode='custom' match='exact' check='none'> <model fallback='forbid'>qemu64</model> diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args deleted file mode 100644 index e7c9110c95..0000000000 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args +++ /dev/null @@ -1,37 +0,0 @@ -LC_ALL=C \ -PATH=/bin \ -HOME=/var/lib/libvirt/qemu/domain--1-guest \ -USER=test \ -LOGNAME=test \ -XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ -XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ -XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ -/usr/bin/qemu-system-x86_64 \ --name guest=guest,debug-threads=on \ --S \ --object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ --blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ --blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ --blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ --machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ --accel kvm \ --cpu qemu64 \ --global driver=cfi.pflash01,property=secure,value=on \ --m size=1048576k \ --object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ --overcommit mem-lock=off \ --smp 1,sockets=1,cores=1,threads=1 \ --uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ --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 \ --boot strict=on \ --audiodev '{"id":"audio1","driver":"none"}' \ --global ICH9-LPC.noreboot=off \ --watchdog-action reset \ --sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ --msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.err new file mode 100644 index 0000000000..3edb2b3451 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.err @@ -0,0 +1 @@ +operation failed: Unable to find 'efi' firmware that is compatible with the current configuration diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml index f4df8c07ed..1f039061ba 100644 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml @@ -6,17 +6,12 @@ <vcpu placement='static'>1</vcpu> <os firmware='efi'> <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> - <firmware> - <feature enabled='yes' name='enrolled-keys'/> - <feature enabled='yes' name='secure-boot'/> - </firmware> - <loader readonly='yes' secure='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader> - <nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> + <loader format='raw'/> + <nvram templateFormat='qcow2'/> <boot dev='hd'/> </os> <features> <acpi/> - <smm state='on'/> </features> <cpu mode='custom' match='exact' check='none'> <model fallback='forbid'>qemu64</model> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 223310e8a2..75db051e32 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1614,9 +1614,9 @@ mymain(void) DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-nvram-raw-nvramtemplate-path"); DO_TEST_CAPS_ARCH_LATEST("firmware-auto-efi-format-loader-raw", "aarch64"); DO_TEST_CAPS_ARCH_LATEST_ABI_UPDATE("firmware-auto-efi-format-loader-raw", "aarch64"); - DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvramtemplate-qcow2"); + DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-nvramtemplate-qcow2"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-mismatch"); - DO_TEST_CAPS_LATEST("firmware-auto-efi-format-mismatch-nvramtemplate"); + DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-mismatch-nvramtemplate"); /* This test passes, but the outcome is not the desired one: the * generic edk2 build gets selected instead of the AMD SEV one */ -- 2.52.0
Commit d3016e47be5f removed a hunk very similar to the one we're adding with the rationale that there is no actual requirement for the NVRAM file and the NVRAM template to have the same format, which is completely correct: while libvirt will not perform the format conversion itself, the user can do that on their own and everything (except RESET_NVRAM) will work just fine. That said, we also need <nvram format='foo'/> specified on its own with no <loader> element to result in a firmware build with a foo-formatted NVRAM template to be picked. Right now this works thanks to the hack at the top of qemuFirmwareFillDomain() which copies nvram.format to loader.format, but we want to get rid of that because it has additional side effects that can lead to confusing outcomes in certain specific scenarios. So reintroduce this check, but make it extremely narrow: if any other information that can influence firmware selection is present in the domain XML, ignore the NVRAM format entirely; if however the NVRAM format is the only information that was provided, consider it when looking for a match. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index e13cce0887..8714538ba3 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1304,6 +1304,21 @@ qemuFirmwareMatchDomain(const virDomainDef *def, virStorageFileFormatTypeToString(loader->nvramTemplateFormat)); return false; } + /* If nvram.format was specified and no other information + * that can influence firmware selection was, then treat it + * the same as if nvram.templateFormat had been specified. + * This ensures that <nvram format='foo'/> continues to work + * as a shorthand while not getting in the way otherwise */ + if (loader && loader->nvram && loader->nvram->format && + !loader->readonly && !loader->type && !loader->secure && + !loader->stateless && !loader->format && !loader->path && + !loader->nvramTemplateFormat && !loader->nvramTemplate && + STRNEQ(flash->nvram_template.format, virStorageFileFormatTypeToString(loader->nvram->format))) { + VIR_DEBUG("Discarding loader with mismatching nvram template format '%s' != '%s'", + flash->nvram_template.format, + virStorageFileFormatTypeToString(loader->nvram->format)); + return false; + } } else { if (loader && loader->nvram && (loader->nvram->path || loader->nvram->format)) { -- 2.52.0
Now that the hack is gone, a few test cases that were failing before start succeeding instead. The firmware-auto-efi-format-nvramtemplate-qcow2 test case originally passed but produced wrong results, then started failing once we began taking templateFormat into account, and now passes once again, finally producing the correct results. The firmware-auto-efi-format-nvram-raw-loader-path and firmware-auto-efi-format-nvram-raw-nvramtemplate-path test cases, on the other hand, never passed before now, because the hack resulted in information contradicting those provided by the user being injected into the configuration, which in turn made it impossible to successfully pick a firmware build. With the hack gone they can finally succeed, as they should have in the first place. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 19 ++-------- ...t-nvram-raw-loader-path.x86_64-latest.args | 37 ++++++++++++++++++ ...at-nvram-raw-loader-path.x86_64-latest.err | 1 - ...at-nvram-raw-loader-path.x86_64-latest.xml | 9 ++++- ...-raw-nvramtemplate-path.x86_64-latest.args | 37 ++++++++++++++++++ ...m-raw-nvramtemplate-path.x86_64-latest.err | 1 - ...m-raw-nvramtemplate-path.x86_64-latest.xml | 9 ++++- ...mat-nvramtemplate-qcow2.x86_64-latest.args | 38 +++++++++++++++++++ ...rmat-nvramtemplate-qcow2.x86_64-latest.err | 1 - ...rmat-nvramtemplate-qcow2.x86_64-latest.xml | 9 ++++- tests/qemuxmlconftest.c | 6 +-- 11 files changed, 139 insertions(+), 28 deletions(-) create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.args delete mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.err create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.args delete mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.err create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args delete mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.err diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 8714538ba3..70ac88c373 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1859,21 +1859,6 @@ qemuFirmwareFillDomain(virQEMUDriver *driver, bool autoSelection = (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE); int ret; - /* If there is no <loader> element but the <nvram> element - * was present, copy the format from the latter to the - * former. - * - * This ensures that a configuration such as - * - * <os> - * <nvram format='foo'/> - * </os> - * - * behaves as expected, that is, results in a firmware build - * with format 'foo' being selected */ - if (loader && loader->nvram && !loader->format) - loader->format = loader->nvram->format; - /* If we're loading an existing configuration from disk, we * should try as hard as possible to preserve historical * behavior. In particular, firmware autoselection being enabled @@ -1889,7 +1874,9 @@ qemuFirmwareFillDomain(virQEMUDriver *driver, def->os.loader = virDomainLoaderDefNew(); loader = def->os.loader; } - if (!loader->format) { + if (!loader->format && + !loader->nvramTemplateFormat && + (!loader->nvram || !loader->nvram->format)) { loader->format = VIR_STORAGE_FILE_RAW; } } diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.args new file mode 100644 index 0000000000..14027c21db --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"qcow2","file":"libvirt-pflash0-storage","backing":null}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ +-machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-global driver=cfi.pflash01,property=secure,value=on \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.err deleted file mode 100644 index 3edb2b3451..0000000000 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.err +++ /dev/null @@ -1 +0,0 @@ -operation failed: Unable to find 'efi' firmware that is compatible with the current configuration diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.xml index 6bb1ad1507..a02714d7b9 100644 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-loader-path.x86_64-latest.xml @@ -6,12 +6,17 @@ <vcpu placement='static'>1</vcpu> <os firmware='efi'> <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> - <loader type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2</loader> - <nvram format='raw'/> + <firmware> + <feature enabled='yes' name='enrolled-keys'/> + <feature enabled='yes' name='secure-boot'/> + </firmware> + <loader readonly='yes' secure='yes' type='pflash' format='qcow2'>/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2</loader> + <nvram template='/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2' templateFormat='qcow2' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> <boot dev='hd'/> </os> <features> <acpi/> + <smm state='on'/> </features> <cpu mode='custom' match='exact' check='none'> <model fallback='forbid'>qemu64</model> diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.args new file mode 100644 index 0000000000..14027c21db --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"qcow2","file":"libvirt-pflash0-storage","backing":null}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \ +-machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-global driver=cfi.pflash01,property=secure,value=on \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.err deleted file mode 100644 index 3edb2b3451..0000000000 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.err +++ /dev/null @@ -1 +0,0 @@ -operation failed: Unable to find 'efi' firmware that is compatible with the current configuration diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.xml index 8bb8f1b26c..a02714d7b9 100644 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvram-raw-nvramtemplate-path.x86_64-latest.xml @@ -6,12 +6,17 @@ <vcpu placement='static'>1</vcpu> <os firmware='efi'> <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> - <loader format='raw'/> - <nvram template='/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2' format='raw'/> + <firmware> + <feature enabled='yes' name='enrolled-keys'/> + <feature enabled='yes' name='secure-boot'/> + </firmware> + <loader readonly='yes' secure='yes' type='pflash' format='qcow2'>/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2</loader> + <nvram template='/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2' templateFormat='qcow2' format='raw'>/var/lib/libvirt/qemu/nvram/guest_VARS.fd</nvram> <boot dev='hd'/> </os> <features> <acpi/> + <smm state='on'/> </features> <cpu mode='custom' match='exact' check='none'> <model fallback='forbid'>qemu64</model> diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args new file mode 100644 index 0000000000..468ad4326c --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.args @@ -0,0 +1,38 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"qcow2","file":"libvirt-pflash0-storage","backing":null}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/guest_VARS.qcow2","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"qcow2","file":"libvirt-pflash1-storage","backing":null}' \ +-machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-global driver=cfi.pflash01,property=secure,value=on \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.err deleted file mode 100644 index 3edb2b3451..0000000000 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.err +++ /dev/null @@ -1 +0,0 @@ -operation failed: Unable to find 'efi' firmware that is compatible with the current configuration diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml index 1f039061ba..4061a0ae35 100644 --- a/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-nvramtemplate-qcow2.x86_64-latest.xml @@ -6,12 +6,17 @@ <vcpu placement='static'>1</vcpu> <os firmware='efi'> <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> - <loader format='raw'/> - <nvram templateFormat='qcow2'/> + <firmware> + <feature enabled='yes' name='enrolled-keys'/> + <feature enabled='yes' name='secure-boot'/> + </firmware> + <loader readonly='yes' secure='yes' type='pflash' format='qcow2'>/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2</loader> + <nvram template='/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2' templateFormat='qcow2' format='qcow2'>/var/lib/libvirt/qemu/nvram/guest_VARS.qcow2</nvram> <boot dev='hd'/> </os> <features> <acpi/> + <smm state='on'/> </features> <cpu mode='custom' match='exact' check='none'> <model fallback='forbid'>qemu64</model> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 75db051e32..a87863410f 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1610,11 +1610,11 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2-network-nbd"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-raw"); DO_TEST_CAPS_LATEST_ABI_UPDATE("firmware-auto-efi-format-nvram-raw"); - DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-nvram-raw-loader-path"); - DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-nvram-raw-nvramtemplate-path"); + DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-raw-loader-path"); + DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-raw-nvramtemplate-path"); DO_TEST_CAPS_ARCH_LATEST("firmware-auto-efi-format-loader-raw", "aarch64"); DO_TEST_CAPS_ARCH_LATEST_ABI_UPDATE("firmware-auto-efi-format-loader-raw", "aarch64"); - DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-nvramtemplate-qcow2"); + DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvramtemplate-qcow2"); DO_TEST_CAPS_LATEST("firmware-auto-efi-format-mismatch"); DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-efi-format-mismatch-nvramtemplate"); -- 2.52.0
This test cases demonstrates that firmware selection runs for domains manually configured to use the AMD SEV build of edk2, and that the missing information (firmware features, as well as the fact that firmware type is EFI) are correctly filled in. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...nual-efi-sev-snp.x86_64-latest+amdsev.args | 36 ++++++++++++++++ ...anual-efi-sev-snp.x86_64-latest+amdsev.xml | 42 +++++++++++++++++++ .../firmware-manual-efi-sev-snp.xml | 21 ++++++++++ tests/qemuxmlconftest.c | 4 ++ 4 files changed, 103 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.x86_64-latest+amdsev.args create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.x86_64-latest+amdsev.xml create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.xml diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.x86_64-latest+amdsev.args b/tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.x86_64-latest+amdsev.args new file mode 100644 index 0000000000..99350f600c --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.x86_64-latest+amdsev.args @@ -0,0 +1,36 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF.amdsev.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-machine pc-q35-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,confidential-guest-support=lsec0,pflash0=libvirt-pflash0-format,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-object '{"qom-type":"sev-snp-guest","id":"lsec0","cbitpos":51,"reduced-phys-bits":1,"policy":196608}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.x86_64-latest+amdsev.xml b/tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.x86_64-latest+amdsev.xml new file mode 100644 index 0000000000..6ea58f3361 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.x86_64-latest+amdsev.xml @@ -0,0 +1,42 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <firmware> + <feature enabled='no' name='enrolled-keys'/> + <feature enabled='no' name='secure-boot'/> + </firmware> + <loader readonly='yes' type='pflash' stateless='yes' format='raw'>/usr/share/edk2/ovmf/OVMF.amdsev.fd</loader> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> + <launchSecurity type='sev-snp'> + <policy>0x00030000</policy> + </launchSecurity> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.xml b/tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.xml new file mode 100644 index 0000000000..b52900406c --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-sev-snp.xml @@ -0,0 +1,21 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF.amdsev.fd</loader> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='none'/> + <memballoon model='none'/> + </devices> + <launchSecurity type='sev-snp'> + <policy>0x00030000</policy> + </launchSecurity> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index a87863410f..61fd4b5c3e 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1553,6 +1553,10 @@ mymain(void) DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-file"); DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-efi-nvram-stateless"); + DO_TEST_CAPS_ARCH_LATEST_FULL("firmware-manual-efi-sev-snp", "x86_64", + ARG_CAPS_VARIANT, "+amdsev", + ARG_END); + /* Make sure all combinations of ACPI and UEFI behave as expected */ DO_TEST_CAPS_ARCH_LATEST("firmware-manual-efi-acpi-aarch64", "aarch64"); DO_TEST_CAPS_LATEST("firmware-manual-efi-acpi-q35"); -- 2.52.0
This test case demonstrates that firmware selection does not run for domains manually configured to use the Intel TDX build of edk2, and as a result some expected information is missing; in particular, the fact that the firmware type is EFI is not reflected in the domain XML. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- ...manual-efi-tdx.x86_64-latest+inteltdx.args | 34 +++++++++++++++ ...-manual-efi-tdx.x86_64-latest+inteltdx.xml | 42 +++++++++++++++++++ .../firmware-manual-efi-tdx.xml | 25 +++++++++++ tests/qemuxmlconftest.c | 3 ++ 4 files changed, 104 insertions(+) create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.args create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-tdx.xml diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.args b/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.args new file mode 100644 index 0000000000..33a73bfc10 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +-machine pc-q35-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,confidential-guest-support=lsec0,acpi=on \ +-accel kvm \ +-cpu qemu64 \ +-bios /usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ +-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 \ +-boot strict=on \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-object '{"qom-type":"tdx-guest","id":"lsec0","mrconfigid":"ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v","mrowner":"ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v","mrownerconfig":"ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v","quote-generation-socket":{"type":"unix","path":"/var/run/tdx-qgs/qgs.socket"},"attributes":268435456}' \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml b/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml new file mode 100644 index 0000000000..7428a3dfef --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml @@ -0,0 +1,42 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader readonly='yes' type='rom'>/usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd</loader> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <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' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='none'/> + </devices> + <launchSecurity type='tdx'> + <policy>0x10000000</policy> + <mrConfigId>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrConfigId> + <mrOwner>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrOwner> + <mrOwnerConfig>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrOwnerConfig> + <quoteGenerationService path='/var/run/tdx-qgs/qgs.socket'/> + </launchSecurity> +</domain> diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-tdx.xml b/tests/qemuxmlconfdata/firmware-manual-efi-tdx.xml new file mode 100644 index 0000000000..ee9d63c5fe --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-manual-efi-tdx.xml @@ -0,0 +1,25 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <loader readonly='yes' type='rom'>/usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd</loader> + </os> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='none'/> + <memballoon model='none'/> + </devices> + <launchSecurity type='tdx'> + <policy>0x10000000</policy> + <mrConfigId>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrConfigId> + <mrOwner>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrOwner> + <mrOwnerConfig>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrOwnerConfig> + <quoteGenerationService path='/var/run/tdx-qgs/qgs.socket'/> + </launchSecurity> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 61fd4b5c3e..89b8ad1a35 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -1556,6 +1556,9 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST_FULL("firmware-manual-efi-sev-snp", "x86_64", ARG_CAPS_VARIANT, "+amdsev", ARG_END); + DO_TEST_CAPS_ARCH_LATEST_FULL("firmware-manual-efi-tdx", "x86_64", + ARG_CAPS_VARIANT, "+inteltdx", + ARG_END); /* Make sure all combinations of ACPI and UEFI behave as expected */ DO_TEST_CAPS_ARCH_LATEST("firmware-manual-efi-acpi-aarch64", "aarch64"); -- 2.52.0
By definition. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 70ac88c373..9ba5d899fa 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1470,6 +1470,7 @@ qemuFirmwareEnableFeaturesModern(virDomainDef *def, loader = def->os.loader; loader->type = VIR_DOMAIN_LOADER_TYPE_ROM; + loader->format = VIR_STORAGE_FILE_RAW; VIR_FREE(loader->path); loader->path = g_strdup(memory->filename); -- 2.52.0
It's possible to have firmware descriptors for builds intended to be loaded as ROM, as is the case for those loaded as pflash. There is no reason to skip firmware autoselection in those cases, and doing so prevents useful information from being filled in. After this change, the firmware-manual-efi-tdx test case is augmented with some additional information. Even more information will be filled in later, when we improve the matching logic. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 10 ++++------ .../firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 9ba5d899fa..7953b297bc 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1913,13 +1913,11 @@ qemuFirmwareFillDomain(virQEMUDriver *driver, return -1; } - /* If firmware autoselection is disabled and the loader is a ROM - * instead of a PFLASH device, then we're using BIOS and we don't - * need any information at all */ - if (!autoSelection && - (!loader || (loader && loader->type == VIR_DOMAIN_LOADER_TYPE_ROM))) { + /* If firmware autoselection is disabled and no information + * related to the loader was provided, then we're using the + * default built-in firmware and we can stop here */ + if (!autoSelection && !loader) return 0; - } /* Look for the information we need in firmware descriptors */ if ((ret = qemuFirmwareFillDomainModern(driver, def)) < 0) diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml b/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml index 7428a3dfef..cdb92dcf1d 100644 --- a/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml +++ b/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml @@ -6,7 +6,7 @@ <vcpu placement='static'>1</vcpu> <os> <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> - <loader readonly='yes' type='rom'>/usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd</loader> + <loader readonly='yes' type='rom' format='raw'>/usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd</loader> <boot dev='hd'/> </os> <features> -- 2.52.0
Currently we apply a 1:1 mapping between loader type and firmware type: ROM can only match BIOS and pflash can only match UEFI. That was accurate at the time when the check was introduced, but is no longer the case today: the Intel TDX build of edk2, for example, is loaded as a ROM but it still provides an UEFI implementation to the guest. Tweak the matching logic so that a ROM loader is allowed to match both BIOS and UEFI firmware descriptors. The firmware-manual-efi-tdx test case benefits from this change, as all the missing information is now correctly filled in. This will also solve an issue reported to the list, where firmware builds targeting the confidential VM use case on aarch64 would not be usable at all, due to the way UEFI and ACPI are depending on each other on the architecture. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_firmware.c | 43 +++++++++++-------- ...-manual-efi-tdx.x86_64-latest+inteltdx.xml | 6 ++- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 7953b297bc..52205b72f8 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -937,23 +937,6 @@ qemuFirmwareOSInterfaceTypeToOsDefFirmware(qemuFirmwareOSInterface interface) } -static qemuFirmwareOSInterface -qemuFirmwareOSInterfaceTypeFromOsDefLoaderType(virDomainLoader type) -{ - switch (type) { - case VIR_DOMAIN_LOADER_TYPE_ROM: - return QEMU_FIRMWARE_OS_INTERFACE_BIOS; - case VIR_DOMAIN_LOADER_TYPE_PFLASH: - return QEMU_FIRMWARE_OS_INTERFACE_UEFI; - case VIR_DOMAIN_LOADER_TYPE_NONE: - case VIR_DOMAIN_LOADER_TYPE_LAST: - break; - } - - return QEMU_FIRMWARE_OS_INTERFACE_NONE; -} - - /** * qemuFirmwareEnsureNVRAM: * @def: domain definition @@ -1100,6 +1083,8 @@ qemuFirmwareMatchDomain(const virDomainDef *def, const virDomainLoaderDef *loader = def->os.loader; size_t i; qemuFirmwareOSInterface want; + bool wantUEFI = false; + bool wantBIOS = false; bool supportsS3 = false; bool supportsS4 = false; bool requiresSMM = false; @@ -1115,12 +1100,34 @@ qemuFirmwareMatchDomain(const virDomainDef *def, want = qemuFirmwareOSInterfaceTypeFromOsDefFirmware(def->os.firmware); if (want == QEMU_FIRMWARE_OS_INTERFACE_NONE && loader) { - want = qemuFirmwareOSInterfaceTypeFromOsDefLoaderType(loader->type); + /* If an explicit request for a specific type of firmware is + * not present, we can still infer this information from + * other factors. Specifically, the pflash loader type is + * only used for UEFI, while the rom loader type can be used + * both for UEFI and BIOS */ + switch (loader->type) { + case VIR_DOMAIN_LOADER_TYPE_PFLASH: + wantUEFI = true; + break; + case VIR_DOMAIN_LOADER_TYPE_ROM: + wantUEFI = true; + wantBIOS = true; + break; + case VIR_DOMAIN_LOADER_TYPE_NONE: + case VIR_DOMAIN_LOADER_TYPE_LAST: + default: + break; + } } for (i = 0; i < fw->ninterfaces; i++) { if (fw->interfaces[i] == want) break; + + if ((fw->interfaces[i] == QEMU_FIRMWARE_OS_INTERFACE_UEFI && wantUEFI) || + (fw->interfaces[i] == QEMU_FIRMWARE_OS_INTERFACE_BIOS && wantBIOS)) { + break; + } } if (i == fw->ninterfaces) { diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml b/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml index cdb92dcf1d..5b87857425 100644 --- a/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml +++ b/tests/qemuxmlconfdata/firmware-manual-efi-tdx.x86_64-latest+inteltdx.xml @@ -4,8 +4,12 @@ <memory unit='KiB'>1048576</memory> <currentMemory unit='KiB'>1048576</currentMemory> <vcpu placement='static'>1</vcpu> - <os> + <os firmware='efi'> <type arch='x86_64' machine='pc-q35-10.0'>hvm</type> + <firmware> + <feature enabled='yes' name='enrolled-keys'/> + <feature enabled='yes' name='secure-boot'/> + </firmware> <loader readonly='yes' type='rom' format='raw'>/usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd</loader> <boot dev='hd'/> </os> -- 2.52.0
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- NEWS.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index b749ffff79..6ca49a4c1b 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -19,6 +19,14 @@ v12.0.0 (unreleased) * **Improvements** + * qemu: Improvements and fixes to firmware selection + + Firmware selection now works more reliably and predictably in many + scenarios. + + Notably, issues that were preventing the use of firmware designed for + confidential VMs on aarch64 have been addressed. + * **Bug fixes** -- 2.52.0
On 12/29/25 00:33, Andrea Bolognani via Devel wrote:
This series improves validation so that more nonsensical configurations are rejected, fixes a number of scenarios in which user-provided attributes were getting overwritten by the firmware selection process, and overall makes things more predictable and reliable.
Notably, it addresses the inability of starting confidential VMs on aarch64, which was reported[1] some time ago.
It is also a prerequisite of another series that I will post shortly, which introduces support for the uefi-vars QEMU device and thus makes it possible to use Secure Boot for aarch64 VMs. Since all these fixes and improvements make sense on their own, and there is a little bit of work still needed on the QEMU/edk2 side before the other series can be merged, I decided to post this one separately instead of lumping them together. It's not like it's not meaty enough on its own anyway :)
[1] https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/D5UDR...
Andrea Bolognani (36): qemu_firmware: Drop support for kernel descriptors qemu_firmware: Drop 'nvram' local variable qemu_firmware: Move format=raw compat exception qemu_firmware: Move copying of nvram.format to loader.format tests: Add firmware-manual-efi-rw-nvram domain_validate: Reject NVRAM with read/write firmware tests: Add firmware-auto-bios-rw tests: Add firmware-manual-bios-rw domain_validate: Reject read/write ROMs tests: Add firmware-auto-efi-format-loader-qcow2-rom domain_validate: Reject ROMs with format other than raw qemu_firmware: Ignore stateless/combined when NVRAM is configured qemu_firmware: Drop fallback for absent nvramTemplateFormat schemas: Allow templateFormat without template path tests: Add firmware-manual-efi-nvram-template-nonstandard-format tests: Add firmware-manual-efi-nvram-template-nonstandard-legacy-paths tests: Add firmware-auto-efi-format-nvram-raw tests: Add firmware-auto-efi-format-nvram-raw-loader-path tests: Add firmware-auto-efi-format-nvram-raw-nvramtemplate-path tests: Add firmware-auto-efi-format-nvramtemplate-qcow2 tests: Add firmware-auto-efi-format-mismatch-nvramtemplate qemu_firmware: Introduce qemuFirmwareFillDomainCustom() qemu_firmware: Set templateFormat for custom paths qemu_firmware: Simplify handling of legacy paths qemu_firmware: Refactor setting NVRAM format qemu_firmware: Prefer template format to loader format qemu_firmware: Retain user-specified NVRAM format qemu_firmware: Take templateFormat into account when matching qemu_firmware: Take NVRAM format into account when matching qemu_firmware: Remove NVRAM to loader format copy hack tests: Add firmware-manual-efi-sev-snp tests: Add firmware-manual-efi-tdx qemu_firmware: ROM firmware is always in raw format qemu_firmware: Don't skip autoselection for ROM qemu_firmware: Allow matching both UEFI and BIOS for ROM loader news: Mention improvements and fixes to firmware selection
NEWS.rst | 8 + src/conf/domain_conf.c | 18 +- src/conf/domain_validate.c | 30 ++ src/conf/schemas/domaincommon.rng | 10 +- src/qemu/qemu_firmware.c | 367 ++++++++++-------- src/qemu/qemu_postparse.c | 17 - .../firmware-auto-bios-rw.x86_64-latest.err | 1 + ...> firmware-auto-bios-rw.x86_64-latest.xml} | 5 +- .../qemuxmlconfdata/firmware-auto-bios-rw.xml | 18 + ...-format-loader-qcow2-rom.x86_64-latest.err | 1 + ...mware-auto-efi-format-loader-qcow2-rom.xml | 18 + ...t-mismatch-nvramtemplate.x86_64-latest.err | 1 + ...-mismatch-nvramtemplate.x86_64-latest.xml} | 6 +- ...auto-efi-format-mismatch-nvramtemplate.xml | 19 + ...uto-efi-format-mismatch.x86_64-latest.args | 5 +- ...auto-efi-format-mismatch.x86_64-latest.xml | 2 +- ...-nvram-raw-loader-path.x86_64-latest.args} | 4 +- ...t-nvram-raw-loader-path.x86_64-latest.xml} | 4 +- ...-auto-efi-format-nvram-raw-loader-path.xml | 19 + ...raw-nvramtemplate-path.x86_64-latest.args} | 4 +- ...-raw-nvramtemplate-path.x86_64-latest.xml} | 4 +- ...fi-format-nvram-raw-nvramtemplate-path.xml | 18 + ...t-nvram-raw.x86_64-latest.abi-update.args} | 0 ...at-nvram-raw.x86_64-latest.abi-update.xml} | 0 ...o-efi-format-nvram-raw.x86_64-latest.args} | 0 ...to-efi-format-nvram-raw.x86_64-latest.xml} | 0 .../firmware-auto-efi-format-nvram-raw.xml | 18 + ...at-nvramtemplate-qcow2.x86_64-latest.args} | 9 +- ...mat-nvramtemplate-qcow2.x86_64-latest.xml} | 4 +- ...re-auto-efi-format-nvramtemplate-qcow2.xml | 18 + .../firmware-manual-bios-rw.x86_64-latest.err | 1 + .../firmware-manual-bios-rw.xml | 15 + ...-loader-path-nonstandard.x86_64-latest.xml | 2 +- ...ate-nonstandard-format.x86_64-latest.args} | 10 +- ...late-nonstandard-format.x86_64-latest.xml} | 4 +- ...-efi-nvram-template-nonstandard-format.xml | 19 + ...nstandard-legacy-paths.x86_64-latest.args} | 4 +- ...onstandard-legacy-paths.x86_64-latest.xml} | 5 +- ...vram-template-nonstandard-legacy-paths.xml | 20 + ...ram-template-nonstandard.x86_64-latest.xml | 2 +- ...ware-manual-efi-rw-nvram.x86_64-latest.err | 1 + .../firmware-manual-efi-rw-nvram.xml | 19 + ...ual-efi-sev-snp.x86_64-latest+amdsev.args} | 7 +- ...nual-efi-sev-snp.x86_64-latest+amdsev.xml} | 12 +- .../firmware-manual-efi-sev-snp.xml | 21 + ...anual-efi-tdx.x86_64-latest+inteltdx.args} | 9 +- ...manual-efi-tdx.x86_64-latest+inteltdx.xml} | 11 +- .../firmware-manual-efi-tdx.xml | 25 ++ tests/qemuxmlconftest.c | 19 + 49 files changed, 571 insertions(+), 263 deletions(-)
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (3)
-
Andrea Bolognani -
Gerd Hoffmann -
Michal Prívozník