Skip to content

Commit 34d5de0

Browse files
uefi: Use standalone boot functions in the allocator
1 parent 32b04a5 commit 34d5de0

File tree

1 file changed

+17
-24
lines changed

1 file changed

+17
-24
lines changed

uefi/src/allocator.rs

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
1414
use core::alloc::{GlobalAlloc, Layout};
1515
use core::ffi::c_void;
16-
use core::ptr;
16+
use core::ptr::{self, NonNull};
1717
use core::sync::atomic::{AtomicPtr, AtomicU32, Ordering};
1818

19+
use crate::boot;
1920
use crate::mem::memory_map::MemoryType;
2021
use crate::proto::loaded_image::LoadedImage;
21-
use crate::table::boot::BootServices;
2222
use crate::table::{Boot, SystemTable};
2323

2424
/// Reference to the system table, used to call the boot services pool memory
@@ -42,20 +42,12 @@ pub unsafe fn init(system_table: &mut SystemTable<Boot>) {
4242

4343
let boot_services = system_table.boot_services();
4444
if let Ok(loaded_image) =
45-
boot_services.open_protocol_exclusive::<LoadedImage>(boot_services.image_handle())
45+
boot::open_protocol_exclusive::<LoadedImage>(boot_services.image_handle())
4646
{
4747
MEMORY_TYPE.store(loaded_image.data_type().0, Ordering::Release);
4848
}
4949
}
5050

51-
/// Access the boot services
52-
fn boot_services() -> *const BootServices {
53-
let ptr = SYSTEM_TABLE.load(Ordering::Acquire);
54-
let system_table =
55-
unsafe { SystemTable::from_ptr(ptr) }.expect("The system table handle is not available");
56-
system_table.boot_services()
57-
}
58-
5951
/// Notify the allocator library that boot services are not safe to call anymore
6052
///
6153
/// You must arrange for this function to be called on exit from UEFI boot services
@@ -70,27 +62,24 @@ pub fn exit_boot_services() {
7062
pub struct Allocator;
7163

7264
unsafe impl GlobalAlloc for Allocator {
73-
/// Allocate memory using [`BootServices::allocate_pool`]. The allocation is
65+
/// Allocate memory using [`boot::allocate_pool`]. The allocation is
7466
/// of type [`MemoryType::LOADER_DATA`] for UEFI applications, [`MemoryType::BOOT_SERVICES_DATA`]
7567
/// for UEFI boot drivers and [`MemoryType::RUNTIME_SERVICES_DATA`] for UEFI runtime drivers.
7668
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
7769
let size = layout.size();
7870
let align = layout.align();
7971
let memory_type = MemoryType(MEMORY_TYPE.load(Ordering::Acquire));
8072

81-
let boot_services = &*boot_services();
82-
8373
if align > 8 {
8474
// The requested alignment is greater than 8, but `allocate_pool` is
8575
// only guaranteed to provide eight-byte alignment. Allocate extra
8676
// space so that we can return an appropriately-aligned pointer
8777
// within the allocation.
88-
let full_alloc_ptr =
89-
if let Ok(ptr) = boot_services.allocate_pool(memory_type, size + align) {
90-
ptr.as_ptr()
91-
} else {
92-
return ptr::null_mut();
93-
};
78+
let full_alloc_ptr = if let Ok(ptr) = boot::allocate_pool(memory_type, size + align) {
79+
ptr.as_ptr()
80+
} else {
81+
return ptr::null_mut();
82+
};
9483

9584
// Calculate the offset needed to get an aligned pointer within the
9685
// full allocation. If that offset is zero, increase it to `align`
@@ -115,20 +104,24 @@ unsafe impl GlobalAlloc for Allocator {
115104
// The requested alignment is less than or equal to eight, and
116105
// `allocate_pool` always provides eight-byte alignment, so we can
117106
// use `allocate_pool` directly.
118-
boot_services
119-
.allocate_pool(memory_type, size)
107+
boot::allocate_pool(memory_type, size)
120108
.map(|ptr| ptr.as_ptr())
121109
.unwrap_or(ptr::null_mut())
122110
}
123111
}
124112

125-
/// Deallocate memory using [`BootServices::free_pool`].
113+
/// Deallocate memory using [`boot::free_pool`].
126114
unsafe fn dealloc(&self, mut ptr: *mut u8, layout: Layout) {
127115
if layout.align() > 8 {
128116
// Retrieve the pointer to the full allocation that was packed right
129117
// before the aligned allocation in `alloc`.
130118
ptr = (ptr as *const *mut u8).sub(1).read();
131119
}
132-
(*boot_services()).free_pool(ptr).unwrap();
120+
121+
// OK to unwrap: `ptr` is required to be a valid allocation by the trait API.
122+
let ptr = NonNull::new(ptr).unwrap();
123+
124+
// Warning: this will panic after exiting boot services.
125+
boot::free_pool(ptr).unwrap();
133126
}
134127
}

0 commit comments

Comments
 (0)