Notify schemes when mmaps are unmapped.
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user