162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_POWERPC_NOHASH_TLBFLUSH_H 362306a36Sopenharmony_ci#define _ASM_POWERPC_NOHASH_TLBFLUSH_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * TLB flushing: 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * - flush_tlb_mm(mm) flushes the specified mm context TLB's 962306a36Sopenharmony_ci * - flush_tlb_page(vma, vmaddr) flushes one page 1062306a36Sopenharmony_ci * - local_flush_tlb_mm(mm, full) flushes the specified mm context on 1162306a36Sopenharmony_ci * the local processor 1262306a36Sopenharmony_ci * - local_flush_tlb_page(vma, vmaddr) flushes one page on the local processor 1362306a36Sopenharmony_ci * - flush_tlb_range(vma, start, end) flushes a range of pages 1462306a36Sopenharmony_ci * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* 1962306a36Sopenharmony_ci * TLB flushing for software loaded TLB chips 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * TODO: (CONFIG_PPC_85xx) determine if flush_tlb_range & 2262306a36Sopenharmony_ci * flush_tlb_kernel_range are best implemented as tlbia vs 2362306a36Sopenharmony_ci * specific tlbie's 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistruct vm_area_struct; 2762306a36Sopenharmony_cistruct mm_struct; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define MMU_NO_CONTEXT ((unsigned int)-1) 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciextern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 3262306a36Sopenharmony_ci unsigned long end); 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#ifdef CONFIG_PPC_8xx 3562306a36Sopenharmony_cistatic inline void local_flush_tlb_mm(struct mm_struct *mm) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci unsigned int pid = READ_ONCE(mm->context.id); 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci if (pid != MMU_NO_CONTEXT) 4062306a36Sopenharmony_ci asm volatile ("sync; tlbia; isync" : : : "memory"); 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic inline void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci asm volatile ("tlbie %0; sync" : : "r" (vmaddr) : "memory"); 4662306a36Sopenharmony_ci} 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistatic inline void local_flush_tlb_page_psize(struct mm_struct *mm, 4962306a36Sopenharmony_ci unsigned long vmaddr, int psize) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci asm volatile ("tlbie %0; sync" : : "r" (vmaddr) : "memory"); 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci start &= PAGE_MASK; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci if (end - start <= PAGE_SIZE) 5962306a36Sopenharmony_ci asm volatile ("tlbie %0; sync" : : "r" (start) : "memory"); 6062306a36Sopenharmony_ci else 6162306a36Sopenharmony_ci asm volatile ("sync; tlbia; isync" : : : "memory"); 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci#else 6462306a36Sopenharmony_ciextern void flush_tlb_kernel_range(unsigned long start, unsigned long end); 6562306a36Sopenharmony_ciextern void local_flush_tlb_mm(struct mm_struct *mm); 6662306a36Sopenharmony_ciextern void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); 6762306a36Sopenharmony_civoid local_flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, int psize); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ciextern void __local_flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr, 7062306a36Sopenharmony_ci int tsize, int ind); 7162306a36Sopenharmony_ci#endif 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci#ifdef CONFIG_SMP 7462306a36Sopenharmony_ciextern void flush_tlb_mm(struct mm_struct *mm); 7562306a36Sopenharmony_ciextern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); 7662306a36Sopenharmony_ciextern void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr, 7762306a36Sopenharmony_ci int tsize, int ind); 7862306a36Sopenharmony_ci#else 7962306a36Sopenharmony_ci#define flush_tlb_mm(mm) local_flush_tlb_mm(mm) 8062306a36Sopenharmony_ci#define flush_tlb_page(vma,addr) local_flush_tlb_page(vma,addr) 8162306a36Sopenharmony_ci#define __flush_tlb_page(mm,addr,p,i) __local_flush_tlb_page(mm,addr,p,i) 8262306a36Sopenharmony_ci#endif 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci#endif /* _ASM_POWERPC_NOHASH_TLBFLUSH_H */ 85