summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mm/util.c6
-rw-r--r--tools/testing/vma/include/dup.h42
2 files changed, 27 insertions, 21 deletions
diff --git a/mm/util.c b/mm/util.c
index a2cfa0d77c35..54eab29adb56 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -1204,6 +1204,7 @@ int compat_vma_mmap(struct file *file, struct vm_area_struct *vma)
.action.type = MMAP_NOTHING, /* Default */
};
+ struct mmap_action *action = &desc.action;
int err;
err = vfs_mmap_prepare(file, &desc);
@@ -1214,8 +1215,11 @@ int compat_vma_mmap(struct file *file, struct vm_area_struct *vma)
if (err)
return err;
+ /* being invoked from .mmap means we don't have to enforce this. */
+ action->hide_from_rmap_until_complete = false;
+
set_vma_from_desc(vma, &desc);
- err = mmap_action_complete(vma, &desc.action);
+ err = mmap_action_complete(vma, action);
if (err) {
const size_t len = vma_pages(vma) << PAGE_SHIFT;
diff --git a/tools/testing/vma/include/dup.h b/tools/testing/vma/include/dup.h
index 5bc04c801504..64bb56980b9c 100644
--- a/tools/testing/vma/include/dup.h
+++ b/tools/testing/vma/include/dup.h
@@ -1260,8 +1260,17 @@ static inline void vma_set_anonymous(struct vm_area_struct *vma)
static inline void set_vma_from_desc(struct vm_area_struct *vma,
struct vm_area_desc *desc);
-static inline int __compat_vma_mmap(const struct file_operations *f_op,
- struct file *file, struct vm_area_struct *vma)
+static inline int vfs_mmap_prepare(struct file *file, struct vm_area_desc *desc)
+{
+ return file->f_op->mmap_prepare(desc);
+}
+
+static inline unsigned long vma_pages(struct vm_area_struct *vma)
+{
+ return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+}
+
+static inline int compat_vma_mmap(struct file *file, struct vm_area_struct *vma)
{
struct vm_area_desc desc = {
.mm = vma->vm_mm,
@@ -1276,9 +1285,10 @@ static inline int __compat_vma_mmap(const struct file_operations *f_op,
.action.type = MMAP_NOTHING, /* Default */
};
+ struct mmap_action *action = &desc.action;
int err;
- err = f_op->mmap_prepare(&desc);
+ err = vfs_mmap_prepare(file, &desc);
if (err)
return err;
@@ -1286,28 +1296,25 @@ static inline int __compat_vma_mmap(const struct file_operations *f_op,
if (err)
return err;
+ /* being invoked from .mmmap means we don't have to enforce this. */
+ action->hide_from_rmap_until_complete = false;
+
set_vma_from_desc(vma, &desc);
- return mmap_action_complete(vma, &desc.action);
-}
+ err = mmap_action_complete(vma, action);
+ if (err) {
+ const size_t len = vma_pages(vma) << PAGE_SHIFT;
-static inline int compat_vma_mmap(struct file *file,
- struct vm_area_struct *vma)
-{
- return __compat_vma_mmap(file->f_op, file, vma);
+ do_munmap(current->mm, vma->vm_start, len, NULL);
+ }
+ return err;
}
-
static inline void vma_iter_init(struct vma_iterator *vmi,
struct mm_struct *mm, unsigned long addr)
{
mas_init(&vmi->mas, &mm->mm_mt, addr);
}
-static inline unsigned long vma_pages(struct vm_area_struct *vma)
-{
- return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
-}
-
static inline void mmap_assert_locked(struct mm_struct *);
static inline struct vm_area_struct *find_vma_intersection(struct mm_struct *mm,
unsigned long start_addr,
@@ -1477,11 +1484,6 @@ static inline int vfs_mmap(struct file *file, struct vm_area_struct *vma)
return file->f_op->mmap(file, vma);
}
-static inline int vfs_mmap_prepare(struct file *file, struct vm_area_desc *desc)
-{
- return file->f_op->mmap_prepare(desc);
-}
-
static inline void vma_set_file(struct vm_area_struct *vma, struct file *file)
{
/* Changing an anonymous vma with this is illegal */