Description
Describe the bug
stackprot test does not run properly on frdm_k64f, triggering a BusFault
To Reproduce
Steps to reproduce the behavior:
- mkdir build; cd build
- cmake -DBOARD=board\frdm_k64f ..
- make
- See error
Expected behavior
Test should pass.
Logs
***** Booting Zephyr OS v1.14.0-rc1-563-g51c8c550d8 *****
***** BUS FAULT *****
Stacking error
Imprecise data bus error
NXP MPU error, port 3
Mode: Supervisor, Data Address: 0x20002e08
Type: Write, Master: 0, Regions: 0x8000
***** HARD FAULT *****
Fault escalation (see below)
***** BUS FAULT *****
Precise data bus error
BFAR Address: 0x20002e08
NXP MPU error, port 3
Mode: Supervisor, Data Address: 0x20002e08
Type: Read, Master: 0, Regions: 0x8000
***** Hardware exception *****
Current thread ID = 0x20000080
Faulting instruction address = 0x31b6
Fatal fault in ISR! Spinning...
Additional context
The test started failing after (45631c3). This commit forced the test to run on user mode. Alone, this is not a reason for the test to fail, but:
- Running the test on user mode implies re-programming the MPU using (on ARM) the Privileged Stack, which has a limited default size (512 bytes)
- Unfortunately, due to the re-work of MPU in Arch arm mpu re work #12817, the MPU re-programming uses, roughly, 250 bytes of stack memory
- This test sets
CONFIG_STACK_CANARIES=y
, which, forces the compiler to embed more stuff into the stack frame(s).
Therefore, we are running out of privileged stack space, when re-programming the MPU, which causes a BusFault on accessing the Guard area.
Workaround:
Setting CONFIG_PRIVILEGED_STACK_SIZE=1024
makes the test pass.
While we do need to decrease the stack usage of MPU re-programming in ARM builds with User-mode, I believe, it is ok to have an increased size for privileged stack areas, when compiling with support for CANARIES, since, itself, that feature adds to the stack usage. That is, I propose:
config PRIVILEGED_STACK_SIZE
int "Size of privileged stack"
default 512 if MPU_STACK_GUARD || BUILTIN_STACK_GUARD
default 512 if COVERAGE_GCOV
default 384 if ARC
>>> default 1024 if ARM && STACK_CANARIES && (MPU_STACK_GUARD || BUILTIN_STACK_GUARD)
default 256
depends on ARCH_HAS_USERSPACE