-#define CHECK_MASK(field, mask, boot, cur, cpu) \
- check_reg_mask(#field, mask, (boot)->reg_ ## field, (cur)->reg_ ##
field, cpu)
-
-#define CHECK(field, boot, cur, cpu) \
- CHECK_MASK(field, ~0ULL, boot, cur, cpu)
+#define CHECK_CPUINFO(field)
\
+ ({
\
+ int __rc = 0;
\
+ struct arm64_ftr_reg *__regp = get_arm64_sys_reg(sys_ ##
field); \
+ if (__regp) {
\
+ __rc = check_reg_mask(__regp,
\
+ (boot)->reg_ ## field,
\
+ (cur)->reg_ ## field, cpu);
\
+ update_cpu_ftr_reg(__regp, cur->reg_ ## field, cpu);
\
+ }
\
+ __rc;
\
+ })
/*
* Verify that CPUs don't have unexpected differences that will cause
problems.
@@ -123,17 +448,17 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64
*cur)
* caches should look identical. Userspace JITs will make use of
* *minLine.
*/
- diff |= CHECK_MASK(ctr, 0xffff3fff, boot, cur, cpu);
+ diff |= CHECK_CPUINFO(ctr);
/*
* Userspace may perform DC ZVA instructions. Mismatched block sizes
* could result in too much or too little memory being zeroed if a
* process is preempted and migrated between CPUs.
*/
- diff |= CHECK(dczid, boot, cur, cpu);
+ diff |= CHECK_CPUINFO(dczid);
/* If different, timekeeping will be broken (especially with KVM) */
- diff |= CHECK(cntfrq, boot, cur, cpu);
+ diff |= CHECK_CPUINFO(cntfrq);
/*
* The kernel uses self-hosted debug features and expects CPUs to
@@ -141,15 +466,15 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64
*cur)
* and BRPs to be identical.
* ID_AA64DFR1 is currently RES0.
*/
- diff |= CHECK(id_aa64dfr0, boot, cur, cpu);
- diff |= CHECK(id_aa64dfr1, boot, cur, cpu);
+ diff |= CHECK_CPUINFO(id_aa64dfr0);
+ diff |= CHECK_CPUINFO(id_aa64dfr1);
/*
* Even in big.LITTLE, processors should be identical instruction-set
* wise.
*/
- diff |= CHECK(id_aa64isar0, boot, cur, cpu);
- diff |= CHECK(id_aa64isar1, boot, cur, cpu);
+ diff |= CHECK_CPUINFO(id_aa64isar0);
+ diff |= CHECK_CPUINFO(id_aa64isar1);
/*
* Differing PARange support is fine as long as all peripherals and
@@ -157,42 +482,42 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64
*cur)
* Linux should not care about secure memory.
* ID_AA64MMFR1 is currently RES0.
*/
- diff |= CHECK_MASK(id_aa64mmfr0, 0xffffffffffff0ff0, boot, cur, cpu);
- diff |= CHECK(id_aa64mmfr1, boot, cur, cpu);
+ diff |= CHECK_CPUINFO(id_aa64mmfr0);
+ diff |= CHECK_CPUINFO(id_aa64mmfr1);
/*
* EL3 is not our concern.
* ID_AA64PFR1 is currently RES0.
*/
- diff |= CHECK_MASK(id_aa64pfr0, 0xffffffffffff0fff, boot, cur, cpu);
- diff |= CHECK(id_aa64pfr1, boot, cur, cpu);
+ diff |= CHECK_CPUINFO(id_aa64pfr0);
+ diff |= CHECK_CPUINFO(id_aa64pfr1);
/*
* If we have AArch32, we care about 32-bit features for compat. These
* registers should be RES0 otherwise.
*/
- diff |= CHECK(id_dfr0, boot, cur, cpu);
- diff |= CHECK(id_isar0, boot, cur, cpu);
- diff |= CHECK(id_isar1, boot, cur, cpu);
- diff |= CHECK(id_isar2, boot, cur, cpu);
- diff |= CHECK(id_isar3, boot, cur, cpu);
- diff |= CHECK(id_isar4, boot, cur, cpu);
- diff |= CHECK(id_isar5, boot, cur, cpu);
+ diff |= CHECK_CPUINFO(id_dfr0);
+ diff |= CHECK_CPUINFO(id_isar0);
+ diff |= CHECK_CPUINFO(id_isar1);
+ diff |= CHECK_CPUINFO(id_isar2);
+ diff |= CHECK_CPUINFO(id_isar3);
+ diff |= CHECK_CPUINFO(id_isar4);
+ diff |= CHECK_CPUINFO(id_isar5);
/*
* Regardless of the value of the AuxReg field, the AIFSR, ADFSR, and
* ACTLR formats could differ across CPUs and therefore would have to
* be trapped for virtualization anyway.
*/
- diff |= CHECK_MASK(id_mmfr0, 0xff0fffff, boot, cur, cpu);
- diff |= CHECK(id_mmfr1, boot, cur, cpu);
- diff |= CHECK(id_mmfr2, boot, cur, cpu);
- diff |= CHECK(id_mmfr3, boot, cur, cpu);
- diff |= CHECK(id_pfr0, boot, cur, cpu);
- diff |= CHECK(id_pfr1, boot, cur, cpu);
+ diff |= CHECK_CPUINFO(id_mmfr0);
+ diff |= CHECK_CPUINFO(id_mmfr1);
+ diff |= CHECK_CPUINFO(id_mmfr2);
+ diff |= CHECK_CPUINFO(id_mmfr3);
+ diff |= CHECK_CPUINFO(id_pfr0);
+ diff |= CHECK_CPUINFO(id_pfr1);
- diff |= CHECK(mvfr0, boot, cur, cpu);
- diff |= CHECK(mvfr1, boot, cur, cpu);
- diff |= CHECK(mvfr2, boot, cur, cpu);
+ diff |= CHECK_CPUINFO(mvfr0);
+ diff |= CHECK_CPUINFO(mvfr1);
+ diff |= CHECK_CPUINFO(mvfr2);
/*
* Mismatched CPU features are a recipe for disaster. Don't even
@@ -239,7 +564,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
cpuinfo_detect_icache_policy(info);
check_local_cpu_errata();
- check_local_cpu_features();
+ cpuinfo_sanity_check(info);