A new appendix (started ca. 2025) recording why each extension looks the way it does, chronologically, with backfill promised for older ratifications. So far it holds one entry — the design review behind Smepmp’s mseccfg bits. Four decisions:
1. Why mseccfg exists at all
No CSR held global security/PMP behavior settings; creating one gave future security extensions a home and a discovery mechanism (software probes mseccfg to learn the features exist).
2. RLB — Rule-Locking Bypass
Boot firmware wants to enforce-then-edit M-mode rules, but enforcing in M requires locking, and locked rules were previously immutable — so firmware burned PMP entries, stacking overrides by priority. RLB lets boot code edit locked rules, then be cleared and locked down.
3. MMWP — default-deny for M-mode
Classic PMP is default-allow for M: anything uncovered is accessible. MMWP flips M-mode to an allowlist — closing the hole where attacker code sits in directly-addressable flash that no PMP rule covers.
4. MML — M-mode-only vs S/U-mode-only
pmpcfg.L’s old dual meaning (locked + all-modes) was “neither flexible nor clean.” Under MML, L becomes ownership: L=1 = M-mode-only (locking implied — an editable M rule is no rule), L=0 = S/U-mode-only — deliberately mirroring the PTE U bit’s user/kernel split. M-mode then gets access/execution prevention on non-M regions: a buggy M-mode routine tricked into touching or executing S/U memory takes an access fault instead.
| Meaning | |
|---|---|
| Shared DATA (RW=01, L=0) | X bit = S/U write capability. Executable shared data is inexpressible — zero-copy M↔S/U buffers can never become code. |
| Shared CODE (RW=01, L=1) | X bit = M read capability. Writable shared code is inexpressible — vDSO-style vendor routines callable from S/U without an ecall, but immutable. |
| LRWX=1111 | Locked shared read-only data — repurposed from “M-mode RWX” (judged dangerous: M couldn’t further restrict it). Lets firmware share an ELF’s .text via shared code and .rodata via this, with M unable to modify either. |
Zero-copy sharing was chosen per-rule over an M-mode SUM-analog precisely to avoid a global bypass bit someone forgets to clear. MPRV-based copying still works — with S/U permissions and the MMU honored. And once MML is set, no new M-executable regions can be added (without RLB): after firmware init, nothing new should ever run in M-mode.
The appendix closes with Volume II’s bibliography — Goldberg’s 1974 virtualization survey, Navarro’s superpages, Serebryany’s HWASAN paper behind pointer masking.
Hardware Designer Notes
Worth internalizing as a design-review checklist: every Smepmp bit exists to close a specific loophole (RLB → rule exhaustion, MMWP → uncovered flash, MML → M executing user memory, RW=01 → shared regions without a global bypass). If you add custom security CSRs, this appendix is the quality bar for documenting them.
Minimal Linux-boot hart MUST
- Nothing new — every behavior here was implemented with p07’s Smepmp truth table; this appendix is the WHY
MAY simplify / trap-and-emulate
- Use the threat model when arguing corners: Smepmp assumes BUGGY M-mode software, not compromised — MPRV stays enabled, page-table tampering is out of scope
Check yourself — Smepmp rationale
1.Why does leaving mseccfg.RLB set after boot amount to 'a false sense of security'?
2.Under MML, what analogy drives the reinterpretation of pmpcfg.L?
3.Why did shared regions get the reserved RW=01 encoding instead of a per-rule 'shared' bit?