static int shared_copy(struct vir_region *vr, struct vir_region *newvr) { struct vmproc *vmp; struct vir_region *srcvr; if(getsrc(vr, &vmp, &srcvr) != OK) panic("copy: original getsrc failed"); shared_setsource(newvr, vr->param.shared.ep, srcvr); return OK; }
/*===========================================================================* * do_remap * *===========================================================================*/ int do_remap(message *m) { int dn, sn; vir_bytes da, sa; size_t size; u32_t flags; struct vir_region *src_region, *vr; struct vmproc *dvmp, *svmp; int r; int readonly; if(m->m_type == VM_REMAP) readonly = 0; else if(m->m_type == VM_REMAP_RO) readonly = 1; else panic("do_remap: can't be"); da = (vir_bytes) m->m_lsys_vm_vmremap.dest_addr; sa = (vir_bytes) m->m_lsys_vm_vmremap.src_addr; size = m->m_lsys_vm_vmremap.size; if (size <= 0) return EINVAL; if ((r = vm_isokendpt((endpoint_t) m->m_lsys_vm_vmremap.destination, &dn)) != OK) return EINVAL; if ((r = vm_isokendpt((endpoint_t) m->m_lsys_vm_vmremap.source, &sn)) != OK) return EINVAL; dvmp = &vmproc[dn]; svmp = &vmproc[sn]; if (!(src_region = map_lookup(svmp, sa, NULL))) return EINVAL; if(src_region->vaddr != sa) { printf("VM: do_remap: not start of region.\n"); return EFAULT; } if (size % VM_PAGE_SIZE) size += VM_PAGE_SIZE - size % VM_PAGE_SIZE; if(size != src_region->length) { printf("VM: do_remap: not size of region.\n"); return EFAULT; } flags = VR_SHARED; if(!readonly) flags |= VR_WRITABLE; if(da) vr = map_page_region(dvmp, da, 0, size, flags, 0, &mem_type_shared); else vr = map_page_region(dvmp, 0, VM_DATATOP, size, flags, 0, &mem_type_shared); if(!vr) { printf("VM: re-map of shared area failed\n"); return ENOMEM; } shared_setsource(vr, svmp->vm_endpoint, src_region); m->m_lsys_vm_vmremap.ret_addr = (void *) vr->vaddr; return OK; }