2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
34 * Mach Operating System
35 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
36 * All Rights Reserved.
38 * Permission to use, copy, modify and distribute this software and its
39 * documentation is hereby granted, provided that both the copyright
40 * notice and this permission notice appear in all copies of the
41 * software, derivative works or modified versions, and any portions
42 * thereof, and that both notices appear in supporting documentation.
44 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
45 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
46 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48 * Carnegie Mellon requests users of this software to return to
50 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
51 * School of Computer Science
52 * Carnegie Mellon University
53 * Pittsburgh PA 15213-3890
55 * any improvements or extensions that they make and grant Carnegie Mellon
56 * the rights to redistribute these changes.
61 * File: ipc/ipc_kmsg.c
65 * Operations on kernel messages.
70 #include <mach/mach_types.h>
71 #include <mach/boolean.h>
72 #include <mach/kern_return.h>
73 #include <mach/message.h>
74 #include <mach/port.h>
75 #include <mach/vm_map.h>
76 #include <mach/mach_vm.h>
77 #include <mach/vm_statistics.h>
79 #include <kern/kern_types.h>
80 #include <kern/assert.h>
81 #include <kern/ipc_kobject.h>
82 #include <kern/kalloc.h>
83 #include <kern/zalloc.h>
84 #include <kern/processor.h>
85 #include <kern/thread.h>
86 #include <kern/sched_prim.h>
88 #include <kern/misc_protos.h>
89 #include <kern/counters.h>
90 #include <kern/cpu_data.h>
92 #include <vm/vm_map.h>
93 #include <vm/vm_object.h>
94 #include <vm/vm_kern.h>
97 #include <ipc/ipc_types.h>
98 #include <ipc/ipc_entry.h>
99 #include <ipc/ipc_kmsg.h>
100 #include <ipc/ipc_notify.h>
101 #include <ipc/ipc_object.h>
102 #include <ipc/ipc_space.h>
103 #include <ipc/ipc_port.h>
104 #include <ipc/ipc_right.h>
105 #include <ipc/ipc_hash.h>
106 #include <ipc/ipc_table.h>
111 #include <ppc/Firmware.h>
112 #include <ppc/low_trace.h>
116 extern vm_map_t ipc_kernel_copy_map
;
117 extern vm_size_t ipc_kmsg_max_vm_space
;
118 extern vm_size_t msg_ool_size_small
;
120 #define MSG_OOL_SIZE_SMALL msg_ool_size_small
122 #if defined(__LP64__)
123 #define MAP_SIZE_DIFFERS(map) (map->max_offset < MACH_VM_MAX_ADDRESS)
124 #define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor32_t
125 #define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor32_t
127 #define MAP_SIZE_DIFFERS(map) (map->max_offset > VM_MAX_ADDRESS)
128 #define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor64_t
129 #define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor64_t
132 #define DESC_SIZE_ADJUSTMENT (sizeof(OTHER_OOL_DESCRIPTOR) - \
133 sizeof(mach_msg_ool_descriptor_t))
135 /* scatter list macros */
137 #define SKIP_PORT_DESCRIPTORS(s, c) \
139 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
141 if ((s)->type.type != MACH_MSG_PORT_DESCRIPTOR) \
146 (s) = MACH_MSG_DESCRIPTOR_NULL; \
150 #define INCREMENT_SCATTER(s, c, d) \
152 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
153 s = (d) ? (mach_msg_descriptor_t *) \
154 ((OTHER_OOL_DESCRIPTOR *)(s) + 1) : \
160 /* zone for cached ipc_kmsg_t structures */
161 zone_t ipc_kmsg_zone
;
164 * Forward declarations
170 void ipc_kmsg_clean_body(
172 mach_msg_type_number_t number
,
173 mach_msg_descriptor_t
*desc
);
175 void ipc_kmsg_clean_partial(
177 mach_msg_type_number_t number
,
178 mach_msg_descriptor_t
*desc
,
182 mach_msg_return_t
ipc_kmsg_copyin_body(
188 * We keep a per-processor cache of kernel message buffers.
189 * The cache saves the overhead/locking of using kalloc/kfree.
190 * The per-processor cache seems to miss less than a per-thread cache,
191 * and it also uses less memory. Access to the cache doesn't
196 * Routine: ipc_kmsg_alloc
198 * Allocate a kernel message structure. If we can get one from
199 * the cache, that is best. Otherwise, allocate a new one.
205 mach_msg_size_t msg_and_trailer_size
)
207 mach_msg_size_t max_expanded_size
;
210 #if !defined(__LP64__)
213 * Pad the allocation in case we need to expand the
214 * message descrptors for user spaces with pointers larger than
215 * the kernel's own. We don't know how many descriptors
216 * there are yet, so just assume the whole body could be
217 * descriptors (if there could be any at all).
219 * The expansion space is left in front of the header,
220 * because it is easier to pull the header and descriptors
221 * forward as we process them than it is to push all the
225 mach_msg_size_t size
= msg_and_trailer_size
- MAX_TRAILER_SIZE
;
226 if (size
> sizeof(mach_msg_base_t
)) {
227 mach_msg_size_t max_desc
= ((size
- sizeof(mach_msg_base_t
)) /
228 sizeof(mach_msg_ool_descriptor_t
)) *
229 DESC_SIZE_ADJUSTMENT
;
230 if (msg_and_trailer_size
>= MACH_MSG_SIZE_MAX
- max_desc
)
232 max_expanded_size
= msg_and_trailer_size
+ max_desc
;
235 max_expanded_size
= msg_and_trailer_size
;
237 if (max_expanded_size
> ikm_less_overhead(MACH_MSG_SIZE_MAX
))
239 else if (max_expanded_size
< IKM_SAVED_MSG_SIZE
)
240 max_expanded_size
= IKM_SAVED_MSG_SIZE
; /* round up for ikm_cache */
242 if (max_expanded_size
== IKM_SAVED_MSG_SIZE
) {
243 struct ikm_cache
*cache
;
246 disable_preemption();
247 cache
= &PROCESSOR_DATA(current_processor(), ikm_cache
);
248 if ((i
= cache
->avail
) > 0) {
249 assert(i
<= IKM_STASH
);
250 kmsg
= cache
->entries
[--i
];
252 ikm_check_init(kmsg
, max_expanded_size
);
254 kmsg
->ikm_header
= (mach_msg_header_t
*)
255 ((vm_offset_t
)(kmsg
+ 1) +
257 msg_and_trailer_size
);
261 kmsg
= (ipc_kmsg_t
)zalloc(ipc_kmsg_zone
);
263 kmsg
= (ipc_kmsg_t
)kalloc(ikm_plus_overhead(max_expanded_size
));
266 if (kmsg
!= IKM_NULL
) {
267 ikm_init(kmsg
, max_expanded_size
);
268 kmsg
->ikm_header
= (mach_msg_header_t
*)
269 ((vm_offset_t
)(kmsg
+ 1) +
271 msg_and_trailer_size
);
277 * Routine: ipc_kmsg_free
279 * Free a kernel message buffer. If the kms is preallocated
280 * to a port, just "put it back (marked unused)." We have to
281 * do this with the port locked. The port may have its hold
282 * on our message released. In that case, we have to just
283 * revert the message to a traditional one and free it normally.
292 mach_msg_size_t size
= kmsg
->ikm_size
;
296 * Check to see if the message is bound to the port. If so,
297 * mark it not in use. If the port isn't already dead, then
298 * leave the message associated with it. Otherwise, free it.
300 port
= ikm_prealloc_inuse_port(kmsg
);
301 if (port
!= IP_NULL
) {
303 ikm_prealloc_clear_inuse(kmsg
, port
);
304 if (ip_active(port
) && (port
->ip_premsg
== kmsg
)) {
305 assert(IP_PREALLOC(port
));
309 ip_check_unlock(port
); /* May be last reference */
313 * Peek and see if it has to go back in the cache.
315 if (kmsg
->ikm_size
== IKM_SAVED_MSG_SIZE
) {
316 struct ikm_cache
*cache
;
319 disable_preemption();
320 cache
= &PROCESSOR_DATA(current_processor(), ikm_cache
);
321 if ((i
= cache
->avail
) < IKM_STASH
) {
322 cache
->entries
[i
] = kmsg
;
323 cache
->avail
= i
+ 1;
328 zfree(ipc_kmsg_zone
, kmsg
);
331 kfree(kmsg
, ikm_plus_overhead(size
));
336 * Routine: ipc_kmsg_enqueue
343 ipc_kmsg_queue_t queue
,
346 ipc_kmsg_enqueue_macro(queue
, kmsg
);
350 * Routine: ipc_kmsg_dequeue
352 * Dequeue and return a kmsg.
357 ipc_kmsg_queue_t queue
)
361 first
= ipc_kmsg_queue_first(queue
);
363 if (first
!= IKM_NULL
)
364 ipc_kmsg_rmqueue_first_macro(queue
, first
);
370 * Routine: ipc_kmsg_rmqueue
372 * Pull a kmsg out of a queue.
377 ipc_kmsg_queue_t queue
,
380 ipc_kmsg_t next
, prev
;
382 assert(queue
->ikmq_base
!= IKM_NULL
);
384 next
= kmsg
->ikm_next
;
385 prev
= kmsg
->ikm_prev
;
388 assert(prev
== kmsg
);
389 assert(queue
->ikmq_base
== kmsg
);
391 queue
->ikmq_base
= IKM_NULL
;
393 if (queue
->ikmq_base
== kmsg
)
394 queue
->ikmq_base
= next
;
396 next
->ikm_prev
= prev
;
397 prev
->ikm_next
= next
;
399 /* XXX Temporary debug logic */
400 assert(kmsg
->ikm_next
= IKM_BOGUS
);
401 assert(kmsg
->ikm_prev
= IKM_BOGUS
);
405 * Routine: ipc_kmsg_queue_next
407 * Return the kmsg following the given kmsg.
408 * (Or IKM_NULL if it is the last one in the queue.)
413 ipc_kmsg_queue_t queue
,
418 assert(queue
->ikmq_base
!= IKM_NULL
);
420 next
= kmsg
->ikm_next
;
421 if (queue
->ikmq_base
== next
)
428 * Routine: ipc_kmsg_destroy
430 * Destroys a kernel message. Releases all rights,
431 * references, and memory held by the message.
441 ipc_kmsg_queue_t queue
;
445 * ipc_kmsg_clean can cause more messages to be destroyed.
446 * Curtail recursion by queueing messages. If a message
447 * is already queued, then this is a recursive call.
450 queue
= &(current_thread()->ith_messages
);
451 empty
= ipc_kmsg_queue_empty(queue
);
452 ipc_kmsg_enqueue(queue
, kmsg
);
455 /* must leave kmsg in queue while cleaning it */
457 while ((kmsg
= ipc_kmsg_queue_first(queue
)) != IKM_NULL
) {
458 ipc_kmsg_clean(kmsg
);
459 ipc_kmsg_rmqueue(queue
, kmsg
);
466 * Routine: ipc_kmsg_destroy_dest
468 * Destroys a kernel message. Releases all rights,
469 * references, and memory held by the message (including
470 * the destination port reference.
476 ipc_kmsg_destroy_dest(
481 port
= kmsg
->ikm_header
->msgh_remote_port
;
483 ipc_port_release(port
);
484 kmsg
->ikm_header
->msgh_remote_port
= MACH_PORT_NULL
;
485 ipc_kmsg_destroy(kmsg
);
489 * Routine: ipc_kmsg_clean_body
491 * Cleans the body of a kernel message.
492 * Releases all rights, references, and memory.
500 __unused ipc_kmsg_t kmsg
,
501 mach_msg_type_number_t number
,
502 mach_msg_descriptor_t
*saddr
)
504 mach_msg_descriptor_t
*eaddr
;
509 eaddr
= saddr
+ number
;
511 for ( ; saddr
< eaddr
; saddr
++ ) {
513 switch (saddr
->type
.type
) {
515 case MACH_MSG_PORT_DESCRIPTOR
: {
516 mach_msg_port_descriptor_t
*dsc
;
521 * Destroy port rights carried in the message
523 if (!IO_VALID((ipc_object_t
) dsc
->name
))
525 ipc_object_destroy((ipc_object_t
) dsc
->name
, dsc
->disposition
);
528 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
529 case MACH_MSG_OOL_DESCRIPTOR
: {
530 mach_msg_ool_descriptor_t
*dsc
;
532 dsc
= &saddr
->out_of_line
;
535 * Destroy memory carried in the message
537 if (dsc
->size
== 0) {
538 assert(dsc
->address
== (void *) 0);
540 vm_map_copy_discard((vm_map_copy_t
) dsc
->address
);
544 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
545 ipc_object_t
*objects
;
546 mach_msg_type_number_t j
;
547 mach_msg_ool_ports_descriptor_t
*dsc
;
549 dsc
= &saddr
->ool_ports
;
550 objects
= (ipc_object_t
*) dsc
->address
;
552 if (dsc
->count
== 0) {
556 assert(objects
!= (ipc_object_t
*) 0);
558 /* destroy port rights carried in the message */
560 for (j
= 0; j
< dsc
->count
; j
++) {
561 ipc_object_t object
= objects
[j
];
563 if (!IO_VALID(object
))
566 ipc_object_destroy(object
, dsc
->disposition
);
569 /* destroy memory carried in the message */
571 assert(dsc
->count
!= 0);
574 (vm_size_t
) dsc
->count
* sizeof(mach_port_name_t
));
578 printf("cleanup: don't understand this type of descriptor\n");
585 * Routine: ipc_kmsg_clean_partial
587 * Cleans a partially-acquired kernel message.
588 * number is the index of the type descriptor
589 * in the body of the message that contained the error.
590 * If dolast, the memory and port rights in this last
591 * type spec are also cleaned. In that case, number
592 * specifies the number of port rights to clean.
598 ipc_kmsg_clean_partial(
600 mach_msg_type_number_t number
,
601 mach_msg_descriptor_t
*desc
,
606 mach_msg_bits_t mbits
= kmsg
->ikm_header
->msgh_bits
;
608 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
609 assert(IO_VALID(object
));
610 ipc_object_destroy(object
, MACH_MSGH_BITS_REMOTE(mbits
));
612 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
613 if (IO_VALID(object
))
614 ipc_object_destroy(object
, MACH_MSGH_BITS_LOCAL(mbits
));
617 (void) vm_deallocate(ipc_kernel_copy_map
, paddr
, length
);
620 ipc_kmsg_clean_body(kmsg
, number
, desc
);
624 * Routine: ipc_kmsg_clean
626 * Cleans a kernel message. Releases all rights,
627 * references, and memory held by the message.
637 mach_msg_bits_t mbits
;
639 mbits
= kmsg
->ikm_header
->msgh_bits
;
640 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
641 if (IO_VALID(object
))
642 ipc_object_destroy(object
, MACH_MSGH_BITS_REMOTE(mbits
));
644 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
645 if (IO_VALID(object
))
646 ipc_object_destroy(object
, MACH_MSGH_BITS_LOCAL(mbits
));
648 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
649 mach_msg_body_t
*body
;
651 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
652 ipc_kmsg_clean_body(kmsg
, body
->msgh_descriptor_count
,
653 (mach_msg_descriptor_t
*)(body
+ 1));
658 * Routine: ipc_kmsg_set_prealloc
660 * Assign a kmsg as a preallocated message buffer to a port.
666 ipc_kmsg_set_prealloc(
670 assert(kmsg
->ikm_prealloc
== IP_NULL
);
672 kmsg
->ikm_prealloc
= IP_NULL
;
673 IP_SET_PREALLOC(port
, kmsg
);
677 * Routine: ipc_kmsg_clear_prealloc
679 * Release the Assignment of a preallocated message buffer from a port.
684 ipc_kmsg_clear_prealloc(
688 assert(kmsg
->ikm_prealloc
== port
);
690 kmsg
->ikm_prealloc
= IP_NULL
;
691 IP_CLEAR_PREALLOC(port
, kmsg
);
697 * Routine: ipc_kmsg_get
699 * Allocates a kernel message buffer.
700 * Copies a user message to the message buffer.
704 * MACH_MSG_SUCCESS Acquired a message buffer.
705 * MACH_SEND_MSG_TOO_SMALL Message smaller than a header.
706 * MACH_SEND_MSG_TOO_SMALL Message size not long-word multiple.
707 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
708 * MACH_SEND_INVALID_DATA Couldn't copy message data.
713 mach_vm_address_t msg_addr
,
714 mach_msg_size_t size
,
717 mach_msg_size_t msg_and_trailer_size
;
719 mach_msg_max_trailer_t
*trailer
;
721 if ((size
< sizeof(mach_msg_header_t
)) || (size
& 3))
722 return MACH_SEND_MSG_TOO_SMALL
;
724 if (size
> MACH_MSG_SIZE_MAX
- MAX_TRAILER_SIZE
)
725 return MACH_SEND_TOO_LARGE
;
727 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
729 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
731 if (kmsg
== IKM_NULL
)
732 return MACH_SEND_NO_BUFFER
;
734 if (copyinmsg(msg_addr
, (char *) kmsg
->ikm_header
, size
)) {
736 return MACH_SEND_INVALID_DATA
;
739 kmsg
->ikm_header
->msgh_size
= size
;
742 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
743 * However, the internal size field of the trailer (msgh_trailer_size)
744 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize
745 * the cases where no implicit data is requested.
747 trailer
= (mach_msg_max_trailer_t
*) ((vm_offset_t
)kmsg
->ikm_header
+ size
);
748 trailer
->msgh_sender
= current_thread()->task
->sec_token
;
749 trailer
->msgh_audit
= current_thread()->task
->audit_token
;
750 trailer
->msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
751 trailer
->msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
754 if(trcWork
.traceMask
) dbgTrace(0x1100, (unsigned int)kmsg
->ikm_header
->msgh_id
,
755 (unsigned int)kmsg
->ikm_header
->msgh_remote_port
,
756 (unsigned int)kmsg
->ikm_header
->msgh_local_port
, 0);
759 return MACH_MSG_SUCCESS
;
763 * Routine: ipc_kmsg_get_from_kernel
765 * First checks for a preallocated message
766 * reserved for kernel clients. If not found -
767 * allocates a new kernel message buffer.
768 * Copies a kernel message to the message buffer.
769 * Only resource errors are allowed.
772 * Ports in header are ipc_port_t.
774 * MACH_MSG_SUCCESS Acquired a message buffer.
775 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
779 ipc_kmsg_get_from_kernel(
780 mach_msg_header_t
*msg
,
781 mach_msg_size_t size
,
785 mach_msg_size_t msg_and_trailer_size
;
786 mach_msg_max_trailer_t
*trailer
;
787 ipc_port_t dest_port
;
789 assert(size
>= sizeof(mach_msg_header_t
));
790 // assert((size & 3) == 0);
792 assert(IP_VALID((ipc_port_t
) msg
->msgh_remote_port
));
793 dest_port
= (ipc_port_t
)msg
->msgh_remote_port
;
795 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
798 * See if the port has a pre-allocated kmsg for kernel
799 * clients. These are set up for those kernel clients
800 * which cannot afford to wait.
802 if (IP_PREALLOC(dest_port
)) {
804 if (!ip_active(dest_port
)) {
805 ip_unlock(dest_port
);
806 return MACH_SEND_NO_BUFFER
;
808 assert(IP_PREALLOC(dest_port
));
809 kmsg
= dest_port
->ip_premsg
;
810 if (msg_and_trailer_size
> kmsg
->ikm_size
) {
811 ip_unlock(dest_port
);
812 return MACH_SEND_TOO_LARGE
;
814 if (ikm_prealloc_inuse(kmsg
)) {
815 ip_unlock(dest_port
);
816 return MACH_SEND_NO_BUFFER
;
818 ikm_prealloc_set_inuse(kmsg
, dest_port
);
819 ip_unlock(dest_port
);
821 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
822 if (kmsg
== IKM_NULL
)
823 return MACH_SEND_NO_BUFFER
;
826 (void) memcpy((void *) kmsg
->ikm_header
, (const void *) msg
, size
);
828 kmsg
->ikm_header
->msgh_size
= size
;
831 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
832 * However, the internal size field of the trailer (msgh_trailer_size)
833 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to
834 * optimize the cases where no implicit data is requested.
836 trailer
= (mach_msg_max_trailer_t
*)
837 ((vm_offset_t
)kmsg
->ikm_header
+ size
);
838 trailer
->msgh_sender
= KERNEL_SECURITY_TOKEN
;
839 trailer
->msgh_audit
= KERNEL_AUDIT_TOKEN
;
840 trailer
->msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
841 trailer
->msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
844 return MACH_MSG_SUCCESS
;
848 * Routine: ipc_kmsg_send
850 * Send a message. The message holds a reference
851 * for the destination port in the msgh_remote_port field.
853 * If unsuccessful, the caller still has possession of
854 * the message and must do something with it. If successful,
855 * the message is queued, given to a receiver, destroyed,
856 * or handled directly by the kernel via mach_msg.
860 * MACH_MSG_SUCCESS The message was accepted.
861 * MACH_SEND_TIMED_OUT Caller still has message.
862 * MACH_SEND_INTERRUPTED Caller still has message.
867 mach_msg_option_t option
,
868 mach_msg_timeout_t send_timeout
)
872 port
= (ipc_port_t
) kmsg
->ikm_header
->msgh_remote_port
;
873 assert(IP_VALID(port
));
877 if (port
->ip_receiver
== ipc_space_kernel
) {
880 * We can check ip_receiver == ipc_space_kernel
881 * before checking that the port is active because
882 * ipc_port_dealloc_kernel clears ip_receiver
883 * before destroying a kernel port.
885 assert(ip_active(port
));
886 port
->ip_messages
.imq_seqno
++;
889 current_task()->messages_sent
++;
892 * Call the server routine, and get the reply message to send.
894 kmsg
= ipc_kobject_server(kmsg
);
895 if (kmsg
== IKM_NULL
)
896 return MACH_MSG_SUCCESS
;
898 port
= (ipc_port_t
) kmsg
->ikm_header
->msgh_remote_port
;
899 assert(IP_VALID(port
));
901 /* fall thru with reply - same options */
905 * Can't deliver to a dead port.
906 * However, we can pretend it got sent
907 * and was then immediately destroyed.
909 if (!ip_active(port
)) {
911 * We can't let ipc_kmsg_destroy deallocate
912 * the port right, because we might end up
913 * in an infinite loop trying to deliver
914 * a send-once notification.
918 ip_check_unlock(port
);
919 kmsg
->ikm_header
->msgh_remote_port
= MACH_PORT_NULL
;
920 ipc_kmsg_destroy(kmsg
);
921 return MACH_MSG_SUCCESS
;
924 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_CIRCULAR
) {
927 /* don't allow the creation of a circular loop */
929 ipc_kmsg_destroy(kmsg
);
930 return MACH_MSG_SUCCESS
;
934 * We have a valid message and a valid reference on the port.
935 * we can unlock the port and call mqueue_send() on it's message
939 return (ipc_mqueue_send(&port
->ip_messages
, kmsg
, option
, send_timeout
));
943 * Routine: ipc_kmsg_put
945 * Copies a message buffer to a user message.
946 * Copies only the specified number of bytes.
947 * Frees the message buffer.
949 * Nothing locked. The message buffer must have clean
952 * MACH_MSG_SUCCESS Copied data out of message buffer.
953 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
958 mach_vm_address_t msg_addr
,
960 mach_msg_size_t size
)
962 mach_msg_return_t mr
;
964 if (copyoutmsg((const char *) kmsg
->ikm_header
, msg_addr
, size
))
965 mr
= MACH_RCV_INVALID_DATA
;
967 mr
= MACH_MSG_SUCCESS
;
974 * Routine: ipc_kmsg_put_to_kernel
976 * Copies a message buffer to a kernel message.
977 * Frees the message buffer.
984 ipc_kmsg_put_to_kernel(
985 mach_msg_header_t
*msg
,
987 mach_msg_size_t size
)
989 (void) memcpy((void *) msg
, (const void *) kmsg
->ikm_header
, size
);
995 * Routine: ipc_kmsg_copyin_header
997 * "Copy-in" port rights in the header of a message.
998 * Operates atomically; if it doesn't succeed the
999 * message header and the space are left untouched.
1000 * If it does succeed the remote/local port fields
1001 * contain object pointers instead of port names,
1002 * and the bits field is updated. The destination port
1003 * will be a valid port pointer.
1005 * The notify argument implements the MACH_SEND_CANCEL option.
1006 * If it is not MACH_PORT_NULL, it should name a receive right.
1007 * If the processing of the destination port would generate
1008 * a port-deleted notification (because the right for the
1009 * destination port is destroyed and it had a request for
1010 * a dead-name notification registered), and the port-deleted
1011 * notification would be sent to the named receive right,
1012 * then it isn't sent and the send-once right for the notify
1013 * port is quietly destroyed.
1018 * MACH_MSG_SUCCESS Successful copyin.
1019 * MACH_SEND_INVALID_HEADER
1020 * Illegal value in the message header bits.
1021 * MACH_SEND_INVALID_DEST The space is dead.
1022 * MACH_SEND_INVALID_NOTIFY
1023 * Notify is non-null and doesn't name a receive right.
1024 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1025 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1026 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1027 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1028 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1032 ipc_kmsg_copyin_header(
1033 mach_msg_header_t
*msg
,
1035 mach_port_name_t notify
)
1037 mach_msg_bits_t mbits
= msg
->msgh_bits
& MACH_MSGH_BITS_USER
;
1038 mach_port_name_t dest_name
= (mach_port_name_t
)msg
->msgh_remote_port
;
1039 mach_port_name_t reply_name
= (mach_port_name_t
)msg
->msgh_local_port
;
1042 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
1043 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
1044 ipc_object_t dest_port
, reply_port
;
1045 ipc_port_t dest_soright
, reply_soright
;
1046 ipc_port_t notify_port
;
1048 if ((mbits
!= msg
->msgh_bits
) ||
1049 (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type
)) ||
1050 ((reply_type
== 0) ?
1051 (reply_name
!= MACH_PORT_NULL
) :
1052 !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type
)))
1053 return MACH_SEND_INVALID_HEADER
;
1055 reply_soright
= IP_NULL
; /* in case we go to invalid dest early */
1057 is_write_lock(space
);
1058 if (!space
->is_active
)
1061 if (!MACH_PORT_VALID(dest_name
))
1064 if (notify
!= MACH_PORT_NULL
) {
1067 if ((entry
= ipc_entry_lookup(space
, notify
)) == IE_NULL
) {
1068 is_write_unlock(space
);
1069 return MACH_SEND_INVALID_NOTIFY
;
1071 if((entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
) == 0) {
1072 is_write_unlock(space
);
1073 return MACH_SEND_INVALID_NOTIFY
;
1076 notify_port
= (ipc_port_t
) entry
->ie_object
;
1078 notify_port
= IP_NULL
;
1080 if (dest_name
== reply_name
) {
1082 mach_port_name_t name
= dest_name
;
1085 * Destination and reply ports are the same!
1086 * This is a little tedious to make atomic, because
1087 * there are 25 combinations of dest_type/reply_type.
1088 * However, most are easy. If either is move-sonce,
1089 * then there must be an error. If either are
1090 * make-send or make-sonce, then we must be looking
1091 * at a receive right so the port can't die.
1092 * The hard cases are the combinations of
1093 * copy-send and make-send.
1096 entry
= ipc_entry_lookup(space
, name
);
1097 if (entry
== IE_NULL
)
1100 assert(reply_type
!= 0); /* because name not null */
1102 if (!ipc_right_copyin_check(space
, name
, entry
, reply_type
))
1105 if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
) ||
1106 (reply_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
)) {
1108 * Why must there be an error? To get a valid
1109 * destination, this entry must name a live
1110 * port (not a dead name or dead port). However
1111 * a successful move-sonce will destroy a
1112 * live entry. Therefore the other copyin,
1113 * whatever it is, would fail. We've already
1114 * checked for reply port errors above,
1115 * so report a destination error.
1119 } else if ((dest_type
== MACH_MSG_TYPE_MAKE_SEND
) ||
1120 (dest_type
== MACH_MSG_TYPE_MAKE_SEND_ONCE
) ||
1121 (reply_type
== MACH_MSG_TYPE_MAKE_SEND
) ||
1122 (reply_type
== MACH_MSG_TYPE_MAKE_SEND_ONCE
)) {
1123 kr
= ipc_right_copyin(space
, name
, entry
,
1125 &dest_port
, &dest_soright
);
1126 if (kr
!= KERN_SUCCESS
)
1130 * Either dest or reply needs a receive right.
1131 * We know the receive right is there, because
1132 * of the copyin_check and copyin calls. Hence
1133 * the port is not in danger of dying. If dest
1134 * used the receive right, then the right needed
1135 * by reply (and verified by copyin_check) will
1139 assert(IO_VALID(dest_port
));
1140 assert(entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
);
1141 assert(dest_soright
== IP_NULL
);
1143 kr
= ipc_right_copyin(space
, name
, entry
,
1145 &reply_port
, &reply_soright
);
1147 assert(kr
== KERN_SUCCESS
);
1148 assert(reply_port
== dest_port
);
1149 assert(entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
);
1150 assert(reply_soright
== IP_NULL
);
1151 } else if ((dest_type
== MACH_MSG_TYPE_COPY_SEND
) &&
1152 (reply_type
== MACH_MSG_TYPE_COPY_SEND
)) {
1154 * To make this atomic, just do one copy-send,
1155 * and dup the send right we get out.
1158 kr
= ipc_right_copyin(space
, name
, entry
,
1160 &dest_port
, &dest_soright
);
1161 if (kr
!= KERN_SUCCESS
)
1164 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND
);
1165 assert(dest_soright
== IP_NULL
);
1168 * It's OK if the port we got is dead now,
1169 * so reply_port is IP_DEAD, because the msg
1170 * won't go anywhere anyway.
1173 reply_port
= (ipc_object_t
)
1174 ipc_port_copy_send((ipc_port_t
) dest_port
);
1175 reply_soright
= IP_NULL
;
1176 } else if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND
) &&
1177 (reply_type
== MACH_MSG_TYPE_MOVE_SEND
)) {
1179 * This is an easy case. Just use our
1180 * handy-dandy special-purpose copyin call
1181 * to get two send rights for the price of one.
1184 kr
= ipc_right_copyin_two(space
, name
, entry
,
1185 &dest_port
, &dest_soright
);
1186 if (kr
!= KERN_SUCCESS
)
1189 /* the entry might need to be deallocated */
1190 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1191 ipc_entry_dealloc(space
, name
, entry
);
1193 reply_port
= dest_port
;
1194 reply_soright
= IP_NULL
;
1198 assert(((dest_type
== MACH_MSG_TYPE_COPY_SEND
) &&
1199 (reply_type
== MACH_MSG_TYPE_MOVE_SEND
)) ||
1200 ((dest_type
== MACH_MSG_TYPE_MOVE_SEND
) &&
1201 (reply_type
== MACH_MSG_TYPE_COPY_SEND
)));
1204 * To make this atomic, just do a move-send,
1205 * and dup the send right we get out.
1208 kr
= ipc_right_copyin(space
, name
, entry
,
1209 MACH_MSG_TYPE_MOVE_SEND
, FALSE
,
1210 &dest_port
, &soright
);
1211 if (kr
!= KERN_SUCCESS
)
1214 /* the entry might need to be deallocated */
1216 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1217 ipc_entry_dealloc(space
, name
, entry
);
1220 * It's OK if the port we got is dead now,
1221 * so reply_port is IP_DEAD, because the msg
1222 * won't go anywhere anyway.
1225 reply_port
= (ipc_object_t
)
1226 ipc_port_copy_send((ipc_port_t
) dest_port
);
1228 if (dest_type
== MACH_MSG_TYPE_MOVE_SEND
) {
1229 dest_soright
= soright
;
1230 reply_soright
= IP_NULL
;
1232 dest_soright
= IP_NULL
;
1233 reply_soright
= soright
;
1236 } else if (!MACH_PORT_VALID(reply_name
)) {
1240 * No reply port! This is an easy case
1241 * to make atomic. Just copyin the destination.
1244 entry
= ipc_entry_lookup(space
, dest_name
);
1245 if (entry
== IE_NULL
)
1248 kr
= ipc_right_copyin(space
, dest_name
, entry
,
1250 &dest_port
, &dest_soright
);
1251 if (kr
!= KERN_SUCCESS
)
1254 /* the entry might need to be deallocated */
1256 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1257 ipc_entry_dealloc(space
, dest_name
, entry
);
1259 reply_port
= (ipc_object_t
) reply_name
;
1260 reply_soright
= IP_NULL
;
1262 ipc_entry_t dest_entry
, reply_entry
;
1265 * This is the tough case to make atomic.
1266 * The difficult problem is serializing with port death.
1267 * At the time we copyin dest_port, it must be alive.
1268 * If reply_port is alive when we copyin it, then
1269 * we are OK, because we serialize before the death
1270 * of both ports. Assume reply_port is dead at copyin.
1271 * Then if dest_port dies/died after reply_port died,
1272 * we are OK, because we serialize between the death
1273 * of the two ports. So the bad case is when dest_port
1274 * dies after its copyin, reply_port dies before its
1275 * copyin, and dest_port dies before reply_port. Then
1276 * the copyins operated as if dest_port was alive
1277 * and reply_port was dead, which shouldn't have happened
1278 * because they died in the other order.
1280 * Note that it is easy for a user task to tell if
1281 * a copyin happened before or after a port died.
1282 * For example, suppose both dest and reply are
1283 * send-once rights (types are both move-sonce) and
1284 * both rights have dead-name requests registered.
1285 * If a port dies before copyin, a dead-name notification
1286 * is generated and the dead name's urefs are incremented,
1287 * and if the copyin happens first, a port-deleted
1288 * notification is generated.
1290 * Note that although the entries are different,
1291 * dest_port and reply_port might still be the same.
1293 * JMM - The code to handle this was too expensive and, anyway,
1294 * we intend to separate the dest lookup from the reply copyin
1295 * by a wide margin, so the user will have to learn to deal!
1296 * I will be making the change soon!
1299 dest_entry
= ipc_entry_lookup(space
, dest_name
);
1300 if (dest_entry
== IE_NULL
)
1303 reply_entry
= ipc_entry_lookup(space
, reply_name
);
1304 if (reply_entry
== IE_NULL
)
1307 assert(dest_entry
!= reply_entry
); /* names are not equal */
1308 assert(reply_type
!= 0); /* because reply_name not null */
1310 if (!ipc_right_copyin_check(space
, reply_name
, reply_entry
,
1314 kr
= ipc_right_copyin(space
, dest_name
, dest_entry
,
1316 &dest_port
, &dest_soright
);
1317 if (kr
!= KERN_SUCCESS
)
1320 assert(IO_VALID(dest_port
));
1322 kr
= ipc_right_copyin(space
, reply_name
, reply_entry
,
1324 &reply_port
, &reply_soright
);
1326 assert(kr
== KERN_SUCCESS
);
1328 /* the entries might need to be deallocated */
1330 if (IE_BITS_TYPE(reply_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1331 ipc_entry_dealloc(space
, reply_name
, reply_entry
);
1333 if (IE_BITS_TYPE(dest_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1334 ipc_entry_dealloc(space
, dest_name
, dest_entry
);
1338 * At this point, dest_port, reply_port,
1339 * dest_soright, reply_soright are all initialized.
1340 * Any defunct entries have been deallocated.
1341 * The space is still write-locked, and we need to
1342 * make the MACH_SEND_CANCEL check. The notify_port pointer
1343 * is still usable, because the copyin code above won't ever
1344 * deallocate a receive right, so its entry still exists
1345 * and holds a ref. Note notify_port might even equal
1346 * dest_port or reply_port.
1349 if ((notify
!= MACH_PORT_NULL
) &&
1350 (dest_soright
== notify_port
)) {
1351 ipc_port_release_sonce(dest_soright
);
1352 dest_soright
= IP_NULL
;
1355 is_write_unlock(space
);
1357 if (dest_soright
!= IP_NULL
)
1358 ipc_notify_port_deleted(dest_soright
, dest_name
);
1360 if (reply_soright
!= IP_NULL
)
1361 ipc_notify_port_deleted(reply_soright
, reply_name
);
1363 dest_type
= ipc_object_copyin_type(dest_type
);
1364 reply_type
= ipc_object_copyin_type(reply_type
);
1366 msg
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
1367 MACH_MSGH_BITS(dest_type
, reply_type
));
1368 msg
->msgh_remote_port
= (ipc_port_t
)dest_port
;
1369 msg
->msgh_local_port
= (ipc_port_t
)reply_port
;
1371 return MACH_MSG_SUCCESS
;
1374 is_write_unlock(space
);
1375 return MACH_SEND_INVALID_REPLY
;
1378 is_write_unlock(space
);
1379 if (reply_soright
!= IP_NULL
)
1380 ipc_notify_port_deleted(reply_soright
, reply_name
);
1381 return MACH_SEND_INVALID_DEST
;
1385 * Routine: ipc_kmsg_copyin_body
1387 * "Copy-in" port rights and out-of-line memory
1388 * in the message body.
1390 * In all failure cases, the message is left holding
1391 * no rights or memory. However, the message buffer
1392 * is not deallocated. If successful, the message
1393 * contains a valid destination port.
1397 * MACH_MSG_SUCCESS Successful copyin.
1398 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
1399 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
1400 * MACH_SEND_INVALID_TYPE Bad type specification.
1401 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
1402 * MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
1403 * MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
1406 #define DESC_COUNT_SMALL 64
1409 ipc_kmsg_copyin_body(
1415 mach_msg_body_t
*body
;
1416 mach_msg_descriptor_t
*daddr
, *naddr
;
1417 mach_msg_type_number_t dsc_count
;
1418 boolean_t differs
= MAP_SIZE_DIFFERS(map
);
1419 boolean_t
complex = FALSE
;
1420 vm_size_t space_needed
= 0;
1421 vm_size_t desc_size_space
[DESC_COUNT_SMALL
];
1422 vm_size_t
*user_desc_sizes
= NULL
;
1423 vm_offset_t paddr
= 0;
1424 vm_map_copy_t copy
= VM_MAP_COPY_NULL
;
1426 mach_msg_type_number_t i
;
1427 mach_msg_return_t mr
= MACH_MSG_SUCCESS
;
1430 * Determine if the target is a kernel port.
1432 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
1433 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
1434 naddr
= (mach_msg_descriptor_t
*) (body
+ 1);
1436 dsc_count
= body
->msgh_descriptor_count
;
1438 return MACH_MSG_SUCCESS
;
1441 user_desc_sizes
= (dsc_count
<= DESC_COUNT_SMALL
) ?
1442 &desc_size_space
: kalloc(dsc_count
* sizeof(vm_size_t
));
1443 if (user_desc_sizes
== NULL
) {
1444 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1445 return KERN_RESOURCE_SHORTAGE
;
1450 * Make an initial pass to determine kernal VM space requirements for
1451 * physical copies and possible contraction of the descriptors from
1452 * processes with pointers larger than the kernel's.
1455 for (i
= 0; i
< dsc_count
; i
++) {
1458 /* make sure the descriptor fits in the message */
1460 switch (daddr
->type
.type
) {
1461 case MACH_MSG_OOL_DESCRIPTOR
:
1462 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1463 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
1464 user_desc_sizes
[i
] = sizeof(OTHER_OOL_DESCRIPTOR
);
1467 user_desc_sizes
[i
] = sizeof(*daddr
);
1470 naddr
= (mach_msg_descriptor_t
*)
1471 ((vm_offset_t
)daddr
+ user_desc_sizes
[i
]);
1476 if (naddr
> (mach_msg_descriptor_t
*)
1477 ((vm_offset_t
)kmsg
->ikm_header
+ kmsg
->ikm_header
->msgh_size
)) {
1478 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1479 mr
= MACH_SEND_MSG_TOO_SMALL
;
1483 switch (daddr
->type
.type
) {
1484 mach_msg_size_t size
;
1486 case MACH_MSG_OOL_DESCRIPTOR
:
1487 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1489 ((OTHER_OOL_DESCRIPTOR
*)daddr
)->size
:
1490 daddr
->out_of_line
.size
;
1492 if (daddr
->out_of_line
.copy
!= MACH_MSG_PHYSICAL_COPY
&&
1493 daddr
->out_of_line
.copy
!= MACH_MSG_VIRTUAL_COPY
) {
1495 * Invalid copy option
1497 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1498 mr
= MACH_SEND_INVALID_TYPE
;
1502 if ((size
>= MSG_OOL_SIZE_SMALL
) &&
1503 (daddr
->out_of_line
.copy
== MACH_MSG_PHYSICAL_COPY
) &&
1504 !(daddr
->out_of_line
.deallocate
)) {
1507 * Out-of-line memory descriptor, accumulate kernel
1508 * memory requirements
1510 space_needed
+= round_page(size
);
1511 if (space_needed
> ipc_kmsg_max_vm_space
) {
1514 * Per message kernel memory limit exceeded
1516 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1517 mr
= MACH_MSG_VM_KERNEL
;
1525 * Allocate space in the pageable kernel ipc copy map for all the
1526 * ool data that is to be physically copied. Map is marked wait for
1530 if (vm_allocate(ipc_kernel_copy_map
, &paddr
, space_needed
, VM_FLAGS_ANYWHERE
) !=
1532 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1533 mr
= MACH_MSG_VM_KERNEL
;
1539 * handle the OOL regions and port descriptors.
1540 * We process them in reverse order starting with the last one
1541 * scanned above. That way, we can compact them up against
1542 * the message body (if the user-descriptor size is larger than
1543 * the kernel representation).
1548 switch (daddr
->type
.type
) {
1550 /* port descriptors are the same size everywhere, how nice */
1551 case MACH_MSG_PORT_DESCRIPTOR
: {
1552 mach_msg_type_name_t user_disp
;
1553 mach_msg_type_name_t result_disp
;
1554 mach_port_name_t name
;
1555 ipc_object_t object
;
1556 volatile mach_msg_port_descriptor_t
*dsc
;
1557 volatile mach_msg_port_descriptor_t
*user_dsc
;
1559 user_dsc
= &daddr
->port
;
1562 user_disp
= user_dsc
->disposition
;
1563 result_disp
= ipc_object_copyin_type(user_disp
);
1565 name
= (mach_port_name_t
)user_dsc
->name
;
1566 if (MACH_PORT_VALID(name
)) {
1568 kr
= ipc_object_copyin(space
, name
, user_disp
, &object
);
1569 if (kr
!= KERN_SUCCESS
) {
1570 mr
= MACH_SEND_INVALID_RIGHT
;
1574 if ((result_disp
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1575 ipc_port_check_circularity((ipc_port_t
) object
,
1576 (ipc_port_t
) dest
)) {
1577 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
1579 dsc
->name
= (ipc_port_t
) object
;
1581 dsc
->name
= (mach_port_t
)name
;
1583 dsc
->disposition
= result_disp
;
1584 dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
1589 /* out of line descriptors differ in size between 32 and 64 bit processes */
1590 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1591 case MACH_MSG_OOL_DESCRIPTOR
: {
1594 mach_msg_copy_options_t copy_options
;
1595 mach_vm_offset_t addr
;
1596 mach_msg_descriptor_type_t dsc_type
;
1598 volatile mach_msg_ool_descriptor_t
*dsc
;
1601 volatile OTHER_OOL_DESCRIPTOR
*user_dsc
;
1603 user_dsc
= (OTHER_OOL_DESCRIPTOR
*)&daddr
->out_of_line
;
1604 addr
= (mach_vm_offset_t
) user_dsc
->address
;
1605 length
= user_dsc
->size
;
1606 dealloc
= user_dsc
->deallocate
;
1607 copy_options
= user_dsc
->copy
;
1608 dsc_type
= user_dsc
->type
;
1610 volatile mach_msg_ool_descriptor_t
*user_dsc
;
1612 user_dsc
= &daddr
->out_of_line
;
1613 addr
= CAST_USER_ADDR_T(user_dsc
->address
);
1614 dealloc
= user_dsc
->deallocate
;
1615 copy_options
= user_dsc
->copy
;
1616 dsc_type
= user_dsc
->type
;
1617 length
= user_dsc
->size
;
1620 dsc
= &naddr
->out_of_line
;
1622 dsc
->deallocate
= dealloc
;
1623 dsc
->copy
= copy_options
;
1624 dsc
->type
= dsc_type
;
1628 } else if ((length
>= MSG_OOL_SIZE_SMALL
) &&
1629 (copy_options
== MACH_MSG_PHYSICAL_COPY
) && !dealloc
) {
1632 * If the request is a physical copy and the source
1633 * is not being deallocated, then allocate space
1634 * in the kernel's pageable ipc copy map and copy
1635 * the data in. The semantics guarantee that the
1636 * data will have been physically copied before
1637 * the send operation terminates. Thus if the data
1638 * is not being deallocated, we must be prepared
1639 * to page if the region is sufficiently large.
1641 if (copyin(addr
, (char *) paddr
, length
)) {
1642 mr
= MACH_SEND_INVALID_MEMORY
;
1647 * The kernel ipc copy map is marked no_zero_fill.
1648 * If the transfer is not a page multiple, we need
1649 * to zero fill the balance.
1651 if (!page_aligned(length
)) {
1652 (void) memset((void *) (paddr
+ length
), 0,
1653 round_page(length
) - length
);
1655 if (vm_map_copyin(ipc_kernel_copy_map
, (vm_map_address_t
)paddr
,
1656 (vm_map_size_t
)length
, TRUE
, ©
) != KERN_SUCCESS
) {
1657 mr
= MACH_MSG_VM_KERNEL
;
1660 dsc
->address
= (void *) copy
;
1661 paddr
+= round_page(length
);
1662 space_needed
-= round_page(length
);
1666 * Make a vm_map_copy_t of the of the data. If the
1667 * data is small, this will do an optimized physical
1668 * copy. Otherwise, it will do a virtual copy.
1670 * NOTE: A virtual copy is OK if the original is being
1671 * deallocted, even if a physical copy was requested.
1673 kr
= vm_map_copyin(map
, addr
,
1674 (vm_map_size_t
)length
, dealloc
, ©
);
1675 if (kr
!= KERN_SUCCESS
) {
1676 mr
= (kr
== KERN_RESOURCE_SHORTAGE
) ?
1677 MACH_MSG_VM_KERNEL
:
1678 MACH_SEND_INVALID_MEMORY
;
1681 dsc
->address
= (void *) copy
;
1686 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
1689 ipc_object_t
*objects
;
1691 mach_vm_offset_t addr
;
1692 mach_msg_type_name_t user_disp
;
1693 mach_msg_type_name_t result_disp
;
1694 mach_msg_type_number_t count
;
1695 mach_msg_copy_options_t copy_option
;
1696 boolean_t deallocate
;
1698 volatile mach_msg_ool_ports_descriptor_t
*dsc
;
1701 volatile OTHER_OOL_PORTS_DESCRIPTOR
*user_dsc
;
1703 user_dsc
= (OTHER_OOL_PORTS_DESCRIPTOR
*)&daddr
->ool_ports
;
1704 addr
= (mach_vm_offset_t
)user_dsc
->address
;
1705 count
= user_dsc
->count
;
1706 deallocate
= user_dsc
->deallocate
;
1707 copy_option
= user_dsc
->copy
;
1708 user_disp
= user_dsc
->disposition
;
1710 volatile mach_msg_ool_ports_descriptor_t
*user_dsc
;
1712 user_dsc
= &daddr
->ool_ports
;
1713 addr
= CAST_USER_ADDR_T(user_dsc
->address
);
1714 count
= user_dsc
->count
;
1715 deallocate
= user_dsc
->deallocate
;
1716 copy_option
= user_dsc
->copy
;
1717 user_disp
= user_dsc
->disposition
;
1720 dsc
= &naddr
->ool_ports
;
1721 dsc
->deallocate
= deallocate
;
1722 dsc
->copy
= copy_option
;
1723 dsc
->type
= daddr
->type
.type
;
1726 /* calculate length of data in bytes, rounding up */
1727 length
= count
* sizeof(mach_port_name_t
);
1731 dsc
->address
= (void *) 0;
1735 data
= kalloc(length
);
1738 mr
= MACH_SEND_NO_BUFFER
;
1742 if (copyinmap(map
, addr
, data
, length
) != KERN_SUCCESS
) {
1743 kfree(data
, length
);
1744 mr
= MACH_SEND_INVALID_MEMORY
;
1749 (void) mach_vm_deallocate(map
, addr
, (mach_vm_size_t
)length
);
1752 dsc
->address
= data
;
1754 result_disp
= ipc_object_copyin_type(user_disp
);
1755 dsc
->disposition
= result_disp
;
1757 objects
= (ipc_object_t
*) data
;
1759 for ( j
= 0; j
< count
; j
++) {
1760 mach_port_name_t port
= (mach_port_name_t
) objects
[j
];
1761 ipc_object_t object
;
1763 if (!MACH_PORT_VALID(port
))
1766 kr
= ipc_object_copyin(space
, port
, user_disp
, &object
);
1768 if (kr
!= KERN_SUCCESS
) {
1771 for(k
= 0; k
< j
; k
++) {
1772 object
= objects
[k
];
1773 if (IPC_OBJECT_VALID(object
))
1774 ipc_object_destroy(object
, result_disp
);
1776 kfree(data
, length
);
1777 mr
= MACH_SEND_INVALID_RIGHT
;
1781 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1782 ipc_port_check_circularity(
1783 (ipc_port_t
) object
,
1785 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
1787 objects
[j
] = object
;
1795 * Invalid descriptor
1797 mr
= MACH_SEND_INVALID_TYPE
;
1802 if (MACH_MSG_SUCCESS
!= mr
) {
1803 ipc_kmsg_clean_partial(kmsg
, dsc_count
- i
,
1804 naddr
+ 1, paddr
, space_needed
);
1810 (daddr
= (differs
) ? (mach_msg_descriptor_t
*)((vm_offset_t
)(daddr
) -
1811 user_desc_sizes
[i
- 1]) : daddr
- 1)
1816 kmsg
->ikm_header
->msgh_bits
&= ~MACH_MSGH_BITS_COMPLEX
;
1819 if (differs
&& naddr
!= daddr
) {
1820 mach_msg_base_t
*old_base
= (mach_msg_base_t
*)kmsg
->ikm_header
;
1821 mach_msg_base_t
*new_base
= (mach_msg_base_t
*)naddr
- 1;
1823 memmove(new_base
, old_base
, sizeof(mach_msg_base_t
));
1824 new_base
->header
.msgh_size
-= (vm_offset_t
)naddr
- (vm_offset_t
)daddr
;
1825 kmsg
->ikm_header
= &new_base
->header
;
1829 if (differs
&& dsc_count
> DESC_COUNT_SMALL
)
1830 kfree(user_desc_sizes
, body
->msgh_descriptor_count
* sizeof(vm_size_t
));
1837 * Routine: ipc_kmsg_copyin
1839 * "Copy-in" port rights and out-of-line memory
1842 * In all failure cases, the message is left holding
1843 * no rights or memory. However, the message buffer
1844 * is not deallocated. If successful, the message
1845 * contains a valid destination port.
1849 * MACH_MSG_SUCCESS Successful copyin.
1850 * MACH_SEND_INVALID_HEADER
1851 * Illegal value in the message header bits.
1852 * MACH_SEND_INVALID_NOTIFY Bad notify port.
1853 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1854 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1855 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
1856 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
1857 * MACH_SEND_INVALID_TYPE Bad type specification.
1858 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
1866 mach_port_name_t notify
)
1868 mach_msg_return_t mr
;
1870 mr
= ipc_kmsg_copyin_header(kmsg
->ikm_header
, space
, notify
);
1871 if (mr
!= MACH_MSG_SUCCESS
)
1874 if ((kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
1875 return MACH_MSG_SUCCESS
;
1877 return( ipc_kmsg_copyin_body( kmsg
, space
, map
) );
1881 * Routine: ipc_kmsg_copyin_from_kernel
1883 * "Copy-in" port rights and out-of-line memory
1884 * in a message sent from the kernel.
1886 * Because the message comes from the kernel,
1887 * the implementation assumes there are no errors
1888 * or peculiarities in the message.
1890 * Returns TRUE if queueing the message
1891 * would result in a circularity.
1897 ipc_kmsg_copyin_from_kernel(
1900 mach_msg_bits_t bits
= kmsg
->ikm_header
->msgh_bits
;
1901 mach_msg_type_name_t rname
= MACH_MSGH_BITS_REMOTE(bits
);
1902 mach_msg_type_name_t lname
= MACH_MSGH_BITS_LOCAL(bits
);
1903 ipc_object_t remote
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
1904 ipc_object_t local
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
1906 /* translate the destination and reply ports */
1908 ipc_object_copyin_from_kernel(remote
, rname
);
1909 if (IO_VALID(local
))
1910 ipc_object_copyin_from_kernel(local
, lname
);
1913 * The common case is a complex message with no reply port,
1914 * because that is what the memory_object interface uses.
1917 if (bits
== (MACH_MSGH_BITS_COMPLEX
|
1918 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0))) {
1919 bits
= (MACH_MSGH_BITS_COMPLEX
|
1920 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND
, 0));
1922 kmsg
->ikm_header
->msgh_bits
= bits
;
1924 bits
= (MACH_MSGH_BITS_OTHER(bits
) |
1925 MACH_MSGH_BITS(ipc_object_copyin_type(rname
),
1926 ipc_object_copyin_type(lname
)));
1928 kmsg
->ikm_header
->msgh_bits
= bits
;
1929 if ((bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
1933 mach_msg_descriptor_t
*saddr
, *eaddr
;
1934 mach_msg_body_t
*body
;
1936 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
1937 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
1938 eaddr
= (mach_msg_descriptor_t
*) saddr
+ body
->msgh_descriptor_count
;
1940 for ( ; saddr
< eaddr
; saddr
++) {
1942 switch (saddr
->type
.type
) {
1944 case MACH_MSG_PORT_DESCRIPTOR
: {
1945 mach_msg_type_name_t name
;
1946 ipc_object_t object
;
1947 mach_msg_port_descriptor_t
*dsc
;
1951 /* this is really the type SEND, SEND_ONCE, etc. */
1952 name
= dsc
->disposition
;
1953 object
= (ipc_object_t
) dsc
->name
;
1954 dsc
->disposition
= ipc_object_copyin_type(name
);
1956 if (!IO_VALID(object
)) {
1960 ipc_object_copyin_from_kernel(object
, name
);
1962 /* CDY avoid circularity when the destination is also */
1963 /* the kernel. This check should be changed into an */
1964 /* assert when the new kobject model is in place since*/
1965 /* ports will not be used in kernel to kernel chats */
1967 if (((ipc_port_t
)remote
)->ip_receiver
!= ipc_space_kernel
) {
1968 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1969 ipc_port_check_circularity((ipc_port_t
) object
,
1970 (ipc_port_t
) remote
)) {
1971 kmsg
->ikm_header
->msgh_bits
|=
1972 MACH_MSGH_BITS_CIRCULAR
;
1977 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1978 case MACH_MSG_OOL_DESCRIPTOR
: {
1980 * The sender should supply ready-made memory, i.e.
1981 * a vm_map_copy_t, so we don't need to do anything.
1985 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
1986 ipc_object_t
*objects
;
1988 mach_msg_type_name_t name
;
1989 mach_msg_ool_ports_descriptor_t
*dsc
;
1991 dsc
= &saddr
->ool_ports
;
1993 /* this is really the type SEND, SEND_ONCE, etc. */
1994 name
= dsc
->disposition
;
1995 dsc
->disposition
= ipc_object_copyin_type(name
);
1997 objects
= (ipc_object_t
*) dsc
->address
;
1999 for ( j
= 0; j
< dsc
->count
; j
++) {
2000 ipc_object_t object
= objects
[j
];
2002 if (!IO_VALID(object
))
2005 ipc_object_copyin_from_kernel(object
, name
);
2007 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
2008 ipc_port_check_circularity(
2009 (ipc_port_t
) object
,
2010 (ipc_port_t
) remote
))
2011 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
2017 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
2018 #endif /* MACH_ASSERT */
2026 * Routine: ipc_kmsg_copyout_header
2028 * "Copy-out" port rights in the header of a message.
2029 * Operates atomically; if it doesn't succeed the
2030 * message header and the space are left untouched.
2031 * If it does succeed the remote/local port fields
2032 * contain port names instead of object pointers,
2033 * and the bits field is updated.
2035 * The notify argument implements the MACH_RCV_NOTIFY option.
2036 * If it is not MACH_PORT_NULL, it should name a receive right.
2037 * If the process of receiving the reply port creates a
2038 * new right in the receiving task, then the new right is
2039 * automatically registered for a dead-name notification,
2040 * with the notify port supplying the send-once right.
2044 * MACH_MSG_SUCCESS Copied out port rights.
2045 * MACH_RCV_INVALID_NOTIFY
2046 * Notify is non-null and doesn't name a receive right.
2047 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
2048 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
2049 * The space is dead.
2050 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
2051 * No room in space for another name.
2052 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
2053 * Couldn't allocate memory for the reply port.
2054 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
2055 * Couldn't allocate memory for the dead-name request.
2059 ipc_kmsg_copyout_header(
2060 mach_msg_header_t
*msg
,
2062 mach_port_name_t notify
)
2064 mach_msg_bits_t mbits
= msg
->msgh_bits
;
2065 ipc_port_t dest
= (ipc_port_t
) msg
->msgh_remote_port
;
2067 assert(IP_VALID(dest
));
2070 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2071 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2072 ipc_port_t reply
= (ipc_port_t
) msg
->msgh_local_port
;
2073 mach_port_name_t dest_name
, reply_name
;
2075 if (IP_VALID(reply
)) {
2076 ipc_port_t notify_port
;
2081 * Handling notify (for MACH_RCV_NOTIFY) is tricky.
2082 * The problem is atomically making a send-once right
2083 * from the notify port and installing it for a
2084 * dead-name request in the new entry, because this
2085 * requires two port locks (on the notify port and
2086 * the reply port). However, we can safely make
2087 * and consume send-once rights for the notify port
2088 * as long as we hold the space locked. This isn't
2089 * an atomicity problem, because the only way
2090 * to detect that a send-once right has been created
2091 * and then consumed if it wasn't needed is by getting
2092 * at the receive right to look at ip_sorights, and
2093 * because the space is write-locked status calls can't
2094 * lookup the notify port receive right. When we make
2095 * the send-once right, we lock the notify port,
2096 * so any status calls in progress will be done.
2099 is_write_lock(space
);
2102 ipc_port_request_index_t request
;
2104 if (!space
->is_active
) {
2105 is_write_unlock(space
);
2106 return (MACH_RCV_HEADER_ERROR
|
2107 MACH_MSG_IPC_SPACE
);
2110 if (notify
!= MACH_PORT_NULL
) {
2111 notify_port
= ipc_port_lookup_notify(space
,
2113 if (notify_port
== IP_NULL
) {
2114 is_write_unlock(space
);
2115 return MACH_RCV_INVALID_NOTIFY
;
2118 notify_port
= IP_NULL
;
2120 if ((reply_type
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
2121 ipc_right_reverse(space
, (ipc_object_t
) reply
,
2122 &reply_name
, &entry
)) {
2123 /* reply port is locked and active */
2126 * We don't need the notify_port
2127 * send-once right, but we can't release
2128 * it here because reply port is locked.
2129 * Wait until after the copyout to
2130 * release the notify port right.
2133 assert(entry
->ie_bits
&
2134 MACH_PORT_TYPE_SEND_RECEIVE
);
2139 if (!ip_active(reply
)) {
2141 ip_check_unlock(reply
);
2143 if (notify_port
!= IP_NULL
)
2144 ipc_port_release_sonce(notify_port
);
2147 is_write_unlock(space
);
2150 reply_name
= MACH_PORT_DEAD
;
2154 reply_name
= (mach_port_name_t
)reply
;
2155 kr
= ipc_entry_get(space
, &reply_name
, &entry
);
2156 if (kr
!= KERN_SUCCESS
) {
2159 if (notify_port
!= IP_NULL
)
2160 ipc_port_release_sonce(notify_port
);
2162 /* space is locked */
2163 kr
= ipc_entry_grow_table(space
,
2165 if (kr
!= KERN_SUCCESS
) {
2166 /* space is unlocked */
2168 if (kr
== KERN_RESOURCE_SHORTAGE
)
2169 return (MACH_RCV_HEADER_ERROR
|
2170 MACH_MSG_IPC_KERNEL
);
2172 return (MACH_RCV_HEADER_ERROR
|
2173 MACH_MSG_IPC_SPACE
);
2175 /* space is locked again; start over */
2179 assert(IE_BITS_TYPE(entry
->ie_bits
) ==
2180 MACH_PORT_TYPE_NONE
);
2181 assert(entry
->ie_object
== IO_NULL
);
2183 if (notify_port
== IP_NULL
) {
2184 /* not making a dead-name request */
2186 entry
->ie_object
= (ipc_object_t
) reply
;
2190 kr
= ipc_port_dnrequest(reply
, reply_name
,
2191 notify_port
, &request
);
2192 if (kr
!= KERN_SUCCESS
) {
2195 ipc_port_release_sonce(notify_port
);
2197 ipc_entry_dealloc(space
, reply_name
, entry
);
2198 is_write_unlock(space
);
2201 if (!ip_active(reply
)) {
2202 /* will fail next time around loop */
2205 is_write_lock(space
);
2209 kr
= ipc_port_dngrow(reply
, ITS_SIZE_NONE
);
2210 /* port is unlocked */
2211 if (kr
!= KERN_SUCCESS
)
2212 return (MACH_RCV_HEADER_ERROR
|
2213 MACH_MSG_IPC_KERNEL
);
2215 is_write_lock(space
);
2219 notify_port
= IP_NULL
; /* don't release right below */
2221 entry
->ie_object
= (ipc_object_t
) reply
;
2222 entry
->ie_request
= request
;
2226 /* space and reply port are locked and active */
2228 ip_reference(reply
); /* hold onto the reply port */
2230 kr
= ipc_right_copyout(space
, reply_name
, entry
,
2231 reply_type
, TRUE
, (ipc_object_t
) reply
);
2232 /* reply port is unlocked */
2233 assert(kr
== KERN_SUCCESS
);
2235 if (notify_port
!= IP_NULL
)
2236 ipc_port_release_sonce(notify_port
);
2239 is_write_unlock(space
);
2242 * No reply port! This is an easy case.
2243 * We only need to have the space locked
2244 * when checking notify and when locking
2245 * the destination (to ensure atomicity).
2248 is_read_lock(space
);
2249 if (!space
->is_active
) {
2250 is_read_unlock(space
);
2251 return MACH_RCV_HEADER_ERROR
|MACH_MSG_IPC_SPACE
;
2254 if (notify
!= MACH_PORT_NULL
) {
2257 /* must check notify even though it won't be used */
2259 if ((entry
= ipc_entry_lookup(space
, notify
)) == IE_NULL
) {
2260 is_read_unlock(space
);
2261 return MACH_RCV_INVALID_NOTIFY
;
2264 if ((entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
) == 0) {
2265 is_read_unlock(space
);
2266 return MACH_RCV_INVALID_NOTIFY
;
2271 is_read_unlock(space
);
2273 reply_name
= (mach_port_name_t
) reply
;
2277 * At this point, the space is unlocked and the destination
2278 * port is locked. (Lock taken while space was locked.)
2279 * reply_name is taken care of; we still need dest_name.
2280 * We still hold a ref for reply (if it is valid).
2282 * If the space holds receive rights for the destination,
2283 * we return its name for the right. Otherwise the task
2284 * managed to destroy or give away the receive right between
2285 * receiving the message and this copyout. If the destination
2286 * is dead, return MACH_PORT_DEAD, and if the receive right
2287 * exists somewhere else (another space, in transit)
2288 * return MACH_PORT_NULL.
2290 * Making this copyout operation atomic with the previous
2291 * copyout of the reply port is a bit tricky. If there was
2292 * no real reply port (it wasn't IP_VALID) then this isn't
2293 * an issue. If the reply port was dead at copyout time,
2294 * then we are OK, because if dest is dead we serialize
2295 * after the death of both ports and if dest is alive
2296 * we serialize after reply died but before dest's (later) death.
2297 * So assume reply was alive when we copied it out. If dest
2298 * is alive, then we are OK because we serialize before
2299 * the ports' deaths. So assume dest is dead when we look at it.
2300 * If reply dies/died after dest, then we are OK because
2301 * we serialize after dest died but before reply dies.
2302 * So the hard case is when reply is alive at copyout,
2303 * dest is dead at copyout, and reply died before dest died.
2304 * In this case pretend that dest is still alive, so
2305 * we serialize while both ports are alive.
2307 * Because the space lock is held across the copyout of reply
2308 * and locking dest, the receive right for dest can't move
2309 * in or out of the space while the copyouts happen, so
2310 * that isn't an atomicity problem. In the last hard case
2311 * above, this implies that when dest is dead that the
2312 * space couldn't have had receive rights for dest at
2313 * the time reply was copied-out, so when we pretend
2314 * that dest is still alive, we can return MACH_PORT_NULL.
2316 * If dest == reply, then we have to make it look like
2317 * either both copyouts happened before the port died,
2318 * or both happened after the port died. This special
2319 * case works naturally if the timestamp comparison
2320 * is done correctly.
2325 if (ip_active(dest
)) {
2326 ipc_object_copyout_dest(space
, (ipc_object_t
) dest
,
2327 dest_type
, &dest_name
);
2328 /* dest is unlocked */
2330 ipc_port_timestamp_t timestamp
;
2332 timestamp
= dest
->ip_timestamp
;
2334 ip_check_unlock(dest
);
2336 if (IP_VALID(reply
)) {
2338 if (ip_active(reply
) ||
2339 IP_TIMESTAMP_ORDER(timestamp
,
2340 reply
->ip_timestamp
))
2341 dest_name
= MACH_PORT_DEAD
;
2343 dest_name
= MACH_PORT_NULL
;
2346 dest_name
= MACH_PORT_DEAD
;
2349 if (IP_VALID(reply
))
2350 ipc_port_release(reply
);
2352 msg
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
2353 MACH_MSGH_BITS(reply_type
, dest_type
));
2354 msg
->msgh_local_port
= (ipc_port_t
)dest_name
;
2355 msg
->msgh_remote_port
= (ipc_port_t
)reply_name
;
2358 return MACH_MSG_SUCCESS
;
2362 * Routine: ipc_kmsg_copyout_object
2364 * Copy-out a port right. Always returns a name,
2365 * even for unsuccessful return codes. Always
2366 * consumes the supplied object.
2370 * MACH_MSG_SUCCESS The space acquired the right
2371 * (name is valid) or the object is dead (MACH_PORT_DEAD).
2372 * MACH_MSG_IPC_SPACE No room in space for the right,
2373 * or the space is dead. (Name is MACH_PORT_NULL.)
2374 * MACH_MSG_IPC_KERNEL Kernel resource shortage.
2375 * (Name is MACH_PORT_NULL.)
2379 ipc_kmsg_copyout_object(
2381 ipc_object_t object
,
2382 mach_msg_type_name_t msgt_name
,
2383 mach_port_name_t
*namep
)
2387 if (!IO_VALID(object
)) {
2388 *namep
= (mach_port_name_t
) object
;
2389 return MACH_MSG_SUCCESS
;
2392 kr
= ipc_object_copyout(space
, object
, msgt_name
, TRUE
, namep
);
2393 if (kr
!= KERN_SUCCESS
) {
2394 ipc_object_destroy(object
, msgt_name
);
2396 if (kr
== KERN_INVALID_CAPABILITY
)
2397 *namep
= MACH_PORT_DEAD
;
2399 *namep
= MACH_PORT_NULL
;
2401 if (kr
== KERN_RESOURCE_SHORTAGE
)
2402 return MACH_MSG_IPC_KERNEL
;
2404 return MACH_MSG_IPC_SPACE
;
2408 return MACH_MSG_SUCCESS
;
2412 * Routine: ipc_kmsg_copyout_body
2414 * "Copy-out" port rights and out-of-line memory
2415 * in the body of a message.
2417 * The error codes are a combination of special bits.
2418 * The copyout proceeds despite errors.
2422 * MACH_MSG_SUCCESS Successful copyout.
2423 * MACH_MSG_IPC_SPACE No room for port right in name space.
2424 * MACH_MSG_VM_SPACE No room for memory in address space.
2425 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
2426 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
2427 * MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
2431 ipc_kmsg_copyout_body(
2435 mach_msg_body_t
*slist
)
2437 mach_msg_body_t
*body
;
2438 mach_msg_descriptor_t
*daddr
, *naddr
;
2439 mach_msg_descriptor_t
*saddr
;
2440 mach_msg_type_number_t i
, dsc_count
, sdsc_count
;
2441 mach_msg_return_t mr
= MACH_MSG_SUCCESS
;
2444 boolean_t differs
= MAP_SIZE_DIFFERS(map
);
2446 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2447 dsc_count
= body
->msgh_descriptor_count
;
2448 daddr
= (mach_msg_descriptor_t
*) (body
+ 1);
2451 * Do scatter list setup
2453 if (slist
!= MACH_MSG_BODY_NULL
) {
2454 saddr
= (mach_msg_descriptor_t
*) (slist
+ 1);
2455 sdsc_count
= slist
->msgh_descriptor_count
;
2458 saddr
= MACH_MSG_DESCRIPTOR_NULL
;
2463 * Compute the true size of the resulting descriptors
2464 * after potential expansion and adjust the header
2465 * and body location accordingly.
2468 mach_msg_size_t dsc_adjust
;
2472 for (i
= 0; i
< dsc_count
; i
++, naddr
++)
2473 switch (naddr
->type
.type
) {
2474 case MACH_MSG_OOL_DESCRIPTOR
:
2475 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2476 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
2477 dsc_adjust
+= DESC_SIZE_ADJUSTMENT
;
2483 mach_msg_base_t
*old_base
= (mach_msg_base_t
*)kmsg
->ikm_header
;
2484 mach_msg_base_t
*new_base
;
2486 new_base
= (mach_msg_base_t
*)((vm_offset_t
)old_base
- dsc_adjust
);
2487 memmove(new_base
, old_base
, sizeof(mach_msg_base_t
));
2488 kmsg
->ikm_header
= &new_base
->header
;
2489 kmsg
->ikm_header
->msgh_size
+= dsc_adjust
;
2490 naddr
= (mach_msg_descriptor_t
*)(new_base
+ 1);
2499 * Now process the descriptors
2501 for ( i
= 0; i
< dsc_count
; i
++, daddr
++ ) {
2502 switch (daddr
->type
.type
) {
2504 case MACH_MSG_PORT_DESCRIPTOR
: {
2505 volatile mach_msg_port_descriptor_t
*dsc
;
2506 volatile mach_msg_port_descriptor_t
*user_dsc
;
2508 mach_port_name_t name
;
2509 mach_msg_type_name_t disp
;
2512 * Copyout port right carried in the message
2515 user_dsc
= &naddr
->port
;
2517 disp
= dsc
->disposition
;
2518 mr
|= ipc_kmsg_copyout_object(space
,
2522 user_dsc
->name
= (mach_port_t
)name
;
2523 user_dsc
->disposition
= disp
;
2524 user_dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
2529 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2530 case MACH_MSG_OOL_DESCRIPTOR
: {
2532 mach_vm_offset_t rcv_addr
;
2533 mach_msg_ool_descriptor_t
*dsc
;
2534 mach_msg_copy_options_t copy_options
;
2535 mach_msg_size_t size
;
2536 mach_msg_descriptor_type_t dsc_type
;
2538 SKIP_PORT_DESCRIPTORS(saddr
, sdsc_count
);
2540 dsc
= &daddr
->out_of_line
;
2541 copy
= (vm_map_copy_t
) dsc
->address
;
2543 copy_options
= dsc
->copy
;
2544 assert(copy_options
!= MACH_MSG_KALLOC_COPY_T
);
2545 dsc_type
= dsc
->type
;
2547 if (copy
!= VM_MAP_COPY_NULL
) {
2549 * Check to see if there is an overwrite descriptor
2550 * specified in the scatter list for this ool data.
2551 * The descriptor has already been verified.
2553 if (saddr
!= MACH_MSG_DESCRIPTOR_NULL
) {
2555 OTHER_OOL_DESCRIPTOR
*scatter_dsc
;
2557 scatter_dsc
= (OTHER_OOL_DESCRIPTOR
*)saddr
;
2558 if (scatter_dsc
->copy
== MACH_MSG_OVERWRITE
) {
2559 rcv_addr
= (mach_vm_offset_t
) scatter_dsc
->address
;
2560 copy_options
= MACH_MSG_OVERWRITE
;
2563 copy_options
= MACH_MSG_VIRTUAL_COPY
;
2566 mach_msg_ool_descriptor_t
*scatter_dsc
;
2568 scatter_dsc
= &saddr
->out_of_line
;
2569 if (scatter_dsc
->copy
== MACH_MSG_OVERWRITE
) {
2570 rcv_addr
= CAST_USER_ADDR_T(scatter_dsc
->address
);
2571 copy_options
= MACH_MSG_OVERWRITE
;
2574 copy_options
= MACH_MSG_VIRTUAL_COPY
;
2577 INCREMENT_SCATTER(saddr
, sdsc_count
, differs
);
2582 * Whether the data was virtually or physically
2583 * copied we have a vm_map_copy_t for it.
2584 * If there's an overwrite region specified
2585 * overwrite it, otherwise do a virtual copy out.
2587 if (copy_options
== MACH_MSG_OVERWRITE
) {
2588 kr
= vm_map_copy_overwrite(map
, rcv_addr
,
2591 kr
= vm_map_copyout(map
, &rcv_addr
, copy
);
2593 if (kr
!= KERN_SUCCESS
) {
2594 if (kr
== KERN_RESOURCE_SHORTAGE
)
2595 mr
|= MACH_MSG_VM_KERNEL
;
2597 mr
|= MACH_MSG_VM_SPACE
;
2598 vm_map_copy_discard(copy
);
2608 * Now update the descriptor as the user would see it.
2609 * This may require expanding the descriptor to the user
2610 * visible size. There is already space allocated for
2611 * this in what naddr points to.
2614 volatile OTHER_OOL_DESCRIPTOR
*user_dsc
;
2616 user_dsc
= (OTHER_OOL_DESCRIPTOR
*)naddr
;
2617 user_dsc
->address
= rcv_addr
;
2618 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2620 user_dsc
->copy
= copy_options
;
2621 user_dsc
->type
= dsc_type
;
2622 user_dsc
->size
= size
;
2623 naddr
= (mach_msg_descriptor_t
*)((OTHER_OOL_DESCRIPTOR
*)naddr
+ 1);
2625 volatile mach_msg_ool_descriptor_t
*user_dsc
;
2627 user_dsc
= &naddr
->out_of_line
;
2628 user_dsc
->address
= CAST_DOWN(void *, rcv_addr
);
2629 user_dsc
->size
= size
;
2630 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2632 user_dsc
->copy
= copy_options
;
2633 user_dsc
->type
= dsc_type
;
2639 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
2640 mach_vm_offset_t rcv_addr
;
2641 mach_port_name_t
*objects
;
2642 mach_msg_type_name_t disp
;
2643 mach_msg_type_number_t count
, j
;
2646 volatile mach_msg_ool_ports_descriptor_t
*dsc
;
2647 mach_msg_copy_options_t copy_options
= MACH_MSG_VIRTUAL_COPY
;
2649 SKIP_PORT_DESCRIPTORS(saddr
, sdsc_count
);
2651 dsc
= &daddr
->ool_ports
;
2653 disp
= dsc
->disposition
;
2654 length
= count
* sizeof(mach_port_name_t
);
2656 if (length
!= 0 && dsc
->address
!= 0) {
2659 * Check to see if there is an overwrite descriptor
2660 * specified in the scatter list for this ool data.
2661 * The descriptor has already been verified.
2663 if (saddr
!= MACH_MSG_DESCRIPTOR_NULL
) {
2665 OTHER_OOL_DESCRIPTOR
*scatter_dsc
;
2667 scatter_dsc
= (OTHER_OOL_DESCRIPTOR
*)saddr
;
2668 rcv_addr
= (mach_vm_offset_t
) scatter_dsc
->address
;
2669 copy_options
= scatter_dsc
->copy
;
2671 mach_msg_ool_descriptor_t
*scatter_dsc
;
2673 scatter_dsc
= &saddr
->out_of_line
;
2674 rcv_addr
= CAST_USER_ADDR_T(scatter_dsc
->address
);
2675 copy_options
= scatter_dsc
->copy
;
2677 INCREMENT_SCATTER(saddr
, sdsc_count
, differs
);
2680 if (copy_options
== MACH_MSG_VIRTUAL_COPY
) {
2682 * Dynamically allocate the region
2684 int anywhere
= VM_MAKE_TAG(VM_MEMORY_MACH_MSG
)|
2687 if ((kr
= mach_vm_allocate(map
, &rcv_addr
,
2688 (mach_vm_size_t
)length
,
2689 anywhere
)) != KERN_SUCCESS
) {
2690 ipc_kmsg_clean_body(kmsg
, 1, daddr
);
2693 if (kr
== KERN_RESOURCE_SHORTAGE
){
2694 mr
|= MACH_MSG_VM_KERNEL
;
2696 mr
|= MACH_MSG_VM_SPACE
;
2703 * Handle the port rights and copy out the names
2704 * for those rights out to user-space.
2706 if (rcv_addr
!= 0) {
2707 objects
= (mach_port_name_t
*) dsc
->address
;
2709 /* copyout port rights carried in the message */
2711 for ( j
= 0; j
< count
; j
++) {
2712 ipc_object_t object
=
2713 (ipc_object_t
) objects
[j
];
2715 mr
|= ipc_kmsg_copyout_object(space
, object
,
2719 /* copyout to memory allocated above */
2720 data
= dsc
->address
;
2721 if (copyoutmap(map
, data
, rcv_addr
, length
) != KERN_SUCCESS
)
2722 mr
|= MACH_MSG_VM_SPACE
;
2723 kfree(data
, length
);
2730 * Now update the descriptor based on the information
2734 volatile OTHER_OOL_PORTS_DESCRIPTOR
*user_dsc
;
2736 user_dsc
= (OTHER_OOL_PORTS_DESCRIPTOR
*)naddr
;
2737 user_dsc
->address
= rcv_addr
;
2738 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2740 user_dsc
->copy
= copy_options
;
2741 user_dsc
->disposition
= disp
;
2742 user_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
2743 user_dsc
->count
= count
;
2744 naddr
= (mach_msg_descriptor_t
*)((OTHER_OOL_PORTS_DESCRIPTOR
*)naddr
+ 1);
2746 volatile mach_msg_ool_ports_descriptor_t
*user_dsc
;
2748 user_dsc
= &naddr
->ool_ports
;
2749 user_dsc
->address
= CAST_DOWN(void *, rcv_addr
);
2750 user_dsc
->count
= count
;
2751 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2753 user_dsc
->copy
= copy_options
;
2754 user_dsc
->disposition
= disp
;
2755 user_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
2761 panic("untyped IPC copyout body: invalid message descriptor");
2769 * Routine: ipc_kmsg_copyout_size
2771 * Compute the size of the message as copied out to the given
2772 * map. If the destination map's pointers are a different size
2773 * than the kernel's, we have to allow for expansion/
2774 * contraction of the descriptors as appropriate.
2778 * size of the message as it would be received.
2782 ipc_kmsg_copyout_size(
2786 mach_msg_size_t send_size
;
2788 send_size
= kmsg
->ikm_header
->msgh_size
;
2790 if ((kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) &&
2791 MAP_SIZE_DIFFERS(map
)) {
2793 mach_msg_body_t
*body
;
2794 mach_msg_descriptor_t
*saddr
, *eaddr
;
2796 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2797 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
2798 eaddr
= saddr
+ body
->msgh_descriptor_count
;
2800 for ( ; saddr
< eaddr
; saddr
++ ) {
2801 switch (saddr
->type
.type
) {
2803 case MACH_MSG_OOL_DESCRIPTOR
:
2804 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2805 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
2806 send_size
+= DESC_SIZE_ADJUSTMENT
;
2818 * Routine: ipc_kmsg_copyout
2820 * "Copy-out" port rights and out-of-line memory
2825 * MACH_MSG_SUCCESS Copied out all rights and memory.
2826 * MACH_RCV_INVALID_NOTIFY Bad notify port.
2827 * Rights and memory in the message are intact.
2828 * MACH_RCV_HEADER_ERROR + special bits
2829 * Rights and memory in the message are intact.
2830 * MACH_RCV_BODY_ERROR + special bits
2831 * The message header was successfully copied out.
2832 * As much of the body was handled as possible.
2840 mach_port_name_t notify
,
2841 mach_msg_body_t
*slist
)
2843 mach_msg_return_t mr
;
2845 mr
= ipc_kmsg_copyout_header(kmsg
->ikm_header
, space
, notify
);
2846 if (mr
!= MACH_MSG_SUCCESS
)
2849 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
2850 mr
= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
2852 if (mr
!= MACH_MSG_SUCCESS
)
2853 mr
|= MACH_RCV_BODY_ERROR
;
2860 * Routine: ipc_kmsg_copyout_pseudo
2862 * Does a pseudo-copyout of the message.
2863 * This is like a regular copyout, except
2864 * that the ports in the header are handled
2865 * as if they are in the body. They aren't reversed.
2867 * The error codes are a combination of special bits.
2868 * The copyout proceeds despite errors.
2872 * MACH_MSG_SUCCESS Successful copyout.
2873 * MACH_MSG_IPC_SPACE No room for port right in name space.
2874 * MACH_MSG_VM_SPACE No room for memory in address space.
2875 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
2876 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
2880 ipc_kmsg_copyout_pseudo(
2884 mach_msg_body_t
*slist
)
2886 mach_msg_bits_t mbits
= kmsg
->ikm_header
->msgh_bits
;
2887 ipc_object_t dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
2888 ipc_object_t reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
2889 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2890 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2891 mach_port_name_t dest_name
, reply_name
;
2892 mach_msg_return_t mr
;
2894 assert(IO_VALID(dest
));
2896 mr
= (ipc_kmsg_copyout_object(space
, dest
, dest_type
, &dest_name
) |
2897 ipc_kmsg_copyout_object(space
, reply
, reply_type
, &reply_name
));
2899 kmsg
->ikm_header
->msgh_bits
= mbits
&~ MACH_MSGH_BITS_CIRCULAR
;
2900 kmsg
->ikm_header
->msgh_remote_port
= (ipc_port_t
)dest_name
;
2901 kmsg
->ikm_header
->msgh_local_port
= (ipc_port_t
)reply_name
;
2903 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
2904 mr
|= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
2911 * Routine: ipc_kmsg_copyout_dest
2913 * Copies out the destination port in the message.
2914 * Destroys all other rights and memory in the message.
2920 ipc_kmsg_copyout_dest(
2924 mach_msg_bits_t mbits
;
2927 mach_msg_type_name_t dest_type
;
2928 mach_msg_type_name_t reply_type
;
2929 mach_port_name_t dest_name
, reply_name
;
2931 mbits
= kmsg
->ikm_header
->msgh_bits
;
2932 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
2933 reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
2934 dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2935 reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2937 assert(IO_VALID(dest
));
2940 if (io_active(dest
)) {
2941 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
2942 /* dest is unlocked */
2945 io_check_unlock(dest
);
2946 dest_name
= MACH_PORT_DEAD
;
2949 if (IO_VALID(reply
)) {
2950 ipc_object_destroy(reply
, reply_type
);
2951 reply_name
= MACH_PORT_NULL
;
2953 reply_name
= (mach_port_name_t
) reply
;
2955 kmsg
->ikm_header
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
2956 MACH_MSGH_BITS(reply_type
, dest_type
));
2957 kmsg
->ikm_header
->msgh_local_port
= (ipc_port_t
)dest_name
;
2958 kmsg
->ikm_header
->msgh_remote_port
= (ipc_port_t
)reply_name
;
2960 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
2961 mach_msg_body_t
*body
;
2963 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2964 ipc_kmsg_clean_body(kmsg
, body
->msgh_descriptor_count
,
2965 (mach_msg_descriptor_t
*)(body
+ 1));
2970 * Routine: ipc_kmsg_copyin_scatter
2972 * allocate and copyin a scatter list
2974 * The gather (kmsg) is valid since it has been copied in.
2975 * Gather list descriptors are sequentially paired with scatter
2976 * list descriptors, with port descriptors in either list ignored.
2977 * Descriptors are consistent if the type fileds match and size
2978 * of the scatter descriptor is less than or equal to the
2979 * size of the gather descriptor. A MACH_MSG_ALLOCATE copy
2980 * strategy in a scatter descriptor matches any size in the
2981 * corresponding gather descriptor assuming they are the same type.
2982 * Either list may be larger than the other. During the
2983 * subsequent copy out, excess scatter descriptors are ignored
2984 * and excess gather descriptors default to dynamic allocation.
2986 * In the case of a size error, the scatter list is released.
2990 * the allocated message body containing the scatter list.
2994 ipc_kmsg_get_scatter(
2995 mach_vm_address_t msg_addr
,
2996 mach_msg_size_t slist_size
,
2999 mach_msg_body_t
*slist
;
3000 mach_msg_body_t
*body
;
3001 mach_msg_descriptor_t
*gstart
, *gend
;
3002 mach_msg_descriptor_t
*sstart
, *send
;
3005 if (slist_size
< sizeof(mach_msg_base_t
))
3006 return MACH_MSG_BODY_NULL
;
3008 slist_size
-= sizeof(mach_msg_header_t
);
3009 slist
= (mach_msg_body_t
*)kalloc(slist_size
);
3010 if (slist
== MACH_MSG_BODY_NULL
)
3013 if (copyin(msg_addr
+ sizeof(mach_msg_header_t
), (char *)slist
, slist_size
)) {
3014 kfree(slist
, slist_size
);
3015 return MACH_MSG_BODY_NULL
;
3018 if ((slist
->msgh_descriptor_count
* sizeof(mach_msg_descriptor_t
)
3019 + sizeof(mach_msg_size_t
)) > slist_size
) {
3020 kfree(slist
, slist_size
);
3021 return MACH_MSG_BODY_NULL
;
3024 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
3025 gstart
= (mach_msg_descriptor_t
*) (body
+ 1);
3026 gend
= gstart
+ body
->msgh_descriptor_count
;
3028 sstart
= (mach_msg_descriptor_t
*) (slist
+ 1);
3029 send
= sstart
+ slist
->msgh_descriptor_count
;
3031 while (gstart
< gend
) {
3032 mach_msg_descriptor_type_t g_type
;
3035 * Skip port descriptors in gather list.
3037 g_type
= gstart
->type
.type
;
3039 if (g_type
!= MACH_MSG_PORT_DESCRIPTOR
) {
3042 * A scatter list with a 0 descriptor count is treated as an
3043 * automatic size mismatch.
3045 if (slist
->msgh_descriptor_count
== 0) {
3046 kfree(slist
, slist_size
);
3047 return MACH_MSG_BODY_NULL
;
3051 * Skip port descriptors in scatter list.
3053 while (sstart
< send
) {
3054 if (sstart
->type
.type
!= MACH_MSG_PORT_DESCRIPTOR
)
3060 * No more scatter descriptors, we're done
3062 if (sstart
>= send
) {
3067 * Check type, copy and size fields
3069 if (g_type
== MACH_MSG_OOL_DESCRIPTOR
||
3070 g_type
== MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
3071 if (sstart
->type
.type
!= MACH_MSG_OOL_DESCRIPTOR
&&
3072 sstart
->type
.type
!= MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
3073 kfree(slist
, slist_size
);
3074 return MACH_MSG_BODY_NULL
;
3076 if (sstart
->out_of_line
.copy
== MACH_MSG_OVERWRITE
&&
3077 gstart
->out_of_line
.size
> sstart
->out_of_line
.size
) {
3078 kfree(slist
, slist_size
);
3079 return MACH_MSG_BODY_NULL
;
3083 if (sstart
->type
.type
!= MACH_MSG_OOL_PORTS_DESCRIPTOR
) {
3084 kfree(slist
, slist_size
);
3085 return MACH_MSG_BODY_NULL
;
3087 if (sstart
->ool_ports
.copy
== MACH_MSG_OVERWRITE
&&
3088 gstart
->ool_ports
.count
> sstart
->ool_ports
.count
) {
3089 kfree(slist
, slist_size
);
3090 return MACH_MSG_BODY_NULL
;
3102 * Routine: ipc_kmsg_free_scatter
3104 * Deallocate a scatter list. Since we actually allocated
3105 * a body without a header, and since the header was originally
3106 * accounted for in slist_size, we have to ajust it down
3107 * before freeing the scatter list.
3110 ipc_kmsg_free_scatter(
3111 mach_msg_body_t
*slist
,
3112 mach_msg_size_t slist_size
)
3114 slist_size
-= sizeof(mach_msg_header_t
);
3115 kfree(slist
, slist_size
);
3120 * Routine: ipc_kmsg_copyout_to_kernel
3122 * Copies out the destination and reply ports in the message.
3123 * Leaves all other rights and memory in the message alone.
3127 * Derived from ipc_kmsg_copyout_dest.
3128 * Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
3129 * We really do want to save rights and memory.
3133 ipc_kmsg_copyout_to_kernel(
3139 mach_msg_type_name_t dest_type
;
3140 mach_msg_type_name_t reply_type
;
3141 mach_port_name_t dest_name
, reply_name
;
3143 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
3144 reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
3145 dest_type
= MACH_MSGH_BITS_REMOTE(kmsg
->ikm_header
->msgh_bits
);
3146 reply_type
= MACH_MSGH_BITS_LOCAL(kmsg
->ikm_header
->msgh_bits
);
3148 assert(IO_VALID(dest
));
3151 if (io_active(dest
)) {
3152 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
3153 /* dest is unlocked */
3156 io_check_unlock(dest
);
3157 dest_name
= MACH_PORT_DEAD
;
3160 reply_name
= (mach_port_name_t
) reply
;
3162 kmsg
->ikm_header
->msgh_bits
=
3163 (MACH_MSGH_BITS_OTHER(kmsg
->ikm_header
->msgh_bits
) |
3164 MACH_MSGH_BITS(reply_type
, dest_type
));
3165 kmsg
->ikm_header
->msgh_local_port
= (ipc_port_t
)dest_name
;
3166 kmsg
->ikm_header
->msgh_remote_port
= (ipc_port_t
)reply_name
;
3169 #include <mach_kdb.h>
3172 #include <ddb/db_output.h>
3173 #include <ipc/ipc_print.h>
3175 * Forward declarations
3177 void ipc_msg_print_untyped(
3178 mach_msg_body_t
*body
);
3180 const char * ipc_type_name(
3182 boolean_t received
);
3184 void ipc_print_type_name(
3189 mach_msg_bits_t bit
);
3192 mm_copy_options_string(
3193 mach_msg_copy_options_t option
);
3195 void db_print_msg_uid(mach_msg_header_t
*);
3203 switch (type_name
) {
3204 case MACH_MSG_TYPE_PORT_NAME
:
3207 case MACH_MSG_TYPE_MOVE_RECEIVE
:
3209 return "port_receive";
3211 return "move_receive";
3214 case MACH_MSG_TYPE_MOVE_SEND
:
3221 case MACH_MSG_TYPE_MOVE_SEND_ONCE
:
3223 return "port_send_once";
3225 return "move_send_once";
3228 case MACH_MSG_TYPE_COPY_SEND
:
3231 case MACH_MSG_TYPE_MAKE_SEND
:
3234 case MACH_MSG_TYPE_MAKE_SEND_ONCE
:
3235 return "make_send_once";
3243 ipc_print_type_name(
3246 const char *name
= ipc_type_name(type_name
, TRUE
);
3250 printf("type%d", type_name
);
3255 * ipc_kmsg_print [ debug ]
3261 iprintf("kmsg=0x%x\n", kmsg
);
3262 iprintf("ikm_next=0x%x, prev=0x%x, size=%d",
3267 ipc_msg_print(kmsg
->ikm_header
);
3272 mach_msg_bits_t bit
)
3275 case MACH_MSGH_BITS_COMPLEX
: return "complex";
3276 case MACH_MSGH_BITS_CIRCULAR
: return "circular";
3277 default: return (char *) 0;
3282 * ipc_msg_print [ debug ]
3286 mach_msg_header_t
*msgh
)
3288 mach_msg_bits_t mbits
;
3289 unsigned int bit
, i
;
3290 const char *bit_name
;
3293 mbits
= msgh
->msgh_bits
;
3294 iprintf("msgh_bits=0x%x: l=0x%x,r=0x%x\n",
3296 MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
),
3297 MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
3299 mbits
= MACH_MSGH_BITS_OTHER(mbits
) & MACH_MSGH_BITS_USED
;
3302 iprintf("decoded bits: ");
3304 for (i
= 0, bit
= 1; i
< sizeof(mbits
) * 8; ++i
, bit
<<= 1) {
3305 if ((mbits
& bit
) == 0)
3307 bit_name
= msgh_bit_decode((mach_msg_bits_t
)bit
);
3309 printf("%s%s", needs_comma
? "," : "", bit_name
);
3311 printf("%sunknown(0x%x),", needs_comma
? "," : "", bit
);
3314 if (msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
) {
3315 printf("%sunused=0x%x,", needs_comma
? "," : "",
3316 msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
);
3322 if (msgh
->msgh_remote_port
) {
3323 iprintf("remote=0x%x(", msgh
->msgh_remote_port
);
3324 ipc_print_type_name(MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
3327 iprintf("remote=null");
3330 if (msgh
->msgh_local_port
) {
3331 printf("%slocal=0x%x(", needs_comma
? "," : "",
3332 msgh
->msgh_local_port
);
3333 ipc_print_type_name(MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
));
3336 printf("local=null\n");
3339 iprintf("msgh_id=%d, size=%d\n",
3343 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
3344 ipc_msg_print_untyped((mach_msg_body_t
*) (msgh
+ 1));
3350 mm_copy_options_string(
3351 mach_msg_copy_options_t option
)
3356 case MACH_MSG_PHYSICAL_COPY
:
3359 case MACH_MSG_VIRTUAL_COPY
:
3362 case MACH_MSG_OVERWRITE
:
3365 case MACH_MSG_ALLOCATE
:
3368 case MACH_MSG_KALLOC_COPY_T
:
3369 name
= "KALLOC_COPY_T";
3379 ipc_msg_print_untyped(
3380 mach_msg_body_t
*body
)
3382 mach_msg_descriptor_t
*saddr
, *send
;
3383 mach_msg_descriptor_type_t type
;
3385 iprintf("%d descriptors %d: \n", body
->msgh_descriptor_count
);
3387 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
3388 send
= saddr
+ body
->msgh_descriptor_count
;
3390 for ( ; saddr
< send
; saddr
++ ) {
3392 type
= saddr
->type
.type
;
3396 case MACH_MSG_PORT_DESCRIPTOR
: {
3397 mach_msg_port_descriptor_t
*dsc
;
3400 iprintf("-- PORT name = 0x%x disp = ", dsc
->name
);
3401 ipc_print_type_name(dsc
->disposition
);
3405 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
3406 case MACH_MSG_OOL_DESCRIPTOR
: {
3407 mach_msg_ool_descriptor_t
*dsc
;
3409 dsc
= &saddr
->out_of_line
;
3410 iprintf("-- OOL%s addr = 0x%x size = 0x%x copy = %s %s\n",
3411 type
== MACH_MSG_OOL_DESCRIPTOR
? "" : " VOLATILE",
3412 dsc
->address
, dsc
->size
,
3413 mm_copy_options_string(dsc
->copy
),
3414 dsc
->deallocate
? "DEALLOC" : "");
3417 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
3418 mach_msg_ool_ports_descriptor_t
*dsc
;
3420 dsc
= &saddr
->ool_ports
;
3422 iprintf("-- OOL_PORTS addr = 0x%x count = 0x%x ",
3423 dsc
->address
, dsc
->count
);
3425 ipc_print_type_name(dsc
->disposition
);
3426 printf(" copy = %s %s\n",
3427 mm_copy_options_string(dsc
->copy
),
3428 dsc
->deallocate
? "DEALLOC" : "");
3433 iprintf("-- UNKNOWN DESCRIPTOR 0x%x\n", type
);
3439 #endif /* MACH_KDB */