Linux x86-64 上物理内存中的用户空间和内核之间是不是存在显式拆分?

Posted

技术标签:

【中文标题】Linux x86-64 上物理内存中的用户空间和内核之间是不是存在显式拆分?【英文标题】:Is there an explict split between userspace and kernel in physical memory on Linux x86-64?Linux x86-64 上物理内存中的用户空间和内核之间是否存在显式拆分? 【发布时间】:2015-08-08 21:44:52 【问题描述】:

也就是说,给定一个物理地址,我能判断这个地址是否来自用户空间吗?

据我所知,在虚拟地址空间中,内核会使用 上半部分,用户空间将使用下半部分。但是关于 在物理地址空间?

让问题变得复杂的是我想在 KVM 中检查来宾物理地址,这意味着我无法在来宾操作系统中调用某些内核函数。所以我想知道是否有明确的分割线?

【问题讨论】:

【参考方案1】:

没有。

几乎任何物理页框都可以映射到用户空间虚拟地址或内核虚拟地址,甚至两者同时映射。

【讨论】:

非常感谢!那么虚拟地址呢? 47位到63位的虚拟地址在内核空间为1,在用户空间为0? @tamlok:是的,除非你有一个使用vsyscall=native 的内核,在这种情况下,vsyscall 页面被映射到具有高虚拟地址的用户空间任务中。由于您是从管理程序中查看的,因此您也可以自己遍历页表并检查 PTE 中的用户/主管位,以了解您拥有哪种虚拟地址。 如何判断内核是否在使用vsyscall=native @tamlok:我认为唯一的方法是检查[vsyscall] 页面是否出现在来宾的/proc/<pid>/maps 中。您无法检查内核命令行,因为 native 是某些内核版本的默认值,而不是其他版本的默认值。 是的,内核正在使用vsyscall=native。我浏览了 KVM 中的访客页面表,发现了一些有趣且令人困惑的东西。一些PML4E/PDPTE/PDE/PTE 的物理地址映射到页表中,而一些没有映射。例如,cr3 的 val 是 0x1c0e000PML4E0x1fdd067PDE0x36913063。还有PTEs 0x8000000001c0e1630x8000000001fdd163 映射到虚拟地址0xffff81c0e0000xffff81fdd000 但没有PTE 用于PDE 0x36913063 中的地址。为什么?

以上是关于Linux x86-64 上物理内存中的用户空间和内核之间是不是存在显式拆分?的主要内容,如果未能解决你的问题,请参考以下文章

X86-64和ARM64用户栈的结构 ---进程用户栈的初始化

Linux操作系统 内存管理用户操作和文件操作

内存管理(上)

如何从 Linux 中的用户空间访问物理地址?

Linux内存描述之高端内存--Linux内存管理

嵌入式软件开发杂谈:Linux下内存与虚拟内存