1 /* 2 * Record and handle CPU attributes. 3 * 4 * Copyright (C) 2014 ARM Ltd. 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 #include <asm/arch_timer.h> 18 #include <asm/cachetype.h> 19 #include <asm/cpu.h> 20 #include <asm/cputype.h> 21 22 #include <linux/bitops.h> 23 #include <linux/bug.h> 24 #include <linux/init.h> 25 #include <linux/kernel.h> 26 #include <linux/preempt.h> 27 #include <linux/printk.h> 28 #include <linux/smp.h> 29 30 /* 31 * In case the boot CPU is hotpluggable, we record its initial state and 32 * current state separately. Certain system registers may contain different 33 * values depending on configuration at or after reset. 34 */ 35 DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data); 36 static struct cpuinfo_arm64 boot_cpu_data; 37 38 static char *icache_policy_str[] = { 39 [ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN", 40 [ICACHE_POLICY_AIVIVT] = "AIVIVT", 41 [ICACHE_POLICY_VIPT] = "VIPT", 42 [ICACHE_POLICY_PIPT] = "PIPT", 43 }; 44 45 unsigned long __icache_flags; 46 47 static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info) 48 { 49 unsigned int cpu = smp_processor_id(); 50 u32 l1ip = CTR_L1IP(info->reg_ctr); 51 52 if (l1ip != ICACHE_POLICY_PIPT) { 53 /* 54 * VIPT caches are non-aliasing if the VA always equals the PA 55 * in all bit positions that are covered by the index. This is 56 * the case if the size of a way (# of sets * line size) does 57 * not exceed PAGE_SIZE. 58 */ 59 u32 waysize = icache_get_numsets() * icache_get_linesize(); 60 61 if (l1ip != ICACHE_POLICY_VIPT || waysize > PAGE_SIZE) 62 set_bit(ICACHEF_ALIASING, &__icache_flags); 63 } 64 if (l1ip == ICACHE_POLICY_AIVIVT) 65 set_bit(ICACHEF_AIVIVT, &__icache_flags); 66 67 pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu); 68 } 69 70 static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu) 71 { 72 if ((boot & mask) == (cur & mask)) 73 return 0; 74 75 pr_warn("SANITY CHECK: Unexpected variation in %s. Boot CPU: %#016lx, CPU%d: %#016lx\n", 76 name, (unsigned long)boot, cpu, (unsigned long)cur); 77 78 return 1; 79 } 80 81 #define CHECK_MASK(field, mask, boot, cur, cpu) \ 82 check_reg_mask(#field, mask, (boot)->reg_ ## field, (cur)->reg_ ## field, cpu) 83 84 #define CHECK(field, boot, cur, cpu) \ 85 CHECK_MASK(field, ~0ULL, boot, cur, cpu) 86 87 /* 88 * Verify that CPUs don't have unexpected differences that will cause problems. 89 */ 90 static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur) 91 { 92 unsigned int cpu = smp_processor_id(); 93 struct cpuinfo_arm64 *boot = &boot_cpu_data; 94 unsigned int diff = 0; 95 96 /* 97 * The kernel can handle differing I-cache policies, but otherwise 98 * caches should look identical. Userspace JITs will make use of 99 * *minLine. 100 */ 101 diff |= CHECK_MASK(ctr, 0xffff3fff, boot, cur, cpu); 102 103 /* 104 * Userspace may perform DC ZVA instructions. Mismatched block sizes 105 * could result in too much or too little memory being zeroed if a 106 * process is preempted and migrated between CPUs. 107 */ 108 diff |= CHECK(dczid, boot, cur, cpu); 109 110 /* If different, timekeeping will be broken (especially with KVM) */ 111 diff |= CHECK(cntfrq, boot, cur, cpu); 112 113 /* 114 * Even in big.LITTLE, processors should be identical instruction-set 115 * wise. 116 */ 117 diff |= CHECK(id_aa64isar0, boot, cur, cpu); 118 diff |= CHECK(id_aa64isar1, boot, cur, cpu); 119 120 /* 121 * Differing PARange support is fine as long as all peripherals and 122 * memory are mapped within the minimum PARange of all CPUs. 123 * Linux should not care about secure memory. 124 * ID_AA64MMFR1 is currently RES0. 125 */ 126 diff |= CHECK_MASK(id_aa64mmfr0, 0xffffffffffff0ff0, boot, cur, cpu); 127 diff |= CHECK(id_aa64mmfr1, boot, cur, cpu); 128 129 /* 130 * EL3 is not our concern. 131 * ID_AA64PFR1 is currently RES0. 132 */ 133 diff |= CHECK_MASK(id_aa64pfr0, 0xffffffffffff0fff, boot, cur, cpu); 134 diff |= CHECK(id_aa64pfr1, boot, cur, cpu); 135 136 /* 137 * If we have AArch32, we care about 32-bit features for compat. These 138 * registers should be RES0 otherwise. 139 */ 140 diff |= CHECK(id_isar0, boot, cur, cpu); 141 diff |= CHECK(id_isar1, boot, cur, cpu); 142 diff |= CHECK(id_isar2, boot, cur, cpu); 143 diff |= CHECK(id_isar3, boot, cur, cpu); 144 diff |= CHECK(id_isar4, boot, cur, cpu); 145 diff |= CHECK(id_isar5, boot, cur, cpu); 146 diff |= CHECK(id_mmfr0, boot, cur, cpu); 147 diff |= CHECK(id_mmfr1, boot, cur, cpu); 148 diff |= CHECK(id_mmfr2, boot, cur, cpu); 149 diff |= CHECK(id_mmfr3, boot, cur, cpu); 150 diff |= CHECK(id_pfr0, boot, cur, cpu); 151 diff |= CHECK(id_pfr1, boot, cur, cpu); 152 153 /* 154 * Mismatched CPU features are a recipe for disaster. Don't even 155 * pretend to support them. 156 */ 157 WARN_TAINT_ONCE(diff, TAINT_CPU_OUT_OF_SPEC, 158 "Unsupported CPU feature variation."); 159 } 160 161 static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) 162 { 163 info->reg_cntfrq = arch_timer_get_cntfrq(); 164 info->reg_ctr = read_cpuid_cachetype(); 165 info->reg_dczid = read_cpuid(DCZID_EL0); 166 info->reg_midr = read_cpuid_id(); 167 168 info->reg_id_aa64isar0 = read_cpuid(ID_AA64ISAR0_EL1); 169 info->reg_id_aa64isar1 = read_cpuid(ID_AA64ISAR1_EL1); 170 info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1); 171 info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); 172 info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1); 173 info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1); 174 175 info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1); 176 info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1); 177 info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1); 178 info->reg_id_isar3 = read_cpuid(ID_ISAR3_EL1); 179 info->reg_id_isar4 = read_cpuid(ID_ISAR4_EL1); 180 info->reg_id_isar5 = read_cpuid(ID_ISAR5_EL1); 181 info->reg_id_mmfr0 = read_cpuid(ID_MMFR0_EL1); 182 info->reg_id_mmfr1 = read_cpuid(ID_MMFR1_EL1); 183 info->reg_id_mmfr2 = read_cpuid(ID_MMFR2_EL1); 184 info->reg_id_mmfr3 = read_cpuid(ID_MMFR3_EL1); 185 info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1); 186 info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1); 187 188 cpuinfo_detect_icache_policy(info); 189 } 190 191 void cpuinfo_store_cpu(void) 192 { 193 struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data); 194 __cpuinfo_store_cpu(info); 195 cpuinfo_sanity_check(info); 196 } 197 198 void __init cpuinfo_store_boot_cpu(void) 199 { 200 struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0); 201 __cpuinfo_store_cpu(info); 202 203 boot_cpu_data = *info; 204 } 205 206 u64 __attribute_const__ icache_get_ccsidr(void) 207 { 208 u64 ccsidr; 209 210 WARN_ON(preemptible()); 211 212 /* Select L1 I-cache and read its size ID register */ 213 asm("msr csselr_el1, %1; isb; mrs %0, ccsidr_el1" 214 : "=r"(ccsidr) : "r"(1L)); 215 return ccsidr; 216 } 217