break; \
}
-/*===========================================================================*
- * 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.
- */
- assert(!(dst->p_misc_flags & MF_DELIVERMSG));
- assert(dst->p_delivermsg_lin);
- assert(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);
-}
-
/*===========================================================================*
* idle *
*===========================================================================*/
*/
register struct proc *dst_ptr;
register struct proc **xpp;
- struct proc *msg_proc_ptr; /* Proc in which the message can be found */
int dst_p;
- phys_bytes linaddr;
- vir_bytes addr;
- int r;
-
- /* The kernel can send messages on behalf of other processes. In that case
- we need to pass a pointer to the kernel, not the caller_ptr, to
- umap_local as the kernel contains the message to be sent. */
- if (flags & FROM_KERNEL) {
- msg_proc_ptr = proc_addr(KERNEL);
- }
- else {
- msg_proc_ptr = caller_ptr;
- }
-
- if(!(linaddr = umap_local(msg_proc_ptr, D, (vir_bytes) m_ptr,
- sizeof(message)))) {
- return EFAULT;
- }
dst_p = _ENDPOINT_P(dst_e);
dst_ptr = proc_addr(dst_p);
int call;
/* Destination is indeed waiting for this message. */
assert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));
- if((r=QueueMess(caller_ptr->p_endpoint, linaddr, dst_ptr)) != OK)
- return r;
+
+ if (!(flags & FROM_KERNEL)) {
+ if(copy_msg_from_user(caller_ptr, m_ptr, &dst_ptr->p_delivermsg))
+ return EFAULT;
+ } else
+ dst_ptr->p_delivermsg = *m_ptr;
+ dst_ptr->p_delivermsg.m_source = caller_ptr->p_endpoint;
+ dst_ptr->p_misc_flags |= MF_DELIVERMSG;
+
call = (caller_ptr->p_misc_flags & MF_REPLY_PEND ? SENDREC
: (flags & NON_BLOCKING ? SENDNB : SEND));
IPC_STATUS_ADD(dst_ptr, IPC_STATUS_CALL_TO(call));
}
/* Destination is not waiting. Block and dequeue caller. */
- PHYS_COPY_CATCH(linaddr, vir2phys(&caller_ptr->p_sendmsg),
- sizeof(message), addr);
+ if (!(flags & FROM_KERNEL)) {
+ if(copy_msg_from_user(caller_ptr, m_ptr, &caller_ptr->p_sendmsg))
+ return EFAULT;
+ } else
+ caller_ptr->p_sendmsg = *m_ptr;
- if(addr) { return EFAULT; }
RTS_SET(caller_ptr, RTS_SENDING);
caller_ptr->p_sendto_e = dst_e;
* is available block the caller.
*/
register struct proc **xpp;
- message m;
sys_map_t *map;
bitchunk_t *chunk;
int i, r, src_id, src_proc_nr, src_p;
*chunk &= ~(1 << i); /* no longer pending */
/* Found a suitable source, deliver the notification message. */
- BuildNotifyMessage(&m, src_proc_nr, caller_ptr); /* assemble message */
hisep = proc_addr(src_proc_nr)->p_endpoint;
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
assert(src_e == ANY || hisep == src_e);
- if((r=QueueMess(hisep, vir2phys(&m), caller_ptr)) != OK) {
- panic("mini_receive: local QueueMess failed");
- }
+
+ /* assemble message */
+ BuildNotifyMessage(&caller_ptr->p_delivermsg, src_proc_nr, caller_ptr);
+ caller_ptr->p_delivermsg.m_source = hisep;
+ caller_ptr->p_misc_flags |= MF_DELIVERMSG;
+
IPC_STATUS_ADD(caller_ptr, IPC_STATUS_CALL_TO(NOTIFY));
- return(OK); /* report success */
+
+ return(OK);
}
}
/* Found acceptable message. Copy it and update status. */
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
- QueueMess((*xpp)->p_endpoint,
- vir2phys(&(*xpp)->p_sendmsg), caller_ptr);
+ caller_ptr->p_delivermsg = (*xpp)->p_sendmsg;
+ caller_ptr->p_delivermsg.m_source = (*xpp)->p_endpoint;
+ caller_ptr->p_misc_flags |= MF_DELIVERMSG;
+ RTS_UNSET(*xpp, RTS_SENDING);
+
call = ((*xpp)->p_misc_flags & MF_REPLY_PEND ? SENDREC : SEND);
IPC_STATUS_ADD(caller_ptr, IPC_STATUS_CALL_TO(call));
if ((*xpp)->p_misc_flags & MF_SIG_DELAY)
sig_delay_done(*xpp);
- RTS_UNSET(*xpp, RTS_SENDING);
+
*xpp = (*xpp)->p_q_link; /* remove from queue */
return(OK); /* report success */
}
{
register struct proc *dst_ptr;
int src_id; /* source id for late delivery */
- message m; /* the notification message */
- int r;
int dst_p;
if (!isokendpt(dst_e, &dst_p)) {
* message and deliver it. Copy from pseudo-source HARDWARE, since the
* message is in the kernel's address space.
*/
- BuildNotifyMessage(&m, proc_nr(caller_ptr), dst_ptr);
assert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));
- if((r=QueueMess(caller_ptr->p_endpoint, vir2phys(&m), dst_ptr)) != OK) {
- panic("mini_notify: local QueueMess failed");
- }
+
+ BuildNotifyMessage(&dst_ptr->p_delivermsg, proc_nr(caller_ptr), dst_ptr);
+ dst_ptr->p_delivermsg.m_source = caller_ptr->p_endpoint;
+ dst_ptr->p_misc_flags |= MF_DELIVERMSG;
+
IPC_STATUS_ADD(dst_ptr, IPC_STATUS_CALL_TO(NOTIFY));
RTS_UNSET(dst_ptr, RTS_RECEIVING);
+
return(OK);
}
struct priv *privp;
asynmsg_t tabent;
const vir_bytes table_v = (vir_bytes) table;
- vir_bytes linaddr;
privp= priv(caller_ptr);
if (!(privp->s_flags & SYS_PROC))
return OK;
}
- if(!(linaddr = umap_local(caller_ptr, D, (vir_bytes) table,
- size * sizeof(*table)))) {
- printf("mini_senda: umap_local failed; 0x%lx len 0x%lx\n",
- table, size * sizeof(*table));
- return EFAULT;
- }
-
/* Limit size to something reasonable. An arbitrary choice is 16
* times the number of process table entries.
*
{
/* Destination is indeed waiting for this message. */
/* Copy message from sender. */
- tabent.result= QueueMess(caller_ptr->p_endpoint,
- linaddr + (vir_bytes) &table[i].msg -
- (vir_bytes) table, dst_ptr);
- if(tabent.result == OK) {
+ if(copy_msg_from_user(caller_ptr, &table[i].msg,
+ &dst_ptr->p_delivermsg))
+ tabent.result = EFAULT;
+ else {
+ dst_ptr->p_delivermsg.m_source = caller_ptr->p_endpoint;
+ dst_ptr->p_misc_flags |= MF_DELIVERMSG;
IPC_STATUS_ADD(dst_ptr,
IPC_STATUS_CALL_TO(SENDA));
RTS_UNSET(dst_ptr, RTS_RECEIVING);
+ tabent.result = OK;
}
A_INSERT(i, result);
asynmsg_t tabent;
vir_bytes table_v;
struct proc *caller_ptr;
- int r;
privp= priv(src_ptr);
/* Deliver message */
A_RETRIEVE(i, msg);
- r = QueueMess(src_ptr->p_endpoint, vir2phys(&tabent.msg),
- dst_ptr);
+ dst_ptr->p_delivermsg = tabent.msg;
+ dst_ptr->p_delivermsg.m_source = src_ptr->p_endpoint;
+ dst_ptr->p_misc_flags |= MF_DELIVERMSG;
- tabent.result= r;
+ tabent.result = OK;
A_INSERT(i, result);
tabent.flags= flags | AMF_DONE;
A_INSERT(i, flags);