xref: /illumos-gate/usr/src/uts/common/sys/door.h (revision 49b225e1cfa7bbf7738d4df0a03f18e3283426eb)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * The door lightweight RPC I/F.
28  */
29 
30 #ifndef	_SYS_DOOR_H
31 #define	_SYS_DOOR_H
32 
33 #ifdef	__cplusplus
34 extern "C" {
35 #endif
36 
37 /*
38  * Attributes associated with doors.
39  */
40 
41 /* Attributes originally obtained from door_create operation */
42 #define	DOOR_UNREF	0x01	/* Deliver an unref notification with door */
43 #define	DOOR_PRIVATE	0x02	/* Use a private pool of server threads */
44 #define	DOOR_UNREF_MULTI 0x10	/* Deliver unref notification more than once */
45 #define	DOOR_REFUSE_DESC 0x40	/* Do not accept descriptors from callers */
46 #define	DOOR_NO_CANCEL	0x80	/* No server thread cancel on client abort */
47 #define	DOOR_NO_DEPLETION_CB 0x100 /* No thread create callbacks on depletion */
48 
49 /* Attributes (additional) returned with door_info and door_desc_t data */
50 #define	DOOR_LOCAL	0x04	/* Descriptor is local to current process */
51 #define	DOOR_REVOKED	0x08	/* Door has been revoked */
52 #define	DOOR_IS_UNREF	0x20	/* Door is currently unreferenced */
53 #define	DOOR_PRIVCREATE	0x200	/* Door has a private thread creation func */
54 #define	DOOR_DEPLETION_CB 0x400	/* Set only during depletion callbacks */
55 
56 #if !defined(_ASM)
57 
58 #include <sys/types.h>
59 
60 #if defined(_KERNEL)
61 #include <sys/mutex.h>
62 #include <sys/vnode.h>
63 #include <sys/door_impl.h>
64 #endif /* defined(_KERNEL) */
65 
66 /* Basic door type information */
67 typedef unsigned long long door_ptr_t;	/* Handle 64 bit pointers */
68 typedef unsigned long long door_id_t;	/* Unique door identifier */
69 typedef	unsigned int	   door_attr_t;	/* Door attributes */
70 
71 #ifdef _KERNEL
72 struct __door_handle;
73 typedef struct __door_handle *door_handle_t;	/* opaque kernel door handle */
74 #endif
75 
76 #define	DOOR_INVAL -1			/* An invalid door descriptor */
77 #define	DOOR_UNREF_DATA ((void *)1)	/* Unreferenced invocation address */
78 
79 /* Door descriptor passed to door_info to get current thread's binding */
80 #define	DOOR_QUERY -2
81 
82 /* Masks of applicable flags */
83 #define	DOOR_CREATE_MASK	(DOOR_UNREF | DOOR_PRIVATE | \
84 	    DOOR_UNREF_MULTI | DOOR_REFUSE_DESC | DOOR_NO_CANCEL | \
85 	    DOOR_NO_DEPLETION_CB | DOOR_PRIVCREATE)
86 #define	DOOR_KI_CREATE_MASK	(DOOR_UNREF | DOOR_UNREF_MULTI)
87 
88 /* Mask of above attributes */
89 #define	DOOR_ATTR_MASK	(DOOR_CREATE_MASK | \
90 	    DOOR_LOCAL | DOOR_REVOKED | DOOR_IS_UNREF)
91 
92 /* Attributes used to describe door_desc_t data */
93 #define	DOOR_DESCRIPTOR	0x10000	/* A file descriptor is being passed */
94 #ifdef _KERNEL
95 #define	DOOR_HANDLE	0x20000 /* A kernel door handle is being passed */
96 #endif
97 #define	DOOR_RELEASE	0x40000	/* Passed references are also released */
98 
99 /* Misc attributes used internally */
100 #define	DOOR_DELAY	0x80000	/* Delayed unref delivery */
101 #define	DOOR_UNREF_ACTIVE 0x100000	/* Unreferenced call is active */
102 
103 /* door parameters */
104 #define	DOOR_PARAM_DESC_MAX	1	/* max number of request descriptors */
105 #define	DOOR_PARAM_DATA_MAX	2	/* max bytes of request data */
106 #define	DOOR_PARAM_DATA_MIN	3	/* min bytes of request data */
107 
108 /*
109  * On AMD64, 32-bit pack door_desc and door_info to avoid needing special
110  * copyin/copyout conversions due to differing alignment rules between
111  * 32-bit x86 and 64-bit amd64.
112  */
113 
114 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
115 #pragma pack(4)
116 #endif
117 
118 /*
119  * Structure used to pass descriptors/objects in door invocations
120  */
121 
122 typedef struct door_desc {
123 	door_attr_t	d_attributes;	/* Tag for union */
124 	union {
125 		/* File descriptor is passed */
126 		struct {
127 			int		d_descriptor;
128 			door_id_t	d_id;		/* unique id */
129 		} d_desc;
130 #ifdef _KERNEL
131 		/* Kernel passes handles referring to doors */
132 		door_handle_t d_handle;
133 #endif
134 		/* Reserved space */
135 		int		d_resv[5];
136 	} d_data;
137 } door_desc_t;
138 
139 /*
140  * Structure used to return info from door_info
141  */
142 typedef struct door_info {
143 	pid_t		di_target;	/* Server process */
144 	door_ptr_t	di_proc;	/* Server procedure */
145 	door_ptr_t	di_data;	/* Data cookie */
146 	door_attr_t	di_attributes;	/* Attributes associated with door */
147 	door_id_t	di_uniquifier;	/* Unique number */
148 	int		di_resv[4];	/* Future use */
149 } door_info_t;
150 
151 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
152 #pragma pack()
153 #endif
154 
155 /*
156  * Structure used to return info from door_cred
157  */
158 typedef struct door_cred {
159 	uid_t	dc_euid;	/* Effective uid of client */
160 	gid_t	dc_egid;	/* Effective gid of client */
161 	uid_t	dc_ruid;	/* Real uid of client */
162 	gid_t	dc_rgid;	/* Real gid of client */
163 	pid_t	dc_pid;		/* pid of client */
164 	int	dc_resv[4];	/* Future use */
165 } door_cred_t;
166 
167 /*
168  * Structure used to pass/return data from door_call
169  *
170  * All fields are in/out paramters. Upon return these fields
171  * are updated to reflect the true location and size of the results.
172  */
173 typedef struct door_arg {
174 	char		*data_ptr;	/* Argument/result data */
175 	size_t		data_size;	/* Argument/result data size */
176 	door_desc_t	*desc_ptr;	/* Argument/result descriptors */
177 	uint_t		desc_num;	/* Argument/result num discriptors */
178 	char		*rbuf;		/* Result area */
179 	size_t		rsize;		/* Result size */
180 } door_arg_t;
181 
182 #if defined(_SYSCALL32)
183 /*
184  * Structure to pass/return data from 32-bit program's door_call.
185  */
186 typedef struct door_arg32 {
187 	caddr32_t	data_ptr;	/* Argument/result data */
188 	size32_t	data_size;	/* Argument/result data size */
189 	caddr32_t	desc_ptr;	/* Argument/result descriptors */
190 	uint32_t	desc_num;	/* Argument/result num descriptors */
191 	caddr32_t	rbuf;		/* Result area */
192 	size32_t	rsize;		/* Result size */
193 } door_arg32_t;
194 #endif
195 
196 /*
197  * Structure used to pass door invocation information.
198  */
199 struct door_results {
200 	void		*cookie;
201 	char		*data_ptr;
202 	size_t		data_size;
203 	door_desc_t	*desc_ptr;
204 	size_t		desc_num;
205 	void		(*pc)();
206 	int		nservers;	/* zero if thread pool is empty */
207 	door_info_t	*door_info;
208 };
209 
210 #if defined(_SYSCALL32)
211 /*
212  * Structure used to pass door invocation information to 32-bit processes.
213  */
214 struct door_results32 {
215 	caddr32_t	cookie;
216 	caddr32_t	data_ptr;
217 	size32_t	data_size;
218 	caddr32_t	desc_ptr;
219 	size32_t	desc_num;
220 	caddr32_t	pc;
221 	int		nservers;
222 	caddr32_t	door_info;
223 };
224 #endif
225 
226 /*
227  * Structure used to pass a descriptor list to door_return.
228  */
229 typedef struct door_return_desc {
230 	door_desc_t	*desc_ptr;
231 	uint_t		desc_num;
232 } door_return_desc_t;
233 
234 #if defined(_SYSCALL32)
235 typedef struct door_return_desc32 {
236 	caddr32_t	desc_ptr;
237 	uint_t		desc_num;
238 } door_return_desc32_t;
239 #endif
240 
241 #if defined(_KERNEL)
242 
243 /*
244  * Errors used for doors. Negative numbers to avoid conflicts with errnos
245  */
246 #define	DOOR_WAIT	-1	/* Waiting for response */
247 #define	DOOR_EXIT	-2	/* Server thread has exited */
248 
249 #define	VTOD(v)	((struct door_node *)(v->v_data))
250 #define	DTOV(d) ((d)->door_vnode)
251 
252 /*
253  * Underlying 'filesystem' object definition
254  */
255 typedef struct door_node {
256 	vnode_t		*door_vnode;
257 	struct proc 	*door_target;	/* Proc handling this doors invoc's. */
258 	struct door_node *door_list;	/* List of active doors in proc */
259 	struct door_node *door_ulist;	/* Unref list */
260 	void		(*door_pc)();	/* Door server entry point */
261 	void		*door_data;	/* Cookie passed during invocations */
262 	door_id_t	door_index;	/* Used as a uniquifier */
263 	door_attr_t	door_flags;	/* State associated with door */
264 	uint_t		door_active;	/* Number of active invocations */
265 	door_pool_t	door_servers;	/* Private pool of server threads */
266 	size_t		door_data_max;	/* param: max request data size */
267 	size_t		door_data_min;	/* param: min request data size */
268 	uint_t		door_desc_max;	/* param: max request descriptors */
269 	uint_t		door_bound_threads; /* number of bound threads */
270 } door_node_t;
271 
272 /* Test if a door has been revoked */
273 #define	DOOR_INVALID(dp)	((dp)->door_flags & DOOR_REVOKED)
274 
275 struct file;
276 int	door_insert(struct file *, door_desc_t *);
277 int	door_finish_dispatch(caddr_t);
278 uintptr_t door_final_sp(uintptr_t, size_t, int);
279 int	door_upcall(vnode_t *, door_arg_t *, struct cred *, size_t, uint_t);
280 void	door_slam(void);
281 void	door_exit(void);
282 void	door_revoke_all(void);
283 void	door_deliver_unref(door_node_t *);
284 void	door_list_delete(door_node_t *);
285 void	door_fork(kthread_t *, kthread_t *);
286 void	door_bind_thread(door_node_t *);
287 void	door_unbind_thread(door_node_t *);
288 
289 extern kmutex_t door_knob;
290 extern kcondvar_t door_cv;
291 extern size_t door_max_arg;
292 
293 /*
294  * In-kernel doors interface.  These functions are considered Sun Private
295  * and may change incompatibly in a minor release of Solaris.
296  */
297 int	door_ki_upcall(door_handle_t, door_arg_t *);
298 int	door_ki_upcall_limited(door_handle_t, door_arg_t *, struct cred *,
299     size_t, uint_t);
300 int	door_ki_create(void (*)(void *, door_arg_t *,
301     void (**)(void *, void *), void **, int *), void *, door_attr_t,
302     door_handle_t *);
303 void	door_ki_hold(door_handle_t);
304 void	door_ki_rele(door_handle_t);
305 int	door_ki_open(char *, door_handle_t *);
306 int	door_ki_info(door_handle_t, door_info_t *);
307 int	door_ki_getparam(door_handle_t, int, size_t *);
308 int	door_ki_setparam(door_handle_t, int, size_t);
309 door_handle_t door_ki_lookup(int did);
310 
311 #endif	/* defined(_KERNEL) */
312 #endif	/* !defined(_ASM) */
313 
314 /*
315  * System call subcodes
316  */
317 #define	DOOR_CREATE	0
318 #define	DOOR_REVOKE	1
319 #define	DOOR_INFO	2
320 #define	DOOR_CALL	3
321 #define	DOOR_BIND	6
322 #define	DOOR_UNBIND	7
323 #define	DOOR_UNREFSYS	8
324 #define	DOOR_UCRED	9
325 #define	DOOR_RETURN	10
326 #define	DOOR_GETPARAM	11
327 #define	DOOR_SETPARAM	12
328 
329 #ifdef	__cplusplus
330 }
331 #endif
332 
333 #endif	/* _SYS_DOOR_H */
334