diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index c825a25ba..4d5a9f902 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -92,6 +92,7 @@ pub fn main() { } pub fn init() { + thread::init(); util::random::init(); driver::init(); time::init(); diff --git a/kernel/src/thread/exception.rs b/kernel/src/thread/exception.rs index 97d04bb3c..72cd167d3 100644 --- a/kernel/src/thread/exception.rs +++ b/kernel/src/thread/exception.rs @@ -3,9 +3,10 @@ #![expect(unused_variables)] use aster_rights::Full; -use ostd::{cpu::*, mm::VmSpace, task::Task}; +use ostd::cpu::*; use crate::{ + current_userspace, prelude::*, process::signal::signals::fault::FaultSignal, vm::{page_fault_handler::PageFaultHandler, perms::VmPerms, vmar::Vmar}, @@ -41,26 +42,8 @@ pub fn handle_exception(ctx: &Context, context: &UserContext) { generate_fault_signal(trap_info, ctx); } -/// Handles the page fault occurs in the input `VmSpace`. -pub(crate) fn handle_page_fault_from_vm_space( - vm_space: &VmSpace, - page_fault_info: &PageFaultInfo, -) -> core::result::Result<(), ()> { - let task = Task::current().unwrap(); - let current_root_vmar = task.as_thread_local().unwrap().root_vmar().borrow(); - let root_vmar = current_root_vmar.as_ref().unwrap(); - - // If page is not present or due to write access, we should ask the vmar try to commit this page - debug_assert_eq!( - Arc::as_ptr(root_vmar.vm_space()), - vm_space as *const VmSpace - ); - - handle_page_fault_from_vmar(root_vmar, page_fault_info) -} - /// Handles the page fault occurs in the input `Vmar`. -pub(crate) fn handle_page_fault_from_vmar( +fn handle_page_fault_from_vmar( root_vmar: &Vmar, page_fault_info: &PageFaultInfo, ) -> core::result::Result<(), ()> { @@ -92,3 +75,7 @@ fn log_trap_info(trap_info: &CpuExceptionInfo) { trace!("[Trap][{exception:?}][err = {}]", trap_info.error_code) } } + +pub(super) fn page_fault_handler(info: &CpuExceptionInfo) -> core::result::Result<(), ()> { + handle_page_fault_from_vmar(current_userspace!().root_vmar(), &info.try_into().unwrap()) +} diff --git a/kernel/src/thread/mod.rs b/kernel/src/thread/mod.rs index 5bbe455ce..12fe30bd6 100644 --- a/kernel/src/thread/mod.rs +++ b/kernel/src/thread/mod.rs @@ -24,6 +24,23 @@ pub mod work_queue; pub type Tid = u32; +fn post_schedule_handler() { + let task = Task::current().unwrap(); + let Some(thread_local) = task.as_thread_local() else { + return; + }; + + let root_vmar = thread_local.root_vmar().borrow(); + if let Some(vmar) = root_vmar.as_ref() { + vmar.vm_space().activate() + } +} + +pub(super) fn init() { + ostd::task::inject_post_schedule_handler(post_schedule_handler); + ostd::arch::trap::inject_user_page_fault_handler(exception::page_fault_handler); +} + /// A thread is a wrapper on top of task. #[derive(Debug)] pub struct Thread { diff --git a/kernel/src/vm/vmar/mod.rs b/kernel/src/vm/vmar/mod.rs index 99fd88704..ed033811a 100644 --- a/kernel/src/vm/vmar/mod.rs +++ b/kernel/src/vm/vmar/mod.rs @@ -11,10 +11,7 @@ use core::{num::NonZeroUsize, ops::Range}; use align_ext::AlignExt; use aster_rights::Rights; -use ostd::{ - cpu::CpuExceptionInfo, - mm::{tlb::TlbFlushOp, PageFlags, PageProperty, VmSpace, MAX_USERSPACE_VADDR}, -}; +use ostd::mm::{tlb::TlbFlushOp, PageFlags, PageProperty, VmSpace, MAX_USERSPACE_VADDR}; use self::{ interval_set::{Interval, IntervalSet}, @@ -24,7 +21,7 @@ use super::page_fault_handler::PageFaultHandler; use crate::{ prelude::*, process::{Process, ResourceType}, - thread::exception::{handle_page_fault_from_vm_space, PageFaultInfo}, + thread::exception::PageFaultInfo, vm::{ perms::VmPerms, vmo::{Vmo, VmoRightsOp}, @@ -305,7 +302,7 @@ impl Vmar_ { fn new_root() -> Arc { let vmar_inner = VmarInner::new(); - let mut vm_space = VmSpace::new(); + let vm_space = VmSpace::new(); Vmar_::new(vmar_inner, Arc::new(vm_space), 0, ROOT_VMAR_CAP_ADDR) } @@ -429,7 +426,7 @@ impl Vmar_ { pub(super) fn new_fork_root(self: &Arc) -> Result> { let new_vmar_ = { let vmar_inner = VmarInner::new(); - let mut new_space = VmSpace::new(); + let new_space = VmSpace::new(); Vmar_::new(vmar_inner, Arc::new(new_space), self.base, self.size) }; @@ -466,14 +463,6 @@ impl Vmar_ { } } -/// This is for fallible user space write handling. -fn handle_page_fault_wrapper( - vm_space: &VmSpace, - trap_info: &CpuExceptionInfo, -) -> core::result::Result<(), ()> { - handle_page_fault_from_vm_space(vm_space, &trap_info.try_into().unwrap()) -} - impl Vmar { /// The base address, i.e., the offset relative to the root VMAR. ///