Skip to content

Commit 8d485b4

Browse files
author
Fox Snowpatch
committed
1 parent ddf9a4c commit 8d485b4

35 files changed

+628
-76
lines changed

arch/powerpc/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ config PPC
311311
select SYSCTL_EXCEPTION_TRACE
312312
select THREAD_INFO_IN_TASK
313313
select TRACE_IRQFLAGS_SUPPORT
314+
select VDSO_GETRANDOM
314315
#
315316
# Please keep this list sorted alphabetically.
316317
#

arch/powerpc/include/asm/asm-compat.h

+8
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,12 @@
6161

6262
#endif
6363

64+
#ifdef __BIG_ENDIAN__
65+
#define LWZX_LE stringify_in_c(lwbrx)
66+
#define STWX_LE stringify_in_c(stwbrx)
67+
#else
68+
#define LWZX_LE stringify_in_c(lwzx)
69+
#define STWX_LE stringify_in_c(stwx)
70+
#endif
71+
6472
#endif /* _ASM_POWERPC_ASM_COMPAT_H */

arch/powerpc/include/asm/mman.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include <uapi/asm/mman.h>
88

9-
#ifdef CONFIG_PPC64
9+
#if defined(CONFIG_PPC64) && !defined(BUILD_VDSO)
1010

1111
#include <asm/cputable.h>
1212
#include <linux/mm.h>
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Copyright (C) 2024 Christophe Leroy <[email protected]>, CS GROUP France
4+
*/
5+
#ifndef _ASM_POWERPC_VDSO_GETRANDOM_H
6+
#define _ASM_POWERPC_VDSO_GETRANDOM_H
7+
8+
#ifndef __ASSEMBLY__
9+
10+
static __always_inline int do_syscall_3(const unsigned long _r0, const unsigned long _r3,
11+
const unsigned long _r4, const unsigned long _r5)
12+
{
13+
register long r0 asm("r0") = _r0;
14+
register unsigned long r3 asm("r3") = _r3;
15+
register unsigned long r4 asm("r4") = _r4;
16+
register unsigned long r5 asm("r5") = _r5;
17+
register int ret asm ("r3");
18+
19+
asm volatile(
20+
" sc\n"
21+
" bns+ 1f\n"
22+
" neg %0, %0\n"
23+
"1:\n"
24+
: "=r" (ret), "+r" (r4), "+r" (r5), "+r" (r0)
25+
: "r" (r3)
26+
: "memory", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cr0", "ctr");
27+
28+
return ret;
29+
}
30+
31+
/**
32+
* getrandom_syscall - Invoke the getrandom() syscall.
33+
* @buffer: Destination buffer to fill with random bytes.
34+
* @len: Size of @buffer in bytes.
35+
* @flags: Zero or more GRND_* flags.
36+
* Returns: The number of bytes written to @buffer, or a negative value indicating an error.
37+
*/
38+
static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsigned int flags)
39+
{
40+
return do_syscall_3(__NR_getrandom, (unsigned long)buffer,
41+
(unsigned long)len, (unsigned long)flags);
42+
}
43+
44+
static __always_inline struct vdso_rng_data *__arch_get_vdso_rng_data(void)
45+
{
46+
BUILD_BUG();
47+
}
48+
49+
ssize_t __c_kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state,
50+
size_t opaque_len, const struct vdso_rng_data *vd);
51+
52+
/**
53+
* __arch_chacha20_blocks_nostack - Generate ChaCha20 stream without using the stack.
54+
* @dst_bytes: Destination buffer to hold @nblocks * 64 bytes of output.
55+
* @key: 32-byte input key.
56+
* @counter: 8-byte counter, read on input and updated on return.
57+
* @nblocks: Number of blocks to generate.
58+
*
59+
* Generates a given positive number of blocks of ChaCha20 output with nonce=0, and does not write
60+
* to any stack or memory outside of the parameters passed to it, in order to mitigate stack data
61+
* leaking into forked child processes.
62+
*/
63+
void __arch_chacha20_blocks_nostack(u8 *dst_bytes, const u32 *key, u32 *counter, size_t nblocks);
64+
65+
#endif /* !__ASSEMBLY__ */
66+
67+
#endif /* _ASM_POWERPC_VDSO_GETRANDOM_H */

arch/powerpc/include/asm/vdso/vsyscall.h

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ struct vdso_data *__arch_get_k_vdso_data(void)
1717
}
1818
#define __arch_get_k_vdso_data __arch_get_k_vdso_data
1919

20+
static __always_inline
21+
struct vdso_rng_data *__arch_get_k_vdso_rng_data(void)
22+
{
23+
return &vdso_data->rng_data;
24+
}
25+
2026
/* The asm-generic header needs to be included after the definitions above */
2127
#include <asm-generic/vdso/vsyscall.h>
2228

arch/powerpc/include/asm/vdso_datapage.h

+2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ struct vdso_arch_data {
8383
__u32 compat_syscall_map[SYSCALL_MAP_SIZE]; /* Map of compat syscalls */
8484

8585
struct vdso_data data[CS_BASES];
86+
struct vdso_rng_data rng_data;
8687
};
8788

8889
#else /* CONFIG_PPC64 */
@@ -95,6 +96,7 @@ struct vdso_arch_data {
9596
__u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */
9697
__u32 compat_syscall_map[0]; /* No compat syscalls on PPC32 */
9798
struct vdso_data data[CS_BASES];
99+
struct vdso_rng_data rng_data;
98100
};
99101

100102
#endif /* CONFIG_PPC64 */

arch/powerpc/kernel/asm-offsets.c

+1
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ int main(void)
335335

336336
/* datapage offsets for use by vdso */
337337
OFFSET(VDSO_DATA_OFFSET, vdso_arch_data, data);
338+
OFFSET(VDSO_RNG_DATA_OFFSET, vdso_arch_data, rng_data);
338339
OFFSET(CFG_TB_TICKS_PER_SEC, vdso_arch_data, tb_ticks_per_sec);
339340
#ifdef CONFIG_PPC64
340341
OFFSET(CFG_ICACHE_BLOCKSZ, vdso_arch_data, icache_block_size);

arch/powerpc/kernel/vdso/Makefile

+30-15
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,35 @@ include $(srctree)/lib/vdso/Makefile
88
obj-vdso32 = sigtramp32-32.o gettimeofday-32.o datapage-32.o cacheflush-32.o note-32.o getcpu-32.o
99
obj-vdso64 = sigtramp64-64.o gettimeofday-64.o datapage-64.o cacheflush-64.o note-64.o getcpu-64.o
1010

11+
obj-vdso32 += getrandom-32.o vgetrandom-chacha-32.o
12+
obj-vdso64 += getrandom-64.o vgetrandom-chacha-64.o
13+
1114
ifneq ($(c-gettimeofday-y),)
1215
CFLAGS_vgettimeofday-32.o += -include $(c-gettimeofday-y)
13-
CFLAGS_vgettimeofday-32.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
14-
CFLAGS_vgettimeofday-32.o += $(call cc-option, -fno-stack-protector)
15-
CFLAGS_vgettimeofday-32.o += -DDISABLE_BRANCH_PROFILING
16-
CFLAGS_vgettimeofday-32.o += -ffreestanding -fasynchronous-unwind-tables
17-
CFLAGS_REMOVE_vgettimeofday-32.o = $(CC_FLAGS_FTRACE)
1816
CFLAGS_REMOVE_vgettimeofday-32.o += -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc
1917
# This flag is supported by clang for 64-bit but not 32-bit so it will cause
2018
# an unused command line flag warning for this file.
2119
ifdef CONFIG_CC_IS_CLANG
2220
CFLAGS_REMOVE_vgettimeofday-32.o += -fno-stack-clash-protection
2321
endif
2422
CFLAGS_vgettimeofday-64.o += -include $(c-gettimeofday-y)
25-
CFLAGS_vgettimeofday-64.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
26-
CFLAGS_vgettimeofday-64.o += $(call cc-option, -fno-stack-protector)
27-
CFLAGS_vgettimeofday-64.o += -DDISABLE_BRANCH_PROFILING
28-
CFLAGS_vgettimeofday-64.o += -ffreestanding -fasynchronous-unwind-tables
29-
CFLAGS_REMOVE_vgettimeofday-64.o = $(CC_FLAGS_FTRACE)
3023
# Go prior to 1.16.x assumes r30 is not clobbered by any VDSO code. That used to be true
3124
# by accident when the VDSO was hand-written asm code, but may not be now that the VDSO is
3225
# compiler generated. To avoid breaking Go tell GCC not to use r30. Impact on code
3326
# generation is minimal, it will just use r29 instead.
3427
CFLAGS_vgettimeofday-64.o += $(call cc-option, -ffixed-r30)
3528
endif
3629

30+
ifneq ($(c-getrandom-y),)
31+
CFLAGS_vgetrandom-32.o += -include $(c-getrandom-y)
32+
CFLAGS_REMOVE_vgetrandom-32.o += -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc
33+
ifdef CONFIG_CC_IS_CLANG
34+
CFLAGS_REMOVE_vgetrandom-32.o += -fno-stack-clash-protection
35+
endif
36+
CFLAGS_vgetrandom-64.o += -include $(c-getrandom-y)
37+
CFLAGS_vgetrandom-64.o += $(call cc-option, -ffixed-r30)
38+
endif
39+
3740
# Build rules
3841

3942
ifdef CROSS32_COMPILE
@@ -42,13 +45,19 @@ else
4245
VDSOCC := $(CC)
4346
endif
4447

45-
targets := $(obj-vdso32) vdso32.so.dbg vgettimeofday-32.o
48+
targets := $(obj-vdso32) vdso32.so.dbg vgettimeofday-32.o vgetrandom-32.o
49+
targets += crtsavres-32.o
4650
obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
47-
targets += $(obj-vdso64) vdso64.so.dbg vgettimeofday-64.o
51+
targets += $(obj-vdso64) vdso64.so.dbg vgettimeofday-64.o vgetrandom-64.o
4852
obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
4953

50-
ccflags-y := -fno-common -fno-builtin
54+
ccflags-y := -fno-common -fno-builtin -DBUILD_VDSO
55+
ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
56+
ccflags-y += $(call cc-option, -fno-stack-protector)
57+
ccflags-y += -DDISABLE_BRANCH_PROFILING
58+
ccflags-y += -ffreestanding -fasynchronous-unwind-tables
5159
ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
60+
ccflags-remove-y := $(CC_FLAGS_FTRACE)
5261
ldflags-$(CONFIG_LD_IS_LLD) += $(call cc-option,--ld-path=$(LD),-fuse-ld=lld)
5362
ldflags-$(CONFIG_LD_ORPHAN_WARN) += -Wl,--orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
5463

@@ -68,20 +77,26 @@ targets += vdso64.lds
6877
CPPFLAGS_vdso64.lds += -P -C
6978

7079
# link rule for the .so file, .lds has to be first
71-
$(obj)/vdso32.so.dbg: $(obj)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday-32.o FORCE
80+
$(obj)/vdso32.so.dbg: $(obj)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday-32.o $(obj)/vgetrandom-32.o $(obj)/crtsavres-32.o FORCE
7281
$(call if_changed,vdso32ld_and_check)
73-
$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday-64.o FORCE
82+
$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday-64.o $(obj)/vgetrandom-64.o FORCE
7483
$(call if_changed,vdso64ld_and_check)
7584

7685
# assembly rules for the .S files
7786
$(obj-vdso32): %-32.o: %.S FORCE
7887
$(call if_changed_dep,vdso32as)
88+
$(obj)/crtsavres-32.o: %-32.o: $(srctree)/arch/powerpc/lib/crtsavres.S FORCE
89+
$(call if_changed_dep,vdso32as)
7990
$(obj)/vgettimeofday-32.o: %-32.o: %.c FORCE
8091
$(call if_changed_dep,vdso32cc)
92+
$(obj)/vgetrandom-32.o: %-32.o: %.c FORCE
93+
$(call if_changed_dep,vdso32cc)
8194
$(obj-vdso64): %-64.o: %.S FORCE
8295
$(call if_changed_dep,vdso64as)
8396
$(obj)/vgettimeofday-64.o: %-64.o: %.c FORCE
8497
$(call if_changed_dep,cc_o_c)
98+
$(obj)/vgetrandom-64.o: %-64.o: %.c FORCE
99+
$(call if_changed_dep,cc_o_c)
85100

86101
# Generate VDSO offsets using helper script
87102
gen-vdso32sym := $(src)/gen_vdso32_offsets.sh

arch/powerpc/kernel/vdso/getrandom.S

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
/*
3+
* Userland implementation of getrandom() for processes
4+
* for use in the vDSO
5+
*
6+
* Copyright (C) 2024 Christophe Leroy <[email protected]>, CS GROUP France
7+
*/
8+
#include <asm/processor.h>
9+
#include <asm/ppc_asm.h>
10+
#include <asm/vdso.h>
11+
#include <asm/vdso_datapage.h>
12+
#include <asm/asm-offsets.h>
13+
#include <asm/unistd.h>
14+
15+
/*
16+
* The macro sets two stack frames, one for the caller and one for the callee
17+
* because there are no requirement for the caller to set a stack frame when
18+
* calling VDSO so it may have omitted to set one, especially on PPC64
19+
*/
20+
21+
.macro cvdso_call funct
22+
.cfi_startproc
23+
PPC_STLU r1, -PPC_MIN_STKFRM(r1)
24+
.cfi_adjust_cfa_offset PPC_MIN_STKFRM
25+
mflr r0
26+
PPC_STLU r1, -PPC_MIN_STKFRM(r1)
27+
.cfi_adjust_cfa_offset PPC_MIN_STKFRM
28+
PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
29+
.cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF
30+
#ifdef __powerpc64__
31+
PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1)
32+
.cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
33+
#endif
34+
get_datapage r8
35+
addi r8, r8, VDSO_RNG_DATA_OFFSET
36+
bl CFUNC(DOTSYM(\funct))
37+
PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
38+
#ifdef __powerpc64__
39+
PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1)
40+
.cfi_restore r2
41+
#endif
42+
cmpwi r3, 0
43+
mtlr r0
44+
addi r1, r1, 2 * PPC_MIN_STKFRM
45+
.cfi_restore lr
46+
.cfi_def_cfa_offset 0
47+
crclr so
48+
bgelr+
49+
crset so
50+
neg r3, r3
51+
blr
52+
.cfi_endproc
53+
.endm
54+
55+
.text
56+
V_FUNCTION_BEGIN(__kernel_getrandom)
57+
cvdso_call __c_kernel_getrandom
58+
V_FUNCTION_END(__kernel_getrandom)

arch/powerpc/kernel/vdso/gettimeofday.S

-13
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,3 @@ V_FUNCTION_END(__kernel_clock_getres)
118118
V_FUNCTION_BEGIN(__kernel_time)
119119
cvdso_call __c_kernel_time call_time=1
120120
V_FUNCTION_END(__kernel_time)
121-
122-
/* Routines for restoring integer registers, called by the compiler. */
123-
/* Called with r11 pointing to the stack header word of the caller of the */
124-
/* function, just beyond the end of the integer restore area. */
125-
#ifndef __powerpc64__
126-
_GLOBAL(_restgpr_31_x)
127-
_GLOBAL(_rest32gpr_31_x)
128-
lwz r0,4(r11)
129-
lwz r31,-4(r11)
130-
mtlr r0
131-
mr r1,r11
132-
blr
133-
#endif

arch/powerpc/kernel/vdso/vdso32.lds.S

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ VERSION
128128
#if defined(CONFIG_PPC64) || !defined(CONFIG_SMP)
129129
__kernel_getcpu;
130130
#endif
131+
__kernel_getrandom;
131132

132133
local: *;
133134
};

arch/powerpc/kernel/vdso/vdso64.lds.S

+1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ VERSION
123123
__kernel_sigtramp_rt64;
124124
__kernel_getcpu;
125125
__kernel_time;
126+
__kernel_getrandom;
126127

127128
local: *;
128129
};

0 commit comments

Comments
 (0)