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