xref: /xnu-12377.81.4/osfmk/ipc/ipc_entry.h (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796)
1 /*
2  * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * @OSF_COPYRIGHT@
30  */
31 /*
32  * Mach Operating System
33  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
34  * All Rights Reserved.
35  *
36  * Permission to use, copy, modify and distribute this software and its
37  * documentation is hereby granted, provided that both the copyright
38  * notice and this permission notice appear in all copies of the
39  * software, derivative works or modified versions, and any portions
40  * thereof, and that both notices appear in supporting documentation.
41  *
42  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45  *
46  * Carnegie Mellon requests users of this software to return to
47  *
48  *  Software Distribution Coordinator  or  [email protected]
49  *  School of Computer Science
50  *  Carnegie Mellon University
51  *  Pittsburgh PA 15213-3890
52  *
53  * any improvements or extensions that they make and grant Carnegie Mellon
54  * the rights to redistribute these changes.
55  */
56 /*
57  */
58 /*
59  *	File:	ipc/ipc_entry.h
60  *	Author:	Rich Draves
61  *	Date:	1989
62  *
63  *	Definitions for translation entries, which represent
64  *	tasks' capabilities for ports and port sets.
65  */
66 
67 #ifndef _IPC_IPC_ENTRY_H_
68 #define _IPC_IPC_ENTRY_H_
69 
70 #include <mach/mach_types.h>
71 #include <mach/port.h>
72 #include <mach/kern_return.h>
73 
74 #include <kern/kern_types.h>
75 #include <kern/kalloc.h>
76 #include <kern/smr_types.h>
77 
78 #include <ipc/ipc_types.h>
79 
80 #include <prng/random.h>
81 
82 /*
83  *	Spaces hold capabilities for ipc_object_t's.
84  *	Each ipc_entry_t records a capability.  Most capabilities have
85  *	small names, and the entries are elements of a table.
86  *
87  *	The ie_index field of entries in the table implements
88  *	a ordered hash table with open addressing and linear probing.
89  *
90  *	The ie_dist field holds the distance to the desired spot,
91  *	which is used to implement robin-hood hashing.
92  *
93  *	This hash table converts (space, object) -> name.
94  *	It is used independently of the other fields.
95  *
96  *	Free (unallocated) entries in the table have null ie_object
97  *	fields.  The ie_bits field is zero except for IE_BITS_GEN.
98  *	The ie_next (ie_request) field links free entries into a free list.
99  *
100  *	The first entry in the table (index 0) is always free.
101  *	It is used as the head of the free list.
102  */
103 
104 #define IPC_ENTRY_DIST_BITS   12
105 #define IPC_ENTRY_DIST_MAX    ((1 << IPC_ENTRY_DIST_BITS) - 1)
106 #define IPC_ENTRY_INDEX_BITS  32
107 #define IPC_ENTRY_INDEX_MAX   (UINT32_MAX)
108 
109 struct ipc_entry {
110 	union {
111 		struct ipc_object *XNU_PTRAUTH_SIGNED_PTR("ipc_entry.ie_object") ie_object;
112 		struct ipc_port   *XNU_PTRAUTH_SIGNED_PTR("ipc_entry.ie_object") ie_port;
113 		struct ipc_pset   *XNU_PTRAUTH_SIGNED_PTR("ipc_entry.ie_object") ie_pset;
114 		struct ipc_object *XNU_PTRAUTH_SIGNED_PTR("ipc_entry.ie_object") volatile ie_volatile_object;
115 		struct ipc_entry_table *XNU_PTRAUTH_SIGNED_PTR("ipc_entry.ie_self") ie_self;
116 	};
117 	union {
118 		struct {
119 			ipc_entry_bits_t    ie_bits;
120 			union {
121 				mach_port_index_t ie_next;         /* next in freelist, or...  */
122 				ipc_table_index_t ie_request;      /* dead name request notify */
123 			};
124 
125 			/* hash fields */
126 			uint32_t            ie_dist;
127 			mach_port_index_t   ie_index;
128 		};
129 		struct smr_node             ie_smr_node;
130 	};
131 };
132 
133 typedef struct bool_gen        *ipc_entry_prng_t;
134 
135 #define IPC_ENTRY_TABLE_MIN     32
136 #define IPC_ENTRY_TABLE_PERIOD  16
137 KALLOC_ARRAY_TYPE_DECL(ipc_entry_table, struct ipc_entry);
138 
139 #define IE_REQ_NONE             0               /* no request */
140 
141 #define IE_BITS_UREFS_MASK      0x0000ffff      /* 16 bits of user-reference */
142 #define IE_BITS_UREFS(bits)     ((bits) & IE_BITS_UREFS_MASK)
143 
144 #define IE_BITS_TYPE_MASK       0x001f0000      /* 5 bits of capability type */
145 #define IE_BITS_TYPE(bits)      ((bits) & IE_BITS_TYPE_MASK)
146 
147 #define IE_BITS_EXTYPE_MASK     0x00e00000      /* 3 bit for extended capability */
148 #define IE_BITS_EX_RECEIVE      0x00200000      /* entry used to be a receive right */
149 #define IE_BITS_PINNED_SEND     0x00400000      /* last send right can't be destroyed */
150 #define IE_BITS_IMMOVABLE_SEND  0x00800000      /* send right can't be moved */
151 
152 #define IE_BITS_ROLL_MASK       0x03000000      /* 2 bits for rollover period */
153 #define IE_BITS_GEN_MASK        0xfc000000      /* 6 bits for generation */
154 #define IE_BITS_GEN(bits)       (((bits) & IE_BITS_GEN_MASK) | IE_BITS_ROLL_MASK)
155 #define IE_BITS_GEN_ONE         0x04000000      /* low bit of generation */
156 #define IE_BITS_ROLL_BITS       2               /* number of generation rollover bits */
157 #define IE_BITS_GEN_INIT        IE_BITS_GEN_MASK
158 #define IE_BITS_RIGHT_MASK      0x00ffffff      /* relevant to the right */
159 
160 /*
161  * Exported interfaces
162  */
163 
164 extern unsigned int ipc_entry_table_count_max(void) __pure2;
165 
166 /* mask on/off default entry generation bits */
167 extern mach_port_name_t ipc_entry_name_mask(
168 	mach_port_name_t        name);
169 
170 /* Search for entry in a space by name */
171 extern ipc_entry_t ipc_entry_lookup(
172 	ipc_space_t             space,
173 	mach_port_name_t        name);
174 
175 /* Hold a number of entries in a locked space */
176 extern kern_return_t ipc_entries_hold(
177 	ipc_space_t             space,
178 	natural_t               count);
179 
180 /* claim and initialize a held entry in a locked space */
181 extern kern_return_t ipc_entry_claim(
182 	ipc_space_t             space,
183 	ipc_object_t            object,
184 	mach_port_name_t        *namep,
185 	ipc_entry_t             *entryp);
186 
187 /* Allocate an entry in a space, growing the space if necessary */
188 extern kern_return_t ipc_entry_alloc(
189 	ipc_space_t             space,
190 	ipc_object_t            object,
191 	mach_port_name_t        *namep,
192 	ipc_entry_t             *entryp);
193 
194 /* Allocate/find an entry in a space with a specific name */
195 extern kern_return_t ipc_entry_alloc_name(
196 	ipc_space_t             space,
197 	mach_port_name_t        name,
198 	ipc_entry_t             *entryp);
199 
200 /* Deallocate an entry from a space */
201 extern void ipc_entry_dealloc(
202 	ipc_space_t             space,
203 	ipc_object_t            object,
204 	mach_port_name_t        name,
205 	ipc_entry_t             entry);
206 
207 /* Mark and entry modified in a space */
208 extern void ipc_entry_modified(
209 	ipc_space_t             space,
210 	mach_port_name_t        name,
211 	ipc_entry_t             entry);
212 
213 /* Grow the table in a space */
214 extern kern_return_t ipc_entry_grow_table(
215 	ipc_space_t             space,
216 	ipc_table_elems_t       target_size);
217 
218 #endif  /* _IPC_IPC_ENTRY_H_ */
219