Skip to content

Commit 1d2ad08

Browse files
author
Vasily Gorbik
committed
s390/nospec: add an option to use thunk-extern
Currently with -mindirect-branch=thunk and -mfunction-return=thunk compiler options expoline thunks are put into individual COMDAT group sections. s390 is the only architecture which has group sections and it has implications for kpatch and objtool tools support. Using -mindirect-branch=thunk-extern and -mfunction-return=thunk-extern is an alternative, which comes with a need to generate all required expoline thunks manually. Unfortunately modules area is too far away from the kernel image, and expolines from the kernel image cannon be used. But since all new distributions (except Debian) build kernels for machine generations newer than z10, where "exrl" instruction is available, that leaves only 16 expolines thunks possible. Provide an option to build the kernel with -mindirect-branch=thunk-extern and -mfunction-return=thunk-extern for z10 or newer. This also requires to postlink expoline thunks into all modules explicitly. Currently modules already contain most expolines anyhow. Unfortunately -mindirect-branch=thunk-extern and -mfunction-return=thunk-extern options support is broken in gcc <= 11.2. Additional compile test is required to verify proper gcc support. Acked-by: Ilya Leoshkevich <iii@linux.ibm.com> Co-developed-by: Sumanth Korikkar <sumanthk@linux.ibm.com> Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
1 parent eed38cd commit 1d2ad08

7 files changed

Lines changed: 76 additions & 5 deletions

File tree

arch/s390/Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ config KERNEL_NOBP
585585

586586
config EXPOLINE
587587
def_bool n
588+
depends on $(cc-option,-mindirect-branch=thunk)
588589
prompt "Avoid speculative indirect branches in the kernel"
589590
help
590591
Compile the kernel with the expoline compiler options to guard
@@ -595,6 +596,20 @@ config EXPOLINE
595596

596597
If unsure, say N.
597598

599+
config EXPOLINE_EXTERN
600+
def_bool n
601+
depends on EXPOLINE
602+
depends on HAVE_MARCH_Z10_FEATURES
603+
depends on CC_IS_GCC && GCC_VERSION >= 110200
604+
depends on $(success,$(srctree)/arch/s390/tools/gcc-thunk-extern.sh $(CC))
605+
prompt "Generate expolines as extern functions."
606+
help
607+
This option is required for some tooling like kpatch. The kernel is
608+
compiled with -mindirect-branch=thunk-extern and requires a newer
609+
compiler.
610+
611+
If unsure, say N.
612+
598613
choice
599614
prompt "Expoline default"
600615
depends on EXPOLINE

arch/s390/Makefile

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,18 @@ ifneq ($(call cc-option,-mstack-size=8192 -mstack-guard=128),)
8181
endif
8282

8383
ifdef CONFIG_EXPOLINE
84-
ifneq ($(call cc-option,$(CC_FLAGS_MARCH) -mindirect-branch=thunk),)
84+
ifdef CONFIG_EXPOLINE_EXTERN
85+
KBUILD_LDFLAGS_MODULE += arch/s390/lib/expoline.o
86+
CC_FLAGS_EXPOLINE := -mindirect-branch=thunk-extern
87+
CC_FLAGS_EXPOLINE += -mfunction-return=thunk-extern
88+
else
8589
CC_FLAGS_EXPOLINE := -mindirect-branch=thunk
8690
CC_FLAGS_EXPOLINE += -mfunction-return=thunk
87-
CC_FLAGS_EXPOLINE += -mindirect-branch-table
88-
export CC_FLAGS_EXPOLINE
89-
cflags-y += $(CC_FLAGS_EXPOLINE) -DCC_USING_EXPOLINE
90-
aflags-y += -DCC_USING_EXPOLINE
9191
endif
92+
CC_FLAGS_EXPOLINE += -mindirect-branch-table
93+
export CC_FLAGS_EXPOLINE
94+
cflags-y += $(CC_FLAGS_EXPOLINE) -DCC_USING_EXPOLINE
95+
aflags-y += -DCC_USING_EXPOLINE
9296
endif
9397

9498
ifdef CONFIG_FUNCTION_TRACER

arch/s390/include/asm/nospec-insn.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ _LC_BR_R1 = __LC_BR_R1
1818
* the various thunks are merged into a single copy.
1919
*/
2020
.macro __THUNK_PROLOG_NAME name
21+
#ifdef CONFIG_EXPOLINE_EXTERN
22+
.pushsection .text,"ax",@progbits
23+
#else
2124
.pushsection .text.\name,"axG",@progbits,\name,comdat
25+
#endif
2226
.globl \name
2327
.hidden \name
2428
.type \name,@function
@@ -115,7 +119,13 @@ _LC_BR_R1 = __LC_BR_R1
115119
555: br \reg
116120
.endm
117121

122+
#ifdef CONFIG_EXPOLINE_EXTERN
123+
.macro GEN_BR_THUNK reg,ruse=%r1
124+
.endm
125+
.macro GEN_BR_THUNK_EXTERN reg,ruse=%r1
126+
#else
118127
.macro GEN_BR_THUNK reg,ruse=%r1
128+
#endif
119129
__DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse
120130
__THUNK_EX_BR \reg,\ruse
121131
__THUNK_EPILOG

arch/s390/lib/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ lib-y += delay.o string.o uaccess.o find.o spinlock.o
77
obj-y += mem.o xor.o
88
lib-$(CONFIG_KPROBES) += probes.o
99
lib-$(CONFIG_UPROBES) += probes.o
10+
obj-$(CONFIG_EXPOLINE_EXTERN) += expoline.o
1011
obj-$(CONFIG_S390_KPROBES_SANITY_TEST) += test_kprobes_s390.o
1112
test_kprobes_s390-objs += test_kprobes_asm.o test_kprobes.o
1213

arch/s390/lib/expoline.S

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
3+
#include <asm/nospec-insn.h>
4+
#include <linux/linkage.h>
5+
6+
.macro GEN_ALL_BR_THUNK_EXTERN
7+
.irp r1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
8+
GEN_BR_THUNK_EXTERN %r\r1
9+
.endr
10+
.endm
11+
12+
GEN_ALL_BR_THUNK_EXTERN
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/sh
2+
# SPDX-License-Identifier: GPL-2.0
3+
# Borrowed from gcc: gcc/testsuite/gcc.target/s390/nobp-section-type-conflict.c
4+
# Checks that we don't get error: section type conflict with ‘put_page’.
5+
6+
cat << "END" | $@ -x c - -fno-PIE -march=z10 -mindirect-branch=thunk-extern -mfunction-return=thunk-extern -mindirect-branch-table -O2 -c -o /dev/null
7+
int a;
8+
int b (void);
9+
void c (int);
10+
11+
static void
12+
put_page (void)
13+
{
14+
if (b ())
15+
c (a);
16+
}
17+
18+
__attribute__ ((__section__ (".init.text"), __cold__)) void
19+
d (void)
20+
{
21+
put_page ();
22+
put_page ();
23+
}
24+
END

scripts/mod/modpost.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,11 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname)
658658
strstarts(symname, "_savevr_") ||
659659
strcmp(symname, ".TOC.") == 0)
660660
return 1;
661+
662+
if (info->hdr->e_machine == EM_S390)
663+
/* Expoline thunks are linked on all kernel modules during final link of .ko */
664+
if (strstarts(symname, "__s390_indirect_jump_r"))
665+
return 1;
661666
/* Do not ignore this symbol */
662667
return 0;
663668
}

0 commit comments

Comments
 (0)