lkml.org 
[lkml]   [2020]   [Aug]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 033/152] xtensa: add missing exclusive access state management
    Date
    From: Max Filippov <jcmvbkbc@gmail.com>

    commit a0fc1436f1f4f84e93144480bf30e0c958d135b6 upstream.

    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: f7c34874f04a ("xtensa: add exclusive atomics support")
    Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/xtensa/include/asm/thread_info.h | 4 ++++
    arch/xtensa/kernel/asm-offsets.c | 3 +++
    arch/xtensa/kernel/entry.S | 11 +++++++++++
    3 files changed, 18 insertions(+)

    --- a/arch/xtensa/include/asm/thread_info.h
    +++ b/arch/xtensa/include/asm/thread_info.h
    @@ -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
    --- a/arch/xtensa/kernel/asm-offsets.c
    +++ b/arch/xtensa/kernel/asm-offsets.c
    @@ -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));
    --- a/arch/xtensa/kernel/entry.S
    +++ b/arch/xtensa/kernel/entry.S
    @@ -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
    @@ -2024,6 +2029,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

    \
     
     \ /
      Last update: 2020-08-20 14:44    [W:4.464 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site