[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