mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 08:53:29 +00:00
Optimize the latency of lat-sig-install
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
cf9c71119a
commit
fb718fd440
@ -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.
|
||||||
|
@ -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),
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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");
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(¤t_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(¤t_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>()?;
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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, ¤t_posix_thread.tid())
|
.write_val(child_tid_ptr, ¤t_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, ¤t_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, ¤t_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");
|
||||||
|
@ -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(¤t_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(¤t_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));
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user