2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
53 * File: ipc/ipc_kmsg.c
57 * Operations on kernel messages.
63 #include <mach/boolean.h>
64 #include <mach/kern_return.h>
65 #include <mach/message.h>
66 #include <mach/port.h>
67 #include <mach/vm_statistics.h>
68 #include <kern/assert.h>
69 #include <kern/kalloc.h>
70 #include <kern/thread.h>
71 #include <kern/sched_prim.h>
73 #include <kern/misc_protos.h>
74 #include <kern/counters.h>
75 #include <vm/vm_map.h>
76 #include <vm/vm_object.h>
77 #include <vm/vm_kern.h>
79 #include <ipc/ipc_entry.h>
80 #include <ipc/ipc_kmsg.h>
81 #include <ipc/ipc_notify.h>
82 #include <ipc/ipc_object.h>
83 #include <ipc/ipc_space.h>
84 #include <ipc/ipc_port.h>
85 #include <ipc/ipc_right.h>
86 #include <ipc/ipc_hash.h>
87 #include <ipc/ipc_table.h>
91 extern vm_map_t ipc_kernel_copy_map
;
92 extern vm_size_t ipc_kmsg_max_vm_space
;
93 extern vm_size_t msg_ool_size_small
;
95 #define MSG_OOL_SIZE_SMALL msg_ool_size_small
99 * Forward declarations
105 void ipc_kmsg_clean_body(
107 mach_msg_type_number_t number
);
109 void ipc_kmsg_clean_partial(
111 mach_msg_type_number_t number
,
115 mach_msg_return_t
ipc_kmsg_copyout_body(
119 mach_msg_body_t
*slist
);
121 mach_msg_return_t
ipc_kmsg_copyin_body(
126 void ikm_cache_init(void);
128 * We keep a per-processor cache of kernel message buffers.
129 * The cache saves the overhead/locking of using kalloc/kfree.
130 * The per-processor cache seems to miss less than a per-thread cache,
131 * and it also uses less memory. Access to the cache doesn't
134 #define IKM_STASH 16 /* # of cache entries per cpu */
135 ipc_kmsg_t ipc_kmsg_cache
[ NCPUS
][ IKM_STASH
];
136 unsigned int ipc_kmsg_cache_avail
[NCPUS
];
139 * Routine: ipc_kmsg_init
141 * Initialize the kmsg system. For each CPU, we need to
142 * pre-stuff the kmsg cache.
149 for (cpu
= 0; cpu
< NCPUS
; ++cpu
) {
150 for (i
= 0; i
< IKM_STASH
; ++i
) {
154 kalloc(ikm_plus_overhead(IKM_SAVED_MSG_SIZE
));
155 if (kmsg
== IKM_NULL
)
156 panic("ipc_kmsg_init");
157 ikm_init(kmsg
, IKM_SAVED_MSG_SIZE
);
158 ipc_kmsg_cache
[cpu
][i
] = kmsg
;
160 ipc_kmsg_cache_avail
[cpu
] = IKM_STASH
;
165 * Routine: ipc_kmsg_alloc
167 * Allocate a kernel message structure. If we can get one from
168 * the cache, that is best. Otherwise, allocate a new one.
174 mach_msg_size_t msg_and_trailer_size
)
178 if ((msg_and_trailer_size
<= IKM_SAVED_MSG_SIZE
)) {
181 disable_preemption();
183 if ((i
= ipc_kmsg_cache_avail
[cpu
]) > 0) {
184 assert(i
<= IKM_STASH
);
185 kmsg
= ipc_kmsg_cache
[cpu
][--i
];
186 ipc_kmsg_cache_avail
[cpu
] = i
;
187 ikm_check_init(kmsg
, IKM_SAVED_MSG_SIZE
);
194 /* round up for ikm_cache */
195 if (msg_and_trailer_size
< IKM_SAVED_MSG_SIZE
)
196 msg_and_trailer_size
= IKM_SAVED_MSG_SIZE
;
198 kmsg
= (ipc_kmsg_t
)kalloc(ikm_plus_overhead(msg_and_trailer_size
));
199 if (kmsg
!= IKM_NULL
) {
200 ikm_init(kmsg
, msg_and_trailer_size
);
206 * Routine: ipc_kmsg_free
208 * Free a kernel message buffer. If the kms is preallocated
209 * to a port, just "put it back (marked unused)." We have to
210 * do this with the port locked. The port may have its hold
211 * on our message released. In that case, we have to just
212 * revert the message to a traditional one and free it normally.
221 mach_msg_size_t size
= kmsg
->ikm_size
;
225 * Check to see if the message is bound to the port. If so,
226 * mark it not in use. If the port isn't already dead, then
227 * leave the message associated with it. Otherwise, free it
228 * (not to the cache).
230 port
= ikm_prealloc_inuse_port(kmsg
);
231 if (port
!= IP_NULL
) {
233 ikm_prealloc_clear_inuse(kmsg
, port
);
234 if (ip_active(port
) && (port
->ip_premsg
== kmsg
)) {
235 assert(IP_PREALLOC(port
));
244 * Peek and see if it has to go back in the cache.
246 if (kmsg
->ikm_size
== IKM_SAVED_MSG_SIZE
&&
247 ipc_kmsg_cache_avail
[cpu_number()] < IKM_STASH
) {
250 disable_preemption();
253 i
= ipc_kmsg_cache_avail
[cpu
];
256 ipc_kmsg_cache
[cpu
][i
] = kmsg
;
257 ipc_kmsg_cache_avail
[cpu
] = i
+ 1;
265 kfree((vm_offset_t
) kmsg
, ikm_plus_overhead(size
));
270 * Routine: ipc_kmsg_enqueue
277 ipc_kmsg_queue_t queue
,
280 ipc_kmsg_enqueue_macro(queue
, kmsg
);
284 * Routine: ipc_kmsg_dequeue
286 * Dequeue and return a kmsg.
291 ipc_kmsg_queue_t queue
)
295 first
= ipc_kmsg_queue_first(queue
);
297 if (first
!= IKM_NULL
)
298 ipc_kmsg_rmqueue_first_macro(queue
, first
);
304 * Routine: ipc_kmsg_rmqueue
306 * Pull a kmsg out of a queue.
311 ipc_kmsg_queue_t queue
,
314 ipc_kmsg_t next
, prev
;
316 assert(queue
->ikmq_base
!= IKM_NULL
);
318 next
= kmsg
->ikm_next
;
319 prev
= kmsg
->ikm_prev
;
322 assert(prev
== kmsg
);
323 assert(queue
->ikmq_base
== kmsg
);
325 queue
->ikmq_base
= IKM_NULL
;
327 if (queue
->ikmq_base
== kmsg
)
328 queue
->ikmq_base
= next
;
330 next
->ikm_prev
= prev
;
331 prev
->ikm_next
= next
;
333 /* XXX Temporary debug logic */
334 assert(kmsg
->ikm_next
= IKM_BOGUS
);
335 assert(kmsg
->ikm_prev
= IKM_BOGUS
);
339 * Routine: ipc_kmsg_queue_next
341 * Return the kmsg following the given kmsg.
342 * (Or IKM_NULL if it is the last one in the queue.)
347 ipc_kmsg_queue_t queue
,
352 assert(queue
->ikmq_base
!= IKM_NULL
);
354 next
= kmsg
->ikm_next
;
355 if (queue
->ikmq_base
== next
)
362 * Routine: ipc_kmsg_destroy
364 * Destroys a kernel message. Releases all rights,
365 * references, and memory held by the message.
375 ipc_kmsg_queue_t queue
;
379 * ipc_kmsg_clean can cause more messages to be destroyed.
380 * Curtail recursion by queueing messages. If a message
381 * is already queued, then this is a recursive call.
384 queue
= &(current_thread()->ith_messages
);
385 empty
= ipc_kmsg_queue_empty(queue
);
386 ipc_kmsg_enqueue(queue
, kmsg
);
389 /* must leave kmsg in queue while cleaning it */
391 while ((kmsg
= ipc_kmsg_queue_first(queue
)) != IKM_NULL
) {
392 ipc_kmsg_clean(kmsg
);
393 ipc_kmsg_rmqueue(queue
, kmsg
);
400 * Routine: ipc_kmsg_destroy_dest
402 * Destroys a kernel message. Releases all rights,
403 * references, and memory held by the message (including
404 * the destination port reference.
410 ipc_kmsg_destroy_dest(
415 port
= kmsg
->ikm_header
.msgh_remote_port
;
417 ipc_port_release(port
);
418 kmsg
->ikm_header
.msgh_remote_port
= MACH_PORT_NULL
;
419 ipc_kmsg_destroy(kmsg
);
423 * Routine: ipc_kmsg_clean_body
425 * Cleans the body of a kernel message.
426 * Releases all rights, references, and memory.
435 mach_msg_type_number_t number
)
437 mach_msg_descriptor_t
*saddr
, *eaddr
;
442 saddr
= (mach_msg_descriptor_t
*)
443 ((mach_msg_base_t
*) &kmsg
->ikm_header
+ 1);
444 eaddr
= saddr
+ number
;
446 for ( ; saddr
< eaddr
; saddr
++ ) {
448 switch (saddr
->type
.type
) {
450 case MACH_MSG_PORT_DESCRIPTOR
: {
451 mach_msg_port_descriptor_t
*dsc
;
456 * Destroy port rights carried in the message
458 if (!IO_VALID((ipc_object_t
) dsc
->name
))
460 ipc_object_destroy((ipc_object_t
) dsc
->name
, dsc
->disposition
);
463 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
464 case MACH_MSG_OOL_DESCRIPTOR
: {
465 mach_msg_ool_descriptor_t
*dsc
;
467 dsc
= &saddr
->out_of_line
;
470 * Destroy memory carried in the message
472 if (dsc
->size
== 0) {
473 assert(dsc
->address
== (void *) 0);
475 vm_map_copy_discard((vm_map_copy_t
) dsc
->address
);
479 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
480 ipc_object_t
*objects
;
481 mach_msg_type_number_t j
;
482 mach_msg_ool_ports_descriptor_t
*dsc
;
484 dsc
= &saddr
->ool_ports
;
485 objects
= (ipc_object_t
*) dsc
->address
;
487 if (dsc
->count
== 0) {
491 assert(objects
!= (ipc_object_t
*) 0);
493 /* destroy port rights carried in the message */
495 for (j
= 0; j
< dsc
->count
; j
++) {
496 ipc_object_t object
= objects
[j
];
498 if (!IO_VALID(object
))
501 ipc_object_destroy(object
, dsc
->disposition
);
504 /* destroy memory carried in the message */
506 assert(dsc
->count
!= 0);
508 kfree((vm_offset_t
) dsc
->address
,
509 (vm_size_t
) dsc
->count
* sizeof(mach_port_name_t
));
513 printf("cleanup: don't understand this type of descriptor\n");
520 * Routine: ipc_kmsg_clean_partial
522 * Cleans a partially-acquired kernel message.
523 * number is the index of the type descriptor
524 * in the body of the message that contained the error.
525 * If dolast, the memory and port rights in this last
526 * type spec are also cleaned. In that case, number
527 * specifies the number of port rights to clean.
533 ipc_kmsg_clean_partial(
535 mach_msg_type_number_t number
,
540 mach_msg_bits_t mbits
= kmsg
->ikm_header
.msgh_bits
;
542 object
= (ipc_object_t
) kmsg
->ikm_header
.msgh_remote_port
;
543 assert(IO_VALID(object
));
544 ipc_object_destroy(object
, MACH_MSGH_BITS_REMOTE(mbits
));
546 object
= (ipc_object_t
) kmsg
->ikm_header
.msgh_local_port
;
547 if (IO_VALID(object
))
548 ipc_object_destroy(object
, MACH_MSGH_BITS_LOCAL(mbits
));
551 (void) vm_deallocate(ipc_kernel_copy_map
, paddr
, length
);
554 ipc_kmsg_clean_body(kmsg
, number
);
558 * Routine: ipc_kmsg_clean
560 * Cleans a kernel message. Releases all rights,
561 * references, and memory held by the message.
571 mach_msg_bits_t mbits
;
573 mbits
= kmsg
->ikm_header
.msgh_bits
;
574 object
= (ipc_object_t
) kmsg
->ikm_header
.msgh_remote_port
;
575 if (IO_VALID(object
))
576 ipc_object_destroy(object
, MACH_MSGH_BITS_REMOTE(mbits
));
578 object
= (ipc_object_t
) kmsg
->ikm_header
.msgh_local_port
;
579 if (IO_VALID(object
))
580 ipc_object_destroy(object
, MACH_MSGH_BITS_LOCAL(mbits
));
582 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
583 mach_msg_body_t
*body
;
585 body
= (mach_msg_body_t
*) (&kmsg
->ikm_header
+ 1);
586 ipc_kmsg_clean_body(kmsg
, body
->msgh_descriptor_count
);
591 * Routine: ipc_kmsg_set_prealloc
593 * Assign a kmsg as a preallocated message buffer to a port.
599 ipc_kmsg_set_prealloc(
603 assert(kmsg
->ikm_prealloc
== IP_NULL
);
605 kmsg
->ikm_prealloc
= IP_NULL
;
606 IP_SET_PREALLOC(port
, kmsg
);
610 * Routine: ipc_kmsg_clear_prealloc
612 * Release the Assignment of a preallocated message buffer from a port.
617 ipc_kmsg_clear_prealloc(
621 assert(kmsg
->ikm_prealloc
== port
);
623 kmsg
->ikm_prealloc
= IP_NULL
;
624 IP_CLEAR_PREALLOC(port
, kmsg
);
628 * Routine: ipc_kmsg_get
630 * Allocates a kernel message buffer.
631 * Copies a user message to the message buffer.
635 * MACH_MSG_SUCCESS Acquired a message buffer.
636 * MACH_SEND_MSG_TOO_SMALL Message smaller than a header.
637 * MACH_SEND_MSG_TOO_SMALL Message size not long-word multiple.
638 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
639 * MACH_SEND_INVALID_DATA Couldn't copy message data.
644 mach_msg_header_t
*msg
,
645 mach_msg_size_t size
,
648 mach_msg_size_t msg_and_trailer_size
;
650 mach_msg_format_0_trailer_t
*trailer
;
651 mach_port_name_t dest_name
;
652 ipc_entry_t dest_entry
;
653 ipc_port_t dest_port
;
655 if ((size
< sizeof(mach_msg_header_t
)) || (size
& 3))
656 return MACH_SEND_MSG_TOO_SMALL
;
658 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
660 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
662 if (kmsg
== IKM_NULL
)
663 return MACH_SEND_NO_BUFFER
;
665 if (copyinmsg((char *) msg
, (char *) &kmsg
->ikm_header
, size
)) {
667 return MACH_SEND_INVALID_DATA
;
670 kmsg
->ikm_header
.msgh_size
= size
;
673 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
674 * However, the internal size field of the trailer (msgh_trailer_size)
675 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize
676 * the cases where no implicit data is requested.
678 trailer
= (mach_msg_format_0_trailer_t
*) ((vm_offset_t
)&kmsg
->ikm_header
+ size
);
679 trailer
->msgh_sender
= current_thread()->top_act
->task
->sec_token
;
680 trailer
->msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
681 trailer
->msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
684 return MACH_MSG_SUCCESS
;
688 * Routine: ipc_kmsg_get_from_kernel
690 * Allocates a kernel message buffer.
691 * Copies a kernel message to the message buffer.
692 * Only resource errors are allowed.
695 * Ports in header are ipc_port_t.
697 * MACH_MSG_SUCCESS Acquired a message buffer.
698 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
702 ipc_kmsg_get_from_kernel(
703 mach_msg_header_t
*msg
,
704 mach_msg_size_t size
,
708 mach_msg_size_t msg_and_trailer_size
;
709 mach_msg_format_0_trailer_t
*trailer
;
710 ipc_port_t dest_port
;
712 assert(size
>= sizeof(mach_msg_header_t
));
713 assert((size
& 3) == 0);
715 assert(IP_VALID((ipc_port_t
) msg
->msgh_remote_port
));
716 dest_port
= (ipc_port_t
)msg
->msgh_remote_port
;
718 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
721 * See if the port has a pre-allocated kmsg for kernel
722 * clients. These are set up for those kernel clients
723 * which cannot afford to wait.
725 if (IP_PREALLOC(dest_port
)) {
727 if (!ip_active(dest_port
)) {
728 ip_unlock(dest_port
);
729 return MACH_SEND_NO_BUFFER
;
731 assert(IP_PREALLOC(dest_port
));
732 kmsg
= dest_port
->ip_premsg
;
733 if (msg_and_trailer_size
> kmsg
->ikm_size
) {
734 ip_unlock(dest_port
);
735 return MACH_SEND_TOO_LARGE
;
737 if (ikm_prealloc_inuse(kmsg
)) {
738 ip_unlock(dest_port
);
739 return MACH_SEND_NO_BUFFER
;
741 ikm_prealloc_set_inuse(kmsg
, dest_port
);
742 ip_unlock(dest_port
);
744 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
745 if (kmsg
== IKM_NULL
)
746 return MACH_SEND_NO_BUFFER
;
749 (void) memcpy((void *) &kmsg
->ikm_header
, (const void *) msg
, size
);
751 kmsg
->ikm_header
.msgh_size
= size
;
754 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
755 * However, the internal size field of the trailer (msgh_trailer_size)
756 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to
757 * optimize the cases where no implicit data is requested.
759 trailer
= (mach_msg_format_0_trailer_t
*)
760 ((vm_offset_t
)&kmsg
->ikm_header
+ size
);
761 trailer
->msgh_sender
= KERNEL_SECURITY_TOKEN
;
762 trailer
->msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
763 trailer
->msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
766 return MACH_MSG_SUCCESS
;
770 * Routine: ipc_kmsg_send
772 * Send a message. The message holds a reference
773 * for the destination port in the msgh_remote_port field.
775 * If unsuccessful, the caller still has possession of
776 * the message and must do something with it. If successful,
777 * the message is queued, given to a receiver, destroyed,
778 * or handled directly by the kernel via mach_msg.
782 * MACH_MSG_SUCCESS The message was accepted.
783 * MACH_SEND_TIMED_OUT Caller still has message.
784 * MACH_SEND_INTERRUPTED Caller still has message.
789 mach_msg_option_t option
,
790 mach_msg_timeout_t timeout
)
792 kern_return_t save_wait_result
;
795 port
= (ipc_port_t
) kmsg
->ikm_header
.msgh_remote_port
;
796 assert(IP_VALID(port
));
800 if (port
->ip_receiver
== ipc_space_kernel
) {
803 * We can check ip_receiver == ipc_space_kernel
804 * before checking that the port is active because
805 * ipc_port_dealloc_kernel clears ip_receiver
806 * before destroying a kernel port.
808 assert(ip_active(port
));
809 port
->ip_messages
.imq_seqno
++;
812 current_task()->messages_sent
++;
815 * Call the server routine, and get the reply message to send.
817 kmsg
= ipc_kobject_server(kmsg
);
818 if (kmsg
== IKM_NULL
)
819 return MACH_MSG_SUCCESS
;
821 port
= (ipc_port_t
) kmsg
->ikm_header
.msgh_remote_port
;
822 assert(IP_VALID(port
));
824 /* fall thru with reply - same options */
828 * Can't deliver to a dead port.
829 * However, we can pretend it got sent
830 * and was then immediately destroyed.
832 if (!ip_active(port
)) {
834 * We can't let ipc_kmsg_destroy deallocate
835 * the port right, because we might end up
836 * in an infinite loop trying to deliver
837 * a send-once notification.
841 ip_check_unlock(port
);
842 kmsg
->ikm_header
.msgh_remote_port
= MACH_PORT_NULL
;
843 ipc_kmsg_destroy(kmsg
);
844 return MACH_MSG_SUCCESS
;
847 if (kmsg
->ikm_header
.msgh_bits
& MACH_MSGH_BITS_CIRCULAR
) {
850 /* don't allow the creation of a circular loop */
852 ipc_kmsg_destroy(kmsg
);
853 return MACH_MSG_SUCCESS
;
857 * We have a valid message and a valid reference on the port.
858 * we can unlock the port and call mqueue_send() on it's message
862 return (ipc_mqueue_send(&port
->ip_messages
, kmsg
, option
, timeout
));
866 * Routine: ipc_kmsg_put
868 * Copies a message buffer to a user message.
869 * Copies only the specified number of bytes.
870 * Frees the message buffer.
872 * Nothing locked. The message buffer must have clean
875 * MACH_MSG_SUCCESS Copied data out of message buffer.
876 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
881 mach_msg_header_t
*msg
,
883 mach_msg_size_t size
)
885 mach_msg_return_t mr
;
887 if (copyoutmsg((const char *) &kmsg
->ikm_header
, (char *) msg
, size
))
888 mr
= MACH_RCV_INVALID_DATA
;
890 mr
= MACH_MSG_SUCCESS
;
897 * Routine: ipc_kmsg_put_to_kernel
899 * Copies a message buffer to a kernel message.
900 * Frees the message buffer.
907 ipc_kmsg_put_to_kernel(
908 mach_msg_header_t
*msg
,
910 mach_msg_size_t size
)
912 (void) memcpy((void *) msg
, (const void *) &kmsg
->ikm_header
, size
);
918 * Routine: ipc_kmsg_copyin_header
920 * "Copy-in" port rights in the header of a message.
921 * Operates atomically; if it doesn't succeed the
922 * message header and the space are left untouched.
923 * If it does succeed the remote/local port fields
924 * contain object pointers instead of port names,
925 * and the bits field is updated. The destination port
926 * will be a valid port pointer.
928 * The notify argument implements the MACH_SEND_CANCEL option.
929 * If it is not MACH_PORT_NULL, it should name a receive right.
930 * If the processing of the destination port would generate
931 * a port-deleted notification (because the right for the
932 * destination port is destroyed and it had a request for
933 * a dead-name notification registered), and the port-deleted
934 * notification would be sent to the named receive right,
935 * then it isn't sent and the send-once right for the notify
936 * port is quietly destroyed.
941 * MACH_MSG_SUCCESS Successful copyin.
942 * MACH_SEND_INVALID_HEADER
943 * Illegal value in the message header bits.
944 * MACH_SEND_INVALID_DEST The space is dead.
945 * MACH_SEND_INVALID_NOTIFY
946 * Notify is non-null and doesn't name a receive right.
947 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
948 * MACH_SEND_INVALID_DEST Can't copyin destination port.
949 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
950 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
951 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
955 ipc_kmsg_copyin_header(
956 mach_msg_header_t
*msg
,
958 mach_port_name_t notify
)
960 mach_msg_bits_t mbits
= msg
->msgh_bits
& MACH_MSGH_BITS_USER
;
961 mach_port_name_t dest_name
= (mach_port_name_t
)msg
->msgh_remote_port
;
962 mach_port_name_t reply_name
= (mach_port_name_t
)msg
->msgh_local_port
;
965 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
966 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
967 ipc_object_t dest_port
, reply_port
;
968 ipc_port_t dest_soright
, reply_soright
;
969 ipc_port_t notify_port
;
971 if ((mbits
!= msg
->msgh_bits
) ||
972 (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type
)) ||
974 (reply_name
!= MACH_PORT_NULL
) :
975 !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type
)))
976 return MACH_SEND_INVALID_HEADER
;
978 reply_soright
= IP_NULL
; /* in case we go to invalid dest early */
980 is_write_lock(space
);
981 if (!space
->is_active
)
984 if (!MACH_PORT_VALID(dest_name
))
987 if (notify
!= MACH_PORT_NULL
) {
990 if ((entry
= ipc_entry_lookup(space
, notify
)) == IE_NULL
) {
991 is_write_unlock(space
);
992 return MACH_SEND_INVALID_NOTIFY
;
994 if((entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
) == 0) {
995 is_write_unlock(space
);
996 return MACH_SEND_INVALID_NOTIFY
;
999 notify_port
= (ipc_port_t
) entry
->ie_object
;
1002 if (dest_name
== reply_name
) {
1004 mach_port_name_t name
= dest_name
;
1007 * Destination and reply ports are the same!
1008 * This is a little tedious to make atomic, because
1009 * there are 25 combinations of dest_type/reply_type.
1010 * However, most are easy. If either is move-sonce,
1011 * then there must be an error. If either are
1012 * make-send or make-sonce, then we must be looking
1013 * at a receive right so the port can't die.
1014 * The hard cases are the combinations of
1015 * copy-send and make-send.
1018 entry
= ipc_entry_lookup(space
, name
);
1019 if (entry
== IE_NULL
)
1022 assert(reply_type
!= 0); /* because name not null */
1024 if (!ipc_right_copyin_check(space
, name
, entry
, reply_type
))
1027 if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
) ||
1028 (reply_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
)) {
1030 * Why must there be an error? To get a valid
1031 * destination, this entry must name a live
1032 * port (not a dead name or dead port). However
1033 * a successful move-sonce will destroy a
1034 * live entry. Therefore the other copyin,
1035 * whatever it is, would fail. We've already
1036 * checked for reply port errors above,
1037 * so report a destination error.
1041 } else if ((dest_type
== MACH_MSG_TYPE_MAKE_SEND
) ||
1042 (dest_type
== MACH_MSG_TYPE_MAKE_SEND_ONCE
) ||
1043 (reply_type
== MACH_MSG_TYPE_MAKE_SEND
) ||
1044 (reply_type
== MACH_MSG_TYPE_MAKE_SEND_ONCE
)) {
1045 kr
= ipc_right_copyin(space
, name
, entry
,
1047 &dest_port
, &dest_soright
);
1048 if (kr
!= KERN_SUCCESS
)
1052 * Either dest or reply needs a receive right.
1053 * We know the receive right is there, because
1054 * of the copyin_check and copyin calls. Hence
1055 * the port is not in danger of dying. If dest
1056 * used the receive right, then the right needed
1057 * by reply (and verified by copyin_check) will
1061 assert(IO_VALID(dest_port
));
1062 assert(entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
);
1063 assert(dest_soright
== IP_NULL
);
1065 kr
= ipc_right_copyin(space
, name
, entry
,
1067 &reply_port
, &reply_soright
);
1069 assert(kr
== KERN_SUCCESS
);
1070 assert(reply_port
== dest_port
);
1071 assert(entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
);
1072 assert(reply_soright
== IP_NULL
);
1073 } else if ((dest_type
== MACH_MSG_TYPE_COPY_SEND
) &&
1074 (reply_type
== MACH_MSG_TYPE_COPY_SEND
)) {
1076 * To make this atomic, just do one copy-send,
1077 * and dup the send right we get out.
1080 kr
= ipc_right_copyin(space
, name
, entry
,
1082 &dest_port
, &dest_soright
);
1083 if (kr
!= KERN_SUCCESS
)
1086 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND
);
1087 assert(dest_soright
== IP_NULL
);
1090 * It's OK if the port we got is dead now,
1091 * so reply_port is IP_DEAD, because the msg
1092 * won't go anywhere anyway.
1095 reply_port
= (ipc_object_t
)
1096 ipc_port_copy_send((ipc_port_t
) dest_port
);
1097 reply_soright
= IP_NULL
;
1098 } else if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND
) &&
1099 (reply_type
== MACH_MSG_TYPE_MOVE_SEND
)) {
1101 * This is an easy case. Just use our
1102 * handy-dandy special-purpose copyin call
1103 * to get two send rights for the price of one.
1106 kr
= ipc_right_copyin_two(space
, name
, entry
,
1107 &dest_port
, &dest_soright
);
1108 if (kr
!= KERN_SUCCESS
)
1111 /* the entry might need to be deallocated */
1112 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1113 ipc_entry_dealloc(space
, name
, entry
);
1115 reply_port
= dest_port
;
1116 reply_soright
= IP_NULL
;
1120 assert(((dest_type
== MACH_MSG_TYPE_COPY_SEND
) &&
1121 (reply_type
== MACH_MSG_TYPE_MOVE_SEND
)) ||
1122 ((dest_type
== MACH_MSG_TYPE_MOVE_SEND
) &&
1123 (reply_type
== MACH_MSG_TYPE_COPY_SEND
)));
1126 * To make this atomic, just do a move-send,
1127 * and dup the send right we get out.
1130 kr
= ipc_right_copyin(space
, name
, entry
,
1131 MACH_MSG_TYPE_MOVE_SEND
, FALSE
,
1132 &dest_port
, &soright
);
1133 if (kr
!= KERN_SUCCESS
)
1136 /* the entry might need to be deallocated */
1138 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1139 ipc_entry_dealloc(space
, name
, entry
);
1142 * It's OK if the port we got is dead now,
1143 * so reply_port is IP_DEAD, because the msg
1144 * won't go anywhere anyway.
1147 reply_port
= (ipc_object_t
)
1148 ipc_port_copy_send((ipc_port_t
) dest_port
);
1150 if (dest_type
== MACH_MSG_TYPE_MOVE_SEND
) {
1151 dest_soright
= soright
;
1152 reply_soright
= IP_NULL
;
1154 dest_soright
= IP_NULL
;
1155 reply_soright
= soright
;
1158 } else if (!MACH_PORT_VALID(reply_name
)) {
1162 * No reply port! This is an easy case
1163 * to make atomic. Just copyin the destination.
1166 entry
= ipc_entry_lookup(space
, dest_name
);
1167 if (entry
== IE_NULL
)
1170 kr
= ipc_right_copyin(space
, dest_name
, entry
,
1172 &dest_port
, &dest_soright
);
1173 if (kr
!= KERN_SUCCESS
)
1176 /* the entry might need to be deallocated */
1178 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1179 ipc_entry_dealloc(space
, dest_name
, entry
);
1181 reply_port
= (ipc_object_t
) reply_name
;
1182 reply_soright
= IP_NULL
;
1184 ipc_entry_t dest_entry
, reply_entry
;
1185 ipc_port_t saved_reply
;
1188 * This is the tough case to make atomic.
1189 * The difficult problem is serializing with port death.
1190 * At the time we copyin dest_port, it must be alive.
1191 * If reply_port is alive when we copyin it, then
1192 * we are OK, because we serialize before the death
1193 * of both ports. Assume reply_port is dead at copyin.
1194 * Then if dest_port dies/died after reply_port died,
1195 * we are OK, because we serialize between the death
1196 * of the two ports. So the bad case is when dest_port
1197 * dies after its copyin, reply_port dies before its
1198 * copyin, and dest_port dies before reply_port. Then
1199 * the copyins operated as if dest_port was alive
1200 * and reply_port was dead, which shouldn't have happened
1201 * because they died in the other order.
1203 * Note that it is easy for a user task to tell if
1204 * a copyin happened before or after a port died.
1205 * For example, suppose both dest and reply are
1206 * send-once rights (types are both move-sonce) and
1207 * both rights have dead-name requests registered.
1208 * If a port dies before copyin, a dead-name notification
1209 * is generated and the dead name's urefs are incremented,
1210 * and if the copyin happens first, a port-deleted
1211 * notification is generated.
1213 * Note that although the entries are different,
1214 * dest_port and reply_port might still be the same.
1216 * JMM - The code to handle this was too expensive and, anyway,
1217 * we intend to separate the dest lookup from the reply copyin
1218 * by a wide margin, so the user will have to learn to deal!
1219 * I will be making the change soon!
1222 dest_entry
= ipc_entry_lookup(space
, dest_name
);
1223 if (dest_entry
== IE_NULL
)
1226 reply_entry
= ipc_entry_lookup(space
, reply_name
);
1227 if (reply_entry
== IE_NULL
)
1230 assert(dest_entry
!= reply_entry
); /* names are not equal */
1231 assert(reply_type
!= 0); /* because reply_name not null */
1233 if (!ipc_right_copyin_check(space
, reply_name
, reply_entry
,
1237 kr
= ipc_right_copyin(space
, dest_name
, dest_entry
,
1239 &dest_port
, &dest_soright
);
1240 if (kr
!= KERN_SUCCESS
)
1243 assert(IO_VALID(dest_port
));
1245 kr
= ipc_right_copyin(space
, reply_name
, reply_entry
,
1247 &reply_port
, &reply_soright
);
1249 assert(kr
== KERN_SUCCESS
);
1251 /* the entries might need to be deallocated */
1253 if (IE_BITS_TYPE(reply_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1254 ipc_entry_dealloc(space
, reply_name
, reply_entry
);
1256 if (IE_BITS_TYPE(dest_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
1257 ipc_entry_dealloc(space
, dest_name
, dest_entry
);
1261 * At this point, dest_port, reply_port,
1262 * dest_soright, reply_soright are all initialized.
1263 * Any defunct entries have been deallocated.
1264 * The space is still write-locked, and we need to
1265 * make the MACH_SEND_CANCEL check. The notify_port pointer
1266 * is still usable, because the copyin code above won't ever
1267 * deallocate a receive right, so its entry still exists
1268 * and holds a ref. Note notify_port might even equal
1269 * dest_port or reply_port.
1272 if ((notify
!= MACH_PORT_NULL
) &&
1273 (dest_soright
== notify_port
)) {
1274 ipc_port_release_sonce(dest_soright
);
1275 dest_soright
= IP_NULL
;
1278 is_write_unlock(space
);
1280 if (dest_soright
!= IP_NULL
)
1281 ipc_notify_port_deleted(dest_soright
, dest_name
);
1283 if (reply_soright
!= IP_NULL
)
1284 ipc_notify_port_deleted(reply_soright
, reply_name
);
1286 dest_type
= ipc_object_copyin_type(dest_type
);
1287 reply_type
= ipc_object_copyin_type(reply_type
);
1289 msg
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
1290 MACH_MSGH_BITS(dest_type
, reply_type
));
1291 msg
->msgh_remote_port
= (ipc_port_t
)dest_port
;
1292 msg
->msgh_local_port
= (ipc_port_t
)reply_port
;
1294 return MACH_MSG_SUCCESS
;
1297 is_write_unlock(space
);
1298 return MACH_SEND_INVALID_REPLY
;
1301 is_write_unlock(space
);
1302 if (reply_soright
!= IP_NULL
)
1303 ipc_notify_port_deleted(reply_soright
, reply_name
);
1304 return MACH_SEND_INVALID_DEST
;
1308 * Routine: ipc_kmsg_copyin_body
1310 * "Copy-in" port rights and out-of-line memory
1311 * in the message body.
1313 * In all failure cases, the message is left holding
1314 * no rights or memory. However, the message buffer
1315 * is not deallocated. If successful, the message
1316 * contains a valid destination port.
1320 * MACH_MSG_SUCCESS Successful copyin.
1321 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
1322 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
1323 * MACH_SEND_INVALID_TYPE Bad type specification.
1324 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
1325 * MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
1326 * MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
1330 ipc_kmsg_copyin_body(
1336 mach_msg_body_t
*body
;
1337 mach_msg_descriptor_t
*saddr
, *eaddr
;
1339 mach_msg_return_t mr
;
1340 boolean_t use_page_lists
, steal_pages
;
1343 vm_size_t space_needed
= 0;
1344 vm_offset_t paddr
= 0;
1345 mach_msg_descriptor_t
*sstart
;
1346 vm_map_copy_t copy
= VM_MAP_COPY_NULL
;
1349 * Determine if the target is a kernel port.
1351 dest
= (ipc_object_t
) kmsg
->ikm_header
.msgh_remote_port
;
1353 use_page_lists
= ipc_kobject_vm_page_list(ip_kotype((ipc_port_t
)dest
));
1354 steal_pages
= ipc_kobject_vm_page_steal(ip_kotype((ipc_port_t
)dest
));
1356 body
= (mach_msg_body_t
*) (&kmsg
->ikm_header
+ 1);
1357 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
1358 eaddr
= saddr
+ body
->msgh_descriptor_count
;
1360 /* make sure the message does not ask for more msg descriptors
1361 * than the message can hold.
1364 if (eaddr
<= saddr
||
1365 eaddr
> (mach_msg_descriptor_t
*) (&kmsg
->ikm_header
+
1366 kmsg
->ikm_header
.msgh_size
)) {
1367 ipc_kmsg_clean_partial(kmsg
,0,0,0);
1368 return MACH_SEND_MSG_TOO_SMALL
;
1372 * Make an initial pass to determine kernal VM space requirements for
1375 for (sstart
= saddr
; sstart
< eaddr
; sstart
++) {
1377 if (sstart
->type
.type
== MACH_MSG_OOL_DESCRIPTOR
||
1378 sstart
->type
.type
== MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
1380 assert(!(sstart
->out_of_line
.copy
== MACH_MSG_PHYSICAL_COPY
&&
1381 (use_page_lists
|| steal_pages
)));
1383 if (sstart
->out_of_line
.copy
!= MACH_MSG_PHYSICAL_COPY
&&
1384 sstart
->out_of_line
.copy
!= MACH_MSG_VIRTUAL_COPY
) {
1386 * Invalid copy option
1388 ipc_kmsg_clean_partial(kmsg
,0,0,0);
1389 return MACH_SEND_INVALID_TYPE
;
1392 if ((sstart
->out_of_line
.size
>= MSG_OOL_SIZE_SMALL
) &&
1393 (sstart
->out_of_line
.copy
== MACH_MSG_PHYSICAL_COPY
) &&
1394 !(sstart
->out_of_line
.deallocate
)) {
1397 * Out-of-line memory descriptor, accumulate kernel
1398 * memory requirements
1400 space_needed
+= round_page(sstart
->out_of_line
.size
);
1401 if (space_needed
> ipc_kmsg_max_vm_space
) {
1404 * Per message kernel memory limit exceeded
1406 ipc_kmsg_clean_partial(kmsg
,0,0,0);
1407 return MACH_MSG_VM_KERNEL
;
1414 * Allocate space in the pageable kernel ipc copy map for all the
1415 * ool data that is to be physically copied. Map is marked wait for
1419 if (vm_allocate(ipc_kernel_copy_map
, &paddr
, space_needed
, TRUE
) !=
1421 ipc_kmsg_clean_partial(kmsg
,0,0,0);
1422 return MACH_MSG_VM_KERNEL
;
1427 * handle the OOL regions and port descriptors.
1428 * the check for complex messages was done earlier.
1431 for (i
= 0, sstart
= saddr
; sstart
< eaddr
; sstart
++) {
1433 switch (sstart
->type
.type
) {
1435 case MACH_MSG_PORT_DESCRIPTOR
: {
1436 mach_msg_type_name_t name
;
1437 ipc_object_t object
;
1438 mach_msg_port_descriptor_t
*dsc
;
1440 dsc
= &sstart
->port
;
1442 /* this is really the type SEND, SEND_ONCE, etc. */
1443 name
= dsc
->disposition
;
1444 dsc
->disposition
= ipc_object_copyin_type(name
);
1446 if (!MACH_PORT_VALID((mach_port_name_t
)dsc
->name
)) {
1450 kr
= ipc_object_copyin(space
, (mach_port_name_t
)dsc
->name
, name
, &object
);
1451 if (kr
!= KERN_SUCCESS
) {
1452 ipc_kmsg_clean_partial(kmsg
, i
, paddr
, space_needed
);
1453 return MACH_SEND_INVALID_RIGHT
;
1455 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1456 ipc_port_check_circularity((ipc_port_t
) object
,
1457 (ipc_port_t
) dest
)) {
1458 kmsg
->ikm_header
.msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
1460 dsc
->name
= (ipc_port_t
) object
;
1464 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1465 case MACH_MSG_OOL_DESCRIPTOR
: {
1470 mach_msg_ool_descriptor_t
*dsc
;
1472 dsc
= &sstart
->out_of_line
;
1473 dealloc
= dsc
->deallocate
;
1474 addr
= (vm_offset_t
) dsc
->address
;
1480 } else if (use_page_lists
) {
1484 * Use page list copy mechanism if specified.
1486 if (steal_pages
== FALSE
) {
1488 * XXX Temporary Hackaround.
1489 * XXX Because the same page
1490 * XXX might be in more than one
1491 * XXX out of line region, steal
1492 * XXX (busy) pages from previous
1493 * XXX region so that this copyin
1494 * XXX won't block (permanently).
1496 if (copy
!= VM_MAP_COPY_NULL
)
1497 vm_map_copy_steal_pages(copy
);
1501 * Set up options for copying in page list.
1502 * If deallocating, steal pages to prevent
1503 * vm code from lazy evaluating deallocation.
1505 options
= VM_PROT_READ
;
1507 options
|= VM_MAP_COPYIN_OPT_SRC_DESTROY
|
1508 VM_MAP_COPYIN_OPT_STEAL_PAGES
;
1510 else if (steal_pages
) {
1511 options
|= VM_MAP_COPYIN_OPT_STEAL_PAGES
;
1514 if (vm_map_copyin_page_list(map
, addr
, length
, options
,
1518 ipc_kmsg_clean_partial(kmsg
, i
, paddr
, space_needed
);
1519 return MACH_SEND_INVALID_MEMORY
;
1522 dsc
->address
= (void *) copy
;
1523 dsc
->copy
= MACH_MSG_PAGE_LIST_COPY_T
;
1525 } else if ((length
>= MSG_OOL_SIZE_SMALL
) &&
1526 (dsc
->copy
== MACH_MSG_PHYSICAL_COPY
) && !dealloc
) {
1529 * If the request is a physical copy and the source
1530 * is not being deallocated, then allocate space
1531 * in the kernel's pageable ipc copy map and copy
1532 * the data in. The semantics guarantee that the
1533 * data will have been physically copied before
1534 * the send operation terminates. Thus if the data
1535 * is not being deallocated, we must be prepared
1536 * to page if the region is sufficiently large.
1538 if (copyin((const char *) addr
, (char *) paddr
,
1540 ipc_kmsg_clean_partial(kmsg
, i
, paddr
,
1542 return MACH_SEND_INVALID_MEMORY
;
1546 * The kernel ipc copy map is marked no_zero_fill.
1547 * If the transfer is not a page multiple, we need
1548 * to zero fill the balance.
1550 if (!page_aligned(length
)) {
1551 (void) memset((void *) (paddr
+ length
), 0,
1552 round_page(length
) - length
);
1554 if (vm_map_copyin(ipc_kernel_copy_map
, paddr
, length
,
1555 TRUE
, ©
) != KERN_SUCCESS
) {
1556 ipc_kmsg_clean_partial(kmsg
, i
, paddr
,
1558 return MACH_MSG_VM_KERNEL
;
1560 dsc
->address
= (void *) copy
;
1561 paddr
+= round_page(length
);
1562 space_needed
-= round_page(length
);
1566 * Make a vm_map_copy_t of the of the data. If the
1567 * data is small, this will do an optimized physical
1568 * copy. Otherwise, it will do a virtual copy.
1570 * NOTE: A virtual copy is OK if the original is being
1571 * deallocted, even if a physical copy was requested.
1573 kr
= vm_map_copyin(map
, addr
, length
, dealloc
, ©
);
1574 if (kr
!= KERN_SUCCESS
) {
1575 ipc_kmsg_clean_partial(kmsg
,i
,paddr
,space_needed
);
1576 return (kr
== KERN_RESOURCE_SHORTAGE
) ?
1577 MACH_MSG_VM_KERNEL
:
1578 MACH_SEND_INVALID_MEMORY
;
1580 dsc
->address
= (void *) copy
;
1585 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
1589 ipc_object_t
*objects
;
1591 mach_msg_type_name_t name
;
1592 mach_msg_ool_ports_descriptor_t
*dsc
;
1594 dsc
= &sstart
->ool_ports
;
1595 addr
= (vm_offset_t
) dsc
->address
;
1597 /* calculate length of data in bytes, rounding up */
1598 length
= dsc
->count
* sizeof(mach_port_name_t
);
1602 dsc
->address
= (void *) 0;
1606 data
= kalloc(length
);
1609 ipc_kmsg_clean_partial(kmsg
, i
, paddr
, space_needed
);
1610 return MACH_SEND_NO_BUFFER
;
1613 if (copyinmap(map
, addr
, data
, length
)) {
1614 kfree(data
, length
);
1615 ipc_kmsg_clean_partial(kmsg
, i
, paddr
, space_needed
);
1616 return MACH_SEND_INVALID_MEMORY
;
1619 if (dsc
->deallocate
) {
1620 (void) vm_deallocate(map
, addr
, length
);
1623 dsc
->address
= (void *) data
;
1625 /* this is really the type SEND, SEND_ONCE, etc. */
1626 name
= dsc
->disposition
;
1627 dsc
->disposition
= ipc_object_copyin_type(name
);
1629 objects
= (ipc_object_t
*) data
;
1631 for ( j
= 0; j
< dsc
->count
; j
++) {
1632 mach_port_name_t port
= (mach_port_name_t
) objects
[j
];
1633 ipc_object_t object
;
1635 if (!MACH_PORT_VALID(port
))
1638 kr
= ipc_object_copyin(space
, port
, name
, &object
);
1640 if (kr
!= KERN_SUCCESS
) {
1643 for(k
= 0; k
< j
; k
++) {
1644 object
= objects
[k
];
1645 if (!MACH_PORT_VALID(port
))
1647 ipc_object_destroy(object
, dsc
->disposition
);
1649 kfree(data
, length
);
1650 ipc_kmsg_clean_partial(kmsg
, i
, paddr
, space_needed
);
1651 return MACH_SEND_INVALID_RIGHT
;
1654 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1655 ipc_port_check_circularity(
1656 (ipc_port_t
) object
,
1658 kmsg
->ikm_header
.msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
1660 objects
[j
] = object
;
1668 * Invalid descriptor
1670 ipc_kmsg_clean_partial(kmsg
, i
, paddr
, space_needed
);
1671 return MACH_SEND_INVALID_TYPE
;
1678 kmsg
->ikm_header
.msgh_bits
&= ~MACH_MSGH_BITS_COMPLEX
;
1679 return MACH_MSG_SUCCESS
;
1684 * Routine: ipc_kmsg_copyin
1686 * "Copy-in" port rights and out-of-line memory
1689 * In all failure cases, the message is left holding
1690 * no rights or memory. However, the message buffer
1691 * is not deallocated. If successful, the message
1692 * contains a valid destination port.
1696 * MACH_MSG_SUCCESS Successful copyin.
1697 * MACH_SEND_INVALID_HEADER
1698 * Illegal value in the message header bits.
1699 * MACH_SEND_INVALID_NOTIFY Bad notify port.
1700 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1701 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1702 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
1703 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
1704 * MACH_SEND_INVALID_TYPE Bad type specification.
1705 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
1713 mach_port_name_t notify
)
1715 mach_msg_return_t mr
;
1717 mr
= ipc_kmsg_copyin_header(&kmsg
->ikm_header
, space
, notify
);
1718 if (mr
!= MACH_MSG_SUCCESS
)
1721 if ((kmsg
->ikm_header
.msgh_bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
1722 return MACH_MSG_SUCCESS
;
1724 return( ipc_kmsg_copyin_body( kmsg
, space
, map
) );
1728 * Routine: ipc_kmsg_copyin_from_kernel
1730 * "Copy-in" port rights and out-of-line memory
1731 * in a message sent from the kernel.
1733 * Because the message comes from the kernel,
1734 * the implementation assumes there are no errors
1735 * or peculiarities in the message.
1737 * Returns TRUE if queueing the message
1738 * would result in a circularity.
1744 ipc_kmsg_copyin_from_kernel(
1747 mach_msg_bits_t bits
= kmsg
->ikm_header
.msgh_bits
;
1748 mach_msg_type_name_t rname
= MACH_MSGH_BITS_REMOTE(bits
);
1749 mach_msg_type_name_t lname
= MACH_MSGH_BITS_LOCAL(bits
);
1750 ipc_object_t remote
= (ipc_object_t
) kmsg
->ikm_header
.msgh_remote_port
;
1751 ipc_object_t local
= (ipc_object_t
) kmsg
->ikm_header
.msgh_local_port
;
1753 /* translate the destination and reply ports */
1755 ipc_object_copyin_from_kernel(remote
, rname
);
1756 if (IO_VALID(local
))
1757 ipc_object_copyin_from_kernel(local
, lname
);
1760 * The common case is a complex message with no reply port,
1761 * because that is what the memory_object interface uses.
1764 if (bits
== (MACH_MSGH_BITS_COMPLEX
|
1765 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0))) {
1766 bits
= (MACH_MSGH_BITS_COMPLEX
|
1767 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND
, 0));
1769 kmsg
->ikm_header
.msgh_bits
= bits
;
1771 bits
= (MACH_MSGH_BITS_OTHER(bits
) |
1772 MACH_MSGH_BITS(ipc_object_copyin_type(rname
),
1773 ipc_object_copyin_type(lname
)));
1775 kmsg
->ikm_header
.msgh_bits
= bits
;
1776 if ((bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
1780 mach_msg_descriptor_t
*saddr
, *eaddr
;
1781 mach_msg_body_t
*body
;
1783 body
= (mach_msg_body_t
*) (&kmsg
->ikm_header
+ 1);
1784 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
1785 eaddr
= (mach_msg_descriptor_t
*) saddr
+ body
->msgh_descriptor_count
;
1787 for ( ; saddr
< eaddr
; saddr
++) {
1789 switch (saddr
->type
.type
) {
1791 case MACH_MSG_PORT_DESCRIPTOR
: {
1792 mach_msg_type_name_t name
;
1793 ipc_object_t object
;
1794 mach_msg_port_descriptor_t
*dsc
;
1798 /* this is really the type SEND, SEND_ONCE, etc. */
1799 name
= dsc
->disposition
;
1800 object
= (ipc_object_t
) dsc
->name
;
1801 dsc
->disposition
= ipc_object_copyin_type(name
);
1803 if (!IO_VALID(object
)) {
1807 ipc_object_copyin_from_kernel(object
, name
);
1809 /* CDY avoid circularity when the destination is also */
1810 /* the kernel. This check should be changed into an */
1811 /* assert when the new kobject model is in place since*/
1812 /* ports will not be used in kernel to kernel chats */
1814 if (((ipc_port_t
)remote
)->ip_receiver
!= ipc_space_kernel
) {
1815 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1816 ipc_port_check_circularity((ipc_port_t
) object
,
1817 (ipc_port_t
) remote
)) {
1818 kmsg
->ikm_header
.msgh_bits
|=
1819 MACH_MSGH_BITS_CIRCULAR
;
1824 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
1825 case MACH_MSG_OOL_DESCRIPTOR
: {
1827 * The sender should supply ready-made memory, i.e.
1828 * a vm_map_copy_t, so we don't need to do anything.
1832 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
1833 ipc_object_t
*objects
;
1835 mach_msg_type_name_t name
;
1836 mach_msg_ool_ports_descriptor_t
*dsc
;
1838 dsc
= &saddr
->ool_ports
;
1840 /* this is really the type SEND, SEND_ONCE, etc. */
1841 name
= dsc
->disposition
;
1842 dsc
->disposition
= ipc_object_copyin_type(name
);
1844 objects
= (ipc_object_t
*) dsc
->address
;
1846 for ( j
= 0; j
< dsc
->count
; j
++) {
1847 ipc_object_t object
= objects
[j
];
1849 if (!IO_VALID(object
))
1852 ipc_object_copyin_from_kernel(object
, name
);
1854 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
1855 ipc_port_check_circularity(
1856 (ipc_port_t
) object
,
1857 (ipc_port_t
) remote
))
1858 kmsg
->ikm_header
.msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
1864 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
1865 #endif /* MACH_ASSERT */
1873 * Routine: ipc_kmsg_copyout_header
1875 * "Copy-out" port rights in the header of a message.
1876 * Operates atomically; if it doesn't succeed the
1877 * message header and the space are left untouched.
1878 * If it does succeed the remote/local port fields
1879 * contain port names instead of object pointers,
1880 * and the bits field is updated.
1882 * The notify argument implements the MACH_RCV_NOTIFY option.
1883 * If it is not MACH_PORT_NULL, it should name a receive right.
1884 * If the process of receiving the reply port creates a
1885 * new right in the receiving task, then the new right is
1886 * automatically registered for a dead-name notification,
1887 * with the notify port supplying the send-once right.
1891 * MACH_MSG_SUCCESS Copied out port rights.
1892 * MACH_RCV_INVALID_NOTIFY
1893 * Notify is non-null and doesn't name a receive right.
1894 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1895 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
1896 * The space is dead.
1897 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
1898 * No room in space for another name.
1899 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
1900 * Couldn't allocate memory for the reply port.
1901 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
1902 * Couldn't allocate memory for the dead-name request.
1906 ipc_kmsg_copyout_header(
1907 mach_msg_header_t
*msg
,
1909 mach_port_name_t notify
)
1911 mach_msg_bits_t mbits
= msg
->msgh_bits
;
1912 ipc_port_t dest
= (ipc_port_t
) msg
->msgh_remote_port
;
1914 assert(IP_VALID(dest
));
1917 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
1918 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
1919 ipc_port_t reply
= (ipc_port_t
) msg
->msgh_local_port
;
1920 mach_port_name_t dest_name
, reply_name
;
1922 if (IP_VALID(reply
)) {
1923 ipc_port_t notify_port
;
1928 * Handling notify (for MACH_RCV_NOTIFY) is tricky.
1929 * The problem is atomically making a send-once right
1930 * from the notify port and installing it for a
1931 * dead-name request in the new entry, because this
1932 * requires two port locks (on the notify port and
1933 * the reply port). However, we can safely make
1934 * and consume send-once rights for the notify port
1935 * as long as we hold the space locked. This isn't
1936 * an atomicity problem, because the only way
1937 * to detect that a send-once right has been created
1938 * and then consumed if it wasn't needed is by getting
1939 * at the receive right to look at ip_sorights, and
1940 * because the space is write-locked status calls can't
1941 * lookup the notify port receive right. When we make
1942 * the send-once right, we lock the notify port,
1943 * so any status calls in progress will be done.
1946 is_write_lock(space
);
1949 ipc_port_request_index_t request
;
1951 if (!space
->is_active
) {
1952 is_write_unlock(space
);
1953 return (MACH_RCV_HEADER_ERROR
|
1954 MACH_MSG_IPC_SPACE
);
1957 if (notify
!= MACH_PORT_NULL
) {
1958 notify_port
= ipc_port_lookup_notify(space
,
1960 if (notify_port
== IP_NULL
) {
1961 is_write_unlock(space
);
1962 return MACH_RCV_INVALID_NOTIFY
;
1965 notify_port
= IP_NULL
;
1967 if ((reply_type
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
1968 ipc_right_reverse(space
, (ipc_object_t
) reply
,
1969 &reply_name
, &entry
)) {
1970 /* reply port is locked and active */
1973 * We don't need the notify_port
1974 * send-once right, but we can't release
1975 * it here because reply port is locked.
1976 * Wait until after the copyout to
1977 * release the notify port right.
1980 assert(entry
->ie_bits
&
1981 MACH_PORT_TYPE_SEND_RECEIVE
);
1986 if (!ip_active(reply
)) {
1988 ip_check_unlock(reply
);
1990 if (notify_port
!= IP_NULL
)
1991 ipc_port_release_sonce(notify_port
);
1994 is_write_unlock(space
);
1997 reply_name
= MACH_PORT_DEAD
;
2001 reply_name
= (mach_port_name_t
)reply
;
2002 kr
= ipc_entry_get(space
, &reply_name
, &entry
);
2003 if (kr
!= KERN_SUCCESS
) {
2006 if (notify_port
!= IP_NULL
)
2007 ipc_port_release_sonce(notify_port
);
2009 /* space is locked */
2010 kr
= ipc_entry_grow_table(space
,
2012 if (kr
!= KERN_SUCCESS
) {
2013 /* space is unlocked */
2015 if (kr
== KERN_RESOURCE_SHORTAGE
)
2016 return (MACH_RCV_HEADER_ERROR
|
2017 MACH_MSG_IPC_KERNEL
);
2019 return (MACH_RCV_HEADER_ERROR
|
2020 MACH_MSG_IPC_SPACE
);
2022 /* space is locked again; start over */
2026 assert(IE_BITS_TYPE(entry
->ie_bits
) ==
2027 MACH_PORT_TYPE_NONE
);
2028 assert(entry
->ie_object
== IO_NULL
);
2030 if (notify_port
== IP_NULL
) {
2031 /* not making a dead-name request */
2033 entry
->ie_object
= (ipc_object_t
) reply
;
2037 kr
= ipc_port_dnrequest(reply
, reply_name
,
2038 notify_port
, &request
);
2039 if (kr
!= KERN_SUCCESS
) {
2042 ipc_port_release_sonce(notify_port
);
2044 ipc_entry_dealloc(space
, reply_name
, entry
);
2045 is_write_unlock(space
);
2048 if (!ip_active(reply
)) {
2049 /* will fail next time around loop */
2052 is_write_lock(space
);
2056 kr
= ipc_port_dngrow(reply
, ITS_SIZE_NONE
);
2057 /* port is unlocked */
2058 if (kr
!= KERN_SUCCESS
)
2059 return (MACH_RCV_HEADER_ERROR
|
2060 MACH_MSG_IPC_KERNEL
);
2062 is_write_lock(space
);
2066 notify_port
= IP_NULL
; /* don't release right below */
2068 entry
->ie_object
= (ipc_object_t
) reply
;
2069 entry
->ie_request
= request
;
2073 /* space and reply port are locked and active */
2075 ip_reference(reply
); /* hold onto the reply port */
2077 kr
= ipc_right_copyout(space
, reply_name
, entry
,
2078 reply_type
, TRUE
, (ipc_object_t
) reply
);
2079 /* reply port is unlocked */
2080 assert(kr
== KERN_SUCCESS
);
2082 if (notify_port
!= IP_NULL
)
2083 ipc_port_release_sonce(notify_port
);
2086 is_write_unlock(space
);
2089 * No reply port! This is an easy case.
2090 * We only need to have the space locked
2091 * when checking notify and when locking
2092 * the destination (to ensure atomicity).
2095 is_read_lock(space
);
2096 if (!space
->is_active
) {
2097 is_read_unlock(space
);
2098 return MACH_RCV_HEADER_ERROR
|MACH_MSG_IPC_SPACE
;
2101 if (notify
!= MACH_PORT_NULL
) {
2104 /* must check notify even though it won't be used */
2106 if ((entry
= ipc_entry_lookup(space
, notify
)) == IE_NULL
) {
2107 is_read_unlock(space
);
2108 return MACH_RCV_INVALID_NOTIFY
;
2111 if ((entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
) == 0) {
2112 is_read_unlock(space
);
2113 return MACH_RCV_INVALID_NOTIFY
;
2118 is_read_unlock(space
);
2120 reply_name
= (mach_port_name_t
) reply
;
2124 * At this point, the space is unlocked and the destination
2125 * port is locked. (Lock taken while space was locked.)
2126 * reply_name is taken care of; we still need dest_name.
2127 * We still hold a ref for reply (if it is valid).
2129 * If the space holds receive rights for the destination,
2130 * we return its name for the right. Otherwise the task
2131 * managed to destroy or give away the receive right between
2132 * receiving the message and this copyout. If the destination
2133 * is dead, return MACH_PORT_DEAD, and if the receive right
2134 * exists somewhere else (another space, in transit)
2135 * return MACH_PORT_NULL.
2137 * Making this copyout operation atomic with the previous
2138 * copyout of the reply port is a bit tricky. If there was
2139 * no real reply port (it wasn't IP_VALID) then this isn't
2140 * an issue. If the reply port was dead at copyout time,
2141 * then we are OK, because if dest is dead we serialize
2142 * after the death of both ports and if dest is alive
2143 * we serialize after reply died but before dest's (later) death.
2144 * So assume reply was alive when we copied it out. If dest
2145 * is alive, then we are OK because we serialize before
2146 * the ports' deaths. So assume dest is dead when we look at it.
2147 * If reply dies/died after dest, then we are OK because
2148 * we serialize after dest died but before reply dies.
2149 * So the hard case is when reply is alive at copyout,
2150 * dest is dead at copyout, and reply died before dest died.
2151 * In this case pretend that dest is still alive, so
2152 * we serialize while both ports are alive.
2154 * Because the space lock is held across the copyout of reply
2155 * and locking dest, the receive right for dest can't move
2156 * in or out of the space while the copyouts happen, so
2157 * that isn't an atomicity problem. In the last hard case
2158 * above, this implies that when dest is dead that the
2159 * space couldn't have had receive rights for dest at
2160 * the time reply was copied-out, so when we pretend
2161 * that dest is still alive, we can return MACH_PORT_NULL.
2163 * If dest == reply, then we have to make it look like
2164 * either both copyouts happened before the port died,
2165 * or both happened after the port died. This special
2166 * case works naturally if the timestamp comparison
2167 * is done correctly.
2172 if (ip_active(dest
)) {
2173 ipc_object_copyout_dest(space
, (ipc_object_t
) dest
,
2174 dest_type
, &dest_name
);
2175 /* dest is unlocked */
2177 ipc_port_timestamp_t timestamp
;
2179 timestamp
= dest
->ip_timestamp
;
2181 ip_check_unlock(dest
);
2183 if (IP_VALID(reply
)) {
2185 if (ip_active(reply
) ||
2186 IP_TIMESTAMP_ORDER(timestamp
,
2187 reply
->ip_timestamp
))
2188 dest_name
= MACH_PORT_DEAD
;
2190 dest_name
= MACH_PORT_NULL
;
2193 dest_name
= MACH_PORT_DEAD
;
2196 if (IP_VALID(reply
))
2197 ipc_port_release(reply
);
2199 msg
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
2200 MACH_MSGH_BITS(reply_type
, dest_type
));
2201 msg
->msgh_local_port
= (ipc_port_t
)dest_name
;
2202 msg
->msgh_remote_port
= (ipc_port_t
)reply_name
;
2205 return MACH_MSG_SUCCESS
;
2209 * Routine: ipc_kmsg_copyout_object
2211 * Copy-out a port right. Always returns a name,
2212 * even for unsuccessful return codes. Always
2213 * consumes the supplied object.
2217 * MACH_MSG_SUCCESS The space acquired the right
2218 * (name is valid) or the object is dead (MACH_PORT_DEAD).
2219 * MACH_MSG_IPC_SPACE No room in space for the right,
2220 * or the space is dead. (Name is MACH_PORT_NULL.)
2221 * MACH_MSG_IPC_KERNEL Kernel resource shortage.
2222 * (Name is MACH_PORT_NULL.)
2226 ipc_kmsg_copyout_object(
2228 ipc_object_t object
,
2229 mach_msg_type_name_t msgt_name
,
2230 mach_port_name_t
*namep
)
2234 if (!IO_VALID(object
)) {
2235 *namep
= (mach_port_name_t
) object
;
2236 return MACH_MSG_SUCCESS
;
2239 kr
= ipc_object_copyout(space
, object
, msgt_name
, TRUE
, namep
);
2240 if (kr
!= KERN_SUCCESS
) {
2241 ipc_object_destroy(object
, msgt_name
);
2243 if (kr
== KERN_INVALID_CAPABILITY
)
2244 *namep
= MACH_PORT_DEAD
;
2246 *namep
= MACH_PORT_NULL
;
2248 if (kr
== KERN_RESOURCE_SHORTAGE
)
2249 return MACH_MSG_IPC_KERNEL
;
2251 return MACH_MSG_IPC_SPACE
;
2255 return MACH_MSG_SUCCESS
;
2259 * Routine: ipc_kmsg_copyout_body
2261 * "Copy-out" port rights and out-of-line memory
2262 * in the body of a message.
2264 * The error codes are a combination of special bits.
2265 * The copyout proceeds despite errors.
2269 * MACH_MSG_SUCCESS Successful copyout.
2270 * MACH_MSG_IPC_SPACE No room for port right in name space.
2271 * MACH_MSG_VM_SPACE No room for memory in address space.
2272 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
2273 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
2274 * MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
2278 ipc_kmsg_copyout_body(
2282 mach_msg_body_t
*slist
)
2284 mach_msg_body_t
*body
;
2285 mach_msg_descriptor_t
*saddr
, *eaddr
;
2286 mach_msg_return_t mr
= MACH_MSG_SUCCESS
;
2289 mach_msg_descriptor_t
*sstart
, *send
;
2291 body
= (mach_msg_body_t
*) (&kmsg
->ikm_header
+ 1);
2292 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
2293 eaddr
= saddr
+ body
->msgh_descriptor_count
;
2296 * Do scatter list setup
2298 if (slist
!= MACH_MSG_BODY_NULL
) {
2299 sstart
= (mach_msg_descriptor_t
*) (slist
+ 1);
2300 send
= sstart
+ slist
->msgh_descriptor_count
;
2303 sstart
= MACH_MSG_DESCRIPTOR_NULL
;
2306 for ( ; saddr
< eaddr
; saddr
++ ) {
2308 switch (saddr
->type
.type
) {
2310 case MACH_MSG_PORT_DESCRIPTOR
: {
2311 mach_msg_port_descriptor_t
*dsc
;
2314 * Copyout port right carried in the message
2317 mr
|= ipc_kmsg_copyout_object(space
,
2318 (ipc_object_t
) dsc
->name
,
2320 (mach_port_name_t
*) &dsc
->name
);
2324 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2325 case MACH_MSG_OOL_DESCRIPTOR
: {
2326 vm_offset_t rcv_addr
;
2327 vm_offset_t snd_addr
;
2328 mach_msg_ool_descriptor_t
*dsc
;
2329 mach_msg_copy_options_t copy_option
;
2331 SKIP_PORT_DESCRIPTORS(sstart
, send
);
2333 dsc
= &saddr
->out_of_line
;
2335 assert(dsc
->copy
!= MACH_MSG_KALLOC_COPY_T
);
2336 assert(dsc
->copy
!= MACH_MSG_PAGE_LIST_COPY_T
);
2338 copy_option
= dsc
->copy
;
2340 if ((snd_addr
= (vm_offset_t
) dsc
->address
) != 0) {
2341 if (sstart
!= MACH_MSG_DESCRIPTOR_NULL
&&
2342 sstart
->out_of_line
.copy
== MACH_MSG_OVERWRITE
) {
2345 * There is an overwrite descriptor specified in the
2346 * scatter list for this ool data. The descriptor
2347 * has already been verified
2349 rcv_addr
= (vm_offset_t
) sstart
->out_of_line
.address
;
2350 dsc
->copy
= MACH_MSG_OVERWRITE
;
2352 dsc
->copy
= MACH_MSG_ALLOCATE
;
2356 * Whether the data was virtually or physically
2357 * copied we have a vm_map_copy_t for it.
2358 * If there's an overwrite region specified
2359 * overwrite it, otherwise do a virtual copy out.
2361 if (dsc
->copy
== MACH_MSG_OVERWRITE
) {
2362 kr
= vm_map_copy_overwrite(map
, rcv_addr
,
2363 (vm_map_copy_t
) dsc
->address
, TRUE
);
2365 kr
= vm_map_copyout(map
, &rcv_addr
,
2366 (vm_map_copy_t
) dsc
->address
);
2368 if (kr
!= KERN_SUCCESS
) {
2369 if (kr
== KERN_RESOURCE_SHORTAGE
)
2370 mr
|= MACH_MSG_VM_KERNEL
;
2372 mr
|= MACH_MSG_VM_SPACE
;
2373 vm_map_copy_discard((vm_map_copy_t
) dsc
->address
);
2375 INCREMENT_SCATTER(sstart
);
2378 dsc
->address
= (void *) rcv_addr
;
2380 INCREMENT_SCATTER(sstart
);
2383 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
2385 mach_port_name_t
*objects
;
2386 mach_msg_type_number_t j
;
2388 mach_msg_ool_ports_descriptor_t
*dsc
;
2390 SKIP_PORT_DESCRIPTORS(sstart
, send
);
2392 dsc
= &saddr
->ool_ports
;
2394 length
= dsc
->count
* sizeof(mach_port_name_t
);
2397 if (sstart
!= MACH_MSG_DESCRIPTOR_NULL
&&
2398 sstart
->ool_ports
.copy
== MACH_MSG_OVERWRITE
) {
2401 * There is an overwrite descriptor specified in the
2402 * scatter list for this ool data. The descriptor
2403 * has already been verified
2405 addr
= (vm_offset_t
) sstart
->out_of_line
.address
;
2406 dsc
->copy
= MACH_MSG_OVERWRITE
;
2411 * Dynamically allocate the region
2413 int anywhere
= VM_MAKE_TAG(VM_MEMORY_MACH_MSG
)|
2416 dsc
->copy
= MACH_MSG_ALLOCATE
;
2417 if ((kr
= vm_allocate(map
, &addr
, length
,
2418 anywhere
)) != KERN_SUCCESS
) {
2419 ipc_kmsg_clean_body(kmsg
,
2420 body
->msgh_descriptor_count
);
2423 if (kr
== KERN_RESOURCE_SHORTAGE
){
2424 mr
|= MACH_MSG_VM_KERNEL
;
2426 mr
|= MACH_MSG_VM_SPACE
;
2428 INCREMENT_SCATTER(sstart
);
2433 INCREMENT_SCATTER(sstart
);
2438 objects
= (mach_port_name_t
*) dsc
->address
;
2440 /* copyout port rights carried in the message */
2442 for ( j
= 0; j
< dsc
->count
; j
++) {
2443 ipc_object_t object
=
2444 (ipc_object_t
) objects
[j
];
2446 mr
|= ipc_kmsg_copyout_object(space
, object
,
2447 dsc
->disposition
, &objects
[j
]);
2450 /* copyout to memory allocated above */
2452 data
= (vm_offset_t
) dsc
->address
;
2453 (void) copyoutmap(map
, data
, addr
, length
);
2454 kfree(data
, length
);
2456 dsc
->address
= (void *) addr
;
2457 INCREMENT_SCATTER(sstart
);
2461 panic("untyped IPC copyout body: invalid message descriptor");
2469 * Routine: ipc_kmsg_copyout
2471 * "Copy-out" port rights and out-of-line memory
2476 * MACH_MSG_SUCCESS Copied out all rights and memory.
2477 * MACH_RCV_INVALID_NOTIFY Bad notify port.
2478 * Rights and memory in the message are intact.
2479 * MACH_RCV_HEADER_ERROR + special bits
2480 * Rights and memory in the message are intact.
2481 * MACH_RCV_BODY_ERROR + special bits
2482 * The message header was successfully copied out.
2483 * As much of the body was handled as possible.
2491 mach_port_name_t notify
,
2492 mach_msg_body_t
*slist
)
2494 mach_msg_return_t mr
;
2496 mr
= ipc_kmsg_copyout_header(&kmsg
->ikm_header
, space
, notify
);
2497 if (mr
!= MACH_MSG_SUCCESS
)
2500 if (kmsg
->ikm_header
.msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
2501 mr
= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
2503 if (mr
!= MACH_MSG_SUCCESS
)
2504 mr
|= MACH_RCV_BODY_ERROR
;
2511 * Routine: ipc_kmsg_copyout_pseudo
2513 * Does a pseudo-copyout of the message.
2514 * This is like a regular copyout, except
2515 * that the ports in the header are handled
2516 * as if they are in the body. They aren't reversed.
2518 * The error codes are a combination of special bits.
2519 * The copyout proceeds despite errors.
2523 * MACH_MSG_SUCCESS Successful copyout.
2524 * MACH_MSG_IPC_SPACE No room for port right in name space.
2525 * MACH_MSG_VM_SPACE No room for memory in address space.
2526 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
2527 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
2531 ipc_kmsg_copyout_pseudo(
2535 mach_msg_body_t
*slist
)
2537 mach_msg_bits_t mbits
= kmsg
->ikm_header
.msgh_bits
;
2538 ipc_object_t dest
= (ipc_object_t
) kmsg
->ikm_header
.msgh_remote_port
;
2539 ipc_object_t reply
= (ipc_object_t
) kmsg
->ikm_header
.msgh_local_port
;
2540 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2541 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2542 mach_port_name_t dest_name
, reply_name
;
2543 mach_msg_return_t mr
;
2545 assert(IO_VALID(dest
));
2547 mr
= (ipc_kmsg_copyout_object(space
, dest
, dest_type
, &dest_name
) |
2548 ipc_kmsg_copyout_object(space
, reply
, reply_type
, &reply_name
));
2550 kmsg
->ikm_header
.msgh_bits
= mbits
&~ MACH_MSGH_BITS_CIRCULAR
;
2551 kmsg
->ikm_header
.msgh_remote_port
= (ipc_port_t
)dest_name
;
2552 kmsg
->ikm_header
.msgh_local_port
= (ipc_port_t
)reply_name
;
2554 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
2555 mr
|= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
2562 * Routine: ipc_kmsg_copyout_dest
2564 * Copies out the destination port in the message.
2565 * Destroys all other rights and memory in the message.
2571 ipc_kmsg_copyout_dest(
2575 mach_msg_bits_t mbits
;
2578 mach_msg_type_name_t dest_type
;
2579 mach_msg_type_name_t reply_type
;
2580 mach_port_name_t dest_name
, reply_name
;
2582 mbits
= kmsg
->ikm_header
.msgh_bits
;
2583 dest
= (ipc_object_t
) kmsg
->ikm_header
.msgh_remote_port
;
2584 reply
= (ipc_object_t
) kmsg
->ikm_header
.msgh_local_port
;
2585 dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
2586 reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
2588 assert(IO_VALID(dest
));
2591 if (io_active(dest
)) {
2592 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
2593 /* dest is unlocked */
2596 io_check_unlock(dest
);
2597 dest_name
= MACH_PORT_DEAD
;
2600 if (IO_VALID(reply
)) {
2601 ipc_object_destroy(reply
, reply_type
);
2602 reply_name
= MACH_PORT_NULL
;
2604 reply_name
= (mach_port_name_t
) reply
;
2606 kmsg
->ikm_header
.msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
2607 MACH_MSGH_BITS(reply_type
, dest_type
));
2608 kmsg
->ikm_header
.msgh_local_port
= (ipc_port_t
)dest_name
;
2609 kmsg
->ikm_header
.msgh_remote_port
= (ipc_port_t
)reply_name
;
2611 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
2612 mach_msg_body_t
*body
;
2614 body
= (mach_msg_body_t
*) (&kmsg
->ikm_header
+ 1);
2615 ipc_kmsg_clean_body(kmsg
, body
->msgh_descriptor_count
);
2619 * Routine: ipc_kmsg_copyin_scatter
2621 * allocate and copyin a scatter list
2623 * The gather (kmsg) is valid since it has been copied in.
2624 * Gather list descriptors are sequentially paired with scatter
2625 * list descriptors, with port descriptors in either list ignored.
2626 * Descriptors are consistent if the type fileds match and size
2627 * of the scatter descriptor is less than or equal to the
2628 * size of the gather descriptor. A MACH_MSG_ALLOCATE copy
2629 * strategy in a scatter descriptor matches any size in the
2630 * corresponding gather descriptor assuming they are the same type.
2631 * Either list may be larger than the other. During the
2632 * subsequent copy out, excess scatter descriptors are ignored
2633 * and excess gather descriptors default to dynamic allocation.
2635 * In the case of a size error, the scatter list is released.
2639 * the allocated message body containing the scatter list.
2643 ipc_kmsg_copyin_scatter(
2644 mach_msg_header_t
*msg
,
2645 mach_msg_size_t slist_size
,
2648 mach_msg_body_t
*slist
;
2649 mach_msg_body_t
*body
;
2650 mach_msg_descriptor_t
*gstart
, *gend
;
2651 mach_msg_descriptor_t
*sstart
, *send
;
2654 if (slist_size
< sizeof(mach_msg_base_t
))
2655 return MACH_MSG_BODY_NULL
;
2657 slist_size
-= sizeof(mach_msg_header_t
);
2658 slist
= (mach_msg_body_t
*)kalloc(slist_size
);
2659 if (slist
== MACH_MSG_BODY_NULL
)
2662 if (copyin((char *) (msg
+ 1), (char *)slist
, slist_size
)) {
2663 kfree((vm_offset_t
)slist
, slist_size
);
2664 return MACH_MSG_BODY_NULL
;
2667 if ((slist
->msgh_descriptor_count
* sizeof(mach_msg_descriptor_t
)
2668 + sizeof(mach_msg_size_t
)) > slist_size
) {
2669 kfree((vm_offset_t
)slist
, slist_size
);
2670 return MACH_MSG_BODY_NULL
;
2673 body
= (mach_msg_body_t
*) (&kmsg
->ikm_header
+ 1);
2674 gstart
= (mach_msg_descriptor_t
*) (body
+ 1);
2675 gend
= gstart
+ body
->msgh_descriptor_count
;
2677 sstart
= (mach_msg_descriptor_t
*) (slist
+ 1);
2678 send
= sstart
+ slist
->msgh_descriptor_count
;
2680 while (gstart
< gend
) {
2681 mach_msg_descriptor_type_t g_type
;
2684 * Skip port descriptors in gather list.
2686 g_type
= gstart
->type
.type
;
2688 if (g_type
!= MACH_MSG_PORT_DESCRIPTOR
) {
2691 * A scatter list with a 0 descriptor count is treated as an
2692 * automatic size mismatch.
2694 if (slist
->msgh_descriptor_count
== 0) {
2695 kfree((vm_offset_t
)slist
, slist_size
);
2696 return MACH_MSG_BODY_NULL
;
2700 * Skip port descriptors in scatter list.
2702 while (sstart
< send
) {
2703 if (sstart
->type
.type
!= MACH_MSG_PORT_DESCRIPTOR
)
2709 * No more scatter descriptors, we're done
2711 if (sstart
>= send
) {
2716 * Check type, copy and size fields
2718 if (g_type
== MACH_MSG_OOL_DESCRIPTOR
||
2719 g_type
== MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
2720 if (sstart
->type
.type
!= MACH_MSG_OOL_DESCRIPTOR
&&
2721 sstart
->type
.type
!= MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
2722 kfree((vm_offset_t
)slist
, slist_size
);
2723 return MACH_MSG_BODY_NULL
;
2725 if (sstart
->out_of_line
.copy
== MACH_MSG_OVERWRITE
&&
2726 gstart
->out_of_line
.size
> sstart
->out_of_line
.size
) {
2727 kfree((vm_offset_t
)slist
, slist_size
);
2728 return MACH_MSG_BODY_NULL
;
2732 if (sstart
->type
.type
!= MACH_MSG_OOL_PORTS_DESCRIPTOR
) {
2733 kfree((vm_offset_t
)slist
, slist_size
);
2734 return MACH_MSG_BODY_NULL
;
2736 if (sstart
->ool_ports
.copy
== MACH_MSG_OVERWRITE
&&
2737 gstart
->ool_ports
.count
> sstart
->ool_ports
.count
) {
2738 kfree((vm_offset_t
)slist
, slist_size
);
2739 return MACH_MSG_BODY_NULL
;
2751 * Routine: ipc_kmsg_free_scatter
2753 * Deallocate a scatter list. Since we actually allocated
2754 * a body without a header, and since the header was originally
2755 * accounted for in slist_size, we have to ajust it down
2756 * before freeing the scatter list.
2759 ipc_kmsg_free_scatter(
2760 mach_msg_body_t
*slist
,
2761 mach_msg_size_t slist_size
)
2763 slist_size
-= sizeof(mach_msg_header_t
);
2764 kfree((vm_offset_t
)slist
, slist_size
);
2769 * Routine: ipc_kmsg_copyout_to_kernel
2771 * Copies out the destination and reply ports in the message.
2772 * Leaves all other rights and memory in the message alone.
2776 * Derived from ipc_kmsg_copyout_dest.
2777 * Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
2778 * We really do want to save rights and memory.
2782 ipc_kmsg_copyout_to_kernel(
2788 mach_msg_type_name_t dest_type
;
2789 mach_msg_type_name_t reply_type
;
2790 mach_port_name_t dest_name
, reply_name
;
2792 dest
= (ipc_object_t
) kmsg
->ikm_header
.msgh_remote_port
;
2793 reply
= (ipc_object_t
) kmsg
->ikm_header
.msgh_local_port
;
2794 dest_type
= MACH_MSGH_BITS_REMOTE(kmsg
->ikm_header
.msgh_bits
);
2795 reply_type
= MACH_MSGH_BITS_LOCAL(kmsg
->ikm_header
.msgh_bits
);
2797 assert(IO_VALID(dest
));
2800 if (io_active(dest
)) {
2801 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
2802 /* dest is unlocked */
2805 io_check_unlock(dest
);
2806 dest_name
= MACH_PORT_DEAD
;
2809 reply_name
= (mach_port_name_t
) reply
;
2811 kmsg
->ikm_header
.msgh_bits
=
2812 (MACH_MSGH_BITS_OTHER(kmsg
->ikm_header
.msgh_bits
) |
2813 MACH_MSGH_BITS(reply_type
, dest_type
));
2814 kmsg
->ikm_header
.msgh_local_port
= (ipc_port_t
)dest_name
;
2815 kmsg
->ikm_header
.msgh_remote_port
= (ipc_port_t
)reply_name
;
2818 #include <mach_kdb.h>
2821 #include <ddb/db_output.h>
2822 #include <ipc/ipc_print.h>
2824 * Forward declarations
2826 void ipc_msg_print_untyped(
2827 mach_msg_body_t
*body
);
2829 char * ipc_type_name(
2831 boolean_t received
);
2833 void ipc_print_type_name(
2838 mach_msg_bits_t bit
);
2841 mm_copy_options_string(
2842 mach_msg_copy_options_t option
);
2844 void db_print_msg_uid(mach_msg_header_t
*);
2852 switch (type_name
) {
2853 case MACH_MSG_TYPE_PORT_NAME
:
2856 case MACH_MSG_TYPE_MOVE_RECEIVE
:
2858 return "port_receive";
2860 return "move_receive";
2863 case MACH_MSG_TYPE_MOVE_SEND
:
2870 case MACH_MSG_TYPE_MOVE_SEND_ONCE
:
2872 return "port_send_once";
2874 return "move_send_once";
2877 case MACH_MSG_TYPE_COPY_SEND
:
2880 case MACH_MSG_TYPE_MAKE_SEND
:
2883 case MACH_MSG_TYPE_MAKE_SEND_ONCE
:
2884 return "make_send_once";
2892 ipc_print_type_name(
2895 char *name
= ipc_type_name(type_name
, TRUE
);
2899 printf("type%d", type_name
);
2904 * ipc_kmsg_print [ debug ]
2910 iprintf("kmsg=0x%x\n", kmsg
);
2911 iprintf("ikm_next=0x%x, prev=0x%x, size=%d",
2916 ipc_msg_print(&kmsg
->ikm_header
);
2921 mach_msg_bits_t bit
)
2924 case MACH_MSGH_BITS_COMPLEX
: return "complex";
2925 case MACH_MSGH_BITS_CIRCULAR
: return "circular";
2926 default: return (char *) 0;
2931 * ipc_msg_print [ debug ]
2935 mach_msg_header_t
*msgh
)
2937 mach_msg_bits_t mbits
;
2938 unsigned int bit
, i
;
2942 mbits
= msgh
->msgh_bits
;
2943 iprintf("msgh_bits=0x%x: l=0x%x,r=0x%x\n",
2945 MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
),
2946 MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
2948 mbits
= MACH_MSGH_BITS_OTHER(mbits
) & MACH_MSGH_BITS_USED
;
2951 iprintf("decoded bits: ");
2953 for (i
= 0, bit
= 1; i
< sizeof(mbits
) * 8; ++i
, bit
<<= 1) {
2954 if ((mbits
& bit
) == 0)
2956 bit_name
= msgh_bit_decode((mach_msg_bits_t
)bit
);
2958 printf("%s%s", needs_comma
? "," : "", bit_name
);
2960 printf("%sunknown(0x%x),", needs_comma
? "," : "", bit
);
2963 if (msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
) {
2964 printf("%sunused=0x%x,", needs_comma
? "," : "",
2965 msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
);
2971 if (msgh
->msgh_remote_port
) {
2972 iprintf("remote=0x%x(", msgh
->msgh_remote_port
);
2973 ipc_print_type_name(MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
2976 iprintf("remote=null");
2979 if (msgh
->msgh_local_port
) {
2980 printf("%slocal=0x%x(", needs_comma
? "," : "",
2981 msgh
->msgh_local_port
);
2982 ipc_print_type_name(MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
));
2985 printf("local=null\n");
2988 iprintf("msgh_id=%d, size=%d\n",
2992 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
2993 ipc_msg_print_untyped((mach_msg_body_t
*) (msgh
+ 1));
2999 mm_copy_options_string(
3000 mach_msg_copy_options_t option
)
3005 case MACH_MSG_PHYSICAL_COPY
:
3008 case MACH_MSG_VIRTUAL_COPY
:
3011 case MACH_MSG_OVERWRITE
:
3014 case MACH_MSG_ALLOCATE
:
3017 case MACH_MSG_KALLOC_COPY_T
:
3018 name
= "KALLOC_COPY_T";
3020 case MACH_MSG_PAGE_LIST_COPY_T
:
3021 name
= "PAGE_LIST_COPY_T";
3031 ipc_msg_print_untyped(
3032 mach_msg_body_t
*body
)
3034 mach_msg_descriptor_t
*saddr
, *send
;
3035 mach_msg_descriptor_type_t type
;
3037 iprintf("%d descriptors %d: \n", body
->msgh_descriptor_count
);
3039 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
3040 send
= saddr
+ body
->msgh_descriptor_count
;
3042 for ( ; saddr
< send
; saddr
++ ) {
3044 type
= saddr
->type
.type
;
3048 case MACH_MSG_PORT_DESCRIPTOR
: {
3049 mach_msg_port_descriptor_t
*dsc
;
3052 iprintf("-- PORT name = 0x%x disp = ", dsc
->name
);
3053 ipc_print_type_name(dsc
->disposition
);
3057 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
3058 case MACH_MSG_OOL_DESCRIPTOR
: {
3059 mach_msg_ool_descriptor_t
*dsc
;
3061 dsc
= &saddr
->out_of_line
;
3062 iprintf("-- OOL%s addr = 0x%x size = 0x%x copy = %s %s\n",
3063 type
== MACH_MSG_OOL_DESCRIPTOR
? "" : " VOLATILE",
3064 dsc
->address
, dsc
->size
,
3065 mm_copy_options_string(dsc
->copy
),
3066 dsc
->deallocate
? "DEALLOC" : "");
3069 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
3070 mach_msg_ool_ports_descriptor_t
*dsc
;
3072 dsc
= &saddr
->ool_ports
;
3074 iprintf("-- OOL_PORTS addr = 0x%x count = 0x%x ",
3075 dsc
->address
, dsc
->count
);
3077 ipc_print_type_name(dsc
->disposition
);
3078 printf(" copy = %s %s\n",
3079 mm_copy_options_string(dsc
->copy
),
3080 dsc
->deallocate
? "DEALLOC" : "");
3085 iprintf("-- UNKNOWN DESCRIPTOR 0x%x\n", type
);
3091 #endif /* MACH_KDB */