From 24eb3d5aba20eaff90fae0b56db384bf50a3c81f Mon Sep 17 00:00:00 2001 From: X512 Date: Wed, 13 Apr 2022 22:46:34 +0900 Subject: [PATCH] kernel: do not use assembly code for commpage signal handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify with x86 and riscv64 implementation. Change-Id: I2f44575768628eb3a2d4eaaa86f020de582ecd0b Reviewed-on: https://review.haiku-os.org/c/haiku/+/5203 Tested-by: Commit checker robot Reviewed-by: Jérôme Duval Reviewed-by: Fredrik Holmqvist --- src/system/kernel/arch/x86/64/signals.cpp | 71 ++++++++++++++++----- src/system/kernel/arch/x86/64/signals_asm.S | 56 ---------------- src/system/kernel/arch/x86/Jamfile | 1 - 3 files changed, 56 insertions(+), 72 deletions(-) delete mode 100644 src/system/kernel/arch/x86/64/signals_asm.S diff --git a/src/system/kernel/arch/x86/64/signals.cpp b/src/system/kernel/arch/x86/64/signals.cpp index 06d41ac6b2..eee7a7c460 100644 --- a/src/system/kernel/arch/x86/64/signals.cpp +++ b/src/system/kernel/arch/x86/64/signals.cpp @@ -15,25 +15,66 @@ #include #include +#include "syscall_numbers.h" -extern "C" void x86_64_user_signal_handler(void); -extern int x86_64_user_signal_handler_end; + +extern "C" void __attribute__((noreturn)) +x86_64_user_signal_handler(signal_frame_data* data) +{ + if (data->siginfo_handler) { + auto handler = (void (*)(int, siginfo_t*, void*, void*))data->handler; + handler(data->info.si_signo, &data->info, &data->context, data->user_data); + } else { + auto handler = (void (*)(int, void*, vregs*))data->handler; + handler(data->info.si_signo, data->user_data, &data->context.uc_mcontext); + } + + #define TO_STRING_LITERAL_HELPER(number) #number + #define TO_STRING_LITERAL(number) TO_STRING_LITERAL_HELPER(number) + + // _kern_restore_signal_frame(data) + asm volatile( + "movq %0, %%rdi;" + "movq $" TO_STRING_LITERAL(SYSCALL_RESTORE_SIGNAL_FRAME) ", %%rax;" + "syscall;" + :: "r"(data) + ); + + #undef TO_STRING_LITERAL_HELPER + #undef TO_STRING_LITERAL + + __builtin_unreachable(); +} + + +static void +register_commpage_function(const char* functionName, int32 commpageIndex, + const char* commpageSymbolName, addr_t expectedAddress) +{ + // get address and size of function + elf_symbol_info symbolInfo; + if (elf_lookup_kernel_symbol(functionName, &symbolInfo) != B_OK) { + panic("register_commpage_function(): Failed to find " + "signal frame function \"%s\"!", functionName); + } + + ASSERT(expectedAddress == symbolInfo.address); + + // fill in the commpage table entry + addr_t position = fill_commpage_entry(commpageIndex, + (void*)symbolInfo.address, symbolInfo.size); + + // add symbol to the commpage image + image_id image = get_commpage_image(); + elf_add_memory_image_symbol(image, commpageSymbolName, position, + symbolInfo.size, B_SYMBOL_TYPE_TEXT); +} void x86_initialize_commpage_signal_handler() { - void* handlerCode = (void*)&x86_64_user_signal_handler; - void* handlerCodeEnd = &x86_64_user_signal_handler_end; - - // Copy the signal handler code to the commpage. - size_t len = (size_t)((addr_t)handlerCodeEnd - (addr_t)handlerCode); - addr_t position = fill_commpage_entry(COMMPAGE_ENTRY_X86_SIGNAL_HANDLER, - handlerCode, len); - - // Add symbol to the commpage image. - image_id image = get_commpage_image(); - elf_add_memory_image_symbol(image, "commpage_signal_handler", position, - len, B_SYMBOL_TYPE_TEXT); + register_commpage_function("x86_64_user_signal_handler", + COMMPAGE_ENTRY_X86_SIGNAL_HANDLER, "commpage_signal_handler", + (addr_t)&x86_64_user_signal_handler); } - diff --git a/src/system/kernel/arch/x86/64/signals_asm.S b/src/system/kernel/arch/x86/64/signals_asm.S deleted file mode 100644 index 5d85022707..0000000000 --- a/src/system/kernel/arch/x86/64/signals_asm.S +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. - * Distributed under the terms of the MIT License. - */ - - -#include - -#include "asm_offsets.h" -#include "syscall_numbers.h" - - -.text - - -// Userspace signal handler wrapper, copied to the commpage. -FUNCTION(x86_64_user_signal_handler): - push %rbp - movq %rsp, %rbp - - // RDI points to the signal_frame_data structure, however we'll overwrite - // that with the function arguments, so move it somewhere else. We can use - // callee-save registers here without preserving them because the old value - // will be restored when the frame is restored. - movq %rdi, %r12 - - // Check the handler type. - cmpb $0, SIGNAL_FRAME_DATA_siginfo_handler(%r12) - jne .Lsiginfo_handler - -.Lsimple_handler: - // Fetch other arguments (user data, vregs). - movq SIGNAL_FRAME_DATA_user_data(%r12), %rsi - leaq SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%r12), %rdx - -.Lcall_handler: - // Get the handler address and the signal number first argument. - movq SIGNAL_FRAME_DATA_handler(%r12), %rax - movl SIGNAL_FRAME_DATA_info + SIGINFO_T_si_signo(%r12), %edi - - // Call the handler. - callq *%rax - - // Perform the restore_signal_frame() syscall, should not return. - movq $SYSCALL_RESTORE_SIGNAL_FRAME, %rax - movq %r12, %rdi - syscall - -.Lsiginfo_handler: - // Fetch other arguments (info pointer, context, user data). - leaq SIGNAL_FRAME_DATA_info(%r12), %rsi - leaq SIGNAL_FRAME_DATA_context(%r12), %rdx - movq SIGNAL_FRAME_DATA_user_data(%r12), %rcx - jmp .Lcall_handler -FUNCTION_END(x86_64_user_signal_handler) -SYMBOL(x86_64_user_signal_handler_end): diff --git a/src/system/kernel/arch/x86/Jamfile b/src/system/kernel/arch/x86/Jamfile index 08a40cc045..30a81e620c 100644 --- a/src/system/kernel/arch/x86/Jamfile +++ b/src/system/kernel/arch/x86/Jamfile @@ -28,7 +28,6 @@ if $(TARGET_ARCH) = x86_64 { errata.cpp interrupts.S signals.cpp - signals_asm.S syscalls.cpp thread.cpp