Page MenuHomeFreeBSD

D59647.1793637213.diff
No OneTemporary

Authored By
Unknown
Size
10 KB
Referenced Files
None
Subscribers
None

D59647.1793637213.diff

diff --git a/libexec/rtld-elf/riscv/rtld_start.S b/libexec/rtld-elf/riscv/rtld_start.S
--- a/libexec/rtld-elf/riscv/rtld_start.S
+++ b/libexec/rtld-elf/riscv/rtld_start.S
@@ -39,6 +39,7 @@
*/
ENTRY(.rtld_start)
+ .cfi_startproc
.cfi_undefined ra /* Do not attempt to unwind any further. */
mv s0, a0 /* Put ps_strings in a callee-saved register */
mv s1, sp /* And the stack pointer */
@@ -55,6 +56,7 @@
mv a0, s0 /* Restore ps_strings */
mv sp, s1 /* Restore the stack pointer */
jr t0 /* Jump to the entry point */
+ .cfi_endproc
END(.rtld_start)
/*
diff --git a/sys/conf/ldscript.riscv b/sys/conf/ldscript.riscv
--- a/sys/conf/ldscript.riscv
+++ b/sys/conf/ldscript.riscv
@@ -32,6 +32,7 @@
*(.note.gnu.build-id)
PROVIDE (__build_id_end = .);
}
+ .eh_frame : { KEEP (*(.eh_frame)) }
.rel.text :
{ *(.rel.text) *(.rel.gnu.linkonce.t*) }
.rela.text :
diff --git a/sys/riscv/include/asm.h b/sys/riscv/include/asm.h
--- a/sys/riscv/include/asm.h
+++ b/sys/riscv/include/asm.h
@@ -45,8 +45,8 @@
#define _C_LABEL(x) x
#define ENTRY(sym) \
- .text; .globl sym; .type sym,@function; .align 4; sym: .cfi_startproc;
-#define END(sym) .cfi_endproc; .size sym, . - sym
+ .text; .globl sym; .type sym,@function; .align 4; sym:
+#define END(sym) .size sym, . - sym
#define EENTRY(sym) \
.globl sym; sym:
diff --git a/sys/riscv/include/cpu.h b/sys/riscv/include/cpu.h
--- a/sys/riscv/include/cpu.h
+++ b/sys/riscv/include/cpu.h
@@ -103,6 +103,7 @@
void cpu_halt(void) __dead2;
void cpu_reset(void) __dead2;
void fork_trampoline(void);
+void fork_trampoline_kthread(void);
void identify_cpu(u_int cpu);
void printcpuinfo(u_int cpu);
diff --git a/sys/riscv/include/frame.h b/sys/riscv/include/frame.h
--- a/sys/riscv/include/frame.h
+++ b/sys/riscv/include/frame.h
@@ -41,7 +41,8 @@
#include <sys/ucontext.h>
/*
- * NOTE: keep this structure in sync with struct reg and struct mcontext.
+ * NOTE: keep this structure in sync with struct reg, struct mcontext, and the
+ * trap frame CFI information.
*/
struct trapframe {
uint64_t tf_ra;
diff --git a/sys/riscv/include/trap_cfi.h b/sys/riscv/include/trap_cfi.h
new file mode 100644
--- /dev/null
+++ b/sys/riscv/include/trap_cfi.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2026 FreeBSD Foundation
+ *
+ * This software was developed by Minsoo Choo under sponsorship from the
+ * FreeBSD Foundation.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _MACHINE_TRAP_CFI_H_
+#define _MACHINE_TRAP_CFI_H_
+
+#include "assym.inc"
+
+ .cfi_sections .eh_frame
+
+/* DWARF register 64 is the RISC-V alternate frame return column. */
+#define CFI_RA_COLUMN 64
+#define CFI_TF_SIZE (TF_SCAUSE + 8)
+
+.macro trap_cfi_entry name, state=empty
+ .cfi_startproc
+ .cfi_signal_frame
+ .cfi_return_column CFI_RA_COLUMN
+ .cfi_def_cfa sp, 0
+ .cfi_undefined CFI_RA_COLUMN
+.ifc \state,full
+ trap_cfi_full
+.endif
+.ifc \state,terminal
+ .cfi_def_cfa sp, CFI_TF_SIZE
+.endif
+.endm
+
+.macro trap_cfi_end name
+ .cfi_endproc
+.endm
+
+.macro trap_cfi_saved reg, off
+ .cfi_offset \reg, \off - CFI_TF_SIZE
+.endm
+
+.macro trap_cfi_full
+ .cfi_def_cfa sp, CFI_TF_SIZE
+ .cfi_same_value zero
+ trap_cfi_saved ra, TF_RA
+ trap_cfi_saved sp, TF_SP
+ trap_cfi_saved gp, TF_GP
+ trap_cfi_saved tp, TF_TP
+ trap_cfi_saved t0, TF_T + 0 * 8
+ trap_cfi_saved t1, TF_T + 1 * 8
+ trap_cfi_saved t2, TF_T + 2 * 8
+ trap_cfi_saved t3, TF_T + 3 * 8
+ trap_cfi_saved t4, TF_T + 4 * 8
+ trap_cfi_saved t5, TF_T + 5 * 8
+ trap_cfi_saved t6, TF_T + 6 * 8
+ trap_cfi_saved s0, TF_S + 0 * 8
+ trap_cfi_saved s1, TF_S + 1 * 8
+ trap_cfi_saved s2, TF_S + 2 * 8
+ trap_cfi_saved s3, TF_S + 3 * 8
+ trap_cfi_saved s4, TF_S + 4 * 8
+ trap_cfi_saved s5, TF_S + 5 * 8
+ trap_cfi_saved s6, TF_S + 6 * 8
+ trap_cfi_saved s7, TF_S + 7 * 8
+ trap_cfi_saved s8, TF_S + 8 * 8
+ trap_cfi_saved s9, TF_S + 9 * 8
+ trap_cfi_saved s10, TF_S + 10 * 8
+ trap_cfi_saved s11, TF_S + 11 * 8
+ trap_cfi_saved a0, TF_A + 0 * 8
+ trap_cfi_saved a1, TF_A + 1 * 8
+ trap_cfi_saved a2, TF_A + 2 * 8
+ trap_cfi_saved a3, TF_A + 3 * 8
+ trap_cfi_saved a4, TF_A + 4 * 8
+ trap_cfi_saved a5, TF_A + 5 * 8
+ trap_cfi_saved a6, TF_A + 6 * 8
+ trap_cfi_saved a7, TF_A + 7 * 8
+ .cfi_offset CFI_RA_COLUMN, TF_SEPC - CFI_TF_SIZE
+.endm
+
+#endif /* _MACHINE_TRAP_CFI_H_ */
diff --git a/sys/riscv/riscv/db_trace.c b/sys/riscv/riscv/db_trace.c
--- a/sys/riscv/riscv/db_trace.c
+++ b/sys/riscv/riscv/db_trace.c
@@ -110,7 +110,8 @@
continue;
}
- if (strcmp(name, "fork_trampoline") == 0)
+ if (strcmp(name, "fork_trampoline") == 0 ||
+ strcmp(name, "fork_trampoline_kthread") == 0)
break;
if (!unwind_frame(td, frame))
diff --git a/sys/riscv/riscv/exception.S b/sys/riscv/riscv/exception.S
--- a/sys/riscv/riscv/exception.S
+++ b/sys/riscv/riscv/exception.S
@@ -37,13 +37,19 @@
#include <machine/trap.h>
#include <machine/riscvreg.h>
+#include <machine/trap_cfi.h>
.macro save_registers mode
addi sp, sp, -(TF_SIZE)
+ .cfi_def_cfa_offset CFI_TF_SIZE
+ .cfi_undefined sp
sd ra, (TF_RA)(sp)
+ trap_cfi_saved ra, TF_RA
sd tp, (TF_TP)(sp)
+ trap_cfi_saved tp, TF_TP
sd gp, (TF_GP)(sp)
+ trap_cfi_saved gp, TF_GP
.if \mode == 0 /* We came from userspace. */
.option push
@@ -57,49 +63,79 @@
.endif
sd t0, (TF_T + 0 * 8)(sp)
+ trap_cfi_saved t0, TF_T + 0 * 8
sd t1, (TF_T + 1 * 8)(sp)
+ trap_cfi_saved t1, TF_T + 1 * 8
sd t2, (TF_T + 2 * 8)(sp)
+ trap_cfi_saved t2, TF_T + 2 * 8
sd t3, (TF_T + 3 * 8)(sp)
+ trap_cfi_saved t3, TF_T + 3 * 8
sd t4, (TF_T + 4 * 8)(sp)
+ trap_cfi_saved t4, TF_T + 4 * 8
sd t5, (TF_T + 5 * 8)(sp)
+ trap_cfi_saved t5, TF_T + 5 * 8
sd t6, (TF_T + 6 * 8)(sp)
+ trap_cfi_saved t6, TF_T + 6 * 8
sd s0, (TF_S + 0 * 8)(sp)
+ trap_cfi_saved s0, TF_S + 0 * 8
sd s1, (TF_S + 1 * 8)(sp)
+ trap_cfi_saved s1, TF_S + 1 * 8
sd s2, (TF_S + 2 * 8)(sp)
+ trap_cfi_saved s2, TF_S + 2 * 8
sd s3, (TF_S + 3 * 8)(sp)
+ trap_cfi_saved s3, TF_S + 3 * 8
sd s4, (TF_S + 4 * 8)(sp)
+ trap_cfi_saved s4, TF_S + 4 * 8
sd s5, (TF_S + 5 * 8)(sp)
+ trap_cfi_saved s5, TF_S + 5 * 8
sd s6, (TF_S + 6 * 8)(sp)
+ trap_cfi_saved s6, TF_S + 6 * 8
sd s7, (TF_S + 7 * 8)(sp)
+ trap_cfi_saved s7, TF_S + 7 * 8
sd s8, (TF_S + 8 * 8)(sp)
+ trap_cfi_saved s8, TF_S + 8 * 8
sd s9, (TF_S + 9 * 8)(sp)
+ trap_cfi_saved s9, TF_S + 9 * 8
sd s10, (TF_S + 10 * 8)(sp)
+ trap_cfi_saved s10, TF_S + 10 * 8
sd s11, (TF_S + 11 * 8)(sp)
+ trap_cfi_saved s11, TF_S + 11 * 8
sd a0, (TF_A + 0 * 8)(sp)
+ trap_cfi_saved a0, TF_A + 0 * 8
sd a1, (TF_A + 1 * 8)(sp)
+ trap_cfi_saved a1, TF_A + 1 * 8
sd a2, (TF_A + 2 * 8)(sp)
+ trap_cfi_saved a2, TF_A + 2 * 8
sd a3, (TF_A + 3 * 8)(sp)
+ trap_cfi_saved a3, TF_A + 3 * 8
sd a4, (TF_A + 4 * 8)(sp)
+ trap_cfi_saved a4, TF_A + 4 * 8
sd a5, (TF_A + 5 * 8)(sp)
+ trap_cfi_saved a5, TF_A + 5 * 8
sd a6, (TF_A + 6 * 8)(sp)
+ trap_cfi_saved a6, TF_A + 6 * 8
sd a7, (TF_A + 7 * 8)(sp)
+ trap_cfi_saved a7, TF_A + 7 * 8
.if \mode == 1
/* Store kernel sp */
li t1, TF_SIZE
add t0, sp, t1
sd t0, (TF_SP)(sp)
+ trap_cfi_saved sp, TF_SP
.else
/* Store user sp */
csrr t0, sscratch
sd t0, (TF_SP)(sp)
+ trap_cfi_saved sp, TF_SP
.endif
li t0, 0
csrw sscratch, t0
csrr t0, sepc
sd t0, (TF_SEPC)(sp)
+ .cfi_offset CFI_RA_COLUMN, TF_SEPC - CFI_TF_SIZE
csrr t0, sstatus
sd t0, (TF_SSTATUS)(sp)
.if \mode == 1
@@ -179,6 +215,8 @@
ld a7, (TF_A + 7 * 8)(sp)
addi sp, sp, (TF_SIZE)
+ /* CFI_TF_SIZE excludes the stack-alignment padding in TF_SIZE. */
+ .cfi_def_cfa_offset CFI_TF_SIZE - TF_SIZE
.endm
.macro do_ast
@@ -217,19 +255,25 @@
END(cpu_exception_handler)
ENTRY(cpu_exception_handler_supervisor)
+ trap_cfi_entry cpu_exception_handler_supervisor, empty
save_registers 1
mv a0, sp
call _C_LABEL(do_trap_supervisor)
load_registers 1
sret
+ trap_cfi_end cpu_exception_handler_supervisor
END(cpu_exception_handler_supervisor)
ENTRY(cpu_exception_handler_user)
+ trap_cfi_entry cpu_exception_handler_user, empty
save_registers 0
mv a0, sp
call _C_LABEL(do_trap_user)
do_ast
load_registers 0
csrrw sp, sscratch, sp
+ /* The trapframe is no longer addressable after switching to user sp. */
+ .cfi_undefined CFI_RA_COLUMN
sret
+ trap_cfi_end cpu_exception_handler_user
END(cpu_exception_handler_user)
diff --git a/sys/riscv/riscv/swtch.S b/sys/riscv/riscv/swtch.S
--- a/sys/riscv/riscv/swtch.S
+++ b/sys/riscv/riscv/swtch.S
@@ -38,6 +38,8 @@
#include <machine/asm.h>
#include <machine/riscvreg.h>
#include <machine/pte.h>
+#include <machine/trap_cfi.h>
+
.macro __fpe_state_save p
/*
* Enable FPE usage in supervisor mode,
@@ -415,6 +417,7 @@
*/
ENTRY(fork_trampoline)
+ trap_cfi_entry fork_trampoline, full
mv a0, s0
mv a1, s1
mv a2, sp
@@ -475,14 +478,29 @@
/* Save kernel stack so we can use it doing a user trap */
addi sp, sp, TF_SIZE
+ .cfi_def_cfa_offset CFI_TF_SIZE - TF_SIZE
csrw sscratch, sp
/* Load user stack */
ld sp, (TF_SP - TF_SIZE)(sp)
+ /* The trapframe is no longer addressable after switching to user sp. */
+ .cfi_undefined CFI_RA_COLUMN
sret
+ trap_cfi_end fork_trampoline
END(fork_trampoline)
+ENTRY(fork_trampoline_kthread)
+ trap_cfi_entry fork_trampoline_kthread, terminal
+ mv a0, s0
+ mv a1, s1
+ mv a2, sp
+ call _C_LABEL(fork_exit)
+ ebreak
+1: j 1b
+ trap_cfi_end fork_trampoline_kthread
+END(fork_trampoline_kthread)
+
ENTRY(savectx)
/* Store ra, sp and the callee-saved registers */
sd ra, (PCB_RA)(a0)
diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c
--- a/sys/riscv/riscv/vm_machdep.c
+++ b/sys/riscv/riscv/vm_machdep.c
@@ -126,7 +126,10 @@
/* Set the return value registers for fork() */
td2->td_pcb->pcb_s[0] = (uintptr_t)fork_return;
td2->td_pcb->pcb_s[1] = (uintptr_t)td2;
- td2->td_pcb->pcb_ra = (uintptr_t)fork_trampoline;
+ if ((td2->td_pflags & TDP_KTHREAD) != 0)
+ td2->td_pcb->pcb_ra = (uintptr_t)fork_trampoline_kthread;
+ else
+ td2->td_pcb->pcb_ra = (uintptr_t)fork_trampoline;
td2->td_pcb->pcb_sp = (uintptr_t)td2->td_frame;
if ((td1->td_pcb->pcb_vsflags & PCB_VS_STARTED) != 0)
@@ -189,7 +192,10 @@
td->td_pcb->pcb_s[0] = (uintptr_t)fork_return;
td->td_pcb->pcb_s[1] = (uintptr_t)td;
- td->td_pcb->pcb_ra = (uintptr_t)fork_trampoline;
+ if ((td->td_pflags & TDP_KTHREAD) != 0)
+ td->td_pcb->pcb_ra = (uintptr_t)fork_trampoline_kthread;
+ else
+ td->td_pcb->pcb_ra = (uintptr_t)fork_trampoline;
td->td_pcb->pcb_sp = (uintptr_t)td->td_frame;
/* Setup to release spin count in fork_exit(). */
@@ -265,7 +271,6 @@
td->td_pcb->pcb_s[0] = (uintptr_t)func;
td->td_pcb->pcb_s[1] = (uintptr_t)arg;
- td->td_pcb->pcb_ra = (uintptr_t)fork_trampoline;
td->td_pcb->pcb_sp = (uintptr_t)td->td_frame;
}

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 2, 4:33 PM (21 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41336291
Default Alt Text
D59647.1793637213.diff (10 KB)

Event Timeline