libvirt - Use built-in firmware auto-selection for UEFI firmware¶
https://blueprints.launchpad.net/nova/+spec/libvirt-firmware-auto-selection
Libvirt introduced its built-in firmware auto-selection for UEFI firmware, which automatically fills paths for CODE file and VAR file of UEFI firmware files, according to the requested features. This feature is more sophisticated and is capable to detect a few new flags recently introduced, like AMD SEV or stateless firmware.
This spec proposes replacing the existing own logic within nova by the built-in one, so that we don’t have to maintain our own logic and leverage the improved mechanism in underlying libvirt.
Problem description¶
Recent libvirt is capable to select the appropriate firmware files for domains using UEFI boot, according to the requested features such as:
secure boot
amd-sev/amd-sev-es/amd-sev-snp
stateless firmware
This feature is called auto-selection in libvirt and it reads the flags maintained in firmware descriptor files provided by qemu packages in distros.
Nova introduced its own logic when secure boot support was introduced. Because nova explicitly defines firmware files being used for every instance with UEFI boot, libvirt skips its auto-selection feature and use the specified files accordingly. However the existing logic in nova only considers the secure-boot flag, so it is not able to select appropriate firmware for the other features. As a result, an instance with additional features may be launched with a wrong firmware file. One example is stateless firmware, for which a firmware file with “stateless” flag should be used, but the current nova may not consider this flag and may launch instances with a CODE file,
which has non-zero VAR file associated.
In addition to the new feature flags, recent QEMU packages introduced the new ROM type firmwares. Libvirt can recognize these, but nova is not able to handle that new types due to the different keys used to define the firmware path file.
Use Cases¶
As a cloud administrator, I want nova to select the appropriate firmware file according to the features user requested, without additional configuration.
As a cloud user, I want my instance to be booted with an appropriate firmware, according to the feature requested.
Proposed change¶
We propose the following changes in the way guest XML is generated by libvirt driver, so that firmware files are selected by libvirt according to the requested features.
Stop explicitly passing paths for code file and var file when defining a domain.
Current nova fills the loader element and the nvram element when generating a guest XML. The example below describes the
oselement of a guest XML with secure-boot.<os> <type machine='q35'>hvm</type> <loader type='pflash' readonly='yes' secure='yes'>/usr/share/OVMF/OVMF_CODE.secboot.fd</loader> <nvram template='/usr/share/OVMF/OVMF_VARS.secboot.fd'/> <boot dev='hd'/> <smbios mode='sysinfo'/> </os>
Once the proposed change is implemented, nova no longer fills these file paths but adds the firmware feature element for secure-boot. The example below describes the
oselement of a guest XML with secure-boot.<os firmware='efi'> <type machine='q35'>hvm</type> <loader secure='yes'/> <firmware> <feature enabled='yes' name='secure-boot'/> </firmware> <boot dev='hd'/> <smbios mode='sysinfo'/> </os>
Note that the
firmware='efi'is the key to tell libvirt detect the firmware file paths.To keep the existing behavior for guests without secure-boot, the feature is explicitly rejected in a guest XML if secure-boot feature is not requested.
<os firmware='efi'> <type machine='q35'>hvm</type> <loader secure='no'/> <firmware> <feature enabled='no' name='secure-boot'/> </firmware> <boot dev='hd'/> <smbios mode='sysinfo'/> </os>
However, libvirt does not require these firmware feature elements for stateless firmware (libvirt reads the stateless property in the loader element) and AMD SEV/SEV-ES (libvirt reads the launchSecurity element). For example, the
oselement of a guest XML should look like the example below when stateless firmware is requested.<os firmware='efi'> <type machine='q35'>hvm</type> <loader secure='no' stateless='yes'/> <firmware> <feature enabled='no' name='secure-boot'/> </firmware> <boot dev='hd'/> <smbios mode='sysinfo'/> </os>
During the following operations, check the loader element and the nvram element in the existing guest XML, and then explicitly pass these elements and disable auto detection to generate the new guest XML, so that firmware files are not re-selected during these operations.
hard-reboot (and start)
live migration
Note
It’s possible that the domain xml does not exist when an instance is started (for example if the instance is booted from a volume and its host is reinstalled). In that case xml is generated from scratch and firmware file paths may be changed after the operation.
Alternatives¶
An alternative approach is to implement the same auto selection logic in nova, but this requires effort to keep the implementation consistent with libvirt. This causes concern with future code maintenance for no large benefit.
Data model impact¶
None
REST API impact¶
None
Security impact¶
None
Notifications impact¶
None
Other end user impact¶
Instances may be launched with a different (but correct) firmware after the operations which generate domain XML from scratch, such as
Start, when the domain definition does not exists on the hypervisor
Rebuild
Shelve
Resize or cold migration
Evacuate
Performance Impact¶
None
Other deployer impact¶
Deployers have to ensure the firmware descriptor files (which are typically located in /usr/share/qemu/firmware/) are updated to contain the flags for the expected features.
Developer impact¶
None
Upgrade impact¶
As described in the end-user impact section, instances may be launched with a different firmware file, when it is being launched by a new libvirt driver.
After upgrade, instance creation might fail in case none of the firmware descriptor files do not contain the required flags (sev flags and stateless flag) which were not checked earlier.
Implementation¶
Assignee(s)¶
- Primary assignee:
kajinamit (irc: tkajinam)
- Other contributors:
None
Work Items¶
Add detection of used firmware files from existing libvirt XML
Update generation of XML file by libvirt driver to fill firmware file paths only when these are explicitly given.
Update live migration and hard reboot to pass the firmware files currently used, when generating a new XML file.
Unit tests and functional tests should be added according to new logic.
Dependencies¶
Libvirt >= 5.2.0 is required to use auto-selection feature. This is already enforced by minimum libvirt version check.
QEMU firmware files and their descriptor files are updated to contain flags for the features requested by nova. The firmware descriptor files installed by supported distributions mostly contain the required flags, but Ubuntu 24.04 is known to require an update for AMD SEV-ES support. See Bug 2122286 for details.
Testing¶
Corresponding unit/functional tests will need to be extended or added to cover:
Simplified XML file passed during instance XML generation, which does not contain explicit firmware file paths
XML file generated by hard-reboot or live migration should contain explicit firmware file paths, according to the ones in the existing domain XML.
For secure boot and stateless firmware, new scenario tests may be added to tempest. However cirros, which is currently used in CI for guest OS, does not support UEFI boot and we need a different (and likely more heavy) guest OS for these features. In case it was determined that we can’t use these guest in CI, these features may be tested locally.
Also, AMD SEV and AMD SEV-ES have no real firmware available in CI so these will be manually tested.
Documentation Impact¶
None
References¶
History¶
Release Name |
Description |
|---|---|
2026.1 Gazpacho |
Approved |