1 |
From e3a67519ffcf03c2a3c36ed7cc41580ddc69f35e Mon Sep 17 00:00:00 2001 |
2 |
From: Suzuki K Poulose <suzuki.poulose@arm.com> |
3 |
Date: Tue, 9 Oct 2018 14:47:05 +0100 |
4 |
Subject: [PATCH 008/145] arm64: cpufeature: ctr: Fix cpu capability check for |
5 |
late CPUs |
6 |
|
7 |
[ Upstream commit 8ab66cbe63aeaf9e5970fb4aaef1c660fca59321 ] |
8 |
|
9 |
The matches() routine for a capability must honor the "scope" |
10 |
passed to it and return the proper results. |
11 |
i.e, when passed with SCOPE_LOCAL_CPU, it should check the |
12 |
status of the capability on the current CPU. This is used by |
13 |
verify_local_cpu_capabilities() on a late secondary CPU to make |
14 |
sure that it's compliant with the established system features. |
15 |
However, ARM64_HAS_CACHE_{IDC/DIC} always checks the system wide |
16 |
registers and this could mean that a late secondary CPU could return |
17 |
"true" (since the CPU hasn't updated the system wide registers yet) |
18 |
and thus lead the system in an inconsistent state, where |
19 |
the system assumes it has IDC/DIC feature, while the new CPU |
20 |
doesn't. |
21 |
|
22 |
Fixes: commit 6ae4b6e0578886eb36 ("arm64: Add support for new control bits CTR_EL0.DIC and CTR_EL0.IDC") |
23 |
Cc: Philip Elcan <pelcan@codeaurora.org> |
24 |
Cc: Shanker Donthineni <shankerd@codeaurora.org> |
25 |
Cc: Mark Rutland <mark.rutland@arm.com> |
26 |
Cc: Will Deacon <will.deacon@arm.com> |
27 |
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> |
28 |
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> |
29 |
Signed-off-by: Sasha Levin <sashal@kernel.org> |
30 |
--- |
31 |
arch/arm64/kernel/cpufeature.c | 22 ++++++++++++++++++---- |
32 |
1 file changed, 18 insertions(+), 4 deletions(-) |
33 |
|
34 |
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c |
35 |
index e238b7932096..93f69d82225d 100644 |
36 |
--- a/arch/arm64/kernel/cpufeature.c |
37 |
+++ b/arch/arm64/kernel/cpufeature.c |
38 |
@@ -848,15 +848,29 @@ static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unus |
39 |
} |
40 |
|
41 |
static bool has_cache_idc(const struct arm64_cpu_capabilities *entry, |
42 |
- int __unused) |
43 |
+ int scope) |
44 |
{ |
45 |
- return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_IDC_SHIFT); |
46 |
+ u64 ctr; |
47 |
+ |
48 |
+ if (scope == SCOPE_SYSTEM) |
49 |
+ ctr = arm64_ftr_reg_ctrel0.sys_val; |
50 |
+ else |
51 |
+ ctr = read_cpuid_cachetype(); |
52 |
+ |
53 |
+ return ctr & BIT(CTR_IDC_SHIFT); |
54 |
} |
55 |
|
56 |
static bool has_cache_dic(const struct arm64_cpu_capabilities *entry, |
57 |
- int __unused) |
58 |
+ int scope) |
59 |
{ |
60 |
- return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_DIC_SHIFT); |
61 |
+ u64 ctr; |
62 |
+ |
63 |
+ if (scope == SCOPE_SYSTEM) |
64 |
+ ctr = arm64_ftr_reg_ctrel0.sys_val; |
65 |
+ else |
66 |
+ ctr = read_cpuid_cachetype(); |
67 |
+ |
68 |
+ return ctr & BIT(CTR_DIC_SHIFT); |
69 |
} |
70 |
|
71 |
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 |
72 |
-- |
73 |
2.19.1 |
74 |
|