Handle kernel page fault on RISC-V platforms
This commit is contained in:
parent
1e183825d3
commit
dd8de9f381
|
|
@ -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
|
||||
)
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue