]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - 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
1 From b46c0f74657d1fe1c1b0c1452631cc38a9e6987f Mon Sep 17 00:00:00 2001
2 From: Stephen Boyd <sboyd@codeaurora.org>
3 Date: Tue, 7 Feb 2012 19:42:07 +0100
4 Subject: ARM: 7321/1: cache-v7: Disable preemption when reading CCSIDR
5
6 From: Stephen Boyd <sboyd@codeaurora.org>
7
8 commit b46c0f74657d1fe1c1b0c1452631cc38a9e6987f upstream.
9
10 armv7's flush_cache_all() flushes caches via set/way. To
11 determine the cache attributes (line size, number of sets,
12 etc.) the assembly first writes the CSSELR register to select a
13 cache level and then reads the CCSIDR register. The CSSELR register
14 is banked per-cpu and is used to determine which cache level CCSIDR
15 reads. If the task is migrated between when the CSSELR is written and
16 the CCSIDR is read the CCSIDR value may be for an unexpected cache
17 level (for example L1 instead of L2) and incorrect cache flushing
18 could occur.
19
20 Disable interrupts across the write and read so that the correct
21 cache attributes are read and used for the cache flushing
22 routine. We disable interrupts instead of disabling preemption
23 because the critical section is only 3 instructions and we want
24 to call v7_dcache_flush_all from __v7_setup which doesn't have a
25 full kernel stack with a struct thread_info.
26
27 This fixes a problem we see in scm_call() when flush_cache_all()
28 is called from preemptible context and sometimes the L2 cache is
29 not properly flushed out.
30
31 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
32 Acked-by: Catalin Marinas <catalin.marinas@arm.com>
33 Reviewed-by: Nicolas Pitre <nico@linaro.org>
34 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
35 Signed-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