diff --git a/cortex-m/src/critical_section.rs b/cortex-m/src/critical_section.rs index 039d12a0..d69b5c3e 100644 --- a/cortex-m/src/critical_section.rs +++ b/cortex-m/src/critical_section.rs @@ -12,7 +12,8 @@ unsafe impl Impl for SingleCoreCriticalSection { // u32 instead of using the primask::read() function to minimize the number of processor // cycles during which interrupts are disabled. let restore_state = primask::read_raw(); - // NOTE: Fence guarantees are provided by interrupt::disable(), which performs a `compiler_fence(SeqCst)`. + // NOTE: Fence guarantees are provided by interrupt::disable(), + // which performs a `compiler_fence(SeqCst)` fore and aft. interrupt::disable(); restore_state } diff --git a/cortex-m/src/interrupt.rs b/cortex-m/src/interrupt.rs index 07da650b..3cce58f2 100644 --- a/cortex-m/src/interrupt.rs +++ b/cortex-m/src/interrupt.rs @@ -41,7 +41,10 @@ unsafe impl InterruptNumber for T { #[inline] #[asm_cfg(cortex_m)] pub fn disable() { - unsafe { asm!("cpsid i", options(nomem, nostack, preserves_flags)) }; + // Ensure no preceeding memory accesses are reordered to after interrupts are disabled. + compiler_fence(Ordering::SeqCst); + + unsafe { asm!("cpsid i", options(nostack, preserves_flags)) }; // Ensure no subsequent memory accesses are reordered to before interrupts are disabled. compiler_fence(Ordering::SeqCst); @@ -58,7 +61,10 @@ pub unsafe fn enable() { // Ensure no preceeding memory accesses are reordered to after interrupts are enabled. compiler_fence(Ordering::SeqCst); - unsafe { asm!("cpsie i", options(nomem, nostack, preserves_flags)) }; + unsafe { asm!("cpsie i", options(nostack, preserves_flags)) }; + + // Ensure no subsequent memory accesses are reordered to before interrupts are disabled. + compiler_fence(Ordering::SeqCst); } /// Execute closure `f` in an interrupt-free context. diff --git a/cortex-m/src/register/primask.rs b/cortex-m/src/register/primask.rs index 163fee95..2708ef8c 100644 --- a/cortex-m/src/register/primask.rs +++ b/cortex-m/src/register/primask.rs @@ -64,7 +64,9 @@ pub fn read_raw() -> u32 { pub unsafe fn write_raw(r: u32) { // Ensure no preceeding memory accesses are reordered to after interrupts are possibly enabled. compiler_fence(Ordering::SeqCst); - unsafe { asm!("msr PRIMASK, {}", in(reg) r, options(nomem, nostack, preserves_flags)) }; + + unsafe { asm!("msr PRIMASK, {}", in(reg) r, options(nostack, preserves_flags)) }; + // Ensure no subsequent memory accesses are reordered to before interrupts are possibly disabled. compiler_fence(Ordering::SeqCst); }