• Mark Rutland's avatar
    locking/atomic: sparc: Fix arch_cmpxchg64_local() · 7e108876
    Mark Rutland authored
    Anatoly reports that since commit:
    
      ff5b4f1e ("locking/atomic: sparc: move to ARCH_ATOMIC")
    
    ... it's possible to reliably trigger an oops by running:
    
      stress-ng -v --mmap 1 -t 30s
    
    ... which results in a NULL pointer dereference in
    __split_huge_pmd_locked().
    
    The underlying problem is that commit ff5b4f1e left
    arch_cmpxchg64_local() defined in terms of cmpxchg_local() rather than
    arch_cmpxchg_local(). In <asm-generic/atomic-instrumented.h> we wrap
    these with macros which use identically-named variables. When
    cmpxchg_local() nests inside cmpxchg64_local(), this casues it to use an
    unitialized variable as the pointer, which can be NULL.
    
    This can also be seen in pmdp_establish(), where the compiler can
    generate the pointer with a `clr` instruction:
    
    0000000000000360 <pmdp_establish>:
     360:   9d e3 bf 50     save  %sp, -176, %sp
     364:   fa 5e 80 00     ldx  [ %i2 ], %i5
     368:   82 10 00 1b     mov  %i3, %g1
     36c:   84 10 20 00     clr  %g2
     370:   c3 f0 90 1d     casx  [ %g2 ], %i5, %g1
     374:   80 a7 40 01     cmp  %i5, %g1
     378:   32 6f ff fc     bne,a   %xcc, 368 <pmdp_establish+0x8>
     37c:   fa 5e 80 00     ldx  [ %i2 ], %i5
     380:   d0 5e 20 40     ldx  [ %i0 + 0x40 ], %o0
     384:   96 10 00 1b     mov  %i3, %o3
     388:   94 10 00 1d     mov  %i5, %o2
     38c:   92 10 00 19     mov  %i1, %o1
     390:   7f ff ff 84     call  1a0 <__set_pmd_acct>
     394:   b0 10 00 1d     mov  %i5, %i0
     398:   81 cf e0 08     return  %i7 + 8
     39c:   01 00 00 00     nop
    
    This patch fixes the problem by defining arch_cmpxchg64_local() in terms
    of arch_cmpxchg_local(), avoiding potential shadowing, and resulting in
    working cmpxchg64_local() and variants, e.g.
    
    0000000000000360 <pmdp_establish>:
     360:   9d e3 bf 50     save  %sp, -176, %sp
     364:   fa 5e 80 00     ldx  [ %i2 ], %i5
     368:   82 10 00 1b     mov  %i3, %g1
     36c:   c3 f6 90 1d     casx  [ %i2 ], %i5, %g1
     370:   80 a7 40 01     cmp  %i5, %g1
     374:   32 6f ff fd     bne,a   %xcc, 368 <pmdp_establish+0x8>
     378:   fa 5e 80 00     ldx  [ %i2 ], %i5
     37c:   d0 5e 20 40     ldx  [ %i0 + 0x40 ], %o0
     380:   96 10 00 1b     mov  %i3, %o3
     384:   94 10 00 1d     mov  %i5, %o2
     388:   92 10 00 19     mov  %i1, %o1
     38c:   7f ff ff 85     call  1a0 <__set_pmd_acct>
     390:   b0 10 00 1d     mov  %i5, %i0
     394:   81 cf e0 08     return  %i7 + 8
     398:   01 00 00 00     nop
     39c:   01 00 00 00     nop
    
    Fixes: ff5b4f1e ("locking/atomic: sparc: move to ARCH_ATOMIC")
    Reported-by: default avatarAnatoly Pugachev <matorola@gmail.com>
    Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    Tested-by: default avatarAnatoly Pugachev <matorola@gmail.com>
    Link: https://lore.kernel.org/r/20210707083032.567-1-mark.rutland@arm.com
    7e108876
cmpxchg_64.h 5.16 KB