x86-64 页表全局位

标签 x86 x86-64 page-tables

此设置中的每个 PTE(页表条目)都有一个 G 位(G = Global),
它控制由此条目映射的物理页面的范围。

如果设置了 G 位,则该条目对所有进程都是全局的,并且它们可以
所有访问它映射的物理页面,受其他访问权限的约束。
如果 G 位为零,则该条目不是全局的,而是进程私有(private)的。
[内核为其页面设置 G 位,但阻止用户模式访问
通过在其页面上禁用 U 位(U = 用户模式)。]

如果在用户模式 ​​PTE 上设置了 G 位 - 设置了 U 位的那个 - 是不是
安全漏洞,因为系统上的每个进程现在都可以访问该页面
PTE map ?

我错过了什么吗?有没有办法在用户模式 ​​PTE 上设置 G 位
但使其仅在一组受信任的进程中而不是所有进程中全局化
系统上的进程 ?我们可以在 PTE 中同时设置 G 和 U 位吗?

最佳答案

是的,在 x86 上,G 位仅在有其他类型的控制(例如将其限制为 Ring 0,这是内核使用的)或在未 protected 操作系统上时才有用。

将 G 位视为系统调用的优化:内核将其页面映射为全局页面,因此不需要发生 TLB 刷新。您仍然需要在进程之间的上下文切换时刷新 TLB,但这些通常比内核<->用户模式切换少几个数量级。

您可以想象一个场景,其中 G 页对用户进程有用,例如共享内存:在两个进程之间切换不需要使共享内存的 TLB 条目无效 如果 意识到这一点并使用了 G==1两个进程的映射。尽管现在 TLB 重新填充实际上并没有那么糟糕,因为现代 x86 甚至在 TLB 之外缓存了很多表条目以允许快速重新填充。

我不认为设置 G 和 U 位是不允许的,但内核实际上不会那样设置。

最后一点,您实际上可以想象一个只读全局映射是有用的,例如 vdso机制。所有进程都会映射那个页面,但不能修改它,内核会根据需要更新它。当然,我看不到如何实际进行这项工作,因为内核需要写访问权限,并且似乎没有一种方法可以在页表。也许内核可以为此页面使用另一个映射,但我不确定这是否合法:具有覆盖“G”映射的映射(因为如果 G 映射在 TLB 中,CPU 可能永远不会看到覆盖映射)。

1 从技术上讲,它在所有用户模式进程都具有相同权限的单用户操作系统上可能很有用,但内核仍然受到用户模式的保护,但 AFAIK 该模型在当代操作系统中并不真正存在。

关于x86-64 页表全局位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41986862/

相关文章:

assembly - x86 程序集 : movsd instruction issue

assembly - 这两个汇编代码段有什么区别?

c - 将低字节从 int 复制到 char : Simpler to just do a byte load? 的指令

assembly - GAS aarch64 语法获取 .ascii 字符串长度

x86 - x86_64 架构中多页大小的 TLB 使用情况

assembly - 从GP规则加载xmm

您可以将非 ascii 字符传递给 argv 吗?

Linux 内核页表的 copy_to_user 失败

kernel - x86-64 架构中的分页

C 虚拟地址到物理地址的映射