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 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 	.file	"door.s"
     28 
     29 #include "SYS.h"
     30 #include <sys/door.h>
     31 
     32 	/*
     33 	 * weak aliases for public interfaces
     34 	 */
     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)
     40 	ANSI_PRAGMA_WEAK2(door_unbind,__door_unbind,function)
     41 
     42 /*
     43  * Offsets within struct door_results
     44  */
     45 #define	DOOR_COOKIE	_MUL(0, CLONGSIZE)
     46 #define	DOOR_DATA_PTR	_MUL(1, CLONGSIZE)
     47 #define	DOOR_DATA_SIZE	_MUL(2, CLONGSIZE)
     48 #define	DOOR_DESC_PTR	_MUL(3, CLONGSIZE)
     49 #define	DOOR_DESC_SIZE	_MUL(4, CLONGSIZE)
     50 #define	DOOR_PC		_MUL(5, CLONGSIZE)
     51 #define	DOOR_SERVERS	_MUL(6, CLONGSIZE)
     52 #define	DOOR_INFO_PTR	_MUL(7, CLONGSIZE)
     53 
     54 /*
     55  * All of the syscalls except door_return() follow the same pattern.  The
     56  * subcode goes in %r9, after all of the other arguments.
     57  */
     58 #define	DOOR_SYSCALL(name, code)					\
     59 	ENTRY(name);							\
     60 	movq	$code, %r9;		/* subcode */			\
     61 	SYSTRAP_RVAL1(door);						\
     62 	SYSCERROR;							\
     63 	RET;								\
     64 	SET_SIZE(name)
     65 
     66 	DOOR_SYSCALL(__door_bind,	DOOR_BIND)
     67 	DOOR_SYSCALL(__door_call,	DOOR_CALL)
     68 	DOOR_SYSCALL(__door_create,	DOOR_CREATE)
     69 	DOOR_SYSCALL(__door_getparam,	DOOR_GETPARAM)
     70 	DOOR_SYSCALL(__door_info,	DOOR_INFO)
     71 	DOOR_SYSCALL(__door_revoke,	DOOR_REVOKE)
     72 	DOOR_SYSCALL(__door_setparam,	DOOR_SETPARAM)
     73 	DOOR_SYSCALL(__door_ucred,	DOOR_UCRED)
     74 	DOOR_SYSCALL(__door_unbind,	DOOR_UNBIND)
     75 	DOOR_SYSCALL(__door_unref,	DOOR_UNREFSYS)
     76 
     77 /*
     78  * int
     79  * __door_return(
     80  *	void 			*data_ptr,
     81  *	size_t			data_size,	(in bytes)
     82  *	door_return_desc_t	*door_ptr,	(holds returned desc info)
     83  *	caddr_t			stack_base,
     84  *	size_t			stack_size)
     85  */
     86 	ENTRY(__door_return)
     87 	pushq	%rbp
     88 	movq	%rsp, %rbp
     89 	subq	$0x8, %rsp
     90 	/*
     91 	 * Save stack_base (arg4), since %rcx will be trashed if the syscall
     92 	 * returns via sysret
     93 	 */
     94 	movq	%rcx, -0x8(%rbp)
     95 
     96 door_restart:
     97 	movq	$DOOR_RETURN, %r9	/* subcode */
     98 	SYSTRAP_RVAL1(door)
     99 	jb	2f			/* errno is set */
    100 	/*
    101 	 * On return, we're serving a door_call.  Our stack looks like this:
    102 	 *
    103 	 *		descriptors (if any)
    104 	 *		data (if any)
    105 	 *	 sp->	struct door_results
    106 	 */
    107 	movl	DOOR_SERVERS(%rsp), %eax
    108 	andl	%eax, %eax	/* test nservers */
    109 	jg	1f
    110 	/*
    111 	 * this is the last server thread - call creation func for more
    112 	 */
    113 	movq	_daref_(door_server_func), %rax
    114 	movq	0(%rax), %rax
    115 	movq	DOOR_INFO_PTR(%rsp), %rdi
    116 	call	*%rax		/* call create function */
    117 1:
    118 	/* Call the door server function now */
    119 	movq	DOOR_COOKIE(%rsp), %rdi
    120 	movq	DOOR_DATA_PTR(%rsp), %rsi
    121 	movq	DOOR_DATA_SIZE(%rsp), %rdx
    122 	movq	DOOR_DESC_PTR(%rsp), %rcx
    123 	movq	DOOR_DESC_SIZE(%rsp), %r8
    124 	movq	DOOR_PC(%rsp), %rax
    125 	call	*%rax
    126 	/* Exit the thread if we return here */
    127 	movq	$0, %rdi
    128 	call	_thrp_terminate
    129 	/* NOTREACHED */
    130 2:
    131 	/*
    132 	 * Error during door_return call.  Repark the thread in the kernel if
    133 	 * the error code is EINTR (or ERESTART) and this lwp is still part
    134 	 * of the same process.
    135 	 */
    136 	cmpl	$ERESTART, %eax		/* ERESTART is same as EINTR */
    137 	jne	3f
    138 	movl	$EINTR, %eax
    139 3:
    140 	cmpl	$EINTR, %eax		/* interrupted while waiting? */
    141 	jne	4f			/* if not, return the error */
    142 
    143 	call	getpid			/* get current process id */
    144 	movq	_daref_(door_create_pid), %rdx
    145 	movl	0(%rdx), %edx
    146 	cmpl	%eax, %edx		/* same process? */
    147 	movl	$EINTR, %eax	/* if no, return EINTR (child of forkall) */
    148 	jne	4f
    149 
    150 	movq	$0, %rdi		/* clear arguments and restart */
    151 	movq	$0, %rsi
    152 	movq	$0, %rdx
    153 	movq	-0x8(%rbp), %rcx	/* Restore arg4 (stack_base) */
    154 	jmp	door_restart
    155 
    156 4:
    157 	leave
    158 	jmp	__cerror
    159 	SET_SIZE(__door_return)
    160