hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7QNYP
----------------------------------------
Add a `arm64.nopauth=` cmdline to control kernel's perception to CPU's hardware capability of pointer authentication at early boot stage, which provides a method to turn off the PAuth feature without affecting kABI.
The new cmdline parameter shares the same name with the one introduced by the commit ("arm64: cpufeatures: Allow disabling of Pointer Auth from the command-line") in 5.12 kernel, which is implemented in a different mechanism (check the link below).
Link: https://patchwork.kernel.org/project/linux-arm-kernel/patch/20210208095732.3... Signed-off-by: GONG, Ruiqi gongruiqi1@huawei.com --- arch/arm64/kernel/cpufeature.c | 54 +++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 7f5f7e18967a..4e63e05b1ceb 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1687,10 +1687,27 @@ static void cpu_clear_disr(const struct arm64_cpu_capabilities *__unused) #endif /* CONFIG_ARM64_RAS_EXTN */
#ifdef CONFIG_ARM64_PTR_AUTH +/* + * PAuth is enabled by default, and should be explicitly shut down by + * `arm64.nopauth` if needed. + */ +static int arm64_nopauth __ro_after_init; + +static int __init parse_arm64_nopauth(char *str) +{ + arm64_nopauth = 1; + + return 0; +} +early_param("arm64.nopauth", parse_arm64_nopauth); + static bool has_address_auth_cpucap(const struct arm64_cpu_capabilities *entry, int scope) { int boot_val, sec_val;
+ if (arm64_nopauth) + return false; + /* We don't expect to be called with SCOPE_SYSTEM */ WARN_ON(scope == SCOPE_SYSTEM); /* @@ -1720,6 +1737,12 @@ static bool has_address_auth_metacap(const struct arm64_cpu_capabilities *entry, has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope); }
+static bool has_ptr_auth_cpucap(const struct arm64_cpu_capabilities *entry, + int scope) +{ + return !arm64_nopauth && has_cpuid_feature(entry, scope); +} + static bool has_generic_auth(const struct arm64_cpu_capabilities *entry, int __unused) { @@ -2171,7 +2194,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .sign = FTR_UNSIGNED, .field_pos = ID_AA64ISAR1_GPA_SHIFT, .min_field_value = ID_AA64ISAR1_GPA_ARCHITECTED, - .matches = has_cpuid_feature, + .matches = has_ptr_auth_cpucap, }, { .desc = "Generic authentication (IMP DEF algorithm)", @@ -2181,7 +2204,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .sign = FTR_UNSIGNED, .field_pos = ID_AA64ISAR1_GPI_SHIFT, .min_field_value = ID_AA64ISAR1_GPI_IMP_DEF, - .matches = has_cpuid_feature, + .matches = has_ptr_auth_cpucap, }, { .capability = ARM64_HAS_GENERIC_AUTH, @@ -2297,6 +2320,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .sign = s, \ .min_field_value = min_value,
+#define HWCAP_CPUID_MATCH_SELF_DEFINED(match, reg, field, s, min_value) \ + .matches = match, \ + .sys_reg = reg, \ + .field_pos = field, \ + .sign = s, \ + .min_field_value = min_value, + #define __HWCAP_CAP(name, cap_type, cap) \ .desc = name, \ .type = ARM64_CPUCAP_SYSTEM_FEATURE, \ @@ -2325,24 +2355,28 @@ static const struct arm64_cpu_capabilities arm64_features[] = { #ifdef CONFIG_ARM64_PTR_AUTH static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = { { - HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_APA_SHIFT, - FTR_UNSIGNED, ID_AA64ISAR1_APA_ARCHITECTED) + HWCAP_CPUID_MATCH_SELF_DEFINED(has_ptr_auth_cpucap, + SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_APA_SHIFT, + FTR_UNSIGNED, ID_AA64ISAR1_APA_ARCHITECTED) }, { - HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_API_SHIFT, - FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF) + HWCAP_CPUID_MATCH_SELF_DEFINED(has_ptr_auth_cpucap, + SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_API_SHIFT, + FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF) }, {}, };
static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = { { - HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPA_SHIFT, - FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED) + HWCAP_CPUID_MATCH_SELF_DEFINED(has_ptr_auth_cpucap, + SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPA_SHIFT, + FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED) }, { - HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPI_SHIFT, - FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF) + HWCAP_CPUID_MATCH_SELF_DEFINED(has_ptr_auth_cpucap, + SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPI_SHIFT, + FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF) }, {}, };