On Sat, Jul 21, 2018 at 3:34 PM Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote: > > But I basically think that with those patches in place, we can: > > - make vm_area_alloc() just default vm_ops to &dummy_vm_ops > > - just take the part of Kirill's patch that does > > vma->vm_ops = &anon_vm_ops; > > and instead of '&anon_vm_ops', set it to NULL. IOW, Kirill's patch now just boils down to the attached trial patch. I will *not* be committing this last patch, I think it needs more testing and ack's. And honestly, authorship should go to Kirill if he's ok with it, because all the basic "these are the anonymous vma's" places came from Kirill's patch and work. But it works for me, and I did commit and push out the parts that were just trivial cleanups with no actual semantic changes. Comments? Linus
drivers/char/mem.c | 1 + fs/exec.c | 1 + kernel/fork.c | 2 ++ mm/mmap.c | 4 +++- mm/nommu.c | 3 ++- 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/char/mem.c b/drivers/char/mem.c index ffeb60d3434c..0d4c185c2f6c 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -708,6 +708,7 @@ static int mmap_zero(struct file *file, struct vm_area_struct *vma) #endif if (vma->vm_flags & VM_SHARED) return shmem_zero_setup(vma); + vma->vm_ops = NULL; return 0; } diff --git a/fs/exec.c b/fs/exec.c index 72e961a62adb..b0c6efce324a 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -293,6 +293,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm) bprm->vma = vma = vm_area_alloc(mm); if (!vma) return -ENOMEM; + vma->vm_ops = NULL; if (down_write_killable(&mm->mmap_sem)) { err = -EINTR; diff --git a/kernel/fork.c b/kernel/fork.c index a191c05e757d..dd50b5220713 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -310,11 +310,13 @@ static struct kmem_cache *mm_cachep; struct vm_area_struct *vm_area_alloc(struct mm_struct *mm) { + static const struct vm_operations_struct dummy_vm_ops = {}; struct vm_area_struct *vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); if (vma) { vma->vm_mm = mm; INIT_LIST_HEAD(&vma->anon_vma_chain); + vma->vm_ops = &dummy_vm_ops; } return vma; } diff --git a/mm/mmap.c b/mm/mmap.c index ff1944d8d458..b90176eb9e94 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1778,7 +1778,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, error = shmem_zero_setup(vma); if (error) goto free_vma; - } + } else + vma->vm_ops = NULL; vma_link(mm, vma, prev, rb_link, rb_parent); /* Once vma denies write, undo our temporary denial count */ @@ -2983,6 +2984,7 @@ static int do_brk_flags(unsigned long addr, unsigned long len, unsigned long fla return -ENOMEM; } + vma->vm_ops = NULL; vma->vm_start = addr; vma->vm_end = addr + len; vma->vm_pgoff = pgoff; diff --git a/mm/nommu.c b/mm/nommu.c index 1d22fdbf7d7c..e1f8b7eb5683 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1145,7 +1145,8 @@ static int do_mmap_private(struct vm_area_struct *vma, if (ret < len) memset(base + ret, 0, len - ret); - } + } else + vma->vm_ops = NULL; return 0;