xref: /OK3568_Linux_fs/kernel/arch/powerpc/include/asm/book3s/64/tlbflush.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H
3*4882a593Smuzhiyun #define _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #define MMU_NO_CONTEXT	~0UL
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <linux/mm_types.h>
8*4882a593Smuzhiyun #include <asm/book3s/64/tlbflush-hash.h>
9*4882a593Smuzhiyun #include <asm/book3s/64/tlbflush-radix.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /* TLB flush actions. Used as argument to tlbiel_all() */
12*4882a593Smuzhiyun enum {
13*4882a593Smuzhiyun 	TLB_INVAL_SCOPE_GLOBAL = 0,	/* invalidate all TLBs */
14*4882a593Smuzhiyun 	TLB_INVAL_SCOPE_LPID = 1,	/* invalidate TLBs for current LPID */
15*4882a593Smuzhiyun };
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #ifdef CONFIG_PPC_NATIVE
tlbiel_all(void)18*4882a593Smuzhiyun static inline void tlbiel_all(void)
19*4882a593Smuzhiyun {
20*4882a593Smuzhiyun 	/*
21*4882a593Smuzhiyun 	 * This is used for host machine check and bootup.
22*4882a593Smuzhiyun 	 *
23*4882a593Smuzhiyun 	 * This uses early_radix_enabled and implementations use
24*4882a593Smuzhiyun 	 * early_cpu_has_feature etc because that works early in boot
25*4882a593Smuzhiyun 	 * and this is the machine check path which is not performance
26*4882a593Smuzhiyun 	 * critical.
27*4882a593Smuzhiyun 	 */
28*4882a593Smuzhiyun 	if (early_radix_enabled())
29*4882a593Smuzhiyun 		radix__tlbiel_all(TLB_INVAL_SCOPE_GLOBAL);
30*4882a593Smuzhiyun 	else
31*4882a593Smuzhiyun 		hash__tlbiel_all(TLB_INVAL_SCOPE_GLOBAL);
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun #else
tlbiel_all(void)34*4882a593Smuzhiyun static inline void tlbiel_all(void) { BUG(); };
35*4882a593Smuzhiyun #endif
36*4882a593Smuzhiyun 
tlbiel_all_lpid(bool radix)37*4882a593Smuzhiyun static inline void tlbiel_all_lpid(bool radix)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun 	/*
40*4882a593Smuzhiyun 	 * This is used for guest machine check.
41*4882a593Smuzhiyun 	 */
42*4882a593Smuzhiyun 	if (radix)
43*4882a593Smuzhiyun 		radix__tlbiel_all(TLB_INVAL_SCOPE_LPID);
44*4882a593Smuzhiyun 	else
45*4882a593Smuzhiyun 		hash__tlbiel_all(TLB_INVAL_SCOPE_LPID);
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
flush_pmd_tlb_range(struct vm_area_struct * vma,unsigned long start,unsigned long end)50*4882a593Smuzhiyun static inline void flush_pmd_tlb_range(struct vm_area_struct *vma,
51*4882a593Smuzhiyun 				       unsigned long start, unsigned long end)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun 	if (radix_enabled())
54*4882a593Smuzhiyun 		return radix__flush_pmd_tlb_range(vma, start, end);
55*4882a593Smuzhiyun 	return hash__flush_tlb_range(vma, start, end);
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun #define __HAVE_ARCH_FLUSH_HUGETLB_TLB_RANGE
flush_hugetlb_tlb_range(struct vm_area_struct * vma,unsigned long start,unsigned long end)59*4882a593Smuzhiyun static inline void flush_hugetlb_tlb_range(struct vm_area_struct *vma,
60*4882a593Smuzhiyun 					   unsigned long start,
61*4882a593Smuzhiyun 					   unsigned long end)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	if (radix_enabled())
64*4882a593Smuzhiyun 		return radix__flush_hugetlb_tlb_range(vma, start, end);
65*4882a593Smuzhiyun 	return hash__flush_tlb_range(vma, start, end);
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun 
flush_tlb_range(struct vm_area_struct * vma,unsigned long start,unsigned long end)68*4882a593Smuzhiyun static inline void flush_tlb_range(struct vm_area_struct *vma,
69*4882a593Smuzhiyun 				   unsigned long start, unsigned long end)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun 	if (radix_enabled())
72*4882a593Smuzhiyun 		return radix__flush_tlb_range(vma, start, end);
73*4882a593Smuzhiyun 	return hash__flush_tlb_range(vma, start, end);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun 
flush_tlb_kernel_range(unsigned long start,unsigned long end)76*4882a593Smuzhiyun static inline void flush_tlb_kernel_range(unsigned long start,
77*4882a593Smuzhiyun 					  unsigned long end)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	if (radix_enabled())
80*4882a593Smuzhiyun 		return radix__flush_tlb_kernel_range(start, end);
81*4882a593Smuzhiyun 	return hash__flush_tlb_kernel_range(start, end);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
local_flush_tlb_mm(struct mm_struct * mm)84*4882a593Smuzhiyun static inline void local_flush_tlb_mm(struct mm_struct *mm)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun 	if (radix_enabled())
87*4882a593Smuzhiyun 		return radix__local_flush_tlb_mm(mm);
88*4882a593Smuzhiyun 	return hash__local_flush_tlb_mm(mm);
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun 
local_flush_tlb_page(struct vm_area_struct * vma,unsigned long vmaddr)91*4882a593Smuzhiyun static inline void local_flush_tlb_page(struct vm_area_struct *vma,
92*4882a593Smuzhiyun 					unsigned long vmaddr)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	if (radix_enabled())
95*4882a593Smuzhiyun 		return radix__local_flush_tlb_page(vma, vmaddr);
96*4882a593Smuzhiyun 	return hash__local_flush_tlb_page(vma, vmaddr);
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun 
local_flush_all_mm(struct mm_struct * mm)99*4882a593Smuzhiyun static inline void local_flush_all_mm(struct mm_struct *mm)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	if (radix_enabled())
102*4882a593Smuzhiyun 		return radix__local_flush_all_mm(mm);
103*4882a593Smuzhiyun 	return hash__local_flush_all_mm(mm);
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun 
tlb_flush(struct mmu_gather * tlb)106*4882a593Smuzhiyun static inline void tlb_flush(struct mmu_gather *tlb)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun 	if (radix_enabled())
109*4882a593Smuzhiyun 		return radix__tlb_flush(tlb);
110*4882a593Smuzhiyun 	return hash__tlb_flush(tlb);
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun #ifdef CONFIG_SMP
flush_tlb_mm(struct mm_struct * mm)114*4882a593Smuzhiyun static inline void flush_tlb_mm(struct mm_struct *mm)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun 	if (radix_enabled())
117*4882a593Smuzhiyun 		return radix__flush_tlb_mm(mm);
118*4882a593Smuzhiyun 	return hash__flush_tlb_mm(mm);
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun 
flush_tlb_page(struct vm_area_struct * vma,unsigned long vmaddr)121*4882a593Smuzhiyun static inline void flush_tlb_page(struct vm_area_struct *vma,
122*4882a593Smuzhiyun 				  unsigned long vmaddr)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun 	if (radix_enabled())
125*4882a593Smuzhiyun 		return radix__flush_tlb_page(vma, vmaddr);
126*4882a593Smuzhiyun 	return hash__flush_tlb_page(vma, vmaddr);
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun 
flush_all_mm(struct mm_struct * mm)129*4882a593Smuzhiyun static inline void flush_all_mm(struct mm_struct *mm)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun 	if (radix_enabled())
132*4882a593Smuzhiyun 		return radix__flush_all_mm(mm);
133*4882a593Smuzhiyun 	return hash__flush_all_mm(mm);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun #else
136*4882a593Smuzhiyun #define flush_tlb_mm(mm)		local_flush_tlb_mm(mm)
137*4882a593Smuzhiyun #define flush_tlb_page(vma, addr)	local_flush_tlb_page(vma, addr)
138*4882a593Smuzhiyun #define flush_all_mm(mm)		local_flush_all_mm(mm)
139*4882a593Smuzhiyun #endif /* CONFIG_SMP */
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun #define flush_tlb_fix_spurious_fault flush_tlb_fix_spurious_fault
flush_tlb_fix_spurious_fault(struct vm_area_struct * vma,unsigned long address)142*4882a593Smuzhiyun static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma,
143*4882a593Smuzhiyun 						unsigned long address)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	/* See ptep_set_access_flags comment */
146*4882a593Smuzhiyun 	if (atomic_read(&vma->vm_mm->context.copros) > 0)
147*4882a593Smuzhiyun 		flush_tlb_page(vma, address);
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun extern bool tlbie_capable;
151*4882a593Smuzhiyun extern bool tlbie_enabled;
152*4882a593Smuzhiyun 
cputlb_use_tlbie(void)153*4882a593Smuzhiyun static inline bool cputlb_use_tlbie(void)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun 	return tlbie_enabled;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun #endif /*  _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H */
159