xref: /onnv-gate/usr/src/lib/libc/i386/sys/door.s (revision 11102:b91faef0c984)
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
55891Sraf * Common Development and Distribution License (the "License").
65891Sraf * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
215891Sraf
220Sstevel@tonic-gate/*
23*11102SGavin.Maltby@Sun.COM * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
277298SMark.J.Nelson@Sun.COM	.file	"door.s"
280Sstevel@tonic-gate
296812Sraf#include "SYS.h"
306812Sraf#include <sys/door.h>
310Sstevel@tonic-gate
320Sstevel@tonic-gate	/*
330Sstevel@tonic-gate	 * weak aliases for public interfaces
340Sstevel@tonic-gate	 */
356812Sraf	ANSI_PRAGMA_WEAK2(door_bind,__door_bind,function)
366812Sraf	ANSI_PRAGMA_WEAK2(door_getparam,__door_getparam,function)
376812Sraf	ANSI_PRAGMA_WEAK2(door_info,__door_info,function)
386812Sraf	ANSI_PRAGMA_WEAK2(door_revoke,__door_revoke,function)
396812Sraf	ANSI_PRAGMA_WEAK2(door_setparam,__door_setparam,function)
400Sstevel@tonic-gate
410Sstevel@tonic-gate/*
420Sstevel@tonic-gate * Offsets within struct door_results
430Sstevel@tonic-gate */
440Sstevel@tonic-gate#define	DOOR_COOKIE	_MUL(0, CLONGSIZE)
450Sstevel@tonic-gate#define	DOOR_DATA_PTR	_MUL(1, CLONGSIZE)
460Sstevel@tonic-gate#define	DOOR_DATA_SIZE	_MUL(2, CLONGSIZE)
470Sstevel@tonic-gate#define	DOOR_DESC_PTR	_MUL(3, CLONGSIZE)
480Sstevel@tonic-gate#define	DOOR_DESC_SIZE	_MUL(4, CLONGSIZE)
490Sstevel@tonic-gate#define	DOOR_PC		_MUL(5, CLONGSIZE)
500Sstevel@tonic-gate#define	DOOR_SERVERS	_MUL(6, CLONGSIZE)
510Sstevel@tonic-gate#define	DOOR_INFO_PTR	_MUL(7, CLONGSIZE)
520Sstevel@tonic-gate
530Sstevel@tonic-gate/*
540Sstevel@tonic-gate * All of the syscalls except door_return() follow the same pattern.
550Sstevel@tonic-gate * The subcode goes in argument 6, which means we have to copy our
560Sstevel@tonic-gate * arguments into a new bit of stack, large enough to include the
570Sstevel@tonic-gate * subcode.  We fill the unused positions with zeros.
580Sstevel@tonic-gate */
590Sstevel@tonic-gate#define	DOOR_SYSCALL(name, code, copy_args)				\
600Sstevel@tonic-gate	ENTRY(name);							\
610Sstevel@tonic-gate	pushl	%ebp;							\
620Sstevel@tonic-gate	movl	%esp, %ebp;						\
630Sstevel@tonic-gate	pushl	$code;		/* syscall subcode, arg 6 */		\
640Sstevel@tonic-gate	pushl	$0;		/* dummy arg 5 */			\
650Sstevel@tonic-gate	pushl	$0;		/* dummy arg 4 */			\
660Sstevel@tonic-gate	copy_args;		/* args 1, 2, 3 */			\
670Sstevel@tonic-gate	pushl	$0;		/* dummy return PC */			\
680Sstevel@tonic-gate	SYSTRAP_RVAL1(door);						\
690Sstevel@tonic-gate	jae	1f;							\
700Sstevel@tonic-gate	addl	$28, %esp;						\
710Sstevel@tonic-gate	leave;								\
720Sstevel@tonic-gate	jmp	__cerror;						\
730Sstevel@tonic-gate1:									\
740Sstevel@tonic-gate	addl	$28, %esp;						\
750Sstevel@tonic-gate	leave;								\
760Sstevel@tonic-gate	ret;								\
770Sstevel@tonic-gate	SET_SIZE(name)
780Sstevel@tonic-gate
790Sstevel@tonic-gate#define	COPY_0								\
800Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
810Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
820Sstevel@tonic-gate	pushl	$0		/* dummy */
830Sstevel@tonic-gate
840Sstevel@tonic-gate#define	COPY_1								\
850Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
860Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
870Sstevel@tonic-gate	pushl	8(%ebp)		/* 1 */
880Sstevel@tonic-gate
890Sstevel@tonic-gate#define	COPY_2								\
900Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
910Sstevel@tonic-gate	pushl	12(%ebp);	/* 2 */					\
920Sstevel@tonic-gate	pushl	8(%ebp)		/* 1 */
930Sstevel@tonic-gate
940Sstevel@tonic-gate#define	COPY_3								\
950Sstevel@tonic-gate	pushl	16(%ebp);	/* 3 */					\
960Sstevel@tonic-gate	pushl	12(%ebp);	/* 2 */					\
970Sstevel@tonic-gate	pushl	8(%ebp)		/* 1 */
980Sstevel@tonic-gate
990Sstevel@tonic-gate	DOOR_SYSCALL(__door_bind,	DOOR_BIND,	COPY_1)
1000Sstevel@tonic-gate	DOOR_SYSCALL(__door_call,	DOOR_CALL,	COPY_2)
1010Sstevel@tonic-gate	DOOR_SYSCALL(__door_create,	DOOR_CREATE,	COPY_3)
1020Sstevel@tonic-gate	DOOR_SYSCALL(__door_getparam,	DOOR_GETPARAM,	COPY_3)
1030Sstevel@tonic-gate	DOOR_SYSCALL(__door_info,	DOOR_INFO,	COPY_2)
1040Sstevel@tonic-gate	DOOR_SYSCALL(__door_revoke,	DOOR_REVOKE,	COPY_1)
1050Sstevel@tonic-gate	DOOR_SYSCALL(__door_setparam,	DOOR_SETPARAM,	COPY_3)
1060Sstevel@tonic-gate	DOOR_SYSCALL(__door_ucred,	DOOR_UCRED,	COPY_1)
1070Sstevel@tonic-gate	DOOR_SYSCALL(__door_unbind,	DOOR_UNBIND,	COPY_0)
1080Sstevel@tonic-gate	DOOR_SYSCALL(__door_unref,	DOOR_UNREFSYS,	COPY_0)
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate/*
1110Sstevel@tonic-gate * int
1120Sstevel@tonic-gate * __door_return(
1130Sstevel@tonic-gate *	void 			*data_ptr,
1140Sstevel@tonic-gate *	size_t			data_size,	(in bytes)
1150Sstevel@tonic-gate *	door_return_desc_t	*door_ptr,	(holds returned desc info)
1160Sstevel@tonic-gate *	caddr_t			stack_base,
1170Sstevel@tonic-gate *	size_t			stack_size)
1180Sstevel@tonic-gate */
1190Sstevel@tonic-gate	ENTRY(__door_return)
1200Sstevel@tonic-gate	movl	%esp, %edx		/ Save pointer to args
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate	pushl	%edi			/ save old %edi and %esi
1230Sstevel@tonic-gate	pushl	%esi			/ and use them to hold the
1240Sstevel@tonic-gate	movl	16(%edx), %esi		/ stack pointer and
1250Sstevel@tonic-gate	movl	20(%edx), %edi		/ size.
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate	pushl	$DOOR_RETURN		/ syscall subcode
1280Sstevel@tonic-gate	pushl	%edi			/ size of user stack
1290Sstevel@tonic-gate	pushl	%esi			/ base of user stack
1300Sstevel@tonic-gate	pushl	12(%edx)		/ desc arguments ptr
1310Sstevel@tonic-gate	pushl	8(%edx)			/ data size
1320Sstevel@tonic-gate	pushl	4(%edx)			/ data ptr
1330Sstevel@tonic-gate	pushl	0(%edx)			/ dummy return PC
1340Sstevel@tonic-gate
1350Sstevel@tonic-gatedoor_restart:
1360Sstevel@tonic-gate	SYSTRAP_RVAL1(door)
1375540Sdm120769	jb	2f			/* errno is set */
1380Sstevel@tonic-gate	/*
1390Sstevel@tonic-gate	 * On return, we're serving a door_call.  Our stack looks like this:
1400Sstevel@tonic-gate	 *
1410Sstevel@tonic-gate	 *		descriptors (if any)
1420Sstevel@tonic-gate	 *		data (if any)
1430Sstevel@tonic-gate	 *	 sp->	struct door_results
1440Sstevel@tonic-gate	 *
1450Sstevel@tonic-gate	 * struct door_results has the arguments in place for the server proc,
1460Sstevel@tonic-gate	 * so we just call it directly.
1470Sstevel@tonic-gate	 */
1480Sstevel@tonic-gate	movl	DOOR_SERVERS(%esp), %eax
1490Sstevel@tonic-gate	andl	%eax, %eax	/* test nservers */
1500Sstevel@tonic-gate	jg	1f
1510Sstevel@tonic-gate	/*
1520Sstevel@tonic-gate	 * this is the last server thread - call creation func for more
1530Sstevel@tonic-gate	 */
1540Sstevel@tonic-gate	movl	DOOR_INFO_PTR(%esp), %eax
1550Sstevel@tonic-gate	pushl	%eax		/* door_info_t * */
156*11102SGavin.Maltby@Sun.COM	call	door_depletion_cb@PLT
1570Sstevel@tonic-gate	addl	$4, %esp
1580Sstevel@tonic-gate1:
1590Sstevel@tonic-gate	/* Call the door server function now */
1600Sstevel@tonic-gate	movl	DOOR_PC(%esp), %eax
1610Sstevel@tonic-gate	call	*%eax
1620Sstevel@tonic-gate	/* Exit the thread if we return here */
1630Sstevel@tonic-gate	pushl	$0
1646812Sraf	call	_thrp_terminate
1650Sstevel@tonic-gate	/* NOTREACHED */
1665540Sdm1207692:
1670Sstevel@tonic-gate	/*
1680Sstevel@tonic-gate	 * Error during door_return call.  Repark the thread in the kernel if
1690Sstevel@tonic-gate	 * the error code is EINTR (or ERESTART) and this lwp is still part
1700Sstevel@tonic-gate	 * of the same process.
1710Sstevel@tonic-gate	 *
1720Sstevel@tonic-gate	 * If the error code is EINTR or ERESTART, our stack may have been
1730Sstevel@tonic-gate	 * corrupted by a partial door call, so we refresh the system call
1740Sstevel@tonic-gate	 * arguments.
1750Sstevel@tonic-gate	 */
1760Sstevel@tonic-gate	cmpl	$ERESTART, %eax		/* ERESTART is same as EINTR */
1775540Sdm120769	jne	3f
1780Sstevel@tonic-gate	movl	$EINTR, %eax
1795540Sdm1207693:
1800Sstevel@tonic-gate	cmpl	$EINTR, %eax		/* interrupted while waiting? */
1815540Sdm120769	jne	4f			/* if not, return the error */
1820Sstevel@tonic-gate	_prologue_
1836515Sraf	call	getpid
1840Sstevel@tonic-gate	movl	_daref_(door_create_pid), %edx
1850Sstevel@tonic-gate	movl	0(%edx), %edx
1860Sstevel@tonic-gate	_epilogue_
1870Sstevel@tonic-gate	cmpl	%eax, %edx		/* same process? */
1880Sstevel@tonic-gate	movl	$EINTR, %eax	/* if no, return EINTR (child of forkall) */
1895540Sdm120769	jne	4f
1900Sstevel@tonic-gate	movl	$0, 4(%esp)		/* clear arguments and restart */
1910Sstevel@tonic-gate	movl	$0, 8(%esp)
1920Sstevel@tonic-gate	movl	$0, 12(%esp)
1930Sstevel@tonic-gate	movl	%esi, 16(%esp)		/* refresh sp */
1940Sstevel@tonic-gate	movl	%edi, 20(%esp)		/* refresh ssize */
1950Sstevel@tonic-gate	movl	$DOOR_RETURN, 24(%esp)	/* refresh syscall subcode */
1960Sstevel@tonic-gate	jmp	door_restart
1975540Sdm1207694:
1980Sstevel@tonic-gate	/* Something bad happened during the door_return */
1990Sstevel@tonic-gate	addl	$28, %esp
2000Sstevel@tonic-gate	popl	%esi
2010Sstevel@tonic-gate	popl	%edi
2020Sstevel@tonic-gate	jmp	__cerror
2030Sstevel@tonic-gate	SET_SIZE(__door_return)
204