From bb793d5c6918efee6a86de442463a7c9aaa4ecdd Mon Sep 17 00:00:00 2001 From: Minep Date: Sun, 23 Jul 2023 18:45:53 +0100 Subject: [PATCH 1/1] fix: corner case for x87 context restore on execve chore: clean up unused fields --- lunaix-os/includes/lunaix/process.h | 18 +++++----- lunaix-os/kernel/asm/x86/interrupt.S | 53 ++++++---------------------- lunaix-os/kernel/exe/exec.c | 4 +++ lunaix-os/kernel/process/signal.c | 6 ++++ 4 files changed, 30 insertions(+), 51 deletions(-) diff --git a/lunaix-os/includes/lunaix/process.h b/lunaix-os/includes/lunaix/process.h index 7d385a4..1453e71 100644 --- a/lunaix-os/includes/lunaix/process.h +++ b/lunaix-os/includes/lunaix/process.h @@ -45,8 +45,6 @@ #define proc_hanged(proc) (((proc)->state) & PS_BLOCKED) #define proc_runnable(proc) (((proc)->state) & PS_PAUSED) -#define PROC_FINPAUSE 1 - struct sigact { struct sigact* prev; @@ -76,17 +74,17 @@ struct proc_info { /* Any change to *critical section*, including layout, size - must be reflected in kernel/asm/x86/interrupt.S to avoid + must be reflected in arch/x86/interrupt.S.inc to avoid disaster! */ /* ---- critical section start ---- */ - pid_t pid; // offset = 0 - struct proc_info* parent; // offset = 4 - isr_param* intr_ctx; // offset = 8 - ptr_t ustack_top; // offset = 84 -> 56 -> 60 -> 12 - ptr_t page_table; // offset = 88 -> 60 -> 64 -> 16 + pid_t pid; + struct proc_info* parent; + isr_param* intr_ctx; + ptr_t ustack_top; + ptr_t page_table; /* ---- critical section end ---- */ @@ -108,7 +106,6 @@ struct proc_info u8_t state; int32_t exit_code; int32_t k_status; - int flags; struct sighail sigctx; struct v_fdtable* fdtable; struct v_dnode* cwd; @@ -195,4 +192,7 @@ get_process(pid_t pid); void proc_setsignal(struct proc_info* proc, int signum); +void +proc_clear_signal(struct proc_info* proc); + #endif /* __LUNAIX_PROCESS_H */ diff --git a/lunaix-os/kernel/asm/x86/interrupt.S b/lunaix-os/kernel/asm/x86/interrupt.S index 80dee1a..f308503 100644 --- a/lunaix-os/kernel/asm/x86/interrupt.S +++ b/lunaix-os/kernel/asm/x86/interrupt.S @@ -35,34 +35,6 @@ .section .text .global interrupt_wrapper interrupt_wrapper: - /* - Stack layout (layout of struct isr_param) - msa: [ss] > 76 -> 28 - [esp] > 72 -> 24 - eflags > 68 -> 20 - cs > 64 -> 16 - eip > 60 -> 12 - err_code > 56 -> 8 - vector > offset = 52 -> 4 - [saved_prev_ctx] > offset = 0 - --- - esp > 12 * 4 = 48 - gs - fs - es - ds > offset = 8 * 4 = 32 - esi - ebp - edi - edx - ecx - ebx - eax - lsa: depth > offset = 0 - - las: Least Significant Address - msa: Most Significant Address - */ cld subl $4, %esp @@ -98,19 +70,19 @@ movw %ax, %ds movw %ax, %es - movl __current, %eax - - # 保存用户栈顶指针。因为我们允许同级中断的产生,所以需要该手段跟踪用户栈的地址。 - movl iuesp(%esp), %ebx # 取出esp - movl %ebx, proc_ustack_top(%eax) # 存入__current->ustack_top + movl __current, %ebx # Save x87 context to user stack, rather than kernel's memory. - # XXX: what will happen if we triggered a page fault during fxsave? + # XXX what will happen if we triggered a page fault during fxsave? + # FIXME can we remove this overhead? movl iuesp(%esp), %eax andl $stack_alignment, %eax subl $512, %eax fxsave (%eax) + # 保存用户栈顶指针。因为我们允许同级中断的产生,所以需要该手段跟踪用户栈的地址。 + movl %eax, proc_ustack_top(%ebx) # 存入__current->ustack_top + /* kernel space same-level switch */ 1: movl %esp, %eax @@ -132,18 +104,15 @@ movl exeip(%eax), %eax movl %eax, (debug_resv + 4) # eip #endif - // movl __current, %eax - // movl proc_fxstate(%eax), %eax - - // test %eax, %eax # do we have stored x87 context? movl ics(%esp), %eax andl $3, %eax jz 1f - movl iuesp(%esp), %eax - andl $stack_alignment, %eax - subl $512, %eax + movl __current, %eax + movl proc_ustack_top(%eax), %eax + test %eax, %eax + jz 1f fxrstor (%eax) 1: @@ -165,7 +134,6 @@ movl %eax, tmp_store movl __current, %eax - # nested intr: restore saved context popl proc_intr_ctx(%eax) @@ -221,6 +189,7 @@ movl %ecx, (tss_esp0_off + _tss) jmp handle_signal + 1: movl proc_intr_ctx(%ebx), %eax jmp soft_iret diff --git a/lunaix-os/kernel/exe/exec.c b/lunaix-os/kernel/exe/exec.c index a846126..21814d1 100644 --- a/lunaix-os/kernel/exe/exec.c +++ b/lunaix-os/kernel/exe/exec.c @@ -224,6 +224,10 @@ __DEFINE_LXSYSCALL3(int, execp->esp = container.stack_top; execp->eip = container.exe.entry; + // these become meaningless once execved! + __current->ustack_top = 0; + proc_clear_signal(__current); + done: // set return value store_retval(DO_STATUS(errno)); diff --git a/lunaix-os/kernel/process/signal.c b/lunaix-os/kernel/process/signal.c index d00e757..8c4322f 100644 --- a/lunaix-os/kernel/process/signal.c +++ b/lunaix-os/kernel/process/signal.c @@ -77,6 +77,12 @@ signal_dispatch() return sigframe; } +void +proc_clear_signal(struct proc_info* proc) +{ + memset(&proc->sigctx, 0, sizeof(proc->sigctx)); +} + void proc_setsignal(struct proc_info* proc, int signum) { -- 2.27.0