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