Repository navigation
AMD-Vi translates: a blocked device table, identity and own domains, the event log, and one domain registry for every backend - #909
Conversation
…irmware left The AMD-Vi translation and remapping design (issues/an-amd-vi-machine-isolates-no-device.md, stages 5 and 6) arms the unit's event interrupt through its own PCI function, which AMD 48882 §3.1 lets carry MSI, MSI-X or both, and must clear an exclusion range firmware may leave, inside which DMA is neither translated nor checked (§3.4.1, MMIO 0020h and 0028h). Neither is read today, so the bench's answer is unknown. Each unit now logs its function's capability ids and its Miscellaneous Information Register 0 (Capability Offset 10h: VAsize, PAsize, MsiNum), and the hand-over line carries the exclusion base and limit. Nothing the unit does changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
Orchestrator on the design's open decisions.
|
|
AMD bench reading for the design (orchestrator; image For ruling 2: the unit's own EFR reads |
|
Design review: #909 at AssessmentThe architecture is right. The unit picks the remapping table from the requester's own DTE, so giving each kept requester a table indexed by vector verifies the source structurally. It needs no handle allocator, and the device keeps its plain compat message. The cost is 4 KiB per requester with a remapped interrupt, a handful on the bench, plus one Ruling 2: the bench's EFR, decoded against Table 25 (MMIO 0030h, pp. 225-228)
High word
Table 21 (p. 93) selects the 128-bit IRTE for remapping when GASup = 1, GAEn = 1 and GAMEn = 000b, whatever GAMSup is. The bench therefore has both The other new readings agree with the spec and with an independent source on the same machine. Spec facts checked (all hold)
FindingsB1 BLOCKER: the stage 5 plan adds a third copy of the domain registry, contrary to ruling 4. PR body "Stage 5 →
B2 BLOCKER: a claimed function inherits the IVHD pass bits. PR body "Stage 6": "Pass bits (NMI, INIT, ExtInt, LINT0/1) and SysMgt come from the IVHD byte".
B3 BLOCKER: the design does not say what happens to IVMD unity and exclusion ranges. PR body "Stage 5": windows clear of "every IVMD range"; "exclusion range cleared".
B4 BLOCKER: the QEMU issue is not answered by this design, so the body must not say it is. PR body "What it deletes": "
B5 BLOCKER: the spec copy's provenance is knowable and the body misstates it. PR body "Source"; evidence
S1 SUGGESTION: state the order and the reserved DomainID. Write identity DTEs for every enumerated function before S2 SUGGESTION: refuse a unit whose IVHD Coherent flag is clear. The design sets S3 SUGGESTION: read QEMU's I/O APIC special entry now. One S4 SUGGESTION: reword "most of the risk" in Tests. Host tests hold the encodings. Stage 5's most consequential risks are the register sequence and the identity coverage ("if it is wrong the bench returns no log"), and only the bench row holds those. S5 SUGGESTION: tidy the measurement code.
Bench rows and isolationTaken together, the rows prove isolation for a claimed function:
Stage 5 alone proves translation only. A kernel-owned fault halts, so no stage 5 row reaches the event-log drain on metal. The blocked default for unenumerated requesters has no oracle on any target. The body says this honestly, and I am not asking for more. EvidenceAll four checks show exit codes and logs at SEND BACK |
|
Orchestrator: design accepted with the five blockers as named changes; stage 5 builds now, on this branch. The ownership stands: one device table, blocked by default; identity domains for kernel drivers, a domain per claimed function; a remapping table per requester, indexed by vector. The bench's EFR settles ruling 2: Named changes, carried in the build:
Suggestions S1–S5 are taken; S3's one boot is the orchestrator's to run and will be posted here. The figure citation is corrected. |
VT-d and the SMMU each kept the same bookkeeping for the domains a unit translates for: ids from a first one up, a Window of device addresses each, the 2 MiB alignment refusal, the handed-out check before a place, and the records a create, a map and a map-again write. AMD-Vi, the next backend (issues/an-amd-vi-machine-isolates-no-device.md, stage 5), would have been a third copy. `iommu::domains::Domains<S>` now holds it, generic over the backend's own name for a domain's tables. A backend keeps its tables, its invalidation and its lock, and holds the registry under that lock: VT-d its `DOMAINS` (with the width agreement, which is VT-d's alone), the SMMU inside `Live`. VT-d's table module loses `Domain` and its window for a plain `Space` of root and width, with per-leaf `put` and `take`. One behaviour moves: a VT-d unmap refused part-way now invalidates what it cleared before the refusal, as the SMMU's already did; it returned before invalidating. The create record's backend fields now precede "addresses from .. to ..", which ends every such line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
B5 is closed. The owner downloaded |
…and the event log Stage 5 of issues/an-amd-vi-machine-isolates-no-device.md, the design accepted on #909. On a machine whose IVRS describes AMD-Vi units the kernel now programs each unit it can use instead of leaving it off. - toyos-amdvi (kernel/amdvi), pure and host-tested against AMD 48882 rev 3.11's field positions: device table entries (blocked: V, TV, Mode 000b, IR=IW=0; translated: Mode 100b over a 4-level root), the IVHD DTE setting's SysMgt, host page table directory and 2 MiB leaf entries (FC set, so a device's no-snoop cannot read stale memory), the commands, the event records, and the register fields. - One device table every unit reads, all 65,536 entries blocked under domain 0 but each enumerated function's, which names the identity domain (1) over [0, pmm::top()); written before IommuEn. Each unit gets a command buffer and event log, its exclusion range cleared, its own MSI armed through its PCI function (the one message no unit remaps), then CONTROL; then INVALIDATE_IOMMU_ALL and one INVALIDATE_DEVTAB_ENTRY per enumerated function, behind a completion wait. - A unit is left off, by name, on a segment other than 0, without IASup, with a reserved HATS, where the IVRS has an enumerated function issue its requests under another id, where its device entries are refused, or where its function has no MSI capability. An IVMD that asks for an exclusion range or memory no device may reach leaves every unit off; a unity IVMD's requesters keep the identity domain (DeviceSpace::create now takes the function and answers Untranslated for them). - Domains go through iommu::domains, with map, unmap and attach each published by INVALIDATE_IOMMU_PAGES (and INVALIDATE_DEVTAB_ENTRY for a move) behind a completion wait; attach swaps the entry's translation half with the cmpxchg16b VT-d already had, now shared in iommu_unit. - The event log is drained on DMA_FAULT_VECTOR into iommu::fault; IO_PAGE_FAULT and INVALID_DEVICE_REQUEST are a requester's, any other record panics; an overflow restarts the log by §2.5.1. - iommu_unit dispatches domain and fault on the backend init found. - The firmware-left actuator is rebuilt from toyos-amdvi's encodings, and FIRMWARE_LEFT's order is stated by the specification's reason. - amdvi-selftest and the MetalAmdViTestdev profile: two iommu-testdev, one on its own domain landing a write where it maps, the other on the identity domain landing one in memory and refused one past it, recorded as the kernel's, and the machine halts. QEMU 11.1.1's record of that write carries no address, filed as issues/qemus-amd-iommu-page-fault-record-carries-no-address.md. - The AMD bench's row amdvi_translates_the_stick_controller: every unit translating, every xHCI the kernel drives moved to a domain of its own, the stick bound, no DMA refused. build/sourcegate.rs declares the unit's function's enable_bus_master, after the unit's refusals. Declined: refusing a unit whose IVHD leaves Coherent clear (review S2). QEMU's IVHD says flags 0x11, and CONTROL.Coherent's reset value and Table 97's recommended value are both 1; this driver sets it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
Orchestrator: S2 stays declined, as built: QEMU's unit leaves Coherent clear and refusing it would refuse the only AMD-Vi unit CI has; the driver sets Coherent, which is the reset value and the spec's recommendation. B2 moving to stage 6 is right: nothing on AMD-Vi can be claimed before remapping. The three AMD bench boots are running now. |
|
Build review: #909 at AssessmentThe architecture is the one the design accepted, and it is built cleanly:
B1 holds:
The host tests hold every word I checked against 48882:
The bench log matches the design:
The metal control The remaining problems:
FindingsB1 BLOCKER:
B2 BLOCKER: the per-function-invalidation control is misread, and a true QEMU constraint was removed on that basis.
B3 BLOCKER: when one unit is refused, functions it serves still get domains that no unit translates.
B4 BLOCKER: an IVMD with
S1 SUGGESTION: set
S2 SUGGESTION:
S3 SUGGESTION: minor simplifications.
Evidence
None of the fixes above calls for a metal rerun:
SEND BACK |
|
Orchestrator on the build review (6154133561): fix round, with one ruling.
No bench rerun is owed; |
…machine addresses, and the control's reading is corrected Build review of #909 (B1-B4) and the orchestrator's rulings. - B1: every record a requester can cause counts against it and never stops the machine on its own: IO_PAGE_FAULT, IOTLB_INV_TIMEOUT, INVALID_DEVICE_REQUEST, and INVALID_PPR_REQUEST with RX clear, whose DeviceID is the peripheral's (48882 Figure 64, Table 67). Only a record of this driver's tables or commands, or of the unit's own hardware, panics. `Event` is now `Requester` or `Unit`; host tests hold both, and decoding INVALID_PPR_REQUEST as the unit's reds them. - B2: the per-function-invalidation control's `0xdead0002` cannot tell translation from pass-through on a 40-bit guest, so the record is the only discriminator. The track issue gets back QEMU's "only once an INVALIDATE_DEVTAB_ENTRY names it", the boot's per-function commands are commented by that QEMU defect (the specification needs INVALIDATE_IOMMU_ALL alone), and the selftest's and harness's docs say the record, not the answer, establishes translation. - B3 (ruled): a function no programmed unit's device entries name keeps the machine's addresses and says why, so one refused unit costs isolation only behind itself. `firmware_reserves` becomes `untranslated`, answering the reason; its doc states VT-d answers None for every function, an RMRR's included. - B4: an IVMD without Unity is logged as that (Table 113: any translation may be used), not as memory no device may reach. - CONTROL is written whole rather than OR-ed onto firmware's fields, so a DevTblSegEn left over cannot change how the unit reads the table; the device table keeps a page field of its own; the domain width is derived from the root level; the event drain no longer clears EventOverflow ahead of the restart that does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
Build review round 2: #909 at AssessmentThe fix round stays within the accepted design and the rulings. The decoder now has two outcomes:
So Round-1 blockersB1: closed as ruled.
B2: closed.
B3: closed as ruled.
B4: closed.
Suggestions taken
FindingsB5 BLOCKER (body only, the orchestrator's): the firmware bits the whole write drops are misnamed.
S1 SUGGESTION: decide
S2 SUGGESTION, for stage 6: turn the unserved check into a refusal on the claim path.
S3 SUGGESTION: rewrap S4 SUGGESTION (evidence): none of the
Evidence checked
SEND BACK |
One conflict, tests/common/qemu.rs. #912 gave `Smmu` a third state, `WithIts` (virt's SMMUv3 with the ITS behind it, an `edu` and an `e1000e` past a bypassing root port) and built the machine argument from `Arch::irqchip`; this branch had renamed `Smmu` to `Testdevs { Absent, Two }` so a q35 behind AMD-Vi could carry two `iommu-testdev`. Both are kept as one enum, `Probes { Absent, Testdevs, Its }`, under the field `probes`: main's machine-argument code is taken whole with `shape.smmu` read as `shape.probes`, its ITS devices emitted on `Probes::Its`, and the q35 assertion widened to admit `Probes::Testdevs` behind a unit and nothing else. No file under kernel/src/arch/x86_64/amdvi, kernel/src/iommu, kernel/src/arch/x86_64/vtd or kernel/src/arch/aarch64/smmu changed on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
One conflict, kernel/src/drivers/hda.rs. #877 lists every HDA controller at boot and makes one device space before any is chosen, shared by whichever one a bind attaches; this branch had `DeviceSpace::create` take the one function its space is for, so AMD-Vi can answer the machine's own addresses for a function no programmed unit serves or an IVMD names. Main's side is taken whole, and `create` now takes every function that may be attached: the space is the machine's own where any of them keeps it, so whichever is bound reaches what its device addresses name. The other three callers pass their one function. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
kernel/src/arch/x86_64/amdvi/mod.rs takes main's FIRMWARE_LEFT doc from #909, which cites 48882 §2.4 and §2.5.1 and names no Linux; this branch's hunk there goes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…cpufacts One conflict: the root `Cargo.toml`'s members, where main added `kernel/amdvi` beside the `kernel/cpuvuln` this branch deletes; the resolution keeps `kernel/amdvi` alone. Every other file both sides changed merged cleanly: `Cargo.lock`, `kernel/Cargo.toml` and `tests/toyos.rs`, where main adds rows and `RUST_SKIP` entries and this branch drops `counters_on_metal`'s Linux request. Main removed `amdvi/mod.rs`'s Linux citation, so `the-tree-names-linux-as-an-authority.md` no longer lists it among the sweep's lines. Main touches none of `kernel/pure/cpu.rs`, `kernel/pure/xsave.rs`, the HWP path in `control_regs.rs`, `counters.rs`, `cpu.rs`, `microcode.rs`, `toyos-microcode`'s source or the judged rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
The shared domain registry and AMD-Vi's own domains (#909) take the optional declaration as vtd and the SMMUv3 do: Domains::avoid holds None where no declaration is accepted, and amdvi::init reserves its IVMDs only beside declared windows, as vtd its RMRRs. pcidev hands the IOMMU a validated toyos_pci::aperture::Declaration, which only check() makes. PARange 0b0111 is FEAT_D128's 56 bits; the window header names no machine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…le is asserted, and every boot says the CPU's width The AMD bench's recorded root-bridge list (#909's bench log) joins the T14's as a held case of `check`. Its AMD-Vi domains are 48 bits (mode-4 host tables, 48882 §2.2.3) and its IVinfo's PASize is 48; if its CPU also issues 48-bit addresses it keeps the declared rule, from 2^46 to 2^48 with no window above 2^46, which a const assertion now holds. The CPU's width was never in a boot log, so `iommu::init` says it once and the bench's own boot decides which rule it is on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Stage 5 of
issues/an-amd-vi-machine-isolates-no-device.md: AMD-Vi translation, built on the design accepted here with review blockers B1–B5 as named changes. Stage 6, interrupt remapping, is a second PR. Draft. The AMD bench rows ran green at this tree, and the control went red (below).What changes
On a machine whose IVRS describes AMD-Vi units, the kernel programs every unit it can use instead of leaving it off:
V,TV,Mode000b,IR=IW=0, domain 0) but every enumerated function's, which names the identity domain (1) over[0, pmm::top()). All written beforeIommuEn(S1).CONTROL, thenINVALIDATE_IOMMU_ALLand oneINVALIDATE_DEVTAB_ENTRYper enumerated function (B4), behind a completion wait under aTripwire.03:00.3/03:00.4). Every map, unmap and attach is published byINVALIDATE_IOMMU_PAGES, plusINVALIDATE_DEVTAB_ENTRYfor a move (§2.4.2). The move swaps the entry's translation half in onecmpxchg16b(§2.2.2.2).DMA_FAULT_VECTORintoiommu::fault. Every record a requester can cause counts against that requester and never stops the machine on its own:IO_PAGE_FAULT,IOTLB_INV_TIMEOUT,INVALID_DEVICE_REQUEST, andINVALID_PPR_REQUESTwithRXclear (Figure 64, Table 67). Only a record of this driver's tables or commands, or of the unit's own hardware, panics, because past it nothing can say what the unit lets through. An overflow restarts the log (§2.5.1).DeviceSpace::createanswersUntranslated) and the log says why, so one refused unit costs isolation only behind itself (orchestrator's ruling on review B3).IASup;HATS;DeviceSpace::createnow takes the function and answersUntranslatedfor them.ExclusionRangeset, or withUnityclear (Table 113: "any virtual address translation may be used"), leaves every unit off, logged by range and by which of the two it is.Files:
kernel/amdvi/(new pure cratetoyos-amdvi),kernel/src/arch/x86_64/amdvi/{mod,domain,fault,selftest}.rs,kernel/src/arch/x86_64/iommu_unit.rs(backend dispatch fordomainandfault; the sharedcmpxchg16bandMAX_UNITS),kernel/src/iommu/domains.rs.Commits
b3e77cac4: the design round's measurement line (the unit's function caps, misc0, exclusion range).810626cf1(B1): one domain registry,iommu::domains::Domains<S>, for VT-d and the SMMU. Ids, windows, the alignment refusal, the handed-out check and the records move into it; each backend keeps its tables, invalidation and lock. Net −10 lines (232+/242−). One behaviour moves: a VT-d unmap refused part-way now invalidates what it already cleared, as the SMMU's did.9173c339b: AMD-Vi as the third backend of that registry.Net for the branch: +2,054 / −529:
toyos-amdvi: 307 lines of source and 172 of host tests;amdvi/,iommu_unit.rs): 998+/134−;Decisions carried from review
SysMgt) is stage 6's: no claim is handed over on AMD-Vi until remapping exists (NotRemapped). Stage 5 entries carry the IVHD byte'sSysMgtalone (Table 106 → DTE bits 105:104), which the IOAPIC's00:14.0needs (data=0xd7).docs.amd.comFluid Topics API, document2oKZlc87KNCKiT3B~xJjHg,48882_3.11_IOMMU_PUB.pdf) with the build user-agent. The owner downloaded it from AMD as well. Both have SHA-256f7c375a15db5ed63de760356867211063d164a2ed59f2d38613daec95894ce22, equal to the copy the design read (record). 48882 is the host tests' oracle, cited per assertion.0x11, Coherent clear, so refusing such a unit would refuse the only AMD-Vi unit CI has.CONTROL.Coherent's reset value and the value Table 97 recommends are both 1, and the driver sets it. The bench's IVHD has it set (0xb0).FIRMWARE_LEFT's order is now stated by the specification's reason, anddescribe_functionis renamed. The figure citation for the 128-bit IRTE goes to stage 6.FC=1, so a device's no-snoop cannot read stale memory. This is AMD's equivalent of what VT-d's snoop control gives HDA.Checks (head
9173c339b; tree equal toa2e53ebfa, which every run below except the first three used)cargo run -- --build-only/--arch aarch64at810626cf1cargo test --test toyos-build -- virt_smmu usbd_drives_the_spare iommu_virtio_platformat810626cf1cargo test -p toyos-amdvi(inside--ci host)cargo run -- --ci hostcargo test --test toyos-build -- --nocapture amdvi_selftest amdvi_firmware_left usbd_drives_the_spare iommu_virtio_platform virt_smmuamd-iommu,intel-iommu, SMMUv3cargo run -- --build-only --arch aarch64a2e53ebfa:amdvi_translates_the_stick_controller,domain_ends_below_the_host_bridges,iommu_firmware_leftunits-left-off.patch:amdvi_translates_the_stick_controllerNegative controls:
no-per-device-invalidation.patch:INVALIDATE_IOMMU_ALLalone at boot.amdvi_selftestred, exit 1 (log). The device answered0xdead0002and no record was read. On this 40-bit guest a write passed through untranslated to 2^46 also reaches nothing, so the answer cannot tell translation from pass-through; the missing record is the discriminator. This matches the QEMU issue's premise (pass-through until anINVALIDATE_DEVTAB_ENTRYnames the function), soissues/qemus-invalidate-iommu-all-leaves-every-function-untranslated.mdstays open because the defect persists, and the boot's per-function commands are there for it alone (§2.4.8 needsINVALIDATE_IOMMU_ALLonly).ppr-is-the-units.patch:INVALID_PPR_REQUEST(RX=0) decoded as the unit's.a_record_a_requester_causes_is_its_ownred, exit 101 (log).units-left-off.patch: every unit left off, the base's behaviour. On the AMD bench,amdvi_translates_the_stick_controlleris red with "no AMD-Vi unit is translating", and the log saysAMD-Vi isolates no device this boot: 1 unit(s) described, none usable. The stick still binds there, so the row's red comes from the unit lines and not from the stick.The head's bench log against the design (testcases kernel log):
control=0x000022000000140d(IommuEn, EventLogEn, EventIntEn, Coherent, CmdBufEn) andstatus=0x00000018(CmdBufRun, EventLogRun), so the command buffer and event log are running. Its MSI is armed at0xfee00000/0x0025(DMA_FAULT_VECTOR) on its function00:00.2. 28 enumerated functions have identity entries.0x0..0x40f200000.03:00.3moves todomain2and is mapped at0x400000000000(2^46), with addresses from 2^46 to 2^48.03:00.4is ondomain3. The stick binds (usb-storage: 1 device(s)) through that translation, and noDMA FAULTappears in either boot.Fix round (head
e7ab4648c)Build review B1–B4 and the orchestrator's rulings: requester records never panic (B1); the control's reading corrected and the track issue's QEMU constraint restored (B2); unserved functions keep machine addresses (B3, ruled); the IVMD label follows Table 113 (B4). Also:
CONTROLwritten whole rather than OR-ed onto firmware's fields;untranslated(formerlyfirmware_reserves) documents that VT-d answersNonefor every function, an RMRR's included; the device table keeps its own page field; the domain width comes from the root level.cargo run -- --build-onlycargo test --test toyos-build -- --nocapture amdvi_selftest amdvi_firmware_leftamd-iommucargo run -- --ci host(13toyos-amdvitests among 76 steps)| AMD bench (orchestrator), image built at
e7ab4648c:amdvi_translates_the_stick_controller,domain_ends_below_the_host_bridges| AMD bench, 1 boot | 2 passed, 0 failed | judge, kernel log, runner |The head's bench reading sits beside the
a2e53ebfaset above.CONTROLis now written whole, so the unit readstranslating control=0x000000000000140d status=0x00000018: firmware's bits 57 and 61 are gone, and the unit, its command buffer and its event log are running.Merges of
origin/main(headbbc9b924a)4cd56a35b(The ACPI server is trusted platform code: the kernel makes the firmware's writes inside bug fences #906, terminal: the copy chord copies on its press, not again on its release #911, The ITS under HVF: one declaration picks each machine's interrupt controller, and virt_claim_lpi is back #912, issues: toyos-crypto is in the tree, on par with ring, and secure (track) #913):tests/common/qemu.rsconflicted. The ITS under HVF: one declaration picks each machine's interrupt controller, and virt_claim_lpi is back #912'sSmmu::WithItsand this branch's q35 testdevs became one enum,Probes { Absent, Testdevs, Its }.bbc9b924a(The AMD bench's desktop: HDA controller choice, native rate, codec volume and the volume keys #877):kernel/src/drivers/hda.rsconflicted. Main's side is taken whole. The AMD bench's desktop: HDA controller choice, native rate, codec volume and the volume keys #877 makes one HDA space before any controller is chosen, soDeviceSpace::createnow takes every function that may be attached, and the space is the machine's own where any of them keeps it.Neither merge changes
kernel/src/arch/x86_64/amdvi/or the AMD-Vi code iniommu/, so no bench boot is owed.cargo run -- --build-only, x86_64 and aarch644cd56a35b,bbc9b924acargo test --test toyos-build -- amdvi_selftest amdvi_firmware_left virt_smmu virt_claim_lpi4cd56a35bcargo test --test toyos-build -- amdvi_selftest amdvi_firmware_leftbbc9b924acargo run -- --ci host, 77 steps4cd56a35b,bbc9b924aTests
Host (
kernel/amdvi/tests/encodings.rs): every word against 48882's own field positions. Covered: the blocked and translated DTE, the IVHD byte'sSysMgt, the device-table and ring registers, level indices, directory and 2 MiB leaf entries, the five commands,IO_PAGE_FAULT/INVALID_DEVICE_REQUESTdecode with every other code named, andIASup/HATSdecoded on the bench's EFR.Guest
amdvi_firmware_left(changed): the unit is programmed after the switch-off, and the boot stick's controller moves todomain2and binds, in both arms.Guest
amdvi_selftest(new; profileMetalAmdViTestdev:Profile::MetalAmdViplus twoiommu-testdev, shared with the SMMU's selftest throughkernel/src/iommu/testdev.rs):owner=kernelasIO_PAGE_FAULT, and the machine halts.Why a guest: a kernel-owned record halts the machine, so no metal row reaches the event log of a unit that translates for the kernel alone, and only
iommu-testdevaims a DMA where nothing maps. QEMU's record carries no address, so the test holds the record to its requester (filed:issues/qemus-amd-iommu-page-fault-record-carries-no-address.md, raw words in guest-s5-debug.log).Metal row
amdvi_translates_the_stick_controller(AMD bench,testcasesboot): every unit translating, every xHCI the kernel drives moved to a domain of its own, the stick bound, noDMA FAULT, no "isolates no device".domain_ends_below_the_host_bridgesandiommu_firmware_leftride the same request.Risks
Mode0 through, and no known requester on the bench DMAs unenumerated.claim_reuses_its_remapping_entrystays T14-only (issues/a-metal-row-names-no-hardware-and-a-bench-without-it-reds.md), and a T14 run ofamdvi_translates_the_stick_controllerreds for want of an AMD unit, for the same reason.Design-round evidence: d1.
🤖 Generated with Claude Code
https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy