Handle kernel page fault on RISC-V platforms

This commit is contained in:
Zejun Zhao 2025-08-07 02:01:35 +08:00 committed by Ruihan Li
parent 1e183825d3
commit dd8de9f381
1 changed files with 23 additions and 0 deletions

View File

@ -20,6 +20,7 @@ use crate::{
},
cpu::{CpuId, PrivilegeLevel},
irq::call_irq_callback_functions,
mm::MAX_USERSPACE_VADDR,
};
/// Initializes interrupt handling on RISC-V.
@ -68,6 +69,15 @@ extern "C" fn trap_handler(f: &mut TrapFrame) {
enable_local_if(was_irq_enabled);
match exception {
CpuException::InstructionPageFault(fault_addr)
| CpuException::LoadPageFault(fault_addr)
| CpuException::StorePageFault(fault_addr) => {
if (0..MAX_USERSPACE_VADDR).contains(&fault_addr) {
handle_user_page_fault(f, &exception);
} else {
panic!("Cannot handle page fault in kernel space, exception: {:#x?}, trapframe: {:#x?}.", exception, f);
}
}
CpuException::Unknown => {
panic!(
"Cannot handle unknown exception, scause: {:#x}, trapframe: {:#x?}.",
@ -130,3 +140,16 @@ pub fn inject_user_page_fault_handler(
) {
USER_PAGE_FAULT_HANDLER.call_once(|| handler);
}
fn handle_user_page_fault(f: &mut TrapFrame, exception: &CpuException) {
let handler = USER_PAGE_FAULT_HANDLER
.get()
.expect("Page fault handler is missing");
handler(exception).unwrap_or_else(|_| {
panic!(
"Failed to handle page fault, exception: {:?}, trapframe: {:#x?}.",
exception, f
)
});
}