Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/mm/physicalmem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use memory_addresses::{PhysAddr, VirtAddr};

#[cfg(target_arch = "x86_64")]
use crate::arch::mm::paging::PageTableEntryFlagsExt;
use crate::arch::mm::paging::{self, HugePageSize, PageSize, PageTableEntryFlags};
use crate::arch::mm::paging::{self, HugePageSize, LargePageSize, PageSize, PageTableEntryFlags};
use crate::env;
use crate::mm::device_alloc::DeviceAlloc;
use crate::mm::{PageRangeAllocator, PageRangeBox};
Expand All @@ -18,6 +18,13 @@ static PHYSICAL_FREE_LIST: InterruptTicketMutex<FreeList<16>> =
InterruptTicketMutex::new(FreeList::new());
pub static TOTAL_MEMORY: AtomicUsize = AtomicUsize::new(0);

/// When claiming physical memory, ignore all addresses below this one.
/// This ensures we don't accidentally clash with hardcoded low addresses, such
/// as `SMP_BOOT_CODE_ADDRESS` in x86_64 with SMP enabled.
///
/// We use a 2MIB size for now, but this is arbitrary, and could likely be lowered.
const MIN_PHYSICAL_ADDRESS: u64 = LargePageSize::SIZE;

pub struct FrameAlloc;

impl PageRangeAllocator for FrameAlloc {
Expand Down Expand Up @@ -70,7 +77,7 @@ pub unsafe fn map_frame_range(frame_range: PageRange) {
type IdentityPageSize = HugePageSize;
}
target_arch = "x86_64" => {
type IdentityPageSize = paging::LargePageSize;
type IdentityPageSize = LargePageSize;
}
}

Expand Down Expand Up @@ -132,6 +139,18 @@ unsafe fn detect_from_fdt() -> Result<(), ()> {
VirtAddr::new(start_address)
};

let start_address = if start_address.as_u64() < MIN_PHYSICAL_ADDRESS {
// Do not free any address in the real mode addressable range
// We have hardcoded some stuff in the kernel (e.g. SMP_BOOT_CODE_ADDRESS and friends),
// so we don't want to accidentally overwrite them by having an allocation on top
if size <= MIN_PHYSICAL_ADDRESS {
continue;
}
VirtAddr::new(MIN_PHYSICAL_ADDRESS)
} else {
start_address
};

let range = PageRange::new(start_address.as_usize(), end_address as usize).unwrap();
unsafe {
FrameAlloc::deallocate(range);
Expand Down
Loading