unsigned long addr; /* User-specified address from which we remap. */
unsigned long old_len; /* Length of range being remapped. */
unsigned long new_len; /* Desired new length of mapping. */
- unsigned long flags; /* user-specified MREMAP_* flags. */
+ const unsigned long flags; /* user-specified MREMAP_* flags. */
unsigned long new_addr; /* Optionally, desired new address. */
/* uffd state. */
return false;
}
-/* Do the mremap() flags require that the new_addr parameter be specified? */
+/*
+ * Will a new address definitely be assigned? This either if the user specifies
+ * it via MREMAP_FIXED, or if MREMAP_DONTUNMAP is used, indicating we will
+ * always detemrine a target address.
+ */
static bool vrm_implies_new_addr(struct vma_remap_struct *vrm)
{
return vrm->flags & (MREMAP_FIXED | MREMAP_DONTUNMAP);
*
* Returns true on success, false if insufficient memory to charge.
*/
-static bool vrm_charge(struct vma_remap_struct *vrm)
+static bool vrm_calc_charge(struct vma_remap_struct *vrm)
{
unsigned long charged;
if (err)
return err;
- /* If accounted, charge the number of bytes the operation will use. */
- if (!vrm_charge(vrm))
+ /*
+ * If accounted, determine the number of bytes the operation will
+ * charge.
+ */
+ if (!vrm_calc_charge(vrm))
return -ENOMEM;
/* We don't want racing faults. */
}
/*
- * resize_is_valid() - Ensure the vma can be resized to the new length at the give
- * address.
+ * remap_is_valid() - Ensure the VMA can be moved or resized to the new length,
+ * at the given address.
*
* Return 0 on success, error otherwise.
*/
-static int resize_is_valid(struct vma_remap_struct *vrm)
+static int remap_is_valid(struct vma_remap_struct *vrm)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma = vrm->vma;
vrm->old_len = vrm->new_len;
}
- err = resize_is_valid(vrm);
+ err = remap_is_valid(vrm);
if (err)
return err;
struct vm_area_struct *vma = vrm->vma;
VMA_ITERATOR(vmi, mm, vma->vm_end);
- if (!vrm_charge(vrm))
+ if (!vrm_calc_charge(vrm))
return -ENOMEM;
/*
unsigned long err;
unsigned long addr = vrm->addr;
- err = resize_is_valid(vrm);
+ err = remap_is_valid(vrm);
if (err)
return err;
return expand_vma(vrm);
}
- BUG();
+ /* Should not be possible. */
+ WARN_ON_ONCE(1);
+ return -EINVAL;
}
static unsigned long do_mremap(struct vma_remap_struct *vrm)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- unsigned long ret;
+ unsigned long res;
- ret = check_mremap_params(vrm);
- if (ret)
- return ret;
+ res = check_mremap_params(vrm);
+ if (res)
+ return res;
vrm->old_len = PAGE_ALIGN(vrm->old_len);
vrm->new_len = PAGE_ALIGN(vrm->new_len);
vma = vrm->vma = vma_lookup(mm, vrm->addr);
if (!vma) {
- ret = -EFAULT;
+ res = -EFAULT;
goto out;
}
/* If mseal()'d, mremap() is prohibited. */
if (!can_modify_vma(vma)) {
- ret = -EPERM;
+ res = -EPERM;
goto out;
}
/* Align to hugetlb page size, if required. */
if (is_vm_hugetlb_page(vma) && !align_hugetlb(vrm)) {
- ret = -EINVAL;
+ res = -EINVAL;
goto out;
}
vrm->remap_type = vrm_remap_type(vrm);
/* Actually execute mremap. */
- ret = vrm_implies_new_addr(vrm) ? mremap_to(vrm) : mremap_at(vrm);
+ res = vrm_implies_new_addr(vrm) ? mremap_to(vrm) : mremap_at(vrm);
out:
if (vrm->mmap_locked) {
mmap_write_unlock(mm);
vrm->mmap_locked = false;
- if (!offset_in_page(ret) && vrm->mlocked && vrm->new_len > vrm->old_len)
+ if (!offset_in_page(res) && vrm->mlocked && vrm->new_len > vrm->old_len)
mm_populate(vrm->new_addr + vrm->old_len, vrm->delta);
}
userfaultfd_unmap_complete(mm, vrm->uf_unmap_early);
- mremap_userfaultfd_complete(vrm->uf, vrm->addr, ret, vrm->old_len);
+ mremap_userfaultfd_complete(vrm->uf, vrm->addr, res, vrm->old_len);
userfaultfd_unmap_complete(mm, vrm->uf_unmap);
- return ret;
+ return res;
}
/*