Fra*_*c M 1 kernel memory-management linux-kernel page-fault
读完Mel Gorman这本书后我有几个问题Understanding the Linux Virtual Memory Manager。节4.3 Process Address Space Descriptor说kernel threads never page fault or access the user space portion. The only exception is page faulting within the vmalloc space。以下是我的问题。
kenrel 线程从不出现页面错误:这是否意味着只有用户空间代码才会触发页面错误?如果调用kmalloc()or vmalloc(),不会出现页错误吗?我相信内核必须将这些映射到匿名页面。当执行对此页的写入时,会发生页错误。我的理解正确吗?
为什么内核线程不能访问用户空间?不这样做copy_to_user()或者copy_from_user()这样做吗?
Exception is page faulting within vmalloc space:这是否意味着vmalloc()会触发页面错误,但kmalloc()不会?为什么kmalloc()不出现页面错误?内核虚拟地址的物理帧不需要保留为页表条目?
内核线程从不发生页面错误:所讨论的页面错误是在驻留虚拟页面或将其从交换区带回时发生的。内核页面不仅在 kmalloc() 上调入,而且在其生命周期内保持驻留。对于用户空间页面来说,情况并非如此,A)可能是延迟分配的(即,仅保留为 malloc() 上的页表条目,但在 memset() 或其他取消引用之前实际上不会出现错误)并且 B) 可能会被交换内存不足的情况下。
为什么内核线程不能访问用户空间?copy_to_user() 或 copy_from_user() 不是这样做的吗?
这是一个很好的问题,并有特定于硬件的答案。过去的情况是,内核线程不鼓励访问用户空间,正是因为如果访问用户空间中的未分页/分页内存,可能会发生页面错误(回想一下,这不会发生在内核空间中,如上所述确保)。因此 copy_to/from 将是正常的 memcpy,但包含在页面错误处理程序中。这样,任何潜在的页面错误都将被透明地处理(即内存将被分页)并且一切都会很好。但在某些情况下,memcpy 传入/传出用户内存的错误方法确实会起作用——更糟糕的是,它会更频繁地起作用,因为页面错误与 RAM 驻留和可用性密切相关——因此未处理的错误会导致随机恐慌。因此,始终使用 copy_from/to_user 的法令。
然而,最近从安全角度来看,内核/用户内存隔离变得很重要。这是由于许多利用技术(空指针解除引用是一种非常常见且强大的技术),其中可以在用户空间(因此易于控制)内存中构造虚假内核对象(或代码),并可能导致代码在核心。
因此,大多数体系结构都有一个页表位,它在物理上防止属于用户模式的页面被内核访问。以ARM64为例,该功能称为PAN/PXN(Privileged Access/Execute Never)。
因此,copy_from/to now不仅处理页面错误,而且还在操作之前禁用PAN/PXN,并在操作之后恢复它。