From: Heiko Carstens <hca@linux.ibm.com>
To: Alexander Gordeev <agordeev@linux.ibm.com>,
Sven Schnelle <svens@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org
Subject: [PATCH] s390: Use static call trampolines when kCFI is enabled
Date: Mon, 26 Oct 2026 11:29:51 +0100 [thread overview]
Message-ID: <20261026102952.4153711-1-hca@linux.ibm.com> (raw)
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
next reply other threads:[~2026-10-26 10:30 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-26 10:29 Heiko Carstens [this message]
2026-10-26 11:07 ` [PATCH] s390: Use static call trampolines when kCFI is enabled sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261026102952.4153711-1-hca@linux.ibm.com \
--to=hca@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=svens@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.