summaryrefslogtreecommitdiff
path: root/arch/arm64/include/asm/tlbflush.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/include/asm/tlbflush.h')
-rw-r--r--arch/arm64/include/asm/tlbflush.h49
1 files changed, 42 insertions, 7 deletions
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index bc3949064725..e3660cce3e96 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -15,6 +15,12 @@
#include <asm/cputype.h>
#include <asm/mmu.h>
+#ifdef CONFIG_IMX_SCU_SOC
+extern bool TKT340553_SW_WORKAROUND;
+#else
+#define TKT340553_SW_WORKAROUND 0
+#endif
+
/*
* Raw TLBI operations.
*
@@ -149,9 +155,16 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
unsigned long asid = __TLBI_VADDR(0, ASID(mm));
dsb(ishst);
- __tlbi(aside1is, asid);
- __tlbi_user(aside1is, asid);
- dsb(ish);
+ if (TKT340553_SW_WORKAROUND) {
+ /* Flush the entire TLB */
+ __tlbi(vmalle1is);
+ dsb(ish);
+ isb();
+ } else {
+ __tlbi(aside1is, asid);
+ __tlbi_user(aside1is, asid);
+ dsb(ish);
+ }
}
static inline void flush_tlb_page_nosync(struct vm_area_struct *vma,
@@ -160,8 +173,15 @@ static inline void flush_tlb_page_nosync(struct vm_area_struct *vma,
unsigned long addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm));
dsb(ishst);
- __tlbi(vale1is, addr);
- __tlbi_user(vale1is, addr);
+ if (TKT340553_SW_WORKAROUND) {
+ /* Flush the entire TLB */
+ __tlbi(vmalle1is);
+ dsb(ish);
+ isb();
+ } else {
+ __tlbi(vale1is, addr);
+ __tlbi_user(vale1is, addr);
+ }
}
static inline void flush_tlb_page(struct vm_area_struct *vma,
@@ -199,6 +219,15 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
end = __TLBI_VADDR(end, asid);
dsb(ishst);
+
+ if (TKT340553_SW_WORKAROUND) {
+ /* Flush the entire TLB and exit */
+ __tlbi(vmalle1is);
+ dsb(ish);
+ isb();
+ return;
+ }
+
for (addr = start; addr < end; addr += stride) {
if (last_level) {
__tlbi(vale1is, addr);
@@ -208,6 +237,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
__tlbi_user(vae1is, addr);
}
}
+
dsb(ish);
}
@@ -225,7 +255,8 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
{
unsigned long addr;
- if ((end - start) > (MAX_TLBI_OPS * PAGE_SIZE)) {
+ if (((end - start) > (MAX_TLBI_OPS * PAGE_SIZE))
+ || (TKT340553_SW_WORKAROUND)) {
flush_tlb_all();
return;
}
@@ -249,7 +280,11 @@ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr)
unsigned long addr = __TLBI_VADDR(kaddr, 0);
dsb(ishst);
- __tlbi(vaae1is, addr);
+ if (TKT340553_SW_WORKAROUND)
+ /* Flush the entire TLB */
+ __tlbi(vmalle1is);
+ else
+ __tlbi(vaae1is, addr);
dsb(ish);
isb();
}