diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index c5999ab97c9fb863c98d31451fac9e933dfc5086..46164bb8766f91d711bab9343f8de9f17b428b37 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -1258,13 +1258,31 @@ impl KernelScheme for ProcScheme { match info.operation { Operation::GrantHandle { ref description } => { + // Copy Map to user memory + let page_count = 1; // TODO: find size required to store Map + let page = dst_addr_space + .write() + .mmap(None, page_count, MapFlags::PROT_READ, |page, flags, mapper, flusher| { + Ok(Grant::zeroed(page, page_count, flags, mapper, flusher)?) + })?; + + // Write Map using kernel's physmap + let (phys, _flags) = dst_addr_space.read().table.utable.translate(page.start_address()).expect("could not find mapping that was just made"); + unsafe { core::ptr::write(RmmA::phys_to_virt(phys).data() as *mut Map, *map); } + + // Scheme fmap with Map in user memory let (scheme_id, number) = { let description = description.read(); (description.scheme, description.number) }; let scheme = Arc::clone(scheme::schemes().get(scheme_id).ok_or(Error::new(EBADFD))?); - scheme.fmap(number, map) + let res = scheme.fmap(number, unsafe { &*(page.start_address().data() as *const Map) }); + + // Unmap Map user memory + dst_addr_space.write().munmap(page, page_count); + + res } Operation::AddrSpace { ref addrspace } => { if Arc::ptr_eq(addrspace, dst_addr_space) {