xref: /linux/arch/powerpc/include/asm/vdso/getrandom.h (revision 7f71507851fc7764b36a3221839607d3a45c2025)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2024 Christophe Leroy <christophe.leroy@csgroup.eu>, CS GROUP France
4  */
5 #ifndef _ASM_POWERPC_VDSO_GETRANDOM_H
6 #define _ASM_POWERPC_VDSO_GETRANDOM_H
7 
8 #ifndef __ASSEMBLY__
9 
10 #include <asm/vdso_datapage.h>
11 
12 static __always_inline int do_syscall_3(const unsigned long _r0, const unsigned long _r3,
13 					const unsigned long _r4, const unsigned long _r5)
14 {
15 	register long r0 asm("r0") = _r0;
16 	register unsigned long r3 asm("r3") = _r3;
17 	register unsigned long r4 asm("r4") = _r4;
18 	register unsigned long r5 asm("r5") = _r5;
19 	register int ret asm ("r3");
20 
21 	asm volatile(
22 		"       sc\n"
23 		"	bns+	1f\n"
24 		"	neg	%0, %0\n"
25 		"1:\n"
26 	: "=r" (ret), "+r" (r4), "+r" (r5), "+r" (r0)
27 	: "r" (r3)
28 	: "memory", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cr0", "ctr");
29 
30 	return ret;
31 }
32 
33 /**
34  * getrandom_syscall - Invoke the getrandom() syscall.
35  * @buffer:	Destination buffer to fill with random bytes.
36  * @len:	Size of @buffer in bytes.
37  * @flags:	Zero or more GRND_* flags.
38  * Returns:	The number of bytes written to @buffer, or a negative value indicating an error.
39  */
40 static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsigned int flags)
41 {
42 	return do_syscall_3(__NR_getrandom, (unsigned long)buffer,
43 			    (unsigned long)len, (unsigned long)flags);
44 }
45 
46 static __always_inline struct vdso_rng_data *__arch_get_vdso_rng_data(void)
47 {
48 	struct vdso_arch_data *data;
49 
50 	asm (
51 		"	bcl	20, 31, .+4 ;"
52 		"0:	mflr	%0 ;"
53 		"	addis	%0, %0, (_vdso_datapage - 0b)@ha ;"
54 		"	addi	%0, %0, (_vdso_datapage - 0b)@l  ;"
55 		: "=r" (data) : : "lr"
56 	);
57 
58 	return &data->rng_data;
59 }
60 
61 ssize_t __c_kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state,
62 			     size_t opaque_len);
63 
64 #endif /* !__ASSEMBLY__ */
65 
66 #endif /* _ASM_POWERPC_VDSO_GETRANDOM_H */
67