[SOLVED] %fs base not updating (Thread Local Storage)

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
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

[SOLVED] %fs base not updating (Thread Local Storage)

Post by zhiayang »

Hello. I'm starting to implement TLS in my OS, using the traditional %fs:offset as used by GCC's __thread. Problem is, %fs:0x0 == 0, meaning that the base address of %fs is not resolving properly. Here's some info:

- %fs = 0x2B, which is a dummy GDT descriptor that I cloned from my ring3 DS descriptor
- Long mode.

I'm using the MSR method with MSRID = 0xC0000100 to change FS.base (as described in the AMD manual). I'm getting a page fault on address 0xFFFFFFFFFFFFFFFC, which is -4(0). This is the disassembly of the faulting code (in userspace):

Code: Select all

 2000ab9:	64 48 8b 04 25 00 00 	mov    %fs:0x0,%rax
 2000ac0:	00 00 
 2000ac2:	48 8d 80 fc ff ff ff 	lea    -0x4(%rax),%rax
 2000ac9:	c7 00 00 00 00 00    	movl   $0x0,(%rax)
 2000acf:	48 83 c4 08          	add    $0x8,%rsp

Basically, since movl $0x0, (%rax) page faults, then lea -0x4(%rax) must be loading 0xFFFFFFFFFFFFFFFC, therefore %fs:0x0 must be 0.
Here's how I'm changing %fs:

Code: Select all

uint32_t low = tlsptr & 0xFFFFFFFF;
uint32_t high = tlsptr >> 32;
asm volatile(
		"mov $0x2B, %%bx           \n\t"
		"mov %%bx, %%fs            \n\t"

		"movl $0xC0000100, %%ecx	\n\t"
		"movl %[lo], %%eax		   \n\t"
		"movl %[hi], %%edx		   \n\t"
		"wrmsr				         \n\t"

		:: [lo]"g"(low), [hi]"g"(high) : "memory", "rax", "rbx", "rcx", "rdx");

And finally, here's the GDT entry for 0x28:

Code: Select all

	GDTFS:
		.word 0xFFFF		 // Limit (low)
		.word 0			   // Base (low)
		.byte 0			   // Base (middle)
		.byte 0xF2			// Access
		.byte 0xAF			// Granularity (4) / Limit (high) (4)
		.byte 0			   // Base (high)

This has literally been bugging me for more than a few hours now, so any help is appreciated, thanks!
Last edited by zhiayang on Tue Sep 02, 2014 9:22 am, edited 1 time in total.
mrvn
Member
Member
Posts: 43
Joined: Tue Mar 11, 2008 6:56 am

Re: %fs base not updating (Thread Local Storage)

Post by mrvn »

Your code does NOT show that %fs.base is 0 but that the memory %fs.base points to contains 0. You are accessing a NULL pointer.
Life - Don't talk to me about LIFE!
So long and thanks for all the fish.
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: %fs base not updating (Thread Local Storage)

Post by zhiayang »

mrvn wrote:Your code does NOT show that %fs.base is 0 but that the memory %fs.base points to contains 0. You are accessing a NULL pointer.
Yea, totally screwed up there. I guess my mind wasn't working too well, I can see you were trying to tell me this on IRC.
Sorry for wasting your time ):
Icee
Member
Member
Posts: 100
Joined: Wed Jan 08, 2014 8:41 am
Location: Moscow, Russia

Re: [SOLVED] %fs base not updating (Thread Local Storage)

Post by Icee »

You might also want to use a single dedicated WRFSBASE instruction instead of a WRMSR-based sequence.
Post Reply