diff --git a/library/std/src/sys/sgx/abi/mod.rs b/library/std/src/sys/sgx/abi/mod.rs
index b0693b63a48fd..a0eb12c3d154a 100644
--- a/library/std/src/sys/sgx/abi/mod.rs
+++ b/library/std/src/sys/sgx/abi/mod.rs
@@ -45,7 +45,7 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
         // We need to wait until the initialization is done.
         BUSY => {
             while RELOC_STATE.load(Ordering::Acquire) == BUSY {
-                core::arch::x86_64::_mm_pause()
+                core::hint::spin_loop();
             }
         }
         // Initialization is done.
diff --git a/library/std/src/sys/sgx/abi/tls.rs b/library/std/src/sys/sgx/abi/tls.rs
index 0d8952b2f273b..13d96e9a633d3 100644
--- a/library/std/src/sys/sgx/abi/tls.rs
+++ b/library/std/src/sys/sgx/abi/tls.rs
@@ -87,18 +87,21 @@ impl Tls {
     }
 
     pub unsafe fn activate(&self) -> ActiveTls<'_> {
-        set_tls_ptr(self as *const Tls as _);
+        // FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition.
+        unsafe { set_tls_ptr(self as *const Tls as _) };
         ActiveTls { tls: self }
     }
 
     #[allow(unused)]
     pub unsafe fn activate_persistent(self: Box<Self>) {
-        set_tls_ptr((&*self) as *const Tls as _);
+        // FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition.
+        unsafe { set_tls_ptr((&*self) as *const Tls as _) };
         mem::forget(self);
     }
 
     unsafe fn current<'a>() -> &'a Tls {
-        &*(get_tls_ptr() as *const Tls)
+        // FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition.
+        unsafe { &*(get_tls_ptr() as *const Tls) }
     }
 
     pub fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
diff --git a/library/std/src/sys/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/sgx/abi/usercalls/alloc.rs
index 76a9b427b39c6..9fdb1b4584479 100644
--- a/library/std/src/sys/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/alloc.rs
@@ -89,9 +89,12 @@ pub unsafe trait UserSafe {
     /// * the pointed-to range is not in user memory.
     unsafe fn from_raw_sized(ptr: *mut u8, size: usize) -> NonNull<Self> {
         assert!(ptr.wrapping_add(size) >= ptr);
-        let ret = Self::from_raw_sized_unchecked(ptr, size);
-        Self::check_ptr(ret);
-        NonNull::new_unchecked(ret as _)
+        // SAFETY: The caller has guaranteed the pointer is valid
+        let ret = unsafe { Self::from_raw_sized_unchecked(ptr, size) };
+        unsafe {
+            Self::check_ptr(ret);
+            NonNull::new_unchecked(ret as _)
+        }
     }
 
     /// Checks if a pointer may point to `Self` in user memory.
@@ -112,7 +115,7 @@ pub unsafe trait UserSafe {
         let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) };
 
         assert!(is_aligned(ptr as *const u8));
-        assert!(is_user_range(ptr as _, mem::size_of_val(&*ptr)));
+        assert!(is_user_range(ptr as _, mem::size_of_val(unsafe { &*ptr })));
         assert!(!ptr.is_null());
     }
 }
@@ -135,11 +138,23 @@ unsafe impl<T: UserSafeSized> UserSafe for [T] {
         mem::align_of::<T>()
     }
 
+    /// # Safety
+    /// Behavior is undefined if any of these conditions are violated:
+    /// * `ptr` must be [valid] for writes of `size` many bytes, and it must be
+    ///   properly aligned.
+    ///
+    /// [valid]: core::ptr#safety
+    /// # Panics
+    ///
+    /// This function panics if:
+    ///
+    /// * the element size is not a factor of the size
     unsafe fn from_raw_sized_unchecked(ptr: *mut u8, size: usize) -> *mut Self {
         let elem_size = mem::size_of::<T>();
         assert_eq!(size % elem_size, 0);
         let len = size / elem_size;
-        slice::from_raw_parts_mut(ptr as _, len)
+        // SAFETY: The caller must uphold the safety contract for `from_raw_sized_unchecked`
+        unsafe { slice::from_raw_parts_mut(ptr as _, len) }
     }
 }
 
@@ -170,13 +185,15 @@ trait NewUserRef<T: ?Sized> {
 
 impl<T: ?Sized> NewUserRef<*mut T> for NonNull<UserRef<T>> {
     unsafe fn new_userref(v: *mut T) -> Self {
-        NonNull::new_unchecked(v as _)
+        // SAFETY: The caller has guaranteed the pointer is valid
+        unsafe { NonNull::new_unchecked(v as _) }
     }
 }
 
 impl<T: ?Sized> NewUserRef<NonNull<T>> for NonNull<UserRef<T>> {
     unsafe fn new_userref(v: NonNull<T>) -> Self {
-        NonNull::new_userref(v.as_ptr())
+        // SAFETY: The caller has guaranteed the pointer is valid
+        unsafe { NonNull::new_userref(v.as_ptr()) }
     }
 }
 
@@ -231,8 +248,9 @@ where
     /// * The pointer is null
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_raw(ptr: *mut T) -> Self {
-        T::check_ptr(ptr);
-        User(NonNull::new_userref(ptr))
+        // SAFETY: the caller must uphold the safety contract for `from_raw`.
+        unsafe { T::check_ptr(ptr) };
+        User(unsafe { NonNull::new_userref(ptr) })
     }
 
     /// Converts this value into a raw pointer. The value will no longer be
@@ -280,7 +298,9 @@ where
     /// * The pointed-to range does not fit in the address space
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self {
-        User(NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>())))
+        User(unsafe {
+            NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()))
+        })
     }
 }
 
@@ -301,8 +321,9 @@ where
     /// * The pointer is null
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_ptr<'a>(ptr: *const T) -> &'a Self {
-        T::check_ptr(ptr);
-        &*(ptr as *const Self)
+        // SAFETY: The caller must uphold the safety contract for `from_ptr`.
+        unsafe { T::check_ptr(ptr) };
+        unsafe { &*(ptr as *const Self) }
     }
 
     /// Creates a `&mut UserRef<[T]>` from a raw pointer. See the struct
@@ -318,8 +339,9 @@ where
     /// * The pointer is null
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_mut_ptr<'a>(ptr: *mut T) -> &'a mut Self {
-        T::check_ptr(ptr);
-        &mut *(ptr as *mut Self)
+        // SAFETY: The caller must uphold the safety contract for `from_mut_ptr`.
+        unsafe { T::check_ptr(ptr) };
+        unsafe { &mut *(ptr as *mut Self) }
     }
 
     /// Copies `val` into user memory.
@@ -394,7 +416,10 @@ where
     /// * The pointed-to range does not fit in the address space
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_raw_parts<'a>(ptr: *const T, len: usize) -> &'a Self {
-        &*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *const Self)
+        // SAFETY: The caller must uphold the safety contract for `from_raw_parts`.
+        unsafe {
+            &*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *const Self)
+        }
     }
 
     /// Creates a `&mut UserRef<[T]>` from a raw thin pointer and a slice length.
@@ -412,7 +437,10 @@ where
     /// * The pointed-to range does not fit in the address space
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut T, len: usize) -> &'a mut Self {
-        &mut *(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *mut Self)
+        // SAFETY: The caller must uphold the safety contract for `from_raw_parts_mut`.
+        unsafe {
+            &mut *(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *mut Self)
+        }
     }
 
     /// Obtain a raw pointer to the first element of this user slice.
@@ -437,13 +465,12 @@ where
     /// This function panics if the destination doesn't have the same size as
     /// the source. This can happen for dynamically-sized types such as slices.
     pub fn copy_to_enclave_vec(&self, dest: &mut Vec<T>) {
-        unsafe {
-            if let Some(missing) = self.len().checked_sub(dest.capacity()) {
-                dest.reserve(missing)
-            }
-            dest.set_len(self.len());
-            self.copy_to_enclave(&mut dest[..]);
+        if let Some(missing) = self.len().checked_sub(dest.capacity()) {
+            dest.reserve(missing)
         }
+        // SAFETY: We reserve enough space above.
+        unsafe { dest.set_len(self.len()) };
+        self.copy_to_enclave(&mut dest[..]);
     }
 
     /// Copies the value from user memory into a vector in enclave memory.
diff --git a/library/std/src/sys/sgx/abi/usercalls/mod.rs b/library/std/src/sys/sgx/abi/usercalls/mod.rs
index 73f1b951e7430..a6a659df291fc 100644
--- a/library/std/src/sys/sgx/abi/usercalls/mod.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/mod.rs
@@ -140,7 +140,8 @@ pub fn connect_stream(addr: &str) -> IoResult<(Fd, String, String)> {
 /// Usercall `launch_thread`. See the ABI documentation for more information.
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub unsafe fn launch_thread() -> IoResult<()> {
-    raw::launch_thread().from_sgx_result()
+    // SAFETY: The caller must uphold the safety contract for `launch_thread`.
+    unsafe { raw::launch_thread().from_sgx_result() }
 }
 
 /// Usercall `exit`. See the ABI documentation for more information.
diff --git a/library/std/src/sys/sgx/abi/usercalls/raw.rs b/library/std/src/sys/sgx/abi/usercalls/raw.rs
index e0ebf860618c8..b0e6a6aaed7b9 100644
--- a/library/std/src/sys/sgx/abi/usercalls/raw.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/raw.rs
@@ -33,7 +33,7 @@ pub unsafe fn do_usercall(
     p4: u64,
     abort: bool,
 ) -> (u64, u64) {
-    let UsercallReturn(a, b) = usercall(nr, p1, p2, abort as _, p3, p4);
+    let UsercallReturn(a, b) = unsafe { usercall(nr, p1, p2, abort as _, p3, p4) };
     (a, b)
 }
 
@@ -175,14 +175,14 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
         #[unstable(feature = "sgx_platform", issue = "56975")]
         #[inline(always)]
         pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3, $n4: $t4) -> $r {
-            ReturnValue::from_registers(stringify!($f), do_usercall(
-                rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
-                RegisterArgument::into_register($n1),
-                RegisterArgument::into_register($n2),
-                RegisterArgument::into_register($n3),
-                RegisterArgument::into_register($n4),
-                return_type_is_abort!($r)
-            ))
+            ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
+                    rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
+                    RegisterArgument::into_register($n1),
+                    RegisterArgument::into_register($n2),
+                    RegisterArgument::into_register($n3),
+                    RegisterArgument::into_register($n4),
+                    return_type_is_abort!($r)
+            ) })
         }
     );
     (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty, $n3:ident: $t3:ty) -> $r:tt) => (
@@ -191,14 +191,14 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
         #[unstable(feature = "sgx_platform", issue = "56975")]
         #[inline(always)]
         pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3) -> $r {
-            ReturnValue::from_registers(stringify!($f), do_usercall(
-                rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
-                RegisterArgument::into_register($n1),
-                RegisterArgument::into_register($n2),
-                RegisterArgument::into_register($n3),
-                0,
-                return_type_is_abort!($r)
-            ))
+            ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
+                    rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
+                    RegisterArgument::into_register($n1),
+                    RegisterArgument::into_register($n2),
+                    RegisterArgument::into_register($n3),
+                    0,
+                    return_type_is_abort!($r)
+            ) })
         }
     );
     (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty) -> $r:tt) => (
@@ -207,13 +207,13 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
         #[unstable(feature = "sgx_platform", issue = "56975")]
         #[inline(always)]
         pub unsafe fn $f($n1: $t1, $n2: $t2) -> $r {
-            ReturnValue::from_registers(stringify!($f), do_usercall(
-                rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
-                RegisterArgument::into_register($n1),
-                RegisterArgument::into_register($n2),
-                0,0,
-                return_type_is_abort!($r)
-            ))
+            ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
+                    rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
+                    RegisterArgument::into_register($n1),
+                    RegisterArgument::into_register($n2),
+                    0,0,
+                    return_type_is_abort!($r)
+            ) })
         }
     );
     (def fn $f:ident($n1:ident: $t1:ty) -> $r:tt) => (
@@ -222,12 +222,12 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
         #[unstable(feature = "sgx_platform", issue = "56975")]
         #[inline(always)]
         pub unsafe fn $f($n1: $t1) -> $r {
-            ReturnValue::from_registers(stringify!($f), do_usercall(
-                rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
-                RegisterArgument::into_register($n1),
-                0,0,0,
-                return_type_is_abort!($r)
-            ))
+            ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
+                    rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
+                    RegisterArgument::into_register($n1),
+                    0,0,0,
+                    return_type_is_abort!($r)
+            ) })
         }
     );
     (def fn $f:ident() -> $r:tt) => (
@@ -236,11 +236,11 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
         #[unstable(feature = "sgx_platform", issue = "56975")]
         #[inline(always)]
         pub unsafe fn $f() -> $r {
-            ReturnValue::from_registers(stringify!($f), do_usercall(
-                rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
-                0,0,0,0,
-                return_type_is_abort!($r)
-            ))
+            ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
+                    rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
+                    0,0,0,0,
+                    return_type_is_abort!($r)
+            ) })
         }
     );
     (def fn $f:ident($($n:ident: $t:ty),*)) => (
diff --git a/library/std/src/sys/sgx/alloc.rs b/library/std/src/sys/sgx/alloc.rs
index 40daec758a9fc..4559ea7cd2540 100644
--- a/library/std/src/sys/sgx/alloc.rs
+++ b/library/std/src/sys/sgx/alloc.rs
@@ -4,6 +4,10 @@ use super::waitqueue::SpinMutex;
 
 // Using a SpinMutex because we never want to exit the enclave waiting for the
 // allocator.
+//
+// The current allocator here is the `dlmalloc` crate which we've got included
+// in the rust-lang/rust repository as a submodule. The crate is a port of
+// dlmalloc.c from C to Rust.
 #[cfg_attr(test, linkage = "available_externally")]
 #[export_name = "_ZN16__rust_internals3std3sys3sgx5alloc8DLMALLOCE"]
 static DLMALLOC: SpinMutex<dlmalloc::Dlmalloc> = SpinMutex::new(dlmalloc::DLMALLOC_INIT);
@@ -12,22 +16,26 @@ static DLMALLOC: SpinMutex<dlmalloc::Dlmalloc> = SpinMutex::new(dlmalloc::DLMALL
 unsafe impl GlobalAlloc for System {
     #[inline]
     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
-        DLMALLOC.lock().malloc(layout.size(), layout.align())
+        // SAFETY: the caller must uphold the safety contract for `malloc`
+        unsafe { DLMALLOC.lock().malloc(layout.size(), layout.align()) }
     }
 
     #[inline]
     unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
-        DLMALLOC.lock().calloc(layout.size(), layout.align())
+        // SAFETY: the caller must uphold the safety contract for `malloc`
+        unsafe { DLMALLOC.lock().calloc(layout.size(), layout.align()) }
     }
 
     #[inline]
     unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
-        DLMALLOC.lock().free(ptr, layout.size(), layout.align())
+        // SAFETY: the caller must uphold the safety contract for `malloc`
+        unsafe { DLMALLOC.lock().free(ptr, layout.size(), layout.align()) }
     }
 
     #[inline]
     unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
-        DLMALLOC.lock().realloc(ptr, layout.size(), layout.align(), new_size)
+        // SAFETY: the caller must uphold the safety contract for `malloc`
+        unsafe { DLMALLOC.lock().realloc(ptr, layout.size(), layout.align(), new_size) }
     }
 }
 
@@ -36,11 +44,11 @@ unsafe impl GlobalAlloc for System {
 #[cfg(not(test))]
 #[no_mangle]
 pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 {
-    crate::alloc::alloc(Layout::from_size_align_unchecked(size, align))
+    unsafe { crate::alloc::alloc(Layout::from_size_align_unchecked(size, align)) }
 }
 
 #[cfg(not(test))]
 #[no_mangle]
 pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) {
-    crate::alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align))
+    unsafe { crate::alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align)) }
 }
diff --git a/library/std/src/sys/sgx/args.rs b/library/std/src/sys/sgx/args.rs
index 5a53695a8466b..2d2e692ec7d35 100644
--- a/library/std/src/sys/sgx/args.rs
+++ b/library/std/src/sys/sgx/args.rs
@@ -13,7 +13,7 @@ type ArgsStore = Vec<OsString>;
 #[cfg_attr(test, allow(dead_code))]
 pub unsafe fn init(argc: isize, argv: *const *const u8) {
     if argc != 0 {
-        let args = alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _);
+        let args = unsafe { alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _) };
         let args = args
             .iter()
             .map(|a| OsString::from_inner(Buf { inner: a.copy_user_buffer() }))
diff --git a/library/std/src/sys/sgx/condvar.rs b/library/std/src/sys/sgx/condvar.rs
index ed6dbcf497147..f0e8f43ded041 100644
--- a/library/std/src/sys/sgx/condvar.rs
+++ b/library/std/src/sys/sgx/condvar.rs
@@ -27,13 +27,13 @@ impl Condvar {
 
     pub unsafe fn wait(&self, mutex: &Mutex) {
         let guard = self.inner.lock();
-        WaitQueue::wait(guard, || mutex.unlock());
-        mutex.lock()
+        WaitQueue::wait(guard, || unsafe { mutex.unlock() });
+        unsafe { mutex.lock() }
     }
 
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
-        let success = WaitQueue::wait_timeout(&self.inner, dur, || mutex.unlock());
-        mutex.lock();
+        let success = WaitQueue::wait_timeout(&self.inner, dur, || unsafe { mutex.unlock() });
+        unsafe { mutex.lock() };
         success
     }
 
diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs
index 1abd91e75e8c4..b10bed621dbad 100644
--- a/library/std/src/sys/sgx/mod.rs
+++ b/library/std/src/sys/sgx/mod.rs
@@ -2,6 +2,7 @@
 //!
 //! This module contains the facade (aka platform-specific) implementations of
 //! OS level functionality for Fortanix SGX.
+#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::io::ErrorKind;
 use crate::os::raw::c_char;
@@ -121,9 +122,9 @@ pub enum Void {}
 
 pub unsafe fn strlen(mut s: *const c_char) -> usize {
     let mut n = 0;
-    while *s != 0 {
+    while unsafe { *s } != 0 {
         n += 1;
-        s = s.offset(1);
+        s = unsafe { s.offset(1) };
     }
     return n;
 }
diff --git a/library/std/src/sys/sgx/rwlock.rs b/library/std/src/sys/sgx/rwlock.rs
index 3bf2a7d8fb46c..0c96e3fcddcdf 100644
--- a/library/std/src/sys/sgx/rwlock.rs
+++ b/library/std/src/sys/sgx/rwlock.rs
@@ -14,9 +14,12 @@ pub struct RWLock {
 }
 
 // Check at compile time that RWLock size matches C definition (see test_c_rwlock_initializer below)
+//
+// # Safety
+// Never called, as it is a compile time check.
 #[allow(dead_code)]
 unsafe fn rw_lock_size_assert(r: RWLock) {
-    mem::transmute::<RWLock, [u8; 144]>(r);
+    unsafe { mem::transmute::<RWLock, [u8; 144]>(r) };
 }
 
 impl RWLock {
@@ -112,7 +115,7 @@ impl RWLock {
     pub unsafe fn read_unlock(&self) {
         let rguard = self.readers.lock();
         let wguard = self.writer.lock();
-        self.__read_unlock(rguard, wguard);
+        unsafe { self.__read_unlock(rguard, wguard) };
     }
 
     #[inline]
@@ -148,7 +151,7 @@ impl RWLock {
     pub unsafe fn write_unlock(&self) {
         let rguard = self.readers.lock();
         let wguard = self.writer.lock();
-        self.__write_unlock(rguard, wguard);
+        unsafe { self.__write_unlock(rguard, wguard) };
     }
 
     // only used by __rust_rwlock_unlock below
@@ -158,9 +161,9 @@ impl RWLock {
         let rguard = self.readers.lock();
         let wguard = self.writer.lock();
         if *wguard.lock_var() == true {
-            self.__write_unlock(rguard, wguard);
+            unsafe { self.__write_unlock(rguard, wguard) };
         } else {
-            self.__read_unlock(rguard, wguard);
+            unsafe { self.__read_unlock(rguard, wguard) };
         }
     }
 
@@ -179,7 +182,7 @@ pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
     if p.is_null() {
         return EINVAL;
     }
-    (*p).read();
+    unsafe { (*p).read() };
     return 0;
 }
 
@@ -189,7 +192,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
     if p.is_null() {
         return EINVAL;
     }
-    (*p).write();
+    unsafe { (*p).write() };
     return 0;
 }
 #[cfg(not(test))]
@@ -198,6 +201,6 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
     if p.is_null() {
         return EINVAL;
     }
-    (*p).unlock();
+    unsafe { (*p).unlock() };
     return 0;
 }
diff --git a/library/std/src/sys/sgx/stdio.rs b/library/std/src/sys/sgx/stdio.rs
index 49f44f9f498ac..548e28a43d646 100644
--- a/library/std/src/sys/sgx/stdio.rs
+++ b/library/std/src/sys/sgx/stdio.rs
@@ -81,7 +81,7 @@ pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
     if s < 0 {
         return;
     }
-    let buf = slice::from_raw_parts(m as *const u8, s as _);
+    let buf = unsafe { slice::from_raw_parts(m as *const u8, s as _) };
     if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) {
         eprint!("{}", s);
     }
diff --git a/library/std/src/sys/sgx/thread.rs b/library/std/src/sys/sgx/thread.rs
index 5895f70436efa..55ef460cc90c5 100644
--- a/library/std/src/sys/sgx/thread.rs
+++ b/library/std/src/sys/sgx/thread.rs
@@ -51,7 +51,7 @@ impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
         let mut queue_lock = task_queue::lock();
-        usercalls::launch_thread()?;
+        unsafe { usercalls::launch_thread()? };
         let (task, handle) = task_queue::Task::new(p);
         queue_lock.push(task);
         Ok(Thread(handle))
diff --git a/library/std/src/sys/sgx/waitqueue/unsafe_list.rs b/library/std/src/sys/sgx/waitqueue/unsafe_list.rs
index 7a2465427396d..0834d2593fc32 100644
--- a/library/std/src/sys/sgx/waitqueue/unsafe_list.rs
+++ b/library/std/src/sys/sgx/waitqueue/unsafe_list.rs
@@ -30,31 +30,34 @@ impl<T> UnsafeList<T> {
         unsafe { UnsafeList { head_tail: NonNull::new_unchecked(1 as _), head_tail_entry: None } }
     }
 
+    /// # Safety
     unsafe fn init(&mut self) {
         if self.head_tail_entry.is_none() {
             self.head_tail_entry = Some(UnsafeListEntry::dummy());
-            self.head_tail = NonNull::new_unchecked(self.head_tail_entry.as_mut().unwrap());
-            self.head_tail.as_mut().next = self.head_tail;
-            self.head_tail.as_mut().prev = self.head_tail;
+            // SAFETY: `head_tail_entry` must be non-null, which it is because we assign it above.
+            self.head_tail =
+                unsafe { NonNull::new_unchecked(self.head_tail_entry.as_mut().unwrap()) };
+            // SAFETY: `self.head_tail` must meet all requirements for a mutable reference.
+            unsafe { self.head_tail.as_mut() }.next = self.head_tail;
+            unsafe { self.head_tail.as_mut() }.prev = self.head_tail;
         }
     }
 
     pub fn is_empty(&self) -> bool {
-        unsafe {
-            if self.head_tail_entry.is_some() {
-                let first = self.head_tail.as_ref().next;
-                if first == self.head_tail {
-                    // ,-------> /---------\ next ---,
-                    // |         |head_tail|         |
-                    // `--- prev \---------/ <-------`
-                    rtassert!(self.head_tail.as_ref().prev == first);
-                    true
-                } else {
-                    false
-                }
-            } else {
+        if self.head_tail_entry.is_some() {
+            let first = unsafe { self.head_tail.as_ref() }.next;
+            if first == self.head_tail {
+                // ,-------> /---------\ next ---,
+                // |         |head_tail|         |
+                // `--- prev \---------/ <-------`
+                // SAFETY: `self.head_tail` must meet all requirements for a reference.
+                unsafe { rtassert!(self.head_tail.as_ref().prev == first) };
                 true
+            } else {
+                false
             }
+        } else {
+            true
         }
     }
 
@@ -67,7 +70,7 @@ impl<T> UnsafeList<T> {
     /// care must be taken in the caller of `push` to ensure unwinding does
     /// not destroy the stack frame containing the entry.
     pub unsafe fn push<'a>(&mut self, entry: &'a mut UnsafeListEntry<T>) -> &'a T {
-        self.init();
+        unsafe { self.init() };
 
         // BEFORE:
         //     /---------\ next ---> /---------\
@@ -78,13 +81,15 @@ impl<T> UnsafeList<T> {
         //     /---------\ next ---> /-----\ next ---> /---------\
         // ... |prev_tail|           |entry|           |head_tail| ...
         //     \---------/ <--- prev \-----/ <--- prev \---------/
-        let mut entry = NonNull::new_unchecked(entry);
-        let mut prev_tail = mem::replace(&mut self.head_tail.as_mut().prev, entry);
-        entry.as_mut().prev = prev_tail;
-        entry.as_mut().next = self.head_tail;
-        prev_tail.as_mut().next = entry;
+        let mut entry = unsafe { NonNull::new_unchecked(entry) };
+        let mut prev_tail = mem::replace(&mut unsafe { self.head_tail.as_mut() }.prev, entry);
+        // SAFETY: `entry` must meet all requirements for a mutable reference.
+        unsafe { entry.as_mut() }.prev = prev_tail;
+        unsafe { entry.as_mut() }.next = self.head_tail;
+        // SAFETY: `prev_tail` must meet all requirements for a mutable reference.
+        unsafe { prev_tail.as_mut() }.next = entry;
         // unwrap ok: always `Some` on non-dummy entries
-        (*entry.as_ptr()).value.as_ref().unwrap()
+        unsafe { (*entry.as_ptr()).value.as_ref() }.unwrap()
     }
 
     /// Pops an entry from the front of the list.
@@ -94,7 +99,7 @@ impl<T> UnsafeList<T> {
     /// The caller must make sure to synchronize ending the borrow of the
     /// return value and deallocation of the containing entry.
     pub unsafe fn pop<'a>(&mut self) -> Option<&'a T> {
-        self.init();
+        unsafe { self.init() };
 
         if self.is_empty() {
             None
@@ -108,14 +113,14 @@ impl<T> UnsafeList<T> {
             //     /---------\ next ---> /------\
             // ... |head_tail|           |second| ...
             //     \---------/ <--- prev \------/
-            let mut first = self.head_tail.as_mut().next;
-            let mut second = first.as_mut().next;
-            self.head_tail.as_mut().next = second;
-            second.as_mut().prev = self.head_tail;
-            first.as_mut().next = NonNull::dangling();
-            first.as_mut().prev = NonNull::dangling();
+            let mut first = unsafe { self.head_tail.as_mut() }.next;
+            let mut second = unsafe { first.as_mut() }.next;
+            unsafe { self.head_tail.as_mut() }.next = second;
+            unsafe { second.as_mut() }.prev = self.head_tail;
+            unsafe { first.as_mut() }.next = NonNull::dangling();
+            unsafe { first.as_mut() }.prev = NonNull::dangling();
             // unwrap ok: always `Some` on non-dummy entries
-            Some((*first.as_ptr()).value.as_ref().unwrap())
+            Some(unsafe { (*first.as_ptr()).value.as_ref() }.unwrap())
         }
     }
 
@@ -138,8 +143,9 @@ impl<T> UnsafeList<T> {
         //     \----/ <--- prev \----/
         let mut prev = entry.prev;
         let mut next = entry.next;
-        prev.as_mut().next = next;
-        next.as_mut().prev = prev;
+        // SAFETY: `prev` and `next` must meet all requirements for a mutable reference.entry
+        unsafe { prev.as_mut() }.next = next;
+        unsafe { next.as_mut() }.prev = prev;
         entry.next = NonNull::dangling();
         entry.prev = NonNull::dangling();
     }
diff --git a/library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs b/library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs
index 1f031ed1959cf..c653dee17bc36 100644
--- a/library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs
+++ b/library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs
@@ -1,8 +1,10 @@
 use super::*;
 use crate::cell::Cell;
 
+/// # Safety
+/// List must be valid.
 unsafe fn assert_empty<T>(list: &mut UnsafeList<T>) {
-    assert!(list.pop().is_none(), "assertion failed: list is not empty");
+    assert!(unsafe { list.pop() }.is_none(), "assertion failed: list is not empty");
 }
 
 #[test]