162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H 362306a36Sopenharmony_ci#define _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * TLB flushing for 64-bit hash-MMU CPUs 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/percpu.h> 1062306a36Sopenharmony_ci#include <asm/page.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define PPC64_TLB_BATCH_NR 192 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistruct ppc64_tlb_batch { 1562306a36Sopenharmony_ci int active; 1662306a36Sopenharmony_ci unsigned long index; 1762306a36Sopenharmony_ci struct mm_struct *mm; 1862306a36Sopenharmony_ci real_pte_t pte[PPC64_TLB_BATCH_NR]; 1962306a36Sopenharmony_ci unsigned long vpn[PPC64_TLB_BATCH_NR]; 2062306a36Sopenharmony_ci unsigned int psize; 2162306a36Sopenharmony_ci int ssize; 2262306a36Sopenharmony_ci}; 2362306a36Sopenharmony_ciDECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ciextern void __flush_tlb_pending(struct ppc64_tlb_batch *batch); 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistatic inline void arch_enter_lazy_mmu_mode(void) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci struct ppc64_tlb_batch *batch; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci if (radix_enabled()) 3462306a36Sopenharmony_ci return; 3562306a36Sopenharmony_ci /* 3662306a36Sopenharmony_ci * apply_to_page_range can call us this preempt enabled when 3762306a36Sopenharmony_ci * operating on kernel page tables. 3862306a36Sopenharmony_ci */ 3962306a36Sopenharmony_ci preempt_disable(); 4062306a36Sopenharmony_ci batch = this_cpu_ptr(&ppc64_tlb_batch); 4162306a36Sopenharmony_ci batch->active = 1; 4262306a36Sopenharmony_ci} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistatic inline void arch_leave_lazy_mmu_mode(void) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci struct ppc64_tlb_batch *batch; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci if (radix_enabled()) 4962306a36Sopenharmony_ci return; 5062306a36Sopenharmony_ci batch = this_cpu_ptr(&ppc64_tlb_batch); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci if (batch->index) 5362306a36Sopenharmony_ci __flush_tlb_pending(batch); 5462306a36Sopenharmony_ci batch->active = 0; 5562306a36Sopenharmony_ci preempt_enable(); 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci#define arch_flush_lazy_mmu_mode() do {} while (0) 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ciextern void hash__tlbiel_all(unsigned int action); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ciextern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, 6362306a36Sopenharmony_ci int ssize, unsigned long flags); 6462306a36Sopenharmony_ciextern void flush_hash_range(unsigned long number, int local); 6562306a36Sopenharmony_ciextern void flush_hash_hugepage(unsigned long vsid, unsigned long addr, 6662306a36Sopenharmony_ci pmd_t *pmdp, unsigned int psize, int ssize, 6762306a36Sopenharmony_ci unsigned long flags); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistruct mmu_gather; 7062306a36Sopenharmony_ciextern void hash__tlb_flush(struct mmu_gather *tlb); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#ifdef CONFIG_PPC_64S_HASH_MMU 7362306a36Sopenharmony_ci/* Private function for use by PCI IO mapping code */ 7462306a36Sopenharmony_ciextern void __flush_hash_table_range(unsigned long start, unsigned long end); 7562306a36Sopenharmony_civoid flush_hash_table_pmd_range(struct mm_struct *mm, pmd_t *pmd, unsigned long addr); 7662306a36Sopenharmony_ci#else 7762306a36Sopenharmony_cistatic inline void __flush_hash_table_range(unsigned long start, unsigned long end) { } 7862306a36Sopenharmony_ci#endif 7962306a36Sopenharmony_ci#endif /* _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H */ 80