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
Unified · Split
| @@ -252,6 +252,7 @@ config ARM64 · 251 unmodified lines | ||
| 252 | 252 | select HAVE_RSEQ |
| 253 | 253 | select HAVE_RUST if RUSTC_SUPPORTS_ARM64 |
| 254 | 254 | select HAVE_STACKPROTECTOR |
| 255 | + select HAVE_STATIC_CALL if CFI | |
| 255 | 256 | select HAVE_SYSCALL_TRACEPOINTS |
| 256 | 257 | select HAVE_KPROBES |
| 257 | 258 | select HAVE_KRETPROBES |
| @@ -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 */ | |
| @@ -46,6 +46,7 @@ obj-$(CONFIG_MODULES) += module.o module-plts.o · 45 unmodified lines | ||
| 46 | 46 | obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o |
| 47 | 47 | obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o |
| 48 | 48 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o |
| 49 | +obj-$(CONFIG_HAVE_STATIC_CALL) += static_call.o | |
| 49 | 50 | obj-$(CONFIG_CPU_PM) += sleep.o suspend.o |
| 50 | 51 | obj-$(CONFIG_KGDB) += kgdb.o |
| 51 | 52 | obj-$(CONFIG_EFI) += efi.o efi-rt-wrapper.o |
| @@ -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); | |
| @@ -191,6 +191,7 @@ SECTIONS · 190 unmodified lines | ||
| 191 | 191 | LOCK_TEXT |
| 192 | 192 | KPROBES_TEXT |
| 193 | 193 | HYPERVISOR_TEXT |
| 194 | + STATIC_CALL_TEXT | |
| 194 | 195 | *(.gnu.warning) |
| 195 | 196 | } |
| 196 | 197 | |