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 smcntrpmf Privilege-mode filtering for cycle/instret via mcyclecfg (0x321) / minstretcfg (0x322): MINH/SINH/UINH/VSINH/VUINH inhibit counting per mode (Sscofpmf register format, OF bit dead). instret: retire-mode gated; xRET counts by originating mode - so a faulting user instruction counts exactly once. Removes kernel noise and a timing side channel from user self-profiling.
defined in ch. II·7 — open in glossary
adds per-privilege
inhibit bits.
mcyclecfg (0x321) / minstretcfg (0x322)
(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
| Rule | |
|---|---|
| cycle | Counts 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 instructions | Increment iff they retire in a non-inhibited mode |
| instret — exception-raising instructions | Never retire, never count (the u07 rule, unchanged) |
| instret — xRET | Counts iff its ORIGINATING mode is non-inhibited |
| Software emulation | An emulator running in an inhibited mode must emulate the increment for the emulated instruction |
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?