/*===========================================================================* * QueueMess * *===========================================================================*/ PRIVATE int QueueMess(endpoint_t ep, vir_bytes msg_lin, struct proc *dst) { int k; phys_bytes addr; NOREC_ENTER(queuemess); /* Queue a message from the src process (in memory) to the dst * process (using dst process table entry). Do actual copy to * kernel here; it's an error if the copy fails into kernel. */ vmassert(!(dst->p_misc_flags & MF_DELIVERMSG)); vmassert(dst->p_delivermsg_lin); vmassert(isokendpt(ep, &k)); #if 0 if(INMEMORY(dst)) { PHYS_COPY_CATCH(msg_lin, dst->p_delivermsg_lin, sizeof(message), addr); if(!addr) { PHYS_COPY_CATCH(vir2phys(&ep), dst->p_delivermsg_lin, sizeof(ep), addr); if(!addr) { NOREC_RETURN(queuemess, OK); } } } #endif PHYS_COPY_CATCH(msg_lin, vir2phys(&dst->p_delivermsg), sizeof(message), addr); if(addr) { NOREC_RETURN(queuemess, EFAULT); } dst->p_delivermsg.m_source = ep; dst->p_misc_flags |= MF_DELIVERMSG; NOREC_RETURN(queuemess, OK); }
/*===========================================================================* * lin_lin_copy * *===========================================================================*/ PRIVATE int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr, struct proc *dstproc, vir_bytes dstlinaddr, vir_bytes bytes) { u32_t addr; int procslot; NOREC_ENTER(linlincopy); vmassert(vm_running); vmassert(nfreepdes >= 3); vmassert(ptproc); vmassert(proc_ptr); vmassert(read_cr3() == ptproc->p_seg.p_cr3); procslot = ptproc->p_nr; vmassert(procslot >= 0 && procslot < I386_VM_DIR_ENTRIES); while(bytes > 0) { phys_bytes srcptr, dstptr; vir_bytes chunk = bytes; int srcpde, dstpde; int srctype, dsttype; /* Set up 4MB ranges. */ inusepde = NOPDE; CREATEPDE(srcproc, srcptr, srclinaddr, chunk, bytes, srcpde, srctype); CREATEPDE(dstproc, dstptr, dstlinaddr, chunk, bytes, dstpde, dsttype); /* Copy pages. */ PHYS_COPY_CATCH(srcptr, dstptr, chunk, addr); DONEPDE(srcpde); DONEPDE(dstpde); if(addr) { /* If addr is nonzero, a page fault was caught. */ if(addr >= srcptr && addr < (srcptr + chunk)) { WIPEPDE(srcpde); WIPEPDE(dstpde); NOREC_RETURN(linlincopy, EFAULT_SRC); } if(addr >= dstptr && addr < (dstptr + chunk)) { WIPEPDE(srcpde); WIPEPDE(dstpde); NOREC_RETURN(linlincopy, EFAULT_DST); } minix_panic("lin_lin_copy fault out of range", NO_NUM); /* Not reached. */ NOREC_RETURN(linlincopy, EFAULT); } WIPEPDE(srcpde); WIPEPDE(dstpde); /* Update counter and addresses for next iteration, if any. */ bytes -= chunk; srclinaddr += chunk; dstlinaddr += chunk; } NOREC_RETURN(linlincopy, OK); }