162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * arch/arm/include/asm/tlb.h 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2002 Russell King 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Experimentation shows that on a StrongARM, it appears to be faster 862306a36Sopenharmony_ci * to use the "invalidate whole tlb" rather than "invalidate single 962306a36Sopenharmony_ci * tlb" for this. 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * This appears true for both the process fork+exit case, as well as 1262306a36Sopenharmony_ci * the munmap-large-area case. 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci#ifndef __ASMARM_TLB_H 1562306a36Sopenharmony_ci#define __ASMARM_TLB_H 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include <asm/cacheflush.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#ifndef CONFIG_MMU 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <linux/pagemap.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#define tlb_flush(tlb) ((void) tlb) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#include <asm-generic/tlb.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#else /* !CONFIG_MMU */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#include <linux/swap.h> 3062306a36Sopenharmony_ci#include <asm/tlbflush.h> 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic inline void __tlb_remove_table(void *_table) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci free_page_and_swap_cache((struct page *)_table); 3562306a36Sopenharmony_ci} 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#include <asm-generic/tlb.h> 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic inline void 4062306a36Sopenharmony_ci__pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long addr) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci struct ptdesc *ptdesc = page_ptdesc(pte); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci pagetable_pte_dtor(ptdesc); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#ifndef CONFIG_ARM_LPAE 4762306a36Sopenharmony_ci /* 4862306a36Sopenharmony_ci * With the classic ARM MMU, a pte page has two corresponding pmd 4962306a36Sopenharmony_ci * entries, each covering 1MB. 5062306a36Sopenharmony_ci */ 5162306a36Sopenharmony_ci addr = (addr & PMD_MASK) + SZ_1M; 5262306a36Sopenharmony_ci __tlb_adjust_range(tlb, addr - PAGE_SIZE, 2 * PAGE_SIZE); 5362306a36Sopenharmony_ci#endif 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci tlb_remove_ptdesc(tlb, ptdesc); 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistatic inline void 5962306a36Sopenharmony_ci__pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr) 6062306a36Sopenharmony_ci{ 6162306a36Sopenharmony_ci#ifdef CONFIG_ARM_LPAE 6262306a36Sopenharmony_ci struct ptdesc *ptdesc = virt_to_ptdesc(pmdp); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci pagetable_pmd_dtor(ptdesc); 6562306a36Sopenharmony_ci tlb_remove_ptdesc(tlb, ptdesc); 6662306a36Sopenharmony_ci#endif 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci#endif /* CONFIG_MMU */ 7062306a36Sopenharmony_ci#endif 71