Notify schemes when mmaps are unmapped.

This commit is contained in:
4lDO2
2023-07-12 15:33:18 +02:00
parent 02f04752e8
commit d3ecedefd9
5 changed files with 34 additions and 9 deletions
-2
View File
@@ -34,8 +34,6 @@ pub fn map_flags(page_flags: PageFlags<RmmA>) -> MapFlags {
let mut flags = MapFlags::PROT_READ;
if page_flags.has_write() { flags |= MapFlags::PROT_WRITE; }
if page_flags.has_execute() { flags |= MapFlags::PROT_EXEC; }
// TODO: MAP_SHARED/MAP_PRIVATE (requires that grants keep track of what they borrow and if
// they borrow shared or CoW).
flags
}
+2 -4
View File
@@ -592,7 +592,7 @@ impl Scheme for ProcScheme {
match handle.info.operation {
Operation::AwaitingAddrSpaceChange { new, new_sp, new_ip } => {
stop_context(handle.info.pid, |context: &mut Context| unsafe {
let prev_addr_space = stop_context(handle.info.pid, |context: &mut Context| unsafe {
if let Some(saved_regs) = ptrace::regs_for_mut(context) {
#[cfg(target_arch = "aarch64")]
{
@@ -615,9 +615,7 @@ impl Scheme for ProcScheme {
context.clone_entry = Some([new_ip, new_sp]);
}
let _prev_addr_space = context.set_addr_space(new);
Ok(())
Ok(context.set_addr_space(new))
})?;
let _ = ptrace::send_event(crate::syscall::ptrace_event!(PTRACE_EVENT_ADDRSPACE_SWITCH, 0));
}
+20 -1
View File
@@ -543,10 +543,15 @@ impl UserInner {
};
let page_count_nz = NonZeroUsize::new(page_count).expect("already validated map.size != 0");
let dst_base = dst_addr_space.write().mmap(dst_base, page_count_nz, map.flags | MAP_FIXED_NOREPLACE, &mut Vec::new(), |dst_base, flags, mapper, flusher| {
let mut notify_files = Vec::new();
let dst_base = dst_addr_space.write().mmap(dst_base, page_count_nz, map.flags | MAP_FIXED_NOREPLACE, &mut notify_files, |dst_base, flags, mapper, flusher| {
Grant::borrow_fmap(PageSpan::new(dst_base, page_count), page_flags(map.flags), file_ref, src, mapper, flusher)
})?;
for map in notify_files {
let _ = map.unmap();
}
Ok(dst_base.start_address().data())
}
}
@@ -829,6 +834,20 @@ impl KernelScheme for UserScheme {
inner.fmap_inner(Arc::clone(addr_space), file, map)
}
fn kfunmap(&self, number: usize, offset: usize, size: usize) -> Result<()> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let res = inner.call_extended(CallerCtx {
pid: context::context_id().into(),
uid: offset as u32,
gid: (offset >> 32) as u32,
}, [KSMSG_MUNMAP, number, size, 0])?;
match res {
Response::Regular(_) => Ok(()),
Response::Fd(_) => Err(Error::new(EIO)),
}
}
fn as_user_inner(&self) -> Option<Result<Arc<UserInner>>> {
Some(self.inner.upgrade().ok_or(Error::new(ENODEV)))
+11 -1
View File
@@ -387,6 +387,12 @@ pub fn fstat(fd: FileHandle, user_buf: UserSliceWo) -> Result<usize> {
}
pub fn funmap(virtual_address: usize, length: usize) -> Result<usize> {
// Partial lengths in funmap are allowed according to POSIX, but not particularly meaningful;
// since the memory needs to SIGSEGV if later read, the entire page needs to disappear.
//
// Thus, while (temporarily) allowing unaligned lengths for compatibility, aligning the length
// should be done by libc.
let length_aligned = length.next_multiple_of(PAGE_SIZE);
if length != length_aligned {
log::warn!("funmap passed length {:#x} instead of {:#x}", length, length_aligned);
@@ -395,7 +401,11 @@ pub fn funmap(virtual_address: usize, length: usize) -> Result<usize> {
let addr_space = Arc::clone(context::current()?.read().addr_space()?);
let span = PageSpan::validate_nonempty(VirtualAddress::new(virtual_address), length_aligned).ok_or(Error::new(EINVAL))?;
let unpin = false;
addr_space.write().munmap(span, unpin)?;
let notify = addr_space.write().munmap(span, unpin)?;
for map in notify {
let _ = map.unmap();
}
Ok(0)
}
+1 -1
Submodule syscall updated: ff149946c0...ed28083b73