Skip to content

Commit

Permalink
powerpc/vdso: Implement __arch_get_vdso_rng_data()
Browse files Browse the repository at this point in the history
VDSO time functions do not call any other function, so they don't
need to save/restore LR. However, retrieving the address of VDSO data
page requires using LR hence saving then restoring it, which can be
heavy on some CPUs. On the other hand, VDSO functions on powerpc are
not standard functions and require a wrapper function to call C VDSO
functions. And that wrapper has to save and restore LR in order to
call the C VDSO function, so retrieving VDSO data page address in that
wrapper doesn't require additional save/restore of LR.

For random VDSO functions it is a bit different. Because the function
calls __arch_chacha20_blocks_nostack(), it saves and restores LR.
Retrieving VDSO data page address can then be done there without
additional save/restore of LR.

So lets implement __arch_get_vdso_rng_data() and simplify the wrapper.

It starts paving the way for the day powerpc will implement a more
standard ABI for VDSO functions.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://patch.msgid.link/a1a9bd0df508f1b5c04684b7366940577dfc6262.1727858295.git.christophe.leroy@csgroup.eu
  • Loading branch information
Christophe Leroy authored and Michael Ellerman committed Oct 16, 2024
1 parent c39b1dc commit 4e3fa1a
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 6 deletions.
16 changes: 14 additions & 2 deletions arch/powerpc/include/asm/vdso/getrandom.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#ifndef __ASSEMBLY__

#include <asm/vdso_datapage.h>

static __always_inline int do_syscall_3(const unsigned long _r0, const unsigned long _r3,
const unsigned long _r4, const unsigned long _r5)
{
Expand Down Expand Up @@ -43,11 +45,21 @@ static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsig

static __always_inline struct vdso_rng_data *__arch_get_vdso_rng_data(void)
{
return NULL;
struct vdso_arch_data *data;

asm (
" bcl 20, 31, .+4 ;"
"0: mflr %0 ;"
" addis %0, %0, (_vdso_datapage - 0b)@ha ;"
" addi %0, %0, (_vdso_datapage - 0b)@l ;"
: "=r" (data) : : "lr"
);

return &data->rng_data;
}

ssize_t __c_kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state,
size_t opaque_len, const struct vdso_rng_data *vd);
size_t opaque_len);

#endif /* !__ASSEMBLY__ */

Expand Down
1 change: 0 additions & 1 deletion arch/powerpc/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ int main(void)

/* datapage offsets for use by vdso */
OFFSET(VDSO_DATA_OFFSET, vdso_arch_data, data);
OFFSET(VDSO_RNG_DATA_OFFSET, vdso_arch_data, rng_data);
OFFSET(CFG_TB_TICKS_PER_SEC, vdso_arch_data, tb_ticks_per_sec);
#ifdef CONFIG_PPC64
OFFSET(CFG_ICACHE_BLOCKSZ, vdso_arch_data, icache_block_size);
Expand Down
1 change: 0 additions & 1 deletion arch/powerpc/kernel/vdso/getrandom.S
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1)
.cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
#endif
get_datapage r8 VDSO_RNG_DATA_OFFSET
bl CFUNC(DOTSYM(\funct))
PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
#ifdef __powerpc64__
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/kernel/vdso/vgetrandom.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <linux/types.h>

ssize_t __c_kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state,
size_t opaque_len, const struct vdso_rng_data *vd)
size_t opaque_len)
{
return __cvdso_getrandom_data(vd, buffer, len, flags, opaque_state, opaque_len);
return __cvdso_getrandom(buffer, len, flags, opaque_state, opaque_len);
}

0 comments on commit 4e3fa1a

Please sign in to comment.