Linux内核页表更新

2024-05-11

在linux x86 中分页。

  1. 每个进程都有它自己的页面目录。

  2. 页表遍历从 CR3 指向的页目录开始。

  3. 每个进程共享内核页目录内容

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

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

如何管理?


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

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

某些内核内存对于所有进程来说都是不可见的,并且是每个进程私有的(不会改变它仍然是ring 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 分配基地址;如果它对所有进程都可见,它将很快占用虚拟内存,因为每组页面都必须按顺序分配。它不需要对所有进程都可见,因为一个进程对另一个进程的页表条目不感兴趣。页面错误始终在当前进程的上下文中进行处理,并且 0xC0000000–0xC0200000 在每个进程上下文中表示不同的内容。

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

然而,不可能将用户 PDE 和内核 PDE 部分分开,使得前者是私有的,后者是全局的(即使 0xC0300000–0xC0300800 私有(指向不同的物理地址)和 0xC0300000–0xC0300FFF 指向相同的物理地址)每个进程),因为整个 PDE 区域 (0xC0300000–0xC0300FFF) 将位于同一物理帧上,并构成由cr3,以及cr3对于每个进程来说都是不同的,这意味着整个 PDE 区域(所有 PDE)必须为每个进程私有(每个进程复制和安装)。如果内核页表页面(包含内核页表的页面)被调出并调入新的物理位置,则所有 PDE 都必须同步,因为所有进程在不同的 cr3 物理地址处都有副本,而不是相同的物理 PDE 。我不确定它是如何(有效)ATM 的,因此明智的做法是施加限制,不允许内核页表被调出并将它们放在非分页池中;这样内核 PDE 将在所有 CR3 页面上保持不变。在 64 位上,可能会施加限制,即内核 PDPT 无法调出。在 32 位 Windows 上,进程以物理 CR3 页面启动,其 PDE 位于偏移量 1100000000(base 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 位)附加到其自身的条目,附加到您要查找其服务 PTE 虚拟地址的虚拟地址的开头(这就是添加 0xC0000000在前面的 32 位方程中)并删除最后 12 位,然后将虚拟地址末尾的 PT 中的偏移量乘以 8(或 4),将其弥补为 12 位(因此右移 12左移 3 位(对于 32 位条目左移 2 位)。 1 个环回消除了 1 层间接,您将获得 PTE 的虚拟地址。 2 个环回将为您留下用于转换该特定虚拟地址等的 PDE 的虚拟地址。 32 位窗口上的 PTE_BASE 是左移 110000000 的偏移量,以形成 32 位,PDE_BASE 是左移 32 位的偏移量 110000000110000000。它用在宏中,并且根据定义,具有此前缀的任何虚拟地址将分别成为 PTE 或 PDE 的一部分。 Windows 为页表层次结构选择偏移量 1100000000,但它可以是 2^9 组合中的任何一种。

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

至于windows上的物理内存,请看这里:https://superuser.com/a/1549970/933117 https://superuser.com/a/1549970/933117

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux内核页表更新 的相关文章

随机推荐

  • 从内存流播放视频文件

    只是好奇看看这是否可能 我有一个 Windows 应用程序 它从我的电脑上的 avi 文件读取所有字节 然后将其存储在 byte 中 现在我的内存中有 avi 文件 我想直接从内存将其加载到某种视频播放器控件中 我尝试过使用 wmplaye
  • Javascript 警报/消息框中的欧元符号或其他实体

    有谁知道我如何在 javascript 警报窗口中显示欧元或其他 html 实体 alert u20AC HTML 实体字符查找 http leftlogic com lounge articles entity lookup
  • 从delphi应用程序调用.net4.0 com服务器后出现错误异常

    我们正在将代码库从 BDS2006 迁移到 Rad Studio XE 我们发现了一些非常奇怪的行为 如果我们在从 Net4 0 中实现的 COM 服务器创建一些对象后进行无效的浮点运算 即除以零 我们不会没有得到正常异常 即 EDivis
  • 为什么像 BindingList 或 ObservableCollection 这样的类不是线程安全的?

    我一次又一次发现自己必须编写 BindingList 和 ObservableCollection 的线程安全版本 因为当绑定到 UI 时 这些控件无法从多个线程更改 我想理解的是why情况就是这样 这是设计错误还是故意的 问题是设计一个线
  • IE11 元元素破坏 SVG

    我已将 SVG 文件数据直接嵌入到我的 html 中 它在 Chrome 和 Firefox 中显示 但在 IE11 中根本不显示 SVG 的 Pastebin 链接是http pastebin com eZpLXFfD http past
  • Webpack中watch编译时加速scss的方法

    太长了 滚动到底部寻找答案 或者将 Webpack 和 Dart Sass VM 结合起来 https github com sass dart sass releases https github com sass dart sass r
  • 在 .NET Core 中从 HttpResponseMessage 转换为 IActionResult

    我正在将之前在 NET Framework 中编写的一些代码移植到 NET Core 我有这样的事情 HttpResponseMessage result await client SendAync request if result St
  • Spark:出现心跳错误后丢失数据

    我有一个在 Spark 集群上运行的 Python 程序 有四个工作线程 它处理一个包含大约 1500 万条记录的巨大 Oracle 表 检查结果后发现大约有600万条记录没有插入 我的写入功能如下 df write format jdbc
  • 如何在 PyTorch 中对子集使用不同的数据增强

    如何针对不同的情况使用不同的数据增强 转换 Subset在 PyTorch 中吗 例如 train test torch utils data random split dataset 80000 2000 train and test将具
  • 如何在打开导航抽屉时使背景 Activity 变小?

    我想做我的背景Activity打开时稍微小一点Navigation Drawer 模拟存在的效果Airbnb应用 我想最好的解释是截图 但重点不是让 View 变小 而是让它成为与 Drawer 打开 关闭动画同步的动画 因此 如果您开始打
  • 是否可以从 JBoss 容器中部署的所有 .war 文件中读取属性文件

    我已成功将 war 部署到 Jboss Web 容器 其中包含并读取位于 META INF groupid dir artifactid dir 下的 pom properties 为了访问该文件 我在同一 war 中的 JSP 中使用了以
  • 将 try catch finally 块放入另一个 finally 块中

    try catch finally try catch finally 上面的代码好不好 是的 你可以这样做 实际上 在处理想要正确关闭的流时 您甚至需要这样做 InputStream in try catch finally try in
  • QSpinBox 输入 NaN 作为有效值

    我正在尝试扩展 QSpinBox 以能够输入 NaN 或 nan 作为有效值 根据文档 我应该使用 textFromValue valueFromText 和 validate 函数来完成此操作 但我无法让它工作 因为它仍然不允许我输入除数
  • JVM内存段分配

    好吧 我有一个关于 JVM 内存段的问题 我知道每个 JVM 都会选择稍微不同地实现这一点 但这是一个总体概念 在所有 JVM 中应该保持相同 一个在运行时不使用虚拟机执行的标准C C 程序在运行时有四个内存段 代码 堆栈 堆 数据 所有这
  • 从react-loadable中命名webpack块

    我已经成功在我的项目中添加了react loadable库以启用代码分割 我发现的唯一问题是webpack生成的块没有命名 它们被赋予了整数名称 我的反应可加载使用代码是 const AppRootLoadable Loadable loa
  • 使用 React Hook Form 和 Yup 进行文件输入验证

    我尝试使用 React Hook Form 进行文件输入验证 是的 我写了下面的代码 但是当我测试文件的大小时 它在这里显示console log value 0 size 即使我在文件输入中选择了一个文件 该值也是未定义的 这有什么问题吗
  • 如何在Android JUnit测试用例中调用Button.performClick?

    我是 Android 测试方面的新手 我想测试单击按钮是否会打开相应的活动 我做了一些研究 发现我需要使用 ActivityManager 来进行检查 问题是 我无法让 点击 部分正常工作 我正在尝试使用Button performClic
  • 需要用户使用 NTLM 重新进行身份验证

    我是 NTLM web config 中的authenication windows 有一个 asp net mvc 2 0 站点 现在 一旦用户登录 他们就会一次保持登录状态数周 该应用程序的使用正在向共享使用登录服务帐户的计算机的用户开
  • 如何使用 CUDA/Thrust 对两个数组/向量根据其中一个数组中的值进行排序

    这是一个关于编程的概念问题 总而言之 我有两个数组 向量 我需要对一个数组 向量进行排序 并将更改传播到另一个数组 向量中 这样 如果我对 arrayOne 进行排序 则对于排序中的每个交换 arrayTwo 也会发生同样的情况 现在 我知
  • Linux内核页表更新

    在linux x86 中分页 每个进程都有它自己的页面目录 页表遍历从 CR3 指向的页目录开始 每个进程共享内核页目录内容 假设三个句子是正确的 假设某个进程进入内核 模式并更新他的内核页目录内容 地址映射 访问 权利等 问题 由于内核地