Memory protection regions.
More...
|
| int | pbl_mpu_region_add (const struct pbl_mpu_region *region) |
| | Add a static region, for every thread and until reset.
|
| |
| void | pbl_mpu_user_ro_write (void *dst, const void *src, size_t n) |
| | Write to the PBL_MPU_P_RW_U_RO region from privileged code.
|
| |
| bool | pbl_mpu_region_is_stack_guard (uintptr_t start, uintptr_t end) |
| | Check whether a stack guard covers any of a memory range.
|
| |
| const struct pbl_mpu_region * | pbl_mpu_region_firmware (void) |
| | Get the memory of the running firmware image, to check pointers against.
|
| |
| bool | pbl_mpu_region_contains (const struct pbl_mpu_region *region, const void *ptr) |
| | Check whether a region contains an address.
|
| |
| bool | pbl_mpu_region_contains_buffer (const struct pbl_mpu_region *region, const void *buf, size_t length) |
| | Check whether a region contains a whole buffer.
|
| |
| bool | pbl_mpu_region_contains_cstring (const struct pbl_mpu_region *region, const char *str, size_t max_length) |
| | Check whether a region contains a whole NUL-terminated string.
|
| |
| void | pbl_mpu_regions_print (void(*print)(void *ctx, const char *line), void *ctx) |
| | Print every programmed region, one line at a time.
|
| |
Memory protection regions.
A region describes a range of memory: who may access it and what kind of memory it is. The kernel owns the protection hardware, so callers never see its slots or register encodings.
Static regions apply to every thread and stay until reset. Thread regions are switched in with a thread, see pbl_thread_attr::regions.
Privileged code can access anything no region covers, through the default memory map. Unprivileged code can only access what a region grants. Static regions must not overlap.
.base = BANKS_BASE,
.size = BANKS_SIZE,
};
#define PBL_ASSERTN(expr)
Panic if an expression is false.
Definition assert.h:42
const char * name
Name shown by pbl_mpu_regions_print(); optional.
Definition mpu.h:93
Memory region.
Definition mpu.h:91
int pbl_mpu_region_add(const struct pbl_mpu_region *region)
Add a static region, for every thread and until reset.
#define PBL_MPU_P_RO_U_RO
Privileged and unprivileged read-only.
Definition mpu.h:65
#define PBL_MPU_NORMAL_WT
Normal memory, write-through cached.
Definition mpu.h:72
◆ pbl_mpu_region
Memory region.
The base and size must be multiples of 32 bytes. Not every range can be protected on every architecture: ARMv7-M needs it to line up with eighths of a power-of-two block.
| Data Fields |
|
uint32_t |
attr |
Access, memory type and flags: PBL_MPU_*. |
|
uintptr_t |
base |
Lowest address. |
|
const char * |
name |
Name shown by pbl_mpu_regions_print(); optional. |
|
size_t |
size |
Size in bytes. |
◆ KERNEL_READONLY_DATA
| #define KERNEL_READONLY_DATA PBL_SECTION(".kernel_unpriv_ro_bss") |
Places a variable where unprivileged code can read it but not write to it.
◆ KERNEL_READONLY_DATA_SET
| #define KERNEL_READONLY_DATA_SET |
( |
|
var, |
|
|
|
val |
|
) |
| |
Value: do { \
typeof(var) val_ = (val); \
pbl_mpu_user_ro_write(&(var), &val_, sizeof(val_)); \
} while (0)
Assign a KERNEL_READONLY_DATA variable.
Privileged code only.
- Parameters
-
◆ PBL_MPU_ACCESS_MSK
| #define PBL_MPU_ACCESS_MSK 7U |
Mask of the access attribute.
◆ PBL_MPU_DEVICE
| #define PBL_MPU_DEVICE (3U << 3) |
Device memory: accesses are not merged, reordered or cached.
◆ PBL_MPU_EXEC
| #define PBL_MPU_EXEC (1U << 5) |
Instructions may be fetched from the region.
◆ PBL_MPU_NO_ACCESS
| #define PBL_MPU_NO_ACCESS 0U |
No access.
Below a stack, this makes a guard.
◆ PBL_MPU_NORMAL_NC
| #define PBL_MPU_NORMAL_NC (0U << 3) |
Normal memory, not cached.
◆ PBL_MPU_NORMAL_WB
| #define PBL_MPU_NORMAL_WB (2U << 3) |
Normal memory, write-back cached.
◆ PBL_MPU_NORMAL_WT
| #define PBL_MPU_NORMAL_WT (1U << 3) |
Normal memory, write-through cached.
◆ PBL_MPU_P_RO
Privileged read-only, no unprivileged access.
◆ PBL_MPU_P_RO_U_RO
| #define PBL_MPU_P_RO_U_RO 5U |
Privileged and unprivileged read-only.
◆ PBL_MPU_P_RW
Privileged read/write, no unprivileged access.
◆ PBL_MPU_P_RW_U_RO
| #define PBL_MPU_P_RW_U_RO 2U |
Privileged read/write, unprivileged read-only.
◆ PBL_MPU_P_RW_U_RW
| #define PBL_MPU_P_RW_U_RW 3U |
Privileged and unprivileged read/write.
◆ PBL_MPU_SHAREABLE
| #define PBL_MPU_SHAREABLE (1U << 6) |
Coherent with other bus masters.
Some cores do not cache shareable memory at all.
◆ PBL_MPU_TYPE_MSK
| #define PBL_MPU_TYPE_MSK (3U << 3) |
Mask of the memory type attribute.
◆ pbl_mpu_region_add()
Add a static region, for every thread and until reset.
- Parameters
-
| region | Region to add, which must stay valid. |
- Returns
- 0 on success.
- Return values
-
| -ENOSPC | No slot is left. |
| -EINVAL | The region overlaps another static region. |
◆ pbl_mpu_region_contains()
| bool pbl_mpu_region_contains |
( |
const struct pbl_mpu_region * |
region, |
|
|
const void * |
ptr |
|
) |
| |
Check whether a region contains an address.
- Parameters
-
- Returns
- true if
ptr is inside region.
◆ pbl_mpu_region_contains_buffer()
| bool pbl_mpu_region_contains_buffer |
( |
const struct pbl_mpu_region * |
region, |
|
|
const void * |
buf, |
|
|
size_t |
length |
|
) |
| |
Check whether a region contains a whole buffer.
- Parameters
-
| region | Region. |
| buf | Buffer. |
| length | Buffer size in bytes. |
- Returns
- true if all of
buf is inside region.
◆ pbl_mpu_region_contains_cstring()
| bool pbl_mpu_region_contains_cstring |
( |
const struct pbl_mpu_region * |
region, |
|
|
const char * |
str, |
|
|
size_t |
max_length |
|
) |
| |
Check whether a region contains a whole NUL-terminated string.
Never reads outside of the region.
- Parameters
-
| region | Region. |
| str | String. |
| max_length | Longest accepted string, without the terminator. |
- Returns
- true if
str and its terminator are inside region.
◆ pbl_mpu_region_firmware()
Get the memory of the running firmware image, to check pointers against.
Not always what the MPU protects: an architecture may have to round its region up.
- Returns
- Firmware image region.
◆ pbl_mpu_region_is_stack_guard()
| bool pbl_mpu_region_is_stack_guard |
( |
uintptr_t |
start, |
|
|
uintptr_t |
end |
|
) |
| |
Check whether a stack guard covers any of a memory range.
Usable from fault handlers.
- Parameters
-
| start | Lowest address of the range. |
| end | End of the range, exclusive. |
- Returns
- true if the range overlaps the ISR stack guard or one of the running thread.
◆ pbl_mpu_regions_print()
| void pbl_mpu_regions_print |
( |
void(*)(void *ctx, const char *line) |
print, |
|
|
void * |
ctx |
|
) |
| |
Print every programmed region, one line at a time.
Usable from fault handlers.
- Parameters
-
| print | Called with each line. |
| ctx | Passed to print. |
◆ pbl_mpu_user_ro_write()
| void pbl_mpu_user_ro_write |
( |
void * |
dst, |
|
|
const void * |
src, |
|
|
size_t |
n |
|
) |
| |
Write to the PBL_MPU_P_RW_U_RO region from privileged code.
ARMv8-M cannot let only privileged code write to a region, so the region is lifted for the duration of the copy, with interrupts masked. Elsewhere this is a plain copy.
- Parameters
-
| dst | Destination. |
| src | Source. |
| n | Number of bytes. |
◆ pbl_soc_mpu_regions
Regions the SoC declares, with CONFIG_SOC_HAS_MPU_REGIONS.
The kernel adds them first thing on boot, before pbl_soc_early_init().
◆ pbl_soc_num_mpu_regions
| const size_t pbl_soc_num_mpu_regions |
|
extern |