"Smcntrpmf": Privilege-Mode Filtering for cycle & instret

Part II Linux boot: optional Vol. II (Privileged) pp. 88–89 · ~2 min read

  • smcntrpmf

By default cycle and instret tick straight through page faults and interrupts — so a user program self-profiling with two counter reads sees kernel noise, and worse, measures privileged execution (a timing side channel). Smcntrpmf adds per-privilege inhibit bits.

mcyclecfg (0x321) / minstretcfg (0x322)

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

(Address trivia the spec admits: 0x320 would’ve been natural, but mcountinhibit got there first. RV32 gets mcyclecfgh/minstretcfgh; Smcdeleg/Ssccfg can expose these to S-mode.)

The counting rules

What counts where
Rule
cycleCounts CPU cycles only in non-inhibited modes; multi-cycle trap/return transitions attribute the switchover to ANY one transition cycle, implementation-defined and not necessarily consistent
instret — ordinary instructionsIncrement iff they retire in a non-inhibited mode
instret — exception-raising instructionsNever retire, never count (the u07 rule, unchanged)
instret — xRETCounts iff its ORIGINATING mode is non-inhibited
Software emulationAn emulator running in an inhibited mode must emulate the increment for the emulated instruction
Dotted-underlined cells have explanations — click one.

Hardware Designer Notes

Cost: two config registers and two AND gates on existing increment wires; the only subtlety is plumbing the xRET originating mode to the commit-stage counter logic — which your trap unit already knows. Worthwhile the moment your users run perf.

Minimal Linux-boot hart MUST

  • Gate the cycle increment with !xINH[current mode] and the instret increment with !xINH[retire mode] — except xRET, which uses its pre-return (originating) mode
  • Read-only-zero the INH bits of unimplemented modes and the OF position

MAY simplify / trap-and-emulate

  • Skip the extension (both cfg CSRs absent) — legacy counting is still conformant
  • Attribute transition cycles however your trap microsequence falls — no consistency required

Check yourself — counter filtering

1.minstretcfg inhibits every mode except U. A user load page-faults, the kernel fixes it, the load re-executes. How many instret increments?

2.During a trap's multi-cycle mode transition, which mode do the transition cycles count toward?

3.Why do mcyclecfg/minstretcfg mirror the Sscofpmf event-register format with bit 63 read-only zero?

3 questions