From 1d1cbb0abfa7ceb5f55767b32536164c42050096 Mon Sep 17 00:00:00 2001 From: LI Qing Date: Thu, 27 Jan 2022 17:46:53 +0800 Subject: [PATCH] [hyper mode] Add UntrustedSlice --- src/libos/src/net/mod.rs | 2 +- src/libos/src/net/socket/host/recv.rs | 12 ++-- src/libos/src/net/socket/host/send.rs | 7 +- src/libos/src/untrusted/mod.rs | 2 +- src/libos/src/untrusted/slice_alloc.rs | 92 ++++++++++++++++++++++++-- 5 files changed, 102 insertions(+), 13 deletions(-) diff --git a/src/libos/src/net/mod.rs b/src/libos/src/net/mod.rs index 152fb646..b8518a15 100644 --- a/src/libos/src/net/mod.rs +++ b/src/libos/src/net/mod.rs @@ -1,6 +1,6 @@ use super::*; use std; -use untrusted::{SliceAsMutPtrAndLen, SliceAsPtrAndLen, UntrustedSliceAlloc}; +use untrusted::{SliceAsMutPtrAndLen, SliceAsPtrAndLen, UntrustedSlice, UntrustedSliceAlloc}; pub use self::io_multiplexing::{ clear_notifier_status, notify_thread, wait_for_notification, EpollEvent, IoEvent, PollEvent, diff --git a/src/libos/src/net/socket/host/recv.rs b/src/libos/src/net/socket/host/recv.rs index e9ef036a..63824f65 100644 --- a/src/libos/src/net/socket/host/recv.rs +++ b/src/libos/src/net/socket/host/recv.rs @@ -45,10 +45,10 @@ impl HostSocket { let mut remain = retval.0; for (i, buf) in data.iter_mut().enumerate() { if remain >= buf.len() { - buf.copy_from_slice(u_data[i]); + u_data[i].write_to_slice(buf)?; remain -= buf.len(); } else { - buf[0..remain].copy_from_slice(&u_data[i][0..remain]); + u_data[i].write_to_slice(&mut buf[0..remain])?; break; } } @@ -57,7 +57,7 @@ impl HostSocket { fn do_recvmsg_untrusted_data( &self, - data: &mut [&mut [u8]], + data: &mut [UntrustedSlice], flags: RecvFlags, mut name: Option<&mut [u8]>, mut control: Option<&mut [u8]>, @@ -70,8 +70,10 @@ impl HostSocket { let msg_name = msg_name as *mut c_void; let mut msg_namelen_recvd = 0_u32; // Iovs - let mut raw_iovs: Vec = - data.iter().map(|slice| slice.as_libc_iovec()).collect(); + let mut raw_iovs: Vec = data + .iter() + .map(|slice| slice.as_ref().as_libc_iovec()) + .collect(); let (msg_iov, msg_iovlen) = raw_iovs.as_mut_slice().as_mut_ptr_and_len(); // Control let (msg_control, msg_controllen) = control.as_mut_ptr_and_len(); diff --git a/src/libos/src/net/socket/host/send.rs b/src/libos/src/net/socket/host/send.rs index 37ca607d..15487a75 100644 --- a/src/libos/src/net/socket/host/send.rs +++ b/src/libos/src/net/socket/host/send.rs @@ -38,7 +38,7 @@ impl HostSocket { fn do_sendmsg_untrusted_data( &self, - u_data: &[&[u8]], + u_data: &[UntrustedSlice], flags: SendFlags, name: Option<&[u8]>, control: Option<&[u8]>, @@ -51,7 +51,10 @@ impl HostSocket { let (msg_name, msg_namelen) = name.as_ptr_and_len(); let msg_name = msg_name as *const c_void; // Iovs - let raw_iovs: Vec = u_data.iter().map(|slice| slice.as_libc_iovec()).collect(); + let raw_iovs: Vec = u_data + .iter() + .map(|slice| slice.as_ref().as_libc_iovec()) + .collect(); let (msg_iov, msg_iovlen) = raw_iovs.as_slice().as_ptr_and_len(); // Control let (msg_control, msg_controllen) = control.as_ptr_and_len(); diff --git a/src/libos/src/untrusted/mod.rs b/src/libos/src/untrusted/mod.rs index 9e35d794..4b1fa455 100644 --- a/src/libos/src/untrusted/mod.rs +++ b/src/libos/src/untrusted/mod.rs @@ -6,5 +6,5 @@ mod slice_ext; use super::*; pub use self::alloc::UNTRUSTED_ALLOC; -pub use self::slice_alloc::UntrustedSliceAlloc; +pub use self::slice_alloc::{UntrustedSlice, UntrustedSliceAlloc}; pub use self::slice_ext::{SliceAsMutPtrAndLen, SliceAsPtrAndLen}; diff --git a/src/libos/src/untrusted/slice_alloc.rs b/src/libos/src/untrusted/slice_alloc.rs index a79d830b..c1130a4f 100644 --- a/src/libos/src/untrusted/slice_alloc.rs +++ b/src/libos/src/untrusted/slice_alloc.rs @@ -1,5 +1,6 @@ use super::*; use std::alloc::{AllocError, Allocator, Layout}; +use std::ops::{Deref, DerefMut}; use std::ptr::NonNull; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -36,13 +37,13 @@ impl UntrustedSliceAlloc { }) } - pub fn new_slice(&self, src_slice: &[u8]) -> Result<&[u8]> { + pub fn new_slice(&self, src_slice: &[u8]) -> Result { let mut new_slice = self.new_slice_mut(src_slice.len())?; - new_slice.copy_from_slice(src_slice); + new_slice.read_from_slice(src_slice)?; Ok(new_slice) } - pub fn new_slice_mut(&self, new_slice_len: usize) -> Result<&mut [u8]> { + pub fn new_slice_mut(&self, new_slice_len: usize) -> Result { let new_slice_ptr = { // Move self.buf_pos forward if enough space _atomically_. let old_pos = self @@ -59,7 +60,7 @@ impl UntrustedSliceAlloc { unsafe { self.buf_ptr.add(old_pos) } }; let new_slice = unsafe { std::slice::from_raw_parts_mut(new_slice_ptr, new_slice_len) }; - Ok(new_slice) + Ok(UntrustedSlice { slice: new_slice }) } } @@ -76,3 +77,86 @@ impl Drop for UntrustedSliceAlloc { } } } + +pub struct UntrustedSlice<'a> { + slice: &'a mut [u8], +} + +impl UntrustedSlice<'_> { + pub fn read_from_slice(&mut self, src_slice: &[u8]) -> Result<()> { + assert!(self.len() >= src_slice.len()); + + #[cfg(not(feature = "hyper_mode"))] + self[..src_slice.len()].copy_from_slice(src_slice); + #[cfg(feature = "hyper_mode")] + { + let n = unsafe { + libc::ocall::write_shared_buf( + self.as_mut_ptr() as *mut _, + src_slice.as_ptr() as *const _, + src_slice.len(), + 0, + ) + }; + match n { + n if n < 0 => return_errno!(ENOMEM, "No enough space"), + n if n as usize == src_slice.len() => {} + _ => return_errno!(ENOMEM, "failed to fill whole buffer"), + } + } + + Ok(()) + } + + pub fn write_to_slice(&self, dest_slice: &mut [u8]) -> Result<()> { + assert!(self.len() >= dest_slice.len()); + + #[cfg(not(feature = "hyper_mode"))] + dest_slice.copy_from_slice(&self[..dest_slice.len()]); + #[cfg(feature = "hyper_mode")] + { + let n = unsafe { + libc::ocall::read_shared_buf( + self.as_ptr() as *const _, + dest_slice.as_mut_ptr() as *mut _, + dest_slice.len(), + 0, + ) + }; + match n { + n if n < 0 => return_errno!(ENOMEM, "No enough space"), + n if n as usize == dest_slice.len() => {} + _ => return_errno!(ENOMEM, "failed to write whole buffer"), + } + } + + Ok(()) + } +} + +impl AsRef<[u8]> for UntrustedSlice<'_> { + fn as_ref(&self) -> &[u8] { + &**self + } +} + +impl AsMut<[u8]> for UntrustedSlice<'_> { + fn as_mut(&mut self) -> &mut [u8] { + &mut **self + } +} + +impl Deref for UntrustedSlice<'_> { + type Target = [u8]; + #[inline] + fn deref(&self) -> &Self::Target { + self.slice + } +} + +impl DerefMut for UntrustedSlice<'_> { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + self.slice + } +}