Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ADR-079 — PAN CPU reopen foundation (sponsor unlock; default -cpu cortex-a76)

  • Status: Accepted (CPU reopen foundation). Meets ADR-054 reopen gate items 1–2: sponsor-approved FEAT_PAN default probe CPU + serial pan: present. Enable+fault is ADR-080 (Accepted). Taken SError reopen is ADR-081 (follow-up). Does not claim “EL0 isolated.”
  • Date: 2026-09-19
  • Tracks #125. Sponsor unlock Sat 19 Sep 2026 via DSO. CloudAgent HELD — agent-box / amd64 workstation / GHA only.

Context

ADR-054 locked PAN enable as non-goal on default -cpu cortex-a57 (pan: absent, ADR-026). Reopen required: (1) sponsor-approved FEAT_PAN CPU + new ADR; (2) ID_AA64MMFR1_EL1.PAN != 0 / pan: present; (3) later enable+fault ADR; (4) ledger/smoke update; keep a57 pan: absent historical.

Sponsor / DSO unlocked mile (1): research honest QEMU virt CPUs, pick one CI-viable default, switch smoke scripts with this ADR cite, print pan: present. Do not implement enable or taken SError Verified in this PR. ADR-053 stays hard-stopped until ADR-081. Umbrella “EL0 isolated” stays non-claim (ADR-055 / ADR-060). Never yank _start. No silent -cpu without this ADR.

Research (agent-box, 2026-09-19 CEST)

Host: agent-box. qemu-system-aarch64 10.0.13 (Debian 1:10.0.13+ds-0+deb13u1). Machine: -machine virt. Short freestanding guest probe (MRS ID_AA64MMFR1_EL1, PL011 serial) — not a silent host invent.

-cpuID_AA64MMFR1_EL1.PAN [23:20]Serial
cortex-a570pan: id=0 / pan: absent (historical)
cortex-a720pan: id=0 / pan: absent
cortex-a552pan: id=2 / pan: present
cortex-a762pan: id=2 / pan: present (chosen default)
cortex-a7102pan: id=2 / pan: present
neoverse-n12pan: id=2 / pan: present (UDP not CI-viable here)
neoverse-n22pan: id=2 / pan: present
neoverse-v12pan: id=2 / pan: present
max3pan: id=3 / pan: present (moving target — rejected as default)

CI / smoke viability (agent-box, same tip ELF, inject runner)

-cpupan:N1–N5 netFAT / samples
cortex-a57absentokok (historical)
neoverse-n1presentUDP miss (net: udp-tx then net: probe missed)ok after miss
cortex-a76presentok (udp+tcp)ok
cortex-a55presentokok
maxpresent (id=3)okok (rejected as default — moving target)

Chosen default: cortex-a76. FEAT_PAN id=2, full existing smoke (net/FAT/samples) green on agent-box QEMU 10.0.13. neoverse-n1 is FEAT_PAN-present but not CI-viable for this tree’s UDP path without a separate timing/net ADR.

inject-nmi note (SError mile later)

QMP inject-nmi on the same host still returns machine does not provide NMIs for cortex-a57, cortex-a76, neoverse-n1, and max (re-probed 2026-09-19). CPU switch alone does not unlock taken SError — ADR-081 documents the blocker.

Hypotheses

IDOptionNotes
H1 (chosen)Default probe CPU → -cpu cortex-a76; smoke expects pan: present; cite this ADR; keep a57 rows historical; no MSR PAN.FEAT_PAN id=2; full net/FAT/samples smoke green on agent-box; not max; neoverse-n1 UDP-fails on this tree.
H2 (rejected)Stay on cortex-a57 and only document research.Sponsor asked for concrete CPU switch evidence when a FEAT_PAN CPU works honestly.
H3 (rejected)Default to -cpu max.Field value drifts with QEMU; ADR-026 already rejected silent max.
H4 (rejected)Enable PSTATE.PAN / claim Verified enable this PR.Mile 2 = ADR-080.
H5 (rejected)Fake pan: present on a57 or invent Verified SError.Honesty fail.

Decision

  1. Sponsor unlock recorded. Isolation leftovers reopen mile (1) is authorized (#125). ADR-054 gate items 1–2 are met by this ADR + evidence below. Items 3–4 landed in ADR-080.

  2. Default probe CPU. scripts/qemu-aarch64.sh and scripts/qemu-serial-inject.py use -cpu cortex-a76 with this ADR cite. Do not silent-edit without an ADR.

  3. Serial contract (this mile). Guest reads ID_AA64MMFR1_EL1.PAN (ADR-026 probe). On the new default: pan: id=<n> with n != 0 and pan: present. ADR-080 adds pan: enabled / pan: el1-fault. Historical a57 pan: absent rows remain truth for a57.

  4. Probe success semantics. pan::observe_probe returns success for both absent and present (ID field printed). Fail-closed only if the probe did not publish. No MSR PAN in this mile.

  5. Still non-claim. Taken SError until ADR-081. Umbrella “EL0 isolated” (ADR-055 / ADR-060). Never yank _start. No Guest Linux / containers marketing.

  6. Toolchain pin. rust-toolchain.toml pins nightly-2026-09-12 (0fc141305) — same tip as ADR-078 ledger evidence. Floating nightly @ 2026-09-18 failed freestanding cargo test with E0463 (can't find crate for test). Smoke uses cargo (pin) not cargo +nightly.

  7. Follow-ups. ADR-080 (Accepted): enable + EL1-vs-EL0 fault. ADR-081 (Accepted): taken SError reopen re-probe — still blocked; sponsor unlock B1/B2/B3.

Honesty

Say: “default smoke CPU is -cpu cortex-a76 (ADR-079); ID_AA64MMFR1_EL1.PAN != 0 → pan: present; enable still locked pending ADR-080; a57 pan: absent remains historical.” Do not say:

  • PAN is enabled / “privileged access never”
  • “EL0 isolated” / “secure OS”
  • taken lower-EL SError is Verified
  • the probe silently used a different -cpu than the scripts
  • Guest Linux / containers / immutable-OS

Consequences

  • Scripts + smoke + src/pan.rs / #[test_case] updated for cortex-a76 / pan: present.
  • Docs: this ADR, ADR-054 reopen note, ADR-060, honesty ledger, roadmap P-SEC-3k, threat-model light bump, SUMMARY, limits / el0 light touch.
  • Preserve all existing smoke greps (net/FAT/samples). CloudAgent HELD. Do not self-merge (ADR-002).