arm64/errata: add REVIDR handling to framework
In some cases, core variants that are affected by a certain erratum also exist in versions that have the erratum fixed, and this fact is recorded in a dedicated bit in system register REVIDR_EL1. Since the architecture does not require that a certain bit retains its meaning across different variants of the same model, each such REVIDR bit is tightly coupled to a certain revision/variant value, and so we need a list of revidr_mask/midr pairs to carry this information. So add the struct member and the associated macros and handling to allow REVIDR fixes to be taken into account. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
parent
a257e02579
commit
e8002e02ab
|
@ -105,6 +105,10 @@ struct arm64_cpu_capabilities {
|
|||
struct { /* To be used for erratum handling only */
|
||||
u32 midr_model;
|
||||
u32 midr_range_min, midr_range_max;
|
||||
const struct arm64_midr_revidr {
|
||||
u32 midr_rv; /* revision/variant */
|
||||
u32 revidr_mask;
|
||||
} * const fixed_revs;
|
||||
};
|
||||
|
||||
struct { /* Feature register checking */
|
||||
|
|
|
@ -24,10 +24,22 @@
|
|||
static bool __maybe_unused
|
||||
is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
|
||||
{
|
||||
const struct arm64_midr_revidr *fix;
|
||||
u32 midr = read_cpuid_id(), revidr;
|
||||
|
||||
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);
|
||||
if (!MIDR_IS_CPU_MODEL_RANGE(midr, entry->midr_model,
|
||||
entry->midr_range_min,
|
||||
entry->midr_range_max))
|
||||
return false;
|
||||
|
||||
midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK;
|
||||
revidr = read_cpuid(REVIDR_EL1);
|
||||
for (fix = entry->fixed_revs; fix && fix->revidr_mask; fix++)
|
||||
if (midr == fix->midr_rv && (revidr & fix->revidr_mask))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __maybe_unused
|
||||
|
@ -242,6 +254,9 @@ static int qcom_enable_link_stack_sanitization(void *data)
|
|||
.midr_range_min = 0, \
|
||||
.midr_range_max = (MIDR_VARIANT_MASK | MIDR_REVISION_MASK)
|
||||
|
||||
#define MIDR_FIXED(rev, revidr_mask) \
|
||||
.fixed_revs = (struct arm64_midr_revidr[]){{ (rev), (revidr_mask) }, {}}
|
||||
|
||||
const struct arm64_cpu_capabilities arm64_errata[] = {
|
||||
#if defined(CONFIG_ARM64_ERRATUM_826319) || \
|
||||
defined(CONFIG_ARM64_ERRATUM_827319) || \
|
||||
|
|
Loading…
Reference in New Issue