xref: /freebsd/sys/compat/linux/linux_misc.c (revision 9a8d5af1ba0174ec5fcc3eedba545aec9a627987)
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 2002 Doug Rabson
5  * Copyright (c) 1994-1995 Søren Schmidt
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer
13  *    in this position and unchanged.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/param.h>
33 #include <sys/fcntl.h>
34 #include <sys/jail.h>
35 #include <sys/imgact.h>
36 #include <sys/limits.h>
37 #include <sys/lock.h>
38 #include <sys/membarrier.h>
39 #include <sys/msgbuf.h>
40 #include <sys/mqueue.h>
41 #include <sys/mutex.h>
42 #include <sys/poll.h>
43 #include <sys/priv.h>
44 #include <sys/proc.h>
45 #include <sys/procctl.h>
46 #include <sys/reboot.h>
47 #include <sys/random.h>
48 #include <sys/resourcevar.h>
49 #include <sys/rtprio.h>
50 #include <sys/sched.h>
51 #include <sys/smp.h>
52 #include <sys/stat.h>
53 #include <sys/syscallsubr.h>
54 #include <sys/sysctl.h>
55 #include <sys/sysent.h>
56 #include <sys/sysproto.h>
57 #include <sys/time.h>
58 #include <sys/unistd.h>
59 #include <sys/vmmeter.h>
60 #include <sys/vnode.h>
61 
62 #include <security/audit/audit.h>
63 #include <security/mac/mac_framework.h>
64 
65 #include <vm/pmap.h>
66 #include <vm/vm_extern.h>
67 #include <vm/vm_map.h>
68 #include <vm/swap_pager.h>
69 
70 #ifdef COMPAT_LINUX32
71 #include <machine/../linux32/linux.h>
72 #include <machine/../linux32/linux32_proto.h>
73 #else
74 #include <machine/../linux/linux.h>
75 #include <machine/../linux/linux_proto.h>
76 #endif
77 
78 #include <compat/linux/linux_common.h>
79 #include <compat/linux/linux_dtrace.h>
80 #include <compat/linux/linux_file.h>
81 #include <compat/linux/linux_mib.h>
82 #include <compat/linux/linux_mmap.h>
83 #include <compat/linux/linux_signal.h>
84 #include <compat/linux/linux_time.h>
85 #include <compat/linux/linux_util.h>
86 #include <compat/linux/linux_emul.h>
87 #include <compat/linux/linux_misc.h>
88 
89 int stclohz;				/* Statistics clock frequency */
90 
91 static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = {
92 	RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK,
93 	RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE,
94 	RLIMIT_MEMLOCK, RLIMIT_AS
95 };
96 
97 struct l_sysinfo {
98 	l_long		uptime;		/* Seconds since boot */
99 	l_ulong		loads[3];	/* 1, 5, and 15 minute load averages */
100 #define LINUX_SYSINFO_LOADS_SCALE 65536
101 	l_ulong		totalram;	/* Total usable main memory size */
102 	l_ulong		freeram;	/* Available memory size */
103 	l_ulong		sharedram;	/* Amount of shared memory */
104 	l_ulong		bufferram;	/* Memory used by buffers */
105 	l_ulong		totalswap;	/* Total swap space size */
106 	l_ulong		freeswap;	/* swap space still available */
107 	l_ushort	procs;		/* Number of current processes */
108 	l_ushort	pads;
109 	l_ulong		totalhigh;
110 	l_ulong		freehigh;
111 	l_uint		mem_unit;
112 	char		_f[20-2*sizeof(l_long)-sizeof(l_int)];	/* padding */
113 };
114 
115 struct l_pselect6arg {
116 	l_uintptr_t	ss;
117 	l_size_t	ss_len;
118 };
119 
120 /**
121  * `SCHED_ATTR_SIZE_VER0` represents the size of the initial published structure.
122  *
123  * See `linux/kernel/sched/syscalls.c` for more details.
124  */
125 #define LINUX_SCHED_ATTR_SIZE_VER0 48
126 /**
127  * Linux struct sched_attr
128  */
129 struct linux_sched_attr {
130 	l_uint 		size;
131 	l_uint 		sched_policy;
132 	uint64_t 	sched_flags;
133 	int32_t  	sched_nice;
134 	l_uint 		sched_priority;
135 
136 	uint64_t 	sched_runtime;
137 	uint64_t 	sched_deadline;
138 	uint64_t 	sched_period;
139 
140 	l_uint 		sched_util_min;
141 	l_uint 		sched_util_max;
142 };
143 /**
144  * `.size` must be checked at runtime as well in the syscall to match the
145  * Linux implementation.
146  *
147  * This `_Static_assert(..)` is a sanity check to ensure that the structure
148  * meets the minimum expected bar.
149  */
150 _Static_assert(sizeof(struct linux_sched_attr) >= LINUX_SCHED_ATTR_SIZE_VER0,
151     "struct linux_sched_attr size");
152 
153 static int	bsd_sched_policy_to_linux_sched_policy(int);
154 
155 static int	linux_utimensat_lts_to_ts(struct l_timespec *,
156 			struct timespec *);
157 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
158 static int	linux_utimensat_lts64_to_ts(struct l_timespec64 *,
159 			struct timespec *);
160 #endif
161 static int	linux_common_utimensat(struct thread *, int,
162 			const char *, struct timespec *, int);
163 static int	linux_common_pselect6(struct thread *, l_int,
164 			l_fd_set *, l_fd_set *, l_fd_set *,
165 			struct timespec *, l_uintptr_t *);
166 static int	linux_common_ppoll(struct thread *, struct pollfd *,
167 			uint32_t, struct timespec *, l_sigset_t *,
168 			l_size_t);
169 static int	linux_pollin(struct thread *, struct pollfd *,
170 			struct pollfd *, u_int);
171 static int	linux_pollout(struct thread *, struct pollfd *,
172 			struct pollfd *, u_int);
173 
174 int
175 linux_sysinfo(struct thread *td, struct linux_sysinfo_args *args)
176 {
177 	struct l_sysinfo sysinfo;
178 	int i, j;
179 	struct timespec ts;
180 
181 	bzero(&sysinfo, sizeof(sysinfo));
182 	getnanouptime(&ts);
183 	if (ts.tv_nsec != 0)
184 		ts.tv_sec++;
185 	sysinfo.uptime = ts.tv_sec;
186 
187 	/* Use the information from the mib to get our load averages */
188 	for (i = 0; i < 3; i++)
189 		sysinfo.loads[i] = averunnable.ldavg[i] *
190 		    LINUX_SYSINFO_LOADS_SCALE / averunnable.fscale;
191 
192 	sysinfo.totalram = physmem * PAGE_SIZE;
193 	sysinfo.freeram = (u_long)vm_free_count() * PAGE_SIZE;
194 
195 	/*
196 	 * sharedram counts pages allocated to named, swap-backed objects such
197 	 * as shared memory segments and tmpfs files.  There is no cheap way to
198 	 * compute this, so just leave the field unpopulated.  Linux itself only
199 	 * started setting this field in the 3.x timeframe.
200 	 */
201 	sysinfo.sharedram = 0;
202 	sysinfo.bufferram = 0;
203 
204 	swap_pager_status(&i, &j);
205 	sysinfo.totalswap = i * PAGE_SIZE;
206 	sysinfo.freeswap = (i - j) * PAGE_SIZE;
207 
208 	sysinfo.procs = nprocs;
209 
210 	/*
211 	 * Platforms supported by the emulation layer do not have a notion of
212 	 * high memory.
213 	 */
214 	sysinfo.totalhigh = 0;
215 	sysinfo.freehigh = 0;
216 
217 	sysinfo.mem_unit = 1;
218 
219 	return (copyout(&sysinfo, args->info, sizeof(sysinfo)));
220 }
221 
222 #ifdef LINUX_LEGACY_SYSCALLS
223 int
224 linux_alarm(struct thread *td, struct linux_alarm_args *args)
225 {
226 	struct itimerval it, old_it;
227 	u_int secs;
228 	int error __diagused;
229 
230 	secs = args->secs;
231 	/*
232 	 * Linux alarm() is always successful. Limit secs to INT32_MAX / 2
233 	 * to match kern_setitimer()'s limit to avoid error from it.
234 	 *
235 	 * XXX. Linux limit secs to INT_MAX on 32 and does not limit on 64-bit
236 	 * platforms.
237 	 */
238 	if (secs > INT32_MAX / 2)
239 		secs = INT32_MAX / 2;
240 
241 	it.it_value.tv_sec = secs;
242 	it.it_value.tv_usec = 0;
243 	timevalclear(&it.it_interval);
244 	error = kern_setitimer(td, ITIMER_REAL, &it, &old_it);
245 	KASSERT(error == 0, ("kern_setitimer returns %d", error));
246 
247 	if ((old_it.it_value.tv_sec == 0 && old_it.it_value.tv_usec > 0) ||
248 	    old_it.it_value.tv_usec >= 500000)
249 		old_it.it_value.tv_sec++;
250 	td->td_retval[0] = old_it.it_value.tv_sec;
251 	return (0);
252 }
253 #endif
254 
255 int
256 linux_brk(struct thread *td, struct linux_brk_args *args)
257 {
258 	struct vmspace *vm = td->td_proc->p_vmspace;
259 	uintptr_t new, old;
260 
261 	old = (uintptr_t)vm->vm_daddr + ctob(vm->vm_dsize);
262 	new = (uintptr_t)args->dsend;
263 	if ((caddr_t)new > vm->vm_daddr && !kern_break(td, &new))
264 		td->td_retval[0] = (register_t)new;
265 	else
266 		td->td_retval[0] = (register_t)old;
267 
268 	return (0);
269 }
270 
271 #ifdef LINUX_LEGACY_SYSCALLS
272 int
273 linux_select(struct thread *td, struct linux_select_args *args)
274 {
275 	l_timeval ltv;
276 	struct timeval tv0, tv1, utv, *tvp;
277 	int error;
278 
279 	/*
280 	 * Store current time for computation of the amount of
281 	 * time left.
282 	 */
283 	if (args->timeout) {
284 		if ((error = copyin(args->timeout, &ltv, sizeof(ltv))))
285 			goto select_out;
286 		utv.tv_sec = ltv.tv_sec;
287 		utv.tv_usec = ltv.tv_usec;
288 
289 		if (itimerfix(&utv)) {
290 			/*
291 			 * The timeval was invalid.  Convert it to something
292 			 * valid that will act as it does under Linux.
293 			 */
294 			utv.tv_sec += utv.tv_usec / 1000000;
295 			utv.tv_usec %= 1000000;
296 			if (utv.tv_usec < 0) {
297 				utv.tv_sec -= 1;
298 				utv.tv_usec += 1000000;
299 			}
300 			if (utv.tv_sec < 0)
301 				timevalclear(&utv);
302 		}
303 		microtime(&tv0);
304 		tvp = &utv;
305 	} else
306 		tvp = NULL;
307 
308 	error = kern_select(td, args->nfds, args->readfds, args->writefds,
309 	    args->exceptfds, tvp, LINUX_NFDBITS);
310 	if (error)
311 		goto select_out;
312 
313 	if (args->timeout) {
314 		if (td->td_retval[0]) {
315 			/*
316 			 * Compute how much time was left of the timeout,
317 			 * by subtracting the current time and the time
318 			 * before we started the call, and subtracting
319 			 * that result from the user-supplied value.
320 			 */
321 			microtime(&tv1);
322 			timevalsub(&tv1, &tv0);
323 			timevalsub(&utv, &tv1);
324 			if (utv.tv_sec < 0)
325 				timevalclear(&utv);
326 		} else
327 			timevalclear(&utv);
328 		ltv.tv_sec = utv.tv_sec;
329 		ltv.tv_usec = utv.tv_usec;
330 		if ((error = copyout(&ltv, args->timeout, sizeof(ltv))))
331 			goto select_out;
332 	}
333 
334 select_out:
335 	return (error);
336 }
337 #endif
338 
339 int
340 linux_mremap(struct thread *td, struct linux_mremap_args *args)
341 {
342 	uintptr_t addr;
343 	size_t len;
344 	int error = 0;
345 
346 	if (args->flags & ~(LINUX_MREMAP_FIXED | LINUX_MREMAP_MAYMOVE)) {
347 		td->td_retval[0] = 0;
348 		return (EINVAL);
349 	}
350 
351 	/*
352 	 * Check for the page alignment.
353 	 * Linux defines PAGE_MASK to be FreeBSD ~PAGE_MASK.
354 	 */
355 	if (args->addr & PAGE_MASK) {
356 		td->td_retval[0] = 0;
357 		return (EINVAL);
358 	}
359 
360 	args->new_len = round_page(args->new_len);
361 	args->old_len = round_page(args->old_len);
362 
363 	if (args->new_len > args->old_len) {
364 		td->td_retval[0] = 0;
365 		if (useracc((void *)(uintptr_t)args->addr, args->old_len,
366 		    VM_PROT_READ))
367 			return (ENOMEM);
368 		return (EFAULT);
369 	}
370 
371 	if (args->new_len < args->old_len) {
372 		addr = args->addr + args->new_len;
373 		len = args->old_len - args->new_len;
374 		error = kern_munmap(td, addr, len);
375 	}
376 
377 	td->td_retval[0] = error ? 0 : (uintptr_t)args->addr;
378 	return (error);
379 }
380 
381 #define LINUX_MS_ASYNC       0x0001
382 #define LINUX_MS_INVALIDATE  0x0002
383 #define LINUX_MS_SYNC        0x0004
384 
385 int
386 linux_msync(struct thread *td, struct linux_msync_args *args)
387 {
388 
389 	return (kern_msync(td, args->addr, args->len,
390 	    args->fl & ~LINUX_MS_SYNC));
391 }
392 
393 int
394 linux_mprotect(struct thread *td, struct linux_mprotect_args *uap)
395 {
396 
397 	return (linux_mprotect_common(td, PTROUT(uap->addr), uap->len,
398 	    uap->prot));
399 }
400 
401 int
402 linux_pkey_mprotect(struct thread *td, struct linux_pkey_mprotect_args *uap)
403 {
404 
405 	return (linux_pkey_mprotect_common(td, uap->start, uap->len,
406 	    uap->prot, uap->pkey));
407 }
408 
409 int
410 linux_pkey_alloc(struct thread *td, struct linux_pkey_alloc_args *uap)
411 {
412 
413 	return (linux_pkey_alloc_common(td, uap->flags, uap->init_val));
414 }
415 
416 int
417 linux_pkey_free(struct thread *td, struct linux_pkey_free_args *uap)
418 {
419 
420 	return (linux_pkey_free_common(td, uap->pkey));
421 }
422 
423 int
424 linux_madvise(struct thread *td, struct linux_madvise_args *uap)
425 {
426 
427 	return (linux_madvise_common(td, PTROUT(uap->addr), uap->len,
428 	    uap->behav));
429 }
430 
431 int
432 linux_mmap2(struct thread *td, struct linux_mmap2_args *uap)
433 {
434 #if defined(LINUX_ARCHWANT_MMAP2PGOFF)
435 	/*
436 	 * For architectures with sizeof (off_t) < sizeof (loff_t) mmap is
437 	 * implemented with mmap2 syscall and the offset is represented in
438 	 * multiples of page size.
439 	 */
440 	return (linux_mmap_common(td, PTROUT(uap->addr), uap->len, uap->prot,
441 	    uap->flags, uap->fd, (uint64_t)(uint32_t)uap->pgoff * PAGE_SIZE));
442 #else
443 	return (linux_mmap_common(td, PTROUT(uap->addr), uap->len, uap->prot,
444 	    uap->flags, uap->fd, uap->pgoff));
445 #endif
446 }
447 
448 #ifdef LINUX_LEGACY_SYSCALLS
449 int
450 linux_time(struct thread *td, struct linux_time_args *args)
451 {
452 	struct timeval tv;
453 	l_time_t tm;
454 	int error;
455 
456 	microtime(&tv);
457 	tm = tv.tv_sec;
458 	if (args->tm && (error = copyout(&tm, args->tm, sizeof(tm))))
459 		return (error);
460 	td->td_retval[0] = tm;
461 	return (0);
462 }
463 #endif
464 
465 struct l_times_argv {
466 	l_clock_t	tms_utime;
467 	l_clock_t	tms_stime;
468 	l_clock_t	tms_cutime;
469 	l_clock_t	tms_cstime;
470 };
471 
472 /*
473  * Glibc versions prior to 2.2.1 always use hard-coded CLK_TCK value.
474  * Since 2.2.1 Glibc uses value exported from kernel via AT_CLKTCK
475  * auxiliary vector entry.
476  */
477 #define	CLK_TCK		100
478 
479 #define	CONVOTCK(r)	(r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
480 #define	CONVNTCK(r)	(r.tv_sec * stclohz + r.tv_usec / (1000000 / stclohz))
481 
482 #define	CONVTCK(r)	(linux_kernver(td) >= LINUX_KERNVER(2,4,0) ?	\
483 			    CONVNTCK(r) : CONVOTCK(r))
484 
485 int
486 linux_times(struct thread *td, struct linux_times_args *args)
487 {
488 	struct timeval tv, utime, stime, cutime, cstime;
489 	struct l_times_argv tms;
490 	struct proc *p;
491 	int error;
492 
493 	if (args->buf != NULL) {
494 		p = td->td_proc;
495 		PROC_LOCK(p);
496 		PROC_STATLOCK(p);
497 		calcru(p, &utime, &stime);
498 		PROC_STATUNLOCK(p);
499 		calccru(p, &cutime, &cstime);
500 		PROC_UNLOCK(p);
501 
502 		tms.tms_utime = CONVTCK(utime);
503 		tms.tms_stime = CONVTCK(stime);
504 
505 		tms.tms_cutime = CONVTCK(cutime);
506 		tms.tms_cstime = CONVTCK(cstime);
507 
508 		if ((error = copyout(&tms, args->buf, sizeof(tms))))
509 			return (error);
510 	}
511 
512 	microuptime(&tv);
513 	td->td_retval[0] = (int)CONVTCK(tv);
514 	return (0);
515 }
516 
517 int
518 linux_newuname(struct thread *td, struct linux_newuname_args *args)
519 {
520 	struct l_new_utsname utsname;
521 	char osname[LINUX_MAX_UTSNAME];
522 	char osrelease[LINUX_MAX_UTSNAME];
523 	char *p;
524 
525 	linux_get_osname(td, osname);
526 	linux_get_osrelease(td, osrelease);
527 
528 	bzero(&utsname, sizeof(utsname));
529 	strlcpy(utsname.sysname, osname, LINUX_MAX_UTSNAME);
530 	getcredhostname(td->td_ucred, utsname.nodename, LINUX_MAX_UTSNAME);
531 	getcreddomainname(td->td_ucred, utsname.domainname, LINUX_MAX_UTSNAME);
532 	strlcpy(utsname.release, osrelease, LINUX_MAX_UTSNAME);
533 	strlcpy(utsname.version, version, LINUX_MAX_UTSNAME);
534 	for (p = utsname.version; *p != '\0'; ++p)
535 		if (*p == '\n') {
536 			*p = '\0';
537 			break;
538 		}
539 #if defined(__amd64__)
540 	/*
541 	 * On amd64, Linux uname(2) needs to return "x86_64"
542 	 * for both 64-bit and 32-bit applications.  On 32-bit,
543 	 * the string returned by getauxval(AT_PLATFORM) needs
544 	 * to remain "i686", though.
545 	 */
546 #if defined(COMPAT_LINUX32)
547 	if (linux32_emulate_i386)
548 		strlcpy(utsname.machine, "i686", LINUX_MAX_UTSNAME);
549 	else
550 #endif
551 	strlcpy(utsname.machine, "x86_64", LINUX_MAX_UTSNAME);
552 #elif defined(__aarch64__)
553 	strlcpy(utsname.machine, "aarch64", LINUX_MAX_UTSNAME);
554 #elif defined(__i386__)
555 	strlcpy(utsname.machine, "i686", LINUX_MAX_UTSNAME);
556 #endif
557 
558 	return (copyout(&utsname, args->buf, sizeof(utsname)));
559 }
560 
561 struct l_utimbuf {
562 	l_time_t l_actime;
563 	l_time_t l_modtime;
564 };
565 
566 #ifdef LINUX_LEGACY_SYSCALLS
567 int
568 linux_utime(struct thread *td, struct linux_utime_args *args)
569 {
570 	struct timeval tv[2], *tvp;
571 	struct l_utimbuf lut;
572 	int error;
573 
574 	if (args->times) {
575 		if ((error = copyin(args->times, &lut, sizeof lut)) != 0)
576 			return (error);
577 		tv[0].tv_sec = lut.l_actime;
578 		tv[0].tv_usec = 0;
579 		tv[1].tv_sec = lut.l_modtime;
580 		tv[1].tv_usec = 0;
581 		tvp = tv;
582 	} else
583 		tvp = NULL;
584 
585 	return (kern_utimesat(td, AT_FDCWD, args->fname, UIO_USERSPACE,
586 	    tvp, UIO_SYSSPACE));
587 }
588 #endif
589 
590 #ifdef LINUX_LEGACY_SYSCALLS
591 int
592 linux_utimes(struct thread *td, struct linux_utimes_args *args)
593 {
594 	l_timeval ltv[2];
595 	struct timeval tv[2], *tvp = NULL;
596 	int error;
597 
598 	if (args->tptr != NULL) {
599 		if ((error = copyin(args->tptr, ltv, sizeof ltv)) != 0)
600 			return (error);
601 		tv[0].tv_sec = ltv[0].tv_sec;
602 		tv[0].tv_usec = ltv[0].tv_usec;
603 		tv[1].tv_sec = ltv[1].tv_sec;
604 		tv[1].tv_usec = ltv[1].tv_usec;
605 		tvp = tv;
606 	}
607 
608 	return (kern_utimesat(td, AT_FDCWD, args->fname, UIO_USERSPACE,
609 	    tvp, UIO_SYSSPACE));
610 }
611 #endif
612 
613 static int
614 linux_utimensat_lts_to_ts(struct l_timespec *l_times, struct timespec *times)
615 {
616 
617 	if (l_times->tv_nsec != LINUX_UTIME_OMIT &&
618 	    l_times->tv_nsec != LINUX_UTIME_NOW &&
619 	    (l_times->tv_nsec < 0 || l_times->tv_nsec > 999999999))
620 		return (EINVAL);
621 
622 	times->tv_sec = l_times->tv_sec;
623 	switch (l_times->tv_nsec)
624 	{
625 	case LINUX_UTIME_OMIT:
626 		times->tv_nsec = UTIME_OMIT;
627 		break;
628 	case LINUX_UTIME_NOW:
629 		times->tv_nsec = UTIME_NOW;
630 		break;
631 	default:
632 		times->tv_nsec = l_times->tv_nsec;
633 	}
634 
635 	return (0);
636 }
637 
638 static int
639 linux_common_utimensat(struct thread *td, int ldfd, const char *pathname,
640     struct timespec *timesp, int lflags)
641 {
642 	int dfd, flags = 0;
643 
644 	dfd = (ldfd == LINUX_AT_FDCWD) ? AT_FDCWD : ldfd;
645 
646 	if (lflags & ~(LINUX_AT_SYMLINK_NOFOLLOW | LINUX_AT_EMPTY_PATH))
647 		return (EINVAL);
648 
649 	if (timesp != NULL) {
650 		/* This breaks POSIX, but is what the Linux kernel does
651 		 * _on purpose_ (documented in the man page for utimensat(2)),
652 		 * so we must follow that behaviour. */
653 		if (timesp[0].tv_nsec == UTIME_OMIT &&
654 		    timesp[1].tv_nsec == UTIME_OMIT)
655 			return (0);
656 	}
657 
658 	if (lflags & LINUX_AT_SYMLINK_NOFOLLOW)
659 		flags |= AT_SYMLINK_NOFOLLOW;
660 	if (lflags & LINUX_AT_EMPTY_PATH)
661 		flags |= AT_EMPTY_PATH;
662 
663 	if (pathname != NULL)
664 		return (kern_utimensat(td, dfd, pathname,
665 		    UIO_USERSPACE, timesp, UIO_SYSSPACE, flags));
666 
667 	if (lflags != 0)
668 		return (EINVAL);
669 
670 	return (kern_futimens(td, dfd, timesp, UIO_SYSSPACE));
671 }
672 
673 int
674 linux_utimensat(struct thread *td, struct linux_utimensat_args *args)
675 {
676 	struct l_timespec l_times[2];
677 	struct timespec times[2], *timesp;
678 	int error;
679 
680 	if (args->times != NULL) {
681 		error = copyin(args->times, l_times, sizeof(l_times));
682 		if (error != 0)
683 			return (error);
684 
685 		error = linux_utimensat_lts_to_ts(&l_times[0], &times[0]);
686 		if (error != 0)
687 			return (error);
688 		error = linux_utimensat_lts_to_ts(&l_times[1], &times[1]);
689 		if (error != 0)
690 			return (error);
691 		timesp = times;
692 	} else
693 		timesp = NULL;
694 
695 	return (linux_common_utimensat(td, args->dfd, args->pathname,
696 	    timesp, args->flags));
697 }
698 
699 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
700 static int
701 linux_utimensat_lts64_to_ts(struct l_timespec64 *l_times, struct timespec *times)
702 {
703 
704 	/* Zero out the padding in compat mode. */
705 	l_times->tv_nsec &= 0xFFFFFFFFUL;
706 
707 	if (l_times->tv_nsec != LINUX_UTIME_OMIT &&
708 	    l_times->tv_nsec != LINUX_UTIME_NOW &&
709 	    (l_times->tv_nsec < 0 || l_times->tv_nsec > 999999999))
710 		return (EINVAL);
711 
712 	times->tv_sec = l_times->tv_sec;
713 	switch (l_times->tv_nsec)
714 	{
715 	case LINUX_UTIME_OMIT:
716 		times->tv_nsec = UTIME_OMIT;
717 		break;
718 	case LINUX_UTIME_NOW:
719 		times->tv_nsec = UTIME_NOW;
720 		break;
721 	default:
722 		times->tv_nsec = l_times->tv_nsec;
723 	}
724 
725 	return (0);
726 }
727 
728 int
729 linux_utimensat_time64(struct thread *td, struct linux_utimensat_time64_args *args)
730 {
731 	struct l_timespec64 l_times[2];
732 	struct timespec times[2], *timesp;
733 	int error;
734 
735 	if (args->times64 != NULL) {
736 		error = copyin(args->times64, l_times, sizeof(l_times));
737 		if (error != 0)
738 			return (error);
739 
740 		error = linux_utimensat_lts64_to_ts(&l_times[0], &times[0]);
741 		if (error != 0)
742 			return (error);
743 		error = linux_utimensat_lts64_to_ts(&l_times[1], &times[1]);
744 		if (error != 0)
745 			return (error);
746 		timesp = times;
747 	} else
748 		timesp = NULL;
749 
750 	return (linux_common_utimensat(td, args->dfd, args->pathname,
751 	    timesp, args->flags));
752 }
753 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
754 
755 #ifdef LINUX_LEGACY_SYSCALLS
756 int
757 linux_futimesat(struct thread *td, struct linux_futimesat_args *args)
758 {
759 	l_timeval ltv[2];
760 	struct timeval tv[2], *tvp = NULL;
761 	int error, dfd;
762 
763 	dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
764 
765 	if (args->utimes != NULL) {
766 		if ((error = copyin(args->utimes, ltv, sizeof ltv)) != 0)
767 			return (error);
768 		tv[0].tv_sec = ltv[0].tv_sec;
769 		tv[0].tv_usec = ltv[0].tv_usec;
770 		tv[1].tv_sec = ltv[1].tv_sec;
771 		tv[1].tv_usec = ltv[1].tv_usec;
772 		tvp = tv;
773 	}
774 
775 	return (kern_utimesat(td, dfd, args->filename, UIO_USERSPACE,
776 	    tvp, UIO_SYSSPACE));
777 }
778 #endif
779 
780 static int
781 linux_common_wait(struct thread *td, idtype_t idtype, int id, int *statusp,
782     int options, void *rup, l_siginfo_t *infop)
783 {
784 	l_siginfo_t lsi;
785 	siginfo_t siginfo;
786 	struct __wrusage wru;
787 	int error, status, tmpstat, sig;
788 
789 	error = kern_wait6(td, idtype, id, &status, options,
790 	    rup != NULL ? &wru : NULL, &siginfo);
791 
792 	if (error == 0 && statusp) {
793 		tmpstat = status & 0xffff;
794 		if (WIFSIGNALED(tmpstat)) {
795 			tmpstat = (tmpstat & 0xffffff80) |
796 			    bsd_to_linux_signal(WTERMSIG(tmpstat));
797 		} else if (WIFSTOPPED(tmpstat)) {
798 			tmpstat = (tmpstat & 0xffff00ff) |
799 			    (bsd_to_linux_signal(WSTOPSIG(tmpstat)) << 8);
800 #if defined(__aarch64__) || (defined(__amd64__) && !defined(COMPAT_LINUX32))
801 			if (WSTOPSIG(status) == SIGTRAP) {
802 				tmpstat = linux_ptrace_status(td,
803 				    siginfo.si_pid, tmpstat);
804 			}
805 #endif
806 		} else if (WIFCONTINUED(tmpstat)) {
807 			tmpstat = 0xffff;
808 		}
809 		error = copyout(&tmpstat, statusp, sizeof(int));
810 	}
811 	if (error == 0 && rup != NULL)
812 		error = linux_copyout_rusage(&wru.wru_self, rup);
813 	if (error == 0 && infop != NULL && td->td_retval[0] != 0) {
814 		sig = bsd_to_linux_signal(siginfo.si_signo);
815 		memset(&lsi, 0, sizeof(lsi));
816 		siginfo_to_lsiginfo(&siginfo, &lsi, sig);
817 		error = copyout(&lsi, infop, sizeof(lsi));
818 	}
819 
820 	return (error);
821 }
822 
823 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
824 int
825 linux_waitpid(struct thread *td, struct linux_waitpid_args *args)
826 {
827 	struct linux_wait4_args wait4_args = {
828 		.pid = args->pid,
829 		.status = args->status,
830 		.options = args->options,
831 		.rusage = NULL,
832 	};
833 
834 	return (linux_wait4(td, &wait4_args));
835 }
836 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
837 
838 int
839 linux_wait4(struct thread *td, struct linux_wait4_args *args)
840 {
841 	struct proc *p;
842 	int options, id, idtype;
843 
844 	if (args->options & ~(LINUX_WUNTRACED | LINUX_WNOHANG |
845 	    LINUX_WCONTINUED | __WCLONE | __WNOTHREAD | __WALL))
846 		return (EINVAL);
847 
848 	/* -INT_MIN is not defined. */
849 	if (args->pid == INT_MIN)
850 		return (ESRCH);
851 
852 	options = 0;
853 	linux_to_bsd_waitopts(args->options, &options);
854 
855 	/*
856 	 * For backward compatibility we implicitly add flags WEXITED
857 	 * and WTRAPPED here.
858 	 */
859 	options |= WEXITED | WTRAPPED;
860 
861 	if (args->pid == WAIT_ANY) {
862 		idtype = P_ALL;
863 		id = 0;
864 	} else if (args->pid < 0) {
865 		idtype = P_PGID;
866 		id = (id_t)-args->pid;
867 	} else if (args->pid == 0) {
868 		idtype = P_PGID;
869 		p = td->td_proc;
870 		PROC_LOCK(p);
871 		id = p->p_pgid;
872 		PROC_UNLOCK(p);
873 	} else {
874 		idtype = P_PID;
875 		id = (id_t)args->pid;
876 	}
877 
878 	return (linux_common_wait(td, idtype, id, args->status, options,
879 	    args->rusage, NULL));
880 }
881 
882 int
883 linux_waitid(struct thread *td, struct linux_waitid_args *args)
884 {
885 	idtype_t idtype;
886 	int error, options;
887 	struct proc *p;
888 	pid_t id;
889 
890 	if (args->options & ~(LINUX_WNOHANG | LINUX_WNOWAIT | LINUX_WEXITED |
891 	    LINUX_WSTOPPED | LINUX_WCONTINUED | __WCLONE | __WNOTHREAD | __WALL))
892 		return (EINVAL);
893 
894 	options = 0;
895 	linux_to_bsd_waitopts(args->options, &options);
896 
897 	id = args->id;
898 	switch (args->idtype) {
899 	case LINUX_P_ALL:
900 		idtype = P_ALL;
901 		break;
902 	case LINUX_P_PID:
903 		if (args->id <= 0)
904 			return (EINVAL);
905 		idtype = P_PID;
906 		break;
907 	case LINUX_P_PGID:
908 		if (linux_kernver(td) >= LINUX_KERNVER(5,4,0) && args->id == 0) {
909 			p = td->td_proc;
910 			PROC_LOCK(p);
911 			id = p->p_pgid;
912 			PROC_UNLOCK(p);
913 		} else if (args->id <= 0)
914 			return (EINVAL);
915 		idtype = P_PGID;
916 		break;
917 	case LINUX_P_PIDFD:
918 		LINUX_RATELIMIT_MSG("unsupported waitid P_PIDFD idtype");
919 		return (ENOSYS);
920 	default:
921 		return (EINVAL);
922 	}
923 
924 	error = linux_common_wait(td, idtype, id, NULL, options,
925 	    args->rusage, args->info);
926 	td->td_retval[0] = 0;
927 
928 	return (error);
929 }
930 
931 #ifdef LINUX_LEGACY_SYSCALLS
932 int
933 linux_mknod(struct thread *td, struct linux_mknod_args *args)
934 {
935 	int error;
936 
937 	switch (args->mode & S_IFMT) {
938 	case S_IFIFO:
939 	case S_IFSOCK:
940 		error = kern_mkfifoat(td, AT_FDCWD, args->path, UIO_USERSPACE,
941 		    args->mode);
942 		break;
943 
944 	case S_IFCHR:
945 	case S_IFBLK:
946 		error = kern_mknodat(td, AT_FDCWD, args->path, UIO_USERSPACE,
947 		    args->mode, linux_decode_dev(args->dev));
948 		break;
949 
950 	case S_IFDIR:
951 		error = EPERM;
952 		break;
953 
954 	case 0:
955 		args->mode |= S_IFREG;
956 		/* FALLTHROUGH */
957 	case S_IFREG:
958 		error = kern_openat(td, AT_FDCWD, args->path, UIO_USERSPACE,
959 		    O_WRONLY | O_CREAT | O_TRUNC, args->mode);
960 		if (error == 0)
961 			kern_close(td, td->td_retval[0]);
962 		break;
963 
964 	default:
965 		error = EINVAL;
966 		break;
967 	}
968 	return (error);
969 }
970 #endif
971 
972 int
973 linux_mknodat(struct thread *td, struct linux_mknodat_args *args)
974 {
975 	int error, dfd;
976 
977 	dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
978 
979 	switch (args->mode & S_IFMT) {
980 	case S_IFIFO:
981 	case S_IFSOCK:
982 		error = kern_mkfifoat(td, dfd, args->filename, UIO_USERSPACE,
983 		    args->mode);
984 		break;
985 
986 	case S_IFCHR:
987 	case S_IFBLK:
988 		error = kern_mknodat(td, dfd, args->filename, UIO_USERSPACE,
989 		    args->mode, linux_decode_dev(args->dev));
990 		break;
991 
992 	case S_IFDIR:
993 		error = EPERM;
994 		break;
995 
996 	case 0:
997 		args->mode |= S_IFREG;
998 		/* FALLTHROUGH */
999 	case S_IFREG:
1000 		error = kern_openat(td, dfd, args->filename, UIO_USERSPACE,
1001 		    O_WRONLY | O_CREAT | O_TRUNC, args->mode);
1002 		if (error == 0)
1003 			kern_close(td, td->td_retval[0]);
1004 		break;
1005 
1006 	default:
1007 		error = EINVAL;
1008 		break;
1009 	}
1010 	return (error);
1011 }
1012 
1013 /*
1014  * UGH! This is just about the dumbest idea I've ever heard!!
1015  */
1016 int
1017 linux_personality(struct thread *td, struct linux_personality_args *args)
1018 {
1019 	struct linux_pemuldata *pem;
1020 	struct proc *p = td->td_proc;
1021 	uint32_t old;
1022 
1023 	PROC_LOCK(p);
1024 	pem = pem_find(p);
1025 	old = pem->persona;
1026 	if (args->per != 0xffffffff)
1027 		pem->persona = args->per;
1028 	PROC_UNLOCK(p);
1029 
1030 	td->td_retval[0] = old;
1031 	return (0);
1032 }
1033 
1034 struct l_itimerval {
1035 	l_timeval it_interval;
1036 	l_timeval it_value;
1037 };
1038 
1039 #define	B2L_ITIMERVAL(bip, lip)						\
1040 	(bip)->it_interval.tv_sec = (lip)->it_interval.tv_sec;		\
1041 	(bip)->it_interval.tv_usec = (lip)->it_interval.tv_usec;	\
1042 	(bip)->it_value.tv_sec = (lip)->it_value.tv_sec;		\
1043 	(bip)->it_value.tv_usec = (lip)->it_value.tv_usec;
1044 
1045 int
1046 linux_setitimer(struct thread *td, struct linux_setitimer_args *uap)
1047 {
1048 	int error;
1049 	struct l_itimerval ls;
1050 	struct itimerval aitv, oitv;
1051 
1052 	if (uap->itv == NULL) {
1053 		uap->itv = uap->oitv;
1054 		return (linux_getitimer(td, (struct linux_getitimer_args *)uap));
1055 	}
1056 
1057 	error = copyin(uap->itv, &ls, sizeof(ls));
1058 	if (error != 0)
1059 		return (error);
1060 	B2L_ITIMERVAL(&aitv, &ls);
1061 	error = kern_setitimer(td, uap->which, &aitv, &oitv);
1062 	if (error != 0 || uap->oitv == NULL)
1063 		return (error);
1064 	B2L_ITIMERVAL(&ls, &oitv);
1065 
1066 	return (copyout(&ls, uap->oitv, sizeof(ls)));
1067 }
1068 
1069 int
1070 linux_getitimer(struct thread *td, struct linux_getitimer_args *uap)
1071 {
1072 	int error;
1073 	struct l_itimerval ls;
1074 	struct itimerval aitv;
1075 
1076 	error = kern_getitimer(td, uap->which, &aitv);
1077 	if (error != 0)
1078 		return (error);
1079 	B2L_ITIMERVAL(&ls, &aitv);
1080 	return (copyout(&ls, uap->itv, sizeof(ls)));
1081 }
1082 
1083 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
1084 int
1085 linux_nice(struct thread *td, struct linux_nice_args *args)
1086 {
1087 
1088 	return (kern_setpriority(td, PRIO_PROCESS, 0, args->inc));
1089 }
1090 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
1091 
1092 int
1093 linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
1094 {
1095 	const int ngrp = args->gidsetsize;
1096 	struct ucred *newcred, *oldcred;
1097 	l_gid_t *linux_gidset;
1098 	int error;
1099 	struct proc *p;
1100 
1101 	if (ngrp < 0 || ngrp > ngroups_max)
1102 		return (EINVAL);
1103 	linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK);
1104 	error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t));
1105 	if (error)
1106 		goto out;
1107 
1108 	newcred = crget();
1109 	crextend(newcred, ngrp);
1110 	p = td->td_proc;
1111 	PROC_LOCK(p);
1112 	oldcred = crcopysafe(p, newcred);
1113 
1114 	if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS)) != 0) {
1115 		PROC_UNLOCK(p);
1116 		crfree(newcred);
1117 		goto out;
1118 	}
1119 
1120 	newcred->cr_ngroups = ngrp;
1121 	for (int i = 0; i < ngrp; i++)
1122 		newcred->cr_groups[i] = linux_gidset[i];
1123 	newcred->cr_flags |= CRED_FLAG_GROUPSET;
1124 
1125 	setsugid(p);
1126 	proc_set_cred(p, newcred);
1127 	PROC_UNLOCK(p);
1128 	crfree(oldcred);
1129 	error = 0;
1130 out:
1131 	free(linux_gidset, M_LINUX);
1132 	return (error);
1133 }
1134 
1135 int
1136 linux_getgroups(struct thread *td, struct linux_getgroups_args *args)
1137 {
1138 	const struct ucred *const cred = td->td_ucred;
1139 	l_gid_t *linux_gidset;
1140 	int ngrp, error;
1141 
1142 	ngrp = args->gidsetsize;
1143 
1144 	if (ngrp == 0) {
1145 		td->td_retval[0] = cred->cr_ngroups;
1146 		return (0);
1147 	}
1148 	if (ngrp < cred->cr_ngroups)
1149 		return (EINVAL);
1150 
1151 	ngrp = cred->cr_ngroups;
1152 
1153 	linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK);
1154 	for (int i = 0; i < ngrp; ++i)
1155 		linux_gidset[i] = cred->cr_groups[i];
1156 
1157 	error = copyout(linux_gidset, args->grouplist, ngrp * sizeof(l_gid_t));
1158 	free(linux_gidset, M_LINUX);
1159 
1160 	if (error != 0)
1161 		return (error);
1162 
1163 	td->td_retval[0] = ngrp;
1164 	return (0);
1165 }
1166 
1167 static bool
1168 linux_get_dummy_limit(struct thread *td, l_uint resource, struct rlimit *rlim)
1169 {
1170 	ssize_t size;
1171 	int res, error;
1172 
1173 	if (linux_dummy_rlimits == 0)
1174 		return (false);
1175 
1176 	switch (resource) {
1177 	case LINUX_RLIMIT_LOCKS:
1178 	case LINUX_RLIMIT_RTTIME:
1179 		rlim->rlim_cur = LINUX_RLIM_INFINITY;
1180 		rlim->rlim_max = LINUX_RLIM_INFINITY;
1181 		return (true);
1182 	case LINUX_RLIMIT_NICE:
1183 	case LINUX_RLIMIT_RTPRIO:
1184 		rlim->rlim_cur = 0;
1185 		rlim->rlim_max = 0;
1186 		return (true);
1187 	case LINUX_RLIMIT_SIGPENDING:
1188 		error = kernel_sysctlbyname(td,
1189 		    "kern.sigqueue.max_pending_per_proc",
1190 		    &res, &size, 0, 0, 0, 0);
1191 		if (error != 0)
1192 			return (false);
1193 		rlim->rlim_cur = res;
1194 		rlim->rlim_max = res;
1195 		return (true);
1196 	case LINUX_RLIMIT_MSGQUEUE:
1197 		error = kernel_sysctlbyname(td,
1198 		    "kern.ipc.msgmnb", &res, &size, 0, 0, 0, 0);
1199 		if (error != 0)
1200 			return (false);
1201 		rlim->rlim_cur = res;
1202 		rlim->rlim_max = res;
1203 		return (true);
1204 	default:
1205 		return (false);
1206 	}
1207 }
1208 
1209 int
1210 linux_setrlimit(struct thread *td, struct linux_setrlimit_args *args)
1211 {
1212 	struct rlimit bsd_rlim;
1213 	struct l_rlimit rlim;
1214 	u_int which;
1215 	int error;
1216 
1217 	if (args->resource >= LINUX_RLIM_NLIMITS)
1218 		return (EINVAL);
1219 
1220 	which = linux_to_bsd_resource[args->resource];
1221 	if (which == -1)
1222 		return (EINVAL);
1223 
1224 	error = copyin(args->rlim, &rlim, sizeof(rlim));
1225 	if (error)
1226 		return (error);
1227 
1228 	bsd_rlim.rlim_cur = (rlim_t)rlim.rlim_cur;
1229 	bsd_rlim.rlim_max = (rlim_t)rlim.rlim_max;
1230 	return (kern_setrlimit(td, which, &bsd_rlim));
1231 }
1232 
1233 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
1234 int
1235 linux_old_getrlimit(struct thread *td, struct linux_old_getrlimit_args *args)
1236 {
1237 	struct l_rlimit rlim;
1238 	struct rlimit bsd_rlim;
1239 	u_int which;
1240 
1241 	if (linux_get_dummy_limit(td, args->resource, &bsd_rlim)) {
1242 		rlim.rlim_cur = bsd_rlim.rlim_cur;
1243 		rlim.rlim_max = bsd_rlim.rlim_max;
1244 		return (copyout(&rlim, args->rlim, sizeof(rlim)));
1245 	}
1246 
1247 	if (args->resource >= LINUX_RLIM_NLIMITS)
1248 		return (EINVAL);
1249 
1250 	which = linux_to_bsd_resource[args->resource];
1251 	if (which == -1)
1252 		return (EINVAL);
1253 
1254 	lim_rlimit(td, which, &bsd_rlim);
1255 
1256 #ifdef COMPAT_LINUX32
1257 	rlim.rlim_cur = (unsigned int)bsd_rlim.rlim_cur;
1258 	if (rlim.rlim_cur == UINT_MAX)
1259 		rlim.rlim_cur = INT_MAX;
1260 	rlim.rlim_max = (unsigned int)bsd_rlim.rlim_max;
1261 	if (rlim.rlim_max == UINT_MAX)
1262 		rlim.rlim_max = INT_MAX;
1263 #else
1264 	rlim.rlim_cur = (unsigned long)bsd_rlim.rlim_cur;
1265 	if (rlim.rlim_cur == ULONG_MAX)
1266 		rlim.rlim_cur = LONG_MAX;
1267 	rlim.rlim_max = (unsigned long)bsd_rlim.rlim_max;
1268 	if (rlim.rlim_max == ULONG_MAX)
1269 		rlim.rlim_max = LONG_MAX;
1270 #endif
1271 	return (copyout(&rlim, args->rlim, sizeof(rlim)));
1272 }
1273 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
1274 
1275 int
1276 linux_getrlimit(struct thread *td, struct linux_getrlimit_args *args)
1277 {
1278 	struct l_rlimit rlim;
1279 	struct rlimit bsd_rlim;
1280 	u_int which;
1281 
1282 	if (linux_get_dummy_limit(td, args->resource, &bsd_rlim)) {
1283 		rlim.rlim_cur = bsd_rlim.rlim_cur;
1284 		rlim.rlim_max = bsd_rlim.rlim_max;
1285 		return (copyout(&rlim, args->rlim, sizeof(rlim)));
1286 	}
1287 
1288 	if (args->resource >= LINUX_RLIM_NLIMITS)
1289 		return (EINVAL);
1290 
1291 	which = linux_to_bsd_resource[args->resource];
1292 	if (which == -1)
1293 		return (EINVAL);
1294 
1295 	lim_rlimit(td, which, &bsd_rlim);
1296 
1297 	rlim.rlim_cur = (l_ulong)bsd_rlim.rlim_cur;
1298 	rlim.rlim_max = (l_ulong)bsd_rlim.rlim_max;
1299 	return (copyout(&rlim, args->rlim, sizeof(rlim)));
1300 }
1301 
1302 int
1303 linux_sched_setscheduler(struct thread *td,
1304     struct linux_sched_setscheduler_args *args)
1305 {
1306 	struct sched_param sched_param;
1307 	struct thread *tdt;
1308 	int error, policy;
1309 
1310 	switch (args->policy) {
1311 	case LINUX_SCHED_OTHER:
1312 		policy = SCHED_OTHER;
1313 		break;
1314 	case LINUX_SCHED_FIFO:
1315 		policy = SCHED_FIFO;
1316 		break;
1317 	case LINUX_SCHED_RR:
1318 		policy = SCHED_RR;
1319 		break;
1320 	default:
1321 		return (EINVAL);
1322 	}
1323 
1324 	error = copyin(args->param, &sched_param, sizeof(sched_param));
1325 	if (error)
1326 		return (error);
1327 
1328 	if (linux_map_sched_prio) {
1329 		switch (policy) {
1330 		case SCHED_OTHER:
1331 			if (sched_param.sched_priority != 0)
1332 				return (EINVAL);
1333 
1334 			sched_param.sched_priority =
1335 			    PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE;
1336 			break;
1337 		case SCHED_FIFO:
1338 		case SCHED_RR:
1339 			if (sched_param.sched_priority < 1 ||
1340 			    sched_param.sched_priority >= LINUX_MAX_RT_PRIO)
1341 				return (EINVAL);
1342 
1343 			/*
1344 			 * Map [1, LINUX_MAX_RT_PRIO - 1] to
1345 			 * [0, RTP_PRIO_MAX - RTP_PRIO_MIN] (rounding down).
1346 			 */
1347 			sched_param.sched_priority =
1348 			    (sched_param.sched_priority - 1) *
1349 			    (RTP_PRIO_MAX - RTP_PRIO_MIN + 1) /
1350 			    (LINUX_MAX_RT_PRIO - 1);
1351 			break;
1352 		}
1353 	}
1354 
1355 	tdt = linux_tdfind(td, args->pid, -1);
1356 	if (tdt == NULL)
1357 		return (ESRCH);
1358 
1359 	error = kern_sched_setscheduler(td, tdt, policy, &sched_param);
1360 	PROC_UNLOCK(tdt->td_proc);
1361 	return (error);
1362 }
1363 
1364 int
1365 linux_sched_getscheduler(struct thread *td,
1366     struct linux_sched_getscheduler_args *args)
1367 {
1368 	struct thread *tdt;
1369 	int error, policy;
1370 
1371 	tdt = linux_tdfind(td, args->pid, -1);
1372 	if (tdt == NULL)
1373 		return (ESRCH);
1374 
1375 	error = kern_sched_getscheduler(td, tdt, &policy);
1376 	PROC_UNLOCK(tdt->td_proc);
1377 
1378 	switch (policy) {
1379 	case SCHED_OTHER:
1380 		td->td_retval[0] = LINUX_SCHED_OTHER;
1381 		break;
1382 	case SCHED_FIFO:
1383 		td->td_retval[0] = LINUX_SCHED_FIFO;
1384 		break;
1385 	case SCHED_RR:
1386 		td->td_retval[0] = LINUX_SCHED_RR;
1387 		break;
1388 	}
1389 	return (error);
1390 }
1391 
1392 static int
1393 bsd_sched_policy_to_linux_sched_policy(int bsd_policy)
1394 {
1395 
1396 	switch (bsd_policy) {
1397 	case SCHED_FIFO:
1398 		return (LINUX_SCHED_FIFO);
1399 	case SCHED_RR:
1400 		return (LINUX_SCHED_RR);
1401 	case SCHED_OTHER:
1402 		/* FALLTHROUGH */
1403 	default:
1404 		return (LINUX_SCHED_OTHER);
1405 	}
1406 }
1407 
1408 int
1409 linux_sched_getattr(struct thread *td, struct linux_sched_getattr_args *args)
1410 {
1411 	struct linux_sched_attr lattr;
1412 	struct sched_param bsd;
1413 	struct thread *tdt;
1414 	int error, policy;
1415 
1416 	if (args->attr == NULL || args->pid < 0 || args->flags != 0 ||
1417 	    args->size < LINUX_SCHED_ATTR_SIZE_VER0 || args->size > PAGE_SIZE)
1418 		return (EINVAL);
1419 
1420 	tdt = linux_tdfind(td, args->pid, -1);
1421 	if (tdt == NULL)
1422 		return (ESRCH);
1423 
1424 	error = kern_sched_getscheduler(td, tdt, &policy);
1425 	if (error != 0) {
1426 		PROC_UNLOCK(tdt->td_proc);
1427 		return (error);
1428 	}
1429 
1430 	error = kern_sched_getparam(td, tdt, &bsd);
1431 	PROC_UNLOCK(tdt->td_proc);
1432 	if (error != 0)
1433 		return (error);
1434 
1435 	memset(&lattr, 0, sizeof(lattr));
1436 	lattr.size = MIN(args->size, sizeof(lattr));
1437 	lattr.sched_policy = bsd_sched_policy_to_linux_sched_policy(policy);
1438 	/*
1439 	 * TODO(PR#299617,ngie): fill in `.sched_nice` with policies like
1440 	 * `LINUX_SCHED_NORMAL`, etc.
1441 	 */
1442 
1443 	if (linux_map_sched_prio) {
1444 		switch (lattr.sched_policy) {
1445 		case LINUX_SCHED_OTHER:
1446 			lattr.sched_priority = 0;
1447 			break;
1448 		case LINUX_SCHED_FIFO:
1449 		case LINUX_SCHED_RR:
1450 			/**
1451 			 * Map [0, RTP_PRIO_MAX - RTP_PRIO_MIN] to
1452 			 * [1, LINUX_MAX_RT_PRIO - 1] (rounding up).
1453 			 */
1454 			lattr.sched_priority =
1455 			    (bsd.sched_priority *
1456 				    (LINUX_MAX_RT_PRIO - 1) +
1457 				(RTP_PRIO_MAX - RTP_PRIO_MIN - 1)) /
1458 				(RTP_PRIO_MAX - RTP_PRIO_MIN) + 1;
1459 			break;
1460 		}
1461 	} else {
1462 		lattr.sched_priority = bsd.sched_priority;
1463 	}
1464 
1465 	return (copyout(&lattr, args->attr, lattr.size));
1466 }
1467 
1468 int
1469 linux_sched_get_priority_max(struct thread *td,
1470     struct linux_sched_get_priority_max_args *args)
1471 {
1472 	struct sched_get_priority_max_args bsd;
1473 
1474 	if (linux_map_sched_prio) {
1475 		switch (args->policy) {
1476 		case LINUX_SCHED_OTHER:
1477 			td->td_retval[0] = 0;
1478 			return (0);
1479 		case LINUX_SCHED_FIFO:
1480 		case LINUX_SCHED_RR:
1481 			td->td_retval[0] = LINUX_MAX_RT_PRIO - 1;
1482 			return (0);
1483 		default:
1484 			return (EINVAL);
1485 		}
1486 	}
1487 
1488 	switch (args->policy) {
1489 	case LINUX_SCHED_OTHER:
1490 		bsd.policy = SCHED_OTHER;
1491 		break;
1492 	case LINUX_SCHED_FIFO:
1493 		bsd.policy = SCHED_FIFO;
1494 		break;
1495 	case LINUX_SCHED_RR:
1496 		bsd.policy = SCHED_RR;
1497 		break;
1498 	default:
1499 		return (EINVAL);
1500 	}
1501 	return (sys_sched_get_priority_max(td, &bsd));
1502 }
1503 
1504 int
1505 linux_sched_get_priority_min(struct thread *td,
1506     struct linux_sched_get_priority_min_args *args)
1507 {
1508 	struct sched_get_priority_min_args bsd;
1509 
1510 	if (linux_map_sched_prio) {
1511 		switch (args->policy) {
1512 		case LINUX_SCHED_OTHER:
1513 			td->td_retval[0] = 0;
1514 			return (0);
1515 		case LINUX_SCHED_FIFO:
1516 		case LINUX_SCHED_RR:
1517 			td->td_retval[0] = 1;
1518 			return (0);
1519 		default:
1520 			return (EINVAL);
1521 		}
1522 	}
1523 
1524 	switch (args->policy) {
1525 	case LINUX_SCHED_OTHER:
1526 		bsd.policy = SCHED_OTHER;
1527 		break;
1528 	case LINUX_SCHED_FIFO:
1529 		bsd.policy = SCHED_FIFO;
1530 		break;
1531 	case LINUX_SCHED_RR:
1532 		bsd.policy = SCHED_RR;
1533 		break;
1534 	default:
1535 		return (EINVAL);
1536 	}
1537 	return (sys_sched_get_priority_min(td, &bsd));
1538 }
1539 
1540 #define REBOOT_CAD_ON	0x89abcdef
1541 #define REBOOT_CAD_OFF	0
1542 #define REBOOT_HALT	0xcdef0123
1543 #define REBOOT_RESTART	0x01234567
1544 #define REBOOT_RESTART2	0xA1B2C3D4
1545 #define REBOOT_POWEROFF	0x4321FEDC
1546 #define REBOOT_MAGIC1	0xfee1dead
1547 #define REBOOT_MAGIC2	0x28121969
1548 #define REBOOT_MAGIC2A	0x05121996
1549 #define REBOOT_MAGIC2B	0x16041998
1550 
1551 int
1552 linux_reboot(struct thread *td, struct linux_reboot_args *args)
1553 {
1554 	struct reboot_args bsd_args;
1555 
1556 	if (args->magic1 != REBOOT_MAGIC1)
1557 		return (EINVAL);
1558 
1559 	switch (args->magic2) {
1560 	case REBOOT_MAGIC2:
1561 	case REBOOT_MAGIC2A:
1562 	case REBOOT_MAGIC2B:
1563 		break;
1564 	default:
1565 		return (EINVAL);
1566 	}
1567 
1568 	switch (args->cmd) {
1569 	case REBOOT_CAD_ON:
1570 	case REBOOT_CAD_OFF:
1571 		return (priv_check(td, PRIV_REBOOT));
1572 	case REBOOT_HALT:
1573 		bsd_args.opt = RB_HALT;
1574 		break;
1575 	case REBOOT_RESTART:
1576 	case REBOOT_RESTART2:
1577 		bsd_args.opt = 0;
1578 		break;
1579 	case REBOOT_POWEROFF:
1580 		bsd_args.opt = RB_POWEROFF;
1581 		break;
1582 	default:
1583 		return (EINVAL);
1584 	}
1585 	return (sys_reboot(td, &bsd_args));
1586 }
1587 
1588 int
1589 linux_getpid(struct thread *td, struct linux_getpid_args *args)
1590 {
1591 
1592 	td->td_retval[0] = td->td_proc->p_pid;
1593 
1594 	return (0);
1595 }
1596 
1597 int
1598 linux_gettid(struct thread *td, struct linux_gettid_args *args)
1599 {
1600 	struct linux_emuldata *em;
1601 
1602 	em = em_find(td);
1603 	KASSERT(em != NULL, ("gettid: emuldata not found.\n"));
1604 
1605 	td->td_retval[0] = em->em_tid;
1606 
1607 	return (0);
1608 }
1609 
1610 int
1611 linux_getppid(struct thread *td, struct linux_getppid_args *args)
1612 {
1613 
1614 	td->td_retval[0] = kern_getppid(td);
1615 	return (0);
1616 }
1617 
1618 int
1619 linux_getgid(struct thread *td, struct linux_getgid_args *args)
1620 {
1621 
1622 	td->td_retval[0] = td->td_ucred->cr_rgid;
1623 	return (0);
1624 }
1625 
1626 int
1627 linux_getuid(struct thread *td, struct linux_getuid_args *args)
1628 {
1629 
1630 	td->td_retval[0] = td->td_ucred->cr_ruid;
1631 	return (0);
1632 }
1633 
1634 int
1635 linux_getsid(struct thread *td, struct linux_getsid_args *args)
1636 {
1637 
1638 	return (kern_getsid(td, args->pid));
1639 }
1640 
1641 int
1642 linux_getpriority(struct thread *td, struct linux_getpriority_args *args)
1643 {
1644 	int error;
1645 
1646 	error = kern_getpriority(td, args->which, args->who);
1647 	td->td_retval[0] = 20 - td->td_retval[0];
1648 	return (error);
1649 }
1650 
1651 int
1652 linux_sethostname(struct thread *td, struct linux_sethostname_args *args)
1653 {
1654 	int name[2];
1655 
1656 	name[0] = CTL_KERN;
1657 	name[1] = KERN_HOSTNAME;
1658 	return (userland_sysctl(td, name, 2, 0, 0, 0, args->hostname,
1659 	    args->len, 0, 0));
1660 }
1661 
1662 int
1663 linux_setdomainname(struct thread *td, struct linux_setdomainname_args *args)
1664 {
1665 	int name[2];
1666 
1667 	name[0] = CTL_KERN;
1668 	name[1] = KERN_NISDOMAINNAME;
1669 	return (userland_sysctl(td, name, 2, 0, 0, 0, args->name,
1670 	    args->len, 0, 0));
1671 }
1672 
1673 int
1674 linux_exit_group(struct thread *td, struct linux_exit_group_args *args)
1675 {
1676 
1677 	LINUX_CTR2(exit_group, "thread(%d) (%d)", td->td_tid,
1678 	    args->error_code);
1679 
1680 	/*
1681 	 * XXX: we should send a signal to the parent if
1682 	 * SIGNAL_EXIT_GROUP is set. We ignore that (temporarily?)
1683 	 * as it doesnt occur often.
1684 	 */
1685 	kern_exit(td, args->error_code, 0);
1686 	return (0);
1687 }
1688 
1689 #define _LINUX_CAPABILITY_VERSION_1  0x19980330
1690 #define _LINUX_CAPABILITY_VERSION_2  0x20071026
1691 #define _LINUX_CAPABILITY_VERSION_3  0x20080522
1692 
1693 struct l_user_cap_header {
1694 	l_int	version;
1695 	l_int	pid;
1696 };
1697 
1698 struct l_user_cap_data {
1699 	l_int	effective;
1700 	l_int	permitted;
1701 	l_int	inheritable;
1702 };
1703 
1704 int
1705 linux_capget(struct thread *td, struct linux_capget_args *uap)
1706 {
1707 	struct l_user_cap_header luch;
1708 	struct l_user_cap_data lucd[2];
1709 	int error, u32s;
1710 
1711 	if (uap->hdrp == NULL)
1712 		return (EFAULT);
1713 
1714 	error = copyin(uap->hdrp, &luch, sizeof(luch));
1715 	if (error != 0)
1716 		return (error);
1717 
1718 	switch (luch.version) {
1719 	case _LINUX_CAPABILITY_VERSION_1:
1720 		u32s = 1;
1721 		break;
1722 	case _LINUX_CAPABILITY_VERSION_2:
1723 	case _LINUX_CAPABILITY_VERSION_3:
1724 		u32s = 2;
1725 		break;
1726 	default:
1727 		luch.version = _LINUX_CAPABILITY_VERSION_1;
1728 		error = copyout(&luch, uap->hdrp, sizeof(luch));
1729 		if (error)
1730 			return (error);
1731 		return (EINVAL);
1732 	}
1733 
1734 	if (luch.pid)
1735 		return (EPERM);
1736 
1737 	if (uap->datap) {
1738 		/*
1739 		 * The current implementation doesn't support setting
1740 		 * a capability (it's essentially a stub) so indicate
1741 		 * that no capabilities are currently set or available
1742 		 * to request.
1743 		 */
1744 		memset(&lucd, 0, u32s * sizeof(lucd[0]));
1745 		error = copyout(&lucd, uap->datap, u32s * sizeof(lucd[0]));
1746 	}
1747 
1748 	return (error);
1749 }
1750 
1751 int
1752 linux_capset(struct thread *td, struct linux_capset_args *uap)
1753 {
1754 	struct l_user_cap_header luch;
1755 	struct l_user_cap_data lucd[2];
1756 	int error, i, u32s;
1757 
1758 	if (uap->hdrp == NULL || uap->datap == NULL)
1759 		return (EFAULT);
1760 
1761 	error = copyin(uap->hdrp, &luch, sizeof(luch));
1762 	if (error != 0)
1763 		return (error);
1764 
1765 	switch (luch.version) {
1766 	case _LINUX_CAPABILITY_VERSION_1:
1767 		u32s = 1;
1768 		break;
1769 	case _LINUX_CAPABILITY_VERSION_2:
1770 	case _LINUX_CAPABILITY_VERSION_3:
1771 		u32s = 2;
1772 		break;
1773 	default:
1774 		luch.version = _LINUX_CAPABILITY_VERSION_1;
1775 		error = copyout(&luch, uap->hdrp, sizeof(luch));
1776 		if (error)
1777 			return (error);
1778 		return (EINVAL);
1779 	}
1780 
1781 	if (luch.pid)
1782 		return (EPERM);
1783 
1784 	error = copyin(uap->datap, &lucd, u32s * sizeof(lucd[0]));
1785 	if (error != 0)
1786 		return (error);
1787 
1788 	/* We currently don't support setting any capabilities. */
1789 	for (i = 0; i < u32s; i++) {
1790 		if (lucd[i].effective || lucd[i].permitted ||
1791 		    lucd[i].inheritable) {
1792 			linux_msg(td,
1793 			    "capset[%d] effective=0x%x, permitted=0x%x, "
1794 			    "inheritable=0x%x is not implemented", i,
1795 			    (int)lucd[i].effective, (int)lucd[i].permitted,
1796 			    (int)lucd[i].inheritable);
1797 			return (EPERM);
1798 		}
1799 	}
1800 
1801 	return (0);
1802 }
1803 
1804 int
1805 linux_prctl(struct thread *td, struct linux_prctl_args *args)
1806 {
1807 	int error = 0, max_size, arg;
1808 	struct proc *p = td->td_proc;
1809 	char comm[LINUX_MAX_COMM_LEN];
1810 	int pdeath_signal, trace_state;
1811 
1812 	switch (args->option) {
1813 	case LINUX_PR_SET_PDEATHSIG:
1814 		if (!LINUX_SIG_VALID(args->arg2))
1815 			return (EINVAL);
1816 		pdeath_signal = linux_to_bsd_signal(args->arg2);
1817 		return (kern_procctl(td, P_PID, 0, PROC_PDEATHSIG_CTL,
1818 		    &pdeath_signal));
1819 	case LINUX_PR_GET_PDEATHSIG:
1820 		error = kern_procctl(td, P_PID, 0, PROC_PDEATHSIG_STATUS,
1821 		    &pdeath_signal);
1822 		if (error != 0)
1823 			return (error);
1824 		pdeath_signal = bsd_to_linux_signal(pdeath_signal);
1825 		return (copyout(&pdeath_signal,
1826 		    (void *)(register_t)args->arg2,
1827 		    sizeof(pdeath_signal)));
1828 	/*
1829 	 * In Linux, this flag controls if set[gu]id processes can coredump.
1830 	 * There are additional semantics imposed on processes that cannot
1831 	 * coredump:
1832 	 * - Such processes can not be ptraced.
1833 	 * - There are some semantics around ownership of process-related files
1834 	 *   in the /proc namespace.
1835 	 *
1836 	 * In FreeBSD, we can (and by default, do) disable setuid coredump
1837 	 * system-wide with 'sugid_coredump.'  We control tracability on a
1838 	 * per-process basis with the procctl PROC_TRACE (=> P2_NOTRACE flag).
1839 	 * By happy coincidence, P2_NOTRACE also prevents coredumping.  So the
1840 	 * procctl is roughly analogous to Linux's DUMPABLE.
1841 	 *
1842 	 * So, proxy these knobs to the corresponding PROC_TRACE setting.
1843 	 */
1844 	case LINUX_PR_GET_DUMPABLE:
1845 		error = kern_procctl(td, P_PID, p->p_pid, PROC_TRACE_STATUS,
1846 		    &trace_state);
1847 		if (error != 0)
1848 			return (error);
1849 		td->td_retval[0] = (trace_state != -1);
1850 		return (0);
1851 	case LINUX_PR_SET_DUMPABLE:
1852 		/*
1853 		 * It is only valid for userspace to set one of these two
1854 		 * flags, and only one at a time.
1855 		 */
1856 		switch (args->arg2) {
1857 		case LINUX_SUID_DUMP_DISABLE:
1858 			trace_state = PROC_TRACE_CTL_DISABLE_EXEC;
1859 			break;
1860 		case LINUX_SUID_DUMP_USER:
1861 			trace_state = PROC_TRACE_CTL_ENABLE;
1862 			break;
1863 		default:
1864 			return (EINVAL);
1865 		}
1866 		return (kern_procctl(td, P_PID, p->p_pid, PROC_TRACE_CTL,
1867 		    &trace_state));
1868 	case LINUX_PR_GET_KEEPCAPS:
1869 		/*
1870 		 * Indicate that we always clear the effective and
1871 		 * permitted capability sets when the user id becomes
1872 		 * non-zero (actually the capability sets are simply
1873 		 * always zero in the current implementation).
1874 		 */
1875 		td->td_retval[0] = 0;
1876 		break;
1877 	case LINUX_PR_SET_KEEPCAPS:
1878 		/*
1879 		 * Ignore requests to keep the effective and permitted
1880 		 * capability sets when the user id becomes non-zero.
1881 		 */
1882 		break;
1883 	case LINUX_PR_SET_NAME:
1884 		/*
1885 		 * To be on the safe side we need to make sure to not
1886 		 * overflow the size a Linux program expects. We already
1887 		 * do this here in the copyin, so that we don't need to
1888 		 * check on copyout.
1889 		 */
1890 		max_size = MIN(sizeof(comm), sizeof(p->p_comm));
1891 		error = copyinstr((void *)(register_t)args->arg2, comm,
1892 		    max_size, NULL);
1893 
1894 		/* Linux silently truncates the name if it is too long. */
1895 		if (error == ENAMETOOLONG) {
1896 			/*
1897 			 * XXX: copyinstr() isn't documented to populate the
1898 			 * array completely, so do a copyin() to be on the
1899 			 * safe side. This should be changed in case
1900 			 * copyinstr() is changed to guarantee this.
1901 			 */
1902 			error = copyin((void *)(register_t)args->arg2, comm,
1903 			    max_size - 1);
1904 			comm[max_size - 1] = '\0';
1905 		}
1906 		if (error)
1907 			return (error);
1908 
1909 		PROC_LOCK(p);
1910 		strlcpy(p->p_comm, comm, sizeof(p->p_comm));
1911 		PROC_UNLOCK(p);
1912 		break;
1913 	case LINUX_PR_GET_NAME:
1914 		PROC_LOCK(p);
1915 		strlcpy(comm, p->p_comm, sizeof(comm));
1916 		PROC_UNLOCK(p);
1917 		error = copyout(comm, (void *)(register_t)args->arg2,
1918 		    strlen(comm) + 1);
1919 		break;
1920 	case LINUX_PR_GET_SECCOMP:
1921 	case LINUX_PR_SET_SECCOMP:
1922 		/*
1923 		 * Same as returned by Linux without CONFIG_SECCOMP enabled.
1924 		 */
1925 		error = EINVAL;
1926 		break;
1927 	case LINUX_PR_CAPBSET_READ:
1928 #if 0
1929 		/*
1930 		 * This makes too much noise with Ubuntu Focal.
1931 		 */
1932 		linux_msg(td, "unsupported prctl PR_CAPBSET_READ %d",
1933 		    (int)args->arg2);
1934 #endif
1935 		error = EINVAL;
1936 		break;
1937 	case LINUX_PR_SET_CHILD_SUBREAPER:
1938 		if (args->arg2 == 0) {
1939 			return (kern_procctl(td, P_PID, 0, PROC_REAP_RELEASE,
1940 			    NULL));
1941 		}
1942 
1943 		return (kern_procctl(td, P_PID, 0, PROC_REAP_ACQUIRE,
1944 		    NULL));
1945 	case LINUX_PR_GET_CHILD_SUBREAPER: {
1946 		struct procctl_reaper_status rs;
1947 		l_int val;
1948 
1949 		error = kern_procctl(td, P_PID, 0, PROC_REAP_STATUS, &rs);
1950 		if (error != 0)
1951 			return (error);
1952 		val = rs.rs_reaper == p->p_pid ? 1 : 0;
1953 		error = copyout(&val, (void *)(register_t)args->arg2,
1954 		    sizeof(val));
1955 		break;
1956 	}
1957 	case LINUX_PR_SET_NO_NEW_PRIVS:
1958 		arg = args->arg2 == 1 ?
1959 		    PROC_NO_NEW_PRIVS_ENABLE : PROC_NO_NEW_PRIVS_DISABLE;
1960 		error = kern_procctl(td, P_PID, p->p_pid,
1961 		    PROC_NO_NEW_PRIVS_CTL, &arg);
1962 		break;
1963 	case LINUX_PR_GET_NO_NEW_PRIVS:
1964 		error = kern_procctl(td, P_PID, p->p_pid,
1965 		    PROC_NO_NEW_PRIVS_STATUS, &arg);
1966 		if (error != 0)
1967 			return (error);
1968 		/* Linux returns the value as the syscall return */
1969 		td->td_retval[0] = arg == PROC_NO_NEW_PRIVS_ENABLE ? 1 : 0;
1970 		break;
1971 	case LINUX_PR_SET_PTRACER:
1972 		linux_msg(td, "unsupported prctl PR_SET_PTRACER");
1973 		error = EINVAL;
1974 		break;
1975 	case LINUX_PR_SET_VMA:
1976 		if (args->arg2 != LINUX_PR_SET_VMA_ANON_NAME) {
1977 			linux_msg(td, "unsupported prctl PR_SET_VMA attr %ju",
1978 			    (uintmax_t)args->arg2);
1979 			error = EINVAL;
1980 		}
1981 		break;
1982 	case LINUX_PR_GET_THP_DISABLE:
1983 		/*
1984 		 * THP not in play, since FreeBSD doesn't have THP. Although
1985 		 * similar, superpages don't have the crazy issues THP does, so
1986 		 * tell the best lie possible: there's no problems with crazy
1987 		 * latency spikes: this feature is disabled.
1988 		 */
1989 
1990 		td->td_retval[0] = 1;
1991 		break;
1992 	case LINUX_PR_SET_THP_DISABLE:
1993 		/*
1994 		 * Accept anything that's valid: Linux treats any nonzero
1995 		 * arg2 as "disable", so there's nothing to reject here.
1996 		 */
1997 		td->td_retval[0] = 0;
1998 		break;
1999 	default:
2000 		linux_msg(td, "unsupported prctl option %d", args->option);
2001 		error = EINVAL;
2002 		break;
2003 	}
2004 
2005 	return (error);
2006 }
2007 
2008 int
2009 linux_sched_setparam(struct thread *td,
2010     struct linux_sched_setparam_args *uap)
2011 {
2012 	struct sched_param sched_param;
2013 	struct thread *tdt;
2014 	int error, policy;
2015 
2016 	error = copyin(uap->param, &sched_param, sizeof(sched_param));
2017 	if (error)
2018 		return (error);
2019 
2020 	tdt = linux_tdfind(td, uap->pid, -1);
2021 	if (tdt == NULL)
2022 		return (ESRCH);
2023 
2024 	if (linux_map_sched_prio) {
2025 		error = kern_sched_getscheduler(td, tdt, &policy);
2026 		if (error)
2027 			goto out;
2028 
2029 		switch (policy) {
2030 		case SCHED_OTHER:
2031 			if (sched_param.sched_priority != 0) {
2032 				error = EINVAL;
2033 				goto out;
2034 			}
2035 			sched_param.sched_priority =
2036 			    PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE;
2037 			break;
2038 		case SCHED_FIFO:
2039 		case SCHED_RR:
2040 			if (sched_param.sched_priority < 1 ||
2041 			    sched_param.sched_priority >= LINUX_MAX_RT_PRIO) {
2042 				error = EINVAL;
2043 				goto out;
2044 			}
2045 			/*
2046 			 * Map [1, LINUX_MAX_RT_PRIO - 1] to
2047 			 * [0, RTP_PRIO_MAX - RTP_PRIO_MIN] (rounding down).
2048 			 */
2049 			sched_param.sched_priority =
2050 			    (sched_param.sched_priority - 1) *
2051 			    (RTP_PRIO_MAX - RTP_PRIO_MIN + 1) /
2052 			    (LINUX_MAX_RT_PRIO - 1);
2053 			break;
2054 		}
2055 	}
2056 
2057 	error = kern_sched_setparam(td, tdt, &sched_param);
2058 out:	PROC_UNLOCK(tdt->td_proc);
2059 	return (error);
2060 }
2061 
2062 int
2063 linux_sched_getparam(struct thread *td,
2064     struct linux_sched_getparam_args *uap)
2065 {
2066 	struct sched_param sched_param;
2067 	struct thread *tdt;
2068 	int error, policy;
2069 
2070 	tdt = linux_tdfind(td, uap->pid, -1);
2071 	if (tdt == NULL)
2072 		return (ESRCH);
2073 
2074 	error = kern_sched_getparam(td, tdt, &sched_param);
2075 	if (error) {
2076 		PROC_UNLOCK(tdt->td_proc);
2077 		return (error);
2078 	}
2079 
2080 	if (linux_map_sched_prio) {
2081 		error = kern_sched_getscheduler(td, tdt, &policy);
2082 		PROC_UNLOCK(tdt->td_proc);
2083 		if (error)
2084 			return (error);
2085 
2086 		switch (policy) {
2087 		case SCHED_OTHER:
2088 			sched_param.sched_priority = 0;
2089 			break;
2090 		case SCHED_FIFO:
2091 		case SCHED_RR:
2092 			/*
2093 			 * Map [0, RTP_PRIO_MAX - RTP_PRIO_MIN] to
2094 			 * [1, LINUX_MAX_RT_PRIO - 1] (rounding up).
2095 			 */
2096 			sched_param.sched_priority =
2097 			    (sched_param.sched_priority *
2098 			    (LINUX_MAX_RT_PRIO - 1) +
2099 			    (RTP_PRIO_MAX - RTP_PRIO_MIN - 1)) /
2100 			    (RTP_PRIO_MAX - RTP_PRIO_MIN) + 1;
2101 			break;
2102 		}
2103 	} else
2104 		PROC_UNLOCK(tdt->td_proc);
2105 
2106 	error = copyout(&sched_param, uap->param, sizeof(sched_param));
2107 	return (error);
2108 }
2109 
2110 /*
2111  * Get affinity of a process.
2112  */
2113 int
2114 linux_sched_getaffinity(struct thread *td,
2115     struct linux_sched_getaffinity_args *args)
2116 {
2117 	struct thread *tdt;
2118 	cpuset_t *mask;
2119 	size_t size;
2120 	int error;
2121 	id_t tid;
2122 
2123 	tdt = linux_tdfind(td, args->pid, -1);
2124 	if (tdt == NULL)
2125 		return (ESRCH);
2126 	tid = tdt->td_tid;
2127 	PROC_UNLOCK(tdt->td_proc);
2128 
2129 	mask = malloc(sizeof(cpuset_t), M_LINUX, M_WAITOK | M_ZERO);
2130 	size = min(args->len, sizeof(cpuset_t));
2131 	error = kern_cpuset_getaffinity(td, CPU_LEVEL_WHICH, CPU_WHICH_TID,
2132 	    tid, size, mask);
2133 	if (error == ERANGE)
2134 		error = EINVAL;
2135  	if (error == 0)
2136 		error = copyout(mask, args->user_mask_ptr, size);
2137 	if (error == 0)
2138 		td->td_retval[0] = size;
2139 	free(mask, M_LINUX);
2140 	return (error);
2141 }
2142 
2143 /*
2144  *  Set affinity of a process.
2145  */
2146 int
2147 linux_sched_setaffinity(struct thread *td,
2148     struct linux_sched_setaffinity_args *args)
2149 {
2150 	struct thread *tdt;
2151 	cpuset_t *mask;
2152 	int cpu, error;
2153 	size_t len;
2154 	id_t tid;
2155 
2156 	tdt = linux_tdfind(td, args->pid, -1);
2157 	if (tdt == NULL)
2158 		return (ESRCH);
2159 	tid = tdt->td_tid;
2160 	PROC_UNLOCK(tdt->td_proc);
2161 
2162 	len = min(args->len, sizeof(cpuset_t));
2163 	mask = malloc(sizeof(cpuset_t), M_TEMP, M_WAITOK | M_ZERO);
2164 	error = copyin(args->user_mask_ptr, mask, len);
2165 	if (error != 0)
2166 		goto out;
2167 	/* Linux ignore high bits */
2168 	CPU_FOREACH_ISSET(cpu, mask)
2169 		if (cpu > mp_maxid)
2170 			CPU_CLR(cpu, mask);
2171 
2172 	error = kern_cpuset_setaffinity(td, CPU_LEVEL_WHICH, CPU_WHICH_TID,
2173 	    tid, mask);
2174 	if (error == EDEADLK)
2175 		error = EINVAL;
2176 out:
2177 	free(mask, M_TEMP);
2178 	return (error);
2179 }
2180 
2181 struct linux_rlimit64 {
2182 	uint64_t	rlim_cur;
2183 	uint64_t	rlim_max;
2184 };
2185 
2186 int
2187 linux_prlimit64(struct thread *td, struct linux_prlimit64_args *args)
2188 {
2189 	struct rlimit rlim, nrlim;
2190 	struct linux_rlimit64 lrlim;
2191 	struct proc *p;
2192 	u_int which;
2193 	int flags;
2194 	int error;
2195 	bool exec_blocked;
2196 
2197 	if (args->new == NULL && args->old != NULL) {
2198 		if (linux_get_dummy_limit(td, args->resource, &rlim)) {
2199 			lrlim.rlim_cur = rlim.rlim_cur;
2200 			lrlim.rlim_max = rlim.rlim_max;
2201 			return (copyout(&lrlim, args->old, sizeof(lrlim)));
2202 		}
2203 	}
2204 
2205 	if (args->resource >= LINUX_RLIM_NLIMITS)
2206 		return (EINVAL);
2207 
2208 	which = linux_to_bsd_resource[args->resource];
2209 	if (which == -1)
2210 		return (EINVAL);
2211 
2212 	if (args->new != NULL) {
2213 		/*
2214 		 * Note. Unlike FreeBSD where rlim is signed 64-bit Linux
2215 		 * rlim is unsigned 64-bit. FreeBSD treats negative limits
2216 		 * as INFINITY so we do not need a conversion even.
2217 		 */
2218 		error = copyin(args->new, &nrlim, sizeof(nrlim));
2219 		if (error != 0)
2220 			return (error);
2221 	}
2222 
2223 	exec_blocked = false;
2224 	flags = PGET_HOLD | PGET_NOTWEXIT;
2225 	if (args->new != NULL)
2226 		flags |= PGET_CANDEBUG;
2227 	else
2228 		flags |= PGET_CANSEE;
2229 	if (args->pid == 0) {
2230 		p = td->td_proc;
2231 		PHOLD(p);
2232 	} else {
2233 		error = pget(args->pid, flags, &p);
2234 		if (error != 0)
2235 			return (error);
2236 		exec_blocked = true;
2237 		PROC_LOCK(p);
2238 		execve_block_wait(td, p);
2239 		error = args->new != NULL ? p_candebug(td, p) :
2240 		    p_cansee(td, p);
2241 		PROC_UNLOCK(p);
2242 		if (error != 0)
2243 			goto out;
2244 	}
2245 	if (args->old != NULL) {
2246 		PROC_LOCK(p);
2247 		lim_rlimit_proc(p, which, &rlim);
2248 		PROC_UNLOCK(p);
2249 		if (rlim.rlim_cur == RLIM_INFINITY)
2250 			lrlim.rlim_cur = LINUX_RLIM_INFINITY;
2251 		else
2252 			lrlim.rlim_cur = rlim.rlim_cur;
2253 		if (rlim.rlim_max == RLIM_INFINITY)
2254 			lrlim.rlim_max = LINUX_RLIM_INFINITY;
2255 		else
2256 			lrlim.rlim_max = rlim.rlim_max;
2257 		error = copyout(&lrlim, args->old, sizeof(lrlim));
2258 		if (error != 0)
2259 			goto out;
2260 	}
2261 
2262 	if (args->new != NULL)
2263 		error = kern_proc_setrlimit(td, p, which, &nrlim);
2264 
2265  out:
2266 	if (exec_blocked) {
2267 		PROC_LOCK(p);
2268 		execve_unblock(td, p);
2269 		PROC_UNLOCK(p);
2270 	}
2271 	PRELE(p);
2272 	return (error);
2273 }
2274 
2275 int
2276 linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
2277 {
2278 	struct timespec ts, *tsp;
2279 	int error;
2280 
2281 	if (args->tsp != NULL) {
2282 		error = linux_get_timespec(&ts, args->tsp);
2283 		if (error != 0)
2284 			return (error);
2285 		tsp = &ts;
2286 	} else
2287 		tsp = NULL;
2288 
2289 	error = linux_common_pselect6(td, args->nfds, args->readfds,
2290 	    args->writefds, args->exceptfds, tsp, args->sig);
2291 
2292 	if (args->tsp != NULL)
2293 		linux_put_timespec(&ts, args->tsp);
2294 	return (error);
2295 }
2296 
2297 static int
2298 linux_common_pselect6(struct thread *td, l_int nfds, l_fd_set *readfds,
2299     l_fd_set *writefds, l_fd_set *exceptfds, struct timespec *tsp,
2300     l_uintptr_t *sig)
2301 {
2302 	struct timeval utv, tv0, tv1, *tvp;
2303 	struct l_pselect6arg lpse6;
2304 	sigset_t *ssp;
2305 	sigset_t ss;
2306 	int error;
2307 
2308 	ssp = NULL;
2309 	if (sig != NULL) {
2310 		error = copyin(sig, &lpse6, sizeof(lpse6));
2311 		if (error != 0)
2312 			return (error);
2313 		error = linux_copyin_sigset(td, PTRIN(lpse6.ss),
2314 		    lpse6.ss_len, &ss, &ssp);
2315 		if (error != 0)
2316 		    return (error);
2317 	} else
2318 		ssp = NULL;
2319 
2320 	/*
2321 	 * Currently glibc changes nanosecond number to microsecond.
2322 	 * This mean losing precision but for now it is hardly seen.
2323 	 */
2324 	if (tsp != NULL) {
2325 		TIMESPEC_TO_TIMEVAL(&utv, tsp);
2326 		if (itimerfix(&utv))
2327 			return (EINVAL);
2328 
2329 		microtime(&tv0);
2330 		tvp = &utv;
2331 	} else
2332 		tvp = NULL;
2333 
2334 	error = kern_pselect(td, nfds, readfds, writefds,
2335 	    exceptfds, tvp, ssp, LINUX_NFDBITS);
2336 
2337 	if (tsp != NULL) {
2338 		/*
2339 		 * Compute how much time was left of the timeout,
2340 		 * by subtracting the current time and the time
2341 		 * before we started the call, and subtracting
2342 		 * that result from the user-supplied value.
2343 		 */
2344 		microtime(&tv1);
2345 		timevalsub(&tv1, &tv0);
2346 		timevalsub(&utv, &tv1);
2347 		if (utv.tv_sec < 0)
2348 			timevalclear(&utv);
2349 		TIMEVAL_TO_TIMESPEC(&utv, tsp);
2350 	}
2351 	return (error);
2352 }
2353 
2354 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
2355 int
2356 linux_pselect6_time64(struct thread *td,
2357     struct linux_pselect6_time64_args *args)
2358 {
2359 	struct timespec ts, *tsp;
2360 	int error;
2361 
2362 	if (args->tsp != NULL) {
2363 		error = linux_get_timespec64(&ts, args->tsp);
2364 		if (error != 0)
2365 			return (error);
2366 		tsp = &ts;
2367 	} else
2368 		tsp = NULL;
2369 
2370 	error = linux_common_pselect6(td, args->nfds, args->readfds,
2371 	    args->writefds, args->exceptfds, tsp, args->sig);
2372 
2373 	if (args->tsp != NULL)
2374 		linux_put_timespec64(&ts, args->tsp);
2375 	return (error);
2376 }
2377 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
2378 
2379 int
2380 linux_ppoll(struct thread *td, struct linux_ppoll_args *args)
2381 {
2382 	struct timespec uts, *tsp;
2383 	int error;
2384 
2385 	if (args->tsp != NULL) {
2386 		error = linux_get_timespec(&uts, args->tsp);
2387 		if (error != 0)
2388 			return (error);
2389 		tsp = &uts;
2390 	} else
2391 		tsp = NULL;
2392 
2393 	error = linux_common_ppoll(td, args->fds, args->nfds, tsp,
2394 	    args->sset, args->ssize);
2395 	if (error == 0 && args->tsp != NULL)
2396 		error = linux_put_timespec(&uts, args->tsp);
2397 	return (error);
2398 }
2399 
2400 static int
2401 linux_common_ppoll(struct thread *td, struct pollfd *fds, uint32_t nfds,
2402     struct timespec *tsp, l_sigset_t *sset, l_size_t ssize)
2403 {
2404 	struct timespec ts0, ts1;
2405 	struct pollfd stackfds[32];
2406 	struct pollfd *kfds;
2407  	sigset_t *ssp;
2408  	sigset_t ss;
2409  	int error;
2410 
2411 	if (kern_poll_maxfds(nfds))
2412 		return (EINVAL);
2413 	if (sset != NULL) {
2414 		error = linux_copyin_sigset(td, sset, ssize, &ss, &ssp);
2415 		if (error != 0)
2416 		    return (error);
2417 	} else
2418 		ssp = NULL;
2419 	if (tsp != NULL)
2420 		nanotime(&ts0);
2421 
2422 	if (nfds > nitems(stackfds))
2423 		kfds = mallocarray(nfds, sizeof(*kfds), M_TEMP, M_WAITOK);
2424 	else
2425 		kfds = stackfds;
2426 	error = linux_pollin(td, kfds, fds, nfds);
2427 	if (error != 0)
2428 		goto out;
2429 
2430 	error = kern_poll_kfds(td, kfds, nfds, tsp, ssp);
2431 	if (error == 0)
2432 		error = linux_pollout(td, kfds, fds, nfds);
2433 
2434 	if (error == 0 && tsp != NULL) {
2435 		if (td->td_retval[0]) {
2436 			nanotime(&ts1);
2437 			timespecsub(&ts1, &ts0, &ts1);
2438 			timespecsub(tsp, &ts1, tsp);
2439 			if (tsp->tv_sec < 0)
2440 				timespecclear(tsp);
2441 		} else
2442 			timespecclear(tsp);
2443 	}
2444 
2445 out:
2446 	if (nfds > nitems(stackfds))
2447 		free(kfds, M_TEMP);
2448 	return (error);
2449 }
2450 
2451 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
2452 int
2453 linux_ppoll_time64(struct thread *td, struct linux_ppoll_time64_args *args)
2454 {
2455 	struct timespec uts, *tsp;
2456 	int error;
2457 
2458 	if (args->tsp != NULL) {
2459 		error = linux_get_timespec64(&uts, args->tsp);
2460 		if (error != 0)
2461 			return (error);
2462 		tsp = &uts;
2463 	} else
2464  		tsp = NULL;
2465 	error = linux_common_ppoll(td, args->fds, args->nfds, tsp,
2466 	    args->sset, args->ssize);
2467 	if (error == 0 && args->tsp != NULL)
2468 		error = linux_put_timespec64(&uts, args->tsp);
2469 	return (error);
2470 }
2471 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
2472 
2473 static int
2474 linux_pollin(struct thread *td, struct pollfd *fds, struct pollfd *ufds, u_int nfd)
2475 {
2476 	int error;
2477 	u_int i;
2478 
2479 	error = copyin(ufds, fds, nfd * sizeof(*fds));
2480 	if (error != 0)
2481 		return (error);
2482 
2483 	for (i = 0; i < nfd; i++) {
2484 		if (fds->events != 0)
2485 			linux_to_bsd_poll_events(td, fds->fd,
2486 			    fds->events, &fds->events);
2487 		fds++;
2488 	}
2489 	return (0);
2490 }
2491 
2492 static int
2493 linux_pollout(struct thread *td, struct pollfd *fds, struct pollfd *ufds, u_int nfd)
2494 {
2495 	int error = 0;
2496 	u_int i, n = 0;
2497 
2498 	for (i = 0; i < nfd; i++) {
2499 		if (fds->revents != 0) {
2500 			bsd_to_linux_poll_events(fds->revents,
2501 			    &fds->revents);
2502 			n++;
2503 		}
2504 		error = copyout(&fds->revents, &ufds->revents,
2505 		    sizeof(ufds->revents));
2506 		if (error)
2507 			return (error);
2508 		fds++;
2509 		ufds++;
2510 	}
2511 	td->td_retval[0] = n;
2512 	return (0);
2513 }
2514 
2515 static int
2516 linux_sched_rr_get_interval_common(struct thread *td, pid_t pid,
2517     struct timespec *ts)
2518 {
2519 	struct thread *tdt;
2520 	int error;
2521 
2522 	/*
2523 	 * According to man in case the invalid pid specified
2524 	 * EINVAL should be returned.
2525 	 */
2526 	if (pid < 0)
2527 		return (EINVAL);
2528 
2529 	tdt = linux_tdfind(td, pid, -1);
2530 	if (tdt == NULL)
2531 		return (ESRCH);
2532 
2533 	error = kern_sched_rr_get_interval_td(td, tdt, ts);
2534 	PROC_UNLOCK(tdt->td_proc);
2535 	return (error);
2536 }
2537 
2538 int
2539 linux_sched_rr_get_interval(struct thread *td,
2540     struct linux_sched_rr_get_interval_args *uap)
2541 {
2542 	struct timespec ts;
2543 	int error;
2544 
2545 	error = linux_sched_rr_get_interval_common(td, uap->pid, &ts);
2546 	if (error != 0)
2547 		return (error);
2548 	return (linux_put_timespec(&ts, uap->interval));
2549 }
2550 
2551 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
2552 int
2553 linux_sched_rr_get_interval_time64(struct thread *td,
2554     struct linux_sched_rr_get_interval_time64_args *uap)
2555 {
2556 	struct timespec ts;
2557 	int error;
2558 
2559 	error = linux_sched_rr_get_interval_common(td, uap->pid, &ts);
2560 	if (error != 0)
2561 		return (error);
2562 	return (linux_put_timespec64(&ts, uap->interval));
2563 }
2564 #endif
2565 
2566 /*
2567  * In case when the Linux thread is the initial thread in
2568  * the thread group thread id is equal to the process id.
2569  * Glibc depends on this magic (assert in pthread_getattr_np.c).
2570  */
2571 struct thread *
2572 linux_tdfind(struct thread *td, lwpid_t tid, pid_t pid)
2573 {
2574 	struct linux_emuldata *em;
2575 	struct thread *tdt;
2576 	struct proc *p;
2577 
2578 	tdt = NULL;
2579 	if (tid == 0 || tid == td->td_tid) {
2580 		if (pid != -1 && td->td_proc->p_pid != pid)
2581 			return (NULL);
2582 		PROC_LOCK(td->td_proc);
2583 		return (td);
2584 	} else if (tid > PID_MAX)
2585 		return (tdfind(tid, pid));
2586 
2587 	/*
2588 	 * Initial thread where the tid equal to the pid.
2589 	 */
2590 	p = pfind(tid);
2591 	if (p != NULL) {
2592 		if (SV_PROC_ABI(p) != SV_ABI_LINUX ||
2593 		    (pid != -1 && tid != pid)) {
2594 			/*
2595 			 * p is not a Linuxulator process.
2596 			 */
2597 			PROC_UNLOCK(p);
2598 			return (NULL);
2599 		}
2600 		FOREACH_THREAD_IN_PROC(p, tdt) {
2601 			em = em_find(tdt);
2602 			if (tid == em->em_tid)
2603 				return (tdt);
2604 		}
2605 		PROC_UNLOCK(p);
2606 	}
2607 	return (NULL);
2608 }
2609 
2610 void
2611 linux_to_bsd_waitopts(int options, int *bsdopts)
2612 {
2613 
2614 	if (options & LINUX_WNOHANG)
2615 		*bsdopts |= WNOHANG;
2616 	if (options & LINUX_WUNTRACED)
2617 		*bsdopts |= WUNTRACED;
2618 	if (options & LINUX_WEXITED)
2619 		*bsdopts |= WEXITED;
2620 	if (options & LINUX_WCONTINUED)
2621 		*bsdopts |= WCONTINUED;
2622 	if (options & LINUX_WNOWAIT)
2623 		*bsdopts |= WNOWAIT;
2624 
2625 	if (options & __WCLONE)
2626 		*bsdopts |= WLINUXCLONE;
2627 }
2628 
2629 int
2630 linux_getrandom(struct thread *td, struct linux_getrandom_args *args)
2631 {
2632 	struct uio uio;
2633 	struct iovec iov;
2634 	int error;
2635 
2636 	if (args->flags & ~(LINUX_GRND_NONBLOCK|LINUX_GRND_RANDOM))
2637 		return (EINVAL);
2638 	if (args->count > INT_MAX)
2639 		args->count = INT_MAX;
2640 
2641 	iov.iov_base = args->buf;
2642 	iov.iov_len = args->count;
2643 
2644 	uio.uio_iov = &iov;
2645 	uio.uio_iovcnt = 1;
2646 	uio.uio_resid = iov.iov_len;
2647 	uio.uio_segflg = UIO_USERSPACE;
2648 	uio.uio_rw = UIO_READ;
2649 	uio.uio_td = td;
2650 
2651 	error = read_random_uio(&uio, args->flags & LINUX_GRND_NONBLOCK);
2652 	if (error == 0)
2653 		td->td_retval[0] = args->count - uio.uio_resid;
2654 	return (error);
2655 }
2656 
2657 int
2658 linux_mincore(struct thread *td, struct linux_mincore_args *args)
2659 {
2660 
2661 	/* Needs to be page-aligned */
2662 	if (args->start & PAGE_MASK)
2663 		return (EINVAL);
2664 	return (kern_mincore(td, args->start, args->len, args->vec));
2665 }
2666 
2667 #define	SYSLOG_TAG	"<6>"
2668 
2669 int
2670 linux_syslog(struct thread *td, struct linux_syslog_args *args)
2671 {
2672 	char buf[128], *src, *dst;
2673 	u_int seq;
2674 	int buflen, error;
2675 
2676 	if (args->type != LINUX_SYSLOG_ACTION_READ_ALL) {
2677 		linux_msg(td, "syslog unsupported type 0x%x", args->type);
2678 		return (EINVAL);
2679 	}
2680 
2681 	if (args->len < 6) {
2682 		td->td_retval[0] = 0;
2683 		return (0);
2684 	}
2685 
2686 	error = priv_check(td, PRIV_MSGBUF);
2687 	if (error)
2688 		return (error);
2689 
2690 	mtx_lock(&msgbuf_lock);
2691 	msgbuf_peekbytes(msgbufp, NULL, 0, &seq);
2692 	mtx_unlock(&msgbuf_lock);
2693 
2694 	dst = args->buf;
2695 	error = copyout(&SYSLOG_TAG, dst, sizeof(SYSLOG_TAG));
2696 	/* The -1 is to skip the trailing '\0'. */
2697 	dst += sizeof(SYSLOG_TAG) - 1;
2698 
2699 	while (error == 0) {
2700 		mtx_lock(&msgbuf_lock);
2701 		buflen = msgbuf_peekbytes(msgbufp, buf, sizeof(buf), &seq);
2702 		mtx_unlock(&msgbuf_lock);
2703 
2704 		if (buflen == 0)
2705 			break;
2706 
2707 		for (src = buf; src < buf + buflen && error == 0; src++) {
2708 			if (*src == '\0')
2709 				continue;
2710 
2711 			if (dst >= args->buf + args->len)
2712 				goto out;
2713 
2714 			error = copyout(src, dst, 1);
2715 			dst++;
2716 
2717 			if (*src == '\n' && *(src + 1) != '<' &&
2718 			    dst + sizeof(SYSLOG_TAG) < args->buf + args->len) {
2719 				error = copyout(&SYSLOG_TAG,
2720 				    dst, sizeof(SYSLOG_TAG));
2721 				dst += sizeof(SYSLOG_TAG) - 1;
2722 			}
2723 		}
2724 	}
2725 out:
2726 	td->td_retval[0] = dst - args->buf;
2727 	return (error);
2728 }
2729 
2730 int
2731 linux_getcpu(struct thread *td, struct linux_getcpu_args *args)
2732 {
2733 	int cpu, error, node;
2734 
2735 	cpu = td->td_oncpu; /* Make sure it doesn't change during copyout(9) */
2736 	error = 0;
2737 	node = cpuid_to_pcpu[cpu]->pc_domain;
2738 
2739 	if (args->cpu != NULL)
2740 		error = copyout(&cpu, args->cpu, sizeof(l_int));
2741 	if (args->node != NULL)
2742 		error = copyout(&node, args->node, sizeof(l_int));
2743 	return (error);
2744 }
2745 
2746 #if defined(__i386__) || defined(__amd64__)
2747 int
2748 linux_poll(struct thread *td, struct linux_poll_args *args)
2749 {
2750 	struct timespec ts, *tsp;
2751 
2752 	if (args->timeout != INFTIM) {
2753 		if (args->timeout < 0)
2754 			return (EINVAL);
2755 		ts.tv_sec = args->timeout / 1000;
2756 		ts.tv_nsec = (args->timeout % 1000) * 1000000;
2757 		tsp = &ts;
2758 	} else
2759 		tsp = NULL;
2760 
2761 	return (linux_common_ppoll(td, args->fds, args->nfds,
2762 	    tsp, NULL, 0));
2763 }
2764 #endif /* __i386__ || __amd64__ */
2765 
2766 int
2767 linux_seccomp(struct thread *td, struct linux_seccomp_args *args)
2768 {
2769 
2770 	switch (args->op) {
2771 	case LINUX_SECCOMP_GET_ACTION_AVAIL:
2772 		return (EOPNOTSUPP);
2773 	default:
2774 		/*
2775 		 * Ignore unknown operations, just like Linux kernel built
2776 		 * without CONFIG_SECCOMP.
2777 		 */
2778 		return (EINVAL);
2779 	}
2780 }
2781 
2782 /*
2783  * Custom version of exec_copyin_args(), to copy out argument and environment
2784  * strings from the old process address space into the temporary string buffer.
2785  * Based on freebsd32_exec_copyin_args.
2786  */
2787 static int
2788 linux_exec_copyin_args(struct image_args *args, const char *fname,
2789     l_uintptr_t *argv, l_uintptr_t *envv)
2790 {
2791 	char *argp, *envp;
2792 	l_uintptr_t *ptr, arg;
2793 	int error;
2794 
2795 	bzero(args, sizeof(*args));
2796 	if (argv == NULL)
2797 		return (EFAULT);
2798 
2799 	/*
2800 	 * Allocate demand-paged memory for the file name, argument, and
2801 	 * environment strings.
2802 	 */
2803 	error = exec_alloc_args(args);
2804 	if (error != 0)
2805 		return (error);
2806 
2807 	/*
2808 	 * Copy the file name.
2809 	 */
2810 	error = exec_args_add_fname(args, fname, UIO_USERSPACE);
2811 	if (error != 0)
2812 		goto err_exit;
2813 
2814 	/*
2815 	 * extract arguments first
2816 	 */
2817 	ptr = argv;
2818 	for (;;) {
2819 		error = copyin(ptr++, &arg, sizeof(arg));
2820 		if (error)
2821 			goto err_exit;
2822 		if (arg == 0)
2823 			break;
2824 		argp = PTRIN(arg);
2825 		error = exec_args_add_arg(args, argp, UIO_USERSPACE);
2826 		if (error != 0)
2827 			goto err_exit;
2828 	}
2829 
2830 	/*
2831 	 * This comment is from Linux do_execveat_common:
2832 	 * When argv is empty, add an empty string ("") as argv[0] to
2833 	 * ensure confused userspace programs that start processing
2834 	 * from argv[1] won't end up walking envp.
2835 	 */
2836 	if (args->argc == 0 &&
2837 	    (error = exec_args_add_arg(args, "", UIO_SYSSPACE) != 0))
2838 		goto err_exit;
2839 
2840 	/*
2841 	 * extract environment strings
2842 	 */
2843 	if (envv) {
2844 		ptr = envv;
2845 		for (;;) {
2846 			error = copyin(ptr++, &arg, sizeof(arg));
2847 			if (error)
2848 				goto err_exit;
2849 			if (arg == 0)
2850 				break;
2851 			envp = PTRIN(arg);
2852 			error = exec_args_add_env(args, envp, UIO_USERSPACE);
2853 			if (error != 0)
2854 				goto err_exit;
2855 		}
2856 	}
2857 
2858 	return (0);
2859 
2860 err_exit:
2861 	exec_free_args(args);
2862 	return (error);
2863 }
2864 
2865 int
2866 linux_execve(struct thread *td, struct linux_execve_args *args)
2867 {
2868 	struct image_args eargs;
2869 	int error;
2870 
2871 	LINUX_CTR(execve);
2872 
2873 	error = linux_exec_copyin_args(&eargs, args->path, args->argp,
2874 	    args->envp);
2875 	if (error == 0)
2876 		error = linux_common_execve(td, &eargs);
2877 	AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td);
2878 	return (error);
2879 }
2880 
2881 static void
2882 linux_up_rtprio_if(struct thread *td1, struct rtprio *rtp)
2883 {
2884 	struct rtprio rtp2;
2885 
2886 	pri_to_rtp(td1, &rtp2);
2887 	if (rtp2.type <  rtp->type ||
2888 	    (rtp2.type == rtp->type &&
2889 	    rtp2.prio < rtp->prio)) {
2890 		rtp->type = rtp2.type;
2891 		rtp->prio = rtp2.prio;
2892 	}
2893 }
2894 
2895 #define	LINUX_PRIO_DIVIDER	RTP_PRIO_MAX / LINUX_IOPRIO_MAX
2896 
2897 static int
2898 linux_rtprio2ioprio(struct rtprio *rtp)
2899 {
2900 	int ioprio, prio;
2901 
2902 	switch (rtp->type) {
2903 	case RTP_PRIO_IDLE:
2904 		prio = RTP_PRIO_MIN;
2905 		ioprio = LINUX_IOPRIO_PRIO(LINUX_IOPRIO_CLASS_IDLE, prio);
2906 		break;
2907 	case RTP_PRIO_NORMAL:
2908 		prio = rtp->prio / LINUX_PRIO_DIVIDER;
2909 		ioprio = LINUX_IOPRIO_PRIO(LINUX_IOPRIO_CLASS_BE, prio);
2910 		break;
2911 	case RTP_PRIO_REALTIME:
2912 		prio = rtp->prio / LINUX_PRIO_DIVIDER;
2913 		ioprio = LINUX_IOPRIO_PRIO(LINUX_IOPRIO_CLASS_RT, prio);
2914 		break;
2915 	default:
2916 		prio = RTP_PRIO_MIN;
2917 		ioprio = LINUX_IOPRIO_PRIO(LINUX_IOPRIO_CLASS_NONE, prio);
2918 		break;
2919 	}
2920 	return (ioprio);
2921 }
2922 
2923 static int
2924 linux_ioprio2rtprio(int ioprio, struct rtprio *rtp)
2925 {
2926 
2927 	switch (LINUX_IOPRIO_PRIO_CLASS(ioprio)) {
2928 	case LINUX_IOPRIO_CLASS_IDLE:
2929 		rtp->prio = RTP_PRIO_MIN;
2930 		rtp->type = RTP_PRIO_IDLE;
2931 		break;
2932 	case LINUX_IOPRIO_CLASS_BE:
2933 		rtp->prio = LINUX_IOPRIO_PRIO_DATA(ioprio) * LINUX_PRIO_DIVIDER;
2934 		rtp->type = RTP_PRIO_NORMAL;
2935 		break;
2936 	case LINUX_IOPRIO_CLASS_RT:
2937 		rtp->prio = LINUX_IOPRIO_PRIO_DATA(ioprio) * LINUX_PRIO_DIVIDER;
2938 		rtp->type = RTP_PRIO_REALTIME;
2939 		break;
2940 	default:
2941 		return (EINVAL);
2942 	}
2943 	return (0);
2944 }
2945 #undef LINUX_PRIO_DIVIDER
2946 
2947 int
2948 linux_ioprio_get(struct thread *td, struct linux_ioprio_get_args *args)
2949 {
2950 	struct thread *td1;
2951 	struct rtprio rtp;
2952 	struct pgrp *pg;
2953 	struct proc *p;
2954 	int error, found;
2955 
2956 	p = NULL;
2957 	td1 = NULL;
2958 	error = 0;
2959 	found = 0;
2960 	rtp.type = RTP_PRIO_IDLE;
2961 	rtp.prio = RTP_PRIO_MAX;
2962 	switch (args->which) {
2963 	case LINUX_IOPRIO_WHO_PROCESS:
2964 		if (args->who == 0) {
2965 			td1 = td;
2966 			p = td1->td_proc;
2967 			PROC_LOCK(p);
2968 		} else if (args->who > PID_MAX) {
2969 			td1 = linux_tdfind(td, args->who, -1);
2970 			if (td1 != NULL)
2971 				p = td1->td_proc;
2972 		} else
2973 			p = pfind(args->who);
2974 		if (p == NULL)
2975 			return (ESRCH);
2976 		if ((error = p_cansee(td, p))) {
2977 			PROC_UNLOCK(p);
2978 			break;
2979 		}
2980 		if (td1 != NULL) {
2981 			pri_to_rtp(td1, &rtp);
2982 		} else {
2983 			FOREACH_THREAD_IN_PROC(p, td1) {
2984 				linux_up_rtprio_if(td1, &rtp);
2985 			}
2986 		}
2987 		found++;
2988 		PROC_UNLOCK(p);
2989 		break;
2990 	case LINUX_IOPRIO_WHO_PGRP:
2991 		sx_slock(&proctree_lock);
2992 		if (args->who == 0) {
2993 			pg = td->td_proc->p_pgrp;
2994 			PGRP_LOCK(pg);
2995 		} else {
2996 			pg = pgfind(args->who);
2997 			if (pg == NULL) {
2998 				sx_sunlock(&proctree_lock);
2999 				error = ESRCH;
3000 				break;
3001 			}
3002 		}
3003 		sx_sunlock(&proctree_lock);
3004 		LIST_FOREACH(p, &pg->pg_members, p_pglist) {
3005 			PROC_LOCK(p);
3006 			if (p->p_state == PRS_NORMAL &&
3007 			    p_cansee(td, p) == 0) {
3008 				FOREACH_THREAD_IN_PROC(p, td1) {
3009 					linux_up_rtprio_if(td1, &rtp);
3010 					found++;
3011 				}
3012 			}
3013 			PROC_UNLOCK(p);
3014 		}
3015 		PGRP_UNLOCK(pg);
3016 		break;
3017 	case LINUX_IOPRIO_WHO_USER:
3018 		if (args->who == 0)
3019 			args->who = td->td_ucred->cr_uid;
3020 		sx_slock(&allproc_lock);
3021 		FOREACH_PROC_IN_SYSTEM(p) {
3022 			PROC_LOCK(p);
3023 			if (p->p_state == PRS_NORMAL &&
3024 			    p->p_ucred->cr_uid == args->who &&
3025 			    p_cansee(td, p) == 0) {
3026 				FOREACH_THREAD_IN_PROC(p, td1) {
3027 					linux_up_rtprio_if(td1, &rtp);
3028 					found++;
3029 				}
3030 			}
3031 			PROC_UNLOCK(p);
3032 		}
3033 		sx_sunlock(&allproc_lock);
3034 		break;
3035 	default:
3036 		error = EINVAL;
3037 		break;
3038 	}
3039 	if (error == 0) {
3040 		if (found != 0)
3041 			td->td_retval[0] = linux_rtprio2ioprio(&rtp);
3042 		else
3043 			error = ESRCH;
3044 	}
3045 	return (error);
3046 }
3047 
3048 int
3049 linux_ioprio_set(struct thread *td, struct linux_ioprio_set_args *args)
3050 {
3051 	struct thread *td1;
3052 	struct rtprio rtp;
3053 	struct pgrp *pg;
3054 	struct proc *p;
3055 	int error;
3056 
3057 	if ((error = linux_ioprio2rtprio(args->ioprio, &rtp)) != 0)
3058 		return (error);
3059 	/* Attempts to set high priorities (REALTIME) require su privileges. */
3060 	if (RTP_PRIO_BASE(rtp.type) == RTP_PRIO_REALTIME &&
3061 	    (error = priv_check(td, PRIV_SCHED_RTPRIO)) != 0)
3062 		return (error);
3063 
3064 	p = NULL;
3065 	td1 = NULL;
3066 	switch (args->which) {
3067 	case LINUX_IOPRIO_WHO_PROCESS:
3068 		if (args->who == 0) {
3069 			td1 = td;
3070 			p = td1->td_proc;
3071 			PROC_LOCK(p);
3072 		} else if (args->who > PID_MAX) {
3073 			td1 = linux_tdfind(td, args->who, -1);
3074 			if (td1 != NULL)
3075 				p = td1->td_proc;
3076 		} else
3077 			p = pfind(args->who);
3078 		if (p == NULL)
3079 			return (ESRCH);
3080 		if ((error = p_cansched(td, p))) {
3081 			PROC_UNLOCK(p);
3082 			break;
3083 		}
3084 		if (td1 != NULL) {
3085 			error = rtp_to_pri(&rtp, td1);
3086 		} else {
3087 			FOREACH_THREAD_IN_PROC(p, td1) {
3088 				if ((error = rtp_to_pri(&rtp, td1)) != 0)
3089 					break;
3090 			}
3091 		}
3092 		PROC_UNLOCK(p);
3093 		break;
3094 	case LINUX_IOPRIO_WHO_PGRP:
3095 		sx_slock(&proctree_lock);
3096 		if (args->who == 0) {
3097 			pg = td->td_proc->p_pgrp;
3098 			PGRP_LOCK(pg);
3099 		} else {
3100 			pg = pgfind(args->who);
3101 			if (pg == NULL) {
3102 				sx_sunlock(&proctree_lock);
3103 				error = ESRCH;
3104 				break;
3105 			}
3106 		}
3107 		sx_sunlock(&proctree_lock);
3108 		LIST_FOREACH(p, &pg->pg_members, p_pglist) {
3109 			PROC_LOCK(p);
3110 			if (p->p_state == PRS_NORMAL &&
3111 			    p_cansched(td, p) == 0) {
3112 				FOREACH_THREAD_IN_PROC(p, td1) {
3113 					if ((error = rtp_to_pri(&rtp, td1)) != 0)
3114 						break;
3115 				}
3116 			}
3117 			PROC_UNLOCK(p);
3118 			if (error != 0)
3119 				break;
3120 		}
3121 		PGRP_UNLOCK(pg);
3122 		break;
3123 	case LINUX_IOPRIO_WHO_USER:
3124 		if (args->who == 0)
3125 			args->who = td->td_ucred->cr_uid;
3126 		sx_slock(&allproc_lock);
3127 		FOREACH_PROC_IN_SYSTEM(p) {
3128 			PROC_LOCK(p);
3129 			if (p->p_state == PRS_NORMAL &&
3130 			    p->p_ucred->cr_uid == args->who &&
3131 			    p_cansched(td, p) == 0) {
3132 				FOREACH_THREAD_IN_PROC(p, td1) {
3133 					if ((error = rtp_to_pri(&rtp, td1)) != 0)
3134 						break;
3135 				}
3136 			}
3137 			PROC_UNLOCK(p);
3138 			if (error != 0)
3139 				break;
3140 		}
3141 		sx_sunlock(&allproc_lock);
3142 		break;
3143 	default:
3144 		error = EINVAL;
3145 		break;
3146 	}
3147 	return (error);
3148 }
3149 
3150 /* The only flag is O_NONBLOCK */
3151 #define B2L_MQ_FLAGS(bflags)	((bflags) != 0 ? LINUX_O_NONBLOCK : 0)
3152 #define L2B_MQ_FLAGS(lflags)	((lflags) != 0 ? O_NONBLOCK : 0)
3153 
3154 int
3155 linux_mq_open(struct thread *td, struct linux_mq_open_args *args)
3156 {
3157 	struct mq_attr attr;
3158 	int error, flags;
3159 
3160 	flags = linux_common_openflags(args->oflag);
3161 	if ((flags & O_ACCMODE) == O_ACCMODE || (flags & O_EXEC) != 0)
3162 		return (EINVAL);
3163 	flags = FFLAGS(flags);
3164 	if ((flags & O_CREAT) != 0 && args->attr != NULL) {
3165 		error = copyin(args->attr, &attr, sizeof(attr));
3166 		if (error != 0)
3167 			return (error);
3168 		attr.mq_flags = L2B_MQ_FLAGS(attr.mq_flags);
3169 	}
3170 
3171 	return (kern_kmq_open(td, args->name, flags, args->mode,
3172 	    args->attr != NULL ? &attr : NULL));
3173 }
3174 
3175 int
3176 linux_mq_unlink(struct thread *td, struct linux_mq_unlink_args *args)
3177 {
3178 	struct kmq_unlink_args bsd_args = {
3179 		.path = PTRIN(args->name)
3180 	};
3181 
3182 	return (sys_kmq_unlink(td, &bsd_args));
3183 }
3184 
3185 int
3186 linux_mq_timedsend(struct thread *td, struct linux_mq_timedsend_args *args)
3187 {
3188 	struct timespec ts, *abs_timeout;
3189 	int error;
3190 
3191 	if (args->abs_timeout == NULL)
3192 		abs_timeout = NULL;
3193 	else {
3194 		error = linux_get_timespec(&ts, args->abs_timeout);
3195 		if (error != 0)
3196 			return (error);
3197 		abs_timeout = &ts;
3198 	}
3199 
3200 	return (kern_kmq_timedsend(td, args->mqd, PTRIN(args->msg_ptr),
3201 		args->msg_len, args->msg_prio, abs_timeout));
3202 }
3203 
3204 int
3205 linux_mq_timedreceive(struct thread *td, struct linux_mq_timedreceive_args *args)
3206 {
3207 	struct timespec ts, *abs_timeout;
3208 	int error;
3209 
3210 	if (args->abs_timeout == NULL)
3211 		abs_timeout = NULL;
3212 	else {
3213 		error = linux_get_timespec(&ts, args->abs_timeout);
3214 		if (error != 0)
3215 			return (error);
3216 		abs_timeout = &ts;
3217 	}
3218 
3219 	return (kern_kmq_timedreceive(td, args->mqd, PTRIN(args->msg_ptr),
3220 		args->msg_len, args->msg_prio, abs_timeout));
3221 }
3222 
3223 int
3224 linux_mq_notify(struct thread *td, struct linux_mq_notify_args *args)
3225 {
3226 	struct sigevent ev, *evp;
3227 	struct l_sigevent l_ev;
3228 	int error;
3229 
3230 	if (args->sevp == NULL)
3231 		evp = NULL;
3232 	else {
3233 		error = copyin(args->sevp, &l_ev, sizeof(l_ev));
3234 		if (error != 0)
3235 			return (error);
3236 		error = linux_convert_l_sigevent(&l_ev, &ev);
3237 		if (error != 0)
3238 			return (error);
3239 		evp = &ev;
3240 	}
3241 
3242 	return (kern_kmq_notify(td, args->mqd, evp));
3243 }
3244 
3245 int
3246 linux_mq_getsetattr(struct thread *td, struct linux_mq_getsetattr_args *args)
3247 {
3248 	struct mq_attr attr, oattr;
3249 	int error;
3250 
3251 	if (args->attr != NULL) {
3252 		error = copyin(args->attr, &attr, sizeof(attr));
3253 		if (error != 0)
3254 			return (error);
3255 		attr.mq_flags = L2B_MQ_FLAGS(attr.mq_flags);
3256 	}
3257 
3258 	error = kern_kmq_setattr(td, args->mqd, args->attr != NULL ? &attr : NULL,
3259 	    &oattr);
3260 	if (error == 0 && args->oattr != NULL) {
3261 		oattr.mq_flags = B2L_MQ_FLAGS(oattr.mq_flags);
3262 		bzero(oattr.__reserved, sizeof(oattr.__reserved));
3263 		error = copyout(&oattr, args->oattr, sizeof(oattr));
3264 	}
3265 
3266 	return (error);
3267 }
3268 
3269 int
3270 linux_kcmp(struct thread *td, struct linux_kcmp_args *args)
3271 {
3272 	int type;
3273 
3274 	switch (args->type) {
3275 	case LINUX_KCMP_FILE:
3276 		type = KCMP_FILE;
3277 		break;
3278 	case LINUX_KCMP_FILES:
3279 		type = KCMP_FILES;
3280 		break;
3281 	case LINUX_KCMP_SIGHAND:
3282 		type = KCMP_SIGHAND;
3283 		break;
3284 	case LINUX_KCMP_VM:
3285 		type = KCMP_VM;
3286 		break;
3287 	default:
3288 		return (EINVAL);
3289 	}
3290 
3291 	return (kern_kcmp(td, args->pid1, args->pid2, type, args->idx1,
3292 	    args->idx));
3293 }
3294 
3295 int
3296 linux_membarrier(struct thread *td, struct linux_membarrier_args *args)
3297 {
3298 	static const struct {
3299 		int linux_cmd;
3300 		int freebsd_cmd;
3301 	} cmds[] = {
3302 		{ LINUX_MEMBARRIER_CMD_QUERY,
3303 		    MEMBARRIER_CMD_QUERY },
3304 		{ LINUX_MEMBARRIER_CMD_GLOBAL,
3305 		    MEMBARRIER_CMD_GLOBAL },
3306 		{ LINUX_MEMBARRIER_CMD_GLOBAL_EXPEDITED,
3307 		    MEMBARRIER_CMD_GLOBAL_EXPEDITED },
3308 		{ LINUX_MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED,
3309 		    MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED },
3310 		{ LINUX_MEMBARRIER_CMD_PRIVATE_EXPEDITED,
3311 		    MEMBARRIER_CMD_PRIVATE_EXPEDITED },
3312 		{ LINUX_MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
3313 		    MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED },
3314 		{ LINUX_MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE,
3315 		    MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE },
3316 		{ LINUX_MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
3317 		    MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE },
3318 		{ LINUX_MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ,
3319 		    MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ },
3320 		{ LINUX_MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ,
3321 		    MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ },
3322 		{ LINUX_MEMBARRIER_CMD_GET_REGISTRATIONS,
3323 		    MEMBARRIER_CMD_GET_REGISTRATIONS },
3324 	};
3325 	int cmd, error, flags, i, mask;
3326 
3327 	cmd = -1;
3328 	for (i = 0; i < nitems(cmds); i++) {
3329 		if (args->cmd == cmds[i].linux_cmd) {
3330 			cmd = cmds[i].freebsd_cmd;
3331 			break;
3332 		}
3333 	}
3334 
3335 	if (cmd == -1 || (args->flags & ~LINUX_MEMBARRIER_CMD_FLAG_CPU) != 0)
3336 		return (EINVAL);
3337 
3338 	flags = 0;
3339 	if ((args->flags & LINUX_MEMBARRIER_CMD_FLAG_CPU) != 0)
3340 		flags |= MEMBARRIER_CMD_FLAG_CPU;
3341 
3342 	error = kern_membarrier(td, cmd, flags, args->cpu_id);
3343 	if (error != 0)
3344 		return (error);
3345 
3346 	if (args->cmd == LINUX_MEMBARRIER_CMD_QUERY ||
3347 	    args->cmd == LINUX_MEMBARRIER_CMD_GET_REGISTRATIONS) {
3348 		mask = td->td_retval[0];
3349 		td->td_retval[0] = 0;
3350 		for (i = 0; i < nitems(cmds); i++)
3351 			if ((mask & cmds[i].freebsd_cmd) != 0)
3352 				td->td_retval[0] |= cmds[i].linux_cmd;
3353 	}
3354 
3355 	return (0);
3356 }
3357 
3358 /*
3359  * setfsuid() & setfsgid() exist to decouple the Linux filesystem credentials
3360  * from the effective credentials, avoiding signal exposure during privilege
3361  * transitions. The signal permission model that motivated this was revised in
3362  * Linux 2.0, making these syscalls obsolete for new applications.
3363  *
3364  * As there's no FreeBSD equivalent, implement both syscalls as no-ops that
3365  * return the current effective UID/GID as the previous filesystem UID/GID.
3366  * Linux returns the previous filesystem UID/GID for these syscalls, with no
3367  * error indication.
3368  */
3369 
3370 int
3371 linux_setfsuid(struct thread *td, struct linux_setfsuid_args *args)
3372 {
3373 	td->td_retval[0] = td->td_ucred->cr_uid;
3374 	return (0);
3375 }
3376 
3377 int
3378 linux_setfsgid(struct thread *td, struct linux_setfsgid_args *args)
3379 {
3380 	td->td_retval[0] = td->td_ucred->cr_gid;
3381 	return (0);
3382 }
3383 
3384 MODULE_DEPEND(linux, mqueuefs, 1, 1, 1);
3385