Merge branches 'for-next/sve-remove-pseudo-regs', 'for-next/backtrace-ipi', 'for...
[linux-2.6-microblaze.git] / arch / arm64 / kernel / cpufeature.c
index ea36dc5..2ccb9df 100644 (file)
@@ -1828,6 +1828,8 @@ static int __init parse_kpti(char *str)
 early_param("kpti", parse_kpti);
 
 #ifdef CONFIG_ARM64_HW_AFDBM
+static struct cpumask dbm_cpus __read_mostly;
+
 static inline void __cpu_enable_hw_dbm(void)
 {
        u64 tcr = read_sysreg(tcr_el1) | TCR_HD;
@@ -1863,35 +1865,22 @@ static bool cpu_can_use_dbm(const struct arm64_cpu_capabilities *cap)
 
 static void cpu_enable_hw_dbm(struct arm64_cpu_capabilities const *cap)
 {
-       if (cpu_can_use_dbm(cap))
+       if (cpu_can_use_dbm(cap)) {
                __cpu_enable_hw_dbm();
+               cpumask_set_cpu(smp_processor_id(), &dbm_cpus);
+       }
 }
 
 static bool has_hw_dbm(const struct arm64_cpu_capabilities *cap,
                       int __unused)
 {
-       static bool detected = false;
        /*
         * DBM is a non-conflicting feature. i.e, the kernel can safely
         * run a mix of CPUs with and without the feature. So, we
         * unconditionally enable the capability to allow any late CPU
         * to use the feature. We only enable the control bits on the
-        * CPU, if it actually supports.
-        *
-        * We have to make sure we print the "feature" detection only
-        * when at least one CPU actually uses it. So check if this CPU
-        * can actually use it and print the message exactly once.
-        *
-        * This is safe as all CPUs (including secondary CPUs - due to the
-        * LOCAL_CPU scope - and the hotplugged CPUs - via verification)
-        * goes through the "matches" check exactly once. Also if a CPU
-        * matches the criteria, it is guaranteed that the CPU will turn
-        * the DBM on, as the capability is unconditionally enabled.
+        * CPU, if it is supported.
         */
-       if (!detected && cpu_can_use_dbm(cap)) {
-               detected = true;
-               pr_info("detected: Hardware dirty bit management\n");
-       }
 
        return true;
 }
@@ -1924,8 +1913,6 @@ int get_cpu_with_amu_feat(void)
 static void cpu_amu_enable(struct arm64_cpu_capabilities const *cap)
 {
        if (has_cpuid_feature(cap, SCOPE_LOCAL_CPU)) {
-               pr_info("detected CPU%d: Activity Monitors Unit (AMU)\n",
-                       smp_processor_id());
                cpumask_set_cpu(smp_processor_id(), &amu_cpus);
 
                /* 0 reference values signal broken/disabled counters */
@@ -2385,16 +2372,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 #endif /* CONFIG_ARM64_RAS_EXTN */
 #ifdef CONFIG_ARM64_AMU_EXTN
        {
-               /*
-                * The feature is enabled by default if CONFIG_ARM64_AMU_EXTN=y.
-                * Therefore, don't provide .desc as we don't want the detection
-                * message to be shown until at least one CPU is detected to
-                * support the feature.
-                */
+               .desc = "Activity Monitors Unit (AMU)",
                .capability = ARM64_HAS_AMU_EXTN,
                .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
                .matches = has_amu,
                .cpu_enable = cpu_amu_enable,
+               .cpus = &amu_cpus,
                ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, AMU, IMP)
        },
 #endif /* CONFIG_ARM64_AMU_EXTN */
@@ -2434,18 +2417,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
        },
 #ifdef CONFIG_ARM64_HW_AFDBM
        {
-               /*
-                * Since we turn this on always, we don't want the user to
-                * think that the feature is available when it may not be.
-                * So hide the description.
-                *
-                * .desc = "Hardware pagetable Dirty Bit Management",
-                *
-                */
+               .desc = "Hardware dirty bit management",
                .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
                .capability = ARM64_HW_DBM,
                .matches = has_hw_dbm,
                .cpu_enable = cpu_enable_hw_dbm,
+               .cpus = &dbm_cpus,
                ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, DBM)
        },
 #endif
@@ -2961,7 +2938,7 @@ static void update_cpu_capabilities(u16 scope_mask)
                    !caps->matches(caps, cpucap_default_scope(caps)))
                        continue;
 
-               if (caps->desc)
+               if (caps->desc && !caps->cpus)
                        pr_info("detected: %s\n", caps->desc);
 
                __set_bit(caps->capability, system_cpucaps);
@@ -3294,6 +3271,7 @@ unsigned long cpu_get_elf_hwcap2(void)
 
 static void __init setup_system_capabilities(void)
 {
+       int i;
        /*
         * We have finalised the system-wide safe feature
         * registers, finalise the capabilities that depend
@@ -3302,6 +3280,15 @@ static void __init setup_system_capabilities(void)
         */
        update_cpu_capabilities(SCOPE_SYSTEM);
        enable_cpu_capabilities(SCOPE_ALL & ~SCOPE_BOOT_CPU);
+
+       for (i = 0; i < ARM64_NCAPS; i++) {
+               const struct arm64_cpu_capabilities *caps = cpucap_ptrs[i];
+
+               if (caps && caps->cpus && caps->desc &&
+                       cpumask_any(caps->cpus) < nr_cpu_ids)
+                       pr_info("detected: %s on CPU%*pbl\n",
+                               caps->desc, cpumask_pr_args(caps->cpus));
+       }
 }
 
 void __init setup_cpu_features(void)