Commit b389d799 authored by Mark Rutland's avatar Mark Rutland Committed by Will Deacon

arm64: cpufeature: treat unknown fields as RES0

Any fields not defined in an arm64_ftr_bits entry are propagated to the
system-wide register value in init_cpu_ftr_reg(), and while we require
that these strictly match for the sanity checks, we don't update them in
update_cpu_ftr_reg().

Generally, the lack of an arm64_ftr_bits entry indicates that the bits
are currently RES0 (as is the case for the upper 32 bits of all
supposedly 32-bit registers).

A better default would be to use zero for the system-wide value of
unallocated bits, making all register checking consistent, and allowing
for subsequent simplifications to the arm64_ftr_bits arrays.

This patch updates init_cpu_ftr_reg() to treat unallocated bits as RES0
for the purpose of the system-wide safe value. These bits will still be
sanity checked with strict match requirements, as is currently the case.
Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Reviewed-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent f31deaad
...@@ -415,23 +415,33 @@ static void __init sort_ftr_regs(void) ...@@ -415,23 +415,33 @@ static void __init sort_ftr_regs(void)
/* /*
* Initialise the CPU feature register from Boot CPU values. * Initialise the CPU feature register from Boot CPU values.
* Also initiliases the strict_mask for the register. * Also initiliases the strict_mask for the register.
* Any bits that are not covered by an arm64_ftr_bits entry are considered
* RES0 for the system-wide value, and must strictly match.
*/ */
static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new) static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new)
{ {
u64 val = 0; u64 val = 0;
u64 strict_mask = ~0x0ULL; u64 strict_mask = ~0x0ULL;
u64 valid_mask = 0;
const struct arm64_ftr_bits *ftrp; const struct arm64_ftr_bits *ftrp;
struct arm64_ftr_reg *reg = get_arm64_ftr_reg(sys_reg); struct arm64_ftr_reg *reg = get_arm64_ftr_reg(sys_reg);
BUG_ON(!reg); BUG_ON(!reg);
for (ftrp = reg->ftr_bits; ftrp->width; ftrp++) { for (ftrp = reg->ftr_bits; ftrp->width; ftrp++) {
u64 ftr_mask = arm64_ftr_mask(ftrp);
s64 ftr_new = arm64_ftr_value(ftrp, new); s64 ftr_new = arm64_ftr_value(ftrp, new);
val = arm64_ftr_set_value(ftrp, val, ftr_new); val = arm64_ftr_set_value(ftrp, val, ftr_new);
valid_mask |= ftr_mask;
if (!ftrp->strict) if (!ftrp->strict)
strict_mask &= ~arm64_ftr_mask(ftrp); strict_mask &= ~ftr_mask;
} }
val &= valid_mask;
reg->sys_val = val; reg->sys_val = val;
reg->strict_mask = strict_mask; reg->strict_mask = strict_mask;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment