Skip to content

Commit

Permalink
xtensa: add missing exclusive access state management
Browse files Browse the repository at this point in the history
The result of the s32ex opcode is recorded in the ATOMCTL special
register and must be retrieved with the getex opcode. Context switch
between s32ex and getex may trash the ATOMCTL register and result in
duplicate update or missing update of the atomic variable.
Add atomctl8 field to the struct thread_info and use getex to swap
ATOMCTL bit 8 as a part of context switch.
Clear exclusive access monitor on kernel entry.

Cc: stable@vger.kernel.org
Fixes: f7c3487 ("xtensa: add exclusive atomics support")
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
  • Loading branch information
Max Filippov committed Jul 31, 2020
1 parent 6d65d37 commit a0fc143
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 0 deletions.
4 changes: 4 additions & 0 deletions arch/xtensa/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ struct thread_info {
mm_segment_t addr_limit; /* thread address space */

unsigned long cpenable;
#if XCHAL_HAVE_EXCLUSIVE
/* result of the most recent exclusive store */
unsigned long atomctl8;
#endif

/* Allocate storage for extra user states and coprocessor states. */
#if XTENSA_HAVE_COPROCESSORS
Expand Down
3 changes: 3 additions & 0 deletions arch/xtensa/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ int main(void)
DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable));
#if XCHAL_HAVE_EXCLUSIVE
DEFINE(THREAD_ATOMCTL8, offsetof (struct thread_info, atomctl8));
#endif
#if XTENSA_HAVE_COPROCESSORS
DEFINE(THREAD_XTREGS_CP0, offsetof(struct thread_info, xtregs_cp.cp0));
DEFINE(THREAD_XTREGS_CP1, offsetof(struct thread_info, xtregs_cp.cp1));
Expand Down
11 changes: 11 additions & 0 deletions arch/xtensa/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,11 @@ common_exception:
s32i a2, a1, PT_LCOUNT
#endif

#if XCHAL_HAVE_EXCLUSIVE
/* Clear exclusive access monitor set by interrupted code */
clrex
#endif

/* It is now save to restore the EXC_TABLE_FIXUP variable. */

rsr a2, exccause
Expand Down Expand Up @@ -2020,6 +2025,12 @@ ENTRY(_switch_to)
s32i a3, a4, THREAD_CPENABLE
#endif

#if XCHAL_HAVE_EXCLUSIVE
l32i a3, a5, THREAD_ATOMCTL8
getex a3
s32i a3, a4, THREAD_ATOMCTL8
#endif

/* Flush register file. */

spill_registers_kernel
Expand Down

0 comments on commit a0fc143

Please sign in to comment.