diff --git a/kernel/aster-nix/src/context.rs b/kernel/aster-nix/src/context.rs new file mode 100644 index 000000000..fb4e84751 --- /dev/null +++ b/kernel/aster-nix/src/context.rs @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: MPL-2.0 + +//! The context that can be accessed from the current task, thread or process. + +use core::mem; + +use ostd::{ + mm::{UserSpace, VmReader, VmSpace, VmWriter}, + task::Task, +}; + +use crate::{ + prelude::*, + process::{posix_thread::PosixThread, Process}, + thread::Thread, +}; + +/// The context that can be accessed from the current POSIX thread. +#[derive(Clone, Copy)] +pub struct Context<'a> { + pub process: &'a Process, + pub posix_thread: &'a PosixThread, + pub thread: &'a Thread, + pub task: &'a Task, +} + +impl Context<'_> { + /// Gets the userspace of the current task. + pub fn get_user_space(&self) -> CurrentUserSpace { + CurrentUserSpace(self.task.user_space().unwrap().vm_space().clone()) + } +} + +/// The user's memory space of the current task. +/// +/// It provides methods to read from or write to the user space efficiently. +pub struct CurrentUserSpace(Arc); + +impl !Sync for CurrentUserSpace {} +impl !Send for CurrentUserSpace {} + +impl CurrentUserSpace { + /// Gets the `CurrentUserSpace` from the current task. + /// + /// This is slower than [`Context::get_user_space`]. Don't use this getter + /// If you get the access to the [`Context`]. + pub fn get() -> Self { + let vm_space = { + let current_task = Task::current().unwrap(); + let user_space = current_task.user_space().unwrap(); + user_space.vm_space().clone() + }; + Self(vm_space) + } + + /// Creates a reader to read data from the user space of the current task. + /// + /// Returns `Err` if the `vaddr` and `len` do not represent a user space memory range. + pub fn reader(&self, vaddr: Vaddr, len: usize) -> Result> { + Ok(self.0.reader(vaddr, len)?) + } + + /// Creates a writer to write data into the user space. + /// + /// Returns `Err` if the `vaddr` and `len` do not represent a user space memory range. + pub fn writer(&self, vaddr: Vaddr, len: usize) -> Result> { + Ok(self.0.writer(vaddr, len)?) + } + + /// Reads bytes into the destination `VmWriter` from the user space of the + /// current process. + /// + /// If the reading is completely successful, returns `Ok`. Otherwise, it + /// returns `Err`. + /// + /// If the destination `VmWriter` (`dest`) is empty, this function still + /// checks if the current task and user space are available. If they are, + /// it returns `Ok`. + pub fn read_bytes(&self, src: Vaddr, dest: &mut VmWriter<'_>) -> Result<()> { + let copy_len = dest.avail(); + + if copy_len > 0 { + check_vaddr(src)?; + } + + let mut user_reader = self.reader(src, copy_len)?; + user_reader.read_fallible(dest).map_err(|err| err.0)?; + Ok(()) + } + + /// Reads a value typed `Pod` from the user space of the current process. + pub fn read_val(&self, src: Vaddr) -> Result { + if core::mem::size_of::() > 0 { + check_vaddr(src)?; + } + + let mut user_reader = self.reader(src, core::mem::size_of::())?; + Ok(user_reader.read_val()?) + } + + /// Writes bytes from the source `VmReader` to the user space of the current + /// process. + /// + /// If the writing is completely successful, returns `Ok`. Otherwise, it + /// returns `Err`. + /// + /// If the source `VmReader` (`src`) is empty, this function still checks if + /// the current task and user space are available. If they are, it returns + /// `Ok`. + pub fn write_bytes(&self, dest: Vaddr, src: &mut VmReader<'_>) -> Result<()> { + let copy_len = src.remain(); + + if copy_len > 0 { + check_vaddr(dest)?; + } + + let mut user_writer = self.writer(dest, copy_len)?; + user_writer.write_fallible(src).map_err(|err| err.0)?; + Ok(()) + } + + /// Writes `val` to the user space of the current process. + pub fn write_val(&self, dest: Vaddr, val: &T) -> Result<()> { + if core::mem::size_of::() > 0 { + check_vaddr(dest)?; + } + + let mut user_writer = self.writer(dest, core::mem::size_of::())?; + Ok(user_writer.write_val(val)?) + } + + /// Reads a C string from the user space of the current process. + /// The length of the string should not exceed `max_len`, + /// including the final `\0` byte. + pub fn read_cstring(&self, vaddr: Vaddr, max_len: usize) -> Result { + if max_len > 0 { + check_vaddr(vaddr)?; + } + + let mut user_reader = self.reader(vaddr, max_len)?; + user_reader.read_cstring() + } +} + +/// A trait providing the ability to read a C string from the user space +/// of the current process specifically for [`VmReader<'_, UserSpace>`], which +/// should reading the bytes iteratively in the reader until encountering +/// the end of the reader or reading a `\0` (is also included into the final C String). +pub trait ReadCString { + fn read_cstring(&mut self) -> Result; +} + +impl<'a> ReadCString for VmReader<'a, UserSpace> { + /// This implementation is inspired by + /// the `do_strncpy_from_user` function in Linux kernel. + /// The original Linux implementation can be found at: + /// + fn read_cstring(&mut self) -> Result { + let max_len = self.remain(); + let mut buffer: Vec = Vec::with_capacity(max_len); + + macro_rules! read_one_byte_at_a_time_while { + ($cond:expr) => { + while $cond { + let byte = self.read_val::()?; + buffer.push(byte); + if byte == 0 { + return Ok(CString::from_vec_with_nul(buffer) + .expect("We provided 0 but no 0 is found")); + } + } + }; + } + + // Handle the first few bytes to make `cur_addr` aligned with `size_of::` + read_one_byte_at_a_time_while!( + (self.cursor() as usize) % mem::size_of::() != 0 && buffer.len() < max_len + ); + + // Handle the rest of the bytes in bulk + while (buffer.len() + mem::size_of::()) <= max_len { + let Ok(word) = self.read_val::() else { + break; + }; + + if has_zero(word) { + for byte in word.to_ne_bytes() { + buffer.push(byte); + if byte == 0 { + return Ok(CString::from_vec_with_nul(buffer) + .expect("We provided 0 but no 0 is found")); + } + } + unreachable!("The branch should never be reached unless `has_zero` has bugs.") + } + + buffer.extend_from_slice(&word.to_ne_bytes()); + } + + // Handle the last few bytes that are not enough for a word + read_one_byte_at_a_time_while!(buffer.len() < max_len); + + // Maximum length exceeded before finding the null terminator + return_errno_with_message!(Errno::EFAULT, "Fails to read CString from user"); + } +} + +/// Determines whether the value contains a zero byte. +/// +/// This magic algorithm is from the Linux `has_zero` function: +/// +const fn has_zero(value: usize) -> bool { + const ONE_BITS: usize = usize::from_le_bytes([0x01; mem::size_of::()]); + const HIGH_BITS: usize = usize::from_le_bytes([0x80; mem::size_of::()]); + + value.wrapping_sub(ONE_BITS) & !value & HIGH_BITS != 0 +} + +/// Checks if the user space pointer is below the lowest userspace address. +/// +/// If a pointer is below the lowest userspace address, it is likely to be a +/// NULL pointer. Reading from or writing to a NULL pointer should trigger a +/// segmentation fault. +/// +/// If it is not checked here, a kernel page fault will happen and we would +/// deny the access in the page fault handler either. It may save a page fault +/// in some occasions. More importantly, double page faults may not be handled +/// quite well on some platforms. +fn check_vaddr(va: Vaddr) -> Result<()> { + if va < crate::vm::vmar::ROOT_VMAR_LOWEST_ADDR { + Err(Error::with_message( + Errno::EFAULT, + "Bad user space pointer specified", + )) + } else { + Ok(()) + } +} diff --git a/kernel/aster-nix/src/lib.rs b/kernel/aster-nix/src/lib.rs index 9e592a1df..ac2872b28 100644 --- a/kernel/aster-nix/src/lib.rs +++ b/kernel/aster-nix/src/lib.rs @@ -48,6 +48,7 @@ extern crate getset; pub mod arch; pub mod console; +pub mod context; pub mod cpu; pub mod device; pub mod driver; diff --git a/kernel/aster-nix/src/prelude.rs b/kernel/aster-nix/src/prelude.rs index 316173652..abfa8524d 100644 --- a/kernel/aster-nix/src/prelude.rs +++ b/kernel/aster-nix/src/prelude.rs @@ -50,11 +50,11 @@ macro_rules! current_thread { pub(crate) use lazy_static::lazy_static; pub(crate) use crate::{ + context::{Context, CurrentUserSpace, ReadCString}, current, current_thread, error::{Errno, Error}, print, println, time::{wait::WaitTimeout, Clock}, - util::{CurrentUserSpace, ReadCString}, }; pub(crate) type Result = core::result::Result; pub(crate) use crate::{return_errno, return_errno_with_message}; diff --git a/kernel/aster-nix/src/process/clone.rs b/kernel/aster-nix/src/process/clone.rs index 409eefc35..70d1be2f7 100644 --- a/kernel/aster-nix/src/process/clone.rs +++ b/kernel/aster-nix/src/process/clone.rs @@ -1,7 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -#![allow(unused_variables)] - use core::sync::atomic::Ordering; use ostd::{ @@ -19,7 +17,6 @@ use super::{ }; use crate::{ cpu::LinuxAbi, - current_thread, fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask}, prelude::*, thread::{allocate_tid, thread_table, Thread, Tid}, @@ -129,16 +126,20 @@ impl CloneFlags { /// /// FIXME: currently, the child process or thread will be scheduled to run at once, /// but this may not be the expected bahavior. -pub fn clone_child(parent_context: &UserContext, clone_args: CloneArgs) -> Result { +pub fn clone_child( + ctx: &Context, + parent_context: &UserContext, + clone_args: CloneArgs, +) -> Result { clone_args.clone_flags.check_unsupported_flags()?; if clone_args.clone_flags.contains(CloneFlags::CLONE_THREAD) { - let child_thread = clone_child_thread(parent_context, clone_args)?; + let child_thread = clone_child_thread(ctx, parent_context, clone_args)?; child_thread.run(); let child_tid = child_thread.tid(); Ok(child_tid) } else { - let child_process = clone_child_process(parent_context, clone_args)?; + let child_process = clone_child_process(ctx, parent_context, clone_args)?; child_process.run(); let child_pid = child_process.pid(); @@ -146,13 +147,23 @@ pub fn clone_child(parent_context: &UserContext, clone_args: CloneArgs) -> Resul } } -fn clone_child_thread(parent_context: &UserContext, clone_args: CloneArgs) -> Result> { +fn clone_child_thread( + ctx: &Context, + parent_context: &UserContext, + clone_args: CloneArgs, +) -> Result> { + let Context { + process, + posix_thread, + thread: _, + task: _, + } = ctx; + let clone_flags = clone_args.clone_flags; - let current = current!(); debug_assert!(clone_flags.contains(CloneFlags::CLONE_VM)); debug_assert!(clone_flags.contains(CloneFlags::CLONE_FILES)); debug_assert!(clone_flags.contains(CloneFlags::CLONE_SIGHAND)); - let child_root_vmar = current.root_vmar(); + let child_root_vmar = process.root_vmar(); let child_user_space = { let child_vm_space = child_root_vmar.vm_space().clone(); @@ -168,14 +179,7 @@ fn clone_child_thread(parent_context: &UserContext, clone_args: CloneArgs) -> Re clone_sysvsem(clone_flags)?; // Inherit sigmask from current thread - let sig_mask = { - let current_thread = current_thread!(); - let current_posix_thread = current_thread.as_posix_thread().unwrap(); - current_posix_thread - .sig_mask() - .load(Ordering::Relaxed) - .into() - }; + let sig_mask = posix_thread.sig_mask().load(Ordering::Relaxed).into(); let child_tid = allocate_tid(); let child_thread = { @@ -185,12 +189,12 @@ fn clone_child_thread(parent_context: &UserContext, clone_args: CloneArgs) -> Re }; let thread_builder = PosixThreadBuilder::new(child_tid, child_user_space, credentials) - .process(Arc::downgrade(¤t)) + .process(posix_thread.weak_process()) .sig_mask(sig_mask); thread_builder.build() }; - current.threads().lock().push(child_thread.clone()); + process.threads().lock().push(child_thread.clone()); let child_posix_thread = child_thread.as_posix_thread().unwrap(); clone_parent_settid(child_tid, clone_args.parent_tidptr, clone_flags)?; @@ -200,16 +204,22 @@ fn clone_child_thread(parent_context: &UserContext, clone_args: CloneArgs) -> Re } fn clone_child_process( + ctx: &Context, parent_context: &UserContext, clone_args: CloneArgs, ) -> Result> { - let current = current!(); - let parent = Arc::downgrade(¤t); + let Context { + process, + posix_thread, + thread: _, + task: _, + } = ctx; + let clone_flags = clone_args.clone_flags; // clone vm let child_process_vm = { - let parent_process_vm = current.vm(); + let parent_process_vm = process.vm(); clone_vm(parent_process_vm, clone_flags)? }; @@ -230,37 +240,33 @@ fn clone_child_process( }; // clone file table - let child_file_table = clone_files(current.file_table(), clone_flags); + let child_file_table = clone_files(process.file_table(), clone_flags); // clone fs - let child_fs = clone_fs(current.fs(), clone_flags); + let child_fs = clone_fs(process.fs(), clone_flags); // clone umask let child_umask = { - let parent_umask = current.umask().read().get(); + let parent_umask = process.umask().read().get(); Arc::new(RwLock::new(FileCreationMask::new(parent_umask))) }; // clone sig dispositions - let child_sig_dispositions = clone_sighand(current.sig_dispositions(), clone_flags); + let child_sig_dispositions = clone_sighand(process.sig_dispositions(), clone_flags); // clone system V semaphore clone_sysvsem(clone_flags)?; // inherit parent's sig mask - let child_sig_mask = { - let current_thread = current_thread!(); - let posix_thread = current_thread.as_posix_thread().unwrap(); - posix_thread.sig_mask().load(Ordering::Relaxed).into() - }; + let child_sig_mask = posix_thread.sig_mask().load(Ordering::Relaxed).into(); // inherit parent's nice value - let child_nice = current.nice().load(Ordering::Relaxed); + let child_nice = process.nice().load(Ordering::Relaxed); let child_tid = allocate_tid(); let child = { - let child_elf_path = current.executable_path(); + let child_elf_path = process.executable_path(); let child_thread_builder = { let child_thread_name = ThreadName::new_from_executable_path(&child_elf_path)?; @@ -275,7 +281,7 @@ fn clone_child_process( }; let mut process_builder = - ProcessBuilder::new(child_tid, &child_elf_path, Arc::downgrade(¤t)); + ProcessBuilder::new(child_tid, &child_elf_path, posix_thread.weak_process()); process_builder .main_thread_builder(child_thread_builder) @@ -297,7 +303,7 @@ fn clone_child_process( clone_child_settid(child_posix_thread, clone_args.child_tidptr, clone_flags)?; // Sets parent process and group for child process. - set_parent_and_group(¤t, &child); + set_parent_and_group(process, &child); Ok(child) } @@ -421,7 +427,7 @@ fn clone_sysvsem(clone_flags: CloneFlags) -> Result<()> { Ok(()) } -fn set_parent_and_group(parent: &Arc, child: &Arc) { +fn set_parent_and_group(parent: &Process, child: &Arc) { let process_group = parent.process_group().unwrap(); let mut process_table_mut = process_table::process_table_mut(); diff --git a/kernel/aster-nix/src/process/posix_thread/mod.rs b/kernel/aster-nix/src/process/posix_thread/mod.rs index 32b52e299..25c076bac 100644 --- a/kernel/aster-nix/src/process/posix_thread/mod.rs +++ b/kernel/aster-nix/src/process/posix_thread/mod.rs @@ -80,6 +80,10 @@ impl PosixThread { self.process.upgrade().unwrap() } + pub fn weak_process(&self) -> Weak { + Weak::clone(&self.process) + } + pub fn thread_name(&self) -> &Mutex> { &self.name } diff --git a/kernel/aster-nix/src/process/posix_thread/name.rs b/kernel/aster-nix/src/process/posix_thread/name.rs index 6cc4347e6..fa5005e03 100644 --- a/kernel/aster-nix/src/process/posix_thread/name.rs +++ b/kernel/aster-nix/src/process/posix_thread/name.rs @@ -10,6 +10,12 @@ pub struct ThreadName { count: usize, } +impl Default for ThreadName { + fn default() -> Self { + ThreadName::new() + } +} + impl ThreadName { pub fn new() -> Self { ThreadName { diff --git a/kernel/aster-nix/src/syscall/accept.rs b/kernel/aster-nix/src/syscall/accept.rs index df9f6fc12..413f55d33 100644 --- a/kernel/aster-nix/src/syscall/accept.rs +++ b/kernel/aster-nix/src/syscall/accept.rs @@ -14,6 +14,7 @@ pub fn sys_accept( sockfd: FileDesc, sockaddr_ptr: Vaddr, addrlen_ptr: Vaddr, + _ctx: &Context, ) -> Result { debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); @@ -26,6 +27,7 @@ pub fn sys_accept4( sockaddr_ptr: Vaddr, addrlen_ptr: Vaddr, flags: u32, + _ctx: &Context, ) -> Result { trace!("raw flags = 0x{:x}", flags); let flags = Flags::from_bits_truncate(flags); diff --git a/kernel/aster-nix/src/syscall/access.rs b/kernel/aster-nix/src/syscall/access.rs index a3153bc14..5ed0c8534 100644 --- a/kernel/aster-nix/src/syscall/access.rs +++ b/kernel/aster-nix/src/syscall/access.rs @@ -10,7 +10,12 @@ use crate::{ prelude::*, }; -pub fn sys_faccessat(dirfd: FileDesc, path_ptr: Vaddr, mode: u16) -> Result { +pub fn sys_faccessat( + dirfd: FileDesc, + path_ptr: Vaddr, + mode: u16, + _ctx: &Context, +) -> Result { debug!( "faccessat: dirfd = {}, path_ptr = {:#x}, mode = {:o}", dirfd, path_ptr, mode @@ -19,7 +24,7 @@ pub fn sys_faccessat(dirfd: FileDesc, path_ptr: Vaddr, mode: u16) -> Result Result { +pub fn sys_access(path_ptr: Vaddr, mode: u16, _ctx: &Context) -> Result { debug!("access: path_ptr = {:#x}, mode = {:o}", path_ptr, mode); do_faccessat(AT_FDCWD, path_ptr, mode, 0) diff --git a/kernel/aster-nix/src/syscall/alarm.rs b/kernel/aster-nix/src/syscall/alarm.rs index f1cc6e29c..9e115d984 100644 --- a/kernel/aster-nix/src/syscall/alarm.rs +++ b/kernel/aster-nix/src/syscall/alarm.rs @@ -5,7 +5,7 @@ use core::time::Duration; use super::SyscallReturn; use crate::{prelude::*, time::timer::Timeout}; -pub fn sys_alarm(seconds: u32) -> Result { +pub fn sys_alarm(seconds: u32, _ctx: &Context) -> Result { debug!("seconds = {}", seconds); let current = current!(); diff --git a/kernel/aster-nix/src/syscall/arch/x86.rs b/kernel/aster-nix/src/syscall/arch/x86.rs index f342a91e4..249343a7e 100644 --- a/kernel/aster-nix/src/syscall/arch/x86.rs +++ b/kernel/aster-nix/src/syscall/arch/x86.rs @@ -145,7 +145,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_BRK = 12 => sys_brk(args[..1]); SYS_RT_SIGACTION = 13 => sys_rt_sigaction(args[..4]); SYS_RT_SIGPROCMASK = 14 => sys_rt_sigprocmask(args[..4]); - SYS_RT_SIGRETURN = 15 => sys_rt_sigreturn(args[..0], &mut context); + SYS_RT_SIGRETURN = 15 => sys_rt_sigreturn(args[..0], &mut user_ctx); SYS_IOCTL = 16 => sys_ioctl(args[..3]); SYS_PREAD64 = 17 => sys_pread64(args[..4]); SYS_PWRITE64 = 18 => sys_pwrite64(args[..4]); @@ -180,9 +180,9 @@ impl_syscall_nums_and_dispatch_fn! { SYS_SOCKETPAIR = 53 => sys_socketpair(args[..4]); SYS_SETSOCKOPT = 54 => sys_setsockopt(args[..5]); SYS_GETSOCKOPT = 55 => sys_getsockopt(args[..5]); - SYS_CLONE = 56 => sys_clone(args[..5], &context); - SYS_FORK = 57 => sys_fork(args[..0], &context); - SYS_EXECVE = 59 => sys_execve(args[..3], &mut context); + SYS_CLONE = 56 => sys_clone(args[..5], &user_ctx); + SYS_FORK = 57 => sys_fork(args[..0], &user_ctx); + SYS_EXECVE = 59 => sys_execve(args[..3], &mut user_ctx); SYS_EXIT = 60 => sys_exit(args[..1]); SYS_WAIT4 = 61 => sys_wait4(args[..4]); SYS_KILL = 62 => sys_kill(args[..2]); @@ -245,7 +245,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_GET_PRIORITY = 140 => sys_get_priority(args[..2]); SYS_SET_PRIORITY = 141 => sys_set_priority(args[..3]); SYS_PRCTL = 157 => sys_prctl(args[..5]); - SYS_ARCH_PRCTL = 158 => sys_arch_prctl(args[..2], &mut context); + SYS_ARCH_PRCTL = 158 => sys_arch_prctl(args[..2], &mut user_ctx); SYS_CHROOT = 161 => sys_chroot(args[..1]); SYS_SYNC = 162 => sys_sync(args[..0]); SYS_MOUNT = 165 => sys_mount(args[..5]); @@ -297,8 +297,8 @@ impl_syscall_nums_and_dispatch_fn! { SYS_PWRITEV = 296 => sys_pwritev(args[..4]); SYS_PRLIMIT64 = 302 => sys_prlimit64(args[..4]); SYS_GETRANDOM = 318 => sys_getrandom(args[..3]); - SYS_EXECVEAT = 322 => sys_execveat(args[..5], &mut context); + SYS_EXECVEAT = 322 => sys_execveat(args[..5], &mut user_ctx); SYS_PREADV2 = 327 => sys_preadv2(args[..5]); SYS_PWRITEV2 = 328 => sys_pwritev2(args[..5]); - SYS_CLONE3 = 435 => sys_clone3(args[..2], &context); + SYS_CLONE3 = 435 => sys_clone3(args[..2], &user_ctx); } diff --git a/kernel/aster-nix/src/syscall/arch_prctl.rs b/kernel/aster-nix/src/syscall/arch_prctl.rs index 64b0f00cb..fbd84bfb0 100644 --- a/kernel/aster-nix/src/syscall/arch_prctl.rs +++ b/kernel/aster-nix/src/syscall/arch_prctl.rs @@ -15,23 +15,28 @@ pub enum ArchPrctlCode { ARCH_GET_GS = 0x1004, } -pub fn sys_arch_prctl(code: u64, addr: u64, context: &mut UserContext) -> Result { +pub fn sys_arch_prctl( + code: u64, + addr: u64, + _ctx: &Context, + user_ctx: &mut UserContext, +) -> Result { let arch_prctl_code = ArchPrctlCode::try_from(code)?; debug!( "arch_prctl_code: {:?}, addr = 0x{:x}", arch_prctl_code, addr ); - let res = do_arch_prctl(arch_prctl_code, addr, context).unwrap(); + let res = do_arch_prctl(arch_prctl_code, addr, user_ctx).unwrap(); Ok(SyscallReturn::Return(res as _)) } -pub fn do_arch_prctl(code: ArchPrctlCode, addr: u64, context: &mut UserContext) -> Result { +pub fn do_arch_prctl(code: ArchPrctlCode, addr: u64, ctx: &mut UserContext) -> Result { match code { ArchPrctlCode::ARCH_SET_FS => { - context.set_tls_pointer(addr as usize); + ctx.set_tls_pointer(addr as usize); Ok(0) } - ArchPrctlCode::ARCH_GET_FS => Ok(context.tls_pointer() as u64), + ArchPrctlCode::ARCH_GET_FS => Ok(ctx.tls_pointer() as u64), ArchPrctlCode::ARCH_GET_GS | ArchPrctlCode::ARCH_SET_GS => { return_errno_with_message!(Errno::EINVAL, "GS cannot be accessed from the user space") } diff --git a/kernel/aster-nix/src/syscall/bind.rs b/kernel/aster-nix/src/syscall/bind.rs index e5320d051..3d3a87bc2 100644 --- a/kernel/aster-nix/src/syscall/bind.rs +++ b/kernel/aster-nix/src/syscall/bind.rs @@ -7,7 +7,12 @@ use crate::{ util::net::{get_socket_from_fd, read_socket_addr_from_user}, }; -pub fn sys_bind(sockfd: FileDesc, sockaddr_ptr: Vaddr, addrlen: u32) -> Result { +pub fn sys_bind( + sockfd: FileDesc, + sockaddr_ptr: Vaddr, + addrlen: u32, + _ctx: &Context, +) -> Result { let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addrlen as usize)?; debug!("sockfd = {sockfd}, socket_addr = {socket_addr:?}"); diff --git a/kernel/aster-nix/src/syscall/brk.rs b/kernel/aster-nix/src/syscall/brk.rs index 37775fce0..51c7cca29 100644 --- a/kernel/aster-nix/src/syscall/brk.rs +++ b/kernel/aster-nix/src/syscall/brk.rs @@ -3,7 +3,7 @@ use crate::{prelude::*, syscall::SyscallReturn}; /// expand the user heap to new heap end, returns the new heap end if expansion succeeds. -pub fn sys_brk(heap_end: u64) -> Result { +pub fn sys_brk(heap_end: u64, _ctx: &Context) -> Result { let new_heap_end = if heap_end == 0 { None } else { diff --git a/kernel/aster-nix/src/syscall/capget.rs b/kernel/aster-nix/src/syscall/capget.rs index beaf578d0..0f0d11656 100644 --- a/kernel/aster-nix/src/syscall/capget.rs +++ b/kernel/aster-nix/src/syscall/capget.rs @@ -9,7 +9,11 @@ use crate::{ }, }; -pub fn sys_capget(cap_user_header_addr: Vaddr, cap_user_data_addr: Vaddr) -> Result { +pub fn sys_capget( + cap_user_header_addr: Vaddr, + cap_user_data_addr: Vaddr, + _ctx: &Context, +) -> Result { let user_space = CurrentUserSpace::get(); let cap_user_header: cap_user_header_t = user_space.read_val::(cap_user_header_addr)?; diff --git a/kernel/aster-nix/src/syscall/capset.rs b/kernel/aster-nix/src/syscall/capset.rs index b307d7a44..daacc5408 100644 --- a/kernel/aster-nix/src/syscall/capset.rs +++ b/kernel/aster-nix/src/syscall/capset.rs @@ -16,7 +16,11 @@ fn make_kernel_cap(low: u32, high: u32) -> u64 { ((low as u64) | ((high as u64) << 32)) & ((1u64 << (CapSet::most_significant_bit() + 1)) - 1) } -pub fn sys_capset(cap_user_header_addr: Vaddr, cap_user_data_addr: Vaddr) -> Result { +pub fn sys_capset( + cap_user_header_addr: Vaddr, + cap_user_data_addr: Vaddr, + _ctx: &Context, +) -> Result { let user_space = CurrentUserSpace::get(); let cap_user_header: cap_user_header_t = user_space.read_val::(cap_user_header_addr)?; diff --git a/kernel/aster-nix/src/syscall/chdir.rs b/kernel/aster-nix/src/syscall/chdir.rs index 37b96ed0f..6b4c9099a 100644 --- a/kernel/aster-nix/src/syscall/chdir.rs +++ b/kernel/aster-nix/src/syscall/chdir.rs @@ -7,7 +7,7 @@ use crate::{ syscall::constants::MAX_FILENAME_LEN, }; -pub fn sys_chdir(path_ptr: Vaddr) -> Result { +pub fn sys_chdir(path_ptr: Vaddr, _ctx: &Context) -> Result { let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?; debug!("path = {:?}", path); @@ -28,7 +28,7 @@ pub fn sys_chdir(path_ptr: Vaddr) -> Result { Ok(SyscallReturn::Return(0)) } -pub fn sys_fchdir(fd: FileDesc) -> Result { +pub fn sys_fchdir(fd: FileDesc, _ctx: &Context) -> Result { debug!("fd = {}", fd); let current = current!(); diff --git a/kernel/aster-nix/src/syscall/chmod.rs b/kernel/aster-nix/src/syscall/chmod.rs index 7e1a4e714..8c6f7a826 100644 --- a/kernel/aster-nix/src/syscall/chmod.rs +++ b/kernel/aster-nix/src/syscall/chmod.rs @@ -10,7 +10,7 @@ use crate::{ prelude::*, }; -pub fn sys_fchmod(fd: FileDesc, mode: u16) -> Result { +pub fn sys_fchmod(fd: FileDesc, mode: u16, _ctx: &Context) -> Result { debug!("fd = {}, mode = 0o{:o}", fd, mode); let current = current!(); @@ -20,8 +20,8 @@ pub fn sys_fchmod(fd: FileDesc, mode: u16) -> Result { Ok(SyscallReturn::Return(0)) } -pub fn sys_chmod(path_ptr: Vaddr, mode: u16) -> Result { - self::sys_fchmodat(AT_FDCWD, path_ptr, mode) +pub fn sys_chmod(path_ptr: Vaddr, mode: u16, ctx: &Context) -> Result { + self::sys_fchmodat(AT_FDCWD, path_ptr, mode, ctx) } // Glibc handles the `flags` argument, so we just ignore it. @@ -30,6 +30,7 @@ pub fn sys_fchmodat( path_ptr: Vaddr, mode: u16, /* flags: u32, */ + _ctx: &Context, ) -> Result { let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?; debug!("dirfd = {}, path = {:?}, mode = 0o{:o}", dirfd, path, mode,); diff --git a/kernel/aster-nix/src/syscall/chown.rs b/kernel/aster-nix/src/syscall/chown.rs index 27029a65a..2684bb415 100644 --- a/kernel/aster-nix/src/syscall/chown.rs +++ b/kernel/aster-nix/src/syscall/chown.rs @@ -11,7 +11,7 @@ use crate::{ process::{Gid, Uid}, }; -pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32) -> Result { +pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32, _ctx: &Context) -> Result { debug!("fd = {}, uid = {}, gid = {}", fd, uid, gid); let uid = to_optional_id(uid, Uid::new)?; @@ -32,17 +32,18 @@ pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32) -> Result { Ok(SyscallReturn::Return(0)) } -pub fn sys_chown(path_ptr: Vaddr, uid: i32, gid: i32) -> Result { - self::sys_fchownat(AT_FDCWD, path_ptr, uid, gid, 0) +pub fn sys_chown(path_ptr: Vaddr, uid: i32, gid: i32, ctx: &Context) -> Result { + self::sys_fchownat(AT_FDCWD, path_ptr, uid, gid, 0, ctx) } -pub fn sys_lchown(path_ptr: Vaddr, uid: i32, gid: i32) -> Result { +pub fn sys_lchown(path_ptr: Vaddr, uid: i32, gid: i32, ctx: &Context) -> Result { self::sys_fchownat( AT_FDCWD, path_ptr, uid, gid, ChownFlags::AT_SYMLINK_NOFOLLOW.bits(), + ctx, ) } @@ -52,6 +53,7 @@ pub fn sys_fchownat( uid: i32, gid: i32, flags: u32, + ctx: &Context, ) -> Result { let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?; let flags = ChownFlags::from_bits(flags) @@ -65,7 +67,7 @@ pub fn sys_fchownat( if !flags.contains(ChownFlags::AT_EMPTY_PATH) { return_errno_with_message!(Errno::ENOENT, "path is empty"); } - return self::sys_fchown(dirfd, uid, gid); + return self::sys_fchown(dirfd, uid, gid, ctx); } let uid = to_optional_id(uid, Uid::new)?; diff --git a/kernel/aster-nix/src/syscall/chroot.rs b/kernel/aster-nix/src/syscall/chroot.rs index 8d5c20b98..491262984 100644 --- a/kernel/aster-nix/src/syscall/chroot.rs +++ b/kernel/aster-nix/src/syscall/chroot.rs @@ -7,7 +7,7 @@ use crate::{ syscall::constants::MAX_FILENAME_LEN, }; -pub fn sys_chroot(path_ptr: Vaddr) -> Result { +pub fn sys_chroot(path_ptr: Vaddr, _ctx: &Context) -> Result { let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?; debug!("path = {:?}", path); diff --git a/kernel/aster-nix/src/syscall/clock_gettime.rs b/kernel/aster-nix/src/syscall/clock_gettime.rs index bf7fc7e86..e1609008a 100644 --- a/kernel/aster-nix/src/syscall/clock_gettime.rs +++ b/kernel/aster-nix/src/syscall/clock_gettime.rs @@ -19,7 +19,11 @@ use crate::{ }, }; -pub fn sys_clock_gettime(clockid: clockid_t, timespec_addr: Vaddr) -> Result { +pub fn sys_clock_gettime( + clockid: clockid_t, + timespec_addr: Vaddr, + _ctx: &Context, +) -> Result { debug!("clockid = {:?}", clockid); let time_duration = read_clock(clockid)?; diff --git a/kernel/aster-nix/src/syscall/clone.rs b/kernel/aster-nix/src/syscall/clone.rs index c76fa39a5..45cb7ea72 100644 --- a/kernel/aster-nix/src/syscall/clone.rs +++ b/kernel/aster-nix/src/syscall/clone.rs @@ -16,18 +16,20 @@ pub fn sys_clone( parent_tidptr: Vaddr, child_tidptr: Vaddr, tls: u64, + ctx: &Context, parent_context: &UserContext, ) -> Result { let clone_flags = CloneFlags::from(clone_flags); debug!("flags = {:?}, child_stack_ptr = 0x{:x}, parent_tid_ptr = 0x{:x}, child tid ptr = 0x{:x}, tls = 0x{:x}", clone_flags, new_sp, parent_tidptr, child_tidptr, tls); let clone_args = CloneArgs::new(new_sp, 0, parent_tidptr, child_tidptr, tls, clone_flags); - let child_pid = clone_child(parent_context, clone_args).unwrap(); + let child_pid = clone_child(ctx, parent_context, clone_args).unwrap(); Ok(SyscallReturn::Return(child_pid as _)) } pub fn sys_clone3( clong_args_addr: Vaddr, size: usize, + ctx: &Context, parent_context: &UserContext, ) -> Result { trace!( @@ -46,7 +48,7 @@ pub fn sys_clone3( }; debug!("clone args = {:x?}", clone_args); - let child_pid = clone_child(parent_context, clone_args)?; + let child_pid = clone_child(ctx, parent_context, clone_args)?; trace!("child pid = {}", child_pid); Ok(SyscallReturn::Return(child_pid as _)) } diff --git a/kernel/aster-nix/src/syscall/close.rs b/kernel/aster-nix/src/syscall/close.rs index f7a970017..b84d37e69 100644 --- a/kernel/aster-nix/src/syscall/close.rs +++ b/kernel/aster-nix/src/syscall/close.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{fs::file_table::FileDesc, prelude::*}; -pub fn sys_close(fd: FileDesc) -> Result { +pub fn sys_close(fd: FileDesc, _ctx: &Context) -> Result { debug!("fd = {}", fd); let file = { diff --git a/kernel/aster-nix/src/syscall/connect.rs b/kernel/aster-nix/src/syscall/connect.rs index fd905ae36..e487c6a65 100644 --- a/kernel/aster-nix/src/syscall/connect.rs +++ b/kernel/aster-nix/src/syscall/connect.rs @@ -7,7 +7,12 @@ use crate::{ util::net::{get_socket_from_fd, read_socket_addr_from_user}, }; -pub fn sys_connect(sockfd: FileDesc, sockaddr_ptr: Vaddr, addr_len: u32) -> Result { +pub fn sys_connect( + sockfd: FileDesc, + sockaddr_ptr: Vaddr, + addr_len: u32, + _ctx: &Context, +) -> Result { let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addr_len as _)?; debug!("fd = {sockfd}, socket_addr = {socket_addr:?}"); diff --git a/kernel/aster-nix/src/syscall/dup.rs b/kernel/aster-nix/src/syscall/dup.rs index 243fe849c..54ff2ec1e 100644 --- a/kernel/aster-nix/src/syscall/dup.rs +++ b/kernel/aster-nix/src/syscall/dup.rs @@ -7,7 +7,7 @@ use crate::{ process::ResourceType, }; -pub fn sys_dup(old_fd: FileDesc) -> Result { +pub fn sys_dup(old_fd: FileDesc, _ctx: &Context) -> Result { debug!("old_fd = {}", old_fd); let current = current!(); @@ -17,7 +17,7 @@ pub fn sys_dup(old_fd: FileDesc) -> Result { Ok(SyscallReturn::Return(new_fd as _)) } -pub fn sys_dup2(old_fd: FileDesc, new_fd: FileDesc) -> Result { +pub fn sys_dup2(old_fd: FileDesc, new_fd: FileDesc, _ctx: &Context) -> Result { debug!("old_fd = {}, new_fd = {}", old_fd, new_fd); if old_fd == new_fd { @@ -30,7 +30,12 @@ pub fn sys_dup2(old_fd: FileDesc, new_fd: FileDesc) -> Result { do_dup3(old_fd, new_fd, FdFlags::empty()) } -pub fn sys_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32) -> Result { +pub fn sys_dup3( + old_fd: FileDesc, + new_fd: FileDesc, + flags: u32, + _ctx: &Context, +) -> Result { debug!("old_fd = {}, new_fd = {}", old_fd, new_fd); let fdflag = match flags { diff --git a/kernel/aster-nix/src/syscall/epoll.rs b/kernel/aster-nix/src/syscall/epoll.rs index bc025ec53..d5b95e010 100644 --- a/kernel/aster-nix/src/syscall/epoll.rs +++ b/kernel/aster-nix/src/syscall/epoll.rs @@ -14,14 +14,14 @@ use crate::{ process::{posix_thread::PosixThreadExt, signal::sig_mask::SigMask}, }; -pub fn sys_epoll_create(size: i32) -> Result { +pub fn sys_epoll_create(size: i32, ctx: &Context) -> Result { if size <= 0 { return_errno_with_message!(Errno::EINVAL, "size is not positive"); } - sys_epoll_create1(0) + sys_epoll_create1(0, ctx) } -pub fn sys_epoll_create1(flags: u32) -> Result { +pub fn sys_epoll_create1(flags: u32, _ctx: &Context) -> Result { debug!("flags = 0x{:x}", flags); let fd_flags = { @@ -49,6 +49,7 @@ pub fn sys_epoll_ctl( op: i32, fd: FileDesc, event_addr: Vaddr, + _ctx: &Context, ) -> Result { debug!( "epfd = {}, op = {}, fd = {}, event_addr = 0x{:x}", @@ -128,6 +129,7 @@ pub fn sys_epoll_wait( events_addr: Vaddr, max_events: i32, timeout: i32, + _ctx: &Context, ) -> Result { debug!( "epfd = {}, events_addr = 0x{:x}, max_events = {}, timeout = {:?}", @@ -182,6 +184,7 @@ pub fn sys_epoll_pwait( timeout: i32, sigmask: Vaddr, sigset_size: usize, + _ctx: &Context, ) -> Result { debug!( "epfd = {}, events_addr = 0x{:x}, max_events = {}, timeout = {:?}, sigmask = 0x{:x}, sigset_size = {}", diff --git a/kernel/aster-nix/src/syscall/eventfd.rs b/kernel/aster-nix/src/syscall/eventfd.rs index 751c1efb7..9be19f221 100644 --- a/kernel/aster-nix/src/syscall/eventfd.rs +++ b/kernel/aster-nix/src/syscall/eventfd.rs @@ -30,7 +30,7 @@ use crate::{ time::clocks::RealTimeClock, }; -pub fn sys_eventfd(init_val: u64) -> Result { +pub fn sys_eventfd(init_val: u64, _ctx: &Context) -> Result { debug!("init_val = 0x{:x}", init_val); let fd = do_sys_eventfd2(init_val, Flags::empty()); @@ -38,7 +38,7 @@ pub fn sys_eventfd(init_val: u64) -> Result { Ok(SyscallReturn::Return(fd as _)) } -pub fn sys_eventfd2(init_val: u64, flags: u32) -> Result { +pub fn sys_eventfd2(init_val: u64, flags: u32, _ctx: &Context) -> Result { trace!("raw flags = {}", flags); let flags = Flags::from_bits(flags) .ok_or_else(|| Error::with_message(Errno::EINVAL, "unknown flags"))?; diff --git a/kernel/aster-nix/src/syscall/execve.rs b/kernel/aster-nix/src/syscall/execve.rs index 06f50975b..da7450b5f 100644 --- a/kernel/aster-nix/src/syscall/execve.rs +++ b/kernel/aster-nix/src/syscall/execve.rs @@ -14,8 +14,7 @@ use crate::{ }, prelude::*, process::{ - check_executable_file, credentials_mut, load_program_to_vm, - posix_thread::{PosixThreadExt, ThreadName}, + check_executable_file, credentials_mut, load_program_to_vm, posix_thread::ThreadName, Credentials, Process, MAX_ARGV_NUMBER, MAX_ARG_LEN, MAX_ENVP_NUMBER, MAX_ENV_LEN, }, }; @@ -24,14 +23,15 @@ pub fn sys_execve( filename_ptr: Vaddr, argv_ptr_ptr: Vaddr, envp_ptr_ptr: Vaddr, - context: &mut UserContext, + ctx: &Context, + user_ctx: &mut UserContext, ) -> Result { let elf_file = { let executable_path = read_filename(filename_ptr)?; lookup_executable_file(AT_FDCWD, executable_path, OpenFlags::empty())? }; - do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, context)?; + do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, ctx, user_ctx)?; Ok(SyscallReturn::NoReturn) } @@ -41,7 +41,8 @@ pub fn sys_execveat( argv_ptr_ptr: Vaddr, envp_ptr_ptr: Vaddr, flags: u32, - context: &mut UserContext, + ctx: &Context, + user_ctx: &mut UserContext, ) -> Result { let elf_file = { let flags = OpenFlags::from_bits_truncate(flags); @@ -49,7 +50,7 @@ pub fn sys_execveat( lookup_executable_file(dfd, filename, flags)? }; - do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, context)?; + do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, ctx, user_ctx)?; Ok(SyscallReturn::NoReturn) } @@ -82,8 +83,16 @@ fn do_execve( elf_file: Arc, argv_ptr_ptr: Vaddr, envp_ptr_ptr: Vaddr, - context: &mut UserContext, + ctx: &Context, + user_ctx: &mut UserContext, ) -> Result<()> { + let Context { + process, + posix_thread, + thread: _, + task: _, + } = ctx; + let executable_path = elf_file.abs_path(); let argv = read_cstring_vec(argv_ptr_ptr, MAX_ARGV_NUMBER, MAX_ARG_LEN)?; let envp = read_cstring_vec(envp_ptr_ptr, MAX_ENVP_NUMBER, MAX_ENV_LEN)?; @@ -92,24 +101,20 @@ fn do_execve( executable_path, argv, envp ); // FIXME: should we set thread name in execve? - let current_thread = current_thread!(); - let posix_thread = current_thread.as_posix_thread().unwrap(); *posix_thread.thread_name().lock() = Some(ThreadName::new_from_executable_path(&executable_path)?); // clear ctid // FIXME: should we clear ctid when execve? *posix_thread.clear_child_tid().lock() = 0; - let current = current!(); - // Ensure that the file descriptors with the close-on-exec flag are closed. - let closed_files = current.file_table().lock().close_files_on_exec(); + let closed_files = process.file_table().lock().close_files_on_exec(); drop(closed_files); debug!("load program to root vmar"); let (new_executable_path, elf_load_info) = { - let fs_resolver = &*current.fs().read(); - let process_vm = current.vm(); + let fs_resolver = &*process.fs().read(); + let process_vm = process.vm(); load_program_to_vm(process_vm, elf_file.clone(), argv, envp, fs_resolver, 1)? }; @@ -119,23 +124,23 @@ fn do_execve( debug!("load elf in execve succeeds"); let credentials = credentials_mut(); - set_uid_from_elf(¤t, &credentials, &elf_file)?; - set_gid_from_elf(¤t, &credentials, &elf_file)?; + set_uid_from_elf(process, &credentials, &elf_file)?; + set_gid_from_elf(process, &credentials, &elf_file)?; // set executable path - current.set_executable_path(new_executable_path); + process.set_executable_path(new_executable_path); // set signal disposition to default - current.sig_dispositions().lock().inherit(); - // set cpu context to default + process.sig_dispositions().lock().inherit(); + // set cpu ctx to default let default_content = UserContext::default(); - *context.general_regs_mut() = *default_content.general_regs(); - context.set_tls_pointer(default_content.tls_pointer()); - *context.fp_regs_mut() = *default_content.fp_regs(); + *user_ctx.general_regs_mut() = *default_content.general_regs(); + user_ctx.set_tls_pointer(default_content.tls_pointer()); + *user_ctx.fp_regs_mut() = *default_content.fp_regs(); // set new entry point - context.set_instruction_pointer(elf_load_info.entry_point() as _); + user_ctx.set_instruction_pointer(elf_load_info.entry_point() as _); debug!("entry_point: 0x{:x}", elf_load_info.entry_point()); // set new user stack top - context.set_stack_pointer(elf_load_info.user_stack_top() as _); + user_ctx.set_stack_pointer(elf_load_info.user_stack_top() as _); debug!("user stack top: 0x{:x}", elf_load_info.user_stack_top()); Ok(()) } @@ -184,7 +189,7 @@ fn read_cstring_vec( /// Sets uid for credentials as the same of uid of elf file if elf file has `set_uid` bit. fn set_uid_from_elf( - current: &Arc, + current: &Process, credentials: &Credentials, elf_file: &Arc, ) -> Result<()> { @@ -202,7 +207,7 @@ fn set_uid_from_elf( /// Sets gid for credentials as the same of gid of elf file if elf file has `set_gid` bit. fn set_gid_from_elf( - current: &Arc, + current: &Process, credentials: &Credentials, elf_file: &Arc, ) -> Result<()> { diff --git a/kernel/aster-nix/src/syscall/exit.rs b/kernel/aster-nix/src/syscall/exit.rs index ad28a786f..48917479f 100644 --- a/kernel/aster-nix/src/syscall/exit.rs +++ b/kernel/aster-nix/src/syscall/exit.rs @@ -6,7 +6,7 @@ use crate::{ syscall::SyscallReturn, }; -pub fn sys_exit(exit_code: i32) -> Result { +pub fn sys_exit(exit_code: i32, _ctx: &Context) -> Result { debug!("exid code = {}", exit_code); let current_thread = current_thread!(); diff --git a/kernel/aster-nix/src/syscall/exit_group.rs b/kernel/aster-nix/src/syscall/exit_group.rs index ddb42fb7b..20d0af3e4 100644 --- a/kernel/aster-nix/src/syscall/exit_group.rs +++ b/kernel/aster-nix/src/syscall/exit_group.rs @@ -7,7 +7,7 @@ use crate::{ }; /// Exit all thread in a process. -pub fn sys_exit_group(exit_code: u64) -> Result { +pub fn sys_exit_group(exit_code: u64, _ctx: &Context) -> Result { // Exit all thread in current process let term_status = TermStatus::Exited(exit_code as _); do_exit_group(term_status); diff --git a/kernel/aster-nix/src/syscall/fallocate.rs b/kernel/aster-nix/src/syscall/fallocate.rs index 2476f8ad9..8edb4b5cb 100644 --- a/kernel/aster-nix/src/syscall/fallocate.rs +++ b/kernel/aster-nix/src/syscall/fallocate.rs @@ -7,7 +7,13 @@ use crate::{ process::ResourceType, }; -pub fn sys_fallocate(fd: FileDesc, mode: u64, offset: i64, len: i64) -> Result { +pub fn sys_fallocate( + fd: FileDesc, + mode: u64, + offset: i64, + len: i64, + _ctx: &Context, +) -> Result { debug!( "fd = {}, mode = {}, offset = {}, len = {}", fd, mode, offset, len diff --git a/kernel/aster-nix/src/syscall/fcntl.rs b/kernel/aster-nix/src/syscall/fcntl.rs index 7c05321f7..e70ba8c62 100644 --- a/kernel/aster-nix/src/syscall/fcntl.rs +++ b/kernel/aster-nix/src/syscall/fcntl.rs @@ -10,7 +10,7 @@ use crate::{ process::Pid, }; -pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64) -> Result { +pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64, _ctx: &Context) -> Result { let fcntl_cmd = FcntlCmd::try_from(cmd)?; debug!("fd = {}, cmd = {:?}, arg = {}", fd, fcntl_cmd, arg); match fcntl_cmd { diff --git a/kernel/aster-nix/src/syscall/fork.rs b/kernel/aster-nix/src/syscall/fork.rs index 987a7f351..801f9365e 100644 --- a/kernel/aster-nix/src/syscall/fork.rs +++ b/kernel/aster-nix/src/syscall/fork.rs @@ -8,8 +8,8 @@ use crate::{ process::{clone_child, CloneArgs}, }; -pub fn sys_fork(parent_context: &UserContext) -> Result { +pub fn sys_fork(ctx: &Context, parent_context: &UserContext) -> Result { let clone_args = CloneArgs::for_fork(); - let child_pid = clone_child(parent_context, clone_args).unwrap(); + let child_pid = clone_child(ctx, parent_context, clone_args).unwrap(); Ok(SyscallReturn::Return(child_pid as _)) } diff --git a/kernel/aster-nix/src/syscall/fsync.rs b/kernel/aster-nix/src/syscall/fsync.rs index c73740617..112e66fac 100644 --- a/kernel/aster-nix/src/syscall/fsync.rs +++ b/kernel/aster-nix/src/syscall/fsync.rs @@ -6,7 +6,7 @@ use crate::{ prelude::*, }; -pub fn sys_fsync(fd: FileDesc) -> Result { +pub fn sys_fsync(fd: FileDesc, _ctx: &Context) -> Result { debug!("fd = {}", fd); let dentry = { @@ -22,7 +22,7 @@ pub fn sys_fsync(fd: FileDesc) -> Result { Ok(SyscallReturn::Return(0)) } -pub fn sys_fdatasync(fd: FileDesc) -> Result { +pub fn sys_fdatasync(fd: FileDesc, _ctx: &Context) -> Result { debug!("fd = {}", fd); let dentry = { diff --git a/kernel/aster-nix/src/syscall/futex.rs b/kernel/aster-nix/src/syscall/futex.rs index 1dbf4af9c..952467445 100644 --- a/kernel/aster-nix/src/syscall/futex.rs +++ b/kernel/aster-nix/src/syscall/futex.rs @@ -16,6 +16,7 @@ pub fn sys_futex( utime_addr: u64, futex_new_addr: u64, bitset: u64, + _ctx: &Context, ) -> Result { // FIXME: we current ignore futex flags let (futex_op, futex_flags) = futex_op_and_flags_from_u32(futex_op as _).unwrap(); diff --git a/kernel/aster-nix/src/syscall/getcwd.rs b/kernel/aster-nix/src/syscall/getcwd.rs index a21ef00d5..8cace4d25 100644 --- a/kernel/aster-nix/src/syscall/getcwd.rs +++ b/kernel/aster-nix/src/syscall/getcwd.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::prelude::*; -pub fn sys_getcwd(buf: Vaddr, len: usize) -> Result { +pub fn sys_getcwd(buf: Vaddr, len: usize, _ctx: &Context) -> Result { // TODO: getcwd only return a fake result now let fake_cwd = CString::new("/")?; let bytes = fake_cwd.as_bytes_with_nul(); diff --git a/kernel/aster-nix/src/syscall/getdents64.rs b/kernel/aster-nix/src/syscall/getdents64.rs index c9d297239..5d0f94e14 100644 --- a/kernel/aster-nix/src/syscall/getdents64.rs +++ b/kernel/aster-nix/src/syscall/getdents64.rs @@ -12,7 +12,12 @@ use crate::{ prelude::*, }; -pub fn sys_getdents(fd: FileDesc, buf_addr: Vaddr, buf_len: usize) -> Result { +pub fn sys_getdents( + fd: FileDesc, + buf_addr: Vaddr, + buf_len: usize, + _ctx: &Context, +) -> Result { debug!( "fd = {}, buf_addr = 0x{:x}, buf_len = 0x{:x}", fd, buf_addr, buf_len @@ -37,7 +42,12 @@ pub fn sys_getdents(fd: FileDesc, buf_addr: Vaddr, buf_len: usize) -> Result Result { +pub fn sys_getdents64( + fd: FileDesc, + buf_addr: Vaddr, + buf_len: usize, + _ctx: &Context, +) -> Result { debug!( "fd = {}, buf_addr = 0x{:x}, buf_len = 0x{:x}", fd, buf_addr, buf_len diff --git a/kernel/aster-nix/src/syscall/getegid.rs b/kernel/aster-nix/src/syscall/getegid.rs index 97c3e2e18..5c0cf1320 100644 --- a/kernel/aster-nix/src/syscall/getegid.rs +++ b/kernel/aster-nix/src/syscall/getegid.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{prelude::*, process::credentials}; -pub fn sys_getegid() -> Result { +pub fn sys_getegid(_ctx: &Context) -> Result { let egid = { let credentials = credentials(); credentials.egid() diff --git a/kernel/aster-nix/src/syscall/geteuid.rs b/kernel/aster-nix/src/syscall/geteuid.rs index 33549ee42..b34e8a996 100644 --- a/kernel/aster-nix/src/syscall/geteuid.rs +++ b/kernel/aster-nix/src/syscall/geteuid.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{prelude::*, process::credentials}; -pub fn sys_geteuid() -> Result { +pub fn sys_geteuid(_ctx: &Context) -> Result { let euid = { let credentials = credentials(); credentials.euid() diff --git a/kernel/aster-nix/src/syscall/getgid.rs b/kernel/aster-nix/src/syscall/getgid.rs index 2e78e78d0..336b0e8ee 100644 --- a/kernel/aster-nix/src/syscall/getgid.rs +++ b/kernel/aster-nix/src/syscall/getgid.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{prelude::*, process::credentials}; -pub fn sys_getgid() -> Result { +pub fn sys_getgid(_ctx: &Context) -> Result { let gid = { let credentials = credentials(); credentials.rgid() diff --git a/kernel/aster-nix/src/syscall/getgroups.rs b/kernel/aster-nix/src/syscall/getgroups.rs index fb571ccf0..51131c71d 100644 --- a/kernel/aster-nix/src/syscall/getgroups.rs +++ b/kernel/aster-nix/src/syscall/getgroups.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{prelude::*, process::credentials}; -pub fn sys_getgroups(size: i32, group_list_addr: Vaddr) -> Result { +pub fn sys_getgroups(size: i32, group_list_addr: Vaddr, _ctx: &Context) -> Result { debug!("size = {}, group_list_addr = 0x{:x}", size, group_list_addr); if size < 0 { diff --git a/kernel/aster-nix/src/syscall/getpeername.rs b/kernel/aster-nix/src/syscall/getpeername.rs index 3f523aa09..61d23db23 100644 --- a/kernel/aster-nix/src/syscall/getpeername.rs +++ b/kernel/aster-nix/src/syscall/getpeername.rs @@ -7,7 +7,12 @@ use crate::{ util::net::{get_socket_from_fd, write_socket_addr_to_user}, }; -pub fn sys_getpeername(sockfd: FileDesc, addr: Vaddr, addrlen_ptr: Vaddr) -> Result { +pub fn sys_getpeername( + sockfd: FileDesc, + addr: Vaddr, + addrlen_ptr: Vaddr, + _ctx: &Context, +) -> Result { debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); let peer_addr = { diff --git a/kernel/aster-nix/src/syscall/getpgrp.rs b/kernel/aster-nix/src/syscall/getpgrp.rs index 5947971a7..911275c2a 100644 --- a/kernel/aster-nix/src/syscall/getpgrp.rs +++ b/kernel/aster-nix/src/syscall/getpgrp.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::prelude::*; -pub fn sys_getpgrp() -> Result { +pub fn sys_getpgrp(_ctx: &Context) -> Result { let current = current!(); Ok(SyscallReturn::Return(current.pgid() as _)) } diff --git a/kernel/aster-nix/src/syscall/getpid.rs b/kernel/aster-nix/src/syscall/getpid.rs index b323c510b..07d6c266c 100644 --- a/kernel/aster-nix/src/syscall/getpid.rs +++ b/kernel/aster-nix/src/syscall/getpid.rs @@ -3,8 +3,8 @@ use super::SyscallReturn; use crate::prelude::*; -pub fn sys_getpid() -> Result { - let pid = current!().pid(); +pub fn sys_getpid(ctx: &Context) -> Result { + let pid = ctx.process.pid(); debug!("[sys_getpid]: pid = {}", pid); Ok(SyscallReturn::Return(pid as _)) } diff --git a/kernel/aster-nix/src/syscall/getppid.rs b/kernel/aster-nix/src/syscall/getppid.rs index 3baed26ac..8b7013267 100644 --- a/kernel/aster-nix/src/syscall/getppid.rs +++ b/kernel/aster-nix/src/syscall/getppid.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::prelude::*; -pub fn sys_getppid() -> Result { +pub fn sys_getppid(_ctx: &Context) -> Result { let current = current!(); let parent = current.parent(); match parent { diff --git a/kernel/aster-nix/src/syscall/getrandom.rs b/kernel/aster-nix/src/syscall/getrandom.rs index b5e946e03..4857718b1 100644 --- a/kernel/aster-nix/src/syscall/getrandom.rs +++ b/kernel/aster-nix/src/syscall/getrandom.rs @@ -3,7 +3,12 @@ use super::SyscallReturn; use crate::{device, prelude::*}; -pub fn sys_getrandom(buf: Vaddr, count: usize, flags: u32) -> Result { +pub fn sys_getrandom( + buf: Vaddr, + count: usize, + flags: u32, + _ctx: &Context, +) -> Result { let flags = GetRandomFlags::from_bits_truncate(flags); debug!( "buf = 0x{:x}, count = 0x{:x}, flags = {:?}", diff --git a/kernel/aster-nix/src/syscall/getresgid.rs b/kernel/aster-nix/src/syscall/getresgid.rs index ba47c7956..68166e15a 100644 --- a/kernel/aster-nix/src/syscall/getresgid.rs +++ b/kernel/aster-nix/src/syscall/getresgid.rs @@ -3,7 +3,12 @@ use super::SyscallReturn; use crate::{prelude::*, process::credentials}; -pub fn sys_getresgid(rgid_ptr: Vaddr, egid_ptr: Vaddr, sgid_ptr: Vaddr) -> Result { +pub fn sys_getresgid( + rgid_ptr: Vaddr, + egid_ptr: Vaddr, + sgid_ptr: Vaddr, + _ctx: &Context, +) -> Result { debug!("rgid_ptr = 0x{rgid_ptr:x}, egid_ptr = 0x{egid_ptr:x}, sgid_ptr = 0x{sgid_ptr:x}"); let credentials = credentials(); diff --git a/kernel/aster-nix/src/syscall/getresuid.rs b/kernel/aster-nix/src/syscall/getresuid.rs index 3aa8c8ee5..fbef5c59d 100644 --- a/kernel/aster-nix/src/syscall/getresuid.rs +++ b/kernel/aster-nix/src/syscall/getresuid.rs @@ -3,7 +3,12 @@ use super::SyscallReturn; use crate::{prelude::*, process::credentials}; -pub fn sys_getresuid(ruid_ptr: Vaddr, euid_ptr: Vaddr, suid_ptr: Vaddr) -> Result { +pub fn sys_getresuid( + ruid_ptr: Vaddr, + euid_ptr: Vaddr, + suid_ptr: Vaddr, + _ctx: &Context, +) -> Result { debug!("ruid_ptr = 0x{ruid_ptr:x}, euid_ptr = 0x{euid_ptr:x}, suid_ptr = 0x{suid_ptr:x}"); let credentials = credentials(); diff --git a/kernel/aster-nix/src/syscall/getrusage.rs b/kernel/aster-nix/src/syscall/getrusage.rs index c6c2b5a4d..d7f1448b8 100644 --- a/kernel/aster-nix/src/syscall/getrusage.rs +++ b/kernel/aster-nix/src/syscall/getrusage.rs @@ -14,7 +14,7 @@ enum RusageTarget { Thread = 1, } -pub fn sys_getrusage(target: i32, rusage_addr: Vaddr) -> Result { +pub fn sys_getrusage(target: i32, rusage_addr: Vaddr, _ctx: &Context) -> Result { let rusage_target = RusageTarget::try_from(target)?; debug!( @@ -86,7 +86,7 @@ pub struct rusage_t { pub ru_msgrcv: u64, /// signals received pub ru_nsignals: u64, - /// voluntary context switches + /// voluntary ctx switches pub ru_nvcsw: u64, /// involuntary pub ru_nivcsw: u64, diff --git a/kernel/aster-nix/src/syscall/getsid.rs b/kernel/aster-nix/src/syscall/getsid.rs index b0df8a366..08b880661 100644 --- a/kernel/aster-nix/src/syscall/getsid.rs +++ b/kernel/aster-nix/src/syscall/getsid.rs @@ -6,7 +6,7 @@ use crate::{ process::{process_table, Pid}, }; -pub fn sys_getsid(pid: Pid) -> Result { +pub fn sys_getsid(pid: Pid, _ctx: &Context) -> Result { debug!("pid = {}", pid); let session = current!().session().unwrap(); diff --git a/kernel/aster-nix/src/syscall/getsockname.rs b/kernel/aster-nix/src/syscall/getsockname.rs index bbb7643db..25efd03b6 100644 --- a/kernel/aster-nix/src/syscall/getsockname.rs +++ b/kernel/aster-nix/src/syscall/getsockname.rs @@ -7,7 +7,12 @@ use crate::{ util::net::{get_socket_from_fd, write_socket_addr_to_user}, }; -pub fn sys_getsockname(sockfd: FileDesc, addr: Vaddr, addrlen_ptr: Vaddr) -> Result { +pub fn sys_getsockname( + sockfd: FileDesc, + addr: Vaddr, + addrlen_ptr: Vaddr, + _ctx: &Context, +) -> Result { debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); let socket_addr = { diff --git a/kernel/aster-nix/src/syscall/getsockopt.rs b/kernel/aster-nix/src/syscall/getsockopt.rs index 73e97b929..9b2f797e2 100644 --- a/kernel/aster-nix/src/syscall/getsockopt.rs +++ b/kernel/aster-nix/src/syscall/getsockopt.rs @@ -13,6 +13,7 @@ pub fn sys_getsockopt( optname: i32, optval: Vaddr, optlen_addr: Vaddr, + _ctx: &Context, ) -> Result { let level = CSocketOptionLevel::try_from(level)?; if optval == 0 || optlen_addr == 0 { diff --git a/kernel/aster-nix/src/syscall/gettid.rs b/kernel/aster-nix/src/syscall/gettid.rs index df650f4f0..8e84ca528 100644 --- a/kernel/aster-nix/src/syscall/gettid.rs +++ b/kernel/aster-nix/src/syscall/gettid.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::prelude::*; -pub fn sys_gettid() -> Result { +pub fn sys_gettid(_ctx: &Context) -> Result { let current_thread = current_thread!(); let tid = current_thread.tid(); Ok(SyscallReturn::Return(tid as _)) diff --git a/kernel/aster-nix/src/syscall/gettimeofday.rs b/kernel/aster-nix/src/syscall/gettimeofday.rs index cf7986cff..f30204e56 100644 --- a/kernel/aster-nix/src/syscall/gettimeofday.rs +++ b/kernel/aster-nix/src/syscall/gettimeofday.rs @@ -8,7 +8,10 @@ use crate::{ // The use of the timezone structure is obsolete. // Glibc sets the timezone_addr argument to NULL, so just ignore it. -pub fn sys_gettimeofday(timeval_addr: Vaddr, /* timezone_addr: Vaddr */) -> Result { +pub fn sys_gettimeofday( + timeval_addr: Vaddr, + /* timezone_addr: Vaddr */ _ctx: &Context, +) -> Result { if timeval_addr == 0 { return Ok(SyscallReturn::Return(0)); } diff --git a/kernel/aster-nix/src/syscall/getuid.rs b/kernel/aster-nix/src/syscall/getuid.rs index 5065db510..8b392df68 100644 --- a/kernel/aster-nix/src/syscall/getuid.rs +++ b/kernel/aster-nix/src/syscall/getuid.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{prelude::*, process::credentials}; -pub fn sys_getuid() -> Result { +pub fn sys_getuid(_ctx: &Context) -> Result { let uid = { let credentials = credentials(); credentials.ruid() diff --git a/kernel/aster-nix/src/syscall/ioctl.rs b/kernel/aster-nix/src/syscall/ioctl.rs index 0ada065e0..d1f92c591 100644 --- a/kernel/aster-nix/src/syscall/ioctl.rs +++ b/kernel/aster-nix/src/syscall/ioctl.rs @@ -9,7 +9,7 @@ use crate::{ prelude::*, }; -pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr) -> Result { +pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr, _ctx: &Context) -> Result { let ioctl_cmd = IoctlCmd::try_from(cmd)?; debug!( "fd = {}, ioctl_cmd = {:?}, arg = 0x{:x}", diff --git a/kernel/aster-nix/src/syscall/kill.rs b/kernel/aster-nix/src/syscall/kill.rs index 8bf8c5b21..1444b6ffc 100644 --- a/kernel/aster-nix/src/syscall/kill.rs +++ b/kernel/aster-nix/src/syscall/kill.rs @@ -13,7 +13,7 @@ use crate::{ }, }; -pub fn sys_kill(process_filter: u64, sig_num: u64) -> Result { +pub fn sys_kill(process_filter: u64, sig_num: u64, _ctx: &Context) -> Result { let process_filter = ProcessFilter::from_id(process_filter as _); let sig_num = if sig_num == 0 { None diff --git a/kernel/aster-nix/src/syscall/link.rs b/kernel/aster-nix/src/syscall/link.rs index 3374de091..be592ac24 100644 --- a/kernel/aster-nix/src/syscall/link.rs +++ b/kernel/aster-nix/src/syscall/link.rs @@ -16,6 +16,7 @@ pub fn sys_linkat( new_dirfd: FileDesc, new_path_addr: Vaddr, flags: u32, + _ctx: &Context, ) -> Result { let user_space = CurrentUserSpace::get(); @@ -58,8 +59,12 @@ pub fn sys_linkat( Ok(SyscallReturn::Return(0)) } -pub fn sys_link(old_path_addr: Vaddr, new_path_addr: Vaddr) -> Result { - self::sys_linkat(AT_FDCWD, old_path_addr, AT_FDCWD, new_path_addr, 0) +pub fn sys_link( + old_path_addr: Vaddr, + new_path_addr: Vaddr, + ctx: &Context, +) -> Result { + self::sys_linkat(AT_FDCWD, old_path_addr, AT_FDCWD, new_path_addr, 0, ctx) } bitflags::bitflags! { diff --git a/kernel/aster-nix/src/syscall/listen.rs b/kernel/aster-nix/src/syscall/listen.rs index e81aa6a89..6337324b6 100644 --- a/kernel/aster-nix/src/syscall/listen.rs +++ b/kernel/aster-nix/src/syscall/listen.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{fs::file_table::FileDesc, prelude::*, util::net::get_socket_from_fd}; -pub fn sys_listen(sockfd: FileDesc, backlog: i32) -> Result { +pub fn sys_listen(sockfd: FileDesc, backlog: i32, _ctx: &Context) -> Result { debug!("sockfd = {sockfd}, backlog = {backlog}"); let socket = get_socket_from_fd(sockfd)?; diff --git a/kernel/aster-nix/src/syscall/lseek.rs b/kernel/aster-nix/src/syscall/lseek.rs index e168b9020..b9af9a939 100644 --- a/kernel/aster-nix/src/syscall/lseek.rs +++ b/kernel/aster-nix/src/syscall/lseek.rs @@ -6,7 +6,12 @@ use crate::{ prelude::*, }; -pub fn sys_lseek(fd: FileDesc, offset: isize, whence: u32) -> Result { +pub fn sys_lseek( + fd: FileDesc, + offset: isize, + whence: u32, + _ctx: &Context, +) -> Result { debug!("fd = {}, offset = {}, whence = {}", fd, offset, whence); let seek_from = match whence { 0 => { diff --git a/kernel/aster-nix/src/syscall/madvise.rs b/kernel/aster-nix/src/syscall/madvise.rs index 4d9a794ec..eefd428fb 100644 --- a/kernel/aster-nix/src/syscall/madvise.rs +++ b/kernel/aster-nix/src/syscall/madvise.rs @@ -3,7 +3,12 @@ use super::SyscallReturn; use crate::prelude::*; -pub fn sys_madvise(start: Vaddr, len: usize, behavior: i32) -> Result { +pub fn sys_madvise( + start: Vaddr, + len: usize, + behavior: i32, + _ctx: &Context, +) -> Result { let behavior = MadviseBehavior::try_from(behavior)?; debug!( "start = 0x{:x}, len = 0x{:x}, behavior = {:?}", diff --git a/kernel/aster-nix/src/syscall/mkdir.rs b/kernel/aster-nix/src/syscall/mkdir.rs index 9f6873a64..1ac989649 100644 --- a/kernel/aster-nix/src/syscall/mkdir.rs +++ b/kernel/aster-nix/src/syscall/mkdir.rs @@ -11,7 +11,12 @@ use crate::{ syscall::constants::MAX_FILENAME_LEN, }; -pub fn sys_mkdirat(dirfd: FileDesc, path_addr: Vaddr, mode: u16) -> Result { +pub fn sys_mkdirat( + dirfd: FileDesc, + path_addr: Vaddr, + mode: u16, + _ctx: &Context, +) -> Result { let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?; debug!("dirfd = {}, path = {:?}, mode = {}", dirfd, path, mode); @@ -36,6 +41,6 @@ pub fn sys_mkdirat(dirfd: FileDesc, path_addr: Vaddr, mode: u16) -> Result Result { - self::sys_mkdirat(AT_FDCWD, path_addr, mode) +pub fn sys_mkdir(path_addr: Vaddr, mode: u16, ctx: &Context) -> Result { + self::sys_mkdirat(AT_FDCWD, path_addr, mode, ctx) } diff --git a/kernel/aster-nix/src/syscall/mknod.rs b/kernel/aster-nix/src/syscall/mknod.rs index 9009f4696..2ecf368cb 100644 --- a/kernel/aster-nix/src/syscall/mknod.rs +++ b/kernel/aster-nix/src/syscall/mknod.rs @@ -17,6 +17,7 @@ pub fn sys_mknodat( path_addr: Vaddr, mode: u16, dev: usize, + _ctx: &Context, ) -> Result { let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?; let current = current!(); @@ -59,6 +60,6 @@ pub fn sys_mknodat( Ok(SyscallReturn::Return(0)) } -pub fn sys_mknod(path_addr: Vaddr, mode: u16, dev: usize) -> Result { - self::sys_mknodat(AT_FDCWD, path_addr, mode, dev) +pub fn sys_mknod(path_addr: Vaddr, mode: u16, dev: usize, ctx: &Context) -> Result { + self::sys_mknodat(AT_FDCWD, path_addr, mode, dev, ctx) } diff --git a/kernel/aster-nix/src/syscall/mmap.rs b/kernel/aster-nix/src/syscall/mmap.rs index 12e4da329..d888ab95f 100644 --- a/kernel/aster-nix/src/syscall/mmap.rs +++ b/kernel/aster-nix/src/syscall/mmap.rs @@ -22,6 +22,7 @@ pub fn sys_mmap( flags: u64, fd: u64, offset: u64, + _ctx: &Context, ) -> Result { let perms = VmPerms::from_posix_prot_bits(perms as u32).unwrap(); let option = MMapOptions::try_from(flags as u32)?; diff --git a/kernel/aster-nix/src/syscall/mod.rs b/kernel/aster-nix/src/syscall/mod.rs index 411ed7c03..ce21d559f 100644 --- a/kernel/aster-nix/src/syscall/mod.rs +++ b/kernel/aster-nix/src/syscall/mod.rs @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MPL-2.0 -//! Read the Cpu context content then dispatch syscall to corrsponding handler +//! Read the Cpu ctx content then dispatch syscall to corrsponding handler //! The each sub module contains functions that handle real syscall logic. pub use clock_gettime::ClockId; use ostd::cpu::UserContext; -use crate::{cpu::LinuxAbi, prelude::*}; +use crate::{context::Context, cpu::LinuxAbi, prelude::*}; mod accept; mod access; @@ -139,40 +139,119 @@ mod write; /// The first param is ths number of parameters, /// The second param is the function name of syscall handler, /// The third is optional, means the args(if parameter number > 0), -/// The third is optional, means if cpu context is required. +/// The third is optional, means if cpu ctx is required. macro_rules! syscall_handler { - (0, $fn_name: ident, $args: ident) => { $fn_name() }; - (0, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($context) }; - (1, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _) }; - (1, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $context) }; - (2, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _)}; - (2, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $context)}; - (3, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _)}; - (3, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $context)}; - (4, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _)}; - (4, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _), $context}; - (5, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _)}; - (5, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _, $context)}; - (6, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _, $args[5] as _)}; - (6, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _, $args[5] as _, $context)}; + (0, $fn_name: ident, $args: ident, $ctx: expr) => { + $fn_name($ctx) + }; + (0, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => { + $fn_name($ctx, $user_ctx) + }; + + (1, $fn_name: ident, $args: ident, $ctx: expr) => { + $fn_name($args[0] as _, $ctx) + }; + (1, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => { + $fn_name($args[0] as _, $ctx, $user_ctx) + }; + + (2, $fn_name: ident, $args: ident, $ctx: expr) => { + $fn_name($args[0] as _, $args[1] as _, $ctx) + }; + (2, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => { + $fn_name($args[0] as _, $args[1] as _, $ctx, $user_ctx) + }; + + (3, $fn_name: ident, $args: ident, $ctx: expr) => { + $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $ctx) + }; + (3, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => { + $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $ctx, $user_ctx) + }; + + (4, $fn_name: ident, $args: ident, $ctx: expr) => { + $fn_name( + $args[0] as _, + $args[1] as _, + $args[2] as _, + $args[3] as _, + $ctx, + ) + }; + (4, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => { + $fn_name( + $args[0] as _, + $args[1] as _, + $args[2] as _, + $args[3] as _, + $ctx, + $user_ctx, + ) + }; + + (5, $fn_name: ident, $args: ident, $ctx: expr) => { + $fn_name( + $args[0] as _, + $args[1] as _, + $args[2] as _, + $args[3] as _, + $args[4] as _, + $ctx, + ) + }; + (5, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => { + $fn_name( + $args[0] as _, + $args[1] as _, + $args[2] as _, + $args[3] as _, + $args[4] as _, + $ctx, + $user_ctx, + ) + }; + + (6, $fn_name: ident, $args: ident, $ctx: expr) => { + $fn_name( + $args[0] as _, + $args[1] as _, + $args[2] as _, + $args[3] as _, + $args[4] as _, + $args[5] as _, + $ctx, + ) + }; + (6, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => { + $fn_name( + $args[0] as _, + $args[1] as _, + $args[2] as _, + $args[3] as _, + $args[4] as _, + $args[5] as _, + $ctx, + $user_ctx, + ) + }; } macro_rules! dispatch_fn_inner { - ( $args: ident, $context: ident, $handler: ident ( args[ .. $cnt: tt ] ) ) => { - $crate::syscall::syscall_handler!($cnt, $handler, $args) + ( $args: ident, $ctx: ident, $user_ctx: ident, $handler: ident ( args[ .. $cnt: tt ] ) ) => { + $crate::syscall::syscall_handler!($cnt, $handler, $args, $ctx) }; - ( $args: ident, $context: ident, $handler: ident ( args[ .. $cnt: tt ] , &context ) ) => { - $crate::syscall::syscall_handler!($cnt, $handler, $args, &$context) + ( $args: ident, $ctx: ident, $user_ctx: ident, $handler: ident ( args[ .. $cnt: tt ] , &user_ctx ) ) => { + $crate::syscall::syscall_handler!($cnt, $handler, $args, $ctx, &$user_ctx) }; - ( $args: ident, $context: ident, $handler: ident ( args[ .. $cnt: tt ] , &mut context ) ) => { - // `$context` is already of type `&mut ostd::cpu::UserContext`, + ( $args: ident, $ctx: ident, $user_ctx: ident, $handler: ident ( args[ .. $cnt: tt ] , &mut user_ctx ) ) => { + // `$user_ctx` is already of type `&mut ostd::cpu::UserContext`, // so no need to take `&mut` again - $crate::syscall::syscall_handler!($cnt, $handler, $args, $context) + $crate::syscall::syscall_handler!($cnt, $handler, $args, $ctx, $user_ctx) }; } macro_rules! impl_syscall_nums_and_dispatch_fn { - // $args, $context, and $dispatcher_name are needed since Rust macro is hygienic + // $args, $user_ctx, and $dispatcher_name are needed since Rust macro is hygienic ( $( $name: ident = $num: literal => $handler: ident $args: tt );* $(;)? ) => { // First, define the syscall numbers $( @@ -183,13 +262,14 @@ macro_rules! impl_syscall_nums_and_dispatch_fn { pub fn syscall_dispatch( syscall_number: u64, args: [u64; 6], - context: &mut ostd::cpu::UserContext, + ctx: &crate::context::Context, + user_ctx: &mut ostd::cpu::UserContext, ) -> $crate::prelude::Result<$crate::syscall::SyscallReturn> { match syscall_number { $( $num => { $crate::log_syscall_entry!($name); - $crate::syscall::dispatch_fn_inner!(args, context, $handler $args) + $crate::syscall::dispatch_fn_inner!(args, ctx, user_ctx, $handler $args) } )* _ => { @@ -221,9 +301,9 @@ pub enum SyscallReturn { } impl SyscallArgument { - fn new_from_context(context: &UserContext) -> Self { - let syscall_number = context.syscall_num() as u64; - let args = context.syscall_args().map(|x| x as u64); + fn new_from_context(user_ctx: &UserContext) -> Self { + let syscall_number = user_ctx.syscall_num() as u64; + let args = user_ctx.syscall_args().map(|x| x as u64); Self { syscall_number, args, @@ -231,21 +311,25 @@ impl SyscallArgument { } } -pub fn handle_syscall(context: &mut UserContext) { - let syscall_frame = SyscallArgument::new_from_context(context); - let syscall_return = - arch::syscall_dispatch(syscall_frame.syscall_number, syscall_frame.args, context); +pub fn handle_syscall(ctx: &Context, user_ctx: &mut UserContext) { + let syscall_frame = SyscallArgument::new_from_context(user_ctx); + let syscall_return = arch::syscall_dispatch( + syscall_frame.syscall_number, + syscall_frame.args, + ctx, + user_ctx, + ); match syscall_return { Ok(return_value) => { if let SyscallReturn::Return(return_value) = return_value { - context.set_syscall_ret(return_value as usize); + user_ctx.set_syscall_ret(return_value as usize); } } Err(err) => { debug!("syscall return error: {:?}", err); let errno = err.error() as i32; - context.set_syscall_ret((-errno) as usize) + user_ctx.set_syscall_ret((-errno) as usize) } } } diff --git a/kernel/aster-nix/src/syscall/mount.rs b/kernel/aster-nix/src/syscall/mount.rs index 45966d016..8c6d3f98f 100644 --- a/kernel/aster-nix/src/syscall/mount.rs +++ b/kernel/aster-nix/src/syscall/mount.rs @@ -23,6 +23,7 @@ pub fn sys_mount( fstype_addr: Vaddr, flags: u64, data: Vaddr, + _ctx: &Context, ) -> Result { let user_space = CurrentUserSpace::get(); let devname = user_space.read_cstring(devname_addr, MAX_FILENAME_LEN)?; diff --git a/kernel/aster-nix/src/syscall/mprotect.rs b/kernel/aster-nix/src/syscall/mprotect.rs index 9cc0114d7..da0e258ac 100644 --- a/kernel/aster-nix/src/syscall/mprotect.rs +++ b/kernel/aster-nix/src/syscall/mprotect.rs @@ -5,7 +5,7 @@ use align_ext::AlignExt; use super::SyscallReturn; use crate::{prelude::*, vm::perms::VmPerms}; -pub fn sys_mprotect(addr: Vaddr, len: usize, perms: u64) -> Result { +pub fn sys_mprotect(addr: Vaddr, len: usize, perms: u64, _ctx: &Context) -> Result { let vm_perms = VmPerms::from_bits_truncate(perms as u32); debug!( "addr = 0x{:x}, len = 0x{:x}, perms = {:?}", diff --git a/kernel/aster-nix/src/syscall/munmap.rs b/kernel/aster-nix/src/syscall/munmap.rs index 0ff4b4a43..b057365be 100644 --- a/kernel/aster-nix/src/syscall/munmap.rs +++ b/kernel/aster-nix/src/syscall/munmap.rs @@ -5,7 +5,7 @@ use align_ext::AlignExt; use super::SyscallReturn; use crate::prelude::*; -pub fn sys_munmap(addr: Vaddr, len: usize) -> Result { +pub fn sys_munmap(addr: Vaddr, len: usize, _ctx: &Context) -> Result { debug!("addr = 0x{:x}, len = {}", addr, len); let current = current!(); let root_vmar = current.root_vmar(); diff --git a/kernel/aster-nix/src/syscall/nanosleep.rs b/kernel/aster-nix/src/syscall/nanosleep.rs index ed880a4e3..e2b01161a 100644 --- a/kernel/aster-nix/src/syscall/nanosleep.rs +++ b/kernel/aster-nix/src/syscall/nanosleep.rs @@ -12,6 +12,7 @@ use crate::{ pub fn sys_nanosleep( request_timespec_addr: Vaddr, remain_timespec_addr: Vaddr, + _ctx: &Context, ) -> Result { let clockid = ClockId::CLOCK_MONOTONIC; @@ -28,6 +29,7 @@ pub fn sys_clock_nanosleep( flags: i32, request_timespec_addr: Vaddr, remain_timespec_addr: Vaddr, + _ctx: &Context, ) -> Result { let is_abs_time = if flags == 0 { false diff --git a/kernel/aster-nix/src/syscall/open.rs b/kernel/aster-nix/src/syscall/open.rs index 9d262a029..6c8e7e0e3 100644 --- a/kernel/aster-nix/src/syscall/open.rs +++ b/kernel/aster-nix/src/syscall/open.rs @@ -16,6 +16,7 @@ pub fn sys_openat( path_addr: Vaddr, flags: u32, mode: u16, + _ctx: &Context, ) -> Result { let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?; debug!( @@ -44,12 +45,12 @@ pub fn sys_openat( Ok(SyscallReturn::Return(fd as _)) } -pub fn sys_open(path_addr: Vaddr, flags: u32, mode: u16) -> Result { - self::sys_openat(AT_FDCWD, path_addr, flags, mode) +pub fn sys_open(path_addr: Vaddr, flags: u32, mode: u16, ctx: &Context) -> Result { + self::sys_openat(AT_FDCWD, path_addr, flags, mode, ctx) } -pub fn sys_creat(path_addr: Vaddr, mode: u16) -> Result { +pub fn sys_creat(path_addr: Vaddr, mode: u16, ctx: &Context) -> Result { let flags = AccessMode::O_WRONLY as u32 | CreationFlags::O_CREAT.bits() | CreationFlags::O_TRUNC.bits(); - self::sys_openat(AT_FDCWD, path_addr, flags, mode) + self::sys_openat(AT_FDCWD, path_addr, flags, mode, ctx) } diff --git a/kernel/aster-nix/src/syscall/pause.rs b/kernel/aster-nix/src/syscall/pause.rs index 95e9e3fbc..04f5d5087 100644 --- a/kernel/aster-nix/src/syscall/pause.rs +++ b/kernel/aster-nix/src/syscall/pause.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{prelude::*, process::signal::Pauser}; -pub fn sys_pause() -> Result { +pub fn sys_pause(_ctx: &Context) -> Result { // FIXME: like sleep, paused thread can only be interrupted by signals that will call signal // handler or terminate current process let pauser = Pauser::new(); diff --git a/kernel/aster-nix/src/syscall/pipe.rs b/kernel/aster-nix/src/syscall/pipe.rs index 50ba8d260..9fd74f316 100644 --- a/kernel/aster-nix/src/syscall/pipe.rs +++ b/kernel/aster-nix/src/syscall/pipe.rs @@ -10,7 +10,7 @@ use crate::{ prelude::*, }; -pub fn sys_pipe2(fds: Vaddr, flags: u32) -> Result { +pub fn sys_pipe2(fds: Vaddr, flags: u32, _ctx: &Context) -> Result { debug!("flags: {:?}", flags); let (pipe_reader, pipe_writer) = { @@ -48,8 +48,8 @@ pub fn sys_pipe2(fds: Vaddr, flags: u32) -> Result { Ok(SyscallReturn::Return(0)) } -pub fn sys_pipe(fds: Vaddr) -> Result { - self::sys_pipe2(fds, 0) +pub fn sys_pipe(fds: Vaddr, ctx: &Context) -> Result { + self::sys_pipe2(fds, 0, ctx) } #[derive(Debug, Clone, Copy, Pod)] diff --git a/kernel/aster-nix/src/syscall/poll.rs b/kernel/aster-nix/src/syscall/poll.rs index 392540572..0c50779a5 100644 --- a/kernel/aster-nix/src/syscall/poll.rs +++ b/kernel/aster-nix/src/syscall/poll.rs @@ -5,7 +5,7 @@ use core::{cell::Cell, time::Duration}; use super::SyscallReturn; use crate::{events::IoEvents, fs::file_table::FileDesc, prelude::*, process::signal::Poller}; -pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32) -> Result { +pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32, _ctx: &Context) -> Result { let user_space = CurrentUserSpace::get(); let poll_fds = { let mut read_addr = fds; diff --git a/kernel/aster-nix/src/syscall/prctl.rs b/kernel/aster-nix/src/syscall/prctl.rs index 7b71e63bd..72dcbd56c 100644 --- a/kernel/aster-nix/src/syscall/prctl.rs +++ b/kernel/aster-nix/src/syscall/prctl.rs @@ -9,7 +9,14 @@ use crate::{ }, }; -pub fn sys_prctl(option: i32, arg2: u64, arg3: u64, arg4: u64, arg5: u64) -> Result { +pub fn sys_prctl( + option: i32, + arg2: u64, + arg3: u64, + arg4: u64, + arg5: u64, + _ctx: &Context, +) -> Result { let prctl_cmd = PrctlCmd::from_args(option, arg2, arg3, arg4, arg5)?; debug!("prctl cmd = {:x?}", prctl_cmd); let current_thread = current_thread!(); diff --git a/kernel/aster-nix/src/syscall/pread64.rs b/kernel/aster-nix/src/syscall/pread64.rs index a92e11cf9..a2caf2fc1 100644 --- a/kernel/aster-nix/src/syscall/pread64.rs +++ b/kernel/aster-nix/src/syscall/pread64.rs @@ -8,6 +8,7 @@ pub fn sys_pread64( user_buf_ptr: Vaddr, user_buf_len: usize, offset: i64, + _ctx: &Context, ) -> Result { debug!( "fd = {}, buf = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}", diff --git a/kernel/aster-nix/src/syscall/preadv.rs b/kernel/aster-nix/src/syscall/preadv.rs index 0c4414b92..d1b07686a 100644 --- a/kernel/aster-nix/src/syscall/preadv.rs +++ b/kernel/aster-nix/src/syscall/preadv.rs @@ -7,7 +7,12 @@ use crate::{ util::{copy_iovs_from_user, IoVec}, }; -pub fn sys_readv(fd: FileDesc, io_vec_ptr: Vaddr, io_vec_count: usize) -> Result { +pub fn sys_readv( + fd: FileDesc, + io_vec_ptr: Vaddr, + io_vec_count: usize, + _ctx: &Context, +) -> Result { let res = do_sys_readv(fd, io_vec_ptr, io_vec_count)?; Ok(SyscallReturn::Return(res as _)) } @@ -17,6 +22,7 @@ pub fn sys_preadv( io_vec_ptr: Vaddr, io_vec_count: usize, offset: i64, + _ctx: &Context, ) -> Result { let res = do_sys_preadv(fd, io_vec_ptr, io_vec_count, offset, RWFFlag::empty())?; Ok(SyscallReturn::Return(res as _)) @@ -28,6 +34,7 @@ pub fn sys_preadv2( io_vec_count: usize, offset: i64, flags: u32, + _ctx: &Context, ) -> Result { let flags = match RWFFlag::from_bits(flags) { Some(flags) => flags, diff --git a/kernel/aster-nix/src/syscall/prlimit64.rs b/kernel/aster-nix/src/syscall/prlimit64.rs index a2b3b3467..a7d4df467 100644 --- a/kernel/aster-nix/src/syscall/prlimit64.rs +++ b/kernel/aster-nix/src/syscall/prlimit64.rs @@ -11,6 +11,7 @@ pub fn sys_prlimit64( resource: u32, new_rlim_addr: Vaddr, old_rlim_addr: Vaddr, + _ctx: &Context, ) -> Result { let resource = ResourceType::try_from(resource)?; debug!( diff --git a/kernel/aster-nix/src/syscall/pselect6.rs b/kernel/aster-nix/src/syscall/pselect6.rs index 67eff5da3..4f8160247 100644 --- a/kernel/aster-nix/src/syscall/pselect6.rs +++ b/kernel/aster-nix/src/syscall/pselect6.rs @@ -17,6 +17,7 @@ pub fn sys_pselect6( exceptfds_addr: Vaddr, timespec_addr: Vaddr, sigmask_addr: Vaddr, + _ctx: &Context, ) -> Result { let current_thread = current_thread!(); let posix_thread = current_thread.as_posix_thread().unwrap(); diff --git a/kernel/aster-nix/src/syscall/pwrite64.rs b/kernel/aster-nix/src/syscall/pwrite64.rs index 898dc3039..76e7177b0 100644 --- a/kernel/aster-nix/src/syscall/pwrite64.rs +++ b/kernel/aster-nix/src/syscall/pwrite64.rs @@ -8,6 +8,7 @@ pub fn sys_pwrite64( user_buf_ptr: Vaddr, user_buf_len: usize, offset: i64, + _ctx: &Context, ) -> Result { debug!( "fd = {}, user_buf_ptr = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}", diff --git a/kernel/aster-nix/src/syscall/pwritev.rs b/kernel/aster-nix/src/syscall/pwritev.rs index 4f7d9664e..a0b7113ca 100644 --- a/kernel/aster-nix/src/syscall/pwritev.rs +++ b/kernel/aster-nix/src/syscall/pwritev.rs @@ -3,7 +3,12 @@ use super::SyscallReturn; use crate::{fs::file_table::FileDesc, prelude::*, util::copy_iovs_from_user}; -pub fn sys_writev(fd: FileDesc, io_vec_ptr: Vaddr, io_vec_count: usize) -> Result { +pub fn sys_writev( + fd: FileDesc, + io_vec_ptr: Vaddr, + io_vec_count: usize, + _ctx: &Context, +) -> Result { let res = do_sys_writev(fd, io_vec_ptr, io_vec_count)?; Ok(SyscallReturn::Return(res as _)) } @@ -13,6 +18,7 @@ pub fn sys_pwritev( io_vec_ptr: Vaddr, io_vec_count: usize, offset: i64, + _ctx: &Context, ) -> Result { let res = do_sys_pwritev(fd, io_vec_ptr, io_vec_count, offset, RWFFlag::empty())?; Ok(SyscallReturn::Return(res as _)) @@ -24,6 +30,7 @@ pub fn sys_pwritev2( io_vec_count: usize, offset: i64, flags: u32, + _ctx: &Context, ) -> Result { let flags = match RWFFlag::from_bits(flags) { Some(flags) => flags, diff --git a/kernel/aster-nix/src/syscall/read.rs b/kernel/aster-nix/src/syscall/read.rs index 8aee12210..1a5af9d4d 100644 --- a/kernel/aster-nix/src/syscall/read.rs +++ b/kernel/aster-nix/src/syscall/read.rs @@ -5,7 +5,12 @@ use core::cmp::min; use super::SyscallReturn; use crate::{fs::file_table::FileDesc, prelude::*}; -pub fn sys_read(fd: FileDesc, user_buf_addr: Vaddr, buf_len: usize) -> Result { +pub fn sys_read( + fd: FileDesc, + user_buf_addr: Vaddr, + buf_len: usize, + _ctx: &Context, +) -> Result { debug!( "fd = {}, user_buf_ptr = 0x{:x}, buf_len = 0x{:x}", fd, user_buf_addr, buf_len diff --git a/kernel/aster-nix/src/syscall/readlink.rs b/kernel/aster-nix/src/syscall/readlink.rs index adfb49abe..317183758 100644 --- a/kernel/aster-nix/src/syscall/readlink.rs +++ b/kernel/aster-nix/src/syscall/readlink.rs @@ -15,6 +15,7 @@ pub fn sys_readlinkat( path_addr: Vaddr, usr_buf_addr: Vaddr, usr_buf_len: usize, + _ctx: &Context, ) -> Result { let user_space = CurrentUserSpace::get(); let path = user_space.read_cstring(path_addr, MAX_FILENAME_LEN)?; @@ -43,6 +44,7 @@ pub fn sys_readlink( path_addr: Vaddr, usr_buf_addr: Vaddr, usr_buf_len: usize, + ctx: &Context, ) -> Result { - self::sys_readlinkat(AT_FDCWD, path_addr, usr_buf_addr, usr_buf_len) + self::sys_readlinkat(AT_FDCWD, path_addr, usr_buf_addr, usr_buf_len, ctx) } diff --git a/kernel/aster-nix/src/syscall/recvfrom.rs b/kernel/aster-nix/src/syscall/recvfrom.rs index 6d5001f1a..6bff30098 100644 --- a/kernel/aster-nix/src/syscall/recvfrom.rs +++ b/kernel/aster-nix/src/syscall/recvfrom.rs @@ -18,6 +18,7 @@ pub fn sys_recvfrom( flags: i32, src_addr: Vaddr, addrlen_ptr: Vaddr, + _ctx: &Context, ) -> Result { let flags = SendRecvFlags::from_bits_truncate(flags); debug!("sockfd = {sockfd}, buf = 0x{buf:x}, len = {len}, flags = {flags:?}, src_addr = 0x{src_addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); diff --git a/kernel/aster-nix/src/syscall/recvmsg.rs b/kernel/aster-nix/src/syscall/recvmsg.rs index 8592d7d34..57a3a0aa1 100644 --- a/kernel/aster-nix/src/syscall/recvmsg.rs +++ b/kernel/aster-nix/src/syscall/recvmsg.rs @@ -8,7 +8,12 @@ use crate::{ util::net::{get_socket_from_fd, CUserMsgHdr}, }; -pub fn sys_recvmsg(sockfd: FileDesc, user_msghdr_ptr: Vaddr, flags: i32) -> Result { +pub fn sys_recvmsg( + sockfd: FileDesc, + user_msghdr_ptr: Vaddr, + flags: i32, + _ctx: &Context, +) -> Result { let c_user_msghdr: CUserMsgHdr = CurrentUserSpace::get().read_val(user_msghdr_ptr)?; let flags = SendRecvFlags::from_bits_truncate(flags); diff --git a/kernel/aster-nix/src/syscall/rename.rs b/kernel/aster-nix/src/syscall/rename.rs index 7f7905d33..10dd1aae2 100644 --- a/kernel/aster-nix/src/syscall/rename.rs +++ b/kernel/aster-nix/src/syscall/rename.rs @@ -16,6 +16,7 @@ pub fn sys_renameat( old_path_addr: Vaddr, new_dirfd: FileDesc, new_path_addr: Vaddr, + _ctx: &Context, ) -> Result { let user_space = CurrentUserSpace::get(); let old_path = user_space.read_cstring(old_path_addr, MAX_FILENAME_LEN)?; @@ -69,6 +70,10 @@ pub fn sys_renameat( Ok(SyscallReturn::Return(0)) } -pub fn sys_rename(old_path_addr: Vaddr, new_path_addr: Vaddr) -> Result { - self::sys_renameat(AT_FDCWD, old_path_addr, AT_FDCWD, new_path_addr) +pub fn sys_rename( + old_path_addr: Vaddr, + new_path_addr: Vaddr, + ctx: &Context, +) -> Result { + self::sys_renameat(AT_FDCWD, old_path_addr, AT_FDCWD, new_path_addr, ctx) } diff --git a/kernel/aster-nix/src/syscall/rmdir.rs b/kernel/aster-nix/src/syscall/rmdir.rs index 204e7a62b..a780dc996 100644 --- a/kernel/aster-nix/src/syscall/rmdir.rs +++ b/kernel/aster-nix/src/syscall/rmdir.rs @@ -10,11 +10,15 @@ use crate::{ syscall::constants::MAX_FILENAME_LEN, }; -pub fn sys_rmdir(path_addr: Vaddr) -> Result { - self::sys_rmdirat(AT_FDCWD, path_addr) +pub fn sys_rmdir(path_addr: Vaddr, ctx: &Context) -> Result { + self::sys_rmdirat(AT_FDCWD, path_addr, ctx) } -pub(super) fn sys_rmdirat(dirfd: FileDesc, path_addr: Vaddr) -> Result { +pub(super) fn sys_rmdirat( + dirfd: FileDesc, + path_addr: Vaddr, + _ctx: &Context, +) -> Result { let path_addr = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?; debug!("dirfd = {}, path_addr = {:?}", dirfd, path_addr); diff --git a/kernel/aster-nix/src/syscall/rt_sigaction.rs b/kernel/aster-nix/src/syscall/rt_sigaction.rs index 0dfed7e58..86c55383f 100644 --- a/kernel/aster-nix/src/syscall/rt_sigaction.rs +++ b/kernel/aster-nix/src/syscall/rt_sigaction.rs @@ -11,6 +11,7 @@ pub fn sys_rt_sigaction( sig_action_addr: Vaddr, old_sig_action_addr: Vaddr, sigset_size: u64, + _ctx: &Context, ) -> Result { let sig_num = SigNum::try_from(sig_num)?; debug!( diff --git a/kernel/aster-nix/src/syscall/rt_sigpending.rs b/kernel/aster-nix/src/syscall/rt_sigpending.rs index d017a434f..246958c12 100644 --- a/kernel/aster-nix/src/syscall/rt_sigpending.rs +++ b/kernel/aster-nix/src/syscall/rt_sigpending.rs @@ -5,7 +5,11 @@ use core::sync::atomic::Ordering; use super::SyscallReturn; use crate::{prelude::*, process::posix_thread::PosixThreadExt}; -pub fn sys_rt_sigpending(u_set_ptr: Vaddr, sigset_size: usize) -> Result { +pub fn sys_rt_sigpending( + u_set_ptr: Vaddr, + sigset_size: usize, + _ctx: &Context, +) -> Result { debug!( "u_set_ptr = 0x{:x}, sigset_size = {}", u_set_ptr, sigset_size diff --git a/kernel/aster-nix/src/syscall/rt_sigprocmask.rs b/kernel/aster-nix/src/syscall/rt_sigprocmask.rs index dd21e4051..ced101447 100644 --- a/kernel/aster-nix/src/syscall/rt_sigprocmask.rs +++ b/kernel/aster-nix/src/syscall/rt_sigprocmask.rs @@ -19,6 +19,7 @@ pub fn sys_rt_sigprocmask( set_ptr: Vaddr, oldset_ptr: Vaddr, sigset_size: usize, + _ctx: &Context, ) -> Result { let mask_op = MaskOp::try_from(how).unwrap(); debug!( diff --git a/kernel/aster-nix/src/syscall/rt_sigreturn.rs b/kernel/aster-nix/src/syscall/rt_sigreturn.rs index bd3701571..f9900ac6c 100644 --- a/kernel/aster-nix/src/syscall/rt_sigreturn.rs +++ b/kernel/aster-nix/src/syscall/rt_sigreturn.rs @@ -5,14 +5,15 @@ use core::sync::atomic::Ordering; use ostd::{cpu::UserContext, user::UserContextApi}; use super::SyscallReturn; -use crate::{ - prelude::*, - process::{posix_thread::PosixThreadExt, signal::c_types::ucontext_t}, -}; +use crate::{prelude::*, process::signal::c_types::ucontext_t}; -pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result { - let current_thread = current_thread!(); - let posix_thread = current_thread.as_posix_thread().unwrap(); +pub fn sys_rt_sigreturn(ctx: &Context, user_ctx: &mut UserContext) -> Result { + let Context { + process: _, + posix_thread, + thread: _, + task: _, + } = ctx; let mut sig_context = posix_thread.sig_context().lock(); if (*sig_context).is_none() { return_errno_with_message!(Errno::EINVAL, "sigreturn should not been called"); @@ -21,13 +22,13 @@ pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result { // FIXME: This assertion is not always true, if RESTORER flag is not presented. // In this case, we will put restorer code on user stack, then the assertion will fail. // However, for most glibc applications, the restorer codes is provided by glibc and RESTORER flag is set. - debug_assert!(sig_context_addr == context.stack_pointer() as Vaddr); + debug_assert!(sig_context_addr == user_ctx.stack_pointer() as Vaddr); let ucontext = CurrentUserSpace::get().read_val::(sig_context_addr)?; // If the sig stack is active and used by current handler, decrease handler counter. if let Some(sig_stack) = posix_thread.sig_stack().lock().as_mut() { - let rsp = context.stack_pointer(); + let rsp = user_ctx.stack_pointer(); if rsp >= sig_stack.base() && rsp <= sig_stack.base() + sig_stack.size() { sig_stack.decrease_handler_counter(); } @@ -43,7 +44,7 @@ pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result { .uc_mcontext .inner .gp_regs - .copy_to_raw(context.general_regs_mut()); + .copy_to_raw(user_ctx.general_regs_mut()); // unblock sig mask let sig_mask = ucontext.uc_sigmask; let old_mask = posix_thread.sig_mask().load(Ordering::Relaxed); diff --git a/kernel/aster-nix/src/syscall/rt_sigsuspend.rs b/kernel/aster-nix/src/syscall/rt_sigsuspend.rs index 273593f99..1a864f613 100644 --- a/kernel/aster-nix/src/syscall/rt_sigsuspend.rs +++ b/kernel/aster-nix/src/syscall/rt_sigsuspend.rs @@ -10,7 +10,11 @@ use crate::{ }, }; -pub fn sys_rt_sigsuspend(sigmask_addr: Vaddr, sigmask_size: usize) -> Result { +pub fn sys_rt_sigsuspend( + sigmask_addr: Vaddr, + sigmask_size: usize, + _ctx: &Context, +) -> Result { debug!( "sigmask_addr = 0x{:x}, sigmask_size = {}", sigmask_addr, sigmask_size diff --git a/kernel/aster-nix/src/syscall/sched_getaffinity.rs b/kernel/aster-nix/src/syscall/sched_getaffinity.rs index 01b63ae95..086d2d108 100644 --- a/kernel/aster-nix/src/syscall/sched_getaffinity.rs +++ b/kernel/aster-nix/src/syscall/sched_getaffinity.rs @@ -18,6 +18,7 @@ pub fn sys_sched_getaffinity( pid: Pid, cpuset_size: usize, cpu_set_ptr: Vaddr, + _ctx: &Context, ) -> Result { let num_cpus = get_num_cpus(); diff --git a/kernel/aster-nix/src/syscall/sched_yield.rs b/kernel/aster-nix/src/syscall/sched_yield.rs index c6d2da810..7035a4702 100644 --- a/kernel/aster-nix/src/syscall/sched_yield.rs +++ b/kernel/aster-nix/src/syscall/sched_yield.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{prelude::*, thread::Thread}; -pub fn sys_sched_yield() -> Result { +pub fn sys_sched_yield(_ctx: &Context) -> Result { Thread::yield_now(); Ok(SyscallReturn::Return(0)) } diff --git a/kernel/aster-nix/src/syscall/select.rs b/kernel/aster-nix/src/syscall/select.rs index bd48e1606..4ae5a8edb 100644 --- a/kernel/aster-nix/src/syscall/select.rs +++ b/kernel/aster-nix/src/syscall/select.rs @@ -14,6 +14,7 @@ pub fn sys_select( writefds_addr: Vaddr, exceptfds_addr: Vaddr, timeval_addr: Vaddr, + _ctx: &Context, ) -> Result { let timeout = if timeval_addr == 0 { None diff --git a/kernel/aster-nix/src/syscall/sendfile.rs b/kernel/aster-nix/src/syscall/sendfile.rs index 8f2a2bce8..24031c78b 100644 --- a/kernel/aster-nix/src/syscall/sendfile.rs +++ b/kernel/aster-nix/src/syscall/sendfile.rs @@ -8,6 +8,7 @@ pub fn sys_sendfile( in_fd: FileDesc, offset_ptr: Vaddr, count: isize, + _ctx: &Context, ) -> Result { trace!("raw offset ptr = 0x{:x}", offset_ptr); diff --git a/kernel/aster-nix/src/syscall/sendmsg.rs b/kernel/aster-nix/src/syscall/sendmsg.rs index 11f71a2d7..675e8bb3a 100644 --- a/kernel/aster-nix/src/syscall/sendmsg.rs +++ b/kernel/aster-nix/src/syscall/sendmsg.rs @@ -8,7 +8,12 @@ use crate::{ util::net::{get_socket_from_fd, CUserMsgHdr}, }; -pub fn sys_sendmsg(sockfd: FileDesc, user_msghdr_ptr: Vaddr, flags: i32) -> Result { +pub fn sys_sendmsg( + sockfd: FileDesc, + user_msghdr_ptr: Vaddr, + flags: i32, + _ctx: &Context, +) -> Result { let c_user_msghdr: CUserMsgHdr = CurrentUserSpace::get().read_val(user_msghdr_ptr)?; let flags = SendRecvFlags::from_bits_truncate(flags); diff --git a/kernel/aster-nix/src/syscall/sendto.rs b/kernel/aster-nix/src/syscall/sendto.rs index 683ad5428..e33538fa9 100644 --- a/kernel/aster-nix/src/syscall/sendto.rs +++ b/kernel/aster-nix/src/syscall/sendto.rs @@ -18,6 +18,7 @@ pub fn sys_sendto( flags: i32, dest_addr: Vaddr, addrlen: usize, + _ctx: &Context, ) -> Result { let flags = SendRecvFlags::from_bits_truncate(flags); let socket_addr = if dest_addr == 0 { diff --git a/kernel/aster-nix/src/syscall/set_get_priority.rs b/kernel/aster-nix/src/syscall/set_get_priority.rs index 7e5e2f82a..75201017b 100644 --- a/kernel/aster-nix/src/syscall/set_get_priority.rs +++ b/kernel/aster-nix/src/syscall/set_get_priority.rs @@ -9,7 +9,7 @@ use crate::{ sched::nice::Nice, }; -pub fn sys_set_priority(which: i32, who: u32, prio: i32) -> Result { +pub fn sys_set_priority(which: i32, who: u32, prio: i32, _ctx: &Context) -> Result { let prio_target = PriorityTarget::new(which, who)?; let new_nice = { let norm_prio = prio.clamp(i8::MIN as i32, i8::MAX as i32) as i8; @@ -29,7 +29,7 @@ pub fn sys_set_priority(which: i32, who: u32, prio: i32) -> Result Result { +pub fn sys_get_priority(which: i32, who: u32, _ctx: &Context) -> Result { let prio_target = PriorityTarget::new(which, who)?; debug!("get_priority prio_target: {:?}", prio_target); diff --git a/kernel/aster-nix/src/syscall/set_robust_list.rs b/kernel/aster-nix/src/syscall/set_robust_list.rs index 1e1ba33f6..80a6cf90c 100644 --- a/kernel/aster-nix/src/syscall/set_robust_list.rs +++ b/kernel/aster-nix/src/syscall/set_robust_list.rs @@ -6,7 +6,11 @@ use crate::{ process::posix_thread::{PosixThreadExt, RobustListHead}, }; -pub fn sys_set_robust_list(robust_list_head_ptr: Vaddr, len: usize) -> Result { +pub fn sys_set_robust_list( + robust_list_head_ptr: Vaddr, + len: usize, + _ctx: &Context, +) -> Result { debug!( "robust list head ptr: 0x{:x}, len = {}", robust_list_head_ptr, len diff --git a/kernel/aster-nix/src/syscall/set_tid_address.rs b/kernel/aster-nix/src/syscall/set_tid_address.rs index a6476d7fc..ee0037f93 100644 --- a/kernel/aster-nix/src/syscall/set_tid_address.rs +++ b/kernel/aster-nix/src/syscall/set_tid_address.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{prelude::*, process::posix_thread::PosixThreadExt}; -pub fn sys_set_tid_address(tidptr: Vaddr) -> Result { +pub fn sys_set_tid_address(tidptr: Vaddr, _ctx: &Context) -> Result { debug!("tidptr = 0x{:x}", tidptr); let current_thread = current_thread!(); let posix_thread = current_thread.as_posix_thread().unwrap(); diff --git a/kernel/aster-nix/src/syscall/setfsgid.rs b/kernel/aster-nix/src/syscall/setfsgid.rs index c2dec3bac..d6080f5ae 100644 --- a/kernel/aster-nix/src/syscall/setfsgid.rs +++ b/kernel/aster-nix/src/syscall/setfsgid.rs @@ -6,7 +6,7 @@ use crate::{ process::{credentials_mut, Gid}, }; -pub fn sys_setfsgid(gid: i32) -> Result { +pub fn sys_setfsgid(gid: i32, _ctx: &Context) -> Result { debug!("gid = {}", gid); let fsgid = if gid < 0 { diff --git a/kernel/aster-nix/src/syscall/setfsuid.rs b/kernel/aster-nix/src/syscall/setfsuid.rs index 3563c4063..b751cf7f3 100644 --- a/kernel/aster-nix/src/syscall/setfsuid.rs +++ b/kernel/aster-nix/src/syscall/setfsuid.rs @@ -6,7 +6,7 @@ use crate::{ process::{credentials_mut, Uid}, }; -pub fn sys_setfsuid(uid: i32) -> Result { +pub fn sys_setfsuid(uid: i32, _ctx: &Context) -> Result { debug!("uid = {}", uid); let fsuid = if uid < 0 { diff --git a/kernel/aster-nix/src/syscall/setgid.rs b/kernel/aster-nix/src/syscall/setgid.rs index d48948feb..a26a6bf2b 100644 --- a/kernel/aster-nix/src/syscall/setgid.rs +++ b/kernel/aster-nix/src/syscall/setgid.rs @@ -6,7 +6,7 @@ use crate::{ process::{credentials_mut, Gid}, }; -pub fn sys_setgid(gid: i32) -> Result { +pub fn sys_setgid(gid: i32, _ctx: &Context) -> Result { debug!("gid = {}", gid); if gid < 0 { diff --git a/kernel/aster-nix/src/syscall/setgroups.rs b/kernel/aster-nix/src/syscall/setgroups.rs index cb658dbe8..9c7f65954 100644 --- a/kernel/aster-nix/src/syscall/setgroups.rs +++ b/kernel/aster-nix/src/syscall/setgroups.rs @@ -6,7 +6,7 @@ use crate::{ process::{credentials_mut, Gid}, }; -pub fn sys_setgroups(size: usize, group_list_addr: Vaddr) -> Result { +pub fn sys_setgroups(size: usize, group_list_addr: Vaddr, _ctx: &Context) -> Result { debug!("size = {}, group_list_addr = 0x{:x}", size, group_list_addr); // TODO: check perm: the calling process should have the CAP_SETGID capability diff --git a/kernel/aster-nix/src/syscall/setitimer.rs b/kernel/aster-nix/src/syscall/setitimer.rs index c50216415..380b66d8d 100644 --- a/kernel/aster-nix/src/syscall/setitimer.rs +++ b/kernel/aster-nix/src/syscall/setitimer.rs @@ -22,6 +22,7 @@ pub fn sys_setitimer( itimer_type: i32, new_itimerval_addr: Vaddr, old_itimerval_addr: Vaddr, + _ctx: &Context, ) -> Result { debug!( "itimer_type = {}, new_itimerval_addr = 0x{:x}, old_itimerval_addr = 0x{:x}, ", @@ -65,7 +66,11 @@ pub fn sys_setitimer( Ok(SyscallReturn::Return(0)) } -pub fn sys_getitimer(itimer_type: i32, itimerval_addr: Vaddr) -> Result { +pub fn sys_getitimer( + itimer_type: i32, + itimerval_addr: Vaddr, + _ctx: &Context, +) -> Result { debug!( "itimer_type = {}, itimerval_addr = 0x{:x}", itimer_type, itimerval_addr diff --git a/kernel/aster-nix/src/syscall/setpgid.rs b/kernel/aster-nix/src/syscall/setpgid.rs index 2b60c94ed..6afd2bd82 100644 --- a/kernel/aster-nix/src/syscall/setpgid.rs +++ b/kernel/aster-nix/src/syscall/setpgid.rs @@ -6,7 +6,7 @@ use crate::{ process::{process_table, Pgid, Pid}, }; -pub fn sys_setpgid(pid: Pid, pgid: Pgid) -> Result { +pub fn sys_setpgid(pid: Pid, pgid: Pgid, _ctx: &Context) -> Result { let current = current!(); // if pid is 0, pid should be the pid of current process let pid = if pid == 0 { current.pid() } else { pid }; diff --git a/kernel/aster-nix/src/syscall/setregid.rs b/kernel/aster-nix/src/syscall/setregid.rs index e38acd653..46997e9bb 100644 --- a/kernel/aster-nix/src/syscall/setregid.rs +++ b/kernel/aster-nix/src/syscall/setregid.rs @@ -6,7 +6,7 @@ use crate::{ process::{credentials_mut, Gid}, }; -pub fn sys_setregid(rgid: i32, egid: i32) -> Result { +pub fn sys_setregid(rgid: i32, egid: i32, _ctx: &Context) -> Result { debug!("rgid = {}, egid = {}", rgid, egid); let rgid = if rgid > 0 { diff --git a/kernel/aster-nix/src/syscall/setresgid.rs b/kernel/aster-nix/src/syscall/setresgid.rs index 0868dfe2f..4ce0b2687 100644 --- a/kernel/aster-nix/src/syscall/setresgid.rs +++ b/kernel/aster-nix/src/syscall/setresgid.rs @@ -6,7 +6,7 @@ use crate::{ process::{credentials_mut, Gid}, }; -pub fn sys_setresgid(rgid: i32, egid: i32, sgid: i32) -> Result { +pub fn sys_setresgid(rgid: i32, egid: i32, sgid: i32, _ctx: &Context) -> Result { let rgid = if rgid > 0 { Some(Gid::new(rgid as u32)) } else { diff --git a/kernel/aster-nix/src/syscall/setresuid.rs b/kernel/aster-nix/src/syscall/setresuid.rs index c8b5aa499..1b9ef2737 100644 --- a/kernel/aster-nix/src/syscall/setresuid.rs +++ b/kernel/aster-nix/src/syscall/setresuid.rs @@ -6,7 +6,7 @@ use crate::{ process::{credentials_mut, Uid}, }; -pub fn sys_setresuid(ruid: i32, euid: i32, suid: i32) -> Result { +pub fn sys_setresuid(ruid: i32, euid: i32, suid: i32, _ctx: &Context) -> Result { let ruid = if ruid > 0 { Some(Uid::new(ruid as u32)) } else { diff --git a/kernel/aster-nix/src/syscall/setreuid.rs b/kernel/aster-nix/src/syscall/setreuid.rs index 5efcd9849..b394b42ed 100644 --- a/kernel/aster-nix/src/syscall/setreuid.rs +++ b/kernel/aster-nix/src/syscall/setreuid.rs @@ -6,7 +6,7 @@ use crate::{ process::{credentials_mut, Uid}, }; -pub fn sys_setreuid(ruid: i32, euid: i32) -> Result { +pub fn sys_setreuid(ruid: i32, euid: i32, _ctx: &Context) -> Result { debug!("ruid = {}, euid = {}", ruid, euid); let ruid = if ruid > 0 { diff --git a/kernel/aster-nix/src/syscall/setsid.rs b/kernel/aster-nix/src/syscall/setsid.rs index e0fb3df8d..c9a6e13a0 100644 --- a/kernel/aster-nix/src/syscall/setsid.rs +++ b/kernel/aster-nix/src/syscall/setsid.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::prelude::*; -pub fn sys_setsid() -> Result { +pub fn sys_setsid(_ctx: &Context) -> Result { let current = current!(); let session = current.to_new_session()?; diff --git a/kernel/aster-nix/src/syscall/setsockopt.rs b/kernel/aster-nix/src/syscall/setsockopt.rs index c74fd3583..75d9cbfb9 100644 --- a/kernel/aster-nix/src/syscall/setsockopt.rs +++ b/kernel/aster-nix/src/syscall/setsockopt.rs @@ -13,6 +13,7 @@ pub fn sys_setsockopt( optname: i32, optval: Vaddr, optlen: u32, + _ctx: &Context, ) -> Result { let level = CSocketOptionLevel::try_from(level)?; if optval == 0 { diff --git a/kernel/aster-nix/src/syscall/setuid.rs b/kernel/aster-nix/src/syscall/setuid.rs index eb2e78456..7f0d3715d 100644 --- a/kernel/aster-nix/src/syscall/setuid.rs +++ b/kernel/aster-nix/src/syscall/setuid.rs @@ -6,7 +6,7 @@ use crate::{ process::{credentials_mut, Uid}, }; -pub fn sys_setuid(uid: i32) -> Result { +pub fn sys_setuid(uid: i32, _ctx: &Context) -> Result { debug!("uid = {}", uid); if uid < 0 { diff --git a/kernel/aster-nix/src/syscall/shutdown.rs b/kernel/aster-nix/src/syscall/shutdown.rs index 78c2ea8d7..80d5acaaf 100644 --- a/kernel/aster-nix/src/syscall/shutdown.rs +++ b/kernel/aster-nix/src/syscall/shutdown.rs @@ -6,7 +6,7 @@ use crate::{ util::net::get_socket_from_fd, }; -pub fn sys_shutdown(sockfd: FileDesc, how: i32) -> Result { +pub fn sys_shutdown(sockfd: FileDesc, how: i32, _ctx: &Context) -> Result { let shutdown_cmd = SockShutdownCmd::try_from(how)?; debug!("sockfd = {sockfd}, cmd = {shutdown_cmd:?}"); diff --git a/kernel/aster-nix/src/syscall/sigaltstack.rs b/kernel/aster-nix/src/syscall/sigaltstack.rs index 6b856c4bc..d4484d9d0 100644 --- a/kernel/aster-nix/src/syscall/sigaltstack.rs +++ b/kernel/aster-nix/src/syscall/sigaltstack.rs @@ -9,7 +9,11 @@ use crate::{ }, }; -pub fn sys_sigaltstack(sig_stack_addr: Vaddr, old_sig_stack_addr: Vaddr) -> Result { +pub fn sys_sigaltstack( + sig_stack_addr: Vaddr, + old_sig_stack_addr: Vaddr, + _ctx: &Context, +) -> Result { debug!( "sig_stack_addr = 0x{:x}, old_sig_stack_addr: 0x{:x}", sig_stack_addr, old_sig_stack_addr diff --git a/kernel/aster-nix/src/syscall/socket.rs b/kernel/aster-nix/src/syscall/socket.rs index 9b49485d6..d01d138e4 100644 --- a/kernel/aster-nix/src/syscall/socket.rs +++ b/kernel/aster-nix/src/syscall/socket.rs @@ -12,7 +12,7 @@ use crate::{ util::net::{CSocketAddrFamily, Protocol, SockFlags, SockType, SOCK_TYPE_MASK}, }; -pub fn sys_socket(domain: i32, type_: i32, protocol: i32) -> Result { +pub fn sys_socket(domain: i32, type_: i32, protocol: i32, _ctx: &Context) -> Result { let domain = CSocketAddrFamily::try_from(domain)?; let sock_type = SockType::try_from(type_ & SOCK_TYPE_MASK)?; let sock_flags = SockFlags::from_bits_truncate(type_ & !SOCK_TYPE_MASK); diff --git a/kernel/aster-nix/src/syscall/socketpair.rs b/kernel/aster-nix/src/syscall/socketpair.rs index 0a92ea6f1..921c10864 100644 --- a/kernel/aster-nix/src/syscall/socketpair.rs +++ b/kernel/aster-nix/src/syscall/socketpair.rs @@ -8,7 +8,13 @@ use crate::{ util::net::{CSocketAddrFamily, Protocol, SockFlags, SockType, SOCK_TYPE_MASK}, }; -pub fn sys_socketpair(domain: i32, type_: i32, protocol: i32, sv: Vaddr) -> Result { +pub fn sys_socketpair( + domain: i32, + type_: i32, + protocol: i32, + sv: Vaddr, + _ctx: &Context, +) -> Result { let domain = CSocketAddrFamily::try_from(domain)?; let sock_type = SockType::try_from(type_ & SOCK_TYPE_MASK)?; let sock_flags = SockFlags::from_bits_truncate(type_ & !SOCK_TYPE_MASK); diff --git a/kernel/aster-nix/src/syscall/stat.rs b/kernel/aster-nix/src/syscall/stat.rs index df05b7e93..69b2c9ce4 100644 --- a/kernel/aster-nix/src/syscall/stat.rs +++ b/kernel/aster-nix/src/syscall/stat.rs @@ -12,7 +12,7 @@ use crate::{ time::timespec_t, }; -pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr) -> Result { +pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr, _ctx: &Context) -> Result { debug!("fd = {}, stat_buf_addr = 0x{:x}", fd, stat_buf_ptr); let current = current!(); @@ -23,16 +23,17 @@ pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr) -> Result { Ok(SyscallReturn::Return(0)) } -pub fn sys_stat(filename_ptr: Vaddr, stat_buf_ptr: Vaddr) -> Result { - self::sys_fstatat(AT_FDCWD, filename_ptr, stat_buf_ptr, 0) +pub fn sys_stat(filename_ptr: Vaddr, stat_buf_ptr: Vaddr, ctx: &Context) -> Result { + self::sys_fstatat(AT_FDCWD, filename_ptr, stat_buf_ptr, 0, ctx) } -pub fn sys_lstat(filename_ptr: Vaddr, stat_buf_ptr: Vaddr) -> Result { +pub fn sys_lstat(filename_ptr: Vaddr, stat_buf_ptr: Vaddr, ctx: &Context) -> Result { self::sys_fstatat( AT_FDCWD, filename_ptr, stat_buf_ptr, StatFlags::AT_SYMLINK_NOFOLLOW.bits(), + ctx, ) } @@ -41,6 +42,7 @@ pub fn sys_fstatat( filename_ptr: Vaddr, stat_buf_ptr: Vaddr, flags: u32, + ctx: &Context, ) -> Result { let user_space = CurrentUserSpace::get(); let filename = user_space.read_cstring(filename_ptr, MAX_FILENAME_LEN)?; @@ -56,7 +58,7 @@ pub fn sys_fstatat( return_errno_with_message!(Errno::ENOENT, "path is empty"); } // In this case, the behavior of fstatat() is similar to that of fstat(). - return self::sys_fstat(dirfd, stat_buf_ptr); + return self::sys_fstat(dirfd, stat_buf_ptr, ctx); } let current = current!(); diff --git a/kernel/aster-nix/src/syscall/statfs.rs b/kernel/aster-nix/src/syscall/statfs.rs index 1a6b1a6d2..0228821b2 100644 --- a/kernel/aster-nix/src/syscall/statfs.rs +++ b/kernel/aster-nix/src/syscall/statfs.rs @@ -11,7 +11,7 @@ use crate::{ prelude::*, }; -pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr) -> Result { +pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr, _ctx: &Context) -> Result { let user_space = CurrentUserSpace::get(); let path = user_space.read_cstring(path_ptr, PATH_MAX)?; debug!("path = {:?}, statfs_buf_ptr = 0x{:x}", path, statfs_buf_ptr,); @@ -27,7 +27,7 @@ pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr) -> Result Result { +pub fn sys_fstatfs(fd: FileDesc, statfs_buf_ptr: Vaddr, _ctx: &Context) -> Result { debug!("fd = {}, statfs_buf_addr = 0x{:x}", fd, statfs_buf_ptr); let current = current!(); diff --git a/kernel/aster-nix/src/syscall/symlink.rs b/kernel/aster-nix/src/syscall/symlink.rs index 3f9357271..0aeec9b75 100644 --- a/kernel/aster-nix/src/syscall/symlink.rs +++ b/kernel/aster-nix/src/syscall/symlink.rs @@ -15,6 +15,7 @@ pub fn sys_symlinkat( target_addr: Vaddr, dirfd: FileDesc, linkpath_addr: Vaddr, + _ctx: &Context, ) -> Result { let user_space = CurrentUserSpace::get(); let target = user_space.read_cstring(target_addr, MAX_FILENAME_LEN)?; @@ -50,6 +51,10 @@ pub fn sys_symlinkat( Ok(SyscallReturn::Return(0)) } -pub fn sys_symlink(target_addr: Vaddr, linkpath_addr: Vaddr) -> Result { - self::sys_symlinkat(target_addr, AT_FDCWD, linkpath_addr) +pub fn sys_symlink( + target_addr: Vaddr, + linkpath_addr: Vaddr, + ctx: &Context, +) -> Result { + self::sys_symlinkat(target_addr, AT_FDCWD, linkpath_addr, ctx) } diff --git a/kernel/aster-nix/src/syscall/sync.rs b/kernel/aster-nix/src/syscall/sync.rs index c6d068020..4a7180e16 100644 --- a/kernel/aster-nix/src/syscall/sync.rs +++ b/kernel/aster-nix/src/syscall/sync.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::prelude::*; -pub fn sys_sync() -> Result { +pub fn sys_sync(_ctx: &Context) -> Result { crate::fs::rootfs::root_mount().sync()?; Ok(SyscallReturn::Return(0)) } diff --git a/kernel/aster-nix/src/syscall/tgkill.rs b/kernel/aster-nix/src/syscall/tgkill.rs index 197f5754a..fad4d4488 100644 --- a/kernel/aster-nix/src/syscall/tgkill.rs +++ b/kernel/aster-nix/src/syscall/tgkill.rs @@ -15,7 +15,7 @@ use crate::{ }; /// tgkill send a signal to a thread with pid as its thread id, and tgid as its thread group id. -pub fn sys_tgkill(tgid: Pid, tid: Tid, sig_num: u8) -> Result { +pub fn sys_tgkill(tgid: Pid, tid: Tid, sig_num: u8, _ctx: &Context) -> Result { let sig_num = if sig_num == 0 { None } else { diff --git a/kernel/aster-nix/src/syscall/time.rs b/kernel/aster-nix/src/syscall/time.rs index 1c10b0d60..973cd36fa 100644 --- a/kernel/aster-nix/src/syscall/time.rs +++ b/kernel/aster-nix/src/syscall/time.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::{prelude::*, time::SystemTime}; -pub fn sys_time(tloc: Vaddr) -> Result { +pub fn sys_time(tloc: Vaddr, _ctx: &Context) -> Result { debug!("tloc = 0x{tloc:x}"); let now_as_secs = { diff --git a/kernel/aster-nix/src/syscall/timer_create.rs b/kernel/aster-nix/src/syscall/timer_create.rs index 38be5c7bb..c32b5dafe 100644 --- a/kernel/aster-nix/src/syscall/timer_create.rs +++ b/kernel/aster-nix/src/syscall/timer_create.rs @@ -31,6 +31,7 @@ pub fn sys_timer_create( clockid: clockid_t, sigevent_addr: Vaddr, timer_id_addr: Vaddr, + _ctx: &Context, ) -> Result { if timer_id_addr == 0 { return_errno_with_message!( @@ -155,7 +156,7 @@ pub fn sys_timer_create( Ok(SyscallReturn::Return(0)) } -pub fn sys_timer_delete(timer_id: usize) -> Result { +pub fn sys_timer_delete(timer_id: usize, _ctx: &Context) -> Result { let current_process = current!(); let Some(timer) = current_process.timer_manager().remove_posix_timer(timer_id) else { return_errno_with_message!(Errno::EINVAL, "invalid timer ID"); diff --git a/kernel/aster-nix/src/syscall/timer_settime.rs b/kernel/aster-nix/src/syscall/timer_settime.rs index 468c54277..1382fd3e3 100644 --- a/kernel/aster-nix/src/syscall/timer_settime.rs +++ b/kernel/aster-nix/src/syscall/timer_settime.rs @@ -13,6 +13,7 @@ pub fn sys_timer_settime( flags: i32, new_itimerspec_addr: Vaddr, old_itimerspec_addr: Vaddr, + _ctx: &Context, ) -> Result { if new_itimerspec_addr == 0 { return_errno_with_message!(Errno::EINVAL, "invalid pointer to new value"); @@ -56,7 +57,11 @@ pub fn sys_timer_settime( Ok(SyscallReturn::Return(0)) } -pub fn sys_timer_gettime(timer_id: usize, itimerspec_addr: Vaddr) -> Result { +pub fn sys_timer_gettime( + timer_id: usize, + itimerspec_addr: Vaddr, + _ctx: &Context, +) -> Result { if itimerspec_addr == 0 { return_errno_with_message!(Errno::EINVAL, "invalid pointer to return value"); } diff --git a/kernel/aster-nix/src/syscall/truncate.rs b/kernel/aster-nix/src/syscall/truncate.rs index 1fd9db449..ab4141c41 100644 --- a/kernel/aster-nix/src/syscall/truncate.rs +++ b/kernel/aster-nix/src/syscall/truncate.rs @@ -11,7 +11,7 @@ use crate::{ process::ResourceType, }; -pub fn sys_ftruncate(fd: FileDesc, len: isize) -> Result { +pub fn sys_ftruncate(fd: FileDesc, len: isize, _ctx: &Context) -> Result { debug!("fd = {}, lentgh = {}", fd, len); check_length(len)?; @@ -23,7 +23,7 @@ pub fn sys_ftruncate(fd: FileDesc, len: isize) -> Result { Ok(SyscallReturn::Return(0)) } -pub fn sys_truncate(path_ptr: Vaddr, len: isize) -> Result { +pub fn sys_truncate(path_ptr: Vaddr, len: isize, _ctx: &Context) -> Result { let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?; debug!("path = {:?}, length = {}", path, len); diff --git a/kernel/aster-nix/src/syscall/umask.rs b/kernel/aster-nix/src/syscall/umask.rs index 4a8549ded..1429e333c 100644 --- a/kernel/aster-nix/src/syscall/umask.rs +++ b/kernel/aster-nix/src/syscall/umask.rs @@ -3,7 +3,7 @@ use super::SyscallReturn; use crate::prelude::*; -pub fn sys_umask(mask: u16) -> Result { +pub fn sys_umask(mask: u16, _ctx: &Context) -> Result { debug!("mask = 0o{:o}", mask); let current = current!(); let old_mask = current.umask().write().set(mask); diff --git a/kernel/aster-nix/src/syscall/umount.rs b/kernel/aster-nix/src/syscall/umount.rs index 7f65fc61f..22b991274 100644 --- a/kernel/aster-nix/src/syscall/umount.rs +++ b/kernel/aster-nix/src/syscall/umount.rs @@ -7,7 +7,7 @@ use crate::{ syscall::constants::MAX_FILENAME_LEN, }; -pub fn sys_umount(path_addr: Vaddr, flags: u64) -> Result { +pub fn sys_umount(path_addr: Vaddr, flags: u64, _ctx: &Context) -> Result { let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?; let umount_flags = UmountFlags::from_bits_truncate(flags as u32); debug!("path = {:?}, flags = {:?}", path, umount_flags); diff --git a/kernel/aster-nix/src/syscall/uname.rs b/kernel/aster-nix/src/syscall/uname.rs index 41e2dbd75..d3fcefac1 100644 --- a/kernel/aster-nix/src/syscall/uname.rs +++ b/kernel/aster-nix/src/syscall/uname.rs @@ -57,7 +57,7 @@ fn copy_cstring_to_u8_slice(src: &CStr, dst: &mut [u8]) { dst[..len].copy_from_slice(&src[..len]); } -pub fn sys_uname(old_uname_addr: Vaddr) -> Result { +pub fn sys_uname(old_uname_addr: Vaddr, _ctx: &Context) -> Result { debug!("old uname addr = 0x{:x}", old_uname_addr); CurrentUserSpace::get().write_val(old_uname_addr, &*UTS_NAME)?; Ok(SyscallReturn::Return(0)) diff --git a/kernel/aster-nix/src/syscall/unlink.rs b/kernel/aster-nix/src/syscall/unlink.rs index b40428768..fa6dcf119 100644 --- a/kernel/aster-nix/src/syscall/unlink.rs +++ b/kernel/aster-nix/src/syscall/unlink.rs @@ -10,11 +10,16 @@ use crate::{ syscall::constants::MAX_FILENAME_LEN, }; -pub fn sys_unlinkat(dirfd: FileDesc, path_addr: Vaddr, flags: u32) -> Result { +pub fn sys_unlinkat( + dirfd: FileDesc, + path_addr: Vaddr, + flags: u32, + ctx: &Context, +) -> Result { let flags = UnlinkFlags::from_bits(flags).ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))?; if flags.contains(UnlinkFlags::AT_REMOVEDIR) { - return super::rmdir::sys_rmdirat(dirfd, path_addr); + return super::rmdir::sys_rmdirat(dirfd, path_addr, ctx); } let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?; @@ -36,8 +41,8 @@ pub fn sys_unlinkat(dirfd: FileDesc, path_addr: Vaddr, flags: u32) -> Result Result { - self::sys_unlinkat(AT_FDCWD, path_addr, 0) +pub fn sys_unlink(path_addr: Vaddr, ctx: &Context) -> Result { + self::sys_unlinkat(AT_FDCWD, path_addr, 0, ctx) } bitflags::bitflags! { diff --git a/kernel/aster-nix/src/syscall/utimens.rs b/kernel/aster-nix/src/syscall/utimens.rs index 9bdf6052a..15823a141 100644 --- a/kernel/aster-nix/src/syscall/utimens.rs +++ b/kernel/aster-nix/src/syscall/utimens.rs @@ -23,6 +23,7 @@ pub fn sys_utimensat( pathname_ptr: Vaddr, timespecs_ptr: Vaddr, flags: u32, + _ctx: &Context, ) -> Result { debug!( "utimensat: dirfd: {}, pathname_ptr: {:#x}, timespecs_ptr: {:#x}, flags: {:#x}", @@ -50,6 +51,7 @@ pub fn sys_futimesat( dirfd: FileDesc, pathname_ptr: Vaddr, timeval_ptr: Vaddr, + _ctx: &Context, ) -> Result { debug!( "futimesat: dirfd: {}, pathname_ptr: {:#x}, timeval_ptr: {:#x}", @@ -61,7 +63,11 @@ pub fn sys_futimesat( /// The 'sys_utimes' system call sets the access and modification times of a file. /// It receives time values in the form of timeval structures like 'sys_futimesat', /// but it uses the current working directory as the base directory. -pub fn sys_utimes(pathname_ptr: Vaddr, timeval_ptr: Vaddr) -> Result { +pub fn sys_utimes( + pathname_ptr: Vaddr, + timeval_ptr: Vaddr, + _ctx: &Context, +) -> Result { debug!( "utimes: pathname_ptr: {:#x}, timeval_ptr: {:#x}", pathname_ptr, timeval_ptr @@ -70,7 +76,7 @@ pub fn sys_utimes(pathname_ptr: Vaddr, timeval_ptr: Vaddr) -> Result Result { +pub fn sys_utime(pathname_ptr: Vaddr, utimbuf_ptr: Vaddr, _ctx: &Context) -> Result { debug!( "utime: pathname_ptr: {:#x}, utimbuf_ptr: {:#x}", pathname_ptr, utimbuf_ptr diff --git a/kernel/aster-nix/src/syscall/wait4.rs b/kernel/aster-nix/src/syscall/wait4.rs index f823756a8..52828e48a 100644 --- a/kernel/aster-nix/src/syscall/wait4.rs +++ b/kernel/aster-nix/src/syscall/wait4.rs @@ -11,6 +11,7 @@ pub fn sys_wait4( exit_status_ptr: u64, wait_options: u32, rusage_addr: Vaddr, + _ctx: &Context, ) -> Result { let wait_options = WaitOptions::from_bits(wait_options) .ok_or_else(|| Error::with_message(Errno::EINVAL, "unknown wait option"))?; diff --git a/kernel/aster-nix/src/syscall/waitid.rs b/kernel/aster-nix/src/syscall/waitid.rs index 8446a2853..ff85bfc92 100644 --- a/kernel/aster-nix/src/syscall/waitid.rs +++ b/kernel/aster-nix/src/syscall/waitid.rs @@ -12,6 +12,7 @@ pub fn sys_waitid( _infoq_addr: u64, options: u64, _rusage_addr: u64, + _ctx: &Context, ) -> Result { // FIXME: what does infoq and rusage use for? let process_filter = ProcessFilter::from_which_and_id(which, upid); diff --git a/kernel/aster-nix/src/syscall/write.rs b/kernel/aster-nix/src/syscall/write.rs index 3fe0e8fcf..bed036ad7 100644 --- a/kernel/aster-nix/src/syscall/write.rs +++ b/kernel/aster-nix/src/syscall/write.rs @@ -3,7 +3,12 @@ use super::SyscallReturn; use crate::{fs::file_table::FileDesc, prelude::*}; -pub fn sys_write(fd: FileDesc, user_buf_ptr: Vaddr, user_buf_len: usize) -> Result { +pub fn sys_write( + fd: FileDesc, + user_buf_ptr: Vaddr, + user_buf_len: usize, + _ctx: &Context, +) -> Result { debug!( "fd = {}, user_buf_ptr = 0x{:x}, user_buf_len = 0x{:x}", fd, user_buf_ptr, user_buf_len diff --git a/kernel/aster-nix/src/thread/exception.rs b/kernel/aster-nix/src/thread/exception.rs index b6fa39c2f..2c0eb9bb4 100644 --- a/kernel/aster-nix/src/thread/exception.rs +++ b/kernel/aster-nix/src/thread/exception.rs @@ -10,12 +10,11 @@ use crate::{ }; /// We can't handle most exceptions, just send self a fault signal before return to user space. -pub fn handle_exception(context: &UserContext) { +pub fn handle_exception(ctx: &Context, context: &UserContext) { let trap_info = context.trap_information(); let exception = CpuException::to_cpu_exception(trap_info.id as u16).unwrap(); log_trap_info(exception, trap_info); - let current = current!(); - let root_vmar = current.root_vmar(); + let root_vmar = ctx.process.root_vmar(); match *exception { PAGE_FAULT => { diff --git a/kernel/aster-nix/src/thread/task.rs b/kernel/aster-nix/src/thread/task.rs index 2e75f4bf4..63692339f 100644 --- a/kernel/aster-nix/src/thread/task.rs +++ b/kernel/aster-nix/src/thread/task.rs @@ -19,7 +19,10 @@ use crate::{ pub fn create_new_user_task(user_space: Arc, thread_ref: Weak) -> Arc { fn user_task_entry() { let current_thread = current_thread!(); + let current_posix_thread = current_thread.as_posix_thread().unwrap(); + let current_process = current_posix_thread.process(); let current_task = current_thread.task(); + let user_space = current_task .user_space() .expect("user task should have user space"); @@ -37,9 +40,7 @@ pub fn create_new_user_task(user_space: Arc, thread_ref: Weak user_mode.context().syscall_ret() ); - let posix_thread = current_thread.as_posix_thread().unwrap(); - - let child_tid_ptr = *posix_thread.set_child_tid().lock(); + let child_tid_ptr = *current_posix_thread.set_child_tid().lock(); // The `clone` syscall may require child process to write the thread pid to the specified address. // Make sure the store operation completes before the clone call returns control to user space @@ -49,26 +50,35 @@ pub fn create_new_user_task(user_space: Arc, thread_ref: Weak .write_val(child_tid_ptr, ¤t_thread.tid()) .unwrap(); } - let has_kernel_event_fn = || posix_thread.has_pending(); + + let has_kernel_event_fn = || current_posix_thread.has_pending(); + + let ctx = Context { + process: current_process.as_ref(), + posix_thread: current_posix_thread, + thread: current_thread.as_ref(), + task: current_task.as_ref(), + }; + loop { let return_reason = user_mode.execute(has_kernel_event_fn); - let context = user_mode.context_mut(); + let user_ctx = user_mode.context_mut(); // handle user event: match return_reason { - ReturnReason::UserException => handle_exception(context), - ReturnReason::UserSyscall => handle_syscall(context), + ReturnReason::UserException => handle_exception(&ctx, user_ctx), + ReturnReason::UserSyscall => handle_syscall(&ctx, user_ctx), ReturnReason::KernelEvent => {} }; if current_thread.status().is_exited() { break; } - handle_pending_signal(context, ¤t_thread).unwrap(); + handle_pending_signal(user_ctx, ¤t_thread).unwrap(); // If current is suspended, wait for a signal to wake up self while current_thread.status().is_stopped() { Thread::yield_now(); debug!("{} is suspended.", current_thread.tid()); - handle_pending_signal(context, ¤t_thread).unwrap(); + handle_pending_signal(user_ctx, ¤t_thread).unwrap(); } if current_thread.status().is_exited() { debug!("exit due to signal"); diff --git a/kernel/aster-nix/src/util/mod.rs b/kernel/aster-nix/src/util/mod.rs index 3c711ea88..53298294e 100644 --- a/kernel/aster-nix/src/util/mod.rs +++ b/kernel/aster-nix/src/util/mod.rs @@ -1,218 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 -use core::mem; - -use ostd::{ - mm::{UserSpace, VmReader, VmSpace, VmWriter}, - task::Task, -}; - -use crate::prelude::*; mod iovec; pub mod net; pub mod random; pub use iovec::{copy_iovs_from_user, IoVec}; - -/// A struct represents owning the user space of the current task, -/// and provides the ability to do reading and writing instructions -/// for the user space. -pub struct CurrentUserSpace(Arc); - -impl !Sync for CurrentUserSpace {} -impl !Send for CurrentUserSpace {} - -impl CurrentUserSpace { - /// Gets the `CurrentUserSpace` from the current task. - pub fn get() -> Self { - let vm_space = { - let current_task = Task::current().unwrap(); - let user_space = current_task.user_space().unwrap(); - user_space.vm_space().clone() - }; - Self(vm_space) - } - - /// Creates a reader to read data from the user space of the current task. - /// - /// Returns `Err` if the `vaddr` and `len` do not represent a user space memory range. - pub fn reader(&self, vaddr: Vaddr, len: usize) -> Result> { - Ok(self.0.reader(vaddr, len)?) - } - - /// Creates a writer to write data into the user space. - /// - /// Returns `Err` if the `vaddr` and `len` do not represent a user space memory range. - pub fn writer(&self, vaddr: Vaddr, len: usize) -> Result> { - Ok(self.0.writer(vaddr, len)?) - } - - /// Reads bytes into the destination `VmWriter` from the user space of the - /// current process. - /// - /// If the reading is completely successful, returns `Ok`. Otherwise, it - /// returns `Err`. - /// - /// If the destination `VmWriter` (`dest`) is empty, this function still - /// checks if the current task and user space are available. If they are, - /// it returns `Ok`. - pub fn read_bytes(&self, src: Vaddr, dest: &mut VmWriter<'_>) -> Result<()> { - let copy_len = dest.avail(); - - if copy_len > 0 { - check_vaddr(src)?; - } - - let mut user_reader = self.reader(src, copy_len)?; - user_reader.read_fallible(dest).map_err(|err| err.0)?; - Ok(()) - } - - /// Reads a value typed `Pod` from the user space of the current process. - pub fn read_val(&self, src: Vaddr) -> Result { - if core::mem::size_of::() > 0 { - check_vaddr(src)?; - } - - let mut user_reader = self.reader(src, core::mem::size_of::())?; - Ok(user_reader.read_val()?) - } - - /// Writes bytes from the source `VmReader` to the user space of the current - /// process. - /// - /// If the writing is completely successful, returns `Ok`. Otherwise, it - /// returns `Err`. - /// - /// If the source `VmReader` (`src`) is empty, this function still checks if - /// the current task and user space are available. If they are, it returns - /// `Ok`. - pub fn write_bytes(&self, dest: Vaddr, src: &mut VmReader<'_>) -> Result<()> { - let copy_len = src.remain(); - - if copy_len > 0 { - check_vaddr(dest)?; - } - - let mut user_writer = self.writer(dest, copy_len)?; - user_writer.write_fallible(src).map_err(|err| err.0)?; - Ok(()) - } - - /// Writes `val` to the user space of the current process. - pub fn write_val(&self, dest: Vaddr, val: &T) -> Result<()> { - if core::mem::size_of::() > 0 { - check_vaddr(dest)?; - } - - let mut user_writer = self.writer(dest, core::mem::size_of::())?; - Ok(user_writer.write_val(val)?) - } - - /// Reads a C string from the user space of the current process. - /// The length of the string should not exceed `max_len`, - /// including the final `\0` byte. - pub fn read_cstring(&self, vaddr: Vaddr, max_len: usize) -> Result { - if max_len > 0 { - check_vaddr(vaddr)?; - } - - let mut user_reader = self.reader(vaddr, max_len)?; - user_reader.read_cstring() - } -} - -/// A trait providing the ability to read a C string from the user space -/// of the current process specifically for [`VmReader<'_, UserSpace>`], which -/// should reading the bytes iteratively in the reader until encountering -/// the end of the reader or reading a `\0` (is also included into the final C String). -pub trait ReadCString { - fn read_cstring(&mut self) -> Result; -} - -impl<'a> ReadCString for VmReader<'a, UserSpace> { - /// This implementation is inspired by - /// the `do_strncpy_from_user` function in Linux kernel. - /// The original Linux implementation can be found at: - /// - fn read_cstring(&mut self) -> Result { - let max_len = self.remain(); - let mut buffer: Vec = Vec::with_capacity(max_len); - - macro_rules! read_one_byte_at_a_time_while { - ($cond:expr) => { - while $cond { - let byte = self.read_val::()?; - buffer.push(byte); - if byte == 0 { - return Ok(CString::from_vec_with_nul(buffer) - .expect("We provided 0 but no 0 is found")); - } - } - }; - } - - // Handle the first few bytes to make `cur_addr` aligned with `size_of::` - read_one_byte_at_a_time_while!( - (self.cursor() as usize) % mem::size_of::() != 0 && buffer.len() < max_len - ); - - // Handle the rest of the bytes in bulk - while (buffer.len() + mem::size_of::()) <= max_len { - let Ok(word) = self.read_val::() else { - break; - }; - - if has_zero(word) { - for byte in word.to_ne_bytes() { - buffer.push(byte); - if byte == 0 { - return Ok(CString::from_vec_with_nul(buffer) - .expect("We provided 0 but no 0 is found")); - } - } - unreachable!("The branch should never be reached unless `has_zero` has bugs.") - } - - buffer.extend_from_slice(&word.to_ne_bytes()); - } - - // Handle the last few bytes that are not enough for a word - read_one_byte_at_a_time_while!(buffer.len() < max_len); - - // Maximum length exceeded before finding the null terminator - return_errno_with_message!(Errno::EFAULT, "Fails to read CString from user"); - } -} - -/// Determines whether the value contains a zero byte. -/// -/// This magic algorithm is from the Linux `has_zero` function: -/// -const fn has_zero(value: usize) -> bool { - const ONE_BITS: usize = usize::from_le_bytes([0x01; mem::size_of::()]); - const HIGH_BITS: usize = usize::from_le_bytes([0x80; mem::size_of::()]); - - value.wrapping_sub(ONE_BITS) & !value & HIGH_BITS != 0 -} - -/// Checks if the user space pointer is below the lowest userspace address. -/// -/// If a pointer is below the lowest userspace address, it is likely to be a -/// NULL pointer. Reading from or writing to a NULL pointer should trigger a -/// segmentation fault. -/// -/// If it is not checked here, a kernel page fault will happen and we would -/// deny the access in the page fault handler either. It may save a page fault -/// in some occasions. More importantly, double page faults may not be handled -/// quite well on some platforms. -fn check_vaddr(va: Vaddr) -> Result<()> { - if va < crate::vm::vmar::ROOT_VMAR_LOWEST_ADDR { - Err(Error::with_message( - Errno::EFAULT, - "Bad user space pointer specified", - )) - } else { - Ok(()) - } -} diff --git a/kernel/aster-nix/src/util/net/options/utils.rs b/kernel/aster-nix/src/util/net/options/utils.rs index a5d94cf43..fa838ce01 100644 --- a/kernel/aster-nix/src/util/net/options/utils.rs +++ b/kernel/aster-nix/src/util/net/options/utils.rs @@ -46,7 +46,7 @@ macro_rules! impl_read_write_for_pod_type { if (max_len as usize) < core::mem::size_of::<$pod_ty>() { return_errno_with_message!(Errno::EINVAL, "max_len is too short"); } - crate::util::CurrentUserSpace::get().read_val::<$pod_ty>(addr) + crate::context::CurrentUserSpace::get().read_val::<$pod_ty>(addr) } } @@ -58,7 +58,7 @@ macro_rules! impl_read_write_for_pod_type { return_errno_with_message!(Errno::EINVAL, "max_len is too short"); } - crate::util::CurrentUserSpace::get().write_val(addr, self)?; + crate::context::CurrentUserSpace::get().write_val(addr, self)?; Ok(write_len) } }