Repository navigation
The kernel loads Intel's CPU microcode early on every CPU, and an AMD CPU says ToyOS has no loader for it - #886
Conversation
|
The AMD bench's Linux microcode reading, owed by the orchestrator, is now on the evidence branch: amd-bench-linux-microcode.txt at
The command is recorded in the file's header. |
|
Design review of #886 at Size: Judged against the sources, no finding. I fetched Linux v7.2 and Xen
BLOCKER
NOTE
DESIGN NEEDS CHANGES: a CPU that reports revision 0xffffffff loads nothing and is refused by name on both makers, as Xen does; drop the guest assertion of the hypervisor line, and rewrite that exit in the branch's own issue; replace the host test of which half of MSR 8BH each maker reports with a revision constructor per maker. |
|
Design acceptance, by the orchestrator, with the review's named changes and NOTEs (#886 (comment)). This follows the owner's standing ruling: the manufacturers' documents and the published state of the art, Linux and Xen. The build is the body's design with these changes:
The hand-off with #873: #873 lands first and its |
…nything reads what an update changes `toyos-microcode` gains AMD's containers beside Intel's files (`amd`, as AMD's `amd_ucode_info.py` and Linux v7.2's `amd.c` read them: patches matched by the CPUID their Zen patch ID decodes to, chipset-specific patches and a nonzero minimum-revision word refused as unmodelled, a patch at or above the running revision loaded, an equal one again on every thread as Linux's early loader does), whether a CPU loads at all (`Maker::of` over `toyos_cpuvuln::Vendor`, `may_load` refusing a hypervisor and revision 0xffffffff by name, as Linux and Xen do), one revision constructor per maker's half of MSR 8BH, revisions as the unsigned dword Linux compares, and the two files the kernel embeds 16-byte aligned: Intel's 06-8c-01 and linux-firmware 20260916's microcode_amd_fam17h.bin. `arch::x86_64::microcode::load` runs on the BSP in `after_console`, right after `init_cr0` and before `random::key` and `control_regs::init`, and on each AP right after its `init_cr0`, as Intel's guidance asks. Intel's trigger takes the update data's address, AMD's the patch's, each an `asm!` of its own that reads memory; family 0x17 then drops the translation of the patch's first and last byte (Linux c809b0d0e52d). The load is read back, and every CPU that reads a revision must run the first CPU's. One line per CPU says what it found, what the file holds and what it runs. There is no runtime SHA-256 of an AMD patch, where Linux and Xen have one: their patch is a file the kernel did not ship, and these are inside the kernel image. A host test holds every patch in the embedded container to Linux v7.2's `amd_shas.c` (committed under tests/linux/, outside every shipped package), which records none above EntrySign's cutoff: that is the cutoff rule's build-time form. The licence gate gains `Terms::Firmware`, scoped to vendor firmware a device or CPU verifies by its maker's signature, the one place LicenseRef-Intel-Microcode and LicenseRef-AMD-ucode pass; every x86-64 ROOT carries both makers' licence texts under share/licenses/, as each asks. The `boot-actuators` arm `microcode-reseal` hands the BSP the T14's update with its header's revision raised to 0xbf and its checksum resealed, a const-built aligned static, so the read-back is shown to stop a boot on real Intel. The `microcode` metal row holds every CPU's line to Linux's reading of the same machine: the T14's cpuinfo, and the AMD bench's capture, committed under tests/metal/amd-linux/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Clippy's type_complexity refused the boxed closure it held per signature. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
bc44b76 to
f126fb5
Compare
|
Ruling after the hung negative controls. The T14 Cause. The BSP loads in Ruling: a failed read-back is a refusal, not a panic. By the vendors' documentation, a microcode update the processor does not take leaves it running the revision it had. The CPU's own revision register (
Filed separately, not fixed here: on x86-64 a panic before |
…os-microcode Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…tes Linux or Xen Both negative-control arms of the microcode row hung their benches: the read-back's panic came inside after_console, before power::init_reset decodes the reset and, on the AMD bench, before any clock can time the panic's bound, so the panel was held until a power cycle. The ruling on #886 (comment 6131006022) makes a failed read-back a refusal: by the SDM (Vol. 3A §12.11.7.1, §12.11.7.2 Example 12-10) and AMD's PPR 55922 (MSR0000_008B), MSR 8BH after a load is the revision the CPU runs, so a CPU that does not take an update runs what it reads back. The loader now says `refused <update>` with that read-back as `running`, holds it to the machine's like any other, and the boot goes on; the metal judge reds any refused line. By the owner's clean-room ruling (#902), the judge is no longer held to a Linux reading of either bench but to the update each maker's embedded file holds for it, Linux's amd_shas.c and the AMD bench's Linux capture are deleted with the digest test that read them, and every Linux and Xen citation is replaced by Intel's or AMD's document or removed. The word at patch offset 12 is named as AMD's parser names it, mc_patch_data_checksum. A panic before the reset register is read holds the machine for good: filed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…rocode Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
Round 2 on metal, at
The T14 reseal arm answers round 1's open question: the old hang was the panic hold, not a fault at the trigger, since with the refusal in place the boot completes. One thing to check in review: the judge rebuilt the reseal image from |
|
Review of #886 at Size.
The deletion this review names is under BLOCKER 4. Round 1's BLOCKERs (design review, comment 6126224559)
The ruling after the hung controls (comment 6131006022): built.
On metal, both negative controls now finish their boots and red the row. The T14 reseal arm reads The image-hash question: the verdict stands.
BLOCKER
NOTE
SEND BACK |
|
Ruling after round 2's review (#886 (comment)): #886 lands Intel's loader alone, and the AMD loader leaves this branch. Intel's half is built from the SDM, judged on the T14 (head green, both controls red, the reseal arm refused as ruled), and owes nothing. AMD's half owes a clean-room reader (BLOCKER 2), matching by the equivalence table (1), and undocumented behaviours stated with their measurements (3). Holding Intel's half for that work delays it for nothing. So:
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…as no loader for it The owner's ruling after round 2's review (#886 (comment)): the AMD container reader was not built clean-room, matched a patch by its decoded ID rather than the equivalence table, and carried behaviours no document or measurement backs, among them the family-0x17 INVLPG that the no-invlpg arm showed changes nothing. It leaves this branch. - amd.rs, its tests, the embedded container, its NOTICE section, its licence text, its ROOT copy and its licence-gate row are deleted, and with them Maker, Revision::from_patch_level and the kernel's AMD trigger and INVLPG. - toyos_microcode::loader admits Intel alone; any other vendor's CPU logs "loads nothing: ToyOS has no <Vendor> microcode loader" and reads nothing more. - With one maker left, the intel module folds back into lib.rs, where main has the reader, and Choice is no longer generic. - The metal judge holds the AMD bench to that line on every CPU; the host test accepts it on eight CPUs, the roster the bench brings up, and refuses an AMD line that read and loaded. - issues/the-kernel-loads-no-cpu-microcode.md keeps the AMD half open with the ruling's exit; the T14 half is recorded as met. - issues/a-metal-readback-does-not-prove-which-image-wrote-its-log.md files the review's readback-provenance note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
Round 3 on metal, at
Every arm reads as the request predicted. The judge logs are beside each readback under |
|
Review of #886 at Size.
The production growth is the loader the issue asks for. Nothing in it can be deleted or merged into something that already exists. Round 2's BLOCKERs (comment 6135201083)
The split ruling (comment 6135209087)
Evidence, checked
Round 3's metal run, read from the readbacks the brief names
The run says what the orchestrator's comment says. None of it is on the record the body cites.
BLOCKER
NOTE
SEND BACK |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…clean-room rule as root CLAUDE.md gives it The kernel loads Intel's microcode at this branch, so "the kernel loads no CPU microcode" is refuted; issues/README.md's "Slugs" has the work that takes an issue up rename it and move every citation, here the security track's list. The AMD paragraph and the exit said the reader must have read no other implementation. Root CLAUDE.md lets the source be read, and asks only that one agent write a specification of facts citing no implementation and another build from it alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
Review of #886 at Size.
These match the body's figures, read from What changed since
Round 3's BLOCKERs (comment 6139149316)
Round 3's NOTEs
Evidence at this head.
The guest suite was measured at No BLOCKER and no NOTE remains. LAND |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
tests/toyos.rs: #886's `microcode` row and this branch's `ps2server_arms` were each added after `metal_sim_scanout_wc`; both are kept, each on METALCASE. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Fix round 4. Head
56f08c24b. It builds the owner's ruling after round 2's review (ruling, points 1-4; review): this branch lands Intel's loader alone, and the AMD loader leaves it. Round 4 answers round 3's review: round 3's metal readings are published, the issue is renamed, andorigin/mainis merged at52e32385d(#894). It takes up the issue now atissues/the-kernel-loads-no-amd-microcode.md, whose AMD half stays open. A draft. Before it lands: a review.Evidence is on
ToyOSOrg/evidencepr-886: round 3's gates, mutations and staging ata6963e0d, round 3's metal readings at70025e35, round 4's host gate ateaf66e29, and round 2's metal readings atf17cea3b, whose exits are files since70025e35. Authority is Intel's: SDM Vol. 3A (325384-093US) §12.11, Intel's Microcode Update Guidance, and the 500 Series PCH datasheet for the T14's reset.The design (accepted in the ruling)
The kernel loads, on every CPU, the newest update Intel's embedded file holds for it, before anything reads what an update changes. On a CPU of any other vendor it reads nothing and logs by name that ToyOS has no loader for it:
microcode: cpu0 Amd signature 0x860f01 loads nothing: ToyOS has no Amd microcode loader. The AMD row expects that line.Its roast. An AMD machine runs its firmware's microcode, however stale, until the AMD half is built. That is the issue's open half, not a fallback: no AMD path runs. The line names the vendor so a bench reading tells a missing loader from a load that failed.
What this round changed
The AMD loader leaves the branch (ruling 1; review BLOCKERs 1-4)
Deleted:
kernel/microcode/src/amd.rsand its tests;kernel/microcode/amd-ucode/microcode_amd_fam17h.bin, itsNOTICEsection,licenses/AMD-ucode-license.txt, its ROOT copy and itsbuild/licence.rsrow;Maker,Revision::from_patch_level;AMD_TRIGGER,load_amd, and the family-0x17INVLPGwithPatch::leaves_its_mapping_uncached(BLOCKER 4).The review's BLOCKERs 1 to 3 asked for a rebuilt AMD reader. The ruling moves that work to the issue's exit, so no AMD reader is on this branch for them to apply to.
Added:
toyos_microcode::loader(vendor)admits Intel alone, andUnloaded::Vendorreads "ToyOS has no microcode loader". The kernel calls it before it reads any MSR. Test:a_vendor_toyos_has_no_loader_for_loads_nothing.Folded back. With one maker left, the
intelmodule goes back intolib.rs, wheremainhas the reader, andChoice<'a>is no longer generic. The crate'sdescriptionsays Intel alone again.build/build.rs's licence slice becomes the oneMICROCODE_LICENCE, pushed on x86-64.The judge.
microcode_on_metalholds:currentorloaded;microcode_linesstill reds the firstrefusedline on any machine.microcode_verdictaccepts both benches on eight CPUs and refuses eight machines. The eight CPUs are the roster the AMD bench brings up (SMP: roster full at 8 CPUs), which fixes the review's roster NOTE.The issue (ruling 2; round 3's BLOCKER 2 and NOTE 1)
issues/the-kernel-loads-no-cpu-microcode.mdis renamedissues/the-kernel-loads-no-amd-microcode.md, for the old slug is false of this tree (issues/README.md, "Slugs"), and its one citation, inissues/the-kernel-is-at-least-as-secure-as-linux-on-every-machine-toyos-supports.md, moves in the same commit. It isopen, records the T14 half as met by this branch, and states the clean-room rule as rootCLAUDE.md("Zero legacy") gives it. Its exit is the ruling's:amd_ucode_infoand writes from it a specification of facts citing no implementation, keeping the provenance in its own evidence; another builds from that specification alone, handed to it in its brief and never committed;Round 2's readings are published (ruling 3, BLOCKER 5)
Each arm's judge log,
kernel.logandboot.txtare masked and onpr-886atf17cea3b. The orchestrator booted and judged every arm. Each arm's exit, as the orchestrator reported it, is recorded inr2/readings/<arm>/judge.exitat70025e35; a failing judge log also carries its exit in its last line.t14-heade2b398cb6t14-reverted(m3)1e92b3edct14-reseal(m1), judged fromb7a7b062ab7a7b062aamd-heade2b398cb6amd-reverted(m3)406b5863damd-trigger-removed(m2)5b029c0a8amd-no-invlpg(m4)0cb620caeEach judge command was
cargo test --test toyos-build -- --metal --metal-readback <arm dir> microcode, with--metal-hoston the AMD arms. Thet14-resealarm also has the first judging, from the head tree: it restaged the arm (exit 2) and judged nothing.amd-no-invlpgbesideamd-head, reported only. Both read the same eight lines.amd-headamd-no-invlpgOn this branch the family-0x17
INVLPGis deleted (BLOCKER 4). These readings are only a record of the AMD reader that left.The NOTEs (ruling 4)
b680a973b, merged here. ItsPCIDEis decided by PCID and INVPCID (control_regs.rs) and reads no microcode revision, so the acceptedRunningwitness has nothing to thread into, and this head builds none.issues/a-metal-readback-does-not-prove-which-image-wrote-its-log.md, owned by the orchestrator. Its exit: a judge from a tree other than the one a readback's log names refuses it by name, and judging never writes a readback'simage.img.cargo,git applyandgit diffrun directly, and no script was committed. Round 2's scripts stay onpr-886, whose branches are append-only.Tests, cheapest tier first
Host. The judge and the vendor admission run as mutations. Each is a checked patch, applied, run, reported and reverted, with the porcelain empty after each (run.out; patches and logs beside it, at
a8130e0e4, whose tree differs from the head only by one comment intests/toyos.rs):cargo test --test toyos-checks microcode_verdictcargo test -p toyos-microcodea_vendor_toyos_has_no_loader_for_loads_nothingThe Intel reader's tests are the build round's, moved from
intel/tests.rsback totests.rsunchanged except for theinclude_bytes!paths. The build round's mutations guarded that code atf126fb514(run.out); this round did not run them again.Guest. No guest test is added or changed. An x86-64 guest takes the hypervisor arm on an Intel host and the no-loader arm on
AuthenticAMDqemu64. Neither reads past the line, and no guest test asserts it.Metal. Staged with the harness's own
--metal-readback; the request is below.Checks (root
CLAUDE.md)b680a973b, the base this head merged, with the row kept (m3). It is staged on both benches, and each must red on "no microcode line".t14-reseal(m1): a header revision Intel's payload does not carry. It must red on cpu0'srefusedline on a completed boot.microcode_verdict: what the judge refuses;Gates
cargo run -- --ci hostdfee7fa3dcargo run -- --ci hosta8130e0e4cargo run -- --build-onlya8130e0e4cargo run -- --build-only --arch aarch64a8130e0e4cargo test, the whole guest suite, 62 of 62, at a one-minute load average of 24.59 to 24.73a8130e0e4--metal-readbackstagingsVerdict::Staged)r3/readingscargo run -- --ci host56f08c24ba8130e0e4anddfee7fa3ddiffer by one comment intests/toyos.rs, which builds into no image.56f08c24bmergesorigin/mainat52e32385d; sinceb680a973bit has taken #892, #903, #875, #874, #887, #893, #863, #896, #900 and #894, none touching a path the metal row measured (round 3's review). The merge and the issue's rename are the only changes pastdfee7fa3d, and the host gate above is run at56f08c24b.Metal
The request gives each arm's tree, image sha256,
toyos-metalinvocation, judge command (row wordmicrocode) and expected verdict. The mutation trees are local commits on a detached head, never pushed.t14-headdfee7fa3dacf803b1…current 0xbe running 0xbet14-reseal(m1)117f0d454009a7959…found 0xbe refused 0xbf running 0xbeamd-headdfee7fa3dac488ca6…loads nothing: ToyOS has no Amd microcode loadert14-reverted(m3)e4b2817c358d5e9a6…amd-reverted(m3)2e8aba69f1bc2bb99…The readings. The orchestrator booted and judged each arm; its exit, judge command, judge log,
kernel.logandboot.txtare onpr-886at70025e35, masked. Eachkernel.log'ssupervisor: buildnames the arm's tree.t14-headdfee7fa3damd-headdfee7fa3dt14-reverted(m3)dfee7fa3damd-reverted(m3)dfee7fa3dt14-reseal(m1)117f0d454Every arm reads as its request expects. The images are
dfee7fa3d's. Past it,56f08c24badds only the merge ofmain, which reaches no path the row measured, and the issue's rename.The first m3 staging diffed against an
origin/mainthat another worktree's fetch had moved pastb680a973b. It failed to build (exit 101) and was discarded;stage.outrecords it.What I am unsure of
amd-headboot can catch a drift between the two.Revisioncompares unsigned, as acceptance 1 ruled. No pinned file carries one.Size
git diff --shortstat origin/main...56f08c24b: 21 files, +718 −128, against round 2's 24 files, +1568 −521.kernel/microcode/src/lib.rs,kernel/src,build, manifests,Cargo.lock): +412 −43.kernel/microcode/src/tests.rs,tests/): +182 −7.NOTICE,issues/): +124 −78, the issue's rename counted as a delete and an add.Round 3's commit,
dfee7fa3d: +680 −1141, most of it the AMD reader, its container and theintelmodule folded back.🤖 Generated with Claude Code
https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy