Skip to content

Cortex-M MPU driver and pseudo-module for guarding against stack overflows#5564

Merged
kYc0o merged 4 commits intoRIOT-OS:masterfrom
locicontrols:mpu-rebase2
Oct 25, 2016
Merged

Cortex-M MPU driver and pseudo-module for guarding against stack overflows#5564
kYc0o merged 4 commits intoRIOT-OS:masterfrom
locicontrols:mpu-rebase2

Conversation

@hexluthor
Copy link
Copy Markdown
Contributor

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".

@hexluthor hexluthor added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Platform: ARM Platform: This PR/issue effects ARM-based platforms Area: drivers Area: Device drivers labels Jun 21, 2016
@hexluthor hexluthor added this to the Release 2016.07 milestone Jun 21, 2016
@kaspar030
Copy link
Copy Markdown
Contributor

nice!

PSEUDOMODULES += lwip_tcp
PSEUDOMODULES += lwip_udp
PSEUDOMODULES += lwip_udplite
PSEUDOMODULES += mpu_stack_guard
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cortexm_ ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered that, but wanted to leave room for other MPUs to be used in the same way.

@jnohlgard
Copy link
Copy Markdown
Member

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.
The same test would be interesting for the isr stack since the cortexm isr stack relocation pr was merged.

/* Enable the memory fault exception */
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;

return 0;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This returns 0 on success, 1 on "not available", right?
I find the opposite more intuitive.

@hexluthor
Copy link
Copy Markdown
Contributor Author

@gebart I had a feeling someone would ask for a test app. I don't have one yet but will think about it.

@jnohlgard
Copy link
Copy Markdown
Member

@kaspar030 @hexluthor
wouldn't it be more consistent to use negative return values for errors, like in the periph drivers do it?

@jnohlgard
Copy link
Copy Markdown
Member

Suggestion for a follow up PR: Mark the running stack non-executable.

@hexluthor
Copy link
Copy Markdown
Contributor Author

@gebart RIOT seems pretty inconsistent about this but what you describe is also the Linux coding style so I'm going with it.

@hexluthor
Copy link
Copy Markdown
Contributor Author

Here's a test app too. Tested on cc2538dk.

@hexluthor hexluthor added the CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable label Jun 29, 2016
@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Jul 22, 2016

Great! tested on arduino-due and it works like a charm, so ACK. Please squash and set the flag for Murdock if possible.

@OlegHahm
Copy link
Copy Markdown
Member

@gebart RIOT seems pretty inconsistent about this

Can you elaborate on where you found these inconsistencies?

@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Jul 25, 2016

We can wait for the next release on this one...

@kYc0o kYc0o self-assigned this Jul 25, 2016
@kYc0o kYc0o modified the milestones: Release 2016.10, Release 2016.07 Jul 25, 2016
@hexluthor hexluthor added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: new feature The issue requests / The PR implemements a new feature for RIOT and removed CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable labels Jul 25, 2016
@hexluthor
Copy link
Copy Markdown
Contributor Author

@OlegHahm I did something like ack-grep 'return.*(success|fail)'. In most cases functions return 0 on success, but there are some that return 1. Didn't really investigate beyond the grep.

@OlegHahm
Copy link
Copy Markdown
Member

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

@miri64
Copy link
Copy Markdown
Member

miri64 commented Aug 31, 2016

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 */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prevents overwriting the lowest byte of the stack?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please ignore the noise, just read the PR description again. ;)

@hexluthor
Copy link
Copy Markdown
Contributor Author

I see no reason to not merge it (but I'm also the author).

*
* @return combined region attribute word
*/
#define MPU_ATTR(xn, ap, tex, c, b, s, size) ( \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conventions say multiline macros should be static inline functions. Would that optimize to the same code in this case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the macro but yield to convention. They are binary equivalent for tests/mpu_stack_guard.

@miri64 miri64 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Sep 30, 2016
@miri64 miri64 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Oct 4, 2016
@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Oct 19, 2016

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.

@miri64 miri64 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Oct 19, 2016
@miri64
Copy link
Copy Markdown
Member

miri64 commented Oct 19, 2016

@kYc0o

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?

@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Oct 19, 2016

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.

@miri64
Copy link
Copy Markdown
Member

miri64 commented Oct 19, 2016

Oh, I didn't know you tried afterwards.

I'm not sure this is clear now: I did not test this PR, I just observed Murdock's results ;-).

@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Oct 19, 2016

Yes, it was me who tested successfully ;)

@hexluthor
Copy link
Copy Markdown
Contributor Author

Ok I

  • Rebased onto master.
  • Whitelisted new Cortex-M boards arduino-duemilanove, arduino-uno, arduino-zero, nucleo-f207, nucleo-f446, sodaq-autonomo in tests/mpu_stack_guard.
  • Corrected a doxygen typo about return values. Besides mpu_enabled(), all functions return 0 on success, -1 on failure.

@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Oct 24, 2016

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.

@hexluthor
Copy link
Copy Markdown
Contributor Author

@kYc0o ok I committed the test app separately. Not sure what else could be divided.

@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Oct 24, 2016

Maybe the commits for core and cpu... I can also see some commit on another test but I don't know if split it too... Since this PR is touching "delicate" files I'd like to have them in a separated commit.

Copy link
Copy Markdown
Contributor

@kYc0o kYc0o left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Oct 25, 2016

and go!

@kYc0o kYc0o merged commit b2bed29 into RIOT-OS:master Oct 25, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Type: new feature The issue requests / The PR implemements a new feature for RIOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants