mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [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®