如何修改PTE仅调整其中的PFN使其指向其他指定物理地址
修改PTE仅替换PFN保留权限位的实现方法
前置说明
你对mk_pte的认知是正确的:mk_pte是通过传入的页和权限参数生成全新PTE,默认不会保留原PTE的权限位,直接使用会覆盖原有标志位,不符合你的需求。
具体实现步骤
所有操作均使用内核跨架构兼容的标准宏实现,避免直接操作PTE位掩码带来的兼容性问题:
- 提取原PTE的权限配置
调用pte_pgprot()宏从现有PTE(PTE0)中提取所有权限、标志位,返回独立的pgprot_t结构,该过程不会包含原PFN信息:pgprot_t original_prot = pte_pgprot(pte0); - 获取目标物理地址对应的PFN
调用phys_to_pfn()将目标物理地址phys1转换为页帧号,注意需提前确认phys1为页对齐地址:unsigned long pfn1 = phys_to_pfn(phys1); - 生成新PTE并替换
调用pfn_pte()用目标PFN和原权限生成新的PTE值,直接替换原有PTE即可:pte_t new_pte = pfn_pte(pfn1, original_prot); set_pte(pte_ptr, new_pte); // pte_ptr为PTE0的地址指针
必须注意的边界事项
- 操作PTE前必须持有对应页表锁(用户地址空间需先持有
mmap_lock再拿页表锁,内核地址空间根据场景选择对应锁),避免并发修改导致页表损坏 - 修改PTE完成后必须调用TLB刷新接口,例如
flush_tlb_page(vma, addr),避免CPU TLB缓存的旧映射引发访问异常 - 需确保
phys1对应的物理页已持有有效引用(如分配页后未提前释放),防止物理页被回收后出现野指针访问 - 原PTE指向的
phys0对应的物理页如果不再使用,需及时释放引用避免内存泄漏
内容的提问来源于stack exchange,提问作者688仙友
相关产品推荐
相关产品推荐

