Add CCA Realm support to ArmVirtQemu#518
Add CCA Realm support to ArmVirtQemu#518jpbrucker wants to merge 78 commits intotianocore:arm-ccafrom
Conversation
Arm Confidential Compute Architecture (CCA) is a reference software architecture and implementation that builds on the Realm Management Extension (RME), enabling the execution of Virtual machines (VMs), while preventing access by more privileged software, such as hypervisor. The 'Realm Guest firmware' is an important part of the Arm CCA reference software stack. Support for Realm Guest firmware is not yet merged in the edk2 mainline and a PR to add initial support for Arm CCA guest firmware is in review at: tianocore/edk2#6480 A staging branch would allow more flexibility for integration and the review process without breaking/impacting the edk2 mainline. This branch will: - be used as an integration branch until the PRs have been satisfactorily reviewed for merging in edk2 mainline - provide a central location for developers to utilise the latest Realm Guest firmware code for testing, and reporting issues - serve as a baseline for developers to add new features - Remove the necessity of maintaining downstream forks. The description is in the Readme.md file. Please create the following branch: 1. edk2-staging Repo URL: https://github.com/tianocore/edk2-staging.git Branch Name: arm-cca Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The PrePiMemoryAllocationLib supports AllocateAlignedPages(), however is missing the corresponding FreeAlignedPages(). Although the FreeAlignedPages() in PrePiMemoryAllocationLib does not support the ability to free pages in the PrePei Memory Allocator and the allocated memory is lost, it would be good to have an empty implementation of FreeAlignedPages() so that implementations utilises the correct deallocation function. Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Add helper function to check if the Realm Management Extension (RME) is implemented by the hardware. Continuous-integration-options: PatchCheck.ignore-multi-package Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Arm CCA requires the software in a Realm to treat the most significant bit of an IPA as a protection attribute. To enable/disable sharing of memory regions with the host, the protection attribute needs to be set/cleared accordingly. Therefore, introduce SetMemoryProtectionAttribute() so that the memory regions can be shared/unshared with the host. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The Realm Management Monitor (RMM) is a software component which forms part of a system which implements the Arm Confidential Compute Architecture (CCA) and is responsible for management of Realms. The RMM specification defines a Realm Service Interface (RSI) that the Guest can use to request services from the RMM. Therefore, add a library that implements the RSI interfaces to: - query the RSI version - get the Realm configuration. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The IPA space of a Realm is divided into two halves: Protected IPA space and Unprotected IPA space. Software in a Realm should treat the most significant bit of an IPA as a protection attribute. A Protected IPA is an address in the lower half of a Realm's IPA space. An Unprotected IPA is an address in the upper half of a Realm's IPA space. A Protected IPA has an associated Realm IPA state (RIPAS). The RIPAS values are: * EMPTY - Unused address * RAM - Private code or data owned by the Realm. Software in the Realm needs to share memory with the host to communicate with the outside world, e.g. network, disk image, etc. To share memory, the software in the Realm first transitions the RIPAS of memory region it wants to share with the host from RAM to EMPTY. The Realm software can then access the shared memory region using the Unprotected IPA address. The RMM specification defines the following Realm Service Interfaces for managing the IPA state: * RSI_IPA_STATE_GET * RSI_IPA_STATE_SET Therefore, update the ArmCcaRsiLib to add interfaces to get and set the IPA state of Realm memory pages. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
A CCA attestation token is a collection of claims about the state of a
Realm and of the CCA platform on which the Realm is running.
A CCA attestation token consists of two parts:
* Realm token - Contains attributes of the Realm, including:
# Realm Initial Measurement
# Realm Extensible Measurements
* CCA platform token - Contains attributes of the CCA platform
on which the Realm is running, including:
# CCA platform identity
# CCA platform life cycle state
# CCA platform software component measurements
The CCA attestation token is used by a verification service to validate
these claims.
The Realm Service Interface defines the following interfaces to retrieve
an attestation token from the Realm Management Monitor (RMM).
- RSI_ATTESTATION_TOKEN_INIT
- RSI_ATTESTATION_TOKEN_CONTINUE
Therefore, update the ArmCcaRsiLib to add an interface to get an
attestation token from the RMM.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The Section A2.1.3 Realm attributes, RMM Specification, version A-bet0
introduces the concept of REMs as described below:
DGRFCS - A Realm Extensible Measurement (REM) is a measurement value
which can be extended during the lifetime of a Realm.
IFMPYL - Attributes of a Realm include an array of measurement values.
The first entry in this array is a RIM. The remaining entries
in this array are REMs.
The Realm Service Interface commands defined in section
B4.3.7 RSI_MEASUREMENT_READ and B4.3.6 RSI_MEASUREMENT_EXTEND
specify the interfaces to read and extend measurements to REMs.
Therefore, update ArmCcaRsiLib to add interfaces to get and extend REMs.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The Section A4.5 Host call, RMM Specification, version A-bet0
describes the programming model for Realm communication with
the Host and specifies the following:
DYDJWT - A Host call is a call made by the Realm to the Host, by
execution of the RSI_HOST_CALL command.
IXNFKZ - A Host call can be used by a Realm to make a hypercall.
DYDJWT - A Host call is a call made by the Realm to the Host, by
execution of the RSI_HOST_CALL command.
Therefore, introduce definition of HOST_CALL_ARGS structure that
represents the arguments to the RSI_HOST_CALL command as defined
in Section B4.3.3 RSI_HOST_CALL command.
Also update the ArmCcaRsiLib library to add a new interface
RsiHostCall () to make a Host call.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The IPA width of a Realm is read from the Realm Config by invoking the RSI call RSI_REALM_CONFIG to read the Realm Config. The IPA width is then stored in a GUID HOB gArmCcaIpaWidthGuid for subsequent use. This GUID HOB is also useful to pass the IPA width of the Realm to the DXE phase. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Add ArmCcaInitPeiLib library that performs the Arm CCA specific initialisation in the PEI phase like: - Configuring the system memory as Protected RAM. - Reading the Realm Config and storing the IPA width in a GUID HOB i.e., gArmCcaIpaWidthGuid for subsequent use. - Calling ArmCcaConfigureMmio () to configure the MMIO regions by setting the Unprotected IPA attribute in the page tables. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Add a NULL instance of ArmCcaInitPeiLib library that guest firmware for VMMs that do not implement Arm CCA Realms can use. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Introduce ArmCcaLib library that implements helper functions to: - probe if the code is executing in a Realm context - configure the protection attribute in page tables for the memory regions shared with the host - get the IPA width of the Realm which was stored in the GUID HOB gArmCcaIpaWidthGuid. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Add a Null instance of ArmCcaLib so that guest firmware that does not support Arm CCA can link to this Null version of the library. Also include it in ArmVirt.dsc.inc so that it is linked for the non-Arm CCA firmware builds. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The IPA space of a Realm is divided into two halves: - Protected IPA space and - Unprotected IPA space. Software in a Realm should treat the most significant bit of an IPA as a protection attribute. The Unprotected IPA space is used for sharing memory and for performing MMIO accesses with the Host. An Unprotected IPA is an address in the upper half of a Realm's IPA space. The most significant bit of an Unprotected IPA is 1. Therefore, the page tables for the MMIO regions must be updated to set the most significant bit of the IPA space. To facilitate this define ArmCcaConfigureMmio () that can be called during the early firmware startup. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
To support Arm CCA, a hook function ArmCcaConfigureMmio () has been added to the ArmVirtMemInfoLib library. Since, Arm CCA has not been enabled for the Cloud Hypervisor guest firmware, update the CloudHvVirtMemInfoLib library to add a NULL implementation for ArmCcaConfigureMmio () that returns RETURN_UNSUPPORTED. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
To support Arm CCA, a hook function ArmCcaConfigureMmio () has been added to the ArmVirtMemInfoLib library. Since, Arm CCA has not been enabled for the Qemu guest firmware, update the QemuVirtMemInfoLib library to add a NULL implementation for ArmCcaConfigureMmio () that returns RETURN_UNSUPPORTED. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
To support Arm CCA, a hook function ArmCcaConfigureMmio () has been added to the ArmVirtMemInfoLib library. Since, Arm CCA has not been enabled for the Xen guest firmware, update the XenVirtMemInfoLib library to add a NULL implementation for ArmCcaConfigureMmio () that returns RETURN_UNSUPPORTED. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The IPA space of a Realm is divided into two halves: - Protected IPA space and - Unprotected IPA space. Software in a Realm should treat the most significant bit of an IPA as a protection attribute. The Unprotected IPA space is used for sharing memory and for performing MMIO accesses with the Host. An Unprotected IPA is an address in the upper half of a Realm's IPA space. The most significant bit of an Unprotected IPA is 1. The page tables for the MMIO regions must be updated to set the most significant bit of the IPA space. Therefore, implement ArmCcaConfigureMmio () which configures the MMIO regions as Unprotected IPA by setting the protection attribute in the page tables for the MMIO regions. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The patch at "6c8a08bd8a680 ArmVirtPkg/PrePi: Ensure timely execution of library constructors" moved the processing of library constructors before the MMU is initialised. This resulted in the BaseDebugLibSerialPort library constructor BaseDebugLibSerialPortConstructor () which initialises the serial port, being invoked before the MMU is enabled. However, the Realm Code requires the protection attribute of the MMIO regions to be configured as unprotected (shared with the host), which requires the MMU to be enabled. Otherwise, accesses to the MMIO region result in a synchronous external abort being reflected to the Realm by the RMM. Therefore, link the Null version of DebugLib in PrePi stage. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The following libraries have been introduced for Arm CCA:
* ArmCcaInitPeiLib - provides functions for ARM CCA
initialisations in early PEI phase.
* ArmCcaLib - provides the necessary helper functions
for Arm CCA
* ArmCcaRsiLib - implements functions to call the Realm
Service Interface.
Therefore, add these libraries in the Kvmtool guest firmware
workspace as part of enabling support for Arm CCA.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
When a VMM creates a Realm, a small amount of DRAM (which contains the firmware image) and the initial content is configured as Protected RAM. The remaining System Memory is in the Protected Empty state. The firmware must then initialise the remaining System Memory as Protected RAM before it can be accessed. Therefore, call the ArmCcaConfigureSystemMemory () in the early Pei phase so that the System Memory is configured as Protected RAM. Note: ArmCcaConfigureSystemMemory () is implemented in ArmCcaInitPeiLib for which a Null implementation is provided. Therefore, this change should not have an impact for non-Arm CCA enabled systems. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Add ArmCcaInitialize () to perform Arm CCA specific initialisation like: - Reading the Realm Config by calling the RSI interface. - Storing the IPA width of the Realm in PcdArmCcaEarlyIpaWidth. - Configuring the MMIO regions to update the page tables to set the protection attribute as Unprotected IPA. Note: ArmCcaInitialize () is implemented in ArmCcaInitPeiLib for which a Null implementation is provided. Therefore, this change should not break existing platforms that do not implement the Arm CCA. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The Realm Aperture Management Protocol (RAMP) is used to manage the sharing of buffers between the Guest and Host. It configures the memory regions as Protected EMPTY or Protected RAM by calling RSI_IPA_STATE_SET command. The RAMP provides interfaces that device drivers can use to open/close apertures for sharing buffers. The RAMP also keeps track of the apertures that have been opened and closes them on ExitBootServices. It also registers for reset notification and closes all open apertures before the platform resets the system. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
On Arm CCA systems the access to pages inside the Realm is protected. However, software executing in a Realm needs to interact with the external world. This may be done using para virtualisation of the disk, network interfaces, etc. For this to work the buffers in the Realm need to be shared with the Host. The sharing and management of the Realm buffers is done by the Realm Aperture Management Protocol, which invokes the necessary Realm Service Interfaces to transition the buffers from Protected IPA to Unprotected IPA. The ArmCcaIoMmu driver provides the necessary hooks so that DMA operations can be performed by bouncing buffers using pages shared with the Host. It uses the Realm Aperture Management protocol to share the buffers with the Host. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Arm CCA Realms protect the access to memory from outside the Realm. For Virtio to work the Realm Guest and the Host should be able to share buffers. Realm Aperture Management protocol (RAMP) manages the sharing of buffers between the Realm Guest and the Host, while the ArmCcaIoMmuDxe implements the EDKII_IOMMU_PROTOCOL which provides the necessary hooks so that DMA accesses can be performed by bouncing buffers using pages shared with the host. Therefore, enable the support for Realm Aperture Management Protocol and ArmCcaIoMmuDxe for Kvmtool Guest firmware. Note: The ArmCcaIoMmuDxe and RAMP check if the code is executing in a Realm before installing the respective protocols. If the code is not executing in a Realm the gIoMmuAbsentProtocolGuid is installed, thereby allowing the same firmware to be used both for normal and Realm Guest firmware. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The BaseRngLib library constructor for AArch64 used to asserts if the RNDR instruction is not supported by the CPU, until the patch "4ddf2448ed3a MdePkg/BaseRngLib AARCH64: Remove overzealous ASSERT()" It would however be useful to have a warning message that is printed in the debug builds. Therefore, add a warning message to print if RNDR instruction is not supported by the processor. Also modify the computation of mRndrSupported value to be similar to the rest of the edk2 codebase. Note: - If RNDR instruction is not supported, the GetRandomNumberXXX functions will return FALSE to indicate that the random number generation has failed. It is expected that the calling function checks the status and handles this error appropriately. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Zhiguang Liu <zhiguang.liu@intel.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The RMM 1.0-bet1 updates the width of the RsiHostCall structure to 256 (0x100) bytes. Therefore, update the RSI HOST_CALL_ARGS structure to reflect these changes. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The RMM 1.0-bet2 spec expands the set of GPRs for RSI host call to X0-X30. Therefore, update the RSI HOST_CALL_ARGS structure to reflect these changes. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
The RMM 1.0-eac0 specification updates the parameter usage for the RSI_IPA_STATE_SET command to change the parameter 3 from IPA region size to Top of target IPA region. Therefore, update the RseSetIpaState () implementation to reflect this change. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Add QemuPlatformDxe which installs the Variable store emulation when a Flash device is not available. Link NorFlashQemuLib as a NULL library so that it can setup PcdEmuVariableNvModeEnable. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
When code in .text uses adrp to obtain an address from .data, if the sections don't have the same alignment modulo 4KB, GenFw fails with: WriteSections64(): Build/ArmVirtQemu-AARCH64/RELEASE_GCC5/AARCH64/ArmPlatformPkg/Sec/Sec/DEBUG/Sec.dll AARCH64 small code model requires identical ELF and PE/COFF section offsets modulo 4 KB. Since we will need to move ID-map to .data and introduce a writable buffer for CCA, define the section alignment to 4kB. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
As we're about to introduce more identity mappings into IdMap.S, introduce a macro that create identity PTEs, to make the page table code more readable. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
…ART idmap In a realm, we'll need to patch the early page tables to access the emulated uart through the unprotected IPA range. Add a third level table for the VA range which contains the UART. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
A Realm needs to access emulated devices via the unprotected IPA range (upper IPA bit set). After probing the RMM using some RSI calls, update the page table entry that maps the UART. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Pull in the Arm CCA libraries needed for discovering the address space width and sharing DMA memory with the VMM. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
When creating the identity mapping, copy the 'unprotected' top bit from the physical address as an attribute in the PTE. The virtual address then points to the top half of the address space, which in a Realm is the unprotected half, shared with the host. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
…r CCA A Realm guest needs to access peripherals emulated with the host with the 'unprotected' bit set (most significant bit of the Intermediate Physical Address). Initialize the page tables with all device mappings. When launching QEMU with more than 254M of potential RAM, the high PCIe regions are shifted to make space for RAM. Find their location in the device tree. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> QemuVirtMemInfoLib: Parse device-tree to find the PCIe registers Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
To ensure I/O buffers are shared with the host, add those libs Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Add a small module that calls ArmCcaInitPeiLib function to initialize the Realm address space. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Before MMU initialization, call the ArmCcaInitPei function to detect whether we're in a Realm, and provide the IPA width which is needed to setup device mappings. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
…tributes An 'unprotected' bit set by ArmCcaConfigureMmio() may get cleared later by ArmSetMemoryAttributes(). For example the PCIe ECAM region on QEMU is mapped late by MapGcdMmioSpace(). Ensure the 'unprotected' bit does not get cleared. Note that we should probably consolidate this: ArmCcaConfigureMmio() initializes those page table entries as valid even though they don't have the correct memory attributes yet. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
The ArmCcaIoMmuDxe driver depends on gEfiRealmApertureManagementProtocolGuid, and produces either gEdkiiIoMmuProtocolGuid or gIoMmuAbsentProtocolGuid. Other drivers, for example those including QemuFwCfgLibMmio, thus depend on either the IOMMU or IOMMU Absent protocol. Since ArmCcaIoMmuDxe only produces gEfiRealmApertureManagementProtocolGuid when in a Realm at the moment, those drivers cannot be loaded when not in a Realm, and boot doesn't reach BDS. Add an empty instance of gEfiRealmApertureManagementProtocolGuid so that ArmCcaIoMmuDxe always produces something and unblocks other drivers. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Signed-off-by: Dhanus M Lal <Dhanus.MLal@fujitsu.com>
Add a NULL library for non-x86 platforms that need the IoMmuDxe driver without SEV and TDX. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
As the ArmVirtQemu platforms are getting support for confidential computing, they needs to start supporting IOMMU protocols that share and unshare DMA buffers with the host. This means we'll need to ensure that the driver that provides the IOMMU protocol and client drivers that perform DMA are loaded in the right order. For instance QemuFwCfgLibMmio needs new Depex entries so that drivers including this library are loaded after either gEdkiiIoMmuProtocolGuid or gIoMmuAbsentProtocolGuid get produced. Since RiscVVirtQemu uses QemuFwCfgLibMmio, it now needs something that produces gIoMmuAbsentProtocolGuid. Include IoMmuDxe for this purpose. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> --- Only build-tested
When running in a realm, we must explicitly share DMA buffers with the host. Use the IoMmuProtocol when available. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
The ArmVirtQemu guest firmware loads the kernel and initrd images from the host through the FwCfg device. When running in a realm, measure those images and add them to the realm measurement, so that the realm owner can later authenticate them. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Use the Arm CCA BlobVerifier to add hashes of FwCfg images to the realm measurement. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
When run early in the QEMU boot, writing the static variable FlagsInitialised causes a Synchronous Exception. Supposedly the data page containing the static variable isn't mapped writable at this point, but I didn't investigate further. Use a GUID HOB to cache the variable. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
|
This latest version adds support for VMs with more than 254G of RAM, where the shared PCIe MMIO region is shifted and needs to be found in device tree. |
SummaryPR #518 currently breaks the Kvmtool guest firmware. The issue appears to be caused by:
To facilitate broader testing and alignment, I have integrated the PR #518 changes into the edk2-staging/arm-cca branch. Changes in the Kvmtool Guest firmware series.
PR #518 IntegrationThe following patches from PR #518 were cherry-picked and merge conflicts resolved:
|
|
We have tested the ArmVirtQemu firmware with Google's internal VMM and successfully booted a Realm guest. |
@hajirazaman Thank you for testing the edk2-staging/arm-cca branch and reporting back. |
I’ve just tested PR tianocore/edk2#12224 and successfully booted a Confidential VM. I left a comment in that PR thread as well. |
These patches add support for ArmVirtQemu to be run in a Realm guest. A lot of it is just plumbing to use the Arm CCA libraries, for example to create DMA mappings in the shared IPA region. We also need to create a mapping to access the shared UART early, enabled emulated variable storage, and measure blobs loaded via fw_cfg.
Long term it would be good to create a single EDK2 platform for Realms rather than one per VMM, for a number of reasons:
Although I started working on this, it's unlikely I will have time to complete anytime soon. Adding CCA support to ArmVirtQemu is easier for now.