| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/12 10:14 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [
"mlock_fixup",
"apply_vma_lock_flags",
"apply_mlockall_flags",
"unmap_source_vma",
"check_prep_vma",
"memfd_check_seals_mmap",
"create_init_stack_vma",
"thp_get_unmapped_area_vmaflags"
],
"Reasoning": "The patch introduces a major refactoring of VMA flags handling in the core memory management subsystem, transitioning from `vm_flags_t` to `vma_flags_t`. It modifies critical paths in mmap, mremap, mlock, and mprotect. These changes functionally alter how VMA flags are set, cleared, and tested, which could introduce bugs like incorrect memory protections, accounting errors, or locking issues. Fuzzing should focus on the modified functions that handle these flags, avoiding the absolute hottest paths like `do_mmap` to prevent skewed distributions.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/12 10:14 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 7e8de2bd119de73d9468da4ef7e39d8e84794cae\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sun Jul 12 10:14:35 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c\nindex bd1fc17d3975dc..94873775fc0f45 100644\n--- a/arch/mips/kernel/vdso.c\n+++ b/arch/mips/kernel/vdso.c\n@@ -91,8 +91,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)\n \n \t\t/* Map delay slot emulation page */\n \t\tbase = do_mmap(NULL, STACK_TOP, PAGE_SIZE, PROT_READ | PROT_EXEC,\n-\t\t\t MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0, \u0026unused,\n-\t\t\t NULL);\n+\t\t\t MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED,\n+\t\t\t EMPTY_VMA_FLAGS, 0, \u0026unused, NULL);\n \t\tif (IS_ERR_VALUE(base)) {\n \t\t\tret = base;\n \t\t\tgoto out;\ndiff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c\nindex 28bec5bc787949..82127e31dca6de 100644\n--- a/arch/powerpc/mm/book3s64/slice.c\n+++ b/arch/powerpc/mm/book3s64/slice.c\n@@ -659,7 +659,8 @@ unsigned long arch_get_unmapped_area(struct file *filp,\n \tunsigned int psize;\n \n \tif (radix_enabled())\n-\t\treturn generic_get_unmapped_area(filp, addr, len, pgoff, flags, vm_flags);\n+\t\treturn generic_get_unmapped_area(filp, addr, len, pgoff, flags,\n+\t\t\t\t\t\t legacy_to_vma_flags(vm_flags));\n \n \tif (filp \u0026\u0026 is_file_hugepages(filp))\n \t\tpsize = file_to_psize(filp);\n@@ -679,7 +680,8 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,\n \tunsigned int psize;\n \n \tif (radix_enabled())\n-\t\treturn generic_get_unmapped_area_topdown(filp, addr0, len, pgoff, flags, vm_flags);\n+\t\treturn generic_get_unmapped_area_topdown(filp, addr0, len,\n+\t\t\t\tpgoff, flags, legacy_to_vma_flags(vm_flags));\n \n \tif (filp \u0026\u0026 is_file_hugepages(filp))\n \t\tpsize = file_to_psize(filp);\ndiff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c\nindex e3ed684ddcf291..32a05d889b9a2b 100644\n--- a/drivers/gpu/drm/drm_gem.c\n+++ b/drivers/gpu/drm/drm_gem.c\n@@ -1252,7 +1252,7 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,\n \t\t}\n \n \t\tvm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);\n-\t\tvma-\u003evm_page_prot = pgprot_writecombine(vm_get_page_prot(vma-\u003evm_flags));\n+\t\tvma-\u003evm_page_prot = pgprot_writecombine(vma_get_page_prot(vma));\n \t\tvma-\u003evm_page_prot = pgprot_decrypted(vma-\u003evm_page_prot);\n \t}\n \ndiff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/drm_gem_dma_helper.c\nindex 1c00a71ab3c9d0..7d9612075d310b 100644\n--- a/drivers/gpu/drm/drm_gem_dma_helper.c\n+++ b/drivers/gpu/drm/drm_gem_dma_helper.c\n@@ -540,7 +540,7 @@ int drm_gem_dma_mmap(struct drm_gem_dma_object *dma_obj, struct vm_area_struct *\n \tvm_flags_mod(vma, VM_DONTDUMP | VM_DONTEXPAND, VM_PFNMAP);\n \n \tif (dma_obj-\u003emap_noncoherent) {\n-\t\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\t\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \n \t\tret = dma_mmap_pages(drm_dev_dma_dev(dma_obj-\u003ebase.dev),\n \t\t\t\t vma, vma-\u003evm_end - vma-\u003evm_start,\ndiff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c\nindex c989459eb21591..06d019d51d3e6b 100644\n--- a/drivers/gpu/drm/drm_gem_shmem_helper.c\n+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c\n@@ -764,7 +764,7 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct\n \t\treturn ret;\n \n \tvm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);\n-\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \tif (shmem-\u003emap_wc)\n \t\tvma-\u003evm_page_prot = pgprot_writecombine(vma-\u003evm_page_prot);\n \ndiff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c\nindex 2e4d6d117ee2d8..f9c8b7b2bfc7af 100644\n--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c\n+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c\n@@ -133,7 +133,7 @@ static int etnaviv_gem_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,\n \n \tvm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);\n \n-\tvm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\tvm_page_prot = vma_get_page_prot(vma);\n \n \tif (etnaviv_obj-\u003eflags \u0026 ETNA_BO_WC) {\n \t\tvma-\u003evm_page_prot = pgprot_writecombine(vm_page_prot);\ndiff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c\nindex 9a6270f3dca6bf..0208c92595725c 100644\n--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c\n+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c\n@@ -377,13 +377,13 @@ static int exynos_drm_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct\n \n \t/* non-cachable as default. */\n \tif (exynos_gem-\u003eflags \u0026 EXYNOS_BO_CACHABLE)\n-\t\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\t\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \telse if (exynos_gem-\u003eflags \u0026 EXYNOS_BO_WC)\n \t\tvma-\u003evm_page_prot =\n-\t\t\tpgprot_writecombine(vm_get_page_prot(vma-\u003evm_flags));\n+\t\t\tpgprot_writecombine(vma_get_page_prot(vma));\n \telse\n \t\tvma-\u003evm_page_prot =\n-\t\t\tpgprot_noncached(vm_get_page_prot(vma-\u003evm_flags));\n+\t\t\tpgprot_noncached(vma_get_page_prot(vma));\n \n \tret = exynos_drm_gem_mmap_buffer(exynos_gem, vma);\n \tif (ret)\ndiff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c\nindex 0644f85c6c8e52..9ca90c1bb5b422 100644\n--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c\n+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c\n@@ -112,7 +112,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,\n \t\tvma = find_vma(mm, addr);\n \t\tif (vma \u0026\u0026 __vma_matches(vma, obj-\u003ebase.filp, addr, args-\u003esize))\n \t\t\tvma-\u003evm_page_prot =\n-\t\t\t\tpgprot_writecombine(vm_get_page_prot(vma-\u003evm_flags));\n+\t\t\t\tpgprot_writecombine(vma_get_page_prot(vma));\n \t\telse\n \t\t\taddr = -ENOMEM;\n \t\tmmap_write_unlock(mm);\n@@ -1024,7 +1024,7 @@ i915_gem_object_mmap(struct drm_i915_gem_object *obj,\n \tfput(anon);\n \n \tif (obj-\u003eops-\u003emmap_ops) {\n-\t\tvma-\u003evm_page_prot = pgprot_decrypted(vm_get_page_prot(vma-\u003evm_flags));\n+\t\tvma-\u003evm_page_prot = pgprot_decrypted(vma_get_page_prot(vma));\n \t\tvma-\u003evm_ops = obj-\u003eops-\u003emmap_ops;\n \t\tvma-\u003evm_private_data = obj-\u003ebase.vma_node.driver_private;\n \t\treturn 0;\n@@ -1035,7 +1035,7 @@ i915_gem_object_mmap(struct drm_i915_gem_object *obj,\n \tswitch (mmo-\u003emmap_type) {\n \tcase I915_MMAP_TYPE_WC:\n \t\tvma-\u003evm_page_prot =\n-\t\t\tpgprot_writecombine(vm_get_page_prot(vma-\u003evm_flags));\n+\t\t\tpgprot_writecombine(vma_get_page_prot(vma));\n \t\tvma-\u003evm_ops = \u0026vm_ops_cpu;\n \t\tbreak;\n \n@@ -1043,19 +1043,19 @@ i915_gem_object_mmap(struct drm_i915_gem_object *obj,\n \t\tGEM_WARN_ON(1);\n \t\tfallthrough;\n \tcase I915_MMAP_TYPE_WB:\n-\t\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\t\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \t\tvma-\u003evm_ops = \u0026vm_ops_cpu;\n \t\tbreak;\n \n \tcase I915_MMAP_TYPE_UC:\n \t\tvma-\u003evm_page_prot =\n-\t\t\tpgprot_noncached(vm_get_page_prot(vma-\u003evm_flags));\n+\t\t\tpgprot_noncached(vma_get_page_prot(vma));\n \t\tvma-\u003evm_ops = \u0026vm_ops_cpu;\n \t\tbreak;\n \n \tcase I915_MMAP_TYPE_GTT:\n \t\tvma-\u003evm_page_prot =\n-\t\t\tpgprot_writecombine(vm_get_page_prot(vma-\u003evm_flags));\n+\t\t\tpgprot_writecombine(vma_get_page_prot(vma));\n \t\tvma-\u003evm_ops = \u0026vm_ops_gtt;\n \t\tbreak;\n \t}\ndiff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c\nindex cbf723a5d86fa9..6a78e242de7c6b 100644\n--- a/drivers/gpu/drm/msm/msm_gem.c\n+++ b/drivers/gpu/drm/msm/msm_gem.c\n@@ -1125,7 +1125,7 @@ static int msm_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct\n \tstruct msm_gem_object *msm_obj = to_msm_bo(obj);\n \n \tvm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);\n-\tvma-\u003evm_page_prot = msm_gem_pgprot(msm_obj, vm_get_page_prot(vma-\u003evm_flags));\n+\tvma-\u003evm_page_prot = msm_gem_pgprot(msm_obj, vma_get_page_prot(vma));\n \n \treturn 0;\n }\ndiff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c\nindex 20dba02d6175bc..9a6ee2e880c0ae 100644\n--- a/drivers/gpu/drm/nouveau/nouveau_gem.c\n+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c\n@@ -55,7 +55,7 @@ static vm_fault_t nouveau_ttm_fault(struct vm_fault *vmf)\n \t\tgoto error_unlock;\n \n \tnouveau_bo_del_io_reserve_lru(bo);\n-\tprot = vm_get_page_prot(vma-\u003evm_flags);\n+\tprot = vma_get_page_prot(vma);\n \tret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT);\n \tnouveau_bo_add_io_reserve_lru(bo);\n \tif (ret == VM_FAULT_RETRY \u0026\u0026 !(vmf-\u003eflags \u0026 FAULT_FLAG_RETRY_NOWAIT))\ndiff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c\nindex ca3fb186bf1954..4881777642d296 100644\n--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c\n+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c\n@@ -84,7 +84,7 @@ static int omap_fbdev_pan_display(struct fb_var_screeninfo *var, struct fb_info\n \n static int omap_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)\n {\n-\tvma-\u003evm_page_prot = pgprot_writecombine(vm_get_page_prot(vma-\u003evm_flags));\n+\tvma-\u003evm_page_prot = pgprot_writecombine(vma_get_page_prot(vma));\n \n \treturn fb_deferred_io_mmap(info, vma);\n }\ndiff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c\nindex 00404fb6c29aae..fb0e6f556b3147 100644\n--- a/drivers/gpu/drm/omapdrm/omap_gem.c\n+++ b/drivers/gpu/drm/omapdrm/omap_gem.c\n@@ -538,9 +538,9 @@ static int omap_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struc\n \tvm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP | VM_IO | VM_MIXEDMAP);\n \n \tif (omap_obj-\u003eflags \u0026 OMAP_BO_WC) {\n-\t\tvma-\u003evm_page_prot = pgprot_writecombine(vm_get_page_prot(vma-\u003evm_flags));\n+\t\tvma-\u003evm_page_prot = pgprot_writecombine(vma_get_page_prot(vma));\n \t} else if (omap_obj-\u003eflags \u0026 OMAP_BO_UNCACHED) {\n-\t\tvma-\u003evm_page_prot = pgprot_noncached(vm_get_page_prot(vma-\u003evm_flags));\n+\t\tvma-\u003evm_page_prot = pgprot_noncached(vma_get_page_prot(vma));\n \t} else {\n \t\t/*\n \t\t * We do have some private objects, at least for scanout buffers\n@@ -558,7 +558,7 @@ static int omap_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struc\n \t\tvma-\u003evm_pgoff -= drm_vma_node_start(\u0026obj-\u003evma_node);\n \t\tvma_set_file(vma, obj-\u003efilp);\n \n-\t\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\t\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \t}\n \n \tvma-\u003evm_page_prot = pgprot_decrypted(vma-\u003evm_page_prot);\ndiff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c\nindex a1e2eb1ca7bbe6..77055635396870 100644\n--- a/drivers/gpu/drm/panthor/panthor_gem.c\n+++ b/drivers/gpu/drm/panthor/panthor_gem.c\n@@ -776,7 +776,7 @@ static int panthor_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *v\n \t}\n \n \tvm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);\n-\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \tif (should_map_wc(bo))\n \t\tvma-\u003evm_page_prot = pgprot_writecombine(vma-\u003evm_page_prot);\n \ndiff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c\nindex b188539dca0b25..9a1dc9f120729f 100644\n--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c\n+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c\n@@ -255,7 +255,7 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj,\n \t */\n \tvm_flags_mod(vma, VM_IO | VM_DONTEXPAND | VM_DONTDUMP, VM_PFNMAP);\n \n-\tvma-\u003evm_page_prot = pgprot_writecombine(vm_get_page_prot(vma-\u003evm_flags));\n+\tvma-\u003evm_page_prot = pgprot_writecombine(vma_get_page_prot(vma));\n \tvma-\u003evm_page_prot = pgprot_decrypted(vma-\u003evm_page_prot);\n \n \tif (rk_obj-\u003epages)\ndiff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c\nindex 1d8d27a5ea89b8..f76af733ea7939 100644\n--- a/drivers/gpu/drm/tegra/gem.c\n+++ b/drivers/gpu/drm/tegra/gem.c\n@@ -602,7 +602,7 @@ int __tegra_gem_mmap(struct drm_gem_object *gem, struct vm_area_struct *vma)\n \n \t\tvma-\u003evm_pgoff = vm_pgoff;\n \t} else {\n-\t\tpgprot_t prot = vm_get_page_prot(vma-\u003evm_flags);\n+\t\tpgprot_t prot = vma_get_page_prot(vma);\n \n \t\tvm_flags_mod(vma, VM_MIXEDMAP, VM_PFNMAP);\n \ndiff --git a/drivers/gpu/drm/virtio/virtgpu_vram.c b/drivers/gpu/drm/virtio/virtgpu_vram.c\nindex 4ae3cbc35dd364..544a6abddbc8b6 100644\n--- a/drivers/gpu/drm/virtio/virtgpu_vram.c\n+++ b/drivers/gpu/drm/virtio/virtgpu_vram.c\n@@ -55,7 +55,7 @@ static int virtio_gpu_vram_mmap(struct drm_gem_object *obj,\n \n \tvma-\u003evm_pgoff -= drm_vma_node_start(\u0026obj-\u003evma_node);\n \tvm_flags_set(vma, VM_MIXEDMAP | VM_DONTEXPAND);\n-\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \tvma-\u003evm_page_prot = pgprot_decrypted(vma-\u003evm_page_prot);\n \tvma-\u003evm_ops = \u0026virtio_gpu_vram_vm_ops;\n \ndiff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c\nindex 45561bc1c9effe..a9fd4015a0caa7 100644\n--- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c\n+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c\n@@ -481,7 +481,7 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf)\n \tif (vbo-\u003edirty \u0026\u0026 vbo-\u003edirty-\u003emethod == VMW_BO_DIRTY_MKWRITE)\n \t\tprot = vm_get_page_prot(vma-\u003evm_flags \u0026 ~VM_SHARED);\n \telse\n-\t\tprot = vm_get_page_prot(vma-\u003evm_flags);\n+\t\tprot = vma_get_page_prot(vma);\n \n \tret = ttm_bo_vm_fault_reserved(vmf, prot, num_prefault);\n \tif (ret == VM_FAULT_RETRY \u0026\u0026 !(vmf-\u003eflags \u0026 FAULT_FLAG_RETRY_NOWAIT))\ndiff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c\nindex abe25aedeeadef..838797cc65d790 100644\n--- a/drivers/gpu/drm/xe/xe_device.c\n+++ b/drivers/gpu/drm/xe/xe_device.c\n@@ -281,7 +281,7 @@ static vm_fault_t barrier_fault(struct vm_fault *vmf)\n \tpgprot_t prot;\n \tint idx;\n \n-\tprot = vm_get_page_prot(vma-\u003evm_flags);\n+\tprot = vma_get_page_prot(vma);\n \n \tif (drm_dev_enter(dev, \u0026idx)) {\n \t\tunsigned long pfn;\ndiff --git a/drivers/gpu/drm/xe/xe_mmio_gem.c b/drivers/gpu/drm/xe/xe_mmio_gem.c\nindex 8c803ef233cc4d..3741ae60f532bf 100644\n--- a/drivers/gpu/drm/xe/xe_mmio_gem.c\n+++ b/drivers/gpu/drm/xe/xe_mmio_gem.c\n@@ -149,7 +149,7 @@ static int xe_mmio_gem_mmap(struct drm_gem_object *base, struct vm_area_struct *\n \n \t/* Set vm_pgoff (used as a fake buffer offset by DRM) to 0 */\n \tvma-\u003evm_pgoff = 0;\n-\tvma-\u003evm_page_prot = pgprot_noncached(vm_get_page_prot(vma-\u003evm_flags));\n+\tvma-\u003evm_page_prot = pgprot_noncached(vma_get_page_prot(vma));\n \tvm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP |\n \t\t VM_DONTCOPY | VM_NORESERVE);\n \ndiff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c\nindex eec4c1da3f9e31..dd158443f55f10 100644\n--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c\n+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c\n@@ -80,7 +80,7 @@ static int xen_drm_front_gem_object_mmap(struct drm_gem_object *gem_obj,\n \t * which is mapped as Normal Inner Write-Back Outer Write-Back\n \t * Inner-Shareable.\n \t */\n-\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \n \t/*\n \t * vm_operations_struct.fault handler will be called if CPU access\ndiff --git a/drivers/video/fbdev/core/fb_io_fops.c b/drivers/video/fbdev/core/fb_io_fops.c\nindex 6ab60fcd005014..6d0a8c8e141a22 100644\n--- a/drivers/video/fbdev/core/fb_io_fops.c\n+++ b/drivers/video/fbdev/core/fb_io_fops.c\n@@ -161,7 +161,7 @@ int fb_io_mmap(struct fb_info *info, struct vm_area_struct *vma)\n \t\tlen = info-\u003efix.mmio_len;\n \t}\n \n-\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \tvma-\u003evm_page_prot = pgprot_framebuffer(vma-\u003evm_page_prot, vma-\u003evm_start,\n \t\t\t\t\t vma-\u003evm_end, start);\n \ndiff --git a/fs/aio.c b/fs/aio.c\nindex f57fa21a250353..3de586da197bd9 100644\n--- a/fs/aio.c\n+++ b/fs/aio.c\n@@ -604,7 +604,7 @@ static int aio_setup_ring(struct kioctx *ctx, unsigned int nr_events)\n \n \tctx-\u003emmap_base = do_mmap(ctx-\u003eaio_ring_file, 0, ctx-\u003emmap_size,\n \t\t\t\t PROT_READ | PROT_WRITE,\n-\t\t\t\t MAP_SHARED, 0, 0, \u0026unused, NULL);\n+\t\t\t\t MAP_SHARED, EMPTY_VMA_FLAGS, 0, \u0026unused, NULL);\n \tmmap_write_unlock(mm);\n \tif (IS_ERR((void *)ctx-\u003emmap_base)) {\n \t\tctx-\u003emmap_size = 0;\ndiff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c\nindex 9fddd1e0b813ab..43066f9ddf52d1 100644\n--- a/fs/hugetlbfs/inode.c\n+++ b/fs/hugetlbfs/inode.c\n@@ -184,7 +184,8 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,\n \tif (addr)\n \t\taddr0 = ALIGN(addr, huge_page_size(h));\n \n-\treturn mm_get_unmapped_area_vmflags(file, addr0, len, pgoff, flags, 0);\n+\treturn mm_get_unmapped_area_vmaflags(file, addr0, len, pgoff, flags,\n+\t\t\t\t\t EMPTY_VMA_FLAGS);\n }\n \n /*\ndiff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h\nindex cae97c30728097..9e43e138c0b777 100644\n--- a/include/linux/huge_mm.h\n+++ b/include/linux/huge_mm.h\n@@ -391,9 +391,9 @@ static inline bool thp_disabled_by_hw(void)\n \n unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr,\n \t\tunsigned long len, unsigned long pgoff, unsigned long flags);\n-unsigned long thp_get_unmapped_area_vmflags(struct file *filp, unsigned long addr,\n+unsigned long thp_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr,\n \t\tunsigned long len, unsigned long pgoff, unsigned long flags,\n-\t\tvm_flags_t vm_flags);\n+\t\tvma_flags_t vma_flags);\n \n enum split_type {\n \tSPLIT_TYPE_UNIFORM,\n@@ -617,9 +617,9 @@ static inline unsigned long thp_vma_allowable_orders(struct vm_area_struct *vma,\n #define thp_get_unmapped_area\tNULL\n \n static inline unsigned long\n-thp_get_unmapped_area_vmflags(struct file *filp, unsigned long addr,\n-\t\t\t unsigned long len, unsigned long pgoff,\n-\t\t\t unsigned long flags, vm_flags_t vm_flags)\n+thp_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr,\n+\t\t\t unsigned long len, unsigned long pgoff,\n+\t\t\t unsigned long flags, vma_flags_t vma_flags)\n {\n \treturn 0;\n }\ndiff --git a/include/linux/memfd.h b/include/linux/memfd.h\nindex b4fda09dab9f61..c159e40e3f34a0 100644\n--- a/include/linux/memfd.h\n+++ b/include/linux/memfd.h\n@@ -14,9 +14,9 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx);\n * to sealing, or 0 otherwise.\n *\n * We also update VMA flags if appropriate by manipulating the VMA flags pointed\n- * to by vm_flags_ptr.\n+ * to by vma_flags_ptr.\n */\n-int memfd_check_seals_mmap(struct file *file, vm_flags_t *vm_flags_ptr);\n+int memfd_check_seals_mmap(struct file *file, vma_flags_t *vma_flags_ptr);\n struct file *memfd_alloc_file(const char *name, unsigned int flags);\n int memfd_get_seals(struct file *file);\n int memfd_add_seals(struct file *file, unsigned int seals);\n@@ -30,7 +30,7 @@ static inline struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx)\n \treturn ERR_PTR(-EINVAL);\n }\n static inline int memfd_check_seals_mmap(struct file *file,\n-\t\t\t\t\t vm_flags_t *vm_flags_ptr)\n+\t\t\t\t\t vma_flags_t *vma_flags_ptr)\n {\n \treturn 0;\n }\ndiff --git a/include/linux/mm.h b/include/linux/mm.h\nindex 32bb723ffbb92d..550fb92957d189 100644\n--- a/include/linux/mm.h\n+++ b/include/linux/mm.h\n@@ -442,8 +442,10 @@ enum {\n #define VM_STACK\tINIT_VM_FLAG(STACK)\n #ifdef CONFIG_STACK_GROWSUP\n #define VM_STACK_EARLY\tINIT_VM_FLAG(STACK_EARLY)\n+#define VMA_STACK_EARLY mk_vma_flags(VMA_STACK_EARLY_BIT)\n #else\n #define VM_STACK_EARLY\tVM_NONE\n+#define VMA_STACK_EARLY EMPTY_VMA_FLAGS\n #endif\n #ifdef CONFIG_ARCH_HAS_PKEYS\n #define VM_PKEY_SHIFT ((__force int)VMA_HIGH_ARCH_0_BIT)\n@@ -465,15 +467,18 @@ enum {\n #if defined(CONFIG_X86_USER_SHADOW_STACK) || defined(CONFIG_ARM64_GCS) || \\\n \tdefined(CONFIG_RISCV_USER_CFI)\n #define VM_SHADOW_STACK\tINIT_VM_FLAG(SHADOW_STACK)\n+#define VMA_SHADOW_STACK mk_vma_flags(VMA_SHADOW_STACK_BIT)\n #define VMA_STARTGAP_FLAGS mk_vma_flags(VMA_GROWSDOWN_BIT, VMA_SHADOW_STACK_BIT)\n #else\n #define VM_SHADOW_STACK\tVM_NONE\n+#define VMA_SHADOW_STACK EMPTY_VMA_FLAGS\n #define VMA_STARTGAP_FLAGS mk_vma_flags(VMA_GROWSDOWN_BIT)\n #endif\n #if defined(CONFIG_PPC64)\n #define VM_SAO\t\tINIT_VM_FLAG(SAO)\n #elif defined(CONFIG_PARISC)\n #define VM_GROWSUP\tINIT_VM_FLAG(GROWSUP)\n+#define VMA_GROWSUP\tmk_vma_flags(VMA_GROWSUP_BIT)\n #elif defined(CONFIG_SPARC64)\n #define VM_SPARC_ADI\tINIT_VM_FLAG(SPARC_ADI)\n #define VM_ARCH_CLEAR\tINIT_VM_FLAG(ARCH_CLEAR)\n@@ -485,6 +490,7 @@ enum {\n #endif\n #ifndef VM_GROWSUP\n #define VM_GROWSUP\tVM_NONE\n+#define VMA_GROWSUP\tEMPTY_VMA_FLAGS\n #endif\n #ifdef CONFIG_ARM64_MTE\n #define VM_MTE\t\tINIT_VM_FLAG(MTE)\n@@ -540,6 +546,8 @@ enum {\n \n /* Bits set in the VMA until the stack is in its final location */\n #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)\n+#define VMA_STACK_INCOMPLETE_SETUP append_vma_flags(\t\t\\\n+\tVMA_STACK_EARLY, VMA_RAND_READ_BIT, VMA_SEQ_READ_BIT)\n \n #define TASK_EXEC_BIT ((current-\u003epersonality \u0026 READ_IMPLIES_EXEC) ? \\\n \t\t VMA_EXEC_BIT : VMA_READ_BIT)\n@@ -1578,11 +1586,24 @@ static inline bool vma_is_initial_stack(const struct vm_area_struct *vma)\n \t\tvma-\u003evm_end \u003e= vma-\u003evm_mm-\u003estart_stack;\n }\n \n-static inline bool vma_is_temporary_stack(const struct vm_area_struct *vma)\n+static inline bool vma_flags_can_grow(const vma_flags_t *flags)\n {\n-\tint maybe_stack = vma-\u003evm_flags \u0026 (VM_GROWSDOWN | VM_GROWSUP);\n+\tif (vma_flags_test_single_mask(flags, VMA_GROWSUP))\n+\t\treturn true;\n+\tif (vma_flags_test(flags, VMA_GROWSDOWN_BIT))\n+\t\treturn true;\n+\n+\treturn false;\n+}\n+\n+static inline bool vma_can_grow(const struct vm_area_struct *vma)\n+{\n+\treturn vma_flags_can_grow(\u0026vma-\u003eflags);\n+}\n \n-\tif (!maybe_stack)\n+static inline bool vma_is_temporary_stack(const struct vm_area_struct *vma)\n+{\n+\tif (!vma_can_grow(vma))\n \t\treturn false;\n \n \tif ((vma-\u003evm_flags \u0026 VM_STACK_INCOMPLETE_SETUP) ==\n@@ -4174,18 +4195,20 @@ unsigned long randomize_page(unsigned long start, unsigned long range);\n \n unsigned long\n __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,\n-\t\t unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags);\n+\t\t unsigned long pgoff, unsigned long flags,\n+\t\t vma_flags_t vma_flags);\n \n static inline unsigned long\n get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,\n \t\t unsigned long pgoff, unsigned long flags)\n {\n-\treturn __get_unmapped_area(file, addr, len, pgoff, flags, 0);\n+\treturn __get_unmapped_area(file, addr, len, pgoff, flags,\n+\t\t\t\t EMPTY_VMA_FLAGS);\n }\n \n-extern unsigned long do_mmap(struct file *file, unsigned long addr,\n+unsigned long do_mmap(struct file *file, unsigned long addr,\n \tunsigned long len, unsigned long prot, unsigned long flags,\n-\tvm_flags_t vm_flags, unsigned long pgoff, unsigned long *populate,\n+\tvma_flags_t vma_flags, unsigned long pgoff, unsigned long *populate,\n \tstruct list_head *uf);\n extern int do_vmi_munmap(struct vma_iterator *vmi, struct mm_struct *mm,\n \t\t\t unsigned long start, size_t len, struct list_head *uf,\n@@ -4584,26 +4607,35 @@ static inline bool range_in_vma_desc(const struct vm_area_desc *desc,\n #ifdef CONFIG_MMU\n pgprot_t vm_get_page_prot(vm_flags_t vm_flags);\n \n-static inline pgprot_t vma_get_page_prot(vma_flags_t vma_flags)\n+static inline pgprot_t vma_flags_to_page_prot(vma_flags_t vma_flags)\n {\n \tconst vm_flags_t vm_flags = vma_flags_to_legacy(vma_flags);\n \n \treturn vm_get_page_prot(vm_flags);\n }\n \n+static inline pgprot_t vma_get_page_prot(const struct vm_area_struct *vma)\n+{\n+\treturn vma_flags_to_page_prot(vma-\u003eflags);\n+}\n+\n void vma_set_page_prot(struct vm_area_struct *vma);\n #else\n static inline pgprot_t vm_get_page_prot(vm_flags_t vm_flags)\n {\n \treturn __pgprot(0);\n }\n-static inline pgprot_t vma_get_page_prot(vma_flags_t vma_flags)\n+static inline pgprot_t vma_flags_to_page_prot(vma_flags_t vma_flags)\n+{\n+\treturn __pgprot(0);\n+}\n+static inline pgprot_t vma_get_page_prot(const struct vm_area_struct *vma)\n {\n \treturn __pgprot(0);\n }\n static inline void vma_set_page_prot(struct vm_area_struct *vma)\n {\n-\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n }\n #endif\n \ndiff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h\nindex 95d0040df58413..10be8a54b416f9 100644\n--- a/include/linux/sched/mm.h\n+++ b/include/linux/sched/mm.h\n@@ -193,21 +193,18 @@ unsigned long mm_get_unmapped_area(struct file *filp, unsigned long addr,\n \t\t\t\t unsigned long len, unsigned long pgoff,\n \t\t\t\t unsigned long flags);\n \n-unsigned long mm_get_unmapped_area_vmflags(struct file *filp,\n-\t\t\t\t\t unsigned long addr,\n-\t\t\t\t\t unsigned long len,\n-\t\t\t\t\t unsigned long pgoff,\n-\t\t\t\t\t unsigned long flags,\n-\t\t\t\t\t vm_flags_t vm_flags);\n+unsigned long mm_get_unmapped_area_vmaflags(struct file *filp,\n+\t\tunsigned long addr, unsigned long len, unsigned long pgoff,\n+\t\tunsigned long flags, vma_flags_t vma_flags);\n \n unsigned long\n generic_get_unmapped_area(struct file *filp, unsigned long addr,\n \t\t\t unsigned long len, unsigned long pgoff,\n-\t\t\t unsigned long flags, vm_flags_t vm_flags);\n+\t\t\t unsigned long flags, vma_flags_t vma_flags);\n unsigned long\n generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,\n \t\t\t\t unsigned long len, unsigned long pgoff,\n-\t\t\t\t unsigned long flags, vm_flags_t vm_flags);\n+\t\t\t\t unsigned long flags, vma_flags_t vma_flags);\n #else\n static inline void arch_pick_mmap_layout(struct mm_struct *mm,\n \t\t\t\t\t const struct rlimit *rlim_stack) {}\ndiff --git a/ipc/shm.c b/ipc/shm.c\nindex b3e8a58e177d3b..bb1a721a3e746e 100644\n--- a/ipc/shm.c\n+++ b/ipc/shm.c\n@@ -1661,7 +1661,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,\n \t\t\tgoto invalid;\n \t}\n \n-\taddr = do_mmap(file, addr, size, prot, flags, 0, 0, \u0026populate, NULL);\n+\taddr = do_mmap(file, addr, size, prot, flags, EMPTY_VMA_FLAGS, 0,\n+\t\t \u0026populate, NULL);\n \t*raddr = addr;\n \terr = 0;\n \tif (IS_ERR_VALUE(addr))\ndiff --git a/mm/debug.c b/mm/debug.c\nindex 497654b36f1ab5..9a0297b3988d89 100644\n--- a/mm/debug.c\n+++ b/mm/debug.c\n@@ -197,7 +197,7 @@ void dump_mm(const struct mm_struct *mm)\n \t\t\"numa_next_scan %lu numa_scan_offset %lu numa_scan_seq %d\\n\"\n #endif\n \t\t\"tlb_flush_pending %d\\n\"\n-\t\t\"def_flags: %#lx(%pGv)\\n\",\n+\t\t\"def_flags: %*pb(%pGv)\\n\",\n \n \t\tmm, mm-\u003etask_size,\n \t\tmm-\u003emmap_base, mm-\u003emmap_legacy_base,\n@@ -226,7 +226,8 @@ void dump_mm(const struct mm_struct *mm)\n \t\tmm-\u003enuma_next_scan, mm-\u003enuma_scan_offset, mm-\u003enuma_scan_seq,\n #endif\n \t\tatomic_read(\u0026mm-\u003etlb_flush_pending),\n-\t\tmm-\u003edef_flags, \u0026mm-\u003edef_flags\n+\t\tNUM_VMA_FLAG_BITS, mm-\u003edef_vma_flags.__vma_flags,\n+\t\t\u0026mm-\u003edef_vma_flags\n \t);\n }\n EXPORT_SYMBOL(dump_mm);\ndiff --git a/mm/huge_memory.c b/mm/huge_memory.c\nindex 0dc6d630570faf..40d6b4078e3d43 100644\n--- a/mm/huge_memory.c\n+++ b/mm/huge_memory.c\n@@ -1196,7 +1196,7 @@ static inline bool is_transparent_hugepage(const struct folio *folio)\n static unsigned long __thp_get_unmapped_area(struct file *filp,\n \t\tunsigned long addr, unsigned long len,\n \t\tloff_t off, unsigned long flags, unsigned long size,\n-\t\tvm_flags_t vm_flags)\n+\t\tvma_flags_t vma_flags)\n {\n \tloff_t off_end = off + len;\n \tloff_t off_align = round_up(off, size);\n@@ -1212,8 +1212,9 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,\n \tif (len_pad \u003c len || (off + len_pad) \u003c off)\n \t\treturn 0;\n \n-\tret = mm_get_unmapped_area_vmflags(filp, addr, len_pad,\n-\t\t\t\t\t off \u003e\u003e PAGE_SHIFT, flags, vm_flags);\n+\tret = mm_get_unmapped_area_vmaflags(filp, addr, len_pad,\n+\t\t\t\t\t off \u003e\u003e PAGE_SHIFT, flags,\n+\t\t\t\t\t vma_flags);\n \n \t/*\n \t * The failure might be due to length padding. The caller will retry\n@@ -1238,25 +1239,27 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,\n \treturn ret;\n }\n \n-unsigned long thp_get_unmapped_area_vmflags(struct file *filp, unsigned long addr,\n+unsigned long thp_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr,\n \t\tunsigned long len, unsigned long pgoff, unsigned long flags,\n-\t\tvm_flags_t vm_flags)\n+\t\tvma_flags_t vma_flags)\n {\n \tunsigned long ret;\n \tloff_t off = (loff_t)pgoff \u003c\u003c PAGE_SHIFT;\n \n-\tret = __thp_get_unmapped_area(filp, addr, len, off, flags, PMD_SIZE, vm_flags);\n+\tret = __thp_get_unmapped_area(filp, addr, len, off, flags, PMD_SIZE,\n+\t\t\t\t vma_flags);\n \tif (ret)\n \t\treturn ret;\n \n-\treturn mm_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags,\n-\t\t\t\t\t vm_flags);\n+\treturn mm_get_unmapped_area_vmaflags(filp, addr, len, pgoff, flags,\n+\t\t\t\t\t vma_flags);\n }\n \n unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr,\n \t\tunsigned long len, unsigned long pgoff, unsigned long flags)\n {\n-\treturn thp_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags, 0);\n+\treturn thp_get_unmapped_area_vmaflags(filp, addr, len, pgoff, flags,\n+\t\t\t\t\t EMPTY_VMA_FLAGS);\n }\n EXPORT_SYMBOL_GPL(thp_get_unmapped_area);\n \ndiff --git a/mm/memfd.c b/mm/memfd.c\nindex 6c72fe6caef75d..c708d92533f4ab 100644\n--- a/mm/memfd.c\n+++ b/mm/memfd.c\n@@ -370,39 +370,36 @@ static inline bool is_write_sealed(unsigned int seals)\n \treturn seals \u0026 (F_SEAL_WRITE | F_SEAL_FUTURE_WRITE);\n }\n \n-static int check_write_seal(vm_flags_t *vm_flags_ptr)\n+static int check_write_seal(vma_flags_t *vma_flags_ptr)\n {\n-\tvm_flags_t vm_flags = *vm_flags_ptr;\n-\tvm_flags_t mask = vm_flags \u0026 (VM_SHARED | VM_WRITE);\n-\n \t/* If a private mapping then writability is irrelevant. */\n-\tif (!(mask \u0026 VM_SHARED))\n+\tif (!vma_flags_test(vma_flags_ptr, VMA_SHARED_BIT))\n \t\treturn 0;\n \n \t/*\n \t * New PROT_WRITE and MAP_SHARED mmaps are not allowed when\n \t * write seals are active.\n \t */\n-\tif (mask \u0026 VM_WRITE)\n+\tif (vma_flags_test(vma_flags_ptr, VMA_WRITE_BIT))\n \t\treturn -EPERM;\n \n \t/*\n \t * This is a read-only mapping, disallow mprotect() from making a\n \t * write-sealed mapping writable in future.\n \t */\n-\t*vm_flags_ptr \u0026= ~VM_MAYWRITE;\n+\tvma_flags_clear(vma_flags_ptr, VMA_MAYWRITE_BIT);\n \n \treturn 0;\n }\n \n-int memfd_check_seals_mmap(struct file *file, vm_flags_t *vm_flags_ptr)\n+int memfd_check_seals_mmap(struct file *file, vma_flags_t *vma_flags_ptr)\n {\n \tint err = 0;\n \tunsigned int *seals_ptr = memfd_file_seals_ptr(file);\n \tunsigned int seals = seals_ptr ? *seals_ptr : 0;\n \n \tif (is_write_sealed(seals))\n-\t\terr = check_write_seal(vm_flags_ptr);\n+\t\terr = check_write_seal(vma_flags_ptr);\n \n \treturn err;\n }\ndiff --git a/mm/mlock.c b/mm/mlock.c\nindex 97e49038d8d33e..efa6716e4dfbdf 100644\n--- a/mm/mlock.c\n+++ b/mm/mlock.c\n@@ -329,7 +329,7 @@ static inline bool allow_mlock_munlock(struct folio *folio,\n \t * be split. And the pages are not in VM_LOCKed VMA\n \t * can be reclaimed.\n \t */\n-\tif (!(vma-\u003evm_flags \u0026 VM_LOCKED))\n+\tif (!vma_test(vma, VMA_LOCKED_BIT))\n \t\treturn true;\n \n \t/* folio_within_range() cannot take KSM, but any small folio is OK */\n@@ -368,7 +368,7 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,\n \t\tfolio = pmd_folio(*pmd);\n \t\tif (folio_is_zone_device(folio))\n \t\t\tgoto out;\n-\t\tif (vma-\u003evm_flags \u0026 VM_LOCKED)\n+\t\tif (vma_test(vma, VMA_LOCKED_BIT))\n \t\t\tmlock_folio(folio);\n \t\telse\n \t\t\tmunlock_folio(folio);\n@@ -393,7 +393,7 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,\n \t\tif (!allow_mlock_munlock(folio, vma, start, end, step))\n \t\t\tgoto next_entry;\n \n-\t\tif (vma-\u003evm_flags \u0026 VM_LOCKED)\n+\t\tif (vma_test(vma, VMA_LOCKED_BIT))\n \t\t\tmlock_folio(folio);\n \t\telse\n \t\t\tmunlock_folio(folio);\n@@ -417,8 +417,8 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,\n * @end - end of range in @vma\n * @new_vma_flags - the new set of flags for @vma.\n *\n- * Called for mlock(), mlock2() and mlockall(), to set @vma VM_LOCKED;\n- * called for munlock() and munlockall(), to clear VM_LOCKED from @vma.\n+ * Called for mlock(), mlock2() and mlockall(), to set @vma VMA_LOCKED_BIT;\n+ * called for munlock() and munlockall(), to clear VMA_LOCKED_BIT from @vma.\n */\n static void mlock_vma_pages_range(struct vm_area_struct *vma,\n \tunsigned long start, unsigned long end,\n@@ -431,14 +431,14 @@ static void mlock_vma_pages_range(struct vm_area_struct *vma,\n \n \t/*\n \t * There is a slight chance that concurrent page migration,\n-\t * or page reclaim finding a page of this now-VM_LOCKED vma,\n+\t * or page reclaim finding a page of this now-VMA_LOCKED_BIT vma,\n \t * will call mlock_vma_folio() and raise page's mlock_count:\n \t * double counting, leaving the page unevictable indefinitely.\n-\t * Communicate this danger to mlock_vma_folio() with VM_IO,\n-\t * which is a VM_SPECIAL flag not allowed on VM_LOCKED vmas.\n+\t * Communicate this danger to mlock_vma_folio() with VMA_IO_BIT,\n+\t * which is a VMA_SPECIAL_FLAGS flag not allowed on VMA_LOCKED_BIT vmas.\n \t * mmap_lock is held in write mode here, so this weird\n \t * combination should not be visible to other mmap_lock users;\n-\t * but WRITE_ONCE so rmap walkers must see VM_IO if VM_LOCKED.\n+\t * but WRITE_ONCE so rmap walkers must see VMA_IO_BIT if VMA_LOCKED_BIT.\n \t */\n \tif (vma_flags_test(new_vma_flags, VMA_LOCKED_BIT))\n \t\tvma_flags_set(new_vma_flags, VMA_IO_BIT);\n@@ -458,7 +458,7 @@ static void mlock_vma_pages_range(struct vm_area_struct *vma,\n /*\n * mlock_fixup - handle mlock[all]/munlock[all] requests.\n *\n- * Filters out \"special\" vmas -- VM_LOCKED never gets set for these, and\n+ * Filters out \"special\" vmas -- VMA_LOCKED_BIT never gets set for these, and\n * munlock is a no-op. However, for some special vmas, we go ahead and\n * populate the ptes.\n *\n@@ -466,24 +466,23 @@ static void mlock_vma_pages_range(struct vm_area_struct *vma,\n */\n static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,\n \t struct vm_area_struct **prev, unsigned long start,\n-\t unsigned long end, vm_flags_t newflags)\n+\t unsigned long end, vma_flags_t *new_vma_flags)\n {\n-\tvma_flags_t new_vma_flags = legacy_to_vma_flags(newflags);\n \tconst vma_flags_t old_vma_flags = vma-\u003eflags;\n \tstruct mm_struct *mm = vma-\u003evm_mm;\n \tint nr_pages;\n \tint ret = 0;\n \n-\tif (vma_flags_same_pair(\u0026old_vma_flags, \u0026new_vma_flags) ||\n+\tif (vma_flags_same_pair(\u0026old_vma_flags, new_vma_flags) ||\n \t vma_is_secretmem(vma) || !vma_supports_mlock(vma)) {\n \t\t/*\n-\t\t * Don't set VM_LOCKED or VM_LOCKONFAULT and don't count.\n-\t\t * For secretmem, don't allow the memory to be unlocked.\n+\t\t * Don't set VMA_LOCKED_BIT or VMA_LOCKONFAULT_BIT and don't\n+\t\t * count. For secretmem, don't allow the memory to be unlocked.\n \t\t */\n \t\tgoto out;\n \t}\n \n-\tvma = vma_modify_flags(vmi, *prev, vma, start, end, \u0026new_vma_flags);\n+\tvma = vma_modify_flags(vmi, *prev, vma, start, end, new_vma_flags);\n \tif (IS_ERR(vma)) {\n \t\tret = PTR_ERR(vma);\n \t\tgoto out;\n@@ -493,7 +492,7 @@ static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,\n \t * Keep track of amount of locked VM.\n \t */\n \tnr_pages = (end - start) \u003e\u003e PAGE_SHIFT;\n-\tif (!vma_flags_test(\u0026new_vma_flags, VMA_LOCKED_BIT))\n+\tif (!vma_flags_test(new_vma_flags, VMA_LOCKED_BIT))\n \t\tnr_pages = -nr_pages;\n \telse if (vma_flags_test(\u0026old_vma_flags, VMA_LOCKED_BIT))\n \t\tnr_pages = 0;\n@@ -502,15 +501,15 @@ static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,\n \t/*\n \t * vm_flags is protected by the mmap_lock held in write mode.\n \t * It's okay if try_to_unmap_one unmaps a page just after we\n-\t * set VM_LOCKED, populate_vma_page_range will bring it back.\n+\t * set VMA_LOCKED_BIT, populate_vma_page_range will bring it back.\n \t */\n-\tif (vma_flags_test(\u0026new_vma_flags, VMA_LOCKED_BIT) \u0026\u0026\n+\tif (vma_flags_test(new_vma_flags, VMA_LOCKED_BIT) \u0026\u0026\n \t vma_flags_test(\u0026old_vma_flags, VMA_LOCKED_BIT)) {\n \t\t/* No work to do, and mlocking twice would be wrong */\n \t\tvma_start_write(vma);\n-\t\tvma-\u003eflags = new_vma_flags;\n+\t\tvma-\u003eflags = *new_vma_flags;\n \t} else {\n-\t\tmlock_vma_pages_range(vma, start, end, \u0026new_vma_flags);\n+\t\tmlock_vma_pages_range(vma, start, end, new_vma_flags);\n \t}\n out:\n \t*prev = vma;\n@@ -518,7 +517,7 @@ static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,\n }\n \n static int apply_vma_lock_flags(unsigned long start, size_t len,\n-\t\t\t\tvm_flags_t flags)\n+\t\t\t\tconst vma_flags_t *flags)\n {\n \tunsigned long nstart, end, tmp;\n \tstruct vm_area_struct *vma, *prev;\n@@ -543,18 +542,20 @@ static int apply_vma_lock_flags(unsigned long start, size_t len,\n \ttmp = vma-\u003evm_start;\n \tfor_each_vma_range(vmi, vma, end) {\n \t\tint error;\n-\t\tvm_flags_t newflags;\n+\t\tvma_flags_t newflags;\n \n \t\tif (vma-\u003evm_start != tmp)\n \t\t\treturn -ENOMEM;\n \n-\t\tnewflags = vma-\u003evm_flags \u0026 ~VM_LOCKED_MASK;\n-\t\tnewflags |= flags;\n+\t\tnewflags = vma-\u003eflags;\n+\t\tvma_flags_clear_mask(\u0026newflags, VMA_LOCKED_MASK);\n+\t\tvma_flags_set_mask(\u0026newflags, *flags);\n+\n \t\t/* Here we know that vma-\u003evm_start \u003c= nstart \u003c vma-\u003evm_end. */\n \t\ttmp = vma-\u003evm_end;\n \t\tif (tmp \u003e end)\n \t\t\ttmp = end;\n-\t\terror = mlock_fixup(\u0026vmi, vma, \u0026prev, nstart, tmp, newflags);\n+\t\terror = mlock_fixup(\u0026vmi, vma, \u0026prev, nstart, tmp, \u0026newflags);\n \t\tif (error)\n \t\t\treturn error;\n \t\ttmp = vma_iter_end(\u0026vmi);\n@@ -589,7 +590,7 @@ static unsigned long count_mm_mlocked_page_nr(struct mm_struct *mm,\n \t\tend = start + len;\n \n \tfor_each_vma_range(vmi, vma, end) {\n-\t\tif (vma-\u003evm_flags \u0026 VM_LOCKED) {\n+\t\tif (vma_test(vma, VMA_LOCKED_BIT)) {\n \t\t\tif (start \u003e vma-\u003evm_start)\n \t\t\t\tcount -= (start - vma-\u003evm_start);\n \t\t\tif (end \u003c vma-\u003evm_end) {\n@@ -615,7 +616,8 @@ static int __mlock_posix_error_return(long retval)\n \treturn retval;\n }\n \n-static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t flags)\n+static __must_check int do_mlock(unsigned long start, size_t len,\n+\t\t\t\t vma_flags_t *flags)\n {\n \tunsigned long locked;\n \tunsigned long lock_limit;\n@@ -664,24 +666,27 @@ static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t fla\n \n SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)\n {\n-\treturn do_mlock(start, len, VM_LOCKED);\n+\tvma_flags_t flags = mk_vma_flags(VMA_LOCKED_BIT);\n+\n+\treturn do_mlock(start, len, \u0026flags);\n }\n \n SYSCALL_DEFINE3(mlock2, unsigned long, start, size_t, len, int, flags)\n {\n-\tvm_flags_t vm_flags = VM_LOCKED;\n+\tvma_flags_t vma_flags = mk_vma_flags(VMA_LOCKED_BIT);\n \n \tif (flags \u0026 ~MLOCK_ONFAULT)\n \t\treturn -EINVAL;\n \n \tif (flags \u0026 MLOCK_ONFAULT)\n-\t\tvm_flags |= VM_LOCKONFAULT;\n+\t\tvma_flags_set(\u0026vma_flags, VMA_LOCKONFAULT_BIT);\n \n-\treturn do_mlock(start, len, vm_flags);\n+\treturn do_mlock(start, len, \u0026vma_flags);\n }\n \n SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)\n {\n+\tvma_flags_t flags = EMPTY_VMA_FLAGS;\n \tint ret;\n \n \tstart = untagged_addr(start);\n@@ -691,7 +696,7 @@ SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)\n \n \tif (mmap_write_lock_killable(current-\u003emm))\n \t\treturn -EINTR;\n-\tret = apply_vma_lock_flags(start, len, 0);\n+\tret = apply_vma_lock_flags(start, len, \u0026flags);\n \tmmap_write_unlock(current-\u003emm);\n \n \treturn ret;\n@@ -699,46 +704,48 @@ SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)\n \n /*\n * Take the MCL_* flags passed into mlockall (or 0 if called from munlockall)\n- * and translate into the appropriate modifications to mm-\u003edef_flags and/or the\n- * flags for all current VMAs.\n+ * and translate into the appropriate modifications to mm-\u003edef_vma_flags and/or\n+ * the flags for all current VMAs.\n *\n * There are a couple of subtleties with this. If mlockall() is called multiple\n * times with different flags, the values do not necessarily stack. If mlockall\n * is called once including the MCL_FUTURE flag and then a second time without\n- * it, VM_LOCKED and VM_LOCKONFAULT will be cleared from mm-\u003edef_flags.\n+ * it, VMA_LOCKED_BIT and VMA_LOCKONFAULT_BIT will be cleared from\n+ * mm-\u003edef_vma_flags.\n */\n static int apply_mlockall_flags(int flags)\n {\n \tVMA_ITERATOR(vmi, current-\u003emm, 0);\n+\tstruct mm_struct *mm = current-\u003emm;\n \tstruct vm_area_struct *vma, *prev = NULL;\n-\tvm_flags_t to_add = 0;\n+\tvma_flags_t to_add = EMPTY_VMA_FLAGS;\n \n-\tcurrent-\u003emm-\u003edef_flags \u0026= ~VM_LOCKED_MASK;\n+\tvma_flags_clear_mask(\u0026mm-\u003edef_vma_flags, VMA_LOCKED_MASK);\n \tif (flags \u0026 MCL_FUTURE) {\n-\t\tcurrent-\u003emm-\u003edef_flags |= VM_LOCKED;\n+\t\tvma_flags_set(\u0026mm-\u003edef_vma_flags, VMA_LOCKED_BIT);\n \n \t\tif (flags \u0026 MCL_ONFAULT)\n-\t\t\tcurrent-\u003emm-\u003edef_flags |= VM_LOCKONFAULT;\n+\t\t\tvma_flags_set(\u0026mm-\u003edef_vma_flags, VMA_LOCKONFAULT_BIT);\n \n \t\tif (!(flags \u0026 MCL_CURRENT))\n \t\t\tgoto out;\n \t}\n \n \tif (flags \u0026 MCL_CURRENT) {\n-\t\tto_add |= VM_LOCKED;\n+\t\tvma_flags_set(\u0026to_add, VMA_LOCKED_BIT);\n \t\tif (flags \u0026 MCL_ONFAULT)\n-\t\t\tto_add |= VM_LOCKONFAULT;\n+\t\t\tvma_flags_set(\u0026to_add, VMA_LOCKONFAULT_BIT);\n \t}\n \n \tfor_each_vma(vmi, vma) {\n \t\tint error;\n-\t\tvm_flags_t newflags;\n+\t\tvma_flags_t newflags = vma-\u003eflags;\n \n-\t\tnewflags = vma-\u003evm_flags \u0026 ~VM_LOCKED_MASK;\n-\t\tnewflags |= to_add;\n+\t\tvma_flags_clear_mask(\u0026newflags, VMA_LOCKED_MASK);\n+\t\tvma_flags_set_mask(\u0026newflags, to_add);\n \n \t\terror = mlock_fixup(\u0026vmi, vma, \u0026prev, vma-\u003evm_start, vma-\u003evm_end,\n-\t\t\t\t newflags);\n+\t\t\t\t \u0026newflags);\n \t\t/* Ignore errors, but prev needs fixing up. */\n \t\tif (error)\n \t\t\tprev = vma;\ndiff --git a/mm/mmap.c b/mm/mmap.c\nindex 308a43eabd83b1..4bf26b0f1e6e36 100644\n--- a/mm/mmap.c\n+++ b/mm/mmap.c\n@@ -80,13 +80,13 @@ core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644);\n /* Update vma-\u003evm_page_prot to reflect vma-\u003evm_flags. */\n void vma_set_page_prot(struct vm_area_struct *vma)\n {\n-\tvm_flags_t vm_flags = vma-\u003evm_flags;\n+\tvma_flags_t vma_flags = vma-\u003eflags;\n \tpgprot_t vm_page_prot;\n \n-\tvm_page_prot = vm_pgprot_modify(vma-\u003evm_page_prot, vm_flags);\n+\tvm_page_prot = vma_pgprot_modify(vma-\u003evm_page_prot, vma_flags);\n \tif (vma_wants_writenotify(vma, vm_page_prot)) {\n-\t\tvm_flags \u0026= ~VM_SHARED;\n-\t\tvm_page_prot = vm_pgprot_modify(vm_page_prot, vm_flags);\n+\t\tvma_flags_clear(\u0026vma_flags, VMA_SHARED_BIT);\n+\t\tvm_page_prot = vma_pgprot_modify(vm_page_prot, vma_flags);\n \t}\n \t/* remove_protection_ptes reads vma-\u003evm_page_prot without mmap_lock */\n \tWRITE_ONCE(vma-\u003evm_page_prot, vm_page_prot);\n@@ -102,15 +102,16 @@ void vma_set_page_prot(struct vm_area_struct *vma)\n */\n static int check_brk_limits(unsigned long addr, unsigned long len)\n {\n+\tconst struct mm_struct *mm = current-\u003emm;\n+\tconst bool is_def_locked =\n+\t\tvma_flags_test(\u0026mm-\u003edef_vma_flags, VMA_LOCKED_BIT);\n \tunsigned long mapped_addr;\n \n \tmapped_addr = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED);\n \tif (IS_ERR_VALUE(mapped_addr))\n \t\treturn mapped_addr;\n \n-\treturn mlock_future_ok(current-\u003emm,\n-\t\t\t current-\u003emm-\u003edef_flags \u0026 VM_LOCKED, len)\n-\t\t? 0 : -EAGAIN;\n+\treturn mlock_future_ok(mm, is_def_locked, len) ? 0 : -EAGAIN;\n }\n \n SYSCALL_DEFINE1(brk, unsigned long, brk)\n@@ -197,7 +198,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)\n \t\tgoto out;\n \n \tmm-\u003ebrk = brk;\n-\tif (mm-\u003edef_flags \u0026 VM_LOCKED)\n+\tif (vma_flags_test(\u0026mm-\u003edef_vma_flags, VMA_LOCKED_BIT))\n \t\tpopulate = true;\n \n success:\n@@ -280,7 +281,7 @@ static inline bool file_mmap_ok(struct file *file, struct inode *inode,\n * do_mmap() - Perform a userland memory mapping into the current process\n * address space of length @len with protection bits @prot, mmap flags @flags\n * (from which VMA flags will be inferred), and any additional VMA flags to\n- * apply @vm_flags. If this is a file-backed mapping then the file is specified\n+ * apply @vma_flags. If this is a file-backed mapping then the file is specified\n * in @file and page offset into the file via @pgoff.\n *\n * This function does not perform security checks on the file and assumes, if\n@@ -320,7 +321,8 @@ static inline bool file_mmap_ok(struct file *file, struct inode *inode,\n * (2) for details.\n * @flags: Flags specifying how the mapping should be performed, see mmap (2)\n * for details.\n- * @vm_flags: VMA flags which should be set by default, or 0 otherwise.\n+ * @vma_flags: VMA flags which should be set by default, or EMPTY_VMA_FLAGS\n+ * otherwise.\n * @pgoff: Page offset into the @file if file-backed, should be 0 otherwise.\n * @populate: A pointer to a value which will be set to 0 if no population of\n * the range is required, or the number of bytes to populate if it is. Must be\n@@ -335,7 +337,7 @@ static inline bool file_mmap_ok(struct file *file, struct inode *inode,\n */\n unsigned long do_mmap(struct file *file, unsigned long addr,\n \t\t\tunsigned long len, unsigned long prot,\n-\t\t\tunsigned long flags, vm_flags_t vm_flags,\n+\t\t\tunsigned long flags, vma_flags_t vma_flags,\n \t\t\tunsigned long pgoff, unsigned long *populate,\n \t\t\tstruct list_head *uf)\n {\n@@ -399,13 +401,18 @@ unsigned long do_mmap(struct file *file, unsigned long addr,\n \t * to. we assume access permissions have been handled by the open\n \t * of the memory object, so we don't do any here.\n \t */\n-\tvm_flags |= calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(file, flags) |\n-\t\t\tmm-\u003edef_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;\n+\tvma_flags_set_mask(\u0026vma_flags,\n+\t\t\t legacy_to_vma_flags(calc_vm_prot_bits(prot, pkey)));\n+\tvma_flags_set_mask(\u0026vma_flags,\n+\t\t\t legacy_to_vma_flags(calc_vm_flag_bits(file, flags)));\n+\tvma_flags_set_mask(\u0026vma_flags, mm-\u003edef_vma_flags);\n+\tvma_flags_set(\u0026vma_flags, VMA_MAYREAD_BIT, VMA_MAYWRITE_BIT,\n+\t\t VMA_MAYEXEC_BIT);\n \n \t/* Obtain the address to map to. we verify (or select) it and ensure\n \t * that it represents a valid section of the address space.\n \t */\n-\taddr = __get_unmapped_area(file, addr, len, pgoff, flags, vm_flags);\n+\taddr = __get_unmapped_area(file, addr, len, pgoff, flags, vma_flags);\n \tif (IS_ERR_VALUE(addr))\n \t\treturn addr;\n \n@@ -418,7 +425,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,\n \t\tif (!can_do_mlock())\n \t\t\treturn -EPERM;\n \n-\tif (!mlock_future_ok(mm, vm_flags \u0026 VM_LOCKED, len))\n+\tif (!mlock_future_ok(mm, vma_flags_test(\u0026vma_flags, VMA_LOCKED_BIT), len))\n \t\treturn -EAGAIN;\n \n \tif (file) {\n@@ -461,22 +468,23 @@ unsigned long do_mmap(struct file *file, unsigned long addr,\n \t\t\tif (IS_APPEND(inode) \u0026\u0026 (file-\u003ef_mode \u0026 FMODE_WRITE))\n \t\t\t\treturn -EACCES;\n \n-\t\t\tvm_flags |= VM_SHARED | VM_MAYSHARE;\n+\t\t\tvma_flags_set(\u0026vma_flags, VMA_SHARED_BIT, VMA_MAYSHARE_BIT);\n \t\t\tif (!(file-\u003ef_mode \u0026 FMODE_WRITE))\n-\t\t\t\tvm_flags \u0026= ~(VM_MAYWRITE | VM_SHARED);\n+\t\t\t\tvma_flags_clear(\u0026vma_flags, VMA_MAYWRITE_BIT,\n+\t\t\t\t\t\tVMA_SHARED_BIT);\n \t\t\tfallthrough;\n \t\tcase MAP_PRIVATE:\n \t\t\tif (!(file-\u003ef_mode \u0026 FMODE_READ))\n \t\t\t\treturn -EACCES;\n \t\t\tif (path_noexec(\u0026file-\u003ef_path)) {\n-\t\t\t\tif (vm_flags \u0026 VM_EXEC)\n+\t\t\t\tif (vma_flags_test(\u0026vma_flags, VMA_EXEC_BIT))\n \t\t\t\t\treturn -EPERM;\n-\t\t\t\tvm_flags \u0026= ~VM_MAYEXEC;\n+\t\t\t\tvma_flags_clear(\u0026vma_flags, VMA_MAYEXEC_BIT);\n \t\t\t}\n \n \t\t\tif (!can_mmap_file(file))\n \t\t\t\treturn -ENODEV;\n-\t\t\tif (vm_flags \u0026 (VM_GROWSDOWN|VM_GROWSUP))\n+\t\t\tif (vma_flags_can_grow(\u0026vma_flags))\n \t\t\t\treturn -EINVAL;\n \t\t\tbreak;\n \n@@ -488,23 +496,27 @@ unsigned long do_mmap(struct file *file, unsigned long addr,\n \t\t * Check to see if we are violating any seals and update VMA\n \t\t * flags if necessary to avoid future seal violations.\n \t\t */\n-\t\terr = memfd_check_seals_mmap(file, \u0026vm_flags);\n+\t\terr = memfd_check_seals_mmap(file, \u0026vma_flags);\n \t\tif (err)\n \t\t\treturn (unsigned long)err;\n \t} else {\n \t\tswitch (flags \u0026 MAP_TYPE) {\n \t\tcase MAP_SHARED:\n-\t\t\tif (vm_flags \u0026 (VM_GROWSDOWN|VM_GROWSUP))\n+\t\t\tif (vma_flags_can_grow(\u0026vma_flags))\n \t\t\t\treturn -EINVAL;\n \t\t\t/*\n \t\t\t * Ignore pgoff.\n \t\t\t */\n \t\t\tpgoff = 0;\n-\t\t\tvm_flags |= VM_SHARED | VM_MAYSHARE;\n+\t\t\tvma_flags_set(\u0026vma_flags, VMA_SHARED_BIT, VMA_MAYSHARE_BIT);\n \t\t\tbreak;\n-\t\tcase MAP_DROPPABLE:\n-\t\t\tif (VM_DROPPABLE == VM_NONE)\n+\t\tcase MAP_DROPPABLE: {\n+\t\t\tvma_flags_t droppable = VMA_DROPPABLE;\n+\n+\t\t\tif (vma_flags_empty(\u0026droppable))\n \t\t\t\treturn -EOPNOTSUPP;\n+\t\t\tvma_flags_set_mask(\u0026vma_flags, droppable);\n+\n \t\t\t/*\n \t\t\t * A locked or stack area makes no sense to be droppable.\n \t\t\t *\n@@ -515,23 +527,24 @@ unsigned long do_mmap(struct file *file, unsigned long addr,\n \t\t\t */\n \t\t\tif (flags \u0026 (MAP_LOCKED | MAP_HUGETLB))\n \t\t\t return -EINVAL;\n-\t\t\tif (vm_flags \u0026 (VM_GROWSDOWN | VM_GROWSUP))\n+\t\t\tif (vma_flags_can_grow(\u0026vma_flags))\n \t\t\t return -EINVAL;\n \n-\t\t\tvm_flags |= VM_DROPPABLE;\n-\n \t\t\t/*\n \t\t\t * If the pages can be dropped, then it doesn't make\n \t\t\t * sense to reserve them.\n \t\t\t */\n-\t\t\tvm_flags |= VM_NORESERVE;\n+\t\t\tvma_flags_set(\u0026vma_flags, VMA_NORESERVE_BIT);\n \n \t\t\t/*\n \t\t\t * Likewise, they're volatile enough that they\n \t\t\t * shouldn't survive forks or coredumps.\n \t\t\t */\n-\t\t\tvm_flags |= VM_WIPEONFORK | VM_DONTDUMP;\n+\t\t\tvma_flags_set(\u0026vma_flags, VMA_WIPEONFORK_BIT,\n+\t\t\t\t VMA_DONTDUMP_BIT);\n+\n \t\t\tfallthrough;\n+\t\t}\n \t\tcase MAP_PRIVATE:\n \t\t\t/*\n \t\t\t * Set pgoff according to addr for anon_vma.\n@@ -544,22 +557,22 @@ unsigned long do_mmap(struct file *file, unsigned long addr,\n \t}\n \n \t/*\n-\t * Set 'VM_NORESERVE' if we should not account for the\n-\t * memory use of this mapping.\n+\t * Set VMA_NORESERVE_BIT if we should not account for the memory use\n+\t * of this mapping.\n \t */\n \tif (flags \u0026 MAP_NORESERVE) {\n \t\t/* We honor MAP_NORESERVE if allowed to overcommit */\n \t\tif (sysctl_overcommit_memory != OVERCOMMIT_NEVER)\n-\t\t\tvm_flags |= VM_NORESERVE;\n+\t\t\tvma_flags_set(\u0026vma_flags, VMA_NORESERVE_BIT);\n \n \t\t/* hugetlb applies strict overcommit unless MAP_NORESERVE */\n \t\tif (file \u0026\u0026 is_file_hugepages(file))\n-\t\t\tvm_flags |= VM_NORESERVE;\n+\t\t\tvma_flags_set(\u0026vma_flags, VMA_NORESERVE_BIT);\n \t}\n \n-\taddr = mmap_region(file, addr, len, vm_flags, pgoff, uf);\n+\taddr = mmap_region(file, addr, len, vma_flags, pgoff, uf);\n \tif (!IS_ERR_VALUE(addr) \u0026\u0026\n-\t ((vm_flags \u0026 VM_LOCKED) ||\n+\t (vma_flags_test(\u0026vma_flags, VMA_LOCKED_BIT) ||\n \t (flags \u0026 (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE))\n \t\t*populate = len;\n \treturn addr;\n@@ -645,9 +658,9 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)\n * Determine if the allocation needs to ensure that there is no\n * existing mapping within it's guard gaps, for use as start_gap.\n */\n-static inline unsigned long stack_guard_placement(vm_flags_t vm_flags)\n+static inline unsigned long stack_guard_placement(vma_flags_t vma_flags)\n {\n-\tif (vm_flags \u0026 VM_SHADOW_STACK)\n+\tif (vma_flags_test_single_mask(\u0026vma_flags, VMA_SHADOW_STACK))\n \t\treturn PAGE_SIZE;\n \n \treturn 0;\n@@ -689,7 +702,7 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info)\n unsigned long\n generic_get_unmapped_area(struct file *filp, unsigned long addr,\n \t\t\t unsigned long len, unsigned long pgoff,\n-\t\t\t unsigned long flags, vm_flags_t vm_flags)\n+\t\t\t unsigned long flags, vma_flags_t vma_flags)\n {\n \tstruct mm_struct *mm = current-\u003emm;\n \tstruct vm_area_struct *vma, *prev;\n@@ -714,7 +727,7 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,\n \tinfo.length = len;\n \tinfo.low_limit = mm-\u003emmap_base;\n \tinfo.high_limit = mmap_end;\n-\tinfo.start_gap = stack_guard_placement(vm_flags);\n+\tinfo.start_gap = stack_guard_placement(vma_flags);\n \tif (filp \u0026\u0026 is_file_hugepages(filp))\n \t\tinfo.align_mask = huge_page_mask_align(filp);\n \treturn vm_unmapped_area(\u0026info);\n@@ -727,7 +740,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,\n \t\t unsigned long flags, vm_flags_t vm_flags)\n {\n \treturn generic_get_unmapped_area(filp, addr, len, pgoff, flags,\n-\t\t\t\t\t vm_flags);\n+\t\t\t\t\t legacy_to_vma_flags(vm_flags));\n }\n #endif\n \n@@ -738,7 +751,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,\n unsigned long\n generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,\n \t\t\t\t unsigned long len, unsigned long pgoff,\n-\t\t\t\t unsigned long flags, vm_flags_t vm_flags)\n+\t\t\t\t unsigned long flags, vma_flags_t vma_flags)\n {\n \tstruct vm_area_struct *vma, *prev;\n \tstruct mm_struct *mm = current-\u003emm;\n@@ -766,7 +779,7 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,\n \tinfo.length = len;\n \tinfo.low_limit = PAGE_SIZE;\n \tinfo.high_limit = arch_get_mmap_base(addr, mm-\u003emmap_base);\n-\tinfo.start_gap = stack_guard_placement(vm_flags);\n+\tinfo.start_gap = stack_guard_placement(vma_flags);\n \tif (filp \u0026\u0026 is_file_hugepages(filp))\n \t\tinfo.align_mask = huge_page_mask_align(filp);\n \taddr = vm_unmapped_area(\u0026info);\n@@ -795,23 +808,24 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,\n \t\t\t unsigned long flags, vm_flags_t vm_flags)\n {\n \treturn generic_get_unmapped_area_topdown(filp, addr, len, pgoff, flags,\n-\t\t\t\t\t\t vm_flags);\n+\t\t\t\t\t\t legacy_to_vma_flags(vm_flags));\n }\n #endif\n \n-unsigned long mm_get_unmapped_area_vmflags(struct file *filp, unsigned long addr,\n-\t\t\t\t\t unsigned long len, unsigned long pgoff,\n-\t\t\t\t\t unsigned long flags, vm_flags_t vm_flags)\n+unsigned long mm_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr,\n+\t\tunsigned long len, unsigned long pgoff, unsigned long flags,\n+\t\tvma_flags_t vma_flags)\n {\n \tif (mm_flags_test(MMF_TOPDOWN, current-\u003emm))\n \t\treturn arch_get_unmapped_area_topdown(filp, addr, len, pgoff,\n-\t\t\t\t\t\t flags, vm_flags);\n-\treturn arch_get_unmapped_area(filp, addr, len, pgoff, flags, vm_flags);\n+\t\t\t\tflags, vma_flags_to_legacy(vma_flags));\n+\treturn arch_get_unmapped_area(filp, addr, len, pgoff, flags,\n+\t\t\tvma_flags_to_legacy(vma_flags));\n }\n \n unsigned long\n __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,\n-\t\tunsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)\n+\t\tunsigned long pgoff, unsigned long flags, vma_flags_t vma_flags)\n {\n \tunsigned long (*get_area)(struct file *, unsigned long,\n \t\t\t\t unsigned long, unsigned long, unsigned long)\n@@ -846,11 +860,11 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,\n \t\t \u0026\u0026 !addr /* no hint */\n \t\t \u0026\u0026 IS_ALIGNED(len, PMD_SIZE)) {\n \t\t/* Ensures that larger anonymous mappings are THP aligned. */\n-\t\taddr = thp_get_unmapped_area_vmflags(file, addr, len,\n-\t\t\t\t\t\t pgoff, flags, vm_flags);\n+\t\taddr = thp_get_unmapped_area_vmaflags(file, addr, len,\n+\t\t\t\t\t\t pgoff, flags, vma_flags);\n \t} else {\n-\t\taddr = mm_get_unmapped_area_vmflags(file, addr, len,\n-\t\t\t\t\t\t pgoff, flags, vm_flags);\n+\t\taddr = mm_get_unmapped_area_vmaflags(file, addr, len,\n+\t\t\t\t\t\t pgoff, flags, vma_flags);\n \t}\n \tif (IS_ERR_VALUE(addr))\n \t\treturn addr;\n@@ -868,7 +882,8 @@ unsigned long\n mm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,\n \t\t unsigned long pgoff, unsigned long flags)\n {\n-\treturn mm_get_unmapped_area_vmflags(file, addr, len, pgoff, flags, 0);\n+\treturn mm_get_unmapped_area_vmaflags(file, addr, len, pgoff, flags,\n+\t\t\t\t\t EMPTY_VMA_FLAGS);\n }\n EXPORT_SYMBOL(mm_get_unmapped_area);\n \n@@ -970,7 +985,7 @@ struct vm_area_struct *find_extend_vma_locked(struct mm_struct *mm, unsigned lon\n \t\treturn NULL;\n \tif (expand_stack_locked(prev, addr))\n \t\treturn NULL;\n-\tif (prev-\u003evm_flags \u0026 VM_LOCKED)\n+\tif (vma_test(prev, VMA_LOCKED_BIT))\n \t\tpopulate_vma_page_range(prev, addr, prev-\u003evm_end, NULL);\n \treturn prev;\n }\n@@ -994,7 +1009,7 @@ struct vm_area_struct *find_extend_vma_locked(struct mm_struct *mm, unsigned lon\n \tstart = vma-\u003evm_start;\n \tif (expand_stack_locked(vma, addr))\n \t\treturn NULL;\n-\tif (vma-\u003evm_flags \u0026 VM_LOCKED)\n+\tif (vma_test(vma, VMA_LOCKED_BIT))\n \t\tpopulate_vma_page_range(vma, addr, start, NULL);\n \treturn vma;\n }\n@@ -1119,18 +1134,18 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,\n \t */\n \tvma = vma_lookup(mm, start);\n \n-\tif (!vma || !(vma-\u003evm_flags \u0026 VM_SHARED)) {\n+\tif (!vma || !vma_test(vma, VMA_SHARED_BIT)) {\n \t\tmmap_read_unlock(mm);\n \t\treturn -EINVAL;\n \t}\n \n-\tprot |= vma-\u003evm_flags \u0026 VM_READ ? PROT_READ : 0;\n-\tprot |= vma-\u003evm_flags \u0026 VM_WRITE ? PROT_WRITE : 0;\n-\tprot |= vma-\u003evm_flags \u0026 VM_EXEC ? PROT_EXEC : 0;\n+\tprot |= vma_test(vma, VMA_READ_BIT) ? PROT_READ : 0;\n+\tprot |= vma_test(vma, VMA_WRITE_BIT) ? PROT_WRITE : 0;\n+\tprot |= vma_test(vma, VMA_EXEC_BIT) ? PROT_EXEC : 0;\n \n \tflags \u0026= MAP_NONBLOCK;\n \tflags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE;\n-\tif (vma-\u003evm_flags \u0026 VM_LOCKED)\n+\tif (vma_test(vma, VMA_LOCKED_BIT))\n \t\tflags |= MAP_LOCKED;\n \n \t/* Save vm_flags used to calculate prot and flags, and recheck later. */\n@@ -1191,7 +1206,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,\n \t}\n \n \tret = do_mmap(vma-\u003evm_file, start, size,\n-\t\t\tprot, flags, 0, pgoff, \u0026populate, NULL);\n+\t\t\tprot, flags, EMPTY_VMA_FLAGS, pgoff, \u0026populate, NULL);\n out:\n \tmmap_write_unlock(mm);\n \tfput(file);\n@@ -1233,7 +1248,7 @@ int vm_brk_flags(unsigned long addr, unsigned long request, bool is_exec)\n \n \tvma = vma_prev(\u0026vmi);\n \tret = do_brk_flags(\u0026vmi, vma, addr, len, vma_flags);\n-\tpopulate = ((mm-\u003edef_flags \u0026 VM_LOCKED) != 0);\n+\tpopulate = vma_flags_test(\u0026mm-\u003edef_vma_flags, VMA_LOCKED_BIT);\n \tmmap_write_unlock(mm);\n \tuserfaultfd_unmap_complete(mm, \u0026uf);\n \tif (populate \u0026\u0026 !ret)\n@@ -1256,7 +1271,7 @@ unsigned long tear_down_vmas(struct mm_struct *mm, struct vma_iterator *vmi,\n \tmmap_assert_write_locked(mm);\n \tvma_iter_set(vmi, vma-\u003evm_end);\n \tdo {\n-\t\tif (vma-\u003evm_flags \u0026 VM_ACCOUNT)\n+\t\tif (vma_test(vma, VMA_ACCOUNT_BIT))\n \t\t\tnr_accounted += vma_pages(vma);\n \t\tvma_mark_detached(vma);\n \t\tremove_vma(vma);\n@@ -1405,7 +1420,7 @@ static int special_mapping_split(struct vm_area_struct *vma, unsigned long addr)\n {\n \t/*\n \t * Forbid splitting special mappings - kernel has expectations over\n-\t * the number of pages in mapping. Together with VM_DONTEXPAND\n+\t * the number of pages in mapping. Together with VMA_DONTEXPAND_BIT\n \t * the size of vma should stay the same over the special mapping's\n \t * lifetime.\n \t */\n@@ -1677,7 +1692,7 @@ bool mmap_read_lock_maybe_expand(struct mm_struct *mm,\n \t\treturn true;\n \t}\n \n-\tif (!(new_vma-\u003evm_flags \u0026 VM_GROWSDOWN))\n+\tif (!vma_test(new_vma, VMA_GROWSDOWN_BIT))\n \t\treturn false;\n \n \tmmap_write_lock(mm);\n@@ -1727,7 +1742,7 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)\n \t\tretval = vma_start_write_killable(mpnt);\n \t\tif (retval \u003c 0)\n \t\t\tgoto loop_out;\n-\t\tif (mpnt-\u003evm_flags \u0026 VM_DONTCOPY) {\n+\t\tif (vma_test(mpnt, VMA_DONTCOPY_BIT)) {\n \t\t\tretval = vma_iter_clear_gfp(\u0026vmi, mpnt-\u003evm_start,\n \t\t\t\t\t\t mpnt-\u003evm_end, GFP_KERNEL);\n \t\t\tif (retval)\n@@ -1737,7 +1752,7 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)\n \t\t\tcontinue;\n \t\t}\n \t\tcharge = 0;\n-\t\tif (mpnt-\u003evm_flags \u0026 VM_ACCOUNT) {\n+\t\tif (vma_test(mpnt, VMA_ACCOUNT_BIT)) {\n \t\t\tunsigned long len = vma_pages(mpnt);\n \n \t\t\tif (security_vm_enough_memory_mm(oldmm, len)) /* sic */\n@@ -1755,16 +1770,19 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)\n \t\tretval = dup_userfaultfd(tmp, \u0026uf);\n \t\tif (retval)\n \t\t\tgoto fail_nomem_anon_vma_fork;\n-\t\tif (tmp-\u003evm_flags \u0026 VM_WIPEONFORK) {\n+\n+\t\tif (vma_test(tmp, VMA_WIPEONFORK_BIT)) {\n \t\t\t/*\n-\t\t\t * VM_WIPEONFORK gets a clean slate in the child.\n+\t\t\t * VMA_WIPEONFORK_BIT gets a clean slate in the child.\n \t\t\t * Don't prepare anon_vma until fault since we don't\n \t\t\t * copy page for current vma.\n \t\t\t */\n \t\t\ttmp-\u003eanon_vma = NULL;\n \t\t} else if (anon_vma_fork(tmp, mpnt))\n \t\t\tgoto fail_nomem_anon_vma_fork;\n-\t\tvm_flags_clear(tmp, VM_LOCKED_MASK);\n+\n+\t\tvma_start_write(tmp);\n+\t\tvma_clear_flags_mask(tmp, VMA_LOCKED_MASK);\n \t\t/*\n \t\t * Copy/update hugetlb private vma information.\n \t\t */\n@@ -1797,7 +1815,7 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)\n \t\t\ti_mmap_unlock_write(mapping);\n \t\t}\n \n-\t\tif (!(tmp-\u003evm_flags \u0026 VM_WIPEONFORK))\n+\t\tif (!vma_test(tmp, VMA_WIPEONFORK_BIT))\n \t\t\tretval = copy_page_range(tmp, mpnt);\n \n \t\tif (retval) {\ndiff --git a/mm/mprotect.c b/mm/mprotect.c\nindex dc27bbc1712fd5..2888ee638d872a 100644\n--- a/mm/mprotect.c\n+++ b/mm/mprotect.c\n@@ -40,7 +40,7 @@\n \n static bool maybe_change_pte_writable(struct vm_area_struct *vma, pte_t pte)\n {\n-\tif (WARN_ON_ONCE(!(vma-\u003evm_flags \u0026 VM_WRITE)))\n+\tif (WARN_ON_ONCE(!vma_test(vma, VMA_WRITE_BIT)))\n \t\treturn false;\n \n \t/* Don't touch entries that are not even readable. */\n@@ -97,7 +97,7 @@ static bool can_change_shared_pte_writable(struct vm_area_struct *vma,\n bool can_change_pte_writable(struct vm_area_struct *vma, unsigned long addr,\n \t\t\t pte_t pte)\n {\n-\tif (!(vma-\u003evm_flags \u0026 VM_SHARED))\n+\tif (!vma_test(vma, VMA_SHARED_BIT))\n \t\treturn can_change_private_pte_writable(vma, addr, pte);\n \n \treturn can_change_shared_pte_writable(vma, pte);\n@@ -194,7 +194,7 @@ static __always_inline void set_write_prot_commit_flush_ptes(struct vm_area_stru\n {\n \tbool set_write;\n \n-\tif (vma-\u003evm_flags \u0026 VM_SHARED) {\n+\tif (vma_test(vma, VMA_SHARED_BIT)) {\n \t\tset_write = can_change_shared_pte_writable(vma, ptent);\n \t\tprot_commit_flush_ptes(vma, addr, ptep, oldpte, ptent, nr_ptes,\n \t\t\t\t /* idx = */ 0, set_write, tlb);\n@@ -846,8 +846,8 @@ mprotect_fixup(struct vma_iterator *vmi, struct mmu_gather *tlb,\n \t\tvm_unacct_memory(nrpages);\n \n \t/*\n-\t * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major\n-\t * fault on access.\n+\t * Private VMA_LOCKED_BIT VMA becoming writable: trigger COW to avoid\n+\t * major fault on access.\n \t */\n \tif (vma_flags_test(\u0026new_vma_flags, VMA_WRITE_BIT) \u0026\u0026\n \t vma_flags_test(\u0026old_vma_flags, VMA_LOCKED_BIT) \u0026\u0026\n@@ -921,7 +921,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,\n \t\t\tgoto out;\n \t\tstart = vma-\u003evm_start;\n \t\terror = -EINVAL;\n-\t\tif (!(vma-\u003evm_flags \u0026 VM_GROWSDOWN))\n+\t\tif (!vma_test(vma, VMA_GROWSDOWN_BIT))\n \t\t\tgoto out;\n \t} else {\n \t\tif (vma-\u003evm_start \u003e start)\n@@ -929,7 +929,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,\n \t\tif (unlikely(grows \u0026 PROT_GROWSUP)) {\n \t\t\tend = vma-\u003evm_end;\n \t\t\terror = -EINVAL;\n-\t\t\tif (!(vma-\u003evm_flags \u0026 VM_GROWSUP))\n+\t\t\tif (!vma_test_single_mask(vma, VMA_GROWSUP))\n \t\t\t\tgoto out;\n \t\t}\n \t}\n@@ -953,7 +953,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,\n \t\t}\n \n \t\t/* Does the application expect PROT_READ to imply PROT_EXEC */\n-\t\tif (rier \u0026\u0026 (vma-\u003evm_flags \u0026 VM_MAYEXEC))\n+\t\tif (rier \u0026\u0026 vma_test(vma, VMA_MAYEXEC_BIT))\n \t\t\tprot |= PROT_EXEC;\n \n \t\t/*\ndiff --git a/mm/mremap.c b/mm/mremap.c\nindex 384ef4cc2195ba..b64aa1f6e07ede 100644\n--- a/mm/mremap.c\n+++ b/mm/mremap.c\n@@ -68,7 +68,7 @@ struct vma_remap_struct {\n \tbool populate_expand;\t\t/* mlock()'d expanded, must populate. */\n \tenum mremap_type remap_type;\t/* expand, shrink, etc. */\n \tbool mmap_locked;\t\t/* Is mm currently write-locked? */\n-\tunsigned long charged;\t\t/* If VM_ACCOUNT, # pages to account. */\n+\tunsigned long charged;\t\t/* If VMA_ACCOUNT_BIT, # pgs to account */\n \tbool vmi_needs_invalidate;\t/* Is the VMA iterator invalidated? */\n };\n \n@@ -963,7 +963,7 @@ static unsigned long vrm_set_new_addr(struct vma_remap_struct *vrm)\n \n \tif (vrm-\u003eflags \u0026 MREMAP_FIXED)\n \t\tmap_flags |= MAP_FIXED;\n-\tif (vma-\u003evm_flags \u0026 VM_MAYSHARE)\n+\tif (vma_test(vma, VMA_MAYSHARE_BIT))\n \t\tmap_flags |= MAP_SHARED;\n \n \tres = get_unmapped_area(vma-\u003evm_file, new_addr, vrm-\u003enew_len, pgoff,\n@@ -985,7 +985,7 @@ static bool vrm_calc_charge(struct vma_remap_struct *vrm)\n {\n \tunsigned long charged;\n \n-\tif (!(vrm-\u003evma-\u003evm_flags \u0026 VM_ACCOUNT))\n+\tif (!vma_test(vrm-\u003evma, VMA_ACCOUNT_BIT))\n \t\treturn true;\n \n \t/*\n@@ -1012,7 +1012,7 @@ static bool vrm_calc_charge(struct vma_remap_struct *vrm)\n */\n static void vrm_uncharge(struct vma_remap_struct *vrm)\n {\n-\tif (!(vrm-\u003evma-\u003evm_flags \u0026 VM_ACCOUNT))\n+\tif (!vma_test(vrm-\u003evma, VMA_ACCOUNT_BIT))\n \t\treturn;\n \n \tvm_unacct_memory(vrm-\u003echarged);\n@@ -1032,7 +1032,7 @@ static void vrm_stat_account(struct vma_remap_struct *vrm,\n \tstruct vm_area_struct *vma = vrm-\u003evma;\n \n \tvm_stat_account(mm, vma-\u003evm_flags, pages);\n-\tif (vma-\u003evm_flags \u0026 VM_LOCKED)\n+\tif (vma_test(vma, VMA_LOCKED_BIT))\n \t\tmm-\u003elocked_vm += pages;\n }\n \n@@ -1176,7 +1176,7 @@ static void unmap_source_vma(struct vma_remap_struct *vrm)\n \t * arose, in which case we _do_ wish to unmap the _new_ VMA, which means\n \t * we actually _do_ want it be unaccounted.\n \t */\n-\tbool accountable_move = (vma-\u003evm_flags \u0026 VM_ACCOUNT) \u0026\u0026\n+\tbool accountable_move = vma_test(vma, VMA_ACCOUNT_BIT) \u0026\u0026\n \t\t!(vrm-\u003eflags \u0026 MREMAP_DONTUNMAP);\n \n \t/*\n@@ -1195,7 +1195,7 @@ static void unmap_source_vma(struct vma_remap_struct *vrm)\n \t * portions of the original VMA that remain.\n \t */\n \tif (accountable_move) {\n-\t\tvm_flags_clear(vma, VM_ACCOUNT);\n+\t\tvma_clear_flags(vma, VMA_ACCOUNT_BIT);\n \t\t/* We are about to split vma, so store the start/end. */\n \t\tvm_start = vma-\u003evm_start;\n \t\tvm_end = vma-\u003evm_end;\n@@ -1220,8 +1220,8 @@ static void unmap_source_vma(struct vma_remap_struct *vrm)\n \t * | |\n \t * |-------------|\n \t *\n-\t * Having cleared VM_ACCOUNT from the whole VMA, after we unmap above\n-\t * we'll end up with:\n+\t * Having cleared VMA_ACCOUNT_BIT from the whole VMA, after we unmap\n+\t * above we'll end up with:\n \t *\n \t * addr end\n \t * | |\n@@ -1241,13 +1241,15 @@ static void unmap_source_vma(struct vma_remap_struct *vrm)\n \t\tif (vm_start \u003c addr) {\n \t\t\tstruct vm_area_struct *prev = vma_prev(\u0026vmi);\n \n-\t\t\tvm_flags_set(prev, VM_ACCOUNT); /* Acquires VMA lock. */\n+\t\t\tvma_start_write(prev);\n+\t\t\tvma_set_flags(prev, VMA_ACCOUNT_BIT);\n \t\t}\n \n \t\tif (vm_end \u003e end) {\n \t\t\tstruct vm_area_struct *next = vma_next(\u0026vmi);\n \n-\t\t\tvm_flags_set(next, VM_ACCOUNT); /* Acquires VMA lock. */\n+\t\t\tvma_start_write(next);\n+\t\t\tvma_set_flags(next, VMA_ACCOUNT_BIT);\n \t\t}\n \t}\n }\n@@ -1330,8 +1332,8 @@ static void dontunmap_complete(struct vma_remap_struct *vrm,\n \tunsigned long old_start = vrm-\u003evma-\u003evm_start;\n \tunsigned long old_end = vrm-\u003evma-\u003evm_end;\n \n-\t/* We always clear VM_LOCKED[ONFAULT] on the old VMA. */\n-\tvm_flags_clear(vrm-\u003evma, VM_LOCKED_MASK);\n+\t/* We always clear VMA_LOCKED[ONFAULT]_BIT on the old VMA. */\n+\tvma_clear_flags_mask(vrm-\u003evma, VMA_LOCKED_MASK);\n \n \t/*\n \t * anon_vma links of the old vma is no longer needed after its page\n@@ -1767,14 +1769,14 @@ static int check_prep_vma(struct vma_remap_struct *vrm)\n \t * based on the original. There are no known use cases for this\n \t * behavior. As a result, fail such attempts.\n \t */\n-\tif (!old_len \u0026\u0026 !(vma-\u003evm_flags \u0026 (VM_SHARED | VM_MAYSHARE))) {\n+\tif (!old_len \u0026\u0026 !vma_test_any(vma, VMA_SHARED_BIT, VMA_MAYSHARE_BIT)) {\n \t\tpr_warn_once(\"%s (%d): attempted to duplicate a private mapping with mremap. This is not supported.\\n\",\n \t\t\t current-\u003ecomm, current-\u003epid);\n \t\treturn -EINVAL;\n \t}\n \n \tif ((vrm-\u003eflags \u0026 MREMAP_DONTUNMAP) \u0026\u0026\n-\t\t\t(vma-\u003evm_flags \u0026 (VM_DONTEXPAND | VM_PFNMAP)))\n+\t vma_test_any(vma, VMA_DONTEXPAND_BIT, VMA_PFNMAP_BIT))\n \t\treturn -EINVAL;\n \n \t/*\n@@ -1804,7 +1806,7 @@ static int check_prep_vma(struct vma_remap_struct *vrm)\n \t\treturn 0;\n \n \t/* We are expanding and the VMA is mlock()'d so we need to populate. */\n-\tif (vma-\u003evm_flags \u0026 VM_LOCKED)\n+\tif (vma_test(vma, VMA_LOCKED_BIT))\n \t\tvrm-\u003epopulate_expand = true;\n \n \t/* Need to be careful about a growing mapping */\n@@ -1812,10 +1814,10 @@ static int check_prep_vma(struct vma_remap_struct *vrm)\n \tif (pgoff + (new_len \u003e\u003e PAGE_SHIFT) \u003c pgoff)\n \t\treturn -EINVAL;\n \n-\tif (vma-\u003evm_flags \u0026 (VM_DONTEXPAND | VM_PFNMAP))\n+\tif (vma_test_any(vma, VMA_DONTEXPAND_BIT, VMA_PFNMAP_BIT))\n \t\treturn -EFAULT;\n \n-\tif (!mlock_future_ok(mm, vma-\u003evm_flags \u0026 VM_LOCKED, vrm-\u003edelta))\n+\tif (!mlock_future_ok(mm, vma_test(vma, VMA_LOCKED_BIT), vrm-\u003edelta))\n \t\treturn -EAGAIN;\n \n \tif (!may_expand_vm(mm, \u0026vma-\u003eflags, vrm-\u003edelta \u003e\u003e PAGE_SHIFT))\ndiff --git a/mm/nommu.c b/mm/nommu.c\nindex adc0b0ca906bdf..498e01ee40b056 100644\n--- a/mm/nommu.c\n+++ b/mm/nommu.c\n@@ -1014,11 +1014,12 @@ unsigned long do_mmap(struct file *file,\n \t\t\tunsigned long len,\n \t\t\tunsigned long prot,\n \t\t\tunsigned long flags,\n-\t\t\tvm_flags_t vm_flags,\n+\t\t\tvma_flags_t vma_flags,\n \t\t\tunsigned long pgoff,\n \t\t\tunsigned long *populate,\n \t\t\tstruct list_head *uf)\n {\n+\tvm_flags_t vm_flags = vma_flags_to_legacy(vma_flags);\n \tstruct vm_area_struct *vma;\n \tstruct vm_region *region;\n \tstruct rb_node *rb;\ndiff --git a/mm/util.c b/mm/util.c\nindex 5090457542ca9c..bf0513d1d3d086 100644\n--- a/mm/util.c\n+++ b/mm/util.c\n@@ -578,8 +578,8 @@ unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr,\n \tif (!ret) {\n \t\tif (mmap_write_lock_killable(mm))\n \t\t\treturn -EINTR;\n-\t\tret = do_mmap(file, addr, len, prot, flag, 0, pgoff, \u0026populate,\n-\t\t\t \u0026uf);\n+\t\tret = do_mmap(file, addr, len, prot, flag, EMPTY_VMA_FLAGS, pgoff,\n+\t\t\t \u0026populate, \u0026uf);\n \t\tmmap_write_unlock(mm);\n \t\tuserfaultfd_unmap_complete(mm, \u0026uf);\n \t\tif (populate)\n@@ -627,20 +627,20 @@ EXPORT_SYMBOL(vm_mmap);\n unsigned long vm_mmap_shadow_stack(unsigned long addr, unsigned long len,\n \t\tunsigned long flags)\n {\n+\tvma_flags_t vma_flags = VMA_SHADOW_STACK;\n \tstruct mm_struct *mm = current-\u003emm;\n \tunsigned long ret, unused;\n-\tvm_flags_t vm_flags = VM_SHADOW_STACK;\n \n \tflags |= MAP_ANONYMOUS | MAP_PRIVATE;\n \tif (addr)\n \t\tflags |= MAP_FIXED_NOREPLACE;\n \n \tif (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))\n-\t\tvm_flags |= VM_NOHUGEPAGE;\n+\t\tvma_flags_set(\u0026vma_flags, VMA_NOHUGEPAGE_BIT);\n \n \tmmap_write_lock(mm);\n \tret = do_mmap(NULL, addr, len, PROT_READ | PROT_WRITE, flags,\n-\t\t vm_flags, 0, \u0026unused, NULL);\n+\t\t vma_flags, 0, \u0026unused, NULL);\n \tmmap_write_unlock(mm);\n \n \treturn ret;\ndiff --git a/mm/vma.c b/mm/vma.c\nindex 9d556d33b24bd1..b5bc3eec961c79 100644\n--- a/mm/vma.c\n+++ b/mm/vma.c\n@@ -56,7 +56,7 @@ struct mmap_state {\n \t\t.pglen = PHYS_PFN(len_),\t\t\t\t\\\n \t\t.vma_flags = vma_flags_,\t\t\t\t\\\n \t\t.file = file_,\t\t\t\t\t\t\\\n-\t\t.page_prot = vma_get_page_prot(vma_flags_),\t\t\\\n+\t\t.page_prot = vma_flags_to_page_prot(vma_flags_),\t\\\n \t}\n \n #define VMG_MMAP_STATE(name, map_, vma_)\t\t\t\t\\\n@@ -2176,7 +2176,7 @@ bool vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot)\n \t/* The open routine did something to the protections that pgprot_modify\n \t * won't preserve? */\n \tif (pgprot_val(vm_page_prot) !=\n-\t pgprot_val(vm_pgprot_modify(vm_page_prot, vma-\u003evm_flags)))\n+\t pgprot_val(vma_pgprot_modify(vm_page_prot, vma-\u003eflags)))\n \t\treturn false;\n \n \t/*\n@@ -2883,7 +2883,7 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr,\n * file to be mapped, otherwise NULL.\n * @addr: The page-aligned address at which to perform the mapping.\n * @len: The page-aligned, non-zero, length of the mapping.\n- * @vm_flags: The VMA flags which should be applied to the mapping.\n+ * @vma_flags: The VMA flags which should be applied to the mapping.\n * @pgoff: If @file is specified, the page offset into the file, if not then\n * the virtual page offset in memory of the anonymous mapping.\n * @uf: Optionally, a pointer to a list head used for tracking userfaultfd unmap\n@@ -2893,12 +2893,11 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr,\n * been performed.\n */\n unsigned long mmap_region(struct file *file, unsigned long addr,\n-\t\t\t unsigned long len, vm_flags_t vm_flags,\n+\t\t\t unsigned long len, vma_flags_t vma_flags,\n \t\t\t unsigned long pgoff, struct list_head *uf)\n {\n \tunsigned long ret;\n \tbool writable_file_mapping = false;\n-\tconst vma_flags_t vma_flags = legacy_to_vma_flags(vm_flags);\n \n \tmmap_assert_write_locked(current-\u003emm);\n \n@@ -2907,7 +2906,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,\n \t\treturn -EACCES;\n \n \t/* Allow architectures to sanity-check the vm_flags. */\n-\tif (!arch_validate_flags(vm_flags))\n+\tif (!arch_validate_flags(vma_flags_to_legacy(vma_flags)))\n \t\treturn -EINVAL;\n \n \t/* Map writable and ensure this isn't a sealed memfd. */\n@@ -3420,18 +3419,21 @@ struct vm_area_struct *__install_special_mapping(\n \tvm_flags_t vm_flags, void *priv,\n \tconst struct vm_operations_struct *ops)\n {\n-\tint ret;\n+\tvma_flags_t vma_flags = legacy_to_vma_flags(vm_flags);\n \tstruct vm_area_struct *vma;\n+\tint ret;\n \n \tvma = vm_area_alloc(mm);\n-\tif (unlikely(vma == NULL))\n+\tif (unlikely(!vma))\n \t\treturn ERR_PTR(-ENOMEM);\n \n-\tvm_flags |= mm-\u003edef_flags | VM_DONTEXPAND;\n+\tvma_flags_set_mask(\u0026vma_flags, mm-\u003edef_vma_flags);\n+\tvma_flags_set(\u0026vma_flags, VMA_DONTEXPAND_BIT);\n \tif (pgtable_supports_soft_dirty())\n-\t\tvm_flags |= VM_SOFTDIRTY;\n-\tvm_flags_init(vma, vm_flags \u0026 ~VM_LOCKED_MASK);\n-\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\t\tvma_flags_set(\u0026vma_flags, VMA_SOFTDIRTY_BIT);\n+\tvma_flags_clear_mask(\u0026vma_flags, VMA_LOCKED_MASK);\n+\tvma-\u003eflags = vma_flags;\n+\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \n \tvma-\u003evm_ops = ops;\n \tvma-\u003evm_private_data = priv;\ndiff --git a/mm/vma.h b/mm/vma.h\nindex adb7a0ba119208..0bc7d521e97677 100644\n--- a/mm/vma.h\n+++ b/mm/vma.h\n@@ -517,7 +517,7 @@ int mm_take_all_locks(struct mm_struct *mm);\n void mm_drop_all_locks(struct mm_struct *mm);\n \n unsigned long mmap_region(struct file *file, unsigned long addr,\n-\t\tunsigned long len, vm_flags_t vm_flags, unsigned long pgoff,\n+\t\tunsigned long len, vma_flags_t vma_flags, unsigned long pgoff,\n \t\tstruct list_head *uf);\n \n int do_brk_flags(struct vma_iterator *vmi, struct vm_area_struct *brkvma,\n@@ -541,9 +541,11 @@ static inline bool vma_wants_manual_pte_write_upgrade(struct vm_area_struct *vma\n }\n \n #ifdef CONFIG_MMU\n-static inline pgprot_t vm_pgprot_modify(pgprot_t oldprot, vm_flags_t vm_flags)\n+static inline pgprot_t vma_pgprot_modify(pgprot_t oldprot, vma_flags_t vma_flags)\n {\n-\treturn pgprot_modify(oldprot, vm_get_page_prot(vm_flags));\n+\tconst pgprot_t prot = vma_flags_to_page_prot(vma_flags);\n+\n+\treturn pgprot_modify(oldprot, prot);\n }\n #endif\n \ndiff --git a/mm/vma_exec.c b/mm/vma_exec.c\nindex ef1fa2b161f3ba..7af1260689b97e 100644\n--- a/mm/vma_exec.c\n+++ b/mm/vma_exec.c\n@@ -112,15 +112,17 @@ int relocate_vma_down(struct vm_area_struct *vma, unsigned long shift)\n int create_init_stack_vma(struct mm_struct *mm, struct vm_area_struct **vmap,\n \t\t\t unsigned long *top_mem_p)\n {\n-\tunsigned long flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;\n+\tvma_flags_t flags = VMA_STACK_INCOMPLETE_SETUP;\n+\tstruct vm_area_struct *vma;\n \tint err;\n-\tstruct vm_area_struct *vma = vm_area_alloc(mm);\n \n+\t/* VMA_STACK_FLAGS and VMA_STACK_INCOMPLETE_SETUP must not overlap. */\n+\tVM_WARN_ON_ONCE(vma_flags_test_any_mask(\u0026flags, VMA_STACK_FLAGS));\n+\n+\tvma = vm_area_alloc(mm);\n \tif (!vma)\n \t\treturn -ENOMEM;\n \n-\tvma_set_anonymous(vma);\n-\n \tif (mmap_write_lock_killable(mm)) {\n \t\terr = -EINTR;\n \t\tgoto err_free;\n@@ -134,19 +136,21 @@ int create_init_stack_vma(struct mm_struct *mm, struct vm_area_struct **vmap,\n \tif (err)\n \t\tgoto err_ksm;\n \n+\tvma_flags_set_mask(\u0026flags, VMA_STACK_FLAGS);\n+\tvma_set_anonymous(vma);\n+\n \t/*\n \t * Place the stack at the largest stack address the architecture\n \t * supports. Later, we'll move this to an appropriate place. We don't\n \t * use STACK_TOP because that can depend on attributes which aren't\n \t * configured yet.\n \t */\n-\tVM_WARN_ON_ONCE(VM_STACK_FLAGS \u0026 VM_STACK_INCOMPLETE_SETUP);\n \tvma-\u003evm_end = STACK_TOP_MAX;\n \tvma-\u003evm_start = vma-\u003evm_end - PAGE_SIZE;\n \tif (pgtable_supports_soft_dirty())\n-\t\tflags |= VM_SOFTDIRTY;\n-\tvm_flags_init(vma, flags);\n-\tvma-\u003evm_page_prot = vm_get_page_prot(vma-\u003evm_flags);\n+\t\tvma_flags_set(\u0026flags, VMA_SOFTDIRTY_BIT);\n+\tvma-\u003eflags = flags;\n+\tvma-\u003evm_page_prot = vma_get_page_prot(vma);\n \n \terr = insert_vm_struct(mm, vma);\n \tif (err)\ndiff --git a/sound/core/memalloc.c b/sound/core/memalloc.c\nindex 9320671dfcc8b0..5bc7e586b430f5 100644\n--- a/sound/core/memalloc.c\n+++ b/sound/core/memalloc.c\n@@ -851,7 +851,7 @@ static void snd_dma_noncoherent_free(struct snd_dma_buffer *dmab)\n static int snd_dma_noncoherent_mmap(struct snd_dma_buffer *dmab,\n \t\t\t\t struct vm_area_struct *area)\n {\n-\tarea-\u003evm_page_prot = vm_get_page_prot(area-\u003evm_flags);\n+\tarea-\u003evm_page_prot = vma_get_page_prot(area);\n \treturn dma_mmap_pages(dmab-\u003edev.dev, area,\n \t\t\t area-\u003evm_end - area-\u003evm_start,\n \t\t\t virt_to_page(dmab-\u003earea));\ndiff --git a/tools/testing/vma/include/dup.h b/tools/testing/vma/include/dup.h\nindex 773e23303e26af..64f38a83613e54 100644\n--- a/tools/testing/vma/include/dup.h\n+++ b/tools/testing/vma/include/dup.h\n@@ -245,8 +245,10 @@ enum {\n #define VM_STACK\tINIT_VM_FLAG(STACK)\n #ifdef CONFIG_STACK_GROWSUP\n #define VM_STACK_EARLY\tINIT_VM_FLAG(STACK_EARLY)\n+#define VMA_STACK_EARLY mk_vma_flags(VMA_STACK_EARLY_BIT)\n #else\n #define VM_STACK_EARLY\tVM_NONE\n+#define VMA_STACK_EARLY EMPTY_VMA_FLAGS\n #endif\n #ifdef CONFIG_ARCH_HAS_PKEYS\n #define VM_PKEY_SHIFT ((__force int)VMA_HIGH_ARCH_0_BIT)\n@@ -315,6 +317,8 @@ enum {\n \n /* Bits set in the VMA until the stack is in its final location */\n #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)\n+#define VMA_STACK_INCOMPLETE_SETUP append_vma_flags(\t\t\\\n+\tVMA_STACK_EARLY, VMA_RAND_READ_BIT, VMA_SEQ_READ_BIT)\n \n #define TASK_EXEC_BIT ((current-\u003epersonality \u0026 READ_IMPLIES_EXEC) ? \\\n \t\t VM_EXEC_BIT : VM_READ_BIT)\n@@ -1424,20 +1428,18 @@ struct vm_area_struct *vma_iter_next_range(struct vma_iterator *vmi)\n }\n \n bool vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot);\n+static inline pgprot_t vma_pgprot_modify(pgprot_t oldprot, vma_flags_t vma_flags);\n \n /* Update vma-\u003evm_page_prot to reflect vma-\u003evm_flags. */\n static inline void vma_set_page_prot(struct vm_area_struct *vma)\n {\n-\tvm_flags_t vm_flags = vma-\u003evm_flags;\n+\tvma_flags_t vma_flags = vma-\u003eflags;\n \tpgprot_t vm_page_prot;\n \n-\t/* testing: we inline vm_pgprot_modify() to avoid clash with vma.h. */\n-\tvm_page_prot = pgprot_modify(vma-\u003evm_page_prot, vm_get_page_prot(vm_flags));\n-\n+\tvm_page_prot = vma_pgprot_modify(vma-\u003evm_page_prot, vma_flags);\n \tif (vma_wants_writenotify(vma, vm_page_prot)) {\n-\t\tvm_flags \u0026= ~VM_SHARED;\n-\t\t/* testing: we inline vm_pgprot_modify() to avoid clash with vma.h. */\n-\t\tvm_page_prot = pgprot_modify(vm_page_prot, vm_get_page_prot(vm_flags));\n+\t\tvma_flags_clear(\u0026vma_flags, VMA_SHARED_BIT);\n+\t\tvm_page_prot = vma_pgprot_modify(vm_page_prot, vma_flags);\n \t}\n \t/* remove_protection_ptes reads vma-\u003evm_page_prot without mmap_lock */\n \tWRITE_ONCE(vma-\u003evm_page_prot, vm_page_prot);\n@@ -1547,7 +1549,7 @@ static inline int get_sysctl_max_map_count(void)\n #define pgtable_supports_soft_dirty()\tIS_ENABLED(CONFIG_MEM_SOFT_DIRTY)\n #endif\n \n-static inline pgprot_t vma_get_page_prot(vma_flags_t vma_flags)\n+static inline pgprot_t vma_flags_to_page_prot(vma_flags_t vma_flags)\n {\n \tconst vm_flags_t vm_flags = vma_flags_to_legacy(vma_flags);\n \n@@ -1575,3 +1577,8 @@ static inline void vma_assert_can_modify(struct vm_area_struct *vma)\n \tif (vma_is_attached(vma))\n \t\tvma_assert_write_locked(vma);\n }\n+\n+static inline pgprot_t vma_get_page_prot(const struct vm_area_struct *vma)\n+{\n+\treturn vma_flags_to_page_prot(vma-\u003eflags);\n+}\n"
} |
| 2/1 | 2026/07/12 10:14 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [
"mlock_fixup",
"apply_vma_lock_flags",
"apply_mlockall_flags",
"unmap_source_vma",
"check_prep_vma",
"memfd_check_seals_mmap",
"create_init_stack_vma",
"thp_get_unmapped_area_vmaflags"
],
"Reasoning": "The patch introduces a major refactoring of VMA flags handling in the core memory management subsystem, transitioning from `vm_flags_t` to `vma_flags_t`. It modifies critical paths in mmap, mremap, mlock, and mprotect. These changes functionally alter how VMA flags are set, cleared, and tested, which could introduce bugs like incorrect memory protections, accounting errors, or locking issues. Fuzzing should focus on the modified functions that handle these flags, avoiding the absolute hottest paths like `do_mmap` to prevent skewed distributions.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 7e8de2bd119de73d9468da4ef7e39d8e84794cae
Author: syz-cluster <triage@syzkaller.com>
Date: Sun Jul 12 10:14:35 2026 +0000
syz-cluster: applied patch under review
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index bd1fc17d3975dc..94873775fc0f45 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -91,8 +91,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
/* Map delay slot emulation page */
base = do_mmap(NULL, STACK_TOP, PAGE_SIZE, PROT_READ | PROT_EXEC,
- MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0, &unused,
- NULL);
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED,
+ EMPTY_VMA_FLAGS, 0, &unused, NULL);
if (IS_ERR_VALUE(base)) {
ret = base;
goto out;
diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c
index 28bec5bc787949..82127e31dca6de 100644
--- a/arch/powerpc/mm/book3s64/slice.c
+++ b/arch/powerpc/mm/book3s64/slice.c
@@ -659,7 +659,8 @@ unsigned long arch_get_unmapped_area(struct file *filp,
unsigned int psize;
if (radix_enabled())
- return generic_get_unmapped_area(filp, addr, len, pgoff, flags, vm_flags);
+ return generic_get_unmapped_area(filp, addr, len, pgoff, flags,
+ legacy_to_vma_flags(vm_flags));
if (filp && is_file_hugepages(filp))
psize = file_to_psize(filp);
@@ -679,7 +680,8 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
unsigned int psize;
if (radix_enabled())
- return generic_get_unmapped_area_topdown(filp, addr0, len, pgoff, flags, vm_flags);
+ return generic_get_unmapped_area_topdown(filp, addr0, len,
+ pgoff, flags, legacy_to_vma_flags(vm_flags));
if (filp && is_file_hugepages(filp))
psize = file_to_psize(filp);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index e3ed684ddcf291..32a05d889b9a2b 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1252,7 +1252,7 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
}
vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
- vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ vma->vm_page_prot = pgprot_writecombine(vma_get_page_prot(vma));
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
}
diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/drm_gem_dma_helper.c
index 1c00a71ab3c9d0..7d9612075d310b 100644
--- a/drivers/gpu/drm/drm_gem_dma_helper.c
+++ b/drivers/gpu/drm/drm_gem_dma_helper.c
@@ -540,7 +540,7 @@ int drm_gem_dma_mmap(struct drm_gem_dma_object *dma_obj, struct vm_area_struct *
vm_flags_mod(vma, VM_DONTDUMP | VM_DONTEXPAND, VM_PFNMAP);
if (dma_obj->map_noncoherent) {
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_page_prot = vma_get_page_prot(vma);
ret = dma_mmap_pages(drm_dev_dma_dev(dma_obj->base.dev),
vma, vma->vm_end - vma->vm_start,
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index c989459eb21591..06d019d51d3e6b 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -764,7 +764,7 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct
return ret;
vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_page_prot = vma_get_page_prot(vma);
if (shmem->map_wc)
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index 2e4d6d117ee2d8..f9c8b7b2bfc7af 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -133,7 +133,7 @@ static int etnaviv_gem_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
- vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vm_page_prot = vma_get_page_prot(vma);
if (etnaviv_obj->flags & ETNA_BO_WC) {
vma->vm_page_prot = pgprot_writecombine(vm_page_prot);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 9a6270f3dca6bf..0208c92595725c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -377,13 +377,13 @@ static int exynos_drm_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct
/* non-cachable as default. */
if (exynos_gem->flags & EXYNOS_BO_CACHABLE)
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_page_prot = vma_get_page_prot(vma);
else if (exynos_gem->flags & EXYNOS_BO_WC)
vma->vm_page_prot =
- pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ pgprot_writecombine(vma_get_page_prot(vma));
else
vma->vm_page_prot =
- pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+ pgprot_noncached(vma_get_page_prot(vma));
ret = exynos_drm_gem_mmap_buffer(exynos_gem, vma);
if (ret)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 0644f85c6c8e52..9ca90c1bb5b422 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -112,7 +112,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
vma = find_vma(mm, addr);
if (vma && __vma_matches(vma, obj->base.filp, addr, args->size))
vma->vm_page_prot =
- pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ pgprot_writecombine(vma_get_page_prot(vma));
else
addr = -ENOMEM;
mmap_write_unlock(mm);
@@ -1024,7 +1024,7 @@ i915_gem_object_mmap(struct drm_i915_gem_object *obj,
fput(anon);
if (obj->ops->mmap_ops) {
- vma->vm_page_prot = pgprot_decrypted(vm_get_page_prot(vma->vm_flags));
+ vma->vm_page_prot = pgprot_decrypted(vma_get_page_prot(vma));
vma->vm_ops = obj->ops->mmap_ops;
vma->vm_private_data = obj->base.vma_node.driver_private;
return 0;
@@ -1035,7 +1035,7 @@ i915_gem_object_mmap(struct drm_i915_gem_object *obj,
switch (mmo->mmap_type) {
case I915_MMAP_TYPE_WC:
vma->vm_page_prot =
- pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ pgprot_writecombine(vma_get_page_prot(vma));
vma->vm_ops = &vm_ops_cpu;
break;
@@ -1043,19 +1043,19 @@ i915_gem_object_mmap(struct drm_i915_gem_object *obj,
GEM_WARN_ON(1);
fallthrough;
case I915_MMAP_TYPE_WB:
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_page_prot = vma_get_page_prot(vma);
vma->vm_ops = &vm_ops_cpu;
break;
case I915_MMAP_TYPE_UC:
vma->vm_page_prot =
- pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+ pgprot_noncached(vma_get_page_prot(vma));
vma->vm_ops = &vm_ops_cpu;
break;
case I915_MMAP_TYPE_GTT:
vma->vm_page_prot =
- pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ pgprot_writecombine(vma_get_page_prot(vma));
vma->vm_ops = &vm_ops_gtt;
break;
}
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index cbf723a5d86fa9..6a78e242de7c6b 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -1125,7 +1125,7 @@ static int msm_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct
struct msm_gem_object *msm_obj = to_msm_bo(obj);
vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
- vma->vm_page_prot = msm_gem_pgprot(msm_obj, vm_get_page_prot(vma->vm_flags));
+ vma->vm_page_prot = msm_gem_pgprot(msm_obj, vma_get_page_prot(vma));
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 20dba02d6175bc..9a6ee2e880c0ae 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -55,7 +55,7 @@ static vm_fault_t nouveau_ttm_fault(struct vm_fault *vmf)
goto error_unlock;
nouveau_bo_del_io_reserve_lru(bo);
- prot = vm_get_page_prot(vma->vm_flags);
+ prot = vma_get_page_prot(vma);
ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT);
nouveau_bo_add_io_reserve_lru(bo);
if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index ca3fb186bf1954..4881777642d296 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -84,7 +84,7 @@ static int omap_fbdev_pan_display(struct fb_var_screeninfo *var, struct fb_info
static int omap_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
- vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ vma->vm_page_prot = pgprot_writecombine(vma_get_page_prot(vma));
return fb_deferred_io_mmap(info, vma);
}
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index 00404fb6c29aae..fb0e6f556b3147 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -538,9 +538,9 @@ static int omap_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struc
vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP | VM_IO | VM_MIXEDMAP);
if (omap_obj->flags & OMAP_BO_WC) {
- vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ vma->vm_page_prot = pgprot_writecombine(vma_get_page_prot(vma));
} else if (omap_obj->flags & OMAP_BO_UNCACHED) {
- vma->vm_page_prot = pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+ vma->vm_page_prot = pgprot_noncached(vma_get_page_prot(vma));
} else {
/*
* We do have some private objects, at least for scanout buffers
@@ -558,7 +558,7 @@ static int omap_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struc
vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
vma_set_file(vma, obj->filp);
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_page_prot = vma_get_page_prot(vma);
}
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
index a1e2eb1ca7bbe6..77055635396870 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.c
+++ b/drivers/gpu/drm/panthor/panthor_gem.c
@@ -776,7 +776,7 @@ static int panthor_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *v
}
vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_page_prot = vma_get_page_prot(vma);
if (should_map_wc(bo))
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index b188539dca0b25..9a1dc9f120729f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -255,7 +255,7 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj,
*/
vm_flags_mod(vma, VM_IO | VM_DONTEXPAND | VM_DONTDUMP, VM_PFNMAP);
- vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ vma->vm_page_prot = pgprot_writecombine(vma_get_page_prot(vma));
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
if (rk_obj->pages)
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 1d8d27a5ea89b8..f76af733ea7939 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -602,7 +602,7 @@ int __tegra_gem_mmap(struct drm_gem_object *gem, struct vm_area_struct *vma)
vma->vm_pgoff = vm_pgoff;
} else {
- pgprot_t prot = vm_get_page_prot(vma->vm_flags);
+ pgprot_t prot = vma_get_page_prot(vma);
vm_flags_mod(vma, VM_MIXEDMAP, VM_PFNMAP);
diff --git a/drivers/gpu/drm/virtio/virtgpu_vram.c b/drivers/gpu/drm/virtio/virtgpu_vram.c
index 4ae3cbc35dd364..544a6abddbc8b6 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vram.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vram.c
@@ -55,7 +55,7 @@ static int virtio_gpu_vram_mmap(struct drm_gem_object *obj,
vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
vm_flags_set(vma, VM_MIXEDMAP | VM_DONTEXPAND);
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_page_prot = vma_get_page_prot(vma);
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
vma->vm_ops = &virtio_gpu_vram_vm_ops;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
index 45561bc1c9effe..a9fd4015a0caa7 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
@@ -481,7 +481,7 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf)
if (vbo->dirty && vbo->dirty->method == VMW_BO_DIRTY_MKWRITE)
prot = vm_get_page_prot(vma->vm_flags & ~VM_SHARED);
else
- prot = vm_get_page_prot(vma->vm_flags);
+ prot = vma_get_page_prot(vma);
ret = ttm_bo_vm_fault_reserved(vmf, prot, num_prefault);
if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index abe25aedeeadef..838797cc65d790 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -281,7 +281,7 @@ static vm_fault_t barrier_fault(struct vm_fault *vmf)
pgprot_t prot;
int idx;
- prot = vm_get_page_prot(vma->vm_flags);
+ prot = vma_get_page_prot(vma);
if (drm_dev_enter(dev, &idx)) {
unsigned long pfn;
diff --git a/drivers/gpu/drm/xe/xe_mmio_gem.c b/drivers/gpu/drm/xe/xe_mmio_gem.c
index 8c803ef233cc4d..3741ae60f532bf 100644
--- a/drivers/gpu/drm/xe/xe_mmio_gem.c
+++ b/drivers/gpu/drm/xe/xe_mmio_gem.c
@@ -149,7 +149,7 @@ static int xe_mmio_gem_mmap(struct drm_gem_object *base, struct vm_area_struct *
/* Set vm_pgoff (used as a fake buffer offset by DRM) to 0 */
vma->vm_pgoff = 0;
- vma->vm_page_prot = pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+ vma->vm_page_prot = pgprot_noncached(vma_get_page_prot(vma));
vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP |
VM_DONTCOPY | VM_NORESERVE);
diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index eec4c1da3f9e31..dd158443f55f10 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -80,7 +80,7 @@ static int xen_drm_front_gem_object_mmap(struct drm_gem_object *gem_obj,
* which is mapped as Normal Inner Write-Back Outer Write-Back
* Inner-Shareable.
*/
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_page_prot = vma_get_page_prot(vma);
/*
* vm_operations_struct.fault handler will be called if CPU access
diff --git a/drivers/video/fbdev/core/fb_io_fops.c b/drivers/video/fbdev/core/fb_io_fops.c
index 6ab60fcd005014..6d0a8c8e141a22 100644
--- a/drivers/video/fbdev/core/fb_io_fops.c
+++ b/drivers/video/fbdev/core/fb_io_fops.c
@@ -161,7 +161,7 @@ int fb_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
len = info->fix.mmio_len;
}
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_page_prot = vma_get_page_prot(vma);
vma->vm_page_prot = pgprot_framebuffer(vma->vm_page_prot, vma->vm_start,
vma->vm_end, start);
diff --git a/fs/aio.c b/fs/aio.c
index f57fa21a250353..3de586da197bd9 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -604,7 +604,7 @@ static int aio_setup_ring(struct kioctx *ctx, unsigned int nr_events)
ctx->mmap_base = do_mmap(ctx->aio_ring_file, 0, ctx->mmap_size,
PROT_READ | PROT_WRITE,
- MAP_SHARED, 0, 0, &unused, NULL);
+ MAP_SHARED, EMPTY_VMA_FLAGS, 0, &unused, NULL);
mmap_write_unlock(mm);
if (IS_ERR((void *)ctx->mmap_base)) {
ctx->mmap_size = 0;
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 9fddd1e0b813ab..43066f9ddf52d1 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -184,7 +184,8 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
if (addr)
addr0 = ALIGN(addr, huge_page_size(h));
- return mm_get_unmapped_area_vmflags(file, addr0, len, pgoff, flags, 0);
+ return mm_get_unmapped_area_vmaflags(file, addr0, len, pgoff, flags,
+ EMPTY_VMA_FLAGS);
}
/*
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index cae97c30728097..9e43e138c0b777 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -391,9 +391,9 @@ static inline bool thp_disabled_by_hw(void)
unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags);
-unsigned long thp_get_unmapped_area_vmflags(struct file *filp, unsigned long addr,
+unsigned long thp_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags,
- vm_flags_t vm_flags);
+ vma_flags_t vma_flags);
enum split_type {
SPLIT_TYPE_UNIFORM,
@@ -617,9 +617,9 @@ static inline unsigned long thp_vma_allowable_orders(struct vm_area_struct *vma,
#define thp_get_unmapped_area NULL
static inline unsigned long
-thp_get_unmapped_area_vmflags(struct file *filp, unsigned long addr,
- unsigned long len, unsigned long pgoff,
- unsigned long flags, vm_flags_t vm_flags)
+thp_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long pgoff,
+ unsigned long flags, vma_flags_t vma_flags)
{
return 0;
}
diff --git a/include/linux/memfd.h b/include/linux/memfd.h
index b4fda09dab9f61..c159e40e3f34a0 100644
--- a/include/linux/memfd.h
+++ b/include/linux/memfd.h
@@ -14,9 +14,9 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx);
* to sealing, or 0 otherwise.
*
* We also update VMA flags if appropriate by manipulating the VMA flags pointed
- * to by vm_flags_ptr.
+ * to by vma_flags_ptr.
*/
-int memfd_check_seals_mmap(struct file *file, vm_flags_t *vm_flags_ptr);
+int memfd_check_seals_mmap(struct file *file, vma_flags_t *vma_flags_ptr);
struct file *memfd_alloc_file(const char *name, unsigned int flags);
int memfd_get_seals(struct file *file);
int memfd_add_seals(struct file *file, unsigned int seals);
@@ -30,7 +30,7 @@ static inline struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx)
return ERR_PTR(-EINVAL);
}
static inline int memfd_check_seals_mmap(struct file *file,
- vm_flags_t *vm_flags_ptr)
+ vma_flags_t *vma_flags_ptr)
{
return 0;
}
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 32bb723ffbb92d..550fb92957d189 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -442,8 +442,10 @@ enum {
#define VM_STACK INIT_VM_FLAG(STACK)
#ifdef CONFIG_STACK_GROWSUP
#define VM_STACK_EARLY INIT_VM_FLAG(STACK_EARLY)
+#define VMA_STACK_EARLY mk_vma_flags(VMA_STACK_EARLY_BIT)
#else
#define VM_STACK_EARLY VM_NONE
+#define VMA_STACK_EARLY EMPTY_VMA_FLAGS
#endif
#ifdef CONFIG_ARCH_HAS_PKEYS
#define VM_PKEY_SHIFT ((__force int)VMA_HIGH_ARCH_0_BIT)
@@ -465,15 +467,18 @@ enum {
#if defined(CONFIG_X86_USER_SHADOW_STACK) || defined(CONFIG_ARM64_GCS) || \
defined(CONFIG_RISCV_USER_CFI)
#define VM_SHADOW_STACK INIT_VM_FLAG(SHADOW_STACK)
+#define VMA_SHADOW_STACK mk_vma_flags(VMA_SHADOW_STACK_BIT)
#define VMA_STARTGAP_FLAGS mk_vma_flags(VMA_GROWSDOWN_BIT, VMA_SHADOW_STACK_BIT)
#else
#define VM_SHADOW_STACK VM_NONE
+#define VMA_SHADOW_STACK EMPTY_VMA_FLAGS
#define VMA_STARTGAP_FLAGS mk_vma_flags(VMA_GROWSDOWN_BIT)
#endif
#if defined(CONFIG_PPC64)
#define VM_SAO INIT_VM_FLAG(SAO)
#elif defined(CONFIG_PARISC)
#define VM_GROWSUP INIT_VM_FLAG(GROWSUP)
+#define VMA_GROWSUP mk_vma_flags(VMA_GROWSUP_BIT)
#elif defined(CONFIG_SPARC64)
#define VM_SPARC_ADI INIT_VM_FLAG(SPARC_ADI)
#define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR)
@@ -485,6 +490,7 @@ enum {
#endif
#ifndef VM_GROWSUP
#define VM_GROWSUP VM_NONE
+#define VMA_GROWSUP EMPTY_VMA_FLAGS
#endif
#ifdef CONFIG_ARM64_MTE
#define VM_MTE INIT_VM_FLAG(MTE)
@@ -540,6 +546,8 @@ enum {
/* Bits set in the VMA until the stack is in its final location */
#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
+#define VMA_STACK_INCOMPLETE_SETUP append_vma_flags( \
+ VMA_STACK_EARLY, VMA_RAND_READ_BIT, VMA_SEQ_READ_BIT)
#define TASK_EXEC_BIT ((current->personality & READ_IMPLIES_EXEC) ? \
VMA_EXEC_BIT : VMA_READ_BIT)
@@ -1578,11 +1586,24 @@ static inline bool vma_is_initial_stack(const struct vm_area_struct *vma)
vma->vm_end >= vma->vm_mm->start_stack;
}
-static inline bool vma_is_temporary_stack(const struct vm_area_struct *vma)
+static inline bool vma_flags_can_grow(const vma_flags_t *flags)
{
- int maybe_stack = vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP);
+ if (vma_flags_test_single_mask(flags, VMA_GROWSUP))
+ return true;
+ if (vma_flags_test(flags, VMA_GROWSDOWN_BIT))
+ return true;
+
+ return false;
+}
+
+static inline bool vma_can_grow(const struct vm_area_struct *vma)
+{
+ return vma_flags_can_grow(&vma->flags);
+}
- if (!maybe_stack)
+static inline bool vma_is_temporary_stack(const struct vm_area_struct *vma)
+{
+ if (!vma_can_grow(vma))
return false;
if ((vma->vm_flags & VM_STACK_INCOMPLETE_SETUP) ==
@@ -4174,18 +4195,20 @@ unsigned long randomize_page(unsigned long start, unsigned long range);
unsigned long
__get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
- unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags);
+ unsigned long pgoff, unsigned long flags,
+ vma_flags_t vma_flags);
static inline unsigned long
get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags)
{
- return __get_unmapped_area(file, addr, len, pgoff, flags, 0);
+ return __get_unmapped_area(file, addr, len, pgoff, flags,
+ EMPTY_VMA_FLAGS);
}
-extern unsigned long do_mmap(struct file *file, unsigned long addr,
+unsigned long do_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot, unsigned long flags,
- vm_flags_t vm_flags, unsigned long pgoff, unsigned long *populate,
+ vma_flags_t vma_flags, unsigned long pgoff, unsigned long *populate,
struct list_head *uf);
extern int do_vmi_munmap(struct vma_iterator *vmi, struct mm_struct *mm,
unsigned long start, size_t len, struct list_head *uf,
@@ -4584,26 +4607,35 @@ static inline bool range_in_vma_desc(const struct vm_area_desc *desc,
#ifdef CONFIG_MMU
pgprot_t vm_get_page_prot(vm_flags_t vm_flags);
-static inline pgprot_t vma_get_page_prot(vma_flags_t vma_flags)
+static inline pgprot_t vma_flags_to_page_prot(vma_flags_t vma_flags)
{
const vm_flags_t vm_flags = vma_flags_to_legacy(vma_flags);
return vm_get_page_prot(vm_flags);
}
+static inline pgprot_t vma_get_page_prot(const struct vm_area_struct *vma)
+{
+ return vma_flags_to_page_prot(vma->flags);
+}
+
void vma_set_page_prot(struct vm_area_struct *vma);
#else
static inline pgprot_t vm_get_page_prot(vm_flags_t vm_flags)
{
return __pgprot(0);
}
-static inline pgprot_t vma_get_page_prot(vma_flags_t vma_flags)
+static inline pgprot_t vma_flags_to_page_prot(vma_flags_t vma_flags)
+{
+ return __pgprot(0);
+}
+static inline pgprot_t vma_get_page_prot(const struct vm_area_struct *vma)
{
return __pgprot(0);
}
static inline void vma_set_page_prot(struct vm_area_struct *vma)
{
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_page_prot = vma_get_page_prot(vma);
}
#endif
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index 95d0040df58413..10be8a54b416f9 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -193,21 +193,18 @@ unsigned long mm_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff,
unsigned long flags);
-unsigned long mm_get_unmapped_area_vmflags(struct file *filp,
- unsigned long addr,
- unsigned long len,
- unsigned long pgoff,
- unsigned long flags,
- vm_flags_t vm_flags);
+unsigned long mm_get_unmapped_area_vmaflags(struct file *filp,
+ unsigned long addr, unsigned long len, unsigned long pgoff,
+ unsigned long flags, vma_flags_t vma_flags);
unsigned long
generic_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff,
- unsigned long flags, vm_flags_t vm_flags);
+ unsigned long flags, vma_flags_t vma_flags);
unsigned long
generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff,
- unsigned long flags, vm_flags_t vm_flags);
+ unsigned long flags, vma_flags_t vma_flags);
#else
static inline void arch_pick_mmap_layout(struct mm_struct *mm,
const struct rlimit *rlim_stack) {}
diff --git a/ipc/shm.c b/ipc/shm.c
index b3e8a58e177d3b..bb1a721a3e746e 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1661,7 +1661,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
goto invalid;
}
- addr = do_mmap(file, addr, size, prot, flags, 0, 0, &populate, NULL);
+ addr = do_mmap(file, addr, size, prot, flags, EMPTY_VMA_FLAGS, 0,
+ &populate, NULL);
*raddr = addr;
err = 0;
if (IS_ERR_VALUE(addr))
diff --git a/mm/debug.c b/mm/debug.c
index 497654b36f1ab5..9a0297b3988d89 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -197,7 +197,7 @@ void dump_mm(const struct mm_struct *mm)
"numa_next_scan %lu numa_scan_offset %lu numa_scan_seq %d\n"
#endif
"tlb_flush_pending %d\n"
- "def_flags: %#lx(%pGv)\n",
+ "def_flags: %*pb(%pGv)\n",
mm, mm->task_size,
mm->mmap_base, mm->mmap_legacy_base,
@@ -226,7 +226,8 @@ void dump_mm(const struct mm_struct *mm)
mm->numa_next_scan, mm->numa_scan_offset, mm->numa_scan_seq,
#endif
atomic_read(&mm->tlb_flush_pending),
- mm->def_flags, &mm->def_flags
+ NUM_VMA_FLAG_BITS, mm->def_vma_flags.__vma_flags,
+ &mm->def_vma_flags
);
}
EXPORT_SYMBOL(dump_mm);
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 0dc6d630570faf..40d6b4078e3d43 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1196,7 +1196,7 @@ static inline bool is_transparent_hugepage(const struct folio *folio)
static unsigned long __thp_get_unmapped_area(struct file *filp,
unsigned long addr, unsigned long len,
loff_t off, unsigned long flags, unsigned long size,
- vm_flags_t vm_flags)
+ vma_flags_t vma_flags)
{
loff_t off_end = off + len;
loff_t off_align = round_up(off, size);
@@ -1212,8 +1212,9 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
if (len_pad < len || (off + len_pad) < off)
return 0;
- ret = mm_get_unmapped_area_vmflags(filp, addr, len_pad,
- off >> PAGE_SHIFT, flags, vm_flags);
+ ret = mm_get_unmapped_area_vmaflags(filp, addr, len_pad,
+ off >> PAGE_SHIFT, flags,
+ vma_flags);
/*
* The failure might be due to length padding. The caller will retry
@@ -1238,25 +1239,27 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
return ret;
}
-unsigned long thp_get_unmapped_area_vmflags(struct file *filp, unsigned long addr,
+unsigned long thp_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags,
- vm_flags_t vm_flags)
+ vma_flags_t vma_flags)
{
unsigned long ret;
loff_t off = (loff_t)pgoff << PAGE_SHIFT;
- ret = __thp_get_unmapped_area(filp, addr, len, off, flags, PMD_SIZE, vm_flags);
+ ret = __thp_get_unmapped_area(filp, addr, len, off, flags, PMD_SIZE,
+ vma_flags);
if (ret)
return ret;
- return mm_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags,
- vm_flags);
+ return mm_get_unmapped_area_vmaflags(filp, addr, len, pgoff, flags,
+ vma_flags);
}
unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags)
{
- return thp_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags, 0);
+ return thp_get_unmapped_area_vmaflags(filp, addr, len, pgoff, flags,
+ EMPTY_VMA_FLAGS);
}
EXPORT_SYMBOL_GPL(thp_get_unmapped_area);
diff --git a/mm/memfd.c b/mm/memfd.c
index 6c72fe6caef75d..c708d92533f4ab 100644
--- a/mm/memfd.c
+++ b/mm/memfd.c
@@ -370,39 +370,36 @@ static inline bool is_write_sealed(unsigned int seals)
return seals & (F_SEAL_WRITE | F_SEAL_FUTURE_WRITE);
}
-static int check_write_seal(vm_flags_t *vm_flags_ptr)
+static int check_write_seal(vma_flags_t *vma_flags_ptr)
{
- vm_flags_t vm_flags = *vm_flags_ptr;
- vm_flags_t mask = vm_flags & (VM_SHARED | VM_WRITE);
-
/* If a private mapping then writability is irrelevant. */
- if (!(mask & VM_SHARED))
+ if (!vma_flags_test(vma_flags_ptr, VMA_SHARED_BIT))
return 0;
/*
* New PROT_WRITE and MAP_SHARED mmaps are not allowed when
* write seals are active.
*/
- if (mask & VM_WRITE)
+ if (vma_flags_test(vma_flags_ptr, VMA_WRITE_BIT))
return -EPERM;
/*
* This is a read-only mapping, disallow mprotect() from making a
* write-sealed mapping writable in future.
*/
- *vm_flags_ptr &= ~VM_MAYWRITE;
+ vma_flags_clear(vma_flags_ptr, VMA_MAYWRITE_BIT);
return 0;
}
-int memfd_check_seals_mmap(struct file *file, vm_flags_t *vm_flags_ptr)
+int memfd_check_seals_mmap(struct file *file, vma_flags_t *vma_flags_ptr)
{
int err = 0;
unsigned int *seals_ptr = memfd_file_seals_ptr(file);
unsigned int seals = seals_ptr ? *seals_ptr : 0;
if (is_write_sealed(seals))
- err = check_write_seal(vm_flags_ptr);
+ err = check_write_seal(vma_flags_ptr);
return err;
}
diff --git a/mm/mlock.c b/mm/mlock.c
index 97e49038d8d33e..efa6716e4dfbdf 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -329,7 +329,7 @@ static inline bool allow_mlock_munlock(struct folio *folio,
* be split. And the pages are not in VM_LOCKed VMA
* can be reclaimed.
*/
- if (!(vma->vm_flags & VM_LOCKED))
+ if (!vma_test(vma, VMA_LOCKED_BIT))
return true;
/* folio_within_range() cannot take KSM, but any small folio is OK */
@@ -368,7 +368,7 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,
folio = pmd_folio(*pmd);
if (folio_is_zone_device(folio))
goto out;
- if (vma->vm_flags & VM_LOCKED)
+ if (vma_test(vma, VMA_LOCKED_BIT))
mlock_folio(folio);
else
munlock_folio(folio);
@@ -393,7 +393,7 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,
if (!allow_mlock_munlock(folio, vma, start, end, step))
goto next_entry;
- if (vma->vm_flags & VM_LOCKED)
+ if (vma_test(vma, VMA_LOCKED_BIT))
mlock_folio(folio);
else
munlock_folio(folio);
@@ -417,8 +417,8 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,
* @end - end of range in @vma
* @new_vma_flags - the new set of flags for @vma.
*
- * Called for mlock(), mlock2() and mlockall(), to set @vma VM_LOCKED;
- * called for munlock() and munlockall(), to clear VM_LOCKED from @vma.
+ * Called for mlock(), mlock2() and mlockall(), to set @vma VMA_LOCKED_BIT;
+ * called for munlock() and munlockall(), to clear VMA_LOCKED_BIT from @vma.
*/
static void mlock_vma_pages_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end,
@@ -431,14 +431,14 @@ static void mlock_vma_pages_range(struct vm_area_struct *vma,
/*
* There is a slight chance that concurrent page migration,
- * or page reclaim finding a page of this now-VM_LOCKED vma,
+ * or page reclaim finding a page of this now-VMA_LOCKED_BIT vma,
* will call mlock_vma_folio() and raise page's mlock_count:
* double counting, leaving the page unevictable indefinitely.
- * Communicate this danger to mlock_vma_folio() with VM_IO,
- * which is a VM_SPECIAL flag not allowed on VM_LOCKED vmas.
+ * Communicate this danger to mlock_vma_folio() with VMA_IO_BIT,
+ * which is a VMA_SPECIAL_FLAGS flag not allowed on VMA_LOCKED_BIT vmas.
* mmap_lock is held in write mode here, so this weird
* combination should not be visible to other mmap_lock users;
- * but WRITE_ONCE so rmap walkers must see VM_IO if VM_LOCKED.
+ * but WRITE_ONCE so rmap walkers must see VMA_IO_BIT if VMA_LOCKED_BIT.
*/
if (vma_flags_test(new_vma_flags, VMA_LOCKED_BIT))
vma_flags_set(new_vma_flags, VMA_IO_BIT);
@@ -458,7 +458,7 @@ static void mlock_vma_pages_range(struct vm_area_struct *vma,
/*
* mlock_fixup - handle mlock[all]/munlock[all] requests.
*
- * Filters out "special" vmas -- VM_LOCKED never gets set for these, and
+ * Filters out "special" vmas -- VMA_LOCKED_BIT never gets set for these, and
* munlock is a no-op. However, for some special vmas, we go ahead and
* populate the ptes.
*
@@ -466,24 +466,23 @@ static void mlock_vma_pages_range(struct vm_area_struct *vma,
*/
static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,
struct vm_area_struct **prev, unsigned long start,
- unsigned long end, vm_flags_t newflags)
+ unsigned long end, vma_flags_t *new_vma_flags)
{
- vma_flags_t new_vma_flags = legacy_to_vma_flags(newflags);
const vma_flags_t old_vma_flags = vma->flags;
struct mm_struct *mm = vma->vm_mm;
int nr_pages;
int ret = 0;
- if (vma_flags_same_pair(&old_vma_flags, &new_vma_flags) ||
+ if (vma_flags_same_pair(&old_vma_flags, new_vma_flags) ||
vma_is_secretmem(vma) || !vma_supports_mlock(vma)) {
/*
- * Don't set VM_LOCKED or VM_LOCKONFAULT and don't count.
- * For secretmem, don't allow the memory to be unlocked.
+ * Don't set VMA_LOCKED_BIT or VMA_LOCKONFAULT_BIT and don't
+ * count. For secretmem, don't allow the memory to be unlocked.
*/
goto out;
}
- vma = vma_modify_flags(vmi, *prev, vma, start, end, &new_vma_flags);
+ vma = vma_modify_flags(vmi, *prev, vma, start, end, new_vma_flags);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto out;
@@ -493,7 +492,7 @@ static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,
* Keep track of amount of locked VM.
*/
nr_pages = (end - start) >> PAGE_SHIFT;
- if (!vma_flags_test(&new_vma_flags, VMA_LOCKED_BIT))
+ if (!vma_flags_test(new_vma_flags, VMA_LOCKED_BIT))
nr_pages = -nr_pages;
else if (vma_flags_test(&old_vma_flags, VMA_LOCKED_BIT))
nr_pages = 0;
@@ -502,15 +501,15 @@ static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,
/*
* vm_flags is protected by the mmap_lock held in write mode.
* It's okay if try_to_unmap_one unmaps a page just after we
- * set VM_LOCKED, populate_vma_page_range will bring it back.
+ * set VMA_LOCKED_BIT, populate_vma_page_range will bring it back.
*/
- if (vma_flags_test(&new_vma_flags, VMA_LOCKED_BIT) &&
+ if (vma_flags_test(new_vma_flags, VMA_LOCKED_BIT) &&
vma_flags_test(&old_vma_flags, VMA_LOCKED_BIT)) {
/* No work to do, and mlocking twice would be wrong */
vma_start_write(vma);
- vma->flags = new_vma_flags;
+ vma->flags = *new_vma_flags;
} else {
- mlock_vma_pages_range(vma, start, end, &new_vma_flags);
+ mlock_vma_pages_range(vma, start, end, new_vma_flags);
}
out:
*prev = vma;
@@ -518,7 +517,7 @@ static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,
}
static int apply_vma_lock_flags(unsigned long start, size_t len,
- vm_flags_t flags)
+ const vma_flags_t *flags)
{
unsigned long nstart, end, tmp;
struct vm_area_struct *vma, *prev;
@@ -543,18 +542,20 @@ static int apply_vma_lock_flags(unsigned long start, size_t len,
tmp = vma->vm_start;
for_each_vma_range(vmi, vma, end) {
int error;
- vm_flags_t newflags;
+ vma_flags_t newflags;
if (vma->vm_start != tmp)
return -ENOMEM;
- newflags = vma->vm_flags & ~VM_LOCKED_MASK;
- newflags |= flags;
+ newflags = vma->flags;
+ vma_flags_clear_mask(&newflags, VMA_LOCKED_MASK);
+ vma_flags_set_mask(&newflags, *flags);
+
/* Here we know that vma->vm_start <= nstart < vma->vm_end. */
tmp = vma->vm_end;
if (tmp > end)
tmp = end;
- error = mlock_fixup(&vmi, vma, &prev, nstart, tmp, newflags);
+ error = mlock_fixup(&vmi, vma, &prev, nstart, tmp, &newflags);
if (error)
return error;
tmp = vma_iter_end(&vmi);
@@ -589,7 +590,7 @@ static unsigned long count_mm_mlocked_page_nr(struct mm_struct *mm,
end = start + len;
for_each_vma_range(vmi, vma, end) {
- if (vma->vm_flags & VM_LOCKED) {
+ if (vma_test(vma, VMA_LOCKED_BIT)) {
if (start > vma->vm_start)
count -= (start - vma->vm_start);
if (end < vma->vm_end) {
@@ -615,7 +616,8 @@ static int __mlock_posix_error_return(long retval)
return retval;
}
-static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t flags)
+static __must_check int do_mlock(unsigned long start, size_t len,
+ vma_flags_t *flags)
{
unsigned long locked;
unsigned long lock_limit;
@@ -664,24 +666,27 @@ static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t fla
SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
{
- return do_mlock(start, len, VM_LOCKED);
+ vma_flags_t flags = mk_vma_flags(VMA_LOCKED_BIT);
+
+ return do_mlock(start, len, &flags);
}
SYSCALL_DEFINE3(mlock2, unsigned long, start, size_t, len, int, flags)
{
- vm_flags_t vm_flags = VM_LOCKED;
+ vma_flags_t vma_flags = mk_vma_flags(VMA_LOCKED_BIT);
if (flags & ~MLOCK_ONFAULT)
return -EINVAL;
if (flags & MLOCK_ONFAULT)
- vm_flags |= VM_LOCKONFAULT;
+ vma_flags_set(&vma_flags, VMA_LOCKONFAULT_BIT);
- return do_mlock(start, len, vm_flags);
+ return do_mlock(start, len, &vma_flags);
}
SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)
{
+ vma_flags_t flags = EMPTY_VMA_FLAGS;
int ret;
start = untagged_addr(start);
@@ -691,7 +696,7 @@ SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)
if (mmap_write_lock_killable(current->mm))
return -EINTR;
- ret = apply_vma_lock_flags(start, len, 0);
+ ret = apply_vma_lock_flags(start, len, &flags);
mmap_write_unlock(current->mm);
return ret;
@@ -699,46 +704,48 @@ SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)
/*
* Take the MCL_* flags passed into mlockall (or 0 if called from munlockall)
- * and translate into the appropriate modifications to mm->def_flags and/or the
- * flags for all current VMAs.
+ * and translate into the appropriate modifications to mm->def_vma_flags and/or
+ * the flags for all current VMAs.
*
* There are a couple of subtleties with this. If mlockall() is called multiple
* times with different flags, the values do not necessarily stack. If mlockall
* is called once including the MCL_FUTURE flag and then a second time without
- * it, VM_LOCKED and VM_LOCKONFAULT will be cleared from mm->def_flags.
+ * it, VMA_LOCKED_BIT and VMA_LOCKONFAULT_BIT will be cleared from
+ * mm->def_vma_flags.
*/
static int apply_mlockall_flags(int flags)
{
VMA_ITERATOR(vmi, current->mm, 0);
+ struct mm_struct *mm = current->mm;
struct vm_area_struct *vma, *prev = NULL;
- vm_flags_t to_add = 0;
+ vma_flags_t to_add = EMPTY_VMA_FLAGS;
- current->mm->def_flags &= ~VM_LOCKED_MASK;
+ vma_flags_clear_mask(&mm->def_vma_flags, VMA_LOCKED_MASK);
if (flags & MCL_FUTURE) {
- current->mm->def_flags |= VM_LOCKED;
+ vma_flags_set(&mm->def_vma_flags, VMA_LOCKED_BIT);
if (flags & MCL_ONFAULT)
- current->mm->def_flags |= VM_LOCKONFAULT;
+ vma_flags_set(&mm->def_vma_flags, VMA_LOCKONFAULT_BIT);
if (!(flags & MCL_CURRENT))
goto out;
}
if (flags & MCL_CURRENT) {
- to_add |= VM_LOCKED;
+ vma_flags_set(&to_add, VMA_LOCKED_BIT);
if (flags & MCL_ONFAULT)
- to_add |= VM_LOCKONFAULT;
+ vma_flags_set(&to_add, VMA_LOCKONFAULT_BIT);
}
for_each_vma(vmi, vma) {
int error;
- vm_flags_t newflags;
+ vma_flags_t newflags = vma->flags;
- newflags = vma->vm_flags & ~VM_LOCKED_MASK;
- newflags |= to_add;
+ vma_flags_clear_mask(&newflags, VMA_LOCKED_MASK);
+ vma_flags_set_mask(&newflags, to_add);
error = mlock_fixup(&vmi, vma, &prev, vma->vm_start, vma->vm_end,
- newflags);
+ &newflags);
/* Ignore errors, but prev needs fixing up. */
if (error)
prev = vma;
diff --git a/mm/mmap.c b/mm/mmap.c
index 308a43eabd83b1..4bf26b0f1e6e36 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -80,13 +80,13 @@ core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644);
/* Update vma->vm_page_prot to reflect vma->vm_flags. */
void vma_set_page_prot(struct vm_area_struct *vma)
{
- vm_flags_t vm_flags = vma->vm_flags;
+ vma_flags_t vma_flags = vma->flags;
pgprot_t vm_page_prot;
- vm_page_prot = vm_pgprot_modify(vma->vm_page_prot, vm_flags);
+ vm_page_prot = vma_pgprot_modify(vma->vm_page_prot, vma_flags);
if (vma_wants_writenotify(vma, vm_page_prot)) {
- vm_flags &= ~VM_SHARED;
- vm_page_prot = vm_pgprot_modify(vm_page_prot, vm_flags);
+ vma_flags_clear(&vma_flags, VMA_SHARED_BIT);
+ vm_page_prot = vma_pgprot_modify(vm_page_prot, vma_flags);
}
/* remove_protection_ptes reads vma->vm_page_prot without mmap_lock */
WRITE_ONCE(vma->vm_page_prot, vm_page_prot);
@@ -102,15 +102,16 @@ void vma_set_page_prot(struct vm_area_struct *vma)
*/
static int check_brk_limits(unsigned long addr, unsigned long len)
{
+ const struct mm_struct *mm = current->mm;
+ const bool is_def_locked =
+ vma_flags_test(&mm->def_vma_flags, VMA_LOCKED_BIT);
unsigned long mapped_addr;
mapped_addr = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED);
if (IS_ERR_VALUE(mapped_addr))
return mapped_addr;
- return mlock_future_ok(current->mm,
- current->mm->def_flags & VM_LOCKED, len)
- ? 0 : -EAGAIN;
+ return mlock_future_ok(mm, is_def_locked, len) ? 0 : -EAGAIN;
}
SYSCALL_DEFINE1(brk, unsigned long, brk)
@@ -197,7 +198,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
goto out;
mm->brk = brk;
- if (mm->def_flags & VM_LOCKED)
+ if (vma_flags_test(&mm->def_vma_flags, VMA_LOCKED_BIT))
populate = true;
success:
@@ -280,7 +281,7 @@ static inline bool file_mmap_ok(struct file *file, struct inode *inode,
* do_mmap() - Perform a userland memory mapping into the current process
* address space of length @len with protection bits @prot, mmap flags @flags
* (from which VMA flags will be inferred), and any additional VMA flags to
- * apply @vm_flags. If this is a file-backed mapping then the file is specified
+ * apply @vma_flags. If this is a file-backed mapping then the file is specified
* in @file and page offset into the file via @pgoff.
*
* This function does not perform security checks on the file and assumes, if
@@ -320,7 +321,8 @@ static inline bool file_mmap_ok(struct file *file, struct inode *inode,
* (2) for details.
* @flags: Flags specifying how the mapping should be performed, see mmap (2)
* for details.
- * @vm_flags: VMA flags which should be set by default, or 0 otherwise.
+ * @vma_flags: VMA flags which should be set by default, or EMPTY_VMA_FLAGS
+ * otherwise.
* @pgoff: Page offset into the @file if file-backed, should be 0 otherwise.
* @populate: A pointer to a value which will be set to 0 if no population of
* the range is required, or the number of bytes to populate if it is. Must be
@@ -335,7 +337,7 @@ static inline bool file_mmap_ok(struct file *file, struct inode *inode,
*/
unsigned long do_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
- unsigned long flags, vm_flags_t vm_flags,
+ unsigned long flags, vma_flags_t vma_flags,
unsigned long pgoff, unsigned long *populate,
struct list_head *uf)
{
@@ -399,13 +401,18 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
* to. we assume access permissions have been handled by the open
* of the memory object, so we don't do any here.
*/
- vm_flags |= calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(file, flags) |
- mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+ vma_flags_set_mask(&vma_flags,
+ legacy_to_vma_flags(calc_vm_prot_bits(prot, pkey)));
+ vma_flags_set_mask(&vma_flags,
+ legacy_to_vma_flags(calc_vm_flag_bits(file, flags)));
+ vma_flags_set_mask(&vma_flags, mm->def_vma_flags);
+ vma_flags_set(&vma_flags, VMA_MAYREAD_BIT, VMA_MAYWRITE_BIT,
+ VMA_MAYEXEC_BIT);
/* Obtain the address to map to. we verify (or select) it and ensure
* that it represents a valid section of the address space.
*/
- addr = __get_unmapped_area(file, addr, len, pgoff, flags, vm_flags);
+ addr = __get_unmapped_area(file, addr, len, pgoff, flags, vma_flags);
if (IS_ERR_VALUE(addr))
return addr;
@@ -418,7 +425,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
if (!can_do_mlock())
return -EPERM;
- if (!mlock_future_ok(mm, vm_flags & VM_LOCKED, len))
+ if (!mlock_future_ok(mm, vma_flags_test(&vma_flags, VMA_LOCKED_BIT), len))
return -EAGAIN;
if (file) {
@@ -461,22 +468,23 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
if (IS_APPEND(inode) && (file->f_mode & FMODE_WRITE))
return -EACCES;
- vm_flags |= VM_SHARED | VM_MAYSHARE;
+ vma_flags_set(&vma_flags, VMA_SHARED_BIT, VMA_MAYSHARE_BIT);
if (!(file->f_mode & FMODE_WRITE))
- vm_flags &= ~(VM_MAYWRITE | VM_SHARED);
+ vma_flags_clear(&vma_flags, VMA_MAYWRITE_BIT,
+ VMA_SHARED_BIT);
fallthrough;
case MAP_PRIVATE:
if (!(file->f_mode & FMODE_READ))
return -EACCES;
if (path_noexec(&file->f_path)) {
- if (vm_flags & VM_EXEC)
+ if (vma_flags_test(&vma_flags, VMA_EXEC_BIT))
return -EPERM;
- vm_flags &= ~VM_MAYEXEC;
+ vma_flags_clear(&vma_flags, VMA_MAYEXEC_BIT);
}
if (!can_mmap_file(file))
return -ENODEV;
- if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
+ if (vma_flags_can_grow(&vma_flags))
return -EINVAL;
break;
@@ -488,23 +496,27 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
* Check to see if we are violating any seals and update VMA
* flags if necessary to avoid future seal violations.
*/
- err = memfd_check_seals_mmap(file, &vm_flags);
+ err = memfd_check_seals_mmap(file, &vma_flags);
if (err)
return (unsigned long)err;
} else {
switch (flags & MAP_TYPE) {
case MAP_SHARED:
- if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
+ if (vma_flags_can_grow(&vma_flags))
return -EINVAL;
/*
* Ignore pgoff.
*/
pgoff = 0;
- vm_flags |= VM_SHARED | VM_MAYSHARE;
+ vma_flags_set(&vma_flags, VMA_SHARED_BIT, VMA_MAYSHARE_BIT);
break;
- case MAP_DROPPABLE:
- if (VM_DROPPABLE == VM_NONE)
+ case MAP_DROPPABLE: {
+ vma_flags_t droppable = VMA_DROPPABLE;
+
+ if (vma_flags_empty(&droppable))
return -EOPNOTSUPP;
+ vma_flags_set_mask(&vma_flags, droppable);
+
/*
* A locked or stack area makes no sense to be droppable.
*
@@ -515,23 +527,24 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
*/
if (flags & (MAP_LOCKED | MAP_HUGETLB))
return -EINVAL;
- if (vm_flags & (VM_GROWSDOWN | VM_GROWSUP))
+ if (vma_flags_can_grow(&vma_flags))
return -EINVAL;
- vm_flags |= VM_DROPPABLE;
-
/*
* If the pages can be dropped, then it doesn't make
* sense to reserve them.
*/
- vm_flags |= VM_NORESERVE;
+ vma_flags_set(&vma_flags, VMA_NORESERVE_BIT);
/*
* Likewise, they're volatile enough that they
* shouldn't survive forks or coredumps.
*/
- vm_flags |= VM_WIPEONFORK | VM_DONTDUMP;
+ vma_flags_set(&vma_flags, VMA_WIPEONFORK_BIT,
+ VMA_DONTDUMP_BIT);
+
fallthrough;
+ }
case MAP_PRIVATE:
/*
* Set pgoff according to addr for anon_vma.
@@ -544,22 +557,22 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
}
/*
- * Set 'VM_NORESERVE' if we should not account for the
- * memory use of this mapping.
+ * Set VMA_NORESERVE_BIT if we should not account for the memory use
+ * of this mapping.
*/
if (flags & MAP_NORESERVE) {
/* We honor MAP_NORESERVE if allowed to overcommit */
if (sysctl_overcommit_memory != OVERCOMMIT_NEVER)
- vm_flags |= VM_NORESERVE;
+ vma_flags_set(&vma_flags, VMA_NORESERVE_BIT);
/* hugetlb applies strict overcommit unless MAP_NORESERVE */
if (file && is_file_hugepages(file))
- vm_flags |= VM_NORESERVE;
+ vma_flags_set(&vma_flags, VMA_NORESERVE_BIT);
}
- addr = mmap_region(file, addr, len, vm_flags, pgoff, uf);
+ addr = mmap_region(file, addr, len, vma_flags, pgoff, uf);
if (!IS_ERR_VALUE(addr) &&
- ((vm_flags & VM_LOCKED) ||
+ (vma_flags_test(&vma_flags, VMA_LOCKED_BIT) ||
(flags & (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE))
*populate = len;
return addr;
@@ -645,9 +658,9 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)
* Determine if the allocation needs to ensure that there is no
* existing mapping within it's guard gaps, for use as start_gap.
*/
-static inline unsigned long stack_guard_placement(vm_flags_t vm_flags)
+static inline unsigned long stack_guard_placement(vma_flags_t vma_flags)
{
- if (vm_flags & VM_SHADOW_STACK)
+ if (vma_flags_test_single_mask(&vma_flags, VMA_SHADOW_STACK))
return PAGE_SIZE;
return 0;
@@ -689,7 +702,7 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info)
unsigned long
generic_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff,
- unsigned long flags, vm_flags_t vm_flags)
+ unsigned long flags, vma_flags_t vma_flags)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma, *prev;
@@ -714,7 +727,7 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = mmap_end;
- info.start_gap = stack_guard_placement(vm_flags);
+ info.start_gap = stack_guard_placement(vma_flags);
if (filp && is_file_hugepages(filp))
info.align_mask = huge_page_mask_align(filp);
return vm_unmapped_area(&info);
@@ -727,7 +740,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long flags, vm_flags_t vm_flags)
{
return generic_get_unmapped_area(filp, addr, len, pgoff, flags,
- vm_flags);
+ legacy_to_vma_flags(vm_flags));
}
#endif
@@ -738,7 +751,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long
generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff,
- unsigned long flags, vm_flags_t vm_flags)
+ unsigned long flags, vma_flags_t vma_flags)
{
struct vm_area_struct *vma, *prev;
struct mm_struct *mm = current->mm;
@@ -766,7 +779,7 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = PAGE_SIZE;
info.high_limit = arch_get_mmap_base(addr, mm->mmap_base);
- info.start_gap = stack_guard_placement(vm_flags);
+ info.start_gap = stack_guard_placement(vma_flags);
if (filp && is_file_hugepages(filp))
info.align_mask = huge_page_mask_align(filp);
addr = vm_unmapped_area(&info);
@@ -795,23 +808,24 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
unsigned long flags, vm_flags_t vm_flags)
{
return generic_get_unmapped_area_topdown(filp, addr, len, pgoff, flags,
- vm_flags);
+ legacy_to_vma_flags(vm_flags));
}
#endif
-unsigned long mm_get_unmapped_area_vmflags(struct file *filp, unsigned long addr,
- unsigned long len, unsigned long pgoff,
- unsigned long flags, vm_flags_t vm_flags)
+unsigned long mm_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags,
+ vma_flags_t vma_flags)
{
if (mm_flags_test(MMF_TOPDOWN, current->mm))
return arch_get_unmapped_area_topdown(filp, addr, len, pgoff,
- flags, vm_flags);
- return arch_get_unmapped_area(filp, addr, len, pgoff, flags, vm_flags);
+ flags, vma_flags_to_legacy(vma_flags));
+ return arch_get_unmapped_area(filp, addr, len, pgoff, flags,
+ vma_flags_to_legacy(vma_flags));
}
unsigned long
__get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
- unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
+ unsigned long pgoff, unsigned long flags, vma_flags_t vma_flags)
{
unsigned long (*get_area)(struct file *, unsigned long,
unsigned long, unsigned long, unsigned long)
@@ -846,11 +860,11 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
&& !addr /* no hint */
&& IS_ALIGNED(len, PMD_SIZE)) {
/* Ensures that larger anonymous mappings are THP aligned. */
- addr = thp_get_unmapped_area_vmflags(file, addr, len,
- pgoff, flags, vm_flags);
+ addr = thp_get_unmapped_area_vmaflags(file, addr, len,
+ pgoff, flags, vma_flags);
} else {
- addr = mm_get_unmapped_area_vmflags(file, addr, len,
- pgoff, flags, vm_flags);
+ addr = mm_get_unmapped_area_vmaflags(file, addr, len,
+ pgoff, flags, vma_flags);
}
if (IS_ERR_VALUE(addr))
return addr;
@@ -868,7 +882,8 @@ unsigned long
mm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags)
{
- return mm_get_unmapped_area_vmflags(file, addr, len, pgoff, flags, 0);
+ return mm_get_unmapped_area_vmaflags(file, addr, len, pgoff, flags,
+ EMPTY_VMA_FLAGS);
}
EXPORT_SYMBOL(mm_get_unmapped_area);
@@ -970,7 +985,7 @@ struct vm_area_struct *find_extend_vma_locked(struct mm_struct *mm, unsigned lon
return NULL;
if (expand_stack_locked(prev, addr))
return NULL;
- if (prev->vm_flags & VM_LOCKED)
+ if (vma_test(prev, VMA_LOCKED_BIT))
populate_vma_page_range(prev, addr, prev->vm_end, NULL);
return prev;
}
@@ -994,7 +1009,7 @@ struct vm_area_struct *find_extend_vma_locked(struct mm_struct *mm, unsigned lon
start = vma->vm_start;
if (expand_stack_locked(vma, addr))
return NULL;
- if (vma->vm_flags & VM_LOCKED)
+ if (vma_test(vma, VMA_LOCKED_BIT))
populate_vma_page_range(vma, addr, start, NULL);
return vma;
}
@@ -1119,18 +1134,18 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
*/
vma = vma_lookup(mm, start);
- if (!vma || !(vma->vm_flags & VM_SHARED)) {
+ if (!vma || !vma_test(vma, VMA_SHARED_BIT)) {
mmap_read_unlock(mm);
return -EINVAL;
}
- prot |= vma->vm_flags & VM_READ ? PROT_READ : 0;
- prot |= vma->vm_flags & VM_WRITE ? PROT_WRITE : 0;
- prot |= vma->vm_flags & VM_EXEC ? PROT_EXEC : 0;
+ prot |= vma_test(vma, VMA_READ_BIT) ? PROT_READ : 0;
+ prot |= vma_test(vma, VMA_WRITE_BIT) ? PROT_WRITE : 0;
+ prot |= vma_test(vma, VMA_EXEC_BIT) ? PROT_EXEC : 0;
flags &= MAP_NONBLOCK;
flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE;
- if (vma->vm_flags & VM_LOCKED)
+ if (vma_test(vma, VMA_LOCKED_BIT))
flags |= MAP_LOCKED;
/* Save vm_flags used to calculate prot and flags, and recheck later. */
@@ -1191,7 +1206,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
}
ret = do_mmap(vma->vm_file, start, size,
- prot, flags, 0, pgoff, &populate, NULL);
+ prot, flags, EMPTY_VMA_FLAGS, pgoff, &populate, NULL);
out:
mmap_write_unlock(mm);
fput(file);
@@ -1233,7 +1248,7 @@ int vm_brk_flags(unsigned long addr, unsigned long request, bool is_exec)
vma = vma_prev(&vmi);
ret = do_brk_flags(&vmi, vma, addr, len, vma_flags);
- populate = ((mm->def_flags & VM_LOCKED) != 0);
+ populate = vma_flags_test(&mm->def_vma_flags, VMA_LOCKED_BIT);
mmap_write_unlock(mm);
userfaultfd_unmap_complete(mm, &uf);
if (populate && !ret)
@@ -1256,7 +1271,7 @@ unsigned long tear_down_vmas(struct mm_struct *mm, struct vma_iterator *vmi,
mmap_assert_write_locked(mm);
vma_iter_set(vmi, vma->vm_end);
do {
- if (vma->vm_flags & VM_ACCOUNT)
+ if (vma_test(vma, VMA_ACCOUNT_BIT))
nr_accounted += vma_pages(vma);
vma_mark_detached(vma);
remove_vma(vma);
@@ -1405,7 +1420,7 @@ static int special_mapping_split(struct vm_area_struct *vma, unsigned long addr)
{
/*
* Forbid splitting special mappings - kernel has expectations over
- * the number of pages in mapping. Together with VM_DONTEXPAND
+ * the number of pages in mapping. Together with VMA_DONTEXPAND_BIT
* the size of vma should stay the same over the special mapping's
* lifetime.
*/
@@ -1677,7 +1692,7 @@ bool mmap_read_lock_maybe_expand(struct mm_struct *mm,
return true;
}
- if (!(new_vma->vm_flags & VM_GROWSDOWN))
+ if (!vma_test(new_vma, VMA_GROWSDOWN_BIT))
return false;
mmap_write_lock(mm);
@@ -1727,7 +1742,7 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
retval = vma_start_write_killable(mpnt);
if (retval < 0)
goto loop_out;
- if (mpnt->vm_flags & VM_DONTCOPY) {
+ if (vma_test(mpnt, VMA_DONTCOPY_BIT)) {
retval = vma_iter_clear_gfp(&vmi, mpnt->vm_start,
mpnt->vm_end, GFP_KERNEL);
if (retval)
@@ -1737,7 +1752,7 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
continue;
}
charge = 0;
- if (mpnt->vm_flags & VM_ACCOUNT) {
+ if (vma_test(mpnt, VMA_ACCOUNT_BIT)) {
unsigned long len = vma_pages(mpnt);
if (security_vm_enough_memory_mm(oldmm, len)) /* sic */
@@ -1755,16 +1770,19 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
retval = dup_userfaultfd(tmp, &uf);
if (retval)
goto fail_nomem_anon_vma_fork;
- if (tmp->vm_flags & VM_WIPEONFORK) {
+
+ if (vma_test(tmp, VMA_WIPEONFORK_BIT)) {
/*
- * VM_WIPEONFORK gets a clean slate in the child.
+ * VMA_WIPEONFORK_BIT gets a clean slate in the child.
* Don't prepare anon_vma until fault since we don't
* copy page for current vma.
*/
tmp->anon_vma = NULL;
} else if (anon_vma_fork(tmp, mpnt))
goto fail_nomem_anon_vma_fork;
- vm_flags_clear(tmp, VM_LOCKED_MASK);
+
+ vma_start_write(tmp);
+ vma_clear_flags_mask(tmp, VMA_LOCKED_MASK);
/*
* Copy/update hugetlb private vma information.
*/
@@ -1797,7 +1815,7 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
i_mmap_unlock_write(mapping);
}
- if (!(tmp->vm_flags & VM_WIPEONFORK))
+ if (!vma_test(tmp, VMA_WIPEONFORK_BIT))
retval = copy_page_range(tmp, mpnt);
if (retval) {
diff --git a/mm/mprotect.c b/mm/mprotect.c
index dc27bbc1712fd5..2888ee638d872a 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -40,7 +40,7 @@
static bool maybe_change_pte_writable(struct vm_area_struct *vma, pte_t pte)
{
- if (WARN_ON_ONCE(!(vma->vm_flags & VM_WRITE)))
+ if (WARN_ON_ONCE(!vma_test(vma, VMA_WRITE_BIT)))
return false;
/* Don't touch entries that are not even readable. */
@@ -97,7 +97,7 @@ static bool can_change_shared_pte_writable(struct vm_area_struct *vma,
bool can_change_pte_writable(struct vm_area_struct *vma, unsigned long addr,
pte_t pte)
{
- if (!(vma->vm_flags & VM_SHARED))
+ if (!vma_test(vma, VMA_SHARED_BIT))
return can_change_private_pte_writable(vma, addr, pte);
return can_change_shared_pte_writable(vma, pte);
@@ -194,7 +194,7 @@ static __always_inline void set_write_prot_commit_flush_ptes(struct vm_area_stru
{
bool set_write;
- if (vma->vm_flags & VM_SHARED) {
+ if (vma_test(vma, VMA_SHARED_BIT)) {
set_write = can_change_shared_pte_writable(vma, ptent);
prot_commit_flush_ptes(vma, addr, ptep, oldpte, ptent, nr_ptes,
/* idx = */ 0, set_write, tlb);
@@ -846,8 +846,8 @@ mprotect_fixup(struct vma_iterator *vmi, struct mmu_gather *tlb,
vm_unacct_memory(nrpages);
/*
- * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
- * fault on access.
+ * Private VMA_LOCKED_BIT VMA becoming writable: trigger COW to avoid
+ * major fault on access.
*/
if (vma_flags_test(&new_vma_flags, VMA_WRITE_BIT) &&
vma_flags_test(&old_vma_flags, VMA_LOCKED_BIT) &&
@@ -921,7 +921,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
goto out;
start = vma->vm_start;
error = -EINVAL;
- if (!(vma->vm_flags & VM_GROWSDOWN))
+ if (!vma_test(vma, VMA_GROWSDOWN_BIT))
goto out;
} else {
if (vma->vm_start > start)
@@ -929,7 +929,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
if (unlikely(grows & PROT_GROWSUP)) {
end = vma->vm_end;
error = -EINVAL;
- if (!(vma->vm_flags & VM_GROWSUP))
+ if (!vma_test_single_mask(vma, VMA_GROWSUP))
goto out;
}
}
@@ -953,7 +953,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
}
/* Does the application expect PROT_READ to imply PROT_EXEC */
- if (rier && (vma->vm_flags & VM_MAYEXEC))
+ if (rier && vma_test(vma, VMA_MAYEXEC_BIT))
prot |= PROT_EXEC;
/*
diff --git a/mm/mremap.c b/mm/mremap.c
index 384ef4cc2195ba..b64aa1f6e07ede 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -68,7 +68,7 @@ struct vma_remap_struct {
bool populate_expand; /* mlock()'d expanded, must populate. */
enum mremap_type remap_type; /* expand, shrink, etc. */
bool mmap_locked; /* Is mm currently write-locked? */
- unsigned long charged; /* If VM_ACCOUNT, # pages to account. */
+ unsigned long charged; /* If VMA_ACCOUNT_BIT, # pgs to account */
bool vmi_needs_invalidate; /* Is the VMA iterator invalidated? */
};
@@ -963,7 +963,7 @@ static unsigned long vrm_set_new_addr(struct vma_remap_struct *vrm)
if (vrm->flags & MREMAP_FIXED)
map_flags |= MAP_FIXED;
- if (vma->vm_flags & VM_MAYSHARE)
+ if (vma_test(vma, VMA_MAYSHARE_BIT))
map_flags |= MAP_SHARED;
res = get_unmapped_area(vma->vm_file, new_addr, vrm->new_len, pgoff,
@@ -985,7 +985,7 @@ static bool vrm_calc_charge(struct vma_remap_struct *vrm)
{
unsigned long charged;
- if (!(vrm->vma->vm_flags & VM_ACCOUNT))
+ if (!vma_test(vrm->vma, VMA_ACCOUNT_BIT))
return true;
/*
@@ -1012,7 +1012,7 @@ static bool vrm_calc_charge(struct vma_remap_struct *vrm)
*/
static void vrm_uncharge(struct vma_remap_struct *vrm)
{
- if (!(vrm->vma->vm_flags & VM_ACCOUNT))
+ if (!vma_test(vrm->vma, VMA_ACCOUNT_BIT))
return;
vm_unacct_memory(vrm->charged);
@@ -1032,7 +1032,7 @@ static void vrm_stat_account(struct vma_remap_struct *vrm,
struct vm_area_struct *vma = vrm->vma;
vm_stat_account(mm, vma->vm_flags, pages);
- if (vma->vm_flags & VM_LOCKED)
+ if (vma_test(vma, VMA_LOCKED_BIT))
mm->locked_vm += pages;
}
@@ -1176,7 +1176,7 @@ static void unmap_source_vma(struct vma_remap_struct *vrm)
* arose, in which case we _do_ wish to unmap the _new_ VMA, which means
* we actually _do_ want it be unaccounted.
*/
- bool accountable_move = (vma->vm_flags & VM_ACCOUNT) &&
+ bool accountable_move = vma_test(vma, VMA_ACCOUNT_BIT) &&
!(vrm->flags & MREMAP_DONTUNMAP);
/*
@@ -1195,7 +1195,7 @@ static void unmap_source_vma(struct vma_remap_struct *vrm)
* portions of the original VMA that remain.
*/
if (accountable_move) {
- vm_flags_clear(vma, VM_ACCOUNT);
+ vma_clear_flags(vma, VMA_ACCOUNT_BIT);
/* We are about to split vma, so store the start/end. */
vm_start = vma->vm_start;
vm_end = vma->vm_end;
@@ -1220,8 +1220,8 @@ static void unmap_source_vma(struct vma_remap_struct *vrm)
* | |
* |-------------|
*
- * Having cleared VM_ACCOUNT from the whole VMA, after we unmap above
- * we'll end up with:
+ * Having cleared VMA_ACCOUNT_BIT from the whole VMA, after we unmap
+ * above we'll end up with:
*
* addr end
* | |
@@ -1241,13 +1241,15 @@ static void unmap_source_vma(struct vma_remap_struct *vrm)
if (vm_start < addr) {
struct vm_area_struct *prev = vma_prev(&vmi);
- vm_flags_set(prev, VM_ACCOUNT); /* Acquires VMA lock. */
+ vma_start_write(prev);
+ vma_set_flags(prev, VMA_ACCOUNT_BIT);
}
if (vm_end > end) {
struct vm_area_struct *next = vma_next(&vmi);
- vm_flags_set(next, VM_ACCOUNT); /* Acquires VMA lock. */
+ vma_start_write(next);
+ vma_set_flags(next, VMA_ACCOUNT_BIT);
}
}
}
@@ -1330,8 +1332,8 @@ static void dontunmap_complete(struct vma_remap_struct *vrm,
unsigned long old_start = vrm->vma->vm_start;
unsigned long old_end = vrm->vma->vm_end;
- /* We always clear VM_LOCKED[ONFAULT] on the old VMA. */
- vm_flags_clear(vrm->vma, VM_LOCKED_MASK);
+ /* We always clear VMA_LOCKED[ONFAULT]_BIT on the old VMA. */
+ vma_clear_flags_mask(vrm->vma, VMA_LOCKED_MASK);
/*
* anon_vma links of the old vma is no longer needed after its page
@@ -1767,14 +1769,14 @@ static int check_prep_vma(struct vma_remap_struct *vrm)
* based on the original. There are no known use cases for this
* behavior. As a result, fail such attempts.
*/
- if (!old_len && !(vma->vm_flags & (VM_SHARED | VM_MAYSHARE))) {
+ if (!old_len && !vma_test_any(vma, VMA_SHARED_BIT, VMA_MAYSHARE_BIT)) {
pr_warn_once("%s (%d): attempted to duplicate a private mapping with mremap. This is not supported.\n",
current->comm, current->pid);
return -EINVAL;
}
if ((vrm->flags & MREMAP_DONTUNMAP) &&
- (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)))
+ vma_test_any(vma, VMA_DONTEXPAND_BIT, VMA_PFNMAP_BIT))
return -EINVAL;
/*
@@ -1804,7 +1806,7 @@ static int check_prep_vma(struct vma_remap_struct *vrm)
return 0;
/* We are expanding and the VMA is mlock()'d so we need to populate. */
- if (vma->vm_flags & VM_LOCKED)
+ if (vma_test(vma, VMA_LOCKED_BIT))
vrm->populate_expand = true;
/* Need to be careful about a growing mapping */
@@ -1812,10 +1814,10 @@ static int check_prep_vma(struct vma_remap_struct *vrm)
if (pgoff + (new_len >> PAGE_SHIFT) < pgoff)
return -EINVAL;
- if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP))
+ if (vma_test_any(vma, VMA_DONTEXPAND_BIT, VMA_PFNMAP_BIT))
return -EFAULT;
- if (!mlock_future_ok(mm, vma->vm_flags & VM_LOCKED, vrm->delta))
+ if (!mlock_future_ok(mm, vma_test(vma, VMA_LOCKED_BIT), vrm->delta))
return -EAGAIN;
if (!may_expand_vm(mm, &vma->flags, vrm->delta >> PAGE_SHIFT))
diff --git a/mm/nommu.c b/mm/nommu.c
index adc0b0ca906bdf..498e01ee40b056 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1014,11 +1014,12 @@ unsigned long do_mmap(struct file *file,
unsigned long len,
unsigned long prot,
unsigned long flags,
- vm_flags_t vm_flags,
+ vma_flags_t vma_flags,
unsigned long pgoff,
unsigned long *populate,
struct list_head *uf)
{
+ vm_flags_t vm_flags = vma_flags_to_legacy(vma_flags);
struct vm_area_struct *vma;
struct vm_region *region;
struct rb_node *rb;
diff --git a/mm/util.c b/mm/util.c
index 5090457542ca9c..bf0513d1d3d086 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -578,8 +578,8 @@ unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr,
if (!ret) {
if (mmap_write_lock_killable(mm))
return -EINTR;
- ret = do_mmap(file, addr, len, prot, flag, 0, pgoff, &populate,
- &uf);
+ ret = do_mmap(file, addr, len, prot, flag, EMPTY_VMA_FLAGS, pgoff,
+ &populate, &uf);
mmap_write_unlock(mm);
userfaultfd_unmap_complete(mm, &uf);
if (populate)
@@ -627,20 +627,20 @@ EXPORT_SYMBOL(vm_mmap);
unsigned long vm_mmap_shadow_stack(unsigned long addr, unsigned long len,
unsigned long flags)
{
+ vma_flags_t vma_flags = VMA_SHADOW_STACK;
struct mm_struct *mm = current->mm;
unsigned long ret, unused;
- vm_flags_t vm_flags = VM_SHADOW_STACK;
flags |= MAP_ANONYMOUS | MAP_PRIVATE;
if (addr)
flags |= MAP_FIXED_NOREPLACE;
if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
- vm_flags |= VM_NOHUGEPAGE;
+ vma_flags_set(&vma_flags, VMA_NOHUGEPAGE_BIT);
mmap_write_lock(mm);
ret = do_mmap(NULL, addr, len, PROT_READ | PROT_WRITE, flags,
- vm_flags, 0, &unused, NULL);
+ vma_flags, 0, &unused, NULL);
mmap_write_unlock(mm);
return ret;
diff --git a/mm/vma.c b/mm/vma.c
index 9d556d33b24bd1..b5bc3eec961c79 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -56,7 +56,7 @@ struct mmap_state {
.pglen = PHYS_PFN(len_), \
.vma_flags = vma_flags_, \
.file = file_, \
- .page_prot = vma_get_page_prot(vma_flags_), \
+ .page_prot = vma_flags_to_page_prot(vma_flags_), \
}
#define VMG_MMAP_STATE(name, map_, vma_) \
@@ -2176,7 +2176,7 @@ bool vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot)
/* The open routine did something to the protections that pgprot_modify
* won't preserve? */
if (pgprot_val(vm_page_prot) !=
- pgprot_val(vm_pgprot_modify(vm_page_prot, vma->vm_flags)))
+ pgprot_val(vma_pgprot_modify(vm_page_prot, vma->flags)))
return false;
/*
@@ -2883,7 +2883,7 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr,
* file to be mapped, otherwise NULL.
* @addr: The page-aligned address at which to perform the mapping.
* @len: The page-aligned, non-zero, length of the mapping.
- * @vm_flags: The VMA flags which should be applied to the mapping.
+ * @vma_flags: The VMA flags which should be applied to the mapping.
* @pgoff: If @file is specified, the page offset into the file, if not then
* the virtual page offset in memory of the anonymous mapping.
* @uf: Optionally, a pointer to a list head used for tracking userfaultfd unmap
@@ -2893,12 +2893,11 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr,
* been performed.
*/
unsigned long mmap_region(struct file *file, unsigned long addr,
- unsigned long len, vm_flags_t vm_flags,
+ unsigned long len, vma_flags_t vma_flags,
unsigned long pgoff, struct list_head *uf)
{
unsigned long ret;
bool writable_file_mapping = false;
- const vma_flags_t vma_flags = legacy_to_vma_flags(vm_flags);
mmap_assert_write_locked(current->mm);
@@ -2907,7 +2906,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
return -EACCES;
/* Allow architectures to sanity-check the vm_flags. */
- if (!arch_validate_flags(vm_flags))
+ if (!arch_validate_flags(vma_flags_to_legacy(vma_flags)))
return -EINVAL;
/* Map writable and ensure this isn't a sealed memfd. */
@@ -3420,18 +3419,21 @@ struct vm_area_struct *__install_special_mapping(
vm_flags_t vm_flags, void *priv,
const struct vm_operations_struct *ops)
{
- int ret;
+ vma_flags_t vma_flags = legacy_to_vma_flags(vm_flags);
struct vm_area_struct *vma;
+ int ret;
vma = vm_area_alloc(mm);
- if (unlikely(vma == NULL))
+ if (unlikely(!vma))
return ERR_PTR(-ENOMEM);
- vm_flags |= mm->def_flags | VM_DONTEXPAND;
+ vma_flags_set_mask(&vma_flags, mm->def_vma_flags);
+ vma_flags_set(&vma_flags, VMA_DONTEXPAND_BIT);
if (pgtable_supports_soft_dirty())
- vm_flags |= VM_SOFTDIRTY;
- vm_flags_init(vma, vm_flags & ~VM_LOCKED_MASK);
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma_flags_set(&vma_flags, VMA_SOFTDIRTY_BIT);
+ vma_flags_clear_mask(&vma_flags, VMA_LOCKED_MASK);
+ vma->flags = vma_flags;
+ vma->vm_page_prot = vma_get_page_prot(vma);
vma->vm_ops = ops;
vma->vm_private_data = priv;
diff --git a/mm/vma.h b/mm/vma.h
index adb7a0ba119208..0bc7d521e97677 100644
--- a/mm/vma.h
+++ b/mm/vma.h
@@ -517,7 +517,7 @@ int mm_take_all_locks(struct mm_struct *mm);
void mm_drop_all_locks(struct mm_struct *mm);
unsigned long mmap_region(struct file *file, unsigned long addr,
- unsigned long len, vm_flags_t vm_flags, unsigned long pgoff,
+ unsigned long len, vma_flags_t vma_flags, unsigned long pgoff,
struct list_head *uf);
int do_brk_flags(struct vma_iterator *vmi, struct vm_area_struct *brkvma,
@@ -541,9 +541,11 @@ static inline bool vma_wants_manual_pte_write_upgrade(struct vm_area_struct *vma
}
#ifdef CONFIG_MMU
-static inline pgprot_t vm_pgprot_modify(pgprot_t oldprot, vm_flags_t vm_flags)
+static inline pgprot_t vma_pgprot_modify(pgprot_t oldprot, vma_flags_t vma_flags)
{
- return pgprot_modify(oldprot, vm_get_page_prot(vm_flags));
+ const pgprot_t prot = vma_flags_to_page_prot(vma_flags);
+
+ return pgprot_modify(oldprot, prot);
}
#endif
diff --git a/mm/vma_exec.c b/mm/vma_exec.c
index ef1fa2b161f3ba..7af1260689b97e 100644
--- a/mm/vma_exec.c
+++ b/mm/vma_exec.c
@@ -112,15 +112,17 @@ int relocate_vma_down(struct vm_area_struct *vma, unsigned long shift)
int create_init_stack_vma(struct mm_struct *mm, struct vm_area_struct **vmap,
unsigned long *top_mem_p)
{
- unsigned long flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
+ vma_flags_t flags = VMA_STACK_INCOMPLETE_SETUP;
+ struct vm_area_struct *vma;
int err;
- struct vm_area_struct *vma = vm_area_alloc(mm);
+ /* VMA_STACK_FLAGS and VMA_STACK_INCOMPLETE_SETUP must not overlap. */
+ VM_WARN_ON_ONCE(vma_flags_test_any_mask(&flags, VMA_STACK_FLAGS));
+
+ vma = vm_area_alloc(mm);
if (!vma)
return -ENOMEM;
- vma_set_anonymous(vma);
-
if (mmap_write_lock_killable(mm)) {
err = -EINTR;
goto err_free;
@@ -134,19 +136,21 @@ int create_init_stack_vma(struct mm_struct *mm, struct vm_area_struct **vmap,
if (err)
goto err_ksm;
+ vma_flags_set_mask(&flags, VMA_STACK_FLAGS);
+ vma_set_anonymous(vma);
+
/*
* Place the stack at the largest stack address the architecture
* supports. Later, we'll move this to an appropriate place. We don't
* use STACK_TOP because that can depend on attributes which aren't
* configured yet.
*/
- VM_WARN_ON_ONCE(VM_STACK_FLAGS & VM_STACK_INCOMPLETE_SETUP);
vma->vm_end = STACK_TOP_MAX;
vma->vm_start = vma->vm_end - PAGE_SIZE;
if (pgtable_supports_soft_dirty())
- flags |= VM_SOFTDIRTY;
- vm_flags_init(vma, flags);
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma_flags_set(&flags, VMA_SOFTDIRTY_BIT);
+ vma->flags = flags;
+ vma->vm_page_prot = vma_get_page_prot(vma);
err = insert_vm_struct(mm, vma);
if (err)
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 9320671dfcc8b0..5bc7e586b430f5 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -851,7 +851,7 @@ static void snd_dma_noncoherent_free(struct snd_dma_buffer *dmab)
static int snd_dma_noncoherent_mmap(struct snd_dma_buffer *dmab,
struct vm_area_struct *area)
{
- area->vm_page_prot = vm_get_page_prot(area->vm_flags);
+ area->vm_page_prot = vma_get_page_prot(area);
return dma_mmap_pages(dmab->dev.dev, area,
area->vm_end - area->vm_start,
virt_to_page(dmab->area));
diff --git a/tools/testing/vma/include/dup.h b/tools/testing/vma/include/dup.h
index 773e23303e26af..64f38a83613e54 100644
--- a/tools/testing/vma/include/dup.h
+++ b/tools/testing/vma/include/dup.h
@@ -245,8 +245,10 @@ enum {
#define VM_STACK INIT_VM_FLAG(STACK)
#ifdef CONFIG_STACK_GROWSUP
#define VM_STACK_EARLY INIT_VM_FLAG(STACK_EARLY)
+#define VMA_STACK_EARLY mk_vma_flags(VMA_STACK_EARLY_BIT)
#else
#define VM_STACK_EARLY VM_NONE
+#define VMA_STACK_EARLY EMPTY_VMA_FLAGS
#endif
#ifdef CONFIG_ARCH_HAS_PKEYS
#define VM_PKEY_SHIFT ((__force int)VMA_HIGH_ARCH_0_BIT)
@@ -315,6 +317,8 @@ enum {
/* Bits set in the VMA until the stack is in its final location */
#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
+#define VMA_STACK_INCOMPLETE_SETUP append_vma_flags( \
+ VMA_STACK_EARLY, VMA_RAND_READ_BIT, VMA_SEQ_READ_BIT)
#define TASK_EXEC_BIT ((current->personality & READ_IMPLIES_EXEC) ? \
VM_EXEC_BIT : VM_READ_BIT)
@@ -1424,20 +1428,18 @@ struct vm_area_struct *vma_iter_next_range(struct vma_iterator *vmi)
}
bool vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot);
+static inline pgprot_t vma_pgprot_modify(pgprot_t oldprot, vma_flags_t vma_flags);
/* Update vma->vm_page_prot to reflect vma->vm_flags. */
static inline void vma_set_page_prot(struct vm_area_struct *vma)
{
- vm_flags_t vm_flags = vma->vm_flags;
+ vma_flags_t vma_flags = vma->flags;
pgprot_t vm_page_prot;
- /* testing: we inline vm_pgprot_modify() to avoid clash with vma.h. */
- vm_page_prot = pgprot_modify(vma->vm_page_prot, vm_get_page_prot(vm_flags));
-
+ vm_page_prot = vma_pgprot_modify(vma->vm_page_prot, vma_flags);
if (vma_wants_writenotify(vma, vm_page_prot)) {
- vm_flags &= ~VM_SHARED;
- /* testing: we inline vm_pgprot_modify() to avoid clash with vma.h. */
- vm_page_prot = pgprot_modify(vm_page_prot, vm_get_page_prot(vm_flags));
+ vma_flags_clear(&vma_flags, VMA_SHARED_BIT);
+ vm_page_prot = vma_pgprot_modify(vm_page_prot, vma_flags);
}
/* remove_protection_ptes reads vma->vm_page_prot without mmap_lock */
WRITE_ONCE(vma->vm_page_prot, vm_page_prot);
@@ -1547,7 +1549,7 @@ static inline int get_sysctl_max_map_count(void)
#define pgtable_supports_soft_dirty() IS_ENABLED(CONFIG_MEM_SOFT_DIRTY)
#endif
-static inline pgprot_t vma_get_page_prot(vma_flags_t vma_flags)
+static inline pgprot_t vma_flags_to_page_prot(vma_flags_t vma_flags)
{
const vm_flags_t vm_flags = vma_flags_to_legacy(vma_flags);
@@ -1575,3 +1577,8 @@ static inline void vma_assert_can_modify(struct vm_area_struct *vma)
if (vma_is_attached(vma))
vma_assert_write_locked(vma);
}
+
+static inline pgprot_t vma_get_page_prot(const struct vm_area_struct *vma)
+{
+ return vma_flags_to_page_prot(vma->flags);
+}
|
| 3/2 | 2026/07/12 10:14 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 34774 output: 237 thoughts: 1794 Thoughts: **Fuzzing Plan: vma_flags_t Transition**
Okay, so we have a substantial patch here, fundamentally altering how VMA flags are managed within the kernel. The key shift is from the standard `vm_flags_t` to a new `vma_flags_t` type, which, based on the presence of helper functions like `vma_flags_test` and related structs/unions, seems to be a more complex data structure than a simple `unsigned long`. This change touches a vast number of files, essentially replacing `vma->vm_flags` with `vma->flags` across the board and introducing several new helper functions for flag manipulation. Crucially, this patch modifies core memory management functionality across the board, which makes it a very high-value target for fuzzing.
My primary focus here will be on pinpointing the specific functions most impacted by the refactoring, paying particular attention to those related to `do_mmap`, `mmap_region`, `mlock`, `mprotect`, and `mremap`. I need to ensure the fuzzing targets are representative and that I don't overlook critical paths. Since it's a hot-path function list, I'll pay attention to instructions from the tool author. The prompt wants me to avoid hot path functions.
I need to confirm the changes within specific files and functions:
* **`mm/mmap.c`**: We need to examine `mmap_region`.
* **`mm/mprotect.c`**: Investigate `mprotect_fixup` and `do_mprotect_pkey`.
* **`mm/mremap.c`**: Look at `vrm_calc_charge`, `unmap_source_vma`, `check_prep_vma`.
* **`mm/mlock.c`**: Check `mlock_fixup`, `apply_vma_lock_flags`, `apply_mlockall_flags`.
* **`mm/vma.c`**: Verify the modifications in `mmap_region`.
* **`mm/vma_exec.c`**: Confirm the changes in `create_init_stack_vma`.
* **`mm/huge_memory.c`**: Check `thp_get_unmapped_area_vmaflags`.
* **`mm/memfd.c`**: Check `memfd_check_seals_mmap`.
Given that `do_mmap` and `mmap_region` are hot paths, I need to focus on less generic entrypoints. Functions like `mlock_fixup`, `apply_vma_lock_flags`, `apply_mlockall_flags`, `unmap_source_vma`, `check_prep_vma`, `create_init_stack_vma`, and `memfd_check_seals_mmap` should be less frequent and can still be fuzzed effectively. I will also include `do_mprotect_pkey` since the entry point was modified.
There don't seem to be any specific configurations needed since this is a core MM change. `CONFIG_TRANSPARENT_HUGEPAGE` for `thp_get_unmapped_area_vmaflags` and `CONFIG_MEMFD_CREATE` for `memfd_check_seals_mmap` are related but likely to already be enabled by default.
Thus, my proposed `set-results` call will have:
* `WorthFuzzing: true`
* `FocusSymbols`:
* `mlock_fixup`
* `apply_vma_lock_flags`
* `apply_mlockall_flags`
* `unmap_source_vma`
* `check_prep_vma`
* `memfd_check_seals_mmap`
* `create_init_stack_vma`
* `thp_get_unmapped_area_vmaflags`
* `do_mprotect_pkey`
* `EnableConfigs`: `[]`
I have also verified that most of the listed functions are static, but Syzkaller can still fuzz static functions if they are in the symbol table (which they are).
|
| 4/2 | 2026/07/12 10:14 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [
"mlock_fixup",
"apply_vma_lock_flags",
"apply_mlockall_flags",
"unmap_source_vma",
"check_prep_vma",
"memfd_check_seals_mmap",
"create_init_stack_vma",
"thp_get_unmapped_area_vmaflags"
],
"Reasoning": "The patch introduces a major refactoring of VMA flags handling in the core memory management subsystem, transitioning from `vm_flags_t` to `vma_flags_t`. It modifies critical paths in mmap, mremap, mlock, and mprotect. These changes functionally alter how VMA flags are set, cleared, and tested, which could introduce bugs like incorrect memory protections, accounting errors, or locking issues. Fuzzing should focus on the modified functions that handle these flags, avoiding the absolute hottest paths like `do_mmap` to prevent skewed distributions.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": null,
"FocusSymbols": [
"mlock_fixup",
"apply_vma_lock_flags",
"apply_mlockall_flags",
"unmap_source_vma",
"check_prep_vma",
"memfd_check_seals_mmap",
"create_init_stack_vma",
"thp_get_unmapped_area_vmaflags"
],
"Reasoning": "The patch introduces a major refactoring of VMA flags handling in the core memory management subsystem, transitioning from `vm_flags_t` to `vma_flags_t`. It modifies critical paths in mmap, mremap, mlock, and mprotect. These changes functionally alter how VMA flags are set, cleared, and tested, which could introduce bugs like incorrect memory protections, accounting errors, or locking issues. Fuzzing should focus on the modified functions that handle these flags, avoiding the absolute hottest paths like `do_mmap` to prevent skewed distributions.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|