Commit 62a679cb authored by Mark Rutland's avatar Mark Rutland Committed by Will Deacon
Browse files

arm64: simplify ptrauth initialization



Currently __cpu_setup conditionally initializes the address
authentication keys and enables them in SCTLR_EL1, doing so differently
for the primary CPU and secondary CPUs, and skipping this work for CPUs
returning from an idle state. For the latter case, cpu_do_resume
restores the keys and SCTLR_EL1 value after the MMU has been enabled.

This flow is rather difficult to follow, so instead let's move the
primary and secondary CPU initialization into their respective boot
paths. By following the example of cpu_do_resume and doing so once the
MMU is enabled, we can always initialize the keys from the values in
thread_struct, and avoid the machinery necessary to pass the keys in
secondary_data or open-coding initialization for the boot CPU.

This means we perform an additional RMW of SCTLR_EL1, but we already do
this in the cpu_do_resume path, and for other features in cpufeature.c,
so this isn't a major concern in a bringup path. Note that even while
the enable bits are clear, the key registers are accessible.

As this now renders the argument to __cpu_setup redundant, let's also
remove that entirely. Future extensions can follow a similar approach to
initialize values that differ for primary/secondary CPUs.

Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Tested-by: default avatarAmit Daniel Kachhap <amit.kachhap@arm.com>
Reviewed-by: default avatarAmit Daniel Kachhap <amit.kachhap@arm.com>
Cc: Amit Daniel Kachhap <amit.kachhap@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20200423101606.37601-3-mark.rutland@arm.com


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent d0055da5
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -60,6 +60,28 @@ alternative_if ARM64_HAS_ADDRESS_AUTH
alternative_else_nop_endif
	.endm

	.macro __ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
	mrs	\tmp1, id_aa64isar1_el1
	ubfx	\tmp1, \tmp1, #ID_AA64ISAR1_APA_SHIFT, #8
	cbz	\tmp1, .Lno_addr_auth\@
	mov_q	\tmp1, (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
			SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
	mrs	\tmp2, sctlr_el1
	orr	\tmp2, \tmp2, \tmp1
	msr	sctlr_el1, \tmp2
	__ptrauth_keys_install_kernel_nosync \tsk, \tmp1, \tmp2, \tmp3
	isb
.Lno_addr_auth\@:
	.endm

	.macro ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
alternative_if_not ARM64_HAS_ADDRESS_AUTH
	b	.Lno_addr_auth\@
alternative_else_nop_endif
	__ptrauth_keys_init_cpu \tsk, \tmp1, \tmp2, \tmp3
.Lno_addr_auth\@:
	.endm

#else /* CONFIG_ARM64_PTR_AUTH */

	.macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
+0 −11
Original line number Diff line number Diff line
@@ -23,14 +23,6 @@
#define CPU_STUCK_REASON_52_BIT_VA	(UL(1) << CPU_STUCK_REASON_SHIFT)
#define CPU_STUCK_REASON_NO_GRAN	(UL(2) << CPU_STUCK_REASON_SHIFT)

/* Possible options for __cpu_setup */
/* Option to setup primary cpu */
#define ARM64_CPU_BOOT_PRIMARY		(1)
/* Option to setup secondary cpus */
#define ARM64_CPU_BOOT_SECONDARY	(2)
/* Option to setup cpus for different cpu run time services */
#define ARM64_CPU_RUNTIME		(3)

#ifndef __ASSEMBLY__

#include <asm/percpu.h>
@@ -96,9 +88,6 @@ asmlinkage void secondary_start_kernel(void);
struct secondary_data {
	void *stack;
	struct task_struct *task;
#ifdef CONFIG_ARM64_PTR_AUTH
	struct ptrauth_keys_kernel ptrauth_key;
#endif
	long status;
};

+0 −3
Original line number Diff line number Diff line
@@ -92,9 +92,6 @@ int main(void)
  BLANK();
  DEFINE(CPU_BOOT_STACK,	offsetof(struct secondary_data, stack));
  DEFINE(CPU_BOOT_TASK,		offsetof(struct secondary_data, task));
#ifdef CONFIG_ARM64_PTR_AUTH
  DEFINE(CPU_BOOT_PTRAUTH_KEY,	offsetof(struct secondary_data, ptrauth_key));
#endif
  BLANK();
#ifdef CONFIG_KVM_ARM_HOST
  DEFINE(VCPU_CONTEXT,		offsetof(struct kvm_vcpu, arch.ctxt));
+10 −2
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/irqchip/arm-gic-v3.h>

#include <asm/asm_pointer_auth.h>
#include <asm/assembler.h>
#include <asm/boot.h>
#include <asm/ptrace.h>
@@ -118,7 +119,6 @@ SYM_CODE_START(stext)
	 * On return, the CPU will be ready for the MMU to be turned on and
	 * the TCR will have been set.
	 */
	mov	x0, #ARM64_CPU_BOOT_PRIMARY
	bl	__cpu_setup			// initialise processor
	b	__primary_switch
SYM_CODE_END(stext)
@@ -417,6 +417,10 @@ SYM_FUNC_START_LOCAL(__primary_switched)
	adr_l	x5, init_task
	msr	sp_el0, x5			// Save thread_info

#ifdef CONFIG_ARM64_PTR_AUTH
	__ptrauth_keys_init_cpu	x5, x6, x7, x8
#endif

	adr_l	x8, vectors			// load VBAR_EL1 with virtual
	msr	vbar_el1, x8			// vector table address
	isb
@@ -717,7 +721,6 @@ SYM_FUNC_START_LOCAL(secondary_startup)
	 * Common entry point for secondary CPUs.
	 */
	bl	__cpu_secondary_check52bitva
	mov	x0, #ARM64_CPU_BOOT_SECONDARY
	bl	__cpu_setup			// initialise processor
	adrp	x1, swapper_pg_dir
	bl	__enable_mmu
@@ -739,6 +742,11 @@ SYM_FUNC_START_LOCAL(__secondary_switched)
	msr	sp_el0, x2
	mov	x29, #0
	mov	x30, #0

#ifdef CONFIG_ARM64_PTR_AUTH
	ptrauth_keys_init_cpu x2, x3, x4, x5
#endif

	b	secondary_start_kernel
SYM_FUNC_END(__secondary_switched)

+0 −1
Original line number Diff line number Diff line
@@ -100,7 +100,6 @@ ENDPROC(__cpu_suspend_enter)
	.pushsection ".idmap.text", "awx"
ENTRY(cpu_resume)
	bl	el2_setup		// if in EL2 drop to EL1 cleanly
	mov	x0, #ARM64_CPU_RUNTIME
	bl	__cpu_setup
	/* enable the MMU early - so we can access sleep_save_stash by va */
	adrp	x1, swapper_pg_dir
Loading