Skip to content
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

arch: arm: move stack switching back to ASM code #16099

Merged
merged 2 commits into from
May 16, 2019

Conversation

wentongwu
Copy link
Contributor

@wentongwu wentongwu commented May 13, 2019

With -O0 optimizion, gcc compiler doesn't inline "static inline"
marked function. So when function call return from function
set_and_switch_to_psp which is to switch sp from MSP to PSP, the
ending "mov sp, r7" instruction will overwrite the just updated
sp value(PSP) with the beginning stack pointer(should be MSP)
stored in r7 register, so the switch doesn't happen. And it causes
unpredictable problems in the initialization process, the backward
analysis for this problem can be found on Github issue #15794.

Also increase stack buffer when code coverage enabled.

Fixes: #15794.

@wentongwu wentongwu requested review from ioannisg and a user May 13, 2019 10:30
Copy link
Member

@ioannisg ioannisg left a comment

Choose a reason for hiding this comment

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

Although this seems to work, I wonder if we should just revert to using inline assembly for setting and switching to PSP.

@psidhu
Copy link
Contributor

psidhu commented May 13, 2019

Although this seems to work, I wonder if we should just revert to using inline assembly for setting and switching to PSP.

@ioannisg Why did we switch away from asm here anyways? I'm assuming it was something to do with maintainability, but I'm not totally sure.

@ioannisg
Copy link
Member

ioannisg commented May 13, 2019

Although this seems to work, I wonder if we should just revert to using inline assembly for setting and switching to PSP.

@ioannisg Why did we switch away from asm here anyways? I'm assuming it was something to do with maintainability, but I'm not totally sure.

Yeah, it was an effort to make the code more readable, but I guess we didn't review all the cases, unfortunately. and ended up with this kind of issues. You can look at the history, if you are interested in the original discussion around the refactoring; can't recall the author on top of my head.

I favor reverting the switch-and-set-psp() to assembly, but other reviewers are welcome to comment on the current way of fixing the bug.

@psidhu
Copy link
Contributor

psidhu commented May 13, 2019

Yeah, it was an effort to make the code more readable, but I guess we didn't review all the cases, unfortunately. and ended up with this kind of issues. I favor reverting the switch-and-set-psp() to assembly, but other reviewers are welcome to comment on the current way of fixing the bug.

I agree with you to revert to this back to asm instead of fixing it this way. This is the second time I've seen a project attempt to do this, then decide to backoff so as not to rely on the compiler.

I think there's much merit in sticking with asm, but add in a block comment the roughly equivalent C code if anyone can't understand the asm, but would like to still understand what's happening.

@andrewboie
Copy link
Contributor

I think we should go back to assembly. Switching the stack pointer within C code is incredibly perilous, one bad assumption by the compiler about what is on the stack causes everything to come crashing down. You could consider x86_64's approach as a model however, look for _switch_top / _switch_bottom

@ioannisg
Copy link
Member

I think we should go back to assembly. Switching the stack pointer within C code is incredibly perilous, one bad assumption by the compiler about what is on the stack causes everything to come crashing down. You could consider x86_64's approach as a model however, look for _switch_top / _switch_bottom

Will you be able to provide the patch @wentongwu ?

@wentongwu
Copy link
Contributor Author

I think we should go back to assembly. Switching the stack pointer within C code is incredibly perilous, one bad assumption by the compiler about what is on the stack causes everything to come crashing down. You could consider x86_64's approach as a model however, look for _switch_top / _switch_bottom

Will you be able to provide the patch @wentongwu ?

Yes, I'm preparing the patch. Thanks.

@ioannisg
Copy link
Member

I think we should go back to assembly. Switching the stack pointer within C code is incredibly perilous, one bad assumption by the compiler about what is on the stack causes everything to come crashing down. You could consider x86_64's approach as a model however, look for _switch_top / _switch_bottom

Will you be able to provide the patch @wentongwu ?

Yes, I'm preparing the patch. Thanks.

Thank you!

@ioannisg ioannisg added the area: ARM ARM (32-bit) Architecture label May 14, 2019
@andrewboie andrewboie changed the title arch: arm: force static inline on changing stack function arch: arm: move stack switching back to ASM code May 14, 2019
@andrewboie
Copy link
Contributor

@ioannisg please have another look

Copy link
Member

@ioannisg ioannisg left a comment

Choose a reason for hiding this comment

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

Did a pass - left some review comments, and a question for @andrewboie

arch/arm/core/cortex_m/reset.S Show resolved Hide resolved
#ifdef CONFIG_WDOG_INIT
/* board-specific watchdog initialization is necessary */
bl _WdogInit
#endif

#ifdef CONFIG_INIT_STACKS
Copy link
Member

Choose a reason for hiding this comment

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

This is OK with me, I think we can just keep it as is. Although, still the C code should work, cause I don't see any SP manipulation.

arch/arm/core/cortex_m/reset.S Show resolved Hide resolved
arch/arm/core/cortex_m/reset.S Show resolved Hide resolved
arch/arm/core/cortex_m/reset.S Outdated Show resolved Hide resolved
@wentongwu wentongwu force-pushed the coverage branch 2 times, most recently from 9a369ec to 772ff5b Compare May 16, 2019 11:16
@wentongwu wentongwu requested a review from ioannisg May 16, 2019 13:02
* CONTROL_SPSEL_Msk
*/
mrs r0, CONTROL
movs r1, #2
Copy link
Member

@ioannisg ioannisg May 16, 2019

Choose a reason for hiding this comment

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

Pls, add the /* CONTROL_SPSEL_Msk */ comment in this line: orrs r0, r1
Actually, probably, you can do "orrs" directly with an immediate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, it seems ARMV7-m can orrs immediate, but ARMV6-M can not (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662a/CIHBDBJH.html )

Copy link
Member

@ioannisg ioannisg left a comment

Choose a reason for hiding this comment

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

just a minor suggestion for the inline comment

With -O0 optimizion, gcc compiler doesn't inline "static inline"
marked function. So when function call return from function
set_and_switch_to_psp which is to switch sp from MSP to PSP, the
ending "mov sp, r7" instruction will overwrite the just updated
sp value(PSP) with the beginning stack pointer(should be MSP)
stored in r7 register, so the switch doesn't happen. And it causes
unpredictable problems in the initialization process, the backward
analysis for this problem can be found on Github issue zephyrproject-rtos#15794.

Fixes: zephyrproject-rtos#15794.

Signed-off-by: Wentong Wu <wentong.wu@intel.com>
increase stack buffer when code coverage enabled.

Fixes: zephyrproject-rtos#15794.

Signed-off-by: Wentong Wu <wentong.wu@intel.com>
@wentongwu wentongwu requested a review from ioannisg May 16, 2019 16:18
@manochavikas
Copy link

With -O0 optimizion, gcc compiler doesn't inline "static inline" marked function

just saw this revert, an easy fix seems to be using always inline (__always_inline).

Cheers,
Vikas

@manochavikas
Copy link

@wentongwu
Can you check with always_inline, it should fix the issue with -O0.

Cheers,
Vikas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: ARM ARM (32-bit) Architecture priority: high High impact/importance bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

mps2_an385 crashes if CONFIG_INIT_STACKS=y and CONFIG_COVERAGE=y
6 participants