mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-31 04:01:48 -04:00
userfaultfd: non-cooperative: add mremap() event
The event denotes that an area [start:end] moves to different location. Length change isn't reported as "new" addresses, if they appear on the uffd reader side they will not contain any data and the latter can just zeromap them. Waiting for the event ACK is also done outside of mmap sem, as for fork event. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Pavel Emelyanov <[email protected]> Signed-off-by: Mike Rapoport <[email protected]> Signed-off-by: Andrea Arcangeli <[email protected]> Cc: "Dr. David Alan Gilbert" <[email protected]> Cc: Hillf Danton <[email protected]> Cc: Michael Rapoport <[email protected]> Cc: Mike Kravetz <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
d3aadc8ed4
commit
72f87654c6
4 changed files with 76 additions and 6 deletions
17
mm/mremap.c
17
mm/mremap.c
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/mmu_notifier.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/mm-arch-hooks.h>
|
||||
#include <linux/userfaultfd_k.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
|
@ -250,7 +251,8 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
|
|||
|
||||
static unsigned long move_vma(struct vm_area_struct *vma,
|
||||
unsigned long old_addr, unsigned long old_len,
|
||||
unsigned long new_len, unsigned long new_addr, bool *locked)
|
||||
unsigned long new_len, unsigned long new_addr,
|
||||
bool *locked, struct vm_userfaultfd_ctx *uf)
|
||||
{
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
struct vm_area_struct *new_vma;
|
||||
|
|
@ -309,6 +311,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
|
|||
old_addr = new_addr;
|
||||
new_addr = err;
|
||||
} else {
|
||||
mremap_userfaultfd_prep(new_vma, uf);
|
||||
arch_remap(mm, old_addr, old_addr + old_len,
|
||||
new_addr, new_addr + new_len);
|
||||
}
|
||||
|
|
@ -413,7 +416,8 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
|
|||
}
|
||||
|
||||
static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
|
||||
unsigned long new_addr, unsigned long new_len, bool *locked)
|
||||
unsigned long new_addr, unsigned long new_len, bool *locked,
|
||||
struct vm_userfaultfd_ctx *uf)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
struct vm_area_struct *vma;
|
||||
|
|
@ -458,7 +462,7 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
|
|||
if (offset_in_page(ret))
|
||||
goto out1;
|
||||
|
||||
ret = move_vma(vma, addr, old_len, new_len, new_addr, locked);
|
||||
ret = move_vma(vma, addr, old_len, new_len, new_addr, locked, uf);
|
||||
if (!(offset_in_page(ret)))
|
||||
goto out;
|
||||
out1:
|
||||
|
|
@ -497,6 +501,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
|
|||
unsigned long ret = -EINVAL;
|
||||
unsigned long charged = 0;
|
||||
bool locked = false;
|
||||
struct vm_userfaultfd_ctx uf = NULL_VM_UFFD_CTX;
|
||||
|
||||
if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
|
||||
return ret;
|
||||
|
|
@ -523,7 +528,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
|
|||
|
||||
if (flags & MREMAP_FIXED) {
|
||||
ret = mremap_to(addr, old_len, new_addr, new_len,
|
||||
&locked);
|
||||
&locked, &uf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -592,7 +597,8 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = move_vma(vma, addr, old_len, new_len, new_addr, &locked);
|
||||
ret = move_vma(vma, addr, old_len, new_len, new_addr,
|
||||
&locked, &uf);
|
||||
}
|
||||
out:
|
||||
if (offset_in_page(ret)) {
|
||||
|
|
@ -602,5 +608,6 @@ out:
|
|||
up_write(¤t->mm->mmap_sem);
|
||||
if (locked && new_len > old_len)
|
||||
mm_populate(new_addr + old_len, new_len - old_len);
|
||||
mremap_userfaultfd_complete(uf, addr, new_addr, old_len);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue