2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
27 * Mach Operating System
28 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
29 * All Rights Reserved.
31 * Permission to use, copy, modify and distribute this software and its
32 * documentation is hereby granted, provided that both the copyright
33 * notice and this permission notice appear in all copies of the
34 * software, derivative works or modified versions, and any portions
35 * thereof, and that both notices appear in supporting documentation.
37 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
38 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 * Carnegie Mellon requests users of this software to return to
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
48 * any improvements or extensions that they make and grant Carnegie Mellon
49 * the rights to redistribute these changes.
54 * File: ipc/ipc_kmsg.c
58 * Operations on kernel messages.
63 #include <mach/mach_types.h>
64 #include <mach/boolean.h>
65 #include <mach/kern_return.h>
66 #include <mach/message.h>
67 #include <mach/port.h>
68 #include <mach/vm_map.h>
69 #include <mach/mach_vm.h>
70 #include <mach/vm_statistics.h>
72 #include <kern/kern_types.h>
73 #include <kern/assert.h>
74 #include <kern/ipc_kobject.h>
75 #include <kern/kalloc.h>
76 #include <kern/zalloc.h>
77 #include <kern/processor.h>
78 #include <kern/thread.h>
79 #include <kern/sched_prim.h>
81 #include <kern/misc_protos.h>
82 #include <kern/counters.h>
83 #include <kern/cpu_data.h>
85 #include <vm/vm_map.h>
86 #include <vm/vm_object.h>
87 #include <vm/vm_kern.h>
90 #include <ipc/ipc_types.h>
91 #include <ipc/ipc_entry.h>
92 #include <ipc/ipc_kmsg.h>
93 #include <ipc/ipc_notify.h>
94 #include <ipc/ipc_object.h>
95 #include <ipc/ipc_space.h>
96 #include <ipc/ipc_port.h>
97 #include <ipc/ipc_right.h>
98 #include <ipc/ipc_hash.h>
99 #include <ipc/ipc_table.h>
104 #include <ppc/Firmware.h>
105 #include <ppc/low_trace.h>
109 extern vm_map_t ipc_kernel_copy_map
;
110 extern vm_size_t ipc_kmsg_max_vm_space
;
111 extern vm_size_t msg_ool_size_small
;
113 #define MSG_OOL_SIZE_SMALL msg_ool_size_small
115 #if defined(__LP64__)
116 #define MAP_SIZE_DIFFERS(map) (map->max_offset < MACH_VM_MAX_ADDRESS)
117 #define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor32_t
118 #define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor32_t
120 #define MAP_SIZE_DIFFERS(map) (map->max_offset > VM_MAX_ADDRESS)
121 #define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor64_t
122 #define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor64_t
125 #define DESC_SIZE_ADJUSTMENT (sizeof(OTHER_OOL_DESCRIPTOR) - \
126 sizeof(mach_msg_ool_descriptor_t))
128 /* scatter list macros */
130 #define SKIP_PORT_DESCRIPTORS(s, c) \
132 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
134 if ((s)->type.type != MACH_MSG_PORT_DESCRIPTOR) \
139 (s) = MACH_MSG_DESCRIPTOR_NULL; \
143 #define INCREMENT_SCATTER(s, c, d) \
145 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
146 s = (d) ? (mach_msg_descriptor_t *) \
147 ((OTHER_OOL_DESCRIPTOR *)(s) + 1) : \
153 /* zone for cached ipc_kmsg_t structures */
154 zone_t ipc_kmsg_zone
;
157 * Forward declarations
163 void ipc_kmsg_clean_body(
165 mach_msg_type_number_t number
,
166 mach_msg_descriptor_t
*desc
);
168 void ipc_kmsg_clean_partial(
170 mach_msg_type_number_t number
,
171 mach_msg_descriptor_t
*desc
,
175 mach_msg_return_t
ipc_kmsg_copyin_body(
181 * We keep a per-processor cache of kernel message buffers.
182 * The cache saves the overhead/locking of using kalloc/kfree.
183 * The per-processor cache seems to miss less than a per-thread cache,
184 * and it also uses less memory. Access to the cache doesn't
189 * Routine: ipc_kmsg_alloc
191 * Allocate a kernel message structure. If we can get one from
192 * the cache, that is best. Otherwise, allocate a new one.
198 mach_msg_size_t msg_and_trailer_size
)
200 mach_msg_size_t max_expanded_size
;
203 #if !defined(__LP64__)
204 mach_msg_size_t size
= msg_and_trailer_size
- MAX_TRAILER_SIZE
;
208 * Pad the allocation in case we need to expand the
209 * message descrptors for user spaces with pointers larger than
210 * the kernel's own. We don't know how many descriptors
211 * there are yet, so just assume the whole body could be
212 * descriptors (if there could be any at all).
214 * The expansion space is left in front of the header,
215 * because it is easier to pull the header and descriptors
216 * forward as we process them than it is to push all the
220 (size
> sizeof(mach_msg_base_t
)) ?
221 (msg_and_trailer_size
+ DESC_SIZE_ADJUSTMENT
*
222 ((size
- sizeof(mach_msg_base_t
)) /
223 (sizeof(mach_msg_ool_descriptor_t
))))
225 (msg_and_trailer_size
);
227 max_expanded_size
= msg_and_trailer_size
;
230 /* round up for ikm_cache */
231 if (max_expanded_size
< IKM_SAVED_MSG_SIZE
)
232 max_expanded_size
= IKM_SAVED_MSG_SIZE
;
234 if (max_expanded_size
== IKM_SAVED_MSG_SIZE
) {
235 struct ikm_cache
*cache
;
238 disable_preemption();
239 cache
= &PROCESSOR_DATA(current_processor(), ikm_cache
);
240 if ((i
= cache
->avail
) > 0) {
241 assert(i
<= IKM_STASH
);
242 kmsg
= cache
->entries
[--i
];
244 ikm_check_init(kmsg
, max_expanded_size
);
246 kmsg
->ikm_header
= (mach_msg_header_t
*)
247 ((vm_offset_t
)(kmsg
+ 1) +
249 msg_and_trailer_size
);
253 kmsg
= (ipc_kmsg_t
)zalloc(ipc_kmsg_zone
);
255 kmsg
= (ipc_kmsg_t
)kalloc(ikm_plus_overhead(max_expanded_size
));
258 if (kmsg
!= IKM_NULL
) {
259 ikm_init(kmsg
, max_expanded_size
);
260 kmsg
->ikm_header
= (mach_msg_header_t
*)
261 ((vm_offset_t
)(kmsg
+ 1) +
263 msg_and_trailer_size
);
269 * Routine: ipc_kmsg_free
271 * Free a kernel message buffer. If the kms is preallocated
272 * to a port, just "put it back (marked unused)." We have to
273 * do this with the port locked. The port may have its hold
274 * on our message released. In that case, we have to just
275 * revert the message to a traditional one and free it normally.
284 mach_msg_size_t size
= kmsg
->ikm_size
;
288 * Check to see if the message is bound to the port. If so,
289 * mark it not in use. If the port isn't already dead, then
290 * leave the message associated with it. Otherwise, free it.
292 port
= ikm_prealloc_inuse_port(kmsg
);
293 if (port
!= IP_NULL
) {
295 ikm_prealloc_clear_inuse(kmsg
, port
);
296 if (ip_active(port
) && (port
->ip_premsg
== kmsg
)) {
297 assert(IP_PREALLOC(port
));
301 ip_check_unlock(port
); /* May be last reference */
305 * Peek and see if it has to go back in the cache.
307 if (kmsg
->ikm_size
== IKM_SAVED_MSG_SIZE
) {
308 struct ikm_cache
*cache
;
311 disable_preemption();
312 cache
= &PROCESSOR_DATA(current_processor(), ikm_cache
);
313 if ((i
= cache
->avail
) < IKM_STASH
) {
314 cache
->entries
[i
] = kmsg
;
315 cache
->avail
= i
+ 1;
320 zfree(ipc_kmsg_zone
, kmsg
);
323 kfree(kmsg
, ikm_plus_overhead(size
));
328 * Routine: ipc_kmsg_enqueue
335 ipc_kmsg_queue_t queue
,
338 ipc_kmsg_enqueue_macro(queue
, kmsg
);
342 * Routine: ipc_kmsg_dequeue
344 * Dequeue and return a kmsg.
349 ipc_kmsg_queue_t queue
)
353 first
= ipc_kmsg_queue_first(queue
);
355 if (first
!= IKM_NULL
)
356 ipc_kmsg_rmqueue_first_macro(queue
, first
);
362 * Routine: ipc_kmsg_rmqueue
364 * Pull a kmsg out of a queue.
369 ipc_kmsg_queue_t queue
,
372 ipc_kmsg_t next
, prev
;
374 assert(queue
->ikmq_base
!= IKM_NULL
);
376 next
= kmsg
->ikm_next
;
377 prev
= kmsg
->ikm_prev
;
380 assert(prev
== kmsg
);
381 assert(queue
->ikmq_base
== kmsg
);
383 queue
->ikmq_base
= IKM_NULL
;
385 if (queue
->ikmq_base
== kmsg
)
386 queue
->ikmq_base
= next
;
388 next
->ikm_prev
= prev
;
389 prev
->ikm_next
= next
;
391 /* XXX Temporary debug logic */
392 assert(kmsg
->ikm_next
= IKM_BOGUS
);
393 assert(kmsg
->ikm_prev
= IKM_BOGUS
);
397 * Routine: ipc_kmsg_queue_next
399 * Return the kmsg following the given kmsg.
400 * (Or IKM_NULL if it is the last one in the queue.)
405 ipc_kmsg_queue_t queue
,
410 assert(queue
->ikmq_base
!= IKM_NULL
);
412 next
= kmsg
->ikm_next
;
413 if (queue
->ikmq_base
== next
)
420 * Routine: ipc_kmsg_destroy
422 * Destroys a kernel message. Releases all rights,
423 * references, and memory held by the message.
433 ipc_kmsg_queue_t queue
;
437 * ipc_kmsg_clean can cause more messages to be destroyed.
438 * Curtail recursion by queueing messages. If a message
439 * is already queued, then this is a recursive call.
442 queue
= &(current_thread()->ith_messages
);
443 empty
= ipc_kmsg_queue_empty(queue
);
444 ipc_kmsg_enqueue(queue
, kmsg
);
447 /* must leave kmsg in queue while cleaning it */
449 while ((kmsg
= ipc_kmsg_queue_first(queue
)) != IKM_NULL
) {
450 ipc_kmsg_clean(kmsg
);
451 ipc_kmsg_rmqueue(queue
, kmsg
);
458 * Routine: ipc_kmsg_destroy_dest
460 * Destroys a kernel message. Releases all rights,
461 * references, and memory held by the message (including
462 * the destination port reference.
468 ipc_kmsg_destroy_dest(
473 port
= kmsg
->ikm_header
->msgh_remote_port
;
475 ipc_port_release(port
);
476 kmsg
->ikm_header
->msgh_remote_port
= MACH_PORT_NULL
;
477 ipc_kmsg_destroy(kmsg
);
481 * Routine: ipc_kmsg_clean_body
483 * Cleans the body of a kernel message.
484 * Releases all rights, references, and memory.
492 __unused ipc_kmsg_t kmsg
,
493 mach_msg_type_number_t number
,
494 mach_msg_descriptor_t
*saddr
)
496 mach_msg_descriptor_t
*eaddr
;
501 eaddr
= saddr
+ number
;
503 for ( ; saddr
< eaddr
; saddr
++ ) {
505 switch (saddr
->type
.type
) {
507 case MACH_MSG_PORT_DESCRIPTOR
: {
508 mach_msg_port_descriptor_t
*dsc
;
513 * Destroy port rights carried in the message
515 if (!IO_VALID((ipc_object_t
) dsc
->name
))
517 ipc_object_destroy((ipc_object_t
) dsc
->name
, dsc
->disposition
);
520 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
521 case MACH_MSG_OOL_DESCRIPTOR
: {
522 mach_msg_ool_descriptor_t
*dsc
;
524 dsc
= &saddr
->out_of_line
;
527 * Destroy memory carried in the message
529 if (dsc
->size
== 0) {
530 assert(dsc
->address
== (void *) 0);
532 vm_map_copy_discard((vm_map_copy_t
) dsc
->address
);
536 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
537 ipc_object_t
*objects
;
538 mach_msg_type_number_t j
;
539 mach_msg_ool_ports_descriptor_t
*dsc
;
541 dsc
= &saddr
->ool_ports
;
542 objects
= (ipc_object_t
*) dsc
->address
;
544 if (dsc
->count
== 0) {
548 assert(objects
!= (ipc_object_t
*) 0);
550 /* destroy port rights carried in the message */
552 for (j
= 0; j
< dsc
->count
; j
++) {
553 ipc_object_t object
= objects
[j
];
555 if (!IO_VALID(object
))
558 ipc_object_destroy(object
, dsc
->disposition
);
561 /* destroy memory carried in the message */
563 assert(dsc
->count
!= 0);
566 (vm_size_t
) dsc
->count
* sizeof(mach_port_name_t
));
570 printf("cleanup: don't understand this type of descriptor\n");
577 * Routine: ipc_kmsg_clean_partial
579 * Cleans a partially-acquired kernel message.
580 * number is the index of the type descriptor
581 * in the body of the message that contained the error.
582 * If dolast, the memory and port rights in this last
583 * type spec are also cleaned. In that case, number
584 * specifies the number of port rights to clean.
590 ipc_kmsg_clean_partial(
592 mach_msg_type_number_t number
,
593 mach_msg_descriptor_t
*desc
,
598 mach_msg_bits_t mbits
= kmsg
->ikm_header
->msgh_bits
;
600 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
601 assert(IO_VALID(object
));
602 ipc_object_destroy(object
, MACH_MSGH_BITS_REMOTE(mbits
));
604 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
605 if (IO_VALID(object
))
606 ipc_object_destroy(object
, MACH_MSGH_BITS_LOCAL(mbits
));
609 (void) vm_deallocate(ipc_kernel_copy_map
, paddr
, length
);
612 ipc_kmsg_clean_body(kmsg
, number
, desc
);
616 * Routine: ipc_kmsg_clean
618 * Cleans a kernel message. Releases all rights,
619 * references, and memory held by the message.
629 mach_msg_bits_t mbits
;
631 mbits
= kmsg
->ikm_header
->msgh_bits
;
632 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
633 if (IO_VALID(object
))
634 ipc_object_destroy(object
, MACH_MSGH_BITS_REMOTE(mbits
));
636 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
637 if (IO_VALID(object
))
638 ipc_object_destroy(object
, MACH_MSGH_BITS_LOCAL(mbits
));
640 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
641 mach_msg_body_t
*body
;
643 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
644 ipc_kmsg_clean_body(kmsg
, body
->msgh_descriptor_count
,
645 (mach_msg_descriptor_t
*)(body
+ 1));
650 * Routine: ipc_kmsg_set_prealloc
652 * Assign a kmsg as a preallocated message buffer to a port.
658 ipc_kmsg_set_prealloc(
662 assert(kmsg
->ikm_prealloc
== IP_NULL
);
664 kmsg
->ikm_prealloc
= IP_NULL
;
665 IP_SET_PREALLOC(port
, kmsg
);
669 * Routine: ipc_kmsg_clear_prealloc
671 * Release the Assignment of a preallocated message buffer from a port.
676 ipc_kmsg_clear_prealloc(
680 assert(kmsg
->ikm_prealloc
== port
);
682 kmsg
->ikm_prealloc
= IP_NULL
;
683 IP_CLEAR_PREALLOC(port
, kmsg
);
689 * Routine: ipc_kmsg_get
691 * Allocates a kernel message buffer.
692 * Copies a user message to the message buffer.
696 * MACH_MSG_SUCCESS Acquired a message buffer.
697 * MACH_SEND_MSG_TOO_SMALL Message smaller than a header.
698 * MACH_SEND_MSG_TOO_SMALL Message size not long-word multiple.
699 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
700 * MACH_SEND_INVALID_DATA Couldn't copy message data.
705 mach_vm_address_t msg_addr
,
706 mach_msg_size_t size
,
709 mach_msg_size_t msg_and_trailer_size
;
711 mach_msg_max_trailer_t
*trailer
;
713 if ((size
< sizeof(mach_msg_header_t
)) || (size
& 3))
714 return MACH_SEND_MSG_TOO_SMALL
;
716 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
718 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
720 if (kmsg
== IKM_NULL
)
721 return MACH_SEND_NO_BUFFER
;
723 if (copyinmsg(msg_addr
, (char *) kmsg
->ikm_header
, size
)) {
725 return MACH_SEND_INVALID_DATA
;
728 kmsg
->ikm_header
->msgh_size
= size
;
731 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
732 * However, the internal size field of the trailer (msgh_trailer_size)
733 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize
734 * the cases where no implicit data is requested.
736 trailer
= (mach_msg_max_trailer_t
*) ((vm_offset_t
)kmsg
->ikm_header
+ size
);
737 trailer
->msgh_sender
= current_thread()->task
->sec_token
;
738 trailer
->msgh_audit
= current_thread()->task
->audit_token
;
739 trailer
->msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
740 trailer
->msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
743 if(trcWork
.traceMask
) dbgTrace(0x1100, (unsigned int)kmsg
->ikm_header
->msgh_id
,
744 (unsigned int)kmsg
->ikm_header
->msgh_remote_port
,
745 (unsigned int)kmsg
->ikm_header
->msgh_local_port
, 0);
748 return MACH_MSG_SUCCESS
;
752 * Routine: ipc_kmsg_get_from_kernel
754 * First checks for a preallocated message
755 * reserved for kernel clients. If not found -
756 * allocates a new kernel message buffer.
757 * Copies a kernel message to the message buffer.
758 * Only resource errors are allowed.
761 * Ports in header are ipc_port_t.
763 * MACH_MSG_SUCCESS Acquired a message buffer.
764 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
768 ipc_kmsg_get_from_kernel(
769 mach_msg_header_t
*msg
,
770 mach_msg_size_t size
,
774 mach_msg_size_t msg_and_trailer_size
;
775 mach_msg_max_trailer_t
*trailer
;
776 ipc_port_t dest_port
;
778 assert(size
>= sizeof(mach_msg_header_t
));
779 // assert((size & 3) == 0);
781 assert(IP_VALID((ipc_port_t
) msg
->msgh_remote_port
));
782 dest_port
= (ipc_port_t
)msg
->msgh_remote_port
;
784 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
787 * See if the port has a pre-allocated kmsg for kernel
788 * clients. These are set up for those kernel clients
789 * which cannot afford to wait.
791 if (IP_PREALLOC(dest_port
)) {
793 if (!ip_active(dest_port
)) {
794 ip_unlock(dest_port
);
795 return MACH_SEND_NO_BUFFER
;
797 assert(IP_PREALLOC(dest_port
));
798 kmsg
= dest_port
->ip_premsg
;
799 if (msg_and_trailer_size
> kmsg
->ikm_size
) {
800 ip_unlock(dest_port
);
801 return MACH_SEND_TOO_LARGE
;
803 if (ikm_prealloc_inuse(kmsg
)) {
804 ip_unlock(dest_port
);
805 return MACH_SEND_NO_BUFFER
;
807 ikm_prealloc_set_inuse(kmsg
, dest_port
);
808 ip_unlock(dest_port
);
810 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
811 if (kmsg
== IKM_NULL
)
812 return MACH_SEND_NO_BUFFER
;
815 (void) memcpy((void *) kmsg
->ikm_header
, (const void *) msg
, size
);
817 kmsg
->ikm_header
->msgh_size
= size
;
820 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
821 * However, the internal size field of the trailer (msgh_trailer_size)
822 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to
823 * optimize the cases where no implicit data is requested.
825 trailer
= (mach_msg_max_trailer_t
*)
826 ((vm_offset_t
)kmsg
->ikm_header
+ size
);
827 trailer
->msgh_sender
= KERNEL_SECURITY_TOKEN
;
828 trailer
->msgh_audit
= KERNEL_AUDIT_TOKEN
;
829 trailer
->msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
830 trailer
->msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
833 return MACH_MSG_SUCCESS
;
837 * Routine: ipc_kmsg_send
839 * Send a message. The message holds a reference
840 * for the destination port in the msgh_remote_port field.
842 * If unsuccessful, the caller still has possession of
843 * the message and must do something with it. If successful,
844 * the message is queued, given to a receiver, destroyed,
845 * or handled directly by the kernel via mach_msg.
849 * MACH_MSG_SUCCESS The message was accepted.
850 * MACH_SEND_TIMED_OUT Caller still has message.
851 * MACH_SEND_INTERRUPTED Caller still has message.
856 mach_msg_option_t option
,
857 mach_msg_timeout_t send_timeout
)
861 port
= (ipc_port_t
) kmsg
->ikm_header
->msgh_remote_port
;
862 assert(IP_VALID(port
));
866 if (port
->ip_receiver
== ipc_space_kernel
) {
869 * We can check ip_receiver == ipc_space_kernel
870 * before checking that the port is active because
871 * ipc_port_dealloc_kernel clears ip_receiver
872 * before destroying a kernel port.
874 assert(ip_active(port
));
875 port
->ip_messages
.imq_seqno
++;
878 current_task()->messages_sent
++;
881 * Call the server routine, and get the reply message to send.
883 kmsg
= ipc_kobject_server(kmsg
);
884 if (kmsg
== IKM_NULL
)
885 return MACH_MSG_SUCCESS
;
887 port
= (ipc_port_t
) kmsg
->ikm_header
->msgh_remote_port
;
888 assert(IP_VALID(port
));
890 /* fall thru with reply - same options */
894 * Can't deliver to a dead port.
895 * However, we can pretend it got sent
896 * and was then immediately destroyed.
898 if (!ip_active(port
)) {
900 * We can't let ipc_kmsg_destroy deallocate
901 * the port right, because we might end up
902 * in an infinite loop trying to deliver
903 * a send-once notification.
907 ip_check_unlock(port
);
908 kmsg
->ikm_header
->msgh_remote_port
= MACH_PORT_NULL
;
909 ipc_kmsg_destroy(kmsg
);
910 return MACH_MSG_SUCCESS
;
913 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_CIRCULAR
) {
916 /* don't allow the creation of a circular loop */
918 ipc_kmsg_destroy(kmsg
);
919 return MACH_MSG_SUCCESS
;
923 * We have a valid message and a valid reference on the port.
924 * we can unlock the port and call mqueue_send() on it's message
928 return (ipc_mqueue_send(&port
->ip_messages
, kmsg
, option
, send_timeout
));
932 * Routine: ipc_kmsg_put
934 * Copies a message buffer to a user message.
935 * Copies only the specified number of bytes.
936 * Frees the message buffer.
938 * Nothing locked. The message buffer must have clean
941 * MACH_MSG_SUCCESS Copied data out of message buffer.
942 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
947 mach_vm_address_t msg_addr
,
949 mach_msg_size_t size
)
951 mach_msg_return_t mr
;
953 if (copyoutmsg((const char *) kmsg
->ikm_header
, msg_addr
, size
))
954 mr
= MACH_RCV_INVALID_DATA
;
956 mr
= MACH_MSG_SUCCESS
;
963 * Routine: ipc_kmsg_put_to_kernel
965 * Copies a message buffer to a kernel message.
966 * Frees the message buffer.
973 ipc_kmsg_put_to_kernel(
974 mach_msg_header_t
*msg
,
976 mach_msg_size_t size
)
978 (void) memcpy((void *) msg
, (const void *) kmsg
->ikm_header
, size
);
984 * Routine: ipc_kmsg_copyin_header
986 * "Copy-in" port rights in the header of a message.
987 * Operates atomically; if it doesn't succeed the
988 * message header and the space are left untouched.
989 * If it does succeed the remote/local port fields
990 * contain object pointers instead of port names,
991 * and the bits field is updated. The destination port
992 * will be a valid port pointer.
994 * The notify argument implements the MACH_SEND_CANCEL option.
995 * If it is not MACH_PORT_NULL, it should name a receive right.
996 * If the processing of the destination port would generate
997 * a port-deleted notification (because the right for the
998 * destination port is destroyed and it had a request for
999 * a dead-name notification registered), and the port-deleted
1000 * notification would be sent to the named receive right,
1001 * then it isn't sent and the send-once right for the notify
1002 * port is quietly destroyed.
1007 * MACH_MSG_SUCCESS Successful copyin.
1008 * MACH_SEND_INVALID_HEADER
1009 * Illegal value in the message header bits.
1010 * MACH_SEND_INVALID_DEST The space is dead.
1011 * MACH_SEND_INVALID_NOTIFY
1012 * Notify is non-null and doesn't name a receive right.
1013 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1014 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1015 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1016 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1017 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1021 ipc_kmsg_copyin_header(
1022 mach_msg_header_t
*msg
,
1024 mach_port_name_t notify
)
1026 mach_msg_bits_t mbits
= msg
->msgh_bits
& MACH_MSGH_BITS_USER
;
1027 mach_port_name_t dest_name
= (mach_port_name_t
)msg
->msgh_remote_port
;
1028 mach_port_name_t reply_name
= (mach_port_name_t
)msg
->msgh_local_port
;
1031 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
1032 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
1033 ipc_object_t dest_port
, reply_port
;
1034 ipc_port_t dest_soright
, reply_soright
;
1035 ipc_port_t notify_port
;
1037 if ((mbits
!= msg
->msgh_bits
) ||
1038 (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type
)) ||
1039 ((reply_type
== 0) ?
1040 (reply_name
!= MACH_PORT_NULL
) :
1041 !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type
)))
1042 return MACH_SEND_INVALID_HEADER
;
1044 reply_soright
= IP_NULL
; /* in case we go to invalid dest early */
1046 is_write_lock(space
);
1047 if (!space
->is_active
)
1050 if (!MACH_PORT_VALID(dest_name
))
1053 if (notify
!= MACH_PORT_NULL
) {
1056 if ((entry
= ipc_entry_lookup(space
, notify
)) == IE_NULL
) {
1057 is_write_unlock(space
);
1058 return MACH_SEND_INVALID_NOTIFY
;
1060 if((entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
) == 0) {
1061 is_write_unlock(space
);
1062 return MACH_SEND_INVALID_NOTIFY
;
1065 notify_port
= (ipc_port_t
) entry
->ie_object
;
1067 notify_port
= IP_NULL
;
1069 if (dest_name
== reply_name
) {
1071 mach_port_name_t name
= dest_name
;
1074 * Destination and reply ports are the same!
1075 * This is a little tedious to make atomic, because
1076 * there are 25 combinations of dest_type/reply_type.
1077 * However, most are easy. If either is move-sonce,
1078 * then there must be an error. If either are
1079 * make-send or make-sonce, then we must be looking
1080 * at a receive right so the port can't die.
1081 * The hard cases are the combinations of
1082 * copy-send and make-send.
1085 entry
= ipc_entry_lookup(space
, name
);
1086 if (entry
== IE_NULL
)
1089 assert(reply_type
!= 0); /* because name not null */
1091 if (!ipc_right_copyin_check(space
, name
, entry
, reply_type
))
1094 if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
) ||
1095 (reply_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
)) {
1097 * Why must there be an error? To get a valid
1098 * destination, this entry must name a live
1099 * port (not a dead name or dead port). However
1100 * a successful move-sonce will destroy a
1101 * live entry. Therefore the other copyin,
1102 * whatever it is, would fail. We've already
1103 * checked for reply port errors above,
1104 * so report a destination error.
1108 } else if ((dest_type
== MACH_MSG_TYPE_MAKE_SEND
) ||
1109 (dest_type
== MACH_MSG_TYPE_MAKE_SEND_ONCE
) ||
1110 (reply_type
== MACH_MSG_TYPE_MAKE_SEND
) ||
1111 (reply_type
== MACH_MSG_TYPE_MAKE_SEND_ONCE
)) {
1112 kr
= ipc_right_copyin(space
, name
, entry
,
1114 &dest_port
, &dest_soright
);
1115 if (kr
!= KERN_SUCCESS
)
1119 * Either dest or reply needs a receive right.
1120 * We know the receive right is there, because
1121 * of the copyin_check and copyin calls. Hence
1122 * the port is not in danger of dying. If dest
1123 * used the receive right, then the right needed
1124 * by reply (and verified by copyin_check) will
1128 assert(IO_VALID(dest_port
));
1129 assert(entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
);
1130 assert(dest_soright
== IP_NULL
);
1132 kr
= ipc_right_copyin(space
, name
, entry
,
1134 &reply_port
, &reply_soright
);
1136 assert(kr
== KERN_SUCCESS
);
1137 assert(reply_port
== dest_port
);
1138 assert(entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
);
1139 assert(reply_soright
== IP_NULL
);
1140 } else if ((dest_type
== MACH_MSG_TYPE_COPY_SEND
) &&
1141 (reply_type
== MACH_MSG_TYPE_COPY_SEND
)) {
1143 * To make this atomic, just do one copy-send,
1144 * and dup the send right we get out.
1147 kr
= ipc_right_copyin(space
, name
, entry
,
1149 &dest_port
, &dest_soright
);
1150 if (kr
!= KERN_SUCCESS
)
1153 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND
);
1154 assert(dest_soright
== IP_NULL
);
1157 * It's OK if the port we got is dead now,
1158 * so reply_port is IP_DEAD, because the msg
1159 * won't go anywhere anyway.
1162 reply_port
= (ipc_object_t
)
1163 ipc_port_copy_send((ipc_port_t
) dest_port
);
1164 reply_soright
= IP_NULL
;
1165 } else if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND
) &&
1166 (reply_type
== MACH_MSG_TYPE_MOVE_SEND
)) {
1168 * This is an easy case. Just use our
1169 * handy-dandy special-purpose copyin call
1170 * to get two send rights for the price of one.
1173 kr
= ipc_right_copyin_two(space
, name
, entry
,
1174 &dest_port
, &dest_soright
);
1175 if (kr
!= KERN_SUCCESS
)
1178 /* the entry might need to be deallocated */
1179 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1180 ipc_entry_dealloc(space
, name
, entry
);
1182 reply_port
= dest_port
;
1183 reply_soright
= IP_NULL
;
1187 assert(((dest_type
== MACH_MSG_TYPE_COPY_SEND
) &&
1188 (reply_type
== MACH_MSG_TYPE_MOVE_SEND
)) ||
1189 ((dest_type
== MACH_MSG_TYPE_MOVE_SEND
) &&
1190 (reply_type
== MACH_MSG_TYPE_COPY_SEND
)));
1193 * To make this atomic, just do a move-send,
1194 * and dup the send right we get out.
1197 kr
= ipc_right_copyin(space
, name
, entry
,
1198 MACH_MSG_TYPE_MOVE_SEND
, FALSE
,
1199 &dest_port
, &soright
);
1200 if (kr
!= KERN_SUCCESS
)
1203 /* the entry might need to be deallocated */
1205 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1206 ipc_entry_dealloc(space
, name
, entry
);
1209 * It's OK if the port we got is dead now,
1210 * so reply_port is IP_DEAD, because the msg
1211 * won't go anywhere anyway.
1214 reply_port
= (ipc_object_t
)
1215 ipc_port_copy_send((ipc_port_t
) dest_port
);
1217 if (dest_type
== MACH_MSG_TYPE_MOVE_SEND
) {
1218 dest_soright
= soright
;
1219 reply_soright
= IP_NULL
;
1221 dest_soright
= IP_NULL
;
1222 reply_soright
= soright
;
1225 } else if (!MACH_PORT_VALID(reply_name
)) {
1229 * No reply port! This is an easy case
1230 * to make atomic. Just copyin the destination.
1233 entry
= ipc_entry_lookup(space
, dest_name
);
1234 if (entry
== IE_NULL
)
1237 kr
= ipc_right_copyin(space
, dest_name
, entry
,
1239 &dest_port
, &dest_soright
);
1240 if (kr
!= KERN_SUCCESS
)
1243 /* the entry might need to be deallocated */
1245 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1246 ipc_entry_dealloc(space
, dest_name
, entry
);
1248 reply_port
= (ipc_object_t
) reply_name
;
1249 reply_soright
= IP_NULL
;
1251 ipc_entry_t dest_entry
, reply_entry
;
1254 * This is the tough case to make atomic.
1255 * The difficult problem is serializing with port death.
1256 * At the time we copyin dest_port, it must be alive.
1257 * If reply_port is alive when we copyin it, then
1258 * we are OK, because we serialize before the death
1259 * of both ports. Assume reply_port is dead at copyin.
1260 * Then if dest_port dies/died after reply_port died,
1261 * we are OK, because we serialize between the death
1262 * of the two ports. So the bad case is when dest_port
1263 * dies after its copyin, reply_port dies before its
1264 * copyin, and dest_port dies before reply_port. Then
1265 * the copyins operated as if dest_port was alive
1266 * and reply_port was dead, which shouldn't have happened
1267 * because they died in the other order.
1269 * Note that it is easy for a user task to tell if
1270 * a copyin happened before or after a port died.
1271 * For example, suppose both dest and reply are
1272 * send-once rights (types are both move-sonce) and
1273 * both rights have dead-name requests registered.
1274 * If a port dies before copyin, a dead-name notification
1275 * is generated and the dead name's urefs are incremented,
1276 * and if the copyin happens first, a port-deleted
1277 * notification is generated.
1279 * Note that although the entries are different,
1280 * dest_port and reply_port might still be the same.
1282 * JMM - The code to handle this was too expensive and, anyway,
1283 * we intend to separate the dest lookup from the reply copyin
1284 * by a wide margin, so the user will have to learn to deal!
1285 * I will be making the change soon!
1288 dest_entry
= ipc_entry_lookup(space
, dest_name
);
1289 if (dest_entry
== IE_NULL
)
1292 reply_entry
= ipc_entry_lookup(space
, reply_name
);
1293 if (reply_entry
== IE_NULL
)
1296 assert(dest_entry
!= reply_entry
); /* names are not equal */
1297 assert(reply_type
!= 0); /* because reply_name not null */
1299 if (!ipc_right_copyin_check(space
, reply_name
, reply_entry
,
1303 kr
= ipc_right_copyin(space
, dest_name
, dest_entry
,
1305 &dest_port
, &dest_soright
);
1306 if (kr
!= KERN_SUCCESS
)
1309 assert(IO_VALID(dest_port
));
1311 kr
= ipc_right_copyin(space
, reply_name
, reply_entry
,
1313 &reply_port
, &reply_soright
);
1315 assert(kr
== KERN_SUCCESS
);
1317 /* the entries might need to be deallocated */
1319 if (IE_BITS_TYPE(reply_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1320 ipc_entry_dealloc(space
, reply_name
, reply_entry
);
1322 if (IE_BITS_TYPE(dest_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1323 ipc_entry_dealloc(space
, dest_name
, dest_entry
);
1327 * At this point, dest_port, reply_port,
1328 * dest_soright, reply_soright are all initialized.
1329 * Any defunct entries have been deallocated.
1330 * The space is still write-locked, and we need to
1331 * make the MACH_SEND_CANCEL check. The notify_port pointer
1332 * is still usable, because the copyin code above won't ever
1333 * deallocate a receive right, so its entry still exists
1334 * and holds a ref. Note notify_port might even equal
1335 * dest_port or reply_port.
1338 if ((notify
!= MACH_PORT_NULL
) &&
1339 (dest_soright
== notify_port
)) {
1340 ipc_port_release_sonce(dest_soright
);
1341 dest_soright
= IP_NULL
;
1344 is_write_unlock(space
);
1346 if (dest_soright
!= IP_NULL
)
1347 ipc_notify_port_deleted(dest_soright
, dest_name
);
1349 if (reply_soright
!= IP_NULL
)
1350 ipc_notify_port_deleted(reply_soright
, reply_name
);
1352 dest_type
= ipc_object_copyin_type(dest_type
);
1353 reply_type
= ipc_object_copyin_type(reply_type
);
1355 msg
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
1356 MACH_MSGH_BITS(dest_type
, reply_type
));
1357 msg
->msgh_remote_port
= (ipc_port_t
)dest_port
;
1358 msg
->msgh_local_port
= (ipc_port_t
)reply_port
;
1360 return MACH_MSG_SUCCESS
;
1363 is_write_unlock(space
);
1364 return MACH_SEND_INVALID_REPLY
;
1367 is_write_unlock(space
);
1368 if (reply_soright
!= IP_NULL
)
1369 ipc_notify_port_deleted(reply_soright
, reply_name
);
1370 return MACH_SEND_INVALID_DEST
;
1374 * Routine: ipc_kmsg_copyin_body
1376 * "Copy-in" port rights and out-of-line memory
1377 * in the message body.
1379 * In all failure cases, the message is left holding
1380 * no rights or memory. However, the message buffer
1381 * is not deallocated. If successful, the message
1382 * contains a valid destination port.
1386 * MACH_MSG_SUCCESS Successful copyin.
1387 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
1388 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
1389 * MACH_SEND_INVALID_TYPE Bad type specification.
1390 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
1391 * MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
1392 * MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
1395 #define DESC_COUNT_SMALL 64
1398 ipc_kmsg_copyin_body(
1404 mach_msg_body_t
*body
;
1405 mach_msg_descriptor_t
*daddr
, *naddr
;
1406 mach_msg_type_number_t dsc_count
;
1407 boolean_t differs
= MAP_SIZE_DIFFERS(map
);
1408 boolean_t
complex = FALSE
;
1409 vm_size_t space_needed
= 0;
1410 vm_size_t desc_size_space
[DESC_COUNT_SMALL
];
1411 vm_size_t
*user_desc_sizes
= NULL
;
1412 vm_offset_t paddr
= 0;
1413 vm_map_copy_t copy
= VM_MAP_COPY_NULL
;
1415 mach_msg_type_number_t i
;
1416 mach_msg_return_t mr
= MACH_MSG_SUCCESS
;
1419 * Determine if the target is a kernel port.
1421 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
1422 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
1423 naddr
= (mach_msg_descriptor_t
*) (body
+ 1);
1425 dsc_count
= body
->msgh_descriptor_count
;
1427 return MACH_MSG_SUCCESS
;
1430 user_desc_sizes
= (dsc_count
<= DESC_COUNT_SMALL
) ?
1431 &desc_size_space
: kalloc(dsc_count
* sizeof(vm_size_t
));
1432 if (user_desc_sizes
== NULL
) {
1433 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1434 return KERN_RESOURCE_SHORTAGE
;
1439 * Make an initial pass to determine kernal VM space requirements for
1440 * physical copies and possible contraction of the descriptors from
1441 * processes with pointers larger than the kernel's.
1444 for (i
= 0; i
< dsc_count
; i
++) {
1447 /* make sure the descriptor fits in the message */
1449 switch (daddr
->type
.type
) {
1450 case MACH_MSG_OOL_DESCRIPTOR
:
1451 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1452 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
1453 user_desc_sizes
[i
] = sizeof(OTHER_OOL_DESCRIPTOR
);
1456 user_desc_sizes
[i
] = sizeof(*daddr
);
1459 naddr
= (mach_msg_descriptor_t
*)
1460 ((vm_offset_t
)daddr
+ user_desc_sizes
[i
]);
1465 if (naddr
> (mach_msg_descriptor_t
*)
1466 ((vm_offset_t
)kmsg
->ikm_header
+ kmsg
->ikm_header
->msgh_size
)) {
1467 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1468 mr
= MACH_SEND_MSG_TOO_SMALL
;
1472 switch (daddr
->type
.type
) {
1473 mach_msg_size_t size
;
1475 case MACH_MSG_OOL_DESCRIPTOR
:
1476 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1478 ((OTHER_OOL_DESCRIPTOR
*)daddr
)->size
:
1479 daddr
->out_of_line
.size
;
1481 if (daddr
->out_of_line
.copy
!= MACH_MSG_PHYSICAL_COPY
&&
1482 daddr
->out_of_line
.copy
!= MACH_MSG_VIRTUAL_COPY
) {
1484 * Invalid copy option
1486 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1487 mr
= MACH_SEND_INVALID_TYPE
;
1491 if ((size
>= MSG_OOL_SIZE_SMALL
) &&
1492 (daddr
->out_of_line
.copy
== MACH_MSG_PHYSICAL_COPY
) &&
1493 !(daddr
->out_of_line
.deallocate
)) {
1496 * Out-of-line memory descriptor, accumulate kernel
1497 * memory requirements
1499 space_needed
+= round_page(size
);
1500 if (space_needed
> ipc_kmsg_max_vm_space
) {
1503 * Per message kernel memory limit exceeded
1505 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1506 mr
= MACH_MSG_VM_KERNEL
;
1514 * Allocate space in the pageable kernel ipc copy map for all the
1515 * ool data that is to be physically copied. Map is marked wait for
1519 if (vm_allocate(ipc_kernel_copy_map
, &paddr
, space_needed
, VM_FLAGS_ANYWHERE
) !=
1521 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1522 mr
= MACH_MSG_VM_KERNEL
;
1528 * handle the OOL regions and port descriptors.
1529 * We process them in reverse order starting with the last one
1530 * scanned above. That way, we can compact them up against
1531 * the message body (if the user-descriptor size is larger than
1532 * the kernel representation).
1537 switch (daddr
->type
.type
) {
1539 /* port descriptors are the same size everywhere, how nice */
1540 case MACH_MSG_PORT_DESCRIPTOR
: {
1541 mach_msg_type_name_t user_disp
;
1542 mach_msg_type_name_t result_disp
;
1543 mach_port_name_t name
;
1544 ipc_object_t object
;
1545 volatile mach_msg_port_descriptor_t
*dsc
;
1546 volatile mach_msg_port_descriptor_t
*user_dsc
;
1548 user_dsc
= &daddr
->port
;
1551 user_disp
= user_dsc
->disposition
;
1552 result_disp
= ipc_object_copyin_type(user_disp
);
1554 name
= (mach_port_name_t
)user_dsc
->name
;
1555 if (MACH_PORT_VALID(name
)) {
1557 kr
= ipc_object_copyin(space
, name
, user_disp
, &object
);
1558 if (kr
!= KERN_SUCCESS
) {
1559 mr
= MACH_SEND_INVALID_RIGHT
;
1563 if ((result_disp
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1564 ipc_port_check_circularity((ipc_port_t
) object
,
1565 (ipc_port_t
) dest
)) {
1566 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
1568 dsc
->name
= (ipc_port_t
) object
;
1570 dsc
->name
= (mach_port_t
)name
;
1572 dsc
->disposition
= result_disp
;
1573 dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
1578 /* out of line descriptors differ in size between 32 and 64 bit processes */
1579 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1580 case MACH_MSG_OOL_DESCRIPTOR
: {
1583 mach_msg_copy_options_t copy_options
;
1584 mach_vm_offset_t addr
;
1585 mach_msg_descriptor_type_t dsc_type
;
1587 volatile mach_msg_ool_descriptor_t
*dsc
;
1590 volatile OTHER_OOL_DESCRIPTOR
*user_dsc
;
1592 user_dsc
= (OTHER_OOL_DESCRIPTOR
*)&daddr
->out_of_line
;
1593 addr
= (mach_vm_offset_t
) user_dsc
->address
;
1594 length
= user_dsc
->size
;
1595 dealloc
= user_dsc
->deallocate
;
1596 copy_options
= user_dsc
->copy
;
1597 dsc_type
= user_dsc
->type
;
1599 volatile mach_msg_ool_descriptor_t
*user_dsc
;
1601 user_dsc
= &daddr
->out_of_line
;
1602 addr
= CAST_USER_ADDR_T(user_dsc
->address
);
1603 dealloc
= user_dsc
->deallocate
;
1604 copy_options
= user_dsc
->copy
;
1605 dsc_type
= user_dsc
->type
;
1606 length
= user_dsc
->size
;
1609 dsc
= &naddr
->out_of_line
;
1611 dsc
->deallocate
= dealloc
;
1612 dsc
->copy
= copy_options
;
1613 dsc
->type
= dsc_type
;
1617 } else if ((length
>= MSG_OOL_SIZE_SMALL
) &&
1618 (copy_options
== MACH_MSG_PHYSICAL_COPY
) && !dealloc
) {
1621 * If the request is a physical copy and the source
1622 * is not being deallocated, then allocate space
1623 * in the kernel's pageable ipc copy map and copy
1624 * the data in. The semantics guarantee that the
1625 * data will have been physically copied before
1626 * the send operation terminates. Thus if the data
1627 * is not being deallocated, we must be prepared
1628 * to page if the region is sufficiently large.
1630 if (copyin(addr
, (char *) paddr
, length
)) {
1631 mr
= MACH_SEND_INVALID_MEMORY
;
1636 * The kernel ipc copy map is marked no_zero_fill.
1637 * If the transfer is not a page multiple, we need
1638 * to zero fill the balance.
1640 if (!page_aligned(length
)) {
1641 (void) memset((void *) (paddr
+ length
), 0,
1642 round_page(length
) - length
);
1644 if (vm_map_copyin(ipc_kernel_copy_map
, (vm_map_address_t
)paddr
,
1645 (vm_map_size_t
)length
, TRUE
, ©
) != KERN_SUCCESS
) {
1646 mr
= MACH_MSG_VM_KERNEL
;
1649 dsc
->address
= (void *) copy
;
1650 paddr
+= round_page(length
);
1651 space_needed
-= round_page(length
);
1655 * Make a vm_map_copy_t of the of the data. If the
1656 * data is small, this will do an optimized physical
1657 * copy. Otherwise, it will do a virtual copy.
1659 * NOTE: A virtual copy is OK if the original is being
1660 * deallocted, even if a physical copy was requested.
1662 kr
= vm_map_copyin(map
, addr
,
1663 (vm_map_size_t
)length
, dealloc
, ©
);
1664 if (kr
!= KERN_SUCCESS
) {
1665 mr
= (kr
== KERN_RESOURCE_SHORTAGE
) ?
1666 MACH_MSG_VM_KERNEL
:
1667 MACH_SEND_INVALID_MEMORY
;
1670 dsc
->address
= (void *) copy
;
1675 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
1678 ipc_object_t
*objects
;
1680 mach_vm_offset_t addr
;
1681 mach_msg_type_name_t user_disp
;
1682 mach_msg_type_name_t result_disp
;
1683 mach_msg_type_number_t count
;
1684 mach_msg_copy_options_t copy_option
;
1685 boolean_t deallocate
;
1687 volatile mach_msg_ool_ports_descriptor_t
*dsc
;
1690 volatile OTHER_OOL_PORTS_DESCRIPTOR
*user_dsc
;
1692 user_dsc
= (OTHER_OOL_PORTS_DESCRIPTOR
*)&daddr
->ool_ports
;
1693 addr
= (mach_vm_offset_t
)user_dsc
->address
;
1694 count
= user_dsc
->count
;
1695 deallocate
= user_dsc
->deallocate
;
1696 copy_option
= user_dsc
->copy
;
1697 user_disp
= user_dsc
->disposition
;
1699 volatile mach_msg_ool_ports_descriptor_t
*user_dsc
;
1701 user_dsc
= &daddr
->ool_ports
;
1702 addr
= CAST_USER_ADDR_T(user_dsc
->address
);
1703 count
= user_dsc
->count
;
1704 deallocate
= user_dsc
->deallocate
;
1705 copy_option
= user_dsc
->copy
;
1706 user_disp
= user_dsc
->disposition
;
1709 dsc
= &naddr
->ool_ports
;
1710 dsc
->deallocate
= deallocate
;
1711 dsc
->copy
= copy_option
;
1712 dsc
->type
= daddr
->type
.type
;
1715 /* calculate length of data in bytes, rounding up */
1716 length
= count
* sizeof(mach_port_name_t
);
1720 dsc
->address
= (void *) 0;
1724 data
= kalloc(length
);
1727 mr
= MACH_SEND_NO_BUFFER
;
1731 if (copyinmap(map
, addr
, data
, length
) != KERN_SUCCESS
) {
1732 kfree(data
, length
);
1733 mr
= MACH_SEND_INVALID_MEMORY
;
1738 (void) mach_vm_deallocate(map
, addr
, (mach_vm_size_t
)length
);
1741 dsc
->address
= data
;
1743 result_disp
= ipc_object_copyin_type(user_disp
);
1744 dsc
->disposition
= result_disp
;
1746 objects
= (ipc_object_t
*) data
;
1748 for ( j
= 0; j
< count
; j
++) {
1749 mach_port_name_t port
= (mach_port_name_t
) objects
[j
];
1750 ipc_object_t object
;
1752 if (!MACH_PORT_VALID(port
))
1755 kr
= ipc_object_copyin(space
, port
, user_disp
, &object
);
1757 if (kr
!= KERN_SUCCESS
) {
1760 for(k
= 0; k
< j
; k
++) {
1761 object
= objects
[k
];
1762 if (IPC_OBJECT_VALID(object
))
1763 ipc_object_destroy(object
, result_disp
);
1765 kfree(data
, length
);
1766 mr
= MACH_SEND_INVALID_RIGHT
;
1770 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1771 ipc_port_check_circularity(
1772 (ipc_port_t
) object
,
1774 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
1776 objects
[j
] = object
;
1784 * Invalid descriptor
1786 mr
= MACH_SEND_INVALID_TYPE
;
1791 if (MACH_MSG_SUCCESS
!= mr
) {
1792 ipc_kmsg_clean_partial(kmsg
, dsc_count
- i
,
1793 naddr
+ 1, paddr
, space_needed
);
1799 (daddr
= (differs
) ? (mach_msg_descriptor_t
*)((vm_offset_t
)(daddr
) -
1800 user_desc_sizes
[i
- 1]) : daddr
- 1)
1805 kmsg
->ikm_header
->msgh_bits
&= ~MACH_MSGH_BITS_COMPLEX
;
1808 if (differs
&& naddr
!= daddr
) {
1809 mach_msg_base_t
*old_base
= (mach_msg_base_t
*)kmsg
->ikm_header
;
1810 mach_msg_base_t
*new_base
= (mach_msg_base_t
*)naddr
- 1;
1812 memmove(new_base
, old_base
, sizeof(mach_msg_base_t
));
1813 new_base
->header
.msgh_size
-= (vm_offset_t
)naddr
- (vm_offset_t
)daddr
;
1814 kmsg
->ikm_header
= &new_base
->header
;
1818 if (differs
&& dsc_count
> DESC_COUNT_SMALL
)
1819 kfree(user_desc_sizes
, body
->msgh_descriptor_count
* sizeof(vm_size_t
));
1826 * Routine: ipc_kmsg_copyin
1828 * "Copy-in" port rights and out-of-line memory
1831 * In all failure cases, the message is left holding
1832 * no rights or memory. However, the message buffer
1833 * is not deallocated. If successful, the message
1834 * contains a valid destination port.
1838 * MACH_MSG_SUCCESS Successful copyin.
1839 * MACH_SEND_INVALID_HEADER
1840 * Illegal value in the message header bits.
1841 * MACH_SEND_INVALID_NOTIFY Bad notify port.
1842 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1843 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1844 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
1845 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
1846 * MACH_SEND_INVALID_TYPE Bad type specification.
1847 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
1855 mach_port_name_t notify
)
1857 mach_msg_return_t mr
;
1859 mr
= ipc_kmsg_copyin_header(kmsg
->ikm_header
, space
, notify
);
1860 if (mr
!= MACH_MSG_SUCCESS
)
1863 if ((kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
1864 return MACH_MSG_SUCCESS
;
1866 return( ipc_kmsg_copyin_body( kmsg
, space
, map
) );
1870 * Routine: ipc_kmsg_copyin_from_kernel
1872 * "Copy-in" port rights and out-of-line memory
1873 * in a message sent from the kernel.
1875 * Because the message comes from the kernel,
1876 * the implementation assumes there are no errors
1877 * or peculiarities in the message.
1879 * Returns TRUE if queueing the message
1880 * would result in a circularity.
1886 ipc_kmsg_copyin_from_kernel(
1889 mach_msg_bits_t bits
= kmsg
->ikm_header
->msgh_bits
;
1890 mach_msg_type_name_t rname
= MACH_MSGH_BITS_REMOTE(bits
);
1891 mach_msg_type_name_t lname
= MACH_MSGH_BITS_LOCAL(bits
);
1892 ipc_object_t remote
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
1893 ipc_object_t local
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
1895 /* translate the destination and reply ports */
1897 ipc_object_copyin_from_kernel(remote
, rname
);
1898 if (IO_VALID(local
))
1899 ipc_object_copyin_from_kernel(local
, lname
);
1902 * The common case is a complex message with no reply port,
1903 * because that is what the memory_object interface uses.
1906 if (bits
== (MACH_MSGH_BITS_COMPLEX
|
1907 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0))) {
1908 bits
= (MACH_MSGH_BITS_COMPLEX
|
1909 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND
, 0));
1911 kmsg
->ikm_header
->msgh_bits
= bits
;
1913 bits
= (MACH_MSGH_BITS_OTHER(bits
) |
1914 MACH_MSGH_BITS(ipc_object_copyin_type(rname
),
1915 ipc_object_copyin_type(lname
)));
1917 kmsg
->ikm_header
->msgh_bits
= bits
;
1918 if ((bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
1922 mach_msg_descriptor_t
*saddr
, *eaddr
;
1923 mach_msg_body_t
*body
;
1925 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
1926 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
1927 eaddr
= (mach_msg_descriptor_t
*) saddr
+ body
->msgh_descriptor_count
;
1929 for ( ; saddr
< eaddr
; saddr
++) {
1931 switch (saddr
->type
.type
) {
1933 case MACH_MSG_PORT_DESCRIPTOR
: {
1934 mach_msg_type_name_t name
;
1935 ipc_object_t object
;
1936 mach_msg_port_descriptor_t
*dsc
;
1940 /* this is really the type SEND, SEND_ONCE, etc. */
1941 name
= dsc
->disposition
;
1942 object
= (ipc_object_t
) dsc
->name
;
1943 dsc
->disposition
= ipc_object_copyin_type(name
);
1945 if (!IO_VALID(object
)) {
1949 ipc_object_copyin_from_kernel(object
, name
);
1951 /* CDY avoid circularity when the destination is also */
1952 /* the kernel. This check should be changed into an */
1953 /* assert when the new kobject model is in place since*/
1954 /* ports will not be used in kernel to kernel chats */
1956 if (((ipc_port_t
)remote
)->ip_receiver
!= ipc_space_kernel
) {
1957 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1958 ipc_port_check_circularity((ipc_port_t
) object
,
1959 (ipc_port_t
) remote
)) {
1960 kmsg
->ikm_header
->msgh_bits
|=
1961 MACH_MSGH_BITS_CIRCULAR
;
1966 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1967 case MACH_MSG_OOL_DESCRIPTOR
: {
1969 * The sender should supply ready-made memory, i.e.
1970 * a vm_map_copy_t, so we don't need to do anything.
1974 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
1975 ipc_object_t
*objects
;
1977 mach_msg_type_name_t name
;
1978 mach_msg_ool_ports_descriptor_t
*dsc
;
1980 dsc
= &saddr
->ool_ports
;
1982 /* this is really the type SEND, SEND_ONCE, etc. */
1983 name
= dsc
->disposition
;
1984 dsc
->disposition
= ipc_object_copyin_type(name
);
1986 objects
= (ipc_object_t
*) dsc
->address
;
1988 for ( j
= 0; j
< dsc
->count
; j
++) {
1989 ipc_object_t object
= objects
[j
];
1991 if (!IO_VALID(object
))
1994 ipc_object_copyin_from_kernel(object
, name
);
1996 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1997 ipc_port_check_circularity(
1998 (ipc_port_t
) object
,
1999 (ipc_port_t
) remote
))
2000 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
2006 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
2007 #endif /* MACH_ASSERT */
2015 * Routine: ipc_kmsg_copyout_header
2017 * "Copy-out" port rights in the header of a message.
2018 * Operates atomically; if it doesn't succeed the
2019 * message header and the space are left untouched.
2020 * If it does succeed the remote/local port fields
2021 * contain port names instead of object pointers,
2022 * and the bits field is updated.
2024 * The notify argument implements the MACH_RCV_NOTIFY option.
2025 * If it is not MACH_PORT_NULL, it should name a receive right.
2026 * If the process of receiving the reply port creates a
2027 * new right in the receiving task, then the new right is
2028 * automatically registered for a dead-name notification,
2029 * with the notify port supplying the send-once right.
2033 * MACH_MSG_SUCCESS Copied out port rights.
2034 * MACH_RCV_INVALID_NOTIFY
2035 * Notify is non-null and doesn't name a receive right.
2036 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
2037 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
2038 * The space is dead.
2039 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
2040 * No room in space for another name.
2041 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
2042 * Couldn't allocate memory for the reply port.
2043 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
2044 * Couldn't allocate memory for the dead-name request.
2048 ipc_kmsg_copyout_header(
2049 mach_msg_header_t
*msg
,
2051 mach_port_name_t notify
)
2053 mach_msg_bits_t mbits
= msg
->msgh_bits
;
2054 ipc_port_t dest
= (ipc_port_t
) msg
->msgh_remote_port
;
2056 assert(IP_VALID(dest
));
2059 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2060 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2061 ipc_port_t reply
= (ipc_port_t
) msg
->msgh_local_port
;
2062 mach_port_name_t dest_name
, reply_name
;
2064 if (IP_VALID(reply
)) {
2065 ipc_port_t notify_port
;
2070 * Handling notify (for MACH_RCV_NOTIFY) is tricky.
2071 * The problem is atomically making a send-once right
2072 * from the notify port and installing it for a
2073 * dead-name request in the new entry, because this
2074 * requires two port locks (on the notify port and
2075 * the reply port). However, we can safely make
2076 * and consume send-once rights for the notify port
2077 * as long as we hold the space locked. This isn't
2078 * an atomicity problem, because the only way
2079 * to detect that a send-once right has been created
2080 * and then consumed if it wasn't needed is by getting
2081 * at the receive right to look at ip_sorights, and
2082 * because the space is write-locked status calls can't
2083 * lookup the notify port receive right. When we make
2084 * the send-once right, we lock the notify port,
2085 * so any status calls in progress will be done.
2088 is_write_lock(space
);
2091 ipc_port_request_index_t request
;
2093 if (!space
->is_active
) {
2094 is_write_unlock(space
);
2095 return (MACH_RCV_HEADER_ERROR
|
2096 MACH_MSG_IPC_SPACE
);
2099 if (notify
!= MACH_PORT_NULL
) {
2100 notify_port
= ipc_port_lookup_notify(space
,
2102 if (notify_port
== IP_NULL
) {
2103 is_write_unlock(space
);
2104 return MACH_RCV_INVALID_NOTIFY
;
2107 notify_port
= IP_NULL
;
2109 if ((reply_type
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
2110 ipc_right_reverse(space
, (ipc_object_t
) reply
,
2111 &reply_name
, &entry
)) {
2112 /* reply port is locked and active */
2115 * We don't need the notify_port
2116 * send-once right, but we can't release
2117 * it here because reply port is locked.
2118 * Wait until after the copyout to
2119 * release the notify port right.
2122 assert(entry
->ie_bits
&
2123 MACH_PORT_TYPE_SEND_RECEIVE
);
2128 if (!ip_active(reply
)) {
2130 ip_check_unlock(reply
);
2132 if (notify_port
!= IP_NULL
)
2133 ipc_port_release_sonce(notify_port
);
2136 is_write_unlock(space
);
2139 reply_name
= MACH_PORT_DEAD
;
2143 reply_name
= (mach_port_name_t
)reply
;
2144 kr
= ipc_entry_get(space
, &reply_name
, &entry
);
2145 if (kr
!= KERN_SUCCESS
) {
2148 if (notify_port
!= IP_NULL
)
2149 ipc_port_release_sonce(notify_port
);
2151 /* space is locked */
2152 kr
= ipc_entry_grow_table(space
,
2154 if (kr
!= KERN_SUCCESS
) {
2155 /* space is unlocked */
2157 if (kr
== KERN_RESOURCE_SHORTAGE
)
2158 return (MACH_RCV_HEADER_ERROR
|
2159 MACH_MSG_IPC_KERNEL
);
2161 return (MACH_RCV_HEADER_ERROR
|
2162 MACH_MSG_IPC_SPACE
);
2164 /* space is locked again; start over */
2168 assert(IE_BITS_TYPE(entry
->ie_bits
) ==
2169 MACH_PORT_TYPE_NONE
);
2170 assert(entry
->ie_object
== IO_NULL
);
2172 if (notify_port
== IP_NULL
) {
2173 /* not making a dead-name request */
2175 entry
->ie_object
= (ipc_object_t
) reply
;
2179 kr
= ipc_port_dnrequest(reply
, reply_name
,
2180 notify_port
, &request
);
2181 if (kr
!= KERN_SUCCESS
) {
2184 ipc_port_release_sonce(notify_port
);
2186 ipc_entry_dealloc(space
, reply_name
, entry
);
2187 is_write_unlock(space
);
2190 if (!ip_active(reply
)) {
2191 /* will fail next time around loop */
2194 is_write_lock(space
);
2198 kr
= ipc_port_dngrow(reply
, ITS_SIZE_NONE
);
2199 /* port is unlocked */
2200 if (kr
!= KERN_SUCCESS
)
2201 return (MACH_RCV_HEADER_ERROR
|
2202 MACH_MSG_IPC_KERNEL
);
2204 is_write_lock(space
);
2208 notify_port
= IP_NULL
; /* don't release right below */
2210 entry
->ie_object
= (ipc_object_t
) reply
;
2211 entry
->ie_request
= request
;
2215 /* space and reply port are locked and active */
2217 ip_reference(reply
); /* hold onto the reply port */
2219 kr
= ipc_right_copyout(space
, reply_name
, entry
,
2220 reply_type
, TRUE
, (ipc_object_t
) reply
);
2221 /* reply port is unlocked */
2222 assert(kr
== KERN_SUCCESS
);
2224 if (notify_port
!= IP_NULL
)
2225 ipc_port_release_sonce(notify_port
);
2228 is_write_unlock(space
);
2231 * No reply port! This is an easy case.
2232 * We only need to have the space locked
2233 * when checking notify and when locking
2234 * the destination (to ensure atomicity).
2237 is_read_lock(space
);
2238 if (!space
->is_active
) {
2239 is_read_unlock(space
);
2240 return MACH_RCV_HEADER_ERROR
|MACH_MSG_IPC_SPACE
;
2243 if (notify
!= MACH_PORT_NULL
) {
2246 /* must check notify even though it won't be used */
2248 if ((entry
= ipc_entry_lookup(space
, notify
)) == IE_NULL
) {
2249 is_read_unlock(space
);
2250 return MACH_RCV_INVALID_NOTIFY
;
2253 if ((entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
) == 0) {
2254 is_read_unlock(space
);
2255 return MACH_RCV_INVALID_NOTIFY
;
2260 is_read_unlock(space
);
2262 reply_name
= (mach_port_name_t
) reply
;
2266 * At this point, the space is unlocked and the destination
2267 * port is locked. (Lock taken while space was locked.)
2268 * reply_name is taken care of; we still need dest_name.
2269 * We still hold a ref for reply (if it is valid).
2271 * If the space holds receive rights for the destination,
2272 * we return its name for the right. Otherwise the task
2273 * managed to destroy or give away the receive right between
2274 * receiving the message and this copyout. If the destination
2275 * is dead, return MACH_PORT_DEAD, and if the receive right
2276 * exists somewhere else (another space, in transit)
2277 * return MACH_PORT_NULL.
2279 * Making this copyout operation atomic with the previous
2280 * copyout of the reply port is a bit tricky. If there was
2281 * no real reply port (it wasn't IP_VALID) then this isn't
2282 * an issue. If the reply port was dead at copyout time,
2283 * then we are OK, because if dest is dead we serialize
2284 * after the death of both ports and if dest is alive
2285 * we serialize after reply died but before dest's (later) death.
2286 * So assume reply was alive when we copied it out. If dest
2287 * is alive, then we are OK because we serialize before
2288 * the ports' deaths. So assume dest is dead when we look at it.
2289 * If reply dies/died after dest, then we are OK because
2290 * we serialize after dest died but before reply dies.
2291 * So the hard case is when reply is alive at copyout,
2292 * dest is dead at copyout, and reply died before dest died.
2293 * In this case pretend that dest is still alive, so
2294 * we serialize while both ports are alive.
2296 * Because the space lock is held across the copyout of reply
2297 * and locking dest, the receive right for dest can't move
2298 * in or out of the space while the copyouts happen, so
2299 * that isn't an atomicity problem. In the last hard case
2300 * above, this implies that when dest is dead that the
2301 * space couldn't have had receive rights for dest at
2302 * the time reply was copied-out, so when we pretend
2303 * that dest is still alive, we can return MACH_PORT_NULL.
2305 * If dest == reply, then we have to make it look like
2306 * either both copyouts happened before the port died,
2307 * or both happened after the port died. This special
2308 * case works naturally if the timestamp comparison
2309 * is done correctly.
2314 if (ip_active(dest
)) {
2315 ipc_object_copyout_dest(space
, (ipc_object_t
) dest
,
2316 dest_type
, &dest_name
);
2317 /* dest is unlocked */
2319 ipc_port_timestamp_t timestamp
;
2321 timestamp
= dest
->ip_timestamp
;
2323 ip_check_unlock(dest
);
2325 if (IP_VALID(reply
)) {
2327 if (ip_active(reply
) ||
2328 IP_TIMESTAMP_ORDER(timestamp
,
2329 reply
->ip_timestamp
))
2330 dest_name
= MACH_PORT_DEAD
;
2332 dest_name
= MACH_PORT_NULL
;
2335 dest_name
= MACH_PORT_DEAD
;
2338 if (IP_VALID(reply
))
2339 ipc_port_release(reply
);
2341 msg
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
2342 MACH_MSGH_BITS(reply_type
, dest_type
));
2343 msg
->msgh_local_port
= (ipc_port_t
)dest_name
;
2344 msg
->msgh_remote_port
= (ipc_port_t
)reply_name
;
2347 return MACH_MSG_SUCCESS
;
2351 * Routine: ipc_kmsg_copyout_object
2353 * Copy-out a port right. Always returns a name,
2354 * even for unsuccessful return codes. Always
2355 * consumes the supplied object.
2359 * MACH_MSG_SUCCESS The space acquired the right
2360 * (name is valid) or the object is dead (MACH_PORT_DEAD).
2361 * MACH_MSG_IPC_SPACE No room in space for the right,
2362 * or the space is dead. (Name is MACH_PORT_NULL.)
2363 * MACH_MSG_IPC_KERNEL Kernel resource shortage.
2364 * (Name is MACH_PORT_NULL.)
2368 ipc_kmsg_copyout_object(
2370 ipc_object_t object
,
2371 mach_msg_type_name_t msgt_name
,
2372 mach_port_name_t
*namep
)
2376 if (!IO_VALID(object
)) {
2377 *namep
= (mach_port_name_t
) object
;
2378 return MACH_MSG_SUCCESS
;
2381 kr
= ipc_object_copyout(space
, object
, msgt_name
, TRUE
, namep
);
2382 if (kr
!= KERN_SUCCESS
) {
2383 ipc_object_destroy(object
, msgt_name
);
2385 if (kr
== KERN_INVALID_CAPABILITY
)
2386 *namep
= MACH_PORT_DEAD
;
2388 *namep
= MACH_PORT_NULL
;
2390 if (kr
== KERN_RESOURCE_SHORTAGE
)
2391 return MACH_MSG_IPC_KERNEL
;
2393 return MACH_MSG_IPC_SPACE
;
2397 return MACH_MSG_SUCCESS
;
2401 * Routine: ipc_kmsg_copyout_body
2403 * "Copy-out" port rights and out-of-line memory
2404 * in the body of a message.
2406 * The error codes are a combination of special bits.
2407 * The copyout proceeds despite errors.
2411 * MACH_MSG_SUCCESS Successful copyout.
2412 * MACH_MSG_IPC_SPACE No room for port right in name space.
2413 * MACH_MSG_VM_SPACE No room for memory in address space.
2414 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
2415 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
2416 * MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
2420 ipc_kmsg_copyout_body(
2424 mach_msg_body_t
*slist
)
2426 mach_msg_body_t
*body
;
2427 mach_msg_descriptor_t
*daddr
, *naddr
;
2428 mach_msg_descriptor_t
*saddr
;
2429 mach_msg_type_number_t i
, dsc_count
, sdsc_count
;
2430 mach_msg_return_t mr
= MACH_MSG_SUCCESS
;
2433 boolean_t differs
= MAP_SIZE_DIFFERS(map
);
2435 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2436 dsc_count
= body
->msgh_descriptor_count
;
2437 daddr
= (mach_msg_descriptor_t
*) (body
+ 1);
2440 * Do scatter list setup
2442 if (slist
!= MACH_MSG_BODY_NULL
) {
2443 saddr
= (mach_msg_descriptor_t
*) (slist
+ 1);
2444 sdsc_count
= slist
->msgh_descriptor_count
;
2447 saddr
= MACH_MSG_DESCRIPTOR_NULL
;
2452 * Compute the true size of the resulting descriptors
2453 * after potential expansion and adjust the header
2454 * and body location accordingly.
2457 mach_msg_size_t dsc_adjust
;
2461 for (i
= 0; i
< dsc_count
; i
++, naddr
++)
2462 switch (naddr
->type
.type
) {
2463 case MACH_MSG_OOL_DESCRIPTOR
:
2464 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2465 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
2466 dsc_adjust
+= DESC_SIZE_ADJUSTMENT
;
2472 mach_msg_base_t
*old_base
= (mach_msg_base_t
*)kmsg
->ikm_header
;
2473 mach_msg_base_t
*new_base
;
2475 new_base
= (mach_msg_base_t
*)((vm_offset_t
)old_base
- dsc_adjust
);
2476 memmove(new_base
, old_base
, sizeof(mach_msg_base_t
));
2477 kmsg
->ikm_header
= &new_base
->header
;
2478 kmsg
->ikm_header
->msgh_size
+= dsc_adjust
;
2479 naddr
= (mach_msg_descriptor_t
*)(new_base
+ 1);
2488 * Now process the descriptors
2490 for ( i
= 0; i
< dsc_count
; i
++, daddr
++ ) {
2491 switch (daddr
->type
.type
) {
2493 case MACH_MSG_PORT_DESCRIPTOR
: {
2494 volatile mach_msg_port_descriptor_t
*dsc
;
2495 volatile mach_msg_port_descriptor_t
*user_dsc
;
2497 mach_port_name_t name
;
2498 mach_msg_type_name_t disp
;
2501 * Copyout port right carried in the message
2504 user_dsc
= &naddr
->port
;
2506 disp
= dsc
->disposition
;
2507 mr
|= ipc_kmsg_copyout_object(space
,
2511 user_dsc
->name
= (mach_port_t
)name
;
2512 user_dsc
->disposition
= disp
;
2513 user_dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
2518 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2519 case MACH_MSG_OOL_DESCRIPTOR
: {
2521 mach_vm_offset_t rcv_addr
;
2522 mach_msg_ool_descriptor_t
*dsc
;
2523 mach_msg_copy_options_t copy_options
;
2524 mach_msg_size_t size
;
2525 mach_msg_descriptor_type_t dsc_type
;
2527 SKIP_PORT_DESCRIPTORS(saddr
, sdsc_count
);
2529 dsc
= &daddr
->out_of_line
;
2530 copy
= (vm_map_copy_t
) dsc
->address
;
2532 copy_options
= dsc
->copy
;
2533 assert(copy_options
!= MACH_MSG_KALLOC_COPY_T
);
2534 dsc_type
= dsc
->type
;
2536 if (copy
!= VM_MAP_COPY_NULL
) {
2538 * Check to see if there is an overwrite descriptor
2539 * specified in the scatter list for this ool data.
2540 * The descriptor has already been verified.
2542 if (saddr
!= MACH_MSG_DESCRIPTOR_NULL
) {
2544 OTHER_OOL_DESCRIPTOR
*scatter_dsc
;
2546 scatter_dsc
= (OTHER_OOL_DESCRIPTOR
*)saddr
;
2547 if (scatter_dsc
->copy
== MACH_MSG_OVERWRITE
) {
2548 rcv_addr
= (mach_vm_offset_t
) scatter_dsc
->address
;
2549 copy_options
= MACH_MSG_OVERWRITE
;
2552 copy_options
= MACH_MSG_VIRTUAL_COPY
;
2555 mach_msg_ool_descriptor_t
*scatter_dsc
;
2557 scatter_dsc
= &saddr
->out_of_line
;
2558 if (scatter_dsc
->copy
== MACH_MSG_OVERWRITE
) {
2559 rcv_addr
= CAST_USER_ADDR_T(scatter_dsc
->address
);
2560 copy_options
= MACH_MSG_OVERWRITE
;
2563 copy_options
= MACH_MSG_VIRTUAL_COPY
;
2566 INCREMENT_SCATTER(saddr
, sdsc_count
, differs
);
2571 * Whether the data was virtually or physically
2572 * copied we have a vm_map_copy_t for it.
2573 * If there's an overwrite region specified
2574 * overwrite it, otherwise do a virtual copy out.
2576 if (copy_options
== MACH_MSG_OVERWRITE
) {
2577 kr
= vm_map_copy_overwrite(map
, rcv_addr
,
2580 kr
= vm_map_copyout(map
, &rcv_addr
, copy
);
2582 if (kr
!= KERN_SUCCESS
) {
2583 if (kr
== KERN_RESOURCE_SHORTAGE
)
2584 mr
|= MACH_MSG_VM_KERNEL
;
2586 mr
|= MACH_MSG_VM_SPACE
;
2587 vm_map_copy_discard(copy
);
2597 * Now update the descriptor as the user would see it.
2598 * This may require expanding the descriptor to the user
2599 * visible size. There is already space allocated for
2600 * this in what naddr points to.
2603 volatile OTHER_OOL_DESCRIPTOR
*user_dsc
;
2605 user_dsc
= (OTHER_OOL_DESCRIPTOR
*)naddr
;
2606 user_dsc
->address
= rcv_addr
;
2607 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2609 user_dsc
->copy
= copy_options
;
2610 user_dsc
->type
= dsc_type
;
2611 user_dsc
->size
= size
;
2612 naddr
= (mach_msg_descriptor_t
*)((OTHER_OOL_DESCRIPTOR
*)naddr
+ 1);
2614 volatile mach_msg_ool_descriptor_t
*user_dsc
;
2616 user_dsc
= &naddr
->out_of_line
;
2617 user_dsc
->address
= CAST_DOWN(void *, rcv_addr
);
2618 user_dsc
->size
= size
;
2619 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2621 user_dsc
->copy
= copy_options
;
2622 user_dsc
->type
= dsc_type
;
2628 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
2629 mach_vm_offset_t rcv_addr
;
2630 mach_port_name_t
*objects
;
2631 mach_msg_type_name_t disp
;
2632 mach_msg_type_number_t count
, j
;
2635 volatile mach_msg_ool_ports_descriptor_t
*dsc
;
2636 mach_msg_copy_options_t copy_options
= MACH_MSG_VIRTUAL_COPY
;
2638 SKIP_PORT_DESCRIPTORS(saddr
, sdsc_count
);
2640 dsc
= &daddr
->ool_ports
;
2642 disp
= dsc
->disposition
;
2643 length
= count
* sizeof(mach_port_name_t
);
2645 if (length
!= 0 && dsc
->address
!= 0) {
2648 * Check to see if there is an overwrite descriptor
2649 * specified in the scatter list for this ool data.
2650 * The descriptor has already been verified.
2652 if (saddr
!= MACH_MSG_DESCRIPTOR_NULL
) {
2654 OTHER_OOL_DESCRIPTOR
*scatter_dsc
;
2656 scatter_dsc
= (OTHER_OOL_DESCRIPTOR
*)saddr
;
2657 rcv_addr
= (mach_vm_offset_t
) scatter_dsc
->address
;
2658 copy_options
= scatter_dsc
->copy
;
2660 mach_msg_ool_descriptor_t
*scatter_dsc
;
2662 scatter_dsc
= &saddr
->out_of_line
;
2663 rcv_addr
= CAST_USER_ADDR_T(scatter_dsc
->address
);
2664 copy_options
= scatter_dsc
->copy
;
2666 INCREMENT_SCATTER(saddr
, sdsc_count
, differs
);
2669 if (copy_options
== MACH_MSG_VIRTUAL_COPY
) {
2671 * Dynamically allocate the region
2673 int anywhere
= VM_MAKE_TAG(VM_MEMORY_MACH_MSG
)|
2676 if ((kr
= mach_vm_allocate(map
, &rcv_addr
,
2677 (mach_vm_size_t
)length
,
2678 anywhere
)) != KERN_SUCCESS
) {
2679 ipc_kmsg_clean_body(kmsg
, 1, daddr
);
2682 if (kr
== KERN_RESOURCE_SHORTAGE
){
2683 mr
|= MACH_MSG_VM_KERNEL
;
2685 mr
|= MACH_MSG_VM_SPACE
;
2692 * Handle the port rights and copy out the names
2693 * for those rights out to user-space.
2695 if (rcv_addr
!= 0) {
2696 objects
= (mach_port_name_t
*) dsc
->address
;
2698 /* copyout port rights carried in the message */
2700 for ( j
= 0; j
< count
; j
++) {
2701 ipc_object_t object
=
2702 (ipc_object_t
) objects
[j
];
2704 mr
|= ipc_kmsg_copyout_object(space
, object
,
2708 /* copyout to memory allocated above */
2709 data
= dsc
->address
;
2710 if (copyoutmap(map
, data
, rcv_addr
, length
) != KERN_SUCCESS
)
2711 mr
|= MACH_MSG_VM_SPACE
;
2712 kfree(data
, length
);
2719 * Now update the descriptor based on the information
2723 volatile OTHER_OOL_PORTS_DESCRIPTOR
*user_dsc
;
2725 user_dsc
= (OTHER_OOL_PORTS_DESCRIPTOR
*)naddr
;
2726 user_dsc
->address
= rcv_addr
;
2727 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2729 user_dsc
->copy
= copy_options
;
2730 user_dsc
->disposition
= disp
;
2731 user_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
2732 user_dsc
->count
= count
;
2733 naddr
= (mach_msg_descriptor_t
*)((OTHER_OOL_PORTS_DESCRIPTOR
*)naddr
+ 1);
2735 volatile mach_msg_ool_ports_descriptor_t
*user_dsc
;
2737 user_dsc
= &naddr
->ool_ports
;
2738 user_dsc
->address
= CAST_DOWN(void *, rcv_addr
);
2739 user_dsc
->count
= count
;
2740 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2742 user_dsc
->copy
= copy_options
;
2743 user_dsc
->disposition
= disp
;
2744 user_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
2750 panic("untyped IPC copyout body: invalid message descriptor");
2758 * Routine: ipc_kmsg_copyout_size
2760 * Compute the size of the message as copied out to the given
2761 * map. If the destination map's pointers are a different size
2762 * than the kernel's, we have to allow for expansion/
2763 * contraction of the descriptors as appropriate.
2767 * size of the message as it would be received.
2771 ipc_kmsg_copyout_size(
2775 mach_msg_size_t send_size
;
2777 send_size
= kmsg
->ikm_header
->msgh_size
;
2779 if ((kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) &&
2780 MAP_SIZE_DIFFERS(map
)) {
2782 mach_msg_body_t
*body
;
2783 mach_msg_descriptor_t
*saddr
, *eaddr
;
2785 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2786 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
2787 eaddr
= saddr
+ body
->msgh_descriptor_count
;
2789 for ( ; saddr
< eaddr
; saddr
++ ) {
2790 switch (saddr
->type
.type
) {
2792 case MACH_MSG_OOL_DESCRIPTOR
:
2793 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2794 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
2795 send_size
+= DESC_SIZE_ADJUSTMENT
;
2807 * Routine: ipc_kmsg_copyout
2809 * "Copy-out" port rights and out-of-line memory
2814 * MACH_MSG_SUCCESS Copied out all rights and memory.
2815 * MACH_RCV_INVALID_NOTIFY Bad notify port.
2816 * Rights and memory in the message are intact.
2817 * MACH_RCV_HEADER_ERROR + special bits
2818 * Rights and memory in the message are intact.
2819 * MACH_RCV_BODY_ERROR + special bits
2820 * The message header was successfully copied out.
2821 * As much of the body was handled as possible.
2829 mach_port_name_t notify
,
2830 mach_msg_body_t
*slist
)
2832 mach_msg_return_t mr
;
2834 mr
= ipc_kmsg_copyout_header(kmsg
->ikm_header
, space
, notify
);
2835 if (mr
!= MACH_MSG_SUCCESS
)
2838 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
2839 mr
= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
2841 if (mr
!= MACH_MSG_SUCCESS
)
2842 mr
|= MACH_RCV_BODY_ERROR
;
2849 * Routine: ipc_kmsg_copyout_pseudo
2851 * Does a pseudo-copyout of the message.
2852 * This is like a regular copyout, except
2853 * that the ports in the header are handled
2854 * as if they are in the body. They aren't reversed.
2856 * The error codes are a combination of special bits.
2857 * The copyout proceeds despite errors.
2861 * MACH_MSG_SUCCESS Successful copyout.
2862 * MACH_MSG_IPC_SPACE No room for port right in name space.
2863 * MACH_MSG_VM_SPACE No room for memory in address space.
2864 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
2865 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
2869 ipc_kmsg_copyout_pseudo(
2873 mach_msg_body_t
*slist
)
2875 mach_msg_bits_t mbits
= kmsg
->ikm_header
->msgh_bits
;
2876 ipc_object_t dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
2877 ipc_object_t reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
2878 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2879 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2880 mach_port_name_t dest_name
, reply_name
;
2881 mach_msg_return_t mr
;
2883 assert(IO_VALID(dest
));
2885 mr
= (ipc_kmsg_copyout_object(space
, dest
, dest_type
, &dest_name
) |
2886 ipc_kmsg_copyout_object(space
, reply
, reply_type
, &reply_name
));
2888 kmsg
->ikm_header
->msgh_bits
= mbits
&~ MACH_MSGH_BITS_CIRCULAR
;
2889 kmsg
->ikm_header
->msgh_remote_port
= (ipc_port_t
)dest_name
;
2890 kmsg
->ikm_header
->msgh_local_port
= (ipc_port_t
)reply_name
;
2892 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
2893 mr
|= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
2900 * Routine: ipc_kmsg_copyout_dest
2902 * Copies out the destination port in the message.
2903 * Destroys all other rights and memory in the message.
2909 ipc_kmsg_copyout_dest(
2913 mach_msg_bits_t mbits
;
2916 mach_msg_type_name_t dest_type
;
2917 mach_msg_type_name_t reply_type
;
2918 mach_port_name_t dest_name
, reply_name
;
2920 mbits
= kmsg
->ikm_header
->msgh_bits
;
2921 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
2922 reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
2923 dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2924 reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2926 assert(IO_VALID(dest
));
2929 if (io_active(dest
)) {
2930 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
2931 /* dest is unlocked */
2934 io_check_unlock(dest
);
2935 dest_name
= MACH_PORT_DEAD
;
2938 if (IO_VALID(reply
)) {
2939 ipc_object_destroy(reply
, reply_type
);
2940 reply_name
= MACH_PORT_NULL
;
2942 reply_name
= (mach_port_name_t
) reply
;
2944 kmsg
->ikm_header
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
2945 MACH_MSGH_BITS(reply_type
, dest_type
));
2946 kmsg
->ikm_header
->msgh_local_port
= (ipc_port_t
)dest_name
;
2947 kmsg
->ikm_header
->msgh_remote_port
= (ipc_port_t
)reply_name
;
2949 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
2950 mach_msg_body_t
*body
;
2952 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2953 ipc_kmsg_clean_body(kmsg
, body
->msgh_descriptor_count
,
2954 (mach_msg_descriptor_t
*)(body
+ 1));
2959 * Routine: ipc_kmsg_copyin_scatter
2961 * allocate and copyin a scatter list
2963 * The gather (kmsg) is valid since it has been copied in.
2964 * Gather list descriptors are sequentially paired with scatter
2965 * list descriptors, with port descriptors in either list ignored.
2966 * Descriptors are consistent if the type fileds match and size
2967 * of the scatter descriptor is less than or equal to the
2968 * size of the gather descriptor. A MACH_MSG_ALLOCATE copy
2969 * strategy in a scatter descriptor matches any size in the
2970 * corresponding gather descriptor assuming they are the same type.
2971 * Either list may be larger than the other. During the
2972 * subsequent copy out, excess scatter descriptors are ignored
2973 * and excess gather descriptors default to dynamic allocation.
2975 * In the case of a size error, the scatter list is released.
2979 * the allocated message body containing the scatter list.
2983 ipc_kmsg_get_scatter(
2984 mach_vm_address_t msg_addr
,
2985 mach_msg_size_t slist_size
,
2988 mach_msg_body_t
*slist
;
2989 mach_msg_body_t
*body
;
2990 mach_msg_descriptor_t
*gstart
, *gend
;
2991 mach_msg_descriptor_t
*sstart
, *send
;
2994 if (slist_size
< sizeof(mach_msg_base_t
))
2995 return MACH_MSG_BODY_NULL
;
2997 slist_size
-= sizeof(mach_msg_header_t
);
2998 slist
= (mach_msg_body_t
*)kalloc(slist_size
);
2999 if (slist
== MACH_MSG_BODY_NULL
)
3002 if (copyin(msg_addr
+ sizeof(mach_msg_header_t
), (char *)slist
, slist_size
)) {
3003 kfree(slist
, slist_size
);
3004 return MACH_MSG_BODY_NULL
;
3007 if ((slist
->msgh_descriptor_count
* sizeof(mach_msg_descriptor_t
)
3008 + sizeof(mach_msg_size_t
)) > slist_size
) {
3009 kfree(slist
, slist_size
);
3010 return MACH_MSG_BODY_NULL
;
3013 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
3014 gstart
= (mach_msg_descriptor_t
*) (body
+ 1);
3015 gend
= gstart
+ body
->msgh_descriptor_count
;
3017 sstart
= (mach_msg_descriptor_t
*) (slist
+ 1);
3018 send
= sstart
+ slist
->msgh_descriptor_count
;
3020 while (gstart
< gend
) {
3021 mach_msg_descriptor_type_t g_type
;
3024 * Skip port descriptors in gather list.
3026 g_type
= gstart
->type
.type
;
3028 if (g_type
!= MACH_MSG_PORT_DESCRIPTOR
) {
3031 * A scatter list with a 0 descriptor count is treated as an
3032 * automatic size mismatch.
3034 if (slist
->msgh_descriptor_count
== 0) {
3035 kfree(slist
, slist_size
);
3036 return MACH_MSG_BODY_NULL
;
3040 * Skip port descriptors in scatter list.
3042 while (sstart
< send
) {
3043 if (sstart
->type
.type
!= MACH_MSG_PORT_DESCRIPTOR
)
3049 * No more scatter descriptors, we're done
3051 if (sstart
>= send
) {
3056 * Check type, copy and size fields
3058 if (g_type
== MACH_MSG_OOL_DESCRIPTOR
||
3059 g_type
== MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
3060 if (sstart
->type
.type
!= MACH_MSG_OOL_DESCRIPTOR
&&
3061 sstart
->type
.type
!= MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
3062 kfree(slist
, slist_size
);
3063 return MACH_MSG_BODY_NULL
;
3065 if (sstart
->out_of_line
.copy
== MACH_MSG_OVERWRITE
&&
3066 gstart
->out_of_line
.size
> sstart
->out_of_line
.size
) {
3067 kfree(slist
, slist_size
);
3068 return MACH_MSG_BODY_NULL
;
3072 if (sstart
->type
.type
!= MACH_MSG_OOL_PORTS_DESCRIPTOR
) {
3073 kfree(slist
, slist_size
);
3074 return MACH_MSG_BODY_NULL
;
3076 if (sstart
->ool_ports
.copy
== MACH_MSG_OVERWRITE
&&
3077 gstart
->ool_ports
.count
> sstart
->ool_ports
.count
) {
3078 kfree(slist
, slist_size
);
3079 return MACH_MSG_BODY_NULL
;
3091 * Routine: ipc_kmsg_free_scatter
3093 * Deallocate a scatter list. Since we actually allocated
3094 * a body without a header, and since the header was originally
3095 * accounted for in slist_size, we have to ajust it down
3096 * before freeing the scatter list.
3099 ipc_kmsg_free_scatter(
3100 mach_msg_body_t
*slist
,
3101 mach_msg_size_t slist_size
)
3103 slist_size
-= sizeof(mach_msg_header_t
);
3104 kfree(slist
, slist_size
);
3109 * Routine: ipc_kmsg_copyout_to_kernel
3111 * Copies out the destination and reply ports in the message.
3112 * Leaves all other rights and memory in the message alone.
3116 * Derived from ipc_kmsg_copyout_dest.
3117 * Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
3118 * We really do want to save rights and memory.
3122 ipc_kmsg_copyout_to_kernel(
3128 mach_msg_type_name_t dest_type
;
3129 mach_msg_type_name_t reply_type
;
3130 mach_port_name_t dest_name
, reply_name
;
3132 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
3133 reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
3134 dest_type
= MACH_MSGH_BITS_REMOTE(kmsg
->ikm_header
->msgh_bits
);
3135 reply_type
= MACH_MSGH_BITS_LOCAL(kmsg
->ikm_header
->msgh_bits
);
3137 assert(IO_VALID(dest
));
3140 if (io_active(dest
)) {
3141 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
3142 /* dest is unlocked */
3145 io_check_unlock(dest
);
3146 dest_name
= MACH_PORT_DEAD
;
3149 reply_name
= (mach_port_name_t
) reply
;
3151 kmsg
->ikm_header
->msgh_bits
=
3152 (MACH_MSGH_BITS_OTHER(kmsg
->ikm_header
->msgh_bits
) |
3153 MACH_MSGH_BITS(reply_type
, dest_type
));
3154 kmsg
->ikm_header
->msgh_local_port
= (ipc_port_t
)dest_name
;
3155 kmsg
->ikm_header
->msgh_remote_port
= (ipc_port_t
)reply_name
;
3158 #include <mach_kdb.h>
3161 #include <ddb/db_output.h>
3162 #include <ipc/ipc_print.h>
3164 * Forward declarations
3166 void ipc_msg_print_untyped(
3167 mach_msg_body_t
*body
);
3169 const char * ipc_type_name(
3171 boolean_t received
);
3173 void ipc_print_type_name(
3178 mach_msg_bits_t bit
);
3181 mm_copy_options_string(
3182 mach_msg_copy_options_t option
);
3184 void db_print_msg_uid(mach_msg_header_t
*);
3192 switch (type_name
) {
3193 case MACH_MSG_TYPE_PORT_NAME
:
3196 case MACH_MSG_TYPE_MOVE_RECEIVE
:
3198 return "port_receive";
3200 return "move_receive";
3203 case MACH_MSG_TYPE_MOVE_SEND
:
3210 case MACH_MSG_TYPE_MOVE_SEND_ONCE
:
3212 return "port_send_once";
3214 return "move_send_once";
3217 case MACH_MSG_TYPE_COPY_SEND
:
3220 case MACH_MSG_TYPE_MAKE_SEND
:
3223 case MACH_MSG_TYPE_MAKE_SEND_ONCE
:
3224 return "make_send_once";
3232 ipc_print_type_name(
3235 const char *name
= ipc_type_name(type_name
, TRUE
);
3239 printf("type%d", type_name
);
3244 * ipc_kmsg_print [ debug ]
3250 iprintf("kmsg=0x%x\n", kmsg
);
3251 iprintf("ikm_next=0x%x, prev=0x%x, size=%d",
3256 ipc_msg_print(kmsg
->ikm_header
);
3261 mach_msg_bits_t bit
)
3264 case MACH_MSGH_BITS_COMPLEX
: return "complex";
3265 case MACH_MSGH_BITS_CIRCULAR
: return "circular";
3266 default: return (char *) 0;
3271 * ipc_msg_print [ debug ]
3275 mach_msg_header_t
*msgh
)
3277 mach_msg_bits_t mbits
;
3278 unsigned int bit
, i
;
3279 const char *bit_name
;
3282 mbits
= msgh
->msgh_bits
;
3283 iprintf("msgh_bits=0x%x: l=0x%x,r=0x%x\n",
3285 MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
),
3286 MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
3288 mbits
= MACH_MSGH_BITS_OTHER(mbits
) & MACH_MSGH_BITS_USED
;
3291 iprintf("decoded bits: ");
3293 for (i
= 0, bit
= 1; i
< sizeof(mbits
) * 8; ++i
, bit
<<= 1) {
3294 if ((mbits
& bit
) == 0)
3296 bit_name
= msgh_bit_decode((mach_msg_bits_t
)bit
);
3298 printf("%s%s", needs_comma
? "," : "", bit_name
);
3300 printf("%sunknown(0x%x),", needs_comma
? "," : "", bit
);
3303 if (msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
) {
3304 printf("%sunused=0x%x,", needs_comma
? "," : "",
3305 msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
);
3311 if (msgh
->msgh_remote_port
) {
3312 iprintf("remote=0x%x(", msgh
->msgh_remote_port
);
3313 ipc_print_type_name(MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
3316 iprintf("remote=null");
3319 if (msgh
->msgh_local_port
) {
3320 printf("%slocal=0x%x(", needs_comma
? "," : "",
3321 msgh
->msgh_local_port
);
3322 ipc_print_type_name(MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
));
3325 printf("local=null\n");
3328 iprintf("msgh_id=%d, size=%d\n",
3332 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
3333 ipc_msg_print_untyped((mach_msg_body_t
*) (msgh
+ 1));
3339 mm_copy_options_string(
3340 mach_msg_copy_options_t option
)
3345 case MACH_MSG_PHYSICAL_COPY
:
3348 case MACH_MSG_VIRTUAL_COPY
:
3351 case MACH_MSG_OVERWRITE
:
3354 case MACH_MSG_ALLOCATE
:
3357 case MACH_MSG_KALLOC_COPY_T
:
3358 name
= "KALLOC_COPY_T";
3368 ipc_msg_print_untyped(
3369 mach_msg_body_t
*body
)
3371 mach_msg_descriptor_t
*saddr
, *send
;
3372 mach_msg_descriptor_type_t type
;
3374 iprintf("%d descriptors %d: \n", body
->msgh_descriptor_count
);
3376 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
3377 send
= saddr
+ body
->msgh_descriptor_count
;
3379 for ( ; saddr
< send
; saddr
++ ) {
3381 type
= saddr
->type
.type
;
3385 case MACH_MSG_PORT_DESCRIPTOR
: {
3386 mach_msg_port_descriptor_t
*dsc
;
3389 iprintf("-- PORT name = 0x%x disp = ", dsc
->name
);
3390 ipc_print_type_name(dsc
->disposition
);
3394 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
3395 case MACH_MSG_OOL_DESCRIPTOR
: {
3396 mach_msg_ool_descriptor_t
*dsc
;
3398 dsc
= &saddr
->out_of_line
;
3399 iprintf("-- OOL%s addr = 0x%x size = 0x%x copy = %s %s\n",
3400 type
== MACH_MSG_OOL_DESCRIPTOR
? "" : " VOLATILE",
3401 dsc
->address
, dsc
->size
,
3402 mm_copy_options_string(dsc
->copy
),
3403 dsc
->deallocate
? "DEALLOC" : "");
3406 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
3407 mach_msg_ool_ports_descriptor_t
*dsc
;
3409 dsc
= &saddr
->ool_ports
;
3411 iprintf("-- OOL_PORTS addr = 0x%x count = 0x%x ",
3412 dsc
->address
, dsc
->count
);
3414 ipc_print_type_name(dsc
->disposition
);
3415 printf(" copy = %s %s\n",
3416 mm_copy_options_string(dsc
->copy
),
3417 dsc
->deallocate
? "DEALLOC" : "");
3422 iprintf("-- UNKNOWN DESCRIPTOR 0x%x\n", type
);
3428 #endif /* MACH_KDB */