powerpc/uaccess: Fix __get_user() with CONFIG_CC_HAS_ASM_GOTO_OUTPUT
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Sat, 8 May 2021 09:25:32 +0000 (09:25 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 12 May 2021 01:07:39 +0000 (11:07 +1000)
commit7315e457d6bc342d06ba0b7ee498221c5237a547
treef1b9d1d3f0ccfbd0f03f78e55a14a604053961a6
parent4f242fc5f2e24412b89e934dad025b10293b2712
powerpc/uaccess: Fix __get_user() with CONFIG_CC_HAS_ASM_GOTO_OUTPUT

Building kernel mainline with GCC 11 leads to following failure
when starting 'init':

  init[1]: bad frame in sys_sigreturn: 7ff5a900 nip 001083cc lr 001083c4
  Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

This is an issue due to a segfault happening in
__unsafe_restore_general_regs() in a loop copying registers from user
to kernel:

  10: 7d 09 03 a6  mtctr   r8
  14: 80 ca 00 00  lwz     r6,0(r10)
  18: 80 ea 00 04  lwz     r7,4(r10)
  1c: 90 c9 00 08  stw     r6,8(r9)
  20: 90 e9 00 0c  stw     r7,12(r9)
  24: 39 0a 00 08  addi    r8,r10,8
  28: 39 29 00 08  addi    r9,r9,8
  2c: 81 4a 00 08  lwz     r10,8(r10)  <== r10 is clobbered here
  30: 81 6a 00 0c  lwz     r11,12(r10)
  34: 91 49 00 08  stw     r10,8(r9)
  38: 91 69 00 0c  stw     r11,12(r9)
  3c: 39 48 00 08  addi    r10,r8,8
  40: 39 29 00 08  addi    r9,r9,8
  44: 42 00 ff d0  bdnz    14 <__unsafe_restore_general_regs+0x14>

As shown above, this is due to r10 being re-used by GCC. This didn't
happen with CLANG.

This is fixed by tagging 'x' output as an earlyclobber operand in
__get_user_asm2_goto().

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/cf0a050d124d4f426cdc7a74009d17b01d8d8969.1620465917.git.christophe.leroy@csgroup.eu
arch/powerpc/include/asm/uaccess.h