Skip to content

uefi: alloc_pages() and alloc_pool() now return NonNull<[u8]> #1606

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

phip1611
Copy link
Member

@phip1611 phip1611 commented Apr 6, 2025

uefi: alloc_pages() and alloc_pool() now return NonNull<[u8]>. This aligns the signature with the Rust allocator API and also makes more sense.

Checklist

  • Sensible git history (for example, squash "typo" or "fix" commits). See the Rewriting History guide for help.
  • Update the changelog (if necessary)

@phip1611 phip1611 requested a review from nicholasbishop April 6, 2025 19:17
@phip1611 phip1611 mentioned this pull request Apr 6, 2025
13 tasks
@phip1611 phip1611 self-assigned this Apr 7, 2025

Ok(NonNull::new(ptr).expect("allocate_pool must not return a null pointer if successful"))
if let Some(ptr) = NonNull::new(ptr) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if let Some(ptr) = NonNull::new(ptr) {
NonNull::new(ptr).map(|ptr| NonNull::slice_from_raw_parts(ptr, size)).ok_or(Status::OUT_OF_RESOURCES.into())

@@ -281,7 +281,7 @@ impl MemoryMapBackingMemory {
pub(crate) fn new(memory_type: MemoryType) -> crate::Result<Self> {
let memory_map_meta = boot::memory_map_size();
let len = Self::safe_allocation_size_hint(memory_map_meta);
let ptr = boot::allocate_pool(memory_type, len)?.as_ptr();
let ptr = boot::allocate_pool(memory_type, len)?.cast::<u8>().as_ptr();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just making the new API compatible with existing code; shortcut

@@ -100,7 +102,8 @@ unsafe impl GlobalAlloc for Allocator {
// `allocate_pool` always provides eight-byte alignment, so we can
// use `allocate_pool` directly.
boot::allocate_pool(memory_type, size)
.map(|ptr| ptr.as_ptr())
.map(|mut ptr: NonNull<[u8]>| unsafe { ptr.as_mut() })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is unsound: as_mut creates a reference, but that's not valid because the allocated memory is uninitialized. I think instead this can be:

            boot::allocate_pool(memory_type, size)
                .map(|ptr: NonNull<[u8]>| ptr.as_ptr().cast::<u8>())
                .unwrap_or(ptr::null_mut())

(Potentially in the future it could be further simplified to ptr.as_mut_ptr(), but it's not yet stable.)

let addr = ptr.as_ptr() as usize;
assert_eq!(addr % 4096, 0, "Page pointer is not page-aligned");

let buffer = unsafe { ptr.as_mut() };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue here, this is unsound with uninitialized memory. I don't think we have to use write_volatile like the code here did originally, but we do need to use some pointer function like ptr::write or ptr::write_bytes.

Since so many of the NonNull<[T]>/*mut [T] functions are unstable, I think it's most convenient to cast it back to *mut u8. Then you can do unsafe { ptr.write_bytes(...) }.

Ditto for the docstring examples on boot::allocate_pages/boot::allocate_pool.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh yes, good catch, thanks!

This aligns the signature with the Rust allocator API.
This aligns the signature with the Rust allocator API.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants