From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E2A33A16B8; Tue, 8 Sep 2026 20:02:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788897750; cv=none; b=sU+qyda9VZ4jIiRrPb+RYn5LO/DxQebfRULHJAweVIm7AEi1nPs6A+A/9w51lo4YtPDOaCA0yYt9yN1TFnDdga9cCsXSPaVOwA9EsalqRmTmgCvA2D1k1Yr6ycTt2NYVImqJEWy5UGvcO0wXPZo3PIfDzkMp+Z+cS8zuoBBo55g= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788897750; c=relaxed/simple; bh=bmDihYBTPF4s+vtesyigFctx5fwOO/lCZ7Euwx9606c=; h=From:Subject:Date:Message-Id:MIME-Version:Content-Type:To:Cc; b=XJmRzSPlXimAh9YXLQuZLIFMEmyKpSie9J7zBjqVd4k3mAcn5glixTjg5Uoy8dXMYNnwntZPrRXeqcV5/du5urY6dTX6c4OqlX81yFSrD9PP2ITghPdf5c5I5YOcwpnwklnYfUpw7WCed0xmKu4au00QefBeIkKBt2dVgpOm3AE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YU+Xck8C; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YU+Xck8C" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A2BE11F00A3D; Tue, 8 Sep 2026 20:01:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788897747; bh=uIndAhwL3wqvdcSni3GXyOpISzBISCVdYFz9JNsvqeQ=; h=From:Subject:Date:To:Cc; b=YU+Xck8C+XjnsENVDQG6USbnOUb+aYEb+z3QjWcnFUpRoboWzDSJm/ve55xNBXnPz VgRvExc5Kva/9BnOHdurKjRPDm3Ft1OrcC3qMwbvTUAozMre+hC/kspsJ1SR2kOznE 2P5inHtPA2s1ewMeO1/CgjKzGee8eAkXi9bnCLISEPEdn7EifxSjL1/CRvt/8Kabid /D6G0BjYPYuszsaBnSin5vkycvI7daTPfopP1YmxREAxMj5DAp4A6TEyCzXVgJmAY+ wG7DfK1fw/6V47qtZWrjBKL/Mjo6hmM0E31ATaPUyDdYzTBKabLRqWnDJArfZK5EH5 i+cxeDdU6Vgaw== From: "Lorenzo Stoakes (ARM)" Subject: [PATCH 00/39] mm: make VMA flag semantics explicit, eliminate VM_SPECIAL Date: Tue, 08 Sep 2026 21:01:04 +0100 Message-Id: <20260908-b4-mmap-prepare-vma-flag-sanify-v1-0-dacf19cce22b@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-B4-Tracking: v=1; b=H4sIAAAAAAAC/yXN0QrCMAyF4VcZuTbQhk3BVxEvsi2dEVtLo2Nj7 N2tevnB4T8bmBQVg3OzQZFZTZ+pwh8aGG6cJkEdq4EcHd2JPPYtxsgZc5HMRXCOjOHBExonDSu Sd66lbgwdM9RK3QVdfg+X69/27u8yvL5Z2PcPxx1VW4MAAAA= X-Change-ID: 20260721-b4-mmap-prepare-vma-flag-sanify-2100425df5aa To: Andrew Morton , "Liam R. Howlett" , Vlastimil Babka , Jann Horn , Pedro Falcato , David Hildenbrand , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Jonathan Corbet , Greg Kroah-Hartman , Dennis Dalessandro , Jason Gunthorpe , Leon Romanovsky , Paul Moore , Stephen Smalley , Jaroslav Kysela , Takashi Iwai , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Zi Yan , Baolin Wang , Nico Pache , Ryan Roberts , Dev Jain , Barry Song , Lance Yang , Usama Arif , Kiryl Shutsemau , Doug Gilbert , "James E.J. Bottomley" , "Martin K. Petersen" , Jaya Kumar , Simona Vetter , Helge Deller , Sebastian Reichel , John Hubbard , Peter Xu , Masami Hiramatsu , Oleg Nesterov , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Rik van Riel , Harry Yoo , Juri Lelli , Vincent Guittot , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Will Deacon , "Aneesh Kumar K.V" , Nick Piggin , Arnd Bergmann , Muchun Song , Oscar Salvador , "Matthew Wilcox (Oracle)" , Jan Kara , Marc Zyngier , Oliver Upton , Catalin Marinas , Madhavan Srinivasan , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Christian Borntraeger , Janosch Frank , Claudio Imbrenda , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , "David S. Miller" , Andreas Larsson , Alexander Viro , Christian Brauner , Matthew Brost , Joshua Hahn , Rakie Kim , Byungchul Park , Gregory Price , Ying Huang , Alistair Popple , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Baoquan He , Youngjun Park , Johannes Weiner , Qi Zheng , Shakeel Butt , Axel Rasmussen , Yuanchu Xie , Wei Xu , Xu Xin , Chengming Zhou , Michal Hocko , Miklos Szeredi Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-usb@vger.kernel.org, linux-rdma@vger.kernel.org, selinux@vger.kernel.org, linux-sound@vger.kernel.org, bpf@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-trace-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org, sparclinux@vger.kernel.org, fuse-devel@lists.linux.dev, "Lorenzo Stoakes (ARM)" X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9577; i=ljs@kernel.org; h=from:subject:message-id; bh=bmDihYBTPF4s+vtesyigFctx5fwOO/lCZ7Euwx9606c=; b=owGbwMvMwCV2fu7ZrsZH9SKMp9WSGLIWZG5gXXD/6AsmSxPurl1NWQeuatoyue3v8zrcIerNb Z7iceJhRykLgxgXg6yYIsvzL+L7g0TC5nVe8HeDmcPKBDKEgYtTACai/IThF/Py3YWvW1dcT9wh H5qbnp6/PNRhjYKI6OYvUvUbbHZMbGVk2Lrs/nedQ1eiioIs/nuuf/H/Xkd/77w/O3b++q6ToOE 8nw8A X-Developer-Key: i=ljs@kernel.org; a=openpgp; fpr=E7F417BF5214569E89D04F46CF9DCD8A81E27F14 The VM_SPECIAL / VMA_SPECIAL_FLAGS mask conflates several unrelated properties: * Is this kernel-owned, whether MMIO, kernel-allocated pages, or ordinary pages a driver maps itself? * Can it be expanded or merged? * Is this a 'weird' case like mlock where migration might race and we 'have' to set invalid flags to notify? * Is it another 'weird' case where we just want to stop GUP from touching it? Driver writers have often been confused about this, and who can blame them? It also interacts badly with the eternal edgecase known as hugetlb - which sets VMA_DONTEXPAND_BIT but doesn't also want to be treated like a 'special' flag. Another issue is that we cannot make sensible assumptions about flag use. It's not possible to assume VMA_IO_BIT means iommu because drivers abuse it and mlock abuses it. Special is also an overloaded term in mm. VDSO and VVAR mappings are also called 'special' but they're special in a... special way. Sometimes things are called special that are a subset of VMA_SPECIAL_FLAGS (VMA_PFNMAP_BIT and VMA_MIXEDMAP_BIT for instance when it comes to zapping or vm_normal_folio()). There's a specific kind of special for THP too, which considers PFN map, mixed map 'special' but DAX not. It's all rather a mess. This series brings some order to things by both limiting what drivers can do with VMA flags and switching to using predicates that describe behaviour, not arbitrary flags. It establishes the invariant that only kernel-owned mappings may set VMA_IO_BIT or clear VMA_MAYWRITE_BIT in an mmap hook, enforcing this by validating VMA state after every mmap and mmap_prepare hook. It updates usbmon and sg to mmap_prepare in order to do so, adding a new mmap action for mapping discontiguous kernel pages, and has hfi1 and the ALSA PCM status page map their pages eagerly instead. It also establishes the invariant that VMA_MIXEDMAP_BIT be set when mapping kernel memory, something that is usually the case but happens not to be for some users - specifically defio, cmt_speech, uprobes and the bpf arena, all of which are updated to do the right thing. It replaces VM_SPECIAL and arbitrary flag tests with predicates that say what is actually being tested: vma_is_kernel_owned() Does a driver or kernel code manage a VMA's life cycle? vma_is_fixed_mapping() Is the VMA not permitted to be expanded or merged? vma_is_persistent() Do bytes written to the VMA stay written, and bytes read stay the same unless userland changes them? vma_can_merge() Can the VMA be merged with a compatible neighbour? vma_can_gup() Can GUP obtain pages from the VMA, i.e. is it neither a PFN map nor memory-mapped I/O? Remaining raw VMA_IO_BIT, VMA_PFNMAP_BIT and VMA_MIXEDMAP_BIT tests scattered across mm are also converted to predicates where it makes sense to do so. And also the opportunity is taken to eliminate THP's vma_is_special_huge() which was an existing source of confusion. Signed-off-by: Lorenzo Stoakes (ARM) --- Lorenzo Stoakes (ARM) (39): mm/vma: predicate setting mmap_prepare VMA fields on new vma alloc mm/vma: introduce and use vma_[flags_]can_merge() mm: consistently validate VMA state after mmap[_prepare] hooks mm/vma: ensure mmap_prepare doesn't set actions on a mergeable vma mm: make map_kernel_pages_[prepare,complete] internal and unexported mm/vma: tidy up map kernel pages enum values mm: add mmap action for discontiguous kernel page mapping docs: filesystems: update mmap_prepare docs for discontig kernel pgs drivers/usb/mon: update to use mmap_prepare + map kernel pages infiniband: update hfi1 to use remap_vmalloc_range() selinux: reject writable opens of policy file, drop mmap shared/write check ALSA: pcm: use vm_insert_page() to map PCM status page bpf: arena: mark arena_map_mmap() mappings VM_MIXEDMAP mm/vma: add vma[_flags]_is_kernel_owned() predicates mm/vma: only allow mmap to clear VMA_MAYWRITE_BIT if kernel-owned mm/vma: add and use vma_[flags]_is_fixed_mapping scsi: sg: convert mmap hook to mmap_prepare and rework fbdev: defio: assert FBINFO_VIRTFB, drop VM_IO, add VM_MIXEDMAP HSI: cmt_speech: convert mmap hook to mmap_prepare, refactor mm/gup: error out early on !VMA_MAYREAD_BIT VMAs uprobes: remove VM_IO, set VM_MIXEDMAP for mapped kernel pages mm/mlock: clear VMA_LOCKED_MASK over mmap callback mm/mlock: eliminate weird VMA_IO_BIT abuse and simplify mm/vma: enforce that only kernel-owned mappings may set VMA_IO_BIT mm: remove VMA_IO_BIT check in vma[_flags]_is_kernel_owned() mm: remove hugetlb_inline.h mm: rename is_vm_hugetlb_page() to vma_is_hugetlb() mm: drop some redundant checks around hugetlb VMAs mm/madvise: update is_valid_guard_vma() to use vma_can_merge() mm/vma: introduce vma[_flags]_is_persistent() mm/uffd: use predicates for userfaultfd checks mm/madvise: use predicates for madvise(..., MADV_DOFORK) mm: eliminate VMA_SPECIAL_FLAGS usage when hugetlb explicitly tested mm: eliminate VMA_SPECIAL_FLAGS check in lru_gen_look_around() mm: avoid use of VMA_SPECIAL_FLAGS in migrate_vma_setup() mm: eliminate VM_SPECIAL, VMA_SPECIAL_FLAGS fuse: dax: do not set VM_MIXEDMAP mm/huge_memory: remove vma_is_special_huge() mm/vma: introduce and use vma[_flags]_can_gup() Documentation/filesystems/mmap_prepare.rst | 81 +++++++++ arch/arm64/kvm/mmu.c | 4 +- arch/powerpc/mm/book3s64/radix_tlb.c | 6 +- arch/powerpc/mm/nohash/e500_hugetlbpage.c | 2 +- arch/powerpc/mm/nohash/tlb.c | 2 +- arch/riscv/kvm/mmu.c | 2 +- arch/riscv/mm/tlbflush.c | 2 +- arch/s390/mm/gmap_helpers.c | 6 +- arch/sparc/mm/init_64.c | 2 +- arch/x86/kernel/uprobes.c | 2 +- drivers/gpu/drm/drm_gpusvm.c | 5 +- drivers/hsi/clients/cmt_speech.c | 33 +--- drivers/infiniband/hw/hfi1/file_ops.c | 79 +++------ drivers/scsi/sg.c | 115 ++++++------- drivers/usb/mon/mon_bin.c | 82 +++++---- drivers/video/fbdev/core/fb_defio.c | 6 +- drivers/video/fbdev/ssd1307fb.c | 2 + fs/coredump.c | 6 +- fs/fuse/dax.c | 2 +- fs/hugetlbfs/inode.c | 2 +- fs/proc/task_mmu.c | 8 +- include/asm-generic/tlb.h | 4 +- include/linux/hugetlb.h | 5 +- include/linux/hugetlb_inline.h | 28 --- include/linux/mm.h | 266 +++++++++++++++++++++++++++-- include/linux/mm_types.h | 50 +++++- include/linux/pagemap.h | 1 - include/linux/rmap.h | 2 +- include/linux/userfaultfd_k.h | 1 - kernel/bpf/arena.c | 3 +- kernel/events/core.c | 2 +- kernel/events/uprobes.c | 4 +- kernel/sched/fair.c | 3 +- mm/folio.c | 2 +- mm/gup.c | 15 +- mm/hmm.c | 3 +- mm/huge_memory.c | 31 ++-- mm/hugetlb.c | 14 +- mm/internal.h | 71 ++++---- mm/ksm.c | 4 +- mm/madvise.c | 28 +-- mm/memory.c | 142 ++++++++++++--- mm/mempolicy.c | 5 +- mm/migrate_device.c | 12 +- mm/mlock.c | 51 +++--- mm/mmap.c | 2 +- mm/mmu_gather.c | 2 +- mm/mprotect.c | 5 +- mm/mremap.c | 11 +- mm/page_vma_mapped.c | 4 +- mm/pagewalk.c | 2 +- mm/rmap.c | 4 +- mm/swapfile.c | 2 +- mm/userfaultfd.c | 45 +++-- mm/util.c | 22 ++- mm/vma.c | 161 +++++++++++++---- mm/vma.h | 24 ++- mm/vma_internal.h | 1 - mm/vmscan.c | 9 +- security/selinux/selinuxfs.c | 11 +- sound/core/pcm_native.c | 37 ++-- tools/testing/vma/include/dup.h | 60 +++++-- tools/testing/vma/include/stubs.h | 2 +- tools/testing/vma/tests/merge.c | 10 +- 64 files changed, 1071 insertions(+), 539 deletions(-) --- base-commit: d118502628f8b673be9023db8bdf878f64a7ed45 change-id: 20260721-b4-mmap-prepare-vma-flag-sanify-2100425df5aa Best regards, -- Lorenzo Stoakes (ARM)