mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 12:21:22 -05:00
mm/mremap: cleanup post-processing stage of mremap
Separate out the uffd bits so it clear's what's happening. Don't bother setting vrm->mmap_locked after unlocking, because after this we are done anyway. The only time we drop the mmap lock is on VMA shrink, at which point vrm->new_len will be < vrm->old_len and the operation will not be performed anyway, so move this code out of the if (vrm->mmap_locked) block. All addresses returned by mremap() are page-aligned, so the offset_in_page() check on ret seems only to be incorrectly trying to detect whether an error occurred - explicitly check for this. No functional change intended. Link: https://lkml.kernel.org/r/ebb8f29650b8e343fe98fefc67b3a61a24d1e0f1.1752770784.git.lorenzo.stoakes@oracle.com Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Reviewed-by: Vlastimil Babka <vbabka@suse.cz> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christian Brauner <brauner@kernel.org> Cc: Jan Kara <jack@suse.cz> Cc: Jann Horn <jannh@google.com> Cc: Liam Howlett <liam.howlett@oracle.com> Cc: Peter Xu <peterx@redhat.com> Cc: Rik van Riel <riel@surriel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
f256a7a4ca
commit
e49e76c20b
22
mm/mremap.c
22
mm/mremap.c
@@ -1729,6 +1729,15 @@ static int check_prep_vma(struct vma_remap_struct *vrm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void notify_uffd(struct vma_remap_struct *vrm, unsigned long to)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
userfaultfd_unmap_complete(mm, vrm->uf_unmap_early);
|
||||
mremap_userfaultfd_complete(vrm->uf, vrm->addr, to, vrm->old_len);
|
||||
userfaultfd_unmap_complete(mm, vrm->uf_unmap);
|
||||
}
|
||||
|
||||
static unsigned long do_mremap(struct vma_remap_struct *vrm)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
@@ -1754,18 +1763,13 @@ static unsigned long do_mremap(struct vma_remap_struct *vrm)
|
||||
res = vrm_implies_new_addr(vrm) ? mremap_to(vrm) : mremap_at(vrm);
|
||||
|
||||
out:
|
||||
if (vrm->mmap_locked) {
|
||||
if (vrm->mmap_locked)
|
||||
mmap_write_unlock(mm);
|
||||
vrm->mmap_locked = false;
|
||||
|
||||
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, res, vrm->old_len);
|
||||
userfaultfd_unmap_complete(mm, vrm->uf_unmap);
|
||||
if (!IS_ERR_VALUE(res) && vrm->mlocked && vrm->new_len > vrm->old_len)
|
||||
mm_populate(vrm->new_addr + vrm->old_len, vrm->delta);
|
||||
|
||||
notify_uffd(vrm, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user