1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Based on arch/arm/include/asm/tlb.h
5 * Copyright (C) 2002 Russell King
6 * Copyright (C) 2012 ARM Ltd.
11 #include <linux/pagemap.h>
12 #include <linux/swap.h>
14 static inline void __tlb_remove_table(void *_table
)
16 free_page_and_swap_cache((struct page
*)_table
);
19 #define tlb_flush tlb_flush
20 static void tlb_flush(struct mmu_gather
*tlb
);
22 #include <asm-generic/tlb.h>
24 static inline void tlb_flush(struct mmu_gather
*tlb
)
26 struct vm_area_struct vma
= TLB_FLUSH_VMA(tlb
->mm
, 0);
27 bool last_level
= !tlb
->freed_tables
;
28 unsigned long stride
= tlb_get_unmap_size(tlb
);
31 * If we're tearing down the address space then we only care about
32 * invalidating the walk-cache, since the ASID allocator won't
33 * reallocate our ASID without invalidating the entire TLB.
37 flush_tlb_mm(tlb
->mm
);
41 __flush_tlb_range(&vma
, tlb
->start
, tlb
->end
, stride
, last_level
);
44 static inline void __pte_free_tlb(struct mmu_gather
*tlb
, pgtable_t pte
,
47 pgtable_page_dtor(pte
);
48 tlb_remove_table(tlb
, pte
);
51 #if CONFIG_PGTABLE_LEVELS > 2
52 static inline void __pmd_free_tlb(struct mmu_gather
*tlb
, pmd_t
*pmdp
,
55 struct page
*page
= virt_to_page(pmdp
);
57 pgtable_pmd_page_dtor(page
);
58 tlb_remove_table(tlb
, page
);
62 #if CONFIG_PGTABLE_LEVELS > 3
63 static inline void __pud_free_tlb(struct mmu_gather
*tlb
, pud_t
*pudp
,
66 tlb_remove_table(tlb
, virt_to_page(pudp
));