Skip to content

amdvi: the firmware-left actuator invalidates with one INVALIDATE_IOMMU_ALL, and its metal row judges AMD-Vi units - #884

Merged
Japabu merged 5 commits into
mainfrom
wt/toyos-amdvi-ring
Oct 12, 2026
Merged

Japabu merged 5 commits into
mainfrom
wt/toyos-amdvi-ring

Conversation

@Japabu

@Japabu Japabu commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

The iommu-firmware-left actuator's AMD-Vi arm overflowed its own 256-entry command ring on the AMD bench, so every shared-debug boot there panicked at amdvi/mod.rs:325 before the unit was switched off. This change makes it invalidate with one INVALIDATE_IOMMU_ALL and the existing COMPLETION_WAIT, and refuses by name a unit that cannot take that command. The iommu_firmware_left metal row now judges AMD-Vi units by their own lines.

Head 56095b138, on main at c0cdddf4e. This is the build of the design the orchestrator accepted with the review's named changes. The empty design commit is dropped. Review round 2 (LAND AFTER NAMED CHANGES) named two NOTEs: the AMD-Vi hand-over lines are now one declaration, and this body carries the metal results.

The defect

leave_on wrote one INVALIDATE_DEVTAB_ENTRY into its 256-entry ring for each requester ID its unit's IVHD names. It never refilled the ring, and it asserted once 255 were written. The AMD bench's IVHD names 65,535 IDs. The panic is in #873's flash log. 0d783accc (#837) brought the IVHD walk in. QEMU's IVHD names only eight functions, so the guest test never reached the bound.

What changed, per decision

  • kernel/src/arch/x86_64/amdvi/mod.rs, leave_on: one INVALIDATE_IOMMU_ALL, then the existing COMPLETION_WAIT. This follows AMD 48882 and Linux:
    • Table 41: the command is opcode 08h at bits 63:60, and every other bit is reserved.
    • §2.4.8: once it completes, "all IOMMU caches are empty". That also drops translations the unit holds under the BLOCKED entries' DomainID 1. A per-entry walk left those behind (§2.4.2: INVALIDATE_DEVTAB_ENTRY "does not invalidate translation cache entries"), which was the design review's BLOCKER 3.
    • Linux's amd_iommu_flush_all_caches sends the same pair whenever FEATURE_IA is set.
    • Two commands fit the 256-entry ring, so there is no ring bound and no drain.
  • A unit whose EFR IASup (bit 6) is clear is refused by name before anything is written: assert! naming the EFR and the missing command. IASup is optional (§1.3.3.3, §2.4.8). Both units in reach set it: the bench's 0x206d73ef22254ade and QEMU's 0x29d3. The refusal states the test machines' feature set. It is not a second path.
  • Deleted: the IVHD walk, its 14-line DeviceEntry match, its expect on the device list, the ring's overflow assert, the push closure, and leave_on's ivrs and unit parameters.
  • tests/common/iommu.rs, amdvi_left_on: what the actuator leaves on an AMD-Vi unit is one declaration. It returns the kernel's was handed over with <field> on; it goes off line for CmdBufEn, EventLogEn and IommuEn. Both the guest test and the metal row's judge read it, as the judge already reads unit_fields (review round 2, NOTE 1).
  • tests/common/iommu.rs, amdvi_firmware_left: the stick-never-binds claim is dropped.
    • Its assertions are unchanged. It reads the fields' lines from amdvi_left_on.
    • The doc now says that with the switch-off reverted, the second boot reds on the register half: the fields' lines, and control reading back zero. It also says the stick still binds there under QEMU 11.1.1, and that the AMD bench holds the DMA half.
  • issues/qemus-invalidate-iommu-all-leaves-every-function-untranslated.md, filed.
    • What QEMU 11.1.1 does: amdvi_inval_all never reads a device table entry's mode. A function therefore stays on iommu_nodma under a blocking entry.
    • Owner: the AMD laptop track.
    • Exit: amdvi_firmware_left with switch_off skipping every field reds on usb-storage: 1 device(s) under the QEMU that build/ci/qemu-version names.
    • Measured below: the mutated boot binds the stick with control=0x…1005 left on.
  • tests/toyos.rs, the iommu_firmware_left row's judge, also reads AMD-Vi units.
    • It takes every iommu: amdvi unit<N> handed over control= line as a unit.
    • For each, it requires that unit's amdvi_left_on lines and its @<base> switched off control= line.
    • VT-d units are judged as before. A log with neither kind of unit still reds.
    • On an AMD-Vi machine those lines reach the stick's log partition only if the switch-off let the stick's DMA through. That makes this judge the DMA half's reader.
  • issues/the-iommu-firmware-left-row-reads-only-vt-d-lines-so-it-reds-on-an-amd-vi-machine.md, filed in the design round, closes here. Its exit has three parts:
    • The judge reds with any of the four lines missing: each is a contains that returns Err, which reading shows.
    • It passes the AMD bench's boot, and still passes the T14's: the metal table's two head arms, re-judged at this head below.
    • Why this row judges AMD-Vi, not "declared VT-d" under issues/a-metal-row-names-no-hardware-and-a-bench-without-it-reds.md: the actuator has an AMD-Vi arm that runs on the bench, and this row is the only reader of its DMA half.

Checks

Every row ran at 56095b138 from one script, which printed an empty git status --porcelain --ignore-submodules=none before, after the mutation and at the end (gates.log). The one-minute load average read 37.3 to 55.3 across the run; the volume was 82% full.

gate exit log
cargo run -- --ci host: 76 steps, "all green" 0 gates.log L19, ci-host.log L8826
cargo run -- --build-only --arch x86_64 0 gates.log L16, log
cargo run -- --build-only --arch aarch64 0 gates.log L17, log
cargo test --test toyos-build -- amdvi_firmware_left, the green arm. Under the actuator the unit is handed over at control=0x0000000000001005 status=0x00000018: the completion wait behind INVALIDATE_IOMMU_ALL stored. 0 gates.log L8, L13-L14
The register half's negative control: the same test with the switch-off reverted (patch, #837's control), applied after git apply --check and restored with git apply -R. It reds on switched off control=0x0000000000000000. The boot's own lines show the unit left at 0x…1005 and the stick bound (usb-storage: 1 device(s)), which is the QEMU gap. The supervisor reports 56095b138… dirty. 1 gates.log L12, L13, L141-L142, L192, L232
The new judge on the AMD head's readback: cargo test --test toyos-build -- --metal --metal-readback <dir> --metal-host '<user>@<amd-bench>' iommu_firmware_left, the staging words, against the readback the metal run left there. No machine was touched. One unit. 0 gates.log L5, L14-L15
The new judge on the T14 head's readback, the same way without --metal-host. Four VT-d units. 0 gates.log L6, L16-L17

Metal

The four boots ran at f2c537a51 (the results). Each image's sha256 matched images.sha256 before its flash. From f2c537a51 to this head, git diff --stat f2c537a51 HEAD -- kernel/src loader system sdk lib apps is empty: the merge brought build/, the host simulator kernel/sim/, two issue files and a prompt, and this round changed only tests/.

arm bench result expected
head AMD Boot: complete (1333ms) (kernel L290). unit0 is handed over at status=0x00000018, then its CmdBufEn, EventLogEn and IommuEn lines, then switched off (L118-L122). The completion wait behind INVALIDATE_IOMMU_ALL stored on the silicon, so the encoding holds. The iommu_firmware_left judge exited 0 (flash, judge). met
head T14 the judge exited 0 on the VT-d lines (kernel, judge) met
base (main 867ec23ed), the whole fix reverted AMD panics at amdvi/mod.rs:325:9, "the unit's requesters overflow the actuator's 256-entry ring" (L72-L78); no Boot: complete (L217) met: the negative control is red
switch-off reverted, the head with the guest control's patch AMD no Boot: complete on the log partition (L106). The black-box tail counts xhci=0 on every one of the eight CPUs (L78-L86); the head's cpu0 counts xhci=232 (L89). It did not hang: the loader read the black box as DONE, so the boot handed the machine back on purpose, and its last record is the kernel's Rebooting. at 20.919 s (L71-L73). met: the DMA half's control is red

Every file is masked and committed whole at evidence commit 7b6ac575cf12e4afb2adda3bd2ec80d76896a06f.

Why a guest test

No type or host test reaches the unit's register sequence. The T14 is an Intel machine, and QEMU's amd-iommu is the only AMD-Vi unit the merge queue runs. It is third-party, and it executes the hand-over's register writes and reads them back. Under 11.1.1 it no longer shows the DMA half, so that half is the AMD bench's: the metal table's head and switch-off-reverted arms.

Independent oracles

  • AMD 48882 rev 3.11: Table 41, §2.4.8, §1.3.3.3 and EFR bit 6, as the design review read them. I did not fetch it myself.
  • Linux's amd_iommu_flush_all_caches, the published state of the art.
  • QEMU's amd-iommu, a differential implementation of the register sequence.
  • The AMD bench's silicon, the metal table above.

Growth

git diff --shortstat origin/main...56095b138: 4 files, +102 −46.

  • Production, amdvi/mod.rs: +20 −31.
  • Tests: tests/toyos.rs +31 −8, and tests/common/iommu.rs +18 −7.
  • Issues: +33, the QEMU gap. The VT-d-row issue is added and deleted within the branch.

Unsure

  • Which program asked for the switch-off-reverted boot's reboot. The black box keeps only that boot's newest records, and none of them names the caller. The arm's verdict does not rest on it.

🤖 Generated with Claude Code

https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy

@Japabu

Japabu commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

Review, round 1 (design), at 206ece491. No earlier round.

Net lines (git diff --shortstat origin/main...206ece491): 1 file changed, 36 insertions, all of them in one issue file. Production 0, tests 0. The body estimates the build at about +94: production about +24, host tests about +70.

Sources.

  • AMD's spec: 48882 rev 3.11 (Apr 2026, sha256 f7c375a1…ce22). Every sentence cited below is also in rev 3.10 (cd755933…8a12). Both come from the kib.kiev.ua x86docs mirror, because amd.com failed here as well under the toyos-build User-Agent: HTTP/2 INTERNAL_ERROR, then a 90 s timeout. Page numbers are the printed ones.
  • Linux: torvalds/linux master 24a19b953e2a, drivers/iommu/amd/.
  • QEMU: v11.1.1 c3d48b7d, hw/i386/amd_iommu.c.

The defect's own evidence holds:

  • The flash log's L72-78, L86 and L186-206 say what the body says.
  • The IVHD's names add up: 65,527 + 1 + 3 + 4 = 65,535 IDs.
  • 0d783accc is an ancestor of a5242a411 and not of its first parent.

BLOCKER

  1. kernel/src/arch/x86_64/amdvi/mod.rs:330-344, choice 4 and roast a: refusing INVALIDATE_IOMMU_ALL on a unit that sets IASup. With the spec read, the refusal rests on QEMU's handler and on units that no test machine is.

    • AMD's answer.
      • §1.3.3.3 (p.44) says the optional INVALIDATE_IOMMU_ALL "may simplify trusted boot, error recovery, and resumption from low-power states".
      • §2.4.8 (p.136) says that when it completes, "all IOMMU caches are empty".
      • IASup is EFR bit 6, RO, reset Xb (p.228), defined since spec rev 2.0 (p.39).
    • Linux's answer.
      • amd_iommu_flush_all_caches (iommu.c:1648-1657) sends INVALIDATE_IOMMU_ALL and a completion wait (:1615-1622) whenever check_feature(FEATURE_IA) is true.
      • early_enable_iommu calls it right after iommu_enable (init.c:2888-2901).
      • Linux calls it again after making every uninitialised DTE block, "to make sure the changes to the device table are active" (init.c:2326-2340). That is exactly the actuator's moment.
      • Linux walks per ID only where IASup is clear.
    • The units in reach. Both set bit 6, decoded here: the bench's 0x206d73ef22254ade and QEMU's 0x29d3. The only IASup-clear units the spec names are emulated ones (§2.4.8: "HV should emulate[] guest IOMMU to have IASup set to 0"), and no test machine is one.
    • What follows. leave_on sends INVALIDATE_IOMMU_ALL (Table 41, p.137: opcode 08h at +04[31:28], every other bit reserved), then the existing COMPLETION_WAIT. Before the push, it refuses by name a unit whose bit 6 is clear. That refusal is the test machines' feature set, not a second path.
  2. kernel/src/arch/x86_64/amdvi/mod.rs:91,272,323-343, choices 1 and 3: growth.

    • Under BLOCKER 1, two commands fit the spec's minimum ring of 256 entries (MMIO 0008h, p.215). The drain, the kernel/pure/ producer and both host tests would serve nothing.
    • What goes: the DeviceEntry match and its loop (:330-343), and leave_on's ivrs and unit parameters, with their arguments at :91.
    • The branch can delete more than it adds. The design instead adds about 94 lines.
  3. kernel/src/arch/x86_64/amdvi/mod.rs:309-312,341, choice 2. "Invalidating each one exactly matches what it wrote" is not the spec's complete invalidation.

    • §2.4.2 (p.125): INVALIDATE_DEVTAB_ENTRY "does not invalidate translation cache entries".
    • Table 7 (p.70): DomainID is what "the IOMMU must use to tag its internal translation caches".
    • Every BLOCKED entry gets DomainID 1 (:311). So a translation the unit already holds under DomainID 1 outlives the walk.
    • Where IASup is clear, Linux's walk comes with INVALIDATE_INTERRUPT_TABLE for every ID and INVALIDATE_IOMMU_PAGES for every domain (iommu.c:1560-1572, :1634-1646).
    • INVALIDATE_IOMMU_ALL closes this gap. A walk that survives owes at least DomainID 1's pages.
  4. tests/common/iommu.rs:450-451: the guest test's DMA claim. "With the switch-off reverted that boot's stick never binds" cannot fail on QEMU v11.1.1 once metal takes INVALIDATE_IOMMU_ALL.

    • Why it goes blind. Every function's address space starts on iommu_nodma (amd_iommu.c:2425, :2470, :1161-1175). It moves to translation only in amdvi_update_addr_translation_mode (:1249-1289). That function's only caller is amdvi_inval_devtab_entry (:1292-1313), and amdvi_inval_all (:1332-1351) never calls it. That breaks §2.4.8's empty caches, so the gap is QEMU's.
    • What the change owes:
      • (a) The gap is filed in issues/, with an owner and an exit that a QEMU at build/ci/qemu-version can meet.
      • (b) amdvi_firmware_left drops the claim in the same diff.
      • (c) The guest test keeps the switch-off reverted as its negative control. It still goes red on the three was handed over with … on; it goes off lines and on AMDVI_OFF's control=0x0000000000000000, which QEMU's register model reads back.
      • (d) The DMA half and its negative control are held on the AMD bench: with the switch-off reverted, the bench's stick never binds and no Boot: complete appears. The body's Guest tests reason says so.
    • Who checks the new command's encoding. QEMU logs an illegal command and carries on (:394-402, :1574-1578), where the spec halts the buffer (§2.4, p.123). Only the bench, or a reader holding Table 41, checks how the new command is encoded.

NOTE

  1. PR body, spec table. Every claim marked "not read" holds against 48882:

    • ComLen 1000b to 1111b is 256 to 32,768 entries, and values below 1000b are reserved (p.215).
    • CmdHeadPtr and CmdTailPtr are bits [18:4] (p.252-253).
    • DevTabSize 1FFh is the 2 MiB maximum (p.214).
    • IASup is optional (§1.3.3.3, §2.4.8).
    • A slot is free once the head passes it: "After incrementing this register, the IOMMU cannot re-fetch the command" (p.252). So both the design's wait and the investigation's are legal.
    • COMPLETION_WAIT "does not finish until all older commands issued since a prior COMPLETION_WAIT have completely executed" (§2.4.1, p.123-124). So design point 2 holds.
    • Head equal to tail means fetched, not executed (§2.4, p.123), as the body says.
  2. PR body, roasts h and c.

    • Roast h: by the spec, a tail written equal to the head after adding commands is undefined (MMIO 2008h, p.253). "Reads as empty and skips" is what QEMU does, not what the spec says.
    • Roast c's "for no gain": Linux writes the tail after every command (iommu.c:1260-1276) into a 512-entry ring (amd_iommu_types.h:237-238), and waits for room by re-reading the head (iommu.c:1410-1445). Its gain is the overlap.
  3. issues/the-iommu-firmware-left-row-reads-only-vt-d-lines-so-it-reds-on-an-amd-vi-machine.md. The owner exists (issues/an-amd-vi-machine-isolates-no-device.md holds the AMD laptop track), and the exit is readable.

    • Under BLOCKER 4, this judge is the only reader of the DMA half's negative control, so it is no longer later work.
    • issues/a-metal-row-names-no-hardware-and-a-bench-without-it-reds.md has an exit that would let this row be declared VT-d and not run on the bench. This file should say why the row has to judge AMD-Vi instead.

DESIGN NEEDS CHANGES: leave_on invalidates with one INVALIDATE_IOMMU_ALL and the existing COMPLETION_WAIT, after refusing by name a unit whose EFR bit 6 (IASup) is clear; the IVHD walk, its parameters, the drain, the kernel/pure/ producer and its host tests go; QEMU v11.1.1's INVALIDATE_IOMMU_ALL gap is filed; amdvi_firmware_left drops its stick-never-binds claim and keeps the register half's negative control, and the DMA half's negative control is held on the AMD bench and stated in the body.

@Japabu

Japabu commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

Design acceptance, by the orchestrator, with the review's named changes (#884 (comment)). The owner's standing rule is that a design follows the manufacturer's documents and the published state of the art. Here that is AMD's 48882 §2.4.8 and Linux's amd_iommu_flush_all_caches. The build is:

  • The invalidation. leave_on invalidates with one INVALIDATE_IOMMU_ALL, then the existing COMPLETION_WAIT. Before that, it refuses by name a unit whose EFR bit 6 (IASup) is clear.
  • What goes. The IVHD walk, its parameters, the drain, the kernel/pure/ producer and its host tests.
  • QEMU v11.1.1's INVALIDATE_IOMMU_ALL gap is filed (amdvi_inval_all never re-reads a DTE's mode), with an owner and an exit.
  • amdvi_firmware_left drops its stick-never-binds claim and keeps the register half's negative control.
  • The DMA half's negative control is held on the AMD bench: with the switch-off reverted, the stick never binds. The body states it.
  • The iommu_firmware_left row's judge reads AMD-Vi lines. That is the issue this PR files, and per the review's NOTE 3 it is now part of this branch, because that judge is the DMA half's only reader. The issue file closes in this PR.

Japabu and others added 3 commits October 12, 2026 15:27
…t reds on an AMD-Vi machine

Its judge finds units by ` translating gsts=`, which only vtd prints. An
AMD-Vi machine programs no unit and says what it switched off in amdvi's
own lines, so once the actuator's ring stops panicking the AMD bench's
shared-debug boot, the row reds there on "no unit was programmed".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…MU_ALL

The actuator wrote one INVALIDATE_DEVTAB_ENTRY for every requester id its
unit's IVHD names into a 256-entry ring it never refilled, and asserted
once 255 were written. The AMD bench's IVHD names 65,535 ids, so every
shared-debug boot there panicked at amdvi/mod.rs:325 before the unit was
switched off (#873's run). 0d783ac brought the IVHD walk in (#837);
QEMU's IVHD names eight functions, so the guest test never reached the
bound.

It now sends INVALIDATE_IOMMU_ALL (48882 Table 41: opcode 08h, every
other bit reserved) and the existing COMPLETION_WAIT. Per §2.4.8 every
cache is empty once it completes, which also drops translations tagged
with the BLOCKED entries' DomainID 1 that a per-entry walk left behind
(§2.4.2). Linux does the same in amd_iommu_flush_all_caches whenever
FEATURE_IA is set. A unit whose EFR IASup (bit 6) is clear is refused by
name before anything is written: both units in reach set it, the bench's
0x206d73ef22254ade and QEMU's 0x29d3. The walk, its expect on the device
list, the ring bound and leave_on's ivrs and unit parameters go.

QEMU 11.1.1's amdvi_inval_all never re-reads a device table entry's mode,
so under QEMU the actuator's entries block nothing: amdvi_firmware_left
drops its stick-never-binds claim, keeps the register half's negative
control, and the gap is filed with its exit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
The judge found units only by VT-d's ` translating gsts=`, so once the
actuator stops panicking the AMD bench's shared-debug boot it would red
there on "no unit was programmed". It now also takes every
`iommu: amdvi unit<N> handed over control=` line as a unit, and requires
that unit's CmdBufEn, EventLogEn and IommuEn hand-over lines and its
switched-off line; the T14's VT-d units are judged as before. That log is
on the stick only if the switch-off let the stick's DMA through, which is
the half QEMU cannot show.

Closes issues/the-iommu-firmware-left-row-reads-only-vt-d-lines-so-it-reds-on-an-amd-vi-machine.md,
filed in this pull request's design round.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
@Japabu
Japabu force-pushed the wt/toyos-amdvi-ring branch from 206ece4 to f2c537a Compare October 12, 2026 13:57
@Japabu Japabu changed the title Design: the AMD-Vi firmware-left actuator drains its command ring before it wraps, so the AMD bench's shared-debug boot stops panicking amdvi: the firmware-left actuator invalidates with one INVALIDATE_IOMMU_ALL, and its metal row judges AMD-Vi units Oct 12, 2026
@Japabu

Japabu commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

Metal results at f2c537a51. Four boots, each image's sha256 matching images.sha256 before its flash.

arm bench result expected
head AMD boots: Boot: complete (1333ms), unit0's CmdBufEn and IommuEn hand-over lines, switched off; iommu_firmware_left judge exit 0 (flash, kernel, judge) met
head T14 judge exit 0 on the VT-d lines (kernel, judge) met
base (main 867ec23ed) AMD panics at amdvi/mod.rs:325:9, "the unit's requesters overflow the actuator's 256-entry ring"; no Boot: complete (flash) met: the negative control is red
switch-off reverted AMD no Boot: complete on the log partition (flash) met: the DMA half's control is red

Every file is masked and committed whole at evidence commit 7b6ac575cf12e4afb2adda3bd2ec80d76896a06f.

@Japabu

Japabu commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

Review, round 2 (build), at f2c537a51. Checked against .claude/agents/reviewer.md at origin/main cc52b456c. The branch merges onto it cleanly (git merge-tree), and none of the files it touches has moved since 867ec23ed.

Round 1's BLOCKERs (design review at 206ece491)

  1. CLOSED. kernel/src/arch/x86_64/amdvi/mod.rs:291,296-301,329-334: leave_on asserts EFR bit 6, then writes 8 << 60, 0, COMPLETION_WAIT | done_at, DONE.
    • I read it against 48882 rev 3.11 (sha256 f7c375a1…ce22, the design review's copy). Table 41 puts 08h at +04[31:28], which is bits 63:60 of the first little-endian quadword, and reserves every other bit. MMIO 0030h bit 6 is IASup.
    • The silicon agrees. The AMD bench's head boot hands the unit over at status=0x00000018 (head-amd-kernel.log L118): CmdBufRun is 1 and EventLogInt is 0, and the completion wait behind the command stored. An ILLEGAL_COMMAND_ERROR would have stopped command processing (MMIO 2020h bit 4) and written an event.
  2. CLOSED. These are gone: the walk, its DeviceEntry match, its expect, the ring bound, push, and the ivrs and unit parameters. No drain, kernel/pure/ producer or host test was built.
  3. CLOSED, by 1. §2.4.8: "At the completion of an INVALIDATE_IOMMU_ALL command, all IOMMU caches are empty."
  4. CLOSED.
    • (a) issues/qemus-invalidate-iommu-all-leaves-every-function-untranslated.md is filed. Its owner exists (issues/an-amd-vi-machine-isolates-no-device.md), and a guest run can read its exit. Its QEMU citations hold at c3d48b7d.
    • (b) The doc drops the claim.
    • (c) With the switch-off reverted, the guest test exits 1 (guest-control.log L8). It goes red on switched off control=0x0000000000000000 (L13) while the stick binds (L192).
    • (d) The AMD bench with the switch-off reverted puts no Boot: complete on the log partition (L106). Its black-box tail counts xhci=0 on all eight CPUs (L78-L86). The head's cpu0 counts xhci=232 (L89).

Measurements at this head

  • cargo run -- --ci host: exit 0, "Host: 76 step(s), all green" (L9997).
  • The judge's AMD-Vi lines match what the head boot printed. head-amd-kernel.log L118-L122 has every line in the form tests/toyos.rs:5249-5266 asks for: unit0 handed over control=, the CmdBufEn, EventLogEn and IommuEn lines (was handed over with … on; it goes off), and unit0 @0xfdf00000 switched off control=. The build is f2c537a51 … clean, and the judge passed one unit.
  • The other arms:
    • The T14 head passes four VT-d units.
    • The base 867ec23ed panics at amdvi/mod.rs:325:9 with "overflow the actuator's 256-entry ring".
    • Every flashed image's sha256 matches the staged one.
  • The closed issue's exit is met. No citation of its slug is left.

Net lines (git diff --shortstat origin/main...f2c537a51): 4 files, +92 −43.

  • Production: +20 −31.
  • Tests: +39 −12.
  • Issues: +33.

BLOCKER

None.

NOTE

  1. tests/toyos.rs:5254 — the judge declares ["CmdBufEn", "EventLogEn", "IommuEn"] and the hand-over line's format a second time; tests/common/iommu.rs:485-486 already has them — what the actuator leaves on an AMD-Vi unit is one declaration in tests/common/iommu.rs, read by both, as the judge already reads common::iommu::unit_fields.
  2. PR body — false of the record since the metal results: "Metal: staged, not run", both "Unsure" bullets, and "accepted" linking the design review instead of the acceptance — a behaviour claim stands on the body, so that comment's four-arm table (evidence 7b6ac575) goes into the body as main's record.

LAND AFTER NAMED CHANGES

Japabu and others added 2 commits October 12, 2026 16:22
The guest test amdvi_firmware_left and the iommu_firmware_left metal
row's judge each spelled the three fields (CmdBufEn, EventLogEn,
IommuEn) and the kernel's "was handed over with <field> on; it goes off"
line. They now both read common::iommu::amdvi_left_on, so a field the
actuator leaves or a wording the kernel changes is written once. Review
round 2's NOTE 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
@Japabu
Japabu marked this pull request as ready for review October 12, 2026 14:37
@Japabu
Japabu added this pull request to the merge queue Oct 12, 2026
Merged via the queue into main with commit ecd6d1c Oct 12, 2026
6 checks passed
@Japabu
Japabu deleted the wt/toyos-amdvi-ring branch October 12, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant