|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1995, 1994, 1993, 1992, 1991, 1990
27: * Open Software Foundation, Inc.
28: *
29: * Permission to use, copy, modify, and distribute this software and
30: * its documentation for any purpose and without fee is hereby granted,
31: * provided that the above copyright notice appears in all copies and
32: * that both the copyright notice and this permission notice appear in
33: * supporting documentation, and that the name of ("OSF") or Open Software
34: * Foundation not be used in advertising or publicity pertaining to
35: * distribution of the software without specific, written prior permission.
36: *
37: * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
38: * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
39: * FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL OSF BE LIABLE FOR ANY
40: * SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
42: * ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING
43: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE
44: */
45: /*
46: * OSF Research Institute MK6.1 (unencumbered) 1/31/1995
47: */
48: /*
49: * Mach Operating System
50: * Copyright (c) 1991,1990,1989 Carnegie Mellon University
51: * All Rights Reserved.
52: *
53: * Permission to use, copy, modify and distribute this software and its
54: * documentation is hereby granted, provided that both the copyright
55: * notice and this permission notice appear in all copies of the
56: * software, derivative works or modified versions, and any portions
57: * thereof, and that both notices appear in supporting documentation.
58: *
59: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
60: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
61: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
62: *
63: * Carnegie Mellon requests users of this software to return to
64: *
65: * Software Distribution Coordinator or [email protected]
66: * School of Computer Science
67: * Carnegie Mellon University
68: * Pittsburgh PA 15213-3890
69: *
70: * any improvements or extensions that they make and grant Carnegie Mellon
71: * the rights to redistribute these changes.
72: */
73: /*
74: * File: ipc/ipc_kmsg.h
75: * Author: Rich Draves
76: * Date: 1989
77: *
78: * Definitions for kernel messages.
79: */
80:
81: #ifndef _IPC_IPC_KMSG_H_
82: #define _IPC_IPC_KMSG_H_
83:
84: #import <mach/features.h>
85:
86: #include <mach/machine/vm_types.h>
87: #include <mach/message.h>
88: #include <kern/assert.h>
89: #include <kern/cpu_number.h>
90: #include <kern/macro_help.h>
91: #include <kern/kalloc.h>
92: #include <ipc/ipc_object.h>
93: #include <ipc/ipc_marequest.h>
94: #include <vm/vm_map.h>
95:
96: /*
97: * This structure is only the header for a kmsg buffer;
98: * the actual buffer is normally larger. The rest of the buffer
99: * holds the body of the message.
100: *
101: * In a kmsg, the port fields hold pointers to ports instead
102: * of port names. These pointers hold references.
103: *
104: * The ikm_header.msgh_remote_port field is the destination
105: * of the message.
106: *
107: * The ikm_delta field is set such that (ikm_size + ikm_delta)
108: * indicates the *actual* length of the message and trailer which
109: * was passed by the sender and will be returned to the receiver.
110: * This has two uses in practice:
111: * if (> 0), it indicates the total length of the message
112: * trailer. Note that due to alignment, this is always a
113: * 4 byte aligned quantity. In this case, the message
114: * *cannot* be in the old format since a trailer is never
115: * transmitted or generated (this also implies that messages
116: * in the new format always contains a trailer).
117: *
118: * Otherwise (<= 0), it indicates that the length of the
119: * original sent message was not 4 byte aligned. This
120: * can only occur in the old message format, and in this
121: * case ikm_size *will* be rounded normally to avoid
122: * breaking assertions elsewhere in the implemenatation.
123: */
124:
125: typedef struct ipc_kmsg {
126: struct ipc_kmsg *ikm_next, *ikm_prev;
127: vm_size_t ikm_size;
128: ipc_marequest_t ikm_marequest;
129: security_id_t ikm_sender;
130: integer_t ikm_delta;
131: mach_msg_header_t ikm_header;
132: } *ipc_kmsg_t;
133:
134: #define IKM_NULL ((ipc_kmsg_t) 0)
135:
136: #define IKM_OVERHEAD \
137: (sizeof(struct ipc_kmsg) - sizeof(mach_msg_header_t))
138:
139: #define ikm_plus_overhead(size) ((vm_size_t)((size) + IKM_OVERHEAD))
140: #define ikm_less_overhead(size) ((mach_msg_size_t)((size) - IKM_OVERHEAD))
141:
142: /*
143: * We keep a per-processor cache of kernel message buffers.
144: * The cache saves the overhead/locking of using kalloc/kfree.
145: * The per-processor cache seems to miss less than a per-thread cache,
146: * and it also uses less memory. Access to the cache doesn't
147: * require locking.
148: */
149:
150: extern ipc_kmsg_t ipc_kmsg_cache[NCPUS];
151:
152: #define ikm_cache() ipc_kmsg_cache[cpu_number()]
153:
154: /*
155: * The size of the kernel message buffers that will be cached.
156: * IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't.
157: */
158:
159: #define IKM_SAVED_KMSG_SIZE ((vm_size_t) 256)
160: #define IKM_SAVED_MSG_SIZE ikm_less_overhead(IKM_SAVED_KMSG_SIZE)
161:
162: #define ikm_alloc(size) \
163: ((ipc_kmsg_t) kalloc(ikm_plus_overhead(size)))
164:
165: #define ikm_init(kmsg, size) \
166: MACRO_BEGIN \
167: ikm_init_special((kmsg), ikm_plus_overhead(size)); \
168: MACRO_END
169:
170: #define ikm_init_special(kmsg, size) \
171: MACRO_BEGIN \
172: (kmsg)->ikm_size = (size); \
173: (kmsg)->ikm_marequest = IMAR_NULL; \
174: (kmsg)->ikm_sender = ANONYMOUS_SECURITY_ID_VALUE; \
175: (kmsg)->ikm_delta = 0; \
176: MACRO_END
177:
178: #define ikm_check_initialized(kmsg, size) \
179: MACRO_BEGIN \
180: assert((kmsg)->ikm_size == (size)); \
181: assert((kmsg)->ikm_marequest == IMAR_NULL); \
182: (kmsg)->ikm_sender = ANONYMOUS_SECURITY_ID_VALUE; \
183: (kmsg)->ikm_delta = 0; \
184: MACRO_END
185:
186: /*
187: * Non-positive message sizes are special. They indicate that
188: * the message buffer doesn't come from ikm_alloc and
189: * requires some special handling to free.
190: *
191: * ipc_kmsg_free is the non-macro form of ikm_free.
192: * It frees kmsgs of all varieties.
193: */
194:
195: #define IKM_SIZE_NORMA 0
196: #define IKM_SIZE_NETWORK -1
197: #define IKM_SIZE_DEVICE -2
198: #define IKM_SIZE_NETIPC -3
199:
200: #define ikm_free(kmsg) \
201: MACRO_BEGIN \
202: register vm_size_t _size = (kmsg)->ikm_size; \
203: \
204: if ((integer_t)_size > 0) \
205: kfree((vm_offset_t) (kmsg), _size); \
206: else \
207: ipc_kmsg_free(kmsg); \
208: MACRO_END
209:
210: /*
211: * struct ipc_kmsg_queue is defined in kern/thread.h instead of here,
212: * so that kern/thread.h doesn't have to include ipc/ipc_kmsg.h.
213: */
214:
215: #include <ipc/ipc_kmsg_queue.h>
216:
217: typedef struct ipc_kmsg_queue *ipc_kmsg_queue_t;
218:
219: #define IKMQ_NULL ((ipc_kmsg_queue_t) 0)
220:
221:
222: /*
223: * Exported interfaces
224: */
225:
226: #define ipc_kmsg_queue_init(queue) \
227: MACRO_BEGIN \
228: (queue)->ikmq_base = IKM_NULL; \
229: MACRO_END
230:
231: #define ipc_kmsg_queue_empty(queue) ((queue)->ikmq_base == IKM_NULL)
232:
233: /* Enqueue a kmsg */
234: extern void ipc_kmsg_enqueue(
235: ipc_kmsg_queue_t queue,
236: ipc_kmsg_t kmsg);
237:
238: /* Dequeue and return a kmsg */
239: extern ipc_kmsg_t ipc_kmsg_dequeue(
240: ipc_kmsg_queue_t queue);
241:
242: /* Pull a kmsg out of a queue */
243: extern void ipc_kmsg_rmqueue(
244: ipc_kmsg_queue_t queue,
245: ipc_kmsg_t kmsg);
246:
247: #define ipc_kmsg_queue_first(queue) ((queue)->ikmq_base)
248:
249: /* Return the kmsg following the given kmsg */
250: extern ipc_kmsg_t ipc_kmsg_queue_next(
251: ipc_kmsg_queue_t queue,
252: ipc_kmsg_t kmsg);
253:
254: #define ipc_kmsg_rmqueue_first_macro(queue, kmsg) \
255: MACRO_BEGIN \
256: register ipc_kmsg_t _next; \
257: \
258: assert((queue)->ikmq_base == (kmsg)); \
259: \
260: _next = (kmsg)->ikm_next; \
261: if (_next == (kmsg)) { \
262: assert((kmsg)->ikm_prev == (kmsg)); \
263: (queue)->ikmq_base = IKM_NULL; \
264: } else { \
265: register ipc_kmsg_t _prev = (kmsg)->ikm_prev; \
266: \
267: (queue)->ikmq_base = _next; \
268: _next->ikm_prev = _prev; \
269: _prev->ikm_next = _next; \
270: } \
271: MACRO_END
272:
273: #define ipc_kmsg_enqueue_macro(queue, kmsg) \
274: MACRO_BEGIN \
275: register ipc_kmsg_t _first = (queue)->ikmq_base; \
276: \
277: if (_first == IKM_NULL) { \
278: (queue)->ikmq_base = (kmsg); \
279: (kmsg)->ikm_next = (kmsg); \
280: (kmsg)->ikm_prev = (kmsg); \
281: } else { \
282: register ipc_kmsg_t _last = _first->ikm_prev; \
283: \
284: (kmsg)->ikm_next = _first; \
285: (kmsg)->ikm_prev = _last; \
286: _first->ikm_prev = (kmsg); \
287: _last->ikm_next = (kmsg); \
288: } \
289: MACRO_END
290:
291: /* Destroy kernel message */
292: extern void ipc_kmsg_destroy(
293: ipc_kmsg_t kmsg);
294:
295: /* Free a kernel message buffer */
296: extern void ipc_kmsg_free(
297: ipc_kmsg_t kmsg);
298:
299: /* Allocate a kernel message buffer and copy a user message to the buffer */
300: extern mach_msg_return_t ipc_kmsg_get(
301: mach_msg_header_t *msg,
302: mach_msg_option_t option,
303: mach_msg_size_t size,
304: integer_t delta,
305: ipc_kmsg_t *kmsgp);
306:
307: /* Allocate a kernel message buffer and copy a kernel message to the buffer */
308: extern mach_msg_return_t ipc_kmsg_get_from_kernel(
309: mach_msg_header_t *msg,
310: mach_msg_option_t option,
311: mach_msg_size_t size,
312: integer_t delta,
313: ipc_kmsg_t *kmsgp);
314:
315: /* Copy a kernel message buffer to a user message */
316: extern mach_msg_return_t ipc_kmsg_put(
317: mach_msg_header_t *msg,
318: ipc_kmsg_t kmsg,
319: mach_msg_size_t size);
320:
321: /* Copy a kernel message buffer to a kernel message */
322: extern void ipc_kmsg_put_to_kernel(
323: mach_msg_header_t *msg,
324: ipc_kmsg_t kmsg,
325: mach_msg_size_t size);
326:
327: /* Copyin port rights in the header of a message */
328: extern mach_msg_return_t ipc_kmsg_copyin_header(
329: mach_msg_header_t *msg,
330: ipc_space_t space,
331: mach_port_t notify);
332:
333: /* Copyin port rights and out-of-line memory from a user message */
334: extern mach_msg_return_t ipc_kmsg_copyin(
335: ipc_kmsg_t kmsg,
336: ipc_space_t space,
337: vm_map_t map,
338: mach_port_t notify);
339:
340: /* Copyin port rights and out-of-line memory from a kernel message */
341: extern void ipc_kmsg_copyin_from_kernel(
342: ipc_kmsg_t kmsg);
343:
344: /* Copyout port rights in the header of a message */
345: extern mach_msg_return_t ipc_kmsg_copyout_header(
346: mach_msg_header_t *msg,
347: ipc_space_t space,
348: mach_port_t notify);
349:
350: /* Copyout a port right returning a name */
351: extern mach_msg_return_t ipc_kmsg_copyout_object(
352: ipc_space_t space,
353: ipc_object_t object,
354: mach_msg_type_name_t msgt_name,
355: mach_port_t *namep);
356:
357: /* Copyout the header and body to a user message */
358: extern mach_msg_return_t ipc_kmsg_copyout(
359: ipc_kmsg_t kmsg,
360: ipc_space_t space,
361: vm_map_t map,
362: mach_port_t notify,
363: ipc_kmsg_t list);
364:
365: /* Copyout port rights and out-of-line memory from the body of a message */
366: extern mach_msg_return_t ipc_kmsg_copyout_body(
367: ipc_kmsg_t kmsg,
368: ipc_space_t space,
369: vm_map_t map,
370: ipc_kmsg_t list);
371:
372: /* Copyout port rights and out-of-line memory to a user message,
373: not reversing the ports in the header */
374: extern mach_msg_return_t ipc_kmsg_copyout_pseudo(
375: ipc_kmsg_t kmsg,
376: ipc_space_t space,
377: vm_map_t map,
378: ipc_kmsg_t list);
379:
380: /* Copyout the destination port in the message */
381: extern void ipc_kmsg_copyout_dest(
382: ipc_kmsg_t kmsg,
383: ipc_space_t space);
384:
385: /* kernel's version of ipc_kmsg_copyout_dest */
386: extern void ipc_kmsg_copyout_to_kernel(
387: ipc_kmsg_t kmsg,
388: ipc_space_t space);
389:
390: /* Check scatter and gather lists for consistency */
391: extern mach_msg_return_t ipc_kmsg_check_scatter(
392: ipc_kmsg_t kmsg,
393: mach_msg_option_t option,
394: ipc_kmsg_t *list);
395:
396: #if MACH_IPC_COMPAT
397:
398: extern mach_msg_return_t
399: ipc_kmsg_copyin_compat(/* ipc_kmsg_t, ipc_space_t, vm_map_t */);
400:
401: extern mach_msg_return_t
402: ipc_kmsg_copyout_compat(/* ipc_kmsg_t, ipc_space_t, vm_map_t */);
403:
404: #endif /* MACH_IPC_COMPAT */
405:
406: #endif /* _IPC_IPC_KMSG_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.