xref: /NextBSD/sys/sys/mach/ipc/ipc_kmsg.h (revision 33da5adc555b3bc29986eeadca03829e4ad06b1e)
1 /*
2  * Copyright 1991-1998 by Open Software Foundation, Inc.
3  *              All Rights Reserved
4  *
5  * Permission to use, copy, modify, and distribute this software and
6  * its documentation for any purpose and without fee is hereby granted,
7  * provided that the above copyright notice appears in all copies and
8  * that both the copyright notice and this permission notice appear in
9  * supporting documentation.
10  *
11  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
12  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13  * FOR A PARTICULAR PURPOSE.
14  *
15  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
16  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
18  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
19  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 /*
22  * MkLinux
23  */
24 /* CMU_HIST */
25 /*
26  * Revision 2.11.2.4  92/05/28  18:14:33  jeffreyh
27  * 	Add ikm_has_dest_right boolean.  Put in union with ikm_norma_acked.
28  * 	[92/05/28            dlb]
29  *
30  * Revision 2.11.2.3  92/05/26  18:53:43  jeffreyh
31  * 	Add ikm_norma_acked field for norma message processing.
32  * 	[92/05/05            dlb]
33  *
34  * Revision 2.11.2.2  92/04/08  15:44:33  jeffreyh
35  * 	Temporary debugging logic.
36  * 	[92/04/06            dlb]
37  *
38  * Revision 2.11.2.1  92/01/03  16:35:19  jsb
39  * 	Added ikm_source_node to support norma_ipc_receive_rright.
40  * 	[91/12/28  08:38:53  jsb]
41  *
42  * Revision 2.11  91/12/14  14:26:54  jsb
43  * 	NORMA_IPC: added ikm_copy to struct kmsg.
44  *
45  * Revision 2.10  91/08/28  11:13:31  jsb
46  * 	Renamed IKM_SIZE_CLPORT to IKM_SIZE_NORMA.
47  * 	[91/08/15  08:12:02  jsb]
48  *
49  * Revision 2.9  91/08/03  18:18:24  jsb
50  * 	NORMA_IPC: added ikm_page field to struct ipc_kmsg.
51  * 	[91/07/17  14:01:38  jsb]
52  *
53  * Revision 2.8  91/06/17  15:46:15  jsb
54  * 	Renamed NORMA conditionals.
55  * 	[91/06/17  10:46:12  jsb]
56  *
57  * Revision 2.7  91/05/14  16:33:21  mrt
58  * 	Correcting copyright
59  *
60  * Revision 2.6  91/03/16  14:48:10  rpd
61  * 	Replaced ith_saved with ipc_kmsg_cache.
62  * 	[91/02/16            rpd]
63  *
64  * Revision 2.5  91/02/05  17:22:08  mrt
65  * 	Changed to new Mach copyright
66  * 	[91/02/01  15:45:52  mrt]
67  *
68  * Revision 2.4  91/01/08  15:14:04  rpd
69  * 	Added ipc_kmsg_free.  Generalized the notion of special message sizes.
70  * 	[91/01/05            rpd]
71  * 	Added declarations of ipc_kmsg_copyout_object, ipc_kmsg_copyout_body.
72  * 	[90/12/21            rpd]
73  *
74  * Revision 2.3  90/09/28  16:54:48  jsb
75  * 	Added NORMA_IPC support (hack in ikm_free).
76  * 	[90/09/28  14:03:06  jsb]
77  *
78  * Revision 2.2  90/06/02  14:50:24  rpd
79  * 	Increased IKM_SAVED_KMSG_SIZE from 128 to 256.
80  * 	[90/04/23            rpd]
81  * 	Created for new IPC.
82  * 	[90/03/26  20:56:16  rpd]
83  *
84  */
85 /* CMU_ENDHIST */
86 /*
87  * Mach Operating System
88  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
89  * All Rights Reserved.
90  *
91  * Permission to use, copy, modify and distribute this software and its
92  * documentation is hereby granted, provided that both the copyright
93  * notice and this permission notice appear in all copies of the
94  * software, derivative works or modified versions, and any portions
95  * thereof, and that both notices appear in supporting documentation.
96  *
97  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
98  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
99  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
100  *
101  * Carnegie Mellon requests users of this software to return to
102  *
103  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
104  *  School of Computer Science
105  *  Carnegie Mellon University
106  *  Pittsburgh PA 15213-3890
107  *
108  * any improvements or extensions that they make and grant Carnegie Mellon
109  * the rights to redistribute these changes.
110  */
111 /*
112  */
113 /*
114  *	File:	ipc/ipc_kmsg.h
115  *	Author:	Rich Draves
116  *	Date:	1989
117  *
118  *	Definitions for kernel messages.
119  */
120 
121 #ifndef	_IPC_IPC_KMSG_H_
122 #define _IPC_IPC_KMSG_H_
123 
124 #include <sys/mach/vm_types.h>
125 #include <sys/mach/mach_types.h>
126 #include <sys/mach/message.h>
127 
128 #include <sys/mach/ipc/ipc_object.h>
129 
130 /*
131  *	This structure is only the header for a kmsg buffer;
132  *	the actual buffer is normally larger.  The rest of the buffer
133  *	holds the body of the message.
134  *
135  *	In a kmsg, the port fields hold pointers to ports instead
136  *	of port names.  These pointers hold references.
137  *
138  *	The ikm_header.msgh_remote_port field is the destination
139  *	of the message.
140  */
141 
142 typedef struct ipc_kmsg {
143 	mach_msg_size_t			ikm_size;
144 	struct ipc_kmsg *ikm_next, *ikm_prev;
145 	mach_msg_header_t		*ikm_header;
146 	ipc_port_t			ikm_prealloc;
147 } *ipc_kmsg_t;
148 
149 #define	IKM_NULL		((ipc_kmsg_t) 0)
150 
151 #define	IKM_OVERHEAD   (sizeof(struct ipc_kmsg))
152 
153 #define	ikm_plus_overhead(size)	((mach_msg_size_t)((size) + IKM_OVERHEAD))
154 #define	ikm_less_overhead(size)	((mach_msg_size_t)((size) - IKM_OVERHEAD))
155 
156 /*
157  * XXX	For debugging.
158  */
159 #define IKM_BOGUS		((ipc_kmsg_t) 0xffffff10)
160 
161 /*
162  *	The size of the kernel message buffers that will be cached.
163  *	IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't.
164  */
165 
166 #define	IKM_SAVED_KMSG_SIZE	256
167 #define	IKM_SAVED_MSG_SIZE	ikm_less_overhead(IKM_SAVED_KMSG_SIZE)
168 
169 #define	ikm_alloc(size)	ipc_kmsg_alloc(size);
170 
171 #define	ikm_init(kmsg, size)						\
172 MACRO_BEGIN								\
173 	ikm_init_special((kmsg), ikm_plus_overhead(size));		\
174 MACRO_END
175 
176 #define	ikm_init_special(kmsg, size)					\
177 MACRO_BEGIN								\
178 	(kmsg)->ikm_size = (size);					\
179 	(kmsg)->ikm_prev = NULL;						\
180 	(kmsg)->ikm_next = NULL;						\
181 MACRO_END
182 
183 #define	ikm_check_initialized(kmsg, size)				\
184 MACRO_BEGIN								\
185 	assert((kmsg)->ikm_size == (size));				\
186 MACRO_END
187 
188 #define ikm_set_header(kmsg, mtsize)					\
189 MACRO_BEGIN												\
190 (kmsg)->ikm_header = (mach_msg_header_t *)(kmsg + 1);	\
191 MPASS(kmsg->ikm_size >= mtsize + sizeof(*kmsg));		\
192 MACRO_END
193 
194 /*
195  *	Non-positive message sizes are special.  They indicate that
196  *	the message buffer doesn't come from ikm_alloc and
197  *	requires some special handling to free.
198  *
199  *	ipc_kmsg_free is the non-macro form of ikm_free.
200  *	It frees kmsgs of all varieties.
201  */
202 
203 #define	IKM_SIZE_NETWORK	-1
204 #define	IKM_SIZE_INTR_KMSG	-2
205 
206 
207 #define	ikm_free(kmsg)	ipc_kmsg_free(kmsg)
208 
209 struct ipc_kmsg_queue {
210 	struct ipc_kmsg *ikmq_base;
211 };
212 
213 typedef struct ipc_kmsg_queue *ipc_kmsg_queue_t;
214 
215 #define	IKMQ_NULL		((ipc_kmsg_queue_t) 0)
216 extern uma_zone_t ipc_kmsg_zone;
217 
218 /*
219  * Exported interfaces
220  */
221 
222 #define	ipc_kmsg_queue_init(queue)		\
223 MACRO_BEGIN					\
224 	(queue)->ikmq_base = IKM_NULL;		\
225 MACRO_END
226 
227 #define	ipc_kmsg_queue_empty(queue)	((queue)->ikmq_base == IKM_NULL)
228 
229 /* Enqueue a kmsg */
230 extern void ipc_kmsg_enqueue(
231 	ipc_kmsg_queue_t	queue,
232 	ipc_kmsg_t		kmsg);
233 
234 /* Dequeue and return a kmsg */
235 extern ipc_kmsg_t ipc_kmsg_dequeue(
236 	ipc_kmsg_queue_t        queue);
237 
238 /* Pull a kmsg out of a queue */
239 extern void ipc_kmsg_rmqueue(
240 	ipc_kmsg_queue_t	queue,
241 	ipc_kmsg_t		kmsg);
242 
243 #define	ipc_kmsg_queue_first(queue)		((queue)->ikmq_base)
244 
245 /* Return the kmsg following the given kmsg */
246 extern ipc_kmsg_t ipc_kmsg_queue_next(
247 	ipc_kmsg_queue_t	queue,
248 	ipc_kmsg_t		kmsg);
249 
250 #define	ipc_kmsg_rmqueue_first_macro(queue, kmsg)			\
251 MACRO_BEGIN								\
252 	register ipc_kmsg_t _next;					\
253 									\
254 	assert((queue)->ikmq_base == (kmsg));				\
255 									\
256 	_next = (kmsg)->ikm_next;					\
257 	if (_next == (kmsg)) {						\
258 		assert((kmsg)->ikm_prev == (kmsg));			\
259 		(queue)->ikmq_base = IKM_NULL;				\
260 	} else {							\
261 		register ipc_kmsg_t _prev = (kmsg)->ikm_prev;		\
262 									\
263 		(queue)->ikmq_base = _next;				\
264 		_next->ikm_prev = _prev;				\
265 		_prev->ikm_next = _next;				\
266 	}								\
267   	/* XXX Debug paranoia */					\
268   	kmsg->ikm_next = IKM_BOGUS;					\
269   	kmsg->ikm_prev = IKM_BOGUS;					\
270 MACRO_END
271 
272 #define	ipc_kmsg_enqueue_macro(queue, kmsg)				\
273 MACRO_BEGIN								\
274 	register ipc_kmsg_t _first = (queue)->ikmq_base;		\
275 									\
276 	if (_first == IKM_NULL) {					\
277 		(queue)->ikmq_base = (kmsg);				\
278 		(kmsg)->ikm_next = (kmsg);				\
279 		(kmsg)->ikm_prev = (kmsg);				\
280 	} else {							\
281 		register ipc_kmsg_t _last = _first->ikm_prev;		\
282 									\
283 		(kmsg)->ikm_next = _first;				\
284 		(kmsg)->ikm_prev = _last;				\
285 		_first->ikm_prev = (kmsg);				\
286 		_last->ikm_next = (kmsg);				\
287 	}								\
288 MACRO_END
289 
290 /* scatter list macros */
291 
292 #define SKIP_PORT_DESCRIPTORS(s, e)					\
293 MACRO_BEGIN								\
294 	if ((s) != MACH_MSG_DESCRIPTOR_NULL) {				\
295 		while ((s) < (e)) {					\
296 			if ((s)->type.type != MACH_MSG_PORT_DESCRIPTOR)	\
297 				break;					\
298 			(s)++;						\
299 		}							\
300 		if ((s) >= (e))						\
301 			(s) = MACH_MSG_DESCRIPTOR_NULL;			\
302 	}								\
303 MACRO_END
304 
305 #define INCREMENT_SCATTER(s)						\
306 MACRO_BEGIN								\
307 	if ((s) != MACH_MSG_DESCRIPTOR_NULL) {				\
308 		(s)++;							\
309 	}								\
310 MACRO_END
311 
312 /* Destroy kernel message */
313 extern void ipc_kmsg_destroy(
314 	ipc_kmsg_t	kmsg);
315 
316 /* Allocate a kernel message */
317 extern ipc_kmsg_t ipc_kmsg_alloc(
318 	mach_msg_size_t size);
319 
320 /* Free a kernel message buffer */
321 extern void ipc_kmsg_free(
322 	ipc_kmsg_t	kmsg);
323 
324 /* Allocate a kernel message buffer and copy a user message to the buffer */
325 extern mach_msg_return_t ipc_kmsg_get(
326 	mach_msg_header_t	*msg,
327 	mach_msg_size_t		size,
328 	ipc_kmsg_t		*kmsgp,
329 	ipc_space_t		space);
330 
331 /* Allocate a kernel message buffer and copy a kernel message to the buffer */
332 extern mach_msg_return_t ipc_kmsg_get_from_kernel(
333 	mach_msg_header_t	*msg,
334 	mach_msg_size_t		size,
335 	ipc_kmsg_t		*kmsgp);
336 
337 /* Copy a kernel message buffer to a user message */
338 extern mach_msg_return_t ipc_kmsg_put(
339 	mach_msg_header_t	*msg,
340 	ipc_kmsg_t		kmsg,
341 	mach_msg_size_t		size);
342 
343 /* Copy a kernel message buffer to a kernel message */
344 extern void ipc_kmsg_put_to_kernel(
345 	mach_msg_header_t	*msg,
346 	ipc_kmsg_t		kmsg,
347 	mach_msg_size_t		size);
348 
349 /* Copyin port rights in the header of a message */
350 extern mach_msg_return_t ipc_kmsg_copyin_header(
351 	ipc_kmsg_t	kmsg,
352 	ipc_space_t		space,
353 	mach_port_name_t		notify);
354 
355 /* Copyin port rights and out-of-line memory from a user message */
356 extern mach_msg_return_t ipc_kmsg_copyin(
357 	ipc_kmsg_t	kmsg,
358 	ipc_space_t	space,
359 	vm_map_t	map,
360 	mach_port_name_t	notify);
361 
362 /* Copyin port rights and out-of-line memory from a kernel message */
363 extern void ipc_kmsg_copyin_from_kernel(
364 	ipc_kmsg_t	kmsg);
365 
366 /* Copyout the header and body to a user message */
367 extern mach_msg_return_t ipc_kmsg_copyout(
368 	ipc_kmsg_t		kmsg,
369 	ipc_space_t		space,
370 	vm_map_t		map,
371 	mach_msg_body_t		*slist,
372 	mach_msg_option_t option);
373 
374 /* Compute size of message as copied out to the specified space/map */
375 extern mach_msg_size_t ipc_kmsg_copyout_size(
376 	ipc_kmsg_t		kmsg,
377 	vm_map_t		map);
378 
379 /* Copyout port rights and out-of-line memory to a user message,
380    not reversing the ports in the header */
381 extern mach_msg_return_t ipc_kmsg_copyout_pseudo(
382 	ipc_kmsg_t		kmsg,
383 	ipc_space_t		space,
384 	vm_map_t		map,
385 	mach_msg_body_t		*slist);
386 
387 /* Copyout the destination port in the message */
388 extern void ipc_kmsg_copyout_dest(
389 	ipc_kmsg_t	kmsg,
390 	ipc_space_t	space);
391 
392 /* kernel's version of ipc_kmsg_copyout_dest */
393 extern void ipc_kmsg_copyout_to_kernel(
394 	ipc_kmsg_t		kmsg,
395 	ipc_space_t		space);
396 
397 /* Check scatter and gather lists for consistency */
398 extern mach_msg_return_t ipc_kmsg_check_scatter(
399 	ipc_kmsg_t		kmsg,
400 	mach_msg_option_t	option,
401 	mach_msg_body_t		**slistp,
402 	mach_msg_size_t		*sizep);
403 
404 extern boolean_t	ikm_cache_get(
405 	ipc_kmsg_t		*kmsg);
406 extern boolean_t	ikm_cache_put(
407 	ipc_kmsg_t		kmsg);
408 
409 #if 	MACH_KDB
410 
411 /* Do a formatted dump of a kernel message */
412 extern void ipc_kmsg_print(
413 	ipc_kmsg_t	kmsg);
414 
415 /* Do a formatted dump of a user message */
416 extern void ipc_msg_print(
417 	mach_msg_header_t	*msgh);
418 
419 #endif	/* MACH_KDB */
420 
421 #endif	/* _IPC_IPC_KMSG_H_ */
422