iommu: per-device domains with interim DMA-pool enforcement

Replaces L1's shared blanket identity domain with a private translation
domain per claimed PCI function. A device now reaches only:
  - the DMA pool: every dma_alloc'd region, mapped into every claimed
    device's domain (poolAdd/poolRemove, driven from the dma_alloc and
    dma_free syscalls). This keeps the cross-process buffer handoff
    working (fat's bounce buffer reaches the xHC) while blocking the
    kernel, page tables, process heaps, MMIO, and unallocated RAM.
  - its own firmware reserved region (RMRR), seeded at confine time.
The pool is the honest interim: devices can still reach one another's
DMA buffers. The DMA-region capability layer (next) narrows it to
per-grant reachability.

dma_free unmaps from every domain and invalidates BEFORE the frames
return to the allocator, closing the stale-IOTLB use-after-free window.
Driver death tears down its domains (detach + free tables) before the
broker claims and DMA frames are released.

New iommu_fault_drain syscall (+ driver.iommuFaultDrain) forces pending
fault records to the log on demand. The new iommu-fault case proves it:
a claimed e1000e is programmed to DMA-fetch its TX ring from an unmapped
page; VT-d faults the access (bdf 00:03.0 addr 0x1000 reason 0x6) and the
system stays alive. 104/104.
This commit is contained in:
Daniel Samson
2026-07-26 18:31:27 +01:00
parent f477ef7d9f
commit e94adcfc02
8 changed files with 280 additions and 43 deletions
+9
View File
@@ -184,6 +184,15 @@ CASES = [
"qemu_extra": ["-device", "intel-iommu,intremap=off"],
"expect": r"(?s)(?=.*/system/kernel: iommu online)(?=.*usb-hid-keyboard: ok)(?=.*usb-hid-mouse: ok)",
"fail": r"DANOS-TEST-RESULT: FAIL|DANOS-IOMMU-FAULT"},
# Enforcement, the negative proof: a claimed e1000e fires a DMA at an unmapped page;
# VT-d must fault it (logged) and the system must stay alive. The fault line is the
# point here, so unlike the positive cases it appears in `expect`, not `fail`.
{"name": "iommu-fault",
"smp": 4,
"timeout": 120,
"qemu_extra": ["-device", "intel-iommu,intremap=off", "-device", "e1000e"],
"expect": r"(?s)(?=.*DANOS-IOMMU-FAULT: bdf=)(?=.*iommu-fault-test: system alive)(?=.*DANOS-TEST-RESULT: PASS)",
"fail": r"iommu-fault-test: FAIL|DANOS-TEST-RESULT: FAIL|CPU EXCEPTION|KERNEL PANIC"},
# Port I/O grants: a claimed device's io_port resource lets a driver read/write its
# ports (PS/2 status 0x64), gated by the claim; out-of-range/unclaimed is refused.
{"name": "ioport",