Home | History | Annotate | Download | only in os
      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 2008 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/errno.h>
     29 #include <sys/systm.h>
     30 #include <sys/archsystm.h>
     31 #include <sys/privregs.h>
     32 #include <sys/exec.h>
     33 #include <sys/lwp.h>
     34 #include <sys/sem.h>
     35 #include <sys/brand.h>
     36 #include <sys/lx_brand.h>
     37 #include <sys/lx_pid.h>
     38 #include <sys/lx_futex.h>
     39 
     40 /* Linux specific functions and definitions */
     41 void lx_setrval(klwp_t *, int, int);
     42 void lx_exec();
     43 int lx_initlwp(klwp_t *);
     44 void lx_forklwp(klwp_t *, klwp_t *);
     45 void lx_exitlwp(klwp_t *);
     46 void lx_freelwp(klwp_t *);
     47 static void lx_save(klwp_t *);
     48 static void lx_restore(klwp_t *);
     49 extern void lx_ptrace_free(proc_t *);
     50 
     51 /*
     52  * Set the return code for the forked child, always zero
     53  */
     54 /*ARGSUSED*/
     55 void
     56 lx_setrval(klwp_t *lwp, int v1, int v2)
     57 {
     58 	lwptoregs(lwp)->r_r0 = 0;
     59 }
     60 
     61 /*
     62  * Reset process state on exec(2)
     63  */
     64 void
     65 lx_exec()
     66 {
     67 	klwp_t *lwp = ttolwp(curthread);
     68 	struct lx_lwp_data *lwpd = lwptolxlwp(lwp);
     69 	int err;
     70 
     71 	/*
     72 	 * There are two mutually exclusive special cases we need to
     73 	 * address.  First, if this was a native process prior to this
     74 	 * exec(), then this lwp won't have its brand-specific data
     75 	 * initialized and it won't be assigned a Linux PID yet.  Second,
     76 	 * if this was a multi-threaded Linux process and this lwp wasn't
     77 	 * the main lwp, then we need to make its Solaris and Linux PIDS
     78 	 * match.
     79 	 */
     80 	if (lwpd == NULL) {
     81 		err = lx_initlwp(lwp);
     82 		/*
     83 		 * Only possible failure from this routine should be an
     84 		 * inability to allocate a new PID.  Since single-threaded
     85 		 * processes don't need a new PID, we should never hit this
     86 		 * error.
     87 		 */
     88 		ASSERT(err == 0);
     89 		lwpd = lwptolxlwp(lwp);
     90 	} else if (curthread->t_tid != 1) {
     91 		lx_pid_reassign(curthread);
     92 	}
     93 
     94 	installctx(lwptot(lwp), lwp, lx_save, lx_restore, NULL, NULL, lx_save,
     95 	    NULL);
     96 
     97 	/*
     98 	 * clear out the tls array
     99 	 */
    100 	bzero(lwpd->br_tls, sizeof (lwpd->br_tls));
    101 
    102 	/*
    103 	 * reset the tls entries in the gdt
    104 	 */
    105 	kpreempt_disable();
    106 	lx_restore(lwp);
    107 	kpreempt_enable();
    108 }
    109 
    110 void
    111 lx_exitlwp(klwp_t *lwp)
    112 {
    113 	struct lx_lwp_data *lwpd = lwptolxlwp(lwp);
    114 	proc_t *p;
    115 	kthread_t *t;
    116 	sigqueue_t *sqp = NULL;
    117 	pid_t ppid;
    118 	id_t ptid;
    119 
    120 	if (lwpd == NULL)
    121 		return;		/* second time thru' */
    122 
    123 	if (lwpd->br_clear_ctidp != NULL) {
    124 		(void) suword32(lwpd->br_clear_ctidp, 0);
    125 		(void) lx_futex((uintptr_t)lwpd->br_clear_ctidp, FUTEX_WAKE, 1,
    126 		    NULL, NULL, 0);
    127 	}
    128 
    129 	if (lwpd->br_signal != 0) {
    130 		/*
    131 		 * The first thread in a process doesn't cause a signal to
    132 		 * be sent when it exits.  It was created by a fork(), not
    133 		 * a clone(), so the parent should get signalled when the
    134 		 * process exits.
    135 		 */
    136 		if (lwpd->br_ptid == -1)
    137 			goto free;
    138 
    139 		sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
    140 		/*
    141 		 * If br_ppid is 0, it means this is a CLONE_PARENT thread,
    142 		 * so the signal goes to the parent process - not to a
    143 		 * specific thread in this process.
    144 		 */
    145 		p = lwptoproc(lwp);
    146 		if (lwpd->br_ppid == 0) {
    147 			mutex_enter(&p->p_lock);
    148 			ppid = p->p_ppid;
    149 			t = NULL;
    150 		} else {
    151 			/*
    152 			 * If we have been reparented to init or if our
    153 			 * parent thread is gone, then nobody gets
    154 			 * signaled.
    155 			 */
    156 			if ((lx_lwp_ppid(lwp, &ppid, &ptid) == 1) ||
    157 			    (ptid == -1))
    158 				goto free;
    159 
    160 			mutex_enter(&pidlock);
    161 			if ((p = prfind(ppid)) == NULL || p->p_stat == SIDL) {
    162 				mutex_exit(&pidlock);
    163 				goto free;
    164 			}
    165 			mutex_enter(&p->p_lock);
    166 			mutex_exit(&pidlock);
    167 
    168 			if ((t = idtot(p, ptid)) == NULL) {
    169 				mutex_exit(&p->p_lock);
    170 				goto free;
    171 			}
    172 		}
    173 
    174 		sqp->sq_info.si_signo = lwpd->br_signal;
    175 		sqp->sq_info.si_code = lwpd->br_exitwhy;
    176 		sqp->sq_info.si_status = lwpd->br_exitwhat;
    177 		sqp->sq_info.si_pid = lwpd->br_pid;
    178 		sqp->sq_info.si_uid = crgetruid(CRED());
    179 		sigaddqa(p, t, sqp);
    180 		mutex_exit(&p->p_lock);
    181 		sqp = NULL;
    182 	}
    183 
    184 free:
    185 	if (sqp)
    186 		kmem_free(sqp, sizeof (sigqueue_t));
    187 
    188 	lx_freelwp(lwp);
    189 }
    190 
    191 void
    192 lx_freelwp(klwp_t *lwp)
    193 {
    194 	struct lx_lwp_data *lwpd = lwptolxlwp(lwp);
    195 
    196 	if (lwpd != NULL) {
    197 		(void) removectx(lwptot(lwp), lwp, lx_save, lx_restore,
    198 		    NULL, NULL, lx_save, NULL);
    199 		if (lwpd->br_pid != 0)
    200 			lx_pid_rele(lwptoproc(lwp)->p_pid,
    201 			    lwptot(lwp)->t_tid);
    202 
    203 		lwp->lwp_brand = NULL;
    204 		kmem_free(lwpd, sizeof (struct lx_lwp_data));
    205 	}
    206 }
    207 
    208 int
    209 lx_initlwp(klwp_t *lwp)
    210 {
    211 	struct lx_lwp_data *lwpd;
    212 	struct lx_lwp_data *plwpd;
    213 	kthread_t *tp = lwptot(lwp);
    214 
    215 	lwpd = kmem_zalloc(sizeof (struct lx_lwp_data), KM_SLEEP);
    216 	lwpd->br_exitwhy = CLD_EXITED;
    217 	lwpd->br_lwp = lwp;
    218 	lwpd->br_clear_ctidp = NULL;
    219 	lwpd->br_set_ctidp = NULL;
    220 	lwpd->br_signal = 0;
    221 	/*
    222 	 * lwpd->br_affinitymask was zeroed by kmem_zalloc().
    223 	 */
    224 
    225 	/*
    226 	 * The first thread in a process has ppid set to the parent
    227 	 * process's pid, and ptid set to -1.  Subsequent threads in the
    228 	 * process have their ppid set to the pid of the thread that
    229 	 * created them, and their ptid to that thread's tid.
    230 	 */
    231 	if (tp->t_next == tp) {
    232 		lwpd->br_ppid = tp->t_procp->p_ppid;
    233 		lwpd->br_ptid = -1;
    234 	} else if (ttolxlwp(curthread) != NULL) {
    235 		plwpd = ttolxlwp(curthread);
    236 		bcopy(plwpd->br_tls, lwpd->br_tls, sizeof (lwpd->br_tls));
    237 		lwpd->br_ppid = plwpd->br_pid;
    238 		lwpd->br_ptid = curthread->t_tid;
    239 	} else {
    240 		/*
    241 		 * Oddball case: the parent thread isn't a Linux process.
    242 		 */
    243 		lwpd->br_ppid = 0;
    244 		lwpd->br_ptid = -1;
    245 	}
    246 	lwp->lwp_brand = lwpd;
    247 
    248 	if (lx_pid_assign(tp)) {
    249 		kmem_free(lwpd, sizeof (struct lx_lwp_data));
    250 		lwp->lwp_brand = NULL;
    251 		return (-1);
    252 	}
    253 	lwpd->br_tgid = lwpd->br_pid;
    254 
    255 	installctx(lwptot(lwp), lwp, lx_save, lx_restore, NULL, NULL,
    256 	    lx_save, NULL);
    257 
    258 	return (0);
    259 }
    260 
    261 /*
    262  * There is no need to have any locking for either the source or
    263  * destination struct lx_lwp_data structs.  This is always run in the
    264  * thread context of the source thread, and the destination thread is
    265  * always newly created and not referred to from anywhere else.
    266  */
    267 void
    268 lx_forklwp(klwp_t *srclwp, klwp_t *dstlwp)
    269 {
    270 	struct lx_lwp_data *src = srclwp->lwp_brand;
    271 	struct lx_lwp_data *dst = dstlwp->lwp_brand;
    272 
    273 	dst->br_ppid = src->br_pid;
    274 	dst->br_ptid = lwptot(srclwp)->t_tid;
    275 	bcopy(src->br_tls, dst->br_tls, sizeof (dst->br_tls));
    276 
    277 	/*
    278 	 * copy only these flags
    279 	 */
    280 	dst->br_lwp_flags = src->br_lwp_flags & BR_CPU_BOUND;
    281 	dst->br_clone_args = NULL;
    282 }
    283 
    284 /*
    285  * When switching a Linux process off the CPU, clear its GDT entries.
    286  */
    287 /* ARGSUSED */
    288 static void
    289 lx_save(klwp_t *t)
    290 {
    291 	int i;
    292 
    293 #if defined(__amd64)
    294 	reset_sregs();
    295 #endif
    296 	for (i = 0; i < LX_TLSNUM; i++)
    297 		gdt_update_usegd(GDT_TLSMIN + i, &null_udesc);
    298 }
    299 
    300 /*
    301  * When switching a Linux process on the CPU, set its GDT entries.
    302  */
    303 static void
    304 lx_restore(klwp_t *t)
    305 {
    306 	struct lx_lwp_data *lwpd = lwptolxlwp(t);
    307 	user_desc_t *tls;
    308 	int i;
    309 
    310 	ASSERT(lwpd);
    311 
    312 	tls = lwpd->br_tls;
    313 	for (i = 0; i < LX_TLSNUM; i++)
    314 		gdt_update_usegd(GDT_TLSMIN + i, &tls[i]);
    315 }
    316 
    317 void
    318 lx_set_gdt(int entry, user_desc_t *descrp)
    319 {
    320 
    321 	gdt_update_usegd(entry, descrp);
    322 }
    323 
    324 void
    325 lx_clear_gdt(int entry)
    326 {
    327 	gdt_update_usegd(entry, &null_udesc);
    328 }
    329 
    330 longlong_t
    331 lx_nosys()
    332 {
    333 	return (set_errno(ENOSYS));
    334 }
    335 
    336 longlong_t
    337 lx_opnotsupp()
    338 {
    339 	return (set_errno(EOPNOTSUPP));
    340 }
    341 
    342 /*
    343  * Brand-specific routine to check if given non-Solaris standard segment
    344  * register values should be used as-is or if they should be modified to other
    345  * values.
    346  */
    347 /*ARGSUSED*/
    348 greg_t
    349 lx_fixsegreg(greg_t sr, model_t datamodel)
    350 {
    351 	struct lx_lwp_data *lxlwp = ttolxlwp(curthread);
    352 
    353 	/*
    354 	 * If the segreg is the same as the %gs the brand callback was last
    355 	 * entered with, allow it to be used unmodified.
    356 	 */
    357 	ASSERT(sr == (sr & 0xffff));
    358 
    359 	if (sr == (lxlwp->br_ugs & 0xffff))
    360 		return (sr);
    361 
    362 	/*
    363 	 * Force the SR into the LDT in ring 3 for 32-bit processes.
    364 	 *
    365 	 * 64-bit processes get the null GDT selector since they are not
    366 	 * allowed to have a private LDT.
    367 	 */
    368 #if defined(__amd64)
    369 	return (datamodel == DATAMODEL_ILP32 ? (sr | SEL_TI_LDT | SEL_UPL) : 0);
    370 #elif defined(__i386)
    371 	datamodel = datamodel;  /* datamodel currently unused for 32-bit */
    372 	return (sr | SEL_TI_LDT | SEL_UPL);
    373 #endif	/* __amd64 */
    374 }
    375