When setting up the stack for a (kernel) thread on riscv64, zero the
frame pointer in switchframe so that the frame chain terminates cleanly.
At the moment, the unwinding of kernel thread stacks stops to "bad frame
pointer" error.
OK?
Index: arch/riscv64/riscv64/cpuswitch.S
===================================================================
RCS file: src/sys/arch/riscv64/riscv64/cpuswitch.S,v
retrieving revision 1.5
diff -u -p -r1.5 cpuswitch.S
--- arch/riscv64/riscv64/cpuswitch.S 2 Jul 2021 14:58:33 -0000 1.5
+++ arch/riscv64/riscv64/cpuswitch.S 21 Feb 2022 17:22:43 -0000
@@ -100,8 +100,8 @@ ENTRY(proc_trampoline)
li a0, IPL_NONE
la t0, spllower
jalr t0
- mv a0, s1
- jalr s0
+ mv a0, s2
+ jalr s1
la t0, syscall_return
jr t0
END(cpu_switch)
Index: arch/riscv64/riscv64/vm_machdep.c
===================================================================
RCS file: src/sys/arch/riscv64/riscv64/vm_machdep.c,v
retrieving revision 1.7
diff -u -p -r1.7 vm_machdep.c
--- arch/riscv64/riscv64/vm_machdep.c 30 Jun 2021 22:20:56 -0000 1.7
+++ arch/riscv64/riscv64/vm_machdep.c 21 Feb 2022 17:22:43 -0000
@@ -92,8 +92,9 @@ cpu_fork(struct proc *p1, struct proc *p
tf->tf_sstatus &= ~(SSTATUS_SPP); /* Enter user mode. */
sf = (struct switchframe *)tf - 1;
- sf->sf_s[0] = (uint64_t)func;
- sf->sf_s[1] = (uint64_t)arg;
+ sf->sf_s[0] = 0; /* Terminate chain of call frames. */
+ sf->sf_s[1] = (uint64_t)func;
+ sf->sf_s[2] = (uint64_t)arg;
sf->sf_ra = (u_int64_t)&proc_trampoline;
pcb->pcb_sp = (uint64_t)sf;
}