kernel thread return address... [solved]
Posted: Tue May 03, 2011 1:22 pm
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:
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
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 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