ARM: 7801/1: v6: prevent gcc 4.5 from reordering extended CP15 reads above is_smp...
authorPaul Walmsley <paul@pwsan.com>
Tue, 30 Jul 2013 11:38:45 +0000 (12:38 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 31 Jul 2013 10:12:59 +0000 (11:12 +0100)
commit067e710b9a982a92cc8294d7fa0f1e924c65bba1
treee452b342468aae990be5bfc28062d082ab643622
parentbed859c1eea89feaba2acbb57d967a6d6f68af09
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>
arch/arm/include/asm/cputype.h