ReleaseMicrosoftMicrosoftpublished Jun 12, 2026seen 1w

microsoft/mu_basecore v2025110002.0.2

microsoft/mu_basecore

Open original ↗

Captured source

source ↗
published Jun 12, 2026seen 1wcaptured 1whttp 200method plain

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 -

  • SmmuStreamContext holds {PageTableRoot, Vmid} per StreamID per SMMU; both allocated lazily and the STE promoted INVALID → STAGE_2_TRANSLATE via break-before-make on first SetAttribute*.
  • 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 → platform SMMU_NC_DEVICE_ENTRY HOB → 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_CONFIG gains NcDeviceListSize/Offset; new SMMU_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 UniqueId parameter on RegisterNonDiscoverableMmioDevice.
  • `DmaMap` gains `IommuBase` + `DmaId` parameters. Pass 0/0 to 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 SetAttributeById field is optional. Legacy producers leave it NULL, and consumers that call it through IoMmuLib::IoMmuSetAttributeById get EFI_UNSUPPORTED and must gracefully fall back.

NvmExpressDxe:...

Excerpt shown — open the source for the full document.

Notability

notability 2.0/10

Routine version update with no traction data.