Linux x86 64中关于MSR_GS_BASE的详细信息

7
我尝试了解Linux内核中MACRO电流的详细信息。 current的最终汇编代码如下:
movq %%gs:0xb000,%0

上面的代码可以正常工作!但当我打印%%gs时,它的值为0,所以%%gs指向GDT NULL的第一项!!?? 它是如何工作的?
mov %%gs, %0

相反,gs的基础在MSR_GS_BASE中,当前可被替换为:
/*0xb000 is the offset of per_cpu__current_task*/
cur_task = (unsigned long*)(x86_rdmsr64(MSR_GS_BASE) + 0xb000);
println("cur_task:%p",*cur_task);

我的问题是:

%gs指向GDT NULL的第一个项目!!??从MSR_GS_BASE读取它的工作原理是CPU的特性吗?我需要一些关于此的参考资料。

1个回答

12

来自AMD体系结构程序员手册卷2:系统编程,第4.5.3节:

64位模式下的FS和GS寄存器。与CS、DS、ES和SS不同,FS和GS段覆盖可以在64位模式下使用。当在64位模式下使用FS和GS段覆盖时,它们各自的基地址将用于有效地址(EA)计算。完整的EA计算变为(FS或GS)。base + base +(比例*索引)+位移。 FS.base和GS.base值也扩展到完整的64位虚拟地址大小,如图4-5所示。生成的EA计算允许跨越正地址和负地址。

[...]

更新FS.base和GS.base隐藏描述符字段的内容有两种方法。第一种方法仅对特权软件(CPL = 0)可用。 FS.base和GS.base隐藏描述符寄存器字段映射到MSR。特权软件可以使用单个WRMSR指令将64位基址以规范形式加载到FS.base或GS.base中。 FS.base MSR地址为C000_0100h,而GS.base MSR地址为C000_0101h。

第二种更新FS和GS基址字段的方法可供任何特权级别运行的软件使用(如果实现支持并通过设置CR4 [FSGSBASE]启用)。 WRFSBASE和WRGSBASE指令将GPR的内容复制到FS.base和GS.base字段中,分别。当操作数大小为32位时,基址的上双字被清除。 WRFSBASE和WRGSBASE仅在64位模式下支持。


链接已经失效。这个链接可能是正确的。 - Ruslan
这是直接访问该部分的链接:https://www.amd.com/system/files/TechDocs/24593.pdf#page=124。看起来他们经常更改链接URL。 - Konrad Kleine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接