forked from linuxppc/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
powerpc/vdso: Wire up getrandom() vDSO implementation on PPC32
To be consistent with other VDSO functions, the function is called __kernel_getrandom() __arch_chacha20_blocks_nostack() fonction is implemented basically with 32 bits operations. It performs 4 QUARTERROUND operations in parallele. There are enough registers to avoid using the stack: On input: r3: output bytes r4: 32-byte key input r5: 8-byte counter input/output r6: number of 64-byte blocks to write to output During operation: stack: pointer to counter (r5) and non-volatile registers (r14-131) r0: counter of blocks (initialised with r6) r4: Value '4' after key has been read, used for indexing r5-r12: key r14-r15: block counter r16-r31: chacha state At the end: r0, r6-r12: Zeroised r5, r14-r31: Restored Performance on powerpc 885 (using kernel selftest): ~# ./vdso_test_getrandom bench-single vdso: 25000000 times in 62.938002291 seconds libc: 25000000 times in 535.581916866 seconds syscall: 25000000 times in 531.525042806 seconds Performance on powerpc 8321 (using kernel selftest): ~# ./vdso_test_getrandom bench-single vdso: 25000000 times in 16.899318858 seconds libc: 25000000 times in 131.050596522 seconds syscall: 25000000 times in 129.794790389 seconds This first patch adds support for PPC32. As selftests cannot easily be generated only for PPC32, and because the following patch brings support for PPC64 anyway, this patch opts out all code in __arch_chacha20_blocks_nostack() so that vdso_test_chacha will not fail to compile and will not crash on PPC64/PPC64LE, allthough the selftest itself will fail. This patch also adds a dummy __kernel_getrandom() function that returns ENOSYS on PPC64 so that vdso_test_getrandom returns KSFT_SKIP instead of KSFT_FAIL. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- v5: - Add back vdso symlink that vanished in v4 after a rebase back and forth with rejected patch "selftests: vDSO: Do not rely on $ARCH for vdso_test_getrandom && vdso_test_chacha" - Set meaningfull names to registers and constants in chacha assembly - Add 32 bits LE logic in this patch as well allthought it is only usefull for ppc64le. - Remove the temporary ppc64 __kernel_getrandom added in v4, selftest will return KSFT_FAIL until following patch, not a big issue. - Move the -DBUILD_VDSO logic in patch 3 to allow build VDSO32 on ppc64. v4: - Counter has native byte order - Fix selftest build on ppc64le until implemented. - On ppc64, for now implement __kernel_getrandom to return ENOSYS error - Use stwbrx directly, not compat macro. v3: - Preserve r13, implies saving r5 on stack - Split PPC64 implementation out.
- Loading branch information
Showing
13 changed files
with
455 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Copyright (C) 2024 Christophe Leroy <christophe.leroy@csgroup.eu>, CS GROUP France | ||
*/ | ||
#ifndef _ASM_POWERPC_VDSO_GETRANDOM_H | ||
#define _ASM_POWERPC_VDSO_GETRANDOM_H | ||
|
||
#ifndef __ASSEMBLY__ | ||
|
||
static __always_inline int do_syscall_3(const unsigned long _r0, const unsigned long _r3, | ||
const unsigned long _r4, const unsigned long _r5) | ||
{ | ||
register long r0 asm("r0") = _r0; | ||
register unsigned long r3 asm("r3") = _r3; | ||
register unsigned long r4 asm("r4") = _r4; | ||
register unsigned long r5 asm("r5") = _r5; | ||
register int ret asm ("r3"); | ||
|
||
asm volatile( | ||
" sc\n" | ||
" bns+ 1f\n" | ||
" neg %0, %0\n" | ||
"1:\n" | ||
: "=r" (ret), "+r" (r4), "+r" (r5), "+r" (r0) | ||
: "r" (r3) | ||
: "memory", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cr0", "ctr"); | ||
|
||
return ret; | ||
} | ||
|
||
/** | ||
* getrandom_syscall - Invoke the getrandom() syscall. | ||
* @buffer: Destination buffer to fill with random bytes. | ||
* @len: Size of @buffer in bytes. | ||
* @flags: Zero or more GRND_* flags. | ||
* Returns: The number of bytes written to @buffer, or a negative value indicating an error. | ||
*/ | ||
static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsigned int flags) | ||
{ | ||
return do_syscall_3(__NR_getrandom, (unsigned long)buffer, | ||
(unsigned long)len, (unsigned long)flags); | ||
} | ||
|
||
static __always_inline struct vdso_rng_data *__arch_get_vdso_rng_data(void) | ||
{ | ||
return NULL; | ||
} | ||
|
||
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); | ||
|
||
#endif /* !__ASSEMBLY__ */ | ||
|
||
#endif /* _ASM_POWERPC_VDSO_GETRANDOM_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-or-later */ | ||
/* | ||
* Userland implementation of getrandom() for processes | ||
* for use in the vDSO | ||
* | ||
* Copyright (C) 2024 Christophe Leroy <christophe.leroy@csgroup.eu>, CS GROUP France | ||
*/ | ||
#include <asm/processor.h> | ||
#include <asm/ppc_asm.h> | ||
#include <asm/vdso.h> | ||
#include <asm/vdso_datapage.h> | ||
#include <asm/asm-offsets.h> | ||
#include <asm/unistd.h> | ||
|
||
/* | ||
* The macro sets two stack frames, one for the caller and one for the callee | ||
* because there are no requirement for the caller to set a stack frame when | ||
* calling VDSO so it may have omitted to set one, especially on PPC64 | ||
*/ | ||
|
||
.macro cvdso_call funct | ||
.cfi_startproc | ||
PPC_STLU r1, -PPC_MIN_STKFRM(r1) | ||
.cfi_adjust_cfa_offset PPC_MIN_STKFRM | ||
mflr r0 | ||
PPC_STLU r1, -PPC_MIN_STKFRM(r1) | ||
.cfi_adjust_cfa_offset PPC_MIN_STKFRM | ||
PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) | ||
.cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF | ||
get_datapage r8 | ||
addi r8, r8, VDSO_RNG_DATA_OFFSET | ||
bl CFUNC(DOTSYM(\funct)) | ||
PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) | ||
cmpwi r3, 0 | ||
mtlr r0 | ||
addi r1, r1, 2 * PPC_MIN_STKFRM | ||
.cfi_restore lr | ||
.cfi_def_cfa_offset 0 | ||
crclr so | ||
bgelr+ | ||
crset so | ||
neg r3, r3 | ||
blr | ||
.cfi_endproc | ||
.endm | ||
|
||
.text | ||
V_FUNCTION_BEGIN(__kernel_getrandom) | ||
cvdso_call __c_kernel_getrandom | ||
V_FUNCTION_END(__kernel_getrandom) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.