WIP: Add SYS_MREMAP.

This commit is contained in:
4lDO2
2023-07-17 15:54:44 +02:00
parent 2660c3e07a
commit c9aa5ca851
5 changed files with 52 additions and 8 deletions
+11 -3
View File
@@ -316,9 +316,11 @@ impl AddrSpace {
Ok(selected_span.base)
}
pub fn r#move(dst: &mut AddrSpace, src: &mut AddrSpace, src_span: PageSpan, requested_dst_base: Option<Page>, new_flags: MapFlags, notify_files: &mut Vec<UnmapResult>) -> Result<Page> {
pub fn r#move(dst: &mut AddrSpace, mut src_opt: Option<&mut AddrSpace>, src_span: PageSpan, requested_dst_base: Option<Page>, new_flags: MapFlags, notify_files: &mut Vec<UnmapResult>) -> Result<Page> {
let nz_count = NonZeroUsize::new(src_span.count).ok_or(Error::new(EINVAL))?;
let src = src_opt.as_deref_mut().unwrap_or(&mut *dst);
let grant_base = {
let mut conflicts_iter = src.grants.conflicts(src_span);
@@ -342,7 +344,11 @@ impl AddrSpace {
let src_flusher = PageFlushAll::new();
dst.mmap(requested_dst_base, nz_count, new_flags, notify_files, |dst_page, flags, dst_mapper, dst_flusher| middle.transfer(dst_page, flags, &mut src.table.utable, dst_mapper, src_flusher, dst_flusher))
if let Some(src) = src_opt {
dst.mmap(requested_dst_base, nz_count, new_flags, notify_files, |dst_page, flags, dst_mapper, dst_flusher| middle.transfer(dst_page, flags, &mut src.table.utable, Some(dst_mapper), src_flusher, dst_flusher))
} else {
dst.mmap(requested_dst_base, nz_count, new_flags, notify_files, |dst_page, flags, dst_mapper, dst_flusher| middle.transfer(dst_page, flags, dst_mapper, None, src_flusher, dst_flusher))
}
}
}
@@ -1007,7 +1013,7 @@ impl Grant {
})
}
/// Move a grant between two address spaces.
pub fn transfer(mut self, dst_base: Page, flags: PageFlags<RmmA>, src_mapper: &mut PageMapper, dst_mapper: &mut PageMapper, mut src_flusher: impl Flusher<RmmA>, mut dst_flusher: impl Flusher<RmmA>) -> Result<Grant> {
pub fn transfer(mut self, dst_base: Page, flags: PageFlags<RmmA>, src_mapper: &mut PageMapper, mut dst_mapper: Option<&mut PageMapper>, mut src_flusher: impl Flusher<RmmA>, mut dst_flusher: impl Flusher<RmmA>) -> Result<Grant> {
assert!(!self.info.is_pinned());
for src_page in self.span().pages() {
@@ -1021,6 +1027,8 @@ impl Grant {
};
src_flusher.consume(flush);
let dst_mapper = dst_mapper.as_deref_mut().unwrap_or(&mut *src_mapper);
// TODO: Preallocate to handle OOM?
let flush = unsafe { dst_mapper.map_phys(dst_page.start_address(), phys, flags).expect("TODO: OOM") };
dst_flusher.consume(flush);
+1 -1
View File
@@ -692,7 +692,7 @@ impl KernelScheme for ProcScheme {
// TODO: Validate flags
let result_base = if consume {
AddrSpace::r#move(&mut *dst_addr_space, &mut *src_addr_space, src_span, requested_dst_base, map.flags, &mut notify_files)?
AddrSpace::r#move(&mut *dst_addr_space, Some(&mut *src_addr_space), src_span, requested_dst_base, map.flags, &mut notify_files)?
} else {
dst_addr_space.mmap(requested_dst_base, src_page_count, map.flags, &mut notify_files, |dst_page, flags, dst_mapper, flusher| Ok(Grant::borrow(Arc::clone(addrspace), &mut *src_addr_space, src_span.base, dst_page, src_span.count, flags, dst_mapper, flusher, true, true, false)?))?
};
+35 -2
View File
@@ -1,11 +1,12 @@
//! Filesystem syscalls
use alloc::sync::Arc;
use alloc::vec::Vec;
use spin::RwLock;
use crate::context::file::{FileDescriptor, FileDescription};
use crate::context;
use crate::context::memory::PageSpan;
use crate::paging::{PAGE_SIZE, VirtualAddress};
use crate::context::memory::{PageSpan, AddrSpace};
use crate::paging::{PAGE_SIZE, VirtualAddress, Page};
use crate::scheme::{self, FileHandle, OpenResult, current_caller_ctx, KernelScheme, SchemeId};
use crate::syscall::data::Stat;
use crate::syscall::error::*;
@@ -409,3 +410,35 @@ pub fn funmap(virtual_address: usize, length: usize) -> Result<usize> {
Ok(0)
}
pub fn mremap(old_address: usize, old_size: usize, new_address: usize, new_size: usize, flags: MremapFlags) -> Result<usize> {
if old_address % PAGE_SIZE != 0 || old_size % PAGE_SIZE != 0 || new_address % PAGE_SIZE != 0 || new_size % PAGE_SIZE != 0 {
return Err(Error::new(EINVAL));
}
if old_size == 0 || new_size == 0 {
return Err(Error::new(EINVAL));
}
// TODO
if old_size != new_size {
return Err(Error::new(EOPNOTSUPP));
}
let old_base = Page::containing_address(VirtualAddress::new(old_address));
let new_base = Page::containing_address(VirtualAddress::new(new_address));
let mut map_flags = if flags.contains(MremapFlags::FIXED_REPLACE) {
MapFlags::MAP_FIXED
} else if flags.contains(MremapFlags::FIXED) {
MapFlags::MAP_FIXED_NOREPLACE
} else {
MapFlags::empty()
};
let addr_space = AddrSpace::current()?;
let src_span = PageSpan::new(old_base, old_size / PAGE_SIZE);
let requested_dst_base = Some(new_base).filter(|_| new_address != 0);
let base = AddrSpace::r#move(&mut *addr_space.write(), None, src_span, requested_dst_base, map_flags, &mut Vec::new())?;
Ok(base.start_address().data())
}
+4 -1
View File
@@ -4,7 +4,7 @@
extern crate syscall;
use syscall::{EventFlags, EOVERFLOW};
use syscall::{EventFlags, EOVERFLOW, MremapFlags, EINVAL};
pub use self::syscall::{
FloatRegisters,
@@ -169,6 +169,9 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack
SYS_PHYSMAP => physmap(b, c, PhysmapFlags::from_bits_truncate(d)),
SYS_UMASK => umask(b),
SYS_VIRTTOPHYS => virttophys(b),
SYS_MREMAP => mremap(b, c, d, e, MremapFlags::from_bits(f).ok_or(Error::new(EINVAL))?),
_ => Err(Error::new(ENOSYS))
}
}
+1 -1
Submodule syscall updated: ed28083b73...534267760f