]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.0.23/arm-7321-1-cache-v7-disable-preemption-when-reading-ccsidr.patch
Fix up backported ptrace patch
[thirdparty/kernel/stable-queue.git] / releases / 3.0.23 / arm-7321-1-cache-v7-disable-preemption-when-reading-ccsidr.patch
CommitLineData
f2d4c738
GKH
1From b46c0f74657d1fe1c1b0c1452631cc38a9e6987f Mon Sep 17 00:00:00 2001
2From: Stephen Boyd <sboyd@codeaurora.org>
3Date: Tue, 7 Feb 2012 19:42:07 +0100
4Subject: ARM: 7321/1: cache-v7: Disable preemption when reading CCSIDR
5
6From: Stephen Boyd <sboyd@codeaurora.org>
7
8commit b46c0f74657d1fe1c1b0c1452631cc38a9e6987f upstream.
9
10armv7's flush_cache_all() flushes caches via set/way. To
11determine the cache attributes (line size, number of sets,
12etc.) the assembly first writes the CSSELR register to select a
13cache level and then reads the CCSIDR register. The CSSELR register
14is banked per-cpu and is used to determine which cache level CCSIDR
15reads. If the task is migrated between when the CSSELR is written and
16the CCSIDR is read the CCSIDR value may be for an unexpected cache
17level (for example L1 instead of L2) and incorrect cache flushing
18could occur.
19
20Disable interrupts across the write and read so that the correct
21cache attributes are read and used for the cache flushing
22routine. We disable interrupts instead of disabling preemption
23because the critical section is only 3 instructions and we want
24to call v7_dcache_flush_all from __v7_setup which doesn't have a
25full kernel stack with a struct thread_info.
26
27This fixes a problem we see in scm_call() when flush_cache_all()
28is called from preemptible context and sometimes the L2 cache is
29not properly flushed out.
30
31Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
32Acked-by: Catalin Marinas <catalin.marinas@arm.com>
33Reviewed-by: Nicolas Pitre <nico@linaro.org>
34Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
35Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
36
37---
38 arch/arm/mm/cache-v7.S | 6 ++++++
39 1 file changed, 6 insertions(+)
40
41--- a/arch/arm/mm/cache-v7.S
42+++ b/arch/arm/mm/cache-v7.S
43@@ -54,9 +54,15 @@ loop1:
44 and r1, r1, #7 @ mask of the bits for current cache only
45 cmp r1, #2 @ see what cache we have at this level
46 blt skip @ skip if no cache, or just i-cache
47+#ifdef CONFIG_PREEMPT
48+ save_and_disable_irqs r9 @ make cssr&csidr read atomic
49+#endif
50 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
51 isb @ isb to sych the new cssr&csidr
52 mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
53+#ifdef CONFIG_PREEMPT
54+ restore_irqs_notrace r9
55+#endif
56 and r2, r1, #7 @ extract the length of the cache lines
57 add r2, r2, #4 @ add 4 (line length offset)
58 ldr r4, =0x3ff