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 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/systm.h> 30 #include <sys/errno.h> 31 #include <sys/brand.h> 32 #include <sys/lx_brand.h> 33 #include <sys/lx_ldt.h> 34 35 #define LX_CSIGNAL 0x000000ff 36 #define LX_CLONE_VM 0x00000100 37 #define LX_CLONE_FS 0x00000200 38 #define LX_CLONE_FILES 0x00000400 39 #define LX_CLONE_SIGHAND 0x00000800 40 #define LX_CLONE_PID 0x00001000 41 #define LX_CLONE_PTRACE 0x00002000 42 #define LX_CLONE_PARENT 0x00008000 43 #define LX_CLONE_THREAD 0x00010000 44 #define LX_CLONE_SYSVSEM 0x00040000 45 #define LX_CLONE_SETTLS 0x00080000 46 #define LX_CLONE_PARENT_SETTID 0x00100000 47 #define LX_CLONE_CHILD_CLEARTID 0x00200000 48 #define LX_CLONE_DETACH 0x00400000 49 #define LX_CLONE_CHILD_SETTID 0x01000000 50 51 /* 52 * Our lwp has already been created at this point, so this routine is 53 * responsible for setting up all the state needed to track this as a 54 * linux cloned thread. 55 */ 56 /* ARGSUSED */ 57 long 58 lx_clone(int flags, void *stkp, void *ptidp, void *ldtinfo, void *ctidp) 59 { 60 struct lx_lwp_data *lwpd = ttolxlwp(curthread); 61 struct ldt_info info; 62 struct user_desc descr; 63 int tls_index; 64 int entry = -1; 65 int signo; 66 67 signo = flags & LX_CSIGNAL; 68 if (signo < 0 || signo > MAXSIG) 69 return (set_errno(EINVAL)); 70 71 if (flags & LX_CLONE_SETTLS) { 72 if (copyin((caddr_t)ldtinfo, &info, sizeof (info))) 73 return (set_errno(EFAULT)); 74 75 if (LDT_INFO_EMPTY(&info)) 76 return (set_errno(EINVAL)); 77 78 entry = info.entry_number; 79 if (entry < GDT_TLSMIN || entry > GDT_TLSMAX) 80 return (set_errno(EINVAL)); 81 82 tls_index = entry - GDT_TLSMIN; 83 84 /* 85 * Convert the user-space structure into a real x86 86 * descriptor and copy it into this LWP's TLS array. We 87 * also load it into the GDT. 88 */ 89 LDT_INFO_TO_DESC(&info, &descr); 90 bcopy(&descr, &lwpd->br_tls[tls_index], sizeof (descr)); 91 lx_set_gdt(entry, &lwpd->br_tls[tls_index]); 92 } else { 93 tls_index = -1; 94 bzero(&descr, sizeof (descr)); 95 } 96 97 lwpd->br_clear_ctidp = 98 (flags & LX_CLONE_CHILD_CLEARTID) ? ctidp : NULL; 99 100 if (signo && ! (flags & LX_CLONE_DETACH)) 101 lwpd->br_signal = signo; 102 else 103 lwpd->br_signal = 0; 104 105 if (flags & LX_CLONE_THREAD) 106 lwpd->br_tgid = curthread->t_procp->p_pid; 107 108 if (flags & LX_CLONE_PARENT) 109 lwpd->br_ppid = 0; 110 111 if ((flags & LX_CLONE_CHILD_SETTID) && (ctidp != NULL) && 112 (suword32(ctidp, lwpd->br_pid) != 0)) { 113 if (entry >= 0) 114 lx_clear_gdt(entry); 115 return (set_errno(EFAULT)); 116 } 117 if ((flags & LX_CLONE_PARENT_SETTID) && (ptidp != NULL) && 118 (suword32(ptidp, lwpd->br_pid) != 0)) { 119 if (entry >= 0) 120 lx_clear_gdt(entry); 121 return (set_errno(EFAULT)); 122 } 123 124 return (lwpd->br_pid); 125 } 126 127 long 128 lx_set_tid_address(int *tidp) 129 { 130 struct lx_lwp_data *lwpd = ttolxlwp(curthread); 131 132 lwpd->br_clear_ctidp = tidp; 133 134 return (lwpd->br_pid); 135 }