diff --git a/src/scheme/memory.rs b/src/scheme/memory.rs index ec00306b8c..8346a2affb 100644 --- a/src/scheme/memory.rs +++ b/src/scheme/memory.rs @@ -90,9 +90,11 @@ impl MemoryScheme { return Err(Error::new(EOPNOTSUPP)); } + let fixed = map.flags.contains(MapFlags::MAP_FIXED) || map.flags.contains(MapFlags::MAP_FIXED_NOREPLACE); + let page = addr_space.acquire_write().mmap( addr_space, - (map.address != 0).then_some(span.base), + (map.address != 0 || fixed).then_some(span.base), page_count, map.flags, &mut notify_files, diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index 2aa950b4bb..eec51138da 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -502,7 +502,9 @@ impl KernelScheme for ProcScheme { PageSpan::validate_nonempty(VirtualAddress::new(map.offset), map.size) .ok_or(Error::new(EINVAL))?; - let requested_dst_base = (map.address != 0).then_some(requested_dst_page); + let fixed = map.flags.contains(MapFlags::MAP_FIXED) + || map.flags.contains(MapFlags::MAP_FIXED_NOREPLACE); + let requested_dst_base = (map.address != 0 || fixed).then_some(requested_dst_page); let mut src_addr_space = addrspace.acquire_write(); diff --git a/src/scheme/user.rs b/src/scheme/user.rs index 5f6d9c1ccd..d2d404e068 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -1234,7 +1234,10 @@ impl UserInner { if map.address % PAGE_SIZE != 0 { return Err(Error::new(EINVAL)); }; - let dst_base = (map.address != 0) + + let fixed = map.flags.contains(MapFlags::MAP_FIXED) + || map.flags.contains(MapFlags::MAP_FIXED_NOREPLACE); + let dst_base = (map.address != 0 || fixed) .then_some(Page::containing_address(VirtualAddress::new(map.address))); if map.offset % PAGE_SIZE != 0 { diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index 5ce467b46f..6fc449852f 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -744,7 +744,9 @@ pub fn mremap( let addr_space = AddrSpace::current()?; let src_span = PageSpan::new(old_base, old_size.div_ceil(PAGE_SIZE)); let new_page_count = new_size.div_ceil(PAGE_SIZE); - let requested_dst_base = Some(new_base).filter(|_| new_address != 0); + let fixed = map_flags.contains(MapFlags::MAP_FIXED) + || map_flags.contains(MapFlags::MAP_FIXED_NOREPLACE); + let requested_dst_base = (new_address != 0 || fixed).then_some(new_base); if mremap_flags.contains(MremapFlags::KEEP_OLD) { // TODO: This is a hack! Find a better interface for replacing this, perhaps a capability