2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
34 * All Rights Reserved.
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
59 * File: ipc/ipc_kmsg.c
63 * Operations on kernel messages.
68 #include <mach/mach_types.h>
69 #include <mach/boolean.h>
70 #include <mach/kern_return.h>
71 #include <mach/message.h>
72 #include <mach/port.h>
73 #include <mach/vm_map.h>
74 #include <mach/mach_vm.h>
75 #include <mach/vm_statistics.h>
77 #include <kern/kern_types.h>
78 #include <kern/assert.h>
79 #include <kern/ipc_kobject.h>
80 #include <kern/kalloc.h>
81 #include <kern/zalloc.h>
82 #include <kern/processor.h>
83 #include <kern/thread.h>
84 #include <kern/sched_prim.h>
86 #include <kern/misc_protos.h>
87 #include <kern/counters.h>
88 #include <kern/cpu_data.h>
90 #include <vm/vm_map.h>
91 #include <vm/vm_object.h>
92 #include <vm/vm_kern.h>
95 #include <ipc/ipc_types.h>
96 #include <ipc/ipc_entry.h>
97 #include <ipc/ipc_kmsg.h>
98 #include <ipc/ipc_notify.h>
99 #include <ipc/ipc_object.h>
100 #include <ipc/ipc_space.h>
101 #include <ipc/ipc_port.h>
102 #include <ipc/ipc_right.h>
103 #include <ipc/ipc_hash.h>
104 #include <ipc/ipc_table.h>
109 #include <ppc/Firmware.h>
110 #include <ppc/low_trace.h>
114 extern vm_map_t ipc_kernel_copy_map
;
115 extern vm_size_t ipc_kmsg_max_vm_space
;
116 extern vm_size_t msg_ool_size_small
;
118 #define MSG_OOL_SIZE_SMALL msg_ool_size_small
120 #if defined(__LP64__)
121 #define MAP_SIZE_DIFFERS(map) (map->max_offset < MACH_VM_MAX_ADDRESS)
122 #define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor32_t
123 #define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor32_t
125 #define MAP_SIZE_DIFFERS(map) (map->max_offset > VM_MAX_ADDRESS)
126 #define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor64_t
127 #define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor64_t
130 #define DESC_SIZE_ADJUSTMENT (sizeof(OTHER_OOL_DESCRIPTOR) - \
131 sizeof(mach_msg_ool_descriptor_t))
133 /* scatter list macros */
135 #define SKIP_PORT_DESCRIPTORS(s, c) \
137 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
139 if ((s)->type.type != MACH_MSG_PORT_DESCRIPTOR) \
144 (s) = MACH_MSG_DESCRIPTOR_NULL; \
148 #define INCREMENT_SCATTER(s, c, d) \
150 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
151 s = (d) ? (mach_msg_descriptor_t *) \
152 ((OTHER_OOL_DESCRIPTOR *)(s) + 1) : \
158 /* zone for cached ipc_kmsg_t structures */
159 zone_t ipc_kmsg_zone
;
162 * Forward declarations
168 void ipc_kmsg_clean_body(
170 mach_msg_type_number_t number
,
171 mach_msg_descriptor_t
*desc
);
173 void ipc_kmsg_clean_partial(
175 mach_msg_type_number_t number
,
176 mach_msg_descriptor_t
*desc
,
180 mach_msg_return_t
ipc_kmsg_copyin_body(
186 * We keep a per-processor cache of kernel message buffers.
187 * The cache saves the overhead/locking of using kalloc/kfree.
188 * The per-processor cache seems to miss less than a per-thread cache,
189 * and it also uses less memory. Access to the cache doesn't
194 * Routine: ipc_kmsg_alloc
196 * Allocate a kernel message structure. If we can get one from
197 * the cache, that is best. Otherwise, allocate a new one.
203 mach_msg_size_t msg_and_trailer_size
)
205 mach_msg_size_t max_expanded_size
;
208 #if !defined(__LP64__)
211 * Pad the allocation in case we need to expand the
212 * message descrptors for user spaces with pointers larger than
213 * the kernel's own. We don't know how many descriptors
214 * there are yet, so just assume the whole body could be
215 * descriptors (if there could be any at all).
217 * The expansion space is left in front of the header,
218 * because it is easier to pull the header and descriptors
219 * forward as we process them than it is to push all the
223 mach_msg_size_t size
= msg_and_trailer_size
- MAX_TRAILER_SIZE
;
224 if (size
> sizeof(mach_msg_base_t
)) {
225 mach_msg_size_t max_desc
= ((size
- sizeof(mach_msg_base_t
)) /
226 sizeof(mach_msg_ool_descriptor_t
)) *
227 DESC_SIZE_ADJUSTMENT
;
228 if (msg_and_trailer_size
>= MACH_MSG_SIZE_MAX
- max_desc
)
230 max_expanded_size
= msg_and_trailer_size
+ max_desc
;
233 max_expanded_size
= msg_and_trailer_size
;
235 if (max_expanded_size
> ikm_less_overhead(MACH_MSG_SIZE_MAX
))
237 else if (max_expanded_size
< IKM_SAVED_MSG_SIZE
)
238 max_expanded_size
= IKM_SAVED_MSG_SIZE
; /* round up for ikm_cache */
240 if (max_expanded_size
== IKM_SAVED_MSG_SIZE
) {
241 struct ikm_cache
*cache
;
244 disable_preemption();
245 cache
= &PROCESSOR_DATA(current_processor(), ikm_cache
);
246 if ((i
= cache
->avail
) > 0) {
247 assert(i
<= IKM_STASH
);
248 kmsg
= cache
->entries
[--i
];
250 ikm_check_init(kmsg
, max_expanded_size
);
252 kmsg
->ikm_header
= (mach_msg_header_t
*)
253 ((vm_offset_t
)(kmsg
+ 1) +
255 msg_and_trailer_size
);
259 kmsg
= (ipc_kmsg_t
)zalloc(ipc_kmsg_zone
);
261 kmsg
= (ipc_kmsg_t
)kalloc(ikm_plus_overhead(max_expanded_size
));
264 if (kmsg
!= IKM_NULL
) {
265 ikm_init(kmsg
, max_expanded_size
);
266 kmsg
->ikm_header
= (mach_msg_header_t
*)
267 ((vm_offset_t
)(kmsg
+ 1) +
269 msg_and_trailer_size
);
275 * Routine: ipc_kmsg_free
277 * Free a kernel message buffer. If the kms is preallocated
278 * to a port, just "put it back (marked unused)." We have to
279 * do this with the port locked. The port may have its hold
280 * on our message released. In that case, we have to just
281 * revert the message to a traditional one and free it normally.
290 mach_msg_size_t size
= kmsg
->ikm_size
;
294 * Check to see if the message is bound to the port. If so,
295 * mark it not in use. If the port isn't already dead, then
296 * leave the message associated with it. Otherwise, free it.
298 port
= ikm_prealloc_inuse_port(kmsg
);
299 if (port
!= IP_NULL
) {
301 ikm_prealloc_clear_inuse(kmsg
, port
);
302 if (ip_active(port
) && (port
->ip_premsg
== kmsg
)) {
303 assert(IP_PREALLOC(port
));
307 ip_check_unlock(port
); /* May be last reference */
311 * Peek and see if it has to go back in the cache.
313 if (kmsg
->ikm_size
== IKM_SAVED_MSG_SIZE
) {
314 struct ikm_cache
*cache
;
317 disable_preemption();
318 cache
= &PROCESSOR_DATA(current_processor(), ikm_cache
);
319 if ((i
= cache
->avail
) < IKM_STASH
) {
320 cache
->entries
[i
] = kmsg
;
321 cache
->avail
= i
+ 1;
326 zfree(ipc_kmsg_zone
, kmsg
);
329 kfree(kmsg
, ikm_plus_overhead(size
));
334 * Routine: ipc_kmsg_enqueue
341 ipc_kmsg_queue_t queue
,
344 ipc_kmsg_enqueue_macro(queue
, kmsg
);
348 * Routine: ipc_kmsg_dequeue
350 * Dequeue and return a kmsg.
355 ipc_kmsg_queue_t queue
)
359 first
= ipc_kmsg_queue_first(queue
);
361 if (first
!= IKM_NULL
)
362 ipc_kmsg_rmqueue_first_macro(queue
, first
);
368 * Routine: ipc_kmsg_rmqueue
370 * Pull a kmsg out of a queue.
375 ipc_kmsg_queue_t queue
,
378 ipc_kmsg_t next
, prev
;
380 assert(queue
->ikmq_base
!= IKM_NULL
);
382 next
= kmsg
->ikm_next
;
383 prev
= kmsg
->ikm_prev
;
386 assert(prev
== kmsg
);
387 assert(queue
->ikmq_base
== kmsg
);
389 queue
->ikmq_base
= IKM_NULL
;
391 if (queue
->ikmq_base
== kmsg
)
392 queue
->ikmq_base
= next
;
394 next
->ikm_prev
= prev
;
395 prev
->ikm_next
= next
;
397 /* XXX Temporary debug logic */
398 assert(kmsg
->ikm_next
= IKM_BOGUS
);
399 assert(kmsg
->ikm_prev
= IKM_BOGUS
);
403 * Routine: ipc_kmsg_queue_next
405 * Return the kmsg following the given kmsg.
406 * (Or IKM_NULL if it is the last one in the queue.)
411 ipc_kmsg_queue_t queue
,
416 assert(queue
->ikmq_base
!= IKM_NULL
);
418 next
= kmsg
->ikm_next
;
419 if (queue
->ikmq_base
== next
)
426 * Routine: ipc_kmsg_destroy
428 * Destroys a kernel message. Releases all rights,
429 * references, and memory held by the message.
439 ipc_kmsg_queue_t queue
;
443 * ipc_kmsg_clean can cause more messages to be destroyed.
444 * Curtail recursion by queueing messages. If a message
445 * is already queued, then this is a recursive call.
448 queue
= &(current_thread()->ith_messages
);
449 empty
= ipc_kmsg_queue_empty(queue
);
450 ipc_kmsg_enqueue(queue
, kmsg
);
453 /* must leave kmsg in queue while cleaning it */
455 while ((kmsg
= ipc_kmsg_queue_first(queue
)) != IKM_NULL
) {
456 ipc_kmsg_clean(kmsg
);
457 ipc_kmsg_rmqueue(queue
, kmsg
);
464 * Routine: ipc_kmsg_destroy_dest
466 * Destroys a kernel message. Releases all rights,
467 * references, and memory held by the message (including
468 * the destination port reference.
474 ipc_kmsg_destroy_dest(
479 port
= kmsg
->ikm_header
->msgh_remote_port
;
481 ipc_port_release(port
);
482 kmsg
->ikm_header
->msgh_remote_port
= MACH_PORT_NULL
;
483 ipc_kmsg_destroy(kmsg
);
487 * Routine: ipc_kmsg_clean_body
489 * Cleans the body of a kernel message.
490 * Releases all rights, references, and memory.
498 __unused ipc_kmsg_t kmsg
,
499 mach_msg_type_number_t number
,
500 mach_msg_descriptor_t
*saddr
)
502 mach_msg_descriptor_t
*eaddr
;
507 eaddr
= saddr
+ number
;
509 for ( ; saddr
< eaddr
; saddr
++ ) {
511 switch (saddr
->type
.type
) {
513 case MACH_MSG_PORT_DESCRIPTOR
: {
514 mach_msg_port_descriptor_t
*dsc
;
519 * Destroy port rights carried in the message
521 if (!IO_VALID((ipc_object_t
) dsc
->name
))
523 ipc_object_destroy((ipc_object_t
) dsc
->name
, dsc
->disposition
);
526 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
527 case MACH_MSG_OOL_DESCRIPTOR
: {
528 mach_msg_ool_descriptor_t
*dsc
;
530 dsc
= &saddr
->out_of_line
;
533 * Destroy memory carried in the message
535 if (dsc
->size
== 0) {
536 assert(dsc
->address
== (void *) 0);
538 vm_map_copy_discard((vm_map_copy_t
) dsc
->address
);
542 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
543 ipc_object_t
*objects
;
544 mach_msg_type_number_t j
;
545 mach_msg_ool_ports_descriptor_t
*dsc
;
547 dsc
= &saddr
->ool_ports
;
548 objects
= (ipc_object_t
*) dsc
->address
;
550 if (dsc
->count
== 0) {
554 assert(objects
!= (ipc_object_t
*) 0);
556 /* destroy port rights carried in the message */
558 for (j
= 0; j
< dsc
->count
; j
++) {
559 ipc_object_t object
= objects
[j
];
561 if (!IO_VALID(object
))
564 ipc_object_destroy(object
, dsc
->disposition
);
567 /* destroy memory carried in the message */
569 assert(dsc
->count
!= 0);
572 (vm_size_t
) dsc
->count
* sizeof(mach_port_name_t
));
576 printf("cleanup: don't understand this type of descriptor\n");
583 * Routine: ipc_kmsg_clean_partial
585 * Cleans a partially-acquired kernel message.
586 * number is the index of the type descriptor
587 * in the body of the message that contained the error.
588 * If dolast, the memory and port rights in this last
589 * type spec are also cleaned. In that case, number
590 * specifies the number of port rights to clean.
596 ipc_kmsg_clean_partial(
598 mach_msg_type_number_t number
,
599 mach_msg_descriptor_t
*desc
,
604 mach_msg_bits_t mbits
= kmsg
->ikm_header
->msgh_bits
;
606 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
607 assert(IO_VALID(object
));
608 ipc_object_destroy(object
, MACH_MSGH_BITS_REMOTE(mbits
));
610 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
611 if (IO_VALID(object
))
612 ipc_object_destroy(object
, MACH_MSGH_BITS_LOCAL(mbits
));
615 (void) vm_deallocate(ipc_kernel_copy_map
, paddr
, length
);
618 ipc_kmsg_clean_body(kmsg
, number
, desc
);
622 * Routine: ipc_kmsg_clean
624 * Cleans a kernel message. Releases all rights,
625 * references, and memory held by the message.
635 mach_msg_bits_t mbits
;
637 mbits
= kmsg
->ikm_header
->msgh_bits
;
638 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
639 if (IO_VALID(object
))
640 ipc_object_destroy(object
, MACH_MSGH_BITS_REMOTE(mbits
));
642 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
643 if (IO_VALID(object
))
644 ipc_object_destroy(object
, MACH_MSGH_BITS_LOCAL(mbits
));
646 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
647 mach_msg_body_t
*body
;
649 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
650 ipc_kmsg_clean_body(kmsg
, body
->msgh_descriptor_count
,
651 (mach_msg_descriptor_t
*)(body
+ 1));
656 * Routine: ipc_kmsg_set_prealloc
658 * Assign a kmsg as a preallocated message buffer to a port.
664 ipc_kmsg_set_prealloc(
668 assert(kmsg
->ikm_prealloc
== IP_NULL
);
670 kmsg
->ikm_prealloc
= IP_NULL
;
671 IP_SET_PREALLOC(port
, kmsg
);
675 * Routine: ipc_kmsg_clear_prealloc
677 * Release the Assignment of a preallocated message buffer from a port.
682 ipc_kmsg_clear_prealloc(
686 assert(kmsg
->ikm_prealloc
== port
);
688 kmsg
->ikm_prealloc
= IP_NULL
;
689 IP_CLEAR_PREALLOC(port
, kmsg
);
695 * Routine: ipc_kmsg_get
697 * Allocates a kernel message buffer.
698 * Copies a user message to the message buffer.
702 * MACH_MSG_SUCCESS Acquired a message buffer.
703 * MACH_SEND_MSG_TOO_SMALL Message smaller than a header.
704 * MACH_SEND_MSG_TOO_SMALL Message size not long-word multiple.
705 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
706 * MACH_SEND_INVALID_DATA Couldn't copy message data.
711 mach_vm_address_t msg_addr
,
712 mach_msg_size_t size
,
715 mach_msg_size_t msg_and_trailer_size
;
717 mach_msg_max_trailer_t
*trailer
;
719 if ((size
< sizeof(mach_msg_header_t
)) || (size
& 3))
720 return MACH_SEND_MSG_TOO_SMALL
;
722 if (size
> MACH_MSG_SIZE_MAX
- MAX_TRAILER_SIZE
)
723 return MACH_SEND_TOO_LARGE
;
725 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
727 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
729 if (kmsg
== IKM_NULL
)
730 return MACH_SEND_NO_BUFFER
;
732 if (copyinmsg(msg_addr
, (char *) kmsg
->ikm_header
, size
)) {
734 return MACH_SEND_INVALID_DATA
;
737 kmsg
->ikm_header
->msgh_size
= size
;
740 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
741 * However, the internal size field of the trailer (msgh_trailer_size)
742 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize
743 * the cases where no implicit data is requested.
745 trailer
= (mach_msg_max_trailer_t
*) ((vm_offset_t
)kmsg
->ikm_header
+ size
);
746 trailer
->msgh_sender
= current_thread()->task
->sec_token
;
747 trailer
->msgh_audit
= current_thread()->task
->audit_token
;
748 trailer
->msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
749 trailer
->msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
752 if(trcWork
.traceMask
) dbgTrace(0x1100, (unsigned int)kmsg
->ikm_header
->msgh_id
,
753 (unsigned int)kmsg
->ikm_header
->msgh_remote_port
,
754 (unsigned int)kmsg
->ikm_header
->msgh_local_port
, 0);
757 return MACH_MSG_SUCCESS
;
761 * Routine: ipc_kmsg_get_from_kernel
763 * First checks for a preallocated message
764 * reserved for kernel clients. If not found -
765 * allocates a new kernel message buffer.
766 * Copies a kernel message to the message buffer.
767 * Only resource errors are allowed.
770 * Ports in header are ipc_port_t.
772 * MACH_MSG_SUCCESS Acquired a message buffer.
773 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
777 ipc_kmsg_get_from_kernel(
778 mach_msg_header_t
*msg
,
779 mach_msg_size_t size
,
783 mach_msg_size_t msg_and_trailer_size
;
784 mach_msg_max_trailer_t
*trailer
;
785 ipc_port_t dest_port
;
787 assert(size
>= sizeof(mach_msg_header_t
));
788 // assert((size & 3) == 0);
790 assert(IP_VALID((ipc_port_t
) msg
->msgh_remote_port
));
791 dest_port
= (ipc_port_t
)msg
->msgh_remote_port
;
793 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
796 * See if the port has a pre-allocated kmsg for kernel
797 * clients. These are set up for those kernel clients
798 * which cannot afford to wait.
800 if (IP_PREALLOC(dest_port
)) {
802 if (!ip_active(dest_port
)) {
803 ip_unlock(dest_port
);
804 return MACH_SEND_NO_BUFFER
;
806 assert(IP_PREALLOC(dest_port
));
807 kmsg
= dest_port
->ip_premsg
;
808 if (msg_and_trailer_size
> kmsg
->ikm_size
) {
809 ip_unlock(dest_port
);
810 return MACH_SEND_TOO_LARGE
;
812 if (ikm_prealloc_inuse(kmsg
)) {
813 ip_unlock(dest_port
);
814 return MACH_SEND_NO_BUFFER
;
816 ikm_prealloc_set_inuse(kmsg
, dest_port
);
817 ip_unlock(dest_port
);
819 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
820 if (kmsg
== IKM_NULL
)
821 return MACH_SEND_NO_BUFFER
;
824 (void) memcpy((void *) kmsg
->ikm_header
, (const void *) msg
, size
);
826 kmsg
->ikm_header
->msgh_size
= size
;
829 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
830 * However, the internal size field of the trailer (msgh_trailer_size)
831 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to
832 * optimize the cases where no implicit data is requested.
834 trailer
= (mach_msg_max_trailer_t
*)
835 ((vm_offset_t
)kmsg
->ikm_header
+ size
);
836 trailer
->msgh_sender
= KERNEL_SECURITY_TOKEN
;
837 trailer
->msgh_audit
= KERNEL_AUDIT_TOKEN
;
838 trailer
->msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
839 trailer
->msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
842 return MACH_MSG_SUCCESS
;
846 * Routine: ipc_kmsg_send
848 * Send a message. The message holds a reference
849 * for the destination port in the msgh_remote_port field.
851 * If unsuccessful, the caller still has possession of
852 * the message and must do something with it. If successful,
853 * the message is queued, given to a receiver, destroyed,
854 * or handled directly by the kernel via mach_msg.
858 * MACH_MSG_SUCCESS The message was accepted.
859 * MACH_SEND_TIMED_OUT Caller still has message.
860 * MACH_SEND_INTERRUPTED Caller still has message.
865 mach_msg_option_t option
,
866 mach_msg_timeout_t send_timeout
)
870 port
= (ipc_port_t
) kmsg
->ikm_header
->msgh_remote_port
;
871 assert(IP_VALID(port
));
875 if (port
->ip_receiver
== ipc_space_kernel
) {
878 * We can check ip_receiver == ipc_space_kernel
879 * before checking that the port is active because
880 * ipc_port_dealloc_kernel clears ip_receiver
881 * before destroying a kernel port.
883 assert(ip_active(port
));
884 port
->ip_messages
.imq_seqno
++;
887 current_task()->messages_sent
++;
890 * Call the server routine, and get the reply message to send.
892 kmsg
= ipc_kobject_server(kmsg
);
893 if (kmsg
== IKM_NULL
)
894 return MACH_MSG_SUCCESS
;
896 port
= (ipc_port_t
) kmsg
->ikm_header
->msgh_remote_port
;
897 assert(IP_VALID(port
));
899 /* fall thru with reply - same options */
903 * Can't deliver to a dead port.
904 * However, we can pretend it got sent
905 * and was then immediately destroyed.
907 if (!ip_active(port
)) {
909 * We can't let ipc_kmsg_destroy deallocate
910 * the port right, because we might end up
911 * in an infinite loop trying to deliver
912 * a send-once notification.
916 ip_check_unlock(port
);
917 kmsg
->ikm_header
->msgh_remote_port
= MACH_PORT_NULL
;
918 ipc_kmsg_destroy(kmsg
);
919 return MACH_MSG_SUCCESS
;
922 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_CIRCULAR
) {
925 /* don't allow the creation of a circular loop */
927 ipc_kmsg_destroy(kmsg
);
928 return MACH_MSG_SUCCESS
;
932 * We have a valid message and a valid reference on the port.
933 * we can unlock the port and call mqueue_send() on it's message
937 return (ipc_mqueue_send(&port
->ip_messages
, kmsg
, option
, send_timeout
));
941 * Routine: ipc_kmsg_put
943 * Copies a message buffer to a user message.
944 * Copies only the specified number of bytes.
945 * Frees the message buffer.
947 * Nothing locked. The message buffer must have clean
950 * MACH_MSG_SUCCESS Copied data out of message buffer.
951 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
956 mach_vm_address_t msg_addr
,
958 mach_msg_size_t size
)
960 mach_msg_return_t mr
;
962 if (copyoutmsg((const char *) kmsg
->ikm_header
, msg_addr
, size
))
963 mr
= MACH_RCV_INVALID_DATA
;
965 mr
= MACH_MSG_SUCCESS
;
972 * Routine: ipc_kmsg_put_to_kernel
974 * Copies a message buffer to a kernel message.
975 * Frees the message buffer.
982 ipc_kmsg_put_to_kernel(
983 mach_msg_header_t
*msg
,
985 mach_msg_size_t size
)
987 (void) memcpy((void *) msg
, (const void *) kmsg
->ikm_header
, size
);
993 * Routine: ipc_kmsg_copyin_header
995 * "Copy-in" port rights in the header of a message.
996 * Operates atomically; if it doesn't succeed the
997 * message header and the space are left untouched.
998 * If it does succeed the remote/local port fields
999 * contain object pointers instead of port names,
1000 * and the bits field is updated. The destination port
1001 * will be a valid port pointer.
1003 * The notify argument implements the MACH_SEND_CANCEL option.
1004 * If it is not MACH_PORT_NULL, it should name a receive right.
1005 * If the processing of the destination port would generate
1006 * a port-deleted notification (because the right for the
1007 * destination port is destroyed and it had a request for
1008 * a dead-name notification registered), and the port-deleted
1009 * notification would be sent to the named receive right,
1010 * then it isn't sent and the send-once right for the notify
1011 * port is quietly destroyed.
1016 * MACH_MSG_SUCCESS Successful copyin.
1017 * MACH_SEND_INVALID_HEADER
1018 * Illegal value in the message header bits.
1019 * MACH_SEND_INVALID_DEST The space is dead.
1020 * MACH_SEND_INVALID_NOTIFY
1021 * Notify is non-null and doesn't name a receive right.
1022 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1023 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1024 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1025 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1026 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1030 ipc_kmsg_copyin_header(
1031 mach_msg_header_t
*msg
,
1033 mach_port_name_t notify
)
1035 mach_msg_bits_t mbits
= msg
->msgh_bits
& MACH_MSGH_BITS_USER
;
1036 mach_port_name_t dest_name
= (mach_port_name_t
)msg
->msgh_remote_port
;
1037 mach_port_name_t reply_name
= (mach_port_name_t
)msg
->msgh_local_port
;
1040 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
1041 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
1042 ipc_object_t dest_port
, reply_port
;
1043 ipc_port_t dest_soright
, reply_soright
;
1044 ipc_port_t notify_port
;
1046 if ((mbits
!= msg
->msgh_bits
) ||
1047 (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type
)) ||
1048 ((reply_type
== 0) ?
1049 (reply_name
!= MACH_PORT_NULL
) :
1050 !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type
)))
1051 return MACH_SEND_INVALID_HEADER
;
1053 reply_soright
= IP_NULL
; /* in case we go to invalid dest early */
1055 is_write_lock(space
);
1056 if (!space
->is_active
)
1059 if (!MACH_PORT_VALID(dest_name
))
1062 if (notify
!= MACH_PORT_NULL
) {
1065 if ((entry
= ipc_entry_lookup(space
, notify
)) == IE_NULL
) {
1066 is_write_unlock(space
);
1067 return MACH_SEND_INVALID_NOTIFY
;
1069 if((entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
) == 0) {
1070 is_write_unlock(space
);
1071 return MACH_SEND_INVALID_NOTIFY
;
1074 notify_port
= (ipc_port_t
) entry
->ie_object
;
1076 notify_port
= IP_NULL
;
1078 if (dest_name
== reply_name
) {
1080 mach_port_name_t name
= dest_name
;
1083 * Destination and reply ports are the same!
1084 * This is a little tedious to make atomic, because
1085 * there are 25 combinations of dest_type/reply_type.
1086 * However, most are easy. If either is move-sonce,
1087 * then there must be an error. If either are
1088 * make-send or make-sonce, then we must be looking
1089 * at a receive right so the port can't die.
1090 * The hard cases are the combinations of
1091 * copy-send and make-send.
1094 entry
= ipc_entry_lookup(space
, name
);
1095 if (entry
== IE_NULL
)
1098 assert(reply_type
!= 0); /* because name not null */
1100 if (!ipc_right_copyin_check(space
, name
, entry
, reply_type
))
1103 if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
) ||
1104 (reply_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
)) {
1106 * Why must there be an error? To get a valid
1107 * destination, this entry must name a live
1108 * port (not a dead name or dead port). However
1109 * a successful move-sonce will destroy a
1110 * live entry. Therefore the other copyin,
1111 * whatever it is, would fail. We've already
1112 * checked for reply port errors above,
1113 * so report a destination error.
1117 } else if ((dest_type
== MACH_MSG_TYPE_MAKE_SEND
) ||
1118 (dest_type
== MACH_MSG_TYPE_MAKE_SEND_ONCE
) ||
1119 (reply_type
== MACH_MSG_TYPE_MAKE_SEND
) ||
1120 (reply_type
== MACH_MSG_TYPE_MAKE_SEND_ONCE
)) {
1121 kr
= ipc_right_copyin(space
, name
, entry
,
1123 &dest_port
, &dest_soright
);
1124 if (kr
!= KERN_SUCCESS
)
1128 * Either dest or reply needs a receive right.
1129 * We know the receive right is there, because
1130 * of the copyin_check and copyin calls. Hence
1131 * the port is not in danger of dying. If dest
1132 * used the receive right, then the right needed
1133 * by reply (and verified by copyin_check) will
1137 assert(IO_VALID(dest_port
));
1138 assert(entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
);
1139 assert(dest_soright
== IP_NULL
);
1141 kr
= ipc_right_copyin(space
, name
, entry
,
1143 &reply_port
, &reply_soright
);
1145 assert(kr
== KERN_SUCCESS
);
1146 assert(reply_port
== dest_port
);
1147 assert(entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
);
1148 assert(reply_soright
== IP_NULL
);
1149 } else if ((dest_type
== MACH_MSG_TYPE_COPY_SEND
) &&
1150 (reply_type
== MACH_MSG_TYPE_COPY_SEND
)) {
1152 * To make this atomic, just do one copy-send,
1153 * and dup the send right we get out.
1156 kr
= ipc_right_copyin(space
, name
, entry
,
1158 &dest_port
, &dest_soright
);
1159 if (kr
!= KERN_SUCCESS
)
1162 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND
);
1163 assert(dest_soright
== IP_NULL
);
1166 * It's OK if the port we got is dead now,
1167 * so reply_port is IP_DEAD, because the msg
1168 * won't go anywhere anyway.
1171 reply_port
= (ipc_object_t
)
1172 ipc_port_copy_send((ipc_port_t
) dest_port
);
1173 reply_soright
= IP_NULL
;
1174 } else if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND
) &&
1175 (reply_type
== MACH_MSG_TYPE_MOVE_SEND
)) {
1177 * This is an easy case. Just use our
1178 * handy-dandy special-purpose copyin call
1179 * to get two send rights for the price of one.
1182 kr
= ipc_right_copyin_two(space
, name
, entry
,
1183 &dest_port
, &dest_soright
);
1184 if (kr
!= KERN_SUCCESS
)
1187 /* the entry might need to be deallocated */
1188 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1189 ipc_entry_dealloc(space
, name
, entry
);
1191 reply_port
= dest_port
;
1192 reply_soright
= IP_NULL
;
1196 assert(((dest_type
== MACH_MSG_TYPE_COPY_SEND
) &&
1197 (reply_type
== MACH_MSG_TYPE_MOVE_SEND
)) ||
1198 ((dest_type
== MACH_MSG_TYPE_MOVE_SEND
) &&
1199 (reply_type
== MACH_MSG_TYPE_COPY_SEND
)));
1202 * To make this atomic, just do a move-send,
1203 * and dup the send right we get out.
1206 kr
= ipc_right_copyin(space
, name
, entry
,
1207 MACH_MSG_TYPE_MOVE_SEND
, FALSE
,
1208 &dest_port
, &soright
);
1209 if (kr
!= KERN_SUCCESS
)
1212 /* the entry might need to be deallocated */
1214 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1215 ipc_entry_dealloc(space
, name
, entry
);
1218 * It's OK if the port we got is dead now,
1219 * so reply_port is IP_DEAD, because the msg
1220 * won't go anywhere anyway.
1223 reply_port
= (ipc_object_t
)
1224 ipc_port_copy_send((ipc_port_t
) dest_port
);
1226 if (dest_type
== MACH_MSG_TYPE_MOVE_SEND
) {
1227 dest_soright
= soright
;
1228 reply_soright
= IP_NULL
;
1230 dest_soright
= IP_NULL
;
1231 reply_soright
= soright
;
1234 } else if (!MACH_PORT_VALID(reply_name
)) {
1238 * No reply port! This is an easy case
1239 * to make atomic. Just copyin the destination.
1242 entry
= ipc_entry_lookup(space
, dest_name
);
1243 if (entry
== IE_NULL
)
1246 kr
= ipc_right_copyin(space
, dest_name
, entry
,
1248 &dest_port
, &dest_soright
);
1249 if (kr
!= KERN_SUCCESS
)
1252 /* the entry might need to be deallocated */
1254 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1255 ipc_entry_dealloc(space
, dest_name
, entry
);
1257 reply_port
= (ipc_object_t
) reply_name
;
1258 reply_soright
= IP_NULL
;
1260 ipc_entry_t dest_entry
, reply_entry
;
1263 * This is the tough case to make atomic.
1264 * The difficult problem is serializing with port death.
1265 * At the time we copyin dest_port, it must be alive.
1266 * If reply_port is alive when we copyin it, then
1267 * we are OK, because we serialize before the death
1268 * of both ports. Assume reply_port is dead at copyin.
1269 * Then if dest_port dies/died after reply_port died,
1270 * we are OK, because we serialize between the death
1271 * of the two ports. So the bad case is when dest_port
1272 * dies after its copyin, reply_port dies before its
1273 * copyin, and dest_port dies before reply_port. Then
1274 * the copyins operated as if dest_port was alive
1275 * and reply_port was dead, which shouldn't have happened
1276 * because they died in the other order.
1278 * Note that it is easy for a user task to tell if
1279 * a copyin happened before or after a port died.
1280 * For example, suppose both dest and reply are
1281 * send-once rights (types are both move-sonce) and
1282 * both rights have dead-name requests registered.
1283 * If a port dies before copyin, a dead-name notification
1284 * is generated and the dead name's urefs are incremented,
1285 * and if the copyin happens first, a port-deleted
1286 * notification is generated.
1288 * Note that although the entries are different,
1289 * dest_port and reply_port might still be the same.
1291 * JMM - The code to handle this was too expensive and, anyway,
1292 * we intend to separate the dest lookup from the reply copyin
1293 * by a wide margin, so the user will have to learn to deal!
1294 * I will be making the change soon!
1297 dest_entry
= ipc_entry_lookup(space
, dest_name
);
1298 if (dest_entry
== IE_NULL
)
1301 reply_entry
= ipc_entry_lookup(space
, reply_name
);
1302 if (reply_entry
== IE_NULL
)
1305 assert(dest_entry
!= reply_entry
); /* names are not equal */
1306 assert(reply_type
!= 0); /* because reply_name not null */
1308 if (!ipc_right_copyin_check(space
, reply_name
, reply_entry
,
1312 kr
= ipc_right_copyin(space
, dest_name
, dest_entry
,
1314 &dest_port
, &dest_soright
);
1315 if (kr
!= KERN_SUCCESS
)
1318 assert(IO_VALID(dest_port
));
1320 kr
= ipc_right_copyin(space
, reply_name
, reply_entry
,
1322 &reply_port
, &reply_soright
);
1324 assert(kr
== KERN_SUCCESS
);
1326 /* the entries might need to be deallocated */
1328 if (IE_BITS_TYPE(reply_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1329 ipc_entry_dealloc(space
, reply_name
, reply_entry
);
1331 if (IE_BITS_TYPE(dest_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1332 ipc_entry_dealloc(space
, dest_name
, dest_entry
);
1336 * At this point, dest_port, reply_port,
1337 * dest_soright, reply_soright are all initialized.
1338 * Any defunct entries have been deallocated.
1339 * The space is still write-locked, and we need to
1340 * make the MACH_SEND_CANCEL check. The notify_port pointer
1341 * is still usable, because the copyin code above won't ever
1342 * deallocate a receive right, so its entry still exists
1343 * and holds a ref. Note notify_port might even equal
1344 * dest_port or reply_port.
1347 if ((notify
!= MACH_PORT_NULL
) &&
1348 (dest_soright
== notify_port
)) {
1349 ipc_port_release_sonce(dest_soright
);
1350 dest_soright
= IP_NULL
;
1353 is_write_unlock(space
);
1355 if (dest_soright
!= IP_NULL
)
1356 ipc_notify_port_deleted(dest_soright
, dest_name
);
1358 if (reply_soright
!= IP_NULL
)
1359 ipc_notify_port_deleted(reply_soright
, reply_name
);
1361 dest_type
= ipc_object_copyin_type(dest_type
);
1362 reply_type
= ipc_object_copyin_type(reply_type
);
1364 msg
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
1365 MACH_MSGH_BITS(dest_type
, reply_type
));
1366 msg
->msgh_remote_port
= (ipc_port_t
)dest_port
;
1367 msg
->msgh_local_port
= (ipc_port_t
)reply_port
;
1369 return MACH_MSG_SUCCESS
;
1372 is_write_unlock(space
);
1373 return MACH_SEND_INVALID_REPLY
;
1376 is_write_unlock(space
);
1377 if (reply_soright
!= IP_NULL
)
1378 ipc_notify_port_deleted(reply_soright
, reply_name
);
1379 return MACH_SEND_INVALID_DEST
;
1383 * Routine: ipc_kmsg_copyin_body
1385 * "Copy-in" port rights and out-of-line memory
1386 * in the message body.
1388 * In all failure cases, the message is left holding
1389 * no rights or memory. However, the message buffer
1390 * is not deallocated. If successful, the message
1391 * contains a valid destination port.
1395 * MACH_MSG_SUCCESS Successful copyin.
1396 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
1397 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
1398 * MACH_SEND_INVALID_TYPE Bad type specification.
1399 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
1400 * MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
1401 * MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
1404 #define DESC_COUNT_SMALL 64
1407 ipc_kmsg_copyin_body(
1413 mach_msg_body_t
*body
;
1414 mach_msg_descriptor_t
*daddr
, *naddr
;
1415 mach_msg_type_number_t dsc_count
;
1416 boolean_t differs
= MAP_SIZE_DIFFERS(map
);
1417 boolean_t
complex = FALSE
;
1418 vm_size_t space_needed
= 0;
1419 vm_size_t desc_size_space
[DESC_COUNT_SMALL
];
1420 vm_size_t
*user_desc_sizes
= NULL
;
1421 vm_offset_t paddr
= 0;
1422 vm_map_copy_t copy
= VM_MAP_COPY_NULL
;
1424 mach_msg_type_number_t i
;
1425 mach_msg_return_t mr
= MACH_MSG_SUCCESS
;
1428 * Determine if the target is a kernel port.
1430 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
1431 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
1432 naddr
= (mach_msg_descriptor_t
*) (body
+ 1);
1434 dsc_count
= body
->msgh_descriptor_count
;
1436 return MACH_MSG_SUCCESS
;
1439 user_desc_sizes
= (dsc_count
<= DESC_COUNT_SMALL
) ?
1440 &desc_size_space
: kalloc(dsc_count
* sizeof(vm_size_t
));
1441 if (user_desc_sizes
== NULL
) {
1442 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1443 return KERN_RESOURCE_SHORTAGE
;
1448 * Make an initial pass to determine kernal VM space requirements for
1449 * physical copies and possible contraction of the descriptors from
1450 * processes with pointers larger than the kernel's.
1453 for (i
= 0; i
< dsc_count
; i
++) {
1456 /* make sure the descriptor fits in the message */
1458 switch (daddr
->type
.type
) {
1459 case MACH_MSG_OOL_DESCRIPTOR
:
1460 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1461 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
1462 user_desc_sizes
[i
] = sizeof(OTHER_OOL_DESCRIPTOR
);
1465 user_desc_sizes
[i
] = sizeof(*daddr
);
1468 naddr
= (mach_msg_descriptor_t
*)
1469 ((vm_offset_t
)daddr
+ user_desc_sizes
[i
]);
1474 if (naddr
> (mach_msg_descriptor_t
*)
1475 ((vm_offset_t
)kmsg
->ikm_header
+ kmsg
->ikm_header
->msgh_size
)) {
1476 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1477 mr
= MACH_SEND_MSG_TOO_SMALL
;
1481 switch (daddr
->type
.type
) {
1482 mach_msg_size_t size
;
1484 case MACH_MSG_OOL_DESCRIPTOR
:
1485 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1487 ((OTHER_OOL_DESCRIPTOR
*)daddr
)->size
:
1488 daddr
->out_of_line
.size
;
1490 if (daddr
->out_of_line
.copy
!= MACH_MSG_PHYSICAL_COPY
&&
1491 daddr
->out_of_line
.copy
!= MACH_MSG_VIRTUAL_COPY
) {
1493 * Invalid copy option
1495 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1496 mr
= MACH_SEND_INVALID_TYPE
;
1500 if ((size
>= MSG_OOL_SIZE_SMALL
) &&
1501 (daddr
->out_of_line
.copy
== MACH_MSG_PHYSICAL_COPY
) &&
1502 !(daddr
->out_of_line
.deallocate
)) {
1505 * Out-of-line memory descriptor, accumulate kernel
1506 * memory requirements
1508 space_needed
+= round_page(size
);
1509 if (space_needed
> ipc_kmsg_max_vm_space
) {
1512 * Per message kernel memory limit exceeded
1514 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1515 mr
= MACH_MSG_VM_KERNEL
;
1523 * Allocate space in the pageable kernel ipc copy map for all the
1524 * ool data that is to be physically copied. Map is marked wait for
1528 if (vm_allocate(ipc_kernel_copy_map
, &paddr
, space_needed
, VM_FLAGS_ANYWHERE
) !=
1530 ipc_kmsg_clean_partial(kmsg
,0,0,0,0);
1531 mr
= MACH_MSG_VM_KERNEL
;
1537 * handle the OOL regions and port descriptors.
1538 * We process them in reverse order starting with the last one
1539 * scanned above. That way, we can compact them up against
1540 * the message body (if the user-descriptor size is larger than
1541 * the kernel representation).
1546 switch (daddr
->type
.type
) {
1548 /* port descriptors are the same size everywhere, how nice */
1549 case MACH_MSG_PORT_DESCRIPTOR
: {
1550 mach_msg_type_name_t user_disp
;
1551 mach_msg_type_name_t result_disp
;
1552 mach_port_name_t name
;
1553 ipc_object_t object
;
1554 volatile mach_msg_port_descriptor_t
*dsc
;
1555 volatile mach_msg_port_descriptor_t
*user_dsc
;
1557 user_dsc
= &daddr
->port
;
1560 user_disp
= user_dsc
->disposition
;
1561 result_disp
= ipc_object_copyin_type(user_disp
);
1563 name
= (mach_port_name_t
)user_dsc
->name
;
1564 if (MACH_PORT_VALID(name
)) {
1566 kr
= ipc_object_copyin(space
, name
, user_disp
, &object
);
1567 if (kr
!= KERN_SUCCESS
) {
1568 mr
= MACH_SEND_INVALID_RIGHT
;
1572 if ((result_disp
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1573 ipc_port_check_circularity((ipc_port_t
) object
,
1574 (ipc_port_t
) dest
)) {
1575 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
1577 dsc
->name
= (ipc_port_t
) object
;
1579 dsc
->name
= (mach_port_t
)name
;
1581 dsc
->disposition
= result_disp
;
1582 dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
1587 /* out of line descriptors differ in size between 32 and 64 bit processes */
1588 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1589 case MACH_MSG_OOL_DESCRIPTOR
: {
1592 mach_msg_copy_options_t copy_options
;
1593 mach_vm_offset_t addr
;
1594 mach_msg_descriptor_type_t dsc_type
;
1596 volatile mach_msg_ool_descriptor_t
*dsc
;
1599 volatile OTHER_OOL_DESCRIPTOR
*user_dsc
;
1601 user_dsc
= (OTHER_OOL_DESCRIPTOR
*)&daddr
->out_of_line
;
1602 addr
= (mach_vm_offset_t
) user_dsc
->address
;
1603 length
= user_dsc
->size
;
1604 dealloc
= user_dsc
->deallocate
;
1605 copy_options
= user_dsc
->copy
;
1606 dsc_type
= user_dsc
->type
;
1608 volatile mach_msg_ool_descriptor_t
*user_dsc
;
1610 user_dsc
= &daddr
->out_of_line
;
1611 addr
= CAST_USER_ADDR_T(user_dsc
->address
);
1612 dealloc
= user_dsc
->deallocate
;
1613 copy_options
= user_dsc
->copy
;
1614 dsc_type
= user_dsc
->type
;
1615 length
= user_dsc
->size
;
1618 dsc
= &naddr
->out_of_line
;
1620 dsc
->deallocate
= dealloc
;
1621 dsc
->copy
= copy_options
;
1622 dsc
->type
= dsc_type
;
1626 } else if ((length
>= MSG_OOL_SIZE_SMALL
) &&
1627 (copy_options
== MACH_MSG_PHYSICAL_COPY
) && !dealloc
) {
1630 * If the request is a physical copy and the source
1631 * is not being deallocated, then allocate space
1632 * in the kernel's pageable ipc copy map and copy
1633 * the data in. The semantics guarantee that the
1634 * data will have been physically copied before
1635 * the send operation terminates. Thus if the data
1636 * is not being deallocated, we must be prepared
1637 * to page if the region is sufficiently large.
1639 if (copyin(addr
, (char *) paddr
, length
)) {
1640 mr
= MACH_SEND_INVALID_MEMORY
;
1645 * The kernel ipc copy map is marked no_zero_fill.
1646 * If the transfer is not a page multiple, we need
1647 * to zero fill the balance.
1649 if (!page_aligned(length
)) {
1650 (void) memset((void *) (paddr
+ length
), 0,
1651 round_page(length
) - length
);
1653 if (vm_map_copyin(ipc_kernel_copy_map
, (vm_map_address_t
)paddr
,
1654 (vm_map_size_t
)length
, TRUE
, ©
) != KERN_SUCCESS
) {
1655 mr
= MACH_MSG_VM_KERNEL
;
1658 dsc
->address
= (void *) copy
;
1659 paddr
+= round_page(length
);
1660 space_needed
-= round_page(length
);
1664 * Make a vm_map_copy_t of the of the data. If the
1665 * data is small, this will do an optimized physical
1666 * copy. Otherwise, it will do a virtual copy.
1668 * NOTE: A virtual copy is OK if the original is being
1669 * deallocted, even if a physical copy was requested.
1671 kr
= vm_map_copyin(map
, addr
,
1672 (vm_map_size_t
)length
, dealloc
, ©
);
1673 if (kr
!= KERN_SUCCESS
) {
1674 mr
= (kr
== KERN_RESOURCE_SHORTAGE
) ?
1675 MACH_MSG_VM_KERNEL
:
1676 MACH_SEND_INVALID_MEMORY
;
1679 dsc
->address
= (void *) copy
;
1684 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
1687 ipc_object_t
*objects
;
1689 mach_vm_offset_t addr
;
1690 mach_msg_type_name_t user_disp
;
1691 mach_msg_type_name_t result_disp
;
1692 mach_msg_type_number_t count
;
1693 mach_msg_copy_options_t copy_option
;
1694 boolean_t deallocate
;
1696 volatile mach_msg_ool_ports_descriptor_t
*dsc
;
1699 volatile OTHER_OOL_PORTS_DESCRIPTOR
*user_dsc
;
1701 user_dsc
= (OTHER_OOL_PORTS_DESCRIPTOR
*)&daddr
->ool_ports
;
1702 addr
= (mach_vm_offset_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
;
1708 volatile mach_msg_ool_ports_descriptor_t
*user_dsc
;
1710 user_dsc
= &daddr
->ool_ports
;
1711 addr
= CAST_USER_ADDR_T(user_dsc
->address
);
1712 count
= user_dsc
->count
;
1713 deallocate
= user_dsc
->deallocate
;
1714 copy_option
= user_dsc
->copy
;
1715 user_disp
= user_dsc
->disposition
;
1718 dsc
= &naddr
->ool_ports
;
1719 dsc
->deallocate
= deallocate
;
1720 dsc
->copy
= copy_option
;
1721 dsc
->type
= daddr
->type
.type
;
1724 /* calculate length of data in bytes, rounding up */
1725 length
= count
* sizeof(mach_port_name_t
);
1729 dsc
->address
= (void *) 0;
1733 data
= kalloc(length
);
1736 mr
= MACH_SEND_NO_BUFFER
;
1740 if (copyinmap(map
, addr
, data
, length
) != KERN_SUCCESS
) {
1741 kfree(data
, length
);
1742 mr
= MACH_SEND_INVALID_MEMORY
;
1747 (void) mach_vm_deallocate(map
, addr
, (mach_vm_size_t
)length
);
1750 dsc
->address
= data
;
1752 result_disp
= ipc_object_copyin_type(user_disp
);
1753 dsc
->disposition
= result_disp
;
1755 objects
= (ipc_object_t
*) data
;
1757 for ( j
= 0; j
< count
; j
++) {
1758 mach_port_name_t port
= (mach_port_name_t
) objects
[j
];
1759 ipc_object_t object
;
1761 if (!MACH_PORT_VALID(port
))
1764 kr
= ipc_object_copyin(space
, port
, user_disp
, &object
);
1766 if (kr
!= KERN_SUCCESS
) {
1769 for(k
= 0; k
< j
; k
++) {
1770 object
= objects
[k
];
1771 if (IPC_OBJECT_VALID(object
))
1772 ipc_object_destroy(object
, result_disp
);
1774 kfree(data
, length
);
1775 mr
= MACH_SEND_INVALID_RIGHT
;
1779 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1780 ipc_port_check_circularity(
1781 (ipc_port_t
) object
,
1783 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
1785 objects
[j
] = object
;
1793 * Invalid descriptor
1795 mr
= MACH_SEND_INVALID_TYPE
;
1800 if (MACH_MSG_SUCCESS
!= mr
) {
1801 ipc_kmsg_clean_partial(kmsg
, dsc_count
- i
,
1802 naddr
+ 1, paddr
, space_needed
);
1808 (daddr
= (differs
) ? (mach_msg_descriptor_t
*)((vm_offset_t
)(daddr
) -
1809 user_desc_sizes
[i
- 1]) : daddr
- 1)
1814 kmsg
->ikm_header
->msgh_bits
&= ~MACH_MSGH_BITS_COMPLEX
;
1817 if (differs
&& naddr
!= daddr
) {
1818 mach_msg_base_t
*old_base
= (mach_msg_base_t
*)kmsg
->ikm_header
;
1819 mach_msg_base_t
*new_base
= (mach_msg_base_t
*)naddr
- 1;
1821 memmove(new_base
, old_base
, sizeof(mach_msg_base_t
));
1822 new_base
->header
.msgh_size
-= (vm_offset_t
)naddr
- (vm_offset_t
)daddr
;
1823 kmsg
->ikm_header
= &new_base
->header
;
1827 if (differs
&& dsc_count
> DESC_COUNT_SMALL
)
1828 kfree(user_desc_sizes
, body
->msgh_descriptor_count
* sizeof(vm_size_t
));
1835 * Routine: ipc_kmsg_copyin
1837 * "Copy-in" port rights and out-of-line memory
1840 * In all failure cases, the message is left holding
1841 * no rights or memory. However, the message buffer
1842 * is not deallocated. If successful, the message
1843 * contains a valid destination port.
1847 * MACH_MSG_SUCCESS Successful copyin.
1848 * MACH_SEND_INVALID_HEADER
1849 * Illegal value in the message header bits.
1850 * MACH_SEND_INVALID_NOTIFY Bad notify port.
1851 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1852 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1853 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
1854 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
1855 * MACH_SEND_INVALID_TYPE Bad type specification.
1856 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
1864 mach_port_name_t notify
)
1866 mach_msg_return_t mr
;
1868 mr
= ipc_kmsg_copyin_header(kmsg
->ikm_header
, space
, notify
);
1869 if (mr
!= MACH_MSG_SUCCESS
)
1872 if ((kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
1873 return MACH_MSG_SUCCESS
;
1875 return( ipc_kmsg_copyin_body( kmsg
, space
, map
) );
1879 * Routine: ipc_kmsg_copyin_from_kernel
1881 * "Copy-in" port rights and out-of-line memory
1882 * in a message sent from the kernel.
1884 * Because the message comes from the kernel,
1885 * the implementation assumes there are no errors
1886 * or peculiarities in the message.
1888 * Returns TRUE if queueing the message
1889 * would result in a circularity.
1895 ipc_kmsg_copyin_from_kernel(
1898 mach_msg_bits_t bits
= kmsg
->ikm_header
->msgh_bits
;
1899 mach_msg_type_name_t rname
= MACH_MSGH_BITS_REMOTE(bits
);
1900 mach_msg_type_name_t lname
= MACH_MSGH_BITS_LOCAL(bits
);
1901 ipc_object_t remote
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
1902 ipc_object_t local
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
1904 /* translate the destination and reply ports */
1906 ipc_object_copyin_from_kernel(remote
, rname
);
1907 if (IO_VALID(local
))
1908 ipc_object_copyin_from_kernel(local
, lname
);
1911 * The common case is a complex message with no reply port,
1912 * because that is what the memory_object interface uses.
1915 if (bits
== (MACH_MSGH_BITS_COMPLEX
|
1916 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0))) {
1917 bits
= (MACH_MSGH_BITS_COMPLEX
|
1918 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND
, 0));
1920 kmsg
->ikm_header
->msgh_bits
= bits
;
1922 bits
= (MACH_MSGH_BITS_OTHER(bits
) |
1923 MACH_MSGH_BITS(ipc_object_copyin_type(rname
),
1924 ipc_object_copyin_type(lname
)));
1926 kmsg
->ikm_header
->msgh_bits
= bits
;
1927 if ((bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
1931 mach_msg_descriptor_t
*saddr
, *eaddr
;
1932 mach_msg_body_t
*body
;
1934 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
1935 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
1936 eaddr
= (mach_msg_descriptor_t
*) saddr
+ body
->msgh_descriptor_count
;
1938 for ( ; saddr
< eaddr
; saddr
++) {
1940 switch (saddr
->type
.type
) {
1942 case MACH_MSG_PORT_DESCRIPTOR
: {
1943 mach_msg_type_name_t name
;
1944 ipc_object_t object
;
1945 mach_msg_port_descriptor_t
*dsc
;
1949 /* this is really the type SEND, SEND_ONCE, etc. */
1950 name
= dsc
->disposition
;
1951 object
= (ipc_object_t
) dsc
->name
;
1952 dsc
->disposition
= ipc_object_copyin_type(name
);
1954 if (!IO_VALID(object
)) {
1958 ipc_object_copyin_from_kernel(object
, name
);
1960 /* CDY avoid circularity when the destination is also */
1961 /* the kernel. This check should be changed into an */
1962 /* assert when the new kobject model is in place since*/
1963 /* ports will not be used in kernel to kernel chats */
1965 if (((ipc_port_t
)remote
)->ip_receiver
!= ipc_space_kernel
) {
1966 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1967 ipc_port_check_circularity((ipc_port_t
) object
,
1968 (ipc_port_t
) remote
)) {
1969 kmsg
->ikm_header
->msgh_bits
|=
1970 MACH_MSGH_BITS_CIRCULAR
;
1975 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1976 case MACH_MSG_OOL_DESCRIPTOR
: {
1978 * The sender should supply ready-made memory, i.e.
1979 * a vm_map_copy_t, so we don't need to do anything.
1983 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
1984 ipc_object_t
*objects
;
1986 mach_msg_type_name_t name
;
1987 mach_msg_ool_ports_descriptor_t
*dsc
;
1989 dsc
= &saddr
->ool_ports
;
1991 /* this is really the type SEND, SEND_ONCE, etc. */
1992 name
= dsc
->disposition
;
1993 dsc
->disposition
= ipc_object_copyin_type(name
);
1995 objects
= (ipc_object_t
*) dsc
->address
;
1997 for ( j
= 0; j
< dsc
->count
; j
++) {
1998 ipc_object_t object
= objects
[j
];
2000 if (!IO_VALID(object
))
2003 ipc_object_copyin_from_kernel(object
, name
);
2005 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
2006 ipc_port_check_circularity(
2007 (ipc_port_t
) object
,
2008 (ipc_port_t
) remote
))
2009 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
2015 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
2016 #endif /* MACH_ASSERT */
2024 * Routine: ipc_kmsg_copyout_header
2026 * "Copy-out" port rights in the header of a message.
2027 * Operates atomically; if it doesn't succeed the
2028 * message header and the space are left untouched.
2029 * If it does succeed the remote/local port fields
2030 * contain port names instead of object pointers,
2031 * and the bits field is updated.
2033 * The notify argument implements the MACH_RCV_NOTIFY option.
2034 * If it is not MACH_PORT_NULL, it should name a receive right.
2035 * If the process of receiving the reply port creates a
2036 * new right in the receiving task, then the new right is
2037 * automatically registered for a dead-name notification,
2038 * with the notify port supplying the send-once right.
2042 * MACH_MSG_SUCCESS Copied out port rights.
2043 * MACH_RCV_INVALID_NOTIFY
2044 * Notify is non-null and doesn't name a receive right.
2045 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
2046 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
2047 * The space is dead.
2048 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
2049 * No room in space for another name.
2050 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
2051 * Couldn't allocate memory for the reply port.
2052 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
2053 * Couldn't allocate memory for the dead-name request.
2057 ipc_kmsg_copyout_header(
2058 mach_msg_header_t
*msg
,
2060 mach_port_name_t notify
)
2062 mach_msg_bits_t mbits
= msg
->msgh_bits
;
2063 ipc_port_t dest
= (ipc_port_t
) msg
->msgh_remote_port
;
2065 assert(IP_VALID(dest
));
2068 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2069 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2070 ipc_port_t reply
= (ipc_port_t
) msg
->msgh_local_port
;
2071 mach_port_name_t dest_name
, reply_name
;
2073 if (IP_VALID(reply
)) {
2074 ipc_port_t notify_port
;
2079 * Handling notify (for MACH_RCV_NOTIFY) is tricky.
2080 * The problem is atomically making a send-once right
2081 * from the notify port and installing it for a
2082 * dead-name request in the new entry, because this
2083 * requires two port locks (on the notify port and
2084 * the reply port). However, we can safely make
2085 * and consume send-once rights for the notify port
2086 * as long as we hold the space locked. This isn't
2087 * an atomicity problem, because the only way
2088 * to detect that a send-once right has been created
2089 * and then consumed if it wasn't needed is by getting
2090 * at the receive right to look at ip_sorights, and
2091 * because the space is write-locked status calls can't
2092 * lookup the notify port receive right. When we make
2093 * the send-once right, we lock the notify port,
2094 * so any status calls in progress will be done.
2097 is_write_lock(space
);
2100 ipc_port_request_index_t request
;
2102 if (!space
->is_active
) {
2103 is_write_unlock(space
);
2104 return (MACH_RCV_HEADER_ERROR
|
2105 MACH_MSG_IPC_SPACE
);
2108 if (notify
!= MACH_PORT_NULL
) {
2109 notify_port
= ipc_port_lookup_notify(space
,
2111 if (notify_port
== IP_NULL
) {
2112 is_write_unlock(space
);
2113 return MACH_RCV_INVALID_NOTIFY
;
2116 notify_port
= IP_NULL
;
2118 if ((reply_type
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
2119 ipc_right_reverse(space
, (ipc_object_t
) reply
,
2120 &reply_name
, &entry
)) {
2121 /* reply port is locked and active */
2124 * We don't need the notify_port
2125 * send-once right, but we can't release
2126 * it here because reply port is locked.
2127 * Wait until after the copyout to
2128 * release the notify port right.
2131 assert(entry
->ie_bits
&
2132 MACH_PORT_TYPE_SEND_RECEIVE
);
2137 if (!ip_active(reply
)) {
2139 ip_check_unlock(reply
);
2141 if (notify_port
!= IP_NULL
)
2142 ipc_port_release_sonce(notify_port
);
2145 is_write_unlock(space
);
2148 reply_name
= MACH_PORT_DEAD
;
2152 reply_name
= (mach_port_name_t
)reply
;
2153 kr
= ipc_entry_get(space
, &reply_name
, &entry
);
2154 if (kr
!= KERN_SUCCESS
) {
2157 if (notify_port
!= IP_NULL
)
2158 ipc_port_release_sonce(notify_port
);
2160 /* space is locked */
2161 kr
= ipc_entry_grow_table(space
,
2163 if (kr
!= KERN_SUCCESS
) {
2164 /* space is unlocked */
2166 if (kr
== KERN_RESOURCE_SHORTAGE
)
2167 return (MACH_RCV_HEADER_ERROR
|
2168 MACH_MSG_IPC_KERNEL
);
2170 return (MACH_RCV_HEADER_ERROR
|
2171 MACH_MSG_IPC_SPACE
);
2173 /* space is locked again; start over */
2177 assert(IE_BITS_TYPE(entry
->ie_bits
) ==
2178 MACH_PORT_TYPE_NONE
);
2179 assert(entry
->ie_object
== IO_NULL
);
2181 if (notify_port
== IP_NULL
) {
2182 /* not making a dead-name request */
2184 entry
->ie_object
= (ipc_object_t
) reply
;
2188 kr
= ipc_port_dnrequest(reply
, reply_name
,
2189 notify_port
, &request
);
2190 if (kr
!= KERN_SUCCESS
) {
2193 ipc_port_release_sonce(notify_port
);
2195 ipc_entry_dealloc(space
, reply_name
, entry
);
2196 is_write_unlock(space
);
2199 if (!ip_active(reply
)) {
2200 /* will fail next time around loop */
2203 is_write_lock(space
);
2207 kr
= ipc_port_dngrow(reply
, ITS_SIZE_NONE
);
2208 /* port is unlocked */
2209 if (kr
!= KERN_SUCCESS
)
2210 return (MACH_RCV_HEADER_ERROR
|
2211 MACH_MSG_IPC_KERNEL
);
2213 is_write_lock(space
);
2217 notify_port
= IP_NULL
; /* don't release right below */
2219 entry
->ie_object
= (ipc_object_t
) reply
;
2220 entry
->ie_request
= request
;
2224 /* space and reply port are locked and active */
2226 ip_reference(reply
); /* hold onto the reply port */
2228 kr
= ipc_right_copyout(space
, reply_name
, entry
,
2229 reply_type
, TRUE
, (ipc_object_t
) reply
);
2230 /* reply port is unlocked */
2231 assert(kr
== KERN_SUCCESS
);
2233 if (notify_port
!= IP_NULL
)
2234 ipc_port_release_sonce(notify_port
);
2237 is_write_unlock(space
);
2240 * No reply port! This is an easy case.
2241 * We only need to have the space locked
2242 * when checking notify and when locking
2243 * the destination (to ensure atomicity).
2246 is_read_lock(space
);
2247 if (!space
->is_active
) {
2248 is_read_unlock(space
);
2249 return MACH_RCV_HEADER_ERROR
|MACH_MSG_IPC_SPACE
;
2252 if (notify
!= MACH_PORT_NULL
) {
2255 /* must check notify even though it won't be used */
2257 if ((entry
= ipc_entry_lookup(space
, notify
)) == IE_NULL
) {
2258 is_read_unlock(space
);
2259 return MACH_RCV_INVALID_NOTIFY
;
2262 if ((entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
) == 0) {
2263 is_read_unlock(space
);
2264 return MACH_RCV_INVALID_NOTIFY
;
2269 is_read_unlock(space
);
2271 reply_name
= (mach_port_name_t
) reply
;
2275 * At this point, the space is unlocked and the destination
2276 * port is locked. (Lock taken while space was locked.)
2277 * reply_name is taken care of; we still need dest_name.
2278 * We still hold a ref for reply (if it is valid).
2280 * If the space holds receive rights for the destination,
2281 * we return its name for the right. Otherwise the task
2282 * managed to destroy or give away the receive right between
2283 * receiving the message and this copyout. If the destination
2284 * is dead, return MACH_PORT_DEAD, and if the receive right
2285 * exists somewhere else (another space, in transit)
2286 * return MACH_PORT_NULL.
2288 * Making this copyout operation atomic with the previous
2289 * copyout of the reply port is a bit tricky. If there was
2290 * no real reply port (it wasn't IP_VALID) then this isn't
2291 * an issue. If the reply port was dead at copyout time,
2292 * then we are OK, because if dest is dead we serialize
2293 * after the death of both ports and if dest is alive
2294 * we serialize after reply died but before dest's (later) death.
2295 * So assume reply was alive when we copied it out. If dest
2296 * is alive, then we are OK because we serialize before
2297 * the ports' deaths. So assume dest is dead when we look at it.
2298 * If reply dies/died after dest, then we are OK because
2299 * we serialize after dest died but before reply dies.
2300 * So the hard case is when reply is alive at copyout,
2301 * dest is dead at copyout, and reply died before dest died.
2302 * In this case pretend that dest is still alive, so
2303 * we serialize while both ports are alive.
2305 * Because the space lock is held across the copyout of reply
2306 * and locking dest, the receive right for dest can't move
2307 * in or out of the space while the copyouts happen, so
2308 * that isn't an atomicity problem. In the last hard case
2309 * above, this implies that when dest is dead that the
2310 * space couldn't have had receive rights for dest at
2311 * the time reply was copied-out, so when we pretend
2312 * that dest is still alive, we can return MACH_PORT_NULL.
2314 * If dest == reply, then we have to make it look like
2315 * either both copyouts happened before the port died,
2316 * or both happened after the port died. This special
2317 * case works naturally if the timestamp comparison
2318 * is done correctly.
2323 if (ip_active(dest
)) {
2324 ipc_object_copyout_dest(space
, (ipc_object_t
) dest
,
2325 dest_type
, &dest_name
);
2326 /* dest is unlocked */
2328 ipc_port_timestamp_t timestamp
;
2330 timestamp
= dest
->ip_timestamp
;
2332 ip_check_unlock(dest
);
2334 if (IP_VALID(reply
)) {
2336 if (ip_active(reply
) ||
2337 IP_TIMESTAMP_ORDER(timestamp
,
2338 reply
->ip_timestamp
))
2339 dest_name
= MACH_PORT_DEAD
;
2341 dest_name
= MACH_PORT_NULL
;
2344 dest_name
= MACH_PORT_DEAD
;
2347 if (IP_VALID(reply
))
2348 ipc_port_release(reply
);
2350 msg
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
2351 MACH_MSGH_BITS(reply_type
, dest_type
));
2352 msg
->msgh_local_port
= (ipc_port_t
)dest_name
;
2353 msg
->msgh_remote_port
= (ipc_port_t
)reply_name
;
2356 return MACH_MSG_SUCCESS
;
2360 * Routine: ipc_kmsg_copyout_object
2362 * Copy-out a port right. Always returns a name,
2363 * even for unsuccessful return codes. Always
2364 * consumes the supplied object.
2368 * MACH_MSG_SUCCESS The space acquired the right
2369 * (name is valid) or the object is dead (MACH_PORT_DEAD).
2370 * MACH_MSG_IPC_SPACE No room in space for the right,
2371 * or the space is dead. (Name is MACH_PORT_NULL.)
2372 * MACH_MSG_IPC_KERNEL Kernel resource shortage.
2373 * (Name is MACH_PORT_NULL.)
2377 ipc_kmsg_copyout_object(
2379 ipc_object_t object
,
2380 mach_msg_type_name_t msgt_name
,
2381 mach_port_name_t
*namep
)
2385 if (!IO_VALID(object
)) {
2386 *namep
= (mach_port_name_t
) object
;
2387 return MACH_MSG_SUCCESS
;
2390 kr
= ipc_object_copyout(space
, object
, msgt_name
, TRUE
, namep
);
2391 if (kr
!= KERN_SUCCESS
) {
2392 ipc_object_destroy(object
, msgt_name
);
2394 if (kr
== KERN_INVALID_CAPABILITY
)
2395 *namep
= MACH_PORT_DEAD
;
2397 *namep
= MACH_PORT_NULL
;
2399 if (kr
== KERN_RESOURCE_SHORTAGE
)
2400 return MACH_MSG_IPC_KERNEL
;
2402 return MACH_MSG_IPC_SPACE
;
2406 return MACH_MSG_SUCCESS
;
2410 * Routine: ipc_kmsg_copyout_body
2412 * "Copy-out" port rights and out-of-line memory
2413 * in the body of a message.
2415 * The error codes are a combination of special bits.
2416 * The copyout proceeds despite errors.
2420 * MACH_MSG_SUCCESS Successful copyout.
2421 * MACH_MSG_IPC_SPACE No room for port right in name space.
2422 * MACH_MSG_VM_SPACE No room for memory in address space.
2423 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
2424 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
2425 * MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
2429 ipc_kmsg_copyout_body(
2433 mach_msg_body_t
*slist
)
2435 mach_msg_body_t
*body
;
2436 mach_msg_descriptor_t
*daddr
, *naddr
;
2437 mach_msg_descriptor_t
*saddr
;
2438 mach_msg_type_number_t i
, dsc_count
, sdsc_count
;
2439 mach_msg_return_t mr
= MACH_MSG_SUCCESS
;
2442 boolean_t differs
= MAP_SIZE_DIFFERS(map
);
2444 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2445 dsc_count
= body
->msgh_descriptor_count
;
2446 daddr
= (mach_msg_descriptor_t
*) (body
+ 1);
2449 * Do scatter list setup
2451 if (slist
!= MACH_MSG_BODY_NULL
) {
2452 saddr
= (mach_msg_descriptor_t
*) (slist
+ 1);
2453 sdsc_count
= slist
->msgh_descriptor_count
;
2456 saddr
= MACH_MSG_DESCRIPTOR_NULL
;
2461 * Compute the true size of the resulting descriptors
2462 * after potential expansion and adjust the header
2463 * and body location accordingly.
2466 mach_msg_size_t dsc_adjust
;
2470 for (i
= 0; i
< dsc_count
; i
++, naddr
++)
2471 switch (naddr
->type
.type
) {
2472 case MACH_MSG_OOL_DESCRIPTOR
:
2473 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2474 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
2475 dsc_adjust
+= DESC_SIZE_ADJUSTMENT
;
2481 mach_msg_base_t
*old_base
= (mach_msg_base_t
*)kmsg
->ikm_header
;
2482 mach_msg_base_t
*new_base
;
2484 new_base
= (mach_msg_base_t
*)((vm_offset_t
)old_base
- dsc_adjust
);
2485 memmove(new_base
, old_base
, sizeof(mach_msg_base_t
));
2486 kmsg
->ikm_header
= &new_base
->header
;
2487 kmsg
->ikm_header
->msgh_size
+= dsc_adjust
;
2488 naddr
= (mach_msg_descriptor_t
*)(new_base
+ 1);
2497 * Now process the descriptors
2499 for ( i
= 0; i
< dsc_count
; i
++, daddr
++ ) {
2500 switch (daddr
->type
.type
) {
2502 case MACH_MSG_PORT_DESCRIPTOR
: {
2503 volatile mach_msg_port_descriptor_t
*dsc
;
2504 volatile mach_msg_port_descriptor_t
*user_dsc
;
2506 mach_port_name_t name
;
2507 mach_msg_type_name_t disp
;
2510 * Copyout port right carried in the message
2513 user_dsc
= &naddr
->port
;
2515 disp
= dsc
->disposition
;
2516 mr
|= ipc_kmsg_copyout_object(space
,
2520 user_dsc
->name
= (mach_port_t
)name
;
2521 user_dsc
->disposition
= disp
;
2522 user_dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
2527 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2528 case MACH_MSG_OOL_DESCRIPTOR
: {
2530 mach_vm_offset_t rcv_addr
;
2531 mach_msg_ool_descriptor_t
*dsc
;
2532 mach_msg_copy_options_t copy_options
;
2533 mach_msg_size_t size
;
2534 mach_msg_descriptor_type_t dsc_type
;
2536 SKIP_PORT_DESCRIPTORS(saddr
, sdsc_count
);
2538 dsc
= &daddr
->out_of_line
;
2539 copy
= (vm_map_copy_t
) dsc
->address
;
2541 copy_options
= dsc
->copy
;
2542 assert(copy_options
!= MACH_MSG_KALLOC_COPY_T
);
2543 dsc_type
= dsc
->type
;
2545 if (copy
!= VM_MAP_COPY_NULL
) {
2547 * Check to see if there is an overwrite descriptor
2548 * specified in the scatter list for this ool data.
2549 * The descriptor has already been verified.
2551 if (saddr
!= MACH_MSG_DESCRIPTOR_NULL
) {
2553 OTHER_OOL_DESCRIPTOR
*scatter_dsc
;
2555 scatter_dsc
= (OTHER_OOL_DESCRIPTOR
*)saddr
;
2556 if (scatter_dsc
->copy
== MACH_MSG_OVERWRITE
) {
2557 rcv_addr
= (mach_vm_offset_t
) scatter_dsc
->address
;
2558 copy_options
= MACH_MSG_OVERWRITE
;
2561 copy_options
= MACH_MSG_VIRTUAL_COPY
;
2564 mach_msg_ool_descriptor_t
*scatter_dsc
;
2566 scatter_dsc
= &saddr
->out_of_line
;
2567 if (scatter_dsc
->copy
== MACH_MSG_OVERWRITE
) {
2568 rcv_addr
= CAST_USER_ADDR_T(scatter_dsc
->address
);
2569 copy_options
= MACH_MSG_OVERWRITE
;
2572 copy_options
= MACH_MSG_VIRTUAL_COPY
;
2575 INCREMENT_SCATTER(saddr
, sdsc_count
, differs
);
2580 * Whether the data was virtually or physically
2581 * copied we have a vm_map_copy_t for it.
2582 * If there's an overwrite region specified
2583 * overwrite it, otherwise do a virtual copy out.
2585 if (copy_options
== MACH_MSG_OVERWRITE
) {
2586 kr
= vm_map_copy_overwrite(map
, rcv_addr
,
2589 kr
= vm_map_copyout(map
, &rcv_addr
, copy
);
2591 if (kr
!= KERN_SUCCESS
) {
2592 if (kr
== KERN_RESOURCE_SHORTAGE
)
2593 mr
|= MACH_MSG_VM_KERNEL
;
2595 mr
|= MACH_MSG_VM_SPACE
;
2596 vm_map_copy_discard(copy
);
2606 * Now update the descriptor as the user would see it.
2607 * This may require expanding the descriptor to the user
2608 * visible size. There is already space allocated for
2609 * this in what naddr points to.
2612 volatile OTHER_OOL_DESCRIPTOR
*user_dsc
;
2614 user_dsc
= (OTHER_OOL_DESCRIPTOR
*)naddr
;
2615 user_dsc
->address
= rcv_addr
;
2616 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2618 user_dsc
->copy
= copy_options
;
2619 user_dsc
->type
= dsc_type
;
2620 user_dsc
->size
= size
;
2621 naddr
= (mach_msg_descriptor_t
*)((OTHER_OOL_DESCRIPTOR
*)naddr
+ 1);
2623 volatile mach_msg_ool_descriptor_t
*user_dsc
;
2625 user_dsc
= &naddr
->out_of_line
;
2626 user_dsc
->address
= CAST_DOWN(void *, rcv_addr
);
2627 user_dsc
->size
= size
;
2628 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2630 user_dsc
->copy
= copy_options
;
2631 user_dsc
->type
= dsc_type
;
2637 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
2638 mach_vm_offset_t rcv_addr
;
2639 mach_port_name_t
*objects
;
2640 mach_msg_type_name_t disp
;
2641 mach_msg_type_number_t count
, j
;
2644 volatile mach_msg_ool_ports_descriptor_t
*dsc
;
2645 mach_msg_copy_options_t copy_options
= MACH_MSG_VIRTUAL_COPY
;
2647 SKIP_PORT_DESCRIPTORS(saddr
, sdsc_count
);
2649 dsc
= &daddr
->ool_ports
;
2651 disp
= dsc
->disposition
;
2652 length
= count
* sizeof(mach_port_name_t
);
2654 if (length
!= 0 && dsc
->address
!= 0) {
2657 * Check to see if there is an overwrite descriptor
2658 * specified in the scatter list for this ool data.
2659 * The descriptor has already been verified.
2661 if (saddr
!= MACH_MSG_DESCRIPTOR_NULL
) {
2663 OTHER_OOL_DESCRIPTOR
*scatter_dsc
;
2665 scatter_dsc
= (OTHER_OOL_DESCRIPTOR
*)saddr
;
2666 rcv_addr
= (mach_vm_offset_t
) scatter_dsc
->address
;
2667 copy_options
= scatter_dsc
->copy
;
2669 mach_msg_ool_descriptor_t
*scatter_dsc
;
2671 scatter_dsc
= &saddr
->out_of_line
;
2672 rcv_addr
= CAST_USER_ADDR_T(scatter_dsc
->address
);
2673 copy_options
= scatter_dsc
->copy
;
2675 INCREMENT_SCATTER(saddr
, sdsc_count
, differs
);
2678 if (copy_options
== MACH_MSG_VIRTUAL_COPY
) {
2680 * Dynamically allocate the region
2682 int anywhere
= VM_MAKE_TAG(VM_MEMORY_MACH_MSG
)|
2685 if ((kr
= mach_vm_allocate(map
, &rcv_addr
,
2686 (mach_vm_size_t
)length
,
2687 anywhere
)) != KERN_SUCCESS
) {
2688 ipc_kmsg_clean_body(kmsg
, 1, daddr
);
2691 if (kr
== KERN_RESOURCE_SHORTAGE
){
2692 mr
|= MACH_MSG_VM_KERNEL
;
2694 mr
|= MACH_MSG_VM_SPACE
;
2701 * Handle the port rights and copy out the names
2702 * for those rights out to user-space.
2704 if (rcv_addr
!= 0) {
2705 objects
= (mach_port_name_t
*) dsc
->address
;
2707 /* copyout port rights carried in the message */
2709 for ( j
= 0; j
< count
; j
++) {
2710 ipc_object_t object
=
2711 (ipc_object_t
) objects
[j
];
2713 mr
|= ipc_kmsg_copyout_object(space
, object
,
2717 /* copyout to memory allocated above */
2718 data
= dsc
->address
;
2719 if (copyoutmap(map
, data
, rcv_addr
, length
) != KERN_SUCCESS
)
2720 mr
|= MACH_MSG_VM_SPACE
;
2721 kfree(data
, length
);
2728 * Now update the descriptor based on the information
2732 volatile OTHER_OOL_PORTS_DESCRIPTOR
*user_dsc
;
2734 user_dsc
= (OTHER_OOL_PORTS_DESCRIPTOR
*)naddr
;
2735 user_dsc
->address
= rcv_addr
;
2736 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2738 user_dsc
->copy
= copy_options
;
2739 user_dsc
->disposition
= disp
;
2740 user_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
2741 user_dsc
->count
= count
;
2742 naddr
= (mach_msg_descriptor_t
*)((OTHER_OOL_PORTS_DESCRIPTOR
*)naddr
+ 1);
2744 volatile mach_msg_ool_ports_descriptor_t
*user_dsc
;
2746 user_dsc
= &naddr
->ool_ports
;
2747 user_dsc
->address
= CAST_DOWN(void *, rcv_addr
);
2748 user_dsc
->count
= count
;
2749 user_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
2751 user_dsc
->copy
= copy_options
;
2752 user_dsc
->disposition
= disp
;
2753 user_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
2759 panic("untyped IPC copyout body: invalid message descriptor");
2767 * Routine: ipc_kmsg_copyout_size
2769 * Compute the size of the message as copied out to the given
2770 * map. If the destination map's pointers are a different size
2771 * than the kernel's, we have to allow for expansion/
2772 * contraction of the descriptors as appropriate.
2776 * size of the message as it would be received.
2780 ipc_kmsg_copyout_size(
2784 mach_msg_size_t send_size
;
2786 send_size
= kmsg
->ikm_header
->msgh_size
;
2788 if ((kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) &&
2789 MAP_SIZE_DIFFERS(map
)) {
2791 mach_msg_body_t
*body
;
2792 mach_msg_descriptor_t
*saddr
, *eaddr
;
2794 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2795 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
2796 eaddr
= saddr
+ body
->msgh_descriptor_count
;
2798 for ( ; saddr
< eaddr
; saddr
++ ) {
2799 switch (saddr
->type
.type
) {
2801 case MACH_MSG_OOL_DESCRIPTOR
:
2802 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2803 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
2804 send_size
+= DESC_SIZE_ADJUSTMENT
;
2816 * Routine: ipc_kmsg_copyout
2818 * "Copy-out" port rights and out-of-line memory
2823 * MACH_MSG_SUCCESS Copied out all rights and memory.
2824 * MACH_RCV_INVALID_NOTIFY Bad notify port.
2825 * Rights and memory in the message are intact.
2826 * MACH_RCV_HEADER_ERROR + special bits
2827 * Rights and memory in the message are intact.
2828 * MACH_RCV_BODY_ERROR + special bits
2829 * The message header was successfully copied out.
2830 * As much of the body was handled as possible.
2838 mach_port_name_t notify
,
2839 mach_msg_body_t
*slist
)
2841 mach_msg_return_t mr
;
2843 mr
= ipc_kmsg_copyout_header(kmsg
->ikm_header
, space
, notify
);
2844 if (mr
!= MACH_MSG_SUCCESS
)
2847 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
2848 mr
= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
2850 if (mr
!= MACH_MSG_SUCCESS
)
2851 mr
|= MACH_RCV_BODY_ERROR
;
2858 * Routine: ipc_kmsg_copyout_pseudo
2860 * Does a pseudo-copyout of the message.
2861 * This is like a regular copyout, except
2862 * that the ports in the header are handled
2863 * as if they are in the body. They aren't reversed.
2865 * The error codes are a combination of special bits.
2866 * The copyout proceeds despite errors.
2870 * MACH_MSG_SUCCESS Successful copyout.
2871 * MACH_MSG_IPC_SPACE No room for port right in name space.
2872 * MACH_MSG_VM_SPACE No room for memory in address space.
2873 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
2874 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
2878 ipc_kmsg_copyout_pseudo(
2882 mach_msg_body_t
*slist
)
2884 mach_msg_bits_t mbits
= kmsg
->ikm_header
->msgh_bits
;
2885 ipc_object_t dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
2886 ipc_object_t reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
2887 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2888 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2889 mach_port_name_t dest_name
, reply_name
;
2890 mach_msg_return_t mr
;
2892 assert(IO_VALID(dest
));
2894 mr
= (ipc_kmsg_copyout_object(space
, dest
, dest_type
, &dest_name
) |
2895 ipc_kmsg_copyout_object(space
, reply
, reply_type
, &reply_name
));
2897 kmsg
->ikm_header
->msgh_bits
= mbits
&~ MACH_MSGH_BITS_CIRCULAR
;
2898 kmsg
->ikm_header
->msgh_remote_port
= (ipc_port_t
)dest_name
;
2899 kmsg
->ikm_header
->msgh_local_port
= (ipc_port_t
)reply_name
;
2901 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
2902 mr
|= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
2909 * Routine: ipc_kmsg_copyout_dest
2911 * Copies out the destination port in the message.
2912 * Destroys all other rights and memory in the message.
2918 ipc_kmsg_copyout_dest(
2922 mach_msg_bits_t mbits
;
2925 mach_msg_type_name_t dest_type
;
2926 mach_msg_type_name_t reply_type
;
2927 mach_port_name_t dest_name
, reply_name
;
2929 mbits
= kmsg
->ikm_header
->msgh_bits
;
2930 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
2931 reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
2932 dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2933 reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2935 assert(IO_VALID(dest
));
2938 if (io_active(dest
)) {
2939 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
2940 /* dest is unlocked */
2943 io_check_unlock(dest
);
2944 dest_name
= MACH_PORT_DEAD
;
2947 if (IO_VALID(reply
)) {
2948 ipc_object_destroy(reply
, reply_type
);
2949 reply_name
= MACH_PORT_NULL
;
2951 reply_name
= (mach_port_name_t
) reply
;
2953 kmsg
->ikm_header
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
2954 MACH_MSGH_BITS(reply_type
, dest_type
));
2955 kmsg
->ikm_header
->msgh_local_port
= (ipc_port_t
)dest_name
;
2956 kmsg
->ikm_header
->msgh_remote_port
= (ipc_port_t
)reply_name
;
2958 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
2959 mach_msg_body_t
*body
;
2961 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2962 ipc_kmsg_clean_body(kmsg
, body
->msgh_descriptor_count
,
2963 (mach_msg_descriptor_t
*)(body
+ 1));
2968 * Routine: ipc_kmsg_copyin_scatter
2970 * allocate and copyin a scatter list
2972 * The gather (kmsg) is valid since it has been copied in.
2973 * Gather list descriptors are sequentially paired with scatter
2974 * list descriptors, with port descriptors in either list ignored.
2975 * Descriptors are consistent if the type fileds match and size
2976 * of the scatter descriptor is less than or equal to the
2977 * size of the gather descriptor. A MACH_MSG_ALLOCATE copy
2978 * strategy in a scatter descriptor matches any size in the
2979 * corresponding gather descriptor assuming they are the same type.
2980 * Either list may be larger than the other. During the
2981 * subsequent copy out, excess scatter descriptors are ignored
2982 * and excess gather descriptors default to dynamic allocation.
2984 * In the case of a size error, the scatter list is released.
2988 * the allocated message body containing the scatter list.
2992 ipc_kmsg_get_scatter(
2993 mach_vm_address_t msg_addr
,
2994 mach_msg_size_t slist_size
,
2997 mach_msg_body_t
*slist
;
2998 mach_msg_body_t
*body
;
2999 mach_msg_descriptor_t
*gstart
, *gend
;
3000 mach_msg_descriptor_t
*sstart
, *send
;
3003 if (slist_size
< sizeof(mach_msg_base_t
))
3004 return MACH_MSG_BODY_NULL
;
3006 slist_size
-= sizeof(mach_msg_header_t
);
3007 slist
= (mach_msg_body_t
*)kalloc(slist_size
);
3008 if (slist
== MACH_MSG_BODY_NULL
)
3011 if (copyin(msg_addr
+ sizeof(mach_msg_header_t
), (char *)slist
, slist_size
)) {
3012 kfree(slist
, slist_size
);
3013 return MACH_MSG_BODY_NULL
;
3016 if ((slist
->msgh_descriptor_count
* sizeof(mach_msg_descriptor_t
)
3017 + sizeof(mach_msg_size_t
)) > slist_size
) {
3018 kfree(slist
, slist_size
);
3019 return MACH_MSG_BODY_NULL
;
3022 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
3023 gstart
= (mach_msg_descriptor_t
*) (body
+ 1);
3024 gend
= gstart
+ body
->msgh_descriptor_count
;
3026 sstart
= (mach_msg_descriptor_t
*) (slist
+ 1);
3027 send
= sstart
+ slist
->msgh_descriptor_count
;
3029 while (gstart
< gend
) {
3030 mach_msg_descriptor_type_t g_type
;
3033 * Skip port descriptors in gather list.
3035 g_type
= gstart
->type
.type
;
3037 if (g_type
!= MACH_MSG_PORT_DESCRIPTOR
) {
3040 * A scatter list with a 0 descriptor count is treated as an
3041 * automatic size mismatch.
3043 if (slist
->msgh_descriptor_count
== 0) {
3044 kfree(slist
, slist_size
);
3045 return MACH_MSG_BODY_NULL
;
3049 * Skip port descriptors in scatter list.
3051 while (sstart
< send
) {
3052 if (sstart
->type
.type
!= MACH_MSG_PORT_DESCRIPTOR
)
3058 * No more scatter descriptors, we're done
3060 if (sstart
>= send
) {
3065 * Check type, copy and size fields
3067 if (g_type
== MACH_MSG_OOL_DESCRIPTOR
||
3068 g_type
== MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
3069 if (sstart
->type
.type
!= MACH_MSG_OOL_DESCRIPTOR
&&
3070 sstart
->type
.type
!= MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
3071 kfree(slist
, slist_size
);
3072 return MACH_MSG_BODY_NULL
;
3074 if (sstart
->out_of_line
.copy
== MACH_MSG_OVERWRITE
&&
3075 gstart
->out_of_line
.size
> sstart
->out_of_line
.size
) {
3076 kfree(slist
, slist_size
);
3077 return MACH_MSG_BODY_NULL
;
3081 if (sstart
->type
.type
!= MACH_MSG_OOL_PORTS_DESCRIPTOR
) {
3082 kfree(slist
, slist_size
);
3083 return MACH_MSG_BODY_NULL
;
3085 if (sstart
->ool_ports
.copy
== MACH_MSG_OVERWRITE
&&
3086 gstart
->ool_ports
.count
> sstart
->ool_ports
.count
) {
3087 kfree(slist
, slist_size
);
3088 return MACH_MSG_BODY_NULL
;
3100 * Routine: ipc_kmsg_free_scatter
3102 * Deallocate a scatter list. Since we actually allocated
3103 * a body without a header, and since the header was originally
3104 * accounted for in slist_size, we have to ajust it down
3105 * before freeing the scatter list.
3108 ipc_kmsg_free_scatter(
3109 mach_msg_body_t
*slist
,
3110 mach_msg_size_t slist_size
)
3112 slist_size
-= sizeof(mach_msg_header_t
);
3113 kfree(slist
, slist_size
);
3118 * Routine: ipc_kmsg_copyout_to_kernel
3120 * Copies out the destination and reply ports in the message.
3121 * Leaves all other rights and memory in the message alone.
3125 * Derived from ipc_kmsg_copyout_dest.
3126 * Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
3127 * We really do want to save rights and memory.
3131 ipc_kmsg_copyout_to_kernel(
3137 mach_msg_type_name_t dest_type
;
3138 mach_msg_type_name_t reply_type
;
3139 mach_port_name_t dest_name
, reply_name
;
3141 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
3142 reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
3143 dest_type
= MACH_MSGH_BITS_REMOTE(kmsg
->ikm_header
->msgh_bits
);
3144 reply_type
= MACH_MSGH_BITS_LOCAL(kmsg
->ikm_header
->msgh_bits
);
3146 assert(IO_VALID(dest
));
3149 if (io_active(dest
)) {
3150 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
3151 /* dest is unlocked */
3154 io_check_unlock(dest
);
3155 dest_name
= MACH_PORT_DEAD
;
3158 reply_name
= (mach_port_name_t
) reply
;
3160 kmsg
->ikm_header
->msgh_bits
=
3161 (MACH_MSGH_BITS_OTHER(kmsg
->ikm_header
->msgh_bits
) |
3162 MACH_MSGH_BITS(reply_type
, dest_type
));
3163 kmsg
->ikm_header
->msgh_local_port
= (ipc_port_t
)dest_name
;
3164 kmsg
->ikm_header
->msgh_remote_port
= (ipc_port_t
)reply_name
;
3167 #include <mach_kdb.h>
3170 #include <ddb/db_output.h>
3171 #include <ipc/ipc_print.h>
3173 * Forward declarations
3175 void ipc_msg_print_untyped(
3176 mach_msg_body_t
*body
);
3178 const char * ipc_type_name(
3180 boolean_t received
);
3182 void ipc_print_type_name(
3187 mach_msg_bits_t bit
);
3190 mm_copy_options_string(
3191 mach_msg_copy_options_t option
);
3193 void db_print_msg_uid(mach_msg_header_t
*);
3201 switch (type_name
) {
3202 case MACH_MSG_TYPE_PORT_NAME
:
3205 case MACH_MSG_TYPE_MOVE_RECEIVE
:
3207 return "port_receive";
3209 return "move_receive";
3212 case MACH_MSG_TYPE_MOVE_SEND
:
3219 case MACH_MSG_TYPE_MOVE_SEND_ONCE
:
3221 return "port_send_once";
3223 return "move_send_once";
3226 case MACH_MSG_TYPE_COPY_SEND
:
3229 case MACH_MSG_TYPE_MAKE_SEND
:
3232 case MACH_MSG_TYPE_MAKE_SEND_ONCE
:
3233 return "make_send_once";
3241 ipc_print_type_name(
3244 const char *name
= ipc_type_name(type_name
, TRUE
);
3248 printf("type%d", type_name
);
3253 * ipc_kmsg_print [ debug ]
3259 iprintf("kmsg=0x%x\n", kmsg
);
3260 iprintf("ikm_next=0x%x, prev=0x%x, size=%d",
3265 ipc_msg_print(kmsg
->ikm_header
);
3270 mach_msg_bits_t bit
)
3273 case MACH_MSGH_BITS_COMPLEX
: return "complex";
3274 case MACH_MSGH_BITS_CIRCULAR
: return "circular";
3275 default: return (char *) 0;
3280 * ipc_msg_print [ debug ]
3284 mach_msg_header_t
*msgh
)
3286 mach_msg_bits_t mbits
;
3287 unsigned int bit
, i
;
3288 const char *bit_name
;
3291 mbits
= msgh
->msgh_bits
;
3292 iprintf("msgh_bits=0x%x: l=0x%x,r=0x%x\n",
3294 MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
),
3295 MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
3297 mbits
= MACH_MSGH_BITS_OTHER(mbits
) & MACH_MSGH_BITS_USED
;
3300 iprintf("decoded bits: ");
3302 for (i
= 0, bit
= 1; i
< sizeof(mbits
) * 8; ++i
, bit
<<= 1) {
3303 if ((mbits
& bit
) == 0)
3305 bit_name
= msgh_bit_decode((mach_msg_bits_t
)bit
);
3307 printf("%s%s", needs_comma
? "," : "", bit_name
);
3309 printf("%sunknown(0x%x),", needs_comma
? "," : "", bit
);
3312 if (msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
) {
3313 printf("%sunused=0x%x,", needs_comma
? "," : "",
3314 msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
);
3320 if (msgh
->msgh_remote_port
) {
3321 iprintf("remote=0x%x(", msgh
->msgh_remote_port
);
3322 ipc_print_type_name(MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
3325 iprintf("remote=null");
3328 if (msgh
->msgh_local_port
) {
3329 printf("%slocal=0x%x(", needs_comma
? "," : "",
3330 msgh
->msgh_local_port
);
3331 ipc_print_type_name(MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
));
3334 printf("local=null\n");
3337 iprintf("msgh_id=%d, size=%d\n",
3341 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
3342 ipc_msg_print_untyped((mach_msg_body_t
*) (msgh
+ 1));
3348 mm_copy_options_string(
3349 mach_msg_copy_options_t option
)
3354 case MACH_MSG_PHYSICAL_COPY
:
3357 case MACH_MSG_VIRTUAL_COPY
:
3360 case MACH_MSG_OVERWRITE
:
3363 case MACH_MSG_ALLOCATE
:
3366 case MACH_MSG_KALLOC_COPY_T
:
3367 name
= "KALLOC_COPY_T";
3377 ipc_msg_print_untyped(
3378 mach_msg_body_t
*body
)
3380 mach_msg_descriptor_t
*saddr
, *send
;
3381 mach_msg_descriptor_type_t type
;
3383 iprintf("%d descriptors %d: \n", body
->msgh_descriptor_count
);
3385 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
3386 send
= saddr
+ body
->msgh_descriptor_count
;
3388 for ( ; saddr
< send
; saddr
++ ) {
3390 type
= saddr
->type
.type
;
3394 case MACH_MSG_PORT_DESCRIPTOR
: {
3395 mach_msg_port_descriptor_t
*dsc
;
3398 iprintf("-- PORT name = 0x%x disp = ", dsc
->name
);
3399 ipc_print_type_name(dsc
->disposition
);
3403 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
3404 case MACH_MSG_OOL_DESCRIPTOR
: {
3405 mach_msg_ool_descriptor_t
*dsc
;
3407 dsc
= &saddr
->out_of_line
;
3408 iprintf("-- OOL%s addr = 0x%x size = 0x%x copy = %s %s\n",
3409 type
== MACH_MSG_OOL_DESCRIPTOR
? "" : " VOLATILE",
3410 dsc
->address
, dsc
->size
,
3411 mm_copy_options_string(dsc
->copy
),
3412 dsc
->deallocate
? "DEALLOC" : "");
3415 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
3416 mach_msg_ool_ports_descriptor_t
*dsc
;
3418 dsc
= &saddr
->ool_ports
;
3420 iprintf("-- OOL_PORTS addr = 0x%x count = 0x%x ",
3421 dsc
->address
, dsc
->count
);
3423 ipc_print_type_name(dsc
->disposition
);
3424 printf(" copy = %s %s\n",
3425 mm_copy_options_string(dsc
->copy
),
3426 dsc
->deallocate
? "DEALLOC" : "");
3431 iprintf("-- UNKNOWN DESCRIPTOR 0x%x\n", type
);
3437 #endif /* MACH_KDB */