Skip to content

Commit 2e55501

Browse files
committed
stack allocation: move to end of heap and reserve pages
1 parent 2f73167 commit 2e55501

1 file changed

Lines changed: 9 additions & 6 deletions

File tree

src/mm/stack_alloc.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,21 @@ use crate::arch::mm::paging;
1010
#[cfg(target_arch = "x86_64")]
1111
use crate::arch::mm::paging::PageTableEntryFlagsExt;
1212
use crate::arch::mm::paging::{BasePageSize, HugePageSize, PageSize, PageTableEntryFlags};
13-
use crate::mm::{FrameAlloc, PageRangeAllocator, virtualmem};
13+
use crate::mm::{FrameAlloc, PageAlloc, PageRangeAllocator, virtualmem};
1414

1515
static MAX_STACK_SIZE: usize = HugePageSize::SIZE as usize;
16-
static STACK_REGION_END: usize = virtualmem::kernel_heap_end().as_usize().div_ceil(2);
16+
/// End of the stack. Ideally, we'd take the heap end, but in x86_64 this causes ptr computation
17+
/// problems
18+
static STACK_REGION_END: usize = virtualmem::kernel_heap_end().as_usize() + 1 - MAX_STACK_SIZE;
1719
static STACK_REGION_START: usize = STACK_REGION_END - MAX_STACK_SIZE;
1820
static STACK_FREE_LIST: Lazy<InterruptTicketMutex<FreeList<16>>> = Lazy::new(|| {
1921
// Remove all mappings in the stack region range
2022
let start = VirtAddr::new(STACK_REGION_START as u64);
2123
let count = MAX_STACK_SIZE / HugePageSize::SIZE as usize;
24+
let range = PageRange::new(STACK_REGION_START, STACK_REGION_END).unwrap();
25+
26+
// Take the pages from the allocator
27+
PageAlloc::allocate_at(range).expect("failed to reserve stack area");
2228

2329
paging::unmap::<HugePageSize>(start, count);
2430

@@ -64,12 +70,9 @@ pub fn allocate_stack(requested_size: usize) -> StackAllocation {
6470
let phys_addr_start = PhysAddr::new(frame_range.start() as u64);
6571
let virt_addr_start = VirtAddr::new(stack_start as u64);
6672

67-
// Remove identity mapping if present
68-
paging::unmap::<BasePageSize>(virt_addr_start, pages_with_guard);
69-
7073
// Map first page to a disabled page full of a marker, then unmap it
7174
let mut flags = PageTableEntryFlags::empty();
72-
flags.normal().writable();
75+
flags.normal().writable().execute_disable();
7376
paging::map::<BasePageSize>(virt_addr_start, phys_addr_start, 1, flags);
7477
unsafe {
7578
let marker_pos = virt_addr_start.add(BasePageSize::SIZE as usize - size_of::<u64>());

0 commit comments

Comments
 (0)