Home | History | Annotate | Download | only in sys
      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