gpt4 book ai didi

linux - linux内核页表更新

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:37:08 27 4
gpt4 key购买 nike

在Linux x86分页中。

  • 每个进程都有其自己的页面目录。
  • 页表遍历从CR3指向的页目录开始。
  • 每个进程共享内核页面目录内容

  • 假设三个句子是正确的,假设某个进程进入了内核
    模式并更新其内核页面目录内容(地址映射,访问
    权利等)。

    题。由于内核地址空间是进程之间全局共享的,
    此更新必须与其他进程的页面目录同步,
    对?

    如何管理?

    先感谢您。

    最佳答案

    我不了解Linux,因此我将针对Windows进行回答。某些内核空间是“全局”的,这是在PTE中设置的标志,指示多个进程使用了​​它。可以在寄存器操作数中配置INVPCID指令,以在TLB无效中包括或排除这些条目。这些页表条目在进程之间共享,并且所有条目都出现在每个进程的页表中的同一位置。这样,只需更新单个PTE,而无需同步其他进程的其他PTE,因为它们在物理地址上都共享一个PTE。

    http://www.cs.miami.edu/home/burt/journal/NT/memory.html

    有些内核内存对所有进程都不可见,并且对每个进程都是私有(private)的(不会改变它仍然是环0的事实)。在32位Windows系统上,它将是0xC0000000–0xC0200000,其中包含所有用户空间PTE和PDE,其中0xC0000000是PTE_BASE,这使得方程#define MiGetPteAddress (x) ((PMMPTE)(((((ULONG)(x)) >> 12) << 2) + (ULONG_PTR)MmPteBase)) #define MiAddressToPte(x) MiGetPteAddress(x)可以正常工作,以便将cr2中的故障虚拟地址转换为PTE的地址。这是每个进程专用的,因为每个进程具有相同的基本PTE分配基地址;如果对所有进程可见,则将 swift 占用虚拟内存,因为必须按顺序分配每组页面占用的内存。它不需要对所有进程都可见,因为一个进程对另一个进程的页表条目没有兴趣。页面错误总是在当前进程的上下文中处理,0xC0000000-0xC0200000表示在每个进程上下文中有所不同。

    但是,用于分配内核PTE(用于内核地址)的内核空间0xC0200000–0xC0400000将是全局的,并由所有进程共享,但其中表示0xC0000000–0xC0200000的部分除外,根据我的计算,该部分为0xC0300000–0xC0300800,即PDE的用户模式端为PDE_BASE = 0xC0300000–0xC0300FFF。

    但是,不可能将用户PDE和内核PDE部分分开,以使前者是私有(private)的,而后者是全局的(即,使0xC0300000-0xC0300800私有(private)(指向不同的物理地址),而0xC0300000-0xC0300FFF指向相同的物理地址)。每个进程),因为整个PDE区域(0xC0300000–0xC0300FFF)将位于同一物理帧上,并由cr3指向单个帧,并且每个进程的cr3不同,这意味着整个PDE区域(所有PDE)将必须为每个进程专用(每个进程重复并安装)。如果将内核页面表页面(包含内核页面表的页面)调出页面并移到新的物理位置,则所有PDE都必须同步,因为所有进程在不同的cr3物理地址而不是相同的物理PDE上都有副本。我不确定它是如何做到这一点的(有效的)ATM,因此施加限制是不允许将内核页表调出并放入非分页池中是明智的。这样,内核PDE在所有CR3页面上将保持不变。在64位上,可能会施加限制,即不能分页出内核PDPT。在32位Windows上,进程开始于物理CR3页面,该页面的PDE偏移量为1100000000(基数2)* 4字节,指向其自身,该页面被硬写入,可能是通过短暂关闭cr0中的分页来完成的(因为写入操作不会无需在其中编写递归条目就可以成功,这会产生一个悖论。注意,PD条目本身就是覆盖范围为0xC0000000–0xC0400000的页表,即它指向1023页表和1页目录(本身)(2 ^ 10个条目),因此允许通过其虚拟地址修改PTE。 。 CR3页面位于0xC0300000的原因是因为该地址具有相同的页面目录以及页面表索引1100000000和1100000000,因此它在自身上循环两次,因此产生了CR3页面,您可以按地址修改PDE(还有其他像这样的特殊地址,例如0xE0380000)。设置完成后,将进行适当的内核映射。在64位Windows上,使用单个指向其自身的PML4表页面设置进程的过程将与此类似,并且由于回送的数量可变,因此可以填充和访问任何PML4E,PDPTE,PDE或PTE。在64位Windows上,当某个进程终止时,该进程的所有物理页将移至空闲列表,该列表将包括所有用户物理PDPT页,PD页,PT页和PML4/CR3页。内核列表将不会被标记为空闲列表。

    通常,如果您知道PML4中的哪个条目是物理PML4页面的递归条目,则可以算出某个虚拟地址的PTE的虚拟地址。您将PML4中的偏移量(32位为10位; 64位为9位)附加到其自身的条目,虚拟地址的开头(这是前面32位方程式中0xC0000000的加法运算),并且删除最后12位,然后将虚拟地址末尾的PT中的偏移量乘以8(或4),从而将PT中的偏移量补偿为12位(因此,右移12,左移3(或2) (用于32位条目))。 1个环回占用了1个间接层,您将获得PTE的虚拟地址。 2次环回将为您保留PDE的虚拟地址,依此类推。在32位窗口上的PTE_BASE是偏移量110000000左移为32位,而PDE_BASE是偏移量110000000110000000左移为32位。它在宏中使用,带有此前缀的任何虚拟地址根据定义将分别是PTE或PDE的一部分。 Windows为页表层次结构选择偏移量1100000000,但它可以是2 ^ 9组合中的任何一种。

    KAISER或KPTI旨在缓解崩溃,每个过程很可能具有2个cr3。捕获到内核后,用于用户模式的受限cr3将包含一个包含所有内核PML4E的完整cr3,该受限cr3将包含单个内核PML4E(足以访问执行交换的初步中断调度例程功能)。

    至于Windows上的物理内存,请参见:https://superuser.com/a/1549970/933117

    关于linux - linux内核页表更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26583919/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com