xref: /illumos-gate/usr/src/lib/libc/i386/sys/door.S (revision 5d9d9091)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5a574db85Sraf * Common Development and Distribution License (the "License").
6a574db85Sraf * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21a574db85Sraf
227c478bd9Sstevel@tonic-gate/*
2349b225e1SGavin Maltby * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
25915894efSMatt Barden *
26915894efSMatt Barden * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
277c478bd9Sstevel@tonic-gate */
287c478bd9Sstevel@tonic-gate
299a70fc3bSMark J. Nelson	.file	"door.s"
307c478bd9Sstevel@tonic-gate
317257d1b4Sraf#include "SYS.h"
327257d1b4Sraf#include <sys/door.h>
337c478bd9Sstevel@tonic-gate
347c478bd9Sstevel@tonic-gate	/*
357c478bd9Sstevel@tonic-gate	 * weak aliases for public interfaces
367c478bd9Sstevel@tonic-gate	 */
377257d1b4Sraf	ANSI_PRAGMA_WEAK2(door_bind,__door_bind,function)
387257d1b4Sraf	ANSI_PRAGMA_WEAK2(door_getparam,__door_getparam,function)
397257d1b4Sraf	ANSI_PRAGMA_WEAK2(door_info,__door_info,function)
407257d1b4Sraf	ANSI_PRAGMA_WEAK2(door_revoke,__door_revoke,function)
417257d1b4Sraf	ANSI_PRAGMA_WEAK2(door_setparam,__door_setparam,function)
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate/*
447c478bd9Sstevel@tonic-gate * Offsets within struct door_results
457c478bd9Sstevel@tonic-gate */
467c478bd9Sstevel@tonic-gate#define	DOOR_COOKIE	_MUL(0, CLONGSIZE)
477c478bd9Sstevel@tonic-gate#define	DOOR_DATA_PTR	_MUL(1, CLONGSIZE)
487c478bd9Sstevel@tonic-gate#define	DOOR_DATA_SIZE	_MUL(2, CLONGSIZE)
497c478bd9Sstevel@tonic-gate#define	DOOR_DESC_PTR	_MUL(3, CLONGSIZE)
507c478bd9Sstevel@tonic-gate#define	DOOR_DESC_SIZE	_MUL(4, CLONGSIZE)
517c478bd9Sstevel@tonic-gate#define	DOOR_PC		_MUL(5, CLONGSIZE)
527c478bd9Sstevel@tonic-gate#define	DOOR_SERVERS	_MUL(6, CLONGSIZE)
537c478bd9Sstevel@tonic-gate#define	DOOR_INFO_PTR	_MUL(7, CLONGSIZE)
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate/*
567c478bd9Sstevel@tonic-gate * All of the syscalls except door_return() follow the same pattern.
577c478bd9Sstevel@tonic-gate * The subcode goes in argument 6, which means we have to copy our
587c478bd9Sstevel@tonic-gate * arguments into a new bit of stack, large enough to include the
597c478bd9Sstevel@tonic-gate * subcode.  We fill the unused positions with zeros.
607c478bd9Sstevel@tonic-gate */
617c478bd9Sstevel@tonic-gate#define	DOOR_SYSCALL(name, code, copy_args)				\
627c478bd9Sstevel@tonic-gate	ENTRY(name);							\
637c478bd9Sstevel@tonic-gate	pushl	%ebp;							\
647c478bd9Sstevel@tonic-gate	movl	%esp, %ebp;						\
657c478bd9Sstevel@tonic-gate	pushl	$code;		/* syscall subcode, arg 6 */		\
667c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy arg 5 */			\
677c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy arg 4 */			\
687c478bd9Sstevel@tonic-gate	copy_args;		/* args 1, 2, 3 */			\
697c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy return PC */			\
707c478bd9Sstevel@tonic-gate	SYSTRAP_RVAL1(door);						\
717c478bd9Sstevel@tonic-gate	jae	1f;							\
727c478bd9Sstevel@tonic-gate	addl	$28, %esp;						\
737c478bd9Sstevel@tonic-gate	leave;								\
747c478bd9Sstevel@tonic-gate	jmp	__cerror;						\
757c478bd9Sstevel@tonic-gate1:									\
767c478bd9Sstevel@tonic-gate	addl	$28, %esp;						\
777c478bd9Sstevel@tonic-gate	leave;								\
787c478bd9Sstevel@tonic-gate	ret;								\
797c478bd9Sstevel@tonic-gate	SET_SIZE(name)
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate#define	COPY_0								\
827c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
837c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
847c478bd9Sstevel@tonic-gate	pushl	$0		/* dummy */
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate#define	COPY_1								\
877c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
887c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
897c478bd9Sstevel@tonic-gate	pushl	8(%ebp)		/* 1 */
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate#define	COPY_2								\
927c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
937c478bd9Sstevel@tonic-gate	pushl	12(%ebp);	/* 2 */					\
947c478bd9Sstevel@tonic-gate	pushl	8(%ebp)		/* 1 */
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate#define	COPY_3								\
977c478bd9Sstevel@tonic-gate	pushl	16(%ebp);	/* 3 */					\
987c478bd9Sstevel@tonic-gate	pushl	12(%ebp);	/* 2 */					\
997c478bd9Sstevel@tonic-gate	pushl	8(%ebp)		/* 1 */
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_bind,	DOOR_BIND,	COPY_1)
1027c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_call,	DOOR_CALL,	COPY_2)
1037c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_create,	DOOR_CREATE,	COPY_3)
1047c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_getparam,	DOOR_GETPARAM,	COPY_3)
1057c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_info,	DOOR_INFO,	COPY_2)
1067c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_revoke,	DOOR_REVOKE,	COPY_1)
1077c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_setparam,	DOOR_SETPARAM,	COPY_3)
1087c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_ucred,	DOOR_UCRED,	COPY_1)
1097c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_unbind,	DOOR_UNBIND,	COPY_0)
1107c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_unref,	DOOR_UNREFSYS,	COPY_0)
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate/*
1137c478bd9Sstevel@tonic-gate * int
1147c478bd9Sstevel@tonic-gate * __door_return(
115915894efSMatt Barden *	void			*data_ptr,
1167c478bd9Sstevel@tonic-gate *	size_t			data_size,	(in bytes)
1177c478bd9Sstevel@tonic-gate *	door_return_desc_t	*door_ptr,	(holds returned desc info)
1187c478bd9Sstevel@tonic-gate *	caddr_t			stack_base,
1197c478bd9Sstevel@tonic-gate *	size_t			stack_size)
1207c478bd9Sstevel@tonic-gate */
1217c478bd9Sstevel@tonic-gate	ENTRY(__door_return)
1227c478bd9Sstevel@tonic-gate	movl	%esp, %edx		/ Save pointer to args
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate	pushl	%edi			/ save old %edi and %esi
1257c478bd9Sstevel@tonic-gate	pushl	%esi			/ and use them to hold the
1267c478bd9Sstevel@tonic-gate	movl	16(%edx), %esi		/ stack pointer and
1277c478bd9Sstevel@tonic-gate	movl	20(%edx), %edi		/ size.
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate	pushl	$DOOR_RETURN		/ syscall subcode
1307c478bd9Sstevel@tonic-gate	pushl	%edi			/ size of user stack
1317c478bd9Sstevel@tonic-gate	pushl	%esi			/ base of user stack
1327c478bd9Sstevel@tonic-gate	pushl	12(%edx)		/ desc arguments ptr
1337c478bd9Sstevel@tonic-gate	pushl	8(%edx)			/ data size
1347c478bd9Sstevel@tonic-gate	pushl	4(%edx)			/ data ptr
1357c478bd9Sstevel@tonic-gate	pushl	0(%edx)			/ dummy return PC
1367c478bd9Sstevel@tonic-gate
1377c478bd9Sstevel@tonic-gatedoor_restart:
1387c478bd9Sstevel@tonic-gate	SYSTRAP_RVAL1(door)
139c4ace179Sdm	jb	2f			/* errno is set */
1407c478bd9Sstevel@tonic-gate	/*
1417c478bd9Sstevel@tonic-gate	 * On return, we're serving a door_call.  Our stack looks like this:
1427c478bd9Sstevel@tonic-gate	 *
1437c478bd9Sstevel@tonic-gate	 *		descriptors (if any)
1447c478bd9Sstevel@tonic-gate	 *		data (if any)
1457c478bd9Sstevel@tonic-gate	 *	 sp->	struct door_results
1467c478bd9Sstevel@tonic-gate	 *
147915894efSMatt Barden	 * The stack will be aligned to 16 bytes; we must maintain that
148915894efSMatt Barden	 * alignment prior to any call instruction.
1497c478bd9Sstevel@tonic-gate	 * struct door_results has the arguments in place for the server proc,
1507c478bd9Sstevel@tonic-gate	 * so we just call it directly.
1517c478bd9Sstevel@tonic-gate	 */
1527c478bd9Sstevel@tonic-gate	movl	DOOR_SERVERS(%esp), %eax
1537c478bd9Sstevel@tonic-gate	andl	%eax, %eax	/* test nservers */
1547c478bd9Sstevel@tonic-gate	jg	1f
1557c478bd9Sstevel@tonic-gate	/*
1567c478bd9Sstevel@tonic-gate	 * this is the last server thread - call creation func for more
1577c478bd9Sstevel@tonic-gate	 */
1587c478bd9Sstevel@tonic-gate	movl	DOOR_INFO_PTR(%esp), %eax
159915894efSMatt Barden	subl	$12, %esp
1607c478bd9Sstevel@tonic-gate	pushl	%eax		/* door_info_t * */
16149b225e1SGavin Maltby	call	door_depletion_cb@PLT
162915894efSMatt Barden	addl	$16, %esp
1637c478bd9Sstevel@tonic-gate1:
1647c478bd9Sstevel@tonic-gate	/* Call the door server function now */
1657c478bd9Sstevel@tonic-gate	movl	DOOR_PC(%esp), %eax
1667c478bd9Sstevel@tonic-gate	call	*%eax
1677c478bd9Sstevel@tonic-gate	/* Exit the thread if we return here */
168915894efSMatt Barden	subl	$12, %esp
1697c478bd9Sstevel@tonic-gate	pushl	$0
1707257d1b4Sraf	call	_thrp_terminate
1717c478bd9Sstevel@tonic-gate	/* NOTREACHED */
172c4ace179Sdm2:
1737c478bd9Sstevel@tonic-gate	/*
1747c478bd9Sstevel@tonic-gate	 * Error during door_return call.  Repark the thread in the kernel if
1757c478bd9Sstevel@tonic-gate	 * the error code is EINTR (or ERESTART) and this lwp is still part
1767c478bd9Sstevel@tonic-gate	 * of the same process.
1777c478bd9Sstevel@tonic-gate	 *
1787c478bd9Sstevel@tonic-gate	 * If the error code is EINTR or ERESTART, our stack may have been
1797c478bd9Sstevel@tonic-gate	 * corrupted by a partial door call, so we refresh the system call
1807c478bd9Sstevel@tonic-gate	 * arguments.
1817c478bd9Sstevel@tonic-gate	 */
1827c478bd9Sstevel@tonic-gate	cmpl	$ERESTART, %eax		/* ERESTART is same as EINTR */
183c4ace179Sdm	jne	3f
1847c478bd9Sstevel@tonic-gate	movl	$EINTR, %eax
185c4ace179Sdm3:
1867c478bd9Sstevel@tonic-gate	cmpl	$EINTR, %eax		/* interrupted while waiting? */
187c4ace179Sdm	jne	4f			/* if not, return the error */
1887c478bd9Sstevel@tonic-gate	_prologue_
1898cd45542Sraf	call	getpid
1907c478bd9Sstevel@tonic-gate	movl	_daref_(door_create_pid), %edx
1917c478bd9Sstevel@tonic-gate	movl	0(%edx), %edx
1927c478bd9Sstevel@tonic-gate	_epilogue_
1937c478bd9Sstevel@tonic-gate	cmpl	%eax, %edx		/* same process? */
1947c478bd9Sstevel@tonic-gate	movl	$EINTR, %eax	/* if no, return EINTR (child of forkall) */
195c4ace179Sdm	jne	4f
1967c478bd9Sstevel@tonic-gate	movl	$0, 4(%esp)		/* clear arguments and restart */
1977c478bd9Sstevel@tonic-gate	movl	$0, 8(%esp)
1987c478bd9Sstevel@tonic-gate	movl	$0, 12(%esp)
1997c478bd9Sstevel@tonic-gate	movl	%esi, 16(%esp)		/* refresh sp */
2007c478bd9Sstevel@tonic-gate	movl	%edi, 20(%esp)		/* refresh ssize */
2017c478bd9Sstevel@tonic-gate	movl	$DOOR_RETURN, 24(%esp)	/* refresh syscall subcode */
2027c478bd9Sstevel@tonic-gate	jmp	door_restart
203c4ace179Sdm4:
2047c478bd9Sstevel@tonic-gate	/* Something bad happened during the door_return */
2057c478bd9Sstevel@tonic-gate	addl	$28, %esp
2067c478bd9Sstevel@tonic-gate	popl	%esi
2077c478bd9Sstevel@tonic-gate	popl	%edi
2087c478bd9Sstevel@tonic-gate	jmp	__cerror
2097c478bd9Sstevel@tonic-gate	SET_SIZE(__door_return)
210