• Christophe Leroy's avatar
    powerpc/uaccess: Fix __get_user() with CONFIG_CC_HAS_ASM_GOTO_OUTPUT · 7315e457
    Christophe Leroy authored
    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: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/cf0a050d124d4f426cdc7a74009d17b01d8d8969.1620465917.git.christophe.leroy@csgroup.eu
    7315e457
uaccess.h 13.6 KB