Skip to content

Commit 166ed80

Browse files
uefi: Remove some uses of MaybeUninit in BootServices
While `MaybeUninit` is useful to avoid unnecessarily initializing large buffers, it's not needed for small values like single pointers and integers. For `Event`, `Handle`, and `ProtocolSearchKey`, which internally contain a `NonNull` pointer, we can wrap them in an `Option` and still have the same layout as a raw pointer. The initial value can then be `None` rather than `MaybeUninit`. This has the nice side effect of removing a little bit of `unsafe` code.
1 parent d15b7de commit 166ed80

File tree

1 file changed

+40
-37
lines changed

1 file changed

+40
-37
lines changed

uefi/src/table/boot.rs

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ pub struct BootServices {
122122
notify_tpl: Tpl,
123123
notify_func: Option<EventNotifyFn>,
124124
notify_ctx: Option<NonNull<c_void>>,
125-
out_event: *mut Event,
125+
out_event: *mut Option<Event>,
126126
) -> Status,
127127
set_timer: unsafe extern "efiapi" fn(event: Event, ty: u32, trigger_time: u64) -> Status,
128128
wait_for_event: unsafe extern "efiapi" fn(
@@ -159,7 +159,7 @@ pub struct BootServices {
159159
register_protocol_notify: extern "efiapi" fn(
160160
protocol: &Guid,
161161
event: Event,
162-
registration: *mut ProtocolSearchKey,
162+
registration: *mut Option<ProtocolSearchKey>,
163163
) -> Status,
164164
locate_handle: unsafe extern "efiapi" fn(
165165
search_ty: i32,
@@ -171,7 +171,7 @@ pub struct BootServices {
171171
locate_device_path: unsafe extern "efiapi" fn(
172172
proto: &Guid,
173173
device_path: &mut *const FfiDevicePath,
174-
out_handle: &mut MaybeUninit<Handle>,
174+
out_handle: &mut Option<Handle>,
175175
) -> Status,
176176
install_configuration_table:
177177
extern "efiapi" fn(guid_entry: &Guid, table_ptr: *const c_void) -> Status,
@@ -183,7 +183,7 @@ pub struct BootServices {
183183
device_path: *const FfiDevicePath,
184184
source_buffer: *const u8,
185185
source_size: usize,
186-
image_handle: &mut MaybeUninit<Handle>,
186+
image_handle: &mut Option<Handle>,
187187
) -> Status,
188188
start_image: unsafe extern "efiapi" fn(
189189
image_handle: Handle,
@@ -276,7 +276,7 @@ pub struct BootServices {
276276
notify_fn: Option<EventNotifyFn>,
277277
notify_ctx: Option<NonNull<c_void>>,
278278
event_group: Option<NonNull<Guid>>,
279-
out_event: *mut Event,
279+
out_event: *mut Option<Event>,
280280
) -> Status,
281281
}
282282

@@ -519,18 +519,14 @@ impl BootServices {
519519
notify_fn: Option<EventNotifyFn>,
520520
notify_ctx: Option<NonNull<c_void>>,
521521
) -> Result<Event> {
522-
// Prepare storage for the output Event
523-
let mut event = MaybeUninit::<Event>::uninit();
522+
let mut event = None;
524523

525524
// Now we're ready to call UEFI
526-
(self.create_event)(
527-
event_ty,
528-
notify_tpl,
529-
notify_fn,
530-
notify_ctx,
531-
event.as_mut_ptr(),
532-
)
533-
.to_result_with_val(|| event.assume_init())
525+
(self.create_event)(event_ty, notify_tpl, notify_fn, notify_ctx, &mut event)
526+
.to_result_with_val(
527+
// OK to unwrap: event is non-null for Status::SUCCESS.
528+
|| event.unwrap(),
529+
)
534530
}
535531

536532
/// Creates a new `Event` of type `event_type`. The event's notification function, context,
@@ -584,17 +580,20 @@ impl BootServices {
584580
return Err(Status::UNSUPPORTED.into());
585581
}
586582

587-
let mut event = MaybeUninit::<Event>::uninit();
583+
let mut event = None;
588584

589585
(self.create_event_ex)(
590586
event_type,
591587
notify_tpl,
592588
notify_fn,
593589
notify_ctx,
594590
event_group,
595-
event.as_mut_ptr(),
591+
&mut event,
592+
)
593+
.to_result_with_val(
594+
// OK to unwrap: event is non-null for Status::SUCCESS.
595+
|| event.unwrap(),
596596
)
597-
.to_result_with_val(|| event.assume_init())
598597
}
599598

600599
/// Sets the trigger for `EventType::TIMER` event.
@@ -649,18 +648,17 @@ impl BootServices {
649648
/// * [`uefi::Status::UNSUPPORTED`]
650649
pub fn wait_for_event(&self, events: &mut [Event]) -> Result<usize, Option<usize>> {
651650
let (number_of_events, events) = (events.len(), events.as_mut_ptr());
652-
let mut index = MaybeUninit::<usize>::uninit();
653-
unsafe { (self.wait_for_event)(number_of_events, events, index.as_mut_ptr()) }
654-
.to_result_with(
655-
|| unsafe { index.assume_init() },
656-
|s| {
657-
if s == Status::INVALID_PARAMETER {
658-
unsafe { Some(index.assume_init()) }
659-
} else {
660-
None
661-
}
662-
},
663-
)
651+
let mut index = 0;
652+
unsafe { (self.wait_for_event)(number_of_events, events, &mut index) }.to_result_with(
653+
|| index,
654+
|s| {
655+
if s == Status::INVALID_PARAMETER {
656+
Some(index)
657+
} else {
658+
None
659+
}
660+
},
661+
)
664662
}
665663

666664
/// Place 'event' in the signaled stated. If 'event' is already in the signaled state,
@@ -839,14 +837,15 @@ impl BootServices {
839837
protocol: &Guid,
840838
event: Event,
841839
) -> Result<(Event, SearchType)> {
842-
let mut key: MaybeUninit<ProtocolSearchKey> = MaybeUninit::uninit();
840+
let mut key = None;
843841
// Safety: we clone `event` a couple times, but there will be only one left once we return.
844-
unsafe { (self.register_protocol_notify)(protocol, event.unsafe_clone(), key.as_mut_ptr()) }
842+
unsafe { (self.register_protocol_notify)(protocol, event.unsafe_clone(), &mut key) }
845843
// Safety: as long as this call is successful, `key` will be valid.
846844
.to_result_with_val(|| unsafe {
847845
(
848846
event.unsafe_clone(),
849-
SearchType::ByRegisterNotify(key.assume_init()),
847+
// OK to unwrap: key is non-null for Status::SUCCESS.
848+
SearchType::ByRegisterNotify(key.unwrap()),
850849
)
851850
})
852851
}
@@ -918,13 +917,14 @@ impl BootServices {
918917
&self,
919918
device_path: &mut &DevicePath,
920919
) -> Result<Handle> {
921-
let mut handle = MaybeUninit::uninit();
920+
let mut handle = None;
922921
let mut device_path_ptr = device_path.as_ffi_ptr();
923922
unsafe {
924923
(self.locate_device_path)(&P::GUID, &mut device_path_ptr, &mut handle)
925924
.to_result_with_val(|| {
926925
*device_path = DevicePath::from_ffi_ptr(device_path_ptr);
927-
handle.assume_init()
926+
// OK to unwrap: handle is non-null for Status::SUCCESS.
927+
handle.unwrap()
928928
})
929929
}
930930
}
@@ -1037,7 +1037,7 @@ impl BootServices {
10371037
}
10381038
};
10391039

1040-
let mut image_handle = MaybeUninit::uninit();
1040+
let mut image_handle = None;
10411041
unsafe {
10421042
(self.load_image)(
10431043
boot_policy,
@@ -1047,7 +1047,10 @@ impl BootServices {
10471047
source_size,
10481048
&mut image_handle,
10491049
)
1050-
.to_result_with_val(|| image_handle.assume_init())
1050+
.to_result_with_val(
1051+
// OK to unwrap: image handle is non-null for Status::SUCCESS.
1052+
|| image_handle.unwrap(),
1053+
)
10511054
}
10521055
}
10531056

0 commit comments

Comments
 (0)