WIP: Add SYS_MREMAP.
This commit is contained in:
+11
-3
@@ -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
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user