Skip to content

Commit 83bd7d3

Browse files
ioannisgnashif
authored andcommitted
arch: arm: mpu: protect RNR when reading RBAR, RASR in ARMv7-M driver
We lock IRQs around writing to RNR and immediate reading of RBAR RASR in ARMv7-M MPU driver. We do this for the functions invoked directly or undirectly by arch_buffer_validate(). This locking guarantees that - arch_buffer_validate() calls by ISRs may safely preempt each other - arch_buffer_validate() calls by threads may safely preempt each other (i.e via context switch -out and -in again). Signed-off-by: Ioannis Glaropoulos <[email protected]>
1 parent 1058a65 commit 83bd7d3

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

arch/arm/core/cortex_m/mpu/arm_mpu_v7_internal.h

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,16 @@ static inline u32_t mpu_region_get_size(u32_t index)
151151
*/
152152
static inline int is_enabled_region(u32_t index)
153153
{
154+
/* Lock IRQs to ensure RNR value is correct when reading RASR. */
155+
unsigned int key;
156+
u32_t rasr;
157+
158+
key = irq_lock();
154159
MPU->RNR = index;
155-
return (MPU->RASR & MPU_RASR_ENABLE_Msk) ? 1 : 0;
160+
rasr = MPU->RASR;
161+
irq_unlock(key);
162+
163+
return (rasr & MPU_RASR_ENABLE_Msk) ? 1 : 0;
156164
}
157165

158166
/* Only a single bit is set for all user accessible permissions.
@@ -169,8 +177,16 @@ static inline int is_enabled_region(u32_t index)
169177
*/
170178
static inline u32_t get_region_ap(u32_t r_index)
171179
{
180+
/* Lock IRQs to ensure RNR value is correct when reading RASR. */
181+
unsigned int key;
182+
u32_t rasr;
183+
184+
key = irq_lock();
172185
MPU->RNR = r_index;
173-
return (MPU->RASR & MPU_RASR_AP_Msk) >> MPU_RASR_AP_Pos;
186+
rasr = MPU->RASR;
187+
irq_unlock(key);
188+
189+
return (rasr & MPU_RASR_AP_Msk) >> MPU_RASR_AP_Pos;
174190
}
175191

176192
/**
@@ -185,9 +201,18 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
185201
u32_t r_size_lshift;
186202
u32_t r_addr_end;
187203

204+
/* Lock IRQs to ensure RNR value is correct when reading RBAR, RASR. */
205+
unsigned int key;
206+
u32_t rbar, rasr;
207+
208+
key = irq_lock();
188209
MPU->RNR = r_index;
189-
r_addr_start = MPU->RBAR & MPU_RBAR_ADDR_Msk;
190-
r_size_lshift = ((MPU->RASR & MPU_RASR_SIZE_Msk) >>
210+
rbar = MPU->RBAR;
211+
rasr = MPU->RASR;
212+
irq_unlock(key);
213+
214+
r_addr_start = rbar & MPU_RBAR_ADDR_Msk;
215+
r_size_lshift = ((rasr & MPU_RASR_SIZE_Msk) >>
191216
MPU_RASR_SIZE_Pos) + 1;
192217
r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1;
193218

0 commit comments

Comments
 (0)