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

Commit 065cf519 authored by Catalin Marinas's avatar Catalin Marinas Committed by Russell King
Browse files

[ARM] armv7: add support for asid-tagged VIVT I-cache



ARMv7 can have VIPT, PIPT or ASID-tagged VIVT I-cache. This patch
adds the necessary invalidation of the I-cache when the ASID numbers
are re-used.

Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 56163fcf
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -47,6 +47,13 @@ void __new_context(struct mm_struct *mm)
		    : "r" (0));
		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));
			dsb();
		}
	}

	mm->context.id = asid;
+15 −0
Original line number Diff line number Diff line
@@ -438,6 +438,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
#define __cacheid_vipt(val)			(__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val))
#define __cacheid_vipt_nonaliasing(val)		(__cacheid_type_v7(val) ? 1 : __cacheid_vipt_nonaliasing_prev7(val))
#define __cacheid_vipt_aliasing(val)		(__cacheid_type_v7(val) ? 0 : __cacheid_vipt_aliasing_prev7(val))
#define __cacheid_vivt_asid_tagged_instr(val)	(__cacheid_type_v7(val) ? ((val & (3 << 14)) == (1 << 14)) : 0)

#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT)

@@ -445,6 +446,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
#define cache_is_vipt()			0
#define cache_is_vipt_nonaliasing()	0
#define cache_is_vipt_aliasing()	0
#define icache_is_vivt_asid_tagged()	0

#elif defined(CONFIG_CPU_CACHE_VIPT)

@@ -462,6 +464,12 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
		__cacheid_vipt_aliasing(__val);				\
	})

#define icache_is_vivt_asid_tagged()					\
	({								\
		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\
		__cacheid_vivt_asid_tagged_instr(__val);		\
	})

#else

#define cache_is_vivt()							\
@@ -490,6 +498,13 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
		 __cacheid_vipt_aliasing(__val);			\
	})

#define icache_is_vivt_asid_tagged()					\
	({								\
		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\
		__cacheid_present(__val) &&				\
		 __cacheid_vivt_asid_tagged_instr(__val);		\
	})

#endif

#endif