根据pgtable-2-level.h,ARM Linux有两个版本的PTE; Linux PTE和H / W PTE。 Linux PTE存储在1024字节的偏移量以下。
在handle_pte_fault
pte_file
,pte_mkdirty
,pte_mkyoung
等各种函数中处理页面错误时,请使用版本H / W PTE进行调用。
但实际上ARM H / W不支持其PTE中的脏,访问和文件位。
我的问题是它如何检查H / W PTE上页面的脏访问文件位?理想情况下,它应检查Linux PTE上存储在1024字节偏移量以下的那些位吗?
答案 0 :(得分:4)
我的问题是如何检查H / W PTE上页面的脏访问文件位?
TL; DR - 通过在初始访问时发生页面错误来模拟它们。
中给出仅通过授予硬件写入权限来模拟“脏”位 如果页面在Linux PTE中标记为“可写”和“脏”。这个 写入一个干净的页面会导致权限错误,并且 Linux MM层将通过handle_pte_fault()标记页面脏。 要使硬件注意到权限更改,TLB条目必须 刷新,ptep_set_access_flags()为我们做了。
要采用 dirty 大小写,页面的初始MMU映射标记为只读。当进程写入时,会生成页面错误。这是引用的handle_pte_fault
,主要代码位于fault.c as do_page_fault
,并会调用最终以handle_pte_fault
结尾的通用handle_mm_fault
。你可以看到代码,
if (flags & FAULT_FLAG_WRITE) {
if (!pte_write(entry))
return do_wp_page(mm, vma, address,
pte, pmd, ptl, entry);
entry = pte_mkdirty(entry); /** Here is the dirty emulation. **/
}
因此Linux通用代码将检查页面的权限,看它是可写的并调用pte_mkdirty
将页面标记为脏;整个过程通过故障处理程序启动或模拟。在Linux PTE中将页面标记为 dirty 后,ARM PTE被标记为可写,因此后续写入不会导致错误。
访问只有读取和写入都是相同的。 文件位也完全取消映射,当发生故障时,会查询Linux PTE以查看它是否由文件支持,或者是否是完全未映射的页面错误。
在使用新权限更新硬件表并完成簿记后,用户模式程序将在故障指令处重新启动,除了处理故障的时间间隔外,它不会发现差异。
ARM Linux使用4k页,ARM第二级页表大小为1k(256个条目* 4个字节)。来自 pgtable-2-level.h 评论,
因此,我们略微调整实现 - 我们告诉Linux我们在第一级有2048个条目,每个条目是8个字节(低,两个指向第二级的硬件指针。)第二级包含两个硬件PTE表连续排列,前面是Linux版本,其中包含Linux需要的状态信息。因此,我们最终在“PTE”级别中有512个条目。
为了使用完整的4K页面, PTE 条目的结构类似于
完整4k页面的四个1k项目。必须按流程管理这些页面集合,以便为每个页面提供唯一的内存视图,并共享一些信息以节省实际RAM。函数cpu_set_pte_ext
用于更改物理ARM条目。由于每个ARM CPU版本使用略有不同的表结构和功能,因此processor function table中有一个指向汇编程序例程的条目。例如,cpu_v7_set_pte_ext
是ARMv7或典型的原始Cortex CPU实现。该例程负责检查Linux标志并相应地更新硬件位。可以看出,r3
在此例程结束时写入pte+2048
(从Linux PTE偏移到硬件PTE)。许多较旧的CPU变体使用 proc-marcos.S 中的汇编程序宏armv3_set_pte_ext
。
请参阅:Tim's notes on ARM MM
Page table entry (PTE) descriptor in Linux kernel for ARM