当CPU处于内核模式时,它可以读写任何寄存器吗,或者即使在内核模式下也存在一些不可访问的寄存器?
答案 0 :(得分:3)
在x86上,没有存储寄存器,因此所有寄存器在架构上都可以同时看到。
是的,在内核模式(0环)下,x86可以写入任何寄存器。 (只要内核以64位模式运行,否则它将无法访问x / ymm8..16或zmm8..31或r8..r15)。
是的,从64位用户空间进入内核后,可以切换到32位模式的内核。 Solaris x86-64显然是这样做的,MacOS X used to do this是为了与32位内核驱动程序兼容。在RAM小于4GB且缓存较小的计算机上,在内核中使用较小的指针有一些好处,并且缺点可能不那么大。
wrmsr
(写模型专用寄存器)需要内核模式。 rdmsr
也会读取MSR。因此,与用户空间可以自由使用的整数和向量regs(rax..rsi / r8..r15和xmm0..15)不同,存在 寄存器,只有内核可以修改。 / p>
可能有一些特定于模型的reg,仅在系统管理模式下可以访问。 (有时称为ring -1)我不知道,我对SMM的了解不多。和/或与SGX相关联的寄存器(用于“飞地”),我再次没有研究它。
可能还存在一些您永远无法使用wrmsr
编写的只读MSR。 IDK是您的意思,还是仅计算通常被视为已在上下文开关中保存/恢复的体系结构状态一部分的寄存器,例如通用整数寄存器。所有这些reg都可以在任何模式下写入,甚至是段reg。
内部段的基址/限制寄存器不能直接读取,但是在64位长模式下,除了FS和GS外,它们固定为base = 0 / limit = -1。但是可以通过rdmsr
/ wrmsr
上的MSR_GS_BASE
/ MSR_FS_BASE
访问这些库。
FSGSBASE ISA扩展添加了wrfsbase
等,与MSR相比,它确实使您可以更直接地读/写FS和GS基础。 (无论哪种方式,内核都不必实际修改GDT或LDT条目并重新加载fs
来更新fs
用于线程本地存储的基础)。 Detail about MSR_GS_BASE in linux x86 64
但是我不认为cs / ds / es / ss的基数/限制是通过MSR公开的,这些与32位保护模式有关。 (或者用于切换回实模式以创建“虚幻”模式。)