Esempio n. 1
0
File: proc.c Progetto: egall/OS-code
/*===========================================================================*
 *				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);
}
Esempio n. 2
0
/*===========================================================================*
 *				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);
}