Switch to a bump allocator for user virtual memory allocations
This commit is contained in:
parent
07393d8c71
commit
d4df5b53ff
@ -32,6 +32,7 @@ pub struct AddressSpace {
|
|||||||
pub alloc_force_user: bool,
|
pub alloc_force_user: bool,
|
||||||
pub mapper: OffsetPageTable<'static>,
|
pub mapper: OffsetPageTable<'static>,
|
||||||
bytes_allocated: AtomicUsize,
|
bytes_allocated: AtomicUsize,
|
||||||
|
bump_base: Page,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for AddressSpace {
|
impl fmt::Debug for AddressSpace {
|
||||||
@ -196,6 +197,7 @@ pub static KERNEL_SPACE: Lazy<ASpaceMutex> = Lazy::new(|| {
|
|||||||
}
|
}
|
||||||
let mut kernel_space = AddressSpace::new_with_addr(table);
|
let mut kernel_space = AddressSpace::new_with_addr(table);
|
||||||
kernel_space.is_kernel = true;
|
kernel_space.is_kernel = true;
|
||||||
|
kernel_space.bump_base = KERNEL_PAGE_RANGE.start;
|
||||||
let l4_virt = VirtAddr::from_ptr(ptr::from_ref(kernel_space.mapper.level_4_table()));
|
let l4_virt = VirtAddr::from_ptr(ptr::from_ref(kernel_space.mapper.level_4_table()));
|
||||||
#[expect(
|
#[expect(
|
||||||
clippy::unwrap_used,
|
clippy::unwrap_used,
|
||||||
@ -251,6 +253,7 @@ impl AddressSpace {
|
|||||||
alloc_force_user: false,
|
alloc_force_user: false,
|
||||||
is_kernel: false,
|
is_kernel: false,
|
||||||
bytes_allocated: AtomicUsize::new(0),
|
bytes_allocated: AtomicUsize::new(0),
|
||||||
|
bump_base: USER_PAGE_RANGE.start,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,6 +382,9 @@ impl AddressSpace {
|
|||||||
PhysFrame::from_start_address_unchecked(PhysAddr::new(0x000F_FFFF_FFFF_F000))
|
PhysFrame::from_start_address_unchecked(PhysAddr::new(0x000F_FFFF_FFFF_F000))
|
||||||
};
|
};
|
||||||
self.check_request_valid(page, num_pages)?;
|
self.check_request_valid(page, num_pages)?;
|
||||||
|
if self.bump_base < page + u64(num_pages) {
|
||||||
|
self.bump_base = page + u64(num_pages);
|
||||||
|
}
|
||||||
#[expect(
|
#[expect(
|
||||||
clippy::arithmetic_side_effects,
|
clippy::arithmetic_side_effects,
|
||||||
reason = "This is the maximum physical frame, so there is no way the subtraction can underflow"
|
reason = "This is the maximum physical frame, so there is no way the subtraction can underflow"
|
||||||
@ -455,6 +461,9 @@ impl AddressSpace {
|
|||||||
flags: PageTableFlags,
|
flags: PageTableFlags,
|
||||||
) -> Result<*mut u8, PagingError> {
|
) -> Result<*mut u8, PagingError> {
|
||||||
self.check_request_valid(page, num_pages)?;
|
self.check_request_valid(page, num_pages)?;
|
||||||
|
if self.bump_base < page + u64(num_pages) {
|
||||||
|
self.bump_base = page + u64(num_pages);
|
||||||
|
}
|
||||||
#[expect(
|
#[expect(
|
||||||
clippy::arithmetic_side_effects,
|
clippy::arithmetic_side_effects,
|
||||||
reason = "check_request_valid guarentees this won't overflow"
|
reason = "check_request_valid guarentees this won't overflow"
|
||||||
@ -544,7 +553,8 @@ impl AddressSpace {
|
|||||||
num_pages: usize,
|
num_pages: usize,
|
||||||
flags: PageTableFlags,
|
flags: PageTableFlags,
|
||||||
) -> Result<*mut u8, PagingError> {
|
) -> Result<*mut u8, PagingError> {
|
||||||
unsafe { self.map_to(self.find_free_pages(num_pages)?, phys_frame, num_pages, flags) }
|
let start_page = self.find_free_pages(num_pages)?;
|
||||||
|
unsafe { self.map_to(start_page, phys_frame, num_pages, flags) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps new virtual pages to new physical memory and returns the starting address.
|
/// Maps new virtual pages to new physical memory and returns the starting address.
|
||||||
@ -555,9 +565,10 @@ impl AddressSpace {
|
|||||||
num_pages: usize,
|
num_pages: usize,
|
||||||
flags: PageTableFlags,
|
flags: PageTableFlags,
|
||||||
) -> Result<*mut u8, PagingError> {
|
) -> Result<*mut u8, PagingError> {
|
||||||
|
let start_page = self.find_free_pages(num_pages)?;
|
||||||
// SAFETY: &mut aliasing is prevented by using free physical frames, and uninitialized
|
// SAFETY: &mut aliasing is prevented by using free physical frames, and uninitialized
|
||||||
// values are prevented by using free virtual pages.
|
// values are prevented by using free virtual pages.
|
||||||
let ptr = unsafe { self.map(self.find_free_pages(num_pages)?, num_pages, flags)? };
|
let ptr = unsafe { self.map(start_page, num_pages, flags)? };
|
||||||
self.record_alloc(num_pages * 4096);
|
self.record_alloc(num_pages * 4096);
|
||||||
Ok(ptr)
|
Ok(ptr)
|
||||||
}
|
}
|
||||||
@ -571,10 +582,10 @@ impl AddressSpace {
|
|||||||
num_pages: usize,
|
num_pages: usize,
|
||||||
flags: PageTableFlags,
|
flags: PageTableFlags,
|
||||||
) -> Result<(*mut u8, u64), PagingError> {
|
) -> Result<(*mut u8, u64), PagingError> {
|
||||||
|
let start_page = self.find_free_pages(num_pages)?;
|
||||||
// SAFETY: &mut aliasing is prevented by using free physical frames, and uninitialized
|
// SAFETY: &mut aliasing is prevented by using free physical frames, and uninitialized
|
||||||
// values are prevented by using free virtual pages.
|
// values are prevented by using free virtual pages.
|
||||||
let ptr =
|
let ptr = unsafe { self.map_cont_phys(start_page, num_pages, flags)? };
|
||||||
unsafe { self.map_cont_phys(self.find_free_pages(num_pages)?, num_pages, flags)? };
|
|
||||||
self.record_alloc(num_pages * 4096);
|
self.record_alloc(num_pages * 4096);
|
||||||
Ok(ptr)
|
Ok(ptr)
|
||||||
}
|
}
|
||||||
@ -602,6 +613,9 @@ impl AddressSpace {
|
|||||||
flags: PageTableFlags,
|
flags: PageTableFlags,
|
||||||
) -> Result<*mut u8, PagingError> {
|
) -> Result<*mut u8, PagingError> {
|
||||||
self.check_request_valid(page, num_pages)?;
|
self.check_request_valid(page, num_pages)?;
|
||||||
|
if self.bump_base < page + u64(num_pages) {
|
||||||
|
self.bump_base = page + u64(num_pages);
|
||||||
|
}
|
||||||
assert!(!self.alloc_force_user);
|
assert!(!self.alloc_force_user);
|
||||||
#[expect(
|
#[expect(
|
||||||
clippy::arithmetic_side_effects,
|
clippy::arithmetic_side_effects,
|
||||||
@ -733,7 +747,8 @@ impl AddressSpace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Finds a range of free pages and returns the starting page
|
/// Finds a range of free pages and returns the starting page
|
||||||
fn find_free_pages(&self, num_pages: usize) -> Result<Page, PagingError> {
|
fn find_free_pages(&mut self, num_pages: usize) -> Result<Page, PagingError> {
|
||||||
|
if self.is_kernel {
|
||||||
if num_pages == 0 {
|
if num_pages == 0 {
|
||||||
return Err(PagingError::PageAllocationFailed);
|
return Err(PagingError::PageAllocationFailed);
|
||||||
}
|
}
|
||||||
@ -760,6 +775,13 @@ impl AddressSpace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
Err(PagingError::PageAllocationFailed)
|
Err(PagingError::PageAllocationFailed)
|
||||||
|
} else if USER_PAGE_RANGE.end - self.bump_base < u64(num_pages) {
|
||||||
|
Err(PagingError::PageAllocationFailed)
|
||||||
|
} else {
|
||||||
|
let old_base = self.bump_base;
|
||||||
|
self.bump_base += u64(num_pages);
|
||||||
|
Ok(old_base)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn record_alloc(&self, size: usize) {
|
pub fn record_alloc(&self, size: usize) {
|
||||||
|
Loading…
Reference in New Issue
Block a user