Skip to content

Commit 0e904b3

Browse files
authored
Merge pull request #2008 from hermit-os/mman-prot_none
fix(mman): don't deallocate PROT_NONE frames
2 parents e747b5a + 0cc67df commit 0e904b3

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

src/syscalls/mman.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use core::ffi::{c_int, c_void};
22

33
use align_address::Align;
4-
use free_list::{PageLayout, PageRange};
4+
use free_list::{FreeList, PageLayout, PageRange};
5+
use hermit_sync::SpinMutex;
56
use memory_addresses::{PhysAddr, VirtAddr};
67

78
use crate::arch;
@@ -26,6 +27,8 @@ bitflags! {
2627
}
2728
}
2829

30+
static PROT_NONE_FREE_LIST: SpinMutex<FreeList<16>> = SpinMutex::new(FreeList::new());
31+
2932
/// Creates a new virtual memory mapping of the `size` specified with
3033
/// protection bits specified in `prot_flags`.
3134
#[hermit_macro::system(errno)]
@@ -37,6 +40,9 @@ pub extern "C" fn sys_mmap(size: usize, prot_flags: MemoryProtection, ret: &mut
3740
let virtual_address = VirtAddr::from(page_range.start());
3841
if prot_flags.is_empty() {
3942
*ret = virtual_address.as_mut_ptr();
43+
unsafe {
44+
PROT_NONE_FREE_LIST.lock().deallocate(page_range).unwrap();
45+
}
4046
return 0;
4147
}
4248
let frame_layout = PageLayout::from_size(size).unwrap();
@@ -67,6 +73,11 @@ pub extern "C" fn sys_mmap(size: usize, prot_flags: MemoryProtection, ret: &mut
6773
pub extern "C" fn sys_munmap(ptr: *mut u8, size: usize) -> i32 {
6874
let virtual_address = VirtAddr::from_ptr(ptr);
6975
let size = size.align_up(BasePageSize::SIZE as usize);
76+
let page_range = PageRange::from_start_len(virtual_address.as_usize(), size).unwrap();
77+
78+
if PROT_NONE_FREE_LIST.lock().allocate_at(page_range).is_ok() {
79+
return 0;
80+
}
7081

7182
if let Some(physical_address) = arch::mm::paging::virtual_to_physical(virtual_address) {
7283
arch::mm::paging::unmap::<BasePageSize>(
@@ -75,16 +86,15 @@ pub extern "C" fn sys_munmap(ptr: *mut u8, size: usize) -> i32 {
7586
);
7687
debug!("Unmapping {virtual_address:X} ({size}) -> {physical_address:X}");
7788

78-
let range = PageRange::from_start_len(physical_address.as_u64() as usize, size).unwrap();
79-
if let Err(_err) = unsafe { PHYSICAL_FREE_LIST.lock().deallocate(range) } {
80-
// FIXME: return EINVAL instead, once wasmtime can handle it
81-
error!("Unable to deallocate {range:?}");
89+
let frame_range =
90+
PageRange::from_start_len(physical_address.as_u64() as usize, size).unwrap();
91+
unsafe {
92+
PHYSICAL_FREE_LIST.lock().deallocate(frame_range).unwrap();
8293
}
8394
}
8495

85-
let range = PageRange::from_start_len(virtual_address.as_usize(), size).unwrap();
8696
unsafe {
87-
KERNEL_FREE_LIST.lock().deallocate(range).unwrap();
97+
KERNEL_FREE_LIST.lock().deallocate(page_range).unwrap();
8898
}
8999

90100
0

0 commit comments

Comments
 (0)