Skip to content

Commit 23b8ae5

Browse files
Fix #697
1. Put fences before and after the intrinsics (it would be bad if the disable interrupt operation was moved before the primask read). 2. Remove the `nomem` attribute, so that LLVM believes the asm blocks touch memory and hence cannot move across the fences.
1 parent f259e37 commit 23b8ae5

3 files changed

Lines changed: 13 additions & 4 deletions

File tree

‎cortex-m/src/critical_section.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ unsafe impl Impl for SingleCoreCriticalSection {
1212
// u32 instead of using the primask::read() function to minimize the number of processor
1313
// cycles during which interrupts are disabled.
1414
let restore_state = primask::read_raw();
15-
// NOTE: Fence guarantees are provided by interrupt::disable(), which performs a `compiler_fence(SeqCst)`.
15+
// NOTE: Fence guarantees are provided by interrupt::disable(),
16+
// which performs a `compiler_fence(SeqCst)` fore and aft.
1617
interrupt::disable();
1718
restore_state
1819
}

‎cortex-m/src/interrupt.rs‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ unsafe impl<T: Nr + Copy> InterruptNumber for T {
4141
#[inline]
4242
#[asm_cfg(cortex_m)]
4343
pub fn disable() {
44-
unsafe { asm!("cpsid i", options(nomem, nostack, preserves_flags)) };
44+
// Ensure no preceeding memory accesses are reordered to after interrupts are disabled.
45+
compiler_fence(Ordering::SeqCst);
46+
47+
unsafe { asm!("cpsid i", options(nostack, preserves_flags)) };
4548

4649
// Ensure no subsequent memory accesses are reordered to before interrupts are disabled.
4750
compiler_fence(Ordering::SeqCst);
@@ -58,7 +61,10 @@ pub unsafe fn enable() {
5861
// Ensure no preceeding memory accesses are reordered to after interrupts are enabled.
5962
compiler_fence(Ordering::SeqCst);
6063

61-
unsafe { asm!("cpsie i", options(nomem, nostack, preserves_flags)) };
64+
unsafe { asm!("cpsie i", options(nostack, preserves_flags)) };
65+
66+
// Ensure no subsequent memory accesses are reordered to before interrupts are disabled.
67+
compiler_fence(Ordering::SeqCst);
6268
}
6369

6470
/// Execute closure `f` in an interrupt-free context.

‎cortex-m/src/register/primask.rs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ pub fn read_raw() -> u32 {
6464
pub unsafe fn write_raw(r: u32) {
6565
// Ensure no preceeding memory accesses are reordered to after interrupts are possibly enabled.
6666
compiler_fence(Ordering::SeqCst);
67-
unsafe { asm!("msr PRIMASK, {}", in(reg) r, options(nomem, nostack, preserves_flags)) };
67+
68+
unsafe { asm!("msr PRIMASK, {}", in(reg) r, options(nostack, preserves_flags)) };
69+
6870
// Ensure no subsequent memory accesses are reordered to before interrupts are possibly disabled.
6971
compiler_fence(Ordering::SeqCst);
7072
}

0 commit comments

Comments
 (0)