Enable RISC-V stack unwinding on panic

This commit is contained in:
Zejun Zhao 2025-08-28 00:15:24 +08:00 committed by Junyang Zhang
parent 05f053c56d
commit 920ec7f521
5 changed files with 22 additions and 8 deletions

View File

@ -83,7 +83,7 @@ CARGO_OSDK_COMMON_ARGS += --profile release-lto
OSTD_TASK_STACK_SIZE_IN_PAGES = 8
else ifeq ($(RELEASE), 1)
CARGO_OSDK_COMMON_ARGS += --release
OSTD_TASK_STACK_SIZE_IN_PAGES = 8
OSTD_TASK_STACK_SIZE_IN_PAGES = 16
endif
# If the BENCHMARK is set, we will run the benchmark in the kernel mode.

View File

@ -34,10 +34,6 @@ SECTIONS
*(.rodata .rodata.*)
}
.eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - KERNEL_VMA_OFFSET) {
PROVIDE(__GNU_EH_FRAME_HDR = .);
KEEP(*(.eh_frame_hdr .eh_frame_hdr.*))
}
. = ALIGN(8);
.eh_frame : AT(ADDR(.eh_frame) - KERNEL_VMA_OFFSET) {
PROVIDE(__eh_frame = .);

View File

@ -65,7 +65,7 @@ unwinding = { version = "=0.2.5", default-features = false, features = ["fde-gnu
riscv = { version = "0.11.1", features = ["s-mode"] }
sbi-rt = "0.0.3"
fdt = { version = "0.1.5", features = ["pretty-printing"] }
unwinding = { version = "=0.2.5", default-features = false, features = ["fde-gnu-eh-frame-hdr", "hide-trace", "panic", "personality", "unwinder"] }
unwinding = { version = "=0.2.5", default-features = false, features = ["fde-static", "hide-trace", "panic", "personality", "unwinder"] }
[target.loongarch64-unknown-none-softfloat.dependencies]
loongArch64 = "0.2.5"

View File

@ -3,6 +3,7 @@
.text
.global context_switch
.global first_context_switch
.global kernel_task_entry_wrapper
context_switch: # (nxt: *const TaskContext, cur: *mut TaskContext)
# Save cur's register
@ -39,3 +40,9 @@ first_context_switch: # (nxt: *const TaskContext)
ld s10, 0x58(a0)
ld s11, 0x60(a0)
ret
kernel_task_entry_wrapper:
.cfi_startproc
.cfi_undefined ra # mark return address as undefined to indicate end of call stack
call kernel_task_entry
.cfi_endproc

View File

@ -161,8 +161,11 @@ impl TaskOptions {
/// Builds a new task without running it immediately.
pub fn build(self) -> Result<Task> {
/// all task will entering this function
/// this function is mean to executing the task_fn in Task
// All tasks will enter this function. It is meant to execute the `task_fn` in `Task`.
//
// RISC-V provides an assembly wrapper for this function as the end of call stack so
// we have to disable name mangling for it on RISC-V.
#[cfg_attr(target_arch = "riscv64", no_mangle)]
extern "C" fn kernel_task_entry() -> ! {
// SAFETY: The new task is switched on a CPU for the first time, `after_switching_to`
// hasn't been called yet.
@ -188,10 +191,18 @@ impl TaskOptions {
scheduler::exit_current();
}
#[cfg(target_arch = "riscv64")]
extern "C" {
fn kernel_task_entry_wrapper();
}
let kstack = KernelStack::new_with_guard_page()?;
let mut ctx = TaskContext::new();
#[cfg(not(target_arch = "riscv64"))]
ctx.set_instruction_pointer(kernel_task_entry as usize);
#[cfg(target_arch = "riscv64")]
ctx.set_instruction_pointer(kernel_task_entry_wrapper as usize);
// We should reserve space for the return address in the stack, otherwise
// we will write across the page boundary due to the implementation of
// the context switch.