Skip to content

Commit df454f9

Browse files
uefi-services: Change SYSTEM_TABLE to an atomic pointer
This aligns with how the std uefi target works: https://github.com/rust-lang/rust/blob/f654229c27267334023a22233795b88b75fc340e/library/std/src/os/uefi/env.rs#L8 And also avoids some unsafe; a static atomic be written without being `static mut`, and reads and writes are safe operations.
1 parent aba21d7 commit df454f9

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

uefi-services/src/lib.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ extern crate uefi;
3636

3737
use core::ffi::c_void;
3838
use core::fmt::Write;
39-
use core::ptr::NonNull;
39+
use core::ptr::{self, NonNull};
40+
use core::sync::atomic::{AtomicPtr, Ordering};
4041

4142
use cfg_if::cfg_if;
4243

@@ -50,15 +51,22 @@ use uefi::{Event, Result};
5051
/// This table is only fully safe to use until UEFI boot services have been exited.
5152
/// After that, some fields and methods are unsafe to use, see the documentation of
5253
/// UEFI's ExitBootServices entry point for more details.
53-
static mut SYSTEM_TABLE: Option<SystemTable<Boot>> = None;
54+
static SYSTEM_TABLE: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
5455

5556
/// Global logger object
5657
#[cfg(feature = "logger")]
5758
static mut LOGGER: Option<uefi::logger::Logger> = None;
5859

5960
#[must_use]
6061
fn system_table_opt() -> Option<SystemTable<Boot>> {
61-
unsafe { SYSTEM_TABLE.as_ref().map(|table| table.unsafe_clone()) }
62+
let ptr = SYSTEM_TABLE.load(Ordering::Acquire);
63+
// Safety: the `SYSTEM_TABLE` pointer either be null or a valid system
64+
// table.
65+
//
66+
// Null is the initial value, as well as the value set when exiting boot
67+
// services. Otherwise, the value is set by the call to `init`, which
68+
// requires a valid system table reference as input.
69+
unsafe { SystemTable::from_ptr(ptr) }
6270
}
6371

6472
/// Obtains a pointer to the system table.
@@ -84,10 +92,10 @@ pub fn init(st: &mut SystemTable<Boot>) -> Result<Option<Event>> {
8492
return Status::SUCCESS.to_result_with_val(|| None);
8593
}
8694

87-
unsafe {
88-
// Setup the system table singleton
89-
SYSTEM_TABLE = Some(st.unsafe_clone());
95+
// Setup the system table singleton
96+
SYSTEM_TABLE.store(st.as_ptr().cast_mut(), Ordering::Release);
9097

98+
unsafe {
9199
// Setup logging and memory allocation
92100

93101
#[cfg(feature = "logger")]
@@ -180,7 +188,7 @@ unsafe extern "efiapi" fn exit_boot_services(_e: Event, _ctx: Option<NonNull<c_v
180188
// check that the callback does get called.
181189
//
182190
// info!("Shutting down the UEFI utility library");
183-
SYSTEM_TABLE = None;
191+
SYSTEM_TABLE.store(ptr::null_mut(), Ordering::Release);
184192

185193
#[cfg(feature = "logger")]
186194
if let Some(ref mut logger) = LOGGER {

0 commit comments

Comments
 (0)