diff --git a/src/context/context.rs b/src/context/context.rs index 8912a33fe3..c97c5166be 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -22,7 +22,7 @@ use crate::{ }, percpu::PercpuBlock, scheme::{CallerCtx, FileHandle, SchemeId}, - sync::{CleanLockToken, LockToken, RwLock, L1, L4, L5}, + sync::{CleanLockToken, LockToken, RwLock, L1, L3, L4, L5}, syscall::usercopy::UserSliceRw, }; @@ -490,7 +490,7 @@ pub struct BorrowedHtBuf { head_and_not_tail: bool, } impl BorrowedHtBuf { - pub fn head_locked(token: LockToken) -> Result { + pub fn head_locked(token: LockToken) -> Result { let current = context::current(); let frame = &mut current.write(token).syscall_head; match mem::replace(frame, SyscallFrame::Dummy) { @@ -506,10 +506,7 @@ impl BorrowedHtBuf { SyscallFrame::Used { .. } | SyscallFrame::Dummy => Err(Error::new(EAGAIN)), } } - pub fn tail(token: &mut CleanLockToken) -> Result { - Self::tail_locked(token.downgrade()) - } - pub fn tail_locked(token: LockToken) -> Result { + pub fn tail_locked(token: LockToken) -> Result { let current = context::current(); let frame = &mut current.write(token).syscall_tail; match mem::replace(frame, SyscallFrame::Dummy) { diff --git a/src/context/mod.rs b/src/context/mod.rs index 27c23c7312..37c73f5a37 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -132,8 +132,6 @@ pub fn init(token: &mut CleanLockToken) { context.running = true; context.cpu_id = Some(crate::cpu_id()); - let priority = context.prio; - let context_lock = Arc::new(ContextLock::new(context)); let context_ref = ContextRef(Arc::clone(&context_lock)); diff --git a/src/scheme/sys/context.rs b/src/scheme/sys/context.rs index 30e3afa502..313927a08e 100644 --- a/src/scheme/sys/context.rs +++ b/src/scheme/sys/context.rs @@ -36,7 +36,7 @@ pub fn resource(token: &mut CleanLockToken) -> Result> { let heap = match addr_space { Ok(addr_space) => { - let addr_space_guard = addr_space.acquire_read(token.token()); + let addr_space_guard = addr_space.acquire_read(token.downgrade()); let mut private_memory = 0; let mut shared_memory = 0; // TODO: All user programs must have some grant in order for executable memory to even diff --git a/src/scheme/user.rs b/src/scheme/user.rs index c438444afb..b9013021e6 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -526,27 +526,22 @@ impl UserInner { .split_at(core::cmp::min(align_offset, user_buf.len())) .expect("split must succeed"); - let mut dst_space_guard = dst_space_lock.acquire_write(token.downgrade()); - let (dst_space, mut token) = dst_space_guard.token_split(); + let middle_page_count = middle_tail_part_of_buf.len() / PAGE_SIZE; + let tail_size = middle_tail_part_of_buf.len() % PAGE_SIZE; - let free_span = dst_space - .grants - .find_free(dst_space.mmap_min, page_count) - .ok_or(Error::new(ENOMEM))?; + let (_middle_part_of_buf, tail_part_of_buf) = middle_tail_part_of_buf + .split_at(middle_page_count * PAGE_SIZE) + .expect("split must succeed"); - let head = if !head_part_of_buf.is_empty() { + let head_len = core::cmp::min(PAGE_SIZE - offset, user_buf.len()); + + let head_buf_opt = if !head_part_of_buf.is_empty() { // FIXME: Signal context can probably recursively use head/tail. - let mut array = BorrowedHtBuf::head_locked(token.token())?; - let frame = array.frame(); - - let len = core::cmp::min(PAGE_SIZE - offset, user_buf.len()); - + let mut array = BorrowedHtBuf::head_locked(token.downgrade())?; if READ { array.buf_mut()[..offset].fill(0_u8); - array.buf_mut()[offset + len..].fill(0_u8); - - let slice = &mut array.buf_mut()[offset..][..len]; - let head_part_of_buf = user_buf.limit(len).expect("always smaller than max len"); + array.buf_mut()[offset + head_len..].fill(0_u8); + let slice = &mut array.buf_mut()[offset..][..head_len]; head_part_of_buf .reinterpret_unchecked::() @@ -554,7 +549,41 @@ impl UserInner { } else { array.buf_mut().fill(0_u8); } + Some(array) + } else { + None + }; + let tail_buf_opt = if !tail_part_of_buf.is_empty() { + // FIXME: Signal context can probably recursively use head/tail. + let mut array = BorrowedHtBuf::tail_locked(token.downgrade())?; + + if READ { + let (to_copy, to_zero) = array.buf_mut().split_at_mut(tail_size); + to_zero.fill(0_u8); + + // FIXME: remove reinterpret_unchecked + tail_part_of_buf + .reinterpret_unchecked::() + .copy_to_slice(to_copy)?; + } else { + array.buf_mut().fill(0_u8); + } + Some(array) + } else { + None + }; + + let mut dst_space_guard = dst_space_lock.acquire_write(token.downgrade()); + let (dst_space, _token_split) = dst_space_guard.token_split(); + + let free_span = dst_space + .grants + .find_free(dst_space.mmap_min, page_count) + .ok_or(Error::new(ENOMEM))?; + + let head = if let Some(array) = head_buf_opt { + let frame = array.frame(); dst_space.mmap( &dst_space_lock, Some(free_span.base), @@ -585,13 +614,6 @@ impl UserInner { (free_span.base, src_page) }; - let middle_page_count = middle_tail_part_of_buf.len() / PAGE_SIZE; - let tail_size = middle_tail_part_of_buf.len() % PAGE_SIZE; - - let (_middle_part_of_buf, tail_part_of_buf) = middle_tail_part_of_buf - .split_at(middle_page_count * PAGE_SIZE) - .expect("split must succeed"); - if let Some(middle_page_count) = NonZeroUsize::new(middle_page_count) { dst_space.mmap( &dst_space_lock, @@ -636,26 +658,10 @@ impl UserInner { )?; } - let tail = if !tail_part_of_buf.is_empty() { + let tail = if let Some(array) = tail_buf_opt { let tail_dst_page = first_middle_dst_page.next_by(middle_page_count); - - // FIXME: Signal context can probably recursively use head/tail. - let mut array = BorrowedHtBuf::tail_locked(token.token())?; let frame = array.frame(); - if READ { - let (to_copy, to_zero) = array.buf_mut().split_at_mut(tail_size); - - to_zero.fill(0_u8); - - // FIXME: remove reinterpret_unchecked - tail_part_of_buf - .reinterpret_unchecked::() - .copy_to_slice(to_copy)?; - } else { - array.buf_mut().fill(0_u8); - } - dst_space.mmap( &dst_space_lock, Some(tail_dst_page),