Skip to content

Commit 1ec2842

Browse files
committed
uefi: allocate_pool() now returns NonNull<[u8]>
This aligns the signature with the Rust allocator API.
1 parent 129c8a6 commit 1ec2842

File tree

6 files changed

+34
-19
lines changed

6 files changed

+34
-19
lines changed

Diff for: uefi-test-runner/src/boot/memory.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,17 @@ fn test_allocate_pages() {
4343
}
4444

4545
fn test_allocate_pool() {
46-
let ptr = boot::allocate_pool(MemoryType::LOADER_DATA, 10).unwrap();
46+
let mut ptr = boot::allocate_pool(MemoryType::LOADER_DATA, 10).unwrap();
47+
let buffer = unsafe { ptr.as_mut() };
4748

4849
// Verify the allocation can be written to.
4950
{
50-
let ptr = ptr.as_ptr();
51-
unsafe { ptr.write_volatile(0xff) };
52-
unsafe { ptr.add(9).write_volatile(0xff) };
51+
buffer[0] = 0xff;
52+
buffer[9] = 0xff;
53+
assert_eq!(buffer[0], 0xff);
54+
assert_eq!(buffer[9], 0xff);
5355
}
54-
unsafe { boot::free_pool(ptr) }.unwrap();
56+
unsafe { boot::free_pool(ptr.cast()) }.unwrap();
5557
}
5658

5759
// Simple test to ensure our custom allocator works with the `alloc` crate.

Diff for: uefi-test-runner/src/boot/misc.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,14 @@ fn test_install_configuration_table() {
222222
let initial_table_count = system::with_config_table(|t| t.len());
223223

224224
// Create the entry data.
225-
let config: NonNull<u8> = boot::allocate_pool(MemoryType::RUNTIME_SERVICES_DATA, 1).unwrap();
226-
unsafe { config.write(123u8) };
225+
let mut config_ptr = boot::allocate_pool(MemoryType::RUNTIME_SERVICES_DATA, 1).unwrap();
226+
let buffer = unsafe { config_ptr.as_mut() };
227+
buffer[0] = 123;
227228

228229
// Install the table.
229230
const TABLE_GUID: Guid = guid!("4bec53c4-5fc1-48a1-ab12-df214907d29f");
230231
unsafe {
231-
boot::install_configuration_table(&TABLE_GUID, config.as_ptr().cast()).unwrap();
232+
boot::install_configuration_table(&TABLE_GUID, config_ptr.as_ptr().cast()).unwrap();
232233
}
233234

234235
// Verify the installation.
@@ -244,6 +245,6 @@ fn test_install_configuration_table() {
244245
// Uninstall the table and free the memory.
245246
unsafe {
246247
boot::install_configuration_table(&TABLE_GUID, ptr::null()).unwrap();
247-
boot::free_pool(config).unwrap();
248+
boot::free_pool(config_ptr.cast()).unwrap();
248249
}
249250
}

Diff for: uefi/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
- **Breaking**: `allocate_pages` now returns `NonNull<[u8]>` to align it with
2020
the Rust allocator API. There is an example in the documentation of that
2121
function.
22+
- **Breaking**: `allocate_pool` now returns `NonNull<[u8]>` to align it with
23+
the Rust allocator API. There is an example in the documentation of that
24+
function.
2225
- `boot::memory_map()` will never return `Status::BUFFER_TOO_SMALL` from now on,
2326
as this is considered a hard internal error where users can't do anything
2427
about it anyway. It will panic instead.

Diff for: uefi/src/allocator.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ unsafe impl GlobalAlloc for Allocator {
6868
// only guaranteed to provide eight-byte alignment. Allocate extra
6969
// space so that we can return an appropriately-aligned pointer
7070
// within the allocation.
71-
let full_alloc_ptr = if let Ok(ptr) = boot::allocate_pool(memory_type, size + align) {
72-
ptr.as_ptr()
73-
} else {
74-
return ptr::null_mut();
71+
let full_alloc_ptr = match boot::allocate_pool(memory_type, size + align) {
72+
Ok(ptr) => ptr.cast::<u8>().as_ptr(),
73+
Err(e) => {
74+
log::error!("Failed to allocate pool: {:?}", e);
75+
return ptr::null_mut();
76+
}
7577
};
7678

7779
// Calculate the offset needed to get an aligned pointer within the
@@ -100,7 +102,8 @@ unsafe impl GlobalAlloc for Allocator {
100102
// `allocate_pool` always provides eight-byte alignment, so we can
101103
// use `allocate_pool` directly.
102104
boot::allocate_pool(memory_type, size)
103-
.map(|ptr| ptr.as_ptr())
105+
.map(|mut ptr: NonNull<[u8]>| unsafe { ptr.as_mut() })
106+
.map(|ptr: &mut [u8]| ptr.as_mut_ptr())
104107
.unwrap_or(ptr::null_mut())
105108
}
106109
}

Diff for: uefi/src/boot.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ pub unsafe fn free_pages(ptr: NonNull<u8>, count: usize) -> Result {
218218
unsafe { (bt.free_pages)(addr, count) }.to_result()
219219
}
220220

221-
/// Allocates from a memory pool. The pointer will be 8-byte aligned.
221+
/// Allocates a consecutive region of bytes using the UEFI allocator. The buffer
222+
/// will be 8-byte aligned.
222223
///
223224
/// The caller is responsible to free the memory using [`free_pool`].
224225
///
@@ -250,15 +251,20 @@ pub unsafe fn free_pages(ptr: NonNull<u8>, count: usize) -> Result {
250251
/// * [`Status::OUT_OF_RESOURCES`]: allocation failed.
251252
/// * [`Status::INVALID_PARAMETER`]: `mem_ty` is [`MemoryType::PERSISTENT_MEMORY`],
252253
/// [`MemoryType::UNACCEPTED`], or in the range [`MemoryType::MAX`]`..=0x6fff_ffff`.
253-
pub fn allocate_pool(mem_ty: MemoryType, size: usize) -> Result<NonNull<u8>> {
254+
pub fn allocate_pool(memory_type: MemoryType, size: usize) -> Result<NonNull<[u8]>> {
254255
let bt = boot_services_raw_panicking();
255256
let bt = unsafe { bt.as_ref() };
256257

257258
let mut buffer = ptr::null_mut();
258259
let ptr =
259-
unsafe { (bt.allocate_pool)(mem_ty, size, &mut buffer) }.to_result_with_val(|| buffer)?;
260+
unsafe { (bt.allocate_pool)(memory_type, size, &mut buffer) }.to_result_with_val(|| buffer)?;
260261

261-
Ok(NonNull::new(ptr).expect("allocate_pool must not return a null pointer if successful"))
262+
if let Some(ptr) = NonNull::new(ptr) {
263+
let slice = NonNull::slice_from_raw_parts(ptr, size);
264+
Ok(slice)
265+
} else {
266+
Err(Status::OUT_OF_RESOURCES.into())
267+
}
262268
}
263269

264270
/// Frees memory allocated by [`allocate_pool`].

Diff for: uefi/src/mem/memory_map/impl_.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ impl MemoryMapBackingMemory {
281281
pub(crate) fn new(memory_type: MemoryType) -> crate::Result<Self> {
282282
let memory_map_meta = boot::memory_map_size();
283283
let len = Self::safe_allocation_size_hint(memory_map_meta);
284-
let ptr = boot::allocate_pool(memory_type, len)?.as_ptr();
284+
let ptr = boot::allocate_pool(memory_type, len)?.cast::<u8>().as_ptr();
285285

286286
// Should be fine as UEFI always has allocations with a guaranteed
287287
// alignment of 8 bytes.

0 commit comments

Comments
 (0)