Implement untrusted IO buffer for each thread
This commit is contained in:
parent
c1e04c03cf
commit
99c1f92ddf
21
src/libos/Cargo.lock
generated
21
src/libos/Cargo.lock
generated
@ -36,6 +36,7 @@ dependencies = [
|
||||
"sgx_tse",
|
||||
"sgx_tstd",
|
||||
"sgx_types",
|
||||
"spin 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -257,7 +258,7 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
dependencies = [
|
||||
"spin",
|
||||
"spin 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -444,7 +445,7 @@ name = "rcore-fs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"spin",
|
||||
"spin 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -453,7 +454,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rcore-fs",
|
||||
"spin",
|
||||
"spin 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -462,7 +463,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rcore-fs",
|
||||
"spin",
|
||||
"spin 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -471,7 +472,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rcore-fs",
|
||||
"spin",
|
||||
"spin 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -481,7 +482,7 @@ dependencies = [
|
||||
"bitvec",
|
||||
"log",
|
||||
"rcore-fs",
|
||||
"spin",
|
||||
"spin 0.5.2",
|
||||
"static_assertions",
|
||||
"uuid",
|
||||
]
|
||||
@ -492,7 +493,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rcore-fs",
|
||||
"spin",
|
||||
"spin 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -700,6 +701,12 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13287b4da9d1207a4f4929ac390916d64eacfe236a487e9a9f5b3be392be5162"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
|
@ -32,6 +32,7 @@ ctor = "0.1"
|
||||
regex = { git = "https://github.com/mesalock-linux/regex-sgx", default-features = false, features = ["std", "unicode", "mesalock_sgx"] }
|
||||
goblin = { version = "0.5.4", default-features = false, features = ["elf64", "elf32", "endian_fd"] }
|
||||
intrusive-collections = "0.9"
|
||||
spin = "0.7"
|
||||
|
||||
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
|
||||
sgx_tstd = { path = "../../deps/rust-sgx-sdk/sgx_tstd" }
|
||||
|
@ -4,30 +4,25 @@ use std::mem;
|
||||
|
||||
use atomic::Atomic;
|
||||
|
||||
use self::recv::Receiver;
|
||||
use self::send::Sender;
|
||||
|
||||
use super::*;
|
||||
use crate::fs::{
|
||||
occlum_ocall_ioctl, AccessMode, CreationFlags, File, FileRef, HostFd, IoEvents, IoNotifier,
|
||||
IoctlCmd, StatusFlags,
|
||||
};
|
||||
|
||||
use crate::process::IO_BUF_SIZE;
|
||||
|
||||
mod ioctl_impl;
|
||||
mod recv;
|
||||
mod send;
|
||||
mod socket_file;
|
||||
|
||||
pub const SEND_BUF_SIZE: usize = 128 * 1024;
|
||||
pub const RECV_BUF_SIZE: usize = 128 * 1024;
|
||||
/// Native linux socket
|
||||
#[derive(Debug)]
|
||||
pub struct HostSocket {
|
||||
host_fd: HostFd,
|
||||
host_events: Atomic<IoEvents>,
|
||||
notifier: IoNotifier,
|
||||
sender: SgxMutex<Sender>,
|
||||
receiver: SgxMutex<Receiver>,
|
||||
}
|
||||
|
||||
impl HostSocket {
|
||||
@ -49,14 +44,10 @@ impl HostSocket {
|
||||
fn from_host_fd(host_fd: HostFd) -> Result<HostSocket> {
|
||||
let host_events = Atomic::new(IoEvents::empty());
|
||||
let notifier = IoNotifier::new();
|
||||
let sender = SgxMutex::new(Sender::new()?);
|
||||
let receiver = SgxMutex::new(Receiver::new()?);
|
||||
Ok(Self {
|
||||
host_fd,
|
||||
host_events,
|
||||
notifier,
|
||||
sender,
|
||||
receiver,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,6 @@
|
||||
use super::*;
|
||||
use crate::untrusted::{SliceAsMutPtrAndLen, SliceAsPtrAndLen, UntrustedSliceAlloc};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Receiver {
|
||||
alloc: UntrustedSliceAlloc,
|
||||
}
|
||||
|
||||
impl Receiver {
|
||||
pub fn new() -> Result<Self> {
|
||||
let alloc = UntrustedSliceAlloc::new(RECV_BUF_SIZE)?;
|
||||
Ok(Self { alloc })
|
||||
}
|
||||
}
|
||||
|
||||
impl HostSocket {
|
||||
pub fn recv(&self, buf: &mut [u8], flags: RecvFlags) -> Result<usize> {
|
||||
let (bytes_recvd, _) = self.recvfrom(buf, flags)?;
|
||||
@ -43,18 +31,17 @@ impl HostSocket {
|
||||
mut name: Option<&mut [u8]>,
|
||||
mut control: Option<&mut [u8]>,
|
||||
) -> Result<(usize, usize, usize, MsgHdrFlags)> {
|
||||
let current = current!();
|
||||
let data_length = data.iter().map(|s| s.len()).sum();
|
||||
let mut receiver: SgxMutexGuard<'_, Receiver>;
|
||||
let mut ocall_alloc;
|
||||
// Allocated slice in untrusted memory region
|
||||
let u_allocator = if data_length > RECV_BUF_SIZE {
|
||||
let u_allocator = if data_length > IO_BUF_SIZE {
|
||||
// Ocall allocator
|
||||
ocall_alloc = UntrustedSliceAlloc::new(data_length)?;
|
||||
&mut ocall_alloc
|
||||
ocall_alloc.guard()
|
||||
} else {
|
||||
// Inner allocator, lock buffer until recv ocall completion
|
||||
receiver = self.receiver.lock().unwrap();
|
||||
&mut receiver.alloc
|
||||
// IO buffer per thread
|
||||
current.io_buffer()
|
||||
};
|
||||
|
||||
let mut u_data = {
|
||||
@ -77,7 +64,6 @@ impl HostSocket {
|
||||
break;
|
||||
}
|
||||
}
|
||||
u_allocator.reset();
|
||||
Ok(retval)
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,5 @@
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Sender {
|
||||
alloc: UntrustedSliceAlloc,
|
||||
}
|
||||
|
||||
impl Sender {
|
||||
pub fn new() -> Result<Self> {
|
||||
let alloc = UntrustedSliceAlloc::new(SEND_BUF_SIZE)?;
|
||||
Ok(Self { alloc })
|
||||
}
|
||||
}
|
||||
|
||||
impl HostSocket {
|
||||
pub fn send(&self, buf: &[u8], flags: SendFlags) -> Result<usize> {
|
||||
self.sendto(buf, flags, &None)
|
||||
@ -35,18 +23,17 @@ impl HostSocket {
|
||||
name: Option<&[u8]>,
|
||||
control: Option<&[u8]>,
|
||||
) -> Result<usize> {
|
||||
let current = current!();
|
||||
let data_length = data.iter().map(|s| s.len()).sum();
|
||||
let mut sender: SgxMutexGuard<'_, Sender>;
|
||||
let mut ocall_alloc;
|
||||
// Allocated slice in untrusted memory region
|
||||
let u_allocator = if data_length > SEND_BUF_SIZE {
|
||||
let u_allocator = if data_length > IO_BUF_SIZE {
|
||||
// Ocall allocator
|
||||
ocall_alloc = UntrustedSliceAlloc::new(data_length)?;
|
||||
&mut ocall_alloc
|
||||
ocall_alloc.guard()
|
||||
} else {
|
||||
// Inner allocator, lock buffer until send ocall completion
|
||||
sender = self.sender.lock().unwrap();
|
||||
&mut sender.alloc
|
||||
// IO buffer per thread
|
||||
current.io_buffer()
|
||||
};
|
||||
|
||||
let u_data = {
|
||||
@ -59,7 +46,6 @@ impl HostSocket {
|
||||
};
|
||||
|
||||
let retval = self.do_sendmsg_untrusted_data(&u_data, flags, name, control);
|
||||
u_allocator.reset();
|
||||
retval
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ pub use self::spawn_attribute::SpawnAttr;
|
||||
pub use self::syscalls::*;
|
||||
pub use self::task::Task;
|
||||
pub use self::term_status::{ForcedExitStatus, TermStatus};
|
||||
pub use self::thread::{Thread, ThreadStatus};
|
||||
pub use self::thread::{Thread, ThreadStatus, IO_BUF_SIZE};
|
||||
|
||||
mod do_arch_prctl;
|
||||
mod do_clone;
|
||||
|
@ -1,3 +1,4 @@
|
||||
use spin::Once;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use super::{
|
||||
@ -143,6 +144,7 @@ impl ThreadBuilder {
|
||||
};
|
||||
let host_eventfd = Arc::new(HostEventFd::new()?);
|
||||
let raw_ptr = RwLock::new(0);
|
||||
let io_buffer = Once::new();
|
||||
|
||||
let new_thread = Arc::new(Thread {
|
||||
task,
|
||||
@ -165,6 +167,7 @@ impl ThreadBuilder {
|
||||
profiler,
|
||||
host_eventfd,
|
||||
raw_ptr,
|
||||
io_buffer,
|
||||
});
|
||||
|
||||
let mut inner = new_thread.process().inner();
|
||||
|
@ -1,3 +1,4 @@
|
||||
use spin::Once;
|
||||
use std::fmt;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
@ -12,6 +13,7 @@ use crate::net::THREAD_NOTIFIERS;
|
||||
use crate::prelude::*;
|
||||
use crate::signal::{SigQueues, SigSet, SigStack};
|
||||
use crate::time::ThreadProfiler;
|
||||
use crate::untrusted::{UntrustedSliceAlloc, UntrustedSliceAllocGuard};
|
||||
|
||||
pub use self::builder::ThreadBuilder;
|
||||
pub use self::id::ThreadId;
|
||||
@ -21,6 +23,8 @@ mod builder;
|
||||
mod id;
|
||||
mod name;
|
||||
|
||||
pub const IO_BUF_SIZE: usize = 128 * 1024;
|
||||
|
||||
pub struct Thread {
|
||||
// Low-level info
|
||||
task: Task,
|
||||
@ -50,6 +54,8 @@ pub struct Thread {
|
||||
// Misc
|
||||
host_eventfd: Arc<HostEventFd>,
|
||||
raw_ptr: RwLock<usize>,
|
||||
// Thread ocall buffer
|
||||
io_buffer: Once<UntrustedSliceAlloc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
@ -216,6 +222,12 @@ impl Thread {
|
||||
&self.host_eventfd
|
||||
}
|
||||
|
||||
pub fn io_buffer(&self) -> UntrustedSliceAllocGuard<'_> {
|
||||
self.io_buffer
|
||||
.call_once(|| UntrustedSliceAlloc::new(IO_BUF_SIZE).unwrap())
|
||||
.guard()
|
||||
}
|
||||
|
||||
pub(super) fn start(&self, host_tid: pid_t) {
|
||||
self.sched().lock().unwrap().attach(host_tid);
|
||||
let mut raw_ptr = self.raw_ptr.write().unwrap();
|
||||
|
@ -6,5 +6,5 @@ mod slice_ext;
|
||||
use super::*;
|
||||
|
||||
pub use self::alloc::UNTRUSTED_ALLOC;
|
||||
pub use self::slice_alloc::{UntrustedSlice, UntrustedSliceAlloc};
|
||||
pub use self::slice_alloc::{UntrustedSlice, UntrustedSliceAlloc, UntrustedSliceAllocGuard};
|
||||
pub use self::slice_ext::{SliceAsMutPtrAndLen, SliceAsPtrAndLen};
|
||||
|
@ -46,13 +46,17 @@ impl UntrustedSliceAlloc {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new_slice(&self, src_slice: &[u8]) -> Result<UntrustedSlice> {
|
||||
pub fn guard(&self) -> UntrustedSliceAllocGuard<'_> {
|
||||
UntrustedSliceAllocGuard { alloc: self }
|
||||
}
|
||||
|
||||
fn new_slice(&self, src_slice: &[u8]) -> Result<UntrustedSlice> {
|
||||
let mut new_slice = self.new_slice_mut(src_slice.len())?;
|
||||
new_slice.read_from_slice(src_slice)?;
|
||||
Ok(new_slice)
|
||||
}
|
||||
|
||||
pub fn new_slice_mut(&self, new_slice_len: usize) -> Result<UntrustedSlice> {
|
||||
fn new_slice_mut(&self, new_slice_len: usize) -> Result<UntrustedSlice> {
|
||||
let new_slice_ptr = {
|
||||
// Move self.buf_pos forward if enough space _atomically_.
|
||||
let old_pos = self
|
||||
@ -72,7 +76,7 @@ impl UntrustedSliceAlloc {
|
||||
Ok(UntrustedSlice { slice: new_slice })
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
fn reset(&self) {
|
||||
self.buf_pos.store(0, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
@ -100,6 +104,25 @@ impl Debug for UntrustedSliceAlloc {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UntrustedSliceAllocGuard<'a> {
|
||||
alloc: &'a UntrustedSliceAlloc,
|
||||
}
|
||||
|
||||
impl<'a> UntrustedSliceAllocGuard<'a> {
|
||||
pub fn new_slice(&self, src_slice: &[u8]) -> Result<UntrustedSlice> {
|
||||
self.alloc.new_slice(src_slice)
|
||||
}
|
||||
pub fn new_slice_mut(&self, new_slice_len: usize) -> Result<UntrustedSlice> {
|
||||
self.alloc.new_slice_mut(new_slice_len)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for UntrustedSliceAllocGuard<'a> {
|
||||
fn drop(&mut self) {
|
||||
self.alloc.reset();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UntrustedSlice<'a> {
|
||||
slice: &'a mut [u8],
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user