Skip to content

Commit e204a56

Browse files
committed
Verify that custom mappings have the required alignment
Also: Add a convenience function for allocating page-aligned mappings.
1 parent 41c5f0a commit e204a56

File tree

1 file changed

+35
-24
lines changed

1 file changed

+35
-24
lines changed

common/src/lib.rs

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -204,20 +204,19 @@ where
204204
.expect("no entry point");
205205
log::info!("Entry point at: {:#x}", entry_point.as_u64());
206206
// create a stack
207-
let stack_start_addr = {
208-
let guard_page_start = mapping_addr(
207+
let stack_start = {
208+
// we need page-alignment because we want a guard page directly below the stack
209+
let guard_page = mapping_addr_page_aligned(
209210
config.mappings.kernel_stack,
210211
// allocate an additional page as a guard page
211212
Size4KiB::SIZE + config.kernel_stack_size,
212-
// we need page-alignment because we want a guard page directly below the stack
213-
Size4KiB::SIZE,
214213
&mut used_entries,
214+
"kernel stack start",
215215
);
216-
guard_page_start + Size4KiB::SIZE
216+
guard_page + 1
217217
};
218-
let stack_end_addr = stack_start_addr + config.kernel_stack_size;
218+
let stack_end_addr = stack_start.start_address() + config.kernel_stack_size;
219219

220-
let stack_start: Page = Page::containing_address(stack_start_addr);
221220
let stack_end = Page::containing_address(stack_end_addr - 1u64);
222221
for page in Page::range_inclusive(stack_start, stack_end) {
223222
let frame = frame_allocator
@@ -266,13 +265,12 @@ where
266265
let framebuffer_start_frame: PhysFrame = PhysFrame::containing_address(framebuffer.addr);
267266
let framebuffer_end_frame =
268267
PhysFrame::containing_address(framebuffer.addr + framebuffer.info.byte_len - 1u64);
269-
let start_page = Page::from_start_address(mapping_addr(
268+
let start_page = mapping_addr_page_aligned(
270269
config.mappings.framebuffer,
271270
u64::from_usize(framebuffer.info.byte_len),
272-
Size4KiB::SIZE,
273271
&mut used_entries,
274-
))
275-
.expect("the framebuffer address must be page aligned");
272+
"framebuffer",
273+
);
276274
for (i, frame) in
277275
PhysFrame::range_inclusive(framebuffer_start_frame, framebuffer_end_frame).enumerate()
278276
{
@@ -293,19 +291,17 @@ where
293291
};
294292
let ramdisk_slice_len = system_info.ramdisk_len;
295293
let ramdisk_slice_start = if let Some(ramdisk_address) = system_info.ramdisk_addr {
296-
let ramdisk_address_start = mapping_addr(
294+
let start_page = mapping_addr_page_aligned(
297295
config.mappings.ramdisk_memory,
298296
system_info.ramdisk_len,
299-
Size4KiB::SIZE,
300297
&mut used_entries,
298+
"ramdisk start",
301299
);
302300
let physical_address = PhysAddr::new(ramdisk_address);
303301
let ramdisk_physical_start_page: PhysFrame<Size4KiB> =
304302
PhysFrame::containing_address(physical_address);
305303
let ramdisk_page_count = (system_info.ramdisk_len - 1) / Size4KiB::SIZE;
306304
let ramdisk_physical_end_page = ramdisk_physical_start_page + ramdisk_page_count;
307-
let start_page = Page::from_start_address(ramdisk_address_start)
308-
.expect("the ramdisk start address must be page aligned");
309305

310306
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
311307
for (i, frame) in
@@ -321,7 +317,7 @@ where
321317
),
322318
};
323319
}
324-
Some(ramdisk_address_start)
320+
Some(start_page.start_address())
325321
} else {
326322
None
327323
};
@@ -335,7 +331,8 @@ where
335331

336332
let size = max_phys.as_u64();
337333
let alignment = Size2MiB::SIZE;
338-
let offset = mapping_addr(mapping, size, alignment, &mut used_entries);
334+
let offset = mapping_addr(mapping, size, alignment, &mut used_entries)
335+
.expect("start addraess for physical memory mapping must be 2MiB-page-aligned");
339336

340337
for frame in PhysFrame::range_inclusive(start_frame, end_frame) {
341338
let page = Page::containing_address(offset + frame.start_address().as_u64());
@@ -465,11 +462,8 @@ where
465462
u64::from_usize(combined.size()),
466463
u64::from_usize(combined.align()),
467464
&mut mappings.used_entries,
468-
);
469-
assert!(
470-
boot_info_addr.is_aligned(u64::from_usize(combined.align())),
471-
"boot info addr is not properly aligned"
472-
);
465+
)
466+
.expect("boot info addr is not properly aligned");
473467

474468
let memory_map_regions_addr = boot_info_addr + memory_regions_offset;
475469
let memory_map_regions_end = boot_info_addr + combined.size();
@@ -614,15 +608,32 @@ struct Addresses {
614608
boot_info: &'static mut BootInfo,
615609
}
616610

611+
fn mapping_addr_page_aligned(
612+
mapping: Mapping,
613+
size: u64,
614+
used_entries: &mut UsedLevel4Entries,
615+
kind: &str,
616+
) -> Page {
617+
match mapping_addr(mapping, size, Size4KiB::SIZE, used_entries) {
618+
Ok(addr) => Page::from_start_address(addr).unwrap(),
619+
Err(addr) => panic!("{kind} address must be page-aligned (is `{addr:?})`"),
620+
}
621+
}
622+
617623
fn mapping_addr(
618624
mapping: Mapping,
619625
size: u64,
620626
alignment: u64,
621627
used_entries: &mut UsedLevel4Entries,
622-
) -> VirtAddr {
623-
match mapping {
628+
) -> Result<VirtAddr, VirtAddr> {
629+
let addr = match mapping {
624630
Mapping::FixedAddress(addr) => VirtAddr::new(addr),
625631
Mapping::Dynamic => used_entries.get_free_address(size, alignment),
632+
};
633+
if addr.is_aligned(alignment) {
634+
Ok(addr)
635+
} else {
636+
Err(addr)
626637
}
627638
}
628639

0 commit comments

Comments
 (0)