diff --git a/kernel/arch/x86_64/trapasm.S b/kernel/arch/x86_64/trapasm.S index e5dfed9..1e6ab24 100644 --- a/kernel/arch/x86_64/trapasm.S +++ b/kernel/arch/x86_64/trapasm.S @@ -1,3 +1,4 @@ +#include "core/param.h" /* KSTACKSIZE */ # trapasm.S — kernel/user entry/exit with FS_BASE swapping for TLS # # The kernel uses __thread struct cpu *cpu and __thread struct proc *proc, @@ -209,7 +210,13 @@ syscall_entry: movq %rax, %fs:(8) # save rax in per-CPU scratch slot movq %gs:24, %rax # proc pointer (PERCPU_PROC) movq 0x10(%rax), %rax # proc->kstack (offset 16) - addq $(4096-16), %rax # point to tf->rsp slot + # The top of the whole stack, where allocproc() put the trapframe and + # where a trap from user mode lands (TSS rsp0). This was $(4096-16) from + # when the stack was one page, and stayed that when it became two: every + # syscall ran in the bottom 4 KB with the top 4 KB unused, and a deep + # enough read -- startx exec'ing through a SCFF chunk unpack -- ran + # through the canary at kstack[0]. + addq $(KSTACKSIZE-16), %rax # point to tf->rsp slot movq %rsp, (%rax) # save user rsp movq %rax, %rsp # switch to kernel stack movq %fs:(8), %rax # restore rax diff --git a/kernel/fs/exec.c b/kernel/fs/exec.c index 90bcf43..98edb15 100644 --- a/kernel/fs/exec.c +++ b/kernel/fs/exec.c @@ -619,11 +619,11 @@ exec_elf(char *path, struct argsrc *av, struct argsrc *ev) myproc()->tf->rcx = entry; myproc()->tf->rsp = sp; - // syscall_entry saves user RSP at kstack+PGSIZE-16 (not in the trapframe). + // syscall_entry saves user RSP at kstack+KSTACKSIZE-16 (not in the trapframe). // sysretq reads RSP from that slot, so update it to the new stack pointer. // Without this, sysretq returns with the old parent's RSP, causing lksh to // start with an invalid/wrong stack pointer. - *(uint64*)((char*)myproc()->kstack + PGSIZE - 16) = sp; + *(uint64*)((char*)myproc()->kstack + KSTACKSIZE - 16) = sp; // Userspace is running now, so the splash has done its job and the display // becomes a terminal. Only the first exec does anything; every later one