xref: /kernel/linux/linux-5.10/arch/arm/include/asm/tlb.h (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  arch/arm/include/asm/tlb.h
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 2002 Russell King
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci *  Experimentation shows that on a StrongARM, it appears to be faster
88c2ecf20Sopenharmony_ci *  to use the "invalidate whole tlb" rather than "invalidate single
98c2ecf20Sopenharmony_ci *  tlb" for this.
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci *  This appears true for both the process fork+exit case, as well as
128c2ecf20Sopenharmony_ci *  the munmap-large-area case.
138c2ecf20Sopenharmony_ci */
148c2ecf20Sopenharmony_ci#ifndef __ASMARM_TLB_H
158c2ecf20Sopenharmony_ci#define __ASMARM_TLB_H
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <asm/cacheflush.h>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#ifndef CONFIG_MMU
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#include <linux/pagemap.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#define tlb_flush(tlb)	((void) tlb)
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#include <asm-generic/tlb.h>
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#else /* !CONFIG_MMU */
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#include <linux/swap.h>
308c2ecf20Sopenharmony_ci#include <asm/tlbflush.h>
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_cistatic inline void __tlb_remove_table(void *_table)
338c2ecf20Sopenharmony_ci{
348c2ecf20Sopenharmony_ci	free_page_and_swap_cache((struct page *)_table);
358c2ecf20Sopenharmony_ci}
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#include <asm-generic/tlb.h>
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic inline void
408c2ecf20Sopenharmony_ci__pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long addr)
418c2ecf20Sopenharmony_ci{
428c2ecf20Sopenharmony_ci	pgtable_pte_page_dtor(pte);
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#ifndef CONFIG_ARM_LPAE
458c2ecf20Sopenharmony_ci	/*
468c2ecf20Sopenharmony_ci	 * With the classic ARM MMU, a pte page has two corresponding pmd
478c2ecf20Sopenharmony_ci	 * entries, each covering 1MB.
488c2ecf20Sopenharmony_ci	 */
498c2ecf20Sopenharmony_ci	addr = (addr & PMD_MASK) + SZ_1M;
508c2ecf20Sopenharmony_ci	__tlb_adjust_range(tlb, addr - PAGE_SIZE, 2 * PAGE_SIZE);
518c2ecf20Sopenharmony_ci#endif
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	tlb_remove_table(tlb, pte);
548c2ecf20Sopenharmony_ci}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic inline void
578c2ecf20Sopenharmony_ci__pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci#ifdef CONFIG_ARM_LPAE
608c2ecf20Sopenharmony_ci	struct page *page = virt_to_page(pmdp);
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	pgtable_pmd_page_dtor(page);
638c2ecf20Sopenharmony_ci	tlb_remove_table(tlb, page);
648c2ecf20Sopenharmony_ci#endif
658c2ecf20Sopenharmony_ci}
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci#endif /* CONFIG_MMU */
688c2ecf20Sopenharmony_ci#endif
69