- add uefi variable store support

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmfG9m4ACgkQTLbY7tPo
 cTgk8BAAn60ezSx2iet/JarkMugacOJ6C2UbVQho/Q3WCyrQ7K+F0NByczcfKLA6
 OZX84p93qxiK8KJ9tva41eOIYViyfsKf+wGUInNCbXbyGy7RZV3SjE5Yuk9BE9Ta
 8f/5dDGyCELQWliy4atLUWl2dL0rQ76twLZewYo9n2A+LijIzjuP+kVJeccK8U7A
 qStio3rGZ0vul2OYhE3+veSXd2m2oU32Tce31MUoj9yCbTE1RZSKMXbwbUU/nul9
 RN3X0q4rvXKwbKMUdC+YI+oIzY/1nzrmy5zwwbJsAszsSKjAc2LZeoDqKdbOIynL
 B01dorpg5pVxQUqHz1t+YTfGyuZaYDM6WsaGoU5/9QLW7ZbI857EULq7ptE3DVAS
 YjHiBYqiiYYrCatV4UT1XjkRjX7W8lTdK2M+8Vh1E5b1pGpfPwuKE4YRGwMMK0Ac
 5LD9HMxnXIDOT9A6+tGc6GYLfT7YToFA3pHn6WdLlGSowB7sYVZy0/xGe3ABjvzt
 WOl1WDWtHCpYIiROpEl+KkbRilwvbLF/IW7x0Ovfsjyh5ucBFu6ojxgRBcOee4Na
 oeBz5GfpeIoelhWl1aSYIUrFCvN2Q/9EafHRsfTzPoKlD3t/7oLNYtMYloiQpsks
 IPpD5OMMmWGaD2G76Nw24nS4+zUf4Gagg6+IAlYt6zjqnmxFWxY=
 =HnUt
 -----END PGP SIGNATURE-----

Merge tag 'firmware-20250304-pull-request' of https://gitlab.com/kraxel/qemu into staging

- add uefi variable store support

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmfG9m4ACgkQTLbY7tPo
# cTgk8BAAn60ezSx2iet/JarkMugacOJ6C2UbVQho/Q3WCyrQ7K+F0NByczcfKLA6
# OZX84p93qxiK8KJ9tva41eOIYViyfsKf+wGUInNCbXbyGy7RZV3SjE5Yuk9BE9Ta
# 8f/5dDGyCELQWliy4atLUWl2dL0rQ76twLZewYo9n2A+LijIzjuP+kVJeccK8U7A
# qStio3rGZ0vul2OYhE3+veSXd2m2oU32Tce31MUoj9yCbTE1RZSKMXbwbUU/nul9
# RN3X0q4rvXKwbKMUdC+YI+oIzY/1nzrmy5zwwbJsAszsSKjAc2LZeoDqKdbOIynL
# B01dorpg5pVxQUqHz1t+YTfGyuZaYDM6WsaGoU5/9QLW7ZbI857EULq7ptE3DVAS
# YjHiBYqiiYYrCatV4UT1XjkRjX7W8lTdK2M+8Vh1E5b1pGpfPwuKE4YRGwMMK0Ac
# 5LD9HMxnXIDOT9A6+tGc6GYLfT7YToFA3pHn6WdLlGSowB7sYVZy0/xGe3ABjvzt
# WOl1WDWtHCpYIiROpEl+KkbRilwvbLF/IW7x0Ovfsjyh5ucBFu6ojxgRBcOee4Na
# oeBz5GfpeIoelhWl1aSYIUrFCvN2Q/9EafHRsfTzPoKlD3t/7oLNYtMYloiQpsks
# IPpD5OMMmWGaD2G76Nw24nS4+zUf4Gagg6+IAlYt6zjqnmxFWxY=
# =HnUt
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 04 Mar 2025 20:47:42 HKT
# gpg:                using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* tag 'firmware-20250304-pull-request' of https://gitlab.com/kraxel/qemu: (24 commits)
  docs: add uefi variable service documentation
  hw/uefi: add MAINTAINERS entry
  hw/uefi-vars-sysbus: allow for pc and q35
  hw/uefi-vars-sysbus: allow for arm virt
  hw/uefi-vars-sysbus: add x64 variant
  hw/uefi-vars-sysbus: qemu platform bus support
  hw/uefi: add uefi-vars-sysbus device
  hw/uefi: add to meson
  hw/uefi: add UEFI_VARS to Kconfig
  hw/uefi: add trace-events
  hw/uefi: add var-service-json.c + qapi for NV vars.
  hw/uefi: add var-service-siglist.c
  hw/uefi: add var-service-pkcs7-stub.c
  hw/uefi: add var-service-pkcs7.c
  hw/uefi: add var-service-core.c
  hw/uefi: add var-service-policy.c
  hw/uefi: add var-service-auth.c
  hw/uefi: add var-service-vars.c
  hw/uefi: add var-service-utils.c
  hw/uefi: add var-service-guid.c
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2025-03-05 21:53:36 +08:00
commit 50aa3d0984
33 changed files with 3902 additions and 0 deletions

View file

@ -20,6 +20,7 @@ Details about QEMU's various subsystems including how to add features to them.
s390-cpu-topology
s390-dasd-ipl
tracing
uefi-vars
vfio-iommufd
writing-monitor-commands
virtio-backends

68
docs/devel/uefi-vars.rst Normal file
View file

@ -0,0 +1,68 @@
==============
UEFI variables
==============
Guest UEFI variable management
==============================
The traditional approach for UEFI Variable storage in qemu guests is
to work as close as possible to physical hardware. That means
providing pflash as storage and leaving the management of variables
and flash to the guest.
Secure boot support comes with the requirement that the UEFI variable
storage must be protected against direct access by the OS. All update
requests must pass the sanity checks. (Parts of) the firmware must
run with a higher privilege level than the OS so this can be enforced
by the firmware. On x86 this has been implemented using System
Management Mode (SMM) in qemu and kvm, which again is the same
approach taken by physical hardware. Only privileged code running in
SMM mode is allowed to access flash storage.
Communication with the firmware code running in SMM mode works by
serializing the requests to a shared buffer, then trapping into SMM
mode via SMI. The SMM code processes the request, stores the reply in
the same buffer and returns.
Host UEFI variable service
==========================
Instead of running the privileged code inside the guest we can run it
on the host. The serialization protocol can be reused. The
communication with the host uses a virtual device, which essentially
configures the shared buffer location and size, and traps to the host
to process the requests.
The ``uefi-vars`` device implements the UEFI virtual device. It comes
in ``uefi-vars-x86`` and ``uefi-vars-sysbus`` flavours. The device
reimplements the handlers needed, specifically
``EfiSmmVariableProtocol`` and ``VarCheckPolicyLibMmiHandler``. It
also consumes events (``EfiEndOfDxeEventGroup``,
``EfiEventReadyToBoot`` and ``EfiEventExitBootServices``).
The advantage of the approach is that we do not need a special
privilege level for the firmware to protect itself, i.e. it does not
depend on SMM emulation on x64, which allows the removal of a bunch of
complex code for SMM emulation from the linux kernel
(CONFIG_KVM_SMM=n). It also allows support for secure boot on arm
without implementing secure world (el3) emulation in kvm.
Of course there are also downsides. The added device increases the
attack surface of the host, and we are adding some code duplication
because we have to reimplement some edk2 functionality in qemu.
usage on x86_64
---------------
.. code::
qemu-system-x86_64 \
-device uefi-vars-x86,jsonfile=/path/to/vars.json
usage on aarch64
----------------
.. code::
qemu-system-aarch64 -M virt \
-device uefi-vars-sysbus,jsonfile=/path/to/vars.json