tk — Safety & Security Features (cross-arch reference, staged index)¶
Purpose. One place that describes every safety- and security-relevant feature tk provides, what it costs at runtime, the exact config knob and API to use it, which architectures/boards support it, and — so the picture is complete — which mechanisms are not yet leveraged but are plausible future work.
This is a synthesis + index. Where a subsystem has its own design record, this doc links to it rather than duplicating it. Everything here is grounded in the code; when the code and this doc disagree, the code wins and this doc is the bug.
Migration & staging note (2026-08-19). This index was written against the pre-reshape tree (now
_legacy/). Return-to-root has landed the memory-protection plane (the L1–L3 ladder below) and observability (trace/SystemView) into the rootkernel/+arch/, but the crypto / verified-boot / watchdog / heartbeat / reset-reason / brownout / error-DET / introspect-region subsystems are not yet ported to root — they remain in_legacy/and are marked ⏳ staged (roadmap) throughout. Reconciled config defaults have shifted to minimal-safe (§2, §7): the hardware guard is now opt-in, not default-on. Read §2 and §7 as live; read §3–§6 as a staged index of what re-attaches next (docs/roadmap.md, R2/R3).
How to read the status tags.
Tag |
Meaning |
|---|---|
✅ landed |
present in the root tree ( |
✅ HW-verified |
exercised on real silicon (board named) — some proofs are in the reshape sketch / |
⏳ staged |
proven in |
🧪 bench/one-board |
implemented + verified on a single board; portable but not broadly proven |
🔩 arch-ready, board-gated |
the arch code supports it; a given board also needs linker/HAL support |
📐 software-only |
portable C, no hardware assist |
🕳️ gap / not built |
called out so nobody assumes coverage that isn’t there |
1. The shape of the model¶
tk separates three concerns. They are independent — you can take any subset — and each is compile-time gated so an unused plane costs nothing.
Memory protection — keeps a thread (buggy or hostile) from corrupting another thread, the kernel, or the core. §2. ✅ landed (ARM-MPU + RISC-V-PMP).
Boot & data integrity — proves the code that runs is the code you signed, and provides the crypto primitives to protect data. §3. ⏳ staged.
Availability & fault handling — detects a wedged/starved/browning-out system and drives it to a defined state (halt, reset, or contain). §4. ⏳ staged (except the fault-policy hook plumbing, which rides the arch layer).
Two structural facts shape everything below:
Layering. Memory protection lives in the arch (
arch/<arch>/) with a small board contribution (the linker zones); watchdog / reset-reason / brownout live in the HAL/MCAL as board backends; error reporting and stack checking are portable core (kernel/); cross-core liveness is the system layer (system/). The HAL never depends on the kernel (seedocs/architecture/composability.md), so the crypto/watchdog/reset features work in a bare HAL build with no scheduler.The privileged-background divide (ARM vs TriCore). This is the single most important architectural difference for memory protection. ARM Cortex-M has a privileged background (
MPU_CTRL.PRIVDEFENA): the MPU only needs to describe what unprivileged code sees; privileged code (kernel, handlers) reaches all memory by default. RISC-V PMP is the analog (M-mode bypasses PMP; a U-mode thread reaches only what a PMP entry grants). TriCore has no privileged background — every protection set bounds Supervisor too. Consequences: on TriCore the stack guard works without user mode, and “isolate app threads” and “run app threads unprivileged” are the same mechanism. (The TriCore MPU/unpriv path is proven in_legacybut not yet ported to root —arch/tricore/at root has switch + SMP + CSA reclaim only, noARCH_HAS_MPU/UNPRIV.)
2. Memory protection — the ladder (✅ landed)¶
Three stacked levels. Each is a superset of the one below; you choose how far up you go. All are
gated by TK_CONFIG_ENABLE_STACK_CHECK at the base. Reconciled default posture is minimal-safe:
only L1’s config gate is default-on; L2/L3 are opt-in (via the hardened/full profiles or an
explicit -D), because turning them on installs the MPU + fault vectors and the drop-in must not
seize a vendor SDK’s handlers by default.
Level |
Enable |
Catches / protects from |
Precision |
Cost |
Does not cover |
|---|---|---|---|---|---|
L1 — software canary |
|
your own stack overflow |
late — next context switch, after the growth |
a few cells checked per switch; no per-thread RAM |
anything cross-thread; post-hoc (neighbour may already be clobbered) |
L2 — HW stack guard |
|
your stack overflow |
precise — faults at the overflowing instruction |
1 MPU/PMP range reprogrammed per switch |
cross-thread scribbling: all threads still privileged, so a thread can still write a peer or the kernel |
L3 — unprivileged confinement |
|
cross-thread corruption, kernel-state corruption, privilege escalation, core reconfig, and overflow |
precise |
per-call syscall trap + per-switch MPU/PMP reprogram |
interrupt-masking starvation; corrupting shared globals it legitimately reaches; CPU hogging |
The jump that matters is L2 → L3. L2 tells a thread when it overflows its own stack but leaves every thread able to reach all of memory. L3 is genuine freedom from interference: an app thread sees only its own stack + shared globals + flash + (granted) peripherals — kernel data, peer stacks, and sync-object internals are walled off, and it cannot escalate to Supervisor except through a syscall the kernel controls.
The derived gate (root reconciliation). tk_config.h resolves the two idioms — app choice ×
arch capability — into compile-time TK_FEAT_* flags. The load-bearing derivations:
TK_FEAT_MPU_GUARD = (ENABLE_MPU_GUARD || UNPRIV_THREADS) && ARCH_HAS_MPU (so enabling UNPRIV
implies the guard — confinement requires it); TK_FEAT_UNPRIV = UNPRIV_THREADS && ARCH_HAS_UNPRIV;
TK_FEAT_ISOLATION = ENABLE_MPU_ISOLATION && TK_FEAT_UNPRIV && ARCH_HAS_MPU. An arch without the
hardware folds all of these to 0 — never a broken build, and the minimal default installs no
vectors.
2.1 L1 — software canary (📐 all arches; ⏳ implementation re-hosting)¶
At creation each stack is filled and its low end becomes a trip-wire; the scheduler checks the running thread’s canary on every switch. Same fill pattern backs high-water-mark measurement. Sizes are in addressable cells (ADR 0001), not bytes.
Config:
TK_CONFIG_ENABLE_STACK_CHECK(default1).⏳ Root status: the scheduler already calls
tk_stack_prepare/tk_stack_checkon the create + switch paths, butkernel/tk_stack.his currently a placeholder no-op — the fill / canary / high-water scan, theTK_CONFIG_STACK_CANARY_BYTES/_FILL_BYTEsizing knobs, and thetk_thread_stack_peak/free+ overflow-hook API are not yet re-hosted (they live in_legacy/kernel/tk_stack.*). This is adocs/roadmap.mdR2 item.Runtime impact (when implemented): microscopic (a compare per switch). Detection is after the fact — treat an L1 (
CANARY) fault as “memory may already be wrong → reset.”
2.2 L2 — hardware MPU/PMP stack guard (🔩 arm_v7m + arm_v8m; RISC-V has no HW stack guard)¶
A no-access region at each thread’s stack limit, reprogrammed on switch, so an overflow faults at the offending instruction — before corruption. Overflow detection only.
Config:
TK_CONFIG_ENABLE_MPU_GUARD(default0at root — opt-in; was default-on in the pre-reshape tree). RequiresENABLE_STACK_CHECK; a no-op on a part with no MPU.Arch support at root:
arm_v7mandarm_v8m(ARCH_HAS_MPU 1) program an MPU (arch_mpu_init+ per-switch region reprogram intk_kernel.c, gatedTK_FEAT_MPU_GUARD).arm_v6m(M0+): no MPU region programmed → L1 only. RISC-V has PMP (used for L3 confinement) but no dedicated hardware stack guard. TriCore MPU stack-guard: ⏳ staged (not ported).Fault path: ARM MPU region violation →
MemManage_Handler→ the stack policy in §4.5.✅ HW-verified: M4F (
arm_v7m) — proven on nRF52 (root board) and EK-RA4M1 (reshape sketch). TriCore class-1 guard: verified in_legacy, not at root.
2.3 L3 — unprivileged threads & confinement (🧪 ARM M4F, RISC-V U-mode; ⏳ TriCore)¶
Application threads run unprivileged behind an MPU/PMP memory map that grants only what they own. This is the freedom-from-interference tier. It changes the thread ABI: kernel calls that touch privileged state (yield, sleep, exit, the sync primitives, join/detach) trap through a generic syscall instead of a direct call.
Config:
TK_CONFIG_UNPRIV_THREADS(default0, opt-in — needsARCH_HAS_UNPRIV).TK_CONFIG_ENABLE_MPU_ISOLATION(default0— new at root, replaces the pre-reshapeUNPRIV_REQUIRE_ISOLATABLEmodel). On = full lockdown: kernel-RAM (.privileged_bss) + per-thread (.thread_stacks) MPU section placement — needs the board’s linker regions. Off = reduced isolation: unprivileged confinement via the SCS-unmapped map, no custom sections. The derivedTK_FEAT_ISOLATIONrequires this knob and UNPRIV andARCH_HAS_MPU.
API:
TK_THREAD_STACK(name, size)(kernel/tk_kernel.h) — declare a stack in the isolatable.thread_stackszone (gated onTK_FEAT_ISOLATION; a plain array otherwise).tk_thread_set_privileged(t)(kernel/tk_kernel.h) — opt a specific “system” thread back to privileged after create; the kernel + all handlers stay privileged regardless (no-op without unpriv).The whole existing sync/yield/sleep/exit/join API is unchanged to the caller — the syscall routing is internal (
ARCH_HAS_SYSCALL= ARM SVC or RISC-V ecall; TriCore class-6 SYS in_legacy).
What an unprivileged thread is denied: kernel singleton, peer thread stacks, core-config registers (ARM System Control Space / RISC-V CSRs — no MPU/NVIC/PMP/PSW reconfiguration), and privilege escalation. Sync objects are kernel-owned: the app holds an opaque handle; every call bounds-checks it privileged and the kernel never dereferences an app pointer.
Board requirement: for full lockdown (
ENABLE_MPU_ISOLATION=1) the board’s linker must carve the partitioned zones (.privileged_bss,.thread_stacks, + on ARM the introspect window + MSP zone). No root board carries these zones yet — so full-lockdown isolation is arch-ready but board-gated at root; the reduced-isolation confinement (SCS-unmapped) runs without custom sections.Verification: full-lockdown MPU/unpriv HW-verified on M4F (EK-RA4M1) and RISC-V U-mode + PMP (QEMU) in the reshape — proving the ARM-MPU ↔ RISC-V-PMP generalization. ✅ TriCore confinement HW-verified in
_legacy(examples/unpriv_tricore); ⏳ not yet at root.Detail docs:
docs/architecture/isolation/kernel-ram-isolation.md(kernel-RAM + handler-stack lockdown),docs/architecture/isolation/per-thread-stack-isolation.md(per-thread stack isolation),docs/architecture/isolation/kernel-owned-sync.md(opaque handles).
2.4 Residual risks in L3 (⚠️ read before trusting it)¶
Confinement is memory isolation, not a full sandbox. Known, deliberate gaps:
On TriCore, User-1 can mask interrupts. tk runs app threads in TriCore User-1 so they can reach peripheral MMIO for the HAL/console; User-1 can also execute
enable/disable— a buggy thread can mask interrupts and starve the system. This gap is TriCore-specific: on ARM Cortex-M and RISC-V U-mode, interrupt masking is privileged, so an unprivileged thread cannot mask interrupts at all. (TriCore path is_legacy/roadmap.)Shared state is shared. A thread can corrupt globals it legitimately reaches; isolation firewalls kernel and peer memory, not application data threads share by design.
TriCore shared-CSA gap. TriCore thread contexts live in a shared CSA free-list; the confined set must grant the CSA region, which also exposes peers’ saved contexts. ARM/RISC-V have no equivalent (contexts ride each thread’s isolated stack). Closing it needs per-thread CSA partitioning (future).
CPU hogging is bounded by preemption (all real arches preempt), not by this plane.
3. Boot & data integrity (cryptography + verified boot) (⏳ staged — not at root)¶
Status: the entire crypto / verified-boot plane is
_legacy/only — there are no crypto ortk_vbootheaders at root (hal/tk_sha.h,tk_aes*.h,tk_hmac_sha256.h,tk_ecdsa.*,tk_vboot.*,tk_crc.h,tk_rng.hare all absent). The design below is the port-forward target (docs/roadmap.md§5). Preserved here as the staged index.
3.0 How crypto was enabled (there is no TK_CONFIG_* for it)¶
Enablement is four-layered: portable pieces (tk_vboot.c, tk_ecdsa.c, tk_crc_sw.c, header-only
HMAC/CBC) globbed into every build and dead-stripped if unused; per-silicon backends (tk_sha_*,
tk_aes_*, tk_rng_*) as board sources with a software fallback via TK_SHA256_SW_IMPL; the
app opts in at runtime (tk_*_init()); verified-boot signing is a make-layer pipeline
(VBOOT_SIGN=…). “What crypto do I have” = which board backends exist + what the app calls.
3.1 Primitives (⏳ staged)¶
Primitive |
Header / API ( |
Software |
HW-accelerated |
Notes |
|---|---|---|---|---|
SHA-256 |
|
|
ESP32 |
ctx layout differs by backend |
HMAC-SHA256 |
|
portable (rides SHA) |
inherits SHA accel |
propagates |
AES-128 |
|
host (enc+dec) |
ESP32 (enc+dec), nRF52 (ECB enc-only) |
v1 CBC whole-block, no padding |
ECDSA P-256 (verify) |
|
|
— |
device holds public key only; not constant-time (inputs public) |
CRC-16/CCITT |
|
|
MSP430FR2433 (strong override) |
poly 0x1021, init 0xFFFF |
3.2 Verified / secure boot — trust chain tk_vboot (⏳ staged)¶
tk_vboot_check(image, key, keylen, manifest); manifest MAC stored outside the hashed region;
constant-time compare. Build pipeline VBOOT_SIGN=1|ecdsa + signer scripts; two-stage merge.
Story A (HW-verified on nRF52 in _legacy): A1 software HMAC-SHA256 verified-boot; A2 P-256 ECDSA
verify-only (single + two-stage bootloader); A3 nRF52 APPROTECT debug lockout. Honest caveat: a
software verifier whose key lives in the same rewritable flash is a teaching device, not a real
boundary — a real root of trust needs an immutable boot ROM + hardware key store (§8). Detail doc:
_legacy/docs/notes/trust-chain-secure-boot.md.
3.3 / 3.4 RNG + board accelerators (⏳ staged)¶
tk_rng (nRF52 TRNG; ESP32 HW-RNG RF-gated; host xorshift, non-crypto). Accelerator inventory
(SHA/AES/RNG on ESP32; AES-ECB+TRNG on nRF52; HW CRC on FR2433; APPROTECT anchor) — all _legacy.
4. Availability & fault handling¶
Recurring idiom: weak-default + strong-override and opt-in-by-call.
4.1 Watchdog — tk_wdg (⏳ staged — no hal/tk_wdg.h at root)¶
Mode-based HW watchdog (OFF/SLOW/FAST). API tk_wdg_init/set_mode/trigger/set_warn/get_mode;
opt-in by calling tk_wdg_init(). _legacy boards: nRF52 (500/4000 ms, unstoppable = safe case),
ESP32, host sim. Port-forward target.
4.2 Reset-reason — tk_mcu_reset_reason() (⏳ staged — no tk_mcu reset backend at root)¶
tk_reset_reason_t tk_mcu_reset_reason(void) → {UNKNOWN, POWER_ON, PIN, WATCHDOG, BROWNOUT, SOFT, LOCKUP, OTHER}. _legacy distinguishes causes on nRF52/STM32/RA4M1/ESP32. Port-forward target.
4.3 Brownout / voltage detection (⏳ staged)¶
tk_mcu_brownout_enable() + tk_mcu_set_brownout_cb(cb) — early warning ISR above the hard reset
level. _legacy real ISR on nRF52/STM32H7/STM32F1. Port-forward target.
4.4 Error reporting — tk_error / tk_det (📐 stub at root; full subsystem ⏳ staged)¶
Two reporting paths over one mechanism (global hook + per-module/per-status counters), split Det/Dem.
Root status: kernel/tk_det.h is a no-op stub — TK_DET(mod, id, err) → ((void)0) — used at
the create/sync rejection sites (TK_MOD_KERNEL, TK_MOD_SYNC). The full tk_error.* subsystem
(counters, installable hook, 28 module IDs, TK_CONFIG_DET_ENABLED / ERROR_COUNTERS_ENABLED /
ERROR_SOURCE_INFO, SystemView mirroring) is _legacy/hal/ only, not yet re-ported.
4.5 Stack-overflow / protection-fault policy (📐 hook; arch terminal action)¶
The single policy point every stack/MPU fault funnels to (from L1 canary and L2/L3 MPU alike).
API (target):
tk_set_stack_overflow_hook(fn),fn(tk_thread_t* t, enum tk_stack_fault_cause cause)wherecause ∈ {TK_STACK_FAULT_CANARY, TK_STACK_FAULT_MPU, TK_STACK_FAULT_PROTECTION}. ⏳ Root status: the hook/enum API rides with the L1-canary re-hosting (§2.1) and is not yet at root; the arch fault plumbing (ARMMemManage_Handler→ fault dump/terminal) is present underTK_FEAT_MPU_GUARD.Hook context: runs in scheduler/fault context with the stack at/past its limit and interrupts about to be masked — must not block, yield, or call scheduling APIs.
Default terminal action if no hook: ARM
MemManage_Handler→ fault dump →tk_fault_terminal(weak default masks IRQs +wfi-halts forever, debugger-inspectable; a board supplies a strong one callingNVIC_SystemReset()). TriCore class-1 → decode + halt (⏳_legacy).Recovery beyond reset: for the precise (
MPU) case nothing was corrupted, so fault containment (terminate just the offender, keep scheduling) is architecturally possible.TK_CONFIG_FAULT_CONTAIN+TK_FEAT_FAULT_CONTAINgates exist at root; the full reclaim path (context reclamation + held-lock cleanup) is not built — reset is the honest recovery today.
4.6 Cross-core heartbeat — tk_heartbeat (⏳ staged — no system/tk_heartbeat at root)¶
A software watchdog between cores. _legacy API tk_heartbeat_start() + weak tk_core_stalled
reaction hook; TK_CONFIG_ENABLE_HEARTBEAT (+ _PERIOD_MS/_MISS) — none of these knobs exist at
root. Hard-requires ENABLE_AFFINITY + ARCH_CORE_COUNT > 1. Port-forward target.
Note — EDF is not a deadline-miss detector.
TK_CONFIG_ENABLE_EDF(default0at root — was default-on pre-reshape) only orders the ready set by earliest deadline when the EDF policy is selected. There is no overrun reporting; do not treat it as an availability safety feature.
5. Observability (supports safety analysis)¶
Tracing (
TK_CONFIG_ENABLE_TRACE,TK_CONFIG_ENABLE_SYSVIEW, both default0): ✅ landed — a flight-recorder ring (kernel/tk_trace.h+kernel/tk_trace_ring.c) and/or a SEGGER SystemView backend (kernel/tk_sysview.h+system/tk_sysview.c, SEGGER sources undertools/SEGGER/) behind one set ofTK_TRACE_*hooks. Knobs:TK_CONFIG_TRACE_RECORDS(32, power of two),TK_CONFIG_TRACE_SCHED(1 = record carries the task handle),TK_CONFIG_TRACE_TICK(0 — the tick ISR floods SystemView at ~1 kHz; on only to study tick timing). SystemView HW-verified on nRF52. Demos:examples/{trace,sysview}.Introspection / remote monitor (
TK_CONFIG_ENABLE_INTROSPECT, default0): 🟡 partial — the knob, theTK_TCB_HAS_NAMEfield gate, andtk_kernel_thread_snapshot(struct tk_thread_info*, int)exist at root, but the seqlock-guarded kernel-owned RO region (tk_introspect.{c,h}) and its unprivileged reader (examples/monitor) are ⏳ staged — adocs/roadmap.mdR2 item. Cat-0 was HW-verified on nRF52 in_legacy.⚠️ Type-hygiene carry-forward: the public
struct tk_thread_infostill declaresuint8_t base_priority/uint8_t state— the kind-1-as-uint8_tanti-pattern ADR 0001 (Addendum 2) forbids; fix tounsigned charwhen the introspection surface is next touched.
6. Cross-arch / board support matrix¶
Rows are features; cells are the best status per arch family. “—” = not applicable. ⏳ marks a
row whose subsystem is _legacy-only pending port-forward.
Feature |
arm_v7m (M3/M4/M7) |
arm_v6m (M0+) |
arm_v8m (M33) |
risc_v (RV32) |
tricore (TC2xx) |
|---|---|---|---|---|---|
Preemptive kernel |
✅ |
✅ |
✅ |
✅ |
✅ (switch/SMP) |
L1 software canary |
✅ knob (impl ⏳) |
✅ knob |
✅ knob |
✅ knob |
⏳ |
L2 MPU/PMP stack guard |
✅ nRF52 (MPU parts) |
🕳️ no MPU |
✅ (MPU) |
🕳️ no HW guard |
⏳ |
L3 unpriv confinement |
🧪 M4F |
🕳️ |
🔩 (M33) |
🧪 U-mode/PMP |
⏳ |
Full-lockdown isolation ( |
🔩 board-gated |
🕳️ |
🔩 board-gated |
🔩 board-gated |
⏳ |
Tracing / SystemView |
✅ nRF52 |
🔩 |
🔩 |
🔩 |
🔩 |
Introspect region |
⏳ |
⏳ |
⏳ |
⏳ |
⏳ |
Watchdog / reset-reason / brownout |
⏳ |
⏳ |
⏳ |
⏳ |
⏳ |
Crypto / verified boot |
⏳ |
⏳ |
⏳ |
⏳ |
⏳ |
Cross-core heartbeat |
— |
⏳ (SMP) |
— |
⏳ (SMP) |
⏳ (SMP) |
No root board carries the .thread_stacks/.privileged_bss linker zones yet, so full-lockdown
isolation is arch-ready but board-gated everywhere at root (reduced-isolation confinement runs
without them).
7. Config quick-reference (safety/security knobs — reconciled to root tk_config.h)¶
All in kernel/tk_config.h; every option is #ifndef-guarded so a force-included profile or a -D
overrides it. A profile is part of the ABI. Defaults below are the root minimal-safe posture —
several shifted from the pre-reshape tree (noted).
Knob |
Default |
Effect |
|---|---|---|
|
1 |
L1 canary + high-water; master switch for L2/L3 (impl re-hosting ⏳) |
|
0 (was 1) |
L2 HW stack guard; installs MPU + fault vectors (no-op without an MPU) |
|
0 |
L3 unprivileged threads + confinement (needs |
|
0 (new) |
full lockdown: kernel-RAM + per-thread MPU section placement (needs board linker zones); off = reduced-isolation confinement |
|
0 |
unpriv fatal fault → terminate that thread (reclaim path not built) |
|
0 (was on) |
deadline field + EDF policy availability (orders only; not a miss-detector) |
|
0 |
SMP per-thread core mask (meaningful only when |
|
0 |
|
|
0 |
TCB-name field + snapshot; RO monitor region ⏳ |
|
0 / 32 / 1 / 0 |
flight-recorder ring depth + record shape + tick instrumentation |
|
0 |
SEGGER SystemView (Cortex-M) |
Derived (not user knobs): TK_FEAT_MPU_GUARD, TK_FEAT_UNPRIV, TK_FEAT_ISOLATION,
TK_FEAT_FAULT_CONTAIN, TK_FEAT_AFFINITY — each ANDs the app knob with the arch’s ARCH_HAS_*.
Knobs that moved with a staged subsystem (⏳, not present at root): STACK_CANARY_BYTES /
STACK_FILL_BYTE (with the L1 impl, §2.1), DET_ENABLED / ERROR_COUNTERS_ENABLED /
ERROR_SOURCE_INFO (with tk_error, §4.4), UNPRIV_REQUIRE_ISOLATABLE (superseded by
ENABLE_MPU_ISOLATION), ENABLE_HEARTBEAT / _PERIOD_MS / _MISS (with tk_heartbeat, §4.6),
VBOOT_SIGN / VBOOT_KEY make vars (with the crypto pipeline, §3).
8. Hardware safety/security features NOT yet leveraged (roadmap)¶
So the picture is honest: capabilities present in the supported silicon that tk does not use today. None are promised — plausible next reaches.
AURIX TriCore (TC27x): lockstep checker core (the headline unused safety mechanism); SMU
(alarm aggregation); ECC / MBIST / windowed safety-watchdog; per-thread CSA partitioning (would
close the shared-CSA gap §2.4); HSM/SHE secure key store; SCU_RSTSTAT reset decode; tk_wdg
backend. (Note: the TriCore arch itself is only partially at root — MPU/unpriv not yet ported.)
ARM Cortex-M: ARMv8-M TrustZone-M + SAU (secure/non-secure world partitioning — arch/arm_v8m
is at root and QEMU-proven, but the world dimension is the deliberate next slot); stack-limit
registers (MSPLIM/PSPLIM on M33 — HW overflow trap without an MPU region); nRF52 APPROTECT in a
shipped provisioning flow; nRF52 CryptoCell / STM32 HW crypto; MPU linker zones on more boards.
RISC-V: ePMP / additional PMP entries for finer maps; Sv32 paging isolation beyond the
QEMU proof; supervisor timer/sstc for S-mode ticks.
General: fault containment (kill-the-thread-and-continue) — §4.5, the biggest availability upgrade; deadline-miss detection (EDF orders but does not report overruns, §4.6); redundant/voted execution, control-flow integrity, memory scrubbing — not attempted.