Skip to content

Commit 80343ee

Browse files
committed
mem+boot+x86_64+aarch64: switch to lock-free PFA
1 parent 8c8e129 commit 80343ee

File tree

11 files changed

+202
-197
lines changed

11 files changed

+202
-197
lines changed

oro-arch-aarch64/src/mem/address_space.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,9 @@ impl AddressSpaceLayout {
220220
///
221221
/// This probably isn't used by the kernel, but instead by the
222222
/// preboot environment to map stubs.
223+
#[must_use]
223224
pub fn new_supervisor_space_ttbr0() -> Option<Ttbr0Handle> {
224-
Self::new_supervisor_space_ttbr0_in(&mut oro_mem::global_alloc::GlobalPfa)
225+
Self::new_supervisor_space_ttbr0_in(&oro_mem::global_alloc::GlobalPfa)
225226
}
226227

227228
/// Creates a new supervisor (EL1) address space that addresses
@@ -230,7 +231,7 @@ impl AddressSpaceLayout {
230231
///
231232
/// This probably isn't used by the kernel, but instead by the
232233
/// preboot environment to map stubs.
233-
pub fn new_supervisor_space_ttbr0_in<A>(alloc: &mut A) -> Option<Ttbr0Handle>
234+
pub fn new_supervisor_space_ttbr0_in<A>(alloc: &A) -> Option<Ttbr0Handle>
234235
where
235236
A: Alloc,
236237
{
@@ -327,7 +328,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
327328
}
328329
}
329330

330-
fn new_supervisor_space_in<A>(alloc: &mut A) -> Option<Self::SupervisorHandle>
331+
fn new_supervisor_space_in<A>(alloc: &A) -> Option<Self::SupervisorHandle>
331332
where
332333
A: Alloc,
333334
{
@@ -350,10 +351,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
350351
Some(Ttbr1Handle { base_phys })
351352
}
352353

353-
fn new_user_space_in<A>(
354-
_space: &Self::SupervisorHandle,
355-
alloc: &mut A,
356-
) -> Option<Self::UserHandle>
354+
fn new_user_space_in<A>(_space: &Self::SupervisorHandle, alloc: &A) -> Option<Self::UserHandle>
357355
where
358356
A: Alloc,
359357
{
@@ -370,7 +368,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
370368

371369
fn duplicate_supervisor_space_shallow_in<A>(
372370
space: &Self::SupervisorHandle,
373-
alloc: &mut A,
371+
alloc: &A,
374372
) -> Option<Self::SupervisorHandle>
375373
where
376374
A: Alloc,
@@ -390,7 +388,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
390388

391389
fn duplicate_user_space_shallow_in<A>(
392390
space: &Self::UserHandle,
393-
alloc: &mut A,
391+
alloc: &A,
394392
) -> Option<Self::UserHandle>
395393
where
396394
A: Alloc,
@@ -408,7 +406,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
408406
Some(Self::UserHandle { base_phys })
409407
}
410408

411-
fn new_user_space_empty_in<A>(alloc: &mut A) -> Option<Self::UserHandle>
409+
fn new_user_space_empty_in<A>(alloc: &A) -> Option<Self::UserHandle>
412410
where
413411
A: Alloc,
414412
{
@@ -419,7 +417,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
419417
})
420418
}
421419

422-
fn free_user_space_handle_in<A>(space: Self::UserHandle, alloc: &mut A)
420+
fn free_user_space_handle_in<A>(space: Self::UserHandle, alloc: &A)
423421
where
424422
A: Alloc,
425423
{
@@ -431,7 +429,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
431429
}
432430
}
433431

434-
fn free_user_space_deep_in<A>(_space: Self::UserHandle, _alloc: &mut A)
432+
fn free_user_space_deep_in<A>(_space: Self::UserHandle, _alloc: &A)
435433
where
436434
A: Alloc,
437435
{

oro-arch-aarch64/src/mem/segment.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl Segment {
5757
pub(crate) fn entry<'a, A, Handle>(
5858
&'a self,
5959
space: &'a Handle,
60-
alloc: &'a mut A,
60+
alloc: &'a A,
6161
virt: usize,
6262
) -> Result<&'a mut PageTableEntry, MapError>
6363
where
@@ -185,7 +185,7 @@ impl Segment {
185185
unsafe fn try_unmap<A, Handle>(
186186
&self,
187187
space: &Handle,
188-
alloc: &mut A,
188+
alloc: &A,
189189
virt: usize,
190190
) -> Result<Option<u64>, UnmapError>
191191
where
@@ -300,7 +300,7 @@ impl Segment {
300300
}
301301

302302
unsafe impl<Handle: TtbrHandle> AddressSegment<Handle> for &'static Segment {
303-
unsafe fn unmap_all_and_reclaim_in<A>(&self, _space: &Handle, _alloc: &mut A)
303+
unsafe fn unmap_all_and_reclaim_in<A>(&self, _space: &Handle, _alloc: &A)
304304
where
305305
A: Alloc,
306306
{
@@ -327,7 +327,7 @@ unsafe impl<Handle: TtbrHandle> AddressSegment<Handle> for &'static Segment {
327327
(start, end)
328328
}
329329

330-
fn provision_as_shared_in<A>(&self, space: &Handle, alloc: &mut A) -> Result<(), MapError>
330+
fn provision_as_shared_in<A>(&self, space: &Handle, alloc: &A) -> Result<(), MapError>
331331
where
332332
A: Alloc,
333333
{
@@ -352,13 +352,7 @@ unsafe impl<Handle: TtbrHandle> AddressSegment<Handle> for &'static Segment {
352352
Ok(())
353353
}
354354

355-
fn map_in<A>(
356-
&self,
357-
space: &Handle,
358-
alloc: &mut A,
359-
virt: usize,
360-
phys: u64,
361-
) -> Result<(), MapError>
355+
fn map_in<A>(&self, space: &Handle, alloc: &A, virt: usize, phys: u64) -> Result<(), MapError>
362356
where
363357
A: Alloc,
364358
{
@@ -370,7 +364,7 @@ unsafe impl<Handle: TtbrHandle> AddressSegment<Handle> for &'static Segment {
370364
fn map_nofree_in<A>(
371365
&self,
372366
space: &Handle,
373-
alloc: &mut A,
367+
alloc: &A,
374368

375369
virt: usize,
376370
phys: u64,
@@ -401,7 +395,7 @@ unsafe impl<Handle: TtbrHandle> AddressSegment<Handle> for &'static Segment {
401395
Ok(())
402396
}
403397

404-
fn unmap_in<A>(&self, space: &Handle, alloc: &mut A, virt: usize) -> Result<u64, UnmapError>
398+
fn unmap_in<A>(&self, space: &Handle, alloc: &A, virt: usize) -> Result<u64, UnmapError>
405399
where
406400
A: Alloc,
407401
{
@@ -413,7 +407,7 @@ unsafe impl<Handle: TtbrHandle> AddressSegment<Handle> for &'static Segment {
413407
fn remap_in<A>(
414408
&self,
415409
space: &Handle,
416-
alloc: &mut A,
410+
alloc: &A,
417411
virt: usize,
418412
phys: u64,
419413
) -> Result<Option<u64>, MapError>

oro-arch-x86_64/src/mem/address_space.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
247247
}
248248
}
249249

250-
fn new_supervisor_space_in<A>(alloc: &mut A) -> Option<Self::SupervisorHandle>
250+
fn new_supervisor_space_in<A>(alloc: &A) -> Option<Self::SupervisorHandle>
251251
where
252252
A: Alloc,
253253
{
@@ -265,10 +265,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
265265
})
266266
}
267267

268-
fn new_user_space_in<A>(
269-
space: &Self::SupervisorHandle,
270-
alloc: &mut A,
271-
) -> Option<Self::UserHandle>
268+
fn new_user_space_in<A>(space: &Self::SupervisorHandle, alloc: &A) -> Option<Self::UserHandle>
272269
where
273270
A: Alloc,
274271
{
@@ -286,7 +283,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
286283
Some(duplicated)
287284
}
288285

289-
fn new_user_space_empty_in<A>(alloc: &mut A) -> Option<Self::UserHandle>
286+
fn new_user_space_empty_in<A>(alloc: &A) -> Option<Self::UserHandle>
290287
where
291288
A: Alloc,
292289
{
@@ -306,7 +303,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
306303

307304
fn duplicate_supervisor_space_shallow_in<A: Alloc>(
308305
space: &Self::SupervisorHandle,
309-
alloc: &mut A,
306+
alloc: &A,
310307
) -> Option<Self::SupervisorHandle> {
311308
let base_phys = alloc.allocate()?;
312309

@@ -328,7 +325,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
328325

329326
fn duplicate_user_space_shallow_in<A>(
330327
space: &Self::UserHandle,
331-
alloc: &mut A,
328+
alloc: &A,
332329
) -> Option<Self::UserHandle>
333330
where
334331
A: Alloc,
@@ -337,7 +334,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
337334
Self::duplicate_supervisor_space_shallow_in(space, alloc)
338335
}
339336

340-
fn free_user_space_handle_in<A>(space: Self::UserHandle, alloc: &mut A)
337+
fn free_user_space_handle_in<A>(space: Self::UserHandle, alloc: &A)
341338
where
342339
A: Alloc,
343340
{
@@ -349,7 +346,7 @@ unsafe impl AddressSpace for AddressSpaceLayout {
349346
}
350347
}
351348

352-
fn free_user_space_deep_in<A>(space: Self::UserHandle, alloc: &mut A)
349+
fn free_user_space_deep_in<A>(space: Self::UserHandle, alloc: &A)
353350
where
354351
A: Alloc,
355352
{

oro-arch-x86_64/src/mem/segment.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl AddressSegment {
6767
unsafe fn entry<'a, A, Handle: MapperHandle>(
6868
&'a self,
6969
space: &'a Handle,
70-
alloc: &'a mut A,
70+
alloc: &'a A,
7171
virt: usize,
7272
) -> Result<&'a mut PageTableEntry, MapError>
7373
where
@@ -137,7 +137,7 @@ impl AddressSegment {
137137
unsafe fn try_unmap_l4<A, Handle: MapperHandle>(
138138
&self,
139139
space: &Handle,
140-
alloc: &mut A,
140+
alloc: &A,
141141
virt: usize,
142142
) -> Result<Option<u64>, UnmapError>
143143
where
@@ -229,7 +229,7 @@ impl AddressSegment {
229229
unsafe fn try_unmap_l5<A, Handle: MapperHandle>(
230230
&self,
231231
space: &Handle,
232-
alloc: &mut A,
232+
alloc: &A,
233233
virt: usize,
234234
) -> Result<Option<u64>, UnmapError>
235235
where
@@ -340,12 +340,8 @@ impl AddressSegment {
340340
/// that the entry itself is reclaimable, and that none of the reclaimed pages
341341
/// are still being used.
342342
#[expect(clippy::only_used_in_recursion)] // false positive
343-
unsafe fn unmap_and_reclaim_entry<A>(
344-
&self,
345-
entry: &mut PageTableEntry,
346-
alloc: &mut A,
347-
level: usize,
348-
) where
343+
unsafe fn unmap_and_reclaim_entry<A>(&self, entry: &mut PageTableEntry, alloc: &A, level: usize)
344+
where
349345
A: Alloc,
350346
{
351347
if entry.present() {
@@ -445,7 +441,7 @@ unsafe impl Segment<AddressSpaceHandle> for &'static AddressSegment {
445441
}
446442
}
447443

448-
unsafe fn unmap_all_and_reclaim_in<A>(&self, space: &AddressSpaceHandle, alloc: &mut A)
444+
unsafe fn unmap_all_and_reclaim_in<A>(&self, space: &AddressSpaceHandle, alloc: &A)
449445
where
450446
A: Alloc,
451447
{
@@ -463,7 +459,7 @@ unsafe impl Segment<AddressSpaceHandle> for &'static AddressSegment {
463459
fn provision_as_shared_in<A>(
464460
&self,
465461
space: &AddressSpaceHandle,
466-
alloc: &mut A,
462+
alloc: &A,
467463
) -> Result<(), MapError>
468464
where
469465
A: Alloc,
@@ -492,7 +488,7 @@ unsafe impl Segment<AddressSpaceHandle> for &'static AddressSegment {
492488
fn map_in<A>(
493489
&self,
494490
space: &AddressSpaceHandle,
495-
alloc: &mut A,
491+
alloc: &A,
496492
virt: usize,
497493
phys: u64,
498494
) -> Result<(), MapError>
@@ -507,7 +503,7 @@ unsafe impl Segment<AddressSpaceHandle> for &'static AddressSegment {
507503
fn map_nofree_in<A>(
508504
&self,
509505
space: &AddressSpaceHandle,
510-
alloc: &mut A,
506+
alloc: &A,
511507
virt: usize,
512508
phys: u64,
513509
) -> Result<(), MapError>
@@ -528,7 +524,7 @@ unsafe impl Segment<AddressSpaceHandle> for &'static AddressSegment {
528524
fn unmap_in<A>(
529525
&self,
530526
space: &AddressSpaceHandle,
531-
alloc: &mut A,
527+
alloc: &A,
532528
virt: usize,
533529
) -> Result<u64, UnmapError>
534530
where
@@ -546,7 +542,7 @@ unsafe impl Segment<AddressSpaceHandle> for &'static AddressSegment {
546542
fn remap_in<A>(
547543
&self,
548544
space: &AddressSpaceHandle,
549-
alloc: &mut A,
545+
alloc: &A,
550546
virt: usize,
551547
phys: u64,
552548
) -> Result<Option<u64>, MapError>

oro-boot/src/lib.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub struct OroBootstrapper<
7272
I: Iterator<Item = M> + Clone,
7373
> {
7474
/// The PFA used to write variable length bootloader protocol structures to memory.
75-
pfa: pfa::PrebootPfa<M, I>,
75+
pfa: pfa::UnsafePrebootPfa<M, I>,
7676
/// The supervisor space
7777
supervisor_space: self::target::SupervisorHandle,
7878
/// The mapped kernel's request section scanner.
@@ -125,7 +125,7 @@ impl<M: Into<oro_boot_protocol::MemoryMapEntry> + Clone, I: Iterator<Item = M> +
125125
/// `stack_pages` is zero.
126126
///
127127
/// # Safety
128-
/// Can only be used once per boot.
128+
/// Can only be used once per boot. **Must be called by the primary core.**
129129
#[expect(clippy::needless_pass_by_value)]
130130
pub unsafe fn bootstrap(
131131
linear_offset: u64,
@@ -138,15 +138,15 @@ impl<M: Into<oro_boot_protocol::MemoryMapEntry> + Clone, I: Iterator<Item = M> +
138138
// SAFETY: this is only to be called once.
139139
unsafe { oro_mem::translate::set_global_map_offset(linear_offset) };
140140

141-
let mut pfa = pfa::PrebootPfa::new(iter, linear_offset);
142-
let supervisor_space = target::AddressSpace::new_supervisor_space_in(&mut pfa)
141+
let pfa = pfa::UnsafePrebootPfa::new(iter, linear_offset);
142+
let supervisor_space = target::AddressSpace::new_supervisor_space_in(&pfa)
143143
.ok_or(Error::MapError(MapError::OutOfMemory))?;
144144

145145
let (kernel_entry, scanner) =
146-
self::map::map_kernel_to_supervisor_space(&mut pfa, &supervisor_space, &kernel)?;
146+
self::map::map_kernel_to_supervisor_space(&pfa, &supervisor_space, &kernel)?;
147147

148148
// Map in a stack
149-
let stack_addr = self::map::map_kernel_stack(&mut pfa, &supervisor_space, stack_pages)?;
149+
let stack_addr = self::map::map_kernel_stack(&pfa, &supervisor_space, stack_pages)?;
150150

151151
Ok(Self {
152152
pfa,
@@ -210,8 +210,8 @@ impl<M: Into<oro_boot_protocol::MemoryMapEntry> + Clone, I: Iterator<Item = M> +
210210
let mut last_phys = 0;
211211

212212
for mut item in iter {
213-
let (phys, data) = self
214-
.pfa
213+
// SAFETY: We're only accessing the inner PFA for a short moment.
214+
let (phys, data) = unsafe { self.pfa.get_mut() }
215215
.allocate::<T>()
216216
.ok_or(Error::MapError(MapError::OutOfMemory))?;
217217
item.set_next(last_phys);
@@ -234,8 +234,9 @@ impl<M: Into<oro_boot_protocol::MemoryMapEntry> + Clone, I: Iterator<Item = M> +
234234
unsafe { self::target::prepare_transfer(&mut self.supervisor_space, &mut self.pfa)? };
235235

236236
// Consume the PFA and write out the memory map.
237-
let first_entry = self
238-
.pfa
237+
// SAFETY: We're only accessing the PFA for a short moment.
238+
let pfa = self.pfa.into_inner();
239+
let first_entry = pfa
239240
.write_memory_map()
240241
.ok_or(Error::MapError(MapError::OutOfMemory))?;
241242

@@ -246,8 +247,8 @@ impl<M: Into<oro_boot_protocol::MemoryMapEntry> + Clone, I: Iterator<Item = M> +
246247
);
247248

248249
// Perform the transfer
249-
// SAFETY(qix-): We can assume the kernel entry point is valid given that it's
250-
// SAFETY(qix-): coming from the ELF and validated by the mapper.
250+
// SAFETY: We can assume the kernel entry point is valid given that it's
251+
// SAFETY: coming from the ELF and validated by the mapper.
251252
unsafe {
252253
self::target::transfer(
253254
&mut self.supervisor_space,

0 commit comments

Comments
 (0)