[PATCH] ARM: cacheflush: consolidate single-CPU ARMv7 cache disabling code

Nicolas Pitre nicolas.pitre at linaro.org
Fri Oct 18 16:25:47 EDT 2013


On Fri, 18 Oct 2013, Dave Martin wrote:

> On Tue, Oct 15, 2013 at 11:34:46PM -0400, Nicolas Pitre wrote:
> > 
> > This code is becoming duplicated in many places.  So let's consolidate
> > it into a handy macro that is known to be right and available for reuse.
> > 
> > Signed-off-by: Nicolas Pitre <nico at linaro.org>
> > ---
> > 
> > I forgot which version this one is.  As far as I know, I've incorporated 
> > most review comments, and ignored conflicting ones which tended to look 
> > like bikeshedding and attempted to compensate for them with additional 
> 
> Whoever can you be referring to? :)

Who knows... ;-)

> I think the discussion about whether there was some way to improve this
> was worth having ... but the answer definitely seemed to be no.

Certainly.

> > code comments.
> > 
> > ACK?
> > 
> >  arch/arm/include/asm/cacheflush.h | 45 +++++++++++++++++++++++++++++++
> >  arch/arm/mach-vexpress/dcscb.c    | 56 +++------------------------------------
> >  arch/arm/mach-vexpress/tc2_pm.c   | 48 ++-------------------------------
> >  3 files changed, 51 insertions(+), 98 deletions(-)
> > 
> > diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
> > index 15f2d5bf88..60a0a79b1a 100644
> > --- a/arch/arm/include/asm/cacheflush.h
> > +++ b/arch/arm/include/asm/cacheflush.h
> > @@ -435,4 +435,49 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size)
> >  #define sync_cache_w(ptr) __sync_cache_range_w(ptr, sizeof *(ptr))
> >  #define sync_cache_r(ptr) __sync_cache_range_r(ptr, sizeof *(ptr))
> >  
> > +/*
> > + * Disabling cache access for one CPU in an ARMv7 SMP system is tricky.
> > + * To do so we must:
> > + *
> > + * - Clear the SCTLR.C bit to prevent further cache allocations
> > + * - Flush the desired level of cache
> > + * - Clear the ACTLR "SMP" bit to disable local coherency
> > + *
> > + * ... and so without any intervening memory access in between those steps,
> > + * not even to the stack.
> > + *
> > + * WARNING -- After this has been called:
> > + *
> > + * - No ldrex/strex (and similar) instructions must be used.
> > + * - The CPU is obviously no longer coherent with the other CPUs.
> > + * - This is unlikely to work as expected if Linux is running non-secure.
> > + *
> > + * Note:
> > + *
> > + * - This is known to apply to several ARMv7 processor implementations,
> > + *   however some exceptions may exist.  Caveat emptor.
> 
> Is it worth listing CPUs for which we know this works?  (i.e., A15, A7)
> That could get misleading if the list is not kept up to date, though.

That's what I think.  And some people would interpret it as "this works 
only for A15 and A7".



> 
> > + *
> > + * - The clobber list is dictated by the call to v7_flush_dcache_*.
> > + *   fp is preserved to the stack explicitly prior disabling the cache
> > + *   since adding it to the clobber list is incompatible with having
> > + *   CONFIG_FRAME_POINTER=y.
> > + */
> > +#define v7_exit_coherency_flush(level) \
> > +	asm volatile( \
> > +	"str	fp, [sp, #-4]! \n\t" \
> > +	"mrc	p15, 0, r0, c1, c0, 0	@ get SCTLR \n\t" \
> > +	"bic	r0, r0, #"__stringify(CR_C)" \n\t" \
> > +	"mcr	p15, 0, r0, c1, c0, 0	@ set SCTLR \n\t" \
> > +	"isb	\n\t" \
> > +	"bl	v7_flush_dcache_"__stringify(level)" \n\t" \
> > +	"clrex	\n\t" \
> > +	"mrc	p15, 0, r0, c1, c0, 1	@ get ACTLR \n\t" \
> > +	"bic	r0, r0, #(1 << 6)	@ disable local coherency \n\t" \
> > +	"mcr	p15, 0, r0, c1, c0, 1	@ set ACTLR \n\t" \
> > +	"isb	\n\t" \
> > +	"dsb	\n\t" \
> > +	"ldr	fp, [sp], #4" \
> > +	: : : "r0","r1","r2","r3","r4","r5","r6","r7", \
> > +	      "r9","r10","lr","memory" )
> 
> Should we put r12 in the clobber list too?
> 
> I think that the linker shouldn't introduce an r12-clobbering trampoline
> in practice unless the kernel text gets big (>16MB), but if we can add
> it here without the compiler complaining about register pressuse it might
> save some debugging headaches in the future.

OK.  I'll just save it on the stack alongside fp.


Nicolas
> With that change (or a reason not to do it), Ack.

Thanks.


Nicolas



More information about the linux-arm-kernel mailing list