/* the various vma->vm_userfaultfd_ctx still points to it */
mmap_write_lock(mm);
+ mas_lock(&mas);
mas_for_each(&mas, vma, ULONG_MAX) {
if (vma->vm_userfaultfd_ctx.ctx == release_new_ctx) {
vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
vma->vm_flags &= ~(VM_UFFD_WP | VM_UFFD_MISSING);
}
}
+ mas_unlock(&mas);
mmap_write_unlock(mm);
userfaultfd_ctx_put(release_new_ctx);
{
MA_STATE(mas, &vma->vm_mm->mm_mt, vma->vm_start, vma->vm_start);
+ rcu_read_lock();
mas_for_each(&mas, vma, end) {
struct userfaultfd_unmap_ctx *unmap_ctx;
struct userfaultfd_ctx *ctx = vma->vm_userfaultfd_ctx.ctx;
unmap_ctx->end = end;
list_add_tail(&unmap_ctx->list, unmaps);
}
+ rcu_read_unlock();
return 0;
}
* taking the mmap_lock for writing.
*/
mmap_write_lock(mm);
+ mas_lock(&mas);
prev = NULL;
mas_for_each(&mas, vma, ULONG_MAX) {
+ mas_unlock(&mas);
+ mas_pause(&mas);
cond_resched();
+ mas_lock(&mas);
+
BUG_ON(!!vma->vm_userfaultfd_ctx.ctx ^
!!(vma->vm_flags & (VM_UFFD_MISSING | VM_UFFD_WP)));
if (vma->vm_userfaultfd_ctx.ctx != ctx) {
vma->vm_flags = new_flags;
vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
}
+ mas_unlock(&mas);
mmap_write_unlock(mm);
mmput(mm);
wakeup:
goto out;
mmap_write_lock(mm);
+ rcu_read_lock();
vma = find_vma_prev(mm, start, &prev);
if (!vma)
goto out_unlock;
basic_ioctls = false;
mas_set(&mas, vma->vm_start);
mas_for_each(&mas, cur, end) {
+ rcu_read_unlock();
+ mas_pause(&mas);
cond_resched();
+ rcu_read_lock();
BUG_ON(!!cur->vm_userfaultfd_ctx.ctx ^
!!(cur->vm_flags & (VM_UFFD_MISSING | VM_UFFD_WP)));
vma = vma_next(mm, vma);
} while (vma && vma->vm_start < end);
out_unlock:
+ rcu_read_unlock();
mmap_write_unlock(mm);
mmput(mm);
if (!ret) {
*/
found = false;
ret = -EINVAL;
+ rcu_read_lock();
mas_set(&mas, vma->vm_start);
-
mas_for_each(&mas, cur, end) {
+ rcu_read_unlock();
+ mas_pause(&mas);
cond_resched();
+ rcu_read_lock();
BUG_ON(!!cur->vm_userfaultfd_ctx.ctx ^
!!(cur->vm_flags & (VM_UFFD_MISSING | VM_UFFD_WP)));
found = true;
}
+ rcu_read_unlock();
BUG_ON(!found);
if (vma->vm_start < start)