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 | |
| 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>
| -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 aa4f62f0e37..e48cc22724d 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 | /* |
