[PATCH 2/2] powerpc/vdso: Implement __arch_get_vdso_rng_data()

Christophe Leroy christophe.leroy at csgroup.eu
Sat Oct 12 20:19:32 AEDT 2024



Le 11/10/2024 à 13:46, Michael Ellerman a écrit :
> Christophe Leroy <christophe.leroy at csgroup.eu> writes:
>> Le 10/10/2024 à 11:12, Thomas Weißschuh a écrit :
>>>
>>> I'll try to see why this doesn't work for ppc32.
>>
>> PC-rel instructions only exist on very very recent powerpc CPUs (power10 ?)
>   
> Yeah power10 or later.
> 
>> On PPC64, ELF ABI v2 requires caller to put called function address in
>> r12 and it looks like GCC uses that:
>>
>> 0000000000000000 <__c_kernel_getrandom>:
>>      0:	3c 4c 00 00 	addis   r2,r12,0
>> 			2: R_PPC64_REL16_HA	.TOC.+0x2
>>      4:	38 42 00 00 	addi    r2,r2,0
>> 			6: R_PPC64_REL16_LO	.TOC.+0x6
>> ...
>>     64:	3d 22 00 00 	addis   r9,r2,0
>> 			66: R_PPC64_TOC16_HA	_vdso_datapage+0x100
>>     68:	89 29 00 00 	lbz     r9,0(r9)
>> 			6a: R_PPC64_TOC16_LO	_vdso_datapage+0x100
> 
> Setting up r12 is only required for calls to the global entry point
> (offset 0), local calls can be made to offset 8 and use/don't require
> r12 to be set. That's because local calls should already have the
> correct toc pointer in r2.
> 
> But that's not true in VDSO code. >
>> Which after final link results in:
>>
>> 0000000000001060 <__c_kernel_getrandom>:
>>       1060:	3c 4c 00 01 	addis   r2,r12,1
>>       1064:	38 42 8e a0 	addi    r2,r2,-29024
>> ...
>>       10c4:	3d 22 ff fc 	addis   r9,r2,-4
>>       10c8:	89 29 62 00 	lbz     r9,25088(r9)
> 
> The call to __c_kernel_getrandom skips over the r2 setup because it's a
> local call, even though we haven't setup r2 correctly:

Yes indeed I forgot that. So even if the final check doesn't complain, 
it won't work at the end.

Don't know if we could find a way to detect that and fail the build.

> 
> 0000000000000758 <__kernel_getrandom>:
>       758:       91 ff 21 f8     stdu    r1,-112(r1)
>       75c:       a6 02 08 7c     mflr    r0
>       760:       91 ff 21 f8     stdu    r1,-112(r1)
>       764:       80 00 01 f8     std     r0,128(r1)
>       768:       88 00 41 f8     std     r2,136(r1)
>       76c:       05 00 9f 42     bcl     20,4*cr7+so,770 <__kernel_getrandom+0x18>
>       770:       a6 02 08 7d     mflr    r8
>       774:       fe ff 08 3d     addis   r8,r8,-2
>       778:       90 f8 08 39     addi    r8,r8,-1904
>       77c:       fc 00 68 81     lwz     r11,252(r8)
>       780:       ff 7f 6b 6d     xoris   r11,r11,32767
>       784:       ff ff 6b 69     xori    r11,r11,65535
>       788:       34 00 6b 7d     cntlzw  r11,r11
>       78c:       de 5b 6b 55     rlwinm  r11,r11,11,15,15
>       790:       14 5a 08 7d     add     r8,r8,r11
>       794:       d8 02 08 39     addi    r8,r8,728
>       798:       41 09 00 48     bl      10d8 <__c_kernel_getrandom+0x8>
> 
> We could setup r2, but that would only help 64-bit.
> 
> This also makes me notice that we have a mixture of ELF ABI v1 and v2
> code in the VDSO, depending on whether the kernel is building itself ABI
> v1 or v2:
> 
>    arch/powerpc/kernel/vdso/cacheflush-64.o:        ELF 64-bit LSB relocatable, 64-bit PowerPC or cisco 7500, Unspecified or Power ELF V1 ABI, version 1 (SYSV), not stripped
>    arch/powerpc/kernel/vdso/datapage-64.o:          ELF 64-bit LSB relocatable, 64-bit PowerPC or cisco 7500, Unspecified or Power ELF V1 ABI, version 1 (SYSV), not stripped
>    arch/powerpc/kernel/vdso/getcpu-64.o:            ELF 64-bit LSB relocatable, 64-bit PowerPC or cisco 7500, Unspecified or Power ELF V1 ABI, version 1 (SYSV), not stripped
>    arch/powerpc/kernel/vdso/getrandom-64.o:         ELF 64-bit LSB relocatable, 64-bit PowerPC or cisco 7500, Unspecified or Power ELF V1 ABI, version 1 (SYSV), not stripped
>    arch/powerpc/kernel/vdso/gettimeofday-64.o:      ELF 64-bit LSB relocatable, 64-bit PowerPC or cisco 7500, Unspecified or Power ELF V1 ABI, version 1 (SYSV), not stripped
>    arch/powerpc/kernel/vdso/note-64.o:              ELF 64-bit LSB relocatable, 64-bit PowerPC or cisco 7500, Unspecified or Power ELF V1 ABI, version 1 (SYSV), not stripped
>    arch/powerpc/kernel/vdso/sigtramp64-64.o:        ELF 64-bit LSB relocatable, 64-bit PowerPC or cisco 7500, Unspecified or Power ELF V1 ABI, version 1 (SYSV), not stripped
>    arch/powerpc/kernel/vdso/vgetrandom-64.o:        ELF 64-bit LSB relocatable, 64-bit PowerPC or cisco 7500, OpenPOWER ELF V2 ABI, version 1 (SYSV), not stripped
>    arch/powerpc/kernel/vdso/vgetrandom-chacha-64.o: ELF 64-bit LSB relocatable, 64-bit PowerPC or cisco 7500, Unspecified or Power ELF V1 ABI, version 1 (SYSV), not stripped
>    arch/powerpc/kernel/vdso/vgettimeofday-64.o:     ELF 64-bit LSB relocatable, 64-bit PowerPC or cisco 7500, OpenPOWER ELF V2 ABI, version 1 (SYSV), not stripped
> 
> All the asm files are ABI v1 because they historically were, and don't
> say otherwise. The C code comes out as ABI v1 or v2 depending on what
> we're building the kernel as. Which is a bit fishy.

That's not related to VDSO it seems. There is the same thing in 
arch/powerpc/lib for instance:

$ file arch/powerpc/lib/*.o
arch/powerpc/lib/checksum_64.o:         ELF 64-bit MSB relocatable, 
64-bit PowerPC or cisco 7500, Unspecified or Power ELF V1 ABI, version 1 
(SYSV), not stripped
arch/powerpc/lib/checksum_wrappers.o:   ELF 64-bit MSB relocatable, 
64-bit PowerPC or cisco 7500, OpenPOWER ELF V2 ABI, version 1 (SYSV), 
not stripped
arch/powerpc/lib/code-patching.o:       ELF 64-bit MSB relocatable, 
64-bit PowerPC or cisco 7500, OpenPOWER ELF V2 ABI, version 1 (SYSV), 
not stripped
arch/powerpc/lib/copy_mc_64.o:          ELF 64-bit MSB relocatable, 
64-bit PowerPC or cisco 7500, Unspecified or Power ELF V1 ABI, version 1 
(SYSV), not stripped
arch/powerpc/lib/copypage_64.o:         ELF 64-bit MSB relocatable, 
64-bit PowerPC or cisco 7500, OpenPOWER ELF V2 ABI, version 1 (SYSV), 
not stripped
...

Seems like all .c files result in a ELF V2 while some of .S files are V1 
et some are V2. That's odd because the build arguments seems to be the same:

# AS      arch/powerpc/lib/checksum_64.o
   powerpc64-linux-gcc -Wp,-MMD,arch/powerpc/lib/.checksum_64.o.d 
-nostdinc -I./arch/powerpc/include -I./arch/powerpc/include/generated 
-I./include -I./arch/powerpc/include/uapi 
-I./arch/powerpc/include/generated/uapi -I./include/uapi 
-I./include/generated/uapi -include ./include/linux/compiler-version.h 
-include ./include/linux/kconfig.h -D__KERNEL__ -I ./arch/powerpc 
-DHAVE_AS_ATHIGH=1 -D__ASSEMBLY__ -fno-PIE -m64 -mcpu=power8 -mabi=elfv2 
-mlittle-endian -Wa,--fatal-warnings 
-DKBUILD_MODFILE='"arch/powerpc/lib/checksum_64"' 
-DKBUILD_MODNAME='"checksum_64"' -D__KBUILD_MODNAME=kmod_checksum_64 -c 
-o arch/powerpc/lib/checksum_64.o arch/powerpc/lib/checksum_64.S  ; 
./tools/objtool/objtool --mcount   arch/powerpc/lib/checksum_64.o

# AS      arch/powerpc/lib/copypage_64.o
   powerpc64-linux-gcc -Wp,-MMD,arch/powerpc/lib/.copypage_64.o.d 
-nostdinc -I./arch/powerpc/include -I./arch/powerpc/include/generated 
-I./include -I./arch/powerpc/include/uapi 
-I./arch/powerpc/include/generated/uapi -I./include/uapi 
-I./include/generated/uapi -include ./include/linux/compiler-version.h 
-include ./include/linux/kconfig.h -D__KERNEL__ -I ./arch/powerpc 
-DHAVE_AS_ATHIGH=1 -D__ASSEMBLY__ -fno-PIE -m64 -mcpu=power8 -mabi=elfv2 
-mlittle-endian -Wa,--fatal-warnings 
-DKBUILD_MODFILE='"arch/powerpc/lib/copypage_64"' 
-DKBUILD_MODNAME='"copypage_64"' -D__KBUILD_MODNAME=kmod_copypage_64 -c 
-o arch/powerpc/lib/copypage_64.o arch/powerpc/lib/copypage_64.S  ; 
./tools/objtool/objtool --mcount   arch/powerpc/lib/copypage_64.o



More information about the Linuxppc-dev mailing list