Commit 9772b7f0 authored by Will Deacon's avatar Will Deacon
Browse files

Merge branch 'for-next/stacktrace' into for-next/core

* for-next/stacktrace:
  arm64: move PAC masks to <asm/pointer_auth.h>
  arm64: use XPACLRI to strip PAC
  arm64: avoid redundant PAC stripping in __builtin_return_address()
  arm64: stacktrace: always inline core stacktrace functions
  arm64: stacktrace: move dump functions to end of file
  arm64: stacktrace: recover return address for first entry
parents 9651f00e de1702f6
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -366,6 +366,20 @@ config ARCH_PROC_KCORE_TEXT
config BROKEN_GAS_INST
	def_bool !$(as-instr,1:\n.inst 0\n.rept . - 1b\n\nnop\n.endr\n)

config BUILTIN_RETURN_ADDRESS_STRIPS_PAC
	bool
	# Clang's __builtin_return_adddress() strips the PAC since 12.0.0
	# https://reviews.llvm.org/D75044
	default y if CC_IS_CLANG && (CLANG_VERSION >= 120000)
	# GCC's __builtin_return_address() strips the PAC since 11.1.0,
	# and this was backported to 10.2.0, 9.4.0, 8.5.0, but not earlier
	# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94891
	default y if CC_IS_GCC && (GCC_VERSION >= 110100)
	default y if CC_IS_GCC && (GCC_VERSION >= 100200) && (GCC_VERSION < 110000)
	default y if CC_IS_GCC && (GCC_VERSION >=  90400) && (GCC_VERSION < 100000)
	default y if CC_IS_GCC && (GCC_VERSION >=  80500) && (GCC_VERSION <  90000)
	default n

config KASAN_SHADOW_OFFSET
	hex
	depends on KASAN_GENERIC || KASAN_SW_TAGS
+25 −11
Original line number Diff line number Diff line
@@ -8,19 +8,33 @@
#define ARM64_ASM_PREAMBLE
#endif

/*
 * The EL0/EL1 pointer bits used by a pointer authentication code.
 * This is dependent on TBI0/TBI1 being enabled, or bits 63:56 would also apply.
 */
#define ptrauth_user_pac_mask()		GENMASK_ULL(54, vabits_actual)
#define ptrauth_kernel_pac_mask()	GENMASK_ULL(63, vabits_actual)
#define xpaclri(ptr)							\
({									\
	register unsigned long __xpaclri_ptr asm("x30") = (ptr);	\
									\
	asm(								\
	ARM64_ASM_PREAMBLE						\
	"	hint	#7\n"						\
	: "+r" (__xpaclri_ptr));					\
									\
	__xpaclri_ptr;							\
})

/* Valid for EL0 TTBR0 and EL1 TTBR1 instruction pointers */
#define ptrauth_clear_pac(ptr)						\
	((ptr & BIT_ULL(55)) ? (ptr | ptrauth_kernel_pac_mask()) :	\
			       (ptr & ~ptrauth_user_pac_mask()))
#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
#define ptrauth_strip_kernel_insn_pac(ptr)	xpaclri(ptr)
#else
#define ptrauth_strip_kernel_insn_pac(ptr)	(ptr)
#endif

#ifdef CONFIG_ARM64_PTR_AUTH
#define ptrauth_strip_user_insn_pac(ptr)	xpaclri(ptr)
#else
#define ptrauth_strip_user_insn_pac(ptr)	(ptr)
#endif

#if !defined(CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC)
#define __builtin_return_address(val)					\
	(void *)(ptrauth_clear_pac((unsigned long)__builtin_return_address(val)))
	(void *)(ptrauth_strip_kernel_insn_pac((unsigned long)__builtin_return_address(val)))
#endif

#endif /* __ASM_COMPILER_H */
+7 −6
Original line number Diff line number Diff line
@@ -10,6 +10,13 @@
#include <asm/memory.h>
#include <asm/sysreg.h>

/*
 * The EL0/EL1 pointer bits used by a pointer authentication code.
 * This is dependent on TBI0/TBI1 being enabled, or bits 63:56 would also apply.
 */
#define ptrauth_user_pac_mask()		GENMASK_ULL(54, vabits_actual)
#define ptrauth_kernel_pac_mask()	GENMASK_ULL(63, vabits_actual)

#define PR_PAC_ENABLED_KEYS_MASK                                               \
	(PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY)

@@ -97,11 +104,6 @@ extern int ptrauth_set_enabled_keys(struct task_struct *tsk, unsigned long keys,
				    unsigned long enabled);
extern int ptrauth_get_enabled_keys(struct task_struct *tsk);

static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr)
{
	return ptrauth_clear_pac(ptr);
}

static __always_inline void ptrauth_enable(void)
{
	if (!system_supports_address_auth())
@@ -133,7 +135,6 @@ static __always_inline void ptrauth_enable(void)
#define ptrauth_prctl_reset_keys(tsk, arg)	(-EINVAL)
#define ptrauth_set_enabled_keys(tsk, keys, enabled)	(-EINVAL)
#define ptrauth_get_enabled_keys(tsk)	(-EINVAL)
#define ptrauth_strip_insn_pac(lr)	(lr)
#define ptrauth_suspend_exit()
#define ptrauth_thread_init_user()
#define ptrauth_thread_switch_user(tsk)
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <asm/cpufeature.h>
#include <asm/memory.h>
#include <asm/pgtable-hwdef.h>
#include <asm/pointer_auth.h>

static inline u64 get_tcr_el1_t1sz(void);

+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ user_backtrace(struct frame_tail __user *tail,
	if (err)
		return NULL;

	lr = ptrauth_strip_insn_pac(buftail.lr);
	lr = ptrauth_strip_user_insn_pac(buftail.lr);

	perf_callchain_store(entry, lr);

Loading