18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H
38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci/*
68c2ecf20Sopenharmony_ci * TLB flushing for 64-bit hash-MMU CPUs
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/percpu.h>
108c2ecf20Sopenharmony_ci#include <asm/page.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#define PPC64_TLB_BATCH_NR 192
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_cistruct ppc64_tlb_batch {
158c2ecf20Sopenharmony_ci	int			active;
168c2ecf20Sopenharmony_ci	unsigned long		index;
178c2ecf20Sopenharmony_ci	struct mm_struct	*mm;
188c2ecf20Sopenharmony_ci	real_pte_t		pte[PPC64_TLB_BATCH_NR];
198c2ecf20Sopenharmony_ci	unsigned long		vpn[PPC64_TLB_BATCH_NR];
208c2ecf20Sopenharmony_ci	unsigned int		psize;
218c2ecf20Sopenharmony_ci	int			ssize;
228c2ecf20Sopenharmony_ci};
238c2ecf20Sopenharmony_ciDECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ciextern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistatic inline void arch_enter_lazy_mmu_mode(void)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	struct ppc64_tlb_batch *batch;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	if (radix_enabled())
348c2ecf20Sopenharmony_ci		return;
358c2ecf20Sopenharmony_ci	batch = this_cpu_ptr(&ppc64_tlb_batch);
368c2ecf20Sopenharmony_ci	batch->active = 1;
378c2ecf20Sopenharmony_ci}
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic inline void arch_leave_lazy_mmu_mode(void)
408c2ecf20Sopenharmony_ci{
418c2ecf20Sopenharmony_ci	struct ppc64_tlb_batch *batch;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	if (radix_enabled())
448c2ecf20Sopenharmony_ci		return;
458c2ecf20Sopenharmony_ci	batch = this_cpu_ptr(&ppc64_tlb_batch);
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	if (batch->index)
488c2ecf20Sopenharmony_ci		__flush_tlb_pending(batch);
498c2ecf20Sopenharmony_ci	batch->active = 0;
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci#define arch_flush_lazy_mmu_mode()      do {} while (0)
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ciextern void hash__tlbiel_all(unsigned int action);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ciextern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize,
578c2ecf20Sopenharmony_ci			    int ssize, unsigned long flags);
588c2ecf20Sopenharmony_ciextern void flush_hash_range(unsigned long number, int local);
598c2ecf20Sopenharmony_ciextern void flush_hash_hugepage(unsigned long vsid, unsigned long addr,
608c2ecf20Sopenharmony_ci				pmd_t *pmdp, unsigned int psize, int ssize,
618c2ecf20Sopenharmony_ci				unsigned long flags);
628c2ecf20Sopenharmony_cistatic inline void hash__local_flush_tlb_mm(struct mm_struct *mm)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci}
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistatic inline void hash__flush_tlb_mm(struct mm_struct *mm)
678c2ecf20Sopenharmony_ci{
688c2ecf20Sopenharmony_ci}
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_cistatic inline void hash__local_flush_all_mm(struct mm_struct *mm)
718c2ecf20Sopenharmony_ci{
728c2ecf20Sopenharmony_ci	/*
738c2ecf20Sopenharmony_ci	 * There's no Page Walk Cache for hash, so what is needed is
748c2ecf20Sopenharmony_ci	 * the same as flush_tlb_mm(), which doesn't really make sense
758c2ecf20Sopenharmony_ci	 * with hash. So the only thing we could do is flush the
768c2ecf20Sopenharmony_ci	 * entire LPID! Punt for now, as it's not being used.
778c2ecf20Sopenharmony_ci	 */
788c2ecf20Sopenharmony_ci	WARN_ON_ONCE(1);
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cistatic inline void hash__flush_all_mm(struct mm_struct *mm)
828c2ecf20Sopenharmony_ci{
838c2ecf20Sopenharmony_ci	/*
848c2ecf20Sopenharmony_ci	 * There's no Page Walk Cache for hash, so what is needed is
858c2ecf20Sopenharmony_ci	 * the same as flush_tlb_mm(), which doesn't really make sense
868c2ecf20Sopenharmony_ci	 * with hash. So the only thing we could do is flush the
878c2ecf20Sopenharmony_ci	 * entire LPID! Punt for now, as it's not being used.
888c2ecf20Sopenharmony_ci	 */
898c2ecf20Sopenharmony_ci	WARN_ON_ONCE(1);
908c2ecf20Sopenharmony_ci}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_cistatic inline void hash__local_flush_tlb_page(struct vm_area_struct *vma,
938c2ecf20Sopenharmony_ci					  unsigned long vmaddr)
948c2ecf20Sopenharmony_ci{
958c2ecf20Sopenharmony_ci}
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistatic inline void hash__flush_tlb_page(struct vm_area_struct *vma,
988c2ecf20Sopenharmony_ci				    unsigned long vmaddr)
998c2ecf20Sopenharmony_ci{
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cistatic inline void hash__flush_tlb_range(struct vm_area_struct *vma,
1038c2ecf20Sopenharmony_ci				     unsigned long start, unsigned long end)
1048c2ecf20Sopenharmony_ci{
1058c2ecf20Sopenharmony_ci}
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_cistatic inline void hash__flush_tlb_kernel_range(unsigned long start,
1088c2ecf20Sopenharmony_ci					    unsigned long end)
1098c2ecf20Sopenharmony_ci{
1108c2ecf20Sopenharmony_ci}
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_cistruct mmu_gather;
1148c2ecf20Sopenharmony_ciextern void hash__tlb_flush(struct mmu_gather *tlb);
1158c2ecf20Sopenharmony_ci/* Private function for use by PCI IO mapping code */
1168c2ecf20Sopenharmony_ciextern void __flush_hash_table_range(unsigned long start, unsigned long end);
1178c2ecf20Sopenharmony_ciextern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,
1188c2ecf20Sopenharmony_ci				unsigned long addr);
1198c2ecf20Sopenharmony_ci#endif /*  _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H */
120