[libvirt PATCH 0/5] Support AMD SEV firmware with -bios instead of pflash

The firmware distros have given people for use with AMD SEV thus far has just been one of the regular OVMF builds. This is sufficient for booting a guest with SEV enabled, but is useless if you want to actually validate the guest measurement. The NVRAM store is untrustworthy since it is not included in the measurement. We need to supply a dedicated build of OVMF without NVRAM support enabled. While it is possible to use with pflash, we then get a problem with firmware selection as there is no easy way to make it prefer the firmware without NVRAM. Also the firmware descriptor treats the NVRAM template as a mandatory field today and libvirt enforces that. While we could invent a new feature flag 'sev-stateless' for the firmware descriptors, and/or make the NVRAM template path optional, it makes more sense if the firmware descriptor just reports the SEV firmware as type=memory instead of type=flash. If the libvirt XML parses the <loader type='rom'/> attribute when doing firmware auto-selection, we trivially enable a way for a mgmt app to indicate that it wants the SEV firmware without NVRAM support. This series does all the plumbing we need. The only minor issue is that QEMU support for -bios with SEV enabled firmware is broken: https://lists.gnu.org/archive/html/qemu-devel/2022-01/msg02957.html Daniel P. Berrangé (5): docs: explain that some UEFI images can use 'rom' instead of 'pflash' conf: parse loader 'type' even when doing firmware auto select qemu: filter firmware selection based on loader type tests: add firmware descriptor for SEV dedicated build tests: add a test for selecting a firmware without NVRAM docs/formatdomain.rst | 24 +++++- src/conf/domain_conf.c | 8 +- src/qemu/qemu_firmware.c | 25 +++++++ .../usr/share/qemu/firmware/62-ovmf-sev.json | 27 +++++++ tests/qemufirmwaretest.c | 4 +- .../os-firmware-efi-sev.x86_64-6.0.0.args | 43 +++++++++++ .../qemuxml2argvdata/os-firmware-efi-sev.xml | 74 +++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 8 files changed, 197 insertions(+), 9 deletions(-) create mode 100644 tests/qemufirmwaredata/usr/share/qemu/firmware/62-ovmf-sev.json create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-sev.x86_64-6.0.0.args create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-sev.xml -- 2.33.1

The normal requirements for UEFI firmware images are to support persistence of variables, either in the main image, or more typically in a separate NVRAM file. In a confidential computing environment, however, persistence of variables can cause trust issues and prevent measurement of the firmware during boot up. For these scenarios some UEFI images will disable persistence of variables. To use such images the loader type must be set to 'rom' instead of 'pflash'. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatdomain.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index c0b2d935f3..cd818c1ded 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -214,10 +214,14 @@ harddisk, cdrom, network) determining where to obtain/find the boot image. the fact that the image should be writable or read-only. The second attribute ``type`` accepts values ``rom`` and ``pflash``. It tells the hypervisor where in the guest memory the file should be mapped. For instance, if the loader - path points to an UEFI image, ``type`` should be ``pflash``. Moreover, some - firmwares may implement the Secure boot feature. Attribute ``secure`` can be - used to tell the hypervisor that the firmware is capable of Secure Boot feature. - It cannot be used to enable or disable the feature itself in the firmware. + path points to an UEFI image, ``type`` would normally be ``pflash`` to + enable support for persistence of firmware variables. Moreover, some + firmwares may implement the Secure boot feature. Some UEFI images intended + for use with confidential computing environments like AMD SEV will disable + persistence of variables, and would thus require ``type`` to be ``rom``. + Attribute ``secure`` can be used to tell the hypervisor that the firmware + is capable of Secure Boot feature. It cannot be used to enable or disable + the feature itself in the firmware. :since:`Since 2.1.0` ``nvram`` Some UEFI firmwares may want to use a non-volatile memory to store some -- 2.33.1

On Fri, Jan 14, 2022 at 07:07:11PM +0000, Daniel P. Berrangé wrote:
The normal requirements for UEFI firmware images are to support persistence of variables, either in the main image, or more typically in a separate NVRAM file.
In a confidential computing environment, however, persistence of variables can cause trust issues and prevent measurement of the firmware during boot up. For these scenarios some UEFI images will disable persistence of variables. To use such images the loader type must be set to 'rom' instead of 'pflash'.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatdomain.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index c0b2d935f3..cd818c1ded 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -214,10 +214,14 @@ harddisk, cdrom, network) determining where to obtain/find the boot image. the fact that the image should be writable or read-only. The second attribute ``type`` accepts values ``rom`` and ``pflash``. It tells the hypervisor where in the guest memory the file should be mapped. For instance, if the loader - path points to an UEFI image, ``type`` should be ``pflash``. Moreover, some - firmwares may implement the Secure boot feature. Attribute ``secure`` can be - used to tell the hypervisor that the firmware is capable of Secure Boot feature. - It cannot be used to enable or disable the feature itself in the firmware. + path points to an UEFI image, ``type`` would normally be ``pflash`` to + enable support for persistence of firmware variables. Moreover, some + firmwares may implement the Secure boot feature. Some UEFI images intended
^This Secure boot sentence should go after explaining why confidential computing would prefer the type 'rom' Reviewed-by: Erik Skultety <eskultet@redhat.com>
+ for use with confidential computing environments like AMD SEV will disable + persistence of variables, and would thus require ``type`` to be ``rom``. + Attribute ``secure`` can be used to tell the hypervisor that the firmware + is capable of Secure Boot feature. It cannot be used to enable or disable + the feature itself in the firmware. :since:`Since 2.1.0` ``nvram`` Some UEFI firmwares may want to use a non-volatile memory to store some
-- 2.33.1

The loader 'type' is a property that is useful to filter on when selecting firmware. For example, with AMD SEV it is desirable to be able to request selecting of firmware without NVRAM using: <os firmware='efi'> <loader type='rom'/> </os> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatdomain.rst | 12 ++++++++++++ src/conf/domain_conf.c | 8 ++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index cd818c1ded..3c4ee70835 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -149,6 +149,16 @@ harddisk, cdrom, network) determining where to obtain/find the boot image. </os> ... + <!-- QEMU with automatic UEFI firmware suitable for AMD SEV, where + ROM is preferred over pflash when both are available --> + ... + <os firmware='efi'> + <type>hvm</type> + <loader type='rom'/> + <boot dev='hd'/> + </os> + ... + ``firmware`` The ``firmware`` attribute allows management applications to automatically fill ``<loader/>`` and ``<nvram/>`` elements and possibly enable some @@ -219,6 +229,8 @@ harddisk, cdrom, network) determining where to obtain/find the boot image. firmwares may implement the Secure boot feature. Some UEFI images intended for use with confidential computing environments like AMD SEV will disable persistence of variables, and would thus require ``type`` to be ``rom``. + If set, the ``type`` attribute will also influence what firmware path is + used when firmware auto-select is performed. :since:`Since 8.1.0`. Attribute ``secure`` can be used to tell the hypervisor that the firmware is capable of Secure Boot feature. It cannot be used to enable or disable the feature itself in the firmware. diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a805f7f6a3..4f0d8e27cf 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18044,10 +18044,6 @@ virDomainLoaderDefParseXML(xmlNodePtr node, &loader->readonly) < 0) return -1; - if (virXMLPropEnum(node, "type", virDomainLoaderTypeFromString, - VIR_XML_PROP_NONZERO, &loader->type) < 0) - return -1; - if (!(loader->path = virXMLNodeContentString(node))) return -1; @@ -18055,6 +18051,10 @@ virDomainLoaderDefParseXML(xmlNodePtr node, VIR_FREE(loader->path); } + if (virXMLPropEnum(node, "type", virDomainLoaderTypeFromString, + VIR_XML_PROP_NONZERO, &loader->type) < 0) + return -1; + if (virXMLPropTristateBool(node, "secure", VIR_XML_PROP_NONE, &loader->secure) < 0) return -1; -- 2.33.1

If the '<loader>' type attribute is set, then use this to filter the available firmware files. This allows forcing use of a firmware with or without NVRAM, where both options are available. This will be used for AMD SEV when doing a measured boot, where NVRAM must be forbidden. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/qemu/qemu_firmware.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 84c80eaacb..2c3b28ae13 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1070,6 +1070,31 @@ qemuFirmwareMatchDomain(const virDomainDef *def, return false; } + if (def->os.loader) { + VIR_DEBUG("Check loader type '%s' match for device '%s'", + virDomainLoaderTypeToString(def->os.loader->type), + qemuFirmwareDeviceTypeToString(fw->mapping.device)); + switch (def->os.loader->type) { + case VIR_DOMAIN_LOADER_TYPE_NONE: + break; + + case VIR_DOMAIN_LOADER_TYPE_ROM: + if (fw->mapping.device != QEMU_FIRMWARE_DEVICE_MEMORY) + return false; + break; + + case VIR_DOMAIN_LOADER_TYPE_PFLASH: + if (fw->mapping.device != QEMU_FIRMWARE_DEVICE_FLASH) + return false; + break; + + case VIR_DOMAIN_LOADER_TYPE_LAST: + break; + } + } else { + VIR_DEBUG("Skip loader type match"); + } + if (def->sec) { switch ((virDomainLaunchSecurity) def->sec->sectype) { case VIR_DOMAIN_LAUNCH_SECURITY_SEV: -- 2.33.1

This is different from most OVMF firmware builds in that there is no separate NVRAM variables store. The main image is readonly and does not persist variables. As such it uses the old style -bios config with QEMU rather than pflash. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .../usr/share/qemu/firmware/62-ovmf-sev.json | 27 +++++++++++++++++++ tests/qemufirmwaretest.c | 4 ++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/qemufirmwaredata/usr/share/qemu/firmware/62-ovmf-sev.json diff --git a/tests/qemufirmwaredata/usr/share/qemu/firmware/62-ovmf-sev.json b/tests/qemufirmwaredata/usr/share/qemu/firmware/62-ovmf-sev.json new file mode 100644 index 0000000000..02e5e1dae8 --- /dev/null +++ b/tests/qemufirmwaredata/usr/share/qemu/firmware/62-ovmf-sev.json @@ -0,0 +1,27 @@ +{ + "description": "OVMF for x86_64, with SEV, without SB, without SMM, with NO varstore", + "interface-types": [ + "uefi" + ], + "mapping": { + "device": "memory", + "filename": "/usr/share/OVMF/OVMF.sev.fd" + }, + "targets": [ + { + "architecture": "x86_64", + "machines": [ + "pc-q35-*" + ] + } + ], + "features": [ + "acpi-s3", + "amd-sev", + "amd-sev-es", + "verbose-dynamic" + ], + "tags": [ + + ] +} diff --git a/tests/qemufirmwaretest.c b/tests/qemufirmwaretest.c index cad4b6d383..45c27554f6 100644 --- a/tests/qemufirmwaretest.c +++ b/tests/qemufirmwaretest.c @@ -62,6 +62,7 @@ testFWPrecedence(const void *opaque G_GNUC_UNUSED) SYSCONFDIR "/qemu/firmware/40-ovmf-sb-keys.json", PREFIX "/share/qemu/firmware/50-ovmf-sb-keys.json", PREFIX "/share/qemu/firmware/61-ovmf.json", + PREFIX "/share/qemu/firmware/62-ovmf-sev.json", PREFIX "/share/qemu/firmware/70-aavmf.json", NULL }; @@ -250,7 +251,8 @@ mymain(void) DO_SUPPORTED_TEST("pc-q35-3.1", VIR_ARCH_X86_64, true, "/usr/share/seabios/bios-256k.bin:NULL:" "/usr/share/OVMF/OVMF_CODE.secboot.fd:/usr/share/OVMF/OVMF_VARS.secboot.fd:" - "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd", + "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd:" + "/usr/share/OVMF/OVMF.sev.fd:NULL", VIR_DOMAIN_OS_DEF_FIRMWARE_BIOS, VIR_DOMAIN_OS_DEF_FIRMWARE_EFI); DO_SUPPORTED_TEST("pc-q35-3.1", VIR_ARCH_I686, false, -- 2.33.1

This demonstrates that when the XML config contains <os firmware='efi'> <loader type='rom'/> </os> the firmware auto-selection code will ignore the high priority pflash OVMF builds tagged with the 'amd-sev' feature, and instead pick the ROM builds without a varstore. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .../os-firmware-efi-sev.x86_64-6.0.0.args | 43 +++++++++++ .../qemuxml2argvdata/os-firmware-efi-sev.xml | 74 +++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 3 files changed, 118 insertions(+) create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-sev.x86_64-6.0.0.args create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-sev.xml diff --git a/tests/qemuxml2argvdata/os-firmware-efi-sev.x86_64-6.0.0.args b/tests/qemuxml2argvdata/os-firmware-efi-sev.x86_64-6.0.0.args new file mode 100644 index 0000000000..fdb64fef75 --- /dev/null +++ b/tests/qemuxml2argvdata/os-firmware-efi-sev.x86_64-6.0.0.args @@ -0,0 +1,43 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-fedora \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-fedora/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-fedora/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-fedora/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=fedora,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-fedora/master-key.aes"}' \ +-machine pc-q35-4.0,usb=off,dump-guest-core=off,confidential-guest-support=lsec0,memory-backend=pc.ram \ +-accel kvm \ +-cpu qemu64 \ +-bios /usr/share/OVMF/OVMF.sev.fd \ +-m 8 \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":8388608}' \ +-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 \ +-global ICH9-LPC.disable_s3=0 \ +-global ICH9-LPC.disable_s4=1 \ +-boot menu=on,strict=on \ +-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ +-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ +-device ioh3420,port=8,chassis=3,id=pci.3,bus=pcie.0,addr=0x1 \ +-device ich9-usb-ehci1,id=usb,bus=pcie.0,addr=0x1d.0x7 \ +-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pcie.0,multifunction=on,addr=0x1d \ +-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pcie.0,addr=0x1d.0x1 \ +-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pcie.0,addr=0x1d.0x2 \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x1 \ +-object '{"qom-type":"sev-guest","id":"lsec0","cbitpos":47,"reduced-phys-bits":1,"policy":1,"dh-cert-file":"/tmp/lib/domain--1-fedora/dh_cert.base64","session-file":"/tmp/lib/domain--1-fedora/session.base64"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/os-firmware-efi-sev.xml b/tests/qemuxml2argvdata/os-firmware-efi-sev.xml new file mode 100644 index 0000000000..eb8292b59d --- /dev/null +++ b/tests/qemuxml2argvdata/os-firmware-efi-sev.xml @@ -0,0 +1,74 @@ +<domain type='kvm'> + <name>fedora</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>8192</memory> + <currentMemory unit='KiB'>8192</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> + <loader secure='no' type='rom'/> + <boot dev='hd'/> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='yes'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/> + </controller> + <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'/> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='3' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/> + </memballoon> + </devices> + <launchSecurity type='sev'> + <cbitpos>47</cbitpos> + <reducedPhysBits>1</reducedPhysBits> + <policy>0x0001</policy> + <dhCert>AQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAA</dhCert> + <session>IHAVENOIDEABUTJUSTPROVIDINGASTRING</session> + </launchSecurity> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index cc67d806e4..16765f2471 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3455,6 +3455,7 @@ mymain(void) DO_TEST_CAPS_LATEST("os-firmware-efi"); DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); DO_TEST_CAPS_LATEST("os-firmware-efi-no-enrolled-keys"); + DO_TEST_CAPS_VER("os-firmware-efi-sev", "6.0.0"); DO_TEST_CAPS_ARCH_LATEST("aarch64-os-firmware-efi", "aarch64"); DO_TEST_CAPS_LATEST("vhost-user-vga"); -- 2.33.1

On Fri, Jan 14, 2022 at 07:07:10PM +0000, Daniel P. Berrangé wrote:
The firmware distros have given people for use with AMD SEV thus far has just been one of the regular OVMF builds. This is sufficient for booting a guest with SEV enabled, but is useless if you want to actually validate the guest measurement. The NVRAM store is untrustworthy since it is not included in the measurement. We need to supply a dedicated build of OVMF without NVRAM support enabled. While it is possible to use with pflash, we then get a problem with firmware selection as there is no easy way to make it prefer the firmware without NVRAM. Also the firmware descriptor treats the NVRAM template as a mandatory field today and libvirt enforces that.
While we could invent a new feature flag 'sev-stateless' for the firmware descriptors, and/or make the NVRAM template path optional, it makes more sense if the firmware descriptor just reports the SEV firmware as type=memory instead of type=flash.
If the libvirt XML parses the <loader type='rom'/> attribute when doing firmware auto-selection, we trivially enable a way for a mgmt app to indicate that it wants the SEV firmware without NVRAM support.
This series does all the plumbing we need.
The only minor issue is that QEMU support for -bios with SEV enabled firmware is broken:
https://lists.gnu.org/archive/html/qemu-devel/2022-01/msg02957.html
Well turns out the concept is unfixably broken on the QEMU side with SEV enabled UEFI firmware. So I'm going to ditch the first docs patch. I figure it is still possibly useful to be able to controla auto-firmware selection based on 'type', even if it doesn't help my sev use case, so might as well leave keep that now I've implemented it.
Daniel P. Berrangé (5): docs: explain that some UEFI images can use 'rom' instead of 'pflash' conf: parse loader 'type' even when doing firmware auto select qemu: filter firmware selection based on loader type tests: add firmware descriptor for SEV dedicated build tests: add a test for selecting a firmware without NVRAM
docs/formatdomain.rst | 24 +++++- src/conf/domain_conf.c | 8 +- src/qemu/qemu_firmware.c | 25 +++++++ .../usr/share/qemu/firmware/62-ovmf-sev.json | 27 +++++++ tests/qemufirmwaretest.c | 4 +- .../os-firmware-efi-sev.x86_64-6.0.0.args | 43 +++++++++++ .../qemuxml2argvdata/os-firmware-efi-sev.xml | 74 +++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 8 files changed, 197 insertions(+), 9 deletions(-) create mode 100644 tests/qemufirmwaredata/usr/share/qemu/firmware/62-ovmf-sev.json create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-sev.x86_64-6.0.0.args create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-sev.xml
-- 2.33.1
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On Fri, Jan 21, 2022 at 02:16:14PM +0000, Daniel P. Berrangé wrote:
On Fri, Jan 14, 2022 at 07:07:10PM +0000, Daniel P. Berrangé wrote:
The firmware distros have given people for use with AMD SEV thus far has just been one of the regular OVMF builds. This is sufficient for booting a guest with SEV enabled, but is useless if you want to actually validate the guest measurement. The NVRAM store is untrustworthy since it is not included in the measurement. We need to supply a dedicated build of OVMF without NVRAM support enabled. While it is possible to use with pflash, we then get a problem with firmware selection as there is no easy way to make it prefer the firmware without NVRAM. Also the firmware descriptor treats the NVRAM template as a mandatory field today and libvirt enforces that.
While we could invent a new feature flag 'sev-stateless' for the firmware descriptors, and/or make the NVRAM template path optional, it makes more sense if the firmware descriptor just reports the SEV firmware as type=memory instead of type=flash.
If the libvirt XML parses the <loader type='rom'/> attribute when doing firmware auto-selection, we trivially enable a way for a mgmt app to indicate that it wants the SEV firmware without NVRAM support.
This series does all the plumbing we need.
The only minor issue is that QEMU support for -bios with SEV enabled firmware is broken:
https://lists.gnu.org/archive/html/qemu-devel/2022-01/msg02957.html
Well turns out the concept is unfixably broken on the QEMU side with SEV enabled UEFI firmware. So I'm going to ditch the first docs patch.
I figure it is still possibly useful to be able to controla auto-firmware selection based on 'type', even if it doesn't help my sev use case, so might as well leave keep that now I've implemented it.
In any case, in context of patch 2/5, shouldn't autoselect haven been left untouched and instead pick the type automatically, say in qemuValidateDomainDefBoot or similar depending on whether the domain has LaunchSecurity SEV defined in the XML? Erik

On Fri, Jan 21, 2022 at 03:40:23PM +0100, Erik Skultety wrote:
On Fri, Jan 21, 2022 at 02:16:14PM +0000, Daniel P. Berrangé wrote:
On Fri, Jan 14, 2022 at 07:07:10PM +0000, Daniel P. Berrangé wrote:
The firmware distros have given people for use with AMD SEV thus far has just been one of the regular OVMF builds. This is sufficient for booting a guest with SEV enabled, but is useless if you want to actually validate the guest measurement. The NVRAM store is untrustworthy since it is not included in the measurement. We need to supply a dedicated build of OVMF without NVRAM support enabled. While it is possible to use with pflash, we then get a problem with firmware selection as there is no easy way to make it prefer the firmware without NVRAM. Also the firmware descriptor treats the NVRAM template as a mandatory field today and libvirt enforces that.
While we could invent a new feature flag 'sev-stateless' for the firmware descriptors, and/or make the NVRAM template path optional, it makes more sense if the firmware descriptor just reports the SEV firmware as type=memory instead of type=flash.
If the libvirt XML parses the <loader type='rom'/> attribute when doing firmware auto-selection, we trivially enable a way for a mgmt app to indicate that it wants the SEV firmware without NVRAM support.
This series does all the plumbing we need.
The only minor issue is that QEMU support for -bios with SEV enabled firmware is broken:
https://lists.gnu.org/archive/html/qemu-devel/2022-01/msg02957.html
Well turns out the concept is unfixably broken on the QEMU side with SEV enabled UEFI firmware. So I'm going to ditch the first docs patch.
I figure it is still possibly useful to be able to controla auto-firmware selection based on 'type', even if it doesn't help my sev use case, so might as well leave keep that now I've implemented it.
In any case, in context of patch 2/5, shouldn't autoselect haven been left untouched and instead pick the type automatically, say in qemuValidateDomainDefBoot or similar depending on whether the domain has LaunchSecurity SEV defined in the XML?
Well there's already usage of SEV with existing guests with UEFI split firmware with pflash. I didn't want to change it to prefer ROM based firmware because that's a significant semantic change that means you loose persistence of NVRAM variables. THe new SEV firmware is not necessarily compatible with the currently use SEV firmware from a guest OS POV, because it uses embedded grub rather than invoking grub from the guest disk image. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On Fri, Jan 21, 2022 at 02:44:02PM +0000, Daniel P. Berrangé wrote:
On Fri, Jan 21, 2022 at 03:40:23PM +0100, Erik Skultety wrote:
On Fri, Jan 21, 2022 at 02:16:14PM +0000, Daniel P. Berrangé wrote:
On Fri, Jan 14, 2022 at 07:07:10PM +0000, Daniel P. Berrangé wrote:
The firmware distros have given people for use with AMD SEV thus far has just been one of the regular OVMF builds. This is sufficient for booting a guest with SEV enabled, but is useless if you want to actually validate the guest measurement. The NVRAM store is untrustworthy since it is not included in the measurement. We need to supply a dedicated build of OVMF without NVRAM support enabled. While it is possible to use with pflash, we then get a problem with firmware selection as there is no easy way to make it prefer the firmware without NVRAM. Also the firmware descriptor treats the NVRAM template as a mandatory field today and libvirt enforces that.
While we could invent a new feature flag 'sev-stateless' for the firmware descriptors, and/or make the NVRAM template path optional, it makes more sense if the firmware descriptor just reports the SEV firmware as type=memory instead of type=flash.
If the libvirt XML parses the <loader type='rom'/> attribute when doing firmware auto-selection, we trivially enable a way for a mgmt app to indicate that it wants the SEV firmware without NVRAM support.
This series does all the plumbing we need.
The only minor issue is that QEMU support for -bios with SEV enabled firmware is broken:
https://lists.gnu.org/archive/html/qemu-devel/2022-01/msg02957.html
Well turns out the concept is unfixably broken on the QEMU side with SEV enabled UEFI firmware. So I'm going to ditch the first docs patch.
I figure it is still possibly useful to be able to controla auto-firmware selection based on 'type', even if it doesn't help my sev use case, so might as well leave keep that now I've implemented it.
In any case, in context of patch 2/5, shouldn't autoselect haven been left untouched and instead pick the type automatically, say in qemuValidateDomainDefBoot or similar depending on whether the domain has LaunchSecurity SEV defined in the XML?
Well there's already usage of SEV with existing guests with UEFI split firmware with pflash. I didn't want to change it to prefer ROM based firmware because that's a significant semantic change that means you loose persistence of NVRAM variables. THe new SEV firmware is not necessarily compatible with the currently use SEV firmware from a guest OS POV, because it uses embedded grub rather than invoking grub from the guest disk image.
Hmm, so let me ask if I understand correctly: You want to keep firmware autoselection with SEV as is even though you won't be able to do measurements and instead let the user provide an explicit type 'rom' setting hinting libvirt to pick the right firmware build complying with the confidentiality rules for SEV measurements? Erik

On Fri, Jan 21, 2022 at 03:51:51PM +0100, Erik Skultety wrote:
On Fri, Jan 21, 2022 at 02:44:02PM +0000, Daniel P. Berrangé wrote:
On Fri, Jan 21, 2022 at 03:40:23PM +0100, Erik Skultety wrote:
On Fri, Jan 21, 2022 at 02:16:14PM +0000, Daniel P. Berrangé wrote:
On Fri, Jan 14, 2022 at 07:07:10PM +0000, Daniel P. Berrangé wrote:
The firmware distros have given people for use with AMD SEV thus far has just been one of the regular OVMF builds. This is sufficient for booting a guest with SEV enabled, but is useless if you want to actually validate the guest measurement. The NVRAM store is untrustworthy since it is not included in the measurement. We need to supply a dedicated build of OVMF without NVRAM support enabled. While it is possible to use with pflash, we then get a problem with firmware selection as there is no easy way to make it prefer the firmware without NVRAM. Also the firmware descriptor treats the NVRAM template as a mandatory field today and libvirt enforces that.
While we could invent a new feature flag 'sev-stateless' for the firmware descriptors, and/or make the NVRAM template path optional, it makes more sense if the firmware descriptor just reports the SEV firmware as type=memory instead of type=flash.
If the libvirt XML parses the <loader type='rom'/> attribute when doing firmware auto-selection, we trivially enable a way for a mgmt app to indicate that it wants the SEV firmware without NVRAM support.
This series does all the plumbing we need.
The only minor issue is that QEMU support for -bios with SEV enabled firmware is broken:
https://lists.gnu.org/archive/html/qemu-devel/2022-01/msg02957.html
Well turns out the concept is unfixably broken on the QEMU side with SEV enabled UEFI firmware. So I'm going to ditch the first docs patch.
I figure it is still possibly useful to be able to controla auto-firmware selection based on 'type', even if it doesn't help my sev use case, so might as well leave keep that now I've implemented it.
In any case, in context of patch 2/5, shouldn't autoselect haven been left untouched and instead pick the type automatically, say in qemuValidateDomainDefBoot or similar depending on whether the domain has LaunchSecurity SEV defined in the XML?
Well there's already usage of SEV with existing guests with UEFI split firmware with pflash. I didn't want to change it to prefer ROM based firmware because that's a significant semantic change that means you loose persistence of NVRAM variables. THe new SEV firmware is not necessarily compatible with the currently use SEV firmware from a guest OS POV, because it uses embedded grub rather than invoking grub from the guest disk image.
Hmm, so let me ask if I understand correctly: You want to keep firmware autoselection with SEV as is even though you won't be able to do measurements and instead let the user provide an explicit type 'rom' setting hinting libvirt to pick the right firmware build complying with the confidentiality rules for SEV measurements?
That's what this series did at least. My new approach is to express the different ypes of 'pflash' build - 'split' - traditional CODE & VARS files separated - 'combined' - CODE & VARS merged in a single file - 'stateless' - CODE only, no VARS so a user wanting a measurable SEV launch would request a 'stateless' firmware to be found. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
participants (2)
-
Daniel P. Berrangé
-
Erik Skultety