[libvirt] [PATCH 4/5] qemu: Enable secure boot
Laszlo Ersek
lersek at redhat.com
Wed Jul 27 15:11:59 UTC 2016
On 07/27/16 10:43, Michal Privoznik wrote:
> In qemu, enabling this feature boils down to adding the following
> onto the command line:
>
> -global driver=cfi.pflash01,property=secure,value=on
>
> However, there are some constraints resulting from the
> implementation. For instance, System Management Mode (SMM) is
> required to be enabled, the machine type must be q35-2.5 or
> later, and the guest should be x86_64. While technically it is
> possible to have 32 bit guests with secure boot, some non-trivial
> CPU flags tuning is required (for instance lm and nx flags must
> be prohibited). Given complexity of our CPU driver, this is not
> trivial. Therefore I've chosen to forbid 32 bit guests for now.
> If there's ever need, we can refine the check later.
>
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
> src/qemu/qemu_command.c | 7 ++++++
> src/qemu/qemu_domain.c | 27 ++++++++++++++++++++
> .../qemuxml2argv-bios-nvram-secure.args | 29 ++++++++++++++++++++++
> tests/qemuxml2argvtest.c | 7 ++++++
> 4 files changed, 70 insertions(+)
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-secure.args
This patch looks almost complete to me (it causes all necessary QEMU
options to appear, directly or indirectly (= via requiring SMM)).
However, can you also enforce that the Q35 machtype has version 2.5 or
later? Technically, "pc-q35-2.4" exists too, and it's not good enough
(according to the instructions I wrote up in OvmfPkg/README earlier). I
certainly never tested it.
Thanks,
Laszlo
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 831aba1..c6e629e 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -8731,6 +8731,13 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd,
> goto cleanup;
> }
>
> + if (loader->secure == VIR_TRISTATE_BOOL_YES) {
> + virCommandAddArgList(cmd,
> + "-global",
> + "driver=cfi.pflash01,property=secure,value=on",
> + NULL);
> + }
> +
> virBufferAsprintf(&buf,
> "file=%s,if=pflash,format=raw,unit=%d",
> loader->path, unit);
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 9045f37..ed51481 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -2321,6 +2321,33 @@ qemuDomainDefValidate(const virDomainDef *def,
> return -1;
> }
>
> + if (def->os.loader &&
> + def->os.loader->secure == VIR_TRISTATE_BOOL_YES) {
> + /* These are the QEMU implementation limitations. But we
> + * have to live with them for now. */
> +
> + if (!qemuDomainMachineIsQ35(def)) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("Secure boot is supported with q35 machine types only"));
> + return -1;
> + }
> +
> + /* Now, technically it is possible to have secure boot on
> + * 32bits too, but that would require some -cpu xxx magic
> + * too. Not worth it unless we are explicitly asked. */
> + if (def->os.arch != VIR_ARCH_X86_64) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("Secure boot is supported for x86_64 architecture only"));
> + return -1;
> + }
> +
> + if (def->features[VIR_DOMAIN_FEATURE_SMM] != VIR_TRISTATE_SWITCH_ON) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("Secure boot requires SMM feature enabled"));
> + return -1;
> + }
> + }
> +
> return 0;
> }
>
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-secure.args b/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-secure.args
> new file mode 100644
> index 0000000..c014254
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-secure.args
> @@ -0,0 +1,29 @@
> +LC_ALL=C \
> +PATH=/bin \
> +HOME=/home/test \
> +USER=test \
> +LOGNAME=test \
> +QEMU_AUDIO_DRV=none \
> +/usr/bin/qemu \
> +-name test-bios \
> +-S \
> +-machine pc-q35-2.5,accel=tcg,smm=on \
> +-global driver=cfi.pflash01,property=secure,value=on \
> +-drive file=/usr/share/OVMF/OVMF_CODE.secboot.fd,if=pflash,format=raw,unit=0,\
> +readonly=on \
> +-drive file=/usr/share/OVMF/OVMF_VARS.fd,if=pflash,format=raw,unit=1 \
> +-m 1024 \
> +-smp 1,sockets=1,cores=1,threads=1 \
> +-uuid 362d1fc1-df7d-193e-5c18-49a71bd1da66 \
> +-nographic \
> +-nodefaults \
> +-monitor unix:/tmp/lib/domain--1-test-bios/monitor.sock,server,nowait \
> +-boot c \
> +-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 virtio-scsi-pci,id=scsi0,bus=pci.2,addr=0x1 \
> +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-scsi0-0-0-0 \
> +-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\
> +drive=drive-scsi0-0-0-0,id=scsi0-0-0-0 \
> +-serial pty \
> +-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x2
> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
> index f9588d5..7b05150 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -685,6 +685,13 @@ mymain(void)
>
> DO_TEST("bios", QEMU_CAPS_SGA);
> DO_TEST("bios-nvram", NONE);
> + DO_TEST("bios-nvram-secure",
> + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
> + QEMU_CAPS_DEVICE_PCI_BRIDGE,
> + QEMU_CAPS_ICH9_AHCI,
> + QEMU_CAPS_MACHINE_OPT,
> + QEMU_CAPS_MACHINE_SMM_OPT,
> + QEMU_CAPS_VIRTIO_SCSI);
> DO_TEST("clock-utc", QEMU_CAPS_NODEFCONFIG);
> DO_TEST("clock-localtime", NONE);
> DO_TEST("clock-localtime-basis-localtime", QEMU_CAPS_RTC);
>
More information about the libvir-list
mailing list