kernel thread return address... [solved]

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
proxy
Member
Member
Posts: 108
Joined: Wed Jan 19, 2005 12:00 am
Contact:

kernel thread return address... [solved]

Post by proxy »

So I've been working recently on the amd64 version of my OS and things are going pretty smoothly lately. One thing that I would like is for my kernel threads to be able to just "return" and they will get cleaned up.

I am trying to implement this by putting a cleanup routine on the stack during thread creation, but for some reason it seems off by an entry: Generally, my kernel stack creation routine does the following:

Code: Select all

	kernel_stack_ = mmu::physical_to_virtual(page_manager::allocate_low());

	uint64_t *p = reinterpret_cast<uint64_t *>(util::misc::add_pointer(kernel_stack_, mmu::page_size));
	kernel_stack_address_end_ = p;

	*--p = 0x000012345678abcd;                      // where to go when we return from thread function
	*--p = 0x0000000000000000;                      // SS
	*--p = 0x1111111111111111;                      // RSP
	*--p = 0x0000000000000202;                      // RFLAGS
	*--p = 0x0000000000000008;                      // CS
	*--p = reinterpret_cast<uint64_t>(entry_point); // RIP
	*--p = 0x0000000000000000;                      // ERROR
	*--p = 0x0000000000000000;                      // INT_NUM
	*--p = 0xaaaaaaaaaaaaaaaa;                      // RAX
	*--p = 0xbbbbbbbbbbbbbbbb;                      // RBX
	*--p = 0xcccccccccccccccc;                      // RCX
	*--p = 0xdddddddddddddddd;                      // RDX
	*--p = reinterpret_cast<uint64_t>(user_data);   // RDI
	*--p = 0x6666666666666666;                      // RSI
	*--p = 0x7777777777777777;                      // RBP
	*--p = 0x8888888888888888;                      // R8
	*--p = 0x9999999999999999;                      // R9
	*--p = 0xeeeeeeeeeeeeeeee;                      // R10
	*--p = 0x1111111111111111;                      // R11
	*--p = 0x2222222222222222;                      // R12
	*--p = 0x3333333333333333;                      // R13
	*--p = 0x4444444444444444;                      // R14
	*--p = 0x5555555555555555;                      // R15
	*--p = 0x0000000000000000;                      // FS
	*--p = 0x0000000000000000;                      // GS

	// set the entry for "RSP" to be equal to the stack's base
	p[22] = reinterpret_cast<uint64_t>(&p[23]);
	
	// store the current stack address for stack swapping
	kernel_stack_address_ = p;
I expect to get a page fault where RIP = 0x000012345678abcd, but I don't. Instead i get a page fault where RIP = 0x0000000000000000. I've tried pushing several entries on the stack to see if maybe I was missing an entry or something, but no go. If i put a crash point in the thread instead of a return, it looks like it is taking the 0x0000000000000000 from what I consider SS. (Obviously changing the SS entry in my creation code crashes things, it definitely is the SS in my context.

I realize that I could set the entry point to a function which calls the real entry point and cleans up when it returns, but I would like to know why this isn't working (the same concept worked great in my x86 code).

Any thoughts?
proxy
Last edited by proxy on Wed May 04, 2011 10:35 am, edited 1 time in total.
User avatar
proxy
Member
Member
Posts: 108
Joined: Wed Jan 19, 2005 12:00 am
Contact:

Re: kernel thread return address...

Post by proxy »

Nevermind, I figured it out. I had an off by one error in my code. The part where I set RSP to the base of the stack should have been:

Code: Select all

p[22] = reinterpret_cast<uint64_t>(&p[24]);
Now it works as expected.
Thanks :-).
Post Reply