* [PATCH] s390: Use static call trampolines when kCFI is enabled
@ 2026-10-26 10:29 Heiko Carstens
0 siblings, 0 replies; only message in thread
From: Heiko Carstens @ 2026-10-26 10:29 UTC (permalink / raw)
To: Alexander Gordeev, Sven Schnelle, Vasily Gorbik, Christian Borntraeger
Cc: linux-kernel, linux-s390
Add support for the 'unoptimized' static call variety, which routes all
calls through a trampoline that performs a tail call to the chosen
function. Wire it up for use when kCFI is enabled to work around an
issue where the prototypes of default handlers such as
__static_call_nop() and __static_call_ret0() don't match the expected
prototype of the call site, resulting in kCFI false positives.
This is the s390 version of commit 54ac9ff8f119 ("arm64: Use static
call trampolines when kCFI is enabled").
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
---
arch/s390/Kconfig | 1 +
arch/s390/include/asm/static_call.h | 39 +++++++++++++++++++++++++++++
arch/s390/kernel/Makefile | 1 +
arch/s390/kernel/static_call.c | 20 +++++++++++++++
arch/s390/kernel/vmlinux.lds.S | 1 +
5 files changed, 62 insertions(+)
create mode 100644 arch/s390/include/asm/static_call.h
create mode 100644 arch/s390/kernel/static_call.c
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 10ada552d870..5d096a5eb48c 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -257,6 +257,7 @@ config S390
select HAVE_SETUP_PER_CPU_AREA
select HAVE_SOFTIRQ_ON_OWN_STACK
select HAVE_STACKPROTECTOR if CC_HAS_STACKPROTECTOR_GLOBAL
+ select HAVE_STATIC_CALL if CFI
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_VIRT_CPU_ACCOUNTING
select HAVE_VIRT_CPU_ACCOUNTING_IDLE
diff --git a/arch/s390/include/asm/static_call.h b/arch/s390/include/asm/static_call.h
new file mode 100644
index 000000000000..6e196cd18240
--- /dev/null
+++ b/arch/s390/include/asm/static_call.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_S390_STATIC_CALL_H
+#define _ASM_S390_STATIC_CALL_H
+
+#ifdef CC_USING_EXPOLINE
+#define __STATIC_CALL_BR_EX_R1 \
+ "557: jg __s390_indirect_jump_r1\n" \
+ " .pushsection .s390_indirect_branches,\"a\",@progbits\n" \
+ " .long 557b-.\n" \
+ " .popsection\n"
+#else
+#define __STATIC_CALL_BR_EX_R1 " br %r1\n"
+#endif
+
+#define __ARCH_DEFINE_STATIC_CALL_TRAMP(name, target) \
+ asm(" .pushsection .static_call.text, \"ax\"\n" \
+ " .balign 4\n" \
+ " .globl " name "\n" \
+ name ":\n" \
+ " lgrl %r1,1f\n" \
+ __STATIC_CALL_BR_EX_R1 \
+ " .type " name ", @function\n" \
+ " .size " name ", . - " name "\n" \
+ " .popsection\n" \
+ " .pushsection .rodata, \"a\"\n" \
+ " .balign 8\n" \
+ "1: .quad " target "\n" \
+ " .popsection\n")
+
+#define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func) \
+ __ARCH_DEFINE_STATIC_CALL_TRAMP(STATIC_CALL_TRAMP_STR(name), #func)
+
+#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \
+ ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0)
+
+#define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name) \
+ ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0)
+
+#endif /* _ASM_S390_STATIC_CALL_H */
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index f84b8fb41331..a8800319033d 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_UPROBES) += uprobes.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+obj-$(CONFIG_HAVE_STATIC_CALL) += static_call.o
obj-$(CONFIG_STACKPROTECTOR) += stackprotector.o
obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o
obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o
diff --git a/arch/s390/kernel/static_call.c b/arch/s390/kernel/static_call.c
new file mode 100644
index 000000000000..e8e20e4f782f
--- /dev/null
+++ b/arch/s390/kernel/static_call.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/static_call.h>
+#include <asm/uaccess.h>
+
+struct insn_ril {
+ u16 opc;
+ s32 ri2;
+} __packed;
+
+void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
+{
+ struct insn_ril *insn = tramp;
+ void *literal;
+
+ literal = tramp + insn->ri2 * 2;
+ if (!func)
+ func = __static_call_return0;
+ s390_kernel_write(literal, &func, sizeof(func));
+}
+EXPORT_SYMBOL_GPL(arch_static_call_transform);
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 1f0e71c58eb9..b9d58441f669 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -48,6 +48,7 @@ SECTIONS
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
+ STATIC_CALL_TEXT
IRQENTRY_TEXT
SOFTIRQENTRY_TEXT
FTRACE_HOTPATCH_TRAMPOLINES_TEXT
--
2.53.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-26 10:30 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-26 10:29 [PATCH] s390: Use static call trampolines when kCFI is enabled Heiko Carstens
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®