Skip to content

Conversation

@samimujawar
Copy link

Description

This v4 series enables the Arm Confidential Compute Architecture (CCA)
support for the Kvmtool guest firmware and is aligned with the ARM CCA
RMM 1.0-rel0 specification.

In addition to the RMM 1.0-rel0 specification updated this series has
been rebased with the latest edk2 & edk2-platforms codebase and the
intention is to integrate the Arm CCA support in ArmVirtPkg and enable
the guest firmware support for Realms.

Summary of updates in this v4 Series:

  1. This series is a rebased version of the v3 series at:
    Support for Arm CCA guest firmware v3 (RMM-v1.0-rel0) edk2#6480
  2. The patch "[PATCH v3 03/57] ArmPkg: Extend number of
    parameter registers in SMC" has been dropped as it is no
    longer required.
  3. The feedback raised for the v3 series is not yet addressed and
    the plan is to discuss and address those as part of this pull request.

Summary of updates in the previous v3 Series:

  1. Updates to align with RMM 1.0-rel0 specification.
  2. Add support to parse the Kvmtool guest VM Device Tree
    and populate the memory map accordingly.
  3. Check if the MMIO range is for a protected Realm device
    and if so, skip configuring the shared attribute for the
    MMIO region.
  4. Add check to conditionally install the IORT table if
    a GIVc3-ITS is present.

Summary of updates in the previous v2 Series:

  1. Variable emulation support patches that we part of v1 series
    are already merged, hence dropped from this series.
  2. SetMemoryRegionAttributes() was dropped in the upstream
    code. Therefore, introduced SetMemoryProtectionAttribute()
    to configure the top bit of the Realm IPA space which is
    used as the protection bit
  3. The patch to add the APRIORI Dxe ArmCcaDxe has been dropped.
  4. Dropped patch that configured PcdMonitorConduitHvc as a
    dynamic PCD, and introduced ArmVirtMonitorLib, a new
    instance of the ArmMonitorLib that reads the conduit to
    be used from the FDT.
  5. Bug fixes to correct the size of IMM field in RSI Host
    Call arguments, and to correct the RSI Version mask
  6. Patches 32 to 43 include updates to the firmware support
    to RMM specification v1.0-EAC5.
  7. Minor optimisations, e.g. to cache the current world value.

Introduction

Arm Confidential Compute Architecture (CCA)

Arm 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. Arm CCA allows the hypervisor to control
the VM, but removes the right for access to the code, register state or
data used by VM.

More information on the architecture is available here [1].


        Realm World     ||    Normal World   ||  Secure World  ||
                        ||        |          ||                ||
 EL0 x---------x        || x----x | x------x ||                ||
     | Realm   |        || |    | | |      | ||                ||
     |  VM*    |        || | VM | | |      | ||                ||
     |x-------x|        || |    | | |      | ||                ||
     ||       ||        || |    | | |  H   | ||                ||
     || Guest ||        || |    | | |      | ||                ||
 ----||  OS   ||--------||-|    |---|  o   |-||----------------||
     ||       ||        || |    | | |      | ||                ||
     |x-------x|        || |    | | |  s   | ||                ||
     |    ^    |        || |    | | |      | ||                ||
     |    |    |        || |    | | |  t   | ||                ||
     |+-------+|        || |    | | |      | ||                ||
     || REALM ||        || |    | | |      | ||                ||
     || GUEST ||        || |    | | |  O   | ||                ||
     || UEFI  ||        || |    | | |      | ||                ||
     |+-------+|        || |    | | |  S   | ||                ||
 EL1 x---------x        || x----x | |      | ||                ||
          ^             ||        | |      | ||                ||
          |             ||        | |      | ||                ||
 -------- R*------------||----------|      |-||----------------||
          S             ||          |      | ||                ||
          I             ||      x-->|      | ||                ||
          |             ||      |   |      | ||                ||
          |             ||      |   x------x ||                ||
          |             ||      |       ^    ||                ||
          v             ||     SMC      |    ||                ||
      x-------x         ||      |   x------x ||                ||
      |  RMM* |         ||      |   | HOST | ||                ||
      x-------x         ||      |   | UEFI | ||                ||
          ^             ||      |   x------x ||                ||
 EL2      |             ||      |            ||                ||
          |             ||      |            ||                ||
 =========|=====================|================================
          |                     |
          x------- *RMI* -------x

 EL3                   Root World
                       EL3 Firmware
 ===============================================================

Where:
RMM - Realm Management Monitor
RMI - Realm Management Interface
RSI - Realm Service Interface
SMC - Secure Monitor Call

RME introduces two added additional worlds, "Realm world" and "Root
World" in addition to the traditional Secure world and Normal world.
The Arm CCA defines a new component, Realm Management Monitor (RMM)
that runs at R-EL2. This is a standard piece of firmware, verified,
installed and loaded by the EL3 firmware (e.g., TF-A), at system boot.

The RMM provides a standard interface Realm Management Interface (RMI)
to the Normal world hypervisor to manage the VMs running in the Realm
world (also called Realms). These are exposed via SMC and are routed
through the EL3 firmware.

The RMM also provides certain services to the Realms via SMC, called
the Realm Service Interface (RSI). These include:

  • Realm Guest Configuration
  • Attestation & Measurement services
  • Managing the state of an Intermediate Physical Address (IPA aka GPA)
    page
  • Host Call service (Communication with the Normal world Hypervisor).

This patch series aligns with the RMM v1.0-rel0 specification, and
the latest version is available here [2].

The Trusted Firmware foundation has an implementation of the RMM -
TF-RMM - available here [4].

Implementation

This version of the Realm Guest UEFI firmware is intended to be
used with the Linux Kernel stack[7] which is also based on the
RMM specification v1.0-rel0[3].

This release includes the following features:
a) Boot a Linux Kernel in a Realm VM using the Realm Guest UEFI
firmware
b) Hardware description is provided using ACPI tables
c) Support for Virtio v1.0
d) All I/O are treated as non-secure/shared
e) Load the Linux Kernel and RootFS from a Virtio attached disk
using the Virtio-1.0 PCIe transport.

Overview of updates for enabling Arm CCA

The Arm CCA implementation is spread across a number of libraries
that provide required functionality during various phases of the
firmware boot.

The following libraries have been provided:
i. ArmCcaInitPeiLib - A library that implements the hook functions
in the PEI phase
ii. ArmCcaLib - A library that implements common functions like
checking if RME extension is implemented and to configure the
Protection attribute for the memory regions
iii. ArmCcaRsiLib - A library that implements the Realm Service
Interface functions.

A NULL implementation of the ArmCcaInitPeiLib and ArmCcaLib is also
provided for platforms that do not implement the RME extensions.

Additionally, the following DXE modules have been provided to implement
the required functionality in the DXE phase.
i. RealmApertureManagementProtocolDxe - A DXE that implements the
Realm Aperture Management Protocol, used to manage the sharing
of buffers in a Realm with the Host
ii. ArmCcaIoMmuDxe - A driver which implements the EDKII_IOMMU_PROTOCOL
that provides the necessary hooks so that DMA operations can be
performed by bouncing buffers using pages shared with the Host.

Arm CCA updates in PEI phase

For supporting Arm CCA two hooks have been added in the PrePi module:
i. An early hook to configure the System Memory as Protected RAM
ii. A second hook after the MMU is initialised to perform the
remaining CCA initialisations like reading the Realm Config
to determine the IPA width of the realm, configuring the
Protection attribute for the MMIO regions, etc.

These hook functions are implemented in ArmCcaInitPeiLib. A NULL
version of the library has also been provided for implementations
that do not have the RME extensions.

Additionally, the ArmVirtMemInfoLib has been updated to implement
a platform specific hook function ArmCcaConfigureMmio() that can
configure the protection attribute for the MMIO regions for the
platform.


   +=====+
   |PrePi|
   +=====+
      |
      _ModuleEntryPoint()
      ===================
              |
              DiscoverDramFromDt()
              |
              +--> ArmCcaInitPeiLib|ArmCcaConfigureSystemMemory()
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                             |      // configure System Memory
              ----------------      // as Protected RAM.
              |
             ...
              |
      --------
      |
      CEntryPoint()
      |
      PrePiMain()
      ===========
          |
         ...
          |
          ProcessLibraryConstructorList()
          |
          MemoryPeim()
          |
          ArmCcaInitPeiLib|ArmCcaInitialize()  // Perform Arm CCA
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // initialisations,
                   |                           // like reading the
                   |                           // Realm Config, etc.
                   |
                   ArmVirtMemInfoLib|ArmCcaConfigureMmio()
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                          |   // Configure Protection attribute
                   --------   // for the MMIO region.
                   |
          ----------
          |
         ...
          |
        +===+
        |DXE|
        +===+

Building the UEFI firmware

a. Set up the development environment
Follow the steps as described in
https://github.com/tianocore/edk2-platforms/blob/master/Platform/ARM/Readme.md

b. The source code for the Host and Realm Guest firmware can
be downloaded from [12].

c. Building the Host UEFI firmware for FVP Base RevC AEM Model
Follow the instructions in
https://github.com/tianocore/edk2-platforms/blob/master/Platform/ARM/Readme.md
to "Build the firmware for Arm FVP Base AEMv8A-AEMv8A model
platform" based on your development environment configuration.

Note: The same firmware binary can be used for both the Arm FVP
Base AEMv8A-AEMv8A and the FVP Base RevC AEM Model.

d. Building the Realm Guest UEFI firmware for kvmtool:
To build the kvmtool guest firmware, run the following commands:

   $build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtKvmTool.dsc -b DEBUG
   $build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtKvmTool.dsc -b RELEASE

The Kvmtool guest firmware binaries are at the following location:

   $WORKSPACE/Build/ArmVirtKvmTool-AARCH64/<DEBUG|RELEASE>_GCC5/FV/KVMTOOL_EFI.fd

Running the stack

To run/test the stack, you would need the following components:

i. FVP Base AEM RevC model with FEAT_RME support [5]
ii. TF-A firmware for EL3 [6]
iii. TF-A RMM for R-EL2 [4]
iv. Linux Kernel [7]
v. kvmtool [8]
vi. UEFI Firmware for Arm CCA [12].

Instructions for building the remaining firmware components and
running the model are available here [10]. Once, the host kernel
has finished booting, a Realm can be launched by invoking the
lkvm command as follows:

 $ lkvm run --realm \
   --restricted_mem \
   --measurement-algo=["sha256", "sha512"] \
   --firmware KVMTOOL_EFI.fd \
   -m 512 \
   --irqchip=gicv3-its \
   --force-pci \
   --disk <Disk image containing the Guest Kernel & RootFS>
   <normal-vm-options>

Where:

  • --measurement-algo (Optional) specifies the algorithm selected for
    creating the initial measurements by the RMM for this Realm (defaults
    to sha256)
  • GICv3 is mandatory for the Realms
  • --force-pci is required as only Virtio-v1.0 PCIe transport is
    supported.

Links

[1] Arm CCA Landing page (See Key Resources section for various documentations)
https://www.arm.com/armcca

[2] RMM Specification Latest
https://developer.arm.com/documentation/den0137/latest

[3] RMM v1.0-rel0 specification
https://developer.arm.com/documentation/den0137/1-0rel0

[4] Trusted Firmware RMM - TF-RMM
https://www.trustedfirmware.org/projects/tf-rmm/
GIT: https://git.trustedfirmware.org/TF-RMM/tf-rmm.git
Branch: main
SHA: 5f9ddf18bf5295c705c0e79fe1b60e34aba11198

[5] FVP Base RevC AEM Model (available on x86_64 / Arm64 Linux)
https://developer.arm.com/Tools%20and%20Software/Fixed%20Virtual%20Platforms

[6] Trusted Firmware for A class
https://www.trustedfirmware.org/projects/tf-a/
Branch: master
SHA: 61cdb4545b7de576d8ba18e746033d2c89e4f6c7

[7] Linux kernel support for Arm-CCA
https://gitlab.arm.com/linux-arm/linux-cca
Full stack branch: cca/cca-full/latest
SHA: 78b23c56de79838e09b5594b5281c93562e0f976

[8] kvmtool support for Arm CCA
https://gitlab.arm.com/linux-arm/kvmtool-cca
Branch: cca/latest
SHA: 0310eb6aa59f48786f38bfb12f2fa537ef33a890

[9] kvm-unit-tests support for Arm CCA
https://gitlab.arm.com/linux-arm/kvm-unit-tests-cca
Branch: cca/v2

[10] Instructions for Building Firmware components and running the model, see
section 4.19.2 "Building and running TF-A with RME"
https://trustedfirmware-a.readthedocs.io/en/latest/components/realm-management-extension.html#building-and-running-tf-a-with-rme

[11] RFC series posted previously for adding support for Arm CCA guest firmware:
v3: tianocore/edk2#6480
v2: https://edk2.groups.io/g/devel/message/117716
v1: https://edk2.groups.io/g/devel/message/103581

[12] UEFI Firmware support for Arm CCA
Host & Guest Support:
- Repo:
edk2: https://gitlab.arm.com/linux-arm/edk2-cca
edk2-platforms: https://gitlab.arm.com/linux-arm/edk2-platforms-cca
- Branch: 3223_arm_cca_v4


  • Breaking change?
    No
  • Impacts security?
    No
  • Includes tests?
    See ‘Running the stack’ section above.

How This Was Tested

See ‘Running the stack’ section above.

Integration Instructions

N/A

Copy link
Author

@samimujawar samimujawar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have marked in all the review feedback from the v3 series PR i.e. tianocore/edk2#6480

[LibraryClasses.AARCH64]
ArmCcaLib|ArmVirtPkg/Library/ArmCcaLib/ArmCcaLib.inf
ArmCcaRsiLib|ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.inf
RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HwInfoParser/FdtInfoParser.h
HwInfoParser/FdtUtility.c
HwInfoParser/FdtUtility.h
HwInfoParser/Pci/PciConfigSpaceParser.c
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//
Isar0 = ArmReadIdAA64Isar0Reg ();
mRndrSupported = !!((Isar0 >> ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT) & ARM_ID_AA64ISAR0_EL1_RNDR_MASK);
mRndrSupported = (((Isar0 >> ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT) &
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DEVICE_INFO Dev[MAX_PLAT_DEVICE_COUNT];
/// The max count of devices.
UINTN MaxDevices;
} PLATFROM_DEVICE_INFO;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ARM_SMC_ARGS SmcCmd;

if ((Size == 0) ||
((Size & (REALM_GRANULE_SIZE - 1)) != 0) ||
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SmcCmd.Arg1 = FeatureRegIndex;

ArmCallSmc (&SmcCmd);
*FeatureRegValue = SmcCmd.Arg1;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

*RmmImplLow = (SmcCmd.Arg1 & RSI_VERSION_MASK);
*RmmImplHigh = (SmcCmd.Arg2 & RSI_VERSION_MASK);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RsiGetVersion (
OUT UINT32 *CONST UefiImpl,
OUT UINT32 *CONST RmmImplLow,
OUT UINT32 *CONST RmmImplHigh
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See Section A2.2, RMM Specification, version A-bet0
DNBXXX A Granule is a unit of physical memory whose size is 4KB.
*/
#define REALM_GRANULE_SIZE SIZE_4KB
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exit_handler:
// Scrub the Granule buffer
ZeroMem (Granule, REALM_GRANULE_SIZE);
FreePages (Granule, EFI_SIZE_TO_PAGES (REALM_GRANULE_SIZE));
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

samimujawar added 28 commits May 6, 2025 17:30
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 <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
Add a NULL instance of ArmCcaInitPeiLib library that guest firmware
for VMMs that do not implement Arm CCA Realms can use.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Cc: Michael D Kinney <[email protected]>
Cc: Liming Gao <[email protected]>
Cc: Zhiguang Liu <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
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 <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
samimujawar added 26 commits May 6, 2025 17:32
The RMM 1.0-eac2 specification updates the RsiRealmConfig
structure to add a new member to identify the Realm hash
algorithm.

Therefore, update the REALM_CONFIG structure to add a
new member HashAlgorithm that represents the Realm hash
value. Also add macros to define the RsiHashAlgorithm
enumeration values SHA-256 and SHA-512.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The RMM specification 1.0-eac2 updates the RIPAS state
to add a new DESTROYED state for an address which is
inaccessible to the Realm due to an action taken by
the Host.

Therefore, update the RSI RIPAS state enum to add the
new RIPAS_DESTROYED state.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The RMM specification 1.0-eac2 updates the RSI_IPA_STATE_SET
interface to add a new parameter RsiRipasChangeFlags.

The RsiRipasChangeFlags fieldset is 64 bits and the bit 0
describes the RsiRipasChangeDestroyed type which is used
to indicate if a RIPAS change from DESTROYED should be
permitted or not.

Therefore, define the macros for specifying the
RsiRipasChangeFlags that represent the
RsiRipasChangeDestroyed type.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The RMM specification 1.0-eac2 updates the RSI_IPA_STATE_SET
interface to add a new parameter RsiRipasChangeFlags.

The RsiRipasChangeFlags fieldset is 64 bits and the bit 0
describes the RsiRipasChangeDestroyed type which is used
to indicate if a RIPAS change from DESTROYED should be
permitted or not.

Therefore, update the RsiSetIpaState() to add a new
parameter for specifying the RsiRipasChangeFlags.

Also update the usage of RsiSetIpaState() in:
 - ArmCcaInitPeiLib setting the flag to
   RIPAS_CHANGE_FLAGS_RSI_NO_CHANGE_DESTROYED.
   Since we are configuring the RAM at boot,
   prevent converting anything that might have
   been DESTROYED by the host.
 - RealmApertureManagementProtocolDxe to set the
   flag to RIPAS_CHANGE_FLAGS_RSI_CHANGE_DESTROYED.
   Since we are reclaiming the memory from Shared,
   and we do not rely on the "previous contents"
   of the page, allow transition from DESTROYED.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The RMM 1.0-eac3 specification extends the RSI_IPA_STATE_SET
command to return a new RsiResponse value to indicate if the
Host accepts or rejects the IPA state change request to RAM.

Therefore, define the RsiResponse enum and return an error
RETURN_ACCESS_DENIED if the Host rejects the RIPAS change
request to RAM.

Such a failure is fatal and not recoverable and the caller
is then expected to tear down the Realm.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The RMM 1.0-eac3 specification prohibits the RIPAS RSI_DESTROYED
as an input value in a call to RSI_IPA_STATE_SET.

The specification further documents the following conditions in
section B5.3.6.2 Failure conditions

  ripas_valid pre: (ripas != RSI_EMPTY) && (ripas != RSI_RAM)
              post: result == RSI_ERROR_INPUT

Therefore, validate the RIPAS input parameter passed to
RsiSetIpaState().

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Cc: Pierre Gondois <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The RMM 1.0-eac4 introduces a new FID  RSI_FEATURES
to query the RSI features supported that have been
implemented.

Therefore, introduce a new function RsiGetFeatures
to query the features supported by the RSI.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The RMM 1.0-eac3 specification removed the restriction that
attestation token size must not exceed 4KB. Further it also
extended the RSI_ATTESTATION_TOKEN_CONTINUE command so as to
return up to a granule worth of the attestation token data.

The RMM 1.0-eac5 specification simplified the attestation
token interfaces such that, the RSI_ATTESTATION_TOKEN_INIT
command returns the upper bound of the attestation token
size. This eliminates the need for relocation of token data
buffers during attestation token retrieval.

Therefore, implement the attestation token API updates
from RMM 1.0-eac3 through to RMM 1.0-eac5 specification.

Note: The RsiGetAttestationToken() API has been modified
such that ArmCcaRsiLib allocates memory for the returned
attestation token buffer. The caller is therefore required
to call RsiFreeAttestationToken() to free the memory that
was allocated for the attestation token buffer.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The RMM 1.0-eac5 specification updates the RSI version command
to return the highest interface revision which is supported by
the RMM and the lower revision value which indicates:
  a. The RMM supports an interface revision which is compatible
     with the requested revision and the lower revision is equal
     to the requested revision and the status code is RSI_SUCCESS
  b. The RMM does not support the requested version, but the RMM
     supports an interface revision which is lower than the
     requested revision and the status code is RSI_ERROR_INPUT
  c. The RMM does not support an interface revision which is
     compatible with the requested revision and that it supports
     an interface revision that is greater than the requested
     revision. The status code is RSI_ERROR_INPUT and the lower
     revision is equal to the higher revision.

Therefore, update the RsiGetVersion() to return the lower and
higher revision that is supported by the RMM. The RsiGetVersion
function also returns the RSI version that is implemented by
the firmware.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
IsRealm() probes to check if the code is executing
in a Realm context by checking if RME is supported
and then issuing a RSI_VERSION command to check it
is supported.

Instead of calling RSI_VERSION command every time the
IsRealm() is called, cache the world value we are
running in, to return the value in subsequent calls.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The patch at "049695a0b1e2 MdeModulePkg/PciBusDxe: Add feedback
status for PciIoMap" adds support to propagate the error code
following the invocation of the IoMmu protocol SetAttribute()
operation.

Since the ArmCcaIoMmuDxe implementation of the SetAttribute()
function returned EFI_UNSUPPORTED, it resulted in the virtio
disk not being mounted.

Although there is nothing to be done in SetAttribute(), follow
the approach as done by the patch at "97c3f5b8d272  Provide an
implementation for SetAttribute" to validate the IoMmu access
method being requested against the IoMmu mapping operation and
return a suitable return code.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The section A5.2.2 'Realm IPA state' in the RMM 1.0-rel0 spec
introduces a new Realm IPA state value to represent address
where memory of an assigned Realm device is mapped.

Therefore, update the RIPAS enum to add RipasDev.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The section B5.3.5 'RSI_IPA_STATE_GET command' of the RMM 1.0-rel0
specification extends the RSI_IPA_STATE_GET command to take the
End of the target IPA region as input in addition to the Base of
the IPA region, and returns the Top of IPA region which has the
reported RIPAS value.

Therefore, update the RsiGetIpaState() to reflect the addition
of this IPA range parameter.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The RMM 1.0-rel0 specification updates the RealmConfig
to add a Realm Personalisation Value (RPV), which is
a 64 byte string that can be used to differentiate or
identify a Realm. The RPV value is provided as an input
parameter to the VMM when launching a Realm.

Therefore, update the RealmConfig structure to add a
new field for the RPV. Also add some helper macros
for defining the RealmConfig structure.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The RMM 1.0-rel0 specification introduced a new error code to
indicate that the attestation token generation failed for an
unknown or IMPDEF reason.

Therefore, define the new error code and update the code to
handle the error accordingly.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
Introduce a platform device info library that
parses the FDT and extracts the MMIO base address
and the range for the devices present in the FDT.

This is useful for populating the memory map for a
platform. e.g. the Kvmtool memory map is currently
configured such that the address range outside the
DRAM range is considered as peripheral memory.

Although this currently works, starting with the
RMM 1.0 - rel0 specification, it is expected
that the firmware queries the RMM to get the IPA
state for the MMIO address ranges for the devices
to determine if the shared attribute must be set.
If the IPA state is returned as RIPAS device,
the shared attribute must not be set for the
device. Otherwise the shared attribute needs to be
set for the MMIO address range covering the device
as it is emulated by the VMM.

The files in this library are a scaled down version
of the DynamicTablesPkg/Library/FdtHwInfoParserLib
wherein the parsers only parse the device MMIO base
addresses and range. The functionality to parse
other device information e.g. interrupts, etc.
and to populate the Configuration Manager objects
has been removed.

In this patch the initial infrastructure for parsing
the FDT and populating the PLATFROM_DEVICE_INFO
structure is implemented. Subsequent patches shall
introduce the functionality to parse the device
information.

This PLATFROM_DEVICE_INFO populated by this library
is useful for populating the memory map for the
platform devices and can be utilised by other
architectures. Therefore, add this library to OVMF
package.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
Add functionality to parse the GIC objects from the
FDT and populate the PLATFORM_DEVICE_INFO structure.

This patch adds functionality to parse the following
GIC components and populate their base address and
range in the PLATFORM_DEVICE_INFO structure.
 - GICC
 - GICD
 - GICR

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
Add functionality to parse the PCI components from the
FDT and populate the PLATFORM_DEVICE_INFO structure.

This patch adds functionality to parse the following
PCI components and populates their base address and
range in the PLATFORM_DEVICE_INFO structure.
 - PCI Configuration Space
 - PCI I/O Space
 - PCI 32bit Mem
 - PCI 64bit Mem

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
Add functionality to parse the FDT for the MMIO base address
and range using the compatibility string provided for a device
and populate the PLATFORM_DEVICE_INFO structure.

This common parsing functionality can then be used to extract
information from devices that follow the generic device register
representation scheme.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
Add functionality to parse the Serial port information from
the FDT using the previously introduced generic device parser
and populate the PLATFORM_DEVICE_INFO structure.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
Add functionality to parse the Real Time Clock (RTC) info
from the FDT using the previously introduced generic device
parser and populate the PLATFORM_DEVICE_INFO structure.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
The memory map for the peripherals available for a Guest VM
launched using Kvmtool is currently populated by treating
all the memory before and after the System DRAM as device
memory.

With the introduction of PlatfromDeviceInfoLib it is
now possible to get the MMIO base address and range for
the devices that are present in the FDT.

Therefore, use the PlatfromDeviceInfoLib to get the
PLATFORM_DEVICE_INFO and populate the mem map accordingly.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
Realm Devices are protected devices and are not emulated by
the VMM. The RIPAS value for the MMIO address range for these
devices is RipasDev indicating the address range is protected
MMIO.

Therefore, introduce an helper function to check if the MMIO
address range is protected MMIO by issuing RSI_IPA_STATE_GET
commands.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
Realm Devices are protected devices and are not emulated by
the VMM. The protection attribute for the MMIO regions
covered by these devices must not be set as Unprotected IPA.

Therefore, call the ArmCcaLib ArmCcaMemRangeIsProtectedMmio()
helper function passing in the MMIO base address and range,
to check if the address range is marked as RIPAS_DEV (which
indicates a Realm Device).

The ArmCcaConfigureMmio() then excludes the MMIO address
range for the Realm Devices from being configured as
Unprotected IPA.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
When the Kvmtool guest is launched without ITS support
i.e. when --irq-chip=gicv3-its option is not specified
or if --irq-chip=gicv3 is specified, the guest VM does
not have an ITS.

In such scenarios the guest firmware must not install
the IORT table. Therefore, add checks to see if ITS is
present before installing the IORT ACPI table.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Signed-off-by: Sami Mujawar <[email protected]>
Add support to tear down all mappings on reset.

Signed-off-by: Sami Mujawar <[email protected]>
@samimujawar
Copy link
Author

I have addressed all the feedback except tianocore/edk2#6480 (comment)
which I think will need some alignment.

@samimujawar samimujawar merged commit f89025e into tianocore:arm-cca May 6, 2025
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants