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;
 }

Reply via email to