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 <Ioannis.Glaropoulos@nordicsemi.no>
This commit is contained in:
parent
db0ca2e31a
commit
f8a5f0330d
1 changed files with 29 additions and 4 deletions
|
@ -151,8 +151,16 @@ static inline u32_t mpu_region_get_size(u32_t index)
|
||||||
*/
|
*/
|
||||||
static inline int is_enabled_region(u32_t index)
|
static inline int is_enabled_region(u32_t index)
|
||||||
{
|
{
|
||||||
|
/* Lock IRQs to ensure RNR value is correct when reading RASR. */
|
||||||
|
unsigned int key;
|
||||||
|
u32_t rasr;
|
||||||
|
|
||||||
|
key = irq_lock();
|
||||||
MPU->RNR = index;
|
MPU->RNR = index;
|
||||||
return (MPU->RASR & MPU_RASR_ENABLE_Msk) ? 1 : 0;
|
rasr = MPU->RASR;
|
||||||
|
irq_unlock(key);
|
||||||
|
|
||||||
|
return (rasr & MPU_RASR_ENABLE_Msk) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only a single bit is set for all user accessible permissions.
|
/* Only a single bit is set for all user accessible permissions.
|
||||||
|
@ -169,8 +177,16 @@ static inline int is_enabled_region(u32_t index)
|
||||||
*/
|
*/
|
||||||
static inline u32_t get_region_ap(u32_t r_index)
|
static inline u32_t get_region_ap(u32_t r_index)
|
||||||
{
|
{
|
||||||
|
/* Lock IRQs to ensure RNR value is correct when reading RASR. */
|
||||||
|
unsigned int key;
|
||||||
|
u32_t rasr;
|
||||||
|
|
||||||
|
key = irq_lock();
|
||||||
MPU->RNR = r_index;
|
MPU->RNR = r_index;
|
||||||
return (MPU->RASR & MPU_RASR_AP_Msk) >> MPU_RASR_AP_Pos;
|
rasr = MPU->RASR;
|
||||||
|
irq_unlock(key);
|
||||||
|
|
||||||
|
return (rasr & MPU_RASR_AP_Msk) >> MPU_RASR_AP_Pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,9 +201,18 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
|
||||||
u32_t r_size_lshift;
|
u32_t r_size_lshift;
|
||||||
u32_t r_addr_end;
|
u32_t r_addr_end;
|
||||||
|
|
||||||
|
/* Lock IRQs to ensure RNR value is correct when reading RBAR, RASR. */
|
||||||
|
unsigned int key;
|
||||||
|
u32_t rbar, rasr;
|
||||||
|
|
||||||
|
key = irq_lock();
|
||||||
MPU->RNR = r_index;
|
MPU->RNR = r_index;
|
||||||
r_addr_start = MPU->RBAR & MPU_RBAR_ADDR_Msk;
|
rbar = MPU->RBAR;
|
||||||
r_size_lshift = ((MPU->RASR & MPU_RASR_SIZE_Msk) >>
|
rasr = MPU->RASR;
|
||||||
|
irq_unlock(key);
|
||||||
|
|
||||||
|
r_addr_start = rbar & MPU_RBAR_ADDR_Msk;
|
||||||
|
r_size_lshift = ((rasr & MPU_RASR_SIZE_Msk) >>
|
||||||
MPU_RASR_SIZE_Pos) + 1;
|
MPU_RASR_SIZE_Pos) + 1;
|
||||||
r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1;
|
r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue