microsoft/mu_basecore v2025110002.0.2
microsoft/mu_basecore
Captured source
source ↗v2025110002.0.2
Repository: microsoft/mu_basecore
Tag: v2025110002.0.2
Published: 2026-06-12T22:04:45Z
Prerelease: no
Release notes:
What's Changed
[REBASE \& FF] Add per-streamId isolation for SmmuDxe @eeshanl (#1812)
Change Details
Description
Add per-StreamID isolation for SmmuDxe
Replaces SmmuDxe's previous "shared page table root" model with per-StreamID stage-2 isolation in ArmPkg and adds the supporting plumbing in MdeModulePkg and EmbeddedPkg so non-PCIe and handle-less DMA agents can participate.
Every DMA-capable device gets its own stage-2 page-table root and VMID, mappings made for one device are invisible to any other, and translation related faults are surfaced immediately via GIC EVTQ/GERR ISRs.
Commits
1. Revert "Add `gEdkiiNonDiscoverableDeviceUniqueIdProtocolGuid` ..." - superseded by a RegisterNonDiscoverableMmioDevice parameter in the next commit. 2. `MdeModulePkg`: Add `UniqueId` to `NonDiscoverableDeviceRegistrationLib` - RegisterNonDiscoverableMmioDevice now takes a platform UniqueId, surfaced as PciIo->GetLocation() = (Seg=0xFF, Bus=UniqueId>>5, Dev=UniqueId&0x1F, Func=0). Breaking change. 3. `MdeModulePkg`: Add `SetAttributeById` to IoMmu Protocol - (IommuBase, DmaId, Mapping, IoMmuAccess) entry point for handle-less callers. Protocol revision bumped to 0x00010001. IoMmuLib NULL-checks; IoMmuLibNull is a no-op. 4. `MdeModulePkg`: Add `Handle` to `NON_DISCOVERABLE_PCI_DEVICE` - passes the controller handle (instead of NULL) to IoMmuSetAttribute, so the IOMMU producer can resolve the StreamID via HandleProtocol → PciIo → GetLocation → IORT. 5. `EmbeddedPkg/DmaLib`: Use `IoMmuSetAttributeById` with `IommuBase`/`DmaId` - DmaMap takes two new params, forwarded to SetAttributeById. IommuBase == 0 is the explicit opt-out. Breaking change. 6. `ArmPkg/SmmuDxe`: Add per-StreamID isolation for each DMA capable device -
SmmuStreamContextholds{PageTableRoot, Vmid}per StreamID per SMMU; both allocated lazily and the STE promotedINVALID → STAGE_2_TRANSLATEvia break-before-make on firstSetAttribute*.- Aliases share the primary's root + VMID one page-table update covers DMA from all StreamIDs of one logical device.
DeviceHandleToStreamId: real PCIe → IORT RC;Seg=0xFF→ platformSMMU_NC_DEVICE_ENTRYHOB → IORT Named Component.- GIC EVTQ/GERR ISRs surface faults immediately; opportunistic drain on every
SetAttribute*. - ExitBootServices is per-SMMU: bypass for SMMUs with RMR streams, abort for the rest.
SMMU_CONFIGgainsNcDeviceListSize/Offset; newSMMU_NC_DEVICE_ENTRY {UniqueId, ObjName[32]}maps platform UniqueIds → IORT NC names.
For details on how to complete these options and their meaning refer to CONTRIBUTING.md.
- [ ] Impacts functionality?
- [x] Impacts security?
- [x] Breaking change?
- [ ] Includes tests?
- [x] Includes documentation?
How This Was Tested
Tested on SBSA (https://github.com/OpenDevicePartnership/patina-qemu/pull/261), QemuArmVirtPkg, and physical arm platform.
Integration Instructions
1. Build the IORT. Include one SMMUv3 node, the necessary ITS / Root Complex nodes for PCIe, and one EFI_ACPI_IORT_TYPE_NAMED_COMP node per non-discoverable DMA-capable device. Each Named Component's ID mappings must produce the StreamIDs the device emits and reference the owning SMMUv3 node. 2. (Optional) Register any non-PCI/NonDiscoverable devices with a stable `UniqueId` via RegisterNonDiscoverableMmioDevice (UniqueId, ...). SmmuDxe reconstructs that UniqueId from PciIo->GetLocation() later, so values must be unique across the platform. 3. Build the `SMMU_CONFIG` HOB in your platform SecPlatformSmmuConfigLib. Append (in any order) the IORT blob, the optional NC device lookup table for NonDiscoverable devices, and the optional SMMU disable list, then point the offsets/sizes in the SMMU_CONFIG header at them:
STATIC CONST SMMU_NC_DEVICE_ENTRY NcDeviceTable[] = {
// { UniqueId, IORT NC ObjectName }
{ 0x1, "USB" },
{ 0x2, "SATA_AHCI" },
};
SmmuConfig = AllocateZeroPool (sizeof (SMMU_CONFIG)
+ sizeof (IortData)
+ sizeof (NcDeviceTable));
SmmuConfig->VersionMajor = CURRENT_SMMU_CONFIG_VERSION_MAJOR;
SmmuConfig->VersionMinor = CURRENT_SMMU_CONFIG_VERSION_MINOR;
SmmuConfig->IortSize = sizeof (IortData);
SmmuConfig->IortOffset = sizeof (SMMU_CONFIG);
SmmuConfig->NcDeviceListSize = sizeof (NcDeviceTable);
SmmuConfig->NcDeviceListOffset = sizeof (SMMU_CONFIG) + sizeof (IortData);
CopyMem ((UINT8 *)SmmuConfig + SmmuConfig->IortOffset,
&IortData, sizeof (IortData));
CopyMem ((UINT8 *)SmmuConfig + SmmuConfig->NcDeviceListOffset,
NcDeviceTable, sizeof (NcDeviceTable));
BuildGuidDataHob (&gSmmuConfigHobGuid,
SmmuConfig,
sizeof (SMMU_CONFIG)
+ sizeof (IortData)
+ sizeof (NcDeviceTable));4. Do not install the IORT yourself SmmuDxe installs it as an ACPI table after parsing. 5. Disable specific SMMUs (optional). Append a UINT64[] of SMMU base addresses to put in bypass mode and point SmmuDisabledListOffset / SmmuDisabledListSize at it. 6. Handle-less DMA agents (optional). Firmware components that have no UEFI device handle (and therefore are not in the IORT) call IoMmuLib::IoMmuSetAttributeById (IommuBase, DmaId, ...) directly. Pass IommuBase == 0 to opt out of IOMMU programming entirely.
See [ArmPkg/Drivers/SmmuDxe/README.md](ArmPkg/Drivers/SmmuDxe/README.md) for the end-to-end flow diagrams, HOB layout, and the per-StreamID isolation walkthrough.
Breaking changes
- `RegisterNonDiscoverableMmioDevice` gains a leading `UniqueId` parameter. All existing call sites must be updated to pass a value that is unique across the platform.
- `gEdkiiNonDiscoverableDeviceUniqueIdProtocolGuid` is removed. Any out-of-tree consumer of that protocol must switch to the new
UniqueIdparameter onRegisterNonDiscoverableMmioDevice. - `DmaMap` gains `IommuBase` + `DmaId` parameters. Pass
0/0to keep pre-existing behaviour (no IOMMU programming); supply real values to opt into per-StreamID isolation for handle-less DMA agents. - `EDKII_IOMMU_PROTOCOL_REVISION` bumped to `0x00010001`. The new
SetAttributeByIdfield is optional. Legacy producers leave itNULL, and consumers that call it throughIoMmuLib::IoMmuSetAttributeByIdgetEFI_UNSUPPORTEDand must gracefully fall back.
NvmExpressDxe:...
Excerpt shown — open the source for the full document.
Notability
notability 2.0/10Routine version update with no traction data.