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.
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.
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]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
33 * weak aliases for public interfaces
35 ANSI_PRAGMA_WEAK2
(door_bind
,__door_bind
,function
)
36 ANSI_PRAGMA_WEAK2
(door_getparam
,__door_getparam
,function
)
37 ANSI_PRAGMA_WEAK2
(door_info
,__door_info
,function
)
38 ANSI_PRAGMA_WEAK2
(door_revoke
,__door_revoke
,function
)
39 ANSI_PRAGMA_WEAK2
(door_setparam
,__door_setparam
,function
)
42 * Offsets within struct door_results
44 #define DOOR_COOKIE _MUL(0, CLONGSIZE)
45 #define DOOR_DATA_PTR _MUL(1, CLONGSIZE)
46 #define DOOR_DATA_SIZE _MUL(2, CLONGSIZE)
47 #define DOOR_DESC_PTR _MUL(3, CLONGSIZE)
48 #define DOOR_DESC_SIZE _MUL(4, CLONGSIZE)
49 #define DOOR_PC _MUL(5, CLONGSIZE)
50 #define DOOR_SERVERS _MUL(6, CLONGSIZE)
51 #define DOOR_INFO_PTR _MUL(7, CLONGSIZE)
54 * All of the syscalls except door_return() follow the same pattern.
55 * The subcode goes in argument 6, which means we have to copy our
56 * arguments into a new bit of stack, large enough to include the
57 * subcode. We fill the unused positions with zeros.
59 #define DOOR_SYSCALL(name, code, copy_args) \
63 pushl $code;
/* syscall subcode, arg 6 */ \
64 pushl $
0;
/* dummy arg 5 */ \
65 pushl $
0;
/* dummy arg 4 */ \
66 copy_args;
/* args 1, 2, 3 */ \
67 pushl $
0;
/* dummy return PC */ \
68 SYSTRAP_RVAL1
(door
); \
80 pushl $
0;
/* dummy */ \
81 pushl $
0;
/* dummy */ \
85 pushl $
0;
/* dummy */ \
86 pushl $
0;
/* dummy */ \
90 pushl $
0;
/* dummy */ \
91 pushl
12(%ebp
);
/* 2 */ \
95 pushl
16(%ebp
);
/* 3 */ \
96 pushl
12(%ebp
);
/* 2 */ \
99 DOOR_SYSCALL
(__door_bind
, DOOR_BIND
, COPY_1
)
100 DOOR_SYSCALL
(__door_call
, DOOR_CALL
, COPY_2
)
101 DOOR_SYSCALL
(__door_create
, DOOR_CREATE
, COPY_3
)
102 DOOR_SYSCALL
(__door_getparam
, DOOR_GETPARAM
, COPY_3
)
103 DOOR_SYSCALL
(__door_info
, DOOR_INFO
, COPY_2
)
104 DOOR_SYSCALL
(__door_revoke
, DOOR_REVOKE
, COPY_1
)
105 DOOR_SYSCALL
(__door_setparam
, DOOR_SETPARAM
, COPY_3
)
106 DOOR_SYSCALL
(__door_ucred
, DOOR_UCRED
, COPY_1
)
107 DOOR_SYSCALL
(__door_unbind
, DOOR_UNBIND
, COPY_0
)
108 DOOR_SYSCALL
(__door_unref
, DOOR_UNREFSYS
, COPY_0
)
114 * size_t data_size, (in bytes)
115 * door_return_desc_t *door_ptr, (holds returned desc info)
116 * caddr_t stack_base,
120 movl
%esp
, %edx
/ Save pointer to args
122 pushl
%edi
/ save old
%edi
and %esi
123 pushl
%esi
/ and use them to hold the
124 movl
16(%edx
), %esi
/ stack pointer
and
125 movl
20(%edx
), %edi
/ size.
127 pushl $DOOR_RETURN
/ syscall subcode
128 pushl
%edi
/ size of user stack
129 pushl
%esi
/ base of user stack
130 pushl
12(%edx
) / desc arguments ptr
131 pushl
8(%edx
) / data size
132 pushl
4(%edx
) / data ptr
133 pushl
0(%edx
) / dummy return PC
137 jb
2f
/* errno is set */
139 * On return, we're serving a door_call. Our stack looks like this:
141 * descriptors (if any)
143 * sp-> struct door_results
145 * struct door_results has the arguments in place for the server proc,
146 * so we just call it directly.
148 movl DOOR_SERVERS
(%esp
), %eax
149 andl
%eax
, %eax
/* test nservers */
152 * this is the last server thread - call creation func for more
154 movl DOOR_INFO_PTR
(%esp
), %eax
155 pushl
%eax
/* door_info_t * */
156 call door_depletion_cb@PLT
159 /* Call the door server function now */
160 movl DOOR_PC
(%esp
), %eax
162 /* Exit the thread if we return here */
168 * Error during door_return call. Repark the thread in the kernel if
169 * the error code is EINTR (or ERESTART) and this lwp is still part
170 * of the same process.
172 * If the error code is EINTR or ERESTART, our stack may have been
173 * corrupted by a partial door call, so we refresh the system call
176 cmpl $ERESTART
, %eax
/* ERESTART is same as EINTR */
180 cmpl $EINTR
, %eax
/* interrupted while waiting? */
181 jne
4f
/* if not, return the error */
184 movl _daref_
(door_create_pid
), %edx
187 cmpl %eax
, %edx
/* same process? */
188 movl $EINTR
, %eax
/* if no, return EINTR (child of forkall) */
190 movl $
0, 4(%esp
) /* clear arguments and restart */
193 movl
%esi
, 16(%esp
) /* refresh sp */
194 movl
%edi
, 20(%esp
) /* refresh ssize */
195 movl $DOOR_RETURN
, 24(%esp
) /* refresh syscall subcode */
198 /* Something bad happened during the door_return */
203 SET_SIZE
(__door_return
)