1e71ca95cSGerald Jelinek /*
2e71ca95cSGerald Jelinek  * CDDL HEADER START
3e71ca95cSGerald Jelinek  *
4e71ca95cSGerald Jelinek  * The contents of this file are subject to the terms of the
5e71ca95cSGerald Jelinek  * Common Development and Distribution License (the "License").
6e71ca95cSGerald Jelinek  * You may not use this file except in compliance with the License.
7e71ca95cSGerald Jelinek  *
8e71ca95cSGerald Jelinek  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e71ca95cSGerald Jelinek  * or http://www.opensolaris.org/os/licensing.
10e71ca95cSGerald Jelinek  * See the License for the specific language governing permissions
11e71ca95cSGerald Jelinek  * and limitations under the License.
12e71ca95cSGerald Jelinek  *
13e71ca95cSGerald Jelinek  * When distributing Covered Code, include this CDDL HEADER in each
14e71ca95cSGerald Jelinek  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15e71ca95cSGerald Jelinek  * If applicable, add the following below this CDDL HEADER, with the
16e71ca95cSGerald Jelinek  * fields enclosed by brackets "[]" replaced with your own identifying
17e71ca95cSGerald Jelinek  * information: Portions Copyright [yyyy] [name of copyright owner]
18e71ca95cSGerald Jelinek  *
19e71ca95cSGerald Jelinek  * CDDL HEADER END
20e71ca95cSGerald Jelinek  */
218fd04b83SRoger A. Faulkner 
22e71ca95cSGerald Jelinek /*
23b49b27dcSTheo Schlossnagle  * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
2480e2ca85S  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
25*4e18e297SPatrick Mooney  * Copyright 2019 Joyent, Inc.
26e71ca95cSGerald Jelinek  */
27e71ca95cSGerald Jelinek 
28e71ca95cSGerald Jelinek #include <sys/errno.h>
29e71ca95cSGerald Jelinek #include <sys/exec.h>
308b4cf837Sjv #include <sys/file.h>
31e71ca95cSGerald Jelinek #include <sys/kmem.h>
32e71ca95cSGerald Jelinek #include <sys/modctl.h>
33e71ca95cSGerald Jelinek #include <sys/model.h>
34e71ca95cSGerald Jelinek #include <sys/proc.h>
35e71ca95cSGerald Jelinek #include <sys/syscall.h>
36e71ca95cSGerald Jelinek #include <sys/systm.h>
37e71ca95cSGerald Jelinek #include <sys/thread.h>
38e71ca95cSGerald Jelinek #include <sys/cmn_err.h>
39e71ca95cSGerald Jelinek #include <sys/archsystm.h>
40e71ca95cSGerald Jelinek #include <sys/pathname.h>
41e71ca95cSGerald Jelinek #include <sys/sunddi.h>
42e71ca95cSGerald Jelinek 
43e71ca95cSGerald Jelinek #include <sys/machbrand.h>
44e71ca95cSGerald Jelinek #include <sys/brand.h>
45e71ca95cSGerald Jelinek #include "s10_brand.h"
46e71ca95cSGerald Jelinek 
47e71ca95cSGerald Jelinek char *s10_emulation_table = NULL;
48e71ca95cSGerald Jelinek 
49e71ca95cSGerald Jelinek void	s10_init_brand_data(zone_t *);
50e71ca95cSGerald Jelinek void	s10_free_brand_data(zone_t *);
51e71ca95cSGerald Jelinek void	s10_setbrand(proc_t *);
52e71ca95cSGerald Jelinek int	s10_getattr(zone_t *, int, void *, size_t *);
53e71ca95cSGerald Jelinek int	s10_setattr(zone_t *, int, void *, size_t);
54e71ca95cSGerald Jelinek int	s10_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
55e71ca95cSGerald Jelinek 		uintptr_t, uintptr_t, uintptr_t);
56e71ca95cSGerald Jelinek void	s10_copy_procdata(proc_t *, proc_t *);
57e71ca95cSGerald Jelinek void	s10_proc_exit(struct proc *, klwp_t *);
58e71ca95cSGerald Jelinek void	s10_exec();
59e71ca95cSGerald Jelinek int	s10_initlwp(klwp_t *);
60e71ca95cSGerald Jelinek void	s10_forklwp(klwp_t *, klwp_t *);
61e71ca95cSGerald Jelinek void	s10_freelwp(klwp_t *);
62e71ca95cSGerald Jelinek void	s10_lwpexit(klwp_t *);
63e71ca95cSGerald Jelinek int	s10_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
64*4e18e297SPatrick Mooney 		size_t *, int, caddr_t, cred_t *, int);
658f798d3aSRoger A. Faulkner void	s10_sigset_native_to_s10(sigset_t *);
668f798d3aSRoger A. Faulkner void	s10_sigset_s10_to_native(sigset_t *);
67e71ca95cSGerald Jelinek 
68e71ca95cSGerald Jelinek /* s10 brand */
69e71ca95cSGerald Jelinek struct brand_ops s10_brops = {
70e71ca95cSGerald Jelinek 	s10_init_brand_data,
71e71ca95cSGerald Jelinek 	s10_free_brand_data,
72e71ca95cSGerald Jelinek 	s10_brandsys,
73e71ca95cSGerald Jelinek 	s10_setbrand,
74e71ca95cSGerald Jelinek 	s10_getattr,
75e71ca95cSGerald Jelinek 	s10_setattr,
76e71ca95cSGerald Jelinek 	s10_copy_procdata,
77e71ca95cSGerald Jelinek 	s10_proc_exit,
78e71ca95cSGerald Jelinek 	s10_exec,
79e71ca95cSGerald Jelinek 	lwp_setrval,
80e71ca95cSGerald Jelinek 	s10_initlwp,
81e71ca95cSGerald Jelinek 	s10_forklwp,
82e71ca95cSGerald Jelinek 	s10_freelwp,
83e71ca95cSGerald Jelinek 	s10_lwpexit,
84eb9dbf0cSRoger A. Faulkner 	s10_elfexec,
858f798d3aSRoger A. Faulkner 	s10_sigset_native_to_s10,
868f798d3aSRoger A. Faulkner 	s10_sigset_s10_to_native,
878f798d3aSRoger A. Faulkner 	S10_NSIG,
88e71ca95cSGerald Jelinek };
89e71ca95cSGerald Jelinek 
90e71ca95cSGerald Jelinek #ifdef	sparc
91e71ca95cSGerald Jelinek 
92e71ca95cSGerald Jelinek struct brand_mach_ops s10_mops = {
93e71ca95cSGerald Jelinek 	s10_brand_syscall_callback,
94e71ca95cSGerald Jelinek 	s10_brand_syscall32_callback
95e71ca95cSGerald Jelinek };
96e71ca95cSGerald Jelinek 
97e71ca95cSGerald Jelinek #else	/* sparc */
98e71ca95cSGerald Jelinek 
99e71ca95cSGerald Jelinek #ifdef	__amd64
100e71ca95cSGerald Jelinek 
101e71ca95cSGerald Jelinek struct brand_mach_ops s10_mops = {
102e71ca95cSGerald Jelinek 	s10_brand_sysenter_callback,
103e71ca95cSGerald Jelinek 	s10_brand_int91_callback,
104e71ca95cSGerald Jelinek 	s10_brand_syscall_callback,
105eb5a5c78SSurya Prakki 	s10_brand_syscall32_callback
106e71ca95cSGerald Jelinek };
107e71ca95cSGerald Jelinek 
108e71ca95cSGerald Jelinek #else	/* ! __amd64 */
109e71ca95cSGerald Jelinek 
110e71ca95cSGerald Jelinek struct brand_mach_ops s10_mops = {
111e71ca95cSGerald Jelinek 	s10_brand_sysenter_callback,
112e71ca95cSGerald Jelinek 	NULL,
113e71ca95cSGerald Jelinek 	s10_brand_syscall_callback,
114e71ca95cSGerald Jelinek 	NULL
115e71ca95cSGerald Jelinek };
116e71ca95cSGerald Jelinek #endif	/* __amd64 */
117e71ca95cSGerald Jelinek 
118e71ca95cSGerald Jelinek #endif	/* _sparc */
119e71ca95cSGerald Jelinek 
120e71ca95cSGerald Jelinek struct brand	s10_brand = {
121e71ca95cSGerald Jelinek 	BRAND_VER_1,
122e71ca95cSGerald Jelinek 	"solaris10",
123e71ca95cSGerald Jelinek 	&s10_brops,
124e71ca95cSGerald Jelinek 	&s10_mops
125e71ca95cSGerald Jelinek };
126e71ca95cSGerald Jelinek 
127e71ca95cSGerald Jelinek static struct modlbrand modlbrand = {
128e71ca95cSGerald Jelinek 	&mod_brandops,		/* type of module */
129e71ca95cSGerald Jelinek 	"Solaris 10 Brand",	/* description of module */
130e71ca95cSGerald Jelinek 	&s10_brand		/* driver ops */
131e71ca95cSGerald Jelinek };
132e71ca95cSGerald Jelinek 
133e71ca95cSGerald Jelinek static struct modlinkage modlinkage = {
134e71ca95cSGerald Jelinek 	MODREV_1, (void *)&modlbrand, NULL
135e71ca95cSGerald Jelinek };
136e71ca95cSGerald Jelinek 
137e71ca95cSGerald Jelinek void
s10_setbrand(proc_t * p)138e71ca95cSGerald Jelinek s10_setbrand(proc_t *p)
139e71ca95cSGerald Jelinek {
14080e2ca85S 	brand_solaris_setbrand(p, &s10_brand);
141e71ca95cSGerald Jelinek }
142e71ca95cSGerald Jelinek 
143e71ca95cSGerald Jelinek /*ARGSUSED*/
144e71ca95cSGerald Jelinek int
s10_getattr(zone_t * zone,int attr,void * buf,size_t * bufsize)145e71ca95cSGerald Jelinek s10_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize)
146e71ca95cSGerald Jelinek {
147e71ca95cSGerald Jelinek 	ASSERT(zone->zone_brand == &s10_brand);
148ad601a05Sjv 	if (attr == S10_EMUL_BITMAP) {
149ad601a05Sjv 		if (buf == NULL || *bufsize != sizeof (s10_emul_bitmap_t))
150ad601a05Sjv 			return (EINVAL);
151ad601a05Sjv 		if (copyout(((s10_zone_data_t *)zone->zone_brand_data)->
152ad601a05Sjv 		    emul_bitmap, buf, sizeof (s10_emul_bitmap_t)) != 0)
153e71ca95cSGerald Jelinek 			return (EFAULT);
154e71ca95cSGerald Jelinek 		return (0);
155e71ca95cSGerald Jelinek 	}
156e71ca95cSGerald Jelinek 
157e71ca95cSGerald Jelinek 	return (EINVAL);
158e71ca95cSGerald Jelinek }
159e71ca95cSGerald Jelinek 
160e71ca95cSGerald Jelinek int
s10_setattr(zone_t * zone,int attr,void * buf,size_t bufsize)161e71ca95cSGerald Jelinek s10_setattr(zone_t *zone, int attr, void *buf, size_t bufsize)
162e71ca95cSGerald Jelinek {
163e71ca95cSGerald Jelinek 	ASSERT(zone->zone_brand == &s10_brand);
164ad601a05Sjv 	if (attr == S10_EMUL_BITMAP) {
165ad601a05Sjv 		if (buf == NULL || bufsize != sizeof (s10_emul_bitmap_t))
166ad601a05Sjv 			return (EINVAL);
167ad601a05Sjv 		if (copyin(buf, ((s10_zone_data_t *)zone->zone_brand_data)->
168ad601a05Sjv 		    emul_bitmap, sizeof (s10_emul_bitmap_t)) != 0)
169e71ca95cSGerald Jelinek 			return (EFAULT);
170e71ca95cSGerald Jelinek 		return (0);
171e71ca95cSGerald Jelinek 	}
172e71ca95cSGerald Jelinek 
173e71ca95cSGerald Jelinek 	return (EINVAL);
174e71ca95cSGerald Jelinek }
175e71ca95cSGerald Jelinek 
176e71ca95cSGerald Jelinek #ifdef	__amd64
177e71ca95cSGerald Jelinek /*
178e71ca95cSGerald Jelinek  * The Nevada kernel clears %fs for threads in 64-bit x86 processes but S10's
179e71ca95cSGerald Jelinek  * libc expects %fs to be nonzero.  This causes some committed
180e71ca95cSGerald Jelinek  * libc/libthread interfaces (e.g., thr_main()) to fail, which impacts several
181e71ca95cSGerald Jelinek  * libraries, including libdoor.  This function sets the specified LWP's %fs
182e71ca95cSGerald Jelinek  * register to the legacy S10 selector value (LWPFS_SEL).
183e71ca95cSGerald Jelinek  *
184e71ca95cSGerald Jelinek  * The best solution to the aforementioned problem is backporting CRs
185e71ca95cSGerald Jelinek  * 6467491 to Solaris 10 so that 64-bit x86 Solaris 10 processes
186e71ca95cSGerald Jelinek  * would accept zero for %fs.  Backporting the CRs is a requirement for running
187e71ca95cSGerald Jelinek  * S10 Containers in PV domUs because 64-bit Xen clears %fsbase when %fs is
188e71ca95cSGerald Jelinek  * nonzero.  Such behavior breaks 64-bit processes because Xen has to fetch the
189e71ca95cSGerald Jelinek  * FS segments' base addresses from the LWPs' GDTs, which are only capable of
190e71ca95cSGerald Jelinek  * 32-bit addressing.
191e71ca95cSGerald Jelinek  */
192e71ca95cSGerald Jelinek /*ARGSUSED*/
193e71ca95cSGerald Jelinek static void
s10_amd64_correct_fsreg(klwp_t * l)194e71ca95cSGerald Jelinek s10_amd64_correct_fsreg(klwp_t *l)
195e71ca95cSGerald Jelinek {
196e71ca95cSGerald Jelinek 	if (lwp_getdatamodel(l) == DATAMODEL_NATIVE) {
197e71ca95cSGerald Jelinek 		kpreempt_disable();
198e71ca95cSGerald Jelinek 		l->lwp_pcb.pcb_fs = LWPFS_SEL;
1994c28a617SRobert Mustacchi 		PCB_SET_UPDATE_SEGS(&l->lwp_pcb);
200e71ca95cSGerald Jelinek 		lwptot(l)->t_post_sys = 1;	/* Guarantee update_sregs() */
201e71ca95cSGerald Jelinek 		kpreempt_enable();
202e71ca95cSGerald Jelinek 	}
203e71ca95cSGerald Jelinek }
204e71ca95cSGerald Jelinek #endif	/* __amd64 */
205e71ca95cSGerald Jelinek 
206be614d1fS /*
207c94e9df5S  * Native processes are started with the native ld.so.1 as the command.  This
208c94e9df5S  * brand op is invoked by s10_npreload to fix up the command and arguments
209c94e9df5S  * so that apps like pgrep or ps see the expected command strings.
210be614d1fS  */
211e71ca95cSGerald Jelinek int
s10_native(void * cmd,void * args)212c94e9df5S s10_native(void *cmd, void *args)
213e71ca95cSGerald Jelinek {
214e71ca95cSGerald Jelinek 	struct user	*up = PTOU(curproc);
215c94e9df5S 	char		cmd_buf[MAXCOMLEN + 1];
216c94e9df5S 	char		arg_buf[PSARGSZ];
217e71ca95cSGerald Jelinek 
218c94e9df5S 	if (copyin(cmd, &cmd_buf, sizeof (cmd_buf)) != 0)
219c94e9df5S 		return (EFAULT);
220c94e9df5S 	if (copyin(args, &arg_buf, sizeof (arg_buf)) != 0)
221c94e9df5S 		return (EFAULT);
222e71ca95cSGerald Jelinek 
223e71ca95cSGerald Jelinek 	/*
224e71ca95cSGerald Jelinek 	 * Make sure that the process' interpreter is the native dynamic linker.
225e71ca95cSGerald Jelinek 	 * Convention dictates that native processes executing within solaris10-
226e71ca95cSGerald Jelinek 	 * branded zones are interpreted by the native dynamic linker (the
227e71ca95cSGerald Jelinek 	 * process and its arguments are specified as arguments to the dynamic
228e71ca95cSGerald Jelinek 	 * linker).  If this convention is violated (i.e.,
229e71ca95cSGerald Jelinek 	 * brandsys(B_S10_NATIVE, ...) is invoked by a process that shouldn't be
230e71ca95cSGerald Jelinek 	 * native), then do nothing and silently indicate success.
231e71ca95cSGerald Jelinek 	 */
232e71ca95cSGerald Jelinek 	if (strcmp(up->u_comm, S10_LINKER_NAME) != 0)
233e71ca95cSGerald Jelinek 		return (0);
234c94e9df5S 
235c94e9df5S 	/*
236c94e9df5S 	 * The sizeof has an extra value for the trailing '\0' so this covers
237c94e9df5S 	 * the appended " " in the following strcmps.
238c94e9df5S 	 */
239c94e9df5S 	if (strncmp(up->u_psargs, BRAND_NATIVE_LINKER64 " ",
240c94e9df5S 	    sizeof (BRAND_NATIVE_LINKER64)) != 0 &&
241c94e9df5S 	    strncmp(up->u_psargs, BRAND_NATIVE_LINKER32 " ",
242c94e9df5S 	    sizeof (BRAND_NATIVE_LINKER32)) != 0)
243e71ca95cSGerald Jelinek 		return (0);
244e71ca95cSGerald Jelinek 
245c94e9df5S 	mutex_enter(&curproc->p_lock);
246c94e9df5S 	(void) strlcpy(up->u_comm, cmd_buf, sizeof (up->u_comm));
247c94e9df5S 	(void) strlcpy(up->u_psargs, arg_buf, sizeof (up->u_psargs));
248c94e9df5S 	mutex_exit(&curproc->p_lock);
249e71ca95cSGerald Jelinek 
250e71ca95cSGerald Jelinek 	return (0);
251e71ca95cSGerald Jelinek }
252e71ca95cSGerald Jelinek 
253e71ca95cSGerald Jelinek /*ARGSUSED*/
254e71ca95cSGerald Jelinek int
s10_brandsys(int cmd,int64_t * rval,uintptr_t arg1,uintptr_t arg2,uintptr_t arg3,uintptr_t arg4,uintptr_t arg5,uintptr_t arg6)255e71ca95cSGerald Jelinek s10_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
256e71ca95cSGerald Jelinek     uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
257e71ca95cSGerald Jelinek {
25880e2ca85S 	proc_t	*p = curproc;
25980e2ca85S 	int	res;
260e71ca95cSGerald Jelinek 
261e71ca95cSGerald Jelinek 	*rval = 0;
262e71ca95cSGerald Jelinek 
263e71ca95cSGerald Jelinek 	if (cmd == B_S10_NATIVE)
264c94e9df5S 		return (s10_native((void *)arg1, (void *)arg2));
265e71ca95cSGerald Jelinek 
26680e2ca85S 	res = brand_solaris_cmd(cmd, arg1, arg2, arg3, &s10_brand, S10_VERSION);
26780e2ca85S 	if (res >= 0)
26880e2ca85S 		return (res);
269e71ca95cSGerald Jelinek 
27080e2ca85S 	switch ((cmd)) {
271e71ca95cSGerald Jelinek 	case B_S10_PIDINFO:
272e71ca95cSGerald Jelinek 		/*
273e71ca95cSGerald Jelinek 		 * The s10 brand needs to be able to get the pid of the
274e71ca95cSGerald Jelinek 		 * current process and the pid of the zone's init, and it
275e71ca95cSGerald Jelinek 		 * needs to do this on every process startup.  Early in
276e71ca95cSGerald Jelinek 		 * brand startup, we can't call getpid() because calls to
277e71ca95cSGerald Jelinek 		 * getpid() represent a magical signal to some old-skool
278e71ca95cSGerald Jelinek 		 * debuggers.  By merging all of this into one call, we
279e71ca95cSGerald Jelinek 		 * make this quite a bit cheaper and easier to handle in
280e71ca95cSGerald Jelinek 		 * the brand module.
281e71ca95cSGerald Jelinek 		 */
282e71ca95cSGerald Jelinek 		if (copyout(&p->p_pid, (void *)arg1, sizeof (pid_t)) != 0)
283e71ca95cSGerald Jelinek 			return (EFAULT);
284e71ca95cSGerald Jelinek 		if (copyout(&p->p_zone->zone_proc_initpid, (void *)arg2,
285e71ca95cSGerald Jelinek 		    sizeof (pid_t)) != 0)
286e71ca95cSGerald Jelinek 			return (EFAULT);
287e71ca95cSGerald Jelinek 		return (0);
288e71ca95cSGerald Jelinek 
2898b4cf837Sjv 	case B_S10_ISFDXATTRDIR: {
2908b4cf837Sjv 		/*
2918b4cf837Sjv 		 * This subcommand enables the userland brand emulation library
2928b4cf837Sjv 		 * to determine whether a file descriptor refers to an extended
2938b4cf837Sjv 		 * file attributes directory.  There is no standard syscall or
2948b4cf837Sjv 		 * libc function that can make such a determination.
2958b4cf837Sjv 		 */
2968b4cf837Sjv 		file_t *dir_filep;
2978b4cf837Sjv 
2988b4cf837Sjv 		dir_filep = getf((int)arg1);
2998b4cf837Sjv 		if (dir_filep == NULL)
3008b4cf837Sjv 			return (EBADF);
3018b4cf837Sjv 		ASSERT(dir_filep->f_vnode != NULL);
3028b4cf837Sjv 		*rval = IS_XATTRDIR(dir_filep->f_vnode);
3038b4cf837Sjv 		releasef((int)arg1);
3048b4cf837Sjv 		return (0);
3058b4cf837Sjv 	}
3068b4cf837Sjv 
307e71ca95cSGerald Jelinek #ifdef	__amd64
308e71ca95cSGerald Jelinek 	case B_S10_FSREGCORRECTION:
309e71ca95cSGerald Jelinek 		/*
310e71ca95cSGerald Jelinek 		 * This subcommand exists so that the SYS_lwp_private and
311e71ca95cSGerald Jelinek 		 * SYS_lwp_create syscalls can manually set the current thread's
312e71ca95cSGerald Jelinek 		 * %fs register to the legacy S10 selector value for 64-bit x86
313e71ca95cSGerald Jelinek 		 * processes.
314e71ca95cSGerald Jelinek 		 */
315e71ca95cSGerald Jelinek 		s10_amd64_correct_fsreg(ttolwp(curthread));
316e71ca95cSGerald Jelinek 		return (0);
317e71ca95cSGerald Jelinek #endif	/* __amd64 */
318e71ca95cSGerald Jelinek 	}
319e71ca95cSGerald Jelinek 
320e71ca95cSGerald Jelinek 	return (EINVAL);
321e71ca95cSGerald Jelinek }
322e71ca95cSGerald Jelinek 
323e71ca95cSGerald Jelinek void
s10_copy_procdata(proc_t * child,proc_t * parent)324e71ca95cSGerald Jelinek s10_copy_procdata(proc_t *child, proc_t *parent)
325e71ca95cSGerald Jelinek {
32680e2ca85S 	brand_solaris_copy_procdata(child, parent, &s10_brand);
327e71ca95cSGerald Jelinek }
328e71ca95cSGerald Jelinek 
329e71ca95cSGerald Jelinek void
s10_proc_exit(struct proc * p,klwp_t * l)330e71ca95cSGerald Jelinek s10_proc_exit(struct proc *p, klwp_t *l)
331e71ca95cSGerald Jelinek {
33280e2ca85S 	brand_solaris_proc_exit(p, l, &s10_brand);
333e71ca95cSGerald Jelinek }
334e71ca95cSGerald Jelinek 
335e71ca95cSGerald Jelinek void
s10_exec()336e71ca95cSGerald Jelinek s10_exec()
337e71ca95cSGerald Jelinek {
33880e2ca85S 	brand_solaris_exec(&s10_brand);
339e71ca95cSGerald Jelinek }
340e71ca95cSGerald Jelinek 
341e71ca95cSGerald Jelinek int
s10_initlwp(klwp_t * l)342e71ca95cSGerald Jelinek s10_initlwp(klwp_t *l)
343e71ca95cSGerald Jelinek {
34480e2ca85S 	return (brand_solaris_initlwp(l, &s10_brand));
345e71ca95cSGerald Jelinek }
346e71ca95cSGerald Jelinek 
347e71ca95cSGerald Jelinek void
s10_forklwp(klwp_t * p,klwp_t * c)348e71ca95cSGerald Jelinek s10_forklwp(klwp_t *p, klwp_t *c)
349e71ca95cSGerald Jelinek {
35080e2ca85S 	brand_solaris_forklwp(p, c, &s10_brand);
351e71ca95cSGerald Jelinek 
352e71ca95cSGerald Jelinek #ifdef	__amd64
353e71ca95cSGerald Jelinek 	/*
354e71ca95cSGerald Jelinek 	 * Only correct the child's %fs register if the parent's %fs register
355e71ca95cSGerald Jelinek 	 * is LWPFS_SEL.  If the parent's %fs register is zero, then the Solaris
356e71ca95cSGerald Jelinek 	 * 10 environment that we're emulating uses a version of libc that
357e71ca95cSGerald Jelinek 	 * works when %fs is zero (i.e., it contains backports of CRs 6467491
358e71ca95cSGerald Jelinek 	 * and 6501650).
359e71ca95cSGerald Jelinek 	 */
360e71ca95cSGerald Jelinek 	if (p->lwp_pcb.pcb_fs == LWPFS_SEL)
361e71ca95cSGerald Jelinek 		s10_amd64_correct_fsreg(c);
362e71ca95cSGerald Jelinek #endif	/* __amd64 */
363e71ca95cSGerald Jelinek }
364e71ca95cSGerald Jelinek 
365e71ca95cSGerald Jelinek void
s10_freelwp(klwp_t * l)366e71ca95cSGerald Jelinek s10_freelwp(klwp_t *l)
367e71ca95cSGerald Jelinek {
36880e2ca85S 	brand_solaris_freelwp(l, &s10_brand);
369e71ca95cSGerald Jelinek }
370e71ca95cSGerald Jelinek 
371e71ca95cSGerald Jelinek void
s10_lwpexit(klwp_t * l)372e71ca95cSGerald Jelinek s10_lwpexit(klwp_t *l)
373e71ca95cSGerald Jelinek {
37480e2ca85S 	brand_solaris_lwpexit(l, &s10_brand);
375e71ca95cSGerald Jelinek }
376e71ca95cSGerald Jelinek 
377e71ca95cSGerald Jelinek void
s10_free_brand_data(zone_t * zone)378e71ca95cSGerald Jelinek s10_free_brand_data(zone_t *zone)
379e71ca95cSGerald Jelinek {
380e71ca95cSGerald Jelinek 	kmem_free(zone->zone_brand_data, sizeof (s10_zone_data_t));
381e71ca95cSGerald Jelinek }
382e71ca95cSGerald Jelinek 
383e71ca95cSGerald Jelinek void
s10_init_brand_data(zone_t * zone)384e71ca95cSGerald Jelinek s10_init_brand_data(zone_t *zone)
385e71ca95cSGerald Jelinek {
386e71ca95cSGerald Jelinek 	ASSERT(zone->zone_brand == &s10_brand);
387e71ca95cSGerald Jelinek 	ASSERT(zone->zone_brand_data == NULL);
388ad601a05Sjv 	zone->zone_brand_data = kmem_zalloc(sizeof (s10_zone_data_t), KM_SLEEP);
389e71ca95cSGerald Jelinek }
390e71ca95cSGerald Jelinek 
391e71ca95cSGerald Jelinek int
s10_elfexec(vnode_t * vp,execa_t * uap,uarg_t * args,intpdata_t * idatap,int level,size_t * execsz,int setid,caddr_t exec_file,cred_t * cred,int brand_action)392e71ca95cSGerald Jelinek s10_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
393*4e18e297SPatrick Mooney     int level, size_t *execsz, int setid, caddr_t exec_file, cred_t *cred,
394*4e18e297SPatrick Mooney     int brand_action)
395e71ca95cSGerald Jelinek {
39680e2ca85S 	return (brand_solaris_elfexec(vp, uap, args, idatap, level, execsz,
39780e2ca85S 	    setid, exec_file, cred, brand_action, &s10_brand, S10_BRANDNAME,
39880e2ca85S 	    S10_LIB, S10_LIB32, S10_LINKER, S10_LINKER32));
399e71ca95cSGerald Jelinek }
400e71ca95cSGerald Jelinek 
4018f798d3aSRoger A. Faulkner void
s10_sigset_native_to_s10(sigset_t * set)4028f798d3aSRoger A. Faulkner s10_sigset_native_to_s10(sigset_t *set)
4038f798d3aSRoger A. Faulkner {
4048f798d3aSRoger A. Faulkner 	int nativesig;
4058f798d3aSRoger A. Faulkner 	int s10sig;
4068f798d3aSRoger A. Faulkner 	sigset_t s10set;
4078f798d3aSRoger A. Faulkner 
4088f798d3aSRoger A. Faulkner 	/*
4098f798d3aSRoger A. Faulkner 	 * Shortcut: we know the first 32 signals are the same in both
4108f798d3aSRoger A. Faulkner 	 * s10 and native Solaris.  Just assign the first word.
4118f798d3aSRoger A. Faulkner 	 */
4128f798d3aSRoger A. Faulkner 	s10set.__sigbits[0] = set->__sigbits[0];
4138f798d3aSRoger A. Faulkner 	s10set.__sigbits[1] = 0;
4148f798d3aSRoger A. Faulkner 	s10set.__sigbits[2] = 0;
4158f798d3aSRoger A. Faulkner 	s10set.__sigbits[3] = 0;
4168f798d3aSRoger A. Faulkner 
4178f798d3aSRoger A. Faulkner 	/*
4188f798d3aSRoger A. Faulkner 	 * Copy the remainder of the initial set of common signals.
4198f798d3aSRoger A. Faulkner 	 */
4208f798d3aSRoger A. Faulkner 	for (nativesig = 33; nativesig < S10_SIGRTMIN; nativesig++)
4218f798d3aSRoger A. Faulkner 		if (sigismember(set, nativesig))
4228f798d3aSRoger A. Faulkner 			sigaddset(&s10set, nativesig);
4238f798d3aSRoger A. Faulkner 
4248f798d3aSRoger A. Faulkner 	/*
4258f798d3aSRoger A. Faulkner 	 * Convert any native RT signals to their S10 values.
4268f798d3aSRoger A. Faulkner 	 */
4278f798d3aSRoger A. Faulkner 	for (nativesig = _SIGRTMIN, s10sig = S10_SIGRTMIN;
4288f798d3aSRoger A. Faulkner 	    nativesig <= _SIGRTMAX && s10sig <= S10_SIGRTMAX;
4298f798d3aSRoger A. Faulkner 	    nativesig++, s10sig++) {
4308f798d3aSRoger A. Faulkner 		if (sigismember(set, nativesig))
4318f798d3aSRoger A. Faulkner 			sigaddset(&s10set, s10sig);
4328f798d3aSRoger A. Faulkner 	}
4338f798d3aSRoger A. Faulkner 
4348f798d3aSRoger A. Faulkner 	*set = s10set;
4358f798d3aSRoger A. Faulkner }
4368f798d3aSRoger A. Faulkner 
4378f798d3aSRoger A. Faulkner void
s10_sigset_s10_to_native(sigset_t * set)4388f798d3aSRoger A. Faulkner s10_sigset_s10_to_native(sigset_t *set)
4398f798d3aSRoger A. Faulkner {
4408f798d3aSRoger A. Faulkner 	int s10sig;
4418f798d3aSRoger A. Faulkner 	int nativesig;
4428f798d3aSRoger A. Faulkner 	sigset_t nativeset;
4438f798d3aSRoger A. Faulkner 
4448f798d3aSRoger A. Faulkner 	/*
4458f798d3aSRoger A. Faulkner 	 * Shortcut: we know the first 32 signals are the same in both
4468f798d3aSRoger A. Faulkner 	 * s10 and native Solaris.  Just assign the first word.
4478f798d3aSRoger A. Faulkner 	 */
4488f798d3aSRoger A. Faulkner 	nativeset.__sigbits[0] = set->__sigbits[0];
4498f798d3aSRoger A. Faulkner 	nativeset.__sigbits[1] = 0;
4508f798d3aSRoger A. Faulkner 	nativeset.__sigbits[2] = 0;
4518f798d3aSRoger A. Faulkner 	nativeset.__sigbits[3] = 0;
4528f798d3aSRoger A. Faulkner 
4538f798d3aSRoger A. Faulkner 	/*
4548f798d3aSRoger A. Faulkner 	 * Copy the remainder of the initial set of common signals.
4558f798d3aSRoger A. Faulkner 	 */
4568f798d3aSRoger A. Faulkner 	for (s10sig = 33; s10sig < S10_SIGRTMIN; s10sig++)
4578f798d3aSRoger A. Faulkner 		if (sigismember(set, s10sig))
4588f798d3aSRoger A. Faulkner 			sigaddset(&nativeset, s10sig);
4598f798d3aSRoger A. Faulkner 
4608f798d3aSRoger A. Faulkner 	/*
4618f798d3aSRoger A. Faulkner 	 * Convert any S10 RT signals to their native values.
4628f798d3aSRoger A. Faulkner 	 */
4638f798d3aSRoger A. Faulkner 	for (s10sig = S10_SIGRTMIN, nativesig = _SIGRTMIN;
4648f798d3aSRoger A. Faulkner 	    s10sig <= S10_SIGRTMAX && nativesig <= _SIGRTMAX;
4658f798d3aSRoger A. Faulkner 	    s10sig++, nativesig++) {
4668f798d3aSRoger A. Faulkner 		if (sigismember(set, s10sig))
4678f798d3aSRoger A. Faulkner 			sigaddset(&nativeset, nativesig);
4688f798d3aSRoger A. Faulkner 	}
4698f798d3aSRoger A. Faulkner 
4708f798d3aSRoger A. Faulkner 	*set = nativeset;
4718f798d3aSRoger A. Faulkner }
472e71ca95cSGerald Jelinek 
473e71ca95cSGerald Jelinek int
_init(void)474e71ca95cSGerald Jelinek _init(void)
475e71ca95cSGerald Jelinek {
476e71ca95cSGerald Jelinek 	int err;
477e71ca95cSGerald Jelinek 
478e71ca95cSGerald Jelinek 	/*
479e71ca95cSGerald Jelinek 	 * Set up the table indicating which system calls we want to
480e71ca95cSGerald Jelinek 	 * interpose on.  We should probably build this automatically from
481e71ca95cSGerald Jelinek 	 * a list of system calls that is shared with the user-space
482e71ca95cSGerald Jelinek 	 * library.
483e71ca95cSGerald Jelinek 	 */
484e71ca95cSGerald Jelinek 	s10_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP);
4858fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_forkall] = 1;		/*   2 */
4868fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_open] = 1;			/*   5 */
4878fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_wait] = 1;			/*   7 */
4888fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_creat] = 1;			/*   8 */
489794f0adbSRoger A. Faulkner 	s10_emulation_table[S10_SYS_link] = 1;			/*   9 */
4908fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_unlink] = 1;		/*  10 */
4918fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_exec] = 1;			/*  11 */
492794f0adbSRoger A. Faulkner 	s10_emulation_table[S10_SYS_mknod] = 1;			/*  14 */
493794f0adbSRoger A. Faulkner 	s10_emulation_table[S10_SYS_chmod] = 1;			/*  15 */
4948fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_chown] = 1;			/*  16 */
4958fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_stat] = 1;			/*  18 */
4968fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_umount] = 1;		/*  22 */
4978fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_fstat] = 1;			/*  28 */
4988fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_utime] = 1;			/*  30 */
4998fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_access] = 1;		/*  33 */
500bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_kill] = 1;			/*  37 */
5018fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_dup] = 1;			/*  41 */
502b49b27dcSTheo Schlossnagle 	s10_emulation_table[S10_SYS_pipe] = 1;			/*  42 */
503e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_ioctl] = 1;			/*  54 */
504e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_execve] = 1;			/*  59 */
505e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_acctctl] = 1;			/*  71 */
506e71ca95cSGerald Jelinek 	s10_emulation_table[S10_SYS_issetugid] = 1;		/*  75 */
5078fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_fsat] = 1;			/*  76 */
5088fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_rmdir] = 1;			/*  79 */
509794f0adbSRoger A. Faulkner 	s10_emulation_table[S10_SYS_mkdir] = 1;			/*  80 */
5108b4cf837Sjv 	s10_emulation_table[SYS_getdents] = 1;			/*  81 */
5118fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_poll] = 1;			/*  87 */
5128fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_lstat] = 1;			/*  88 */
513794f0adbSRoger A. Faulkner 	s10_emulation_table[S10_SYS_symlink] = 1;		/*  89 */
514794f0adbSRoger A. Faulkner 	s10_emulation_table[S10_SYS_readlink] = 1;		/*  90 */
515794f0adbSRoger A. Faulkner 	s10_emulation_table[S10_SYS_fchmod] = 1;		/*  93 */
5168fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_fchown] = 1;		/*  94 */
517bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_sigprocmask] = 1;		/*  95 */
518bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_sigsuspend] = 1;		/*  96 */
519bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_sigaction] = 1;			/*  98 */
520bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_sigpending] = 1;		/*  99 */
521bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_waitid] = 1;			/* 107 */
522bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_sigsendsys] = 1;		/* 108 */
5238fd04b83SRoger A. Faulkner #if defined(__x86)
5248fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_xstat] = 1;			/* 123 */
5258fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_lxstat] = 1;		/* 124 */
5268fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_fxstat] = 1;		/* 125 */
5278fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_xmknod] = 1;		/* 126 */
5288fd04b83SRoger A. Faulkner #endif
5298fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_lchown] = 1;		/* 130 */
5308fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_rename] = 1;		/* 134 */
531e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_uname] = 1;			/* 135 */
532bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_sysconfig] = 1;			/* 137 */
533e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_systeminfo] = 1;		/* 139 */
5348fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_fork1] = 1;			/* 143 */
535bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_sigtimedwait] = 1;		/* 144 */
5368fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_lwp_sema_wait] = 1;		/* 147 */
5378fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_utimes] = 1;		/* 154 */
538e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_lwp_create] = 1;		/* 159 */
539bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_lwp_kill] = 1;			/* 163 */
540bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_lwp_sigmask] = 1;		/* 165 */
541bdf0047cSRoger A. Faulkner #if defined(__amd64)
542e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_lwp_private] = 1;		/* 166 */
543e71ca95cSGerald Jelinek #endif	/* __amd64 */
5448fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_lwp_mutex_lock] = 1;	/* 169 */
545e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_pwrite] = 1;			/* 174 */
546f3f1e74cS 	s10_emulation_table[SYS_acl] = 1;			/* 185 */
547e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_auditsys] = 1;			/* 186 */
548e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_sigqueue] = 1;			/* 190 */
549f3f1e74cS 	s10_emulation_table[SYS_facl] = 1;			/* 200 */
550bdf0047cSRoger A. Faulkner 	s10_emulation_table[SYS_signotify] = 1;			/* 205 */
551db94676fSRoger A. Faulkner 	s10_emulation_table[SYS_lwp_mutex_timedlock] = 1;	/* 210 */
5528b4cf837Sjv 	s10_emulation_table[SYS_getdents64] = 1;		/* 213 */
5538fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_stat64] = 1;		/* 215 */
5548fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_lstat64] = 1;		/* 216 */
5558fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_fstat64] = 1;		/* 217 */
556e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_pwrite64] = 1;			/* 223 */
5578fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_creat64] = 1;		/* 224 */
5588fd04b83SRoger A. Faulkner 	s10_emulation_table[S10_SYS_open64] = 1;		/* 225 */
559e71ca95cSGerald Jelinek 	s10_emulation_table[SYS_zone] = 1;			/* 227 */
560b49b27dcSTheo Schlossnagle 	s10_emulation_table[S10_SYS_so_socket] = 1;		/* 230 */
561b49b27dcSTheo Schlossnagle 	s10_emulation_table[S10_SYS_accept] = 1;		/* 234 */
562db94676fSRoger A. Faulkner 	s10_emulation_table[SYS_lwp_mutex_trylock] = 1;		/* 251 */
563e71ca95cSGerald Jelinek 
564e71ca95cSGerald Jelinek 	err = mod_install(&modlinkage);
565e71ca95cSGerald Jelinek 	if (err) {
566e71ca95cSGerald Jelinek 		cmn_err(CE_WARN, "Couldn't install brand module");
567e71ca95cSGerald Jelinek 		kmem_free(s10_emulation_table, NSYSCALL);
568e71ca95cSGerald Jelinek 	}
569e71ca95cSGerald Jelinek 
570e71ca95cSGerald Jelinek 	return (err);
571e71ca95cSGerald Jelinek }
572e71ca95cSGerald Jelinek 
573e71ca95cSGerald Jelinek int
_info(struct modinfo * modinfop)574e71ca95cSGerald Jelinek _info(struct modinfo *modinfop)
575e71ca95cSGerald Jelinek {
576e71ca95cSGerald Jelinek 	return (mod_info(&modlinkage, modinfop));
577e71ca95cSGerald Jelinek }
578e71ca95cSGerald Jelinek 
579e71ca95cSGerald Jelinek int
_fini(void)580e71ca95cSGerald Jelinek _fini(void)
581e71ca95cSGerald Jelinek {
58280e2ca85S 	return (brand_solaris_fini(&s10_emulation_table, &modlinkage,
58380e2ca85S 	    &s10_brand));
584e71ca95cSGerald Jelinek }
585