assembly - 当CPU处于内核模式时,它可以读写任何寄存器吗?
问题描述
当CPU处于内核模式时,它可以读取和写入任何寄存器,还是有一些即使在内核模式下也无法访问的寄存器?
解决方案
在 x86 上,没有分组寄存器,因此所有寄存器在架构上同时可见。
是的,在内核模式(环 0)下,x86 可以写入任何寄存器。(只要内核运行在 64 位模式下,否则无法访问 x/ymm8..16 或 zmm8..31,或 r8..r15)。
是的,从 64 位用户空间进入内核后切换到 32 位模式的内核是可能的;Solaris x86-64 显然是这样做的,而MacOS X 曾经这样做是为了与 32 位内核驱动程序兼容。在内存小于 4GB 且缓存较小的机器上,在内核中使用较小的指针有一些好处,而缺点可能没有那么大。
wrmsr
(写入模型特定寄存器)需要内核模式。rdmsr
阅读 MSR也是如此。因此,与用户空间可以自由使用的整数和向量寄存器(rax..rsi/r8..r15 和 xmm0..15)不同,只有内核才能修改寄存器。
可能有一些特定于模型的 regs 只能在系统管理模式下访问。(有时称为环-1)我不知道,我对SMM的了解不多。和/或与 SGX 相关的寄存器(用于“飞地”),我也没有研究过。
可能还有一些只读 MSR,您永远无法使用wrmsr
. IDK 如果这就是您的意思,或者您只计算通常被认为是在上下文切换上保存/恢复的架构状态的一部分的寄存器,例如通用整数寄存器。所有这些 regs 都可以在任何模式下写入,甚至是段 regs。
内部段基址/限制寄存器不能直接读取,但在 64 位长模式下,它们固定为 base=0 / limit=-1,FS 和 GS 除外。但是这些基础可以通过rdmsr
/ wrmsr
on MSR_GS_BASE
/访问MSR_FS_BASE
。
添加的 FSGSBASE ISA 扩展wrfsbase
等确实让您可以更直接地读取/写入 FS 和 GS 基础,比 MSR 更有效。(无论哪种方式,内核都不必实际修改 GDT 或 LDT 条目并重新加载fs
以更新fs
线程本地存储的基础)。 linux x86 64 中 MSR_GS_BASE 的详细信息
但我不认为 cs/ds/es/ss 基础/限制是通过 MSR 公开的,这些与 32 位保护模式有关。(或切换回实模式以创建“虚幻”模式。)
推荐阅读
- android - 可以使用 Loops 增加作为 EditText id 一部分的数字以在 Kotlin 中创建更短的代码吗?
- reactjs - 缓慢的数据下载 - 在地图中获取
- entity-framework - Blazor Webassembly - System.AggregateException
- go - 如何将 FaunaDB 的 Time 类型数据映射到 go lang 变量?
- c++ - 具有动态变量的 C++ 模板函数
- lua - 基于另一个计数值,遍历嵌套表 - LUA
- javascript - 如何在变量中获取我发送 discord.js 的消息
- blockchain - Ubuntu 18.04 上的 Hyperledger Indy LibIndy 安装问题
- javascript - 如何使用提交按钮和输入按钮提交值?
- android - 如何为汽车安卓开发应用程序