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

Xtensa doesn't save SCOMPARE1 register on context switch #21800

Closed
andyross opened this issue Jan 9, 2020 · 0 comments · Fixed by #22750
Closed

Xtensa doesn't save SCOMPARE1 register on context switch #21800

andyross opened this issue Jan 9, 2020 · 0 comments · Fixed by #22750
Assignees
Labels
bug The issue is a bug, or the PR is fixing a bug priority: low Low impact/importance bug

Comments

@andyross
Copy link
Contributor

andyross commented Jan 9, 2020

Xtensa uses a somewhat odd two-instruction sequence for atomic operations. You first write the SCOMPARE1 special register to the "old value" of the memory address, and then execute a S32C1I instruction to do a compare and swap with a new value if it hasn't changed.

I realized while thinking about the implications of #21771 that the SCOMPARE1 value is not saved by the context switch code. This means that it's possible to take an interrupt between those two instructions, run some code that does more atomic stuff, and get the wrong value in the comparator register when the context is restored!

In practice, this doesn't actually break anything at the moment. The only major user of atomic_cas() currently are in the spinlock code, which always uses a literal "0" for the old value. (Also the sys_sem code uses it with arbitrary values, but that is a userspace abstraction we aren't AFAICT testing on xtensa currently). So not a P1 bug, probably, but something we need to fix for sure.

Context switch on xtensa needs to dump and restore SCOMPARE1.

@andyross andyross added the bug The issue is a bug, or the PR is fixing a bug label Jan 9, 2020
@jhedberg jhedberg added the priority: low Low impact/importance bug label Jan 14, 2020
dcpleung added a commit to dcpleung/zephyr that referenced this issue Feb 12, 2020
Xtensa uses two instructions to perform atomic compare-and-set
instruction: first the comparison register, then the actual
instruction to do compare-and-set. There is a potential that
context switching is performed before these two instructions.
A restored context may have the wrong value in the comparison
register. So we need to save and restore the comparison
register during context switching.

Fixes zephyrproject-rtos#21800

Signed-off-by: Daniel Leung <[email protected]>
jhedberg pushed a commit that referenced this issue Feb 27, 2020
Xtensa uses two instructions to perform atomic compare-and-set
instruction: first the comparison register, then the actual
instruction to do compare-and-set. There is a potential that
context switching is performed before these two instructions.
A restored context may have the wrong value in the comparison
register. So we need to save and restore the comparison
register during context switching.

Fixes #21800

Signed-off-by: Daniel Leung <[email protected]>
hakehuang pushed a commit to hakehuang/zephyr that referenced this issue Mar 18, 2020
Xtensa uses two instructions to perform atomic compare-and-set
instruction: first the comparison register, then the actual
instruction to do compare-and-set. There is a potential that
context switching is performed before these two instructions.
A restored context may have the wrong value in the comparison
register. So we need to save and restore the comparison
register during context switching.

Fixes zephyrproject-rtos#21800

Signed-off-by: Daniel Leung <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug The issue is a bug, or the PR is fixing a bug priority: low Low impact/importance bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants