summaryrefslogtreecommitdiffstats
path: root/mm/mmu_notifier.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mmu_notifier.c')
-rw-r--r--mm/mmu_notifier.c31
1 files changed, 11 insertions, 20 deletions
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
index 5119ff846769..9c884abc7850 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -35,13 +35,6 @@ void mmu_notifier_call_srcu(struct rcu_head *rcu,
35} 35}
36EXPORT_SYMBOL_GPL(mmu_notifier_call_srcu); 36EXPORT_SYMBOL_GPL(mmu_notifier_call_srcu);
37 37
38void mmu_notifier_synchronize(void)
39{
40 /* Wait for any running method to finish. */
41 srcu_barrier(&srcu);
42}
43EXPORT_SYMBOL_GPL(mmu_notifier_synchronize);
44
45/* 38/*
46 * This function can't run concurrently against mmu_notifier_register 39 * This function can't run concurrently against mmu_notifier_register
47 * because mm->mm_users > 0 during mmu_notifier_register and exit_mmap 40 * because mm->mm_users > 0 during mmu_notifier_register and exit_mmap
@@ -174,22 +167,20 @@ void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address,
174 srcu_read_unlock(&srcu, id); 167 srcu_read_unlock(&srcu, id);
175} 168}
176 169
177int __mmu_notifier_invalidate_range_start(struct mm_struct *mm, 170int __mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range)
178 unsigned long start, unsigned long end,
179 bool blockable)
180{ 171{
181 struct mmu_notifier *mn; 172 struct mmu_notifier *mn;
182 int ret = 0; 173 int ret = 0;
183 int id; 174 int id;
184 175
185 id = srcu_read_lock(&srcu); 176 id = srcu_read_lock(&srcu);
186 hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) { 177 hlist_for_each_entry_rcu(mn, &range->mm->mmu_notifier_mm->list, hlist) {
187 if (mn->ops->invalidate_range_start) { 178 if (mn->ops->invalidate_range_start) {
188 int _ret = mn->ops->invalidate_range_start(mn, mm, start, end, blockable); 179 int _ret = mn->ops->invalidate_range_start(mn, range);
189 if (_ret) { 180 if (_ret) {
190 pr_info("%pS callback failed with %d in %sblockable context.\n", 181 pr_info("%pS callback failed with %d in %sblockable context.\n",
191 mn->ops->invalidate_range_start, _ret, 182 mn->ops->invalidate_range_start, _ret,
192 !blockable ? "non-" : ""); 183 !range->blockable ? "non-" : "");
193 ret = _ret; 184 ret = _ret;
194 } 185 }
195 } 186 }
@@ -200,16 +191,14 @@ int __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
200} 191}
201EXPORT_SYMBOL_GPL(__mmu_notifier_invalidate_range_start); 192EXPORT_SYMBOL_GPL(__mmu_notifier_invalidate_range_start);
202 193
203void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, 194void __mmu_notifier_invalidate_range_end(struct mmu_notifier_range *range,
204 unsigned long start,
205 unsigned long end,
206 bool only_end) 195 bool only_end)
207{ 196{
208 struct mmu_notifier *mn; 197 struct mmu_notifier *mn;
209 int id; 198 int id;
210 199
211 id = srcu_read_lock(&srcu); 200 id = srcu_read_lock(&srcu);
212 hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) { 201 hlist_for_each_entry_rcu(mn, &range->mm->mmu_notifier_mm->list, hlist) {
213 /* 202 /*
214 * Call invalidate_range here too to avoid the need for the 203 * Call invalidate_range here too to avoid the need for the
215 * subsystem of having to register an invalidate_range_end 204 * subsystem of having to register an invalidate_range_end
@@ -224,9 +213,11 @@ void __mmu_notifier_invalidate_range_end(struct mm_struct *mm,
224 * already happen under page table lock. 213 * already happen under page table lock.
225 */ 214 */
226 if (!only_end && mn->ops->invalidate_range) 215 if (!only_end && mn->ops->invalidate_range)
227 mn->ops->invalidate_range(mn, mm, start, end); 216 mn->ops->invalidate_range(mn, range->mm,
217 range->start,
218 range->end);
228 if (mn->ops->invalidate_range_end) 219 if (mn->ops->invalidate_range_end)
229 mn->ops->invalidate_range_end(mn, mm, start, end); 220 mn->ops->invalidate_range_end(mn, range);
230 } 221 }
231 srcu_read_unlock(&srcu, id); 222 srcu_read_unlock(&srcu, id);
232} 223}