From dd8de9f381d202ca1e3d4043d34aabd4e3f7792f Mon Sep 17 00:00:00 2001 From: Zejun Zhao Date: Thu, 7 Aug 2025 02:01:35 +0800 Subject: [PATCH] Handle kernel page fault on RISC-V platforms --- ostd/src/arch/riscv/trap/mod.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ostd/src/arch/riscv/trap/mod.rs b/ostd/src/arch/riscv/trap/mod.rs index ce6fd90a4..be7d9f5ee 100644 --- a/ostd/src/arch/riscv/trap/mod.rs +++ b/ostd/src/arch/riscv/trap/mod.rs @@ -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 + ) + }); +}