"Smrnmi": Resumable Non-Maskable Interrupts

Part II Linux boot: optional Vol. II (Privileged) pp. 90–92 · ~3 min read

  • smrnmi

A base-architecture NMI (ch. II·3) clobbers mepc and mcause — land one inside a trap handler and the interrupted context is gone. Smrnmi gives NMIs their own save set and return instruction, making hardware-error handling resumable.

The parallel state: mnscratch (0x740), mnepc (0x741 — same WARL /bit-masking rules as mepc, including for MNRET’s implicit read), mncause (0x742 — MSB set + cause code for interrupts, or MSB clear + exception code when delivering an Smdbltrp double trap), and mnstatus:

mnstatus (0x744) — Figure 9

Reserved3113MNPP1211Reserved10MNPELP9Reserved8MNPV7Reserved64NMIE3Reserved20
WPRI/RO WLRL WARL RW
Click a field for semantics, reset state, and the minimal-implementation note.

Operation

RNMI lifecycle
What happens
Signalrnmi inputs to the hart: higher priority than every interrupt/exception, immune to mstatus.MIE
Entrymnepc ← PC, mncause ← type, MNPP/MNPV ← context, NMIE ← 0; jump to the implementation-defined RNMI interrupt handler in M-mode
Fault inside the windowException in M-mode with NMIE=0 → normal actions but PC ← the separate RNMI EXCEPTION handler address
ReturnMNRET (M-only): PC ← mnepc, mode ← MNPP/MNPV, NMIE ← 1; MPRV ← 0 if leaving M; ELP ← yLPE ∧ MNPELP (Zicfilp)
Non-interactionMRET/SRET neither depend on nor modify NMIE; WFI treats NMIE as a global enable (i.e., unaffected by it)
Dotted-underlined cells have explanations — click one.

Hardware Designer Notes

Think of Smrnmi as a two-entry shadow of your trap unit: four CSRs, two vectors, one return instruction. It becomes load-bearing when you add RAS features (ECC machine-check reporting) or Smdbltrp — for a v1 Linux core it’s an optional stub with mnstatus.NMIE the only bit DV must remember resets to zero.

Minimal Linux-boot hart MUST

  • Give rnmi inputs priority over everything, unmaskable by MIE
  • Reset NMIE to 0 and make it set-only from software
  • Redirect M-mode exceptions to the RNMI exception vector while NMIE=0
  • Suppress MPRV effects while NMIE=0

MAY simplify / trap-and-emulate

  • Point the RNMI exception vector at mtvec
  • Report all RNMI causes as 0 (undistinguished) in mncause
  • Skip Smrnmi entirely on a first Linux core — base NMIs (or none) are still conformant

Check yourself — resumable NMIs

1.Why can't a base-architecture NMI generally resume the interrupted work?

2.Software wants to briefly mask RNMIs around a critical section. Can it?

3.An exception occurs in M-mode while mnstatus.NMIE=0 (inside the RNMI handler). What happens?

4.What does MNRET restore and set?

4 questions