diff --git a/kernel/src/process/process_vm/init_stack/mod.rs b/kernel/src/process/process_vm/init_stack/mod.rs index 2fe7d9ec8..ee93db606 100644 --- a/kernel/src/process/process_vm/init_stack/mod.rs +++ b/kernel/src/process/process_vm/init_stack/mod.rs @@ -20,14 +20,10 @@ use core::{ use align_ext::AlignExt; use aster_rights::Full; -use ostd::{ - mm::{VmIo, MAX_USERSPACE_VADDR}, - task::Task, -}; +use ostd::mm::{vm_space::VmItem, VmIo, VmSpace, MAX_USERSPACE_VADDR}; use self::aux_vec::{AuxKey, AuxVec}; use crate::{ - get_current_userspace, prelude::*, util::random::getrandom, vm::{ @@ -187,10 +183,11 @@ impl InitStack { /// Constructs a reader to parse the content of an `InitStack`. /// The `InitStack` should only be read after initialized - pub(super) fn reader(&self) -> InitStackReader { + pub(super) fn reader<'a>(&self, vm_space: &'a Arc) -> InitStackReader<'a> { debug_assert!(self.is_initialized()); InitStackReader { base: self.pos(), + vm_space, map_addr: self.initial_top - self.max_size, } } @@ -366,17 +363,27 @@ fn generate_random_for_aux_vec() -> [u8; 16] { } /// A reader to parse the content of an `InitStack`. -pub struct InitStackReader { +pub struct InitStackReader<'a> { base: Vaddr, + vm_space: &'a Arc, /// The mapping address of the `InitStack`. map_addr: usize, } -impl InitStackReader { +impl InitStackReader<'_> { /// Reads argc from the process init stack pub fn argc(&self) -> Result { let stack_base = self.init_stack_bottom(); - get_current_userspace!().read_val(stack_base) + let page_base_addr = stack_base.align_down(PAGE_SIZE); + + let mut cursor = self + .vm_space + .cursor(&(page_base_addr..page_base_addr + PAGE_SIZE))?; + let VmItem::Mapped { frame, .. } = cursor.query()? else { + return_errno_with_message!(Errno::EACCES, "Page not accessible"); + }; + + Ok(frame.read_val::(stack_base - page_base_addr)?) } /// Reads argv from the process init stack @@ -387,15 +394,20 @@ impl InitStackReader { let read_offset = self.init_stack_bottom() + size_of::(); let mut argv = Vec::with_capacity(argc); + let page_base_addr = read_offset.align_down(PAGE_SIZE); + let mut cursor = self + .vm_space + .cursor(&(page_base_addr..page_base_addr + PAGE_SIZE))?; + let VmItem::Mapped { frame, .. } = cursor.query()? else { + return_errno_with_message!(Errno::EACCES, "Page not accessible"); + }; - let current_task = Task::current().unwrap(); - let user_space = CurrentUserSpace::new(¤t_task); - - let mut argv_reader = user_space.reader(read_offset, argc * size_of::())?; + let mut arg_ptr_reader = frame.reader().skip(read_offset - page_base_addr); for _ in 0..argc { let arg = { - let arg_ptr = argv_reader.read_val::()?; - user_space.read_cstring(arg_ptr, MAX_ARG_LEN)? + let arg_ptr = arg_ptr_reader.read_val::()?; + let mut arg_reader = frame.reader().skip(arg_ptr - page_base_addr).to_fallible(); + arg_reader.read_cstring()? }; argv.push(arg); } @@ -417,19 +429,26 @@ impl InitStackReader { + size_of::(); let mut envp = Vec::new(); + let page_base_addr = read_offset.align_down(PAGE_SIZE); + let mut cursor = self + .vm_space + .cursor(&(page_base_addr..page_base_addr + PAGE_SIZE))?; + let VmItem::Mapped { frame, .. } = cursor.query()? else { + return_errno_with_message!(Errno::EACCES, "Page not accessible"); + }; - let current_task = Task::current().unwrap(); - let user_space = CurrentUserSpace::new(¤t_task); - - let mut envp_reader = user_space.reader(read_offset, MAX_ENVP_NUMBER)?; + let mut envp_ptr_reader = frame.reader().skip(read_offset - page_base_addr); for _ in 0..MAX_ENVP_NUMBER { - let envp_ptr = envp_reader.read_val::()?; + let env = { + let envp_ptr = envp_ptr_reader.read_val::()?; - if envp_ptr == 0 { - break; - } + if envp_ptr == 0 { + break; + } - let env = user_space.read_cstring(envp_ptr, MAX_ENV_LEN)?; + let mut envp_reader = frame.reader().skip(envp_ptr - page_base_addr).to_fallible(); + envp_reader.read_cstring()? + }; envp.push(env); } diff --git a/kernel/src/process/process_vm/mod.rs b/kernel/src/process/process_vm/mod.rs index 07da2f2e3..59fdaf40d 100644 --- a/kernel/src/process/process_vm/mod.rs +++ b/kernel/src/process/process_vm/mod.rs @@ -111,7 +111,7 @@ impl ProcessVm { /// Returns a reader for reading contents from /// the `InitStack`. pub fn init_stack_reader(&self) -> InitStackReader { - self.init_stack.reader() + self.init_stack.reader(self.root_vmar().vm_space()) } /// Returns the top address of the user stack.