@@ -1436,6 +1436,11 @@ config ARM64_PTR_AUTH
be enabled. However, KVM guest also require VHE mode and hence
CONFIG_ARM64_VHE=y option to use this feature.
+ If the feature is present on the primary CPU but not a secondary CPU,
+ then the secondary CPU will be parked. Also, if the boot CPU does not
+ have address auth and the late CPU has then system panic will occur.
+ On such a system, this option should not be selected.
+
endmenu
config ARM64_SVE
@@ -22,6 +22,7 @@
#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)
+#define CPU_STUCK_REASON_NO_PTRAUTH (UL(4) << CPU_STUCK_REASON_SHIFT)
/* Options for __cpu_setup */
#define ARM64_CPU_BOOT_PRIMARY (1)
@@ -1243,12 +1243,6 @@ static void cpu_clear_disr(const struct arm64_cpu_capabilities *__unused)
#endif /* CONFIG_ARM64_RAS_EXTN */
#ifdef CONFIG_ARM64_PTR_AUTH
-static void cpu_enable_address_auth(struct arm64_cpu_capabilities const *cap)
-{
- sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ENIA | SCTLR_ELx_ENIB |
- SCTLR_ELx_ENDA | SCTLR_ELx_ENDB);
-}
-
static bool has_address_auth(const struct arm64_cpu_capabilities *entry,
int __unused)
{
@@ -1525,7 +1519,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
{
.desc = "Address authentication (architected algorithm)",
.capability = ARM64_HAS_ADDRESS_AUTH_ARCH,
- .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .type = ARM64_CPUCAP_SCOPE_BOOT_CPU,
.sys_reg = SYS_ID_AA64ISAR1_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64ISAR1_APA_SHIFT,
@@ -1535,7 +1529,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
{
.desc = "Address authentication (IMP DEF algorithm)",
.capability = ARM64_HAS_ADDRESS_AUTH_IMP_DEF,
- .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .type = ARM64_CPUCAP_SCOPE_BOOT_CPU,
.sys_reg = SYS_ID_AA64ISAR1_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64ISAR1_API_SHIFT,
@@ -1544,9 +1538,8 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
},
{
.capability = ARM64_HAS_ADDRESS_AUTH,
- .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .type = ARM64_CPUCAP_SCOPE_BOOT_CPU,
.matches = has_address_auth,
- .cpu_enable = cpu_enable_address_auth,
},
{
.desc = "Generic authentication (architected algorithm)",
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/irqchip/arm-gic-v3.h>
+#include <asm/alternative.h>
#include <asm/assembler.h>
#include <asm/boot.h>
#include <asm/ptrace.h>
@@ -713,6 +714,7 @@ secondary_startup:
* Common entry point for secondary CPUs.
*/
bl __cpu_secondary_check52bitva
+ bl __cpu_secondary_checkptrauth
mov x0, #ARM64_CPU_BOOT_LATE
bl __cpu_setup // initialise processor
adrp x1, swapper_pg_dir
@@ -831,6 +833,24 @@ __no_granule_support:
early_park_cpu CPU_STUCK_REASON_NO_GRAN
ENDPROC(__no_granule_support)
+ENTRY(__cpu_secondary_checkptrauth)
+#ifdef CONFIG_ARM64_PTR_AUTH
+ /* Check if the CPU supports ptrauth */
+ mrs x2, id_aa64isar1_el1
+ ubfx x2, x2, #ID_AA64ISAR1_APA_SHIFT, #8
+ cbnz x2, 1f
+alternative_if ARM64_HAS_ADDRESS_AUTH
+ mov x3, 1
+alternative_else
+ mov x3, 0
+alternative_endif
+ cbz x3, 1f
+ /* Park the mismatched secondary CPU */
+ early_park_cpu CPU_STUCK_REASON_NO_PTRAUTH
+#endif
+1: ret
+ENDPROC(__cpu_secondary_checkptrauth)
+
#ifdef CONFIG_RELOCATABLE
__relocate_kernel:
/*
@@ -162,6 +162,8 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
pr_crit("CPU%u: does not support 52-bit VAs\n", cpu);
if (status & CPU_STUCK_REASON_NO_GRAN)
pr_crit("CPU%u: does not support %luK granule \n", cpu, PAGE_SIZE / SZ_1K);
+ if (status & CPU_STUCK_REASON_NO_PTRAUTH)
+ pr_crit("CPU%u: does not support pointer authentication\n", cpu);
cpus_stuck_in_kernel++;
break;
case CPU_PANIC_KERNEL:
@@ -16,6 +16,7 @@
#include <asm/pgtable-hwdef.h>
#include <asm/cpufeature.h>
#include <asm/alternative.h>
+#include <asm/smp.h>
#ifdef CONFIG_ARM64_64K_PAGES
#define TCR_TG_FLAGS TCR_TG0_64K | TCR_TG1_64K
@@ -474,9 +475,39 @@ ENTRY(__cpu_setup)
1:
#endif /* CONFIG_ARM64_HW_AFDBM */
msr tcr_el1, x10
+ mov x1, x0
/*
* Prepare SCTLR
*/
mov_q x0, SCTLR_EL1_SET
+
+#ifdef CONFIG_ARM64_PTR_AUTH
+ /* No ptrauth setup for run time cpus */
+ cmp x1, #ARM64_CPU_RUNTIME
+ b.eq 3f
+
+ /* Check if the CPU supports ptrauth */
+ mrs x2, id_aa64isar1_el1
+ ubfx x2, x2, #ID_AA64ISAR1_APA_SHIFT, #8
+ cbz x2, 3f
+
+ msr_s SYS_APIAKEYLO_EL1, xzr
+ msr_s SYS_APIAKEYHI_EL1, xzr
+
+ /* Just enable ptrauth for primary cpu */
+ cmp x1, #ARM64_CPU_BOOT_PRIMARY
+ b.eq 2f
+
+ /* if !system_supports_address_auth() then skip enable */
+alternative_if_not ARM64_HAS_ADDRESS_AUTH
+ b 3f
+alternative_else_nop_endif
+
+2: /* Enable ptrauth instructions */
+ ldr x2, =SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
+ SCTLR_ELx_ENDA | SCTLR_ELx_ENDB
+ orr x0, x0, x2
+3:
+#endif
ret // return to head.S
ENDPROC(__cpu_setup)