Rollup merge of #59869 - jethrogb:jb/sgx-iovec, r=sfackler
SGX target: implemented vectored I/O r? @sfackler Includes #59857
This commit is contained in:
commit
c54b77ca2d
4 changed files with 60 additions and 15 deletions
|
|
@ -523,7 +523,11 @@ impl<T, I: SliceIndex<[T]>> Index<I> for UserRef<[T]> where [T]: UserSafe, I::Ou
|
|||
#[inline]
|
||||
fn index(&self, index: I) -> &UserRef<I::Output> {
|
||||
unsafe {
|
||||
UserRef::from_ptr(index.index(&*self.as_raw_ptr()))
|
||||
if let Some(slice) = index.get(&*self.as_raw_ptr()) {
|
||||
UserRef::from_ptr(slice)
|
||||
} else {
|
||||
rtabort!("index out of range for user slice");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -533,7 +537,11 @@ impl<T, I: SliceIndex<[T]>> IndexMut<I> for UserRef<[T]> where [T]: UserSafe, I:
|
|||
#[inline]
|
||||
fn index_mut(&mut self, index: I) -> &mut UserRef<I::Output> {
|
||||
unsafe {
|
||||
UserRef::from_mut_ptr(index.index_mut(&mut*self.as_raw_mut_ptr()))
|
||||
if let Some(slice) = index.get_mut(&mut*self.as_raw_mut_ptr()) {
|
||||
UserRef::from_mut_ptr(slice)
|
||||
} else {
|
||||
rtabort!("index out of range for user slice");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::io::{Error as IoError, Result as IoResult};
|
||||
use crate::cmp;
|
||||
use crate::io::{Error as IoError, Result as IoResult, IoSlice, IoSliceMut};
|
||||
use crate::time::Duration;
|
||||
|
||||
pub(crate) mod alloc;
|
||||
|
|
@ -8,13 +9,27 @@ pub(crate) mod raw;
|
|||
use self::raw::*;
|
||||
|
||||
/// Usercall `read`. See the ABI documentation for more information.
|
||||
///
|
||||
/// This will do a single `read` usercall and scatter the read data among
|
||||
/// `bufs`. To read to a single buffer, just pass a slice of length one.
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult<usize> {
|
||||
pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> IoResult<usize> {
|
||||
unsafe {
|
||||
let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.len());
|
||||
let len = raw::read(fd, userbuf.as_mut_ptr(), userbuf.len()).from_sgx_result()?;
|
||||
userbuf[..len].copy_to_enclave(&mut buf[..len]);
|
||||
Ok(len)
|
||||
let total_len = bufs.iter().fold(0usize, |sum, buf| sum.saturating_add(buf.len()));
|
||||
let mut userbuf = alloc::User::<[u8]>::uninitialized(total_len);
|
||||
let ret_len = raw::read(fd, userbuf.as_mut_ptr(), userbuf.len()).from_sgx_result()?;
|
||||
let userbuf = &userbuf[..ret_len];
|
||||
let mut index = 0;
|
||||
for buf in bufs {
|
||||
let end = cmp::min(index + buf.len(), userbuf.len());
|
||||
if let Some(buflen) = end.checked_sub(index) {
|
||||
userbuf[index..end].copy_to_enclave(&mut buf[..buflen]);
|
||||
index += buf.len();
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
Ok(userbuf.len())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -30,10 +45,24 @@ pub fn read_alloc(fd: Fd) -> IoResult<Vec<u8>> {
|
|||
}
|
||||
|
||||
/// Usercall `write`. See the ABI documentation for more information.
|
||||
///
|
||||
/// This will do a single `write` usercall and gather the written data from
|
||||
/// `bufs`. To write from a single buffer, just pass a slice of length one.
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
pub fn write(fd: Fd, buf: &[u8]) -> IoResult<usize> {
|
||||
pub fn write(fd: Fd, bufs: &[IoSlice<'_>]) -> IoResult<usize> {
|
||||
unsafe {
|
||||
let userbuf = alloc::User::new_from_enclave(buf);
|
||||
let total_len = bufs.iter().fold(0usize, |sum, buf| sum.saturating_add(buf.len()));
|
||||
let mut userbuf = alloc::User::<[u8]>::uninitialized(total_len);
|
||||
let mut index = 0;
|
||||
for buf in bufs {
|
||||
let end = cmp::min(index + buf.len(), userbuf.len());
|
||||
if let Some(buflen) = end.checked_sub(index) {
|
||||
userbuf[index..end].copy_from_enclave(&buf[..buflen]);
|
||||
index += buf.len();
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
raw::write(fd, userbuf.as_ptr(), userbuf.len()).from_sgx_result()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use fortanix_sgx_abi::Fd;
|
||||
|
||||
use crate::io;
|
||||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use crate::mem;
|
||||
use crate::sys::{AsInner, FromInner, IntoInner};
|
||||
use super::abi::usercalls;
|
||||
|
|
@ -25,11 +25,19 @@ impl FileDesc {
|
|||
}
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
usercalls::read(self.fd, buf)
|
||||
usercalls::read(self.fd, &mut [IoSliceMut::new(buf)])
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
usercalls::read(self.fd, bufs)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
usercalls::write(self.fd, buf)
|
||||
usercalls::write(self.fd, &[IoSlice::new(buf)])
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
usercalls::write(self.fd, bufs)
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ impl TcpStream {
|
|||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
io::default_read_vectored(|b| self.read(b), bufs)
|
||||
self.inner.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
|
|
@ -145,7 +145,7 @@ impl TcpStream {
|
|||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
io::default_write_vectored(|b| self.write(b), bufs)
|
||||
self.inner.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue