From d119d7123bf2ff03cb5eb3bbb80d3bd8be92e5d5 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sat, 8 Feb 2025 20:16:15 -0300 Subject: [PATCH] signal: fix handling of fpu and some more small things --- kernel-src/include/x86-64/arch/signal.h | 12 ++++-------- kernel-src/sys/signal.c | 6 ++++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/kernel-src/include/x86-64/arch/signal.h b/kernel-src/include/x86-64/arch/signal.h index d97d2381..bfc741bf 100644 --- a/kernel-src/include/x86-64/arch/signal.h +++ b/kernel-src/include/x86-64/arch/signal.h @@ -36,7 +36,7 @@ typedef struct { unsigned long gregs[MCONTEXT_NGREG]; - uint8_t fpu_state[512]; + uint8_t *fpu_state_p; unsigned long __reserved1[8]; } mcontext_t; @@ -60,11 +60,10 @@ typedef struct { #define ARCH_SIGFRAME_GET_UCONTEXT_POINTER(x) (&(x)->uc_flags) -static inline void arch_sigframe_prepare_mcontext(sigframe_t *sigframe) { +static inline void arch_sigframe_prepare_mcontext(void *stack, sigframe_t *sigframe) { context_t *context = &sigframe->context; extracontext_t *extracontext = &sigframe->extracontext; unsigned long *gregs = sigframe->mcontext.gregs; - uint8_t *fpu_state = sigframe->mcontext.fpu_state; gregs[MCONTEXT_REG_R8] = context->r8; gregs[MCONTEXT_REG_R9] = context->r9; @@ -86,18 +85,17 @@ static inline void arch_sigframe_prepare_mcontext(sigframe_t *sigframe) { gregs[MCONTEXT_REG_EFL] = context->rflags; gregs[MCONTEXT_REG_CSGSFS] = 0; gregs[MCONTEXT_REG_ERR] = context->error; - gregs[MCONTEXT_REG_TRAPNO] = 0; + gregs[MCONTEXT_REG_TRAPNO] = context->irq; gregs[MCONTEXT_REG_OLDMASK] = 0; gregs[MCONTEXT_REG_CR2] = context->cr2; - memcpy(fpu_state, extracontext->fx, 512); + sigframe->mcontext.fpu_state_p = &((sigframe_t *)stack)->extracontext.fx; } static inline void arch_sigframe_get_context_from_mcontext(sigframe_t *sigframe) { context_t *context = &sigframe->context; extracontext_t *extracontext = &sigframe->extracontext; unsigned long *gregs = sigframe->mcontext.gregs; - uint8_t *fpu_state = sigframe->mcontext.fpu_state; context->r8 = gregs[MCONTEXT_REG_R8]; context->r9 = gregs[MCONTEXT_REG_R9]; @@ -119,8 +117,6 @@ static inline void arch_sigframe_get_context_from_mcontext(sigframe_t *sigframe) context->rflags = gregs[MCONTEXT_REG_EFL]; context->error = gregs[MCONTEXT_REG_ERR]; context->cr2 = gregs[MCONTEXT_REG_CR2]; - - memcpy(extracontext->fx, fpu_state, 512); } diff --git a/kernel-src/sys/signal.c b/kernel-src/sys/signal.c index 63636096..62180d21 100644 --- a/kernel-src/sys/signal.c +++ b/kernel-src/sys/signal.c @@ -569,12 +569,14 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin memcpy(&sigframe.context, context, sizeof(context_t)); memcpy(&sigframe.extracontext, &thread->extracontext, sizeof(extracontext_t)); - arch_sigframe_prepare_mcontext(&sigframe); + arch_sigframe_prepare_mcontext(stack, &sigframe); memset(&sigframe.siginfo, 0, sizeof(siginfo_t)); + if (signal == SIGSEGV) + sigframe.siginfo.__si_fields.__sigfault.si_addr = CTX_TRAP_ADDR(context); if (usercopy_touser(stack, &sigframe, sizeof(sigframe_t))) { - printf("signal: bad user stack %p\n", stack); + printf("signal: bad user stack %p (altstack %p) handling signal %d trapno %lu\n", stack, altstack, signal, sigframe.mcontext.gregs[MCONTEXT_REG_TRAPNO]); THREAD_LEAVE(thread); PROCESS_LEAVE(proc); interrupt_set(true);