4
4
#include <linux/smp.h>
5
5
#include <linux/sched.h>
6
6
#include <linux/hugetlb.h>
7
+ #include <linux/mmu_notifier.h>
7
8
#include <asm/sbi.h>
8
9
#include <asm/mmu_context.h>
9
10
@@ -78,10 +79,17 @@ static void __ipi_flush_tlb_range_asid(void *info)
78
79
local_flush_tlb_range_asid (d -> start , d -> size , d -> stride , d -> asid );
79
80
}
80
81
81
- static void __flush_tlb_range (const struct cpumask * cmask , unsigned long asid ,
82
+ static inline unsigned long get_mm_asid (struct mm_struct * mm )
83
+ {
84
+ return mm ? cntx2asid (atomic_long_read (& mm -> context .id )) : FLUSH_TLB_NO_ASID ;
85
+ }
86
+
87
+ static void __flush_tlb_range (struct mm_struct * mm ,
88
+ const struct cpumask * cmask ,
82
89
unsigned long start , unsigned long size ,
83
90
unsigned long stride )
84
91
{
92
+ unsigned long asid = get_mm_asid (mm );
85
93
unsigned int cpu ;
86
94
87
95
if (cpumask_empty (cmask ))
@@ -105,30 +113,26 @@ static void __flush_tlb_range(const struct cpumask *cmask, unsigned long asid,
105
113
}
106
114
107
115
put_cpu ();
108
- }
109
116
110
- static inline unsigned long get_mm_asid (struct mm_struct * mm )
111
- {
112
- return cntx2asid (atomic_long_read (& mm -> context .id ));
117
+ if (mm )
118
+ mmu_notifier_arch_invalidate_secondary_tlbs (mm , start , start + size );
113
119
}
114
120
115
121
void flush_tlb_mm (struct mm_struct * mm )
116
122
{
117
- __flush_tlb_range (mm_cpumask (mm ), get_mm_asid (mm ),
118
- 0 , FLUSH_TLB_MAX_SIZE , PAGE_SIZE );
123
+ __flush_tlb_range (mm , mm_cpumask (mm ), 0 , FLUSH_TLB_MAX_SIZE , PAGE_SIZE );
119
124
}
120
125
121
126
void flush_tlb_mm_range (struct mm_struct * mm ,
122
127
unsigned long start , unsigned long end ,
123
128
unsigned int page_size )
124
129
{
125
- __flush_tlb_range (mm_cpumask (mm ), get_mm_asid (mm ),
126
- start , end - start , page_size );
130
+ __flush_tlb_range (mm , mm_cpumask (mm ), start , end - start , page_size );
127
131
}
128
132
129
133
void flush_tlb_page (struct vm_area_struct * vma , unsigned long addr )
130
134
{
131
- __flush_tlb_range (mm_cpumask ( vma -> vm_mm ), get_mm_asid (vma -> vm_mm ),
135
+ __flush_tlb_range (vma -> vm_mm , mm_cpumask (vma -> vm_mm ),
132
136
addr , PAGE_SIZE , PAGE_SIZE );
133
137
}
134
138
@@ -161,21 +165,21 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
161
165
}
162
166
}
163
167
164
- __flush_tlb_range (mm_cpumask ( vma -> vm_mm ), get_mm_asid (vma -> vm_mm ),
168
+ __flush_tlb_range (vma -> vm_mm , mm_cpumask (vma -> vm_mm ),
165
169
start , end - start , stride_size );
166
170
}
167
171
168
172
void flush_tlb_kernel_range (unsigned long start , unsigned long end )
169
173
{
170
- __flush_tlb_range (cpu_online_mask , FLUSH_TLB_NO_ASID ,
174
+ __flush_tlb_range (NULL , cpu_online_mask ,
171
175
start , end - start , PAGE_SIZE );
172
176
}
173
177
174
178
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
175
179
void flush_pmd_tlb_range (struct vm_area_struct * vma , unsigned long start ,
176
180
unsigned long end )
177
181
{
178
- __flush_tlb_range (mm_cpumask ( vma -> vm_mm ), get_mm_asid (vma -> vm_mm ),
182
+ __flush_tlb_range (vma -> vm_mm , mm_cpumask (vma -> vm_mm ),
179
183
start , end - start , PMD_SIZE );
180
184
}
181
185
#endif
@@ -189,7 +193,10 @@ void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *batch,
189
193
struct mm_struct * mm ,
190
194
unsigned long uaddr )
191
195
{
196
+ unsigned long start = uaddr & PAGE_MASK ;
197
+
192
198
cpumask_or (& batch -> cpumask , & batch -> cpumask , mm_cpumask (mm ));
199
+ mmu_notifier_arch_invalidate_secondary_tlbs (mm , start , start + PAGE_SIZE );
193
200
}
194
201
195
202
void arch_flush_tlb_batched_pending (struct mm_struct * mm )
@@ -199,7 +206,7 @@ void arch_flush_tlb_batched_pending(struct mm_struct *mm)
199
206
200
207
void arch_tlbbatch_flush (struct arch_tlbflush_unmap_batch * batch )
201
208
{
202
- __flush_tlb_range (& batch -> cpumask , FLUSH_TLB_NO_ASID , 0 ,
203
- FLUSH_TLB_MAX_SIZE , PAGE_SIZE );
209
+ __flush_tlb_range (NULL , & batch -> cpumask ,
210
+ 0 , FLUSH_TLB_MAX_SIZE , PAGE_SIZE );
204
211
cpumask_clear (& batch -> cpumask );
205
212
}
0 commit comments