forked from M-Labs/artiq
firmware: More explicit panic message if stack guard is tripped
This should give even only mildly technical users a chance to figure out what's going on, which empirically is not the case for a plain Exception(LoadFault) without further context.
This commit is contained in:
parent
6c47aac760
commit
950b9ac4d6
|
@ -471,6 +471,8 @@ unsafe fn attribute_writeback(typeinfo: *const ()) {
|
|||
}
|
||||
}
|
||||
|
||||
static mut STACK_GUARD_BASE: usize = 0x0;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn main() {
|
||||
eh_artiq::reset_exception_buffer(KERNELCPU_PAYLOAD_ADDRESS);
|
||||
|
@ -502,6 +504,7 @@ pub unsafe fn main() {
|
|||
ptr::write_bytes(__bss_start as *mut u8, 0, (_end - __bss_start) as usize);
|
||||
|
||||
board_misoc::pmp::init_stack_guard(_sstack_guard as usize);
|
||||
STACK_GUARD_BASE = _sstack_guard as usize;
|
||||
board_misoc::cache::flush_cpu_dcache();
|
||||
board_misoc::cache::flush_cpu_icache();
|
||||
|
||||
|
@ -531,10 +534,20 @@ pub unsafe fn main() {
|
|||
|
||||
#[no_mangle]
|
||||
#[unwind(allowed)]
|
||||
pub extern fn exception(_regs: *const u32) {
|
||||
pub unsafe extern fn exception(_regs: *const u32) {
|
||||
let pc = mepc::read();
|
||||
let cause = mcause::read().cause();
|
||||
let mtval = mtval::read();
|
||||
if let mcause::Trap::Exception(mcause::Exception::LoadFault)
|
||||
| mcause::Trap::Exception(mcause::Exception::StoreFault) = cause
|
||||
{
|
||||
if mtval >= STACK_GUARD_BASE
|
||||
&& mtval < (STACK_GUARD_BASE + board_misoc::pmp::STACK_GUARD_SIZE)
|
||||
{
|
||||
panic!("{:?} at PC {:#08x} in stack guard page ({:#08x}); stack overflow in user kernel code?",
|
||||
cause, u32::try_from(pc).unwrap(), mtval);
|
||||
}
|
||||
}
|
||||
panic!("{:?} at PC {:#08x}, trap value {:#08x}", cause, u32::try_from(pc).unwrap(), mtval);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ const PMP_W : usize = 0b00000010;
|
|||
const PMP_R : usize = 0b00000001;
|
||||
const PMP_OFF : usize = 0b00000000;
|
||||
|
||||
pub const STACK_GUARD_SIZE: usize = 0x1000;
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn init_stack_guard(guard_base: usize) {
|
||||
pmpaddr2::write((guard_base >> 2) | ((0x1000 - 1) >> 3));
|
||||
|
|
Loading…
Reference in New Issue