-
Notifications
You must be signed in to change notification settings - Fork 173
Description
It calls interrupt::disable
, which uses cpsid i
, which disables interrupts and exceptions that have configurable priority by setting PRIMASK. Notably, this does not affect (on thumbv6) the NMI and HardFault exceptions since they have fixed priorities.
This means that interrupt::free
is unsoundly creating a CriticalSection
token when it's not allowed to do so.
Note that it is impossible to fully fix this just in the cortex-m crate, since NMI is always enabled and can not be masked (which is its entire point, I suppose). Also, FAULTMASK could be used to also disable HardFault, but that only exists on thumbv7+ from what I can tell.
Our options here are:
- Change cortex-m-rt to require
unsafe
to register HardFault, NMI, etc. handlers - Use FAULTMASK /
cpsid f
when targeting thumbv7+, which could allow safe registration of fault handlers except NMI on thumbv7+ (note that FAULTMASK has somewhat subtle behavior that differs from PRIMASK, so this needs some extra care to make sure it's sound) - Make
interrupt::free
anunsafe fn
and document that it's only safe to call when not in one of the non-maskable fault handlers
We should probably change the docs of bare_metal::CriticalSection
to reflect semantics when NMIs are present.
This issue is somewhat thorny since 3 crates rely on properties of each other for soundness (cortex-m, cortex-m-rt, and bare-metal).
(thanks to @japaric for noticing this)