linux/arch/arm64/kernel/cpu_errata.c
<<
>>
Prefs
   1/*
   2 * Contains CPU specific errata definitions
   3 *
   4 * Copyright (C) 2014 ARM Ltd.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17 */
  18
  19#include <linux/types.h>
  20#include <asm/cpu.h>
  21#include <asm/cputype.h>
  22#include <asm/cpufeature.h>
  23
  24static bool __maybe_unused
  25is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
  26{
  27        WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
  28        return MIDR_IS_CPU_MODEL_RANGE(read_cpuid_id(), entry->midr_model,
  29                                       entry->midr_range_min,
  30                                       entry->midr_range_max);
  31}
  32
  33static bool
  34has_mismatched_cache_line_size(const struct arm64_cpu_capabilities *entry,
  35                                int scope)
  36{
  37        WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
  38        return (read_cpuid_cachetype() & arm64_ftr_reg_ctrel0.strict_mask) !=
  39                (arm64_ftr_reg_ctrel0.sys_val & arm64_ftr_reg_ctrel0.strict_mask);
  40}
  41
  42static int cpu_enable_trap_ctr_access(void *__unused)
  43{
  44        /* Clear SCTLR_EL1.UCT */
  45        config_sctlr_el1(SCTLR_EL1_UCT, 0);
  46        return 0;
  47}
  48
  49#define MIDR_RANGE(model, min, max) \
  50        .def_scope = SCOPE_LOCAL_CPU, \
  51        .matches = is_affected_midr_range, \
  52        .midr_model = model, \
  53        .midr_range_min = min, \
  54        .midr_range_max = max
  55
  56#define MIDR_ALL_VERSIONS(model) \
  57        .def_scope = SCOPE_LOCAL_CPU, \
  58        .matches = is_affected_midr_range, \
  59        .midr_model = model, \
  60        .midr_range_min = 0, \
  61        .midr_range_max = (MIDR_VARIANT_MASK | MIDR_REVISION_MASK)
  62
  63const struct arm64_cpu_capabilities arm64_errata[] = {
  64#if     defined(CONFIG_ARM64_ERRATUM_826319) || \
  65        defined(CONFIG_ARM64_ERRATUM_827319) || \
  66        defined(CONFIG_ARM64_ERRATUM_824069)
  67        {
  68        /* Cortex-A53 r0p[012] */
  69                .desc = "ARM errata 826319, 827319, 824069",
  70                .capability = ARM64_WORKAROUND_CLEAN_CACHE,
  71                MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x02),
  72                .enable = cpu_enable_cache_maint_trap,
  73        },
  74#endif
  75#ifdef CONFIG_ARM64_ERRATUM_819472
  76        {
  77        /* Cortex-A53 r0p[01] */
  78                .desc = "ARM errata 819472",
  79                .capability = ARM64_WORKAROUND_CLEAN_CACHE,
  80                MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x01),
  81                .enable = cpu_enable_cache_maint_trap,
  82        },
  83#endif
  84#ifdef CONFIG_ARM64_ERRATUM_832075
  85        {
  86        /* Cortex-A57 r0p0 - r1p2 */
  87                .desc = "ARM erratum 832075",
  88                .capability = ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE,
  89                MIDR_RANGE(MIDR_CORTEX_A57,
  90                           MIDR_CPU_VAR_REV(0, 0),
  91                           MIDR_CPU_VAR_REV(1, 2)),
  92        },
  93#endif
  94#ifdef CONFIG_ARM64_ERRATUM_834220
  95        {
  96        /* Cortex-A57 r0p0 - r1p2 */
  97                .desc = "ARM erratum 834220",
  98                .capability = ARM64_WORKAROUND_834220,
  99                MIDR_RANGE(MIDR_CORTEX_A57,
 100                           MIDR_CPU_VAR_REV(0, 0),
 101                           MIDR_CPU_VAR_REV(1, 2)),
 102        },
 103#endif
 104#ifdef CONFIG_ARM64_ERRATUM_845719
 105        {
 106        /* Cortex-A53 r0p[01234] */
 107                .desc = "ARM erratum 845719",
 108                .capability = ARM64_WORKAROUND_845719,
 109                MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x04),
 110        },
 111#endif
 112#ifdef CONFIG_CAVIUM_ERRATUM_23154
 113        {
 114        /* Cavium ThunderX, pass 1.x */
 115                .desc = "Cavium erratum 23154",
 116                .capability = ARM64_WORKAROUND_CAVIUM_23154,
 117                MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
 118        },
 119#endif
 120#ifdef CONFIG_CAVIUM_ERRATUM_27456
 121        {
 122        /* Cavium ThunderX, T88 pass 1.x - 2.1 */
 123                .desc = "Cavium erratum 27456",
 124                .capability = ARM64_WORKAROUND_CAVIUM_27456,
 125                MIDR_RANGE(MIDR_THUNDERX,
 126                           MIDR_CPU_VAR_REV(0, 0),
 127                           MIDR_CPU_VAR_REV(1, 1)),
 128        },
 129        {
 130        /* Cavium ThunderX, T81 pass 1.0 */
 131                .desc = "Cavium erratum 27456",
 132                .capability = ARM64_WORKAROUND_CAVIUM_27456,
 133                MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x00),
 134        },
 135#endif
 136#ifdef CONFIG_CAVIUM_ERRATUM_30115
 137        {
 138        /* Cavium ThunderX, T88 pass 1.x - 2.2 */
 139                .desc = "Cavium erratum 30115",
 140                .capability = ARM64_WORKAROUND_CAVIUM_30115,
 141                MIDR_RANGE(MIDR_THUNDERX, 0x00,
 142                           (1 << MIDR_VARIANT_SHIFT) | 2),
 143        },
 144        {
 145        /* Cavium ThunderX, T81 pass 1.0 - 1.2 */
 146                .desc = "Cavium erratum 30115",
 147                .capability = ARM64_WORKAROUND_CAVIUM_30115,
 148                MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x02),
 149        },
 150        {
 151        /* Cavium ThunderX, T83 pass 1.0 */
 152                .desc = "Cavium erratum 30115",
 153                .capability = ARM64_WORKAROUND_CAVIUM_30115,
 154                MIDR_RANGE(MIDR_THUNDERX_83XX, 0x00, 0x00),
 155        },
 156#endif
 157        {
 158                .desc = "Mismatched cache line size",
 159                .capability = ARM64_MISMATCHED_CACHE_LINE_SIZE,
 160                .matches = has_mismatched_cache_line_size,
 161                .def_scope = SCOPE_LOCAL_CPU,
 162                .enable = cpu_enable_trap_ctr_access,
 163        },
 164#ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003
 165        {
 166                .desc = "Qualcomm Technologies Falkor erratum 1003",
 167                .capability = ARM64_WORKAROUND_QCOM_FALKOR_E1003,
 168                MIDR_RANGE(MIDR_QCOM_FALKOR_V1,
 169                           MIDR_CPU_VAR_REV(0, 0),
 170                           MIDR_CPU_VAR_REV(0, 0)),
 171        },
 172#endif
 173#ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009
 174        {
 175                .desc = "Qualcomm Technologies Falkor erratum 1009",
 176                .capability = ARM64_WORKAROUND_REPEAT_TLBI,
 177                MIDR_RANGE(MIDR_QCOM_FALKOR_V1,
 178                           MIDR_CPU_VAR_REV(0, 0),
 179                           MIDR_CPU_VAR_REV(0, 0)),
 180        },
 181#endif
 182#ifdef CONFIG_ARM64_ERRATUM_858921
 183        {
 184        /* Cortex-A73 all versions */
 185                .desc = "ARM erratum 858921",
 186                .capability = ARM64_WORKAROUND_858921,
 187                MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
 188        },
 189#endif
 190        {
 191        }
 192};
 193
 194/*
 195 * The CPU Errata work arounds are detected and applied at boot time
 196 * and the related information is freed soon after. If the new CPU requires
 197 * an errata not detected at boot, fail this CPU.
 198 */
 199void verify_local_cpu_errata_workarounds(void)
 200{
 201        const struct arm64_cpu_capabilities *caps = arm64_errata;
 202
 203        for (; caps->matches; caps++)
 204                if (!cpus_have_cap(caps->capability) &&
 205                        caps->matches(caps, SCOPE_LOCAL_CPU)) {
 206                        pr_crit("CPU%d: Requires work around for %s, not detected"
 207                                        " at boot time\n",
 208                                smp_processor_id(),
 209                                caps->desc ? : "an erratum");
 210                        cpu_die_early();
 211                }
 212}
 213
 214void update_cpu_errata_workarounds(void)
 215{
 216        update_cpu_capabilities(arm64_errata, "enabling workaround for");
 217}
 218
 219void __init enable_errata_workarounds(void)
 220{
 221        enable_cpu_capabilities(arm64_errata);
 222}
 223