summaryrefslogtreecommitdiffstats
path: root/arch/arm64/include/asm/tlb.h
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2015-03-18 11:28:06 +0000
committerWill Deacon <will.deacon@arm.com>2015-07-28 11:44:01 +0100
commit4150e50bf5f2171fbe7dfdbc7f2cdf44676b79a4 (patch)
tree6c016c8cd4a70b019a17d0e58ea01a22c98dd846 /arch/arm64/include/asm/tlb.h
parentda4e73303e448aa23b36249a85e239ca118ce941 (diff)
downloadop-kernel-dev-4150e50bf5f2171fbe7dfdbc7f2cdf44676b79a4.zip
op-kernel-dev-4150e50bf5f2171fbe7dfdbc7f2cdf44676b79a4.tar.gz
arm64: Use last level TLBI for user pte changes
The flush_tlb_page() function is used on user address ranges when PTEs (or PMDs/PUDs for huge pages) were changed (attributes or clearing). For such cases, it is more efficient to invalidate only the last level of the TLB with the "tlbi vale1is" instruction. In the TLB shoot-down case, the TLB caching of the intermediate page table levels (pmd, pud, pgd) is handled by __flush_tlb_pgtable() via the __(pte|pmd|pud)_free_tlb() functions and it is not deferred to tlb_finish_mmu() (as of commit 285994a62c80 - "arm64: Invalidate the TLB corresponding to intermediate page table levels"). The tlb_flush() function only needs to invalidate the TLB for the last level of page tables; the __flush_tlb_range() function gains a fourth argument for last level TLBI. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/include/asm/tlb.h')
-rw-r--r--arch/arm64/include/asm/tlb.h7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 3a0242c..d6e6b66 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -41,7 +41,12 @@ static inline void tlb_flush(struct mmu_gather *tlb)
flush_tlb_mm(tlb->mm);
} else {
struct vm_area_struct vma = { .vm_mm = tlb->mm, };
- flush_tlb_range(&vma, tlb->start, tlb->end);
+ /*
+ * The intermediate page table levels are already handled by
+ * the __(pte|pmd|pud)_free_tlb() functions, so last level
+ * TLBI is sufficient here.
+ */
+ __flush_tlb_range(&vma, tlb->start, tlb->end, true);
}
}
OpenPOWER on IntegriCloud