Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df71dfd4 authored by Russell King's avatar Russell King
Browse files

ARM: Fix errata 411920 workarounds



Errata 411920 indicates that any "invalidate entire instruction cache"
operation can fail if the right conditions are present.  This is not
limited just to those operations in flush.c, but elsewhere.  Place the
workaround in the already existing __flush_icache_all() function
instead.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 657e12fd
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -414,9 +414,14 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page

static inline void __flush_icache_all(void)
{
#ifdef CONFIG_ARM_ERRATA_411920
	extern void v6_icache_inval_all(void);
	v6_icache_inval_all();
#else
	asm("mcr	p15, 0, %0, c7, c5, 0	@ invalidate I-cache\n"
	    :
	    : "r" (0));
#endif
}

#define ARCH_HAS_FLUSH_ANON_PAGE
+1 −4
Original line number Diff line number Diff line
@@ -50,10 +50,7 @@ void __new_context(struct mm_struct *mm)
		isb();
		flush_tlb_all();
		if (icache_is_vivt_asid_tagged()) {
			asm("mcr	p15, 0, %0, c7, c5, 0	@ invalidate I-cache\n"
			    "mcr	p15, 0, %0, c7, c5, 6	@ flush BTAC/BTB\n"
			    :
			    : "r" (0));
			__flush_icache_all();
			dsb();
		}
	}
+6 −25
Original line number Diff line number Diff line
@@ -18,10 +18,6 @@

#include "mm.h"

#ifdef CONFIG_ARM_ERRATA_411920
extern void v6_icache_inval_all(void);
#endif

#ifdef CONFIG_CPU_CACHE_VIPT

#define ALIAS_FLUSH_START	0xffff4000
@@ -35,16 +31,11 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
	flush_tlb_kernel_page(to);

	asm(	"mcrr	p15, 0, %1, %0, c14\n"
	"	mcr	p15, 0, %2, c7, c10, 4\n"
#ifndef CONFIG_ARM_ERRATA_411920
	"	mcr	p15, 0, %2, c7, c5, 0\n"
#endif
	"	mcr	p15, 0, %2, c7, c10, 4"
	    :
	    : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
	    : "cc");
#ifdef CONFIG_ARM_ERRATA_411920
	v6_icache_inval_all();
#endif
	__flush_icache_all();
}

void flush_cache_mm(struct mm_struct *mm)
@@ -57,16 +48,11 @@ void flush_cache_mm(struct mm_struct *mm)

	if (cache_is_vipt_aliasing()) {
		asm(	"mcr	p15, 0, %0, c7, c14, 0\n"
		"	mcr	p15, 0, %0, c7, c10, 4\n"
#ifndef CONFIG_ARM_ERRATA_411920
		"	mcr	p15, 0, %0, c7, c5, 0\n"
#endif
		"	mcr	p15, 0, %0, c7, c10, 4"
		    :
		    : "r" (0)
		    : "cc");
#ifdef CONFIG_ARM_ERRATA_411920
		v6_icache_inval_all();
#endif
		__flush_icache_all();
	}
}

@@ -81,16 +67,11 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned

	if (cache_is_vipt_aliasing()) {
		asm(	"mcr	p15, 0, %0, c7, c14, 0\n"
		"	mcr	p15, 0, %0, c7, c10, 4\n"
#ifndef CONFIG_ARM_ERRATA_411920
		"	mcr	p15, 0, %0, c7, c5, 0\n"
#endif
		"	mcr	p15, 0, %0, c7, c10, 4"
		    :
		    : "r" (0)
		    : "cc");
#ifdef CONFIG_ARM_ERRATA_411920
		v6_icache_inval_all();
#endif
		__flush_icache_all();
	}
}