]> Gentwo Git Trees - linux/.git/commitdiff
ARM64: Convert TLB flushes of an address space
authorChristoph Lameter (Ampere) <cl@linux.com>
Thu, 7 Dec 2023 04:11:49 +0000 (20:11 -0800)
committerChristoph Lameter (Ampere) <cl@linux.com>
Wed, 20 Dec 2023 15:20:52 +0000 (07:20 -0800)
Use the TLB strategy infrastructure to allow the ARM64
architecture to create a number of ways to accomplish a TLB flush
for a whole address space.

Signed-off-by: Christoph Lameter (Ampere) <cl@linux.com>
arch/arm64/include/asm/tlbflush.h
arch/arm64/mm/context.c

index 65144b8d88d4490907770e6f2cf56457709508ae..8f0d4b48758bc296cd5cb677cfcea14b213b283d 100644 (file)
@@ -250,18 +250,7 @@ static inline void flush_tlb_all(void)
        _count_vm_tlb_event(NR_TLB_FLUSH_ALL);
 }
 
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
-       unsigned long asid;
-
-       dsb(ishst);
-       asid = __TLBI_VADDR(0, ASID(mm));
-       __tlbi(aside1is, asid);
-       __tlbi_user(aside1is, asid);
-       dsb(ish);
-       mmu_notifier_arch_invalidate_secondary_tlbs(mm, 0, -1UL);
-       _count_vm_tlb_event(NR_TLB_FLUSH_ALL);
-}
+extern void flush_tlb_mm(struct mm_struct *mm);
 
 static inline void __flush_tlb_page_nosync(struct mm_struct *mm,
                                           unsigned long uaddr)
index 53aefa480d8290930145d072fe9d8948332ff4dc..d11213f82d8e9adaf794ce7e7e49e90109dc39e7 100644 (file)
@@ -568,6 +568,36 @@ static inline void flush_tlb_pre(enum tlb_state ts)
        dsb(ishst);
 }
 
+static void ipi_flush_tlb_asid(void *p)
+{
+       unsigned long asid = (unsigned long)p;
+
+       flush_tlb_pre(TLB_LOCAL);
+       flush_tlb_asid(TLB_LOCAL, asid);
+       flush_tlb_post(TLB_LOCAL);
+       count_vm_tlb_event(NR_TLB_REMOTE_FLUSH_RECEIVED);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+       unsigned long asid = __TLBI_VADDR(0, ASID(mm));
+       enum tlb_state ts = tlbstat_mm(mm);
+
+       if (ts == TLB_IPI) {
+
+               on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_asid, (void *)asid, true);
+               count_vm_tlb_event(NR_TLB_REMOTE_FLUSH);
+
+       } else {
+
+               flush_tlb_pre(ts);
+               flush_tlb_asid(ts, asid);
+               flush_tlb_post(ts);
+
+       }
+       mmu_notifier_arch_invalidate_secondary_tlbs(mm, 0, -1UL);
+}
+
 static ssize_t tlb_mode_read_file(struct file *file, char __user *user_buf,
                                size_t count, loff_t *ppos)
 {