内存管理-5-vm_area_struct->vm_flags


一、vma->flags 简介

vma->vm_flags 标志,控制的是一个 VMA 在内核里的行为属性。里面的每个标志都是位掩码。可以把它理解成:同样都是一段虚拟地址区间,不同 flag 决定了这段区间能不能扩展、是否参与 core dump、是否是 I/O 映射、fork 时怎么继承、缺页时怎么处理。


1. 当前权限位: READ/WRITE/EXEC/SHARED

(1) VM_NONE

全0,就是没有任何标志,表示"空的 vm_flags"。无任何权限。

实际意义:不可读、不可写、不可执行、不共享。在现实中单独存在很少见,通常只在初始化或作为判断边界值时出现。一个真实的 VMA 几乎不会只有 VM_NONE,因为没有权限就没实际用途。


(2) VM_READ

这段 VMA 当前允许读访问。当前可读。

对应 mmap(PROT_READ) 或 mprotect(PROT_READ)。处理缺页时,如果访问类型是"读",内核会检查 VM_READ。页表项会按此标志配置是否有读权限(视架构而定).


(3) VM_WRITE

这段 VMA 当前允许写访问。当前可写。

对应 PROT_WRITE。内核在 page fault 处理时,写 fault 会检查此位,如果置位但没有写权限页表项(典型 COW 场景),会触发 COW, 如果不置位但写入,触发 SIGSEGV。


(4) VM_EXEC

这段 VMA 当前允许执行。当前可执行。

对应 PROT_EXEC。代码段、动态库代码映射通常有此标志,支持 NX(No-Execute)的架构会据此设置页表项的执行保护位,没有此 flag 的区域在 NX 架构上执行会 SIGSEGV。


(5) VM_SHARED

这段 VMA 是共享映射。共享映射(写入对外可见)。

对应 mmap(MAP_SHARED),写入会直接反映到底层文件(文件映射)或被多个进程看到(匿名共享)。没有此 flag 的就是私有映射(MAP_PRIVATE),写时会触发 COW,不影响原文件或其他进程。

以文件映射为例:
MAP_SHARED: 写入 VMA --> 直接修改 page cache --> 可 writeback 到磁盘 --> 其他 mmap 此文件的进程可见。
MAP_PRIVATE: 写入 VMA --> 触发 COW --> 只改进程自己的私有副本 --> 其他进程不可见,文件不变。


2. 允许上限位(MAY位): MAYREAD/MAYWRITE/MAYEXEC/MAYSHARE

MAY 位存在的原因: mprotect() 可以动态修改 VM_READ/WRITE/EXEC,但不能无限制修改。MAY 位就是这段 VMA 权限的上限或合法范围,约束 mprotect 能把权限改到哪里。举例:

/*
 * 最初以 PROT_READ|PROT_WRITE 建立。
 * 内核会设置:VM_READ | VM_WRITE 和 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC (一般私有映射都允许 EXEC 上限)
 */
mmap(..., PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)

/* 之后可以: */
mprotect(..., PROT_NONE)   //变为 VM_NONE,但MAY位还在(VM_被清0,但是VM_MAY还在)
mprotect(..., PROT_READ)   //再改回 VM_READ,合法,因为 VM_MAYREAD 存在

/* 如果 VM_MAYEXEC 不在,则以下操作会被拒绝: */
mprotect(..., PROT_EXEC)   // 返回 EACCES

两层关系对比总结:

---------------------------------------------------------------------
当前权限 (现在能不能做)      上限权限 (以后允不允许改)
---------------------------------------------------------------------
VM_READ   (当前可读)    ←→   VM_MAYREAD  (允许 mprotect 改为可读)
VM_WRITE  (当前可写)    ←→   VM_MAYWRITE (允许 mprotect 改为可写)
VM_EXEC   (当前可执行)  ←→   VM_MAYEXEC  (允许 mprotect 改为可执行)
VM_SHARED (当前是共享)  ←→   VM_MAYSHARE (允许保持共享语义)
---------------------------------------------------------------------

对应关系是:VM_READ 被清掉,只要 VM_MAYREAD 在,随时可以 mprotect 恢复。但是 VM_MAYREAD 被清掉,则无论如何都不能再加回 VM_READ(内核会拒绝 mprotect).


(1) VM_MAYREAD

允许这段 VMA 在将来被设置为可读(VM_READ)。允许 mprotect 赋予可读。

mprotect(PROT_READ) 的合法性依赖此位,如果当前是 PROT_NONE 但 VM_MAYREAD 还在,说明可以恢复读权限。


(2) VM_MAYWRITE

允许这段 VMA 在将来被设置为可写(VM_WRITE)。允许 mprotect 赋予可写。

mprotect(PROT_WRITE) 的合法性依赖此位。对于某些特殊映射,内核故意不设置 VM_MAYWRITE,从而永久禁止被改为可写。例:/proc/self/exe 对应的文本段映射,永久只读,VM_MAYWRITE 不会被置。


(3) VM_MAYEXEC

允许这段 VMA 在将来被设置为可执行(VM_EXEC)。允许 mprotect 赋予可执行。

mprotect(PROT_EXEC) 的合法性依赖此位。PaX/W^X 类安全加固可能主动取消 VM_MAYEXEC,防止动态生成可执行代码。普通私有匿名映射默认有 VM_MAYEXEC,所以 JIT 可以 mmap + mprotect(EXEC)


(4) VM_MAYSHARE

允许这段 VMA 具备共享属性。允许保持共享语义。

比 VM_MAYREAD/WRITE/EXEC 稍微特殊,主要用于 MAP_SHARED 映射上,表示可以保持共享语义。也用于某些内核诊断和 /proc/PID/maps 的属性展示。具体限制路径不像前三个那么直接,更多是内核内部一致性检查。


3. 地址空间形态类:VM_GROWSDOWN、VM_DONTEXPAND

(1) VM_GROWSDOWN

含义:这是一段“向低地址方向增长”的 VMA。允许 VMA 向低地址扩栈。

典型场景:用户栈,尤其是主线程栈; 某些架构或线程库创建的栈区.

行为特征:当访问落在当前 vm_start 下方、但仍在允许的栈扩展范围内时,内核会尝试把这段 VMA 向下扩展,而不是直接判为非法访问。所以这类 VMA 的下边界不是绝对固定的

存在意义:栈天然是向下生长的,函数调用、局部变量压栈都会让 SP 向低地址移动。如果没有这个标志,每次栈向下越过当前边界都要重新建 VMA,不现实。

补充:它不是“无限扩展”,还受 RLIMIT_STACK、相邻 VMA 冲突、guard page 等约束。内核里常见配套逻辑是 expand_stack() 或相关扩展路径。


(2) VM_DONTEXPAND

含义:这段 VMA 不能被 mremap() 等机制扩展。不能扩展。

为什么需要:某些 VMA 的边界、页属性、底层映射关系很特殊, 扩展可能破坏其语义或安全性.

典型场景:特殊驱动映射; hugetlb 映射; 一些架构/设备专用 VMA.

直观理解:普通匿名映射可能可以放大。带这个 flag 的映射大小更“刚性”。

常见来源:内核在建立某些特殊映射时主动打上。


4. userfaultfd相关:VM_UFFD_MISSING、VM_UFFD_WP

(1) VM_UFFD_MISSING

含义:这段 VMA 开启了 userfaultfd 的“missing page fault tracking”。缺页交给 userfaultfd。

背景:userfaultfd 允许用户态程序接管某些页错误处理; “missing” 指的是页面根本不存在,访问时产生缺页异常

行为:当这段 VMA 上发生“缺失页” fault 时,内核不立即按普通匿名页/文件页逻辑补页; 而是把 fault 事件投递给注册了 userfaultfd 的用户态处理程序; 用户态可以决定是拷贝内容、zeropage 填充、延迟恢复,还是做 live migration 等高级操作

典型用途:虚拟机内存按需填充; 用户态分页; live migration; checkpoint/restore.

一句话:VM_UFFD_MISSING 表示“这段内存缺页时,交给 userfaultfd 用户态去处理”。


(2) VM_UFFD_WP

含义:这段 VMA 开启了 userfaultfd 的 write-protect 跟踪。写保护 fault 交给 userfaultfd。

与 VM_UFFD_MISSING 区别:VM_UFFD_MISSING 管“页不存在”; VM_UFFD_WP 管“页存在,但写访问被拦截”。

行为:页面可以已经在内存里,但当用户写这个页面时,触发 userfaultfd write-protect fault。用户态处理程序收到事件后决定如何解保护、同步、复制等。

典型用途:增量快照; dirty tracking; live migration 中的脏页追踪; 用户态实现类似软 dirty 的高级控制。

一句话:VM_UFFD_WP 表示“写这段内存时,不直接写,先通知 userfaultfd”。


5. 物理映射/设备映射类:VM_PFNMAP、VM_IO

VM_PFNMAP 强调按 PFN 建映射,没有标准 struct page 语义,VM_IO 强调这是 I/O/设备类映射,实际上二者经常一起出现,但不是完全同义。

(1) VM_PFNMAP

含义:这段 VMA 映射的是纯 PFN 范围,而不是普通由 struct page 管理的页。映射特殊 PFN,不是普通 page。

关键点:普通内存页通常能通过 PFN 找到对应 struct page; 但设备 BAR、某些保留内存、特殊物理区域,可能只有物理页号 PFN,没有标准 page 元数据语义。

典型场景:驱动通过 remap_pfn_range() 把设备内存映射到用户态; 显存、MMIO aperture、framebuffer 等映射。

影响:这类 VMA 通常不能参与普通页缓存、LRU、反向映射、匿名页回收等常规内存管理机制。get_user_pages()、migration、KSM、COW 等很多普通页逻辑会受限制或完全不适用。

直观理解:普通 VMA 映射的是“内核内存管理系统认识的页”,VM_PFNMAP 映射的是“只知道物理页号的特殊页范围”。


(2) VM_IO

含义:这段 VMA 是 I/O 内存映射,或具备类似 I/O 映射的特殊属性。设备/I/O 映射。

典型场景:mmap() 驱动设备; MMIO 寄存器空间; framebuffer; PCI BAR 映射.

影响:不适合普通匿名页/文件页管理; 常与 VM_PFNMAP、特殊 pgprot 一起出现; core dump、mlock、NUMA balancing、KSM、THP 等特性通常会规避这类映射.

一句话:VM_IO 强调“这是设备/特殊 I/O 映射,不是普通 RAM 语义”。


6. 文件写保护/执行文件语义:VM_DENYWRITE

(1) VM_DENYWRITE

含义:对这个映射对应的文件施加“拒绝写入”的语义。底层文件写入受限,防止执行中文件被改。

经典背景:可执行文件正在被执行或映射执行时,内核通常不允许别人去改写这个文件内容。否则会出现“正在执行的文本段被覆盖”的问题。

历史语义:和老 Unix 的 ETXTBSY 概念有关,即“text file busy”。试图写一个当前被执行映射占用的文件,可能得到 ETXTBSY

常见场景:可执行文件、解释器、动态装载相关映射。

注意:这是比较老且偏内部的语义标志,现代内核里它更多是与 deny_write_access() 一类机制配合。它不是“VMA 不可写”的意思,跟 VM_WRITE 不是一回事。

一句话:VM_DENYWRITE 主要是保护“底层文件不要在关键执行/映射期间被写坏”。


7. 访问模式提示类:VM_SEQ_READ、VM_RAND_READ

这两个都只是访问模式 hint,不是硬约束,主要影响预读策略。

(1) VM_SEQ_READ

含义:这段 VMA 的访问模式预计是顺序读。提示顺序访问。

本质:给内核的 readahead/预读/页缓存策略一个提示。

典型来源:madvise(..., MADV_SEQUENTIAL)

效果:内核更倾向进行顺序预读; 更积极地把后续页面读入; 已访问完的页也可能更积极回收,因为未来重复访问概率低.

适用:顺序扫描大文件; 流式处理.

注意:这只是“hint”,不是强制保证


(2) VM_RAND_READ

含义:这段 VMA 的访问模式预计是随机读,不适合聚簇预读。提示随机访问。

典型来源:madvise(..., MADV_RANDOM)

效果:内核减少或关闭 readahead, 避免因为误判顺序访问而读入大量无用页.

适用:索引查找; B-tree/数据库随机访问; 大文件跳跃读取.

与 VM_SEQ_READ 对应:一个鼓励预读, 一个抑制预读.


8. fork/mremap/dump/清零行为:VM_DONTCOPY、VM_WIPEONFORK、VM_DONTDUMP

VM_DONTCOPY 是 fork 不继承,VM_WIPEONFORK 是继承地址范围但不继承内容。

(1) VM_DONTCOPY

含义:fork 时不要把这个 VMA 复制到子进程。fork 不继承。

正常 fork 行为:大多数 VMA 会复制 VMA 元数据到子进程。页面则按 COW 共享或按各自语义处理。

这个标志的行为:子进程直接看不到这段 VMA,相当于这段地址空间不继承

典型场景:某些驱动/设备映射; 特殊 runtime 区域; 不希望子进程继承的用户态管理区。

常见来源:MADV_DONTFORK

和 VM_WIPEONFORK 的区别:VM_DONTCOPY 是子进程里根本没有这段 VMA,VM_WIPEONFORK 是子进程里有这段 VMA,但内容被清零。


(2) VM_WIPEONFORK

含义:fork 后,子进程保留这段 VMA,但其内容被清零。fork 后子进程内容清零。

典型来源:MADV_WIPEONFORK

行为:父进程原 VMA 不变, 子进程会得到同样地址范围的一段 VMA, 但页面内容不继承父进程数据,而是相当于 fresh zeroed memory。

适用:存储敏感信息,但又想保留地址布局。避免 secret 在 fork 后泄漏给子进程。

和 VM_DONTCOPY 区别再强调一次:VM_DONTCOPY 是子进程没有这段映射,VM_WIPEONFORK 是子进程有映射,但内容被抹掉。


(3) VM_DONTDUMP

含义:这段 VMA 不要写入 core dump。不进 core dump。

背景:进程崩溃时,core dump 会把地址空间某些内容写到转储文件, 但有些区域没必要或不应该被转储。

典型场景:大块无意义缓存; 设备映射; 敏感数据; 用户显式声明不想 dump 的区域.

常见来源:MADV_DONTDUMP

好处:减小 core 文件体积; 提高转储速度; 避免泄漏秘密数据。


9. 锁页/内存承诺/资源统计:VM_LOCKED、VM_LOCKONFAULT、VM_ACCOUNT、VM_NORESERVE

VM_LOCKED 是驻留锁定语义已经生效,VM_LOCKONFAULT 是等页 fault 进来再锁,偏延迟生效。VM_ACCOUNT 和 VM_NORESERVE
都与内存承诺/overcommit 有关,前者偏“记账”,后者偏“少预留、少保守”。

(1) VM_LOCKED

含义:这段 VMA 被锁定在内存中,页面不应该被换出。页常驻内存,不换出。

来源:mlock()、mlockall() 等系统调用。

行为:VMA 中已在内存中的页应尽量保持驻留。后续 fault 进来的页也会保持锁定语义。不进入正常 swap 回收路径。

目的:降低实时延迟,防止敏感数据被换出到磁盘,保证关键工作集常驻内存。

注意:锁的是“驻留性”,不是“页表项不变”。仍可能发生缺页,只是进来后要常驻。会受 RLIMIT_MEMLOCK 等限制。


(2) VM_LOCKONFAULT

含义:这段 VMA 不是立刻把所有页锁住,而是在页面 fault 进来时再锁定。fault 进来时再锁页。

背景:普通 VM_LOCKED 可能意味着立即把大量页驻留,代价较高。lock on fault 是一种延迟锁定策略。

典型来源:mlock2(..., MLOCK_ONFAULT)

行为:VMA 具有“将来 fault 到内存的页都锁住”的属性,但还没访问到的页不必现在就拉进来。

优点:避免一次性 fault-in 大量页;兼顾低延迟和较低初始开销。

一句话:VM_LOCKED 更像“现在就锁住”,VM_LOCKONFAULT 更像“以后谁 fault 进来就锁谁”。


(3) VM_ACCOUNT

含义:这段 VMA 需要参与内存 overcommit/accounting 统计。参与内存承诺统计。

背景:Linux 有 overcommit 策略,决定虚拟内存申请时要不要“记账”。某些映射在创建时就要计入 commit charge,表示系统承诺将来有资源满足它。

典型会被 account 的对象:某些私有可写匿名映射; 可能导致实际内存承诺增长的区域.

作用:帮助内核在分配阶段就评估“承诺内存”是否超限; 防止所有进程都过度申请,最终在运行时灾难性 OOM.

一句话:VM_ACCOUNT 表示“这段映射应算入系统内存承诺账本”。


(4) VM_NORESERVE

含义:这段映射不需要预留 swap / commit reserve,抑制常规记账或保留行为。不提前做保守预留。

典型来源:MAP_NORESERVE

行为:创建映射时不为未来可能写入的匿名页提前做严格资源预留,相当于告诉内核:“先别为我保守兜底,后面真用到再说”。

优点:降低创建大映射时的 commit 压力,允许更激进的 overcommit。

风险:运行时真正写入大量页面时,可能更晚才暴露资源不足,某些情况下更容易在后期触发 OOM。

和 VM_ACCOUNT 的关系:两者都和内存承诺有关,一个偏“要计账”,一个偏“别提前保守预留”。


10. 特殊页类型或故障语义:VM_HUGETLB、VM_SYNC

(1) VM_HUGETLB

含义:这段 VMA 使用 hugetlb 页,也就是预留型的大页机制。显式 huge page VMA。

不要和 THP 混淆:VM_HUGETLB 是显式 hugetlbfs / MAP_HUGETLB, THP 是透明大页,机制不同。

特点:页大小是固定 huge page,比如 2MB、1GB。来自 hugetlb pool。管理、fault、回收、页表层级都和普通页不同。

适用:数据库、HPC、需要稳定大页、不希望 THP 抖动的场景。

影响:不走普通匿名页的一些路径;扩展、拆分、swap、migration 等行为与普通页显著不同。

一句话:VM_HUGETLB 表示“这段 VMA 是显式 huge TLB page 映射”。


(2) VM_SYNC

含义:这段 VMA 需要同步语义的 page fault / 持久化故障处理。fault/持久化语义要求同步。

常见背景:DAX 持久内存映射; 对 fault 完成时数据一致性、落久化语义有更严格要求的场景。它不是“所有访问都同步 I/O”的简单意思,而是:page fault 处理不能过于异步/宽松, 需要满足特定同步和持久性要求.

典型关联:MAP_SYNC; 持久内存文件系统; DAX 直接映射.

一句话:VM_SYNC 更多是“这段映射的 fault 和数据可见性要满足同步一致性要求”。


11. 架构私有:VM_ARCH_1

(1) VM_ARCH_1

含义:架构私有标志位之一,语义由具体 CPU 架构定义。架构私有位。

这类标志的特点:在 x86、arm64、powerpc 等架构上用途可能不同; 主线 MM 公共代码通常只保留这个槽位,不赋予统一语义; 真正解释要看对应架构代码。所以它没有一个跨架构统一答案。你只能说:这是给架构专用扩展留的 vm_flags 位。如果你在某个特定内核版本、特定架构上看源码,要结合该架构的 arch/*/include/asm/... 和 fault/mmap 代码一起看。


二、标志位设置接口

1. mmap() 设置的 flag

这些 flag 在 VMA 创建时由 mmap() 的参数直接决定,写入 vm_flags 后一般长期持有。

----------------------------------------------------------------------
flag            触发的mmap参数            说明
----------------------------------------------------------------------
VM_READ         PROT_READ                 可读
VM_WRITE        PROT_WRITE                可写
VM_EXEC         PROT_EXEC                 可执行
VM_SHARED       MAP_SHARED                共享映射
VM_MAYREAD      PROT_READ (任何可读映射)  允许恢复可读
VM_MAYWRITE     PROT_WRITE                允许恢复可写
VM_MAYEXEC      一般私有匿名映射默认有    允许恢复可执行
VM_MAYSHARE     MAP_SHARED                允许保持共享语义
VM_GROWSDOWN    MAP_GROWSDOWN             显式申请向下扩展的栈VMA
VM_NORESERVE    MAP_NORESERVE             不预留 swap 资源 
VM_HUGETLB      MAP_HUGETLB               显式 huge page 映射
VM_SYNC         MAP_SYNC                  同步语义(DAX 场景)
VM_DENYWRITE    MAP_DENYWRITE(已废弃,现由内核exec路径设置)    见下文
----------------------------------------------------------------------

特别说明:
VM_MAYREAD/MAYWRITE/MAYEXEC 不是用户显式传的,而是内核在 do_mmap() 内部根据 PROT_* 和映射类型推导出来的。规则大致是:PROT_READ 同时设置 VM_MAYREAD; PROT_WRITE + MAP_PRIVATE 同时设置 VM_MAYWRITE、VM_MAYEXEC; MAP_SHARED 且底层文件只读时, 不会设置 VM_MAYWRITE.


2. mprotect() 修改的 flag

mprotect() 负责动态修改当前权限位,但受 MAY 位约束。

-----------------------------------------------------------------------------------------------
被修改的 flag    条件
-----------------------------------------------------------------------------------------------
VM_READ          需要 VM_MAYREAD 存在
VM_WRITE         需要 VM_MAYWRITE 存在
VM_EXEC          需要 VM_MAYEXEC 存在
mprotect()       不能修改 MAY 位本身,也不能修改 VM_SHARED、VM_HUGETLB 等描述映射类型的 flag。
-----------------------------------------------------------------------------------------------


3. madvise() 设置的 flag

madvise() 是用户给内核传"访问模式提示"或"行为控制"的接口,它设置的 flag 大多影响内核策略,但不影响权限检查。

-----------------------------------------------------------------------------------------
flag              madvise 参数                                含义
-----------------------------------------------------------------------------------------
VM_SEQ_READ       MADV_SEQUENTIAL                             顺序访问,激进预读
VM_RAND_READ      MADV_RANDOM                                 随机访问,抑制预读
VM_DONTCOPY       MADV_DONTFORK                               fork 不继承此 VMA
VM_WIPEONFORK     MADV_WIPEONFORK                             fork 后子进程内容清零
VM_DONTDUMP       MADV_DONTDUMP                               不写入 core dump
VM_LOCKONFAULT    MADV_FREE 相关,或 mlock2(MLOCK_ONFAULT)    fault 进来时再锁页
-----------------------------------------------------------------------------------------

清除方向也对称:

----------------------------------------------
清除操作              madvise 参数
----------------------------------------------
清除 VM_DONTCOPY      MADV_DOFORK
清除 VM_WIPEONFORK    MADV_KEEPONFORK
清除 VM_DONTDUMP      MADV_DODUMP
清除 VM_SEQ_READ      MADV_NORMAL
清除 VM_RAND_READ     MADV_NORMAL
----------------------------------------------


4. mlock()/mlock2() 设置的 flag

--------------------------------------------------------
flag              来源
--------------------------------------------------------
VM_LOCKED         mlock() 或 mlockall()
VM_LOCKONFAULT    mlock2(addr, len, MLOCK_ONFAULT)
--------------------------------------------------------

解锁时由 munlock() / munlockall() 清除。


5、内核 exec 路径(execve)设置的 flag

装载可执行文件时,内核的 load_elf_binary() 等函数会主动设置某些 flag。

----------------------------------------------------------------------------
flag                  谁设置                         原因
----------------------------------------------------------------------------
VM_DENYWRITE          exec 路径,文本段映射时设置    防止正在执行的文件被写
VM_EXEC               exec 路径,代码段              代码段可执行
VM_GROWSDOWN          exec 路径,主线程栈            栈需要向下扩展
VM_READ + VM_EXEC     exec 路径,代码段              代码段可读可执行
VM_READ + VM_WRITE    exec 路径,数据段/BSS          数据段可读写
----------------------------------------------------------------------------


6、驱动内部/remap_pfn_range()等内核路径设置的 flag

这类 flag 完全由内核或驱动代码在创建特殊映射时主动写入,用户无法直接触发。

--------------------------------------------------------------------------------------------------------
flag             设置路径                                              原因
--------------------------------------------------------------------------------------------------------
VM_IO            驱动调用 remap_pfn_range() 或 io_remap_pfn_range()    标识为设备/I/O 映射
VM_PFNMAP        同上,remap_pfn_range() 内部自动设置                  纯 PFN 映射,无 struct page 语义
VM_DONTEXPAND    驱动或内核建立特殊 VMA 时主动置位                     禁止 mremap 扩展
VM_ACCOUNT       内存统计路径(do_mmap 中按 overcommit 策略决定)        计入内存承诺账本
VM_ARCH_1        架构特定代码(arm/x86/mips 等各自实现)                 架构私有语义
--------------------------------------------------------------------------------------------------------


7. userfaultfd 注册路径设置的 flag

--------------------------------------------------------------------------------------------------------
flag               设置路径
--------------------------------------------------------------------------------------------------------
VM_UFFD_MISSING    ioctl(uffd, UFFDIO_REGISTER, ...) 时,注册模式包含 UFFDIO_REGISTER_MODE_MISSING
VM_UFFD_WP         同上,注册模式包含 UFFDIO_REGISTER_MODE_WP
--------------------------------------------------------------------------------------------------------


8. 规律总结

mmap: 负责建立 VMA 的基本形态(权限、共享/私有、大页、不预留等)。
mprotect: 只改当前权限位,不能突破 MAY 位上限。
madvise: 专门管"内核行为策略"(预读、fork 继承、dump 行为)。
mlock/mlock2: 专门管"驻留性"。
exec 路径: 自动按 ELF 段类型设置对应权限和特殊标志。
驱动/内核内部: 设置设备映射、统计、扩展控制类特殊标志。
userfaultfd: 是独立的注册接口,通过 ioctl 打标志。

 

posted on 2026-04-22 16:01  Hello-World3  阅读(4)  评论(0)    收藏  举报

导航