diff --git a/headers/private/system/arch/x86/arch_commpage_defs.h b/headers/private/system/arch/x86/arch_commpage_defs.h index 5f27f676ee..eb959e14c2 100644 --- a/headers/private/system/arch/x86/arch_commpage_defs.h +++ b/headers/private/system/arch/x86/arch_commpage_defs.h @@ -16,6 +16,8 @@ (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3) #define COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS \ (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 4) +#define COMMPAGE_ENTRY_X86_THREAD_EXIT \ + (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 5) #define ARCH_USER_COMMPAGE_ADDR (0xffff0000) diff --git a/headers/private/system/arch/x86_64/arch_commpage_defs.h b/headers/private/system/arch/x86_64/arch_commpage_defs.h index bf7809e38a..dabf8f0d54 100644 --- a/headers/private/system/arch/x86_64/arch_commpage_defs.h +++ b/headers/private/system/arch/x86_64/arch_commpage_defs.h @@ -13,6 +13,8 @@ #define COMMPAGE_ENTRY_X86_MEMSET (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) #define COMMPAGE_ENTRY_X86_SIGNAL_HANDLER \ (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 2) +#define COMMPAGE_ENTRY_X86_THREAD_EXIT \ + (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3) #define ARCH_USER_COMMPAGE_ADDR (0xffffffffffff0000) diff --git a/src/system/kernel/arch/x86/32/arch.S b/src/system/kernel/arch/x86/32/arch.S index 97eb069a40..90ef56b363 100644 --- a/src/system/kernel/arch/x86/32/arch.S +++ b/src/system/kernel/arch/x86/32/arch.S @@ -115,7 +115,7 @@ FUNCTION(x86_swap_pgdir): ret FUNCTION_END(x86_swap_pgdir) -/* thread exit stub - is copied to the userspace stack in arch_thread_enter_uspace() */ +/* thread exit stub */ .align 4 FUNCTION(x86_userspace_thread_exit): pushl %eax diff --git a/src/system/kernel/arch/x86/32/thread.cpp b/src/system/kernel/arch/x86/32/thread.cpp index 9e13a7ece3..f50b5f4519 100644 --- a/src/system/kernel/arch/x86/32/thread.cpp +++ b/src/system/kernel/arch/x86/32/thread.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -215,8 +216,6 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1, void* args2) { addr_t stackTop = thread->user_stack_base + thread->user_stack_size; - uint32 codeSize = (addr_t)x86_end_userspace_thread_exit - - (addr_t)x86_userspace_thread_exit; uint32 args[3]; TRACE(("arch_thread_enter_userspace: entry 0x%lx, args %p %p, " @@ -224,14 +223,11 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1, stackTop = arch_randomize_stack_pointer(stackTop); - // copy the little stub that calls exit_thread() when the thread entry - // function returns, as well as the arguments of the entry function - stackTop -= codeSize; - - if (user_memcpy((void *)stackTop, (const void *)&x86_userspace_thread_exit, codeSize) < B_OK) - return B_BAD_ADDRESS; - - args[0] = stackTop; + // Copy the address of the stub that calls exit_thread() when the thread + // entry function returns to the top of the stack to act as the return + // address. The stub is inside commpage. + args[0] = *(addr_t*)(USER_COMMPAGE_ADDR + + COMMPAGE_ENTRY_X86_THREAD_EXIT * sizeof(addr_t)); args[1] = (uint32)args1; args[2] = (uint32)args2; stackTop -= sizeof(args); diff --git a/src/system/kernel/arch/x86/64/arch.S b/src/system/kernel/arch/x86/64/arch.S index cbaeec86cd..3f07b957d2 100644 --- a/src/system/kernel/arch/x86/64/arch.S +++ b/src/system/kernel/arch/x86/64/arch.S @@ -118,7 +118,7 @@ FUNCTION(x86_swap_pgdir): FUNCTION_END(x86_swap_pgdir) -/* thread exit stub - copied to the userspace stack in arch_thread_enter_uspace() */ +/* thread exit stub */ .align 8 FUNCTION(x86_userspace_thread_exit): movq %rax, %rdi diff --git a/src/system/kernel/arch/x86/64/thread.cpp b/src/system/kernel/arch/x86/64/thread.cpp index 8c5c2fa83c..4b80ea6c4f 100644 --- a/src/system/kernel/arch/x86/64/thread.cpp +++ b/src/system/kernel/arch/x86/64/thread.cpp @@ -218,20 +218,11 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1, stackTop = arch_randomize_stack_pointer(stackTop); - // Copy the little stub that calls exit_thread() when the thread entry - // function returns. - // TODO: This will become a problem later if we want to support execute - // disable, the stack shouldn't really be executable. - size_t codeSize = (addr_t)x86_end_userspace_thread_exit - - (addr_t)x86_userspace_thread_exit; - stackTop -= codeSize; - if (user_memcpy((void*)stackTop, (const void*)&x86_userspace_thread_exit, - codeSize) != B_OK) - return B_BAD_ADDRESS; - - // Copy the address of the stub to the top of the stack to act as the - // return address. - addr_t codeAddr = stackTop; + // Copy the address of the stub that calls exit_thread() when the thread + // entry function returns to the top of the stack to act as the return + // address. The stub is inside commpage. + addr_t codeAddr = *(addr_t*)(USER_COMMPAGE_ADDR + + COMMPAGE_ENTRY_X86_THREAD_EXIT * sizeof(addr_t)); stackTop -= sizeof(codeAddr); if (user_memcpy((void*)stackTop, (const void*)&codeAddr, sizeof(codeAddr)) != B_OK) diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 7438203853..be6d4889dd 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -868,6 +868,10 @@ arch_cpu_init_post_modules(kernel_args* args) - (addr_t)gOptimizedFunctions.memset; fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMSET, (const void*)gOptimizedFunctions.memset, memsetLen); + size_t threadExitLen = (addr_t)x86_end_userspace_thread_exit + - (addr_t)x86_userspace_thread_exit; + fill_commpage_entry(COMMPAGE_ENTRY_X86_THREAD_EXIT, + (const void*)x86_userspace_thread_exit, threadExitLen); // add the functions to the commpage image image_id image = get_commpage_image(); @@ -877,6 +881,9 @@ arch_cpu_init_post_modules(kernel_args* args) elf_add_memory_image_symbol(image, "commpage_memset", ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_MEMSET], memsetLen, B_SYMBOL_TYPE_TEXT); + elf_add_memory_image_symbol(image, "commpage_thread_exit", + ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_THREAD_EXIT], + threadExitLen, B_SYMBOL_TYPE_TEXT); return B_OK; }