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 | select HAVE_RSEQ | 252 | select HAVE_RSEQ |
| 253 | select HAVE_RUST if RUSTC_SUPPORTS_ARM64 | 253 | select HAVE_RUST if RUSTC_SUPPORTS_ARM64 |
| 254 | select HAVE_STACKPROTECTOR | 254 | select HAVE_STACKPROTECTOR |
| 255 | select HAVE_STATIC_CALL if CFI | ||
| 255 | select HAVE_SYSCALL_TRACEPOINTS | 256 | select HAVE_SYSCALL_TRACEPOINTS |
| 256 | select HAVE_KPROBES | 257 | select HAVE_KPROBES |
| 257 | select HAVE_KRETPROBES | 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 | obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o | 46 | obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o |
| 47 | obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o | 47 | obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o |
| 48 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o | 48 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o |
| 49 | obj-$(CONFIG_HAVE_STATIC_CALL) += static_call.o | ||
| 49 | obj-$(CONFIG_CPU_PM) += sleep.o suspend.o | 50 | obj-$(CONFIG_CPU_PM) += sleep.o suspend.o |
| 50 | obj-$(CONFIG_KGDB) += kgdb.o | 51 | obj-$(CONFIG_KGDB) += kgdb.o |
| 51 | obj-$(CONFIG_EFI) += efi.o efi-rt-wrapper.o | 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 | LOCK_TEXT | 191 | LOCK_TEXT |
| 192 | KPROBES_TEXT | 192 | KPROBES_TEXT |
| 193 | HYPERVISOR_TEXT | 193 | HYPERVISOR_TEXT |
| 194 | STATIC_CALL_TEXT | ||
| 194 | *(.gnu.warning) | 195 | *(.gnu.warning) |
| 195 | } | 196 | } |
| 196 | 197 | ||