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