ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

pgtable pte_mkwrite

pgtable pte_mkwrite pte_mkwrite是 Linux 内核中用于将一个 PTE页表项标记为可写的架构相关函数。它位于 x86 架构的页表操作代码中是缺页异常处理和mprotect()等路径的核心辅助函数。核心作用根据 VMA 类型设置写权限这个函数接收一个 PTE 和一个vm_area_structVMA根据 VMA 的类型决定如何设置写权限pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) { if (vma-vm_flags VM_SHADOW_STACK) return pte_mkwrite_shstk(pte); pte pte_mkwrite_novma(pte); return pte_clear_saveddirty(pte); }代码逐行解析1. 影子栈特殊处理if (vma-vm_flags VM_SHADOW_STACK) return pte_mkwrite_shstk(pte);如果 VMA 标记为VM_SHADOW_STACK影子栈说明这是一个用于Intel CET控制流强制技术的影子栈区域。影子栈的写权限处理与普通内存不同需要调用专门的pte_mkwrite_shstk()来设置正确的权限位避免与 CET 的硬件保护机制冲突。2. 普通内存的可写设置pte pte_mkwrite_novma(pte);对于普通内存调用pte_mkwrite_novma()设置标准的可写位。这个函数是“无 VMA”版本因为此时已经确定不是影子栈了不需要再依赖 VMA 信息。3. 清除 saveddirty 标志return pte_clear_saveddirty(pte);pte_clear_saveddirty()清除 PTE 中的_PAGE_SAVED_DIRTY标志。这个标志是AMD 的硬件特性用于在页表项中“暂存”脏位信息。当 PTE 被重新标记为可写时需要清除这个暂存状态因为它可能会干扰后续的脏位追踪。演进背景从pte_mkwrite到pte_mkwrite_novma这个函数的重构源于 2023 年的一批补丁如mm: introduce pte_mkwrite{_shstk,}。在此之前pte_mkwrite()是一个不带参数的宏或函数。重构的目的是统一接口让所有架构的pte_mkwrite都接收vma参数为影子栈等 VMA 相关特性提供支持。区分场景引入pte_mkwrite_novma()用于不需要 VMA 信息的场景避免强制调用者传递 VMA。支持影子栈通过pte_mkwrite_shstk()为 CET 影子栈提供专门的权限设置路径。在缺页异常中的角色在do_wp_page()写时复制缺页处理中当内核决定允许写入时会调用pte_mkwrite()来更新 PTE。这个函数确保了影子栈页面获得正确的写权限不会破坏 CET 保护。普通页面获得标准的写权限并清除可能干扰的 saveddirty 标志。这个函数是 x86 页表权限管理中“写权限”这一维度的核心入口体现了内核对不同内存类型普通内存 vs. 影子栈的精细区分。
返回列表