M16: IOMMU detection (DMAR parsing)

Detect the IOMMU: discovery now parses the ACPI DMAR table, finds the first VT-d
DMA-remapping unit (DRHD), maps its register block, and records its version and
capabilities (iommu_present/base/version/capabilities in the platform info). On QEMU's
emulated intel-iommu this reads back a real unit (base 0xfed90000, version 1.0).

This is detection only, and deliberately so. A full VT-d bring-up — per-device
translation domains that confine a driver's DMA to the buffers it dma_alloc'd — is the
real device-side safety guarantee, but it cannot be verified without a DMA-capable
device driver (none exist yet) and QEMU's intel-iommu to fault against. Writing that
enforcement now would be a large body of unverifiable page-table code; it belongs with
the first DMA driver, which is both the natural order and the only way to test it. Until
then the caveat stands in full: device_claim on a DMA-capable device is still equivalent
to granting ring 0. The docs say so plainly.

New `iommu` test (harness boots it with -device intel-iommu via a new per-case qemu_extra
hook) confirms the DMAR is parsed and the unit's registers read. Suite 40/40 plus host
tests.
This commit is contained in:
Daniel Samson
2026-07-10 20:07:01 +01:00
parent 4ef21fa083
commit e612d948d2
4 changed files with 94 additions and 1 deletions
+17
View File
@@ -88,6 +88,8 @@ pub fn run(case: []const u8, boot_information: *const BootInformation) void {
dmaTest();
} else if (eql(case, "msi")) {
msiTest();
} else if (eql(case, "iommu")) {
iommuTest();
} else if (eql(case, "smp")) {
smpTest();
} else if (eql(case, "affinity")) {
@@ -1034,6 +1036,21 @@ fn msiTest() void {
result();
}
/// IOMMU (M16): with an emulated VT-d unit present (the harness boots this case with
/// `-device intel-iommu`), danos must find it in the ACPI DMAR table, map its register
/// block, and read back a real version. This is *detection*, the honest first step —
/// no translation domains are programmed yet, so DMA is still unprotected; enforcement
/// lands with the first DMA driver (docs/driver-model.md M16).
fn iommuTest() void {
log("DANOS-TEST-BEGIN: iommu\n", .{});
const pinfo = platform.platformInformation();
check("IOMMU found in the DMAR table", pinfo.iommu_present);
check("VT-d unit has a register base", pinfo.iommu_base != 0);
check("VT-d version register reads back nonzero (real, mappable unit)", pinfo.iommu_version != 0);
log("DANOS-IOMMU: base=0x{x} version=0x{x} capabilities=0x{x}\n", .{ pinfo.iommu_base, pinfo.iommu_version, pinfo.iommu_capabilities });
result();
}
var proc_worker_run: bool = true;
var proc_worker_ran: bool = false;