xref: /illumos-gate/usr/src/lib/libc/i386/sys/door.S (revision 5d9d9091)
1*5d9d9091SRichard Lowe/*
2*5d9d9091SRichard Lowe * CDDL HEADER START
3*5d9d9091SRichard Lowe *
4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the
5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License").
6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License.
7*5d9d9091SRichard Lowe *
8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions
11*5d9d9091SRichard Lowe * and limitations under the License.
12*5d9d9091SRichard Lowe *
13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*5d9d9091SRichard Lowe *
19*5d9d9091SRichard Lowe * CDDL HEADER END
20*5d9d9091SRichard Lowe */
21*5d9d9091SRichard Lowe
22*5d9d9091SRichard Lowe/*
23*5d9d9091SRichard Lowe * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*5d9d9091SRichard Lowe * Use is subject to license terms.
25*5d9d9091SRichard Lowe *
26*5d9d9091SRichard Lowe * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
27*5d9d9091SRichard Lowe */
28*5d9d9091SRichard Lowe
29*5d9d9091SRichard Lowe	.file	"door.s"
30*5d9d9091SRichard Lowe
31*5d9d9091SRichard Lowe#include "SYS.h"
32*5d9d9091SRichard Lowe#include <sys/door.h>
33*5d9d9091SRichard Lowe
34*5d9d9091SRichard Lowe	/*
35*5d9d9091SRichard Lowe	 * weak aliases for public interfaces
36*5d9d9091SRichard Lowe	 */
37*5d9d9091SRichard Lowe	ANSI_PRAGMA_WEAK2(door_bind,__door_bind,function)
38*5d9d9091SRichard Lowe	ANSI_PRAGMA_WEAK2(door_getparam,__door_getparam,function)
39*5d9d9091SRichard Lowe	ANSI_PRAGMA_WEAK2(door_info,__door_info,function)
40*5d9d9091SRichard Lowe	ANSI_PRAGMA_WEAK2(door_revoke,__door_revoke,function)
41*5d9d9091SRichard Lowe	ANSI_PRAGMA_WEAK2(door_setparam,__door_setparam,function)
42*5d9d9091SRichard Lowe
43*5d9d9091SRichard Lowe/*
44*5d9d9091SRichard Lowe * Offsets within struct door_results
45*5d9d9091SRichard Lowe */
46*5d9d9091SRichard Lowe#define	DOOR_COOKIE	_MUL(0, CLONGSIZE)
47*5d9d9091SRichard Lowe#define	DOOR_DATA_PTR	_MUL(1, CLONGSIZE)
48*5d9d9091SRichard Lowe#define	DOOR_DATA_SIZE	_MUL(2, CLONGSIZE)
49*5d9d9091SRichard Lowe#define	DOOR_DESC_PTR	_MUL(3, CLONGSIZE)
50*5d9d9091SRichard Lowe#define	DOOR_DESC_SIZE	_MUL(4, CLONGSIZE)
51*5d9d9091SRichard Lowe#define	DOOR_PC		_MUL(5, CLONGSIZE)
52*5d9d9091SRichard Lowe#define	DOOR_SERVERS	_MUL(6, CLONGSIZE)
53*5d9d9091SRichard Lowe#define	DOOR_INFO_PTR	_MUL(7, CLONGSIZE)
54*5d9d9091SRichard Lowe
55*5d9d9091SRichard Lowe/*
56*5d9d9091SRichard Lowe * All of the syscalls except door_return() follow the same pattern.
57*5d9d9091SRichard Lowe * The subcode goes in argument 6, which means we have to copy our
58*5d9d9091SRichard Lowe * arguments into a new bit of stack, large enough to include the
59*5d9d9091SRichard Lowe * subcode.  We fill the unused positions with zeros.
60*5d9d9091SRichard Lowe */
61*5d9d9091SRichard Lowe#define	DOOR_SYSCALL(name, code, copy_args)				\
62*5d9d9091SRichard Lowe	ENTRY(name);							\
63*5d9d9091SRichard Lowe	pushl	%ebp;							\
64*5d9d9091SRichard Lowe	movl	%esp, %ebp;						\
65*5d9d9091SRichard Lowe	pushl	$code;		/* syscall subcode, arg 6 */		\
66*5d9d9091SRichard Lowe	pushl	$0;		/* dummy arg 5 */			\
67*5d9d9091SRichard Lowe	pushl	$0;		/* dummy arg 4 */			\
68*5d9d9091SRichard Lowe	copy_args;		/* args 1, 2, 3 */			\
69*5d9d9091SRichard Lowe	pushl	$0;		/* dummy return PC */			\
70*5d9d9091SRichard Lowe	SYSTRAP_RVAL1(door);						\
71*5d9d9091SRichard Lowe	jae	1f;							\
72*5d9d9091SRichard Lowe	addl	$28, %esp;						\
73*5d9d9091SRichard Lowe	leave;								\
74*5d9d9091SRichard Lowe	jmp	__cerror;						\
75*5d9d9091SRichard Lowe1:									\
76*5d9d9091SRichard Lowe	addl	$28, %esp;						\
77*5d9d9091SRichard Lowe	leave;								\
78*5d9d9091SRichard Lowe	ret;								\
79*5d9d9091SRichard Lowe	SET_SIZE(name)
80*5d9d9091SRichard Lowe
81*5d9d9091SRichard Lowe#define	COPY_0								\
82*5d9d9091SRichard Lowe	pushl	$0;		/* dummy */				\
83*5d9d9091SRichard Lowe	pushl	$0;		/* dummy */				\
84*5d9d9091SRichard Lowe	pushl	$0		/* dummy */
85*5d9d9091SRichard Lowe
86*5d9d9091SRichard Lowe#define	COPY_1								\
87*5d9d9091SRichard Lowe	pushl	$0;		/* dummy */				\
88*5d9d9091SRichard Lowe	pushl	$0;		/* dummy */				\
89*5d9d9091SRichard Lowe	pushl	8(%ebp)		/* 1 */
90*5d9d9091SRichard Lowe
91*5d9d9091SRichard Lowe#define	COPY_2								\
92*5d9d9091SRichard Lowe	pushl	$0;		/* dummy */				\
93*5d9d9091SRichard Lowe	pushl	12(%ebp);	/* 2 */					\
94*5d9d9091SRichard Lowe	pushl	8(%ebp)		/* 1 */
95*5d9d9091SRichard Lowe
96*5d9d9091SRichard Lowe#define	COPY_3								\
97*5d9d9091SRichard Lowe	pushl	16(%ebp);	/* 3 */					\
98*5d9d9091SRichard Lowe	pushl	12(%ebp);	/* 2 */					\
99*5d9d9091SRichard Lowe	pushl	8(%ebp)		/* 1 */
100*5d9d9091SRichard Lowe
101*5d9d9091SRichard Lowe	DOOR_SYSCALL(__door_bind,	DOOR_BIND,	COPY_1)
102*5d9d9091SRichard Lowe	DOOR_SYSCALL(__door_call,	DOOR_CALL,	COPY_2)
103*5d9d9091SRichard Lowe	DOOR_SYSCALL(__door_create,	DOOR_CREATE,	COPY_3)
104*5d9d9091SRichard Lowe	DOOR_SYSCALL(__door_getparam,	DOOR_GETPARAM,	COPY_3)
105*5d9d9091SRichard Lowe	DOOR_SYSCALL(__door_info,	DOOR_INFO,	COPY_2)
106*5d9d9091SRichard Lowe	DOOR_SYSCALL(__door_revoke,	DOOR_REVOKE,	COPY_1)
107*5d9d9091SRichard Lowe	DOOR_SYSCALL(__door_setparam,	DOOR_SETPARAM,	COPY_3)
108*5d9d9091SRichard Lowe	DOOR_SYSCALL(__door_ucred,	DOOR_UCRED,	COPY_1)
109*5d9d9091SRichard Lowe	DOOR_SYSCALL(__door_unbind,	DOOR_UNBIND,	COPY_0)
110*5d9d9091SRichard Lowe	DOOR_SYSCALL(__door_unref,	DOOR_UNREFSYS,	COPY_0)
111*5d9d9091SRichard Lowe
112*5d9d9091SRichard Lowe/*
113*5d9d9091SRichard Lowe * int
114*5d9d9091SRichard Lowe * __door_return(
115*5d9d9091SRichard Lowe *	void			*data_ptr,
116*5d9d9091SRichard Lowe *	size_t			data_size,	(in bytes)
117*5d9d9091SRichard Lowe *	door_return_desc_t	*door_ptr,	(holds returned desc info)
118*5d9d9091SRichard Lowe *	caddr_t			stack_base,
119*5d9d9091SRichard Lowe *	size_t			stack_size)
120*5d9d9091SRichard Lowe */
121*5d9d9091SRichard Lowe	ENTRY(__door_return)
122*5d9d9091SRichard Lowe	movl	%esp, %edx		/ Save pointer to args
123*5d9d9091SRichard Lowe
124*5d9d9091SRichard Lowe	pushl	%edi			/ save old %edi and %esi
125*5d9d9091SRichard Lowe	pushl	%esi			/ and use them to hold the
126*5d9d9091SRichard Lowe	movl	16(%edx), %esi		/ stack pointer and
127*5d9d9091SRichard Lowe	movl	20(%edx), %edi		/ size.
128*5d9d9091SRichard Lowe
129*5d9d9091SRichard Lowe	pushl	$DOOR_RETURN		/ syscall subcode
130*5d9d9091SRichard Lowe	pushl	%edi			/ size of user stack
131*5d9d9091SRichard Lowe	pushl	%esi			/ base of user stack
132*5d9d9091SRichard Lowe	pushl	12(%edx)		/ desc arguments ptr
133*5d9d9091SRichard Lowe	pushl	8(%edx)			/ data size
134*5d9d9091SRichard Lowe	pushl	4(%edx)			/ data ptr
135*5d9d9091SRichard Lowe	pushl	0(%edx)			/ dummy return PC
136*5d9d9091SRichard Lowe
137*5d9d9091SRichard Lowedoor_restart:
138*5d9d9091SRichard Lowe	SYSTRAP_RVAL1(door)
139*5d9d9091SRichard Lowe	jb	2f			/* errno is set */
140*5d9d9091SRichard Lowe	/*
141*5d9d9091SRichard Lowe	 * On return, we're serving a door_call.  Our stack looks like this:
142*5d9d9091SRichard Lowe	 *
143*5d9d9091SRichard Lowe	 *		descriptors (if any)
144*5d9d9091SRichard Lowe	 *		data (if any)
145*5d9d9091SRichard Lowe	 *	 sp->	struct door_results
146*5d9d9091SRichard Lowe	 *
147*5d9d9091SRichard Lowe	 * The stack will be aligned to 16 bytes; we must maintain that
148*5d9d9091SRichard Lowe	 * alignment prior to any call instruction.
149*5d9d9091SRichard Lowe	 * struct door_results has the arguments in place for the server proc,
150*5d9d9091SRichard Lowe	 * so we just call it directly.
151*5d9d9091SRichard Lowe	 */
152*5d9d9091SRichard Lowe	movl	DOOR_SERVERS(%esp), %eax
153*5d9d9091SRichard Lowe	andl	%eax, %eax	/* test nservers */
154*5d9d9091SRichard Lowe	jg	1f
155*5d9d9091SRichard Lowe	/*
156*5d9d9091SRichard Lowe	 * this is the last server thread - call creation func for more
157*5d9d9091SRichard Lowe	 */
158*5d9d9091SRichard Lowe	movl	DOOR_INFO_PTR(%esp), %eax
159*5d9d9091SRichard Lowe	subl	$12, %esp
160*5d9d9091SRichard Lowe	pushl	%eax		/* door_info_t * */
161*5d9d9091SRichard Lowe	call	door_depletion_cb@PLT
162*5d9d9091SRichard Lowe	addl	$16, %esp
163*5d9d9091SRichard Lowe1:
164*5d9d9091SRichard Lowe	/* Call the door server function now */
165*5d9d9091SRichard Lowe	movl	DOOR_PC(%esp), %eax
166*5d9d9091SRichard Lowe	call	*%eax
167*5d9d9091SRichard Lowe	/* Exit the thread if we return here */
168*5d9d9091SRichard Lowe	subl	$12, %esp
169*5d9d9091SRichard Lowe	pushl	$0
170*5d9d9091SRichard Lowe	call	_thrp_terminate
171*5d9d9091SRichard Lowe	/* NOTREACHED */
172*5d9d9091SRichard Lowe2:
173*5d9d9091SRichard Lowe	/*
174*5d9d9091SRichard Lowe	 * Error during door_return call.  Repark the thread in the kernel if
175*5d9d9091SRichard Lowe	 * the error code is EINTR (or ERESTART) and this lwp is still part
176*5d9d9091SRichard Lowe	 * of the same process.
177*5d9d9091SRichard Lowe	 *
178*5d9d9091SRichard Lowe	 * If the error code is EINTR or ERESTART, our stack may have been
179*5d9d9091SRichard Lowe	 * corrupted by a partial door call, so we refresh the system call
180*5d9d9091SRichard Lowe	 * arguments.
181*5d9d9091SRichard Lowe	 */
182*5d9d9091SRichard Lowe	cmpl	$ERESTART, %eax		/* ERESTART is same as EINTR */
183*5d9d9091SRichard Lowe	jne	3f
184*5d9d9091SRichard Lowe	movl	$EINTR, %eax
185*5d9d9091SRichard Lowe3:
186*5d9d9091SRichard Lowe	cmpl	$EINTR, %eax		/* interrupted while waiting? */
187*5d9d9091SRichard Lowe	jne	4f			/* if not, return the error */
188*5d9d9091SRichard Lowe	_prologue_
189*5d9d9091SRichard Lowe	call	getpid
190*5d9d9091SRichard Lowe	movl	_daref_(door_create_pid), %edx
191*5d9d9091SRichard Lowe	movl	0(%edx), %edx
192*5d9d9091SRichard Lowe	_epilogue_
193*5d9d9091SRichard Lowe	cmpl	%eax, %edx		/* same process? */
194*5d9d9091SRichard Lowe	movl	$EINTR, %eax	/* if no, return EINTR (child of forkall) */
195*5d9d9091SRichard Lowe	jne	4f
196*5d9d9091SRichard Lowe	movl	$0, 4(%esp)		/* clear arguments and restart */
197*5d9d9091SRichard Lowe	movl	$0, 8(%esp)
198*5d9d9091SRichard Lowe	movl	$0, 12(%esp)
199*5d9d9091SRichard Lowe	movl	%esi, 16(%esp)		/* refresh sp */
200*5d9d9091SRichard Lowe	movl	%edi, 20(%esp)		/* refresh ssize */
201*5d9d9091SRichard Lowe	movl	$DOOR_RETURN, 24(%esp)	/* refresh syscall subcode */
202*5d9d9091SRichard Lowe	jmp	door_restart
203*5d9d9091SRichard Lowe4:
204*5d9d9091SRichard Lowe	/* Something bad happened during the door_return */
205*5d9d9091SRichard Lowe	addl	$28, %esp
206*5d9d9091SRichard Lowe	popl	%esi
207*5d9d9091SRichard Lowe	popl	%edi
208*5d9d9091SRichard Lowe	jmp	__cerror
209*5d9d9091SRichard Lowe	SET_SIZE(__door_return)
210