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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29 .file "%M%" 30 31#include "SYS.h" 32#include <sys/door.h> 33 34 /* 35 * weak aliases for public interfaces 36 */ 37 ANSI_PRAGMA_WEAK2(door_bind,__door_bind,function) 38 ANSI_PRAGMA_WEAK2(door_getparam,__door_getparam,function) 39 ANSI_PRAGMA_WEAK2(door_info,__door_info,function) 40 ANSI_PRAGMA_WEAK2(door_revoke,__door_revoke,function) 41 ANSI_PRAGMA_WEAK2(door_setparam,__door_setparam,function) 42 ANSI_PRAGMA_WEAK2(door_unbind,__door_unbind,function) 43 44/* 45 * Offsets within struct door_results 46 */ 47#define DOOR_COOKIE _MUL(0, CLONGSIZE) 48#define DOOR_DATA_PTR _MUL(1, CLONGSIZE) 49#define DOOR_DATA_SIZE _MUL(2, CLONGSIZE) 50#define DOOR_DESC_PTR _MUL(3, CLONGSIZE) 51#define DOOR_DESC_SIZE _MUL(4, CLONGSIZE) 52#define DOOR_PC _MUL(5, CLONGSIZE) 53#define DOOR_SERVERS _MUL(6, CLONGSIZE) 54#define DOOR_INFO_PTR _MUL(7, CLONGSIZE) 55 56/* 57 * All of the syscalls except door_return() follow the same pattern. 58 * The subcode goes in argument 6, which means we have to copy our 59 * arguments into a new bit of stack, large enough to include the 60 * subcode. We fill the unused positions with zeros. 61 */ 62#define DOOR_SYSCALL(name, code, copy_args) \ 63 ENTRY(name); \ 64 pushl %ebp; \ 65 movl %esp, %ebp; \ 66 pushl $code; /* syscall subcode, arg 6 */ \ 67 pushl $0; /* dummy arg 5 */ \ 68 pushl $0; /* dummy arg 4 */ \ 69 copy_args; /* args 1, 2, 3 */ \ 70 pushl $0; /* dummy return PC */ \ 71 SYSTRAP_RVAL1(door); \ 72 jae 1f; \ 73 addl $28, %esp; \ 74 leave; \ 75 jmp __cerror; \ 761: \ 77 addl $28, %esp; \ 78 leave; \ 79 ret; \ 80 SET_SIZE(name) 81 82#define COPY_0 \ 83 pushl $0; /* dummy */ \ 84 pushl $0; /* dummy */ \ 85 pushl $0 /* dummy */ 86 87#define COPY_1 \ 88 pushl $0; /* dummy */ \ 89 pushl $0; /* dummy */ \ 90 pushl 8(%ebp) /* 1 */ 91 92#define COPY_2 \ 93 pushl $0; /* dummy */ \ 94 pushl 12(%ebp); /* 2 */ \ 95 pushl 8(%ebp) /* 1 */ 96 97#define COPY_3 \ 98 pushl 16(%ebp); /* 3 */ \ 99 pushl 12(%ebp); /* 2 */ \ 100 pushl 8(%ebp) /* 1 */ 101 102 DOOR_SYSCALL(__door_bind, DOOR_BIND, COPY_1) 103 DOOR_SYSCALL(__door_call, DOOR_CALL, COPY_2) 104 DOOR_SYSCALL(__door_create, DOOR_CREATE, COPY_3) 105 DOOR_SYSCALL(__door_getparam, DOOR_GETPARAM, COPY_3) 106 DOOR_SYSCALL(__door_info, DOOR_INFO, COPY_2) 107 DOOR_SYSCALL(__door_revoke, DOOR_REVOKE, COPY_1) 108 DOOR_SYSCALL(__door_setparam, DOOR_SETPARAM, COPY_3) 109 DOOR_SYSCALL(__door_ucred, DOOR_UCRED, COPY_1) 110 DOOR_SYSCALL(__door_unbind, DOOR_UNBIND, COPY_0) 111 DOOR_SYSCALL(__door_unref, DOOR_UNREFSYS, COPY_0) 112 113/* 114 * int 115 * __door_return( 116 * void *data_ptr, 117 * size_t data_size, (in bytes) 118 * door_return_desc_t *door_ptr, (holds returned desc info) 119 * caddr_t stack_base, 120 * size_t stack_size) 121 */ 122 ENTRY(__door_return) 123 movl %esp, %edx / Save pointer to args 124 125 pushl %edi / save old %edi and %esi 126 pushl %esi / and use them to hold the 127 movl 16(%edx), %esi / stack pointer and 128 movl 20(%edx), %edi / size. 129 130 pushl $DOOR_RETURN / syscall subcode 131 pushl %edi / size of user stack 132 pushl %esi / base of user stack 133 pushl 12(%edx) / desc arguments ptr 134 pushl 8(%edx) / data size 135 pushl 4(%edx) / data ptr 136 pushl 0(%edx) / dummy return PC 137 138door_restart: 139 SYSTRAP_RVAL1(door) 140 jb 2f /* errno is set */ 141 /* 142 * On return, we're serving a door_call. Our stack looks like this: 143 * 144 * descriptors (if any) 145 * data (if any) 146 * sp-> struct door_results 147 * 148 * struct door_results has the arguments in place for the server proc, 149 * so we just call it directly. 150 */ 151 movl DOOR_SERVERS(%esp), %eax 152 andl %eax, %eax /* test nservers */ 153 jg 1f 154 /* 155 * this is the last server thread - call creation func for more 156 */ 157 movl DOOR_INFO_PTR(%esp), %eax 158 _prologue_ 159 pushl %eax /* door_info_t * */ 160 movl _daref_(door_server_func), %eax 161 movl 0(%eax), %eax 162 call *%eax /* call create function */ 163 addl $4, %esp 164 _epilogue_ 1651: 166 /* Call the door server function now */ 167 movl DOOR_PC(%esp), %eax 168 call *%eax 169 /* Exit the thread if we return here */ 170 pushl $0 171 call _thrp_terminate 172 /* NOTREACHED */ 1732: 174 /* 175 * Error during door_return call. Repark the thread in the kernel if 176 * the error code is EINTR (or ERESTART) and this lwp is still part 177 * of the same process. 178 * 179 * If the error code is EINTR or ERESTART, our stack may have been 180 * corrupted by a partial door call, so we refresh the system call 181 * arguments. 182 */ 183 cmpl $ERESTART, %eax /* ERESTART is same as EINTR */ 184 jne 3f 185 movl $EINTR, %eax 1863: 187 cmpl $EINTR, %eax /* interrupted while waiting? */ 188 jne 4f /* if not, return the error */ 189 _prologue_ 190 call getpid 191 movl _daref_(door_create_pid), %edx 192 movl 0(%edx), %edx 193 _epilogue_ 194 cmpl %eax, %edx /* same process? */ 195 movl $EINTR, %eax /* if no, return EINTR (child of forkall) */ 196 jne 4f 197 198 movl $0, 4(%esp) /* clear arguments and restart */ 199 movl $0, 8(%esp) 200 movl $0, 12(%esp) 201 movl %esi, 16(%esp) /* refresh sp */ 202 movl %edi, 20(%esp) /* refresh ssize */ 203 movl $DOOR_RETURN, 24(%esp) /* refresh syscall subcode */ 204 jmp door_restart 2054: 206 /* Something bad happened during the door_return */ 207 addl $28, %esp 208 popl %esi 209 popl %edi 210 jmp __cerror 211 SET_SIZE(__door_return) 212