• Michael Ellerman's avatar
    powerpc/vdso: Fix DOTSYM for 32-bit LE VDSO · 2eda7f11
    Michael Ellerman authored
    Skirmisher reported on IRC that the 32-bit LE VDSO was hanging. This
    turned out to be due to a branch to self in eg. __kernel_gettimeofday.
    Looking at the disassembly with objdump -dR shows why:
    
      00000528 <__kernel_gettimeofday>:
       528:   f0 ff 21 94     stwu    r1,-16(r1)
       52c:   a6 02 08 7c     mflr    r0
       530:   f0 ff 21 94     stwu    r1,-16(r1)
       534:   14 00 01 90     stw     r0,20(r1)
       538:   05 00 9f 42     bcl     20,4*cr7+so,53c <__kernel_gettimeofday+0x14>
       53c:   a6 02 a8 7c     mflr    r5
       540:   ff ff a5 3c     addis   r5,r5,-1
       544:   c4 fa a5 38     addi    r5,r5,-1340
       548:   f0 00 a5 38     addi    r5,r5,240
       54c:   01 00 00 48     bl      54c <__kernel_gettimeofday+0x24>
                              54c: R_PPC_REL24        .__c_kernel_gettimeofday
    
    Because we don't process relocations for the VDSO, this branch remains
    a branch from 0x54c to 0x54c.
    
    With the preceding patch to prohibit R_PPC_REL24 relocations, we
    instead get a build failure:
    
      0000054c R_PPC_REL24       .__c_kernel_gettimeofday
      00000598 R_PPC_REL24       .__c_kernel_clock_gettime
      000005e4 R_PPC_REL24       .__c_kernel_clock_gettime64
      00000630 R_PPC_REL24       .__c_kernel_clock_getres
      0000067c R_PPC_REL24       .__c_kernel_time
      arch/powerpc/kernel/vdso32/vdso32.so.dbg: dynamic relocations are not supported
    
    The root cause is that we're branching to `.__c_kernel_gettimeofday`.
    But this is 32-bit LE code, which doesn't use function descriptors, so
    there are no dot symbols.
    
    The reason we're trying to branch to a dot symbol is because we're
    using the DOTSYM macro, but the ifdefs we use to define the DOTSYM
    macro do not currently work for 32-bit LE.
    
    So like previous commits we need to differentiate if the current
    compilation unit is 64-bit, rather than the kernel as a whole. ie.
    switch from CONFIG_PPC64 to __powerpc64__.
    
    With that fixed 32-bit LE code gets the empty version of DOTSYM, which
    just resolves to the original symbol name, leading to a direct branch
    and no relocations:
    
      000003f8 <__kernel_gettimeofday>:
       3f8:   f0 ff 21 94     stwu    r1,-16(r1)
       3fc:   a6 02 08 7c     mflr    r0
       400:   f0 ff 21 94     stwu    r1,-16(r1)
       404:   14 00 01 90     stw     r0,20(r1)
       408:   05 00 9f 42     bcl     20,4*cr7+so,40c <__kernel_gettimeofday+0x14>
       40c:   a6 02 a8 7c     mflr    r5
       410:   ff ff a5 3c     addis   r5,r5,-1
       414:   f4 fb a5 38     addi    r5,r5,-1036
       418:   f0 00 a5 38     addi    r5,r5,240
       41c:   85 06 00 48     bl      aa0 <__c_kernel_gettimeofday>
    
    Fixes: ab037dd8 ("powerpc/vdso: Switch VDSO to generic C implementation.")
    Reported-by: "Will Springer <skirmisher@protonmail.com>"
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20201218111619.1206391-3-mpe@ellerman.id.au
    2eda7f11
ppc_asm.h 21.5 KB