summaryrefslogtreecommitdiffstats
path: root/arch/arm64/include
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/include')
-rw-r--r--arch/arm64/include/asm/tlbflush.h18
1 files changed, 12 insertions, 6 deletions
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index 3353f26302de..e1d07612e147 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -104,6 +104,11 @@
__tlbi(op, arg); \
} while(0)
+#define __tlbi_user_level(op, arg, level) do { \
+ if (arm64_kernel_unmapped_at_el0()) \
+ __tlbi_level(op, (arg | USER_ASID_FLAG), level); \
+} while (0)
+
/*
* TLB Invalidation
* ================
@@ -205,8 +210,9 @@ 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);
+ /* This function is only called on a small page */
+ __tlbi_level(vale1is, addr, 3);
+ __tlbi_user_level(vale1is, addr, 3);
}
static inline void flush_tlb_page(struct vm_area_struct *vma,
@@ -246,11 +252,11 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
dsb(ishst);
for (addr = start; addr < end; addr += stride) {
if (last_level) {
- __tlbi(vale1is, addr);
- __tlbi_user(vale1is, addr);
+ __tlbi_level(vale1is, addr, 0);
+ __tlbi_user_level(vale1is, addr, 0);
} else {
- __tlbi(vae1is, addr);
- __tlbi_user(vae1is, addr);
+ __tlbi_level(vae1is, addr, 0);
+ __tlbi_user_level(vae1is, addr, 0);
}
}
dsb(ish);