]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
arm64: Add helpers for checking CPU MIDR against a range
authorSuzuki K Poulose <suzuki.poulose@arm.com>
Wed, 6 Apr 2022 16:45:13 +0000 (17:45 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Apr 2022 05:52:14 +0000 (07:52 +0200)
[ Upstream commit 1df310505d6d544802016f6bae49aab836ae8510 ]

Add helpers for checking if the given CPU midr falls in a range
of variants/revisions for a given model.

Cc: Will Deacon <will.deacon@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Dave Martin <dave.martin@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/cputype.h
arch/arm64/kernel/cpu_errata.c

index 542a082dfdfc6387c914a3efc4bd1ec301af7ca4..f8646d7fae497437b7bbb3cac982a48e9f92267b 100644 (file)
@@ -10,6 +10,7 @@
 #define __ASM_CPUFEATURE_H
 
 #include <asm/cpucaps.h>
+#include <asm/cputype.h>
 #include <asm/hwcap.h>
 #include <asm/sysreg.h>
 
@@ -229,8 +230,7 @@ struct arm64_cpu_capabilities {
        void (*cpu_enable)(const struct arm64_cpu_capabilities *cap);
        union {
                struct {        /* To be used for erratum handling only */
-                       u32 midr_model;
-                       u32 midr_range_min, midr_range_max;
+                       struct midr_range midr_range;
                };
 
                struct {        /* Feature register checking */
index 2270a5f3127137329fde8e0fcf6c4d1f7ceebae8..e76245ea6b6097f91687df01a10c4da9ea706236 100644 (file)
 
 #define read_cpuid(reg)                        read_sysreg_s(SYS_ ## reg)
 
+/*
+ * Represent a range of MIDR values for a given CPU model and a
+ * range of variant/revision values.
+ *
+ * @model      - CPU model as defined by MIDR_CPU_MODEL
+ * @rv_min     - Minimum value for the revision/variant as defined by
+ *               MIDR_CPU_VAR_REV
+ * @rv_max     - Maximum value for the variant/revision for the range.
+ */
+struct midr_range {
+       u32 model;
+       u32 rv_min;
+       u32 rv_max;
+};
+
+#define MIDR_RANGE(m, v_min, r_min, v_max, r_max)              \
+       {                                                       \
+               .model = m,                                     \
+               .rv_min = MIDR_CPU_VAR_REV(v_min, r_min),       \
+               .rv_max = MIDR_CPU_VAR_REV(v_max, r_max),       \
+       }
+
+#define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
+
+static inline bool is_midr_in_range(u32 midr, struct midr_range const *range)
+{
+       return MIDR_IS_CPU_MODEL_RANGE(midr, range->model,
+                                range->rv_min, range->rv_max);
+}
+
 /*
  * The CPU ID never changes at run time, so we might as well tell the
  * compiler that it's constant.  Use this function to read the CPU ID
index 858a4954907da1b95def2b043585a3d70c74c2f8..e2630e88e8ad0aaf85ed7756f8743063d8acad09 100644 (file)
 static bool __maybe_unused
 is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
 {
+       u32 midr = read_cpuid_id();
+
        WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-       return MIDR_IS_CPU_MODEL_RANGE(read_cpuid_id(), entry->midr_model,
-                                      entry->midr_range_min,
-                                      entry->midr_range_max);
+       return is_midr_in_range(midr, &entry->midr_range);
 }
 
 static bool
@@ -370,15 +370,11 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
 
 #define CAP_MIDR_RANGE(model, v_min, r_min, v_max, r_max)      \
        .matches = is_affected_midr_range,                      \
-       .midr_model = model,                                    \
-       .midr_range_min = MIDR_CPU_VAR_REV(v_min, r_min),       \
-       .midr_range_max = MIDR_CPU_VAR_REV(v_max, r_max)
+       .midr_range = MIDR_RANGE(model, v_min, r_min, v_max, r_max)
 
 #define CAP_MIDR_ALL_VERSIONS(model)                                   \
        .matches = is_affected_midr_range,                              \
-       .midr_model = model,                                            \
-       .midr_range_min = MIDR_CPU_VAR_REV(0, 0),                       \
-       .midr_range_max = (MIDR_VARIANT_MASK | MIDR_REVISION_MASK)
+       .midr_range = MIDR_ALL_VERSIONS(model)
 
 #define MIDR_FIXED(rev, revidr_mask) \
        .fixed_revs = (struct arm64_midr_revidr[]){{ (rev), (revidr_mask) }, {}}