Repository navigation
toyos-cpuvuln: Linux's speculation verdicts and mitigation choice, pure (S1) - #602
Conversation
…re (S1) Stage S1 of issues/kernel/the-kernel-mitigates-what-linux-mitigates-on-the-t14.md: a no_std, unsafe-free crate the kernel can depend on later, mapping a CPU's CPUID and MSR facts to the line Ubuntu-6.8.0-142.142 (commit 53e5d07aac02) prints in each of its 17 /sys/devices/system/cpu/vulnerabilities files, and to the mitigation state bugs.c selects under the default command line and the pinned config (/boot/config-6.8.0-142-generic, sha256 3b8533dd...5890, extracted from linux-modules-6.8.0-142-generic_6.8.0-142.142_amd64.deb and checked). Carried from the tag: cpu_vuln_whitelist and cpu_vuln_blacklist (common.c:1182-1344) row for row with x86_match_cpu's first-match rule, cpu_set_bug_bits (common.c:1414-1578), init_speculation_control (common.c:973-1012), spectre_bad_microcodes (intel.c:141-180), tsx_init's state under TSX_MODE_OFF (tsx.c:158-229), every *_select_mitigation in cpu_select_mitigations (bugs.c:149-199) and cpu_show_common's strings (bugs.c:3305-3371). Refused rather than approximated: AMD family 0x15 on and Hygon, whose amd.c/hygon.c derive speculation features from microcode tables and MSR probes the facts do not carry; and the l1tf and itlb_multihit lines of an affected CPU, which read the e820 map, kvm_intel and IA32_FEAT_CTL. Recorded in issues/kernel/the-speculation-decision-refuses-amd-from-family-0x15-and-two-lines.md. Both fixtures are provisional until S0 captures them: the T14's facts are its documented identity (i5-1135G7, family 6 model 0x8C stepping 1) and the TCG model's are read off QEMU v11.1.1's target/i386/cpu.c; the expected lines are Linux's source read by hand. Negative control, applied as a checked patch and restored: deleting GDS from the TIGERLAKE_L blacklist row builds (exit 0) and reds the T14 test (exit 101) with gather_data_sampling "Not affected" against "Mitigation: Microcode". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every bugs.c, common.c, amd.c, hygon.c, intel.c and tsx.c range the crate and its issue cite now ends on the cited function's or block's closing line at Ubuntu-6.8.0-142.142, checked by printing both boundary lines of each. The previous commit's message cites intel.c:141-180 and tsx.c:158-229; the functions end at intel.c:182 and tsx.c:245. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review of #602 at a749acb. CI Oracle checks, measured by the reviewer in scratch. The tag was fetched from launchpad and resolves to 53e5d07a. S0 capture: /Users/jan/Dev/jan/toyos-s0/toyos-t14linux/s0/.
BLOCKER
NOTE
REMOVE
SEND BACK |
…/0x1A Answers the review of #602 at a749acb. The T14's facts are S0's words, from #601's toyos-t14linux/s0/t14/ at commit 44eb3c2: CPUID.1:EAX 0x806c1, 1:ECX 0x7ffafbbf, (7,0) EBX 0xf3bfa7eb and EDX 0xfc100710 (SRBDS_CTRL set), (7,2):EDX 0x1, 0x10A 0x0a005c6b (FBSDP_NO and RFDS_NO set, TAA_NO clear), 0x123 0, microcode 0xbe. fixtures/provisional/ is gone: fixtures/t14.txt is byte-identical to s0/t14/vulnerabilities.txt, and fixtures/tcg.txt is s0/tcg/console.txt lines 379-395 with the serial console's CRs stripped. Every public Decision field is now asserted. The tests read them through an exhaustive destructuring, so a field added to Decision does not build until a test names it. The T14 asserts spec_ctrl == 0x1 against S0's MSR 0x48, which reads 0x1 on all eight CPUs, and the arch_capabilities-zero control asserts clear_cpu_buf. New host tests hold the x86_match_cpu stepping mask (KABYLAKE_L stepping 0xB against 0xC), the first-match rule (SKYLAKE_X stepping 5 against 6), the bad-microcode bound (KABYLAKE stepping 0xA at 0x80 against 0x81) and the hypervisor GDS answer. AMD families 0x17, 0x19 and 0x1A are decided, per the owner's ruling. That takes three new Facts fields. cpuid_8000_0021_ecx carries TSA_SQ_NO and TSA_L1_NO. ls_cfg_readable and sbpb_write_accepted carry the results of bsp_init_amd's LS_CFG read and early_init_amd's PRED_CMD.SBPB write; each is asserted present exactly where Linux probes. The new selections are SRSO under safe-ret, TSA with amd_check_tsa_microcode's table, VMSCAPE's IBPB-on-VMEXIT, and x86_pred_cmd's SBPB. The code the review found unreachable (AUTOIBRS, Retbleed Unret, STIBP always-on and the AMD IBRS_FW clause) is now reached, and Stibp::Prctl's empty arm is gone. X86_FEATURE_ZEN is set by init_amd from identify_cpu (amd.c:1039, common.c:1997), after early_identify_cpu has run cpu_set_bug_bits (common.c:1732). So the "Zen guest" TSA clause never fires on the boot CPU, and a family 0x1A guest is not TSA-affected. The Milan and Turin KVM-guest fixtures take their CPUID from InstLatx64's bare-metal dumps (EPYC 7713 at 2dc186e9, EPYC 9655 at b499237d) with the hypervisor bit set. Their lines are this crate's reading of the tag. They sit in fixtures/awaiting-capture/, and issues/build/no-nightly-runner-has-had-its-cpuid-and-vulnerability-lines-captured.md owes the real capture. In nightly run 36496779560 the 14 KVM shards ran on EPYC 7763 (11), 9V74 (2) and 9V45 (1). The refusal issue is renamed to what still stands: issues/kernel/the-speculation-decision-refuses-amd-0x15-0x16-hygon-and-two-lines.md. The TCG test now asserts its lines over both values of every fact S0 does not verify: the hypervisor bit, RDRAND, the microcode and SMT. The QEMU source reading behind the old constant was qemu64 at v11.1.1's target/i386/cpu.c: xlevel 0x8000000A at 3545-3563, the hypervisor bit at 8486, no speculation bits at 996-1001 and 1024-1034, and the microcode default at 10187-10197. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review round 2 of #602 at ca476ba. CI
The reviewer measured every result below on a scratch copy of the crate at ca476ba, with host Round-1 blockers
Rulings asked for
BLOCKERThe AMD arms and two hypervisor arms have no test that can fail. Every patch below passes all 13 tests (
NOTE
REMOVE
SEND BACK |
…ecide every AMD family Review round 2 of #602 named nine mutations that passed every test. Each now has a host test that goes red, built from the pinned tag's logic (Ubuntu-6.8.0-142.142, 53e5d07a) and citing the lines behind each expected line: - STIBP always-on from AMD_STIBP_ALWAYS_ON without Unret: a native Milan with SMT (bugs.c:1575-1577, 2054-2068, 3185-3186). - The LS_CFG probe as the source of SSBD, and the probe's family bound: AMD 0x15, 0x16 and Zen1 0x17 without AMD_SSBD/VIRT_SSBD (amd.c:576-596). - SRSO_USER_KERNEL_NO's three branches and VMSCAPE's IBPB on VM exit (bugs.c:2703, 2715-2716, 2771-2781, 2861-2863). - The TSA_SQ_NO/TSA_L1_NO decoding (common.c:1555-1561, scattered.c:52-53). - A Zen4 row of the TSA microcode table: Genoa at 0x0a10114c and 0x0a10114b (amd.c:491, 522-525). - SRBDS and MDS inside an Intel guest: KABYLAKE without ARCH_CAPABILITIES (bugs.c:691-692, 3117-3119). The refusals now follow the module's single rule: an input is refused only when its answer rests on something the facts do not carry. AMD 0x15, 0x16, 0x18 and 0x1B and later rest on nothing beyond the facts: the LS_CFG probe is carried, and bugs.c's only family tests are SRSO's. So they are decided, and Refused::AmdFamily is deleted. Hygon stays refused because bsp_init_hygon's own LS_CFG probe (hygon.c:228-239) is not carried. Its table rows could never be reached and are deleted. The refusal issue is renamed to match. amd_check_tsa_microcode's `model <= 0xAF` bound changed no answer, because every row keys a model that bsp_init_amd names Zen3 or Zen4, so it is deleted. The false "does not enumerate ARCH_CAPABILITIES" comment is deleted: KVM enumerates it at the tag (kvm/cpuid.c:691). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review round 3 of #602 at 465b9e9. CI
The reviewer measured on a scratch copy of the crate at 465b9e9 with host
Round-2 blockers
BLOCKEREach patch below leaves all 19 tests green (
NOTE
REMOVENone. SEND BACK 🤖 Generated with Claude Code |
…s, a fixture for every sweep survivor Round 3's review found decision arms no test could fail. This round closes its five blocker groups with fixtures whose expected state and lines are read from the tag's source, and then sweeps the crate for the rest. - Hygon is decided rather than refused: its LS_CFG probe is the same fact as AMD's (hygon.c:228-239, every family), the untrained return thunk and IBPB around firmware take Hygon as bugs.c does, and its whitelist and blacklist rows are back. `decide` returns a `Decision`; `Refused` is gone. - itlb_multihit is decided: `Facts::feat_ctl` carries IA32_FEAT_CTL where Intel, Centaur and Zhaoxin read it, and the line is "VMX unsupported" or, with VMX kept by init_ia32_feat_ctl and no VM running, "VMX disabled". Only an affected CPU's l1tf line stays unmodelled; its issue now names the two facts it lacks. - States no input reaches are unrepresentable: `spectre_v2`, `bhi`, `mds`, `taa`, `mmio` and `rfds` are `Option`s without a "not affected" variant, `ibpb` is a bool (IBPB is conditional wherever Spectre v2 is), and `its` is a bool. MMIO's dead CLEAR_CPU_BUF block, TAA's always-true TSX_CTRL test, the RRSBA helper's dead guard, TSA microcode's dead vendor guard, the brtype probe's redundant vendor test and the doubled Intel check at the bad-microcode call site are deleted. - New fixtures: Zen1 with and without AMD_STIBP, Milan guest at microcode u32::MAX, a KABYLAKE guest at its bad microcode, Alder Lake with BHI_CTRL, retpoline guests with and without RRSBA_CTRL and RRSBA, Comet Lake across MDS_NO, FB_CLEAR, TSX_CTRL, RTM, MD_CLEAR, FLUSH_L1D, SRBDS_CTRL, RDRAND and RDSEED, RTM_ALWAYS_ABORT, GDS locked, Silvermont's MSBDS_ONLY SMT line, the T14's *_NO bits, RFDS by RFDS_CLEAR and by row, Hygon, Zhaoxin, Centaur, an unknown vendor, native Turin, a Zen2 guest, and IA32_FEAT_CTL's cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6SVYFkdvV2t38KzNrESxs
|
Round 4 at e4d4014: round 3's mutations and this round's sweep. Round 3's mutationsEach mutation was restated on e4d4014 where the code moved. Each ran as a checked patch through
Three have no code left to mutate: The sweep
How the 86 survivors of runs 1 and 2 ended:
The one mutant that does not build drops Files, in
🤖 Generated with Claude Code |
|
Review round 5 of #602 at e4d4014. CI
The reviewer measured on a scratch copy of the crate at e4d4014 with host Round-3 blockersAll are closed on the implementer's
The round-3 NOTEs are done: the dead Sweep
Fixtures against the tagEach new fixture's facts were walked through the tag's code. Every expected line and state matches, and none rests on running the crate:
The T14's BLOCKEREach patch below leaves 49/49 green. Each proposed test was run by the reviewer: green at e4d4014, red on its patch.
NOTE
REMOVE
SEND BACK 🤖 Generated with Claude Code |
…ng 0 and Hygon without SMT Three tests, expected values from Ubuntu-6.8.0-142.142: - Zen3 0x00a00f82: microcode 0x0a00820d is Tsa::Full, 0x0a00820c UcodeNeeded (amd.c:479-490,621). - COMETLAKE_L 0x000a0660 has no SRBDS or GDS, 0x000a0661 has both (common.c:1310-1311,1480-1483,1521-1523). - A Dhyana without SMT and with IBPB_BRTYPE is Srso::SmtDisabled (bugs.c:2689-2691,3284-3285). Each of five mutations exits 101 on its test. The owed S0 capture reads MSR 0x3A. Cargo.toml's description no longer names another crate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6SVYFkdvV2t38KzNrESxs
|
Round 5 mutations at e767338. Each patch applied with key_nibble (exit 101)diff --git a/toyos-cpuvuln/src/table.rs b/toyos-cpuvuln/src/table.rs
--- a/toyos-cpuvuln/src/table.rs
+++ b/toyos-cpuvuln/src/table.rs
@@ -341,6 +341,6 @@ pub(crate) fn tsa_microcode(id: &Ident, microcode: u32) -> bool {
(0xaa002, 0x0aa00216),
];
// `union zen_patch_rev` (`asm/cpu.h:80-90`) above its `rev` byte.
- let key = (id.family - 0xf) << 16 | (id.model >> 4) << 12 | (id.model & 0xf) << 4 | id.stepping;
+ let key = (id.family - 0xf) << 16 | (id.model >> 4) << 12 | (id.model & 0x7) << 4 | id.stepping;
ROWS.iter().find(|&&(k, _)| k == key).is_some_and(|&(_, min)| microcode >= min)
}stepping_mask (exit 101)diff --git a/toyos-cpuvuln/src/table.rs b/toyos-cpuvuln/src/table.rs
--- a/toyos-cpuvuln/src/table.rs
+++ b/toyos-cpuvuln/src/table.rs
@@ -60,7 +60,7 @@ const ANY: u32 = 0;
/// `X86_STEPPINGS(mins, maxs)`, `GENMASK(maxs, mins)` (`asm/cpu_device_id.h:59`).
const fn steppings(min: u32, max: u32) -> u32 {
- ((1 << (max + 1)) - 1) & !((1 << min) - 1)
+ ((1 << (max + 1)) - 1) & !(1 << min)
}
pub(crate) struct Row<F> {any_one (exit 101)diff --git a/toyos-cpuvuln/src/table.rs b/toyos-cpuvuln/src/table.rs
--- a/toyos-cpuvuln/src/table.rs
+++ b/toyos-cpuvuln/src/table.rs
@@ -56,7 +56,7 @@ macro_rules! bl { ($($f:ident)|+) => { Bl(0 $(| $f.0)+) }; }
/// `X86_FAMILY_ANY`, `X86_MODEL_ANY` and `X86_STEPPING_ANY`
/// (`include/linux/mod_devicetable.h:700-702`).
-const ANY: u32 = 0;
+const ANY: u32 = 1;
/// `X86_STEPPINGS(mins, maxs)`, `GENMASK(maxs, mins)` (`asm/cpu_device_id.h:59`).
const fn steppings(min: u32, max: u32) -> u32 {row_swap (exit 101)diff --git a/toyos-cpuvuln/src/table.rs b/toyos-cpuvuln/src/table.rs
--- a/toyos-cpuvuln/src/table.rs
+++ b/toyos-cpuvuln/src/table.rs
@@ -248,8 +248,8 @@ const BLACKLIST: &[Row<Bl>] = &[
intel_steppings(ICELAKE_D, ANY, bl!(MMIO | GDS | ITS | ITS_NATIVE_ONLY)),
intel_steppings(ICELAKE_X, ANY, bl!(MMIO | GDS | ITS | ITS_NATIVE_ONLY)),
intel_steppings(COMETLAKE, ANY, bl!(MMIO | MMIO_SBDS | RETBLEED | GDS | ITS | VMSCAPE)),
- intel_steppings(COMETLAKE_L, steppings(0x0, 0x0), bl!(MMIO | RETBLEED | ITS | VMSCAPE)),
intel_steppings(COMETLAKE_L, ANY, bl!(MMIO | MMIO_SBDS | RETBLEED | GDS | ITS | VMSCAPE)),
+ intel_steppings(COMETLAKE_L, steppings(0x0, 0x0), bl!(MMIO | RETBLEED | ITS | VMSCAPE)),
intel_steppings(TIGERLAKE_L, ANY, bl!(GDS | ITS | ITS_NATIVE_ONLY)),
intel_steppings(TIGERLAKE, ANY, bl!(GDS | ITS | ITS_NATIVE_ONLY)),
intel_steppings(LAKEFIELD, ANY, bl!(MMIO | MMIO_SBDS | RETBLEED)),hygon_family (exit 101)diff --git a/toyos-cpuvuln/src/lib.rs b/toyos-cpuvuln/src/lib.rs
--- a/toyos-cpuvuln/src/lib.rs
+++ b/toyos-cpuvuln/src/lib.rs
@@ -808,7 +808,7 @@ pub fn decide(facts: &Facts) -> Decision {
// `srso_select_mitigation` (`bugs.c:2670-2807`) under its default
// `SRSO_CMD_SAFE_RET`; `retbleed` is never `IBPB` here.
let srso = bugs.srso.then_some(
- if ibpb_brtype && id.family < 0x19 && !f.smt {
+ if ibpb_brtype && id.family < 0x18 && !f.smt {
Srso::SmtDisabled
} else if eax21 & CPUID_8000_0021_EAX_SRSO_USER_KERNEL_NO != 0 {
if eax21 & CPUID_8000_0021_EAX_SRSO_BP_SPEC_REDUCE != 0 {Failing tests: key_nibble -> a_tsa_row_keyed_by_a_model_nibble_of_8_or_more_is_read; stepping_mask, any_one, row_swap -> a_blacklist_row_for_stepping_zero_stands_before_its_any_stepping_row; hygon_family -> hygon_without_smt_and_with_ibpb_brtype_has_srso_smt_disabled. Gates: cargo test -p toyos-cpuvuln exit 0 (52 passed); clippy exit 0; cargo run -- --ci host exit 0. 🤖 Generated with Claude Code |
|
Orchestrator: round-4 review's three blockers closed at e767338 — the five named mutations (key_nibble, stepping_mask, any_one, row_swap, hygon_family) each exit 101 on their new test (issuecomment-5891796254); the full 719-mutant sweep and the table diff against the tag were independently re-run by the round-4 reviewer. Landing. 🤖 Generated with Claude Code |
One conflict, issues/kernel/the-kernel-still-creates-threads.md's stages. main (#607) dropped K2 and rewrote K4 with the console wire the boot and the panic path keep; this branch dropped K5, since iod goes with the kernel's write-back queue here and no kthread::spawn is added. The stages are #607's K4 and K6, K6 blocked on K4 alone. #607's hunks in every-driver-is-still-in-the-kernel.md (audio and virtio-gpu re-scoped) and the-kernel-is-small-interrupts-post-and- threads-wait.md (xHCI's MSI-X table) touch lines this branch does not change and merge as main wrote them; #602's toyos-cpuvuln and its sourcegate row likewise. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6SVYFkdvV2t38KzNrESxs
Stage S1 of
issues/kernel/the-kernel-mitigates-what-linux-mitigates-on-the-t14.md: the decision, as a pure function tested on the host. Nothing is wired into the kernel yet; stages S2–S6 of the track do that.What changed
toyos-cpuvulnis a new host-workspace member:#![no_std],#![forbid(unsafe_code)], no dependencies.decide(&Facts) -> Decisiongives two things:Decision::line(Vuln): the exact line the pinned Linux prints in each of its 17/sys/devices/system/cpu/vulnerabilities/*files;Decision's public fields: the statebugs.cselects andtsx_init's state.Factsholds the inputs:IA32_ARCH_CAPABILITIES,IA32_MCU_OPT_CTRLwhereGDS_CTRLenumerates it, andIA32_FEAT_CTLwhere Intel, Centaur and Zhaoxin read it;MSR_AMD64_LS_CFGreads (AMD 0x15–0x17 and Hygon), and whetherPRED_CMD.SBPBwrites (AMD from 0x19);decidepanics when a fact is present where Linux would not read it, or absent where it would. This is the oneFactsthat S0: commit the T14's and TCG model's captures, and read them over #601's reader is to produce.Carried from the tag, row for row:
cpu_vuln_whitelist/cpu_vuln_blacklistwithx86_match_cpu's stepping mask and first-match rule;cpu_set_bug_bits,init_speculation_control,spectre_bad_microcodes,init_ia32_feat_ctl, andtsx_initunderTSX_MODE_OFF;bsp_init_amd'sLS_CFG_SSBD,early_init_amd'sIBPB_BRTYPE/SBPB, andtsa_initwithamd_check_tsa_microcode's table; Hygon:bsp_init_hygon'sLS_CFG_SSBD;*_select_mitigation, including SRSO under its default safe-RET, TSA, and VMSCAPE's IBPB-on-VMEXIT;cpu_show_common.Every vendor is decided. Hygon is decided: its
LS_CFGprobe is the same fact as AMD's, andbugs.c's AMD-or-Hygon tests (1103, 2030, 3268) are carried.Refusedis deleted.itlb_multihitis decided. The line readsX86_FEATURE_MSR_IA32_FEAT_CTL,X86_FEATURE_VMXandCR4.VMXE(bugs.c:3091-3102). The first two are whatinit_ia32_feat_ctlleaves from CPUID andIA32_FEAT_CTL. KVM setsCR4.VMXEonly while a VM exists (vmx.c:2802, fromKVM_CREATE_VM), and none runs, so a kept VMX is "VMX disabled".Only an affected CPU's
l1tfline is unmodelled. It rests on the memory map againstx86_cache_bitsand onkvm_intel's load state.issues/kernel/the-speculation-decision-does-not-model-an-affected-cpus-l1tf-line.mdnames both,.No input reaches a state these types can't hold, and none they can hold is unreachable.
spectre_v2,bhi,mds,taa,mmioandrfdsareOptions without a not-affected variant;ibpbanditsare bools. The deleted code is dead: MMIO'sCLEAR_CPU_BUFblock, TAA'sTSX_CTRLtest (RTM on means noTSX_CTRL), the RRSBA helper's guard, the TSA table's vendor guard, the brtype vendor test, and the call site's copy of the table's Intel check.Fixtures, one per machine:
fixtures/t14.txtis byte-identical to S0: commit the T14's and TCG model's captures, and read them over #601'stoyos-t14linux/s0/t14/vulnerabilities.txtat 44eb3c2.fixtures/tcg.txtiss0/tcg/console.txtlines 379–395, with the serial console's CRs stripped.fixtures/awaiting-capture/{milan,turin}-kvm.txtare this crate's reading of the tag for a Milan guest and a Turin guest.issues/build/no-nightly-runner-has-had-its-cpuid-and-vulnerability-lines-captured.mdowes the capture that replaces them.ARCH_CAPABILITIESand CPUID bits, Silvermont, Zhaoxin, Centaur, an unknown vendor, and the T14 with each*_NObit.Oracle
Ubuntu-6.8.0-142.142ofgit.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/noble, fetched as commit 53e5d07aac028a1523ab0b115f079d6d1bc831ef. It is read atcommon.c,bugs.c,intel.c,amd.c,hygon.c,feat_ctl.c,tsx.c,scattered.c,kvm/vmx/vmx.candvirt/kvm/kvm_main.c. The config values come from/boot/config-6.8.0-142-generic(sha256 3b8533dd…ca5890, the track's) and from the tag'sdebian.master/config/annotations:CPU_UNRET_ENTRY,CPU_IBPB_ENTRY,CPU_SRSO,MITIGATION_TSAandMITIGATION_VMSCAPEarey, andKVM_INTELism.cpuid.txt,msr.txtandcpuinfo.txt: EAX 0x806c1, 1:ECX 0x7ffafbbf, (7,0) EBX 0xf3bfa7eb and EDX 0xfc100710, (7,2):EDX 0x1, 0x10A 0x0a005c6b, 0x123 0, microcode 0xbe, and SMT.feat_ctlisLOCKED | VMX_ENABLED_OUTSIDE_SMX, the two bitsinit_ia32_feat_ctlreads, fromcpuinfo.txt'svmxflag andvmx flagsline, which say Linux kept VMX. The T14 hasPSCHANGE_MC_NO, so none of its 17 lines reads it.spec_ctrl= 0x1, which S0 reads from MSR 0x48 on all eight CPUs.AuthenticAMD0A00F11_K19_Milan_CPUID1.txtat 2dc186e9, and EPYC 9655AuthenticAMD0B00F21_K20_Turin_01_CPUID.txtat b499237d. Every other fixture's facts are constructed, and its expected values are my reading of the tag.Negative controls
Every mutation below was applied at e4d4014 as a checked patch (
git apply --checkexit 0). The mutated tree builds (cargo test -p toyos-cpuvuln --no-runexit 0). Thencargo test -p toyos-cpuvulnran, andgit apply -Rleftgit diff --quietat exit 0.zen1_forces_stibp_from_the_untrained_return_thunk;a_milan_kvm_guest_gives_the_tags_linesat microcode 0 andu32::MAX;an_intel_guest_cannot_know_its_mitigations_or_its_hosts_smt;BHI_DIS_S,RRSBA_DIS_SandBHI: Retpoline:alder_lake_mitigates_bhi_in_hardwareanda_retpoline_guest_leaves_bhi_to_retpolines_only_with_rrsba_disabled;RtmAlwaysAbort,FullLocked, TAA/MMIO Verw and SRBDSTsxOff:rtm_always_abort_decides_tsx_first,firmware_can_lock_the_gds_mitigation,comet_lake_clears_cpu_buffers_by_mds_no_and_fb_clearandsrbds_is_tsx_disabled_only_without_rtm_and_mmio.lib.rsandtable.rs(every&&/||operand,ifcondition, comparison, unary!,|operand, assignment, bool literal,.thenreceiver, match arm and line string): 719 mutants at e4d4014. 718 build and exit 101; 0 survive. One does not build: dropping| Nonefrom an exhaustive match, which the compiler refuses.a_tsa_row_keyed_by_a_model_nibble_of_8_or_more_is_read(amd.c:479-490,621),a_blacklist_row_for_stepping_zero_stands_before_its_any_stepping_row(common.c:1310-1311,1480-1483,1521-1523) andhygon_without_smt_and_with_ibpb_brtype_has_srso_smt_disabled(bugs.c:2689-2691,3284-3285). Five patches, each shown to build, each exits 101 on its named test and leaves the tree clean:(id.model & 0x7) << 4at table.rs:344,& !(1 << min)at table.rs:63,ANY0 to 1 at table.rs:59, the COMETLAKE_L rows swapped at table.rs:251-252, andid.family < 0x18at lib.rs:811.The tests read
Decisionthrough an exhaustive destructuring, so a field added to it fails to build until a test asserts it.Gates, at e767338 (origin/main merged)
cargo test -p toyos-cpuvuln: EXIT=0, 52 passed.cargo clippy -p toyos-cpuvuln --target x86_64-unknown-none -- -D warnings: EXIT=0.cargo run -- --ci host: EXIT=0, "54 step(s), all green".What I am unsure of
IBPB_BRTYPEandVERW_CLEARthrough (kvm/cpuid.c:797-800). Without them, the fixture'sVulnerable: Safe RET, no microcodeand TSAVulnerable: Clear CPU buffers attempted, no microcodehold. With them, the lines areMitigation: Safe RETandMitigation: Clear CPU buffers, anda_guest_with_verw_clear_mitigates_tsaholds the second. Only a real runner capture settles which, andissues/build/no-nightly-runner-has-had-its-cpuid-and-vulnerability-lines-captured.mdowes it.sbpb_write_acceptedandls_cfg_readableare facts that only an MSR probe with exception fixup can produce, and so isfeat_ctl'sNone. S2 has to perform the same probes Linux does.spec_ctrlholds only the bitsbugs.cORs in. Linux keeps the MSR's other bits as it read them (bugs.c:156-165).smtstands for bothsched_smt_active()andcpu_smt_possible(). They agree under the default command line with every sibling online.md_clear_update_mitigationchanges no state or line here. Nor doestsx_dev_mode_disable: on the boot CPU it runs beforetsx_initsetsMSR_TSX_CTRL(tsx.c:145,163,190). That is argued from the source, not measured.🤖 Generated with Claude Code
https://claude.ai/code/session_01U6SVYFkdvV2t38KzNrESxs