18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H 38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#define MMU_NO_CONTEXT ~0UL 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/mm_types.h> 88c2ecf20Sopenharmony_ci#include <asm/book3s/64/tlbflush-hash.h> 98c2ecf20Sopenharmony_ci#include <asm/book3s/64/tlbflush-radix.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/* TLB flush actions. Used as argument to tlbiel_all() */ 128c2ecf20Sopenharmony_cienum { 138c2ecf20Sopenharmony_ci TLB_INVAL_SCOPE_GLOBAL = 0, /* invalidate all TLBs */ 148c2ecf20Sopenharmony_ci TLB_INVAL_SCOPE_LPID = 1, /* invalidate TLBs for current LPID */ 158c2ecf20Sopenharmony_ci}; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_NATIVE 188c2ecf20Sopenharmony_cistatic inline void tlbiel_all(void) 198c2ecf20Sopenharmony_ci{ 208c2ecf20Sopenharmony_ci /* 218c2ecf20Sopenharmony_ci * This is used for host machine check and bootup. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * This uses early_radix_enabled and implementations use 248c2ecf20Sopenharmony_ci * early_cpu_has_feature etc because that works early in boot 258c2ecf20Sopenharmony_ci * and this is the machine check path which is not performance 268c2ecf20Sopenharmony_ci * critical. 278c2ecf20Sopenharmony_ci */ 288c2ecf20Sopenharmony_ci if (early_radix_enabled()) 298c2ecf20Sopenharmony_ci radix__tlbiel_all(TLB_INVAL_SCOPE_GLOBAL); 308c2ecf20Sopenharmony_ci else 318c2ecf20Sopenharmony_ci hash__tlbiel_all(TLB_INVAL_SCOPE_GLOBAL); 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci#else 348c2ecf20Sopenharmony_cistatic inline void tlbiel_all(void) { BUG(); }; 358c2ecf20Sopenharmony_ci#endif 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic inline void tlbiel_all_lpid(bool radix) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci /* 408c2ecf20Sopenharmony_ci * This is used for guest machine check. 418c2ecf20Sopenharmony_ci */ 428c2ecf20Sopenharmony_ci if (radix) 438c2ecf20Sopenharmony_ci radix__tlbiel_all(TLB_INVAL_SCOPE_LPID); 448c2ecf20Sopenharmony_ci else 458c2ecf20Sopenharmony_ci hash__tlbiel_all(TLB_INVAL_SCOPE_LPID); 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE 508c2ecf20Sopenharmony_cistatic inline void flush_pmd_tlb_range(struct vm_area_struct *vma, 518c2ecf20Sopenharmony_ci unsigned long start, unsigned long end) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci if (radix_enabled()) 548c2ecf20Sopenharmony_ci return radix__flush_pmd_tlb_range(vma, start, end); 558c2ecf20Sopenharmony_ci return hash__flush_tlb_range(vma, start, end); 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#define __HAVE_ARCH_FLUSH_HUGETLB_TLB_RANGE 598c2ecf20Sopenharmony_cistatic inline void flush_hugetlb_tlb_range(struct vm_area_struct *vma, 608c2ecf20Sopenharmony_ci unsigned long start, 618c2ecf20Sopenharmony_ci unsigned long end) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci if (radix_enabled()) 648c2ecf20Sopenharmony_ci return radix__flush_hugetlb_tlb_range(vma, start, end); 658c2ecf20Sopenharmony_ci return hash__flush_tlb_range(vma, start, end); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistatic inline void flush_tlb_range(struct vm_area_struct *vma, 698c2ecf20Sopenharmony_ci unsigned long start, unsigned long end) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci if (radix_enabled()) 728c2ecf20Sopenharmony_ci return radix__flush_tlb_range(vma, start, end); 738c2ecf20Sopenharmony_ci return hash__flush_tlb_range(vma, start, end); 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic inline void flush_tlb_kernel_range(unsigned long start, 778c2ecf20Sopenharmony_ci unsigned long end) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci if (radix_enabled()) 808c2ecf20Sopenharmony_ci return radix__flush_tlb_kernel_range(start, end); 818c2ecf20Sopenharmony_ci return hash__flush_tlb_kernel_range(start, end); 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_mm(struct mm_struct *mm) 858c2ecf20Sopenharmony_ci{ 868c2ecf20Sopenharmony_ci if (radix_enabled()) 878c2ecf20Sopenharmony_ci return radix__local_flush_tlb_mm(mm); 888c2ecf20Sopenharmony_ci return hash__local_flush_tlb_mm(mm); 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_page(struct vm_area_struct *vma, 928c2ecf20Sopenharmony_ci unsigned long vmaddr) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci if (radix_enabled()) 958c2ecf20Sopenharmony_ci return radix__local_flush_tlb_page(vma, vmaddr); 968c2ecf20Sopenharmony_ci return hash__local_flush_tlb_page(vma, vmaddr); 978c2ecf20Sopenharmony_ci} 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistatic inline void local_flush_all_mm(struct mm_struct *mm) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci if (radix_enabled()) 1028c2ecf20Sopenharmony_ci return radix__local_flush_all_mm(mm); 1038c2ecf20Sopenharmony_ci return hash__local_flush_all_mm(mm); 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistatic inline void tlb_flush(struct mmu_gather *tlb) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci if (radix_enabled()) 1098c2ecf20Sopenharmony_ci return radix__tlb_flush(tlb); 1108c2ecf20Sopenharmony_ci return hash__tlb_flush(tlb); 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 1148c2ecf20Sopenharmony_cistatic inline void flush_tlb_mm(struct mm_struct *mm) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci if (radix_enabled()) 1178c2ecf20Sopenharmony_ci return radix__flush_tlb_mm(mm); 1188c2ecf20Sopenharmony_ci return hash__flush_tlb_mm(mm); 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic inline void flush_tlb_page(struct vm_area_struct *vma, 1228c2ecf20Sopenharmony_ci unsigned long vmaddr) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci if (radix_enabled()) 1258c2ecf20Sopenharmony_ci return radix__flush_tlb_page(vma, vmaddr); 1268c2ecf20Sopenharmony_ci return hash__flush_tlb_page(vma, vmaddr); 1278c2ecf20Sopenharmony_ci} 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_cistatic inline void flush_all_mm(struct mm_struct *mm) 1308c2ecf20Sopenharmony_ci{ 1318c2ecf20Sopenharmony_ci if (radix_enabled()) 1328c2ecf20Sopenharmony_ci return radix__flush_all_mm(mm); 1338c2ecf20Sopenharmony_ci return hash__flush_all_mm(mm); 1348c2ecf20Sopenharmony_ci} 1358c2ecf20Sopenharmony_ci#else 1368c2ecf20Sopenharmony_ci#define flush_tlb_mm(mm) local_flush_tlb_mm(mm) 1378c2ecf20Sopenharmony_ci#define flush_tlb_page(vma, addr) local_flush_tlb_page(vma, addr) 1388c2ecf20Sopenharmony_ci#define flush_all_mm(mm) local_flush_all_mm(mm) 1398c2ecf20Sopenharmony_ci#endif /* CONFIG_SMP */ 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci#define flush_tlb_fix_spurious_fault flush_tlb_fix_spurious_fault 1428c2ecf20Sopenharmony_cistatic inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma, 1438c2ecf20Sopenharmony_ci unsigned long address) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci /* See ptep_set_access_flags comment */ 1468c2ecf20Sopenharmony_ci if (atomic_read(&vma->vm_mm->context.copros) > 0) 1478c2ecf20Sopenharmony_ci flush_tlb_page(vma, address); 1488c2ecf20Sopenharmony_ci} 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ciextern bool tlbie_capable; 1518c2ecf20Sopenharmony_ciextern bool tlbie_enabled; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_cistatic inline bool cputlb_use_tlbie(void) 1548c2ecf20Sopenharmony_ci{ 1558c2ecf20Sopenharmony_ci return tlbie_enabled; 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H */ 159