Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

About

  • This document discussed about EDK2 Standalone MM design for RISC-V. Before continuing this document, it is recommend to read this good document about how Standalone MM/Traditional MM designed: https://microsoft.github.io/mu/dyn/mu_feature_mm_supv/MmSupervisorPkg/Docs/StandaloneMmOverview/standalone_mm_framework/
  • This document discussed how Standalone MM is implemented for RISC-V. As RISC-V specs is open source and vendors can choose to follow a ratified extension to create Standalone MM, the design of Standalone MM for RISC-V should be portable, minimum footprint.
  • Currently, there are 2 ways to launch Standalone MM that has POC approved:
    • Based on Salus (https://github.com/rivosinc/salus) following APTEE specs (not yet ratified)
      • Overview of Salus:
      •   +---U-mode--+ +-----VS-mode-----+ +-VS-mode-+
          |           | |                 | |         |
          |           | | +---VU-mode---+ | |         |
          |   Salus   | | | VMM(crosvm) | | |  Guest  |
          | Delegated | | +-------------+ | |         |
          |   Tasks   | |                 | |         |
          |           | |    Host(linux)  | |         |
          +-----------+ +-----------------+ +---------+
                |                |               |
           TBD syscall   SBI (COVH-API)    SBI(COVG-API)
                |                |               |
          +-------------HS-mode-----------------------+
          |       Salus                               |
          +-------------------------------------------+
                                 |
                                SBI
                                 |
          +----------M-mode---------------------------+
          |       Firmware(OpenSBI)                   |
          +-------------------------------------------+
      • EDK2 run in VS-mode (Host) then use COVH-API that talks to Salus to create guest TVM in VS-mode.
        • Confidential memory created which converted from EDK2 non-confidential memory. The memory can only be used in Guest.
        • The Standalone MM FD binary is measured and copy to guest memory.
        • The Standalone MM entry point is called then start initialization.
        • After Standalone MM finishes booting, EDK2 takes the control and continuing booting
        • When a request need to sent to Standalone MM, EDK2 copies request content (MM Protocol) to a shared non confidential memory then uses COVH-API to trigger Standalone MM run and serve the request
    • Based on Penglai (https://github.com/Penglai-Enclave/Penglai-Enclave-sPMP) following sPMP extension (not yet ratified)
      • Overview of Penglai
      • Image RemovedImage Added
      • Both EDK2 and StandaloneMm are initiated by the Penglai Secure Monitor and running in S-mode Encalve
        • Use sPMP + PMP to ensure memory isolation between S-mode Enclave
        • Use different interrupt isolation mechanisms for different interrupt controllers to ensure that interrupts are only visible to the specified Enclave
        • Configure the IOPMP to block arbitrary device access to the secure memory.
        • When a request need to sent to Standalone MM, EDK2 copies request content (MM Protocol) to a shared non confidential memory then uses secure communication channel to trigger Standalone MM run and serve the request
  • No matter Standalone MM is launched, it should maintain the following requirements:
    • Standalone MM resources are protected completely from outside including MMIO, confidential memory.
    • Standalone MM can be loaded from any modes such as M-mode, S-Mode, VS-Mode with Hypervisor. U-mode is not suitable as it is limited accessing resource.
    • Standalone MM can be loaded from EDK2 PEI or DXE phase in Salus case and lives through the life cycle of current boot.
  • This document is trying to standardize the following subjects: 
    • Parameters of entry point of EDK2 Standalone MM.
    • Booting information passed from launcher entity to EDK2 Standalone MM.
    • Communication protocols between EDK2 Standalone MM and EDK2
    • How resource in EDK2 Standalone MM is protected based on the design of entity that loads EDK2 Standalone MM:
      • In Salus, EDK2 Standalone MM is loaded as TVM in VS mode. The protection based on APTEE specs.
      • In Penglai, EDK2 Standalone MM is run as enclave TVM that protected by PMP/sPMP.

...

EFI_MMRAM_DESCRIPTIONEFI_MM_COMMUNICATE_HEADER

///
/// Structure describing a MMRAM region and its accessibility attributes.
///
typedefstruct {
///
/// Designates the physical address of the MMRAM in memory. This view of memory is
/// the same as seen by I/O-based agents, for example, but it may not be the address seen
/// by the processors.
///
EFI_PHYSICAL_ADDRESSPhysicalStart;
///
/// Designates the address of the MMRAM, as seen by software executing on the
/// processors. This address may or may not match PhysicalStart.
///
EFI_PHYSICAL_ADDRESSCpuStart;
///
/// Describes the number of bytes in the MMRAM region.
///
UINT64PhysicalSize;
///
/// Describes the accessibility attributes of the MMRAM. These attributes include the
/// hardware state (e.g., Open/Closed/Locked), capability (e.g., cacheable), logical
/// allocation (e.g., allocated), and pre-use initialization (e.g., needs testing/ECC
/// initialization).
///
UINT64RegionState;
} EFI_MMRAM_DESCRIPTOR;

///
/// To avoid confusion in interpreting frames, the communication buffer should always
/// begin with EFI_MM_COMMUNICATE_HEADER
///
typedefstruct {
///
/// Allows for disambiguation of the message format.
///
EFI_GUIDHeaderGuid;
///
/// Describes the size of Data (in bytes) and does not include the size of the header.
///
UINTNMessageLength;
///
/// Designates an array of bytes that is MessageLength in size.
///
UINT8Data[1];
} EFI_MM_COMMUNICATE_HEADE

  • The PhysicalStart and CPUStart have the same value of MmNsCommBufBase.
  • The PhysicalSize have the same value of MmNsCommBufSize.
  • The MessageLength describes the length of payload size.
  • Pseudo code of delegated event loop.

    Make sure MessageLength  is zero

    While true

    • Cpu sleep (in Salus) or SBI request (in Penglai)
    • Check MessageLength non zero then process message


  • Before wake up CPU in MM context, EDK2 makes sure MessageLength and Data are updated with new request.
  • How to wake CPU in MM context is depend how EDK2 MM is loaded as not be discussed in this document.