Fix SGX implementation

This commit is contained in:
Orson Peters 2025-10-03 00:52:18 +02:00
parent 85a49073c3
commit b717684f87
4 changed files with 15 additions and 20 deletions

View file

@ -3,6 +3,7 @@
use core::arch::global_asm;
use core::sync::atomic::{Atomic, AtomicUsize, Ordering};
use crate::alloc::System;
use crate::io::Write;
// runtime features
@ -63,7 +64,9 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
#[unsafe(no_mangle)]
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> EntryReturn {
// FIXME: how to support TLS in library mode?
let tls = Box::new(tls::Tls::new());
// We use the System allocator here such that the global allocator may use
// thread-locals.
let tls = Box::new_in(tls::Tls::new(), System);
let tls_guard = unsafe { tls.activate() };
if secondary {

View file

@ -89,13 +89,6 @@ impl Tls {
ActiveTls { tls: self }
}
#[allow(unused)]
pub unsafe fn activate_persistent(self: Box<Self>) {
// FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition.
let ptr = Box::into_raw(self).cast_const().cast::<u8>();
unsafe { set_tls_ptr(ptr) };
}
unsafe fn current<'a>() -> &'a Tls {
// FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition.
unsafe { &*(get_tls_ptr() as *const Tls) }

View file

@ -2,6 +2,7 @@
use crate::io;
use crate::sys::pal::abi::{thread, usercalls};
use crate::thread::ThreadInit;
use crate::time::Duration;
pub struct Thread(task_queue::JoinHandle);
@ -13,6 +14,7 @@ pub use self::task_queue::JoinNotifier;
mod task_queue {
use super::wait_notify;
use crate::sync::{Mutex, MutexGuard};
use crate::thread::ThreadInit;
pub type JoinHandle = wait_notify::Waiter;
@ -25,19 +27,20 @@ mod task_queue {
}
pub(super) struct Task {
p: Box<dyn FnOnce() + Send>,
init: Box<ThreadInit>,
done: JoinNotifier,
}
impl Task {
pub(super) fn new(p: Box<dyn FnOnce() + Send>) -> (Task, JoinHandle) {
pub(super) fn new(init: Box<ThreadInit>) -> (Task, JoinHandle) {
let (done, recv) = wait_notify::new();
let done = JoinNotifier(Some(done));
(Task { p, done }, recv)
(Task { init, done }, recv)
}
pub(super) fn run(self) -> JoinNotifier {
(self.p)();
let rust_start = self.init.init();
rust_start();
self.done
}
}
@ -93,14 +96,10 @@ pub mod wait_notify {
impl Thread {
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
pub unsafe fn new(
_stack: usize,
_name: Option<&str>,
p: Box<dyn FnOnce() + Send>,
) -> io::Result<Thread> {
pub unsafe fn new(_stack: usize, init: Box<ThreadInit>) -> io::Result<Thread> {
let mut queue_lock = task_queue::lock();
unsafe { usercalls::launch_thread()? };
let (task, handle) = task_queue::Task::new(p);
let (task, handle) = task_queue::Task::new(init);
queue_lock.push(task);
Ok(Thread(handle))
}

View file

@ -218,13 +218,13 @@ pub mod local_impl {
/// the global allocator works.
pub(crate) struct ThreadInit {
pub handle: Thread,
pub rust_start: Box<dyn FnOnce()>,
pub rust_start: Box<dyn FnOnce() + Send>,
}
impl ThreadInit {
/// Initialize the 'current thread' mechanism on this thread, returning the
/// Rust entry point.
pub fn init(self: Box<Self>) -> Box<dyn FnOnce()> {
pub fn init(self: Box<Self>) -> Box<dyn FnOnce() + Send> {
// Set the current thread before any (de)allocations on the global allocator occur,
// so that it may call std::thread::current() in its implementation. This is also
// why we take Box<Self>, to ensure the Box is not destroyed until after this point.