xref: /openbmc/linux/arch/arm/include/asm/tlb.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
24baa9922SRussell King /*
34baa9922SRussell King  *  arch/arm/include/asm/tlb.h
44baa9922SRussell King  *
54baa9922SRussell King  *  Copyright (C) 2002 Russell King
64baa9922SRussell King  *
74baa9922SRussell King  *  Experimentation shows that on a StrongARM, it appears to be faster
84baa9922SRussell King  *  to use the "invalidate whole tlb" rather than "invalidate single
94baa9922SRussell King  *  tlb" for this.
104baa9922SRussell King  *
114baa9922SRussell King  *  This appears true for both the process fork+exit case, as well as
124baa9922SRussell King  *  the munmap-large-area case.
134baa9922SRussell King  */
144baa9922SRussell King #ifndef __ASMARM_TLB_H
154baa9922SRussell King #define __ASMARM_TLB_H
164baa9922SRussell King 
174baa9922SRussell King #include <asm/cacheflush.h>
184baa9922SRussell King 
194baa9922SRussell King #ifndef CONFIG_MMU
204baa9922SRussell King 
214baa9922SRussell King #include <linux/pagemap.h>
2258e9c47fSRussell King 
2358e9c47fSRussell King #define tlb_flush(tlb)	((void) tlb)
2458e9c47fSRussell King 
254baa9922SRussell King #include <asm-generic/tlb.h>
264baa9922SRussell King 
274baa9922SRussell King #else /* !CONFIG_MMU */
284baa9922SRussell King 
2906824ba8SRussell King #include <linux/swap.h>
3006824ba8SRussell King #include <asm/tlbflush.h>
3106824ba8SRussell King 
__tlb_remove_table(void * _table)32a0ad5496SSteve Capper static inline void __tlb_remove_table(void *_table)
33a0ad5496SSteve Capper {
34a0ad5496SSteve Capper 	free_page_and_swap_cache((struct page *)_table);
35a0ad5496SSteve Capper }
36a0ad5496SSteve Capper 
37b78180b9SPeter Zijlstra #include <asm-generic/tlb.h>
38a0ad5496SSteve Capper 
399e14f674SPeter Zijlstra static inline void
__pte_free_tlb(struct mmu_gather * tlb,pgtable_t pte,unsigned long addr)40b78180b9SPeter Zijlstra __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long addr)
4106824ba8SRussell King {
42*358d1c39SVishal Moola (Oracle) 	struct ptdesc *ptdesc = page_ptdesc(pte);
43*358d1c39SVishal Moola (Oracle) 
44*358d1c39SVishal Moola (Oracle) 	pagetable_pte_dtor(ptdesc);
456d3ec1aeSCatalin Marinas 
46b78180b9SPeter Zijlstra #ifndef CONFIG_ARM_LPAE
476d3ec1aeSCatalin Marinas 	/*
486d3ec1aeSCatalin Marinas 	 * With the classic ARM MMU, a pte page has two corresponding pmd
496d3ec1aeSCatalin Marinas 	 * entries, each covering 1MB.
506d3ec1aeSCatalin Marinas 	 */
51b78180b9SPeter Zijlstra 	addr = (addr & PMD_MASK) + SZ_1M;
52b78180b9SPeter Zijlstra 	__tlb_adjust_range(tlb, addr - PAGE_SIZE, 2 * PAGE_SIZE);
53df547e08SWill Deacon #endif
546d3ec1aeSCatalin Marinas 
55*358d1c39SVishal Moola (Oracle) 	tlb_remove_ptdesc(tlb, ptdesc);
56c9f27f10SCatalin Marinas }
57c9f27f10SCatalin Marinas 
588d962507SCatalin Marinas static inline void
__pmd_free_tlb(struct mmu_gather * tlb,pmd_t * pmdp,unsigned long addr)59b78180b9SPeter Zijlstra __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr)
608d962507SCatalin Marinas {
61b78180b9SPeter Zijlstra #ifdef CONFIG_ARM_LPAE
62*358d1c39SVishal Moola (Oracle) 	struct ptdesc *ptdesc = virt_to_ptdesc(pmdp);
638d962507SCatalin Marinas 
64*358d1c39SVishal Moola (Oracle) 	pagetable_pmd_dtor(ptdesc);
65*358d1c39SVishal Moola (Oracle) 	tlb_remove_ptdesc(tlb, ptdesc);
66b78180b9SPeter Zijlstra #endif
67063daa81SAnders Roxell }
68063daa81SAnders Roxell 
694baa9922SRussell King #endif /* CONFIG_MMU */
704baa9922SRussell King #endif
71