我正在尝试编写一个函数,对给定pte
中的每个vm_area_struct
进行写保护。为给定地址提供ptep
的函数是什么?我有:
pte_t *ptep;
for (addr = start; addr < end; addr += PAGE_SIZE) {
ptep = WHATS_THIS_FUNCTION_CALLED(addr);
ptep_set_wrprotect(mm, addr, ptep);
}
WHATS_THIS_FUNCTION_CALLED
叫什么?
答案 0 :(得分:1)
您的问题的简短回答是使用__get_locked_pte
。但是,我建议反对它,因为有更好的(在资源争用方面有效和公平)方法来实现你的目标。
在linux中,遍历页表的典型习惯是嵌套for循环四层深(四是linux支持的页表级数)。有关示例,请参阅copy_page_range
和apply_to_page_range
in mm/memory.c。实际上,如果仔细查看copy_page_range
,就会在kernel / fork.c中从dup_mmap
分叉时调用它。它基本上在整个vm_area_struct
上运行。
您可以复制其中任何一个函数中使用的习语。但是,有一些警告。例如,copy_page_range
通过在copy_huge_pmd
内使用完全独立的copy_pmd_range
来完全支持透明大页(2.6.38)。除非您想要编写两个单独的函数(一个用于普通页面,一个用于透明大页面,请参阅Gracefull fallback
中的Documentation/vm/transhuge.txt
。
关键是linux中的虚拟内存非常复杂,所以一定要完全理解每个可能的用例。 mm/memory.c中的follow_page
应该证明如何涵盖所有基础。
答案 1 :(得分:0)
我相信您正在寻找定义here的函数virt_to_pte
或您自己重新实现它。
此函数使用pte_offset_kernel(pmd_t * dir, unsigned long address)
,它采用pmd(页面中级目录)结构和地址,但也可以使用pte_offset(pmd_t * dir, unsigned long address)
。
有关详细信息,请参阅Linux Device Drivers 3rd Edition Chapter 15或Linux Device Drivers, 2nd Edition Chapter 13 mmap and DMA。