Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detail about MSR_GS_BASE in linux x86 64

I tried to figure out the details of MACRO current in Linux kernel. The final assembly code of current is:

movq %%gs:0xb000,%0

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

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);

My questions is:

%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.

like image 740
hellolwq Avatar asked Jul 16 '12 02:07

hellolwq


1 Answers

From the AMD Architecture Programmer's Manual Volume 2: System Programming, section 4.5.3:

FS and GS Registers in 64-Bit Mode. Unlike the CS,DS,ES, and SS segments, the FS and GS segment overrides can be used in 64-bit mode. When FS and GS segment overrides are used in 64-bit mode, their respective base addresses are used in the effective-address (EA) calculation. The complete EA calculation then becomes (FS or GS).base + base + (scale * index) + displacement. The FS.base and GS.base values are also expanded to the full 64-bit virtual-address size, as shown in Figure 4-5. The resulting EA calculation is allowed to wrap across positive and negative addresses.

[...]

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.

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.

like image 66
Geoff Reedy Avatar answered Nov 08 '22 02:11

Geoff Reedy