Optimize the latency of lat-sig-install

This commit is contained in:
Jianfeng Jiang
2024-08-30 09:12:07 +00:00
committed by Tate, Hongliang Tian
parent cf9c71119a
commit fb718fd440
17 changed files with 148 additions and 99 deletions

View File

@ -16,7 +16,7 @@ use crate::{
}; };
/// The context that can be accessed from the current POSIX thread. /// The context that can be accessed from the current POSIX thread.
#[derive(Clone, Copy)] #[derive(Clone)]
pub struct Context<'a> { pub struct Context<'a> {
pub process: &'a Process, pub process: &'a Process,
pub posix_thread: &'a PosixThread, pub posix_thread: &'a PosixThread,
@ -27,30 +27,47 @@ pub struct Context<'a> {
impl Context<'_> { impl Context<'_> {
/// Gets the userspace of the current task. /// Gets the userspace of the current task.
pub fn get_user_space(&self) -> CurrentUserSpace { pub fn get_user_space(&self) -> CurrentUserSpace {
CurrentUserSpace(self.task.user_space().unwrap().vm_space().clone()) CurrentUserSpace::new(self.task)
} }
} }
/// The user's memory space of the current task. /// The user's memory space of the current task.
/// ///
/// It provides methods to read from or write to the user space efficiently. /// It provides methods to read from or write to the user space efficiently.
pub struct CurrentUserSpace(Arc<VmSpace>); pub struct CurrentUserSpace<'a>(&'a VmSpace);
impl !Sync for CurrentUserSpace {} /// Gets the [`CurrentUserSpace`] from the current task.
impl !Send for CurrentUserSpace {} ///
/// This is slower than [`Context::get_user_space`]. Don't use this getter
/// If you get the access to the [`Context`].
#[macro_export]
macro_rules! get_current_userspace {
() => {
CurrentUserSpace::new(&ostd::task::Task::current().unwrap())
};
}
impl CurrentUserSpace { impl<'a> CurrentUserSpace<'a> {
/// Gets the `CurrentUserSpace` from the current task. /// Creates a new `CurrentUserSpace` from the specified task.
/// ///
/// This is slower than [`Context::get_user_space`]. Don't use this getter /// This method is _not_ recommended for use, as it does not verify whether the provided
/// If you get the access to the [`Context`]. /// `task` is the current task in release builds.
pub fn get() -> Self { ///
let vm_space = { /// If you have access to a [`Context`], it is preferable to call [`Context::get_user_space`].
let current_task = Task::current().unwrap(); ///
let user_space = current_task.user_space().unwrap(); /// Otherwise, you can use the `get_current_userspace` macro
user_space.vm_space().clone() /// to obtain an instance of `CurrentUserSpace` if it will only be used once.
}; ///
Self(vm_space) /// # Panics
///
/// This method will panic in debug builds if the specified `task` is not the current task.
pub fn new(task: &'a Task) -> Self {
let user_space = task.user_space().unwrap();
debug_assert!(Arc::ptr_eq(
task.user_space().unwrap(),
Task::current().unwrap().user_space().unwrap()
));
Self(user_space.vm_space())
} }
/// Creates a reader to read data from the user space of the current task. /// Creates a reader to read data from the user space of the current task.

View File

@ -13,6 +13,7 @@ use crate::{
inode_handle::FileIo, inode_handle::FileIo,
utils::{AccessMode, Inode, InodeMode, IoctlCmd}, utils::{AccessMode, Inode, InodeMode, IoctlCmd},
}, },
get_current_userspace,
prelude::*, prelude::*,
process::{ process::{
signal::{Pollee, Poller}, signal::{Pollee, Poller},
@ -150,11 +151,11 @@ impl FileIo for PtyMaster {
match cmd { match cmd {
IoctlCmd::TCGETS => { IoctlCmd::TCGETS => {
let termios = self.output.termios(); let termios = self.output.termios();
CurrentUserSpace::get().write_val(arg, &termios)?; get_current_userspace!().write_val(arg, &termios)?;
Ok(0) Ok(0)
} }
IoctlCmd::TCSETS => { IoctlCmd::TCSETS => {
let termios = CurrentUserSpace::get().read_val(arg)?; let termios = get_current_userspace!().read_val(arg)?;
self.output.set_termios(termios); self.output.set_termios(termios);
Ok(0) Ok(0)
} }
@ -164,7 +165,7 @@ impl FileIo for PtyMaster {
} }
IoctlCmd::TIOCGPTN => { IoctlCmd::TIOCGPTN => {
let idx = self.index(); let idx = self.index();
CurrentUserSpace::get().write_val(arg, &idx)?; get_current_userspace!().write_val(arg, &idx)?;
Ok(0) Ok(0)
} }
IoctlCmd::TIOCGPTPEER => { IoctlCmd::TIOCGPTPEER => {
@ -197,11 +198,11 @@ impl FileIo for PtyMaster {
} }
IoctlCmd::TIOCGWINSZ => { IoctlCmd::TIOCGWINSZ => {
let winsize = self.output.window_size(); let winsize = self.output.window_size();
CurrentUserSpace::get().write_val(arg, &winsize)?; get_current_userspace!().write_val(arg, &winsize)?;
Ok(0) Ok(0)
} }
IoctlCmd::TIOCSWINSZ => { IoctlCmd::TIOCSWINSZ => {
let winsize = CurrentUserSpace::get().read_val(arg)?; let winsize = get_current_userspace!().read_val(arg)?;
self.output.set_window_size(winsize); self.output.set_window_size(winsize);
Ok(0) Ok(0)
} }
@ -213,12 +214,12 @@ impl FileIo for PtyMaster {
); );
}; };
let fg_pgid = foreground.pgid(); let fg_pgid = foreground.pgid();
CurrentUserSpace::get().write_val(arg, &fg_pgid)?; get_current_userspace!().write_val(arg, &fg_pgid)?;
Ok(0) Ok(0)
} }
IoctlCmd::TIOCSPGRP => { IoctlCmd::TIOCSPGRP => {
let pgid = { let pgid = {
let pgid: i32 = CurrentUserSpace::get().read_val(arg)?; let pgid: i32 = get_current_userspace!().read_val(arg)?;
if pgid < 0 { if pgid < 0 {
return_errno_with_message!(Errno::EINVAL, "negative pgid"); return_errno_with_message!(Errno::EINVAL, "negative pgid");
} }
@ -238,7 +239,7 @@ impl FileIo for PtyMaster {
} }
IoctlCmd::FIONREAD => { IoctlCmd::FIONREAD => {
let len = self.input.lock().len() as i32; let len = self.input.lock().len() as i32;
CurrentUserSpace::get().write_val(arg, &len)?; get_current_userspace!().write_val(arg, &len)?;
Ok(0) Ok(0)
} }
_ => Ok(0), _ => Ok(0),
@ -377,12 +378,12 @@ impl FileIo for PtySlave {
}; };
let fg_pgid = foreground.pgid(); let fg_pgid = foreground.pgid();
CurrentUserSpace::get().write_val(arg, &fg_pgid)?; get_current_userspace!().write_val(arg, &fg_pgid)?;
Ok(0) Ok(0)
} }
IoctlCmd::TIOCSPGRP => { IoctlCmd::TIOCSPGRP => {
let pgid = { let pgid = {
let pgid: i32 = CurrentUserSpace::get().read_val(arg)?; let pgid: i32 = get_current_userspace!().read_val(arg)?;
if pgid < 0 { if pgid < 0 {
return_errno_with_message!(Errno::EINVAL, "negative pgid"); return_errno_with_message!(Errno::EINVAL, "negative pgid");
} }
@ -402,7 +403,7 @@ impl FileIo for PtySlave {
} }
IoctlCmd::FIONREAD => { IoctlCmd::FIONREAD => {
let buffer_len = self.master().slave_buf_len() as i32; let buffer_len = self.master().slave_buf_len() as i32;
CurrentUserSpace::get().write_val(arg, &buffer_len)?; get_current_userspace!().write_val(arg, &buffer_len)?;
Ok(0) Ok(0)
} }
_ => Ok(0), _ => Ok(0),

View File

@ -82,7 +82,7 @@ impl FileIo for TdxGuest {
fn handle_get_report(arg: usize) -> Result<i32> { fn handle_get_report(arg: usize) -> Result<i32> {
const SHARED_BIT: u8 = 51; const SHARED_BIT: u8 = 51;
const SHARED_MASK: u64 = 1u64 << SHARED_BIT; const SHARED_MASK: u64 = 1u64 << SHARED_BIT;
let user_space = CurrentUserSpace::get(); let user_space = get_current_userspace!();
let user_request: TdxReportRequest = user_space.read_val(arg)?; let user_request: TdxReportRequest = user_space.read_val(arg)?;
let vm_segment = FrameAllocOptions::new(2) let vm_segment = FrameAllocOptions::new(2)

View File

@ -13,6 +13,7 @@ use crate::{
inode_handle::FileIo, inode_handle::FileIo,
utils::IoctlCmd, utils::IoctlCmd,
}, },
get_current_userspace,
prelude::*, prelude::*,
process::{ process::{
signal::{signals::kernel::KernelSignal, Poller}, signal::{signals::kernel::KernelSignal, Poller},
@ -100,7 +101,7 @@ impl FileIo for Tty {
// Get terminal attributes // Get terminal attributes
let termios = self.ldisc.termios(); let termios = self.ldisc.termios();
trace!("get termios = {:?}", termios); trace!("get termios = {:?}", termios);
CurrentUserSpace::get().write_val(arg, &termios)?; get_current_userspace!().write_val(arg, &termios)?;
Ok(0) Ok(0)
} }
IoctlCmd::TIOCGPGRP => { IoctlCmd::TIOCGPGRP => {
@ -109,13 +110,13 @@ impl FileIo for Tty {
}; };
let fg_pgid = foreground.pgid(); let fg_pgid = foreground.pgid();
debug!("fg_pgid = {}", fg_pgid); debug!("fg_pgid = {}", fg_pgid);
CurrentUserSpace::get().write_val(arg, &fg_pgid)?; get_current_userspace!().write_val(arg, &fg_pgid)?;
Ok(0) Ok(0)
} }
IoctlCmd::TIOCSPGRP => { IoctlCmd::TIOCSPGRP => {
// Set the process group id of fg progress group // Set the process group id of fg progress group
let pgid = { let pgid = {
let pgid: i32 = CurrentUserSpace::get().read_val(arg)?; let pgid: i32 = get_current_userspace!().read_val(arg)?;
if pgid < 0 { if pgid < 0 {
return_errno_with_message!(Errno::EINVAL, "negative pgid"); return_errno_with_message!(Errno::EINVAL, "negative pgid");
} }
@ -130,20 +131,20 @@ impl FileIo for Tty {
} }
IoctlCmd::TCSETS => { IoctlCmd::TCSETS => {
// Set terminal attributes // Set terminal attributes
let termios = CurrentUserSpace::get().read_val(arg)?; let termios = get_current_userspace!().read_val(arg)?;
debug!("set termios = {:?}", termios); debug!("set termios = {:?}", termios);
self.ldisc.set_termios(termios); self.ldisc.set_termios(termios);
Ok(0) Ok(0)
} }
IoctlCmd::TCSETSW => { IoctlCmd::TCSETSW => {
let termios = CurrentUserSpace::get().read_val(arg)?; let termios = get_current_userspace!().read_val(arg)?;
debug!("set termios = {:?}", termios); debug!("set termios = {:?}", termios);
self.ldisc.set_termios(termios); self.ldisc.set_termios(termios);
// TODO: drain output buffer // TODO: drain output buffer
Ok(0) Ok(0)
} }
IoctlCmd::TCSETSF => { IoctlCmd::TCSETSF => {
let termios = CurrentUserSpace::get().read_val(arg)?; let termios = get_current_userspace!().read_val(arg)?;
debug!("set termios = {:?}", termios); debug!("set termios = {:?}", termios);
self.ldisc.set_termios(termios); self.ldisc.set_termios(termios);
self.ldisc.drain_input(); self.ldisc.drain_input();
@ -152,11 +153,11 @@ impl FileIo for Tty {
} }
IoctlCmd::TIOCGWINSZ => { IoctlCmd::TIOCGWINSZ => {
let winsize = self.ldisc.window_size(); let winsize = self.ldisc.window_size();
CurrentUserSpace::get().write_val(arg, &winsize)?; get_current_userspace!().write_val(arg, &winsize)?;
Ok(0) Ok(0)
} }
IoctlCmd::TIOCSWINSZ => { IoctlCmd::TIOCSWINSZ => {
let winsize = CurrentUserSpace::get().read_val(arg)?; let winsize = get_current_userspace!().read_val(arg)?;
self.ldisc.set_window_size(winsize); self.ldisc.set_window_size(winsize);
Ok(0) Ok(0)
} }

View File

@ -18,6 +18,7 @@ use super::{
use crate::{ use crate::{
cpu::LinuxAbi, cpu::LinuxAbi,
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask}, fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
get_current_userspace,
prelude::*, prelude::*,
process::posix_thread::allocate_posix_tid, process::posix_thread::allocate_posix_tid,
thread::{Thread, Tid}, thread::{Thread, Tid},
@ -338,7 +339,7 @@ fn clone_parent_settid(
clone_flags: CloneFlags, clone_flags: CloneFlags,
) -> Result<()> { ) -> Result<()> {
if clone_flags.contains(CloneFlags::CLONE_PARENT_SETTID) { if clone_flags.contains(CloneFlags::CLONE_PARENT_SETTID) {
CurrentUserSpace::get().write_val(parent_tidptr, &child_tid)?; get_current_userspace!().write_val(parent_tidptr, &child_tid)?;
} }
Ok(()) Ok(())
} }

View File

@ -2,6 +2,7 @@
use super::{futex::futex_wake, robust_list::wake_robust_futex, thread_table, PosixThread}; use super::{futex::futex_wake, robust_list::wake_robust_futex, thread_table, PosixThread};
use crate::{ use crate::{
get_current_userspace,
prelude::*, prelude::*,
process::{do_exit_group, TermStatus}, process::{do_exit_group, TermStatus},
thread::{Thread, Tid}, thread::{Thread, Tid},
@ -25,7 +26,7 @@ pub fn do_exit(thread: &Thread, posix_thread: &PosixThread, term_status: TermSta
if *clear_ctid != 0 { if *clear_ctid != 0 {
futex_wake(*clear_ctid, 1, None)?; futex_wake(*clear_ctid, 1, None)?;
// FIXME: the correct write length? // FIXME: the correct write length?
CurrentUserSpace::get() get_current_userspace!()
.write_val(*clear_ctid, &0u32) .write_val(*clear_ctid, &0u32)
.unwrap(); .unwrap();
*clear_ctid = 0; *clear_ctid = 0;

View File

@ -2,7 +2,11 @@
//! The implementation of robust list is from occlum. //! The implementation of robust list is from occlum.
use crate::{prelude::*, process::posix_thread::futex::futex_wake, thread::Tid}; use ostd::task::Task;
use crate::{
get_current_userspace, prelude::*, process::posix_thread::futex::futex_wake, thread::Tid,
};
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug, Pod)] #[derive(Clone, Copy, Debug, Pod)]
@ -101,7 +105,7 @@ impl<'a> Iterator for FutexIter<'a> {
} else { } else {
None None
}; };
let Ok(robust_list) = CurrentUserSpace::get().read_val::<RobustList>(self.entry_ptr) let Ok(robust_list) = get_current_userspace!().read_val::<RobustList>(self.entry_ptr)
else { else {
return None; return None;
}; };
@ -123,7 +127,9 @@ const FUTEX_TID_MASK: u32 = 0x3FFF_FFFF;
/// Wakeup one robust futex owned by the thread /// Wakeup one robust futex owned by the thread
/// FIXME: requires atomic operations here /// FIXME: requires atomic operations here
pub fn wake_robust_futex(futex_addr: Vaddr, tid: Tid) -> Result<()> { pub fn wake_robust_futex(futex_addr: Vaddr, tid: Tid) -> Result<()> {
let user_space = CurrentUserSpace::get(); let task = Task::current().unwrap();
let user_space = CurrentUserSpace::new(&task);
let futex_val = { let futex_val = {
if futex_addr == 0 { if futex_addr == 0 {
return_errno_with_message!(Errno::EINVAL, "invalid futext addr"); return_errno_with_message!(Errno::EINVAL, "invalid futext addr");

View File

@ -334,7 +334,7 @@ impl Process {
.lock() .lock()
.iter() .iter()
.find(|task| task.tid() == self.pid) .find(|task| task.tid() == self.pid)
.map(Thread::borrow_from_task) .map(|task| Thread::borrow_from_task(task.as_ref()))
.cloned() .cloned()
} }

View File

@ -20,10 +20,14 @@ use core::{
use align_ext::AlignExt; use align_ext::AlignExt;
use aster_rights::Full; use aster_rights::Full;
use ostd::mm::{VmIo, MAX_USERSPACE_VADDR}; use ostd::{
mm::{VmIo, MAX_USERSPACE_VADDR},
task::Task,
};
use self::aux_vec::{AuxKey, AuxVec}; use self::aux_vec::{AuxKey, AuxVec};
use crate::{ use crate::{
get_current_userspace,
prelude::*, prelude::*,
util::random::getrandom, util::random::getrandom,
vm::{ vm::{
@ -372,7 +376,7 @@ impl InitStackReader {
/// Reads argc from the process init stack /// Reads argc from the process init stack
pub fn argc(&self) -> Result<u64> { pub fn argc(&self) -> Result<u64> {
let stack_base = self.init_stack_bottom(); let stack_base = self.init_stack_bottom();
CurrentUserSpace::get().read_val(stack_base) get_current_userspace!().read_val(stack_base)
} }
/// Reads argv from the process init stack /// Reads argv from the process init stack
@ -383,7 +387,10 @@ impl InitStackReader {
let read_offset = self.init_stack_bottom() + size_of::<usize>(); let read_offset = self.init_stack_bottom() + size_of::<usize>();
let mut argv = Vec::with_capacity(argc); let mut argv = Vec::with_capacity(argc);
let user_space = CurrentUserSpace::get();
let current_task = Task::current().unwrap();
let user_space = CurrentUserSpace::new(&current_task);
let mut argv_reader = user_space.reader(read_offset, argc * size_of::<usize>())?; let mut argv_reader = user_space.reader(read_offset, argc * size_of::<usize>())?;
for _ in 0..argc { for _ in 0..argc {
let arg = { let arg = {
@ -410,7 +417,10 @@ impl InitStackReader {
+ size_of::<usize>(); + size_of::<usize>();
let mut envp = Vec::new(); let mut envp = Vec::new();
let user_space = CurrentUserSpace::get();
let current_task = Task::current().unwrap();
let user_space = CurrentUserSpace::new(&current_task);
let mut envp_reader = user_space.reader(read_offset, MAX_ENVP_NUMBER)?; let mut envp_reader = user_space.reader(read_offset, MAX_ENVP_NUMBER)?;
for _ in 0..MAX_ENVP_NUMBER { for _ in 0..MAX_ENVP_NUMBER {
let envp_ptr = envp_reader.read_val::<Vaddr>()?; let envp_ptr = envp_reader.read_val::<Vaddr>()?;

View File

@ -26,11 +26,12 @@ use sig_mask::SigMask;
use sig_num::SigNum; use sig_num::SigNum;
pub use sig_stack::{SigStack, SigStackFlags}; pub use sig_stack::{SigStack, SigStackFlags};
use super::posix_thread::{PosixThread, PosixThreadExt}; use super::posix_thread::PosixThread;
use crate::{ use crate::{
get_current_userspace,
prelude::*, prelude::*,
process::{do_exit_group, TermStatus}, process::{do_exit_group, TermStatus},
thread::{status::ThreadStatus, Thread}, thread::status::ThreadStatus,
}; };
pub trait SignalContext { pub trait SignalContext {
@ -41,12 +42,9 @@ pub trait SignalContext {
// TODO: This interface of this method is error prone. // TODO: This interface of this method is error prone.
// The method takes an argument for the current thread to optimize its efficiency. // The method takes an argument for the current thread to optimize its efficiency.
/// Handle pending signal for current process. /// Handle pending signal for current process.
pub fn handle_pending_signal( pub fn handle_pending_signal(user_ctx: &mut UserContext, ctx: &Context) -> Result<()> {
context: &mut UserContext,
current_thread: &Arc<Thread>,
) -> Result<()> {
// We first deal with signal in current thread, then signal in current process. // We first deal with signal in current thread, then signal in current process.
let posix_thread = current_thread.as_posix_thread().unwrap(); let posix_thread = ctx.posix_thread;
let signal = { let signal = {
let sig_mask = posix_thread.sig_mask().load(Ordering::Relaxed); let sig_mask = posix_thread.sig_mask().load(Ordering::Relaxed);
if let Some(signal) = posix_thread.dequeue_signal(&sig_mask) { if let Some(signal) = posix_thread.dequeue_signal(&sig_mask) {
@ -82,13 +80,13 @@ pub fn handle_pending_signal(
drop(sig_dispositions); drop(sig_dispositions);
handle_user_signal( handle_user_signal(
posix_thread, ctx,
sig_num, sig_num,
handler_addr, handler_addr,
flags, flags,
restorer_addr, restorer_addr,
mask, mask,
context, user_ctx,
signal.to_info(), signal.to_info(),
)? )?
} }
@ -109,7 +107,7 @@ pub fn handle_pending_signal(
} }
SigDefaultAction::Ign => {} SigDefaultAction::Ign => {}
SigDefaultAction::Stop => { SigDefaultAction::Stop => {
let _ = current_thread.atomic_status().compare_exchange( let _ = ctx.thread.atomic_status().compare_exchange(
ThreadStatus::Running, ThreadStatus::Running,
ThreadStatus::Stopped, ThreadStatus::Stopped,
Ordering::AcqRel, Ordering::AcqRel,
@ -117,7 +115,7 @@ pub fn handle_pending_signal(
); );
} }
SigDefaultAction::Cont => { SigDefaultAction::Cont => {
let _ = current_thread.atomic_status().compare_exchange( let _ = ctx.thread.atomic_status().compare_exchange(
ThreadStatus::Stopped, ThreadStatus::Stopped,
ThreadStatus::Running, ThreadStatus::Running,
Ordering::AcqRel, Ordering::AcqRel,
@ -132,13 +130,13 @@ pub fn handle_pending_signal(
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn handle_user_signal( pub fn handle_user_signal(
posix_thread: &PosixThread, ctx: &Context,
sig_num: SigNum, sig_num: SigNum,
handler_addr: Vaddr, handler_addr: Vaddr,
flags: SigActionFlags, flags: SigActionFlags,
restorer_addr: Vaddr, restorer_addr: Vaddr,
mut mask: SigMask, mut mask: SigMask,
context: &mut UserContext, user_ctx: &mut UserContext,
sig_info: siginfo_t, sig_info: siginfo_t,
) -> Result<()> { ) -> Result<()> {
debug!("sig_num = {:?}, signame = {}", sig_num, sig_num.sig_name()); debug!("sig_num = {:?}, signame = {}", sig_num, sig_num.sig_name());
@ -156,23 +154,24 @@ pub fn handle_user_signal(
} }
// block signals in sigmask when running signal handler // block signals in sigmask when running signal handler
let old_mask = posix_thread.sig_mask().load(Ordering::Relaxed); let old_mask = ctx.posix_thread.sig_mask().load(Ordering::Relaxed);
posix_thread ctx.posix_thread
.sig_mask() .sig_mask()
.store(old_mask + mask, Ordering::Relaxed); .store(old_mask + mask, Ordering::Relaxed);
// Set up signal stack. // Set up signal stack.
let mut stack_pointer = if let Some(sp) = use_alternate_signal_stack(posix_thread) { let mut stack_pointer = if let Some(sp) = use_alternate_signal_stack(ctx.posix_thread) {
sp as u64 sp as u64
} else { } else {
// just use user stack // just use user stack
context.stack_pointer() as u64 user_ctx.stack_pointer() as u64
}; };
// To avoid corrupting signal stack, we minus 128 first. // To avoid corrupting signal stack, we minus 128 first.
stack_pointer -= 128; stack_pointer -= 128;
let user_space = CurrentUserSpace::get(); let user_space = ctx.get_user_space();
// 1. write siginfo_t // 1. write siginfo_t
stack_pointer -= mem::size_of::<siginfo_t>() as u64; stack_pointer -= mem::size_of::<siginfo_t>() as u64;
user_space.write_val(stack_pointer as _, &sig_info)?; user_space.write_val(stack_pointer as _, &sig_info)?;
@ -188,8 +187,8 @@ pub fn handle_user_signal(
.uc_mcontext .uc_mcontext
.inner .inner
.gp_regs .gp_regs
.copy_from_raw(context.general_regs()); .copy_from_raw(user_ctx.general_regs());
let mut sig_context = posix_thread.sig_context().lock(); let mut sig_context = ctx.posix_thread.sig_context().lock();
if let Some(sig_context_addr) = *sig_context { if let Some(sig_context_addr) = *sig_context {
ucontext.uc_link = sig_context_addr; ucontext.uc_link = sig_context_addr;
} else { } else {
@ -222,13 +221,13 @@ pub fn handle_user_signal(
} }
// 4. Set correct register values // 4. Set correct register values
context.set_instruction_pointer(handler_addr as _); user_ctx.set_instruction_pointer(handler_addr as _);
context.set_stack_pointer(stack_pointer as usize); user_ctx.set_stack_pointer(stack_pointer as usize);
// parameters of signal handler // parameters of signal handler
if flags.contains(SigActionFlags::SA_SIGINFO) { if flags.contains(SigActionFlags::SA_SIGINFO) {
context.set_arguments(sig_num, siginfo_addr as usize, ucontext_addr as usize); user_ctx.set_arguments(sig_num, siginfo_addr as usize, ucontext_addr as usize);
} else { } else {
context.set_arguments(sig_num, 0, 0); user_ctx.set_arguments(sig_num, 0, 0);
} }
Ok(()) Ok(())
@ -261,7 +260,7 @@ fn use_alternate_signal_stack(posix_thread: &PosixThread) -> Option<usize> {
fn write_u64_to_user_stack(rsp: u64, value: u64) -> Result<u64> { fn write_u64_to_user_stack(rsp: u64, value: u64) -> Result<u64> {
let rsp = rsp - 8; let rsp = rsp - 8;
CurrentUserSpace::get().write_val(rsp as Vaddr, &value)?; get_current_userspace!().write_val(rsp as Vaddr, &value)?;
Ok(rsp) Ok(rsp)
} }

View File

@ -26,9 +26,9 @@ impl SigDispositions {
self.map[idx] self.map[idx]
} }
pub fn set(&mut self, num: SigNum, sa: SigAction) { pub fn set(&mut self, num: SigNum, sa: SigAction) -> SigAction {
let idx = Self::num_to_idx(num); let idx = Self::num_to_idx(num);
self.map[idx] = sa; core::mem::replace(&mut self.map[idx], sa)
} }
pub fn set_default(&mut self, num: SigNum) { pub fn set_default(&mut self, num: SigNum) {

View File

@ -3,6 +3,7 @@
use core::time::Duration; use core::time::Duration;
use crate::{ use crate::{
get_current_userspace,
prelude::*, prelude::*,
process::posix_thread::futex::{ process::posix_thread::futex::{
futex_op_and_flags_from_u32, futex_requeue, futex_wait, futex_wait_bitset, futex_wake, futex_op_and_flags_from_u32, futex_requeue, futex_wait, futex_wait_bitset, futex_wake,
@ -45,7 +46,7 @@ pub fn sys_futex(
} }
let timeout = { let timeout = {
let time_spec: timespec_t = CurrentUserSpace::get().read_val(timeout_addr)?; let time_spec: timespec_t = get_current_userspace!().read_val(timeout_addr)?;
Duration::try_from(time_spec)? Duration::try_from(time_spec)?
}; };

View File

@ -21,20 +21,24 @@ pub fn sys_rt_sigaction(
old_sig_action_addr, old_sig_action_addr,
sigset_size sigset_size
); );
let mut sig_dispositions = ctx.process.sig_dispositions().lock(); let mut sig_dispositions = ctx.process.sig_dispositions().lock();
let old_action = sig_dispositions.get(sig_num);
let old_action_c = old_action.as_c_type(); let old_action = if sig_action_addr != 0 {
if old_sig_action_addr != 0 {
ctx.get_user_space()
.write_val(old_sig_action_addr, &old_action_c)?;
}
if sig_action_addr != 0 {
let sig_action_c = ctx let sig_action_c = ctx
.get_user_space() .get_user_space()
.read_val::<sigaction_t>(sig_action_addr)?; .read_val::<sigaction_t>(sig_action_addr)?;
let sig_action = SigAction::try_from(sig_action_c).unwrap(); let sig_action = SigAction::try_from(sig_action_c).unwrap();
trace!("sig action = {:?}", sig_action); trace!("sig action = {:?}", sig_action);
sig_dispositions.set(sig_num, sig_action); sig_dispositions.set(sig_num, sig_action)
} else {
sig_dispositions.get(sig_num)
};
if old_sig_action_addr != 0 {
let old_action_c = old_action.as_c_type();
ctx.get_user_space()
.write_val(old_sig_action_addr, &old_action_c)?;
} }
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))

View File

@ -55,7 +55,7 @@ impl Thread {
/// # Panics /// # Panics
/// ///
/// This method panics if the task is not a thread. /// This method panics if the task is not a thread.
pub fn borrow_from_task(task: &Arc<Task>) -> &Arc<Self> { pub fn borrow_from_task(task: &Task) -> &Arc<Self> {
task.data().downcast_ref::<Arc<Thread>>().unwrap() task.data().downcast_ref::<Arc<Thread>>().unwrap()
} }

View File

@ -8,6 +8,7 @@ use ostd::{
use super::Thread; use super::Thread;
use crate::{ use crate::{
cpu::LinuxAbi, cpu::LinuxAbi,
get_current_userspace,
prelude::*, prelude::*,
process::{posix_thread::PosixThreadExt, signal::handle_pending_signal}, process::{posix_thread::PosixThreadExt, signal::handle_pending_signal},
syscall::handle_syscall, syscall::handle_syscall,
@ -46,7 +47,7 @@ pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Arc<Thread>)
// Make sure the store operation completes before the clone call returns control to user space // Make sure the store operation completes before the clone call returns control to user space
// in the child process. // in the child process.
if is_userspace_vaddr(child_tid_ptr) { if is_userspace_vaddr(child_tid_ptr) {
CurrentUserSpace::get() get_current_userspace!()
.write_val(child_tid_ptr, &current_posix_thread.tid()) .write_val(child_tid_ptr, &current_posix_thread.tid())
.unwrap(); .unwrap();
} }
@ -73,12 +74,12 @@ pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Arc<Thread>)
if current_thread.status().is_exited() { if current_thread.status().is_exited() {
break; break;
} }
handle_pending_signal(user_ctx, &current_thread).unwrap(); handle_pending_signal(user_ctx, &ctx).unwrap();
// If current is suspended, wait for a signal to wake up self // If current is suspended, wait for a signal to wake up self
while current_thread.status().is_stopped() { while current_thread.status().is_stopped() {
Thread::yield_now(); Thread::yield_now();
debug!("{} is suspended.", current_posix_thread.tid()); debug!("{} is suspended.", current_posix_thread.tid());
handle_pending_signal(user_ctx, &current_thread).unwrap(); handle_pending_signal(user_ctx, &ctx).unwrap();
} }
if current_thread.status().is_exited() { if current_thread.status().is_exited() {
debug!("exit due to signal"); debug!("exit due to signal");

View File

@ -2,8 +2,10 @@
use core::cmp::min; use core::cmp::min;
use ostd::task::Task;
use super::{ip::CSocketAddrInet, unix, vsock::CSocketAddrVm}; use super::{ip::CSocketAddrInet, unix, vsock::CSocketAddrVm};
use crate::{net::socket::SocketAddr, prelude::*}; use crate::{get_current_userspace, net::socket::SocketAddr, prelude::*};
/// Address family. /// Address family.
/// ///
@ -144,7 +146,7 @@ pub fn read_socket_addr_from_user(addr: Vaddr, addr_len: usize) -> Result<Socket
} }
let mut storage = Storage::new_zeroed(); let mut storage = Storage::new_zeroed();
CurrentUserSpace::get().read_bytes( get_current_userspace!().read_bytes(
addr, addr,
&mut VmWriter::from(&mut storage.as_bytes_mut()[..addr_len]), &mut VmWriter::from(&mut storage.as_bytes_mut()[..addr_len]),
)?; )?;
@ -200,7 +202,9 @@ pub fn write_socket_addr_to_user(
dest: Vaddr, dest: Vaddr,
max_len_ptr: Vaddr, max_len_ptr: Vaddr,
) -> Result<()> { ) -> Result<()> {
let user_space = CurrentUserSpace::get(); let current_task = Task::current().unwrap();
let user_space = CurrentUserSpace::new(&current_task);
let max_len = user_space.read_val::<i32>(max_len_ptr)?; let max_len = user_space.read_val::<i32>(max_len_ptr)?;
let actual_len = write_socket_addr_with_max_len(socket_addr, dest, max_len)?; let actual_len = write_socket_addr_with_max_len(socket_addr, dest, max_len)?;
@ -235,7 +239,9 @@ pub fn write_socket_addr_with_max_len(
); );
} }
let user_space = CurrentUserSpace::get(); let current_task = Task::current().unwrap();
let user_space = CurrentUserSpace::new(&current_task);
let actual_len = match socket_addr { let actual_len = match socket_addr {
SocketAddr::IPv4(addr, port) => { SocketAddr::IPv4(addr, port) => {
let socket_addr = CSocketAddrInet::from((*addr, *port)); let socket_addr = CSocketAddrInet::from((*addr, *port));

View File

@ -3,6 +3,7 @@
use core::time::Duration; use core::time::Duration;
use crate::{ use crate::{
get_current_userspace,
net::socket::{ip::stream::CongestionControl, LingerOption}, net::socket::{ip::stream::CongestionControl, LingerOption},
prelude::*, prelude::*,
}; };
@ -46,7 +47,7 @@ macro_rules! impl_read_write_for_pod_type {
if (max_len as usize) < core::mem::size_of::<$pod_ty>() { if (max_len as usize) < core::mem::size_of::<$pod_ty>() {
return_errno_with_message!(Errno::EINVAL, "max_len is too short"); return_errno_with_message!(Errno::EINVAL, "max_len is too short");
} }
crate::context::CurrentUserSpace::get().read_val::<$pod_ty>(addr) crate::get_current_userspace!().read_val::<$pod_ty>(addr)
} }
} }
@ -58,7 +59,7 @@ macro_rules! impl_read_write_for_pod_type {
return_errno_with_message!(Errno::EINVAL, "max_len is too short"); return_errno_with_message!(Errno::EINVAL, "max_len is too short");
} }
crate::context::CurrentUserSpace::get().write_val(addr, self)?; crate::get_current_userspace!().write_val(addr, self)?;
Ok(write_len) Ok(write_len)
} }
} }
@ -73,7 +74,7 @@ impl ReadFromUser for bool {
return_errno_with_message!(Errno::EINVAL, "max_len is too short"); return_errno_with_message!(Errno::EINVAL, "max_len is too short");
} }
let val = CurrentUserSpace::get().read_val::<i32>(addr)?; let val = get_current_userspace!().read_val::<i32>(addr)?;
Ok(val != 0) Ok(val != 0)
} }
@ -88,7 +89,7 @@ impl WriteToUser for bool {
} }
let val = if *self { 1i32 } else { 0i32 }; let val = if *self { 1i32 } else { 0i32 };
CurrentUserSpace::get().write_val(addr, &val)?; get_current_userspace!().write_val(addr, &val)?;
Ok(write_len) Ok(write_len)
} }
} }
@ -106,7 +107,7 @@ impl WriteToUser for Option<Error> {
Some(error) => error.error() as i32, Some(error) => error.error() as i32,
}; };
CurrentUserSpace::get().write_val(addr, &val)?; get_current_userspace!().write_val(addr, &val)?;
Ok(write_len) Ok(write_len)
} }
} }
@ -117,7 +118,7 @@ impl ReadFromUser for LingerOption {
return_errno_with_message!(Errno::EINVAL, "max_len is too short"); return_errno_with_message!(Errno::EINVAL, "max_len is too short");
} }
let c_linger = CurrentUserSpace::get().read_val::<CLinger>(addr)?; let c_linger = get_current_userspace!().read_val::<CLinger>(addr)?;
Ok(LingerOption::from(c_linger)) Ok(LingerOption::from(c_linger))
} }
@ -132,7 +133,7 @@ impl WriteToUser for LingerOption {
} }
let linger = CLinger::from(*self); let linger = CLinger::from(*self);
CurrentUserSpace::get().write_val(addr, &linger)?; get_current_userspace!().write_val(addr, &linger)?;
Ok(write_len) Ok(write_len)
} }
} }
@ -140,7 +141,7 @@ impl WriteToUser for LingerOption {
impl ReadFromUser for CongestionControl { impl ReadFromUser for CongestionControl {
fn read_from_user(addr: Vaddr, max_len: u32) -> Result<Self> { fn read_from_user(addr: Vaddr, max_len: u32) -> Result<Self> {
let mut bytes = vec![0; max_len as usize]; let mut bytes = vec![0; max_len as usize];
CurrentUserSpace::get().read_bytes(addr, &mut VmWriter::from(bytes.as_mut_slice()))?; get_current_userspace!().read_bytes(addr, &mut VmWriter::from(bytes.as_mut_slice()))?;
let name = String::from_utf8(bytes).unwrap(); let name = String::from_utf8(bytes).unwrap();
CongestionControl::new(&name) CongestionControl::new(&name)
} }
@ -155,7 +156,7 @@ impl WriteToUser for CongestionControl {
return_errno_with_message!(Errno::EINVAL, "max_len is too short"); return_errno_with_message!(Errno::EINVAL, "max_len is too short");
} }
CurrentUserSpace::get().write_bytes(addr, &mut VmReader::from(name))?; get_current_userspace!().write_bytes(addr, &mut VmReader::from(name))?;
Ok(write_len) Ok(write_len)
} }