summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/door.h
blob: 7d04847864253afffc63f7f2467be532baa85e0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*
 * The door lightweight RPC I/F.
 */

#ifndef	_SYS_DOOR_H
#define	_SYS_DOOR_H

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Attributes associated with doors.
 */

/* Attributes originally obtained from door_create operation */
#define	DOOR_UNREF	0x01	/* Deliver an unref notification with door */
#define	DOOR_PRIVATE	0x02	/* Use a private pool of server threads */
#define	DOOR_UNREF_MULTI 0x10	/* Deliver unref notification more than once */
#define	DOOR_REFUSE_DESC 0x40	/* Do not accept descriptors from callers */
#define	DOOR_NO_CANCEL	0x80	/* No server thread cancel on client abort */
#define	DOOR_NO_DEPLETION_CB 0x100 /* No thread create callbacks on depletion */

/* Attributes (additional) returned with door_info and door_desc_t data */
#define	DOOR_LOCAL	0x04	/* Descriptor is local to current process */
#define	DOOR_REVOKED	0x08	/* Door has been revoked */
#define	DOOR_IS_UNREF	0x20	/* Door is currently unreferenced */
#define	DOOR_PRIVCREATE	0x200	/* Door has a private thread creation func */
#define	DOOR_DEPLETION_CB 0x400	/* Set only during depletion callbacks */

#if !defined(_ASM)

#include <sys/types.h>

#if defined(_KERNEL)
#include <sys/mutex.h>
#include <sys/vnode.h>
#include <sys/door_impl.h>
#endif /* defined(_KERNEL) */

/* Basic door type information */
typedef unsigned long long door_ptr_t;	/* Handle 64 bit pointers */
typedef unsigned long long door_id_t;	/* Unique door identifier */
typedef	unsigned int	   door_attr_t;	/* Door attributes */

#ifdef _KERNEL
struct __door_handle;
typedef struct __door_handle *door_handle_t;	/* opaque kernel door handle */
#endif

#define	DOOR_INVAL -1			/* An invalid door descriptor */
#define	DOOR_UNREF_DATA ((void *)1)	/* Unreferenced invocation address */

/* Door descriptor passed to door_info to get current thread's binding */
#define	DOOR_QUERY -2

/* Masks of applicable flags */
#define	DOOR_CREATE_MASK	(DOOR_UNREF | DOOR_PRIVATE | \
	    DOOR_UNREF_MULTI | DOOR_REFUSE_DESC | DOOR_NO_CANCEL | \
	    DOOR_NO_DEPLETION_CB | DOOR_PRIVCREATE)
#define	DOOR_KI_CREATE_MASK	(DOOR_UNREF | DOOR_UNREF_MULTI)

/* Mask of above attributes */
#define	DOOR_ATTR_MASK	(DOOR_CREATE_MASK | \
	    DOOR_LOCAL | DOOR_REVOKED | DOOR_IS_UNREF)

/* Attributes used to describe door_desc_t data */
#define	DOOR_DESCRIPTOR	0x10000	/* A file descriptor is being passed */
#ifdef _KERNEL
#define	DOOR_HANDLE	0x20000 /* A kernel door handle is being passed */
#endif
#define	DOOR_RELEASE	0x40000	/* Passed references are also released */

/* Misc attributes used internally */
#define	DOOR_DELAY	0x80000	/* Delayed unref delivery */
#define	DOOR_UNREF_ACTIVE 0x100000	/* Unreferenced call is active */

/* door parameters */
#define	DOOR_PARAM_DESC_MAX	1	/* max number of request descriptors */
#define	DOOR_PARAM_DATA_MAX	2	/* max bytes of request data */
#define	DOOR_PARAM_DATA_MIN	3	/* min bytes of request data */

/*
 * On AMD64, 32-bit pack door_desc and door_info to avoid needing special
 * copyin/copyout conversions due to differing alignment rules between
 * 32-bit x86 and 64-bit amd64.
 */

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack(4)
#endif

/*
 * Structure used to pass descriptors/objects in door invocations
 */

typedef struct door_desc {
	door_attr_t	d_attributes;	/* Tag for union */
	union {
		/* File descriptor is passed */
		struct {
			int		d_descriptor;
			door_id_t	d_id;		/* unique id */
		} d_desc;
#ifdef _KERNEL
		/* Kernel passes handles referring to doors */
		door_handle_t d_handle;
#endif
		/* Reserved space */
		int		d_resv[5];
	} d_data;
} door_desc_t;

/*
 * Structure used to return info from door_info
 */
typedef struct door_info {
	pid_t		di_target;	/* Server process */
	door_ptr_t	di_proc;	/* Server procedure */
	door_ptr_t	di_data;	/* Data cookie */
	door_attr_t	di_attributes;	/* Attributes associated with door */
	door_id_t	di_uniquifier;	/* Unique number */
	int		di_resv[4];	/* Future use */
} door_info_t;

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack()
#endif

/*
 * Structure used to return info from door_cred
 */
typedef struct door_cred {
	uid_t	dc_euid;	/* Effective uid of client */
	gid_t	dc_egid;	/* Effective gid of client */
	uid_t	dc_ruid;	/* Real uid of client */
	gid_t	dc_rgid;	/* Real gid of client */
	pid_t	dc_pid;		/* pid of client */
	int	dc_resv[4];	/* Future use */
} door_cred_t;

/*
 * Structure used to pass/return data from door_call
 *
 * All fields are in/out paramters. Upon return these fields
 * are updated to reflect the true location and size of the results.
 */
typedef struct door_arg {
	char		*data_ptr;	/* Argument/result data */
	size_t		data_size;	/* Argument/result data size */
	door_desc_t	*desc_ptr;	/* Argument/result descriptors */
	uint_t		desc_num;	/* Argument/result num discriptors */
	char		*rbuf;		/* Result area */
	size_t		rsize;		/* Result size */
} door_arg_t;

#if defined(_SYSCALL32)
/*
 * Structure to pass/return data from 32-bit program's door_call.
 */
typedef struct door_arg32 {
	caddr32_t	data_ptr;	/* Argument/result data */
	size32_t	data_size;	/* Argument/result data size */
	caddr32_t	desc_ptr;	/* Argument/result descriptors */
	uint32_t	desc_num;	/* Argument/result num descriptors */
	caddr32_t	rbuf;		/* Result area */
	size32_t	rsize;		/* Result size */
} door_arg32_t;
#endif

/*
 * Structure used to pass door invocation information.
 */
struct door_results {
	void		*cookie;
	char		*data_ptr;
	size_t		data_size;
	door_desc_t	*desc_ptr;
	size_t		desc_num;
	void		(*pc)();
	int		nservers;	/* zero if thread pool is empty */
	door_info_t	*door_info;
};

#if defined(_SYSCALL32)
/*
 * Structure used to pass door invocation information to 32-bit processes.
 */
struct door_results32 {
	caddr32_t	cookie;
	caddr32_t	data_ptr;
	size32_t	data_size;
	caddr32_t	desc_ptr;
	size32_t	desc_num;
	caddr32_t	pc;
	int		nservers;
	caddr32_t	door_info;
};
#endif

/*
 * Structure used to pass a descriptor list to door_return.
 */
typedef struct door_return_desc {
	door_desc_t	*desc_ptr;
	uint_t		desc_num;
} door_return_desc_t;

#if defined(_SYSCALL32)
typedef struct door_return_desc32 {
	caddr32_t	desc_ptr;
	uint_t		desc_num;
} door_return_desc32_t;
#endif

#if defined(_KERNEL)

/*
 * Errors used for doors. Negative numbers to avoid conflicts with errnos
 */
#define	DOOR_WAIT	-1	/* Waiting for response */
#define	DOOR_EXIT	-2	/* Server thread has exited */

#define	VTOD(v)	((struct door_node *)(v->v_data))
#define	DTOV(d) ((d)->door_vnode)

/*
 * Underlying 'filesystem' object definition
 */
typedef struct door_node {
	vnode_t		*door_vnode;
	struct proc 	*door_target;	/* Proc handling this doors invoc's. */
	struct door_node *door_list;	/* List of active doors in proc */
	struct door_node *door_ulist;	/* Unref list */
	void		(*door_pc)();	/* Door server entry point */
	void		*door_data;	/* Cookie passed during invocations */
	door_id_t	door_index;	/* Used as a uniquifier */
	door_attr_t	door_flags;	/* State associated with door */
	uint_t		door_active;	/* Number of active invocations */
	door_pool_t	door_servers;	/* Private pool of server threads */
	size_t		door_data_max;	/* param: max request data size */
	size_t		door_data_min;	/* param: min request data size */
	uint_t		door_desc_max;	/* param: max request descriptors */
	uint_t		door_bound_threads; /* number of bound threads */
} door_node_t;

/* Test if a door has been revoked */
#define	DOOR_INVALID(dp)	((dp)->door_flags & DOOR_REVOKED)

struct file;
int	door_insert(struct file *, door_desc_t *);
int	door_finish_dispatch(caddr_t);
uintptr_t door_final_sp(uintptr_t, size_t, int);
int	door_upcall(vnode_t *, door_arg_t *, struct cred *, size_t, uint_t);
void	door_slam(void);
void	door_exit(void);
void	door_revoke_all(void);
void	door_deliver_unref(door_node_t *);
void	door_list_delete(door_node_t *);
void	door_fork(kthread_t *, kthread_t *);
void	door_bind_thread(door_node_t *);
void	door_unbind_thread(door_node_t *);

extern kmutex_t door_knob;
extern kcondvar_t door_cv;
extern size_t door_max_arg;

/*
 * In-kernel doors interface.  These functions are considered Sun Private
 * and may change incompatibly in a minor release of Solaris.
 */
int	door_ki_upcall(door_handle_t, door_arg_t *);
int	door_ki_upcall_limited(door_handle_t, door_arg_t *, struct cred *,
    size_t, uint_t);
int	door_ki_create(void (*)(void *, door_arg_t *,
    void (**)(void *, void *), void **, int *), void *, door_attr_t,
    door_handle_t *);
void	door_ki_hold(door_handle_t);
void	door_ki_rele(door_handle_t);
int	door_ki_open(char *, door_handle_t *);
int	door_ki_info(door_handle_t, door_info_t *);
int	door_ki_getparam(door_handle_t, int, size_t *);
int	door_ki_setparam(door_handle_t, int, size_t);
door_handle_t door_ki_lookup(int did);

#endif	/* defined(_KERNEL) */
#endif	/* !defined(_ASM) */

/*
 * System call subcodes
 */
#define	DOOR_CREATE	0
#define	DOOR_REVOKE	1
#define	DOOR_INFO	2
#define	DOOR_CALL	3
#define	DOOR_BIND	6
#define	DOOR_UNBIND	7
#define	DOOR_UNREFSYS	8
#define	DOOR_UCRED	9
#define	DOOR_RETURN	10
#define	DOOR_GETPARAM	11
#define	DOOR_SETPARAM	12

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_DOOR_H */