Commit 8ab66cbe authored by Suzuki K Poulose's avatar Suzuki K Poulose Committed by Catalin Marinas
Browse files

arm64: cpufeature: ctr: Fix cpu capability check for late CPUs



The matches() routine for a capability must honor the "scope"
passed to it and return the proper results.
i.e, when passed with SCOPE_LOCAL_CPU, it should check the
status of the capability on the current CPU. This is used by
verify_local_cpu_capabilities() on a late secondary CPU to make
sure that it's compliant with the established system features.
However, ARM64_HAS_CACHE_{IDC/DIC} always checks the system wide
registers and this could mean that a late secondary CPU could return
"true" (since the CPU hasn't updated the system wide registers yet)
and thus lead the system in an inconsistent state, where
the system assumes it has IDC/DIC feature, while the new CPU
doesn't.

Fixes: commit 6ae4b6e0 ("arm64: Add support for new control bits CTR_EL0.DIC and CTR_EL0.IDC")
Cc: Philip Elcan <pelcan@codeaurora.org>
Cc: Shanker Donthineni <shankerd@codeaurora.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 0c09d485
Loading
Loading
Loading
Loading
+18 −4
Original line number Original line Diff line number Diff line
@@ -854,15 +854,29 @@ static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unus
}
}


static bool has_cache_idc(const struct arm64_cpu_capabilities *entry,
static bool has_cache_idc(const struct arm64_cpu_capabilities *entry,
			  int __unused)
			  int scope)
{
{
	return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_IDC_SHIFT);
	u64 ctr;

	if (scope == SCOPE_SYSTEM)
		ctr = arm64_ftr_reg_ctrel0.sys_val;
	else
		ctr = read_cpuid_cachetype();

	return ctr & BIT(CTR_IDC_SHIFT);
}
}


static bool has_cache_dic(const struct arm64_cpu_capabilities *entry,
static bool has_cache_dic(const struct arm64_cpu_capabilities *entry,
			  int __unused)
			  int scope)
{
{
	return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_DIC_SHIFT);
	u64 ctr;

	if (scope == SCOPE_SYSTEM)
		ctr = arm64_ftr_reg_ctrel0.sys_val;
	else
		ctr = read_cpuid_cachetype();

	return ctr & BIT(CTR_DIC_SHIFT);
}
}


static bool __maybe_unused
static bool __maybe_unused