 58d0ba578b
			
		
	
	
	58d0ba578b
	
	
	
		
			
			This patch adds the TLB maintenance functions. There is no distinction made between the I and D TLBs. TLB maintenance operations are automatically broadcast between CPUs in hardware. The inner-shareable operations are always present, even on UP systems. NOTE: Large part of this patch to be dropped once Peter Z's generic mmu_gather patches are merged. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Nicolas Pitre <nico@linaro.org> Acked-by: Olof Johansson <olof@lixom.net> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
		
			
				
	
	
		
			122 lines
		
	
	
	
		
			3.2 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
	
		
			3.2 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Based on arch/arm/include/asm/tlbflush.h
 | |
|  *
 | |
|  * Copyright (C) 1999-2003 Russell King
 | |
|  * Copyright (C) 2012 ARM Ltd.
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU General Public License version 2 as
 | |
|  * published by the Free Software Foundation.
 | |
|  *
 | |
|  * This program is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  * GNU General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU General Public License
 | |
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| #ifndef __ASM_TLBFLUSH_H
 | |
| #define __ASM_TLBFLUSH_H
 | |
| 
 | |
| #ifndef __ASSEMBLY__
 | |
| 
 | |
| #include <linux/sched.h>
 | |
| #include <asm/cputype.h>
 | |
| 
 | |
| extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
 | |
| extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
 | |
| 
 | |
| extern struct cpu_tlb_fns cpu_tlb;
 | |
| 
 | |
| /*
 | |
|  *	TLB Management
 | |
|  *	==============
 | |
|  *
 | |
|  *	The arch/arm64/mm/tlb.S files implement these methods.
 | |
|  *
 | |
|  *	The TLB specific code is expected to perform whatever tests it needs
 | |
|  *	to determine if it should invalidate the TLB for each call.  Start
 | |
|  *	addresses are inclusive and end addresses are exclusive; it is safe to
 | |
|  *	round these addresses down.
 | |
|  *
 | |
|  *	flush_tlb_all()
 | |
|  *
 | |
|  *		Invalidate the entire TLB.
 | |
|  *
 | |
|  *	flush_tlb_mm(mm)
 | |
|  *
 | |
|  *		Invalidate all TLB entries in a particular address space.
 | |
|  *		- mm	- mm_struct describing address space
 | |
|  *
 | |
|  *	flush_tlb_range(mm,start,end)
 | |
|  *
 | |
|  *		Invalidate a range of TLB entries in the specified address
 | |
|  *		space.
 | |
|  *		- mm	- mm_struct describing address space
 | |
|  *		- start - start address (may not be aligned)
 | |
|  *		- end	- end address (exclusive, may not be aligned)
 | |
|  *
 | |
|  *	flush_tlb_page(vaddr,vma)
 | |
|  *
 | |
|  *		Invalidate the specified page in the specified address range.
 | |
|  *		- vaddr - virtual address (may not be aligned)
 | |
|  *		- vma	- vma_struct describing address range
 | |
|  *
 | |
|  *	flush_kern_tlb_page(kaddr)
 | |
|  *
 | |
|  *		Invalidate the TLB entry for the specified page.  The address
 | |
|  *		will be in the kernels virtual memory space.  Current uses
 | |
|  *		only require the D-TLB to be invalidated.
 | |
|  *		- kaddr - Kernel virtual memory address
 | |
|  */
 | |
| static inline void flush_tlb_all(void)
 | |
| {
 | |
| 	dsb();
 | |
| 	asm("tlbi	vmalle1is");
 | |
| 	dsb();
 | |
| 	isb();
 | |
| }
 | |
| 
 | |
| static inline void flush_tlb_mm(struct mm_struct *mm)
 | |
| {
 | |
| 	unsigned long asid = (unsigned long)ASID(mm) << 48;
 | |
| 
 | |
| 	dsb();
 | |
| 	asm("tlbi	aside1is, %0" : : "r" (asid));
 | |
| 	dsb();
 | |
| }
 | |
| 
 | |
| static inline void flush_tlb_page(struct vm_area_struct *vma,
 | |
| 				  unsigned long uaddr)
 | |
| {
 | |
| 	unsigned long addr = uaddr >> 12 |
 | |
| 		((unsigned long)ASID(vma->vm_mm) << 48);
 | |
| 
 | |
| 	dsb();
 | |
| 	asm("tlbi	vae1is, %0" : : "r" (addr));
 | |
| 	dsb();
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Convert calls to our calling convention.
 | |
|  */
 | |
| #define flush_tlb_range(vma,start,end)	__cpu_flush_user_tlb_range(start,end,vma)
 | |
| #define flush_tlb_kernel_range(s,e)	__cpu_flush_kern_tlb_range(s,e)
 | |
| 
 | |
| /*
 | |
|  * On AArch64, the cache coherency is handled via the set_pte_at() function.
 | |
|  */
 | |
| static inline void update_mmu_cache(struct vm_area_struct *vma,
 | |
| 				    unsigned long addr, pte_t *ptep)
 | |
| {
 | |
| 	/*
 | |
| 	 * set_pte() does not have a DSB, so make sure that the page table
 | |
| 	 * write is visible.
 | |
| 	 */
 | |
| 	dsb();
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| #endif
 |