diff options
author | Marc Zyngier <maz@kernel.org> | 2021-04-08 14:10:08 +0100 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2021-04-08 18:45:16 +0100 |
commit | cac642c12a805ae7565a263b59fb94ad19e81952 (patch) | |
tree | e963376e62f64f656a5750b3cc5a28788f432480 /arch/arm64/kernel/idreg-override.c | |
parent | 1e28eed17697bcf343c6743f0028cc3b5dd88bf0 (diff) | |
download | linux-stable-cac642c12a805ae7565a263b59fb94ad19e81952.tar.gz linux-stable-cac642c12a805ae7565a263b59fb94ad19e81952.tar.bz2 linux-stable-cac642c12a805ae7565a263b59fb94ad19e81952.zip |
arm64: cpufeature: Allow early filtering of feature override
Some CPUs are broken enough that some overrides need to be rejected
at the earliest opportunity. In some cases, that's right at cpu
feature override time.
Provide the necessary infrastructure to filter out overrides,
and to report such filtered out overrides to the core cpufeature code.
Acked-by: Will Deacon <will@kernel.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20210408131010.1109027-2-maz@kernel.org
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/idreg-override.c')
-rw-r--r-- | arch/arm64/kernel/idreg-override.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c index 83f1c4b92095..be92fcd319a1 100644 --- a/arch/arm64/kernel/idreg-override.c +++ b/arch/arm64/kernel/idreg-override.c @@ -25,6 +25,7 @@ struct ftr_set_desc { struct { char name[FTR_DESC_FIELD_LEN]; u8 shift; + bool (*filter)(u64 val); } fields[]; }; @@ -124,6 +125,18 @@ static void __init match_options(const char *cmdline) if (find_field(cmdline, regs[i], f, &v)) continue; + /* + * If an override gets filtered out, advertise + * it by setting the value to 0xf, but + * clearing the mask... Yes, this is fragile. + */ + if (regs[i]->fields[f].filter && + !regs[i]->fields[f].filter(v)) { + regs[i]->override->val |= mask; + regs[i]->override->mask &= ~mask; + continue; + } + regs[i]->override->val &= ~mask; regs[i]->override->val |= (v << shift) & mask; regs[i]->override->mask |= mask; |