问题描述
我试图弄清Linux内核中MACRO当前的详细信息.当前的最终汇编代码为:
I tried to figure out the details of MACRO current in Linux kernel.The final assembly code of current is:
movq %%gs:0xb000,%0
上面的代码可以工作!但是当我打印%% gs时,它的值为0,所以%% gs指向GDT NULL的第一项!如何运作?
The code above can work! But when I print the %%gs, its value is 0, so the %%gs points to the first item of GDT NULL!!?? How it works?
mov %%gs, %0
相反,gs的基数位于MSR_GS_BASE中,并且可以像下面这样替换电流:
Instead, the base of gs is in MSR_GS_BASE, and the current can be replaced like:
/*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功能吗?我需要一些对此的参考.
%gs points to the first item of GDT NULL!!?? How it works as read from MSR_GS_BASE, is it a CPU feature? I need some references about this.
推荐答案
来自 AMD体系结构程序员手册第2卷:系统编程,第4.5.3节:
From the AMD Architecture Programmer's Manual Volume 2: System Programming, section 4.5.3:
[...]
有两种方法可以更新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.
There are two methods to update the contents of the FS.base and GS.base hidden descriptor fields. The first is available exclusively to privileged software (CPL = 0). The FS.base and GS.base hidden descriptor-register fields are mapped to MSRs. Privileged software can load a 64-bit base address in canonical form into FS.base or GS.base using a single WRMSR instruction. The FS.base MSR address is C000_0100h while the GS.base MSR address is C000_0101h.
更新FS和GS基本字段的第二种方法可用于以任何特权级别运行的软件(当实现支持并通过设置CR4 [FSGSBASE]启用时). WRFSBASE和WRGSBASE指令分别将GPR的内容复制到FS.base和GS.base字段.当操作数大小为32位时,将清除基址的高位双字. WRFSBASE和WRGSBASE仅在64位模式下受支持.
The second method of updating the FS and GS base fields is available to software running at any privilege level (when supported by the implementation and enabled by setting CR4[FSGSBASE]). The WRFSBASE and WRGSBASE instructions copy the contents of a GPR to the FS.base and GS.base fields respectively. When the operand size is 32 bits, the upper doubleword of the base is cleared. WRFSBASE and WRGSBASE are only supported in 64-bit mode.
这篇关于有关Linux x86 64中MSR_GS_BASE的详细信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!