diff options
author | Paul Mundt <lethal@linux-sh.org> | 2006-09-27 05:37:30 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2006-09-27 05:37:30 -0400 |
commit | 33573c0e3243aaa38b6ad96942de85a1b713c2ff (patch) | |
tree | 977c71557e8c1603ac4934db2d3ceb5535826701 /arch/sh | |
parent | f3c2575818fab45f8609e4aef2e43ab02b3a142e (diff) |
sh: Fix occasional flush_cache_4096() stack corruption.
IRQs disabling in flush_cache_4096 for cache purge. Under certain
workloads we would get an IRQ in the middle of a purge operation,
and the cachelines would remain in an inconsistent state, leading
to occasional stack corruption.
Signed-off-by: Takeo Takahashi <takahashi.takeo@renesas.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/mm/cache-sh4.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index aa4f62f0e374..e48cc22724d9 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c | |||
@@ -221,22 +221,20 @@ void flush_cache_sigtramp(unsigned long addr) | |||
221 | static inline void flush_cache_4096(unsigned long start, | 221 | static inline void flush_cache_4096(unsigned long start, |
222 | unsigned long phys) | 222 | unsigned long phys) |
223 | { | 223 | { |
224 | unsigned long flags, exec_offset = 0; | ||
225 | |||
224 | /* | 226 | /* |
225 | * All types of SH-4 require PC to be in P2 to operate on the I-cache. | 227 | * All types of SH-4 require PC to be in P2 to operate on the I-cache. |
226 | * Some types of SH-4 require PC to be in P2 to operate on the D-cache. | 228 | * Some types of SH-4 require PC to be in P2 to operate on the D-cache. |
227 | */ | 229 | */ |
228 | if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) || | 230 | if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) || |
229 | (start < CACHE_OC_ADDRESS_ARRAY)) { | 231 | (start < CACHE_OC_ADDRESS_ARRAY)) |
230 | unsigned long flags; | 232 | exec_offset = 0x20000000; |
231 | 233 | ||
232 | local_irq_save(flags); | 234 | local_irq_save(flags); |
233 | __flush_cache_4096(start | SH_CACHE_ASSOC, | 235 | __flush_cache_4096(start | SH_CACHE_ASSOC, |
234 | P1SEGADDR(phys), 0x20000000); | 236 | P1SEGADDR(phys), exec_offset); |
235 | local_irq_restore(flags); | 237 | local_irq_restore(flags); |
236 | } else { | ||
237 | __flush_cache_4096(start | SH_CACHE_ASSOC, | ||
238 | P1SEGADDR(phys), 0); | ||
239 | } | ||
240 | } | 238 | } |
241 | 239 | ||
242 | /* | 240 | /* |