aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2013-07-30 07:38:45 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-07-31 06:12:59 -0400
commit067e710b9a982a92cc8294d7fa0f1e924c65bba1 (patch)
treee452b342468aae990be5bfc28062d082ab643622 /arch/arm
parentbed859c1eea89feaba2acbb57d967a6d6f68af09 (diff)
ARM: 7801/1: v6: prevent gcc 4.5 from reordering extended CP15 reads above is_smp() test
Commit 621a0147d5c921f4cc33636ccd0602ad5d7cbfbc ("ARM: 7757/1: mm: don't flush icache in switch_mm with hardware broadcasting") breaks the boot on OMAP2430SDP with omap2plus_defconfig. Tracked to an undefined instruction abort from the CP15 read in cache_ops_need_broadcast(). It turns out that gcc 4.5 reorders the extended CP15 read above the is_smp() test. This breaks ARM1136 r0 cores, since they don't support several CP15 registers that later ARM cores do. ARM1136JF-S TRM section 3.2.1 "Register allocation" has the details. So mark the extended CP15 read as clobbering memory, which prevents the compiler from reordering it before the is_smp() test. Russell states that the code generated from this approach is preferable to marking the inline asm as volatile. Remove the existing condition code clobber as it's obsolete, per Nico's post: http://www.spinics.net/lists/arm-kernel/msg261208.html This patch is a collaboration with Will Deacon and Russell King. Comments from Paul Walmsley: Russell, if you accept this one, might you also add Will's ack from the lists: Comments from Paul Walmsley: I'd also be obliged if you could add a Cc: line for Jonathan Austin, since he helped test: Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Tony Lindgren <tony@atomide.com> Acked-by: Will Deacon <will.deacon@arm.com> Cc: Jonathan Austin <jonathan.austin@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/include/asm/cputype.h7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index 8c25dc4e9851..9672e978d50d 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -89,13 +89,18 @@ extern unsigned int processor_id;
89 __val; \ 89 __val; \
90 }) 90 })
91 91
92/*
93 * The memory clobber prevents gcc 4.5 from reordering the mrc before
94 * any is_smp() tests, which can cause undefined instruction aborts on
95 * ARM1136 r0 due to the missing extended CP15 registers.
96 */
92#define read_cpuid_ext(ext_reg) \ 97#define read_cpuid_ext(ext_reg) \
93 ({ \ 98 ({ \
94 unsigned int __val; \ 99 unsigned int __val; \
95 asm("mrc p15, 0, %0, c0, " ext_reg \ 100 asm("mrc p15, 0, %0, c0, " ext_reg \
96 : "=r" (__val) \ 101 : "=r" (__val) \
97 : \ 102 : \
98 : "cc"); \ 103 : "memory"); \
99 __val; \ 104 __val; \
100 }) 105 })
101 106