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