loading GS base on x86_64

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

loading GS base on x86_64

Post by NickJohnson »

I'm trying to use the MSR GS.base to set the base address for GS but it doesn't seem to be working properly. Here is what I'm doing: (all code is in 64-bit NASM)

Code: Select all

mov rax, (base address I want)
mov rdx, rax
shr rdx, 32
mov ecx, 0xC0000101
wrmsr
Then I check the base address of GS like this:

Code: Select all

lea rax, [gs:0x100]
I would expect rax to be set to the base of GS plus 0x100. However, rax is being set to just 0x100 here. Is there some additional operation I need to perform in order to get the new base for GS to load? Or am I loading the MSR incorrectly?
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: loading GS base on x86_64

Post by gerryg400 »

You need to do a swapgs to move the msr value to the GS base.

In c I do ...

Code: Select all

    /* Set up the gs register */
    wr_msr(0xc0000102, (uintptr_t)&core_data[core]);
    __swapgs();
If a trainstation is where trains stop, what is a workstation ?
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: loading GS base on x86_64

Post by NickJohnson »

That doesn't seem to change anything for me.

On the other hand, it does look like performing loads relative to GS does work, e.g.:

Code: Select all

mov rax, [gs:0]
Is it just not possible to use LEA to get an address relative to the GS base? It seems odd that "lea rax, [gs:0]" is a valid instruction then.
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: loading GS base on x86_64

Post by Kevin »

This is just how lea works. The "effective address" is the offset, not the linear or physical address.
Developer of tyndur - community OS of Lowlevel (German)
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: loading GS base on x86_64

Post by qw »

LEA ignores the segment override; it ignores the segment/selector all together. "lea rax, [0]" clears RAX no matter the base address. So does "lea rax, [gs:0]".
User avatar
iansjack
Member
Member
Posts: 4711
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: loading GS base on x86_64

Post by iansjack »

The Intel manual is pretty clear on this point. The lea instruction works on the offset, not the absolute address.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: loading GS base on x86_64

Post by JamesM »

The clue is in the name. "load effective address" loads the effective address, which is just the addressing mode computation. Segment offset is added to form the linear address later.
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: loading GS base on x86_64

Post by xenos »

It seems that the AMD manuals are confusingly unclear about this...
AMD manuals, Vol. 2, 4.5.3 wrote: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.
In contrast, the Intel manuals state:
Intel manuals, Vol. 3, 3.4.4 wrote:When FS and GS segment overrides are used in 64-bit mode, their respective base addresses are used in the linear address calculation: (FS or GS).base + index + displacement. FS.base and GS.base are then expanded to the full linear-address size supported by the implementation. The resulting effective address calculation can wrap across positive and negative addresses; the resulting linear address must be canonical.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
Post Reply