|
@@ -20,6 +20,7 @@
|
|
|
|
|
|
#include <linux/bsearch.h>
|
|
|
#include <linux/cpumask.h>
|
|
|
+#include <linux/crash_dump.h>
|
|
|
#include <linux/sort.h>
|
|
|
#include <linux/stop_machine.h>
|
|
|
#include <linux/types.h>
|
|
@@ -117,6 +118,7 @@ EXPORT_SYMBOL(cpu_hwcap_keys);
|
|
|
static bool __maybe_unused
|
|
|
cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry, int __unused);
|
|
|
|
|
|
+static void cpu_enable_cnp(struct arm64_cpu_capabilities const *cap);
|
|
|
|
|
|
/*
|
|
|
* NOTE: Any changes to the visibility of features should be kept in
|
|
@@ -863,6 +865,20 @@ static bool has_cache_dic(const struct arm64_cpu_capabilities *entry,
|
|
|
return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_DIC_SHIFT);
|
|
|
}
|
|
|
|
|
|
+static bool __maybe_unused
|
|
|
+has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Kdump isn't guaranteed to power-off all secondary CPUs, CNP
|
|
|
+ * may share TLB entries with a CPU stuck in the crashed
|
|
|
+ * kernel.
|
|
|
+ */
|
|
|
+ if (is_kdump_kernel())
|
|
|
+ return false;
|
|
|
+
|
|
|
+ return has_cpuid_feature(entry, scope);
|
|
|
+}
|
|
|
+
|
|
|
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
|
|
|
static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
|
|
|
|
|
@@ -1311,6 +1327,19 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
|
|
|
.min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY,
|
|
|
.cpu_enable = cpu_enable_ssbs,
|
|
|
},
|
|
|
+#endif
|
|
|
+#ifdef CONFIG_ARM64_CNP
|
|
|
+ {
|
|
|
+ .desc = "Common not Private translations",
|
|
|
+ .capability = ARM64_HAS_CNP,
|
|
|
+ .type = ARM64_CPUCAP_SYSTEM_FEATURE,
|
|
|
+ .matches = has_useable_cnp,
|
|
|
+ .sys_reg = SYS_ID_AA64MMFR2_EL1,
|
|
|
+ .sign = FTR_UNSIGNED,
|
|
|
+ .field_pos = ID_AA64MMFR2_CNP_SHIFT,
|
|
|
+ .min_field_value = 1,
|
|
|
+ .cpu_enable = cpu_enable_cnp,
|
|
|
+ },
|
|
|
#endif
|
|
|
{},
|
|
|
};
|
|
@@ -1749,6 +1778,11 @@ cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry, int __unused)
|
|
|
return (cpus_have_const_cap(ARM64_HAS_PAN) && !cpus_have_const_cap(ARM64_HAS_UAO));
|
|
|
}
|
|
|
|
|
|
+static void __maybe_unused cpu_enable_cnp(struct arm64_cpu_capabilities const *cap)
|
|
|
+{
|
|
|
+ cpu_replace_ttbr1(lm_alias(swapper_pg_dir));
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* We emulate only the following system register space.
|
|
|
* Op0 = 0x3, CRn = 0x0, Op1 = 0x0, CRm = [0, 4 - 7]
|