Cortex-M MPU driver and pseudo-module for guarding against stack overflows#5564
Cortex-M MPU driver and pseudo-module for guarding against stack overflows#5564kYc0o merged 4 commits intoRIOT-OS:masterfrom
Conversation
|
nice! |
| PSEUDOMODULES += lwip_tcp | ||
| PSEUDOMODULES += lwip_udp | ||
| PSEUDOMODULES += lwip_udplite | ||
| PSEUDOMODULES += mpu_stack_guard |
There was a problem hiding this comment.
I considered that, but wanted to leave room for other MPUs to be used in the same way.
|
Cool! We need a test though, do you have an application for testing? Otherwise we can write a recursive function which will run out of stack and put it under tests/stack_overflow or something. |
| /* Enable the memory fault exception */ | ||
| SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; | ||
|
|
||
| return 0; |
There was a problem hiding this comment.
This returns 0 on success, 1 on "not available", right?
I find the opposite more intuitive.
|
@gebart I had a feeling someone would ask for a test app. I don't have one yet but will think about it. |
|
@kaspar030 @hexluthor |
|
Suggestion for a follow up PR: Mark the running stack non-executable. |
|
@gebart RIOT seems pretty inconsistent about this but what you describe is also the Linux coding style so I'm going with it. |
|
Here's a test app too. Tested on |
|
Great! tested on arduino-due and it works like a charm, so ACK. Please squash and set the flag for Murdock if possible. |
Can you elaborate on where you found these inconsistencies? |
|
We can wait for the next release on this one... |
|
@OlegHahm I did something like |
|
I would guess that in some cases (maybe not all) this is okay, according to https://github.com/RIOT-OS/RIOT/wiki/Coding-conventions#return-values |
|
Is there anything to discuss in this PR (it was ACKed in #5564 (comment)) |
| mpu_configure( | ||
| 1, /* MPU region 1 */ | ||
| (uintptr_t)sched_active_thread->stack_start + 31, /* Base Address (rounded up) */ | ||
| MPU_ATTR(1, AP_RO_RO, 0, 1, 0, 1, MPU_SIZE_32B) /* Attributes and Size */ |
There was a problem hiding this comment.
This prevents overwriting the lowest byte of the stack?
There was a problem hiding this comment.
please ignore the noise, just read the PR description again. ;)
|
I see no reason to not merge it (but I'm also the author). |
cpu/cortexm_common/include/mpu.h
Outdated
| * | ||
| * @return combined region attribute word | ||
| */ | ||
| #define MPU_ATTR(xn, ap, tex, c, b, s, size) ( \ |
There was a problem hiding this comment.
Conventions say multiline macros should be static inline functions. Would that optimize to the same code in this case?
There was a problem hiding this comment.
I prefer the macro but yield to convention. They are binary equivalent for tests/mpu_stack_guard.
|
There's just the question about the returns, if 0 or negative values in case of failure. Rebase if possible and maybe we should let Murdock look into it again, because this PR is kind of old and several things were merged in the meantime. |
Murdock seemed to be happy last time I tried it and there are no conflicts so why rebase? |
|
Oh, I didn't know you tried afterwards. It should be OK then. Yeah for the conflicts I agree too. So just this "inconsistency" about the return on failure but the arguments are "sometimes 0 is valid, sometimes not", so that's maybe another discussion. I propose to merge this as is and when an agreement about what are the "right" return errors we can change them all, including this one. |
I'm not sure this is clear now: I did not test this PR, I just observed Murdock's results ;-). |
|
Yes, it was me who tested successfully ;) |
b7723b9 to
9926991
Compare
9926991 to
684c291
Compare
|
Ok I
|
|
It seems OK for me now, I'd re-ACK but I'd like the second commit divided into several for the files you're changing, because now it changes several files and the commit message it's not prefixed. |
684c291 to
9698ddd
Compare
|
@kYc0o ok I committed the test app separately. Not sure what else could be divided. |
|
Maybe the commits for |
triggers an exception during stack overflow, but at a cost of 32-63 bytes of RAM per thread.
9698ddd to
0c588e7
Compare
|
and go! |
A 32-byte region at the bottom of the running stack is made read-only by the MPU. If a stack overflow occurs, a memory management exception is triggered before any data below the stack is overwritten. Depending on the alignment of the individual stacks, this comes at a cost of 32-63 bytes per thread. For this reason, the feature is an optional pseudo-module and is not enabled by default.
As a future PR, I'd like to define an attribute for all statically-allocated stacks that instructs the linker to align them to a 32-byte boundary if this module is used, and would otherwise be just a placeholder or "no-op".