33 |
|
|
34 |
#include "i386/i386-regs.h" |
#include "i386/i386-regs.h" |
35 |
|
|
36 |
extern kern_return_t rtmk__demux (struct rtmk_msg_header *msgh_in, |
extern int rtmk_demux (struct rtmk_msg_header *msgh_in, |
37 |
struct rtmk_msg_header *msgh_out); |
struct rtmk_msg_header *msgh_out); |
38 |
|
|
39 |
/* rtmk_msg_trap |
/* rtmk_msg_trap |
40 |
|
|
219 |
|
|
220 |
/* Demuxer for kernel object requests. Request is located in KMSG_IN. |
/* Demuxer for kernel object requests. Request is located in KMSG_IN. |
221 |
Reply will be put in KMSG_OUT. Returns RIG return code. */ |
Reply will be put in KMSG_OUT. Returns RIG return code. */ |
222 |
static kern_return_t |
static int |
223 |
kobject_demux (struct ipc_kmsg *kmsg_in, struct ipc_kmsg *kmsg_out) |
kobject_demux (struct ipc_kmsg *kmsg_in, struct ipc_kmsg *kmsg_out) |
224 |
{ |
{ |
225 |
kern_return_t kr = RIG_RESULT_SUCCESS; |
struct ipc_port *port; |
226 |
|
int err; |
227 |
|
|
228 |
if (kmsg_in->header.msgh_id == EXCEPTION_REPLY_ID) |
if (kmsg_in->header.msgh_id == EXCEPTION_REPLY_ID) |
229 |
exception_handler (kmsg_in); |
{ |
230 |
|
exception_handler (kmsg_in); |
231 |
|
return 0; |
232 |
|
} |
233 |
else |
else |
234 |
kr = rtmk__demux (&kmsg_in->header, &kmsg_out->header); |
err = rtmk_demux (&kmsg_in->header, &kmsg_out->header); |
235 |
return kr; |
|
236 |
|
port = kmsg_in->destination_port; |
237 |
|
switch (RTMK_MSGH_BITS_REMOTE (kmsg_in->header.msgh_bits)) |
238 |
|
{ |
239 |
|
/* It was a normal request to the kernel. Due to the |
240 |
|
crappy interface generator we must destroy the request |
241 |
|
port AND the encoded target port. */ |
242 |
|
case RTMK_MSG_TYPE_COPY_SEND: |
243 |
|
case RTMK_MSG_TYPE_MOVE_SEND: |
244 |
|
case RTMK_MSG_TYPE_MAKE_SEND: |
245 |
|
ipc_port_release_send (port); |
246 |
|
break; |
247 |
|
|
248 |
|
case RTMK_MSG_TYPE_MAKE_SEND_ONCE: |
249 |
|
case RTMK_MSG_TYPE_MOVE_SEND_ONCE: |
250 |
|
ipc_port_release_send_once (port); |
251 |
|
break; |
252 |
|
|
253 |
|
} |
254 |
|
|
255 |
|
return err; |
256 |
} |
} |
257 |
|
|
258 |
|
|
279 |
struct ipc_kmsg *kmsg; |
struct ipc_kmsg *kmsg; |
280 |
kern_return_t kr; |
kern_return_t kr; |
281 |
bool intratask_p; |
bool intratask_p; |
|
|
|
|
#if 0 |
|
|
trace_printf ("options %d sname %d ssize %d rname %d rsize %d", |
|
|
options, send_name, send_size, recv_name, recv_size); |
|
|
#endif |
|
282 |
|
|
283 |
/* If we should receive a message we lookup the port before we do anything |
/* If we should receive a message we lookup the port before we do anything |
284 |
else since it might be needed when sending a message. */ |
else since it might be needed when sending a message. */ |
293 |
kr = ipc_object_lookup (object, recv_name, &entry); |
kr = ipc_object_lookup (object, recv_name, &entry); |
294 |
if (kr != KERN_SUCCESS) |
if (kr != KERN_SUCCESS) |
295 |
{ |
{ |
296 |
|
panic ("1, recv_name is %d", recv_name); |
297 |
ipc_object_unlock (object); |
ipc_object_unlock (object); |
298 |
return kr; |
return kr; |
299 |
} |
} |
324 |
kr = ipc_object_lookup (object, send_name, &entry); |
kr = ipc_object_lookup (object, send_name, &entry); |
325 |
if (kr != KERN_SUCCESS) |
if (kr != KERN_SUCCESS) |
326 |
{ |
{ |
327 |
|
panic ("2 send name is %d", send_name); |
328 |
ipc_object_unlock (object); |
ipc_object_unlock (object); |
329 |
return kr; |
return kr; |
330 |
} |
} |
331 |
|
|
332 |
if (! (entry->ie_bits & RTMK_PORT_TYPE_SEND_RIGHTS)) |
if (! (entry->ie_bits & RTMK_PORT_TYPE_SEND_RIGHTS)) |
333 |
{ |
{ |
334 |
|
panic ("no send rights"); |
335 |
ipc_object_unlock (object); |
ipc_object_unlock (object); |
336 |
return KERN_INVALID_RIGHT; |
return KERN_INVALID_RIGHT; |
337 |
} |
} |
346 |
{ |
{ |
347 |
struct ipc_port *member = port; |
struct ipc_port *member = port; |
348 |
|
|
|
thread_lock_read (&port->pset->lock); |
|
349 |
port = port->pset; |
port = port->pset; |
350 |
thread_lock_unlock (&member->lock); |
thread_lock_unlock (&member->lock); |
351 |
} |
} |
352 |
|
else |
353 |
|
thread_lock_unlock (&port->lock); |
354 |
|
|
355 |
/* Check if we are sending a intra task message. |
/* Check if we are sending a intra task message. |
356 |
If we are, we can optimize at some points. */ |
If we are, we can optimize at some points. */ |
357 |
intratask_p = (port->rcvobject == object); |
intratask_p = (port->rcvobject == object); |
358 |
|
|
359 |
/* Copy message into a kernel message buffer. */ |
/* Copy message into a kernel message buffer. */ |
|
|
|
360 |
kr = ipc_kmsg_copyin (thread->task, msgh, intratask_p, &kmsg); |
kr = ipc_kmsg_copyin (thread->task, msgh, intratask_p, &kmsg); |
361 |
if (kr != KERN_SUCCESS) |
if (kr != KERN_SUCCESS) |
362 |
{ |
{ |
363 |
thread_lock_unlock (&port->lock); |
panic ("EY no copy in"); |
364 |
ipc_object_unlock (object); |
ipc_object_unlock (object); |
365 |
return kr; |
return kr; |
366 |
} |
} |
367 |
|
thread_lock_read (&port->lock); |
368 |
|
|
369 |
/* If we are sending a message to a port in the kernel we |
/* If we are sending a message to a port in the kernel we |
370 |
can now demux the message. ???? sure about that? */ |
can now demux the message. ???? sure about that? */ |
385 |
kr = kobject_demux (kmsg, reply_kmsg); |
kr = kobject_demux (kmsg, reply_kmsg); |
386 |
ipc_object_lock (object); |
ipc_object_lock (object); |
387 |
|
|
388 |
if (LIKELY (kr == RIG_RESULT_NOTIFY)) |
if (LIKELY (kr == 1)) |
389 |
{ |
{ |
390 |
ipc_kmsg_free (kmsg); |
ipc_kmsg_free (kmsg); |
391 |
|
|
433 |
trace_printf ("should enqueue message on remote port queue"); |
trace_printf ("should enqueue message on remote port queue"); |
434 |
assert (0); |
assert (0); |
435 |
} |
} |
436 |
else if (kr == RIG_RESULT_SUCCESS) |
else if (kr == 0) |
437 |
{ |
{ |
438 |
ipc_kmsg_free (kmsg); |
ipc_kmsg_free (kmsg); |
439 |
ipc_kmsg_free (reply_kmsg); |
ipc_kmsg_free (reply_kmsg); |
440 |
kr = KERN_SUCCESS; |
kr = KERN_SUCCESS; |
441 |
} |
} |
|
else if (kr == RIG_RESULT_FAILURE) |
|
|
{ |
|
|
ipc_kmsg_free (kmsg); |
|
|
ipc_kmsg_free (reply_kmsg); |
|
|
kr = KERN_FAILURE; |
|
|
} |
|
442 |
else |
else |
443 |
assert (0); |
assert (0); |
444 |
|
|
570 |
task address/ipc space. Discard message if we fail. */ |
task address/ipc space. Discard message if we fail. */ |
571 |
kmsg = ipc_mqueue_dequeue (& port->mqueue); |
kmsg = ipc_mqueue_dequeue (& port->mqueue); |
572 |
|
|
573 |
|
thread_lock_unlock (&port->lock); |
574 |
kr = ipc_kmsg_copyout (thread->task, msgh, kmsg); |
kr = ipc_kmsg_copyout (thread->task, msgh, kmsg); |
575 |
if (kr != KERN_SUCCESS) |
if (kr != KERN_SUCCESS) |
576 |
{ |
{ |
590 |
if (ipc_tqueue_empty (&port->blocked_threads) == false) |
if (ipc_tqueue_empty (&port->blocked_threads) == false) |
591 |
thread_wakeup ((int) &port->blocked_threads); |
thread_wakeup ((int) &port->blocked_threads); |
592 |
#endif |
#endif |
|
|
|
|
thread_lock_unlock (&port->lock); |
|
593 |
ipc_object_unlock (object); |
ipc_object_unlock (object); |
594 |
} |
} |
595 |
|
|