]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/kern_sysctl.c
xnu-3247.10.11.tar.gz
[apple/xnu.git] / bsd / kern / kern_sysctl.c
CommitLineData
1c79356b 1/*
316670eb 2 * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
5d5c5d0d 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
29/*-
30 * Copyright (c) 1982, 1986, 1989, 1993
31 * The Regents of the University of California. All rights reserved.
32 *
33 * This code is derived from software contributed to Berkeley by
34 * Mike Karels at Berkeley Software Design, Inc.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the University of
47 * California, Berkeley and its contributors.
48 * 4. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 *
64 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
65 */
2d21ac55
A
66/*
67 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
68 * support for mandatory and extensible security protections. This notice
69 * is included in support of clause 2.2 (b) of the Apple Public License,
70 * Version 2.0.
71 */
1c79356b
A
72
73/*
2d21ac55
A
74* DEPRECATED sysctl system call code
75 *
76 * Everything in this file is deprecated. Sysctls should be handled
77 * by the code in kern_newsysctl.c.
78 * The remaining "case" sections are supposed to be converted into
79 * SYSCTL_*-style definitions, and as soon as all of them are gone,
80 * this source file is supposed to die.
81 *
82 * DO NOT ADD ANY MORE "case" SECTIONS TO THIS FILE, instead define
83 * your sysctl with SYSCTL_INT, SYSCTL_PROC etc. in your source file.
1c79356b
A
84 */
85
86#include <sys/param.h>
87#include <sys/systm.h>
88#include <sys/kernel.h>
89#include <sys/malloc.h>
91447636
A
90#include <sys/proc_internal.h>
91#include <sys/kauth.h>
92#include <sys/file_internal.h>
93#include <sys/vnode_internal.h>
1c79356b
A
94#include <sys/unistd.h>
95#include <sys/buf.h>
96#include <sys/ioctl.h>
55e303ae 97#include <sys/namei.h>
1c79356b
A
98#include <sys/tty.h>
99#include <sys/disklabel.h>
100#include <sys/vm.h>
101#include <sys/sysctl.h>
9bccf70c 102#include <sys/user.h>
55e303ae 103#include <sys/aio_kern.h>
2d21ac55 104#include <sys/reboot.h>
3e170ce0
A
105#include <sys/memory_maintenance.h>
106#include <sys/priv.h>
e5568f75 107
b0d623f7
A
108#include <security/audit/audit.h>
109#include <kern/kalloc.h>
e5568f75 110
1c79356b 111#include <mach/machine.h>
6d2010ae 112#include <mach/mach_host.h>
1c79356b
A
113#include <mach/mach_types.h>
114#include <mach/vm_param.h>
b0d623f7 115#include <kern/mach_param.h>
1c79356b 116#include <kern/task.h>
316670eb 117#include <kern/thread.h>
6d2010ae 118#include <kern/processor.h>
b0d623f7 119#include <kern/debug.h>
3e170ce0 120#include <kern/sched_prim.h>
1c79356b 121#include <vm/vm_kern.h>
91447636 122#include <vm/vm_map.h>
1c79356b
A
123#include <mach/host_info.h>
124
91447636 125#include <sys/mount_internal.h>
1c79356b
A
126#include <sys/kdebug.h>
127
128#include <IOKit/IOPlatformExpert.h>
129#include <pexpert/pexpert.h>
130
55e303ae 131#include <machine/machine_routines.h>
0c530ab8 132#include <machine/exec.h>
1c79356b 133
91447636 134#include <vm/vm_protos.h>
39236c6e 135#include <vm/vm_pageout.h>
6d2010ae 136#include <sys/imgsrc.h>
fe8ab488 137#include <kern/timer_call.h>
91447636 138
b0d623f7 139#if defined(__i386__) || defined(__x86_64__)
0c530ab8
A
140#include <i386/cpuid.h>
141#endif
142
316670eb
A
143#if CONFIG_FREEZE
144#include <sys/kern_memorystatus.h>
145#endif
146
39236c6e
A
147#if KPERF
148#include <kperf/kperf.h>
149#endif
150
fe8ab488
A
151#if HYPERVISOR
152#include <kern/hv_support.h>
153#endif
154
316670eb
A
155/*
156 * deliberately setting max requests to really high number
157 * so that runaway settings do not cause MALLOC overflows
158 */
159#define AIO_MAX_REQUESTS (128 * CONFIG_AIO_MAX)
160
55e303ae
A
161extern int aio_max_requests;
162extern int aio_max_requests_per_process;
163extern int aio_worker_threads;
91447636
A
164extern int lowpri_IO_window_msecs;
165extern int lowpri_IO_delay_msecs;
0c530ab8 166extern int nx_enabled;
2d21ac55 167extern int speculative_reads_disabled;
6d2010ae
A
168extern int ignore_is_ssd;
169extern unsigned int speculative_prefetch_max;
316670eb 170extern unsigned int speculative_prefetch_max_iosize;
fe8ab488
A
171extern unsigned int preheat_max_bytes;
172extern unsigned int preheat_min_bytes;
b0d623f7 173extern long numvnodes;
1c79356b 174
39236c6e
A
175extern uuid_string_t bootsessionuuid_string;
176
6d2010ae
A
177extern unsigned int vm_max_delayed_work_limit;
178extern unsigned int vm_max_batch;
179
180extern unsigned int vm_page_free_min;
181extern unsigned int vm_page_free_target;
182extern unsigned int vm_page_free_reserved;
183extern unsigned int vm_page_speculative_percentage;
184extern unsigned int vm_page_speculative_q_age_ms;
185
04b8595b
A
186#if (DEVELOPMENT || DEBUG)
187extern uint32_t vm_page_creation_throttled_hard;
188extern uint32_t vm_page_creation_throttled_soft;
189#endif /* DEVELOPMENT || DEBUG */
190
6d2010ae
A
191/*
192 * Conditionally allow dtrace to see these functions for debugging purposes.
193 */
194#ifdef STATIC
195#undef STATIC
196#endif
197#if 0
198#define STATIC
199#else
200#define STATIC static
201#endif
202
203extern boolean_t mach_timer_coalescing_enabled;
204
39236c6e
A
205extern uint64_t timer_deadline_tracking_bin_1, timer_deadline_tracking_bin_2;
206
6d2010ae 207STATIC void
316670eb
A
208fill_user32_eproc(proc_t, struct user32_eproc *__restrict);
209STATIC void
210fill_user32_externproc(proc_t, struct user32_extern_proc *__restrict);
6d2010ae 211STATIC void
316670eb 212fill_user64_eproc(proc_t, struct user64_eproc *__restrict);
6d2010ae 213STATIC void
316670eb 214fill_user64_proc(proc_t, struct user64_kinfo_proc *__restrict);
6d2010ae 215STATIC void
316670eb 216fill_user64_externproc(proc_t, struct user64_extern_proc *__restrict);
6d2010ae 217STATIC void
316670eb
A
218fill_user32_proc(proc_t, struct user32_kinfo_proc *__restrict);
219
91447636
A
220extern int
221kdbg_control(int *name, u_int namelen, user_addr_t where, size_t * sizep);
91447636
A
222#if NFSCLIENT
223extern int
224netboot_root(void);
225#endif
226int
227pcsamples_ops(int *name, u_int namelen, user_addr_t where, size_t *sizep,
2d21ac55 228 proc_t p);
91447636
A
229__private_extern__ kern_return_t
230reset_vmobjectcache(unsigned int val1, unsigned int val2);
91447636
A
231int
232sysctl_procargs(int *name, u_int namelen, user_addr_t where,
2d21ac55 233 size_t *sizep, proc_t cur_proc);
6d2010ae 234STATIC int
91447636 235sysctl_procargsx(int *name, u_int namelen, user_addr_t where, size_t *sizep,
2d21ac55 236 proc_t cur_proc, int argc_yes);
91447636
A
237int
238sysctl_struct(user_addr_t oldp, size_t *oldlenp, user_addr_t newp,
239 size_t newlen, void *sp, int len);
1c79356b 240
6d2010ae
A
241STATIC int sysdoproc_filt_KERN_PROC_PID(proc_t p, void * arg);
242STATIC int sysdoproc_filt_KERN_PROC_PGRP(proc_t p, void * arg);
243STATIC int sysdoproc_filt_KERN_PROC_TTY(proc_t p, void * arg);
244STATIC int sysdoproc_filt_KERN_PROC_UID(proc_t p, void * arg);
245STATIC int sysdoproc_filt_KERN_PROC_RUID(proc_t p, void * arg);
2d21ac55 246int sysdoproc_callback(proc_t p, void *arg);
1c79356b 247
6d2010ae
A
248
249/* forward declarations for non-static STATIC */
250STATIC void fill_loadavg64(struct loadavg *la, struct user64_loadavg *la64);
251STATIC void fill_loadavg32(struct loadavg *la, struct user32_loadavg *la32);
6d2010ae
A
252STATIC int sysctl_handle_kern_threadname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
253STATIC int sysctl_sched_stats(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
254STATIC int sysctl_sched_stats_enable(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
6d2010ae 255STATIC int sysctl_kdebug_ops SYSCTL_HANDLER_ARGS;
6d2010ae
A
256#if COUNT_SYSCALLS
257STATIC int sysctl_docountsyscalls SYSCTL_HANDLER_ARGS;
258#endif /* COUNT_SYSCALLS */
6d2010ae 259STATIC int sysctl_doprocargs SYSCTL_HANDLER_ARGS;
6d2010ae
A
260STATIC int sysctl_doprocargs2 SYSCTL_HANDLER_ARGS;
261STATIC int sysctl_prochandle SYSCTL_HANDLER_ARGS;
6d2010ae
A
262STATIC int sysctl_aiomax(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
263STATIC int sysctl_aioprocmax(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
264STATIC int sysctl_aiothreads(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
265STATIC int sysctl_maxproc(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
266STATIC int sysctl_osversion(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
267STATIC int sysctl_sysctl_bootargs(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
268STATIC int sysctl_maxvnodes(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
269STATIC int sysctl_securelvl(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
270STATIC int sysctl_domainname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
271STATIC int sysctl_hostname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
272STATIC int sysctl_procname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
273STATIC int sysctl_boottime(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
274STATIC int sysctl_symfile(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
275#if NFSCLIENT
276STATIC int sysctl_netboot(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
277#endif
278#ifdef CONFIG_IMGSRC_ACCESS
279STATIC int sysctl_imgsrcdev(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
280#endif
281STATIC int sysctl_usrstack(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
282STATIC int sysctl_usrstack64(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
283STATIC int sysctl_coredump(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
284STATIC int sysctl_suid_coredump(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
285STATIC int sysctl_delayterm(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
286STATIC int sysctl_rage_vnode(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
287STATIC int sysctl_kern_check_openevt(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
288STATIC int sysctl_nx(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
289STATIC int sysctl_loadavg(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
290STATIC int sysctl_vm_toggle_address_reuse(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
291STATIC int sysctl_swapusage(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
6d2010ae
A
292STATIC int fetch_process_cputype( proc_t cur_proc, int *name, u_int namelen, cpu_type_t *cputype);
293STATIC int sysctl_sysctl_native(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
294STATIC int sysctl_sysctl_cputype(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
295STATIC int sysctl_safeboot(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
296STATIC int sysctl_singleuser(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
3e170ce0 297STATIC int sysctl_minimalboot(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
316670eb 298STATIC int sysctl_slide(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
6d2010ae 299
2d21ac55
A
300
301extern void IORegistrySetOSBuildVersion(char * build_version);
91447636 302
6d2010ae 303STATIC void
b0d623f7 304fill_loadavg64(struct loadavg *la, struct user64_loadavg *la64)
91447636 305{
b0d623f7
A
306 la64->ldavg[0] = la->ldavg[0];
307 la64->ldavg[1] = la->ldavg[1];
308 la64->ldavg[2] = la->ldavg[2];
309 la64->fscale = (user64_long_t)la->fscale;
310}
311
6d2010ae 312STATIC void
b0d623f7
A
313fill_loadavg32(struct loadavg *la, struct user32_loadavg *la32)
314{
315 la32->ldavg[0] = la->ldavg[0];
316 la32->ldavg[1] = la->ldavg[1];
317 la32->ldavg[2] = la->ldavg[2];
318 la32->fscale = (user32_long_t)la->fscale;
91447636
A
319}
320
1c79356b
A
321/*
322 * Attributes stored in the kernel.
323 */
39236c6e
A
324extern char corefilename[MAXPATHLEN+1];
325extern int do_coredump;
326extern int sugid_coredump;
e5568f75 327
2d21ac55 328#if COUNT_SYSCALLS
39236c6e 329extern int do_count_syscalls;
2d21ac55 330#endif
55e303ae 331
1c79356b
A
332#ifdef INSECURE
333int securelevel = -1;
334#else
335int securelevel;
336#endif
337
6d2010ae 338STATIC int
b0d623f7
A
339sysctl_handle_kern_threadname( __unused struct sysctl_oid *oidp, __unused void *arg1,
340 __unused int arg2, struct sysctl_req *req)
341{
342 int error;
343 struct uthread *ut = get_bsdthread_info(current_thread());
344 user_addr_t oldp=0, newp=0;
345 size_t *oldlenp=NULL;
346 size_t newlen=0;
347
348 oldp = req->oldptr;
349 oldlenp = &(req->oldlen);
350 newp = req->newptr;
351 newlen = req->newlen;
352
353 /* We want the current length, and maybe the string itself */
354 if(oldlenp) {
355 /* if we have no thread name yet tell'em we want MAXTHREADNAMESIZE - 1 */
356 size_t currlen = MAXTHREADNAMESIZE - 1;
357
358 if(ut->pth_name)
359 /* use length of current thread name */
360 currlen = strlen(ut->pth_name);
361 if(oldp) {
362 if(*oldlenp < currlen)
363 return ENOMEM;
364 /* NOTE - we do not copy the NULL terminator */
365 if(ut->pth_name) {
366 error = copyout(ut->pth_name,oldp,currlen);
367 if(error)
368 return error;
369 }
370 }
371 /* return length of thread name minus NULL terminator (just like strlen) */
372 req->oldidx = currlen;
373 }
374
375 /* We want to set the name to something */
376 if(newp)
377 {
378 if(newlen > (MAXTHREADNAMESIZE - 1))
379 return ENAMETOOLONG;
380 if(!ut->pth_name)
381 {
382 ut->pth_name = (char*)kalloc( MAXTHREADNAMESIZE );
383 if(!ut->pth_name)
384 return ENOMEM;
385 }
386 bzero(ut->pth_name, MAXTHREADNAMESIZE);
387 error = copyin(newp, ut->pth_name, newlen);
388 if(error)
389 return error;
390 }
391
392 return 0;
393}
394
6d2010ae 395SYSCTL_PROC(_kern, KERN_THREADNAME, threadname, CTLFLAG_ANYBODY | CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_handle_kern_threadname,"A","");
b0d623f7 396
6d2010ae
A
397#define BSD_HOST 1
398STATIC int
399sysctl_sched_stats(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
400{
401 host_basic_info_data_t hinfo;
402 kern_return_t kret;
403 uint32_t size;
404 int changed;
405 mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
406 struct _processor_statistics_np *buf;
407 int error;
55e303ae 408
6d2010ae
A
409 kret = host_info((host_t)BSD_HOST, HOST_BASIC_INFO, (host_info_t)&hinfo, &count);
410 if (kret != KERN_SUCCESS) {
411 return EINVAL;
412 }
1c79356b 413
6d2010ae
A
414 size = sizeof(struct _processor_statistics_np) * (hinfo.logical_cpu_max + 2); /* One for RT Queue, One for Fair Share Queue */
415
416 if (req->oldlen < size) {
417 return EINVAL;
418 }
419
420 MALLOC(buf, struct _processor_statistics_np*, size, M_TEMP, M_ZERO | M_WAITOK);
421
422 kret = get_sched_statistics(buf, &size);
423 if (kret != KERN_SUCCESS) {
424 error = EINVAL;
425 goto out;
426 }
427
428 error = sysctl_io_opaque(req, buf, size, &changed);
429 if (error) {
430 goto out;
431 }
432
433 if (changed) {
434 panic("Sched info changed?!");
435 }
436out:
437 FREE(buf, M_TEMP);
438 return error;
439}
440
441SYSCTL_PROC(_kern, OID_AUTO, sched_stats, CTLFLAG_LOCKED, 0, 0, sysctl_sched_stats, "-", "");
442
443STATIC int
444sysctl_sched_stats_enable(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, __unused struct sysctl_req *req)
445{
446 boolean_t active;
447 int res;
448
449 if (req->newlen != sizeof(active)) {
450 return EINVAL;
451 }
452
453 res = copyin(req->newptr, &active, sizeof(active));
454 if (res != 0) {
455 return res;
456 }
457
458 return set_sched_stats_active(active);
459}
460
461SYSCTL_PROC(_kern, OID_AUTO, sched_stats_enable, CTLFLAG_LOCKED | CTLFLAG_WR, 0, 0, sysctl_sched_stats_enable, "-", "");
462
3e170ce0
A
463extern uint32_t sched_debug_flags;
464SYSCTL_INT(_debug, OID_AUTO, sched, CTLFLAG_RW | CTLFLAG_LOCKED, &sched_debug_flags, 0, "scheduler debug");
465
466#if (DEBUG || DEVELOPMENT)
467extern boolean_t doprnt_hide_pointers;
468SYSCTL_INT(_debug, OID_AUTO, hide_kernel_pointers, CTLFLAG_RW | CTLFLAG_LOCKED, &doprnt_hide_pointers, 0, "hide kernel pointers from log");
469#endif
470
6d2010ae 471extern int get_kernel_symfile(proc_t, char **);
1c79356b 472
2d21ac55 473#if COUNT_SYSCALLS
6d2010ae
A
474#define KERN_COUNT_SYSCALLS (KERN_OSTYPE + 1000)
475
476extern int nsysent;
477extern int syscalls_log[];
478extern const char *syscallnames[];
479
480STATIC int
481sysctl_docountsyscalls SYSCTL_HANDLER_ARGS
482{
483 __unused int cmd = oidp->oid_arg2; /* subcommand*/
484 __unused int *name = arg1; /* oid element argument vector */
485 __unused int namelen = arg2; /* number of oid element arguments */
486 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
487 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
488 user_addr_t newp = req->newptr; /* user buffer copy in address */
489 size_t newlen = req->newlen; /* user buffer copy in size */
490 int error;
491
492 int tmp;
493
494 /* valid values passed in:
495 * = 0 means don't keep called counts for each bsd syscall
496 * > 0 means keep called counts for each bsd syscall
497 * = 2 means dump current counts to the system log
498 * = 3 means reset all counts
499 * for example, to dump current counts:
500 * sysctl -w kern.count_calls=2
501 */
502 error = sysctl_int(oldp, oldlenp, newp, newlen, &tmp);
503 if ( error != 0 ) {
504 return (error);
505 }
506
507 if ( tmp == 1 ) {
508 do_count_syscalls = 1;
509 }
510 else if ( tmp == 0 || tmp == 2 || tmp == 3 ) {
511 int i;
512 for ( i = 0; i < nsysent; i++ ) {
513 if ( syscalls_log[i] != 0 ) {
514 if ( tmp == 2 ) {
515 printf("%d calls - name %s \n", syscalls_log[i], syscallnames[i]);
516 }
517 else {
518 syscalls_log[i] = 0;
2d21ac55 519 }
2d21ac55
A
520 }
521 }
6d2010ae
A
522 if ( tmp != 0 ) {
523 do_count_syscalls = 1;
524 }
1c79356b 525 }
6d2010ae
A
526
527 /* adjust index so we return the right required/consumed amount */
528 if (!error)
529 req->oldidx += req->oldlen;
530
531 return (error);
1c79356b 532}
6d2010ae
A
533SYSCTL_PROC(_kern, KERN_COUNT_SYSCALLS, count_syscalls, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
534 0, /* Pointer argument (arg1) */
535 0, /* Integer argument (arg2) */
536 sysctl_docountsyscalls, /* Handler function */
537 NULL, /* Data pointer */
538 "");
539#endif /* COUNT_SYSCALLS */
1c79356b 540
2d21ac55
A
541/*
542 * The following sysctl_* functions should not be used
543 * any more, as they can only cope with callers in
544 * user mode: Use new-style
545 * sysctl_io_number()
546 * sysctl_io_string()
547 * sysctl_io_opaque()
548 * instead.
549 */
550
1c79356b
A
551/*
552 * Validate parameters and get old / set new parameters
553 * for an integer-valued sysctl function.
554 */
9bccf70c 555int
91447636
A
556sysctl_int(user_addr_t oldp, size_t *oldlenp,
557 user_addr_t newp, size_t newlen, int *valp)
1c79356b
A
558{
559 int error = 0;
560
91447636
A
561 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
562 return (EFAULT);
1c79356b
A
563 if (oldp && *oldlenp < sizeof(int))
564 return (ENOMEM);
565 if (newp && newlen != sizeof(int))
566 return (EINVAL);
567 *oldlenp = sizeof(int);
568 if (oldp)
569 error = copyout(valp, oldp, sizeof(int));
e5568f75 570 if (error == 0 && newp) {
1c79356b 571 error = copyin(newp, valp, sizeof(int));
b0d623f7 572 AUDIT_ARG(value32, *valp);
e5568f75 573 }
1c79356b
A
574 return (error);
575}
576
9bccf70c
A
577/*
578 * Validate parameters and get old / set new parameters
579 * for an quad(64bit)-valued sysctl function.
580 */
581int
91447636
A
582sysctl_quad(user_addr_t oldp, size_t *oldlenp,
583 user_addr_t newp, size_t newlen, quad_t *valp)
9bccf70c
A
584{
585 int error = 0;
586
91447636
A
587 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
588 return (EFAULT);
9bccf70c
A
589 if (oldp && *oldlenp < sizeof(quad_t))
590 return (ENOMEM);
591 if (newp && newlen != sizeof(quad_t))
592 return (EINVAL);
593 *oldlenp = sizeof(quad_t);
594 if (oldp)
595 error = copyout(valp, oldp, sizeof(quad_t));
596 if (error == 0 && newp)
597 error = copyin(newp, valp, sizeof(quad_t));
598 return (error);
599}
600
6d2010ae 601STATIC int
2d21ac55
A
602sysdoproc_filt_KERN_PROC_PID(proc_t p, void * arg)
603{
b0d623f7 604 if (p->p_pid != (pid_t)*(int*)arg)
2d21ac55
A
605 return(0);
606 else
607 return(1);
608}
609
6d2010ae 610STATIC int
2d21ac55
A
611sysdoproc_filt_KERN_PROC_PGRP(proc_t p, void * arg)
612{
b0d623f7 613 if (p->p_pgrpid != (pid_t)*(int*)arg)
2d21ac55
A
614 return(0);
615 else
616 return(1);
617}
618
6d2010ae 619STATIC int
2d21ac55
A
620sysdoproc_filt_KERN_PROC_TTY(proc_t p, void * arg)
621{
2d21ac55 622 int retval;
b0d623f7 623 struct tty *tp;
2d21ac55 624
2d21ac55
A
625 /* This is very racy but list lock is held.. Hmmm. */
626 if ((p->p_flag & P_CONTROLT) == 0 ||
627 (p->p_pgrp == NULL) || (p->p_pgrp->pg_session == NULL) ||
b0d623f7
A
628 (tp = SESSION_TP(p->p_pgrp->pg_session)) == TTY_NULL ||
629 tp->t_dev != (dev_t)*(int*)arg)
2d21ac55
A
630 retval = 0;
631 else
632 retval = 1;
633
2d21ac55
A
634 return(retval);
635}
636
6d2010ae 637STATIC int
2d21ac55
A
638sysdoproc_filt_KERN_PROC_UID(proc_t p, void * arg)
639{
640 kauth_cred_t my_cred;
641 uid_t uid;
642
643 if (p->p_ucred == NULL)
644 return(0);
645 my_cred = kauth_cred_proc_ref(p);
646 uid = kauth_cred_getuid(my_cred);
647 kauth_cred_unref(&my_cred);
648
b0d623f7 649 if (uid != (uid_t)*(int*)arg)
2d21ac55
A
650 return(0);
651 else
652 return(1);
653}
654
655
6d2010ae 656STATIC int
2d21ac55
A
657sysdoproc_filt_KERN_PROC_RUID(proc_t p, void * arg)
658{
659 kauth_cred_t my_cred;
660 uid_t ruid;
661
662 if (p->p_ucred == NULL)
663 return(0);
664 my_cred = kauth_cred_proc_ref(p);
6d2010ae 665 ruid = kauth_cred_getruid(my_cred);
2d21ac55
A
666 kauth_cred_unref(&my_cred);
667
b0d623f7 668 if (ruid != (uid_t)*(int*)arg)
2d21ac55
A
669 return(0);
670 else
671 return(1);
672}
673
1c79356b
A
674/*
675 * try over estimating by 5 procs
676 */
677#define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc))
2d21ac55
A
678struct sysdoproc_args {
679 int buflen;
316670eb 680 void *kprocp;
2d21ac55
A
681 boolean_t is_64_bit;
682 user_addr_t dp;
683 size_t needed;
684 int sizeof_kproc;
316670eb 685 int *errorp;
2d21ac55
A
686 int uidcheck;
687 int ruidcheck;
688 int ttycheck;
689 int uidval;
690};
691
692int
316670eb 693sysdoproc_callback(proc_t p, void *arg)
2d21ac55 694{
316670eb 695 struct sysdoproc_args *args = arg;
2d21ac55
A
696
697 if (args->buflen >= args->sizeof_kproc) {
316670eb
A
698 if ((args->ruidcheck != 0) && (sysdoproc_filt_KERN_PROC_RUID(p, &args->uidval) == 0))
699 return (PROC_RETURNED);
700 if ((args->uidcheck != 0) && (sysdoproc_filt_KERN_PROC_UID(p, &args->uidval) == 0))
701 return (PROC_RETURNED);
702 if ((args->ttycheck != 0) && (sysdoproc_filt_KERN_PROC_TTY(p, &args->uidval) == 0))
703 return (PROC_RETURNED);
2d21ac55
A
704
705 bzero(args->kprocp, args->sizeof_kproc);
316670eb
A
706 if (args->is_64_bit)
707 fill_user64_proc(p, args->kprocp);
708 else
709 fill_user32_proc(p, args->kprocp);
710 int error = copyout(args->kprocp, args->dp, args->sizeof_kproc);
2d21ac55
A
711 if (error) {
712 *args->errorp = error;
316670eb 713 return (PROC_RETURNED_DONE);
2d21ac55
A
714 }
715 args->dp += args->sizeof_kproc;
716 args->buflen -= args->sizeof_kproc;
717 }
718 args->needed += args->sizeof_kproc;
316670eb 719 return (PROC_RETURNED);
2d21ac55 720}
1c79356b 721
6d2010ae
A
722SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD | CTLFLAG_LOCKED, 0, "");
723STATIC int
724sysctl_prochandle SYSCTL_HANDLER_ARGS
1c79356b 725{
6d2010ae
A
726 int cmd = oidp->oid_arg2; /* subcommand for multiple nodes */
727 int *name = arg1; /* oid element argument vector */
728 int namelen = arg2; /* number of oid element arguments */
729 user_addr_t where = req->oldptr;/* user buffer copy out address */
730
91447636
A
731 user_addr_t dp = where;
732 size_t needed = 0;
6d2010ae 733 int buflen = where != USER_ADDR_NULL ? req->oldlen : 0;
1c79356b 734 int error = 0;
316670eb 735 boolean_t is_64_bit = proc_is64bit(current_proc());
b0d623f7
A
736 struct user32_kinfo_proc user32_kproc;
737 struct user64_kinfo_proc user_kproc;
91447636 738 int sizeof_kproc;
316670eb 739 void *kprocp;
2d21ac55
A
740 int (*filterfn)(proc_t, void *) = 0;
741 struct sysdoproc_args args;
742 int uidcheck = 0;
743 int ruidcheck = 0;
744 int ttycheck = 0;
1c79356b 745
6d2010ae 746 if (namelen != 1 && !(namelen == 0 && cmd == KERN_PROC_ALL))
1c79356b 747 return (EINVAL);
6d2010ae 748
91447636
A
749 if (is_64_bit) {
750 sizeof_kproc = sizeof(user_kproc);
316670eb
A
751 kprocp = &user_kproc;
752 } else {
b0d623f7 753 sizeof_kproc = sizeof(user32_kproc);
316670eb 754 kprocp = &user32_kproc;
91447636 755 }
2d21ac55 756
6d2010ae 757 switch (cmd) {
1c79356b
A
758
759 case KERN_PROC_PID:
2d21ac55 760 filterfn = sysdoproc_filt_KERN_PROC_PID;
1c79356b
A
761 break;
762
763 case KERN_PROC_PGRP:
2d21ac55 764 filterfn = sysdoproc_filt_KERN_PROC_PGRP;
1c79356b 765 break;
2d21ac55 766
1c79356b 767 case KERN_PROC_TTY:
2d21ac55 768 ttycheck = 1;
1c79356b
A
769 break;
770
771 case KERN_PROC_UID:
2d21ac55 772 uidcheck = 1;
1c79356b
A
773 break;
774
775 case KERN_PROC_RUID:
2d21ac55 776 ruidcheck = 1;
1c79356b 777 break;
2d21ac55 778
6d2010ae
A
779 case KERN_PROC_ALL:
780 break;
781
782 default:
783 /* must be kern.proc.<unknown> */
784 return (ENOTSUP);
1c79356b 785 }
2d21ac55
A
786
787 error = 0;
788 args.buflen = buflen;
789 args.kprocp = kprocp;
790 args.is_64_bit = is_64_bit;
791 args.dp = dp;
792 args.needed = needed;
793 args.errorp = &error;
794 args.uidcheck = uidcheck;
795 args.ruidcheck = ruidcheck;
796 args.ttycheck = ttycheck;
797 args.sizeof_kproc = sizeof_kproc;
6d2010ae 798 if (namelen)
316670eb 799 args.uidval = name[0];
2d21ac55 800
316670eb
A
801 proc_iterate((PROC_ALLPROCLIST | PROC_ZOMBPROCLIST),
802 sysdoproc_callback, &args, filterfn, name);
2d21ac55
A
803
804 if (error)
316670eb 805 return (error);
2d21ac55
A
806
807 dp = args.dp;
808 needed = args.needed;
809
91447636 810 if (where != USER_ADDR_NULL) {
6d2010ae
A
811 req->oldlen = dp - where;
812 if (needed > req->oldlen)
1c79356b
A
813 return (ENOMEM);
814 } else {
815 needed += KERN_PROCSLOP;
6d2010ae 816 req->oldlen = needed;
1c79356b 817 }
6d2010ae
A
818 /* adjust index so we return the right required/consumed amount */
819 req->oldidx += req->oldlen;
1c79356b
A
820 return (0);
821}
316670eb 822
6d2010ae
A
823/*
824 * We specify the subcommand code for multiple nodes as the 'req->arg2' value
825 * in the sysctl declaration itself, which comes into the handler function
826 * as 'oidp->oid_arg2'.
827 *
828 * For these particular sysctls, since they have well known OIDs, we could
829 * have just obtained it from the '((int *)arg1)[0]' parameter, but that would
830 * not demonstrate how to handle multiple sysctls that used OID_AUTO instead
831 * of a well known value with a common handler function. This is desirable,
832 * because we want well known values to "go away" at some future date.
833 *
834 * It should be noted that the value of '((int *)arg1)[1]' is used for many
835 * an integer parameter to the subcommand for many of these sysctls; we'd
836 * rather have used '((int *)arg1)[0]' for that, or even better, an element
837 * in a structure passed in as the the 'newp' argument to sysctlbyname(3),
838 * and then use leaf-node permissions enforcement, but that would have
839 * necessitated modifying user space code to correspond to the interface
840 * change, and we are striving for binary backward compatibility here; even
841 * though these are SPI, and not intended for use by user space applications
842 * which are not themselves system tools or libraries, some applications
843 * have erroneously used them.
844 */
845SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
846 0, /* Pointer argument (arg1) */
847 KERN_PROC_ALL, /* Integer argument (arg2) */
848 sysctl_prochandle, /* Handler function */
849 NULL, /* Data is size variant on ILP32/LP64 */
850 "");
851SYSCTL_PROC(_kern_proc, KERN_PROC_PID, pid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
852 0, /* Pointer argument (arg1) */
853 KERN_PROC_PID, /* Integer argument (arg2) */
854 sysctl_prochandle, /* Handler function */
855 NULL, /* Data is size variant on ILP32/LP64 */
856 "");
857SYSCTL_PROC(_kern_proc, KERN_PROC_TTY, tty, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
858 0, /* Pointer argument (arg1) */
859 KERN_PROC_TTY, /* Integer argument (arg2) */
860 sysctl_prochandle, /* Handler function */
861 NULL, /* Data is size variant on ILP32/LP64 */
862 "");
863SYSCTL_PROC(_kern_proc, KERN_PROC_PGRP, pgrp, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
864 0, /* Pointer argument (arg1) */
865 KERN_PROC_PGRP, /* Integer argument (arg2) */
866 sysctl_prochandle, /* Handler function */
867 NULL, /* Data is size variant on ILP32/LP64 */
868 "");
869SYSCTL_PROC(_kern_proc, KERN_PROC_UID, uid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
870 0, /* Pointer argument (arg1) */
871 KERN_PROC_UID, /* Integer argument (arg2) */
872 sysctl_prochandle, /* Handler function */
873 NULL, /* Data is size variant on ILP32/LP64 */
874 "");
875SYSCTL_PROC(_kern_proc, KERN_PROC_RUID, ruid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
876 0, /* Pointer argument (arg1) */
877 KERN_PROC_RUID, /* Integer argument (arg2) */
878 sysctl_prochandle, /* Handler function */
879 NULL, /* Data is size variant on ILP32/LP64 */
880 "");
881SYSCTL_PROC(_kern_proc, KERN_PROC_LCID, lcid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
882 0, /* Pointer argument (arg1) */
883 KERN_PROC_LCID, /* Integer argument (arg2) */
884 sysctl_prochandle, /* Handler function */
885 NULL, /* Data is size variant on ILP32/LP64 */
886 "");
887
1c79356b 888
1c79356b 889/*
316670eb 890 * Fill in non-zero fields of an eproc structure for the specified process.
1c79356b 891 */
6d2010ae 892STATIC void
316670eb 893fill_user32_eproc(proc_t p, struct user32_eproc *__restrict ep)
1c79356b 894{
2d21ac55 895 struct tty *tp;
316670eb
A
896 struct pgrp *pg;
897 struct session *sessp;
2d21ac55 898 kauth_cred_t my_cred;
2d21ac55
A
899
900 pg = proc_pgrp(p);
901 sessp = proc_session(p);
1c79356b 902
2d21ac55 903 if (pg != PGRP_NULL) {
2d21ac55
A
904 ep->e_pgid = p->p_pgrpid;
905 ep->e_jobc = pg->pg_jobc;
316670eb 906 if (sessp != SESSION_NULL && sessp->s_ttyvp)
55e303ae 907 ep->e_flag = EPROC_CTTY;
55e303ae 908 }
2d21ac55 909 ep->e_ppid = p->p_ppid;
91447636 910 if (p->p_ucred) {
2d21ac55 911 my_cred = kauth_cred_proc_ref(p);
91447636
A
912
913 /* A fake historical pcred */
6d2010ae
A
914 ep->e_pcred.p_ruid = kauth_cred_getruid(my_cred);
915 ep->e_pcred.p_svuid = kauth_cred_getsvuid(my_cred);
916 ep->e_pcred.p_rgid = kauth_cred_getrgid(my_cred);
917 ep->e_pcred.p_svgid = kauth_cred_getsvgid(my_cred);
316670eb 918
91447636 919 /* A fake historical *kauth_cred_t */
2d21ac55
A
920 ep->e_ucred.cr_ref = my_cred->cr_ref;
921 ep->e_ucred.cr_uid = kauth_cred_getuid(my_cred);
6d2010ae 922 ep->e_ucred.cr_ngroups = posix_cred_get(my_cred)->cr_ngroups;
316670eb
A
923 bcopy(posix_cred_get(my_cred)->cr_groups,
924 ep->e_ucred.cr_groups, NGROUPS * sizeof (gid_t));
91447636 925
2d21ac55 926 kauth_cred_unref(&my_cred);
55e303ae 927 }
55e303ae 928
2d21ac55 929 if ((p->p_flag & P_CONTROLT) && (sessp != SESSION_NULL) &&
b0d623f7 930 (tp = SESSION_TP(sessp))) {
1c79356b 931 ep->e_tdev = tp->t_dev;
2d21ac55 932 ep->e_tpgid = sessp->s_ttypgrpid;
1c79356b
A
933 } else
934 ep->e_tdev = NODEV;
55e303ae 935
316670eb
A
936 if (sessp != SESSION_NULL) {
937 if (SESS_LEADER(p, sessp))
938 ep->e_flag |= EPROC_SLEADER;
2d21ac55 939 session_rele(sessp);
316670eb
A
940 }
941 if (pg != PGRP_NULL)
2d21ac55 942 pg_rele(pg);
1c79356b 943}
55e303ae 944
91447636 945/*
316670eb 946 * Fill in non-zero fields of an LP64 eproc structure for the specified process.
91447636 947 */
6d2010ae 948STATIC void
316670eb 949fill_user64_eproc(proc_t p, struct user64_eproc *__restrict ep)
91447636 950{
2d21ac55 951 struct tty *tp;
316670eb
A
952 struct pgrp *pg;
953 struct session *sessp;
2d21ac55
A
954 kauth_cred_t my_cred;
955
956 pg = proc_pgrp(p);
957 sessp = proc_session(p);
91447636 958
2d21ac55 959 if (pg != PGRP_NULL) {
2d21ac55
A
960 ep->e_pgid = p->p_pgrpid;
961 ep->e_jobc = pg->pg_jobc;
316670eb
A
962 if (sessp != SESSION_NULL && sessp->s_ttyvp)
963 ep->e_flag = EPROC_CTTY;
91447636 964 }
2d21ac55 965 ep->e_ppid = p->p_ppid;
91447636 966 if (p->p_ucred) {
2d21ac55 967 my_cred = kauth_cred_proc_ref(p);
91447636
A
968
969 /* A fake historical pcred */
6d2010ae
A
970 ep->e_pcred.p_ruid = kauth_cred_getruid(my_cred);
971 ep->e_pcred.p_svuid = kauth_cred_getsvuid(my_cred);
972 ep->e_pcred.p_rgid = kauth_cred_getrgid(my_cred);
973 ep->e_pcred.p_svgid = kauth_cred_getsvgid(my_cred);
91447636
A
974
975 /* A fake historical *kauth_cred_t */
2d21ac55
A
976 ep->e_ucred.cr_ref = my_cred->cr_ref;
977 ep->e_ucred.cr_uid = kauth_cred_getuid(my_cred);
6d2010ae 978 ep->e_ucred.cr_ngroups = posix_cred_get(my_cred)->cr_ngroups;
316670eb
A
979 bcopy(posix_cred_get(my_cred)->cr_groups,
980 ep->e_ucred.cr_groups, NGROUPS * sizeof (gid_t));
91447636 981
2d21ac55 982 kauth_cred_unref(&my_cred);
91447636 983 }
91447636 984
2d21ac55 985 if ((p->p_flag & P_CONTROLT) && (sessp != SESSION_NULL) &&
b0d623f7 986 (tp = SESSION_TP(sessp))) {
91447636 987 ep->e_tdev = tp->t_dev;
2d21ac55 988 ep->e_tpgid = sessp->s_ttypgrpid;
91447636
A
989 } else
990 ep->e_tdev = NODEV;
991
316670eb
A
992 if (sessp != SESSION_NULL) {
993 if (SESS_LEADER(p, sessp))
994 ep->e_flag |= EPROC_SLEADER;
2d21ac55 995 session_rele(sessp);
316670eb 996 }
2d21ac55
A
997 if (pg != PGRP_NULL)
998 pg_rele(pg);
91447636
A
999}
1000
1c79356b
A
1001/*
1002 * Fill in an eproc structure for the specified process.
316670eb 1003 * bzeroed by our caller, so only set non-zero fields.
1c79356b 1004 */
6d2010ae 1005STATIC void
316670eb 1006fill_user32_externproc(proc_t p, struct user32_extern_proc *__restrict exp)
1c79356b 1007{
b0d623f7
A
1008 exp->p_starttime.tv_sec = p->p_start.tv_sec;
1009 exp->p_starttime.tv_usec = p->p_start.tv_usec;
316670eb 1010 exp->p_flag = p->p_flag;
2d21ac55
A
1011 if (p->p_lflag & P_LTRACED)
1012 exp->p_flag |= P_TRACED;
1013 if (p->p_lflag & P_LPPWAIT)
1014 exp->p_flag |= P_PPWAIT;
1015 if (p->p_lflag & P_LEXIT)
1016 exp->p_flag |= P_WEXIT;
316670eb
A
1017 exp->p_stat = p->p_stat;
1018 exp->p_pid = p->p_pid;
1019 exp->p_oppid = p->p_oppid;
1c79356b 1020 /* Mach related */
316670eb
A
1021 exp->user_stack = p->user_stack;
1022 exp->p_debugger = p->p_debugger;
1023 exp->sigwait = p->sigwait;
1c79356b 1024 /* scheduling */
2d21ac55 1025#ifdef _PROC_HAS_SCHEDINFO_
316670eb
A
1026 exp->p_estcpu = p->p_estcpu;
1027 exp->p_pctcpu = p->p_pctcpu;
1028 exp->p_slptime = p->p_slptime;
2d21ac55 1029#endif
316670eb
A
1030 exp->p_realtimer.it_interval.tv_sec =
1031 (user32_time_t)p->p_realtimer.it_interval.tv_sec;
1032 exp->p_realtimer.it_interval.tv_usec =
1033 (__int32_t)p->p_realtimer.it_interval.tv_usec;
1034
1035 exp->p_realtimer.it_value.tv_sec =
1036 (user32_time_t)p->p_realtimer.it_value.tv_sec;
1037 exp->p_realtimer.it_value.tv_usec =
1038 (__int32_t)p->p_realtimer.it_value.tv_usec;
1039
1040 exp->p_rtime.tv_sec = (user32_time_t)p->p_rtime.tv_sec;
1041 exp->p_rtime.tv_usec = (__int32_t)p->p_rtime.tv_usec;
1042
1043 exp->p_sigignore = p->p_sigignore;
1044 exp->p_sigcatch = p->p_sigcatch;
1045 exp->p_priority = p->p_priority;
1046 exp->p_nice = p->p_nice;
1047 bcopy(&p->p_comm, &exp->p_comm, MAXCOMLEN);
1048 exp->p_xstat = p->p_xstat;
1049 exp->p_acflag = p->p_acflag;
91447636
A
1050}
1051
1052/*
1053 * Fill in an LP64 version of extern_proc structure for the specified process.
1054 */
6d2010ae 1055STATIC void
316670eb 1056fill_user64_externproc(proc_t p, struct user64_extern_proc *__restrict exp)
91447636 1057{
2d21ac55
A
1058 exp->p_starttime.tv_sec = p->p_start.tv_sec;
1059 exp->p_starttime.tv_usec = p->p_start.tv_usec;
316670eb 1060 exp->p_flag = p->p_flag;
2d21ac55
A
1061 if (p->p_lflag & P_LTRACED)
1062 exp->p_flag |= P_TRACED;
1063 if (p->p_lflag & P_LPPWAIT)
1064 exp->p_flag |= P_PPWAIT;
1065 if (p->p_lflag & P_LEXIT)
1066 exp->p_flag |= P_WEXIT;
316670eb
A
1067 exp->p_stat = p->p_stat;
1068 exp->p_pid = p->p_pid;
1069 exp->p_oppid = p->p_oppid;
91447636 1070 /* Mach related */
316670eb
A
1071 exp->user_stack = p->user_stack;
1072 exp->p_debugger = p->p_debugger;
1073 exp->sigwait = p->sigwait;
91447636 1074 /* scheduling */
2d21ac55 1075#ifdef _PROC_HAS_SCHEDINFO_
316670eb
A
1076 exp->p_estcpu = p->p_estcpu;
1077 exp->p_pctcpu = p->p_pctcpu;
1078 exp->p_slptime = p->p_slptime;
2d21ac55 1079#endif
91447636
A
1080 exp->p_realtimer.it_interval.tv_sec = p->p_realtimer.it_interval.tv_sec;
1081 exp->p_realtimer.it_interval.tv_usec = p->p_realtimer.it_interval.tv_usec;
316670eb 1082
91447636
A
1083 exp->p_realtimer.it_value.tv_sec = p->p_realtimer.it_value.tv_sec;
1084 exp->p_realtimer.it_value.tv_usec = p->p_realtimer.it_value.tv_usec;
316670eb 1085
91447636
A
1086 exp->p_rtime.tv_sec = p->p_rtime.tv_sec;
1087 exp->p_rtime.tv_usec = p->p_rtime.tv_usec;
316670eb
A
1088
1089 exp->p_sigignore = p->p_sigignore;
1090 exp->p_sigcatch = p->p_sigcatch;
1091 exp->p_priority = p->p_priority;
1092 exp->p_nice = p->p_nice;
1093 bcopy(&p->p_comm, &exp->p_comm, MAXCOMLEN);
1094 exp->p_xstat = p->p_xstat;
1095 exp->p_acflag = p->p_acflag;
1c79356b
A
1096}
1097
6d2010ae 1098STATIC void
316670eb 1099fill_user32_proc(proc_t p, struct user32_kinfo_proc *__restrict kp)
55e303ae 1100{
316670eb 1101 /* on a 64 bit kernel, 32 bit users get some truncated information */
b0d623f7
A
1102 fill_user32_externproc(p, &kp->kp_proc);
1103 fill_user32_eproc(p, &kp->kp_eproc);
55e303ae
A
1104}
1105
6d2010ae 1106STATIC void
316670eb 1107fill_user64_proc(proc_t p, struct user64_kinfo_proc *__restrict kp)
91447636 1108{
b0d623f7
A
1109 fill_user64_externproc(p, &kp->kp_proc);
1110 fill_user64_eproc(p, &kp->kp_eproc);
91447636
A
1111}
1112
6d2010ae
A
1113STATIC int
1114sysctl_kdebug_ops SYSCTL_HANDLER_ARGS
1c79356b 1115{
6d2010ae
A
1116 __unused int cmd = oidp->oid_arg2; /* subcommand*/
1117 int *name = arg1; /* oid element argument vector */
1118 int namelen = arg2; /* number of oid element arguments */
1119 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
1120 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
1121// user_addr_t newp = req->newptr; /* user buffer copy in address */
1122// size_t newlen = req->newlen; /* user buffer copy in size */
1123
1124 proc_t p = current_proc();
9bccf70c 1125 int ret=0;
1c79356b 1126
c910b4d9
A
1127 if (namelen == 0)
1128 return(ENOTSUP);
b0d623f7 1129
6d2010ae 1130 ret = suser(kauth_cred_get(), &p->p_acflag);
39236c6e
A
1131#if KPERF
1132 /* Non-root processes may be blessed by kperf to access data
1133 * logged into trace.
1134 */
1135 if (ret)
1136 ret = kperf_access_check();
1137#endif /* KPERF */
91447636 1138 if (ret)
9bccf70c 1139 return(ret);
b0d623f7 1140
1c79356b
A
1141 switch(name[0]) {
1142 case KERN_KDEFLAGS:
1143 case KERN_KDDFLAGS:
1144 case KERN_KDENABLE:
1145 case KERN_KDGETBUF:
1146 case KERN_KDSETUP:
1147 case KERN_KDREMOVE:
1148 case KERN_KDSETREG:
1149 case KERN_KDGETREG:
1150 case KERN_KDREADTR:
3e170ce0
A
1151 case KERN_KDWRITETR:
1152 case KERN_KDWRITEMAP:
1c79356b
A
1153 case KERN_KDPIDTR:
1154 case KERN_KDTHRMAP:
1155 case KERN_KDPIDEX:
1156 case KERN_KDSETRTCDEC:
1157 case KERN_KDSETBUF:
9bccf70c 1158 case KERN_KDGETENTROPY:
316670eb
A
1159 case KERN_KDENABLE_BG_TRACE:
1160 case KERN_KDDISABLE_BG_TRACE:
39236c6e 1161 case KERN_KDREADCURTHRMAP:
316670eb 1162 case KERN_KDSET_TYPEFILTER:
3e170ce0 1163 case KERN_KDBUFWAIT:
39236c6e 1164 case KERN_KDCPUMAP:
3e170ce0
A
1165 case KERN_KDWAIT_BG_TRACE_RESET:
1166 case KERN_KDSET_BG_TYPEFILTER:
1167 case KERN_KDWRITEMAP_V3:
1168 case KERN_KDWRITETR_V3:
6d2010ae 1169 ret = kdbg_control(name, namelen, oldp, oldlenp);
1c79356b
A
1170 break;
1171 default:
91447636 1172 ret= ENOTSUP;
1c79356b
A
1173 break;
1174 }
6d2010ae
A
1175
1176 /* adjust index so we return the right required/consumed amount */
1177 if (!ret)
1178 req->oldidx += req->oldlen;
1179
1180 return (ret);
1c79356b 1181}
6d2010ae
A
1182SYSCTL_PROC(_kern, KERN_KDEBUG, kdebug, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1183 0, /* Pointer argument (arg1) */
1184 0, /* Integer argument (arg2) */
1185 sysctl_kdebug_ops, /* Handler function */
1186 NULL, /* Data pointer */
1187 "");
1c79356b 1188
1c79356b
A
1189
1190/*
55e303ae
A
1191 * Return the top *sizep bytes of the user stack, or the entire area of the
1192 * user stack down through the saved exec_path, whichever is smaller.
1c79356b 1193 */
6d2010ae
A
1194STATIC int
1195sysctl_doprocargs SYSCTL_HANDLER_ARGS
1196{
1197 __unused int cmd = oidp->oid_arg2; /* subcommand*/
1198 int *name = arg1; /* oid element argument vector */
1199 int namelen = arg2; /* number of oid element arguments */
1200 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
1201 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
1202// user_addr_t newp = req->newptr; /* user buffer copy in address */
1203// size_t newlen = req->newlen; /* user buffer copy in size */
1204 int error;
1205
1206 error = sysctl_procargsx( name, namelen, oldp, oldlenp, current_proc(), 0);
1207
1208 /* adjust index so we return the right required/consumed amount */
1209 if (!error)
1210 req->oldidx += req->oldlen;
1211
1212 return (error);
55e303ae 1213}
6d2010ae
A
1214SYSCTL_PROC(_kern, KERN_PROCARGS, procargs, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1215 0, /* Pointer argument (arg1) */
1216 0, /* Integer argument (arg2) */
1217 sysctl_doprocargs, /* Handler function */
1218 NULL, /* Data pointer */
1219 "");
6d2010ae
A
1220
1221STATIC int
1222sysctl_doprocargs2 SYSCTL_HANDLER_ARGS
1223{
1224 __unused int cmd = oidp->oid_arg2; /* subcommand*/
1225 int *name = arg1; /* oid element argument vector */
1226 int namelen = arg2; /* number of oid element arguments */
1227 user_addr_t oldp = req->oldptr; /* user buffer copy out address */
1228 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
1229// user_addr_t newp = req->newptr; /* user buffer copy in address */
1230// size_t newlen = req->newlen; /* user buffer copy in size */
1231 int error;
55e303ae 1232
6d2010ae
A
1233 error = sysctl_procargsx( name, namelen, oldp, oldlenp, current_proc(), 1);
1234
1235 /* adjust index so we return the right required/consumed amount */
1236 if (!error)
1237 req->oldidx += req->oldlen;
1238
1239 return (error);
55e303ae 1240}
6d2010ae
A
1241SYSCTL_PROC(_kern, KERN_PROCARGS2, procargs2, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED,
1242 0, /* Pointer argument (arg1) */
1243 0, /* Integer argument (arg2) */
1244 sysctl_doprocargs2, /* Handler function */
1245 NULL, /* Data pointer */
1246 "");
55e303ae 1247
6d2010ae 1248STATIC int
c910b4d9 1249sysctl_procargsx(int *name, u_int namelen, user_addr_t where,
2d21ac55 1250 size_t *sizep, proc_t cur_proc, int argc_yes)
1c79356b 1251{
2d21ac55 1252 proc_t p;
91447636 1253 int buflen = where != USER_ADDR_NULL ? *sizep : 0;
1c79356b 1254 int error = 0;
2d21ac55 1255 struct _vm_map *proc_map;
1c79356b
A
1256 struct task * task;
1257 vm_map_copy_t tmp;
91447636
A
1258 user_addr_t arg_addr;
1259 size_t arg_size;
1c79356b 1260 caddr_t data;
2d21ac55 1261 size_t argslen=0;
91447636 1262 int size;
1c79356b 1263 vm_offset_t copy_start, copy_end;
1c79356b
A
1264 kern_return_t ret;
1265 int pid;
2d21ac55
A
1266 kauth_cred_t my_cred;
1267 uid_t uid;
1c79356b 1268
c910b4d9
A
1269 if ( namelen < 1 )
1270 return(EINVAL);
b0d623f7 1271
55e303ae 1272 if (argc_yes)
91447636 1273 buflen -= sizeof(int); /* reserve first word to return argc */
1c79356b 1274
91447636
A
1275 /* we only care about buflen when where (oldp from sysctl) is not NULL. */
1276 /* when where (oldp from sysctl) is NULL and sizep (oldlenp from sysctl */
1277 /* is not NULL then the caller wants us to return the length needed to */
1278 /* hold the data we would return */
1279 if (where != USER_ADDR_NULL && (buflen <= 0 || buflen > ARG_MAX)) {
1c79356b
A
1280 return(EINVAL);
1281 }
1282 arg_size = buflen;
1283
1284 /*
1285 * Lookup process by pid
1286 */
1287 pid = name[0];
2d21ac55 1288 p = proc_find(pid);
1c79356b
A
1289 if (p == NULL) {
1290 return(EINVAL);
1291 }
1292
1293 /*
1294 * Copy the top N bytes of the stack.
1295 * On all machines we have so far, the stack grows
1296 * downwards.
1297 *
1298 * If the user expects no more than N bytes of
1299 * argument list, use that as a guess for the
1300 * size.
1301 */
1302
2d21ac55
A
1303 if (!p->user_stack) {
1304 proc_rele(p);
1c79356b 1305 return(EINVAL);
2d21ac55 1306 }
1c79356b 1307
91447636
A
1308 if (where == USER_ADDR_NULL) {
1309 /* caller only wants to know length of proc args data */
2d21ac55
A
1310 if (sizep == NULL) {
1311 proc_rele(p);
91447636 1312 return(EFAULT);
2d21ac55 1313 }
91447636
A
1314
1315 size = p->p_argslen;
2d21ac55 1316 proc_rele(p);
91447636
A
1317 if (argc_yes) {
1318 size += sizeof(int);
1319 }
1320 else {
1321 /*
1322 * old PROCARGS will return the executable's path and plus some
1323 * extra space for work alignment and data tags
1324 */
1325 size += PATH_MAX + (6 * sizeof(int));
1326 }
1327 size += (size & (sizeof(int) - 1)) ? (sizeof(int) - (size & (sizeof(int) - 1))) : 0;
1328 *sizep = size;
1329 return (0);
1330 }
1331
2d21ac55
A
1332 my_cred = kauth_cred_proc_ref(p);
1333 uid = kauth_cred_getuid(my_cred);
1334 kauth_cred_unref(&my_cred);
1335
1336 if ((uid != kauth_cred_getuid(kauth_cred_get()))
1337 && suser(kauth_cred_get(), &cur_proc->p_acflag)) {
1338 proc_rele(p);
9bccf70c 1339 return (EINVAL);
2d21ac55 1340 }
91447636
A
1341
1342 if ((u_int)arg_size > p->p_argslen)
1343 arg_size = round_page(p->p_argslen);
1344
1345 arg_addr = p->user_stack - arg_size;
1c79356b
A
1346
1347
1348 /*
1349 * Before we can block (any VM code), make another
1350 * reference to the map to keep it alive. We do
1351 * that by getting a reference on the task itself.
1352 */
1353 task = p->task;
2d21ac55
A
1354 if (task == NULL) {
1355 proc_rele(p);
1c79356b 1356 return(EINVAL);
2d21ac55 1357 }
1c79356b 1358
2d21ac55 1359 argslen = p->p_argslen;
0b4e3aa0 1360 /*
91447636
A
1361 * Once we have a task reference we can convert that into a
1362 * map reference, which we will use in the calls below. The
1363 * task/process may change its map after we take this reference
1364 * (see execve), but the worst that will happen then is a return
1365 * of stale info (which is always a possibility).
0b4e3aa0 1366 */
91447636 1367 task_reference(task);
2d21ac55 1368 proc_rele(p);
91447636
A
1369 proc_map = get_task_map_reference(task);
1370 task_deallocate(task);
2d21ac55 1371
91447636
A
1372 if (proc_map == NULL)
1373 return(EINVAL);
1c79356b 1374
91447636 1375
3e170ce0 1376 ret = kmem_alloc(kernel_map, &copy_start, round_page(arg_size), VM_KERN_MEMORY_BSD);
1c79356b 1377 if (ret != KERN_SUCCESS) {
91447636 1378 vm_map_deallocate(proc_map);
1c79356b
A
1379 return(ENOMEM);
1380 }
1381
91447636 1382 copy_end = round_page(copy_start + arg_size);
1c79356b 1383
91447636
A
1384 if( vm_map_copyin(proc_map, (vm_map_address_t)arg_addr,
1385 (vm_map_size_t)arg_size, FALSE, &tmp) != KERN_SUCCESS) {
1386 vm_map_deallocate(proc_map);
1c79356b 1387 kmem_free(kernel_map, copy_start,
91447636 1388 round_page(arg_size));
1c79356b
A
1389 return (EIO);
1390 }
1391
1392 /*
1393 * Now that we've done the copyin from the process'
1394 * map, we can release the reference to it.
1395 */
91447636 1396 vm_map_deallocate(proc_map);
1c79356b 1397
91447636
A
1398 if( vm_map_copy_overwrite(kernel_map,
1399 (vm_map_address_t)copy_start,
1400 tmp, FALSE) != KERN_SUCCESS) {
1c79356b 1401 kmem_free(kernel_map, copy_start,
91447636 1402 round_page(arg_size));
2dced7af 1403 vm_map_copy_discard(tmp);
1c79356b
A
1404 return (EIO);
1405 }
1406
2d21ac55
A
1407 if (arg_size > argslen) {
1408 data = (caddr_t) (copy_end - argslen);
1409 size = argslen;
55e303ae 1410 } else {
91447636
A
1411 data = (caddr_t) (copy_end - arg_size);
1412 size = arg_size;
55e303ae 1413 }
1c79356b 1414
3e170ce0
A
1415 /*
1416 * When these sysctls were introduced, the first string in the strings
1417 * section was just the bare path of the executable. However, for security
1418 * reasons we now prefix this string with executable_path= so it can be
1419 * parsed getenv style. To avoid binary compatability issues with exising
1420 * callers of this sysctl, we strip it off here if present.
1421 * (rdar://problem/13746466)
1422 */
1423#define EXECUTABLE_KEY "executable_path="
1424 if (strncmp(EXECUTABLE_KEY, data, strlen(EXECUTABLE_KEY)) == 0){
1425 data += strlen(EXECUTABLE_KEY);
1426 size -= strlen(EXECUTABLE_KEY);
1427 }
1428
55e303ae
A
1429 if (argc_yes) {
1430 /* Put processes argc as the first word in the copyout buffer */
1431 suword(where, p->p_argc);
91447636
A
1432 error = copyout(data, (where + sizeof(int)), size);
1433 size += sizeof(int);
55e303ae
A
1434 } else {
1435 error = copyout(data, where, size);
1436
1437 /*
1438 * Make the old PROCARGS work to return the executable's path
1439 * But, only if there is enough space in the provided buffer
1440 *
1441 * on entry: data [possibily] points to the beginning of the path
1442 *
1443 * Note: we keep all pointers&sizes aligned to word boundries
1444 */
2d21ac55 1445 if ( (! error) && (buflen > 0 && (u_int)buflen > argslen) )
55e303ae 1446 {
91447636 1447 int binPath_sz, alignedBinPath_sz = 0;
55e303ae 1448 int extraSpaceNeeded, addThis;
91447636 1449 user_addr_t placeHere;
55e303ae 1450 char * str = (char *) data;
91447636 1451 int max_len = size;
55e303ae
A
1452
1453 /* Some apps are really bad about messing up their stacks
1454 So, we have to be extra careful about getting the length
1455 of the executing binary. If we encounter an error, we bail.
1456 */
1457
1458 /* Limit ourselves to PATH_MAX paths */
1459 if ( max_len > PATH_MAX ) max_len = PATH_MAX;
1460
1461 binPath_sz = 0;
1462
1463 while ( (binPath_sz < max_len-1) && (*str++ != 0) )
1464 binPath_sz++;
1465
91447636 1466 /* If we have a NUL terminator, copy it, too */
55e303ae
A
1467 if (binPath_sz < max_len-1) binPath_sz += 1;
1468
1469 /* Pre-Flight the space requiremnts */
1470
1471 /* Account for the padding that fills out binPath to the next word */
91447636 1472 alignedBinPath_sz += (binPath_sz & (sizeof(int)-1)) ? (sizeof(int)-(binPath_sz & (sizeof(int)-1))) : 0;
55e303ae
A
1473
1474 placeHere = where + size;
1475
1476 /* Account for the bytes needed to keep placeHere word aligned */
91447636 1477 addThis = (placeHere & (sizeof(int)-1)) ? (sizeof(int)-(placeHere & (sizeof(int)-1))) : 0;
55e303ae
A
1478
1479 /* Add up all the space that is needed */
91447636 1480 extraSpaceNeeded = alignedBinPath_sz + addThis + binPath_sz + (4 * sizeof(int));
55e303ae
A
1481
1482 /* is there is room to tack on argv[0]? */
2d21ac55 1483 if ( (buflen & ~(sizeof(int)-1)) >= ( argslen + extraSpaceNeeded ))
55e303ae
A
1484 {
1485 placeHere += addThis;
1486 suword(placeHere, 0);
91447636 1487 placeHere += sizeof(int);
55e303ae 1488 suword(placeHere, 0xBFFF0000);
91447636 1489 placeHere += sizeof(int);
55e303ae 1490 suword(placeHere, 0);
91447636 1491 placeHere += sizeof(int);
55e303ae
A
1492 error = copyout(data, placeHere, binPath_sz);
1493 if ( ! error )
1494 {
1495 placeHere += binPath_sz;
1496 suword(placeHere, 0);
1497 size += extraSpaceNeeded;
1498 }
1499 }
1500 }
1501 }
1502
1503 if (copy_start != (vm_offset_t) 0) {
1504 kmem_free(kernel_map, copy_start, copy_end - copy_start);
1c79356b
A
1505 }
1506 if (error) {
1507 return(error);
1508 }
1509
91447636 1510 if (where != USER_ADDR_NULL)
1c79356b
A
1511 *sizep = size;
1512 return (0);
1513}
55e303ae
A
1514
1515
1516/*
2d21ac55 1517 * Max number of concurrent aio requests
55e303ae 1518 */
6d2010ae 1519STATIC int
2d21ac55
A
1520sysctl_aiomax
1521(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
55e303ae 1522{
2d21ac55
A
1523 int new_value, changed;
1524 int error = sysctl_io_number(req, aio_max_requests, sizeof(int), &new_value, &changed);
1525 if (changed) {
1526 /* make sure the system-wide limit is greater than the per process limit */
316670eb 1527 if (new_value >= aio_max_requests_per_process && new_value <= AIO_MAX_REQUESTS)
55e303ae
A
1528 aio_max_requests = new_value;
1529 else
1530 error = EINVAL;
1531 }
2d21ac55
A
1532 return(error);
1533}
55e303ae
A
1534
1535
1536/*
2d21ac55 1537 * Max number of concurrent aio requests per process
55e303ae 1538 */
6d2010ae 1539STATIC int
2d21ac55
A
1540sysctl_aioprocmax
1541(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
55e303ae 1542{
2d21ac55
A
1543 int new_value, changed;
1544 int error = sysctl_io_number(req, aio_max_requests_per_process, sizeof(int), &new_value, &changed);
1545 if (changed) {
1546 /* make sure per process limit is less than the system-wide limit */
1547 if (new_value <= aio_max_requests && new_value >= AIO_LISTIO_MAX)
55e303ae
A
1548 aio_max_requests_per_process = new_value;
1549 else
1550 error = EINVAL;
1551 }
2d21ac55
A
1552 return(error);
1553}
55e303ae
A
1554
1555
1556/*
2d21ac55 1557 * Max number of async IO worker threads
55e303ae 1558 */
6d2010ae 1559STATIC int
2d21ac55
A
1560sysctl_aiothreads
1561(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
55e303ae 1562{
2d21ac55
A
1563 int new_value, changed;
1564 int error = sysctl_io_number(req, aio_worker_threads, sizeof(int), &new_value, &changed);
1565 if (changed) {
1566 /* we only allow an increase in the number of worker threads */
55e303ae 1567 if (new_value > aio_worker_threads ) {
2d21ac55 1568 _aio_create_worker_threads((new_value - aio_worker_threads));
55e303ae
A
1569 aio_worker_threads = new_value;
1570 }
1571 else
1572 error = EINVAL;
1573 }
2d21ac55
A
1574 return(error);
1575}
55e303ae
A
1576
1577
1578/*
2d21ac55 1579 * System-wide limit on the max number of processes
55e303ae 1580 */
6d2010ae 1581STATIC int
2d21ac55
A
1582sysctl_maxproc
1583(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
55e303ae 1584{
2d21ac55
A
1585 int new_value, changed;
1586 int error = sysctl_io_number(req, maxproc, sizeof(int), &new_value, &changed);
1587 if (changed) {
b0d623f7 1588 AUDIT_ARG(value32, new_value);
2d21ac55
A
1589 /* make sure the system-wide limit is less than the configured hard
1590 limit set at kernel compilation */
1591 if (new_value <= hard_maxproc && new_value > 0)
1592 maxproc = new_value;
1593 else
55e303ae
A
1594 error = EINVAL;
1595 }
2d21ac55
A
1596 return(error);
1597}
55e303ae 1598
2d21ac55 1599SYSCTL_STRING(_kern, KERN_OSTYPE, ostype,
6d2010ae 1600 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2d21ac55
A
1601 ostype, 0, "");
1602SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease,
6d2010ae 1603 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2d21ac55
A
1604 osrelease, 0, "");
1605SYSCTL_INT(_kern, KERN_OSREV, osrevision,
6d2010ae 1606 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
b0d623f7 1607 (int *)NULL, BSD, "");
2d21ac55 1608SYSCTL_STRING(_kern, KERN_VERSION, version,
6d2010ae 1609 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2d21ac55 1610 version, 0, "");
6d2010ae
A
1611SYSCTL_STRING(_kern, OID_AUTO, uuid,
1612 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
39236c6e 1613 &kernel_uuid_string[0], 0, "");
2d21ac55 1614
b0d623f7
A
1615#if DEBUG
1616int debug_kprint_syscall = 0;
1617char debug_kprint_syscall_process[MAXCOMLEN+1];
1618
6d2010ae 1619/* Thread safe: bits and string value are not used to reclaim state */
b0d623f7 1620SYSCTL_INT (_debug, OID_AUTO, kprint_syscall,
6d2010ae 1621 CTLFLAG_RW | CTLFLAG_LOCKED, &debug_kprint_syscall, 0, "kprintf syscall tracing");
b0d623f7 1622SYSCTL_STRING(_debug, OID_AUTO, kprint_syscall_process,
6d2010ae 1623 CTLFLAG_RW | CTLFLAG_LOCKED, debug_kprint_syscall_process, sizeof(debug_kprint_syscall_process),
b0d623f7
A
1624 "name of process for kprintf syscall tracing");
1625
1626int debug_kprint_current_process(const char **namep)
1627{
1628 struct proc *p = current_proc();
1629
1630 if (p == NULL) {
1631 return 0;
1632 }
1633
1634 if (debug_kprint_syscall_process[0]) {
1635 /* user asked to scope tracing to a particular process name */
1636 if(0 == strncmp(debug_kprint_syscall_process,
1637 p->p_comm, sizeof(debug_kprint_syscall_process))) {
1638 /* no value in telling the user that we traced what they asked */
1639 if(namep) *namep = NULL;
1640
1641 return 1;
1642 } else {
1643 return 0;
1644 }
1645 }
1646
1647 /* trace all processes. Tell user what we traced */
1648 if (namep) {
1649 *namep = p->p_comm;
1650 }
1651
1652 return 1;
1653}
1654#endif
1655
2d21ac55
A
1656/* PR-5293665: need to use a callback function for kern.osversion to set
1657 * osversion in IORegistry */
55e303ae 1658
6d2010ae 1659STATIC int
2d21ac55 1660sysctl_osversion(__unused struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req)
55e303ae 1661{
2d21ac55 1662 int rval = 0;
55e303ae 1663
2d21ac55
A
1664 rval = sysctl_handle_string(oidp, arg1, arg2, req);
1665
1666 if (req->newptr) {
1667 IORegistrySetOSBuildVersion((char *)arg1);
1668 }
1669
1670 return rval;
1671}
1672
1673SYSCTL_PROC(_kern, KERN_OSVERSION, osversion,
6d2010ae 1674 CTLFLAG_RW | CTLFLAG_KERN | CTLTYPE_STRING | CTLFLAG_LOCKED,
2d21ac55
A
1675 osversion, 256 /* OSVERSIZE*/,
1676 sysctl_osversion, "A", "");
1677
6d2010ae 1678STATIC int
2d21ac55
A
1679sysctl_sysctl_bootargs
1680(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1681{
1682 int error;
1683 char buf[256];
1684
1685 strlcpy(buf, PE_boot_args(), 256);
1686 error = sysctl_io_string(req, buf, 256, 0, NULL);
1687 return(error);
1688}
1689
1690SYSCTL_PROC(_kern, OID_AUTO, bootargs,
1691 CTLFLAG_LOCKED | CTLFLAG_RD | CTLFLAG_KERN | CTLTYPE_STRING,
1692 NULL, 0,
1693 sysctl_sysctl_bootargs, "A", "bootargs");
1694
1695SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles,
6d2010ae 1696 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2d21ac55
A
1697 &maxfiles, 0, "");
1698SYSCTL_INT(_kern, KERN_ARGMAX, argmax,
6d2010ae 1699 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
b0d623f7 1700 (int *)NULL, ARG_MAX, "");
2d21ac55 1701SYSCTL_INT(_kern, KERN_POSIX1, posix1version,
6d2010ae 1702 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
b0d623f7 1703 (int *)NULL, _POSIX_VERSION, "");
2d21ac55 1704SYSCTL_INT(_kern, KERN_NGROUPS, ngroups,
6d2010ae 1705 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
b0d623f7 1706 (int *)NULL, NGROUPS_MAX, "");
2d21ac55 1707SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control,
6d2010ae 1708 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
b0d623f7 1709 (int *)NULL, 1, "");
2d21ac55
A
1710#if 1 /* _POSIX_SAVED_IDS from <unistd.h> */
1711SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids,
6d2010ae 1712 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
b0d623f7 1713 (int *)NULL, 1, "");
2d21ac55
A
1714#else
1715SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids,
6d2010ae 1716 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2d21ac55
A
1717 NULL, 0, "");
1718#endif
b0d623f7 1719SYSCTL_INT(_kern, OID_AUTO, num_files,
6d2010ae 1720 CTLFLAG_RD | CTLFLAG_LOCKED,
b0d623f7
A
1721 &nfiles, 0, "");
1722SYSCTL_COMPAT_INT(_kern, OID_AUTO, num_vnodes,
6d2010ae 1723 CTLFLAG_RD | CTLFLAG_LOCKED,
b0d623f7
A
1724 &numvnodes, 0, "");
1725SYSCTL_INT(_kern, OID_AUTO, num_tasks,
6d2010ae 1726 CTLFLAG_RD | CTLFLAG_LOCKED,
b0d623f7
A
1727 &task_max, 0, "");
1728SYSCTL_INT(_kern, OID_AUTO, num_threads,
6d2010ae 1729 CTLFLAG_RD | CTLFLAG_LOCKED,
b0d623f7
A
1730 &thread_max, 0, "");
1731SYSCTL_INT(_kern, OID_AUTO, num_taskthreads,
6d2010ae 1732 CTLFLAG_RD | CTLFLAG_LOCKED,
b0d623f7 1733 &task_threadmax, 0, "");
2d21ac55 1734
6d2010ae 1735STATIC int
2d21ac55
A
1736sysctl_maxvnodes (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1737{
b0d623f7 1738 int oldval = desiredvnodes;
2d21ac55 1739 int error = sysctl_io_number(req, desiredvnodes, sizeof(int), &desiredvnodes, NULL);
b0d623f7
A
1740
1741 if (oldval != desiredvnodes) {
1742 reset_vmobjectcache(oldval, desiredvnodes);
1743 resize_namecache(desiredvnodes);
1744 }
1745
2d21ac55
A
1746 return(error);
1747}
1748
6d2010ae
A
1749SYSCTL_INT(_kern, OID_AUTO, namecache_disabled,
1750 CTLFLAG_RW | CTLFLAG_LOCKED,
1751 &nc_disabled, 0, "");
1752
2d21ac55 1753SYSCTL_PROC(_kern, KERN_MAXVNODES, maxvnodes,
6d2010ae 1754 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
1755 0, 0, sysctl_maxvnodes, "I", "");
1756
1757SYSCTL_PROC(_kern, KERN_MAXPROC, maxproc,
6d2010ae 1758 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
1759 0, 0, sysctl_maxproc, "I", "");
1760
1761SYSCTL_PROC(_kern, KERN_AIOMAX, aiomax,
6d2010ae 1762 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
1763 0, 0, sysctl_aiomax, "I", "");
1764
1765SYSCTL_PROC(_kern, KERN_AIOPROCMAX, aioprocmax,
6d2010ae 1766 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
1767 0, 0, sysctl_aioprocmax, "I", "");
1768
1769SYSCTL_PROC(_kern, KERN_AIOTHREADS, aiothreads,
6d2010ae 1770 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
1771 0, 0, sysctl_aiothreads, "I", "");
1772
fe8ab488
A
1773#if (DEVELOPMENT || DEBUG)
1774extern int sched_smt_balance;
1775SYSCTL_INT(_kern, OID_AUTO, sched_smt_balance,
1776 CTLFLAG_KERN| CTLFLAG_RW| CTLFLAG_LOCKED,
1777 &sched_smt_balance, 0, "");
1778#endif
1779
6d2010ae 1780STATIC int
2d21ac55
A
1781sysctl_securelvl
1782(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1783{
1784 int new_value, changed;
1785 int error = sysctl_io_number(req, securelevel, sizeof(int), &new_value, &changed);
1786 if (changed) {
1787 if (!(new_value < securelevel && req->p->p_pid != 1)) {
1788 proc_list_lock();
1789 securelevel = new_value;
1790 proc_list_unlock();
1791 } else {
1792 error = EPERM;
e5568f75 1793 }
2d21ac55
A
1794 }
1795 return(error);
1796}
1797
1798SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel,
6d2010ae 1799 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
1800 0, 0, sysctl_securelvl, "I", "");
1801
1802
6d2010ae 1803STATIC int
2d21ac55
A
1804sysctl_domainname
1805(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1806{
1807 int error, changed;
1808 error = sysctl_io_string(req, domainname, sizeof(domainname), 0, &changed);
1809 if (changed) {
1810 domainnamelen = strlen(domainname);
1811 }
1812 return(error);
1813}
1814
1815SYSCTL_PROC(_kern, KERN_DOMAINNAME, nisdomainname,
6d2010ae 1816 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
1817 0, 0, sysctl_domainname, "A", "");
1818
b0d623f7 1819SYSCTL_COMPAT_INT(_kern, KERN_HOSTID, hostid,
6d2010ae 1820 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2d21ac55
A
1821 &hostid, 0, "");
1822
6d2010ae 1823STATIC int
2d21ac55
A
1824sysctl_hostname
1825(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1826{
1827 int error, changed;
1828 error = sysctl_io_string(req, hostname, sizeof(hostname), 1, &changed);
1829 if (changed) {
1830 hostnamelen = req->newlen;
1831 }
1832 return(error);
1833}
1834
1835
1836SYSCTL_PROC(_kern, KERN_HOSTNAME, hostname,
6d2010ae 1837 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
1838 0, 0, sysctl_hostname, "A", "");
1839
6d2010ae 1840STATIC int
2d21ac55
A
1841sysctl_procname
1842(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1843{
1844 /* Original code allowed writing, I'm copying this, although this all makes
1845 no sense to me. Besides, this sysctl is never used. */
1846 return sysctl_io_string(req, &req->p->p_name[0], (2*MAXCOMLEN+1), 1, NULL);
1847}
1848
1849SYSCTL_PROC(_kern, KERN_PROCNAME, procname,
6d2010ae 1850 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED,
2d21ac55
A
1851 0, 0, sysctl_procname, "A", "");
1852
1853SYSCTL_INT(_kern, KERN_SPECULATIVE_READS, speculative_reads_disabled,
6d2010ae 1854 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2d21ac55
A
1855 &speculative_reads_disabled, 0, "");
1856
6d2010ae
A
1857SYSCTL_INT(_kern, OID_AUTO, ignore_is_ssd,
1858 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1859 &ignore_is_ssd, 0, "");
1860
3e170ce0
A
1861SYSCTL_INT(_kern, OID_AUTO, root_is_CF_drive,
1862 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1863 &root_is_CF_drive, 0, "");
1864
fe8ab488 1865SYSCTL_UINT(_kern, OID_AUTO, preheat_max_bytes,
6d2010ae 1866 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
fe8ab488 1867 &preheat_max_bytes, 0, "");
b0d623f7 1868
fe8ab488 1869SYSCTL_UINT(_kern, OID_AUTO, preheat_min_bytes,
6d2010ae 1870 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
fe8ab488 1871 &preheat_min_bytes, 0, "");
b0d623f7 1872
6d2010ae
A
1873SYSCTL_UINT(_kern, OID_AUTO, speculative_prefetch_max,
1874 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1875 &speculative_prefetch_max, 0, "");
b0d623f7 1876
316670eb
A
1877SYSCTL_UINT(_kern, OID_AUTO, speculative_prefetch_max_iosize,
1878 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1879 &speculative_prefetch_max_iosize, 0, "");
1880
6d2010ae
A
1881SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_target,
1882 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1883 &vm_page_free_target, 0, "");
1884
1885SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_min,
1886 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1887 &vm_page_free_min, 0, "");
1888
1889SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_reserved,
1890 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1891 &vm_page_free_reserved, 0, "");
1892
1893SYSCTL_UINT(_kern, OID_AUTO, vm_page_speculative_percentage,
1894 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1895 &vm_page_speculative_percentage, 0, "");
1896
1897SYSCTL_UINT(_kern, OID_AUTO, vm_page_speculative_q_age_ms,
1898 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1899 &vm_page_speculative_q_age_ms, 0, "");
1900
1901SYSCTL_UINT(_kern, OID_AUTO, vm_max_delayed_work_limit,
1902 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1903 &vm_max_delayed_work_limit, 0, "");
1904
1905SYSCTL_UINT(_kern, OID_AUTO, vm_max_batch,
1906 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
1907 &vm_max_batch, 0, "");
1908
39236c6e
A
1909SYSCTL_STRING(_kern, OID_AUTO, bootsessionuuid,
1910 CTLFLAG_RD | CTLFLAG_LOCKED,
1911 &bootsessionuuid_string, sizeof(bootsessionuuid_string) , "");
6d2010ae
A
1912
1913STATIC int
2d21ac55
A
1914sysctl_boottime
1915(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1916{
b0d623f7
A
1917 time_t tv_sec = boottime_sec();
1918 struct proc *p = req->p;
2d21ac55 1919
b0d623f7
A
1920 if (proc_is64bit(p)) {
1921 struct user64_timeval t;
1922 t.tv_sec = tv_sec;
1923 t.tv_usec = 0;
1924 return sysctl_io_opaque(req, &t, sizeof(t), NULL);
1925 } else {
1926 struct user32_timeval t;
1927 t.tv_sec = tv_sec;
1928 t.tv_usec = 0;
1929 return sysctl_io_opaque(req, &t, sizeof(t), NULL);
1930 }
2d21ac55
A
1931}
1932
1933SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime,
fe8ab488 1934 CTLTYPE_STRUCT | CTLFLAG_KERN | CTLFLAG_RD | CTLFLAG_LOCKED,
2d21ac55
A
1935 0, 0, sysctl_boottime, "S,timeval", "");
1936
6d2010ae 1937STATIC int
2d21ac55
A
1938sysctl_symfile
1939(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1940{
1941 char *str;
1942 int error = get_kernel_symfile(req->p, &str);
1943 if (error)
1944 return (error);
1945 return sysctl_io_string(req, str, 0, 0, NULL);
1946}
1947
1948
1949SYSCTL_PROC(_kern, KERN_SYMFILE, symfile,
6d2010ae 1950 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
2d21ac55
A
1951 0, 0, sysctl_symfile, "A", "");
1952
1953#if NFSCLIENT
6d2010ae 1954STATIC int
2d21ac55
A
1955sysctl_netboot
1956(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1957{
1958 return sysctl_io_number(req, netboot_root(), sizeof(int), NULL, NULL);
1959}
1960
1961SYSCTL_PROC(_kern, KERN_NETBOOT, netboot,
6d2010ae 1962 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2d21ac55
A
1963 0, 0, sysctl_netboot, "I", "");
1964#endif
1965
b7266188 1966#ifdef CONFIG_IMGSRC_ACCESS
6d2010ae
A
1967/*
1968 * Legacy--act as if only one layer of nesting is possible.
1969 */
1970STATIC int
b7266188
A
1971sysctl_imgsrcdev
1972(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1973{
1974 vfs_context_t ctx = vfs_context_current();
1975 vnode_t devvp;
1976 int result;
1977
1978 if (!vfs_context_issuser(ctx)) {
1979 return EPERM;
1980 }
1981
6d2010ae 1982 if (imgsrc_rootvnodes[0] == NULL) {
b7266188
A
1983 return ENOENT;
1984 }
1985
6d2010ae 1986 result = vnode_getwithref(imgsrc_rootvnodes[0]);
b7266188
A
1987 if (result != 0) {
1988 return result;
1989 }
1990
6d2010ae 1991 devvp = vnode_mount(imgsrc_rootvnodes[0])->mnt_devvp;
b7266188
A
1992 result = vnode_getwithref(devvp);
1993 if (result != 0) {
1994 goto out;
1995 }
1996
1997 result = sysctl_io_number(req, vnode_specrdev(devvp), sizeof(dev_t), NULL, NULL);
1998
1999 vnode_put(devvp);
2000out:
6d2010ae 2001 vnode_put(imgsrc_rootvnodes[0]);
b7266188
A
2002 return result;
2003}
2004
2005SYSCTL_PROC(_kern, OID_AUTO, imgsrcdev,
6d2010ae 2006 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
b7266188 2007 0, 0, sysctl_imgsrcdev, "I", "");
6d2010ae
A
2008
2009STATIC int
2010sysctl_imgsrcinfo
2011(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2012{
2013 int error;
2014 struct imgsrc_info info[MAX_IMAGEBOOT_NESTING]; /* 2 for now, no problem */
2015 uint32_t i;
2016 vnode_t rvp, devvp;
2017
2018 if (imgsrc_rootvnodes[0] == NULLVP) {
2019 return ENXIO;
2020 }
2021
2022 for (i = 0; i < MAX_IMAGEBOOT_NESTING; i++) {
2023 /*
2024 * Go get the root vnode.
2025 */
2026 rvp = imgsrc_rootvnodes[i];
2027 if (rvp == NULLVP) {
2028 break;
2029 }
2030
2031 error = vnode_get(rvp);
2032 if (error != 0) {
2033 return error;
2034 }
2035
2036 /*
2037 * For now, no getting at a non-local volume.
2038 */
2039 devvp = vnode_mount(rvp)->mnt_devvp;
2040 if (devvp == NULL) {
2041 vnode_put(rvp);
2042 return EINVAL;
2043 }
2044
2045 error = vnode_getwithref(devvp);
2046 if (error != 0) {
2047 vnode_put(rvp);
2048 return error;
2049 }
2050
2051 /*
2052 * Fill in info.
2053 */
2054 info[i].ii_dev = vnode_specrdev(devvp);
2055 info[i].ii_flags = 0;
2056 info[i].ii_height = i;
2057 bzero(info[i].ii_reserved, sizeof(info[i].ii_reserved));
2058
2059 vnode_put(devvp);
2060 vnode_put(rvp);
2061 }
2062
2063 return sysctl_io_opaque(req, info, i * sizeof(info[0]), NULL);
2064}
2065
2066SYSCTL_PROC(_kern, OID_AUTO, imgsrcinfo,
2067 CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_LOCKED,
2068 0, 0, sysctl_imgsrcinfo, "I", "");
2069
b7266188
A
2070#endif /* CONFIG_IMGSRC_ACCESS */
2071
39236c6e
A
2072
2073SYSCTL_DECL(_kern_timer);
2074SYSCTL_NODE(_kern, OID_AUTO, timer, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "timer");
2075
fe8ab488 2076
39236c6e
A
2077SYSCTL_INT(_kern_timer, OID_AUTO, coalescing_enabled,
2078 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
6d2010ae
A
2079 &mach_timer_coalescing_enabled, 0, "");
2080
39236c6e
A
2081SYSCTL_QUAD(_kern_timer, OID_AUTO, deadline_tracking_bin_1,
2082 CTLFLAG_RW | CTLFLAG_LOCKED,
2083 &timer_deadline_tracking_bin_1, "");
2084SYSCTL_QUAD(_kern_timer, OID_AUTO, deadline_tracking_bin_2,
2085 CTLFLAG_RW | CTLFLAG_LOCKED,
2086 &timer_deadline_tracking_bin_2, "");
2087
2088SYSCTL_DECL(_kern_timer_longterm);
2089SYSCTL_NODE(_kern_timer, OID_AUTO, longterm, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "longterm");
2090
fe8ab488 2091
39236c6e
A
2092/* Must match definition in osfmk/kern/timer_call.c */
2093enum {
2094 THRESHOLD, QCOUNT,
2095 ENQUEUES, DEQUEUES, ESCALATES, SCANS, PREEMPTS,
2096 LATENCY, LATENCY_MIN, LATENCY_MAX
2097};
2098extern uint64_t timer_sysctl_get(int);
2099extern int timer_sysctl_set(int, uint64_t);
2100
2101STATIC int
2102sysctl_timer
2103(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2104{
2105 int oid = (int)arg1;
2106 uint64_t value = timer_sysctl_get(oid);
2107 uint64_t new_value;
2108 int error;
2109 int changed;
2110
2111 error = sysctl_io_number(req, value, sizeof(value), &new_value, &changed);
2112 if (changed)
2113 error = timer_sysctl_set(oid, new_value);
2114
2115 return error;
2116}
2117
2118SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, threshold,
2119 CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
2120 (void *) THRESHOLD, 0, sysctl_timer, "Q", "");
2121SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, qlen,
2122 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2123 (void *) QCOUNT, 0, sysctl_timer, "Q", "");
2124#if DEBUG
2125SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, enqueues,
2126 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2127 (void *) ENQUEUES, 0, sysctl_timer, "Q", "");
2128SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, dequeues,
2129 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2130 (void *) DEQUEUES, 0, sysctl_timer, "Q", "");
2131SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, escalates,
2132 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2133 (void *) ESCALATES, 0, sysctl_timer, "Q", "");
2134SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, scans,
2135 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2136 (void *) SCANS, 0, sysctl_timer, "Q", "");
2137SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, preempts,
2138 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2139 (void *) PREEMPTS, 0, sysctl_timer, "Q", "");
2140SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, latency,
2141 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2142 (void *) LATENCY, 0, sysctl_timer, "Q", "");
2143SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, latency_min,
2144 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2145 (void *) LATENCY_MIN, 0, sysctl_timer, "Q", "");
2146SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, latency_max,
2147 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2148 (void *) LATENCY_MAX, 0, sysctl_timer, "Q", "");
2149#endif /* DEBUG */
2150
6d2010ae 2151STATIC int
2d21ac55
A
2152sysctl_usrstack
2153(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2154{
2155 return sysctl_io_number(req, (int)req->p->user_stack, sizeof(int), NULL, NULL);
2156}
2157
b0d623f7 2158SYSCTL_PROC(_kern, KERN_USRSTACK32, usrstack,
6d2010ae 2159 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2d21ac55
A
2160 0, 0, sysctl_usrstack, "I", "");
2161
6d2010ae 2162STATIC int
2d21ac55
A
2163sysctl_usrstack64
2164(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2165{
2166 return sysctl_io_number(req, req->p->user_stack, sizeof(req->p->user_stack), NULL, NULL);
2167}
2168
2169SYSCTL_PROC(_kern, KERN_USRSTACK64, usrstack64,
6d2010ae 2170 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
2d21ac55
A
2171 0, 0, sysctl_usrstack64, "Q", "");
2172
2173SYSCTL_STRING(_kern, KERN_COREFILE, corefile,
6d2010ae 2174 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2d21ac55
A
2175 corefilename, sizeof(corefilename), "");
2176
6d2010ae 2177STATIC int
2d21ac55
A
2178sysctl_coredump
2179(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2180{
593a1d5f 2181#ifdef SECURE_KERNEL
fe8ab488 2182 (void)req;
593a1d5f 2183 return (ENOTSUP);
fe8ab488 2184#else
2d21ac55
A
2185 int new_value, changed;
2186 int error = sysctl_io_number(req, do_coredump, sizeof(int), &new_value, &changed);
2187 if (changed) {
2188 if ((new_value == 0) || (new_value == 1))
2189 do_coredump = new_value;
2190 else
2191 error = EINVAL;
2192 }
2193 return(error);
fe8ab488 2194#endif
2d21ac55
A
2195}
2196
2197SYSCTL_PROC(_kern, KERN_COREDUMP, coredump,
6d2010ae 2198 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
2199 0, 0, sysctl_coredump, "I", "");
2200
6d2010ae 2201STATIC int
2d21ac55
A
2202sysctl_suid_coredump
2203(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2204{
593a1d5f 2205#ifdef SECURE_KERNEL
fe8ab488 2206 (void)req;
593a1d5f 2207 return (ENOTSUP);
fe8ab488 2208#else
2d21ac55
A
2209 int new_value, changed;
2210 int error = sysctl_io_number(req, sugid_coredump, sizeof(int), &new_value, &changed);
2211 if (changed) {
2212 if ((new_value == 0) || (new_value == 1))
2213 sugid_coredump = new_value;
55e303ae
A
2214 else
2215 error = EINVAL;
2216 }
2d21ac55 2217 return(error);
fe8ab488 2218#endif
2d21ac55
A
2219}
2220
2221SYSCTL_PROC(_kern, KERN_SUGID_COREDUMP, sugid_coredump,
6d2010ae 2222 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
2223 0, 0, sysctl_suid_coredump, "I", "");
2224
6d2010ae 2225STATIC int
2d21ac55
A
2226sysctl_delayterm
2227(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2228{
2229 struct proc *p = req->p;
2230 int new_value, changed;
2231 int error = sysctl_io_number(req, (req->p->p_lflag & P_LDELAYTERM)? 1: 0, sizeof(int), &new_value, &changed);
2232 if (changed) {
2233 proc_lock(p);
2234 if (new_value)
2235 req->p->p_lflag |= P_LDELAYTERM;
2236 else
2237 req->p->p_lflag &= ~P_LDELAYTERM;
2238 proc_unlock(p);
2239 }
2240 return(error);
2241}
2242
2243SYSCTL_PROC(_kern, KERN_PROCDELAYTERM, delayterm,
6d2010ae 2244 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
2245 0, 0, sysctl_delayterm, "I", "");
2246
55e303ae 2247
6d2010ae 2248STATIC int
2d21ac55
A
2249sysctl_rage_vnode
2250(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
55e303ae 2251{
2d21ac55
A
2252 struct proc *p = req->p;
2253 struct uthread *ut;
2254 int new_value, old_value, changed;
2255 int error;
55e303ae 2256
2d21ac55
A
2257 ut = get_bsdthread_info(current_thread());
2258
2259 if (ut->uu_flag & UT_RAGE_VNODES)
2260 old_value = KERN_RAGE_THREAD;
2261 else if (p->p_lflag & P_LRAGE_VNODES)
2262 old_value = KERN_RAGE_PROC;
2263 else
2264 old_value = 0;
2265
2266 error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed);
2267
2268 if (error == 0) {
2269 switch (new_value) {
2270 case KERN_RAGE_PROC:
2271 proc_lock(p);
2272 p->p_lflag |= P_LRAGE_VNODES;
2273 proc_unlock(p);
2274 break;
2275 case KERN_UNRAGE_PROC:
2276 proc_lock(p);
2277 p->p_lflag &= ~P_LRAGE_VNODES;
2278 proc_unlock(p);
2279 break;
2280
2281 case KERN_RAGE_THREAD:
2282 ut->uu_flag |= UT_RAGE_VNODES;
2283 break;
2284 case KERN_UNRAGE_THREAD:
2285 ut = get_bsdthread_info(current_thread());
2286 ut->uu_flag &= ~UT_RAGE_VNODES;
2287 break;
e5568f75 2288 }
2d21ac55
A
2289 }
2290 return(error);
2291}
2292
2293SYSCTL_PROC(_kern, KERN_RAGEVNODE, rage_vnode,
6d2010ae 2294 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED,
2d21ac55
A
2295 0, 0, sysctl_rage_vnode, "I", "");
2296
316670eb
A
2297/* XXX move this interface into libproc and remove this sysctl */
2298STATIC int
2299sysctl_setthread_cpupercent
2300(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2301{
2302 int new_value, old_value;
2303 int error = 0;
2304 kern_return_t kret = KERN_SUCCESS;
2305 uint8_t percent = 0;
2306 int ms_refill = 0;
2307
39236c6e
A
2308 if (!req->newptr)
2309 return (0);
2310
316670eb
A
2311 old_value = 0;
2312
2313 if ((error = sysctl_io_number(req, old_value, sizeof(old_value), &new_value, NULL)) != 0)
2314 return (error);
2315
2316 percent = new_value & 0xff; /* low 8 bytes for perent */
2317 ms_refill = (new_value >> 8) & 0xffffff; /* upper 24bytes represent ms refill value */
2318 if (percent > 100)
2319 return (EINVAL);
2320
2321 /*
2322 * If the caller is specifying a percentage of 0, this will unset the CPU limit, if present.
2323 */
39236c6e 2324 if ((kret = thread_set_cpulimit(THREAD_CPULIMIT_BLOCK, percent, ms_refill * (int)NSEC_PER_MSEC)) != 0)
316670eb
A
2325 return (EIO);
2326
2327 return (0);
2328}
2329
2330SYSCTL_PROC(_kern, OID_AUTO, setthread_cpupercent,
39236c6e 2331 CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_ANYBODY,
316670eb
A
2332 0, 0, sysctl_setthread_cpupercent, "I", "set thread cpu percentage limit");
2333
2d21ac55 2334
6d2010ae 2335STATIC int
2d21ac55
A
2336sysctl_kern_check_openevt
2337(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2338{
2339 struct proc *p = req->p;
2340 int new_value, old_value, changed;
2341 int error;
2342
2343 if (p->p_flag & P_CHECKOPENEVT) {
2344 old_value = KERN_OPENEVT_PROC;
2345 } else {
2346 old_value = 0;
2347 }
2348
2349 error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed);
2350
2351 if (error == 0) {
2352 switch (new_value) {
2353 case KERN_OPENEVT_PROC:
b0d623f7 2354 OSBitOrAtomic(P_CHECKOPENEVT, &p->p_flag);
2d21ac55
A
2355 break;
2356
2357 case KERN_UNOPENEVT_PROC:
b0d623f7 2358 OSBitAndAtomic(~((uint32_t)P_CHECKOPENEVT), &p->p_flag);
2d21ac55
A
2359 break;
2360
2361 default:
55e303ae 2362 error = EINVAL;
2d21ac55 2363 }
55e303ae 2364 }
2d21ac55
A
2365 return(error);
2366}
2367
6d2010ae 2368SYSCTL_PROC(_kern, KERN_CHECKOPENEVT, check_openevt, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED,
2d21ac55
A
2369 0, 0, sysctl_kern_check_openevt, "I", "set the per-process check-open-evt flag");
2370
2371
2372
6d2010ae 2373STATIC int
2d21ac55
A
2374sysctl_nx
2375(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2376{
4a3eedf9 2377#ifdef SECURE_KERNEL
fe8ab488 2378 (void)req;
4a3eedf9 2379 return ENOTSUP;
fe8ab488 2380#else
2d21ac55
A
2381 int new_value, changed;
2382 int error;
2383
2384 error = sysctl_io_number(req, nx_enabled, sizeof(nx_enabled), &new_value, &changed);
4a3eedf9
A
2385 if (error)
2386 return error;
2d21ac55 2387
4a3eedf9 2388 if (changed) {
b0d623f7 2389#if defined(__i386__) || defined(__x86_64__)
2d21ac55
A
2390 /*
2391 * Only allow setting if NX is supported on the chip
2392 */
2393 if (!(cpuid_extfeatures() & CPUID_EXTFEATURE_XD))
4a3eedf9 2394 return ENOTSUP;
2d21ac55 2395#endif
4a3eedf9
A
2396 nx_enabled = new_value;
2397 }
2d21ac55 2398 return(error);
fe8ab488 2399#endif /* SECURE_KERNEL */
2d21ac55
A
2400}
2401
2402
2403
2404SYSCTL_PROC(_kern, KERN_NX_PROTECTION, nx,
6d2010ae 2405 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
2d21ac55
A
2406 0, 0, sysctl_nx, "I", "");
2407
6d2010ae 2408STATIC int
2d21ac55
A
2409sysctl_loadavg
2410(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2411{
2412 if (proc_is64bit(req->p)) {
b0d623f7
A
2413 struct user64_loadavg loadinfo64;
2414 fill_loadavg64(&averunnable, &loadinfo64);
2d21ac55
A
2415 return sysctl_io_opaque(req, &loadinfo64, sizeof(loadinfo64), NULL);
2416 } else {
b0d623f7
A
2417 struct user32_loadavg loadinfo32;
2418 fill_loadavg32(&averunnable, &loadinfo32);
2419 return sysctl_io_opaque(req, &loadinfo32, sizeof(loadinfo32), NULL);
2d21ac55
A
2420 }
2421}
2422
2423SYSCTL_PROC(_vm, VM_LOADAVG, loadavg,
6d2010ae 2424 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
2d21ac55
A
2425 0, 0, sysctl_loadavg, "S,loadavg", "");
2426
6d2010ae
A
2427/*
2428 * Note: Thread safe; vm_map_lock protects in vm_toggle_entry_reuse()
2429 */
2430STATIC int
2431sysctl_vm_toggle_address_reuse(__unused struct sysctl_oid *oidp, __unused void *arg1,
2432 __unused int arg2, struct sysctl_req *req)
2433{
2434 int old_value=0, new_value=0, error=0;
2435
2436 if(vm_toggle_entry_reuse( VM_TOGGLE_GETVALUE, &old_value ))
2437 return(error);
2438 error = sysctl_io_number(req, old_value, sizeof(int), &new_value, NULL);
2439 if (!error) {
2440 return (vm_toggle_entry_reuse(new_value, NULL));
2441 }
2442 return(error);
2443}
2444
2445SYSCTL_PROC(_debug, OID_AUTO, toggle_address_reuse, CTLFLAG_ANYBODY | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_vm_toggle_address_reuse,"I","");
2446
2447STATIC int
2d21ac55
A
2448sysctl_swapusage
2449(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2450{
2451 int error;
2452 uint64_t swap_total;
2453 uint64_t swap_avail;
b0d623f7 2454 vm_size_t swap_pagesize;
2d21ac55
A
2455 boolean_t swap_encrypted;
2456 struct xsw_usage xsu;
2457
2458 error = macx_swapinfo(&swap_total,
2459 &swap_avail,
2460 &swap_pagesize,
2461 &swap_encrypted);
2462 if (error)
2463 return error;
2464
2465 xsu.xsu_total = swap_total;
2466 xsu.xsu_avail = swap_avail;
2467 xsu.xsu_used = swap_total - swap_avail;
2468 xsu.xsu_pagesize = swap_pagesize;
2469 xsu.xsu_encrypted = swap_encrypted;
2470 return sysctl_io_opaque(req, &xsu, sizeof(xsu), NULL);
2471}
2472
2473
2474
2475SYSCTL_PROC(_vm, VM_SWAPUSAGE, swapusage,
6d2010ae 2476 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
2d21ac55
A
2477 0, 0, sysctl_swapusage, "S,xsw_usage", "");
2478
6d2010ae
A
2479#if CONFIG_FREEZE
2480extern void vm_page_reactivate_all_throttled(void);
2481
2482static int
2483sysctl_freeze_enabled SYSCTL_HANDLER_ARGS
2484{
2485#pragma unused(arg1, arg2)
316670eb 2486 int error, val = memorystatus_freeze_enabled ? 1 : 0;
6d2010ae
A
2487 boolean_t disabled;
2488
2489 error = sysctl_handle_int(oidp, &val, 0, req);
2490 if (error || !req->newptr)
2491 return (error);
2492
39236c6e
A
2493 if (COMPRESSED_PAGER_IS_ACTIVE || DEFAULT_FREEZER_COMPRESSED_PAGER_IS_ACTIVE) {
2494 //assert(req->newptr);
fe8ab488 2495 printf("Failed attempt to set vm.freeze_enabled sysctl\n");
39236c6e
A
2496 return EINVAL;
2497 }
2498
6d2010ae
A
2499 /*
2500 * If freeze is being disabled, we need to move dirty pages out from the throttle to the active queue.
2501 */
316670eb 2502 disabled = (!val && memorystatus_freeze_enabled);
6d2010ae 2503
316670eb 2504 memorystatus_freeze_enabled = val ? TRUE : FALSE;
6d2010ae
A
2505
2506 if (disabled) {
2507 vm_page_reactivate_all_throttled();
2508 }
2509
2510 return (0);
2511}
2512
316670eb 2513SYSCTL_PROC(_vm, OID_AUTO, freeze_enabled, CTLTYPE_INT|CTLFLAG_RW, &memorystatus_freeze_enabled, 0, sysctl_freeze_enabled, "I", "");
6d2010ae 2514#endif /* CONFIG_FREEZE */
2d21ac55
A
2515
2516/* this kernel does NOT implement shared_region_make_private_np() */
2517SYSCTL_INT(_kern, KERN_SHREG_PRIVATIZABLE, shreg_private,
6d2010ae 2518 CTLFLAG_RD | CTLFLAG_LOCKED,
b0d623f7 2519 (int *)NULL, 0, "");
0c530ab8 2520
6d2010ae 2521STATIC int
0c530ab8 2522fetch_process_cputype(
2d21ac55 2523 proc_t cur_proc,
0c530ab8
A
2524 int *name,
2525 u_int namelen,
2526 cpu_type_t *cputype)
2527{
2d21ac55
A
2528 proc_t p = PROC_NULL;
2529 int refheld = 0;
0c530ab8 2530 cpu_type_t ret = 0;
2d21ac55 2531 int error = 0;
0c530ab8
A
2532
2533 if (namelen == 0)
2534 p = cur_proc;
2535 else if (namelen == 1) {
2d21ac55 2536 p = proc_find(name[0]);
0c530ab8
A
2537 if (p == NULL)
2538 return (EINVAL);
2d21ac55 2539 refheld = 1;
0c530ab8 2540 } else {
2d21ac55
A
2541 error = EINVAL;
2542 goto out;
0c530ab8
A
2543 }
2544
fe8ab488
A
2545 ret = cpu_type() & ~CPU_ARCH_MASK;
2546 if (IS_64BIT_PROCESS(p))
2547 ret |= CPU_ARCH_ABI64;
2548
0c530ab8
A
2549 *cputype = ret;
2550
2d21ac55
A
2551 if (refheld != 0)
2552 proc_rele(p);
2553out:
2554 return (error);
0c530ab8
A
2555}
2556
6d2010ae 2557STATIC int
2d21ac55
A
2558sysctl_sysctl_native(__unused struct sysctl_oid *oidp, void *arg1, int arg2,
2559 struct sysctl_req *req)
0c530ab8
A
2560{
2561 int error;
2562 cpu_type_t proc_cputype = 0;
2563 if ((error = fetch_process_cputype(req->p, (int *)arg1, arg2, &proc_cputype)) != 0)
2564 return error;
2565 int res = 1;
2566 if ((proc_cputype & ~CPU_ARCH_MASK) != (cpu_type() & ~CPU_ARCH_MASK))
2567 res = 0;
2568 return SYSCTL_OUT(req, &res, sizeof(res));
2569}
6d2010ae 2570SYSCTL_PROC(_sysctl, OID_AUTO, proc_native, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, sysctl_sysctl_native ,"I","proc_native");
0c530ab8 2571
6d2010ae 2572STATIC int
2d21ac55
A
2573sysctl_sysctl_cputype(__unused struct sysctl_oid *oidp, void *arg1, int arg2,
2574 struct sysctl_req *req)
0c530ab8
A
2575{
2576 int error;
2577 cpu_type_t proc_cputype = 0;
2578 if ((error = fetch_process_cputype(req->p, (int *)arg1, arg2, &proc_cputype)) != 0)
2579 return error;
2580 return SYSCTL_OUT(req, &proc_cputype, sizeof(proc_cputype));
2581}
6d2010ae 2582SYSCTL_PROC(_sysctl, OID_AUTO, proc_cputype, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, sysctl_sysctl_cputype ,"I","proc_cputype");
0c530ab8 2583
6d2010ae 2584STATIC int
2d21ac55
A
2585sysctl_safeboot
2586(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2587{
2588 return sysctl_io_number(req, boothowto & RB_SAFEBOOT ? 1 : 0, sizeof(int), NULL, NULL);
2589}
2590
2591SYSCTL_PROC(_kern, KERN_SAFEBOOT, safeboot,
6d2010ae 2592 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2d21ac55
A
2593 0, 0, sysctl_safeboot, "I", "");
2594
6d2010ae 2595STATIC int
2d21ac55
A
2596sysctl_singleuser
2597(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2598{
2599 return sysctl_io_number(req, boothowto & RB_SINGLE ? 1 : 0, sizeof(int), NULL, NULL);
2600}
2601
2602SYSCTL_PROC(_kern, OID_AUTO, singleuser,
6d2010ae 2603 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2d21ac55
A
2604 0, 0, sysctl_singleuser, "I", "");
2605
3e170ce0
A
2606STATIC int sysctl_minimalboot
2607(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2608{
2609 return sysctl_io_number(req, minimalboot, sizeof(int), NULL, NULL);
2610}
2611
2612SYSCTL_PROC(_kern, OID_AUTO, minimalboot,
2613 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2614 0, 0, sysctl_minimalboot, "I", "");
2615
2d21ac55
A
2616/*
2617 * Controls for debugging affinity sets - see osfmk/kern/affinity.c
2618 */
2619extern boolean_t affinity_sets_enabled;
2620extern int affinity_sets_mapping;
2621
2622SYSCTL_INT (_kern, OID_AUTO, affinity_sets_enabled,
6d2010ae 2623 CTLFLAG_RW | CTLFLAG_LOCKED, (int *) &affinity_sets_enabled, 0, "hinting enabled");
2d21ac55 2624SYSCTL_INT (_kern, OID_AUTO, affinity_sets_mapping,
6d2010ae 2625 CTLFLAG_RW | CTLFLAG_LOCKED, &affinity_sets_mapping, 0, "mapping policy");
2d21ac55 2626
316670eb
A
2627/*
2628 * Boolean indicating if KASLR is active.
2629 */
2630STATIC int
2631sysctl_slide
2632(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
2633{
2634 uint32_t slide;
2635
2636 slide = vm_kernel_slide ? 1 : 0;
2637
2638 return sysctl_io_number( req, slide, sizeof(int), NULL, NULL);
2639}
2640
2641SYSCTL_PROC(_kern, OID_AUTO, slide,
2642 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
2643 0, 0, sysctl_slide, "I", "");
2644
2d21ac55
A
2645/*
2646 * Limit on total memory users can wire.
2647 *
2648 * vm_global_user_wire_limit - system wide limit on wired memory from all processes combined.
2649 *
2650 * vm_user_wire_limit - per address space limit on wired memory. This puts a cap on the process's rlimit value.
2651 *
2652 * These values are initialized to reasonable defaults at boot time based on the available physical memory in
2653 * kmem_init().
2654 *
2655 * All values are in bytes.
2656 */
2657
b0d623f7 2658vm_map_size_t vm_global_no_user_wire_amount;
2d21ac55
A
2659vm_map_size_t vm_global_user_wire_limit;
2660vm_map_size_t vm_user_wire_limit;
2661
b0d623f7
A
2662/*
2663 * There needs to be a more automatic/elegant way to do this
2664 */
6d2010ae
A
2665SYSCTL_QUAD(_vm, OID_AUTO, global_no_user_wire_amount, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_global_no_user_wire_amount, "");
2666SYSCTL_QUAD(_vm, OID_AUTO, global_user_wire_limit, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_global_user_wire_limit, "");
2667SYSCTL_QUAD(_vm, OID_AUTO, user_wire_limit, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_user_wire_limit, "");
b0d623f7 2668
e2d2fc5c
A
2669extern int vm_map_copy_overwrite_aligned_src_not_internal;
2670extern int vm_map_copy_overwrite_aligned_src_not_symmetric;
2671extern int vm_map_copy_overwrite_aligned_src_large;
2672SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_not_internal, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_not_internal, 0, "");
2673SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_not_symmetric, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_not_symmetric, 0, "");
2674SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_large, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_large, 0, "");
b0d623f7
A
2675
2676
39236c6e
A
2677extern uint32_t vm_page_external_count;
2678extern uint32_t vm_page_filecache_min;
2679
2680SYSCTL_INT(_vm, OID_AUTO, vm_page_external_count, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_page_external_count, 0, "");
2681SYSCTL_INT(_vm, OID_AUTO, vm_page_filecache_min, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_page_filecache_min, 0, "");
2682
2683extern int vm_compressor_mode;
04b8595b 2684extern int vm_compressor_is_active;
3e170ce0
A
2685extern int vm_compressor_available;
2686extern uint32_t vm_ripe_target_age;
39236c6e
A
2687extern uint32_t swapout_target_age;
2688extern int64_t compressor_bytes_used;
3e170ce0
A
2689extern int64_t c_segment_input_bytes;
2690extern int64_t c_segment_compressed_bytes;
39236c6e
A
2691extern uint32_t compressor_eval_period_in_msecs;
2692extern uint32_t compressor_sample_min_in_msecs;
2693extern uint32_t compressor_sample_max_in_msecs;
2694extern uint32_t compressor_thrashing_threshold_per_10msecs;
2695extern uint32_t compressor_thrashing_min_per_10msecs;
2696extern uint32_t vm_compressor_minorcompact_threshold_divisor;
2697extern uint32_t vm_compressor_majorcompact_threshold_divisor;
2698extern uint32_t vm_compressor_unthrottle_threshold_divisor;
2699extern uint32_t vm_compressor_catchup_threshold_divisor;
2700
3e170ce0
A
2701SYSCTL_QUAD(_vm, OID_AUTO, compressor_input_bytes, CTLFLAG_RD | CTLFLAG_LOCKED, &c_segment_input_bytes, "");
2702SYSCTL_QUAD(_vm, OID_AUTO, compressor_compressed_bytes, CTLFLAG_RD | CTLFLAG_LOCKED, &c_segment_compressed_bytes, "");
2703SYSCTL_QUAD(_vm, OID_AUTO, compressor_bytes_used, CTLFLAG_RD | CTLFLAG_LOCKED, &compressor_bytes_used, "");
2704
39236c6e 2705SYSCTL_INT(_vm, OID_AUTO, compressor_mode, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_compressor_mode, 0, "");
04b8595b 2706SYSCTL_INT(_vm, OID_AUTO, compressor_is_active, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_compressor_is_active, 0, "");
39236c6e 2707SYSCTL_INT(_vm, OID_AUTO, compressor_swapout_target_age, CTLFLAG_RD | CTLFLAG_LOCKED, &swapout_target_age, 0, "");
3e170ce0
A
2708SYSCTL_INT(_vm, OID_AUTO, compressor_available, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_compressor_available, 0, "");
2709
2710SYSCTL_INT(_vm, OID_AUTO, vm_ripe_target_age_in_secs, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_ripe_target_age, 0, "");
39236c6e
A
2711
2712SYSCTL_INT(_vm, OID_AUTO, compressor_eval_period_in_msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_eval_period_in_msecs, 0, "");
2713SYSCTL_INT(_vm, OID_AUTO, compressor_sample_min_in_msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_sample_min_in_msecs, 0, "");
2714SYSCTL_INT(_vm, OID_AUTO, compressor_sample_max_in_msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_sample_max_in_msecs, 0, "");
2715SYSCTL_INT(_vm, OID_AUTO, compressor_thrashing_threshold_per_10msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_thrashing_threshold_per_10msecs, 0, "");
2716SYSCTL_INT(_vm, OID_AUTO, compressor_thrashing_min_per_10msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &compressor_thrashing_min_per_10msecs, 0, "");
2717SYSCTL_INT(_vm, OID_AUTO, compressor_minorcompact_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_minorcompact_threshold_divisor, 0, "");
2718SYSCTL_INT(_vm, OID_AUTO, compressor_majorcompact_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_majorcompact_threshold_divisor, 0, "");
2719SYSCTL_INT(_vm, OID_AUTO, compressor_unthrottle_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_unthrottle_threshold_divisor, 0, "");
2720SYSCTL_INT(_vm, OID_AUTO, compressor_catchup_threshold_divisor, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_compressor_catchup_threshold_divisor, 0, "");
2721
fe8ab488
A
2722SYSCTL_STRING(_vm, OID_AUTO, swapfileprefix, CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, swapfilename, sizeof(swapfilename) - SWAPFILENAME_INDEX_LEN, "");
2723
2724#if CONFIG_PHANTOM_CACHE
2725extern uint32_t phantom_cache_thrashing_threshold;
2726extern uint32_t phantom_cache_eval_period_in_msecs;
2727extern uint32_t phantom_cache_thrashing_threshold_ssd;
2728
2729
2730SYSCTL_INT(_vm, OID_AUTO, phantom_cache_eval_period_in_msecs, CTLFLAG_RW | CTLFLAG_LOCKED, &phantom_cache_eval_period_in_msecs, 0, "");
2731SYSCTL_INT(_vm, OID_AUTO, phantom_cache_thrashing_threshold, CTLFLAG_RW | CTLFLAG_LOCKED, &phantom_cache_thrashing_threshold, 0, "");
2732SYSCTL_INT(_vm, OID_AUTO, phantom_cache_thrashing_threshold_ssd, CTLFLAG_RW | CTLFLAG_LOCKED, &phantom_cache_thrashing_threshold_ssd, 0, "");
2733#endif
2734
04b8595b
A
2735#if (DEVELOPMENT || DEBUG)
2736
2737SYSCTL_UINT(_vm, OID_AUTO, vm_page_creation_throttled_hard,
3e170ce0
A
2738 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2739 &vm_page_creation_throttled_hard, 0, "");
04b8595b
A
2740
2741SYSCTL_UINT(_vm, OID_AUTO, vm_page_creation_throttled_soft,
3e170ce0
A
2742 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2743 &vm_page_creation_throttled_soft, 0, "");
04b8595b
A
2744
2745#endif /* DEVELOPMENT || DEBUG */
2746
b0d623f7 2747/*
fe8ab488 2748 * Enable tracing of voucher contents
b0d623f7 2749 */
fe8ab488 2750extern uint32_t ipc_voucher_trace_contents;
b0d623f7 2751
fe8ab488
A
2752SYSCTL_INT (_kern, OID_AUTO, ipc_voucher_trace_contents,
2753 CTLFLAG_RW | CTLFLAG_LOCKED, &ipc_voucher_trace_contents, 0, "Enable tracing voucher contents");
b0d623f7
A
2754
2755/*
2756 * Kernel stack size and depth
2757 */
2758SYSCTL_INT (_kern, OID_AUTO, stack_size,
6d2010ae 2759 CTLFLAG_RD | CTLFLAG_LOCKED, (int *) &kernel_stack_size, 0, "Kernel stack size");
b0d623f7 2760SYSCTL_INT (_kern, OID_AUTO, stack_depth_max,
6d2010ae 2761 CTLFLAG_RD | CTLFLAG_LOCKED, (int *) &kernel_stack_depth_max, 0, "Max kernel stack depth at interrupt or context switch");
b0d623f7 2762
b7266188
A
2763/*
2764 * enable back trace for port allocations
2765 */
2766extern int ipc_portbt;
2767
2768SYSCTL_INT(_kern, OID_AUTO, ipc_portbt,
6d2010ae 2769 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
b7266188
A
2770 &ipc_portbt, 0, "");
2771
6d2010ae
A
2772/*
2773 * Scheduler sysctls
2774 */
2775
6d2010ae
A
2776SYSCTL_STRING(_kern, OID_AUTO, sched,
2777 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
2778 sched_string, sizeof(sched_string),
2779 "Timeshare scheduler implementation");
316670eb
A
2780
2781/*
2782 * Only support runtime modification on embedded platforms
2783 * with development config enabled
2784 */
fe8ab488
A
2785
2786
2787/* Parameters related to timer coalescing tuning, to be replaced
2788 * with a dedicated systemcall in the future.
2789 */
2790/* Enable processing pending timers in the context of any other interrupt
2791 * Coalescing tuning parameters for various thread/task attributes */
2792STATIC int
2793sysctl_timer_user_us_kernel_abstime SYSCTL_HANDLER_ARGS
2794{
2795#pragma unused(oidp)
2796 int size = arg2; /* subcommand*/
2797 int error;
2798 int changed = 0;
2799 uint64_t old_value_ns;
2800 uint64_t new_value_ns;
2801 uint64_t value_abstime;
2802 if (size == sizeof(uint32_t))
2803 value_abstime = *((uint32_t *)arg1);
2804 else if (size == sizeof(uint64_t))
2805 value_abstime = *((uint64_t *)arg1);
2806 else return ENOTSUP;
2807
2808 absolutetime_to_nanoseconds(value_abstime, &old_value_ns);
2809 error = sysctl_io_number(req, old_value_ns, sizeof(old_value_ns), &new_value_ns, &changed);
2810 if ((error) || (!changed))
2811 return error;
2812
2813 nanoseconds_to_absolutetime(new_value_ns, &value_abstime);
2814 if (size == sizeof(uint32_t))
2815 *((uint32_t *)arg1) = (uint32_t)value_abstime;
2816 else
2817 *((uint64_t *)arg1) = value_abstime;
2818 return error;
2819}
2820
2821SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_bg_scale,
2822 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2823 &tcoal_prio_params.timer_coalesce_bg_shift, 0, "");
2824SYSCTL_PROC(_kern, OID_AUTO, timer_resort_threshold_ns,
2825 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2826 &tcoal_prio_params.timer_resort_threshold_abstime,
2827 sizeof(tcoal_prio_params.timer_resort_threshold_abstime),
2828 sysctl_timer_user_us_kernel_abstime,
2829 "Q", "");
2830SYSCTL_PROC(_kern, OID_AUTO, timer_coalesce_bg_ns_max,
2831 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2832 &tcoal_prio_params.timer_coalesce_bg_abstime_max,
2833 sizeof(tcoal_prio_params.timer_coalesce_bg_abstime_max),
2834 sysctl_timer_user_us_kernel_abstime,
2835 "Q", "");
2836
2837SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_kt_scale,
2838 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2839 &tcoal_prio_params.timer_coalesce_kt_shift, 0, "");
2840
2841SYSCTL_PROC(_kern, OID_AUTO, timer_coalesce_kt_ns_max,
2842 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2843 &tcoal_prio_params.timer_coalesce_kt_abstime_max,
2844 sizeof(tcoal_prio_params.timer_coalesce_kt_abstime_max),
2845 sysctl_timer_user_us_kernel_abstime,
2846 "Q", "");
2847
2848SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_fp_scale,
2849 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2850 &tcoal_prio_params.timer_coalesce_fp_shift, 0, "");
2851
2852SYSCTL_PROC(_kern, OID_AUTO, timer_coalesce_fp_ns_max,
2853 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2854 &tcoal_prio_params.timer_coalesce_fp_abstime_max,
2855 sizeof(tcoal_prio_params.timer_coalesce_fp_abstime_max),
2856 sysctl_timer_user_us_kernel_abstime,
2857 "Q", "");
2858
2859SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_ts_scale,
2860 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2861 &tcoal_prio_params.timer_coalesce_ts_shift, 0, "");
2862
2863SYSCTL_PROC(_kern, OID_AUTO, timer_coalesce_ts_ns_max,
2864 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2865 &tcoal_prio_params.timer_coalesce_ts_abstime_max,
2866 sizeof(tcoal_prio_params.timer_coalesce_ts_abstime_max),
2867 sysctl_timer_user_us_kernel_abstime,
2868 "Q", "");
2869
2870SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_tier0_scale,
2871 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2872 &tcoal_prio_params.latency_qos_scale[0], 0, "");
2873
2874SYSCTL_PROC(_kern, OID_AUTO, timer_coalesce_tier0_ns_max,
2875 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2876 &tcoal_prio_params.latency_qos_abstime_max[0],
2877 sizeof(tcoal_prio_params.latency_qos_abstime_max[0]),
2878 sysctl_timer_user_us_kernel_abstime,
2879 "Q", "");
2880
2881SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_tier1_scale,
2882 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2883 &tcoal_prio_params.latency_qos_scale[1], 0, "");
2884
2885SYSCTL_PROC(_kern, OID_AUTO, timer_coalesce_tier1_ns_max,
2886 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2887 &tcoal_prio_params.latency_qos_abstime_max[1],
2888 sizeof(tcoal_prio_params.latency_qos_abstime_max[1]),
2889 sysctl_timer_user_us_kernel_abstime,
2890 "Q", "");
2891
2892SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_tier2_scale,
2893 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2894 &tcoal_prio_params.latency_qos_scale[2], 0, "");
2895
2896SYSCTL_PROC(_kern, OID_AUTO, timer_coalesce_tier2_ns_max,
2897 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2898 &tcoal_prio_params.latency_qos_abstime_max[2],
2899 sizeof(tcoal_prio_params.latency_qos_abstime_max[2]),
2900 sysctl_timer_user_us_kernel_abstime,
2901 "Q", "");
2902
2903SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_tier3_scale,
2904 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2905 &tcoal_prio_params.latency_qos_scale[3], 0, "");
2906
2907SYSCTL_PROC(_kern, OID_AUTO, timer_coalesce_tier3_ns_max,
2908 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2909 &tcoal_prio_params.latency_qos_abstime_max[3],
2910 sizeof(tcoal_prio_params.latency_qos_abstime_max[3]),
2911 sysctl_timer_user_us_kernel_abstime,
2912 "Q", "");
2913
2914SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_tier4_scale,
2915 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2916 &tcoal_prio_params.latency_qos_scale[4], 0, "");
2917
2918SYSCTL_PROC(_kern, OID_AUTO, timer_coalesce_tier4_ns_max,
2919 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2920 &tcoal_prio_params.latency_qos_abstime_max[4],
2921 sizeof(tcoal_prio_params.latency_qos_abstime_max[4]),
2922 sysctl_timer_user_us_kernel_abstime,
2923 "Q", "");
2924
2925SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_tier5_scale,
2926 CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2927 &tcoal_prio_params.latency_qos_scale[5], 0, "");
2928
2929SYSCTL_PROC(_kern, OID_AUTO, timer_coalesce_tier5_ns_max,
2930 CTLTYPE_QUAD | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
2931 &tcoal_prio_params.latency_qos_abstime_max[5],
2932 sizeof(tcoal_prio_params.latency_qos_abstime_max[5]),
2933 sysctl_timer_user_us_kernel_abstime,
2934 "Q", "");
2935
2936/* Communicate the "user idle level" heuristic to the timer layer, and
2937 * potentially other layers in the future.
2938 */
2939
2940static int
2941timer_user_idle_level(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) {
2942 int new_value = 0, old_value = 0, changed = 0, error;
2943
2944 old_value = timer_get_user_idle_level();
2945
2946 error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed);
2947
2948 if (error == 0 && changed) {
2949 if (timer_set_user_idle_level(new_value) != KERN_SUCCESS)
2950 error = ERANGE;
2951 }
2952
2953 return error;
2954}
2955
2956SYSCTL_PROC(_machdep, OID_AUTO, user_idle_level,
2957 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2958 0, 0,
2959 timer_user_idle_level, "I", "User idle level heuristic, 0-128");
2960
2961#if HYPERVISOR
2962SYSCTL_INT(_kern, OID_AUTO, hv_support,
2963 CTLFLAG_KERN | CTLFLAG_RD | CTLFLAG_LOCKED,
2964 &hv_support_available, 0, "");
2965#endif
3e170ce0
A
2966
2967