powerpc/bug: Provide better flexibility to WARN_ON/__WARN_FLAGS() with asm goto
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Tue, 13 Apr 2021 16:38:10 +0000 (16:38 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Sun, 15 Aug 2021 03:49:24 +0000 (13:49 +1000)
commit1e688dd2a3d6759d416616ff07afc4bb836c4213
tree6e83647210b1d93b60481522c12acc5e2e2d34c2
parentdb87a7199229b75c9996bf78117eceb81854fce2
powerpc/bug: Provide better flexibility to WARN_ON/__WARN_FLAGS() with asm goto

Using asm goto in __WARN_FLAGS() and WARN_ON() allows more
flexibility to GCC.

For that add an entry to the exception table so that
program_check_exception() knowns where to resume execution
after a WARNING.

Here are two exemples. The first one is done on PPC32 (which
benefits from the previous patch), the second is on PPC64.

unsigned long test(struct pt_regs *regs)
{
int ret;

WARN_ON(regs->msr & MSR_PR);

return regs->gpr[3];
}

unsigned long test9w(unsigned long a, unsigned long b)
{
if (WARN_ON(!b))
return 0;
return a / b;
}

Before the patch:

000003a8 <test>:
 3a8: 81 23 00 84  lwz     r9,132(r3)
 3ac: 71 29 40 00  andi.   r9,r9,16384
 3b0: 40 82 00 0c  bne     3bc <test+0x14>
 3b4: 80 63 00 0c  lwz     r3,12(r3)
 3b8: 4e 80 00 20  blr

 3bc: 0f e0 00 00  twui    r0,0
 3c0: 80 63 00 0c  lwz     r3,12(r3)
 3c4: 4e 80 00 20  blr

0000000000000bf0 <.test9w>:
 bf0: 7c 89 00 74  cntlzd  r9,r4
 bf4: 79 29 d1 82  rldicl  r9,r9,58,6
 bf8: 0b 09 00 00  tdnei   r9,0
 bfc: 2c 24 00 00  cmpdi   r4,0
 c00: 41 82 00 0c  beq     c0c <.test9w+0x1c>
 c04: 7c 63 23 92  divdu   r3,r3,r4
 c08: 4e 80 00 20  blr

 c0c: 38 60 00 00  li      r3,0
 c10: 4e 80 00 20  blr

After the patch:

000003a8 <test>:
 3a8: 81 23 00 84  lwz     r9,132(r3)
 3ac: 71 29 40 00  andi.   r9,r9,16384
 3b0: 40 82 00 0c  bne     3bc <test+0x14>
 3b4: 80 63 00 0c  lwz     r3,12(r3)
 3b8: 4e 80 00 20  blr

 3bc: 0f e0 00 00  twui    r0,0

0000000000000c50 <.test9w>:
 c50: 7c 89 00 74  cntlzd  r9,r4
 c54: 79 29 d1 82  rldicl  r9,r9,58,6
 c58: 0b 09 00 00  tdnei   r9,0
 c5c: 7c 63 23 92  divdu   r3,r3,r4
 c60: 4e 80 00 20  blr

 c70: 38 60 00 00  li      r3,0
 c74: 4e 80 00 20  blr

In the first exemple, we see GCC doesn't need to duplicate what
happens after the trap.

In the second exemple, we see that GCC doesn't need to emit a test
and a branch in the likely path in addition to the trap.

We've got some WARN_ON() in .softirqentry.text section so it needs
to be added in the OTHER_TEXT_SECTIONS in modpost.c

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/389962b1b702e3c78d169e59bcfac56282889173.1618331882.git.christophe.leroy@csgroup.eu
arch/powerpc/include/asm/book3s/64/kup.h
arch/powerpc/include/asm/bug.h
arch/powerpc/include/asm/extable.h
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/traps.c
scripts/mod/modpost.c
tools/testing/selftests/powerpc/primitives/asm/extable.h [new symlink]