History

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fix from Will Deacon: - Implement a basic static call trampoline to fix CFI failures with the generic implementation * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: Use static call trampolines when kCFI is enabled

Linus Torvalds committed 7 months ago

Commit 441c63f2 parents 60d9212 54ac9ff5 files · +57 −0Browse files

Unified · Split

5 files
  1. arch/arm64/Kconfig +1 −0
  2. arch/arm64/include/asm/static_call.h +31 −0
  3. arch/arm64/kernel/Makefile +1 −0
  4. arch/arm64/kernel/static_call.c +23 −0
  5. arch/arm64/kernel/vmlinux.lds.S +1 −0
arch/arm64/Kconfig+1−0
@@ -252,6 +252,7 @@ config ARM64 · 251 unmodified lines
252252 select HAVE_RSEQ
253253 select HAVE_RUST if RUSTC_SUPPORTS_ARM64
254254 select HAVE_STACKPROTECTOR
255+ select HAVE_STATIC_CALL if CFI
255256 select HAVE_SYSCALL_TRACEPOINTS
256257 select HAVE_KPROBES
257258 select HAVE_KRETPROBES
arch/arm64/include/asm/static_call.h+31−0
@@ -0,0 +1,31 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#ifndef _ASM_STATIC_CALL_H
3+#define _ASM_STATIC_CALL_H
4+
5+#define __ARCH_DEFINE_STATIC_CALL_TRAMP(name, target) \
6+ asm(" .pushsection .static_call.text, \"ax\" \n" \
7+ " .align 4 \n" \
8+ " .globl " name " \n" \
9+ name ": \n" \
10+ " hint 34 /* BTI C */ \n" \
11+ " adrp x16, 1f \n" \
12+ " ldr x16, [x16, :lo12:1f] \n" \
13+ " br x16 \n" \
14+ " .type " name ", %function \n" \
15+ " .size " name ", . - " name " \n" \
16+ " .popsection \n" \
17+ " .pushsection .rodata, \"a\" \n" \
18+ " .align 3 \n" \
19+ "1: .quad " target " \n" \
20+ " .popsection \n")
21+
22+#define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func) \
23+ __ARCH_DEFINE_STATIC_CALL_TRAMP(STATIC_CALL_TRAMP_STR(name), #func)
24+
25+#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \
26+ ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0)
27+
28+#define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name) \
29+ ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0)
30+
31+#endif /* _ASM_STATIC_CALL_H */
arch/arm64/kernel/Makefile+1−0
@@ -46,6 +46,7 @@ obj-$(CONFIG_MODULES) += module.o module-plts.o · 45 unmodified lines
4646 obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
4747 obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o
4848 obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
49+obj-$(CONFIG_HAVE_STATIC_CALL) += static_call.o
4950 obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
5051 obj-$(CONFIG_KGDB) += kgdb.o
5152 obj-$(CONFIG_EFI) += efi.o efi-rt-wrapper.o
arch/arm64/kernel/static_call.c+23−0
@@ -0,0 +1,23 @@
1+// SPDX-License-Identifier: GPL-2.0
2+#include <linux/static_call.h>
3+#include <linux/memory.h>
4+#include <asm/text-patching.h>
5+
6+void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
7+{
8+ u64 literal;
9+ int ret;
10+
11+ if (!func)
12+ func = __static_call_return0;
13+
14+ /* decode the instructions to discover the literal address */
15+ literal = ALIGN_DOWN((u64)tramp + 4, SZ_4K) +
16+ aarch64_insn_adrp_get_offset(le32_to_cpup(tramp + 4)) +
17+ 8 * aarch64_insn_decode_immediate(AARCH64_INSN_IMM_12,
18+ le32_to_cpup(tramp + 8));
19+
20+ ret = aarch64_insn_write_literal_u64((void *)literal, (u64)func);
21+ WARN_ON_ONCE(ret);
22+}
23+EXPORT_SYMBOL_GPL(arch_static_call_transform);
arch/arm64/kernel/vmlinux.lds.S+1−0
@@ -191,6 +191,7 @@ SECTIONS · 190 unmodified lines
191191 LOCK_TEXT
192192 KPROBES_TEXT
193193 HYPERVISOR_TEXT
194+ STATIC_CALL_TEXT
194195 *(.gnu.warning)
195196 }
196197