commit 4c4a39dd5fe2d13e2d2fa5fceb8ef95d19fc389a upstream
If there is a mismatch in the I/D min line size, we must always use the system wide safe value both in applications and in the kernel, while performing cache operations. However, we have been checking more bits than just the min line sizes, which triggers false negatives. We may need to trap the user accesses in such cases, but not necessarily patch the kernel.
This patch fixes the check to do the right thing as advertised. A new capability will be added to check mismatches in other fields and ensure we trap the CTR accesses.
Fixes: be68a8aaf925 ("arm64: cpufeature: Fix CTR_EL0 field definitions") Cc: stable@vger.kernel.org # v4.9 Cc: Mark Rutland mark.rutland@arm.com Cc: Catalin Marinas catalin.marinas@arm.com Reported-by: Will Deacon will.deacon@arm.com Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Signed-off-by: Will Deacon will.deacon@arm.com --- arch/arm64/include/asm/cachetype.h | 5 +++++ arch/arm64/kernel/cpu_errata.c | 7 +++++-- arch/arm64/kernel/cpufeature.c | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/cachetype.h b/arch/arm64/include/asm/cachetype.h index f558869..877d478 100644 --- a/arch/arm64/include/asm/cachetype.h +++ b/arch/arm64/include/asm/cachetype.h @@ -22,6 +22,11 @@ #define CTR_L1IP_MASK 3 #define CTR_CWG_SHIFT 24 #define CTR_CWG_MASK 15 +#define CTR_DMINLINE_SHIFT 16 +#define CTR_IMINLINE_SHIFT 0 + +#define CTR_CACHE_MINLINE_MASK \ + ((0xf << CTR_DMINLINE_SHIFT) | (0xf << CTR_IMINLINE_SHIFT))
#define ICACHE_POLICY_RESERVED 0 #define ICACHE_POLICY_AIVIVT 1 diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 1db97ad..fe604bb 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -17,6 +17,7 @@ */
#include <linux/types.h> +#include <asm/cachetype.h> #include <asm/cpu.h> #include <asm/cputype.h> #include <asm/cpufeature.h> @@ -34,9 +35,11 @@ static bool has_mismatched_cache_line_size(const struct arm64_cpu_capabilities *entry, int scope) { + u64 mask = CTR_CACHE_MINLINE_MASK; + WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); - return (read_cpuid_cachetype() & arm64_ftr_reg_ctrel0.strict_mask) != - (arm64_ftr_reg_ctrel0.sys_val & arm64_ftr_reg_ctrel0.strict_mask); + return (read_cpuid_cachetype() & mask) != + (arm64_ftr_reg_ctrel0.sys_val & mask); }
static int cpu_enable_trap_ctr_access(void *__unused) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index ab15747..a3ab7df 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -152,7 +152,7 @@ static const struct arm64_ftr_bits ftr_ctr[] = { ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 3, 0), ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0), /* CWG */ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), /* ERG */ - ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */ + ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, CTR_DMINLINE_SHIFT, 4, 1), /* * Linux can handle differing I-cache policies. Userspace JITs will * make use of *minLine. @@ -160,7 +160,7 @@ static const struct arm64_ftr_bits ftr_ctr[] = { */ ARM64_FTR_BITS(FTR_NONSTRICT, FTR_EXACT, 14, 2, ICACHE_POLICY_AIVIVT), /* L1Ip */ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 10, 0), /* RAZ */ - ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* IminLine */ + ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, CTR_IMINLINE_SHIFT, 4, 0), ARM64_FTR_END, };
commit 314d53d297980676011e6fd83dac60db4a01dc70 upstream
Track mismatches in the cache type register (CTR_EL0), other than the D/I min line sizes and trap user accesses if there are any.
Fixes: be68a8aaf925 ("arm64: cpufeature: Fix CTR_EL0 field definitions") Cc: stable@vger.kernel.org # v4.9 Cc: Mark Rutland mark.rutland@arm.com Cc: Will Deacon will.deacon@arm.com Cc: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- arch/arm64/include/asm/cpucaps.h | 3 ++- arch/arm64/kernel/cpu_errata.c | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index 7010779a..8c7c4b2 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -37,7 +37,8 @@ #define ARM64_UNMAP_KERNEL_AT_EL0 16 #define ARM64_HARDEN_BRANCH_PREDICTOR 17 #define ARM64_SSBD 18 +#define ARM64_MISMATCHED_CACHE_TYPE 19
-#define ARM64_NCAPS 19 +#define ARM64_NCAPS 20
#endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index fe604bb..930e74d 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -32,11 +32,15 @@ is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope) }
static bool -has_mismatched_cache_line_size(const struct arm64_cpu_capabilities *entry, - int scope) +has_mismatched_cache_type(const struct arm64_cpu_capabilities *entry, + int scope) { u64 mask = CTR_CACHE_MINLINE_MASK;
+ /* Skip matching the min line sizes for cache type check */ + if (entry->capability == ARM64_MISMATCHED_CACHE_TYPE) + mask ^= arm64_ftr_reg_ctrel0.strict_mask; + WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); return (read_cpuid_cachetype() & mask) != (arm64_ftr_reg_ctrel0.sys_val & mask); @@ -449,7 +453,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { { .desc = "Mismatched cache line size", .capability = ARM64_MISMATCHED_CACHE_LINE_SIZE, - .matches = has_mismatched_cache_line_size, + .matches = has_mismatched_cache_type, + .def_scope = SCOPE_LOCAL_CPU, + .enable = cpu_enable_trap_ctr_access, + }, + { + .desc = "Mismatched cache type", + .capability = ARM64_MISMATCHED_CACHE_TYPE, + .matches = has_mismatched_cache_type, .def_scope = SCOPE_LOCAL_CPU, .enable = cpu_enable_trap_ctr_access, },
On Tue, Sep 04, 2018 at 10:10:10AM +0100, Suzuki K Poulose wrote:
commit 314d53d297980676011e6fd83dac60db4a01dc70 upstream
Track mismatches in the cache type register (CTR_EL0), other than the D/I min line sizes and trap user accesses if there are any.
Fixes: be68a8aaf925 ("arm64: cpufeature: Fix CTR_EL0 field definitions") Cc: stable@vger.kernel.org # v4.9
Same 4.9 question here as well.
thanks,
greg k-h
On Tue, Sep 04, 2018 at 10:10:09AM +0100, Suzuki K Poulose wrote:
commit 4c4a39dd5fe2d13e2d2fa5fceb8ef95d19fc389a upstream
If there is a mismatch in the I/D min line size, we must always use the system wide safe value both in applications and in the kernel, while performing cache operations. However, we have been checking more bits than just the min line sizes, which triggers false negatives. We may need to trap the user accesses in such cases, but not necessarily patch the kernel.
This patch fixes the check to do the right thing as advertised. A new capability will be added to check mismatches in other fields and ensure we trap the CTR accesses.
Fixes: be68a8aaf925 ("arm64: cpufeature: Fix CTR_EL0 field definitions") Cc: stable@vger.kernel.org # v4.9
Why 4.9? be68a8aaf925 only showed up in 4.16 and was backported only to 4.14-stable. Not to 4.9-stable from what I can tell.
thanks,
greg k-h
Hi Greg,
On 12/09/18 20:38, Greg KH wrote:
On Tue, Sep 04, 2018 at 10:10:09AM +0100, Suzuki K Poulose wrote:
commit 4c4a39dd5fe2d13e2d2fa5fceb8ef95d19fc389a upstream
If there is a mismatch in the I/D min line size, we must always use the system wide safe value both in applications and in the kernel, while performing cache operations. However, we have been checking more bits than just the min line sizes, which triggers false negatives. We may need to trap the user accesses in such cases, but not necessarily patch the kernel.
This patch fixes the check to do the right thing as advertised. A new capability will be added to check mismatches in other fields and ensure we trap the CTR accesses.
Fixes: be68a8aaf925 ("arm64: cpufeature: Fix CTR_EL0 field definitions") Cc: stable@vger.kernel.org # v4.9
Why 4.9? be68a8aaf925 only showed up in 4.16 and was backported only to 4.14-stable. Not to 4.9-stable from what I can tell.
Now when you asked this, I realise that the Fixes tags were not sufficient.
Actually this series fixes a bit more than the commit: be68a8aaf925 ("arm64: cpufeature: Fix CTR_EL0 field definitions"). I think these patches should have :
Fixes: commit 116c81f427ff6c5 ("arm64: Work around systems with mismatched cache line sizes")
and
Enable trapping on mismatched bits in CTR for IDC/DIC, which were added to v8.3 onwards.
Essentially these patches makes sure that we trap accesses to CTR_EL0 when some of the fields are mismatched across CPUs, so that the CPUs get a consistent view of the cache properties throughout the system. It also makes sure that we put out correct information about why we trap accesses to the CTR_EL0 accesses from the userspace.
Hope this helps. The same applies for the next patch.
Suzuki
On Thu, Sep 13, 2018 at 10:54:06AM +0100, Suzuki K Poulose wrote:
Hi Greg,
On 12/09/18 20:38, Greg KH wrote:
On Tue, Sep 04, 2018 at 10:10:09AM +0100, Suzuki K Poulose wrote:
commit 4c4a39dd5fe2d13e2d2fa5fceb8ef95d19fc389a upstream
If there is a mismatch in the I/D min line size, we must always use the system wide safe value both in applications and in the kernel, while performing cache operations. However, we have been checking more bits than just the min line sizes, which triggers false negatives. We may need to trap the user accesses in such cases, but not necessarily patch the kernel.
This patch fixes the check to do the right thing as advertised. A new capability will be added to check mismatches in other fields and ensure we trap the CTR accesses.
Fixes: be68a8aaf925 ("arm64: cpufeature: Fix CTR_EL0 field definitions") Cc: stable@vger.kernel.org # v4.9
Why 4.9? be68a8aaf925 only showed up in 4.16 and was backported only to 4.14-stable. Not to 4.9-stable from what I can tell.
Now when you asked this, I realise that the Fixes tags were not sufficient.
Actually this series fixes a bit more than the commit: be68a8aaf925 ("arm64: cpufeature: Fix CTR_EL0 field definitions"). I think these patches should have :
Fixes: commit 116c81f427ff6c5 ("arm64: Work around systems with mismatched cache line sizes")
and
Enable trapping on mismatched bits in CTR for IDC/DIC, which were added to v8.3 onwards.
Essentially these patches makes sure that we trap accesses to CTR_EL0 when some of the fields are mismatched across CPUs, so that the CPUs get a consistent view of the cache properties throughout the system. It also makes sure that we put out correct information about why we trap accesses to the CTR_EL0 accesses from the userspace.
Hope this helps. The same applies for the next patch.
Yes, it does help. But these patches do not apply to the 4.14.y series, which I also need to apply them to (you don't want to move from 4.9.y to 4.14.y and get a regression.)
So can you provide backports for both of these patches for 4.14.y? Then I would be glad to queue these all up.
thanks,
greg k-h
On Thu, Sep 13, 2018 at 02:19:51PM +0200, Greg KH wrote:
On Thu, Sep 13, 2018 at 10:54:06AM +0100, Suzuki K Poulose wrote:
Hi Greg,
On 12/09/18 20:38, Greg KH wrote:
On Tue, Sep 04, 2018 at 10:10:09AM +0100, Suzuki K Poulose wrote:
commit 4c4a39dd5fe2d13e2d2fa5fceb8ef95d19fc389a upstream
If there is a mismatch in the I/D min line size, we must always use the system wide safe value both in applications and in the kernel, while performing cache operations. However, we have been checking more bits than just the min line sizes, which triggers false negatives. We may need to trap the user accesses in such cases, but not necessarily patch the kernel.
This patch fixes the check to do the right thing as advertised. A new capability will be added to check mismatches in other fields and ensure we trap the CTR accesses.
Fixes: be68a8aaf925 ("arm64: cpufeature: Fix CTR_EL0 field definitions") Cc: stable@vger.kernel.org # v4.9
Why 4.9? be68a8aaf925 only showed up in 4.16 and was backported only to 4.14-stable. Not to 4.9-stable from what I can tell.
Now when you asked this, I realise that the Fixes tags were not sufficient.
Actually this series fixes a bit more than the commit: be68a8aaf925 ("arm64: cpufeature: Fix CTR_EL0 field definitions"). I think these patches should have :
Fixes: commit 116c81f427ff6c5 ("arm64: Work around systems with mismatched cache line sizes")
and
Enable trapping on mismatched bits in CTR for IDC/DIC, which were added to v8.3 onwards.
Essentially these patches makes sure that we trap accesses to CTR_EL0 when some of the fields are mismatched across CPUs, so that the CPUs get a consistent view of the cache properties throughout the system. It also makes sure that we put out correct information about why we trap accesses to the CTR_EL0 accesses from the userspace.
Hope this helps. The same applies for the next patch.
Yes, it does help. But these patches do not apply to the 4.14.y series, which I also need to apply them to (you don't want to move from 4.9.y to 4.14.y and get a regression.)
So can you provide backports for both of these patches for 4.14.y? Then I would be glad to queue these all up.
Oh nevermind, I found those patches in my queue, you already sent them!
sorry for the noise.
greg k-h
linux-stable-mirror@lists.linaro.org