2 * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
30 * Copyright (c) 1982, 1986, 1989, 1993
31 * The Regents of the University of California. All rights reserved.
33 * This code is derived from software contributed to Berkeley by
34 * Mike Karels at Berkeley Software Design, Inc.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
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.
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
64 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
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,
74 * DEPRECATED sysctl system call code
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.
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.
86 #include <sys/param.h>
87 #include <sys/systm.h>
88 #include <sys/kernel.h>
89 #include <sys/malloc.h>
90 #include <sys/proc_internal.h>
91 #include <sys/kauth.h>
92 #include <sys/file_internal.h>
93 #include <sys/vnode_internal.h>
94 #include <sys/unistd.h>
96 #include <sys/ioctl.h>
97 #include <sys/namei.h>
99 #include <sys/disklabel.h>
101 #include <sys/sysctl.h>
102 #include <sys/user.h>
103 #include <sys/aio_kern.h>
104 #include <sys/reboot.h>
105 #include <sys/memory_maintenance.h>
106 #include <sys/priv.h>
107 #include <stdatomic.h>
108 #include <uuid/uuid.h>
110 #include <security/audit/audit.h>
111 #include <kern/kalloc.h>
113 #include <machine/smp.h>
114 #include <machine/atomic.h>
115 #include <machine/config.h>
116 #include <mach/machine.h>
117 #include <mach/mach_host.h>
118 #include <mach/mach_types.h>
119 #include <mach/processor_info.h>
120 #include <mach/vm_param.h>
121 #include <kern/debug.h>
122 #include <kern/mach_param.h>
123 #include <kern/task.h>
124 #include <kern/thread.h>
125 #include <kern/thread_group.h>
126 #include <kern/processor.h>
127 #include <kern/cpu_number.h>
128 #include <kern/cpu_quiesce.h>
129 #include <kern/sched_prim.h>
130 #include <vm/vm_kern.h>
131 #include <vm/vm_map.h>
132 #include <mach/host_info.h>
134 #include <sys/mount_internal.h>
135 #include <sys/kdebug.h>
136 #include <sys/kern_sysctl.h>
138 #include <IOKit/IOPlatformExpert.h>
139 #include <pexpert/pexpert.h>
141 #include <machine/machine_routines.h>
142 #include <machine/exec.h>
144 #include <nfs/nfs_conf.h>
146 #include <vm/vm_protos.h>
147 #include <vm/vm_pageout.h>
148 #include <vm/vm_compressor_algorithms.h>
149 #include <sys/imgsrc.h>
150 #include <kern/timer_call.h>
151 #include <sys/codesign.h>
152 #include <IOKit/IOBSD.h>
157 #if defined(__i386__) || defined(__x86_64__)
158 #include <i386/cpuid.h>
162 #include <sys/kern_memorystatus.h>
166 #include <kperf/kperf.h>
170 #include <kern/hv_support.h>
174 * deliberately setting max requests to really high number
175 * so that runaway settings do not cause MALLOC overflows
177 #define AIO_MAX_REQUESTS (128 * CONFIG_AIO_MAX)
179 extern int aio_max_requests
;
180 extern int aio_max_requests_per_process
;
181 extern int aio_worker_threads
;
182 extern int lowpri_IO_window_msecs
;
183 extern int lowpri_IO_delay_msecs
;
184 #if DEVELOPMENT || DEBUG
185 extern int nx_enabled
;
187 extern int speculative_reads_disabled
;
188 extern unsigned int speculative_prefetch_max
;
189 extern unsigned int speculative_prefetch_max_iosize
;
190 extern unsigned int preheat_max_bytes
;
191 extern unsigned int preheat_min_bytes
;
192 extern long numvnodes
;
193 extern long freevnodes
;
194 extern long num_recycledvnodes
;
196 extern uuid_string_t bootsessionuuid_string
;
198 extern unsigned int vm_max_delayed_work_limit
;
199 extern unsigned int vm_max_batch
;
201 extern unsigned int vm_page_free_min
;
202 extern unsigned int vm_page_free_target
;
203 extern unsigned int vm_page_free_reserved
;
205 #if (DEVELOPMENT || DEBUG)
206 extern uint32_t vm_page_creation_throttled_hard
;
207 extern uint32_t vm_page_creation_throttled_soft
;
208 #endif /* DEVELOPMENT || DEBUG */
210 #if CONFIG_LOCKERBOOT
211 extern const char kernel_protoboot_mount
[];
215 * Conditionally allow dtrace to see these functions for debugging purposes.
223 #define STATIC static
226 extern boolean_t mach_timer_coalescing_enabled
;
228 extern uint64_t timer_deadline_tracking_bin_1
, timer_deadline_tracking_bin_2
;
231 fill_user32_eproc(proc_t
, struct user32_eproc
*__restrict
);
233 fill_user32_externproc(proc_t
, struct user32_extern_proc
*__restrict
);
235 fill_user64_eproc(proc_t
, struct user64_eproc
*__restrict
);
237 fill_user64_proc(proc_t
, struct user64_kinfo_proc
*__restrict
);
239 fill_user64_externproc(proc_t
, struct user64_extern_proc
*__restrict
);
241 fill_user32_proc(proc_t
, struct user32_kinfo_proc
*__restrict
);
244 kdbg_control(int *name
, u_int namelen
, user_addr_t where
, size_t * sizep
);
245 #if CONFIG_NFS_CLIENT
250 sysctl_procargs(int *name
, u_int namelen
, user_addr_t where
,
251 size_t *sizep
, proc_t cur_proc
);
253 sysctl_procargsx(int *name
, u_int namelen
, user_addr_t where
, size_t *sizep
,
254 proc_t cur_proc
, int argc_yes
);
256 sysctl_struct(user_addr_t oldp
, size_t *oldlenp
, user_addr_t newp
,
257 size_t newlen
, void *sp
, int len
);
259 STATIC
int sysdoproc_filt_KERN_PROC_PID(proc_t p
, void * arg
);
260 STATIC
int sysdoproc_filt_KERN_PROC_PGRP(proc_t p
, void * arg
);
261 STATIC
int sysdoproc_filt_KERN_PROC_TTY(proc_t p
, void * arg
);
262 STATIC
int sysdoproc_filt_KERN_PROC_UID(proc_t p
, void * arg
);
263 STATIC
int sysdoproc_filt_KERN_PROC_RUID(proc_t p
, void * arg
);
264 int sysdoproc_callback(proc_t p
, void *arg
);
266 #if CONFIG_THREAD_GROUPS && (DEVELOPMENT || DEBUG)
267 STATIC
int sysctl_get_thread_group_id SYSCTL_HANDLER_ARGS
;
270 /* forward declarations for non-static STATIC */
271 STATIC
void fill_loadavg64(struct loadavg
*la
, struct user64_loadavg
*la64
);
272 STATIC
void fill_loadavg32(struct loadavg
*la
, struct user32_loadavg
*la32
);
273 STATIC
int sysctl_handle_kern_threadname(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
274 STATIC
int sysctl_sched_stats(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
275 STATIC
int sysctl_sched_stats_enable(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
276 STATIC
int sysctl_kdebug_ops SYSCTL_HANDLER_ARGS
;
278 STATIC
int sysctl_docountsyscalls SYSCTL_HANDLER_ARGS
;
279 #endif /* COUNT_SYSCALLS */
280 #if defined(XNU_TARGET_OS_OSX)
281 STATIC
int sysctl_doprocargs SYSCTL_HANDLER_ARGS
;
282 #endif /* defined(XNU_TARGET_OS_OSX) */
283 STATIC
int sysctl_doprocargs2 SYSCTL_HANDLER_ARGS
;
284 STATIC
int sysctl_prochandle SYSCTL_HANDLER_ARGS
;
285 STATIC
int sysctl_aiomax(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
286 STATIC
int sysctl_aioprocmax(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
287 STATIC
int sysctl_aiothreads(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
288 STATIC
int sysctl_maxproc(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
289 STATIC
int sysctl_osversion(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
290 STATIC
int sysctl_sysctl_bootargs(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
291 STATIC
int sysctl_maxvnodes(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
292 STATIC
int sysctl_securelvl(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
293 STATIC
int sysctl_domainname(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
294 STATIC
int sysctl_hostname(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
295 STATIC
int sysctl_procname(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
296 STATIC
int sysctl_boottime(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
297 STATIC
int sysctl_bootuuid(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
298 STATIC
int sysctl_symfile(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
299 #if CONFIG_NFS_CLIENT
300 STATIC
int sysctl_netboot(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
302 #ifdef CONFIG_IMGSRC_ACCESS
303 STATIC
int sysctl_imgsrcdev(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
305 STATIC
int sysctl_usrstack(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
306 STATIC
int sysctl_usrstack64(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
308 STATIC
int sysctl_coredump(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
309 STATIC
int sysctl_suid_coredump(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
311 STATIC
int sysctl_delayterm(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
312 STATIC
int sysctl_rage_vnode(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
313 STATIC
int sysctl_kern_check_openevt(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
314 #if DEVELOPMENT || DEBUG
315 STATIC
int sysctl_nx(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
317 STATIC
int sysctl_loadavg(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
318 STATIC
int sysctl_vm_toggle_address_reuse(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
319 STATIC
int sysctl_swapusage(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
320 STATIC
int fetch_process_cputype( proc_t cur_proc
, int *name
, u_int namelen
, cpu_type_t
*cputype
);
321 STATIC
int sysctl_sysctl_native(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
322 STATIC
int sysctl_sysctl_cputype(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
323 STATIC
int sysctl_safeboot(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
324 STATIC
int sysctl_singleuser(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
325 STATIC
int sysctl_minimalboot(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
326 STATIC
int sysctl_slide(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
328 #ifdef CONFIG_XNUPOST
329 #include <tests/xnupost.h>
331 STATIC
int sysctl_debug_test_oslog_ctl(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
332 STATIC
int sysctl_debug_test_stackshot_mutex_owner(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
333 STATIC
int sysctl_debug_test_stackshot_rwlck_owner(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
336 extern void IORegistrySetOSBuildVersion(char * build_version
);
339 fill_loadavg64(struct loadavg
*la
, struct user64_loadavg
*la64
)
341 la64
->ldavg
[0] = la
->ldavg
[0];
342 la64
->ldavg
[1] = la
->ldavg
[1];
343 la64
->ldavg
[2] = la
->ldavg
[2];
344 la64
->fscale
= (user64_long_t
)la
->fscale
;
348 fill_loadavg32(struct loadavg
*la
, struct user32_loadavg
*la32
)
350 la32
->ldavg
[0] = la
->ldavg
[0];
351 la32
->ldavg
[1] = la
->ldavg
[1];
352 la32
->ldavg
[2] = la
->ldavg
[2];
353 la32
->fscale
= (user32_long_t
)la
->fscale
;
358 * Attributes stored in the kernel.
360 extern char corefilename
[MAXPATHLEN
+ 1];
361 extern int do_coredump
;
362 extern int sugid_coredump
;
366 extern int do_count_syscalls
;
370 int securelevel
= -1;
376 sysctl_handle_kern_threadname( __unused
struct sysctl_oid
*oidp
, __unused
void *arg1
,
377 __unused
int arg2
, struct sysctl_req
*req
)
380 struct uthread
*ut
= get_bsdthread_info(current_thread());
381 user_addr_t oldp
= 0, newp
= 0;
382 size_t *oldlenp
= NULL
;
386 oldlenp
= &(req
->oldlen
);
388 newlen
= req
->newlen
;
390 /* We want the current length, and maybe the string itself */
392 /* if we have no thread name yet tell'em we want MAXTHREADNAMESIZE - 1 */
393 size_t currlen
= MAXTHREADNAMESIZE
- 1;
396 /* use length of current thread name */
397 currlen
= strlen(ut
->pth_name
);
400 if (*oldlenp
< currlen
) {
403 /* NOTE - we do not copy the NULL terminator */
405 error
= copyout(ut
->pth_name
, oldp
, currlen
);
411 /* return length of thread name minus NULL terminator (just like strlen) */
412 req
->oldidx
= currlen
;
415 /* We want to set the name to something */
417 if (newlen
> (MAXTHREADNAMESIZE
- 1)) {
421 char *tmp_pth_name
= (char *)kalloc(MAXTHREADNAMESIZE
);
425 bzero(tmp_pth_name
, MAXTHREADNAMESIZE
);
426 if (!OSCompareAndSwapPtr(NULL
, tmp_pth_name
, &ut
->pth_name
)) {
427 kfree(tmp_pth_name
, MAXTHREADNAMESIZE
);
431 kernel_debug_string_simple(TRACE_STRING_THREADNAME_PREV
, ut
->pth_name
);
432 bzero(ut
->pth_name
, MAXTHREADNAMESIZE
);
434 error
= copyin(newp
, ut
->pth_name
, newlen
);
439 kernel_debug_string_simple(TRACE_STRING_THREADNAME
, ut
->pth_name
);
445 SYSCTL_PROC(_kern
, KERN_THREADNAME
, threadname
, CTLFLAG_ANYBODY
| CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, 0, sysctl_handle_kern_threadname
, "A", "");
449 sysctl_sched_stats(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
451 host_basic_info_data_t hinfo
;
454 uint32_t buf_size
= 0;
456 mach_msg_type_number_t count
= HOST_BASIC_INFO_COUNT
;
457 struct _processor_statistics_np
*buf
;
460 kret
= host_info((host_t
)BSD_HOST
, HOST_BASIC_INFO
, (host_info_t
)&hinfo
, &count
);
461 if (kret
!= KERN_SUCCESS
) {
465 size
= sizeof(struct _processor_statistics_np
) * (hinfo
.logical_cpu_max
+ 2); /* One for RT Queue, One for Fair Share Queue */
467 if (req
->oldlen
< size
) {
472 buf
= kheap_alloc(KHEAP_TEMP
, buf_size
, Z_ZERO
| Z_WAITOK
);
474 kret
= get_sched_statistics(buf
, &size
);
475 if (kret
!= KERN_SUCCESS
) {
480 error
= sysctl_io_opaque(req
, buf
, size
, &changed
);
486 panic("Sched info changed?!");
489 kheap_free(KHEAP_TEMP
, buf
, buf_size
);
493 SYSCTL_PROC(_kern
, OID_AUTO
, sched_stats
, CTLFLAG_LOCKED
, 0, 0, sysctl_sched_stats
, "-", "");
496 sysctl_sched_stats_enable(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, __unused
struct sysctl_req
*req
)
501 if (req
->newlen
!= sizeof(active
)) {
505 res
= copyin(req
->newptr
, &active
, sizeof(active
));
510 return set_sched_stats_active(active
);
513 SYSCTL_PROC(_kern
, OID_AUTO
, sched_stats_enable
, CTLFLAG_LOCKED
| CTLFLAG_WR
, 0, 0, sysctl_sched_stats_enable
, "-", "");
515 extern uint32_t sched_debug_flags
;
516 SYSCTL_INT(_debug
, OID_AUTO
, sched
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &sched_debug_flags
, 0, "scheduler debug");
518 #if (DEBUG || DEVELOPMENT)
519 extern boolean_t doprnt_hide_pointers
;
520 SYSCTL_INT(_debug
, OID_AUTO
, hide_kernel_pointers
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &doprnt_hide_pointers
, 0, "hide kernel pointers from log");
523 extern int get_kernel_symfile(proc_t
, char **);
526 #define KERN_COUNT_SYSCALLS (KERN_OSTYPE + 1000)
528 extern const unsigned int nsysent
;
529 extern int syscalls_log
[];
530 extern const char *syscallnames
[];
533 sysctl_docountsyscalls SYSCTL_HANDLER_ARGS
535 __unused
int cmd
= oidp
->oid_arg2
; /* subcommand*/
536 __unused
int *name
= arg1
; /* oid element argument vector */
537 __unused
int namelen
= arg2
; /* number of oid element arguments */
542 /* valid values passed in:
543 * = 0 means don't keep called counts for each bsd syscall
544 * > 0 means keep called counts for each bsd syscall
545 * = 2 means dump current counts to the system log
546 * = 3 means reset all counts
547 * for example, to dump current counts:
548 * sysctl -w kern.count_calls=2
550 error
= sysctl_io_number(req
, do_count_syscalls
,
551 sizeof(do_count_syscalls
), &tmp
, &changed
);
553 if (error
!= 0 || !changed
) {
558 do_count_syscalls
= 1;
559 } else if (tmp
== 0 || tmp
== 2 || tmp
== 3) {
560 for (int i
= 0; i
< nsysent
; i
++) {
561 if (syscalls_log
[i
] != 0) {
563 printf("%d calls - name %s \n", syscalls_log
[i
], syscallnames
[i
]);
569 do_count_syscalls
= (tmp
!= 0);
574 SYSCTL_PROC(_kern
, KERN_COUNT_SYSCALLS
, count_syscalls
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
575 0, /* Pointer argument (arg1) */
576 0, /* Integer argument (arg2) */
577 sysctl_docountsyscalls
, /* Handler function */
578 NULL
, /* Data pointer */
580 #endif /* COUNT_SYSCALLS */
583 * The following sysctl_* functions should not be used
584 * any more, as they can only cope with callers in
585 * user mode: Use new-style
593 sysdoproc_filt_KERN_PROC_PID(proc_t p
, void * arg
)
595 if (p
->p_pid
!= (pid_t
)*(int*)arg
) {
603 sysdoproc_filt_KERN_PROC_PGRP(proc_t p
, void * arg
)
605 if (p
->p_pgrpid
!= (pid_t
)*(int*)arg
) {
613 sysdoproc_filt_KERN_PROC_TTY(proc_t p
, void * arg
)
618 /* This is very racy but list lock is held.. Hmmm. */
619 if ((p
->p_flag
& P_CONTROLT
) == 0 ||
620 (p
->p_pgrp
== NULL
) || (p
->p_pgrp
->pg_session
== NULL
) ||
621 (tp
= SESSION_TP(p
->p_pgrp
->pg_session
)) == TTY_NULL
||
622 tp
->t_dev
!= (dev_t
)*(int*)arg
) {
632 sysdoproc_filt_KERN_PROC_UID(proc_t p
, void * arg
)
634 kauth_cred_t my_cred
;
637 if (p
->p_ucred
== NULL
) {
640 my_cred
= kauth_cred_proc_ref(p
);
641 uid
= kauth_cred_getuid(my_cred
);
642 kauth_cred_unref(&my_cred
);
644 if (uid
!= (uid_t
)*(int*)arg
) {
653 sysdoproc_filt_KERN_PROC_RUID(proc_t p
, void * arg
)
655 kauth_cred_t my_cred
;
658 if (p
->p_ucred
== NULL
) {
661 my_cred
= kauth_cred_proc_ref(p
);
662 ruid
= kauth_cred_getruid(my_cred
);
663 kauth_cred_unref(&my_cred
);
665 if (ruid
!= (uid_t
)*(int*)arg
) {
673 * try over estimating by 5 procs
675 #define KERN_PROCSLOP (5 * sizeof(struct kinfo_proc))
676 struct sysdoproc_args
{
682 unsigned int sizeof_kproc
;
691 sysdoproc_callback(proc_t p
, void *arg
)
693 struct sysdoproc_args
*args
= arg
;
695 if (args
->buflen
>= args
->sizeof_kproc
) {
696 if ((args
->ruidcheck
!= 0) && (sysdoproc_filt_KERN_PROC_RUID(p
, &args
->uidval
) == 0)) {
697 return PROC_RETURNED
;
699 if ((args
->uidcheck
!= 0) && (sysdoproc_filt_KERN_PROC_UID(p
, &args
->uidval
) == 0)) {
700 return PROC_RETURNED
;
702 if ((args
->ttycheck
!= 0) && (sysdoproc_filt_KERN_PROC_TTY(p
, &args
->uidval
) == 0)) {
703 return PROC_RETURNED
;
706 bzero(args
->kprocp
, args
->sizeof_kproc
);
707 if (args
->is_64_bit
) {
708 fill_user64_proc(p
, args
->kprocp
);
710 fill_user32_proc(p
, args
->kprocp
);
712 int error
= copyout(args
->kprocp
, args
->dp
, args
->sizeof_kproc
);
714 *args
->errorp
= error
;
715 return PROC_RETURNED_DONE
;
717 args
->dp
+= args
->sizeof_kproc
;
718 args
->buflen
-= args
->sizeof_kproc
;
720 args
->needed
+= args
->sizeof_kproc
;
721 return PROC_RETURNED
;
724 SYSCTL_NODE(_kern
, KERN_PROC
, proc
, CTLFLAG_RD
| CTLFLAG_LOCKED
, 0, "");
726 sysctl_prochandle SYSCTL_HANDLER_ARGS
728 int cmd
= oidp
->oid_arg2
; /* subcommand for multiple nodes */
729 int *name
= arg1
; /* oid element argument vector */
730 int namelen
= arg2
; /* number of oid element arguments */
731 user_addr_t where
= req
->oldptr
;/* user buffer copy out address */
733 user_addr_t dp
= where
;
735 size_t buflen
= where
!= USER_ADDR_NULL
? req
->oldlen
: 0;
737 boolean_t is_64_bit
= proc_is64bit(current_proc());
738 struct user32_kinfo_proc user32_kproc
;
739 struct user64_kinfo_proc user_kproc
;
742 int (*filterfn
)(proc_t
, void *) = 0;
743 struct sysdoproc_args args
;
748 if (namelen
!= 1 && !(namelen
== 0 && cmd
== KERN_PROC_ALL
)) {
753 sizeof_kproc
= sizeof(user_kproc
);
754 kprocp
= &user_kproc
;
756 sizeof_kproc
= sizeof(user32_kproc
);
757 kprocp
= &user32_kproc
;
762 filterfn
= sysdoproc_filt_KERN_PROC_PID
;
766 filterfn
= sysdoproc_filt_KERN_PROC_PGRP
;
785 /* must be kern.proc.<unknown> */
790 args
.buflen
= buflen
;
791 args
.kprocp
= kprocp
;
792 args
.is_64_bit
= is_64_bit
;
794 args
.needed
= needed
;
795 args
.errorp
= &error
;
796 args
.uidcheck
= uidcheck
;
797 args
.ruidcheck
= ruidcheck
;
798 args
.ttycheck
= ttycheck
;
799 args
.sizeof_kproc
= sizeof_kproc
;
801 args
.uidval
= name
[0];
804 proc_iterate((PROC_ALLPROCLIST
| PROC_ZOMBPROCLIST
),
805 sysdoproc_callback
, &args
, filterfn
, name
);
812 needed
= args
.needed
;
814 if (where
!= USER_ADDR_NULL
) {
815 req
->oldlen
= dp
- where
;
816 if (needed
> req
->oldlen
) {
820 needed
+= KERN_PROCSLOP
;
821 req
->oldlen
= needed
;
823 /* adjust index so we return the right required/consumed amount */
824 req
->oldidx
+= req
->oldlen
;
830 * We specify the subcommand code for multiple nodes as the 'req->arg2' value
831 * in the sysctl declaration itself, which comes into the handler function
832 * as 'oidp->oid_arg2'.
834 * For these particular sysctls, since they have well known OIDs, we could
835 * have just obtained it from the '((int *)arg1)[0]' parameter, but that would
836 * not demonstrate how to handle multiple sysctls that used OID_AUTO instead
837 * of a well known value with a common handler function. This is desirable,
838 * because we want well known values to "go away" at some future date.
840 * It should be noted that the value of '((int *)arg1)[1]' is used for many
841 * an integer parameter to the subcommand for many of these sysctls; we'd
842 * rather have used '((int *)arg1)[0]' for that, or even better, an element
843 * in a structure passed in as the the 'newp' argument to sysctlbyname(3),
844 * and then use leaf-node permissions enforcement, but that would have
845 * necessitated modifying user space code to correspond to the interface
846 * change, and we are striving for binary backward compatibility here; even
847 * though these are SPI, and not intended for use by user space applications
848 * which are not themselves system tools or libraries, some applications
849 * have erroneously used them.
851 SYSCTL_PROC(_kern_proc
, KERN_PROC_ALL
, all
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
852 0, /* Pointer argument (arg1) */
853 KERN_PROC_ALL
, /* Integer argument (arg2) */
854 sysctl_prochandle
, /* Handler function */
855 NULL
, /* Data is size variant on ILP32/LP64 */
857 SYSCTL_PROC(_kern_proc
, KERN_PROC_PID
, pid
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
858 0, /* Pointer argument (arg1) */
859 KERN_PROC_PID
, /* Integer argument (arg2) */
860 sysctl_prochandle
, /* Handler function */
861 NULL
, /* Data is size variant on ILP32/LP64 */
863 SYSCTL_PROC(_kern_proc
, KERN_PROC_TTY
, tty
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
864 0, /* Pointer argument (arg1) */
865 KERN_PROC_TTY
, /* Integer argument (arg2) */
866 sysctl_prochandle
, /* Handler function */
867 NULL
, /* Data is size variant on ILP32/LP64 */
869 SYSCTL_PROC(_kern_proc
, KERN_PROC_PGRP
, pgrp
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
870 0, /* Pointer argument (arg1) */
871 KERN_PROC_PGRP
, /* Integer argument (arg2) */
872 sysctl_prochandle
, /* Handler function */
873 NULL
, /* Data is size variant on ILP32/LP64 */
875 SYSCTL_PROC(_kern_proc
, KERN_PROC_UID
, uid
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
876 0, /* Pointer argument (arg1) */
877 KERN_PROC_UID
, /* Integer argument (arg2) */
878 sysctl_prochandle
, /* Handler function */
879 NULL
, /* Data is size variant on ILP32/LP64 */
881 SYSCTL_PROC(_kern_proc
, KERN_PROC_RUID
, ruid
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
882 0, /* Pointer argument (arg1) */
883 KERN_PROC_RUID
, /* Integer argument (arg2) */
884 sysctl_prochandle
, /* Handler function */
885 NULL
, /* Data is size variant on ILP32/LP64 */
887 SYSCTL_PROC(_kern_proc
, KERN_PROC_LCID
, lcid
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
888 0, /* Pointer argument (arg1) */
889 KERN_PROC_LCID
, /* Integer argument (arg2) */
890 sysctl_prochandle
, /* Handler function */
891 NULL
, /* Data is size variant on ILP32/LP64 */
896 * Fill in non-zero fields of an eproc structure for the specified process.
899 fill_user32_eproc(proc_t p
, struct user32_eproc
*__restrict ep
)
903 struct session
*sessp
;
904 kauth_cred_t my_cred
;
907 sessp
= proc_session(p
);
909 if (pg
!= PGRP_NULL
) {
910 ep
->e_pgid
= p
->p_pgrpid
;
911 ep
->e_jobc
= pg
->pg_jobc
;
912 if (sessp
!= SESSION_NULL
&& sessp
->s_ttyvp
) {
913 ep
->e_flag
= EPROC_CTTY
;
916 ep
->e_ppid
= p
->p_ppid
;
918 my_cred
= kauth_cred_proc_ref(p
);
920 /* A fake historical pcred */
921 ep
->e_pcred
.p_ruid
= kauth_cred_getruid(my_cred
);
922 ep
->e_pcred
.p_svuid
= kauth_cred_getsvuid(my_cred
);
923 ep
->e_pcred
.p_rgid
= kauth_cred_getrgid(my_cred
);
924 ep
->e_pcred
.p_svgid
= kauth_cred_getsvgid(my_cred
);
926 /* A fake historical *kauth_cred_t */
927 unsigned long refcnt
= os_atomic_load(&my_cred
->cr_ref
, relaxed
);
928 ep
->e_ucred
.cr_ref
= (uint32_t)MIN(refcnt
, UINT32_MAX
);
929 ep
->e_ucred
.cr_uid
= kauth_cred_getuid(my_cred
);
930 ep
->e_ucred
.cr_ngroups
= (short)posix_cred_get(my_cred
)->cr_ngroups
;
931 bcopy(posix_cred_get(my_cred
)->cr_groups
,
932 ep
->e_ucred
.cr_groups
, NGROUPS
* sizeof(gid_t
));
934 kauth_cred_unref(&my_cred
);
937 if ((p
->p_flag
& P_CONTROLT
) && (sessp
!= SESSION_NULL
) &&
938 (tp
= SESSION_TP(sessp
))) {
939 ep
->e_tdev
= tp
->t_dev
;
940 ep
->e_tpgid
= sessp
->s_ttypgrpid
;
945 if (sessp
!= SESSION_NULL
) {
946 if (SESS_LEADER(p
, sessp
)) {
947 ep
->e_flag
|= EPROC_SLEADER
;
951 if (pg
!= PGRP_NULL
) {
957 * Fill in non-zero fields of an LP64 eproc structure for the specified process.
960 fill_user64_eproc(proc_t p
, struct user64_eproc
*__restrict ep
)
964 struct session
*sessp
;
965 kauth_cred_t my_cred
;
968 sessp
= proc_session(p
);
970 if (pg
!= PGRP_NULL
) {
971 ep
->e_pgid
= p
->p_pgrpid
;
972 ep
->e_jobc
= pg
->pg_jobc
;
973 if (sessp
!= SESSION_NULL
&& sessp
->s_ttyvp
) {
974 ep
->e_flag
= EPROC_CTTY
;
977 ep
->e_ppid
= p
->p_ppid
;
979 my_cred
= kauth_cred_proc_ref(p
);
981 /* A fake historical pcred */
982 ep
->e_pcred
.p_ruid
= kauth_cred_getruid(my_cred
);
983 ep
->e_pcred
.p_svuid
= kauth_cred_getsvuid(my_cred
);
984 ep
->e_pcred
.p_rgid
= kauth_cred_getrgid(my_cred
);
985 ep
->e_pcred
.p_svgid
= kauth_cred_getsvgid(my_cred
);
987 /* A fake historical *kauth_cred_t */
988 unsigned long refcnt
= os_atomic_load(&my_cred
->cr_ref
, relaxed
);
989 ep
->e_ucred
.cr_ref
= (uint32_t)MIN(refcnt
, UINT32_MAX
);
990 ep
->e_ucred
.cr_uid
= kauth_cred_getuid(my_cred
);
991 ep
->e_ucred
.cr_ngroups
= (short)posix_cred_get(my_cred
)->cr_ngroups
;
992 bcopy(posix_cred_get(my_cred
)->cr_groups
,
993 ep
->e_ucred
.cr_groups
, NGROUPS
* sizeof(gid_t
));
995 kauth_cred_unref(&my_cred
);
998 if ((p
->p_flag
& P_CONTROLT
) && (sessp
!= SESSION_NULL
) &&
999 (tp
= SESSION_TP(sessp
))) {
1000 ep
->e_tdev
= tp
->t_dev
;
1001 ep
->e_tpgid
= sessp
->s_ttypgrpid
;
1006 if (sessp
!= SESSION_NULL
) {
1007 if (SESS_LEADER(p
, sessp
)) {
1008 ep
->e_flag
|= EPROC_SLEADER
;
1010 session_rele(sessp
);
1012 if (pg
!= PGRP_NULL
) {
1018 * Fill in an eproc structure for the specified process.
1019 * bzeroed by our caller, so only set non-zero fields.
1022 fill_user32_externproc(proc_t p
, struct user32_extern_proc
*__restrict exp
)
1024 exp
->p_starttime
.tv_sec
= (user32_time_t
)p
->p_start
.tv_sec
;
1025 exp
->p_starttime
.tv_usec
= p
->p_start
.tv_usec
;
1026 exp
->p_flag
= p
->p_flag
;
1027 if (p
->p_lflag
& P_LTRACED
) {
1028 exp
->p_flag
|= P_TRACED
;
1030 if (p
->p_lflag
& P_LPPWAIT
) {
1031 exp
->p_flag
|= P_PPWAIT
;
1033 if (p
->p_lflag
& P_LEXIT
) {
1034 exp
->p_flag
|= P_WEXIT
;
1036 exp
->p_stat
= p
->p_stat
;
1037 exp
->p_pid
= p
->p_pid
;
1038 exp
->p_oppid
= p
->p_oppid
;
1040 exp
->p_debugger
= p
->p_debugger
;
1041 exp
->sigwait
= p
->sigwait
;
1043 #ifdef _PROC_HAS_SCHEDINFO_
1044 exp
->p_estcpu
= p
->p_estcpu
;
1045 exp
->p_pctcpu
= p
->p_pctcpu
;
1046 exp
->p_slptime
= p
->p_slptime
;
1048 exp
->p_realtimer
.it_interval
.tv_sec
=
1049 (user32_time_t
)p
->p_realtimer
.it_interval
.tv_sec
;
1050 exp
->p_realtimer
.it_interval
.tv_usec
=
1051 (__int32_t
)p
->p_realtimer
.it_interval
.tv_usec
;
1053 exp
->p_realtimer
.it_value
.tv_sec
=
1054 (user32_time_t
)p
->p_realtimer
.it_value
.tv_sec
;
1055 exp
->p_realtimer
.it_value
.tv_usec
=
1056 (__int32_t
)p
->p_realtimer
.it_value
.tv_usec
;
1058 exp
->p_rtime
.tv_sec
= (user32_time_t
)p
->p_rtime
.tv_sec
;
1059 exp
->p_rtime
.tv_usec
= (__int32_t
)p
->p_rtime
.tv_usec
;
1061 exp
->p_sigignore
= p
->p_sigignore
;
1062 exp
->p_sigcatch
= p
->p_sigcatch
;
1063 exp
->p_priority
= p
->p_priority
;
1064 exp
->p_nice
= p
->p_nice
;
1065 bcopy(&p
->p_comm
, &exp
->p_comm
, MAXCOMLEN
);
1066 exp
->p_xstat
= (u_short
)MIN(p
->p_xstat
, USHRT_MAX
);
1067 exp
->p_acflag
= p
->p_acflag
;
1071 * Fill in an LP64 version of extern_proc structure for the specified process.
1074 fill_user64_externproc(proc_t p
, struct user64_extern_proc
*__restrict exp
)
1076 exp
->p_starttime
.tv_sec
= p
->p_start
.tv_sec
;
1077 exp
->p_starttime
.tv_usec
= p
->p_start
.tv_usec
;
1078 exp
->p_flag
= p
->p_flag
;
1079 if (p
->p_lflag
& P_LTRACED
) {
1080 exp
->p_flag
|= P_TRACED
;
1082 if (p
->p_lflag
& P_LPPWAIT
) {
1083 exp
->p_flag
|= P_PPWAIT
;
1085 if (p
->p_lflag
& P_LEXIT
) {
1086 exp
->p_flag
|= P_WEXIT
;
1088 exp
->p_stat
= p
->p_stat
;
1089 exp
->p_pid
= p
->p_pid
;
1090 exp
->p_oppid
= p
->p_oppid
;
1092 exp
->p_debugger
= p
->p_debugger
;
1093 exp
->sigwait
= p
->sigwait
;
1095 #ifdef _PROC_HAS_SCHEDINFO_
1096 exp
->p_estcpu
= p
->p_estcpu
;
1097 exp
->p_pctcpu
= p
->p_pctcpu
;
1098 exp
->p_slptime
= p
->p_slptime
;
1100 exp
->p_realtimer
.it_interval
.tv_sec
= p
->p_realtimer
.it_interval
.tv_sec
;
1101 exp
->p_realtimer
.it_interval
.tv_usec
= p
->p_realtimer
.it_interval
.tv_usec
;
1103 exp
->p_realtimer
.it_value
.tv_sec
= p
->p_realtimer
.it_value
.tv_sec
;
1104 exp
->p_realtimer
.it_value
.tv_usec
= p
->p_realtimer
.it_value
.tv_usec
;
1106 exp
->p_rtime
.tv_sec
= p
->p_rtime
.tv_sec
;
1107 exp
->p_rtime
.tv_usec
= p
->p_rtime
.tv_usec
;
1109 exp
->p_sigignore
= p
->p_sigignore
;
1110 exp
->p_sigcatch
= p
->p_sigcatch
;
1111 exp
->p_priority
= p
->p_priority
;
1112 exp
->p_nice
= p
->p_nice
;
1113 bcopy(&p
->p_comm
, &exp
->p_comm
, MAXCOMLEN
);
1114 exp
->p_xstat
= (u_short
)MIN(p
->p_xstat
, USHRT_MAX
);
1115 exp
->p_acflag
= p
->p_acflag
;
1119 fill_user32_proc(proc_t p
, struct user32_kinfo_proc
*__restrict kp
)
1121 /* on a 64 bit kernel, 32 bit users get some truncated information */
1122 fill_user32_externproc(p
, &kp
->kp_proc
);
1123 fill_user32_eproc(p
, &kp
->kp_eproc
);
1127 fill_user64_proc(proc_t p
, struct user64_kinfo_proc
*__restrict kp
)
1129 fill_user64_externproc(p
, &kp
->kp_proc
);
1130 fill_user64_eproc(p
, &kp
->kp_eproc
);
1134 sysctl_kdebug_ops SYSCTL_HANDLER_ARGS
1136 __unused
int cmd
= oidp
->oid_arg2
; /* subcommand*/
1137 int *name
= arg1
; /* oid element argument vector */
1138 int namelen
= arg2
; /* number of oid element arguments */
1139 user_addr_t oldp
= req
->oldptr
; /* user buffer copy out address */
1140 size_t *oldlenp
= &req
->oldlen
; /* user buffer copy out size */
1141 // user_addr_t newp = req->newptr; /* user buffer copy in address */
1142 // size_t newlen = req->newlen; /* user buffer copy in size */
1160 case KERN_KDWRITETR
:
1161 case KERN_KDWRITEMAP
:
1167 case KERN_KDREADCURTHRMAP
:
1168 case KERN_KDSET_TYPEFILTER
:
1169 case KERN_KDBUFWAIT
:
1171 case KERN_KDWRITEMAP_V3
:
1172 case KERN_KDWRITETR_V3
:
1173 ret
= kdbg_control(name
, namelen
, oldp
, oldlenp
);
1180 /* adjust index so we return the right required/consumed amount */
1182 req
->oldidx
+= req
->oldlen
;
1187 SYSCTL_PROC(_kern
, KERN_KDEBUG
, kdebug
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
1188 0, /* Pointer argument (arg1) */
1189 0, /* Integer argument (arg2) */
1190 sysctl_kdebug_ops
, /* Handler function */
1191 NULL
, /* Data pointer */
1195 #if defined(XNU_TARGET_OS_OSX)
1197 * Return the top *sizep bytes of the user stack, or the entire area of the
1198 * user stack down through the saved exec_path, whichever is smaller.
1201 sysctl_doprocargs SYSCTL_HANDLER_ARGS
1203 __unused
int cmd
= oidp
->oid_arg2
; /* subcommand*/
1204 int *name
= arg1
; /* oid element argument vector */
1205 int namelen
= arg2
; /* number of oid element arguments */
1206 user_addr_t oldp
= req
->oldptr
; /* user buffer copy out address */
1207 size_t *oldlenp
= &req
->oldlen
; /* user buffer copy out size */
1208 // user_addr_t newp = req->newptr; /* user buffer copy in address */
1209 // size_t newlen = req->newlen; /* user buffer copy in size */
1212 error
= sysctl_procargsx( name
, namelen
, oldp
, oldlenp
, current_proc(), 0);
1214 /* adjust index so we return the right required/consumed amount */
1216 req
->oldidx
+= req
->oldlen
;
1221 SYSCTL_PROC(_kern
, KERN_PROCARGS
, procargs
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
1222 0, /* Pointer argument (arg1) */
1223 0, /* Integer argument (arg2) */
1224 sysctl_doprocargs
, /* Handler function */
1225 NULL
, /* Data pointer */
1227 #endif /* defined(XNU_TARGET_OS_OSX) */
1230 sysctl_doprocargs2 SYSCTL_HANDLER_ARGS
1232 __unused
int cmd
= oidp
->oid_arg2
; /* subcommand*/
1233 int *name
= arg1
; /* oid element argument vector */
1234 int namelen
= arg2
; /* number of oid element arguments */
1235 user_addr_t oldp
= req
->oldptr
; /* user buffer copy out address */
1236 size_t *oldlenp
= &req
->oldlen
; /* user buffer copy out size */
1237 // user_addr_t newp = req->newptr; /* user buffer copy in address */
1238 // size_t newlen = req->newlen; /* user buffer copy in size */
1241 error
= sysctl_procargsx( name
, namelen
, oldp
, oldlenp
, current_proc(), 1);
1243 /* adjust index so we return the right required/consumed amount */
1245 req
->oldidx
+= req
->oldlen
;
1250 SYSCTL_PROC(_kern
, KERN_PROCARGS2
, procargs2
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
1251 0, /* Pointer argument (arg1) */
1252 0, /* Integer argument (arg2) */
1253 sysctl_doprocargs2
, /* Handler function */
1254 NULL
, /* Data pointer */
1257 #define SYSCTL_PROCARGS_READ_ENVVARS_ENTITLEMENT "com.apple.private.read-environment-variables"
1259 sysctl_procargsx(int *name
, u_int namelen
, user_addr_t where
,
1260 size_t *sizep
, proc_t cur_proc
, int argc_yes
)
1262 assert(sizep
!= NULL
);
1264 size_t buflen
= where
!= USER_ADDR_NULL
? *sizep
: 0;
1266 struct _vm_map
*proc_map
= NULL
;
1268 vm_map_copy_t tmp
= NULL
;
1269 user_addr_t arg_addr
;
1274 vm_offset_t copy_start
= 0, copy_end
;
1275 vm_offset_t smallbuffer_start
;
1278 kauth_cred_t my_cred
;
1283 size_t current_arg_index
;
1284 size_t current_arg_len
;
1285 const char * current_arg
;
1286 bool omit_env_vars
= true;
1294 buflen
-= sizeof(int); /* reserve first word to return argc */
1296 /* we only care about buflen when where (oldp from sysctl) is not NULL. */
1297 /* when where (oldp from sysctl) is NULL and sizep (oldlenp from sysctl */
1298 /* is not NULL then the caller wants us to return the length needed to */
1299 /* hold the data we would return */
1300 if (where
!= USER_ADDR_NULL
&& (buflen
<= 0 || buflen
> ARG_MAX
)) {
1306 * Lookup process by pid
1315 /* Allow reading environment variables if any of the following are true:
1316 * - kernel is DEVELOPMENT || DEBUG
1317 * - target process is same as current_proc()
1318 * - target process is not cs_restricted
1320 * - caller has an entitlement
1323 #if DEVELOPMENT || DEBUG
1324 omit_env_vars
= false;
1326 if (p
== current_proc() ||
1327 !cs_restricted(p
) ||
1329 csr_check(CSR_ALLOW_UNRESTRICTED_DTRACE
) == 0 ||
1331 IOTaskHasEntitlement(current_task(), SYSCTL_PROCARGS_READ_ENVVARS_ENTITLEMENT
)
1333 omit_env_vars
= false;
1337 * Copy the top N bytes of the stack.
1338 * On all machines we have so far, the stack grows
1341 * If the user expects no more than N bytes of
1342 * argument list, use that as a guess for the
1346 if (!p
->user_stack
) {
1351 /* save off argc before releasing the proc */
1354 argslen
= p
->p_argslen
;
1357 * When these sysctls were introduced, the first string in the strings
1358 * section was just the bare path of the executable. However, for security
1359 * reasons we now prefix this string with executable_path= so it can be
1360 * parsed getenv style. To avoid binary compatability issues with exising
1361 * callers of this sysctl, we strip it off here.
1362 * (rdar://problem/13746466)
1364 #define EXECUTABLE_KEY "executable_path="
1365 argslen
-= strlen(EXECUTABLE_KEY
);
1367 if (where
== USER_ADDR_NULL
&& !omit_env_vars
) {
1368 /* caller only wants to know length of proc args data.
1369 * If we don't need to omit environment variables, we can skip
1370 * copying the target process stack */
1371 goto calculate_size
;
1374 my_cred
= kauth_cred_proc_ref(p
);
1375 uid
= kauth_cred_getuid(my_cred
);
1376 kauth_cred_unref(&my_cred
);
1378 if ((uid
!= kauth_cred_getuid(kauth_cred_get()))
1379 && suser(kauth_cred_get(), &cur_proc
->p_acflag
)) {
1384 arg_size
= round_page(argslen
);
1386 arg_addr
= p
->user_stack
- arg_size
;
1389 * Before we can block (any VM code), make another
1390 * reference to the map to keep it alive. We do
1391 * that by getting a reference on the task itself.
1400 * Once we have a task reference we can convert that into a
1401 * map reference, which we will use in the calls below. The
1402 * task/process may change its map after we take this reference
1403 * (see execve), but the worst that will happen then is a return
1404 * of stale info (which is always a possibility).
1406 task_reference(task
);
1409 proc_map
= get_task_map_reference(task
);
1410 task_deallocate(task
);
1412 if (proc_map
== NULL
) {
1417 ret
= kmem_alloc(kernel_map
, ©_start
, arg_size
, VM_KERN_MEMORY_BSD
);
1418 if (ret
!= KERN_SUCCESS
) {
1422 bzero((void *)copy_start
, arg_size
);
1424 /* End of buffer should be page aligned */
1425 assert(copy_start
+ arg_size
== round_page(copy_start
+ arg_size
));
1426 copy_end
= copy_start
+ arg_size
;
1428 if (vm_map_copyin(proc_map
, (vm_map_address_t
)arg_addr
,
1429 (vm_map_size_t
)arg_size
, FALSE
, &tmp
) != KERN_SUCCESS
) {
1435 * Now that we've done the copyin from the process'
1436 * map, we can release the reference to it.
1438 vm_map_deallocate(proc_map
);
1441 if (vm_map_copy_overwrite(kernel_map
,
1442 (vm_map_address_t
)copy_start
,
1443 tmp
, (vm_map_size_t
) arg_size
, FALSE
) != KERN_SUCCESS
) {
1447 /* tmp was consumed */
1450 if (omit_env_vars
) {
1453 /* Iterate over everything in argv, plus one for the bare executable path */
1454 for (current_arg_index
= 0; current_arg_index
< argc
+ 1 && argvsize
< argslen
; ++current_arg_index
) {
1455 current_arg
= (const char *)(copy_end
- argslen
) + argvsize
;
1456 remaining
= argslen
- argvsize
;
1457 current_arg_len
= strnlen(current_arg
, remaining
);
1458 if (current_arg_len
< remaining
) {
1459 /* We have space for the null terminator */
1460 current_arg_len
+= 1;
1462 if (current_arg_index
== 0) {
1463 /* The bare executable path may have multiple null bytes after it for alignment */
1464 while (current_arg_len
< remaining
&& current_arg
[current_arg_len
] == 0) {
1465 current_arg_len
+= 1;
1469 argvsize
+= current_arg_len
;
1471 assert(argvsize
<= argslen
);
1473 /* Adjust argslen and copy_end to make the copyout range extend to the end of argv */
1474 copy_end
= copy_end
- argslen
+ argvsize
;
1478 if (where
== USER_ADDR_NULL
) {
1480 goto calculate_size
;
1483 if (buflen
>= argslen
) {
1484 data
= (caddr_t
) (copy_end
- argslen
);
1488 * Before rdar://25397314, this function contained incorrect logic when buflen is less
1489 * than argslen. The problem was that it copied in `buflen` bytes from the end of the target
1490 * process user stack into the beginning of a buffer of size round_page(buflen), and then
1491 * copied out `buflen` bytes from the end of this buffer. The effect of this was that
1492 * the caller of this sysctl would get zeros at the end of their buffer.
1494 * To preserve this behavior, bzero everything from copy_end-round_page(buflen)+buflen to the
1495 * end of the buffer. This emulates copying in only `buflen` bytes.
1500 * copy_start .... size: round_page(buflen) .... copy_end
1501 * [---copied in data (size: buflen)---|--- zeros ----------]
1503 * data = copy_end - buflen
1507 * copy_start .... size: round_page(p->argslen) .... full copy_end
1508 * ^ ....................... p->argslen ...............................^
1509 * ^ ^ truncated copy_end ^
1511 * ^ ................ argslen ........................ ^
1513 * [-------copied in data (size: round_page(p->argslen))-------:----env vars---]
1515 * ^ data = copy_end - buflen
1516 * smallbuffer_start = max(copy_end - round_page(buflen), copy_start)
1519 * Full copy_end: copy_end calculated from copy_start + round_page(p->argslen)
1520 * Truncated copy_end: copy_end after truncation to remove environment variables.
1522 * If environment variables were omitted, then we use the truncated copy_end, otherwise
1523 * we use full copy_end.
1525 * smallbuffer_start: represents where copy_start would be in the old code.
1526 * data: The beginning of the region we copyout
1528 smallbuffer_start
= copy_end
- round_page(buflen
);
1529 if (smallbuffer_start
< copy_start
) {
1530 smallbuffer_start
= copy_start
;
1532 bzero((void *)(smallbuffer_start
+ buflen
), copy_end
- (smallbuffer_start
+ buflen
));
1533 data
= (caddr_t
) (copy_end
- buflen
);
1538 /* Put processes argc as the first word in the copyout buffer */
1539 suword(where
, argc
);
1540 error
= copyout(data
, (where
+ sizeof(int)), size
);
1541 size
+= sizeof(int);
1543 error
= copyout(data
, where
, size
);
1546 * Make the old PROCARGS work to return the executable's path
1547 * But, only if there is enough space in the provided buffer
1549 * on entry: data [possibily] points to the beginning of the path
1551 * Note: we keep all pointers&sizes aligned to word boundries
1553 if ((!error
) && (buflen
> 0 && (u_int
)buflen
> size
)) {
1554 int binPath_sz
, alignedBinPath_sz
= 0;
1555 int extraSpaceNeeded
, addThis
;
1556 user_addr_t placeHere
;
1557 char * str
= (char *) data
;
1558 size_t max_len
= size
;
1560 /* Some apps are really bad about messing up their stacks
1561 * So, we have to be extra careful about getting the length
1562 * of the executing binary. If we encounter an error, we bail.
1565 /* Limit ourselves to PATH_MAX paths */
1566 if (max_len
> PATH_MAX
) {
1572 while ((binPath_sz
< max_len
- 1) && (*str
++ != 0)) {
1576 /* If we have a NUL terminator, copy it, too */
1577 if (binPath_sz
< max_len
- 1) {
1581 /* Pre-Flight the space requiremnts */
1583 /* Account for the padding that fills out binPath to the next word */
1584 alignedBinPath_sz
+= (binPath_sz
& (sizeof(int) - 1)) ? (sizeof(int) - (binPath_sz
& (sizeof(int) - 1))) : 0;
1586 placeHere
= where
+ size
;
1588 /* Account for the bytes needed to keep placeHere word aligned */
1589 addThis
= (placeHere
& (sizeof(int) - 1)) ? (sizeof(int) - (placeHere
& (sizeof(int) - 1))) : 0;
1591 /* Add up all the space that is needed */
1592 extraSpaceNeeded
= alignedBinPath_sz
+ addThis
+ binPath_sz
+ (4 * sizeof(int));
1594 /* is there is room to tack on argv[0]? */
1595 if ((buflen
& ~(sizeof(int) - 1)) >= (size
+ extraSpaceNeeded
)) {
1596 placeHere
+= addThis
;
1597 suword(placeHere
, 0);
1598 placeHere
+= sizeof(int);
1599 suword(placeHere
, 0xBFFF0000);
1600 placeHere
+= sizeof(int);
1601 suword(placeHere
, 0);
1602 placeHere
+= sizeof(int);
1603 error
= copyout(data
, placeHere
, binPath_sz
);
1605 placeHere
+= binPath_sz
;
1606 suword(placeHere
, 0);
1607 size
+= extraSpaceNeeded
;
1614 /* Size has already been calculated for the where != NULL case */
1615 if (where
== USER_ADDR_NULL
) {
1618 size
+= sizeof(int);
1621 * old PROCARGS will return the executable's path and plus some
1622 * extra space for work alignment and data tags
1624 size
+= PATH_MAX
+ (6 * sizeof(int));
1626 size
+= (size
& (sizeof(int) - 1)) ? (sizeof(int) - (size
& (sizeof(int) - 1))) : 0;
1636 vm_map_copy_discard(tmp
);
1638 if (proc_map
!= NULL
) {
1639 vm_map_deallocate(proc_map
);
1641 if (copy_start
!= (vm_offset_t
) 0) {
1642 kmem_free(kernel_map
, copy_start
, arg_size
);
1649 * Max number of concurrent aio requests
1653 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1655 int new_value
, changed
;
1656 int error
= sysctl_io_number(req
, aio_max_requests
, sizeof(int), &new_value
, &changed
);
1658 /* make sure the system-wide limit is greater than the per process limit */
1659 if (new_value
>= aio_max_requests_per_process
&& new_value
<= AIO_MAX_REQUESTS
) {
1660 aio_max_requests
= new_value
;
1670 * Max number of concurrent aio requests per process
1674 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1676 int new_value
, changed
;
1677 int error
= sysctl_io_number(req
, aio_max_requests_per_process
, sizeof(int), &new_value
, &changed
);
1679 /* make sure per process limit is less than the system-wide limit */
1680 if (new_value
<= aio_max_requests
&& new_value
>= AIO_LISTIO_MAX
) {
1681 aio_max_requests_per_process
= new_value
;
1691 * Max number of async IO worker threads
1695 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1697 int new_value
, changed
;
1698 int error
= sysctl_io_number(req
, aio_worker_threads
, sizeof(int), &new_value
, &changed
);
1700 /* we only allow an increase in the number of worker threads */
1701 if (new_value
> aio_worker_threads
) {
1702 _aio_create_worker_threads((new_value
- aio_worker_threads
));
1703 aio_worker_threads
= new_value
;
1713 * System-wide limit on the max number of processes
1717 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1719 int new_value
, changed
;
1720 int error
= sysctl_io_number(req
, maxproc
, sizeof(int), &new_value
, &changed
);
1722 AUDIT_ARG(value32
, new_value
);
1723 /* make sure the system-wide limit is less than the configured hard
1724 * limit set at kernel compilation */
1725 if (new_value
<= hard_maxproc
&& new_value
> 0) {
1726 maxproc
= new_value
;
1734 extern int sched_enable_smt
;
1736 sysctl_sched_enable_smt
1737 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1739 int new_value
, changed
;
1740 int error
= sysctl_io_number(req
, sched_enable_smt
, sizeof(int), &new_value
, &changed
);
1744 kern_return_t kret
= KERN_SUCCESS
;
1746 AUDIT_ARG(value32
, new_value
);
1747 if (new_value
== 0) {
1748 sched_enable_smt
= 0;
1749 kret
= enable_smt_processors(false);
1751 sched_enable_smt
= 1;
1752 kret
= enable_smt_processors(true);
1759 case KERN_INVALID_ARGUMENT
:
1773 SYSCTL_STRING(_kern
, KERN_OSTYPE
, ostype
,
1774 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
1776 SYSCTL_STRING(_kern
, KERN_OSRELEASE
, osrelease
,
1777 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
1779 SYSCTL_INT(_kern
, KERN_OSREV
, osrevision
,
1780 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
1781 (int *)NULL
, BSD
, "");
1782 SYSCTL_STRING(_kern
, KERN_VERSION
, version
,
1783 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
1785 SYSCTL_STRING(_kern
, OID_AUTO
, uuid
,
1786 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
1787 &kernel_uuid_string
[0], 0, "");
1789 SYSCTL_STRING(_kern
, OID_AUTO
, osbuildconfig
,
1790 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
,
1791 &osbuild_config
[0], 0, "");
1794 sysctl_protoboot(__unused
struct sysctl_oid
*oidp
,
1795 __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1798 #if CONFIG_LOCKERBOOT
1799 char protoboot_buff
[24];
1800 size_t protoboot_len
= sizeof(protoboot_buff
);
1802 if (vnode_tag(rootvnode
) == VT_LOCKERFS
) {
1803 strlcpy(protoboot_buff
, kernel_protoboot_mount
, protoboot_len
);
1804 error
= sysctl_io_string(req
, protoboot_buff
, protoboot_len
, 0, NULL
);
1817 SYSCTL_PROC(_kern
, OID_AUTO
, protoboot
,
1818 CTLTYPE_STRING
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
1819 0, 0, sysctl_protoboot
, "A", "");
1828 int debug_kprint_syscall
= 0;
1829 char debug_kprint_syscall_process
[MAXCOMLEN
+ 1];
1831 /* Thread safe: bits and string value are not used to reclaim state */
1832 SYSCTL_INT(_debug
, OID_AUTO
, kprint_syscall
,
1833 CTLFLAG_RW
| CTLFLAG_LOCKED
, &debug_kprint_syscall
, 0, "kprintf syscall tracing");
1834 SYSCTL_STRING(_debug
, OID_AUTO
, kprint_syscall_process
,
1835 CTLFLAG_RW
| CTLFLAG_LOCKED
, debug_kprint_syscall_process
, sizeof(debug_kprint_syscall_process
),
1836 "name of process for kprintf syscall tracing");
1839 debug_kprint_current_process(const char **namep
)
1841 struct proc
*p
= current_proc();
1847 if (debug_kprint_syscall_process
[0]) {
1848 /* user asked to scope tracing to a particular process name */
1849 if (0 == strncmp(debug_kprint_syscall_process
,
1850 p
->p_comm
, sizeof(debug_kprint_syscall_process
))) {
1851 /* no value in telling the user that we traced what they asked */
1862 /* trace all processes. Tell user what we traced */
1871 /* PR-5293665: need to use a callback function for kern.osversion to set
1872 * osversion in IORegistry */
1875 sysctl_osversion(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
1879 rval
= sysctl_handle_string(oidp
, arg1
, arg2
, req
);
1882 IORegistrySetOSBuildVersion((char *)arg1
);
1888 SYSCTL_PROC(_kern
, KERN_OSVERSION
, osversion
,
1889 CTLFLAG_RW
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
1890 osversion
, 256 /* OSVERSIZE*/,
1891 sysctl_osversion
, "A", "");
1894 _already_set_or_not_launchd(struct sysctl_req
*req
, char *val
)
1896 if (req
->newptr
!= 0) {
1898 * Can only ever be set by launchd, and only once at boot.
1900 if (req
->p
->p_pid
!= 1 || val
[0] != '\0') {
1907 #if XNU_TARGET_OS_OSX
1909 sysctl_system_version_compat
1910 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1912 int oldval
= (task_has_system_version_compat_enabled(current_task()));
1913 int new_value
= 0, changed
= 0;
1915 int error
= sysctl_io_number(req
, oldval
, sizeof(int), &new_value
, &changed
);
1917 task_set_system_version_compat_enabled(current_task(), (new_value
));
1922 SYSCTL_PROC(_kern
, OID_AUTO
, system_version_compat
,
1923 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
,
1924 0, 0, sysctl_system_version_compat
, "A", "");
1926 char osproductversioncompat
[48] = { '\0' };
1929 sysctl_osproductversioncompat(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
1931 if (_already_set_or_not_launchd(req
, osproductversioncompat
)) {
1934 return sysctl_handle_string(oidp
, arg1
, arg2
, req
);
1938 SYSCTL_PROC(_kern
, OID_AUTO
, osproductversioncompat
,
1939 CTLFLAG_RW
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
1940 osproductversioncompat
, sizeof(osproductversioncompat
),
1941 sysctl_osproductversioncompat
, "A", "The ProductVersion from SystemVersionCompat.plist");
1944 char osproductversion
[48] = { '\0' };
1947 sysctl_osproductversion(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
1949 if (_already_set_or_not_launchd(req
, osproductversion
)) {
1953 #if !XNU_TARGET_OS_OSX
1954 return sysctl_handle_string(oidp
, arg1
, arg2
, req
);
1956 if (task_has_system_version_compat_enabled(current_task()) && (osproductversioncompat
[0] != '\0')) {
1957 return sysctl_handle_string(oidp
, osproductversioncompat
, arg2
, req
);
1959 return sysctl_handle_string(oidp
, arg1
, arg2
, req
);
1964 #if XNU_TARGET_OS_OSX
1965 static_assert(sizeof(osproductversioncompat
) == sizeof(osproductversion
),
1966 "osproductversion size matches osproductversioncompat size");
1969 SYSCTL_PROC(_kern
, OID_AUTO
, osproductversion
,
1970 CTLFLAG_RW
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
1971 osproductversion
, sizeof(osproductversion
),
1972 sysctl_osproductversion
, "A", "The ProductVersion from SystemVersion.plist");
1974 char osreleasetype
[48] = { '\0' };
1977 sysctl_osreleasetype(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
1979 if (_already_set_or_not_launchd(req
, osreleasetype
)) {
1982 return sysctl_handle_string(oidp
, arg1
, arg2
, req
);
1985 void reset_osreleasetype(void);
1988 reset_osreleasetype(void)
1990 memset(osreleasetype
, 0, sizeof(osreleasetype
));
1993 SYSCTL_PROC(_kern
, OID_AUTO
, osreleasetype
,
1994 CTLFLAG_RW
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
1995 osreleasetype
, sizeof(osreleasetype
),
1996 sysctl_osreleasetype
, "A", "The ReleaseType from SystemVersion.plist");
1998 static uint64_t iossupportversion_string
[48];
2001 sysctl_iossupportversion(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2003 if (req
->newptr
!= 0) {
2005 * Can only ever be set by launchd, and only once at boot.
2007 if (req
->p
->p_pid
!= 1 || iossupportversion_string
[0] != '\0') {
2012 return sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2015 SYSCTL_PROC(_kern
, OID_AUTO
, iossupportversion
,
2016 CTLFLAG_RW
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2017 iossupportversion_string
, sizeof(iossupportversion_string
),
2018 sysctl_iossupportversion
, "A", "The iOSSupportVersion from SystemVersion.plist");
2020 static uint64_t osvariant_status
= 0;
2023 sysctl_osvariant_status(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2025 if (req
->newptr
!= 0) {
2027 * Can only ever be set by launchd, and only once.
2028 * Reset by usrctl() -> reset_osvariant_status() during
2029 * userspace reboot, since userspace could reboot into
2030 * a different variant.
2032 if (req
->p
->p_pid
!= 1 || osvariant_status
!= 0) {
2037 return sysctl_handle_quad(oidp
, arg1
, arg2
, req
);
2040 SYSCTL_PROC(_kern
, OID_AUTO
, osvariant_status
,
2041 CTLFLAG_RW
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
,
2042 &osvariant_status
, sizeof(osvariant_status
),
2043 sysctl_osvariant_status
, "Q", "Opaque flags used to cache OS variant information");
2045 void reset_osvariant_status(void);
2048 reset_osvariant_status(void)
2050 osvariant_status
= 0;
2053 extern void commpage_update_dyld_flags(uint64_t);
2054 uint64_t dyld_flags
= 0;
2057 sysctl_dyld_flags(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2060 * Can only ever be set by launchd, possibly several times
2061 * as dyld may change its mind after a userspace reboot.
2063 if (req
->newptr
!= 0 && req
->p
->p_pid
!= 1) {
2067 int res
= sysctl_handle_quad(oidp
, arg1
, arg2
, req
);
2068 if (req
->newptr
&& res
== 0) {
2069 commpage_update_dyld_flags(dyld_flags
);
2074 SYSCTL_PROC(_kern
, OID_AUTO
, dyld_flags
,
2075 CTLFLAG_RW
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
,
2076 &dyld_flags
, sizeof(dyld_flags
),
2077 sysctl_dyld_flags
, "Q", "Opaque flags used to cache dyld system-wide configuration");
2079 #if defined(XNU_TARGET_OS_BRIDGE)
2080 char macosproductversion
[MACOS_VERS_LEN
] = { '\0' };
2082 SYSCTL_STRING(_kern
, OID_AUTO
, macosproductversion
,
2083 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2084 &macosproductversion
[0], MACOS_VERS_LEN
, "The currently running macOS ProductVersion (from SystemVersion.plist on macOS)");
2086 char macosversion
[MACOS_VERS_LEN
] = { '\0' };
2088 SYSCTL_STRING(_kern
, OID_AUTO
, macosversion
,
2089 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2090 &macosversion
[0], MACOS_VERS_LEN
, "The currently running macOS build version");
2094 sysctl_sysctl_bootargs
2095 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2098 char buf
[BOOT_LINE_LENGTH
];
2100 strlcpy(buf
, PE_boot_args(), BOOT_LINE_LENGTH
);
2101 error
= sysctl_io_string(req
, buf
, BOOT_LINE_LENGTH
, 0, NULL
);
2105 SYSCTL_PROC(_kern
, OID_AUTO
, bootargs
,
2106 CTLFLAG_LOCKED
| CTLFLAG_RD
| CTLFLAG_KERN
| CTLTYPE_STRING
,
2108 sysctl_sysctl_bootargs
, "A", "bootargs");
2111 sysctl_kernelcacheuuid(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2114 if (kernelcache_uuid_valid
) {
2115 rval
= sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2120 SYSCTL_PROC(_kern
, OID_AUTO
, kernelcacheuuid
,
2121 CTLFLAG_RD
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2122 kernelcache_uuid_string
, sizeof(kernelcache_uuid_string
),
2123 sysctl_kernelcacheuuid
, "A", "");
2126 sysctl_systemfilesetuuid(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2129 if (pageablekc_uuid_valid
) {
2130 rval
= sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2135 SYSCTL_PROC(_kern
, OID_AUTO
, systemfilesetuuid
,
2136 CTLFLAG_RD
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2137 pageablekc_uuid_string
, sizeof(pageablekc_uuid_string
),
2138 sysctl_systemfilesetuuid
, "A", "");
2141 sysctl_auxiliaryfilesetuuid(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2144 if (auxkc_uuid_valid
) {
2145 rval
= sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2150 SYSCTL_PROC(_kern
, OID_AUTO
, auxiliaryfilesetuuid
,
2151 CTLFLAG_RD
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2152 auxkc_uuid_string
, sizeof(auxkc_uuid_string
),
2153 sysctl_auxiliaryfilesetuuid
, "A", "");
2156 sysctl_filesetuuid(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2159 kc_format_t kcformat
;
2160 kernel_mach_header_t
*mh
;
2162 unsigned long uuidlen
= 0;
2163 uuid_string_t uuid_str
;
2165 if (!PE_get_primary_kc_format(&kcformat
) || kcformat
!= KCFormatFileset
) {
2169 mh
= (kernel_mach_header_t
*)PE_get_kc_header(KCKindPrimary
);
2170 uuid
= getuuidfromheader(mh
, &uuidlen
);
2172 if ((uuid
!= NULL
) && (uuidlen
== sizeof(uuid_t
))) {
2173 uuid_unparse_upper(*(uuid_t
*)uuid
, uuid_str
);
2174 rval
= sysctl_io_string(req
, (char *)uuid_str
, sizeof(uuid_str
), 0, NULL
);
2180 SYSCTL_PROC(_kern
, OID_AUTO
, filesetuuid
,
2181 CTLFLAG_RD
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2183 sysctl_filesetuuid
, "A", "");
2186 SYSCTL_INT(_kern
, KERN_MAXFILES
, maxfiles
,
2187 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2189 SYSCTL_INT(_kern
, KERN_ARGMAX
, argmax
,
2190 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2191 (int *)NULL
, ARG_MAX
, "");
2192 SYSCTL_INT(_kern
, KERN_POSIX1
, posix1version
,
2193 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2194 (int *)NULL
, _POSIX_VERSION
, "");
2195 SYSCTL_INT(_kern
, KERN_NGROUPS
, ngroups
,
2196 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2197 (int *)NULL
, NGROUPS_MAX
, "");
2198 SYSCTL_INT(_kern
, KERN_JOB_CONTROL
, job_control
,
2199 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2200 (int *)NULL
, 1, "");
2201 #if 1 /* _POSIX_SAVED_IDS from <unistd.h> */
2202 SYSCTL_INT(_kern
, KERN_SAVED_IDS
, saved_ids
,
2203 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2204 (int *)NULL
, 1, "");
2206 SYSCTL_INT(_kern
, KERN_SAVED_IDS
, saved_ids
,
2207 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2210 SYSCTL_INT(_kern
, OID_AUTO
, num_files
,
2211 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2213 SYSCTL_COMPAT_INT(_kern
, OID_AUTO
, num_vnodes
,
2214 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2216 SYSCTL_INT(_kern
, OID_AUTO
, num_tasks
,
2217 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2219 SYSCTL_INT(_kern
, OID_AUTO
, num_threads
,
2220 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2221 &thread_max
, 0, "");
2222 SYSCTL_INT(_kern
, OID_AUTO
, num_taskthreads
,
2223 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2224 &task_threadmax
, 0, "");
2225 SYSCTL_LONG(_kern
, OID_AUTO
, num_recycledvnodes
,
2226 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2227 &num_recycledvnodes
, "");
2228 SYSCTL_COMPAT_INT(_kern
, OID_AUTO
, free_vnodes
,
2229 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2230 &freevnodes
, 0, "");
2233 sysctl_maxvnodes(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2235 int oldval
= desiredvnodes
;
2236 int error
= sysctl_io_number(req
, desiredvnodes
, sizeof(int), &desiredvnodes
, NULL
);
2238 if (oldval
!= desiredvnodes
) {
2239 resize_namecache(desiredvnodes
);
2245 SYSCTL_INT(_kern
, OID_AUTO
, namecache_disabled
,
2246 CTLFLAG_RW
| CTLFLAG_LOCKED
,
2247 &nc_disabled
, 0, "");
2249 SYSCTL_PROC(_kern
, KERN_MAXVNODES
, maxvnodes
,
2250 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2251 0, 0, sysctl_maxvnodes
, "I", "");
2253 SYSCTL_PROC(_kern
, KERN_MAXPROC
, maxproc
,
2254 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2255 0, 0, sysctl_maxproc
, "I", "");
2257 SYSCTL_PROC(_kern
, KERN_AIOMAX
, aiomax
,
2258 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2259 0, 0, sysctl_aiomax
, "I", "");
2261 SYSCTL_PROC(_kern
, KERN_AIOPROCMAX
, aioprocmax
,
2262 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2263 0, 0, sysctl_aioprocmax
, "I", "");
2265 SYSCTL_PROC(_kern
, KERN_AIOTHREADS
, aiothreads
,
2266 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2267 0, 0, sysctl_aiothreads
, "I", "");
2269 SYSCTL_PROC(_kern
, OID_AUTO
, sched_enable_smt
,
2270 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_KERN
,
2271 0, 0, sysctl_sched_enable_smt
, "I", "");
2273 extern int sched_allow_NO_SMT_threads
;
2274 SYSCTL_INT(_kern
, OID_AUTO
, sched_allow_NO_SMT_threads
,
2275 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2276 &sched_allow_NO_SMT_threads
, 0, "");
2278 #if (DEVELOPMENT || DEBUG)
2279 extern int smt_sched_bonus_16ths
;
2280 SYSCTL_INT(_kern
, OID_AUTO
, smt_sched_bonus_16ths
,
2281 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2282 &smt_sched_bonus_16ths
, 0, "");
2284 extern int smt_timeshare_enabled
;
2285 SYSCTL_INT(_kern
, OID_AUTO
, sched_smt_timeshare_enable
,
2286 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2287 &smt_timeshare_enabled
, 0, "");
2289 extern int sched_smt_balance
;
2290 SYSCTL_INT(_kern
, OID_AUTO
, sched_smt_balance
,
2291 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2292 &sched_smt_balance
, 0, "");
2293 extern int sched_allow_rt_smt
;
2294 SYSCTL_INT(_kern
, OID_AUTO
, sched_allow_rt_smt
,
2295 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2296 &sched_allow_rt_smt
, 0, "");
2297 extern int sched_avoid_cpu0
;
2298 SYSCTL_INT(_kern
, OID_AUTO
, sched_avoid_cpu0
,
2299 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2300 &sched_avoid_cpu0
, 0, "");
2301 #if __arm__ || __arm64__
2302 extern uint32_t perfcontrol_requested_recommended_cores
;
2303 SYSCTL_UINT(_kern
, OID_AUTO
, sched_recommended_cores
,
2304 CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2305 &perfcontrol_requested_recommended_cores
, 0, "");
2307 /* Scheduler perfcontrol callouts sysctls */
2308 SYSCTL_DECL(_kern_perfcontrol_callout
);
2309 SYSCTL_NODE(_kern
, OID_AUTO
, perfcontrol_callout
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0,
2310 "scheduler perfcontrol callouts");
2312 extern int perfcontrol_callout_stats_enabled
;
2313 SYSCTL_INT(_kern_perfcontrol_callout
, OID_AUTO
, stats_enabled
,
2314 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2315 &perfcontrol_callout_stats_enabled
, 0, "");
2317 extern uint64_t perfcontrol_callout_stat_avg(perfcontrol_callout_type_t type
,
2318 perfcontrol_callout_stat_t stat
);
2320 /* On-Core Callout */
2322 sysctl_perfcontrol_callout_stat
2323 (__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2325 perfcontrol_callout_stat_t stat
= (perfcontrol_callout_stat_t
)arg1
;
2326 perfcontrol_callout_type_t type
= (perfcontrol_callout_type_t
)arg2
;
2327 return sysctl_io_number(req
, (int)perfcontrol_callout_stat_avg(type
, stat
),
2328 sizeof(int), NULL
, NULL
);
2331 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, oncore_instr
,
2332 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2333 (void *)PERFCONTROL_STAT_INSTRS
, PERFCONTROL_CALLOUT_ON_CORE
,
2334 sysctl_perfcontrol_callout_stat
, "I", "");
2335 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, oncore_cycles
,
2336 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2337 (void *)PERFCONTROL_STAT_CYCLES
, PERFCONTROL_CALLOUT_ON_CORE
,
2338 sysctl_perfcontrol_callout_stat
, "I", "");
2339 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, offcore_instr
,
2340 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2341 (void *)PERFCONTROL_STAT_INSTRS
, PERFCONTROL_CALLOUT_OFF_CORE
,
2342 sysctl_perfcontrol_callout_stat
, "I", "");
2343 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, offcore_cycles
,
2344 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2345 (void *)PERFCONTROL_STAT_CYCLES
, PERFCONTROL_CALLOUT_OFF_CORE
,
2346 sysctl_perfcontrol_callout_stat
, "I", "");
2347 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, context_instr
,
2348 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2349 (void *)PERFCONTROL_STAT_INSTRS
, PERFCONTROL_CALLOUT_CONTEXT
,
2350 sysctl_perfcontrol_callout_stat
, "I", "");
2351 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, context_cycles
,
2352 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2353 (void *)PERFCONTROL_STAT_CYCLES
, PERFCONTROL_CALLOUT_CONTEXT
,
2354 sysctl_perfcontrol_callout_stat
, "I", "");
2355 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, update_instr
,
2356 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2357 (void *)PERFCONTROL_STAT_INSTRS
, PERFCONTROL_CALLOUT_STATE_UPDATE
,
2358 sysctl_perfcontrol_callout_stat
, "I", "");
2359 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, update_cycles
,
2360 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2361 (void *)PERFCONTROL_STAT_CYCLES
, PERFCONTROL_CALLOUT_STATE_UPDATE
,
2362 sysctl_perfcontrol_callout_stat
, "I", "");
2365 extern int sched_amp_idle_steal
;
2366 SYSCTL_INT(_kern
, OID_AUTO
, sched_amp_idle_steal
,
2367 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2368 &sched_amp_idle_steal
, 0, "");
2369 extern int sched_amp_spill_steal
;
2370 SYSCTL_INT(_kern
, OID_AUTO
, sched_amp_spill_steal
,
2371 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2372 &sched_amp_spill_steal
, 0, "");
2373 extern int sched_amp_spill_count
;
2374 SYSCTL_INT(_kern
, OID_AUTO
, sched_amp_spill_count
,
2375 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2376 &sched_amp_spill_count
, 0, "");
2377 extern int sched_amp_spill_deferred_ipi
;
2378 SYSCTL_INT(_kern
, OID_AUTO
, sched_amp_spill_deferred_ipi
,
2379 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2380 &sched_amp_spill_deferred_ipi
, 0, "");
2381 extern int sched_amp_pcores_preempt_immediate_ipi
;
2382 SYSCTL_INT(_kern
, OID_AUTO
, sched_amp_pcores_preempt_immediate_ipi
,
2383 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2384 &sched_amp_pcores_preempt_immediate_ipi
, 0, "");
2385 #endif /* __AMP__ */
2386 #endif /* __arm__ || __arm64__ */
2389 extern int legacy_footprint_entitlement_mode
;
2390 SYSCTL_INT(_kern
, OID_AUTO
, legacy_footprint_entitlement_mode
,
2391 CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2392 &legacy_footprint_entitlement_mode
, 0, "");
2393 #endif /* __arm64__ */
2396 sysctl_kern_sched_rt_n_backup_processors(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2398 int new_value
, changed
;
2399 int old_value
= sched_get_rt_n_backup_processors();
2400 int error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, &changed
);
2402 sched_set_rt_n_backup_processors(new_value
);
2408 SYSCTL_PROC(_kern
, OID_AUTO
, sched_rt_n_backup_processors
,
2409 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2410 0, 0, sysctl_kern_sched_rt_n_backup_processors
, "I", "");
2412 #endif /* (DEVELOPMENT || DEBUG) */
2416 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2418 int new_value
, changed
;
2419 int error
= sysctl_io_number(req
, securelevel
, sizeof(int), &new_value
, &changed
);
2421 if (!(new_value
< securelevel
&& req
->p
->p_pid
!= 1)) {
2423 securelevel
= new_value
;
2432 SYSCTL_PROC(_kern
, KERN_SECURELVL
, securelevel
,
2433 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2434 0, 0, sysctl_securelvl
, "I", "");
2439 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2442 char tmpname
[MAXHOSTNAMELEN
] = {};
2444 lck_mtx_lock(&domainname_lock
);
2445 strlcpy(tmpname
, domainname
, sizeof(tmpname
));
2446 lck_mtx_unlock(&domainname_lock
);
2448 error
= sysctl_io_string(req
, tmpname
, sizeof(tmpname
), 0, &changed
);
2449 if (!error
&& changed
) {
2450 lck_mtx_lock(&hostname_lock
);
2451 strlcpy(domainname
, tmpname
, sizeof(domainname
));
2452 lck_mtx_unlock(&hostname_lock
);
2457 SYSCTL_PROC(_kern
, KERN_DOMAINNAME
, nisdomainname
,
2458 CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2459 0, 0, sysctl_domainname
, "A", "");
2461 SYSCTL_COMPAT_INT(_kern
, KERN_HOSTID
, hostid
,
2462 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2467 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2470 char tmpname
[MAXHOSTNAMELEN
] = {};
2472 lck_mtx_lock(&hostname_lock
);
2473 strlcpy(tmpname
, hostname
, sizeof(tmpname
));
2474 lck_mtx_unlock(&hostname_lock
);
2476 error
= sysctl_io_string(req
, tmpname
, sizeof(tmpname
), 1, &changed
);
2477 if (!error
&& changed
) {
2478 lck_mtx_lock(&hostname_lock
);
2479 strlcpy(hostname
, tmpname
, sizeof(hostname
));
2480 lck_mtx_unlock(&hostname_lock
);
2485 SYSCTL_PROC(_kern
, KERN_HOSTNAME
, hostname
,
2486 CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2487 0, 0, sysctl_hostname
, "A", "");
2491 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2493 /* Original code allowed writing, I'm copying this, although this all makes
2494 * no sense to me. Besides, this sysctl is never used. */
2495 return sysctl_io_string(req
, &req
->p
->p_name
[0], (2 * MAXCOMLEN
+ 1), 1, NULL
);
2498 SYSCTL_PROC(_kern
, KERN_PROCNAME
, procname
,
2499 CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
,
2500 0, 0, sysctl_procname
, "A", "");
2502 SYSCTL_INT(_kern
, KERN_SPECULATIVE_READS
, speculative_reads_disabled
,
2503 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2504 &speculative_reads_disabled
, 0, "");
2506 SYSCTL_UINT(_kern
, OID_AUTO
, preheat_max_bytes
,
2507 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2508 &preheat_max_bytes
, 0, "");
2510 SYSCTL_UINT(_kern
, OID_AUTO
, preheat_min_bytes
,
2511 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2512 &preheat_min_bytes
, 0, "");
2514 SYSCTL_UINT(_kern
, OID_AUTO
, speculative_prefetch_max
,
2515 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2516 &speculative_prefetch_max
, 0, "");
2518 SYSCTL_UINT(_kern
, OID_AUTO
, speculative_prefetch_max_iosize
,
2519 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2520 &speculative_prefetch_max_iosize
, 0, "");
2522 SYSCTL_UINT(_kern
, OID_AUTO
, vm_page_free_target
,
2523 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2524 &vm_page_free_target
, 0, "");
2526 SYSCTL_UINT(_kern
, OID_AUTO
, vm_page_free_min
,
2527 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2528 &vm_page_free_min
, 0, "");
2530 SYSCTL_UINT(_kern
, OID_AUTO
, vm_page_free_reserved
,
2531 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2532 &vm_page_free_reserved
, 0, "");
2534 SYSCTL_UINT(_kern
, OID_AUTO
, vm_page_speculative_percentage
,
2535 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2536 &vm_pageout_state
.vm_page_speculative_percentage
, 0, "");
2538 SYSCTL_UINT(_kern
, OID_AUTO
, vm_page_speculative_q_age_ms
,
2539 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2540 &vm_pageout_state
.vm_page_speculative_q_age_ms
, 0, "");
2542 SYSCTL_UINT(_kern
, OID_AUTO
, vm_max_delayed_work_limit
,
2543 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2544 &vm_max_delayed_work_limit
, 0, "");
2546 SYSCTL_UINT(_kern
, OID_AUTO
, vm_max_batch
,
2547 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2548 &vm_max_batch
, 0, "");
2550 SYSCTL_STRING(_kern
, OID_AUTO
, bootsessionuuid
,
2551 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2552 &bootsessionuuid_string
, sizeof(bootsessionuuid_string
), "");
2557 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2560 boottime_timeval(&tv
);
2561 struct proc
*p
= req
->p
;
2563 if (proc_is64bit(p
)) {
2564 struct user64_timeval t
= {};
2565 t
.tv_sec
= tv
.tv_sec
;
2566 t
.tv_usec
= tv
.tv_usec
;
2567 return sysctl_io_opaque(req
, &t
, sizeof(t
), NULL
);
2569 struct user32_timeval t
= {};
2570 t
.tv_sec
= (user32_time_t
)tv
.tv_sec
;
2571 t
.tv_usec
= tv
.tv_usec
;
2572 return sysctl_io_opaque(req
, &t
, sizeof(t
), NULL
);
2576 SYSCTL_PROC(_kern
, KERN_BOOTTIME
, boottime
,
2577 CTLTYPE_STRUCT
| CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2578 0, 0, sysctl_boottime
, "S,timeval", "");
2580 extern const char* IOGetBootUUID(void);
2582 /* non-static: written by imageboot.c */
2583 uuid_string_t fake_bootuuid
;
2587 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2591 /* check the first byte to see if the string has been
2592 * populated. this is a uuid_STRING_t, this check would
2593 * not work with a uuid_t.
2595 if (fake_bootuuid
[0] != '\0') {
2596 error
= sysctl_io_string(req
, fake_bootuuid
, 0, 0, NULL
);
2600 const char *uuid_string
= IOGetBootUUID();
2603 error
= uuid_parse(uuid_string
, boot_uuid
);
2605 error
= sysctl_io_string(req
, __DECONST(char *, uuid_string
), 0, 0, NULL
);
2613 SYSCTL_PROC(_kern
, OID_AUTO
, bootuuid
,
2614 CTLTYPE_STRING
| CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2615 0, 0, sysctl_bootuuid
, "A", "");
2618 extern const char* IOGetApfsPrebootUUID(void);
2619 extern const char *IOGetAssociatedApfsVolgroupUUID(void);
2622 sysctl_apfsprebootuuid
2623 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2627 const char *uuid_string
= IOGetApfsPrebootUUID();
2629 uuid_t apfs_preboot_uuid
;
2630 error
= uuid_parse(uuid_string
, apfs_preboot_uuid
);
2632 error
= sysctl_io_string(req
, __DECONST(char *, uuid_string
), 0, 0, NULL
);
2639 SYSCTL_PROC(_kern
, OID_AUTO
, apfsprebootuuid
,
2640 CTLTYPE_STRING
| CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2641 0, 0, sysctl_apfsprebootuuid
, "A", "");
2644 sysctl_targetsystemvolgroupuuid
2645 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2649 const char *uuid_string
= IOGetApfsPrebootUUID();
2651 uuid_t apfs_preboot_uuid
;
2652 error
= uuid_parse(uuid_string
, apfs_preboot_uuid
);
2654 error
= sysctl_io_string(req
, __DECONST(char *, uuid_string
), 0, 0, NULL
);
2658 * In special boot modes, such as kcgen-mode, the
2659 * apfs-preboot-uuid property will not be set. Instead, a
2660 * different property, associated-volume-group, will be set
2661 * which indicates the UUID of the VolumeGroup containing the
2662 * system volume into which you will boot.
2664 uuid_string
= IOGetAssociatedApfsVolgroupUUID();
2666 uuid_t apfs_preboot_uuid
;
2667 error
= uuid_parse(uuid_string
, apfs_preboot_uuid
);
2669 error
= sysctl_io_string(req
, __DECONST(char *, uuid_string
), 0, 0, NULL
);
2677 SYSCTL_PROC(_kern
, OID_AUTO
, targetsystemvolgroupuuid
,
2678 CTLTYPE_STRING
| CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_MASKED
| CTLFLAG_LOCKED
,
2679 0, 0, sysctl_targetsystemvolgroupuuid
, "A", "");
2683 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2686 int error
= get_kernel_symfile(req
->p
, &str
);
2690 return sysctl_io_string(req
, str
, 0, 0, NULL
);
2694 SYSCTL_PROC(_kern
, KERN_SYMFILE
, symfile
,
2695 CTLTYPE_STRING
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2696 0, 0, sysctl_symfile
, "A", "");
2698 #if CONFIG_NFS_CLIENT
2701 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2703 return sysctl_io_number(req
, netboot_root(), sizeof(int), NULL
, NULL
);
2706 SYSCTL_PROC(_kern
, KERN_NETBOOT
, netboot
,
2707 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2708 0, 0, sysctl_netboot
, "I", "");
2711 #ifdef CONFIG_IMGSRC_ACCESS
2713 * Legacy--act as if only one layer of nesting is possible.
2717 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2719 vfs_context_t ctx
= vfs_context_current();
2723 if (!vfs_context_issuser(ctx
)) {
2727 if (imgsrc_rootvnodes
[0] == NULL
) {
2731 result
= vnode_getwithref(imgsrc_rootvnodes
[0]);
2736 devvp
= vnode_mount(imgsrc_rootvnodes
[0])->mnt_devvp
;
2737 result
= vnode_getwithref(devvp
);
2742 result
= sysctl_io_number(req
, vnode_specrdev(devvp
), sizeof(dev_t
), NULL
, NULL
);
2746 vnode_put(imgsrc_rootvnodes
[0]);
2750 SYSCTL_PROC(_kern
, OID_AUTO
, imgsrcdev
,
2751 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2752 0, 0, sysctl_imgsrcdev
, "I", "");
2756 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2759 struct imgsrc_info info
[MAX_IMAGEBOOT_NESTING
] = {}; /* 2 for now, no problem */
2763 if (imgsrc_rootvnodes
[0] == NULLVP
) {
2767 for (i
= 0; i
< MAX_IMAGEBOOT_NESTING
; i
++) {
2769 * Go get the root vnode.
2771 rvp
= imgsrc_rootvnodes
[i
];
2772 if (rvp
== NULLVP
) {
2776 error
= vnode_get(rvp
);
2782 * For now, no getting at a non-local volume.
2784 devvp
= vnode_mount(rvp
)->mnt_devvp
;
2785 if (devvp
== NULL
) {
2790 error
= vnode_getwithref(devvp
);
2799 info
[i
].ii_dev
= vnode_specrdev(devvp
);
2800 info
[i
].ii_flags
= 0;
2801 info
[i
].ii_height
= i
;
2802 bzero(info
[i
].ii_reserved
, sizeof(info
[i
].ii_reserved
));
2808 return sysctl_io_opaque(req
, info
, i
* sizeof(info
[0]), NULL
);
2811 SYSCTL_PROC(_kern
, OID_AUTO
, imgsrcinfo
,
2812 CTLTYPE_OPAQUE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2813 0, 0, sysctl_imgsrcinfo
, "I", "");
2815 #endif /* CONFIG_IMGSRC_ACCESS */
2818 SYSCTL_DECL(_kern_timer
);
2819 SYSCTL_NODE(_kern
, OID_AUTO
, timer
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, "timer");
2822 SYSCTL_INT(_kern_timer
, OID_AUTO
, coalescing_enabled
,
2823 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2824 &mach_timer_coalescing_enabled
, 0, "");
2826 SYSCTL_QUAD(_kern_timer
, OID_AUTO
, deadline_tracking_bin_1
,
2827 CTLFLAG_RW
| CTLFLAG_LOCKED
,
2828 &timer_deadline_tracking_bin_1
, "");
2829 SYSCTL_QUAD(_kern_timer
, OID_AUTO
, deadline_tracking_bin_2
,
2830 CTLFLAG_RW
| CTLFLAG_LOCKED
,
2831 &timer_deadline_tracking_bin_2
, "");
2833 SYSCTL_DECL(_kern_timer_longterm
);
2834 SYSCTL_NODE(_kern_timer
, OID_AUTO
, longterm
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, "longterm");
2837 /* Must match definition in osfmk/kern/timer_call.c */
2840 ENQUEUES
, DEQUEUES
, ESCALATES
, SCANS
, PREEMPTS
,
2841 LATENCY
, LATENCY_MIN
, LATENCY_MAX
, SCAN_LIMIT
, SCAN_INTERVAL
, PAUSES
2843 extern uint64_t timer_sysctl_get(int);
2844 extern int timer_sysctl_set(int, uint64_t);
2848 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2850 int oid
= (int)arg1
;
2851 uint64_t value
= timer_sysctl_get(oid
);
2856 error
= sysctl_io_number(req
, value
, sizeof(value
), &new_value
, &changed
);
2858 error
= timer_sysctl_set(oid
, new_value
);
2864 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, threshold
,
2865 CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2866 (void *) THRESHOLD
, 0, sysctl_timer
, "Q", "");
2867 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, scan_limit
,
2868 CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2869 (void *) SCAN_LIMIT
, 0, sysctl_timer
, "Q", "");
2870 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, scan_interval
,
2871 CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2872 (void *) SCAN_INTERVAL
, 0, sysctl_timer
, "Q", "");
2874 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, qlen
,
2875 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2876 (void *) QCOUNT
, 0, sysctl_timer
, "Q", "");
2877 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, scan_pauses
,
2878 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2879 (void *) PAUSES
, 0, sysctl_timer
, "Q", "");
2882 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, enqueues
,
2883 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2884 (void *) ENQUEUES
, 0, sysctl_timer
, "Q", "");
2885 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, dequeues
,
2886 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2887 (void *) DEQUEUES
, 0, sysctl_timer
, "Q", "");
2888 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, escalates
,
2889 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2890 (void *) ESCALATES
, 0, sysctl_timer
, "Q", "");
2891 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, scans
,
2892 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2893 (void *) SCANS
, 0, sysctl_timer
, "Q", "");
2894 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, preempts
,
2895 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2896 (void *) PREEMPTS
, 0, sysctl_timer
, "Q", "");
2897 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, latency
,
2898 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2899 (void *) LATENCY
, 0, sysctl_timer
, "Q", "");
2900 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, latency_min
,
2901 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2902 (void *) LATENCY_MIN
, 0, sysctl_timer
, "Q", "");
2903 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, latency_max
,
2904 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2905 (void *) LATENCY_MAX
, 0, sysctl_timer
, "Q", "");
2910 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2912 return sysctl_io_number(req
, (int)req
->p
->user_stack
, sizeof(int), NULL
, NULL
);
2915 SYSCTL_PROC(_kern
, KERN_USRSTACK32
, usrstack
,
2916 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2917 0, 0, sysctl_usrstack
, "I", "");
2921 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2923 return sysctl_io_number(req
, req
->p
->user_stack
, sizeof(req
->p
->user_stack
), NULL
, NULL
);
2926 SYSCTL_PROC(_kern
, KERN_USRSTACK64
, usrstack64
,
2927 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2928 0, 0, sysctl_usrstack64
, "Q", "");
2932 SYSCTL_STRING(_kern
, KERN_COREFILE
, corefile
,
2933 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2934 corefilename
, sizeof(corefilename
), "");
2938 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2940 #ifdef SECURE_KERNEL
2944 int new_value
, changed
;
2945 int error
= sysctl_io_number(req
, do_coredump
, sizeof(int), &new_value
, &changed
);
2947 if ((new_value
== 0) || (new_value
== 1)) {
2948 do_coredump
= new_value
;
2957 SYSCTL_PROC(_kern
, KERN_COREDUMP
, coredump
,
2958 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2959 0, 0, sysctl_coredump
, "I", "");
2962 sysctl_suid_coredump
2963 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2965 #ifdef SECURE_KERNEL
2969 int new_value
, changed
;
2970 int error
= sysctl_io_number(req
, sugid_coredump
, sizeof(int), &new_value
, &changed
);
2972 if ((new_value
== 0) || (new_value
== 1)) {
2973 sugid_coredump
= new_value
;
2982 SYSCTL_PROC(_kern
, KERN_SUGID_COREDUMP
, sugid_coredump
,
2983 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2984 0, 0, sysctl_suid_coredump
, "I", "");
2986 #endif /* CONFIG_COREDUMP */
2990 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2992 struct proc
*p
= req
->p
;
2993 int new_value
, changed
;
2994 int error
= sysctl_io_number(req
, (req
->p
->p_lflag
& P_LDELAYTERM
)? 1: 0, sizeof(int), &new_value
, &changed
);
2998 req
->p
->p_lflag
|= P_LDELAYTERM
;
3000 req
->p
->p_lflag
&= ~P_LDELAYTERM
;
3007 SYSCTL_PROC(_kern
, KERN_PROCDELAYTERM
, delayterm
,
3008 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3009 0, 0, sysctl_delayterm
, "I", "");
3014 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3016 struct proc
*p
= req
->p
;
3018 int new_value
, old_value
, changed
;
3021 ut
= get_bsdthread_info(current_thread());
3023 if (ut
->uu_flag
& UT_RAGE_VNODES
) {
3024 old_value
= KERN_RAGE_THREAD
;
3025 } else if (p
->p_lflag
& P_LRAGE_VNODES
) {
3026 old_value
= KERN_RAGE_PROC
;
3031 error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, &changed
);
3033 if ((error
== 0) && (changed
!= 0)) {
3034 switch (new_value
) {
3035 case KERN_RAGE_PROC
:
3037 p
->p_lflag
|= P_LRAGE_VNODES
;
3040 case KERN_UNRAGE_PROC
:
3042 p
->p_lflag
&= ~P_LRAGE_VNODES
;
3046 case KERN_RAGE_THREAD
:
3047 ut
->uu_flag
|= UT_RAGE_VNODES
;
3049 case KERN_UNRAGE_THREAD
:
3050 ut
= get_bsdthread_info(current_thread());
3051 ut
->uu_flag
&= ~UT_RAGE_VNODES
;
3058 SYSCTL_PROC(_kern
, KERN_RAGEVNODE
, rage_vnode
,
3059 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
,
3060 0, 0, sysctl_rage_vnode
, "I", "");
3062 /* XXX until filecoordinationd fixes a bit of inverted logic. */
3065 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3067 int old_value
= 0, new_value
, changed
;
3069 return sysctl_io_number(req
, old_value
, sizeof(int), &new_value
,
3073 SYSCTL_PROC(_kern
, OID_AUTO
, vfsnspace
,
3074 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
,
3075 0, 0, sysctl_vfsnspace
, "I", "");
3077 /* XXX move this interface into libproc and remove this sysctl */
3079 sysctl_setthread_cpupercent
3080 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3082 int new_value
, old_value
;
3084 kern_return_t kret
= KERN_SUCCESS
;
3085 uint8_t percent
= 0;
3094 if ((error
= sysctl_io_number(req
, old_value
, sizeof(old_value
), &new_value
, NULL
)) != 0) {
3098 percent
= new_value
& 0xff; /* low 8 bytes for perent */
3099 ms_refill
= (new_value
>> 8) & 0xffffff; /* upper 24bytes represent ms refill value */
3100 if (percent
> 100) {
3105 * If the caller is specifying a percentage of 0, this will unset the CPU limit, if present.
3107 if ((kret
= thread_set_cpulimit(THREAD_CPULIMIT_BLOCK
, percent
, ms_refill
* (int)NSEC_PER_MSEC
)) != 0) {
3114 SYSCTL_PROC(_kern
, OID_AUTO
, setthread_cpupercent
,
3115 CTLTYPE_INT
| CTLFLAG_WR
| CTLFLAG_ANYBODY
,
3116 0, 0, sysctl_setthread_cpupercent
, "I", "set thread cpu percentage limit");
3120 sysctl_kern_check_openevt
3121 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3123 struct proc
*p
= req
->p
;
3124 int new_value
, old_value
, changed
;
3127 if (p
->p_flag
& P_CHECKOPENEVT
) {
3128 old_value
= KERN_OPENEVT_PROC
;
3133 error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, &changed
);
3135 if ((error
== 0) && (changed
!= 0)) {
3136 switch (new_value
) {
3137 case KERN_OPENEVT_PROC
:
3138 OSBitOrAtomic(P_CHECKOPENEVT
, &p
->p_flag
);
3141 case KERN_UNOPENEVT_PROC
:
3142 OSBitAndAtomic(~((uint32_t)P_CHECKOPENEVT
), &p
->p_flag
);
3152 SYSCTL_PROC(_kern
, KERN_CHECKOPENEVT
, check_openevt
, CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
,
3153 0, 0, sysctl_kern_check_openevt
, "I", "set the per-process check-open-evt flag");
3156 #if DEVELOPMENT || DEBUG
3159 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3161 #ifdef SECURE_KERNEL
3165 int new_value
, changed
;
3168 error
= sysctl_io_number(req
, nx_enabled
, sizeof(nx_enabled
), &new_value
, &changed
);
3174 #if defined(__x86_64__)
3176 * Only allow setting if NX is supported on the chip
3178 if (!(cpuid_extfeatures() & CPUID_EXTFEATURE_XD
)) {
3182 nx_enabled
= new_value
;
3185 #endif /* SECURE_KERNEL */
3189 #if DEVELOPMENT || DEBUG
3190 SYSCTL_PROC(_kern
, KERN_NX_PROTECTION
, nx
,
3191 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
3192 0, 0, sysctl_nx
, "I", "");
3197 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3199 if (proc_is64bit(req
->p
)) {
3200 struct user64_loadavg loadinfo64
= {};
3201 fill_loadavg64(&averunnable
, &loadinfo64
);
3202 return sysctl_io_opaque(req
, &loadinfo64
, sizeof(loadinfo64
), NULL
);
3204 struct user32_loadavg loadinfo32
= {};
3205 fill_loadavg32(&averunnable
, &loadinfo32
);
3206 return sysctl_io_opaque(req
, &loadinfo32
, sizeof(loadinfo32
), NULL
);
3210 SYSCTL_PROC(_vm
, VM_LOADAVG
, loadavg
,
3211 CTLTYPE_STRUCT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3212 0, 0, sysctl_loadavg
, "S,loadavg", "");
3215 * Note: Thread safe; vm_map_lock protects in vm_toggle_entry_reuse()
3218 sysctl_vm_toggle_address_reuse(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
,
3219 __unused
int arg2
, struct sysctl_req
*req
)
3221 int old_value
= 0, new_value
= 0, error
= 0;
3223 if (vm_toggle_entry_reuse( VM_TOGGLE_GETVALUE
, &old_value
)) {
3226 error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, NULL
);
3228 return vm_toggle_entry_reuse(new_value
, NULL
);
3233 SYSCTL_PROC(_debug
, OID_AUTO
, toggle_address_reuse
, CTLFLAG_ANYBODY
| CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, 0, sysctl_vm_toggle_address_reuse
, "I", "");
3235 #ifdef CONFIG_XNUPOST
3237 extern uint32_t xnupost_get_estimated_testdata_size(void);
3238 extern int xnupost_reset_all_tests(void);
3241 sysctl_handle_xnupost_get_tests SYSCTL_HANDLER_ARGS
3243 /* fixup unused arguments warnings */
3244 __unused
int _oa2
= arg2
;
3245 __unused
void * _oa1
= arg1
;
3246 __unused
struct sysctl_oid
* _oidp
= oidp
;
3249 user_addr_t oldp
= 0;
3250 user_addr_t newp
= 0;
3251 uint32_t usedbytes
= 0;
3260 if ((void *)oldp
== NULL
) {
3261 /* return estimated size for second call where info can be placed */
3262 req
->oldidx
= xnupost_get_estimated_testdata_size();
3264 error
= xnupost_export_testdata((void *)oldp
, req
->oldlen
, &usedbytes
);
3265 req
->oldidx
= usedbytes
;
3274 CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLTYPE_OPAQUE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3277 sysctl_handle_xnupost_get_tests
,
3279 "read xnupost test data in kernel");
3282 sysctl_debug_xnupost_ctl SYSCTL_HANDLER_ARGS
3284 /* fixup unused arguments warnings */
3285 __unused
int _oa2
= arg2
;
3286 __unused
void * _oa1
= arg1
;
3287 __unused
struct sysctl_oid
* _oidp
= oidp
;
3291 * INPUT: ACTION, PARAM1, PARAM2, PARAM3
3292 * OUTPUT: RESULTCODE, ADDITIONAL DATA
3294 int32_t outval
[ARRCOUNT
] = {0};
3295 int32_t input
[ARRCOUNT
] = {0};
3296 int32_t out_size
= sizeof(outval
);
3297 int32_t in_size
= sizeof(input
);
3300 /* if this is NULL call to find out size, send out size info */
3305 /* pull in provided value from userspace */
3306 error
= SYSCTL_IN(req
, &input
[0], in_size
);
3311 if (input
[0] == XTCTL_RESET_TESTDATA
) {
3312 outval
[0] = xnupost_reset_all_tests();
3317 error
= SYSCTL_OUT(req
, &outval
[0], out_size
);
3324 CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLTYPE_OPAQUE
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3327 sysctl_debug_xnupost_ctl
,
3329 "xnupost control for kernel testing");
3331 extern void test_oslog_handleOSLogCtl(int32_t * in
, int32_t * out
, int32_t arraycount
);
3334 sysctl_debug_test_oslog_ctl(__unused
struct sysctl_oid
* oidp
, __unused
void * arg1
, __unused
int arg2
, struct sysctl_req
* req
)
3337 int32_t outval
[ARRCOUNT
] = {0};
3338 int32_t input
[ARRCOUNT
] = {0};
3339 int32_t size_outval
= sizeof(outval
);
3340 int32_t size_inval
= sizeof(input
);
3343 /* if this is NULL call to find out size, send out size info */
3345 error
= SYSCTL_OUT(req
, &outval
[0], size_outval
);
3349 /* pull in provided value from userspace */
3350 error
= SYSCTL_IN(req
, &input
[0], size_inval
);
3355 test_oslog_handleOSLogCtl(input
, outval
, ARRCOUNT
);
3357 error
= SYSCTL_OUT(req
, &outval
[0], size_outval
);
3365 CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLTYPE_OPAQUE
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3368 sysctl_debug_test_oslog_ctl
,
3370 "testing oslog in kernel");
3372 #include <mach/task.h>
3373 #include <mach/semaphore.h>
3375 static LCK_GRP_DECLARE(sysctl_debug_test_stackshot_owner_grp
, "test-stackshot-owner-grp");
3376 static LCK_MTX_DECLARE(sysctl_debug_test_stackshot_owner_init_mtx
,
3377 &sysctl_debug_test_stackshot_owner_grp
);
3379 /* This is a sysctl for testing collection of owner info on a lock in kernel space. A multi-threaded
3380 * test from userland sets this sysctl in such a way that a thread blocks in kernel mode, and a
3381 * stackshot is taken to see if the owner of the lock can be identified.
3383 * We can't return to userland with a kernel lock held, so be sure to unlock before we leave.
3384 * the semaphores allow us to artificially create cases where the lock is being held and the
3385 * thread is hanging / taking a long time to do something. */
3387 volatile char sysctl_debug_test_stackshot_mtx_inited
= 0;
3388 semaphore_t sysctl_debug_test_stackshot_mutex_sem
;
3389 lck_mtx_t sysctl_debug_test_stackshot_owner_lck
;
3391 #define SYSCTL_DEBUG_MTX_ACQUIRE_WAIT 1
3392 #define SYSCTL_DEBUG_MTX_ACQUIRE_NOWAIT 2
3393 #define SYSCTL_DEBUG_MTX_SIGNAL 3
3394 #define SYSCTL_DEBUG_MTX_TEARDOWN 4
3397 sysctl_debug_test_stackshot_mutex_owner(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3399 long long option
= -1;
3400 /* if the user tries to read the sysctl, we tell them what the address of the lock is (to test against stackshot's output) */
3401 long long mtx_unslid_addr
= (long long)VM_KERNEL_UNSLIDE_OR_PERM(&sysctl_debug_test_stackshot_owner_lck
);
3402 int error
= sysctl_io_number(req
, mtx_unslid_addr
, sizeof(long long), (void*)&option
, NULL
);
3404 lck_mtx_lock(&sysctl_debug_test_stackshot_owner_init_mtx
);
3405 if (!sysctl_debug_test_stackshot_mtx_inited
) {
3406 lck_mtx_init(&sysctl_debug_test_stackshot_owner_lck
,
3407 &sysctl_debug_test_stackshot_owner_grp
,
3409 semaphore_create(kernel_task
,
3410 &sysctl_debug_test_stackshot_mutex_sem
,
3411 SYNC_POLICY_FIFO
, 0);
3412 sysctl_debug_test_stackshot_mtx_inited
= 1;
3414 lck_mtx_unlock(&sysctl_debug_test_stackshot_owner_init_mtx
);
3418 case SYSCTL_DEBUG_MTX_ACQUIRE_NOWAIT
:
3419 lck_mtx_lock(&sysctl_debug_test_stackshot_owner_lck
);
3420 lck_mtx_unlock(&sysctl_debug_test_stackshot_owner_lck
);
3422 case SYSCTL_DEBUG_MTX_ACQUIRE_WAIT
:
3423 lck_mtx_lock(&sysctl_debug_test_stackshot_owner_lck
);
3424 semaphore_wait(sysctl_debug_test_stackshot_mutex_sem
);
3425 lck_mtx_unlock(&sysctl_debug_test_stackshot_owner_lck
);
3427 case SYSCTL_DEBUG_MTX_SIGNAL
:
3428 semaphore_signal(sysctl_debug_test_stackshot_mutex_sem
);
3430 case SYSCTL_DEBUG_MTX_TEARDOWN
:
3431 lck_mtx_lock(&sysctl_debug_test_stackshot_owner_init_mtx
);
3433 lck_mtx_destroy(&sysctl_debug_test_stackshot_owner_lck
,
3434 &sysctl_debug_test_stackshot_owner_grp
);
3435 semaphore_destroy(kernel_task
,
3436 sysctl_debug_test_stackshot_mutex_sem
);
3437 sysctl_debug_test_stackshot_mtx_inited
= 0;
3439 lck_mtx_unlock(&sysctl_debug_test_stackshot_owner_init_mtx
);
3441 case -1: /* user just wanted to read the value, so do nothing */
3451 /* we can't return to userland with a kernel rwlock held, so be sure to unlock before we leave.
3452 * the semaphores allow us to artificially create cases where the lock is being held and the
3453 * thread is hanging / taking a long time to do something. */
3458 CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3461 sysctl_debug_test_stackshot_mutex_owner
,
3463 "Testing mutex owner in kernel");
3465 volatile char sysctl_debug_test_stackshot_rwlck_inited
= 0;
3466 lck_rw_t sysctl_debug_test_stackshot_owner_rwlck
;
3467 semaphore_t sysctl_debug_test_stackshot_rwlck_sem
;
3469 #define SYSCTL_DEBUG_KRWLCK_RACQUIRE_NOWAIT 1
3470 #define SYSCTL_DEBUG_KRWLCK_RACQUIRE_WAIT 2
3471 #define SYSCTL_DEBUG_KRWLCK_WACQUIRE_NOWAIT 3
3472 #define SYSCTL_DEBUG_KRWLCK_WACQUIRE_WAIT 4
3473 #define SYSCTL_DEBUG_KRWLCK_SIGNAL 5
3474 #define SYSCTL_DEBUG_KRWLCK_TEARDOWN 6
3477 sysctl_debug_test_stackshot_rwlck_owner(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3479 long long option
= -1;
3480 /* if the user tries to read the sysctl, we tell them what the address of the lock is
3481 * (to test against stackshot's output) */
3482 long long rwlck_unslid_addr
= (long long)VM_KERNEL_UNSLIDE_OR_PERM(&sysctl_debug_test_stackshot_owner_rwlck
);
3483 int error
= sysctl_io_number(req
, rwlck_unslid_addr
, sizeof(long long), (void*)&option
, NULL
);
3485 lck_mtx_lock(&sysctl_debug_test_stackshot_owner_init_mtx
);
3486 if (!sysctl_debug_test_stackshot_rwlck_inited
) {
3487 lck_rw_init(&sysctl_debug_test_stackshot_owner_rwlck
,
3488 &sysctl_debug_test_stackshot_owner_grp
,
3490 semaphore_create(kernel_task
,
3491 &sysctl_debug_test_stackshot_rwlck_sem
,
3494 sysctl_debug_test_stackshot_rwlck_inited
= 1;
3496 lck_mtx_unlock(&sysctl_debug_test_stackshot_owner_init_mtx
);
3500 case SYSCTL_DEBUG_KRWLCK_RACQUIRE_NOWAIT
:
3501 lck_rw_lock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_SHARED
);
3502 lck_rw_unlock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_SHARED
);
3504 case SYSCTL_DEBUG_KRWLCK_RACQUIRE_WAIT
:
3505 lck_rw_lock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_SHARED
);
3506 semaphore_wait(sysctl_debug_test_stackshot_rwlck_sem
);
3507 lck_rw_unlock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_SHARED
);
3509 case SYSCTL_DEBUG_KRWLCK_WACQUIRE_NOWAIT
:
3510 lck_rw_lock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_EXCLUSIVE
);
3511 lck_rw_unlock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_EXCLUSIVE
);
3513 case SYSCTL_DEBUG_KRWLCK_WACQUIRE_WAIT
:
3514 lck_rw_lock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_EXCLUSIVE
);
3515 semaphore_wait(sysctl_debug_test_stackshot_rwlck_sem
);
3516 lck_rw_unlock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_EXCLUSIVE
);
3518 case SYSCTL_DEBUG_KRWLCK_SIGNAL
:
3519 semaphore_signal(sysctl_debug_test_stackshot_rwlck_sem
);
3521 case SYSCTL_DEBUG_KRWLCK_TEARDOWN
:
3522 lck_mtx_lock(&sysctl_debug_test_stackshot_owner_init_mtx
);
3524 lck_rw_destroy(&sysctl_debug_test_stackshot_owner_rwlck
,
3525 &sysctl_debug_test_stackshot_owner_grp
);
3526 semaphore_destroy(kernel_task
,
3527 sysctl_debug_test_stackshot_rwlck_sem
);
3528 sysctl_debug_test_stackshot_rwlck_inited
= 0;
3530 lck_mtx_unlock(&sysctl_debug_test_stackshot_owner_init_mtx
);
3532 case -1: /* user just wanted to read the value, so do nothing */
3545 test_RWLockOwnerCtl
,
3546 CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3549 sysctl_debug_test_stackshot_rwlck_owner
,
3551 "Testing rwlock owner in kernel");
3552 #endif /* !CONFIG_XNUPOST */
3556 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3559 uint64_t swap_total
;
3560 uint64_t swap_avail
;
3561 vm_size_t swap_pagesize
;
3562 boolean_t swap_encrypted
;
3563 struct xsw_usage xsu
= {};
3565 error
= macx_swapinfo(&swap_total
,
3573 xsu
.xsu_total
= swap_total
;
3574 xsu
.xsu_avail
= swap_avail
;
3575 xsu
.xsu_used
= swap_total
- swap_avail
;
3576 xsu
.xsu_pagesize
= (u_int32_t
)MIN(swap_pagesize
, UINT32_MAX
);
3577 xsu
.xsu_encrypted
= swap_encrypted
;
3578 return sysctl_io_opaque(req
, &xsu
, sizeof(xsu
), NULL
);
3583 SYSCTL_PROC(_vm
, VM_SWAPUSAGE
, swapusage
,
3584 CTLTYPE_STRUCT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3585 0, 0, sysctl_swapusage
, "S,xsw_usage", "");
3588 extern void vm_page_reactivate_all_throttled(void);
3589 extern void memorystatus_disable_freeze(void);
3592 sysctl_freeze_enabled SYSCTL_HANDLER_ARGS
3594 #pragma unused(arg1, arg2)
3595 int error
, val
= memorystatus_freeze_enabled
? 1 : 0;
3598 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
3599 if (error
|| !req
->newptr
) {
3603 if (!VM_CONFIG_FREEZER_SWAP_IS_ACTIVE
) {
3604 //assert(req->newptr);
3605 printf("Failed attempt to set vm.freeze_enabled sysctl\n");
3610 * If freeze is being disabled, we need to move dirty pages out from the throttle to the active queue.
3612 disabled
= (!val
&& memorystatus_freeze_enabled
);
3614 memorystatus_freeze_enabled
= val
? TRUE
: FALSE
;
3617 vm_page_reactivate_all_throttled();
3618 memorystatus_disable_freeze();
3624 SYSCTL_PROC(_vm
, OID_AUTO
, freeze_enabled
, CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_ANYBODY
, &memorystatus_freeze_enabled
, 0, sysctl_freeze_enabled
, "I", "");
3625 #endif /* CONFIG_FREEZE */
3627 #if DEVELOPMENT || DEBUG
3628 extern int vm_num_swap_files_config
;
3629 extern int vm_num_swap_files
;
3630 extern lck_mtx_t vm_swap_data_lock
;
3631 #define VM_MAX_SWAP_FILE_NUM 100
3634 sysctl_vm_config_num_swap_files SYSCTL_HANDLER_ARGS
3636 #pragma unused(arg1, arg2)
3637 int error
= 0, val
= vm_num_swap_files_config
;
3639 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
3640 if (error
|| !req
->newptr
) {
3644 if (!VM_CONFIG_SWAP_IS_ACTIVE
&& !VM_CONFIG_FREEZER_SWAP_IS_ACTIVE
) {
3645 printf("Swap is disabled\n");
3650 lck_mtx_lock(&vm_swap_data_lock
);
3652 if (val
< vm_num_swap_files
) {
3653 printf("Cannot configure fewer swap files than already exist.\n");
3655 lck_mtx_unlock(&vm_swap_data_lock
);
3659 if (val
> VM_MAX_SWAP_FILE_NUM
) {
3660 printf("Capping number of swap files to upper bound.\n");
3661 val
= VM_MAX_SWAP_FILE_NUM
;
3664 vm_num_swap_files_config
= val
;
3665 lck_mtx_unlock(&vm_swap_data_lock
);
3671 SYSCTL_PROC(_debug
, OID_AUTO
, num_swap_files_configured
, CTLFLAG_ANYBODY
| CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, 0, sysctl_vm_config_num_swap_files
, "I", "");
3672 #endif /* DEVELOPMENT || DEBUG */
3674 /* this kernel does NOT implement shared_region_make_private_np() */
3675 SYSCTL_INT(_kern
, KERN_SHREG_PRIVATIZABLE
, shreg_private
,
3676 CTLFLAG_RD
| CTLFLAG_LOCKED
,
3677 (int *)NULL
, 0, "");
3680 fetch_process_cputype(
3684 cpu_type_t
*cputype
)
3686 proc_t p
= PROC_NULL
;
3693 } else if (namelen
== 1) {
3694 p
= proc_find(name
[0]);
3704 ret
= cpu_type() & ~CPU_ARCH_MASK
;
3705 if (IS_64BIT_PROCESS(p
)) {
3706 ret
|= CPU_ARCH_ABI64
;
3720 sysctl_sysctl_native(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
,
3721 struct sysctl_req
*req
)
3724 cpu_type_t proc_cputype
= 0;
3725 if ((error
= fetch_process_cputype(req
->p
, (int *)arg1
, arg2
, &proc_cputype
)) != 0) {
3729 if ((proc_cputype
& ~CPU_ARCH_MASK
) != (cpu_type() & ~CPU_ARCH_MASK
)) {
3732 return SYSCTL_OUT(req
, &res
, sizeof(res
));
3734 SYSCTL_PROC(_sysctl
, OID_AUTO
, proc_native
, CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
, 0, 0, sysctl_sysctl_native
, "I", "proc_native");
3737 sysctl_sysctl_cputype(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
,
3738 struct sysctl_req
*req
)
3741 cpu_type_t proc_cputype
= 0;
3742 if ((error
= fetch_process_cputype(req
->p
, (int *)arg1
, arg2
, &proc_cputype
)) != 0) {
3745 return SYSCTL_OUT(req
, &proc_cputype
, sizeof(proc_cputype
));
3747 SYSCTL_PROC(_sysctl
, OID_AUTO
, proc_cputype
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
, 0, 0, sysctl_sysctl_cputype
, "I", "proc_cputype");
3751 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3753 return sysctl_io_number(req
, boothowto
& RB_SAFEBOOT
? 1 : 0, sizeof(int), NULL
, NULL
);
3756 SYSCTL_PROC(_kern
, KERN_SAFEBOOT
, safeboot
,
3757 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3758 0, 0, sysctl_safeboot
, "I", "");
3762 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3764 return sysctl_io_number(req
, boothowto
& RB_SINGLE
? 1 : 0, sizeof(int), NULL
, NULL
);
3767 SYSCTL_PROC(_kern
, OID_AUTO
, singleuser
,
3768 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3769 0, 0, sysctl_singleuser
, "I", "");
3773 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3775 return sysctl_io_number(req
, minimalboot
, sizeof(int), NULL
, NULL
);
3778 SYSCTL_PROC(_kern
, OID_AUTO
, minimalboot
,
3779 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3780 0, 0, sysctl_minimalboot
, "I", "");
3783 * Controls for debugging affinity sets - see osfmk/kern/affinity.c
3785 extern boolean_t affinity_sets_enabled
;
3786 extern int affinity_sets_mapping
;
3788 SYSCTL_INT(_kern
, OID_AUTO
, affinity_sets_enabled
,
3789 CTLFLAG_RW
| CTLFLAG_LOCKED
, (int *) &affinity_sets_enabled
, 0, "hinting enabled");
3790 SYSCTL_INT(_kern
, OID_AUTO
, affinity_sets_mapping
,
3791 CTLFLAG_RW
| CTLFLAG_LOCKED
, &affinity_sets_mapping
, 0, "mapping policy");
3794 * Boolean indicating if KASLR is active.
3798 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3802 slide
= vm_kernel_slide
? 1 : 0;
3804 return sysctl_io_number( req
, slide
, sizeof(int), NULL
, NULL
);
3807 SYSCTL_PROC(_kern
, OID_AUTO
, slide
,
3808 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3809 0, 0, sysctl_slide
, "I", "");
3811 /* User address of the PFZ */
3812 #if DEBUG || DEVELOPMENT
3813 extern user32_addr_t commpage_text32_location
;
3814 extern user64_addr_t commpage_text64_location
;
3817 sysctl_pfz_start SYSCTL_HANDLER_ARGS
3819 #pragma unused(oidp, arg1, arg2)
3822 return sysctl_io_number(req
, commpage_text64_location
, sizeof(user64_addr_t
), NULL
, NULL
);
3824 return sysctl_io_number(req
, commpage_text32_location
, sizeof(user32_addr_t
), NULL
, NULL
);
3828 SYSCTL_PROC(_kern
, OID_AUTO
, pfz
,
3829 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
,
3830 0, 0, sysctl_pfz_start
, "I", "");
3835 * Limit on total memory users can wire.
3837 * vm_global_user_wire_limit - system wide limit on wired memory from all processes combined.
3839 * vm_per_task_user_wire_limit - per address space limit on wired memory. This puts a cap on the process's rlimit value.
3841 * These values are initialized to reasonable defaults at boot time based on the available physical memory in
3844 * All values are in bytes.
3847 vm_map_size_t vm_global_user_wire_limit
;
3848 vm_map_size_t vm_per_task_user_wire_limit
;
3849 extern uint64_t max_mem_actual
, max_mem
;
3851 uint64_t vm_add_wire_count_over_global_limit
;
3852 uint64_t vm_add_wire_count_over_user_limit
;
3854 * We used to have a global in the kernel called vm_global_no_user_wire_limit which was the inverse
3855 * of vm_global_user_wire_limit. But maintaining both of those is silly, and vm_global_user_wire_limit is the
3857 * This function is for backwards compatibility with userspace
3858 * since we exposed the old global via a sysctl.
3861 sysctl_global_no_user_wire_amount(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3863 vm_map_size_t old_value
;
3864 vm_map_size_t new_value
;
3867 uint64_t config_memsize
= max_mem
;
3868 #if defined(XNU_TARGET_OS_OSX)
3869 config_memsize
= max_mem_actual
;
3870 #endif /* defined(XNU_TARGET_OS_OSX) */
3872 old_value
= (vm_map_size_t
)(config_memsize
- vm_global_user_wire_limit
);
3873 error
= sysctl_io_number(req
, old_value
, sizeof(vm_map_size_t
), &new_value
, &changed
);
3875 if ((uint64_t)new_value
> config_memsize
) {
3878 vm_global_user_wire_limit
= (vm_map_size_t
)(config_memsize
- new_value
);
3884 * There needs to be a more automatic/elegant way to do this
3886 #if defined(__ARM__)
3887 SYSCTL_INT(_vm
, OID_AUTO
, global_user_wire_limit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_global_user_wire_limit
, 0, "");
3888 SYSCTL_INT(_vm
, OID_AUTO
, user_wire_limit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_per_task_user_wire_limit
, 0, "");
3889 SYSCTL_PROC(_vm
, OID_AUTO
, global_no_user_wire_amount
, CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, 0, &sysctl_global_no_user_wire_amount
, "I", "");
3891 SYSCTL_QUAD(_vm
, OID_AUTO
, global_user_wire_limit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_global_user_wire_limit
, "");
3892 SYSCTL_QUAD(_vm
, OID_AUTO
, user_wire_limit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_per_task_user_wire_limit
, "");
3893 SYSCTL_PROC(_vm
, OID_AUTO
, global_no_user_wire_amount
, CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, 0, &sysctl_global_no_user_wire_amount
, "Q", "");
3897 * Relaxed atomic RW of a 64bit value via sysctl.
3900 sysctl_r_64bit_atomic(uint64_t *ptr
, struct sysctl_req
*req
)
3906 old_value
= os_atomic_load_wide(ptr
, relaxed
);
3907 error
= sysctl_io_number(req
, old_value
, sizeof(vm_map_size_t
), &new_value
, NULL
);
3911 sysctl_add_wire_count_over_global_limit(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3913 return sysctl_r_64bit_atomic(&vm_add_wire_count_over_global_limit
, req
);
3916 sysctl_add_wire_count_over_user_limit(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3918 return sysctl_r_64bit_atomic(&vm_add_wire_count_over_user_limit
, req
);
3921 SYSCTL_PROC(_vm
, OID_AUTO
, add_wire_count_over_global_limit
, CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
, 0, 0, &sysctl_add_wire_count_over_global_limit
, "Q", "");
3922 SYSCTL_PROC(_vm
, OID_AUTO
, add_wire_count_over_user_limit
, CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
, 0, 0, &sysctl_add_wire_count_over_user_limit
, "Q", "");
3924 #if DEVELOPMENT || DEBUG
3925 /* These sysctls are used to test the wired limit. */
3926 extern unsigned int vm_page_wire_count
;
3927 extern uint32_t vm_lopage_free_count
;
3928 SYSCTL_INT(_vm
, OID_AUTO
, page_wire_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_wire_count
, 0, "");
3929 SYSCTL_INT(_vm
, OID_AUTO
, lopage_free_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_lopage_free_count
, 0, "");
3930 #endif /* DEVELOPMENT */
3932 extern int vm_map_copy_overwrite_aligned_src_not_internal
;
3933 extern int vm_map_copy_overwrite_aligned_src_not_symmetric
;
3934 extern int vm_map_copy_overwrite_aligned_src_large
;
3935 SYSCTL_INT(_vm
, OID_AUTO
, vm_copy_src_not_internal
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_map_copy_overwrite_aligned_src_not_internal
, 0, "");
3936 SYSCTL_INT(_vm
, OID_AUTO
, vm_copy_src_not_symmetric
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_map_copy_overwrite_aligned_src_not_symmetric
, 0, "");
3937 SYSCTL_INT(_vm
, OID_AUTO
, vm_copy_src_large
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_map_copy_overwrite_aligned_src_large
, 0, "");
3940 extern uint32_t vm_page_external_count
;
3942 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_external_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_external_count
, 0, "");
3944 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_filecache_min
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_state
.vm_page_filecache_min
, 0, "");
3945 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_xpmapped_min
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_state
.vm_page_xpmapped_min
, 0, "");
3947 #if DEVELOPMENT || DEBUG
3948 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_filecache_min_divisor
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_state
.vm_page_filecache_min_divisor
, 0, "");
3949 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_xpmapped_min_divisor
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_state
.vm_page_xpmapped_min_divisor
, 0, "");
3952 extern int vm_compressor_mode
;
3953 extern int vm_compressor_is_active
;
3954 extern int vm_compressor_available
;
3955 extern uint32_t vm_ripe_target_age
;
3956 extern uint32_t swapout_target_age
;
3957 extern int64_t compressor_bytes_used
;
3958 extern int64_t c_segment_input_bytes
;
3959 extern int64_t c_segment_compressed_bytes
;
3960 extern uint32_t compressor_eval_period_in_msecs
;
3961 extern uint32_t compressor_sample_min_in_msecs
;
3962 extern uint32_t compressor_sample_max_in_msecs
;
3963 extern uint32_t compressor_thrashing_threshold_per_10msecs
;
3964 extern uint32_t compressor_thrashing_min_per_10msecs
;
3965 extern uint32_t vm_compressor_time_thread
;
3967 #if DEVELOPMENT || DEBUG
3968 extern uint32_t vm_compressor_minorcompact_threshold_divisor
;
3969 extern uint32_t vm_compressor_majorcompact_threshold_divisor
;
3970 extern uint32_t vm_compressor_unthrottle_threshold_divisor
;
3971 extern uint32_t vm_compressor_catchup_threshold_divisor
;
3973 extern uint32_t vm_compressor_minorcompact_threshold_divisor_overridden
;
3974 extern uint32_t vm_compressor_majorcompact_threshold_divisor_overridden
;
3975 extern uint32_t vm_compressor_unthrottle_threshold_divisor_overridden
;
3976 extern uint32_t vm_compressor_catchup_threshold_divisor_overridden
;
3978 extern vmct_stats_t vmct_stats
;
3982 sysctl_minorcompact_threshold_divisor(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3984 int new_value
, changed
;
3985 int error
= sysctl_io_number(req
, vm_compressor_minorcompact_threshold_divisor
, sizeof(int), &new_value
, &changed
);
3988 vm_compressor_minorcompact_threshold_divisor
= new_value
;
3989 vm_compressor_minorcompact_threshold_divisor_overridden
= 1;
3994 SYSCTL_PROC(_vm
, OID_AUTO
, compressor_minorcompact_threshold_divisor
,
3995 CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
3996 0, 0, sysctl_minorcompact_threshold_divisor
, "I", "");
4000 sysctl_majorcompact_threshold_divisor(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4002 int new_value
, changed
;
4003 int error
= sysctl_io_number(req
, vm_compressor_majorcompact_threshold_divisor
, sizeof(int), &new_value
, &changed
);
4006 vm_compressor_majorcompact_threshold_divisor
= new_value
;
4007 vm_compressor_majorcompact_threshold_divisor_overridden
= 1;
4012 SYSCTL_PROC(_vm
, OID_AUTO
, compressor_majorcompact_threshold_divisor
,
4013 CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4014 0, 0, sysctl_majorcompact_threshold_divisor
, "I", "");
4018 sysctl_unthrottle_threshold_divisor(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4020 int new_value
, changed
;
4021 int error
= sysctl_io_number(req
, vm_compressor_unthrottle_threshold_divisor
, sizeof(int), &new_value
, &changed
);
4024 vm_compressor_unthrottle_threshold_divisor
= new_value
;
4025 vm_compressor_unthrottle_threshold_divisor_overridden
= 1;
4030 SYSCTL_PROC(_vm
, OID_AUTO
, compressor_unthrottle_threshold_divisor
,
4031 CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4032 0, 0, sysctl_unthrottle_threshold_divisor
, "I", "");
4036 sysctl_catchup_threshold_divisor(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4038 int new_value
, changed
;
4039 int error
= sysctl_io_number(req
, vm_compressor_catchup_threshold_divisor
, sizeof(int), &new_value
, &changed
);
4042 vm_compressor_catchup_threshold_divisor
= new_value
;
4043 vm_compressor_catchup_threshold_divisor_overridden
= 1;
4048 SYSCTL_PROC(_vm
, OID_AUTO
, compressor_catchup_threshold_divisor
,
4049 CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4050 0, 0, sysctl_catchup_threshold_divisor
, "I", "");
4054 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_input_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &c_segment_input_bytes
, "");
4055 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_compressed_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &c_segment_compressed_bytes
, "");
4056 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_bytes_used
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_bytes_used
, "");
4058 SYSCTL_INT(_vm
, OID_AUTO
, compressor_mode
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_compressor_mode
, 0, "");
4059 SYSCTL_INT(_vm
, OID_AUTO
, compressor_is_active
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_compressor_is_active
, 0, "");
4060 SYSCTL_INT(_vm
, OID_AUTO
, compressor_swapout_target_age
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &swapout_target_age
, 0, "");
4061 SYSCTL_INT(_vm
, OID_AUTO
, compressor_available
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_compressor_available
, 0, "");
4063 extern int min_csegs_per_major_compaction
;
4064 SYSCTL_INT(_vm
, OID_AUTO
, compressor_min_csegs_per_major_compaction
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &min_csegs_per_major_compaction
, 0, "");
4066 SYSCTL_INT(_vm
, OID_AUTO
, vm_ripe_target_age_in_secs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_ripe_target_age
, 0, "");
4068 SYSCTL_INT(_vm
, OID_AUTO
, compressor_eval_period_in_msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &compressor_eval_period_in_msecs
, 0, "");
4069 SYSCTL_INT(_vm
, OID_AUTO
, compressor_sample_min_in_msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &compressor_sample_min_in_msecs
, 0, "");
4070 SYSCTL_INT(_vm
, OID_AUTO
, compressor_sample_max_in_msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &compressor_sample_max_in_msecs
, 0, "");
4071 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thrashing_threshold_per_10msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &compressor_thrashing_threshold_per_10msecs
, 0, "");
4072 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thrashing_min_per_10msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &compressor_thrashing_min_per_10msecs
, 0, "");
4074 SYSCTL_STRING(_vm
, OID_AUTO
, swapfileprefix
, CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
, swapfilename
, sizeof(swapfilename
) - SWAPFILENAME_INDEX_LEN
, "");
4076 SYSCTL_INT(_vm
, OID_AUTO
, compressor_timing_enabled
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_compressor_time_thread
, 0, "");
4078 #if DEVELOPMENT || DEBUG
4079 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_runtime0
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_runtimes
[0], "");
4080 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_runtime1
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_runtimes
[1], "");
4082 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_threads_total
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_cthreads_total
, "");
4084 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_pages0
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_pages
[0], "");
4085 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_pages1
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_pages
[1], "");
4087 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_iterations0
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_iterations
[0], "");
4088 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_iterations1
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_iterations
[1], "");
4090 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thread_minpages0
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_minpages
[0], 0, "");
4091 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thread_minpages1
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_minpages
[1], 0, "");
4093 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thread_maxpages0
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_maxpages
[0], 0, "");
4094 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thread_maxpages1
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_maxpages
[1], 0, "");
4096 int vm_compressor_injected_error_count
;
4098 SYSCTL_INT(_vm
, OID_AUTO
, compressor_injected_error_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_compressor_injected_error_count
, 0, "");
4101 sysctl_compressor_inject_error(__unused
struct sysctl_oid
*oidp
,
4102 __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4105 vm_address_t va
= 0;
4108 result
= sysctl_io_number(req
, va
, sizeof(va
), &va
, &changed
);
4109 if (result
== 0 && changed
) {
4110 result
= vm_map_inject_error(current_map(), va
);
4113 * Count the number of errors injected successfully to detect
4114 * situations where corruption was caused by improper use of this
4117 os_atomic_inc(&vm_compressor_injected_error_count
, relaxed
);
4123 SYSCTL_PROC(_vm
, OID_AUTO
, compressor_inject_error
, CTLTYPE_QUAD
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4124 0, 0, sysctl_compressor_inject_error
, "Q", "flips a bit in a compressed page for the current task");
4128 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_compressions
, "");
4129 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_compression_failures
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_compression_failures
, "");
4130 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_compressed_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_compressed_bytes
, "");
4131 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_wk_compression_delta
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_wk_compression_delta
, "");
4132 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_wk_compression_negative_delta
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_wk_compression_negative_delta
, "");
4134 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_decompressions
, "");
4135 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_decompressed_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_decompressed_bytes
, "");
4137 SYSCTL_QUAD(_vm
, OID_AUTO
, uc_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.uc_decompressions
, "");
4139 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_compressions
, "");
4141 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_catime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_cabstime
, "");
4143 SYSCTL_QUAD(_vm
, OID_AUTO
, wkh_catime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wkh_cabstime
, "");
4144 SYSCTL_QUAD(_vm
, OID_AUTO
, wkh_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wkh_compressions
, "");
4146 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_catime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_cabstime
, "");
4147 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_compressions
, "");
4149 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_compressions_exclusive
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_compressions_exclusive
, "");
4150 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_sv_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_sv_compressions
, "");
4151 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_mzv_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_mzv_compressions
, "");
4152 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_compression_failures
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_compression_failures
, "");
4153 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_compressed_bytes_exclusive
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_compressed_bytes_exclusive
, "");
4154 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_compressed_bytes_total
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_compressed_bytes_total
, "");
4156 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_compressed_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_compressed_bytes
, "");
4157 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_compression_failures
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_compression_failures
, "");
4158 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_sv_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_sv_compressions
, "");
4161 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_decompressions
, "");
4163 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_datime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_dabstime
, "");
4165 SYSCTL_QUAD(_vm
, OID_AUTO
, wkh_datime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wkh_dabstime
, "");
4166 SYSCTL_QUAD(_vm
, OID_AUTO
, wkh_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wkh_decompressions
, "");
4168 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_datime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_dabstime
, "");
4169 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_decompressions
, "");
4171 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_decompressed_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_decompressed_bytes
, "");
4172 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_sv_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_sv_decompressions
, "");
4174 SYSCTL_INT(_vm
, OID_AUTO
, lz4_threshold
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_threshold
, 0, "");
4175 SYSCTL_INT(_vm
, OID_AUTO
, wkdm_reeval_threshold
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.wkdm_reeval_threshold
, 0, "");
4176 SYSCTL_INT(_vm
, OID_AUTO
, lz4_max_failure_skips
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_max_failure_skips
, 0, "");
4177 SYSCTL_INT(_vm
, OID_AUTO
, lz4_max_failure_run_length
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_max_failure_run_length
, 0, "");
4178 SYSCTL_INT(_vm
, OID_AUTO
, lz4_max_preselects
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_max_preselects
, 0, "");
4179 SYSCTL_INT(_vm
, OID_AUTO
, lz4_run_preselection_threshold
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_run_preselection_threshold
, 0, "");
4180 SYSCTL_INT(_vm
, OID_AUTO
, lz4_run_continue_bytes
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_run_continue_bytes
, 0, "");
4181 SYSCTL_INT(_vm
, OID_AUTO
, lz4_profitable_bytes
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_profitable_bytes
, 0, "");
4182 #if DEVELOPMENT || DEBUG
4183 extern int vm_compressor_current_codec
;
4184 extern int vm_compressor_test_seg_wp
;
4185 extern boolean_t vm_compressor_force_sw_wkdm
;
4186 SYSCTL_INT(_vm
, OID_AUTO
, compressor_codec
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_compressor_current_codec
, 0, "");
4187 SYSCTL_INT(_vm
, OID_AUTO
, compressor_test_wp
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_compressor_test_seg_wp
, 0, "");
4189 SYSCTL_INT(_vm
, OID_AUTO
, wksw_force
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_compressor_force_sw_wkdm
, 0, "");
4190 extern int precompy
, wkswhw
;
4192 SYSCTL_INT(_vm
, OID_AUTO
, precompy
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &precompy
, 0, "");
4193 SYSCTL_INT(_vm
, OID_AUTO
, wkswhw
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &wkswhw
, 0, "");
4194 extern unsigned int vm_ktrace_enabled
;
4195 SYSCTL_INT(_vm
, OID_AUTO
, vm_ktrace
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_ktrace_enabled
, 0, "");
4198 #if CONFIG_PHANTOM_CACHE
4199 extern uint32_t phantom_cache_thrashing_threshold
;
4200 extern uint32_t phantom_cache_eval_period_in_msecs
;
4201 extern uint32_t phantom_cache_thrashing_threshold_ssd
;
4204 SYSCTL_INT(_vm
, OID_AUTO
, phantom_cache_eval_period_in_msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &phantom_cache_eval_period_in_msecs
, 0, "");
4205 SYSCTL_INT(_vm
, OID_AUTO
, phantom_cache_thrashing_threshold
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &phantom_cache_thrashing_threshold
, 0, "");
4206 SYSCTL_INT(_vm
, OID_AUTO
, phantom_cache_thrashing_threshold_ssd
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &phantom_cache_thrashing_threshold_ssd
, 0, "");
4209 #if CONFIG_BACKGROUND_QUEUE
4211 extern uint32_t vm_page_background_count
;
4212 extern uint32_t vm_page_background_target
;
4213 extern uint32_t vm_page_background_internal_count
;
4214 extern uint32_t vm_page_background_external_count
;
4215 extern uint32_t vm_page_background_mode
;
4216 extern uint32_t vm_page_background_exclude_external
;
4217 extern uint64_t vm_page_background_promoted_count
;
4218 extern uint64_t vm_pageout_rejected_bq_internal
;
4219 extern uint64_t vm_pageout_rejected_bq_external
;
4221 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_mode
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_page_background_mode
, 0, "");
4222 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_exclude_external
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_page_background_exclude_external
, 0, "");
4223 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_target
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_page_background_target
, 0, "");
4224 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_background_count
, 0, "");
4225 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_internal_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_background_internal_count
, 0, "");
4226 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_external_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_background_external_count
, 0, "");
4228 SYSCTL_QUAD(_vm
, OID_AUTO
, vm_page_background_promoted_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_background_promoted_count
, "");
4229 SYSCTL_QUAD(_vm
, OID_AUTO
, vm_pageout_considered_bq_internal
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_vminfo
.vm_pageout_considered_bq_internal
, "");
4230 SYSCTL_QUAD(_vm
, OID_AUTO
, vm_pageout_considered_bq_external
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_vminfo
.vm_pageout_considered_bq_external
, "");
4231 SYSCTL_QUAD(_vm
, OID_AUTO
, vm_pageout_rejected_bq_internal
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_rejected_bq_internal
, "");
4232 SYSCTL_QUAD(_vm
, OID_AUTO
, vm_pageout_rejected_bq_external
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_rejected_bq_external
, "");
4234 #endif /* CONFIG_BACKGROUND_QUEUE */
4236 extern void vm_update_darkwake_mode(boolean_t
);
4237 extern boolean_t vm_darkwake_mode
;
4240 sysctl_toggle_darkwake_mode(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4242 int new_value
, changed
;
4243 int error
= sysctl_io_number(req
, vm_darkwake_mode
, sizeof(int), &new_value
, &changed
);
4245 if (!error
&& changed
) {
4246 if (new_value
!= 0 && new_value
!= 1) {
4247 printf("Error: Invalid value passed to darkwake sysctl. Acceptable: 0 or 1.\n");
4250 vm_update_darkwake_mode((boolean_t
) new_value
);
4257 SYSCTL_PROC(_vm
, OID_AUTO
, darkwake_mode
,
4258 CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4259 0, 0, sysctl_toggle_darkwake_mode
, "I", "");
4261 #if (DEVELOPMENT || DEBUG)
4263 SYSCTL_UINT(_vm
, OID_AUTO
, vm_page_creation_throttled_hard
,
4264 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4265 &vm_page_creation_throttled_hard
, 0, "");
4267 SYSCTL_UINT(_vm
, OID_AUTO
, vm_page_creation_throttled_soft
,
4268 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4269 &vm_page_creation_throttled_soft
, 0, "");
4271 extern uint32_t vm_pageout_memorystatus_fb_factor_nr
;
4272 extern uint32_t vm_pageout_memorystatus_fb_factor_dr
;
4273 SYSCTL_INT(_vm
, OID_AUTO
, vm_pageout_memorystatus_fb_factor_nr
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_memorystatus_fb_factor_nr
, 0, "");
4274 SYSCTL_INT(_vm
, OID_AUTO
, vm_pageout_memorystatus_fb_factor_dr
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_memorystatus_fb_factor_dr
, 0, "");
4276 extern uint32_t vm_grab_anon_nops
;
4278 SYSCTL_INT(_vm
, OID_AUTO
, vm_grab_anon_overrides
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_debug
.vm_grab_anon_overrides
, 0, "");
4279 SYSCTL_INT(_vm
, OID_AUTO
, vm_grab_anon_nops
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_debug
.vm_grab_anon_nops
, 0, "");
4281 extern int vm_page_delayed_work_ctx_needed
;
4282 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_needed_delayed_work_ctx
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_delayed_work_ctx_needed
, 0, "");
4284 /* log message counters for persistence mode */
4285 SCALABLE_COUNTER_DECLARE(oslog_p_total_msgcount
);
4286 SCALABLE_COUNTER_DECLARE(oslog_p_metadata_saved_msgcount
);
4287 SCALABLE_COUNTER_DECLARE(oslog_p_metadata_dropped_msgcount
);
4288 SCALABLE_COUNTER_DECLARE(oslog_p_error_count
);
4289 SCALABLE_COUNTER_DECLARE(oslog_p_saved_msgcount
);
4290 SCALABLE_COUNTER_DECLARE(oslog_p_dropped_msgcount
);
4291 SCALABLE_COUNTER_DECLARE(oslog_p_boot_dropped_msgcount
);
4292 SCALABLE_COUNTER_DECLARE(oslog_p_coprocessor_total_msgcount
);
4293 SCALABLE_COUNTER_DECLARE(oslog_p_coprocessor_dropped_msgcount
);
4294 SCALABLE_COUNTER_DECLARE(oslog_p_unresolved_kc_msgcount
);
4295 SCALABLE_COUNTER_DECLARE(oslog_p_fmt_invalid_msgcount
);
4296 SCALABLE_COUNTER_DECLARE(oslog_p_fmt_max_args_msgcount
);
4297 SCALABLE_COUNTER_DECLARE(oslog_p_truncated_msgcount
);
4299 /* log message counters for streaming mode */
4300 extern uint32_t oslog_s_total_msgcount
;
4301 extern uint32_t oslog_s_metadata_msgcount
;
4302 SCALABLE_COUNTER_DECLARE(oslog_s_error_count
);
4303 extern uint32_t oslog_s_streamed_msgcount
;
4304 extern uint32_t oslog_s_dropped_msgcount
;
4306 /* log message counters for msgbuf logging */
4307 extern uint32_t oslog_msgbuf_msgcount
;
4308 extern uint32_t oslog_msgbuf_dropped_msgcount
;
4309 extern uint32_t oslog_msgbuf_dropped_charcount
;
4311 /* log message counters for vaddlog logging */
4312 extern uint32_t vaddlog_msgcount
;
4313 extern uint32_t vaddlog_msgcount_dropped
;
4315 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_total_msgcount
, oslog_p_total_msgcount
, "");
4316 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_metadata_saved_msgcount
, oslog_p_metadata_saved_msgcount
, "");
4317 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_metadata_dropped_msgcount
, oslog_p_metadata_dropped_msgcount
, "");
4318 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_error_count
, oslog_p_error_count
, "");
4319 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_saved_msgcount
, oslog_p_saved_msgcount
, "");
4320 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_dropped_msgcount
, oslog_p_dropped_msgcount
, "");
4321 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_boot_dropped_msgcount
, oslog_p_boot_dropped_msgcount
, "");
4322 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_coprocessor_total_msgcount
, oslog_p_coprocessor_total_msgcount
, "");
4323 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_coprocessor_dropped_msgcount
, oslog_p_coprocessor_dropped_msgcount
, "");
4324 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_unresolved_kc_msgcount
, oslog_p_unresolved_kc_msgcount
, "");
4326 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_fmt_invalid_msgcount
, oslog_p_fmt_invalid_msgcount
, "");
4327 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_fmt_max_args_msgcount
, oslog_p_fmt_max_args_msgcount
, "");
4328 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_p_truncated_msgcount
, oslog_p_truncated_msgcount
, "");
4330 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_s_total_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_s_total_msgcount
, 0, "");
4331 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_s_metadata_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_s_metadata_msgcount
, 0, "");
4332 SYSCTL_SCALABLE_COUNTER(_debug
, oslog_s_error_count
, oslog_s_error_count
, "");
4333 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_s_streamed_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_s_streamed_msgcount
, 0, "");
4334 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_s_dropped_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_s_dropped_msgcount
, 0, "");
4336 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_msgbuf_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_msgbuf_msgcount
, 0, "");
4337 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_msgbuf_dropped_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_msgbuf_dropped_msgcount
, 0, "");
4338 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_msgbuf_dropped_charcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_msgbuf_dropped_charcount
, 0, "");
4340 SYSCTL_UINT(_debug
, OID_AUTO
, vaddlog_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &vaddlog_msgcount
, 0, "");
4341 SYSCTL_UINT(_debug
, OID_AUTO
, vaddlog_msgcount_dropped
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &vaddlog_msgcount_dropped
, 0, "");
4343 #endif /* DEVELOPMENT || DEBUG */
4346 * Enable tracing of voucher contents
4348 extern uint32_t ipc_voucher_trace_contents
;
4350 SYSCTL_INT(_kern
, OID_AUTO
, ipc_voucher_trace_contents
,
4351 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ipc_voucher_trace_contents
, 0, "Enable tracing voucher contents");
4354 * Kernel stack size and depth
4356 SYSCTL_INT(_kern
, OID_AUTO
, stack_size
,
4357 CTLFLAG_RD
| CTLFLAG_LOCKED
, (int *) &kernel_stack_size
, 0, "Kernel stack size");
4358 SYSCTL_INT(_kern
, OID_AUTO
, stack_depth_max
,
4359 CTLFLAG_RD
| CTLFLAG_LOCKED
, (int *) &kernel_stack_depth_max
, 0, "Max kernel stack depth at interrupt or context switch");
4361 extern unsigned int kern_feature_overrides
;
4362 SYSCTL_INT(_kern
, OID_AUTO
, kern_feature_overrides
,
4363 CTLFLAG_RD
| CTLFLAG_LOCKED
, &kern_feature_overrides
, 0, "Kernel feature override mask");
4366 * enable back trace for port allocations
4368 extern int ipc_portbt
;
4370 SYSCTL_INT(_kern
, OID_AUTO
, ipc_portbt
,
4371 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4372 &ipc_portbt
, 0, "");
4375 * Mach message signature validation control and outputs
4377 extern unsigned int ikm_signature_failures
;
4378 SYSCTL_INT(_kern
, OID_AUTO
, ikm_signature_failures
,
4379 CTLFLAG_RD
| CTLFLAG_LOCKED
, &ikm_signature_failures
, 0, "Message signature failure count");
4380 extern unsigned int ikm_signature_failure_id
;
4381 SYSCTL_INT(_kern
, OID_AUTO
, ikm_signature_failure_id
,
4382 CTLFLAG_RD
| CTLFLAG_LOCKED
, &ikm_signature_failure_id
, 0, "Message signature failure count");
4384 #if (DEVELOPMENT || DEBUG)
4385 extern unsigned int ikm_signature_panic_disable
;
4386 SYSCTL_INT(_kern
, OID_AUTO
, ikm_signature_panic_disable
,
4387 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ikm_signature_panic_disable
, 0, "Message signature failure mode");
4388 extern unsigned int ikm_signature_header_failures
;
4389 SYSCTL_INT(_kern
, OID_AUTO
, ikm_signature_header_failures
,
4390 CTLFLAG_RD
| CTLFLAG_LOCKED
, &ikm_signature_header_failures
, 0, "Message header signature failure count");
4391 extern unsigned int ikm_signature_trailer_failures
;
4392 SYSCTL_INT(_kern
, OID_AUTO
, ikm_signature_trailer_failures
,
4393 CTLFLAG_RD
| CTLFLAG_LOCKED
, &ikm_signature_trailer_failures
, 0, "Message trailer signature failure count");
4400 SYSCTL_STRING(_kern
, OID_AUTO
, sched
,
4401 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4402 sched_string
, sizeof(sched_string
),
4403 "Timeshare scheduler implementation");
4405 #if CONFIG_QUIESCE_COUNTER
4407 sysctl_cpu_quiescent_counter_interval SYSCTL_HANDLER_ARGS
4409 #pragma unused(arg1, arg2)
4411 uint32_t local_min_interval_us
= cpu_quiescent_counter_get_min_interval_us();
4413 int error
= sysctl_handle_int(oidp
, &local_min_interval_us
, 0, req
);
4414 if (error
|| !req
->newptr
) {
4418 cpu_quiescent_counter_set_min_interval_us(local_min_interval_us
);
4423 SYSCTL_PROC(_kern
, OID_AUTO
, cpu_checkin_interval
,
4424 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4426 sysctl_cpu_quiescent_counter_interval
, "I",
4427 "Quiescent CPU checkin interval (microseconds)");
4428 #endif /* CONFIG_QUIESCE_COUNTER */
4432 * Only support runtime modification on development / debug
4434 #if DEVELOPMENT || DEBUG
4435 extern int precise_user_kernel_time
;
4436 SYSCTL_INT(_kern
, OID_AUTO
, precise_user_kernel_time
,
4437 CTLFLAG_RW
| CTLFLAG_LOCKED
,
4438 &precise_user_kernel_time
, 0, "Precise accounting of kernel vs. user time");
4439 #endif /* DEVELOPMENT || DEBUG */
4441 /* Parameters related to timer coalescing tuning, to be replaced
4442 * with a dedicated systemcall in the future.
4444 /* Enable processing pending timers in the context of any other interrupt
4445 * Coalescing tuning parameters for various thread/task attributes */
4447 sysctl_timer_user_us_kernel_abstime SYSCTL_HANDLER_ARGS
4449 #pragma unused(oidp)
4450 int size
= arg2
; /* subcommand*/
4453 uint64_t old_value_ns
;
4454 uint64_t new_value_ns
;
4455 uint64_t value_abstime
;
4456 if (size
== sizeof(uint32_t)) {
4457 value_abstime
= *((uint32_t *)arg1
);
4458 } else if (size
== sizeof(uint64_t)) {
4459 value_abstime
= *((uint64_t *)arg1
);
4464 absolutetime_to_nanoseconds(value_abstime
, &old_value_ns
);
4465 error
= sysctl_io_number(req
, old_value_ns
, sizeof(old_value_ns
), &new_value_ns
, &changed
);
4466 if ((error
) || (!changed
)) {
4470 nanoseconds_to_absolutetime(new_value_ns
, &value_abstime
);
4471 if (size
== sizeof(uint32_t)) {
4472 *((uint32_t *)arg1
) = (uint32_t)value_abstime
;
4474 *((uint64_t *)arg1
) = value_abstime
;
4479 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_bg_scale
,
4480 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4481 &tcoal_prio_params
.timer_coalesce_bg_shift
, 0, "");
4482 SYSCTL_PROC(_kern
, OID_AUTO
, timer_resort_threshold_ns
,
4483 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4484 &tcoal_prio_params
.timer_resort_threshold_abstime
,
4485 sizeof(tcoal_prio_params
.timer_resort_threshold_abstime
),
4486 sysctl_timer_user_us_kernel_abstime
,
4488 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_bg_ns_max
,
4489 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4490 &tcoal_prio_params
.timer_coalesce_bg_abstime_max
,
4491 sizeof(tcoal_prio_params
.timer_coalesce_bg_abstime_max
),
4492 sysctl_timer_user_us_kernel_abstime
,
4495 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_kt_scale
,
4496 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4497 &tcoal_prio_params
.timer_coalesce_kt_shift
, 0, "");
4499 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_kt_ns_max
,
4500 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4501 &tcoal_prio_params
.timer_coalesce_kt_abstime_max
,
4502 sizeof(tcoal_prio_params
.timer_coalesce_kt_abstime_max
),
4503 sysctl_timer_user_us_kernel_abstime
,
4506 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_fp_scale
,
4507 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4508 &tcoal_prio_params
.timer_coalesce_fp_shift
, 0, "");
4510 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_fp_ns_max
,
4511 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4512 &tcoal_prio_params
.timer_coalesce_fp_abstime_max
,
4513 sizeof(tcoal_prio_params
.timer_coalesce_fp_abstime_max
),
4514 sysctl_timer_user_us_kernel_abstime
,
4517 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_ts_scale
,
4518 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4519 &tcoal_prio_params
.timer_coalesce_ts_shift
, 0, "");
4521 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_ts_ns_max
,
4522 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4523 &tcoal_prio_params
.timer_coalesce_ts_abstime_max
,
4524 sizeof(tcoal_prio_params
.timer_coalesce_ts_abstime_max
),
4525 sysctl_timer_user_us_kernel_abstime
,
4528 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier0_scale
,
4529 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4530 &tcoal_prio_params
.latency_qos_scale
[0], 0, "");
4532 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier0_ns_max
,
4533 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4534 &tcoal_prio_params
.latency_qos_abstime_max
[0],
4535 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[0]),
4536 sysctl_timer_user_us_kernel_abstime
,
4539 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier1_scale
,
4540 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4541 &tcoal_prio_params
.latency_qos_scale
[1], 0, "");
4543 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier1_ns_max
,
4544 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4545 &tcoal_prio_params
.latency_qos_abstime_max
[1],
4546 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[1]),
4547 sysctl_timer_user_us_kernel_abstime
,
4550 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier2_scale
,
4551 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4552 &tcoal_prio_params
.latency_qos_scale
[2], 0, "");
4554 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier2_ns_max
,
4555 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4556 &tcoal_prio_params
.latency_qos_abstime_max
[2],
4557 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[2]),
4558 sysctl_timer_user_us_kernel_abstime
,
4561 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier3_scale
,
4562 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4563 &tcoal_prio_params
.latency_qos_scale
[3], 0, "");
4565 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier3_ns_max
,
4566 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4567 &tcoal_prio_params
.latency_qos_abstime_max
[3],
4568 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[3]),
4569 sysctl_timer_user_us_kernel_abstime
,
4572 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier4_scale
,
4573 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4574 &tcoal_prio_params
.latency_qos_scale
[4], 0, "");
4576 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier4_ns_max
,
4577 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4578 &tcoal_prio_params
.latency_qos_abstime_max
[4],
4579 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[4]),
4580 sysctl_timer_user_us_kernel_abstime
,
4583 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier5_scale
,
4584 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4585 &tcoal_prio_params
.latency_qos_scale
[5], 0, "");
4587 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier5_ns_max
,
4588 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4589 &tcoal_prio_params
.latency_qos_abstime_max
[5],
4590 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[5]),
4591 sysctl_timer_user_us_kernel_abstime
,
4594 /* Communicate the "user idle level" heuristic to the timer layer, and
4595 * potentially other layers in the future.
4599 timer_user_idle_level(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4601 int new_value
= 0, old_value
= 0, changed
= 0, error
;
4603 old_value
= timer_get_user_idle_level();
4605 error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, &changed
);
4607 if (error
== 0 && changed
) {
4608 if (timer_set_user_idle_level(new_value
) != KERN_SUCCESS
) {
4616 SYSCTL_PROC(_machdep
, OID_AUTO
, user_idle_level
,
4617 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4619 timer_user_idle_level
, "I", "User idle level heuristic, 0-128");
4622 SYSCTL_INT(_kern
, OID_AUTO
, hv_support
,
4623 CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
4624 &hv_support_available
, 0, "");
4626 SYSCTL_INT(_kern
, OID_AUTO
, hv_disable
,
4627 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4628 &hv_disable
, 0, "");
4631 #if DEVELOPMENT || DEBUG
4632 extern uint64_t driverkit_checkin_timed_out
;
4633 SYSCTL_QUAD(_kern
, OID_AUTO
, driverkit_checkin_timed_out
,
4634 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4635 &driverkit_checkin_timed_out
, "timestamp of dext checkin timeout");
4638 extern int IOGetVMMPresent(void);
4641 hv_vmm_present SYSCTL_HANDLER_ARGS
4643 __unused
struct sysctl_oid
*unused_oidp
= oidp
;
4644 __unused
void *unused_arg1
= arg1
;
4645 __unused
int unused_arg2
= arg2
;
4647 int hv_vmm_present
= 0;
4649 hv_vmm_present
= IOGetVMMPresent();
4651 return SYSCTL_OUT(req
, &hv_vmm_present
, sizeof(hv_vmm_present
));
4654 SYSCTL_PROC(_kern
, OID_AUTO
, hv_vmm_present
,
4655 CTLTYPE_INT
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4657 hv_vmm_present
, "I", "");
4661 sysctl_darkboot SYSCTL_HANDLER_ARGS
4663 int err
= 0, value
= 0;
4664 #pragma unused(oidp, arg1, arg2, err, value, req)
4667 * Handle the sysctl request.
4669 * If this is a read, the function will set the value to the current darkboot value. Otherwise,
4670 * we'll get the request identifier into "value" and then we can honor it.
4672 if ((err
= sysctl_io_number(req
, darkboot
, sizeof(int), &value
, NULL
)) != 0) {
4676 /* writing requested, let's process the request */
4678 /* writing is protected by an entitlement */
4679 if (priv_check_cred(kauth_cred_get(), PRIV_DARKBOOT
, 0) != 0) {
4685 case MEMORY_MAINTENANCE_DARK_BOOT_UNSET
:
4687 * If the darkboot sysctl is unset, the NVRAM variable
4688 * must be unset too. If that's not the case, it means
4689 * someone is doing something crazy and not supported.
4691 if (darkboot
!= 0) {
4692 int ret
= PERemoveNVRAMProperty(MEMORY_MAINTENANCE_DARK_BOOT_NVRAM_NAME
);
4700 case MEMORY_MAINTENANCE_DARK_BOOT_SET
:
4703 case MEMORY_MAINTENANCE_DARK_BOOT_SET_PERSISTENT
: {
4705 * Set the NVRAM and update 'darkboot' in case
4706 * of success. Otherwise, do not update
4707 * 'darkboot' and report the failure.
4709 if (PEWriteNVRAMBooleanProperty(MEMORY_MAINTENANCE_DARK_BOOT_NVRAM_NAME
, TRUE
)) {
4726 SYSCTL_PROC(_kern
, OID_AUTO
, darkboot
,
4727 CTLFLAG_KERN
| CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
| CTLFLAG_ANYBODY
,
4728 0, 0, sysctl_darkboot
, "I", "");
4729 #endif /* CONFIG_DARKBOOT */
4731 #if DEVELOPMENT || DEBUG
4732 #include <sys/sysent.h>
4733 /* This should result in a fatal exception, verifying that "sysent" is
4737 kern_sysent_write(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4739 uint64_t new_value
= 0, old_value
= 0;
4740 int changed
= 0, error
;
4742 error
= sysctl_io_number(req
, old_value
, sizeof(uint64_t), &new_value
, &changed
);
4743 if ((error
== 0) && changed
) {
4744 volatile uint32_t *wraddr
= __DECONST(uint32_t *, &sysent
[0]);
4746 printf("sysent[0] write succeeded\n");
4751 SYSCTL_PROC(_kern
, OID_AUTO
, sysent_const_check
,
4752 CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4754 kern_sysent_write
, "I", "Attempt sysent[0] write");
4758 #if DEVELOPMENT || DEBUG
4759 SYSCTL_COMPAT_INT(_kern
, OID_AUTO
, development
, CTLFLAG_RD
| CTLFLAG_MASKED
| CTLFLAG_KERN
, NULL
, 1, "");
4761 SYSCTL_COMPAT_INT(_kern
, OID_AUTO
, development
, CTLFLAG_RD
| CTLFLAG_MASKED
, NULL
, 0, "");
4765 #if DEVELOPMENT || DEBUG
4768 sysctl_panic_test SYSCTL_HANDLER_ARGS
4770 #pragma unused(arg1, arg2)
4772 char str
[32] = "entry prelog postlog postcore";
4774 rval
= sysctl_handle_string(oidp
, str
, sizeof(str
), req
);
4776 if (rval
== 0 && req
->newptr
) {
4777 if (strncmp("entry", str
, strlen("entry")) == 0) {
4778 panic_with_options(0, NULL
, DEBUGGER_OPTION_RECURPANIC_ENTRY
, "test recursive panic at entry");
4779 } else if (strncmp("prelog", str
, strlen("prelog")) == 0) {
4780 panic_with_options(0, NULL
, DEBUGGER_OPTION_RECURPANIC_PRELOG
, "test recursive panic prior to writing a paniclog");
4781 } else if (strncmp("postlog", str
, strlen("postlog")) == 0) {
4782 panic_with_options(0, NULL
, DEBUGGER_OPTION_RECURPANIC_POSTLOG
, "test recursive panic subsequent to paniclog");
4783 } else if (strncmp("postcore", str
, strlen("postcore")) == 0) {
4784 panic_with_options(0, NULL
, DEBUGGER_OPTION_RECURPANIC_POSTCORE
, "test recursive panic subsequent to on-device core");
4792 sysctl_debugger_test SYSCTL_HANDLER_ARGS
4794 #pragma unused(arg1, arg2)
4796 char str
[32] = "entry prelog postlog postcore";
4798 rval
= sysctl_handle_string(oidp
, str
, sizeof(str
), req
);
4800 if (rval
== 0 && req
->newptr
) {
4801 if (strncmp("entry", str
, strlen("entry")) == 0) {
4802 DebuggerWithContext(0, NULL
, "test recursive panic via debugger at entry", DEBUGGER_OPTION_RECURPANIC_ENTRY
);
4803 } else if (strncmp("prelog", str
, strlen("prelog")) == 0) {
4804 DebuggerWithContext(0, NULL
, "test recursive panic via debugger prior to writing a paniclog", DEBUGGER_OPTION_RECURPANIC_PRELOG
);
4805 } else if (strncmp("postlog", str
, strlen("postlog")) == 0) {
4806 DebuggerWithContext(0, NULL
, "test recursive panic via debugger subsequent to paniclog", DEBUGGER_OPTION_RECURPANIC_POSTLOG
);
4807 } else if (strncmp("postcore", str
, strlen("postcore")) == 0) {
4808 DebuggerWithContext(0, NULL
, "test recursive panic via debugger subsequent to on-device core", DEBUGGER_OPTION_RECURPANIC_POSTCORE
);
4815 decl_lck_spin_data(, spinlock_panic_test_lock
);
4817 __attribute__((noreturn
))
4819 spinlock_panic_test_acquire_spinlock(void * arg __unused
, wait_result_t wres __unused
)
4821 lck_spin_lock(&spinlock_panic_test_lock
);
4828 sysctl_spinlock_panic_test SYSCTL_HANDLER_ARGS
4830 #pragma unused(oidp, arg1, arg2)
4831 if (req
->newlen
== 0) {
4835 thread_t panic_spinlock_thread
;
4836 /* Initialize panic spinlock */
4837 lck_grp_t
* panic_spinlock_grp
;
4838 lck_grp_attr_t
* panic_spinlock_grp_attr
;
4839 lck_attr_t
* panic_spinlock_attr
;
4841 panic_spinlock_grp_attr
= lck_grp_attr_alloc_init();
4842 panic_spinlock_grp
= lck_grp_alloc_init("panic_spinlock", panic_spinlock_grp_attr
);
4843 panic_spinlock_attr
= lck_attr_alloc_init();
4845 lck_spin_init(&spinlock_panic_test_lock
, panic_spinlock_grp
, panic_spinlock_attr
);
4848 /* Create thread to acquire spinlock */
4849 if (kernel_thread_start(spinlock_panic_test_acquire_spinlock
, NULL
, &panic_spinlock_thread
) != KERN_SUCCESS
) {
4853 /* Try to acquire spinlock -- should panic eventually */
4854 lck_spin_lock(&spinlock_panic_test_lock
);
4860 __attribute__((noreturn
))
4862 simultaneous_panic_worker
4863 (void * arg
, wait_result_t wres __unused
)
4865 atomic_int
*start_panic
= (atomic_int
*)arg
;
4867 while (!atomic_load(start_panic
)) {
4870 panic("SIMULTANEOUS PANIC TEST: INITIATING PANIC FROM CPU %d", cpu_number());
4871 __builtin_unreachable();
4875 sysctl_simultaneous_panic_test SYSCTL_HANDLER_ARGS
4877 #pragma unused(oidp, arg1, arg2)
4878 if (req
->newlen
== 0) {
4882 int i
= 0, threads_to_create
= 2 * processor_count
;
4883 atomic_int start_panic
= 0;
4884 unsigned int threads_created
= 0;
4885 thread_t new_panic_thread
;
4887 for (i
= threads_to_create
; i
> 0; i
--) {
4888 if (kernel_thread_start(simultaneous_panic_worker
, (void *) &start_panic
, &new_panic_thread
) == KERN_SUCCESS
) {
4893 /* FAIL if we couldn't create at least processor_count threads */
4894 if (threads_created
< processor_count
) {
4895 panic("SIMULTANEOUS PANIC TEST: FAILED TO CREATE ENOUGH THREADS, ONLY CREATED %d (of %d)",
4896 threads_created
, threads_to_create
);
4899 atomic_exchange(&start_panic
, 1);
4905 SYSCTL_PROC(_debug
, OID_AUTO
, panic_test
, CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_MASKED
, 0, 0, sysctl_panic_test
, "A", "panic test");
4906 SYSCTL_PROC(_debug
, OID_AUTO
, debugger_test
, CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_MASKED
, 0, 0, sysctl_debugger_test
, "A", "debugger test");
4907 SYSCTL_PROC(_debug
, OID_AUTO
, spinlock_panic_test
, CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_MASKED
, 0, 0, sysctl_spinlock_panic_test
, "A", "spinlock panic test");
4908 SYSCTL_PROC(_debug
, OID_AUTO
, simultaneous_panic_test
, CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_MASKED
, 0, 0, sysctl_simultaneous_panic_test
, "A", "simultaneous panic test");
4910 extern int exc_resource_threads_enabled
;
4912 SYSCTL_INT(_kern
, OID_AUTO
, exc_resource_threads_enabled
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &exc_resource_threads_enabled
, 0, "exc_resource thread limit enabled");
4915 #endif /* DEVELOPMENT || DEBUG */
4917 #if CONFIG_THREAD_GROUPS
4918 #if DEVELOPMENT || DEBUG
4921 sysctl_get_thread_group_id SYSCTL_HANDLER_ARGS
4923 #pragma unused(arg1, arg2, oidp)
4924 uint64_t thread_group_id
= thread_group_get_id(thread_group_get(current_thread()));
4925 return SYSCTL_OUT(req
, &thread_group_id
, sizeof(thread_group_id
));
4928 SYSCTL_PROC(_kern
, OID_AUTO
, thread_group_id
, CTLFLAG_RD
| CTLFLAG_LOCKED
| CTLTYPE_QUAD
,
4929 0, 0, &sysctl_get_thread_group_id
, "I", "thread group id of the thread");
4932 sysctl_thread_group_count(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4934 int value
= thread_group_count();
4935 return sysctl_io_number(req
, value
, sizeof(value
), NULL
, NULL
);
4938 SYSCTL_PROC(_kern
, OID_AUTO
, thread_group_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
| CTLFLAG_KERN
,
4939 0, 0, &sysctl_thread_group_count
, "I", "count of thread groups");
4941 #endif /* DEVELOPMENT || DEBUG */
4942 const uint32_t thread_groups_supported
= 1;
4943 #else /* CONFIG_THREAD_GROUPS */
4944 const uint32_t thread_groups_supported
= 0;
4945 #endif /* CONFIG_THREAD_GROUPS */
4948 sysctl_thread_groups_supported(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4950 int value
= thread_groups_supported
;
4951 return sysctl_io_number(req
, value
, sizeof(value
), NULL
, NULL
);
4954 SYSCTL_PROC(_kern
, OID_AUTO
, thread_groups_supported
, CTLFLAG_RD
| CTLFLAG_LOCKED
| CTLFLAG_KERN
,
4955 0, 0, &sysctl_thread_groups_supported
, "I", "thread groups supported");
4958 sysctl_grade_cputype SYSCTL_HANDLER_ARGS
4960 #pragma unused(arg1, arg2, oidp)
4962 int type_tuple
[2] = {};
4963 int return_value
= 0;
4965 error
= SYSCTL_IN(req
, &type_tuple
, sizeof(type_tuple
));
4971 return_value
= grade_binary(type_tuple
[0], type_tuple
[1] & ~CPU_SUBTYPE_MASK
, type_tuple
[1] & CPU_SUBTYPE_MASK
, FALSE
);
4973 error
= SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
4982 SYSCTL_PROC(_kern
, OID_AUTO
, grade_cputype
,
4983 CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_MASKED
| CTLFLAG_LOCKED
| CTLTYPE_OPAQUE
,
4984 0, 0, &sysctl_grade_cputype
, "S",
4985 "grade value of cpu_type_t+cpu_sub_type_t");
4987 extern boolean_t allow_direct_handoff
;
4988 SYSCTL_INT(_kern
, OID_AUTO
, direct_handoff
,
4989 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4990 &allow_direct_handoff
, 0, "Enable direct handoff for realtime threads");
4992 #if DEVELOPMENT || DEBUG
4994 SYSCTL_LONG(_kern
, OID_AUTO
, phys_carveout_pa
, CTLFLAG_RD
| CTLFLAG_LOCKED
,
4996 "base physical address of the phys_carveout_mb boot-arg region");
4997 SYSCTL_LONG(_kern
, OID_AUTO
, phys_carveout_size
, CTLFLAG_RD
| CTLFLAG_LOCKED
,
4998 &phys_carveout_size
,
4999 "size in bytes of the phys_carveout_mb boot-arg region");
5001 extern void do_cseg_wedge_thread(void);
5002 extern void do_cseg_unwedge_thread(void);
5005 cseg_wedge_thread SYSCTL_HANDLER_ARGS
5007 #pragma unused(arg1, arg2)
5010 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5011 if (error
|| val
== 0) {
5015 do_cseg_wedge_thread();
5018 SYSCTL_PROC(_kern
, OID_AUTO
, cseg_wedge_thread
, CTLFLAG_RW
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
, 0, 0, cseg_wedge_thread
, "I", "wedge c_seg thread");
5021 cseg_unwedge_thread SYSCTL_HANDLER_ARGS
5023 #pragma unused(arg1, arg2)
5026 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5027 if (error
|| val
== 0) {
5031 do_cseg_unwedge_thread();
5034 SYSCTL_PROC(_kern
, OID_AUTO
, cseg_unwedge_thread
, CTLFLAG_RW
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
, 0, 0, cseg_unwedge_thread
, "I", "unstuck c_seg thread");
5036 static atomic_int wedge_thread_should_wake
= 0;
5039 unwedge_thread SYSCTL_HANDLER_ARGS
5041 #pragma unused(arg1, arg2)
5043 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5044 if (error
|| val
== 0) {
5048 atomic_store(&wedge_thread_should_wake
, 1);
5052 SYSCTL_PROC(_kern
, OID_AUTO
, unwedge_thread
, CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
, 0, 0, unwedge_thread
, "I", "unwedge the thread wedged by kern.wedge_thread");
5055 wedge_thread SYSCTL_HANDLER_ARGS
5057 #pragma unused(arg1, arg2)
5060 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5061 if (error
|| val
== 0) {
5065 uint64_t interval
= 1;
5066 nanoseconds_to_absolutetime(1000 * 1000 * 50, &interval
);
5068 atomic_store(&wedge_thread_should_wake
, 0);
5069 while (!atomic_load(&wedge_thread_should_wake
)) {
5070 tsleep1(NULL
, 0, "wedge_thread", mach_absolute_time() + interval
, NULL
);
5076 SYSCTL_PROC(_kern
, OID_AUTO
, wedge_thread
,
5077 CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
, 0, 0, wedge_thread
, "I",
5078 "wedge this thread so it cannot be cleaned up");
5081 sysctl_total_corpses_count SYSCTL_HANDLER_ARGS
5083 #pragma unused(oidp, arg1, arg2)
5084 extern unsigned long total_corpses_count(void);
5086 unsigned long corpse_count_long
= total_corpses_count();
5087 unsigned int corpse_count
= (unsigned int)MIN(corpse_count_long
, UINT_MAX
);
5088 return sysctl_io_opaque(req
, &corpse_count
, sizeof(corpse_count
), NULL
);
5091 SYSCTL_PROC(_kern
, OID_AUTO
, total_corpses_count
,
5092 CTLFLAG_RD
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
, 0, 0,
5093 sysctl_total_corpses_count
, "I", "total corpses on the system");
5096 sysctl_turnstile_test_prim_lock SYSCTL_HANDLER_ARGS
;
5098 sysctl_turnstile_test_prim_unlock SYSCTL_HANDLER_ARGS
;
5100 tstile_test_prim_lock(boolean_t use_hashtable
);
5102 tstile_test_prim_unlock(boolean_t use_hashtable
);
5105 sysctl_turnstile_test_prim_lock SYSCTL_HANDLER_ARGS
5107 #pragma unused(arg1, arg2)
5109 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5110 if (error
|| val
== 0) {
5114 case SYSCTL_TURNSTILE_TEST_USER_DEFAULT
:
5115 case SYSCTL_TURNSTILE_TEST_USER_HASHTABLE
:
5116 case SYSCTL_TURNSTILE_TEST_KERNEL_DEFAULT
:
5117 case SYSCTL_TURNSTILE_TEST_KERNEL_HASHTABLE
:
5118 return tstile_test_prim_lock(val
);
5125 sysctl_turnstile_test_prim_unlock SYSCTL_HANDLER_ARGS
5127 #pragma unused(arg1, arg2)
5129 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5130 if (error
|| val
== 0) {
5134 case SYSCTL_TURNSTILE_TEST_USER_DEFAULT
:
5135 case SYSCTL_TURNSTILE_TEST_USER_HASHTABLE
:
5136 case SYSCTL_TURNSTILE_TEST_KERNEL_DEFAULT
:
5137 case SYSCTL_TURNSTILE_TEST_KERNEL_HASHTABLE
:
5138 return tstile_test_prim_unlock(val
);
5144 SYSCTL_PROC(_kern
, OID_AUTO
, turnstiles_test_lock
, CTLFLAG_WR
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5145 0, 0, sysctl_turnstile_test_prim_lock
, "I", "turnstiles test lock");
5147 SYSCTL_PROC(_kern
, OID_AUTO
, turnstiles_test_unlock
, CTLFLAG_WR
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5148 0, 0, sysctl_turnstile_test_prim_unlock
, "I", "turnstiles test unlock");
5151 turnstile_get_boost_stats_sysctl(void *req
);
5153 turnstile_get_unboost_stats_sysctl(void *req
);
5155 sysctl_turnstile_boost_stats SYSCTL_HANDLER_ARGS
;
5157 sysctl_turnstile_unboost_stats SYSCTL_HANDLER_ARGS
;
5158 extern uint64_t thread_block_on_turnstile_count
;
5159 extern uint64_t thread_block_on_regular_waitq_count
;
5162 sysctl_turnstile_boost_stats SYSCTL_HANDLER_ARGS
5164 #pragma unused(arg1, arg2, oidp)
5165 return turnstile_get_boost_stats_sysctl(req
);
5169 sysctl_turnstile_unboost_stats SYSCTL_HANDLER_ARGS
5171 #pragma unused(arg1, arg2, oidp)
5172 return turnstile_get_unboost_stats_sysctl(req
);
5175 SYSCTL_PROC(_kern
, OID_AUTO
, turnstile_boost_stats
, CTLFLAG_RD
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
| CTLTYPE_STRUCT
,
5176 0, 0, sysctl_turnstile_boost_stats
, "S", "turnstiles boost stats");
5177 SYSCTL_PROC(_kern
, OID_AUTO
, turnstile_unboost_stats
, CTLFLAG_RD
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
| CTLTYPE_STRUCT
,
5178 0, 0, sysctl_turnstile_unboost_stats
, "S", "turnstiles unboost stats");
5179 SYSCTL_QUAD(_kern
, OID_AUTO
, thread_block_count_on_turnstile
,
5180 CTLFLAG_RD
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5181 &thread_block_on_turnstile_count
, "thread blocked on turnstile count");
5182 SYSCTL_QUAD(_kern
, OID_AUTO
, thread_block_count_on_reg_waitq
,
5183 CTLFLAG_RD
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5184 &thread_block_on_regular_waitq_count
, "thread blocked on regular waitq count");
5187 sysctl_erase_all_test_mtx_stats SYSCTL_HANDLER_ARGS
5189 #pragma unused(arg1, arg2)
5191 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5192 if (error
|| val
== 0) {
5197 lck_mtx_test_init();
5198 erase_all_test_mtx_stats();
5205 sysctl_get_test_mtx_stats SYSCTL_HANDLER_ARGS
5207 #pragma unused(oidp, arg1, arg2)
5209 int size
, buffer_size
, error
;
5212 buffer
= kheap_alloc(KHEAP_TEMP
, buffer_size
, Z_WAITOK
);
5214 panic("Impossible to allocate memory for %s\n", __func__
);
5217 lck_mtx_test_init();
5219 size
= get_test_mtx_stats_string(buffer
, buffer_size
);
5221 error
= sysctl_io_string(req
, buffer
, size
, 0, NULL
);
5223 kheap_free(KHEAP_TEMP
, buffer
, buffer_size
);
5229 sysctl_test_mtx_uncontended SYSCTL_HANDLER_ARGS
5231 #pragma unused(oidp, arg1, arg2)
5233 int buffer_size
, offset
, error
, iter
;
5244 if (req
->newlen
>= sizeof(input_val
)) {
5248 error
= SYSCTL_IN(req
, input_val
, req
->newlen
);
5252 input_val
[req
->newlen
] = '\0';
5255 error
= sscanf(input_val
, "%d", &iter
);
5257 printf("%s invalid input\n", __func__
);
5262 printf("%s requested %d iterations, not starting the test\n", __func__
, iter
);
5266 lck_mtx_test_init();
5270 buffer
= kheap_alloc(KHEAP_TEMP
, buffer_size
, Z_WAITOK
);
5272 panic("Impossible to allocate memory for %s\n", __func__
);
5274 memset(buffer
, 0, buffer_size
);
5276 printf("%s starting uncontended mutex test with %d iterations\n", __func__
, iter
);
5278 offset
= scnprintf(buffer
, buffer_size
, "STATS INNER LOOP");
5279 offset
+= lck_mtx_test_mtx_uncontended(iter
, &buffer
[offset
], buffer_size
- offset
);
5281 offset
+= scnprintf(&buffer
[offset
], buffer_size
- offset
, "\nSTATS OUTER LOOP");
5282 offset
+= lck_mtx_test_mtx_uncontended_loop_time(iter
, &buffer
[offset
], buffer_size
- offset
);
5284 error
= SYSCTL_OUT(req
, buffer
, offset
);
5286 kheap_free(KHEAP_TEMP
, buffer
, buffer_size
);
5291 sysctl_test_mtx_contended SYSCTL_HANDLER_ARGS
5293 #pragma unused(oidp, arg1, arg2)
5295 int buffer_size
, offset
, error
, iter
;
5306 if (req
->newlen
>= sizeof(input_val
)) {
5310 error
= SYSCTL_IN(req
, input_val
, req
->newlen
);
5314 input_val
[req
->newlen
] = '\0';
5317 error
= sscanf(input_val
, "%d", &iter
);
5319 printf("%s invalid input\n", __func__
);
5324 printf("%s requested %d iterations, not starting the test\n", __func__
, iter
);
5328 lck_mtx_test_init();
5330 erase_all_test_mtx_stats();
5334 buffer
= kheap_alloc(KHEAP_TEMP
, buffer_size
, Z_WAITOK
| Z_ZERO
);
5336 panic("Impossible to allocate memory for %s\n", __func__
);
5339 printf("%s starting contended mutex test with %d iterations FULL_CONTENDED\n", __func__
, iter
);
5341 offset
= scnprintf(buffer
, buffer_size
, "STATS INNER LOOP");
5342 offset
+= lck_mtx_test_mtx_contended(iter
, &buffer
[offset
], buffer_size
- offset
, FULL_CONTENDED
);
5344 printf("%s starting contended mutex loop test with %d iterations FULL_CONTENDED\n", __func__
, iter
);
5346 offset
+= scnprintf(&buffer
[offset
], buffer_size
- offset
, "\nSTATS OUTER LOOP");
5347 offset
+= lck_mtx_test_mtx_contended_loop_time(iter
, &buffer
[offset
], buffer_size
- offset
, FULL_CONTENDED
);
5349 printf("%s starting contended mutex test with %d iterations HALF_CONTENDED\n", __func__
, iter
);
5351 offset
+= scnprintf(&buffer
[offset
], buffer_size
- offset
, "STATS INNER LOOP");
5352 offset
+= lck_mtx_test_mtx_contended(iter
, &buffer
[offset
], buffer_size
- offset
, HALF_CONTENDED
);
5354 printf("%s starting contended mutex loop test with %d iterations HALF_CONTENDED\n", __func__
, iter
);
5356 offset
+= scnprintf(&buffer
[offset
], buffer_size
- offset
, "\nSTATS OUTER LOOP");
5357 offset
+= lck_mtx_test_mtx_contended_loop_time(iter
, &buffer
[offset
], buffer_size
- offset
, HALF_CONTENDED
);
5359 error
= SYSCTL_OUT(req
, buffer
, offset
);
5361 printf("\n%s\n", buffer
);
5362 kheap_free(KHEAP_TEMP
, buffer
, buffer_size
);
5367 SYSCTL_PROC(_kern
, OID_AUTO
, erase_all_test_mtx_stats
,
5368 CTLFLAG_WR
| CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5369 0, 0, sysctl_erase_all_test_mtx_stats
, "I", "erase test_mtx statistics");
5371 SYSCTL_PROC(_kern
, OID_AUTO
, get_test_mtx_stats
,
5372 CTLTYPE_STRING
| CTLFLAG_RD
| CTLFLAG_MASKED
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5373 0, 0, sysctl_get_test_mtx_stats
, "A", "get test_mtx statistics");
5375 SYSCTL_PROC(_kern
, OID_AUTO
, test_mtx_contended
,
5376 CTLTYPE_STRING
| CTLFLAG_MASKED
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5377 0, 0, sysctl_test_mtx_contended
, "A", "get statistics for contended mtx test");
5379 SYSCTL_PROC(_kern
, OID_AUTO
, test_mtx_uncontended
,
5380 CTLTYPE_STRING
| CTLFLAG_MASKED
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5381 0, 0, sysctl_test_mtx_uncontended
, "A", "get statistics for uncontended mtx test");
5383 extern uint64_t MutexSpin
;
5385 SYSCTL_QUAD(_kern
, OID_AUTO
, mutex_spin_abs
, CTLFLAG_RW
, &MutexSpin
,
5386 "Spin time in abs for acquiring a kernel mutex");
5388 extern uint64_t low_MutexSpin
;
5389 extern int64_t high_MutexSpin
;
5390 extern unsigned int real_ncpus
;
5392 SYSCTL_QUAD(_kern
, OID_AUTO
, low_mutex_spin_abs
, CTLFLAG_RW
, &low_MutexSpin
,
5393 "Low spin threshold in abs for acquiring a kernel mutex");
5396 sysctl_high_mutex_spin_ns SYSCTL_HANDLER_ARGS
5398 #pragma unused(oidp, arg1, arg2)
5403 /* Check if the user is writing to high_MutexSpin, or just reading it */
5405 error
= SYSCTL_IN(req
, &val
, sizeof(val
));
5406 if (error
|| (val
< 0 && val
!= -1)) {
5409 high_MutexSpin
= val
;
5412 if (high_MutexSpin
>= 0) {
5413 res
= high_MutexSpin
;
5415 res
= low_MutexSpin
* real_ncpus
;
5417 return SYSCTL_OUT(req
, &res
, sizeof(res
));
5419 SYSCTL_PROC(_kern
, OID_AUTO
, high_mutex_spin_abs
, CTLFLAG_RW
| CTLTYPE_QUAD
, 0, 0, sysctl_high_mutex_spin_ns
, "I",
5420 "High spin threshold in abs for acquiring a kernel mutex");
5423 #if defined (__x86_64__)
5425 semaphore_t sysctl_test_panic_with_thread_sem
;
5427 #pragma clang diagnostic push
5428 #pragma clang diagnostic ignored "-Winfinite-recursion" /* rdar://38801963 */
5429 __attribute__((noreturn
))
5431 panic_thread_test_child_spin(void * arg
, wait_result_t wres
)
5433 static int panic_thread_recurse_count
= 5;
5435 if (panic_thread_recurse_count
> 0) {
5436 panic_thread_recurse_count
--;
5437 panic_thread_test_child_spin(arg
, wres
);
5440 semaphore_signal(sysctl_test_panic_with_thread_sem
);
5445 #pragma clang diagnostic pop
5448 panic_thread_test_child_park(void * arg __unused
, wait_result_t wres __unused
)
5452 assert_wait(&event
, THREAD_UNINT
);
5453 semaphore_signal(sysctl_test_panic_with_thread_sem
);
5454 thread_block(panic_thread_test_child_park
);
5458 sysctl_test_panic_with_thread SYSCTL_HANDLER_ARGS
5460 #pragma unused(arg1, arg2)
5462 char str
[16] = { '\0' };
5463 thread_t child_thread
= THREAD_NULL
;
5465 rval
= sysctl_handle_string(oidp
, str
, sizeof(str
), req
);
5466 if (rval
!= 0 || !req
->newptr
) {
5470 semaphore_create(kernel_task
, &sysctl_test_panic_with_thread_sem
, SYNC_POLICY_FIFO
, 0);
5472 /* Create thread to spin or park in continuation */
5473 if (strncmp("spin", str
, strlen("spin")) == 0) {
5474 if (kernel_thread_start(panic_thread_test_child_spin
, NULL
, &child_thread
) != KERN_SUCCESS
) {
5475 semaphore_destroy(kernel_task
, sysctl_test_panic_with_thread_sem
);
5478 } else if (strncmp("continuation", str
, strlen("continuation")) == 0) {
5479 if (kernel_thread_start(panic_thread_test_child_park
, NULL
, &child_thread
) != KERN_SUCCESS
) {
5480 semaphore_destroy(kernel_task
, sysctl_test_panic_with_thread_sem
);
5484 semaphore_destroy(kernel_task
, sysctl_test_panic_with_thread_sem
);
5488 semaphore_wait(sysctl_test_panic_with_thread_sem
);
5490 panic_with_thread_context(0, NULL
, 0, child_thread
, "testing panic_with_thread_context for thread %p", child_thread
);
5496 SYSCTL_PROC(_kern
, OID_AUTO
, test_panic_with_thread
,
5497 CTLFLAG_MASKED
| CTLFLAG_KERN
| CTLFLAG_LOCKED
| CTLFLAG_WR
| CTLTYPE_STRING
,
5498 0, 0, sysctl_test_panic_with_thread
, "A", "test panic flow for backtracing a different thread");
5499 #endif /* defined (__x86_64__) */
5501 #endif /* DEVELOPMENT || DEBUG */
5504 sysctl_get_owned_vmobjects SYSCTL_HANDLER_ARGS
5506 #pragma unused(oidp, arg1, arg2)
5509 if (req
->newlen
!= sizeof(mach_port_name_t
) || req
->newptr
== USER_ADDR_NULL
||
5510 req
->oldidx
!= 0 || req
->newidx
!= 0 || req
->p
== NULL
) {
5515 mach_port_name_t task_port_name
;
5517 size_t buffer_size
= (req
->oldptr
!= USER_ADDR_NULL
) ? req
->oldlen
: 0;
5518 vmobject_list_output_t buffer
= NULL
;
5522 /* we have a "newptr" (for write) we get a task port name from the caller. */
5523 error
= SYSCTL_IN(req
, &task_port_name
, sizeof(mach_port_name_t
));
5526 goto sysctl_get_vmobject_list_exit
;
5529 task
= port_name_to_task_read(task_port_name
);
5530 if (task
== TASK_NULL
) {
5532 goto sysctl_get_vmobject_list_exit
;
5535 /* get the current size */
5536 task_copy_vmobjects(task
, NULL
, 0, &entries
);
5537 size_t max_size
= (entries
> 0) ? entries
* sizeof(vm_object_query_data_t
) + sizeof(*buffer
) : 0;
5539 /* if buffer_size is specified clamp to the current size then allcoate the kernel buffer */
5541 if (buffer_size
< sizeof(*buffer
) + sizeof(vm_object_query_data_t
)) {
5543 goto sysctl_get_vmobject_list_deallocate_and_exit
;
5546 buffer_size
= (buffer_size
> max_size
) ? max_size
: buffer_size
;
5547 buffer
= kheap_alloc(KHEAP_TEMP
, buffer_size
, Z_WAITOK
);
5551 goto sysctl_get_vmobject_list_deallocate_and_exit
;
5557 /* copy the vmobjects and vmobject data out of the task */
5558 if (buffer_size
== 0) {
5559 output_size
= max_size
;
5561 task_copy_vmobjects(task
, &buffer
->data
[0], buffer_size
- sizeof(*buffer
), &entries
);
5562 buffer
->entries
= (uint64_t)entries
;
5563 output_size
= entries
* sizeof(vm_object_query_data_t
) + sizeof(*buffer
);
5566 error
= SYSCTL_OUT(req
, (char*) buffer
, output_size
);
5568 sysctl_get_vmobject_list_deallocate_and_exit
:
5569 task_deallocate(task
);
5571 sysctl_get_vmobject_list_exit
:
5573 kheap_free(KHEAP_TEMP
, buffer
, buffer_size
);
5579 SYSCTL_PROC(_vm
, OID_AUTO
, get_owned_vmobjects
,
5580 CTLTYPE_OPAQUE
| CTLFLAG_RD
| CTLFLAG_WR
| CTLFLAG_MASKED
| CTLFLAG_KERN
| CTLFLAG_LOCKED
| CTLFLAG_ANYBODY
,
5581 0, 0, sysctl_get_owned_vmobjects
, "A", "get owned vmobjects in task");
5583 extern uint64_t num_static_scalable_counters
;
5584 SYSCTL_QUAD(_kern
, OID_AUTO
, num_static_scalable_counters
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &num_static_scalable_counters
, "");
5586 uuid_string_t trial_treatment_id
;
5587 uuid_string_t trial_experiment_id
;
5588 int trial_deployment_id
= -1;
5590 SYSCTL_STRING(_kern
, OID_AUTO
, trial_treatment_id
, CTLFLAG_RW
| CTLFLAG_LOCKED
| CTLFLAG_ANYBODY
| CTLFLAG_EXPERIMENT
, trial_treatment_id
, sizeof(trial_treatment_id
), "");
5591 SYSCTL_STRING(_kern
, OID_AUTO
, trial_experiment_id
, CTLFLAG_RW
| CTLFLAG_LOCKED
| CTLFLAG_ANYBODY
| CTLFLAG_EXPERIMENT
, trial_experiment_id
, sizeof(trial_experiment_id
), "");
5592 SYSCTL_INT(_kern
, OID_AUTO
, trial_deployment_id
, CTLFLAG_RW
| CTLFLAG_LOCKED
| CTLFLAG_ANYBODY
| CTLFLAG_EXPERIMENT
, &trial_deployment_id
, 0, "");
5594 #if DEVELOPMENT || DEBUG
5595 /* For unit testing setting factors & limits. */
5596 unsigned int testing_experiment_factor
;
5597 EXPERIMENT_FACTOR_UINT(_kern
, testing_experiment_factor
, &testing_experiment_factor
, 5, 10, "");
5598 #endif /* DEVELOPMENT || DEBUG */