mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-26 20:03:54 -06:00
docs: add uefi variable service documentation
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-ID: <20250225163031.1409078-25-kraxel@redhat.com>
This commit is contained in:
parent
06fa8ec6f6
commit
2bc10b15de
3 changed files with 76 additions and 0 deletions
|
@ -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
68
docs/devel/uefi-vars.rst
Normal 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
|
7
hw/uefi/LIMITATIONS.md
Normal file
7
hw/uefi/LIMITATIONS.md
Normal file
|
@ -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…
Add table
Add a link
Reference in a new issue