if (!(flags & FROM_KERNEL)) {
if(copy_msg_from_user(caller_ptr, m_ptr, &dst_ptr->p_delivermsg))
return EFAULT;
- } else
+ } else {
dst_ptr->p_delivermsg = *m_ptr;
+ IPC_STATUS_ADD(dst_ptr,
+ IPC_STATUS_FLAGS(IPC_FLG_MSG_FROM_KERNEL));
+ }
+
dst_ptr->p_delivermsg.m_source = caller_ptr->p_endpoint;
dst_ptr->p_misc_flags |= MF_DELIVERMSG;
if (!(flags & FROM_KERNEL)) {
if(copy_msg_from_user(caller_ptr, m_ptr, &caller_ptr->p_sendmsg))
return EFAULT;
- } else
+ } else {
caller_ptr->p_sendmsg = *m_ptr;
+ /*
+ * we need to remember that this message is from kernel so we
+ * can set the delivery status flags when the message is
+ * actually delivered
+ */
+ caller_ptr->p_misc_flags |= MF_SENDING_FROM_KERNEL;
+ }
RTS_SET(caller_ptr, RTS_SENDING);
caller_ptr->p_sendto_e = dst_e;
call = ((*xpp)->p_misc_flags & MF_REPLY_PEND ? SENDREC : SEND);
IPC_STATUS_ADD(caller_ptr, IPC_STATUS_CALL_TO(call));
+
+ /*
+ * if the message is originaly from the kernel on behalf of this
+ * process, we must send the status flags accordingly
+ */
+ if ((*xpp)->p_misc_flags & MF_SENDING_FROM_KERNEL) {
+ IPC_STATUS_ADD(caller_ptr,
+ IPC_STATUS_FLAGS(IPC_FLG_MSG_FROM_KERNEL));
+ /* we can clean the flag now, not need anymore */
+ (*xpp)->p_misc_flags &= ~MF_SENDING_FROM_KERNEL;
+ }
if ((*xpp)->p_misc_flags & MF_SIG_DELAY)
sig_delay_done(*xpp);
#endif
FORWARD _PROTOTYPE( void sendreply, (void) );
-FORWARD _PROTOTYPE( void get_work, (void) );
FORWARD _PROTOTYPE( int get_nice_value, (int queue) );
FORWARD _PROTOTYPE( void handle_fs_reply, (void) );
/* This is PM's main loop- get work and do it, forever and forever. */
while (TRUE) {
- get_work(); /* wait for an PM system call */
+ int ipc_status;
+
+ /* Wait for the next message and extract useful information from it. */
+ if (sef_receive_status(ANY, &m_in, &ipc_status) != OK)
+ panic("PM sef_receive error");
+ who_e = m_in.m_source; /* who sent the message */
+ if(pm_isokendpt(who_e, &who_p) != OK)
+ panic("PM got message from invalid endpoint: %d", who_e);
+ call_nr = m_in.m_type; /* system call number */
+
+ /* Process slot of caller. Misuse PM's own process slot if the kernel is
+ * calling. This can happen in case of synchronous alarms (CLOCK) or or
+ * event like pending kernel signals (SYSTEM).
+ */
+ mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p];
+ if(who_p >= 0 && mp->mp_endpoint != who_e) {
+ panic("PM endpoint number out of sync with source: %d",
+ mp->mp_endpoint);
+ }
/* Drop delayed calls from exiting processes. */
if (mp->mp_flags & EXITING)
continue;
/* Check for system notifications first. Special cases. */
- if (is_notify(call_nr)) {
+ if (is_ipc_notify(ipc_status)) {
switch(who_p) {
case CLOCK:
pm_expire_timers(m_in.NOTIFY_TIMESTAMP);
break;
case SCHEDULING_NO_QUANTUM:
/* This message was sent from the kernel, don't reply */
- do_noquantum();
+ if (IPC_STATUS_FLAGS_TEST(ipc_status, IPC_FLG_MSG_FROM_KERNEL)) {
+ do_noquantum();
+ } else {
+ printf("PM: process %s/%d faked SCHEDULING_NO_QUANTUM "
+ "message!\n",
+ mp->mp_name, mp->mp_endpoint);
+ }
continue;
default:
/* Else, if the system call number is valid, perform the
return r;
}
-/*===========================================================================*
- * get_work *
- *===========================================================================*/
-PRIVATE void get_work()
-{
-/* Wait for the next message and extract useful information from it. */
- if (sef_receive(ANY, &m_in) != OK)
- panic("PM sef_receive error");
- who_e = m_in.m_source; /* who sent the message */
- if(pm_isokendpt(who_e, &who_p) != OK)
- panic("PM got message from invalid endpoint: %d", who_e);
- call_nr = m_in.m_type; /* system call number */
-
- /* Process slot of caller. Misuse PM's own process slot if the kernel is
- * calling. This can happen in case of synchronous alarms (CLOCK) or or
- * event like pending kernel signals (SYSTEM).
- */
- mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p];
- if(who_p >= 0 && mp->mp_endpoint != who_e) {
- panic("PM endpoint number out of sync with source: %d", mp->mp_endpoint);
- }
-}
-
/*===========================================================================*
* setreply *
*===========================================================================*/