-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ARM: fix TLS pointer issue (1.14 branch) #25636
ARM: fix TLS pointer issue (1.14 branch) #25636
Conversation
This is fixed in master branch by #24714 but I wanted a more targeted fix to backport to 1.14. This needs HW testing on frdm-k64f (or some other board with the custom NXP MPU) |
e6ded6e
to
eb7a165
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to me you have changed the semantics of Z_ARCH_THREAD_STACK_BUFFER and Z_THREAD_STACK_SIZEOF
Currently:
- Z_ARCH_THREAD_STACK_BUFFER points to the start of the available thread stack, i.e. after the MPU guard (if that one exists).
- Z_ARCH_THREAD_STACK_SIZEOF is the size of the stack available for the thread, i.e. after subtracting the MPU guard (if that one exists).
To facilitate review, pls, explain what you intend to reflect with the macros:
Z_ARCH_THREAD_STACK_BUFFER and Z_ARCH_THREAD_STACK_SIZEOF, then I 'll take a second look.
This a the problem here. You cannot do this if the guard is "carved out" because you don't know whether the thread is running in user mode or not. If the thread is running in user mode, there is no guard. The entire stack object is sized to a power of two and the entire stack object is available to the user. ARCH_THREAD_STACK_BUFFER() can only work properly if it skips permanently reserved memory. Not a guard that may or may not be there depending on what mode the thread is running in. You can't have a constant definition for something that changes at runtime.
This was changed for the same reason as ARCH_THREAD_STACK_BUFFER for power-of-two systems: it should only take into account permanently reserved space. Not transient guard memory. What you are thinking of is actually tracked in There were several inconsistencies in implementation and semantics for all of this between X86, ARC, and ARM. I have rewritten all of this in #24714 so that it finally is the same everywhere. I did not want to back port all of that to 1.14. |
eb7a165
to
7d974c3
Compare
The workaround for ARMv7-M architecture (which proactively decreases the available thread stack by the size of the MPU guard) needs to be placed before we calculate the pointer of the user-space local thread data, otherwise this pointer will fall beyond the boundary of the thread stack area. Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
Ensure that the TLS region is within the stack object. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
7d974c3
to
2a27669
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving the fix and the test.
I'd like to have a full run all -userspace tests for e.g. sam_e70_xplained before merging this to the LTS
@ioannisg agreed. Would like some testing on frdm_k64f too since the NXP MPU isn't under emulation. I have a board but have been having trouble flashing it. I am going to fiddle with it more this afternoon. I also have a sam_e70 board, I'll give that a go too. |
I can do all this for you @andrewboie. By the way, although I am fine with testing it on nxp mpu, I find it less important since this workaround does not apply to the nxp mph as far as I remember. Nxp mpu doesn't require power of 2 size alignment |
Thanks appreciate it! |
Testing on sam_e70_xplained and frdm_k64f:
tests are passing |
arm: fix stack size accounting
On ARM Cortex-M, which enforces MPU power-of-two alignment,
the memory for stack guards is 'carved-out' of the stack buffer,
and not reserved permanently.
However, the Z_ARCH_THREAD_STACK_BUFFER and
Z_ARCH_THREAD_STACK_SIZEOF implementations were adding/subtracting
the guard size, which is incorrect for carved-out space. This can
only be done if the space is permanently reserved.
Fix this so that these APIs work correctly in the carve-out case.
Adjust thread->stack_info values on transition to user mode correctly.
See: #25635
Signed-off-by: Andrew Boie andrew.p.boie@intel.com