Browse Source
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-ID: <20250225163031.1409078-25-kraxel@redhat.com>pull/291/head
3 changed files with 76 additions and 0 deletions
@ -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 |
||||
@ -0,0 +1,7 @@ |
|||||
|
known issues and limitations |
||||
|
---------------------------- |
||||
|
|
||||
|
* works only on little endian hosts |
||||
|
- accessing structs in guest ram is done without endian conversion. |
||||
|
* works only for 64-bit guests |
||||
|
- UINTN is mapped to uint64_t, for 32-bit guests that would be uint32_t |
||||
Loading…
Reference in new issue