diff options
Diffstat (limited to 'arch/arm64/kernel/entry.S')
-rw-r--r-- | arch/arm64/kernel/entry.S | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index a31a0a713c85..36ae1cdfaeb6 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -247,7 +247,24 @@ alternative_else_nop_endif check_mte_async_tcf x19, x22 apply_ssbd 1, x22, x23 - ptrauth_keys_install_kernel tsk, x20, x22, x23 + ptrauth_keys_install_kernel_nosync tsk, x20, x22, x23 + +#ifdef CONFIG_ARM64_PTR_AUTH +alternative_if ARM64_HAS_ADDRESS_AUTH + /* + * Enable IA for in-kernel PAC if the task had it disabled. Although + * this could be implemented with an unconditional MRS which would avoid + * a load, this was measured to be slower on Cortex-A75 and Cortex-A76. + */ + ldr x0, [tsk, THREAD_SCTLR_USER] + tbnz x0, SCTLR_ELx_ENIA_SHIFT, 1f + mrs x0, sctlr_el1 + orr x0, x0, SCTLR_ELx_ENIA + msr sctlr_el1, x0 +1: + isb +alternative_else_nop_endif +#endif mte_set_kernel_gcr x22, x23 @@ -351,9 +368,27 @@ alternative_else_nop_endif 3: scs_save tsk, x0 - /* No kernel C function calls after this as user keys are set. */ + /* + * No kernel C function calls after this as user keys are set and IA may + * be disabled. + */ ptrauth_keys_install_user tsk, x0, x1, x2 +#ifdef CONFIG_ARM64_PTR_AUTH +alternative_if ARM64_HAS_ADDRESS_AUTH + /* + * IA was enabled for in-kernel PAC. Disable it now if needed. + * All other per-task SCTLR bits were updated on task switch. + */ + ldr x0, [tsk, THREAD_SCTLR_USER] + tbnz x0, SCTLR_ELx_ENIA_SHIFT, 1f + mrs x0, sctlr_el1 + bic x0, x0, SCTLR_ELx_ENIA + msr sctlr_el1, x0 +1: +alternative_else_nop_endif +#endif + mte_set_user_gcr tsk, x0, x1 apply_ssbd 0, x0, x1 |