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>
109 #include <security/audit/audit.h>
110 #include <kern/kalloc.h>
112 #include <machine/smp.h>
113 #include <machine/atomic.h>
114 #include <machine/config.h>
115 #include <mach/machine.h>
116 #include <mach/mach_host.h>
117 #include <mach/mach_types.h>
118 #include <mach/processor_info.h>
119 #include <mach/vm_param.h>
120 #include <kern/debug.h>
121 #include <kern/mach_param.h>
122 #include <kern/task.h>
123 #include <kern/thread.h>
124 #include <kern/thread_group.h>
125 #include <kern/processor.h>
126 #include <kern/cpu_number.h>
127 #include <kern/cpu_quiesce.h>
128 #include <kern/sched_prim.h>
129 #include <vm/vm_kern.h>
130 #include <vm/vm_map.h>
131 #include <mach/host_info.h>
133 #include <sys/mount_internal.h>
134 #include <sys/kdebug.h>
135 #include <sys/kern_sysctl.h>
137 #include <IOKit/IOPlatformExpert.h>
138 #include <pexpert/pexpert.h>
140 #include <machine/machine_routines.h>
141 #include <machine/exec.h>
143 #include <nfs/nfs_conf.h>
145 #include <vm/vm_protos.h>
146 #include <vm/vm_pageout.h>
147 #include <vm/vm_compressor_algorithms.h>
148 #include <sys/imgsrc.h>
149 #include <kern/timer_call.h>
150 #include <sys/codesign.h>
151 #include <IOKit/IOBSD.h>
156 #if defined(__i386__) || defined(__x86_64__)
157 #include <i386/cpuid.h>
161 #include <sys/kern_memorystatus.h>
165 #include <kperf/kperf.h>
169 #include <kern/hv_support.h>
173 * deliberately setting max requests to really high number
174 * so that runaway settings do not cause MALLOC overflows
176 #define AIO_MAX_REQUESTS (128 * CONFIG_AIO_MAX)
178 extern int aio_max_requests
;
179 extern int aio_max_requests_per_process
;
180 extern int aio_worker_threads
;
181 extern int lowpri_IO_window_msecs
;
182 extern int lowpri_IO_delay_msecs
;
183 #if DEVELOPMENT || DEBUG
184 extern int nx_enabled
;
186 extern int speculative_reads_disabled
;
187 extern unsigned int speculative_prefetch_max
;
188 extern unsigned int speculative_prefetch_max_iosize
;
189 extern unsigned int preheat_max_bytes
;
190 extern unsigned int preheat_min_bytes
;
191 extern long numvnodes
;
192 extern long num_recycledvnodes
;
194 extern uuid_string_t bootsessionuuid_string
;
196 extern unsigned int vm_max_delayed_work_limit
;
197 extern unsigned int vm_max_batch
;
199 extern unsigned int vm_page_free_min
;
200 extern unsigned int vm_page_free_target
;
201 extern unsigned int vm_page_free_reserved
;
203 #if (DEVELOPMENT || DEBUG)
204 extern uint32_t vm_page_creation_throttled_hard
;
205 extern uint32_t vm_page_creation_throttled_soft
;
206 #endif /* DEVELOPMENT || DEBUG */
208 #if CONFIG_LOCKERBOOT
209 extern const char kernel_protoboot_mount
[];
213 * Conditionally allow dtrace to see these functions for debugging purposes.
221 #define STATIC static
224 extern boolean_t mach_timer_coalescing_enabled
;
226 extern uint64_t timer_deadline_tracking_bin_1
, timer_deadline_tracking_bin_2
;
229 fill_user32_eproc(proc_t
, struct user32_eproc
*__restrict
);
231 fill_user32_externproc(proc_t
, struct user32_extern_proc
*__restrict
);
233 fill_user64_eproc(proc_t
, struct user64_eproc
*__restrict
);
235 fill_user64_proc(proc_t
, struct user64_kinfo_proc
*__restrict
);
237 fill_user64_externproc(proc_t
, struct user64_extern_proc
*__restrict
);
239 fill_user32_proc(proc_t
, struct user32_kinfo_proc
*__restrict
);
242 kdbg_control(int *name
, u_int namelen
, user_addr_t where
, size_t * sizep
);
243 #if CONFIG_NFS_CLIENT
248 sysctl_procargs(int *name
, u_int namelen
, user_addr_t where
,
249 size_t *sizep
, proc_t cur_proc
);
251 sysctl_procargsx(int *name
, u_int namelen
, user_addr_t where
, size_t *sizep
,
252 proc_t cur_proc
, int argc_yes
);
254 sysctl_struct(user_addr_t oldp
, size_t *oldlenp
, user_addr_t newp
,
255 size_t newlen
, void *sp
, int len
);
257 STATIC
int sysdoproc_filt_KERN_PROC_PID(proc_t p
, void * arg
);
258 STATIC
int sysdoproc_filt_KERN_PROC_PGRP(proc_t p
, void * arg
);
259 STATIC
int sysdoproc_filt_KERN_PROC_TTY(proc_t p
, void * arg
);
260 STATIC
int sysdoproc_filt_KERN_PROC_UID(proc_t p
, void * arg
);
261 STATIC
int sysdoproc_filt_KERN_PROC_RUID(proc_t p
, void * arg
);
262 int sysdoproc_callback(proc_t p
, void *arg
);
264 #if CONFIG_THREAD_GROUPS && (DEVELOPMENT || DEBUG)
265 STATIC
int sysctl_get_thread_group_id SYSCTL_HANDLER_ARGS
;
268 /* forward declarations for non-static STATIC */
269 STATIC
void fill_loadavg64(struct loadavg
*la
, struct user64_loadavg
*la64
);
270 STATIC
void fill_loadavg32(struct loadavg
*la
, struct user32_loadavg
*la32
);
271 STATIC
int sysctl_handle_kern_threadname(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
272 STATIC
int sysctl_sched_stats(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
273 STATIC
int sysctl_sched_stats_enable(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
274 STATIC
int sysctl_kdebug_ops SYSCTL_HANDLER_ARGS
;
276 STATIC
int sysctl_docountsyscalls SYSCTL_HANDLER_ARGS
;
277 #endif /* COUNT_SYSCALLS */
278 #if defined(XNU_TARGET_OS_OSX)
279 STATIC
int sysctl_doprocargs SYSCTL_HANDLER_ARGS
;
280 #endif /* defined(XNU_TARGET_OS_OSX) */
281 STATIC
int sysctl_doprocargs2 SYSCTL_HANDLER_ARGS
;
282 STATIC
int sysctl_prochandle SYSCTL_HANDLER_ARGS
;
283 STATIC
int sysctl_aiomax(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
284 STATIC
int sysctl_aioprocmax(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
285 STATIC
int sysctl_aiothreads(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
286 STATIC
int sysctl_maxproc(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
287 STATIC
int sysctl_osversion(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
288 STATIC
int sysctl_sysctl_bootargs(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
289 STATIC
int sysctl_maxvnodes(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
290 STATIC
int sysctl_securelvl(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
291 STATIC
int sysctl_domainname(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
292 STATIC
int sysctl_hostname(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
293 STATIC
int sysctl_procname(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
294 STATIC
int sysctl_boottime(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
295 STATIC
int sysctl_bootuuid(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
296 STATIC
int sysctl_symfile(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
297 #if CONFIG_NFS_CLIENT
298 STATIC
int sysctl_netboot(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
300 #ifdef CONFIG_IMGSRC_ACCESS
301 STATIC
int sysctl_imgsrcdev(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
303 STATIC
int sysctl_usrstack(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
304 STATIC
int sysctl_usrstack64(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
306 STATIC
int sysctl_coredump(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
307 STATIC
int sysctl_suid_coredump(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
309 STATIC
int sysctl_delayterm(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
310 STATIC
int sysctl_rage_vnode(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
311 STATIC
int sysctl_kern_check_openevt(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
312 #if DEVELOPMENT || DEBUG
313 STATIC
int sysctl_nx(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
315 STATIC
int sysctl_loadavg(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
316 STATIC
int sysctl_vm_toggle_address_reuse(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
317 STATIC
int sysctl_swapusage(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
318 STATIC
int fetch_process_cputype( proc_t cur_proc
, int *name
, u_int namelen
, cpu_type_t
*cputype
);
319 STATIC
int sysctl_sysctl_native(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
320 STATIC
int sysctl_sysctl_cputype(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
321 STATIC
int sysctl_safeboot(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
322 STATIC
int sysctl_singleuser(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
323 STATIC
int sysctl_minimalboot(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
324 STATIC
int sysctl_slide(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
326 #ifdef CONFIG_XNUPOST
327 #include <tests/xnupost.h>
329 STATIC
int sysctl_debug_test_oslog_ctl(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
330 STATIC
int sysctl_debug_test_stackshot_mutex_owner(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
331 STATIC
int sysctl_debug_test_stackshot_rwlck_owner(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
);
334 extern void IORegistrySetOSBuildVersion(char * build_version
);
337 fill_loadavg64(struct loadavg
*la
, struct user64_loadavg
*la64
)
339 la64
->ldavg
[0] = la
->ldavg
[0];
340 la64
->ldavg
[1] = la
->ldavg
[1];
341 la64
->ldavg
[2] = la
->ldavg
[2];
342 la64
->fscale
= (user64_long_t
)la
->fscale
;
346 fill_loadavg32(struct loadavg
*la
, struct user32_loadavg
*la32
)
348 la32
->ldavg
[0] = la
->ldavg
[0];
349 la32
->ldavg
[1] = la
->ldavg
[1];
350 la32
->ldavg
[2] = la
->ldavg
[2];
351 la32
->fscale
= (user32_long_t
)la
->fscale
;
356 * Attributes stored in the kernel.
358 extern char corefilename
[MAXPATHLEN
+ 1];
359 extern int do_coredump
;
360 extern int sugid_coredump
;
364 extern int do_count_syscalls
;
368 int securelevel
= -1;
374 sysctl_handle_kern_threadname( __unused
struct sysctl_oid
*oidp
, __unused
void *arg1
,
375 __unused
int arg2
, struct sysctl_req
*req
)
378 struct uthread
*ut
= get_bsdthread_info(current_thread());
379 user_addr_t oldp
= 0, newp
= 0;
380 size_t *oldlenp
= NULL
;
384 oldlenp
= &(req
->oldlen
);
386 newlen
= req
->newlen
;
388 /* We want the current length, and maybe the string itself */
390 /* if we have no thread name yet tell'em we want MAXTHREADNAMESIZE - 1 */
391 size_t currlen
= MAXTHREADNAMESIZE
- 1;
394 /* use length of current thread name */
395 currlen
= strlen(ut
->pth_name
);
398 if (*oldlenp
< currlen
) {
401 /* NOTE - we do not copy the NULL terminator */
403 error
= copyout(ut
->pth_name
, oldp
, currlen
);
409 /* return length of thread name minus NULL terminator (just like strlen) */
410 req
->oldidx
= currlen
;
413 /* We want to set the name to something */
415 if (newlen
> (MAXTHREADNAMESIZE
- 1)) {
419 char *tmp_pth_name
= (char *)kalloc(MAXTHREADNAMESIZE
);
423 bzero(tmp_pth_name
, MAXTHREADNAMESIZE
);
424 if (!OSCompareAndSwapPtr(NULL
, tmp_pth_name
, &ut
->pth_name
)) {
425 kfree(tmp_pth_name
, MAXTHREADNAMESIZE
);
429 kernel_debug_string_simple(TRACE_STRING_THREADNAME_PREV
, ut
->pth_name
);
430 bzero(ut
->pth_name
, MAXTHREADNAMESIZE
);
432 error
= copyin(newp
, ut
->pth_name
, newlen
);
437 kernel_debug_string_simple(TRACE_STRING_THREADNAME
, ut
->pth_name
);
443 SYSCTL_PROC(_kern
, KERN_THREADNAME
, threadname
, CTLFLAG_ANYBODY
| CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, 0, sysctl_handle_kern_threadname
, "A", "");
447 sysctl_sched_stats(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
449 host_basic_info_data_t hinfo
;
453 mach_msg_type_number_t count
= HOST_BASIC_INFO_COUNT
;
454 struct _processor_statistics_np
*buf
;
457 kret
= host_info((host_t
)BSD_HOST
, HOST_BASIC_INFO
, (host_info_t
)&hinfo
, &count
);
458 if (kret
!= KERN_SUCCESS
) {
462 size
= sizeof(struct _processor_statistics_np
) * (hinfo
.logical_cpu_max
+ 2); /* One for RT Queue, One for Fair Share Queue */
464 if (req
->oldlen
< size
) {
468 MALLOC(buf
, struct _processor_statistics_np
*, size
, M_TEMP
, M_ZERO
| M_WAITOK
);
470 kret
= get_sched_statistics(buf
, &size
);
471 if (kret
!= KERN_SUCCESS
) {
476 error
= sysctl_io_opaque(req
, buf
, size
, &changed
);
482 panic("Sched info changed?!");
489 SYSCTL_PROC(_kern
, OID_AUTO
, sched_stats
, CTLFLAG_LOCKED
, 0, 0, sysctl_sched_stats
, "-", "");
492 sysctl_sched_stats_enable(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, __unused
struct sysctl_req
*req
)
497 if (req
->newlen
!= sizeof(active
)) {
501 res
= copyin(req
->newptr
, &active
, sizeof(active
));
506 return set_sched_stats_active(active
);
509 SYSCTL_PROC(_kern
, OID_AUTO
, sched_stats_enable
, CTLFLAG_LOCKED
| CTLFLAG_WR
, 0, 0, sysctl_sched_stats_enable
, "-", "");
511 extern uint32_t sched_debug_flags
;
512 SYSCTL_INT(_debug
, OID_AUTO
, sched
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &sched_debug_flags
, 0, "scheduler debug");
514 #if (DEBUG || DEVELOPMENT)
515 extern boolean_t doprnt_hide_pointers
;
516 SYSCTL_INT(_debug
, OID_AUTO
, hide_kernel_pointers
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &doprnt_hide_pointers
, 0, "hide kernel pointers from log");
519 extern int get_kernel_symfile(proc_t
, char **);
522 #define KERN_COUNT_SYSCALLS (KERN_OSTYPE + 1000)
524 extern const unsigned int nsysent
;
525 extern int syscalls_log
[];
526 extern const char *syscallnames
[];
529 sysctl_docountsyscalls SYSCTL_HANDLER_ARGS
531 __unused
int cmd
= oidp
->oid_arg2
; /* subcommand*/
532 __unused
int *name
= arg1
; /* oid element argument vector */
533 __unused
int namelen
= arg2
; /* number of oid element arguments */
534 user_addr_t oldp
= req
->oldptr
; /* user buffer copy out address */
535 size_t *oldlenp
= &req
->oldlen
; /* user buffer copy out size */
536 user_addr_t newp
= req
->newptr
; /* user buffer copy in address */
537 size_t newlen
= req
->newlen
; /* user buffer copy in size */
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_int(oldp
, oldlenp
, newp
, newlen
, &tmp
);
556 do_count_syscalls
= 1;
557 } else if (tmp
== 0 || tmp
== 2 || tmp
== 3) {
559 for (i
= 0; i
< nsysent
; i
++) {
560 if (syscalls_log
[i
] != 0) {
562 printf("%d calls - name %s \n", syscalls_log
[i
], syscallnames
[i
]);
569 do_count_syscalls
= 1;
573 /* adjust index so we return the right required/consumed amount */
575 req
->oldidx
+= req
->oldlen
;
580 SYSCTL_PROC(_kern
, KERN_COUNT_SYSCALLS
, count_syscalls
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
581 0, /* Pointer argument (arg1) */
582 0, /* Integer argument (arg2) */
583 sysctl_docountsyscalls
, /* Handler function */
584 NULL
, /* Data pointer */
586 #endif /* COUNT_SYSCALLS */
589 * The following sysctl_* functions should not be used
590 * any more, as they can only cope with callers in
591 * user mode: Use new-style
599 * Validate parameters and get old / set new parameters
600 * for an integer-valued sysctl function.
603 sysctl_int(user_addr_t oldp
, size_t *oldlenp
,
604 user_addr_t newp
, size_t newlen
, int *valp
)
608 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
) {
611 if (oldp
&& *oldlenp
< sizeof(int)) {
614 if (newp
&& newlen
!= sizeof(int)) {
617 *oldlenp
= sizeof(int);
619 error
= copyout(valp
, oldp
, sizeof(int));
621 if (error
== 0 && newp
) {
622 error
= copyin(newp
, valp
, sizeof(int));
623 AUDIT_ARG(value32
, *valp
);
629 * Validate parameters and get old / set new parameters
630 * for an quad(64bit)-valued sysctl function.
633 sysctl_quad(user_addr_t oldp
, size_t *oldlenp
,
634 user_addr_t newp
, size_t newlen
, quad_t
*valp
)
638 if (oldp
!= USER_ADDR_NULL
&& oldlenp
== NULL
) {
641 if (oldp
&& *oldlenp
< sizeof(quad_t
)) {
644 if (newp
&& newlen
!= sizeof(quad_t
)) {
647 *oldlenp
= sizeof(quad_t
);
649 error
= copyout(valp
, oldp
, sizeof(quad_t
));
651 if (error
== 0 && newp
) {
652 error
= copyin(newp
, valp
, sizeof(quad_t
));
658 sysdoproc_filt_KERN_PROC_PID(proc_t p
, void * arg
)
660 if (p
->p_pid
!= (pid_t
)*(int*)arg
) {
668 sysdoproc_filt_KERN_PROC_PGRP(proc_t p
, void * arg
)
670 if (p
->p_pgrpid
!= (pid_t
)*(int*)arg
) {
678 sysdoproc_filt_KERN_PROC_TTY(proc_t p
, void * arg
)
683 /* This is very racy but list lock is held.. Hmmm. */
684 if ((p
->p_flag
& P_CONTROLT
) == 0 ||
685 (p
->p_pgrp
== NULL
) || (p
->p_pgrp
->pg_session
== NULL
) ||
686 (tp
= SESSION_TP(p
->p_pgrp
->pg_session
)) == TTY_NULL
||
687 tp
->t_dev
!= (dev_t
)*(int*)arg
) {
697 sysdoproc_filt_KERN_PROC_UID(proc_t p
, void * arg
)
699 kauth_cred_t my_cred
;
702 if (p
->p_ucred
== NULL
) {
705 my_cred
= kauth_cred_proc_ref(p
);
706 uid
= kauth_cred_getuid(my_cred
);
707 kauth_cred_unref(&my_cred
);
709 if (uid
!= (uid_t
)*(int*)arg
) {
718 sysdoproc_filt_KERN_PROC_RUID(proc_t p
, void * arg
)
720 kauth_cred_t my_cred
;
723 if (p
->p_ucred
== NULL
) {
726 my_cred
= kauth_cred_proc_ref(p
);
727 ruid
= kauth_cred_getruid(my_cred
);
728 kauth_cred_unref(&my_cred
);
730 if (ruid
!= (uid_t
)*(int*)arg
) {
738 * try over estimating by 5 procs
740 #define KERN_PROCSLOP (5 * sizeof(struct kinfo_proc))
741 struct sysdoproc_args
{
747 unsigned int sizeof_kproc
;
756 sysdoproc_callback(proc_t p
, void *arg
)
758 struct sysdoproc_args
*args
= arg
;
760 if (args
->buflen
>= args
->sizeof_kproc
) {
761 if ((args
->ruidcheck
!= 0) && (sysdoproc_filt_KERN_PROC_RUID(p
, &args
->uidval
) == 0)) {
762 return PROC_RETURNED
;
764 if ((args
->uidcheck
!= 0) && (sysdoproc_filt_KERN_PROC_UID(p
, &args
->uidval
) == 0)) {
765 return PROC_RETURNED
;
767 if ((args
->ttycheck
!= 0) && (sysdoproc_filt_KERN_PROC_TTY(p
, &args
->uidval
) == 0)) {
768 return PROC_RETURNED
;
771 bzero(args
->kprocp
, args
->sizeof_kproc
);
772 if (args
->is_64_bit
) {
773 fill_user64_proc(p
, args
->kprocp
);
775 fill_user32_proc(p
, args
->kprocp
);
777 int error
= copyout(args
->kprocp
, args
->dp
, args
->sizeof_kproc
);
779 *args
->errorp
= error
;
780 return PROC_RETURNED_DONE
;
782 args
->dp
+= args
->sizeof_kproc
;
783 args
->buflen
-= args
->sizeof_kproc
;
785 args
->needed
+= args
->sizeof_kproc
;
786 return PROC_RETURNED
;
789 SYSCTL_NODE(_kern
, KERN_PROC
, proc
, CTLFLAG_RD
| CTLFLAG_LOCKED
, 0, "");
791 sysctl_prochandle SYSCTL_HANDLER_ARGS
793 int cmd
= oidp
->oid_arg2
; /* subcommand for multiple nodes */
794 int *name
= arg1
; /* oid element argument vector */
795 int namelen
= arg2
; /* number of oid element arguments */
796 user_addr_t where
= req
->oldptr
;/* user buffer copy out address */
798 user_addr_t dp
= where
;
800 size_t buflen
= where
!= USER_ADDR_NULL
? req
->oldlen
: 0;
802 boolean_t is_64_bit
= proc_is64bit(current_proc());
803 struct user32_kinfo_proc user32_kproc
;
804 struct user64_kinfo_proc user_kproc
;
807 int (*filterfn
)(proc_t
, void *) = 0;
808 struct sysdoproc_args args
;
813 if (namelen
!= 1 && !(namelen
== 0 && cmd
== KERN_PROC_ALL
)) {
818 sizeof_kproc
= sizeof(user_kproc
);
819 kprocp
= &user_kproc
;
821 sizeof_kproc
= sizeof(user32_kproc
);
822 kprocp
= &user32_kproc
;
827 filterfn
= sysdoproc_filt_KERN_PROC_PID
;
831 filterfn
= sysdoproc_filt_KERN_PROC_PGRP
;
850 /* must be kern.proc.<unknown> */
855 args
.buflen
= buflen
;
856 args
.kprocp
= kprocp
;
857 args
.is_64_bit
= is_64_bit
;
859 args
.needed
= needed
;
860 args
.errorp
= &error
;
861 args
.uidcheck
= uidcheck
;
862 args
.ruidcheck
= ruidcheck
;
863 args
.ttycheck
= ttycheck
;
864 args
.sizeof_kproc
= sizeof_kproc
;
866 args
.uidval
= name
[0];
869 proc_iterate((PROC_ALLPROCLIST
| PROC_ZOMBPROCLIST
),
870 sysdoproc_callback
, &args
, filterfn
, name
);
877 needed
= args
.needed
;
879 if (where
!= USER_ADDR_NULL
) {
880 req
->oldlen
= dp
- where
;
881 if (needed
> req
->oldlen
) {
885 needed
+= KERN_PROCSLOP
;
886 req
->oldlen
= needed
;
888 /* adjust index so we return the right required/consumed amount */
889 req
->oldidx
+= req
->oldlen
;
895 * We specify the subcommand code for multiple nodes as the 'req->arg2' value
896 * in the sysctl declaration itself, which comes into the handler function
897 * as 'oidp->oid_arg2'.
899 * For these particular sysctls, since they have well known OIDs, we could
900 * have just obtained it from the '((int *)arg1)[0]' parameter, but that would
901 * not demonstrate how to handle multiple sysctls that used OID_AUTO instead
902 * of a well known value with a common handler function. This is desirable,
903 * because we want well known values to "go away" at some future date.
905 * It should be noted that the value of '((int *)arg1)[1]' is used for many
906 * an integer parameter to the subcommand for many of these sysctls; we'd
907 * rather have used '((int *)arg1)[0]' for that, or even better, an element
908 * in a structure passed in as the the 'newp' argument to sysctlbyname(3),
909 * and then use leaf-node permissions enforcement, but that would have
910 * necessitated modifying user space code to correspond to the interface
911 * change, and we are striving for binary backward compatibility here; even
912 * though these are SPI, and not intended for use by user space applications
913 * which are not themselves system tools or libraries, some applications
914 * have erroneously used them.
916 SYSCTL_PROC(_kern_proc
, KERN_PROC_ALL
, all
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
917 0, /* Pointer argument (arg1) */
918 KERN_PROC_ALL
, /* Integer argument (arg2) */
919 sysctl_prochandle
, /* Handler function */
920 NULL
, /* Data is size variant on ILP32/LP64 */
922 SYSCTL_PROC(_kern_proc
, KERN_PROC_PID
, pid
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
923 0, /* Pointer argument (arg1) */
924 KERN_PROC_PID
, /* Integer argument (arg2) */
925 sysctl_prochandle
, /* Handler function */
926 NULL
, /* Data is size variant on ILP32/LP64 */
928 SYSCTL_PROC(_kern_proc
, KERN_PROC_TTY
, tty
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
929 0, /* Pointer argument (arg1) */
930 KERN_PROC_TTY
, /* Integer argument (arg2) */
931 sysctl_prochandle
, /* Handler function */
932 NULL
, /* Data is size variant on ILP32/LP64 */
934 SYSCTL_PROC(_kern_proc
, KERN_PROC_PGRP
, pgrp
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
935 0, /* Pointer argument (arg1) */
936 KERN_PROC_PGRP
, /* Integer argument (arg2) */
937 sysctl_prochandle
, /* Handler function */
938 NULL
, /* Data is size variant on ILP32/LP64 */
940 SYSCTL_PROC(_kern_proc
, KERN_PROC_UID
, uid
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
941 0, /* Pointer argument (arg1) */
942 KERN_PROC_UID
, /* Integer argument (arg2) */
943 sysctl_prochandle
, /* Handler function */
944 NULL
, /* Data is size variant on ILP32/LP64 */
946 SYSCTL_PROC(_kern_proc
, KERN_PROC_RUID
, ruid
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
947 0, /* Pointer argument (arg1) */
948 KERN_PROC_RUID
, /* Integer argument (arg2) */
949 sysctl_prochandle
, /* Handler function */
950 NULL
, /* Data is size variant on ILP32/LP64 */
952 SYSCTL_PROC(_kern_proc
, KERN_PROC_LCID
, lcid
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
953 0, /* Pointer argument (arg1) */
954 KERN_PROC_LCID
, /* Integer argument (arg2) */
955 sysctl_prochandle
, /* Handler function */
956 NULL
, /* Data is size variant on ILP32/LP64 */
961 * Fill in non-zero fields of an eproc structure for the specified process.
964 fill_user32_eproc(proc_t p
, struct user32_eproc
*__restrict ep
)
968 struct session
*sessp
;
969 kauth_cred_t my_cred
;
972 sessp
= proc_session(p
);
974 if (pg
!= PGRP_NULL
) {
975 ep
->e_pgid
= p
->p_pgrpid
;
976 ep
->e_jobc
= pg
->pg_jobc
;
977 if (sessp
!= SESSION_NULL
&& sessp
->s_ttyvp
) {
978 ep
->e_flag
= EPROC_CTTY
;
981 ep
->e_ppid
= p
->p_ppid
;
983 my_cred
= kauth_cred_proc_ref(p
);
985 /* A fake historical pcred */
986 ep
->e_pcred
.p_ruid
= kauth_cred_getruid(my_cred
);
987 ep
->e_pcred
.p_svuid
= kauth_cred_getsvuid(my_cred
);
988 ep
->e_pcred
.p_rgid
= kauth_cred_getrgid(my_cred
);
989 ep
->e_pcred
.p_svgid
= kauth_cred_getsvgid(my_cred
);
991 /* A fake historical *kauth_cred_t */
992 unsigned long refcnt
= os_atomic_load(&my_cred
->cr_ref
, relaxed
);
993 ep
->e_ucred
.cr_ref
= (uint32_t)MIN(refcnt
, UINT32_MAX
);
994 ep
->e_ucred
.cr_uid
= kauth_cred_getuid(my_cred
);
995 ep
->e_ucred
.cr_ngroups
= (short)posix_cred_get(my_cred
)->cr_ngroups
;
996 bcopy(posix_cred_get(my_cred
)->cr_groups
,
997 ep
->e_ucred
.cr_groups
, NGROUPS
* sizeof(gid_t
));
999 kauth_cred_unref(&my_cred
);
1002 if ((p
->p_flag
& P_CONTROLT
) && (sessp
!= SESSION_NULL
) &&
1003 (tp
= SESSION_TP(sessp
))) {
1004 ep
->e_tdev
= tp
->t_dev
;
1005 ep
->e_tpgid
= sessp
->s_ttypgrpid
;
1010 if (sessp
!= SESSION_NULL
) {
1011 if (SESS_LEADER(p
, sessp
)) {
1012 ep
->e_flag
|= EPROC_SLEADER
;
1014 session_rele(sessp
);
1016 if (pg
!= PGRP_NULL
) {
1022 * Fill in non-zero fields of an LP64 eproc structure for the specified process.
1025 fill_user64_eproc(proc_t p
, struct user64_eproc
*__restrict ep
)
1029 struct session
*sessp
;
1030 kauth_cred_t my_cred
;
1033 sessp
= proc_session(p
);
1035 if (pg
!= PGRP_NULL
) {
1036 ep
->e_pgid
= p
->p_pgrpid
;
1037 ep
->e_jobc
= pg
->pg_jobc
;
1038 if (sessp
!= SESSION_NULL
&& sessp
->s_ttyvp
) {
1039 ep
->e_flag
= EPROC_CTTY
;
1042 ep
->e_ppid
= p
->p_ppid
;
1044 my_cred
= kauth_cred_proc_ref(p
);
1046 /* A fake historical pcred */
1047 ep
->e_pcred
.p_ruid
= kauth_cred_getruid(my_cred
);
1048 ep
->e_pcred
.p_svuid
= kauth_cred_getsvuid(my_cred
);
1049 ep
->e_pcred
.p_rgid
= kauth_cred_getrgid(my_cred
);
1050 ep
->e_pcred
.p_svgid
= kauth_cred_getsvgid(my_cred
);
1052 /* A fake historical *kauth_cred_t */
1053 unsigned long refcnt
= os_atomic_load(&my_cred
->cr_ref
, relaxed
);
1054 ep
->e_ucred
.cr_ref
= (uint32_t)MIN(refcnt
, UINT32_MAX
);
1055 ep
->e_ucred
.cr_uid
= kauth_cred_getuid(my_cred
);
1056 ep
->e_ucred
.cr_ngroups
= (short)posix_cred_get(my_cred
)->cr_ngroups
;
1057 bcopy(posix_cred_get(my_cred
)->cr_groups
,
1058 ep
->e_ucred
.cr_groups
, NGROUPS
* sizeof(gid_t
));
1060 kauth_cred_unref(&my_cred
);
1063 if ((p
->p_flag
& P_CONTROLT
) && (sessp
!= SESSION_NULL
) &&
1064 (tp
= SESSION_TP(sessp
))) {
1065 ep
->e_tdev
= tp
->t_dev
;
1066 ep
->e_tpgid
= sessp
->s_ttypgrpid
;
1071 if (sessp
!= SESSION_NULL
) {
1072 if (SESS_LEADER(p
, sessp
)) {
1073 ep
->e_flag
|= EPROC_SLEADER
;
1075 session_rele(sessp
);
1077 if (pg
!= PGRP_NULL
) {
1083 * Fill in an eproc structure for the specified process.
1084 * bzeroed by our caller, so only set non-zero fields.
1087 fill_user32_externproc(proc_t p
, struct user32_extern_proc
*__restrict exp
)
1089 exp
->p_starttime
.tv_sec
= (user32_time_t
)p
->p_start
.tv_sec
;
1090 exp
->p_starttime
.tv_usec
= p
->p_start
.tv_usec
;
1091 exp
->p_flag
= p
->p_flag
;
1092 if (p
->p_lflag
& P_LTRACED
) {
1093 exp
->p_flag
|= P_TRACED
;
1095 if (p
->p_lflag
& P_LPPWAIT
) {
1096 exp
->p_flag
|= P_PPWAIT
;
1098 if (p
->p_lflag
& P_LEXIT
) {
1099 exp
->p_flag
|= P_WEXIT
;
1101 exp
->p_stat
= p
->p_stat
;
1102 exp
->p_pid
= p
->p_pid
;
1103 exp
->p_oppid
= p
->p_oppid
;
1105 exp
->p_debugger
= p
->p_debugger
;
1106 exp
->sigwait
= p
->sigwait
;
1108 #ifdef _PROC_HAS_SCHEDINFO_
1109 exp
->p_estcpu
= p
->p_estcpu
;
1110 exp
->p_pctcpu
= p
->p_pctcpu
;
1111 exp
->p_slptime
= p
->p_slptime
;
1113 exp
->p_realtimer
.it_interval
.tv_sec
=
1114 (user32_time_t
)p
->p_realtimer
.it_interval
.tv_sec
;
1115 exp
->p_realtimer
.it_interval
.tv_usec
=
1116 (__int32_t
)p
->p_realtimer
.it_interval
.tv_usec
;
1118 exp
->p_realtimer
.it_value
.tv_sec
=
1119 (user32_time_t
)p
->p_realtimer
.it_value
.tv_sec
;
1120 exp
->p_realtimer
.it_value
.tv_usec
=
1121 (__int32_t
)p
->p_realtimer
.it_value
.tv_usec
;
1123 exp
->p_rtime
.tv_sec
= (user32_time_t
)p
->p_rtime
.tv_sec
;
1124 exp
->p_rtime
.tv_usec
= (__int32_t
)p
->p_rtime
.tv_usec
;
1126 exp
->p_sigignore
= p
->p_sigignore
;
1127 exp
->p_sigcatch
= p
->p_sigcatch
;
1128 exp
->p_priority
= p
->p_priority
;
1129 exp
->p_nice
= p
->p_nice
;
1130 bcopy(&p
->p_comm
, &exp
->p_comm
, MAXCOMLEN
);
1131 exp
->p_xstat
= (u_short
)MIN(p
->p_xstat
, USHRT_MAX
);
1132 exp
->p_acflag
= p
->p_acflag
;
1136 * Fill in an LP64 version of extern_proc structure for the specified process.
1139 fill_user64_externproc(proc_t p
, struct user64_extern_proc
*__restrict exp
)
1141 exp
->p_starttime
.tv_sec
= p
->p_start
.tv_sec
;
1142 exp
->p_starttime
.tv_usec
= p
->p_start
.tv_usec
;
1143 exp
->p_flag
= p
->p_flag
;
1144 if (p
->p_lflag
& P_LTRACED
) {
1145 exp
->p_flag
|= P_TRACED
;
1147 if (p
->p_lflag
& P_LPPWAIT
) {
1148 exp
->p_flag
|= P_PPWAIT
;
1150 if (p
->p_lflag
& P_LEXIT
) {
1151 exp
->p_flag
|= P_WEXIT
;
1153 exp
->p_stat
= p
->p_stat
;
1154 exp
->p_pid
= p
->p_pid
;
1155 exp
->p_oppid
= p
->p_oppid
;
1157 exp
->p_debugger
= p
->p_debugger
;
1158 exp
->sigwait
= p
->sigwait
;
1160 #ifdef _PROC_HAS_SCHEDINFO_
1161 exp
->p_estcpu
= p
->p_estcpu
;
1162 exp
->p_pctcpu
= p
->p_pctcpu
;
1163 exp
->p_slptime
= p
->p_slptime
;
1165 exp
->p_realtimer
.it_interval
.tv_sec
= p
->p_realtimer
.it_interval
.tv_sec
;
1166 exp
->p_realtimer
.it_interval
.tv_usec
= p
->p_realtimer
.it_interval
.tv_usec
;
1168 exp
->p_realtimer
.it_value
.tv_sec
= p
->p_realtimer
.it_value
.tv_sec
;
1169 exp
->p_realtimer
.it_value
.tv_usec
= p
->p_realtimer
.it_value
.tv_usec
;
1171 exp
->p_rtime
.tv_sec
= p
->p_rtime
.tv_sec
;
1172 exp
->p_rtime
.tv_usec
= p
->p_rtime
.tv_usec
;
1174 exp
->p_sigignore
= p
->p_sigignore
;
1175 exp
->p_sigcatch
= p
->p_sigcatch
;
1176 exp
->p_priority
= p
->p_priority
;
1177 exp
->p_nice
= p
->p_nice
;
1178 bcopy(&p
->p_comm
, &exp
->p_comm
, MAXCOMLEN
);
1179 exp
->p_xstat
= (u_short
)MIN(p
->p_xstat
, USHRT_MAX
);
1180 exp
->p_acflag
= p
->p_acflag
;
1184 fill_user32_proc(proc_t p
, struct user32_kinfo_proc
*__restrict kp
)
1186 /* on a 64 bit kernel, 32 bit users get some truncated information */
1187 fill_user32_externproc(p
, &kp
->kp_proc
);
1188 fill_user32_eproc(p
, &kp
->kp_eproc
);
1192 fill_user64_proc(proc_t p
, struct user64_kinfo_proc
*__restrict kp
)
1194 fill_user64_externproc(p
, &kp
->kp_proc
);
1195 fill_user64_eproc(p
, &kp
->kp_eproc
);
1199 sysctl_kdebug_ops SYSCTL_HANDLER_ARGS
1201 __unused
int cmd
= oidp
->oid_arg2
; /* subcommand*/
1202 int *name
= arg1
; /* oid element argument vector */
1203 int namelen
= arg2
; /* number of oid element arguments */
1204 user_addr_t oldp
= req
->oldptr
; /* user buffer copy out address */
1205 size_t *oldlenp
= &req
->oldlen
; /* user buffer copy out size */
1206 // user_addr_t newp = req->newptr; /* user buffer copy in address */
1207 // size_t newlen = req->newlen; /* user buffer copy in size */
1225 case KERN_KDWRITETR
:
1226 case KERN_KDWRITEMAP
:
1232 case KERN_KDREADCURTHRMAP
:
1233 case KERN_KDSET_TYPEFILTER
:
1234 case KERN_KDBUFWAIT
:
1236 case KERN_KDWRITEMAP_V3
:
1237 case KERN_KDWRITETR_V3
:
1238 ret
= kdbg_control(name
, namelen
, oldp
, oldlenp
);
1245 /* adjust index so we return the right required/consumed amount */
1247 req
->oldidx
+= req
->oldlen
;
1252 SYSCTL_PROC(_kern
, KERN_KDEBUG
, kdebug
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
1253 0, /* Pointer argument (arg1) */
1254 0, /* Integer argument (arg2) */
1255 sysctl_kdebug_ops
, /* Handler function */
1256 NULL
, /* Data pointer */
1260 #if defined(XNU_TARGET_OS_OSX)
1262 * Return the top *sizep bytes of the user stack, or the entire area of the
1263 * user stack down through the saved exec_path, whichever is smaller.
1266 sysctl_doprocargs SYSCTL_HANDLER_ARGS
1268 __unused
int cmd
= oidp
->oid_arg2
; /* subcommand*/
1269 int *name
= arg1
; /* oid element argument vector */
1270 int namelen
= arg2
; /* number of oid element arguments */
1271 user_addr_t oldp
= req
->oldptr
; /* user buffer copy out address */
1272 size_t *oldlenp
= &req
->oldlen
; /* user buffer copy out size */
1273 // user_addr_t newp = req->newptr; /* user buffer copy in address */
1274 // size_t newlen = req->newlen; /* user buffer copy in size */
1277 error
= sysctl_procargsx( name
, namelen
, oldp
, oldlenp
, current_proc(), 0);
1279 /* adjust index so we return the right required/consumed amount */
1281 req
->oldidx
+= req
->oldlen
;
1286 SYSCTL_PROC(_kern
, KERN_PROCARGS
, procargs
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
1287 0, /* Pointer argument (arg1) */
1288 0, /* Integer argument (arg2) */
1289 sysctl_doprocargs
, /* Handler function */
1290 NULL
, /* Data pointer */
1292 #endif /* defined(XNU_TARGET_OS_OSX) */
1295 sysctl_doprocargs2 SYSCTL_HANDLER_ARGS
1297 __unused
int cmd
= oidp
->oid_arg2
; /* subcommand*/
1298 int *name
= arg1
; /* oid element argument vector */
1299 int namelen
= arg2
; /* number of oid element arguments */
1300 user_addr_t oldp
= req
->oldptr
; /* user buffer copy out address */
1301 size_t *oldlenp
= &req
->oldlen
; /* user buffer copy out size */
1302 // user_addr_t newp = req->newptr; /* user buffer copy in address */
1303 // size_t newlen = req->newlen; /* user buffer copy in size */
1306 error
= sysctl_procargsx( name
, namelen
, oldp
, oldlenp
, current_proc(), 1);
1308 /* adjust index so we return the right required/consumed amount */
1310 req
->oldidx
+= req
->oldlen
;
1315 SYSCTL_PROC(_kern
, KERN_PROCARGS2
, procargs2
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
1316 0, /* Pointer argument (arg1) */
1317 0, /* Integer argument (arg2) */
1318 sysctl_doprocargs2
, /* Handler function */
1319 NULL
, /* Data pointer */
1322 #define SYSCTL_PROCARGS_READ_ENVVARS_ENTITLEMENT "com.apple.private.read-environment-variables"
1324 sysctl_procargsx(int *name
, u_int namelen
, user_addr_t where
,
1325 size_t *sizep
, proc_t cur_proc
, int argc_yes
)
1327 assert(sizep
!= NULL
);
1329 size_t buflen
= where
!= USER_ADDR_NULL
? *sizep
: 0;
1331 struct _vm_map
*proc_map
= NULL
;
1333 vm_map_copy_t tmp
= NULL
;
1334 user_addr_t arg_addr
;
1339 vm_offset_t copy_start
= 0, copy_end
;
1340 vm_offset_t smallbuffer_start
;
1343 kauth_cred_t my_cred
;
1348 size_t current_arg_index
;
1349 size_t current_arg_len
;
1350 const char * current_arg
;
1351 bool omit_env_vars
= true;
1359 buflen
-= sizeof(int); /* reserve first word to return argc */
1361 /* we only care about buflen when where (oldp from sysctl) is not NULL. */
1362 /* when where (oldp from sysctl) is NULL and sizep (oldlenp from sysctl */
1363 /* is not NULL then the caller wants us to return the length needed to */
1364 /* hold the data we would return */
1365 if (where
!= USER_ADDR_NULL
&& (buflen
<= 0 || buflen
> ARG_MAX
)) {
1371 * Lookup process by pid
1380 /* Allow reading environment variables if any of the following are true:
1381 * - kernel is DEVELOPMENT || DEBUG
1382 * - target process is same as current_proc()
1383 * - target process is not cs_restricted
1385 * - caller has an entitlement
1388 #if DEVELOPMENT || DEBUG
1389 omit_env_vars
= false;
1391 if (p
== current_proc() ||
1392 !cs_restricted(p
) ||
1394 csr_check(CSR_ALLOW_UNRESTRICTED_DTRACE
) == 0 ||
1396 IOTaskHasEntitlement(current_task(), SYSCTL_PROCARGS_READ_ENVVARS_ENTITLEMENT
)
1398 omit_env_vars
= false;
1402 * Copy the top N bytes of the stack.
1403 * On all machines we have so far, the stack grows
1406 * If the user expects no more than N bytes of
1407 * argument list, use that as a guess for the
1411 if (!p
->user_stack
) {
1416 /* save off argc before releasing the proc */
1419 argslen
= p
->p_argslen
;
1422 * When these sysctls were introduced, the first string in the strings
1423 * section was just the bare path of the executable. However, for security
1424 * reasons we now prefix this string with executable_path= so it can be
1425 * parsed getenv style. To avoid binary compatability issues with exising
1426 * callers of this sysctl, we strip it off here.
1427 * (rdar://problem/13746466)
1429 #define EXECUTABLE_KEY "executable_path="
1430 argslen
-= strlen(EXECUTABLE_KEY
);
1432 if (where
== USER_ADDR_NULL
&& !omit_env_vars
) {
1433 /* caller only wants to know length of proc args data.
1434 * If we don't need to omit environment variables, we can skip
1435 * copying the target process stack */
1436 goto calculate_size
;
1439 my_cred
= kauth_cred_proc_ref(p
);
1440 uid
= kauth_cred_getuid(my_cred
);
1441 kauth_cred_unref(&my_cred
);
1443 if ((uid
!= kauth_cred_getuid(kauth_cred_get()))
1444 && suser(kauth_cred_get(), &cur_proc
->p_acflag
)) {
1449 arg_size
= round_page(argslen
);
1451 arg_addr
= p
->user_stack
- arg_size
;
1454 * Before we can block (any VM code), make another
1455 * reference to the map to keep it alive. We do
1456 * that by getting a reference on the task itself.
1465 * Once we have a task reference we can convert that into a
1466 * map reference, which we will use in the calls below. The
1467 * task/process may change its map after we take this reference
1468 * (see execve), but the worst that will happen then is a return
1469 * of stale info (which is always a possibility).
1471 task_reference(task
);
1474 proc_map
= get_task_map_reference(task
);
1475 task_deallocate(task
);
1477 if (proc_map
== NULL
) {
1482 ret
= kmem_alloc(kernel_map
, ©_start
, arg_size
, VM_KERN_MEMORY_BSD
);
1483 if (ret
!= KERN_SUCCESS
) {
1487 bzero((void *)copy_start
, arg_size
);
1489 /* End of buffer should be page aligned */
1490 assert(copy_start
+ arg_size
== round_page(copy_start
+ arg_size
));
1491 copy_end
= copy_start
+ arg_size
;
1493 if (vm_map_copyin(proc_map
, (vm_map_address_t
)arg_addr
,
1494 (vm_map_size_t
)arg_size
, FALSE
, &tmp
) != KERN_SUCCESS
) {
1500 * Now that we've done the copyin from the process'
1501 * map, we can release the reference to it.
1503 vm_map_deallocate(proc_map
);
1506 if (vm_map_copy_overwrite(kernel_map
,
1507 (vm_map_address_t
)copy_start
,
1508 tmp
, (vm_map_size_t
) arg_size
, FALSE
) != KERN_SUCCESS
) {
1512 /* tmp was consumed */
1515 if (omit_env_vars
) {
1518 /* Iterate over everything in argv, plus one for the bare executable path */
1519 for (current_arg_index
= 0; current_arg_index
< argc
+ 1 && argvsize
< argslen
; ++current_arg_index
) {
1520 current_arg
= (const char *)(copy_end
- argslen
) + argvsize
;
1521 remaining
= argslen
- argvsize
;
1522 current_arg_len
= strnlen(current_arg
, remaining
);
1523 if (current_arg_len
< remaining
) {
1524 /* We have space for the null terminator */
1525 current_arg_len
+= 1;
1527 if (current_arg_index
== 0) {
1528 /* The bare executable path may have multiple null bytes after it for alignment */
1529 while (current_arg_len
< remaining
&& current_arg
[current_arg_len
] == 0) {
1530 current_arg_len
+= 1;
1534 argvsize
+= current_arg_len
;
1536 assert(argvsize
<= argslen
);
1538 /* Adjust argslen and copy_end to make the copyout range extend to the end of argv */
1539 copy_end
= copy_end
- argslen
+ argvsize
;
1543 if (where
== USER_ADDR_NULL
) {
1545 goto calculate_size
;
1548 if (buflen
>= argslen
) {
1549 data
= (caddr_t
) (copy_end
- argslen
);
1553 * Before rdar://25397314, this function contained incorrect logic when buflen is less
1554 * than argslen. The problem was that it copied in `buflen` bytes from the end of the target
1555 * process user stack into the beginning of a buffer of size round_page(buflen), and then
1556 * copied out `buflen` bytes from the end of this buffer. The effect of this was that
1557 * the caller of this sysctl would get zeros at the end of their buffer.
1559 * To preserve this behavior, bzero everything from copy_end-round_page(buflen)+buflen to the
1560 * end of the buffer. This emulates copying in only `buflen` bytes.
1565 * copy_start .... size: round_page(buflen) .... copy_end
1566 * [---copied in data (size: buflen)---|--- zeros ----------]
1568 * data = copy_end - buflen
1572 * copy_start .... size: round_page(p->argslen) .... full copy_end
1573 * ^ ....................... p->argslen ...............................^
1574 * ^ ^ truncated copy_end ^
1576 * ^ ................ argslen ........................ ^
1578 * [-------copied in data (size: round_page(p->argslen))-------:----env vars---]
1580 * ^ data = copy_end - buflen
1581 * smallbuffer_start = max(copy_end - round_page(buflen), copy_start)
1584 * Full copy_end: copy_end calculated from copy_start + round_page(p->argslen)
1585 * Truncated copy_end: copy_end after truncation to remove environment variables.
1587 * If environment variables were omitted, then we use the truncated copy_end, otherwise
1588 * we use full copy_end.
1590 * smallbuffer_start: represents where copy_start would be in the old code.
1591 * data: The beginning of the region we copyout
1593 smallbuffer_start
= copy_end
- round_page(buflen
);
1594 if (smallbuffer_start
< copy_start
) {
1595 smallbuffer_start
= copy_start
;
1597 bzero((void *)(smallbuffer_start
+ buflen
), copy_end
- (smallbuffer_start
+ buflen
));
1598 data
= (caddr_t
) (copy_end
- buflen
);
1603 /* Put processes argc as the first word in the copyout buffer */
1604 suword(where
, argc
);
1605 error
= copyout(data
, (where
+ sizeof(int)), size
);
1606 size
+= sizeof(int);
1608 error
= copyout(data
, where
, size
);
1611 * Make the old PROCARGS work to return the executable's path
1612 * But, only if there is enough space in the provided buffer
1614 * on entry: data [possibily] points to the beginning of the path
1616 * Note: we keep all pointers&sizes aligned to word boundries
1618 if ((!error
) && (buflen
> 0 && (u_int
)buflen
> size
)) {
1619 int binPath_sz
, alignedBinPath_sz
= 0;
1620 int extraSpaceNeeded
, addThis
;
1621 user_addr_t placeHere
;
1622 char * str
= (char *) data
;
1623 size_t max_len
= size
;
1625 /* Some apps are really bad about messing up their stacks
1626 * So, we have to be extra careful about getting the length
1627 * of the executing binary. If we encounter an error, we bail.
1630 /* Limit ourselves to PATH_MAX paths */
1631 if (max_len
> PATH_MAX
) {
1637 while ((binPath_sz
< max_len
- 1) && (*str
++ != 0)) {
1641 /* If we have a NUL terminator, copy it, too */
1642 if (binPath_sz
< max_len
- 1) {
1646 /* Pre-Flight the space requiremnts */
1648 /* Account for the padding that fills out binPath to the next word */
1649 alignedBinPath_sz
+= (binPath_sz
& (sizeof(int) - 1)) ? (sizeof(int) - (binPath_sz
& (sizeof(int) - 1))) : 0;
1651 placeHere
= where
+ size
;
1653 /* Account for the bytes needed to keep placeHere word aligned */
1654 addThis
= (placeHere
& (sizeof(int) - 1)) ? (sizeof(int) - (placeHere
& (sizeof(int) - 1))) : 0;
1656 /* Add up all the space that is needed */
1657 extraSpaceNeeded
= alignedBinPath_sz
+ addThis
+ binPath_sz
+ (4 * sizeof(int));
1659 /* is there is room to tack on argv[0]? */
1660 if ((buflen
& ~(sizeof(int) - 1)) >= (size
+ extraSpaceNeeded
)) {
1661 placeHere
+= addThis
;
1662 suword(placeHere
, 0);
1663 placeHere
+= sizeof(int);
1664 suword(placeHere
, 0xBFFF0000);
1665 placeHere
+= sizeof(int);
1666 suword(placeHere
, 0);
1667 placeHere
+= sizeof(int);
1668 error
= copyout(data
, placeHere
, binPath_sz
);
1670 placeHere
+= binPath_sz
;
1671 suword(placeHere
, 0);
1672 size
+= extraSpaceNeeded
;
1679 /* Size has already been calculated for the where != NULL case */
1680 if (where
== USER_ADDR_NULL
) {
1683 size
+= sizeof(int);
1686 * old PROCARGS will return the executable's path and plus some
1687 * extra space for work alignment and data tags
1689 size
+= PATH_MAX
+ (6 * sizeof(int));
1691 size
+= (size
& (sizeof(int) - 1)) ? (sizeof(int) - (size
& (sizeof(int) - 1))) : 0;
1701 vm_map_copy_discard(tmp
);
1703 if (proc_map
!= NULL
) {
1704 vm_map_deallocate(proc_map
);
1706 if (copy_start
!= (vm_offset_t
) 0) {
1707 kmem_free(kernel_map
, copy_start
, arg_size
);
1714 * Max number of concurrent aio requests
1718 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1720 int new_value
, changed
;
1721 int error
= sysctl_io_number(req
, aio_max_requests
, sizeof(int), &new_value
, &changed
);
1723 /* make sure the system-wide limit is greater than the per process limit */
1724 if (new_value
>= aio_max_requests_per_process
&& new_value
<= AIO_MAX_REQUESTS
) {
1725 aio_max_requests
= new_value
;
1735 * Max number of concurrent aio requests per process
1739 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1741 int new_value
, changed
;
1742 int error
= sysctl_io_number(req
, aio_max_requests_per_process
, sizeof(int), &new_value
, &changed
);
1744 /* make sure per process limit is less than the system-wide limit */
1745 if (new_value
<= aio_max_requests
&& new_value
>= AIO_LISTIO_MAX
) {
1746 aio_max_requests_per_process
= new_value
;
1756 * Max number of async IO worker threads
1760 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1762 int new_value
, changed
;
1763 int error
= sysctl_io_number(req
, aio_worker_threads
, sizeof(int), &new_value
, &changed
);
1765 /* we only allow an increase in the number of worker threads */
1766 if (new_value
> aio_worker_threads
) {
1767 _aio_create_worker_threads((new_value
- aio_worker_threads
));
1768 aio_worker_threads
= new_value
;
1778 * System-wide limit on the max number of processes
1782 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1784 int new_value
, changed
;
1785 int error
= sysctl_io_number(req
, maxproc
, sizeof(int), &new_value
, &changed
);
1787 AUDIT_ARG(value32
, new_value
);
1788 /* make sure the system-wide limit is less than the configured hard
1789 * limit set at kernel compilation */
1790 if (new_value
<= hard_maxproc
&& new_value
> 0) {
1791 maxproc
= new_value
;
1799 extern int sched_enable_smt
;
1801 sysctl_sched_enable_smt
1802 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1804 int new_value
, changed
;
1805 int error
= sysctl_io_number(req
, sched_enable_smt
, sizeof(int), &new_value
, &changed
);
1809 kern_return_t kret
= KERN_SUCCESS
;
1811 AUDIT_ARG(value32
, new_value
);
1812 if (new_value
== 0) {
1813 sched_enable_smt
= 0;
1814 kret
= enable_smt_processors(false);
1816 sched_enable_smt
= 1;
1817 kret
= enable_smt_processors(true);
1824 case KERN_INVALID_ARGUMENT
:
1838 SYSCTL_STRING(_kern
, KERN_OSTYPE
, ostype
,
1839 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
1841 SYSCTL_STRING(_kern
, KERN_OSRELEASE
, osrelease
,
1842 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
1844 SYSCTL_INT(_kern
, KERN_OSREV
, osrevision
,
1845 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
1846 (int *)NULL
, BSD
, "");
1847 SYSCTL_STRING(_kern
, KERN_VERSION
, version
,
1848 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
1850 SYSCTL_STRING(_kern
, OID_AUTO
, uuid
,
1851 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
1852 &kernel_uuid_string
[0], 0, "");
1854 SYSCTL_STRING(_kern
, OID_AUTO
, osbuildconfig
,
1855 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
,
1856 &osbuild_config
[0], 0, "");
1859 sysctl_protoboot(__unused
struct sysctl_oid
*oidp
,
1860 __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1863 #if CONFIG_LOCKERBOOT
1864 char protoboot_buff
[24];
1865 size_t protoboot_len
= sizeof(protoboot_buff
);
1867 if (vnode_tag(rootvnode
) == VT_LOCKERFS
) {
1868 strlcpy(protoboot_buff
, kernel_protoboot_mount
, protoboot_len
);
1869 error
= sysctl_io_string(req
, protoboot_buff
, protoboot_len
, 0, NULL
);
1882 SYSCTL_PROC(_kern
, OID_AUTO
, protoboot
,
1883 CTLTYPE_STRING
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
1884 0, 0, sysctl_protoboot
, "A", "");
1893 int debug_kprint_syscall
= 0;
1894 char debug_kprint_syscall_process
[MAXCOMLEN
+ 1];
1896 /* Thread safe: bits and string value are not used to reclaim state */
1897 SYSCTL_INT(_debug
, OID_AUTO
, kprint_syscall
,
1898 CTLFLAG_RW
| CTLFLAG_LOCKED
, &debug_kprint_syscall
, 0, "kprintf syscall tracing");
1899 SYSCTL_STRING(_debug
, OID_AUTO
, kprint_syscall_process
,
1900 CTLFLAG_RW
| CTLFLAG_LOCKED
, debug_kprint_syscall_process
, sizeof(debug_kprint_syscall_process
),
1901 "name of process for kprintf syscall tracing");
1904 debug_kprint_current_process(const char **namep
)
1906 struct proc
*p
= current_proc();
1912 if (debug_kprint_syscall_process
[0]) {
1913 /* user asked to scope tracing to a particular process name */
1914 if (0 == strncmp(debug_kprint_syscall_process
,
1915 p
->p_comm
, sizeof(debug_kprint_syscall_process
))) {
1916 /* no value in telling the user that we traced what they asked */
1927 /* trace all processes. Tell user what we traced */
1936 /* PR-5293665: need to use a callback function for kern.osversion to set
1937 * osversion in IORegistry */
1940 sysctl_osversion(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
1944 rval
= sysctl_handle_string(oidp
, arg1
, arg2
, req
);
1947 IORegistrySetOSBuildVersion((char *)arg1
);
1953 SYSCTL_PROC(_kern
, KERN_OSVERSION
, osversion
,
1954 CTLFLAG_RW
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
1955 osversion
, 256 /* OSVERSIZE*/,
1956 sysctl_osversion
, "A", "");
1959 _already_set_or_not_launchd(struct sysctl_req
*req
, char *val
)
1961 if (req
->newptr
!= 0) {
1963 * Can only ever be set by launchd, and only once at boot.
1965 if (req
->p
->p_pid
!= 1 || val
[0] != '\0') {
1972 #if XNU_TARGET_OS_OSX
1974 sysctl_system_version_compat
1975 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
1977 int oldval
= (task_has_system_version_compat_enabled(current_task()));
1978 int new_value
= 0, changed
= 0;
1980 int error
= sysctl_io_number(req
, oldval
, sizeof(int), &new_value
, &changed
);
1982 task_set_system_version_compat_enabled(current_task(), (new_value
));
1987 SYSCTL_PROC(_kern
, OID_AUTO
, system_version_compat
,
1988 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
,
1989 0, 0, sysctl_system_version_compat
, "A", "");
1991 char osproductversioncompat
[48] = { '\0' };
1994 sysctl_osproductversioncompat(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
1996 if (_already_set_or_not_launchd(req
, osproductversioncompat
)) {
1999 return sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2003 SYSCTL_PROC(_kern
, OID_AUTO
, osproductversioncompat
,
2004 CTLFLAG_RW
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2005 osproductversioncompat
, sizeof(osproductversioncompat
),
2006 sysctl_osproductversioncompat
, "A", "The ProductVersion from SystemVersionCompat.plist");
2009 char osproductversion
[48] = { '\0' };
2012 sysctl_osproductversion(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2014 if (_already_set_or_not_launchd(req
, osproductversion
)) {
2018 #if !XNU_TARGET_OS_OSX
2019 return sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2021 if (task_has_system_version_compat_enabled(current_task()) && (osproductversioncompat
[0] != '\0')) {
2022 return sysctl_handle_string(oidp
, osproductversioncompat
, arg2
, req
);
2024 return sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2029 #if XNU_TARGET_OS_OSX
2030 static_assert(sizeof(osproductversioncompat
) == sizeof(osproductversion
),
2031 "osproductversion size matches osproductversioncompat size");
2034 SYSCTL_PROC(_kern
, OID_AUTO
, osproductversion
,
2035 CTLFLAG_RW
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2036 osproductversion
, sizeof(osproductversion
),
2037 sysctl_osproductversion
, "A", "The ProductVersion from SystemVersion.plist");
2039 char osreleasetype
[48] = { '\0' };
2042 sysctl_osreleasetype(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2044 if (_already_set_or_not_launchd(req
, osreleasetype
)) {
2047 return sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2050 void reset_osreleasetype(void);
2053 reset_osreleasetype(void)
2055 memset(osreleasetype
, 0, sizeof(osreleasetype
));
2058 SYSCTL_PROC(_kern
, OID_AUTO
, osreleasetype
,
2059 CTLFLAG_RW
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2060 osreleasetype
, sizeof(osreleasetype
),
2061 sysctl_osreleasetype
, "A", "The ReleaseType from SystemVersion.plist");
2063 static uint64_t iossupportversion_string
[48];
2066 sysctl_iossupportversion(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2068 if (req
->newptr
!= 0) {
2070 * Can only ever be set by launchd, and only once at boot.
2072 if (req
->p
->p_pid
!= 1 || iossupportversion_string
[0] != '\0') {
2077 return sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2080 SYSCTL_PROC(_kern
, OID_AUTO
, iossupportversion
,
2081 CTLFLAG_RW
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2082 iossupportversion_string
, sizeof(iossupportversion_string
),
2083 sysctl_iossupportversion
, "A", "The iOSSupportVersion from SystemVersion.plist");
2085 static uint64_t osvariant_status
= 0;
2088 sysctl_osvariant_status(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2090 if (req
->newptr
!= 0) {
2092 * Can only ever be set by launchd, and only once.
2093 * Reset by usrctl() -> reset_osvariant_status() during
2094 * userspace reboot, since userspace could reboot into
2095 * a different variant.
2097 if (req
->p
->p_pid
!= 1 || osvariant_status
!= 0) {
2102 return sysctl_handle_quad(oidp
, arg1
, arg2
, req
);
2105 SYSCTL_PROC(_kern
, OID_AUTO
, osvariant_status
,
2106 CTLFLAG_RW
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
,
2107 &osvariant_status
, sizeof(osvariant_status
),
2108 sysctl_osvariant_status
, "Q", "Opaque flags used to cache OS variant information");
2110 void reset_osvariant_status(void);
2113 reset_osvariant_status(void)
2115 osvariant_status
= 0;
2118 extern void commpage_update_dyld_flags(uint64_t);
2119 uint64_t dyld_flags
= 0;
2122 sysctl_dyld_flags(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2125 * Can only ever be set by launchd, possibly several times
2126 * as dyld may change its mind after a userspace reboot.
2128 if (req
->newptr
!= 0 && req
->p
->p_pid
!= 1) {
2132 int res
= sysctl_handle_quad(oidp
, arg1
, arg2
, req
);
2133 if (req
->newptr
&& res
== 0) {
2134 commpage_update_dyld_flags(dyld_flags
);
2139 SYSCTL_PROC(_kern
, OID_AUTO
, dyld_flags
,
2140 CTLFLAG_RW
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
,
2141 &dyld_flags
, sizeof(dyld_flags
),
2142 sysctl_dyld_flags
, "Q", "Opaque flags used to cache dyld system-wide configuration");
2144 #if defined(XNU_TARGET_OS_BRIDGE)
2145 char macosproductversion
[MACOS_VERS_LEN
] = { '\0' };
2147 SYSCTL_STRING(_kern
, OID_AUTO
, macosproductversion
,
2148 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2149 &macosproductversion
[0], MACOS_VERS_LEN
, "The currently running macOS ProductVersion (from SystemVersion.plist on macOS)");
2151 char macosversion
[MACOS_VERS_LEN
] = { '\0' };
2153 SYSCTL_STRING(_kern
, OID_AUTO
, macosversion
,
2154 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2155 &macosversion
[0], MACOS_VERS_LEN
, "The currently running macOS build version");
2159 sysctl_sysctl_bootargs
2160 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2163 char buf
[BOOT_LINE_LENGTH
];
2165 strlcpy(buf
, PE_boot_args(), BOOT_LINE_LENGTH
);
2166 error
= sysctl_io_string(req
, buf
, BOOT_LINE_LENGTH
, 0, NULL
);
2170 SYSCTL_PROC(_kern
, OID_AUTO
, bootargs
,
2171 CTLFLAG_LOCKED
| CTLFLAG_RD
| CTLFLAG_KERN
| CTLTYPE_STRING
,
2173 sysctl_sysctl_bootargs
, "A", "bootargs");
2176 sysctl_kernelcacheuuid(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2179 if (kernelcache_uuid_valid
) {
2180 rval
= sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2185 SYSCTL_PROC(_kern
, OID_AUTO
, kernelcacheuuid
,
2186 CTLFLAG_RD
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2187 kernelcache_uuid_string
, sizeof(kernelcache_uuid_string
),
2188 sysctl_kernelcacheuuid
, "A", "");
2191 sysctl_systemfilesetuuid(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2194 if (pageablekc_uuid_valid
) {
2195 rval
= sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2200 SYSCTL_PROC(_kern
, OID_AUTO
, systemfilesetuuid
,
2201 CTLFLAG_RD
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2202 pageablekc_uuid_string
, sizeof(pageablekc_uuid_string
),
2203 sysctl_systemfilesetuuid
, "A", "");
2206 sysctl_auxiliaryfilesetuuid(struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2209 if (auxkc_uuid_valid
) {
2210 rval
= sysctl_handle_string(oidp
, arg1
, arg2
, req
);
2215 SYSCTL_PROC(_kern
, OID_AUTO
, auxiliaryfilesetuuid
,
2216 CTLFLAG_RD
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2217 auxkc_uuid_string
, sizeof(auxkc_uuid_string
),
2218 sysctl_auxiliaryfilesetuuid
, "A", "");
2221 sysctl_filesetuuid(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2224 kc_format_t kcformat
;
2225 kernel_mach_header_t
*mh
;
2227 unsigned long uuidlen
= 0;
2228 uuid_string_t uuid_str
;
2230 if (!PE_get_primary_kc_format(&kcformat
) || kcformat
!= KCFormatFileset
) {
2234 mh
= (kernel_mach_header_t
*)PE_get_kc_header(KCKindPrimary
);
2235 uuid
= getuuidfromheader(mh
, &uuidlen
);
2237 if ((uuid
!= NULL
) && (uuidlen
== sizeof(uuid_t
))) {
2238 uuid_unparse_upper(*(uuid_t
*)uuid
, uuid_str
);
2239 rval
= sysctl_io_string(req
, (char *)uuid_str
, sizeof(uuid_str
), 0, NULL
);
2245 SYSCTL_PROC(_kern
, OID_AUTO
, filesetuuid
,
2246 CTLFLAG_RD
| CTLFLAG_KERN
| CTLTYPE_STRING
| CTLFLAG_LOCKED
,
2248 sysctl_filesetuuid
, "A", "");
2251 SYSCTL_INT(_kern
, KERN_MAXFILES
, maxfiles
,
2252 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2254 SYSCTL_INT(_kern
, KERN_ARGMAX
, argmax
,
2255 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2256 (int *)NULL
, ARG_MAX
, "");
2257 SYSCTL_INT(_kern
, KERN_POSIX1
, posix1version
,
2258 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2259 (int *)NULL
, _POSIX_VERSION
, "");
2260 SYSCTL_INT(_kern
, KERN_NGROUPS
, ngroups
,
2261 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2262 (int *)NULL
, NGROUPS_MAX
, "");
2263 SYSCTL_INT(_kern
, KERN_JOB_CONTROL
, job_control
,
2264 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2265 (int *)NULL
, 1, "");
2266 #if 1 /* _POSIX_SAVED_IDS from <unistd.h> */
2267 SYSCTL_INT(_kern
, KERN_SAVED_IDS
, saved_ids
,
2268 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2269 (int *)NULL
, 1, "");
2271 SYSCTL_INT(_kern
, KERN_SAVED_IDS
, saved_ids
,
2272 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2275 SYSCTL_INT(_kern
, OID_AUTO
, num_files
,
2276 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2278 SYSCTL_COMPAT_INT(_kern
, OID_AUTO
, num_vnodes
,
2279 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2281 SYSCTL_INT(_kern
, OID_AUTO
, num_tasks
,
2282 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2284 SYSCTL_INT(_kern
, OID_AUTO
, num_threads
,
2285 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2286 &thread_max
, 0, "");
2287 SYSCTL_INT(_kern
, OID_AUTO
, num_taskthreads
,
2288 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2289 &task_threadmax
, 0, "");
2290 SYSCTL_LONG(_kern
, OID_AUTO
, num_recycledvnodes
,
2291 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2292 &num_recycledvnodes
, "");
2295 sysctl_maxvnodes(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2297 int oldval
= desiredvnodes
;
2298 int error
= sysctl_io_number(req
, desiredvnodes
, sizeof(int), &desiredvnodes
, NULL
);
2300 if (oldval
!= desiredvnodes
) {
2301 resize_namecache(desiredvnodes
);
2307 SYSCTL_INT(_kern
, OID_AUTO
, namecache_disabled
,
2308 CTLFLAG_RW
| CTLFLAG_LOCKED
,
2309 &nc_disabled
, 0, "");
2311 SYSCTL_PROC(_kern
, KERN_MAXVNODES
, maxvnodes
,
2312 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2313 0, 0, sysctl_maxvnodes
, "I", "");
2315 SYSCTL_PROC(_kern
, KERN_MAXPROC
, maxproc
,
2316 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2317 0, 0, sysctl_maxproc
, "I", "");
2319 SYSCTL_PROC(_kern
, KERN_AIOMAX
, aiomax
,
2320 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2321 0, 0, sysctl_aiomax
, "I", "");
2323 SYSCTL_PROC(_kern
, KERN_AIOPROCMAX
, aioprocmax
,
2324 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2325 0, 0, sysctl_aioprocmax
, "I", "");
2327 SYSCTL_PROC(_kern
, KERN_AIOTHREADS
, aiothreads
,
2328 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2329 0, 0, sysctl_aiothreads
, "I", "");
2331 SYSCTL_PROC(_kern
, OID_AUTO
, sched_enable_smt
,
2332 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_KERN
,
2333 0, 0, sysctl_sched_enable_smt
, "I", "");
2335 extern int sched_allow_NO_SMT_threads
;
2336 SYSCTL_INT(_kern
, OID_AUTO
, sched_allow_NO_SMT_threads
,
2337 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2338 &sched_allow_NO_SMT_threads
, 0, "");
2340 #if (DEVELOPMENT || DEBUG)
2341 extern int smt_sched_bonus_16ths
;
2342 SYSCTL_INT(_kern
, OID_AUTO
, smt_sched_bonus_16ths
,
2343 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2344 &smt_sched_bonus_16ths
, 0, "");
2346 extern int smt_timeshare_enabled
;
2347 SYSCTL_INT(_kern
, OID_AUTO
, sched_smt_timeshare_enable
,
2348 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2349 &smt_timeshare_enabled
, 0, "");
2351 extern int sched_smt_balance
;
2352 SYSCTL_INT(_kern
, OID_AUTO
, sched_smt_balance
,
2353 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2354 &sched_smt_balance
, 0, "");
2355 extern int sched_allow_rt_smt
;
2356 SYSCTL_INT(_kern
, OID_AUTO
, sched_allow_rt_smt
,
2357 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2358 &sched_allow_rt_smt
, 0, "");
2359 extern int sched_avoid_cpu0
;
2360 SYSCTL_INT(_kern
, OID_AUTO
, sched_avoid_cpu0
,
2361 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2362 &sched_avoid_cpu0
, 0, "");
2363 #if __arm__ || __arm64__
2364 extern uint32_t perfcontrol_requested_recommended_cores
;
2365 SYSCTL_UINT(_kern
, OID_AUTO
, sched_recommended_cores
,
2366 CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2367 &perfcontrol_requested_recommended_cores
, 0, "");
2369 /* Scheduler perfcontrol callouts sysctls */
2370 SYSCTL_DECL(_kern_perfcontrol_callout
);
2371 SYSCTL_NODE(_kern
, OID_AUTO
, perfcontrol_callout
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0,
2372 "scheduler perfcontrol callouts");
2374 extern int perfcontrol_callout_stats_enabled
;
2375 SYSCTL_INT(_kern_perfcontrol_callout
, OID_AUTO
, stats_enabled
,
2376 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2377 &perfcontrol_callout_stats_enabled
, 0, "");
2379 extern uint64_t perfcontrol_callout_stat_avg(perfcontrol_callout_type_t type
,
2380 perfcontrol_callout_stat_t stat
);
2382 /* On-Core Callout */
2384 sysctl_perfcontrol_callout_stat
2385 (__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
, struct sysctl_req
*req
)
2387 perfcontrol_callout_stat_t stat
= (perfcontrol_callout_stat_t
)arg1
;
2388 perfcontrol_callout_type_t type
= (perfcontrol_callout_type_t
)arg2
;
2389 return sysctl_io_number(req
, (int)perfcontrol_callout_stat_avg(type
, stat
),
2390 sizeof(int), NULL
, NULL
);
2393 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, oncore_instr
,
2394 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2395 (void *)PERFCONTROL_STAT_INSTRS
, PERFCONTROL_CALLOUT_ON_CORE
,
2396 sysctl_perfcontrol_callout_stat
, "I", "");
2397 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, oncore_cycles
,
2398 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2399 (void *)PERFCONTROL_STAT_CYCLES
, PERFCONTROL_CALLOUT_ON_CORE
,
2400 sysctl_perfcontrol_callout_stat
, "I", "");
2401 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, offcore_instr
,
2402 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2403 (void *)PERFCONTROL_STAT_INSTRS
, PERFCONTROL_CALLOUT_OFF_CORE
,
2404 sysctl_perfcontrol_callout_stat
, "I", "");
2405 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, offcore_cycles
,
2406 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2407 (void *)PERFCONTROL_STAT_CYCLES
, PERFCONTROL_CALLOUT_OFF_CORE
,
2408 sysctl_perfcontrol_callout_stat
, "I", "");
2409 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, context_instr
,
2410 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2411 (void *)PERFCONTROL_STAT_INSTRS
, PERFCONTROL_CALLOUT_CONTEXT
,
2412 sysctl_perfcontrol_callout_stat
, "I", "");
2413 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, context_cycles
,
2414 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2415 (void *)PERFCONTROL_STAT_CYCLES
, PERFCONTROL_CALLOUT_CONTEXT
,
2416 sysctl_perfcontrol_callout_stat
, "I", "");
2417 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, update_instr
,
2418 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2419 (void *)PERFCONTROL_STAT_INSTRS
, PERFCONTROL_CALLOUT_STATE_UPDATE
,
2420 sysctl_perfcontrol_callout_stat
, "I", "");
2421 SYSCTL_PROC(_kern_perfcontrol_callout
, OID_AUTO
, update_cycles
,
2422 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2423 (void *)PERFCONTROL_STAT_CYCLES
, PERFCONTROL_CALLOUT_STATE_UPDATE
,
2424 sysctl_perfcontrol_callout_stat
, "I", "");
2427 extern int sched_amp_idle_steal
;
2428 SYSCTL_INT(_kern
, OID_AUTO
, sched_amp_idle_steal
,
2429 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2430 &sched_amp_idle_steal
, 0, "");
2431 extern int sched_amp_spill_steal
;
2432 SYSCTL_INT(_kern
, OID_AUTO
, sched_amp_spill_steal
,
2433 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2434 &sched_amp_spill_steal
, 0, "");
2435 extern int sched_amp_spill_count
;
2436 SYSCTL_INT(_kern
, OID_AUTO
, sched_amp_spill_count
,
2437 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2438 &sched_amp_spill_count
, 0, "");
2439 extern int sched_amp_spill_deferred_ipi
;
2440 SYSCTL_INT(_kern
, OID_AUTO
, sched_amp_spill_deferred_ipi
,
2441 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2442 &sched_amp_spill_deferred_ipi
, 0, "");
2443 extern int sched_amp_pcores_preempt_immediate_ipi
;
2444 SYSCTL_INT(_kern
, OID_AUTO
, sched_amp_pcores_preempt_immediate_ipi
,
2445 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2446 &sched_amp_pcores_preempt_immediate_ipi
, 0, "");
2447 #endif /* __AMP__ */
2448 #endif /* __arm__ || __arm64__ */
2451 extern int legacy_footprint_entitlement_mode
;
2452 SYSCTL_INT(_kern
, OID_AUTO
, legacy_footprint_entitlement_mode
,
2453 CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2454 &legacy_footprint_entitlement_mode
, 0, "");
2455 #endif /* __arm64__ */
2458 sysctl_kern_sched_rt_n_backup_processors(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2460 int new_value
, changed
;
2461 int old_value
= sched_get_rt_n_backup_processors();
2462 int error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, &changed
);
2464 sched_set_rt_n_backup_processors(new_value
);
2470 SYSCTL_PROC(_kern
, OID_AUTO
, sched_rt_n_backup_processors
,
2471 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2472 0, 0, sysctl_kern_sched_rt_n_backup_processors
, "I", "");
2474 #endif /* (DEVELOPMENT || DEBUG) */
2478 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2480 int new_value
, changed
;
2481 int error
= sysctl_io_number(req
, securelevel
, sizeof(int), &new_value
, &changed
);
2483 if (!(new_value
< securelevel
&& req
->p
->p_pid
!= 1)) {
2485 securelevel
= new_value
;
2494 SYSCTL_PROC(_kern
, KERN_SECURELVL
, securelevel
,
2495 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2496 0, 0, sysctl_securelvl
, "I", "");
2501 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2504 char tmpname
[MAXHOSTNAMELEN
] = {};
2506 lck_mtx_lock(&domainname_lock
);
2507 strlcpy(tmpname
, domainname
, sizeof(tmpname
));
2508 lck_mtx_unlock(&domainname_lock
);
2510 error
= sysctl_io_string(req
, tmpname
, sizeof(tmpname
), 0, &changed
);
2511 if (!error
&& changed
) {
2512 lck_mtx_lock(&hostname_lock
);
2513 strlcpy(domainname
, tmpname
, sizeof(domainname
));
2514 lck_mtx_unlock(&hostname_lock
);
2519 SYSCTL_PROC(_kern
, KERN_DOMAINNAME
, nisdomainname
,
2520 CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2521 0, 0, sysctl_domainname
, "A", "");
2523 SYSCTL_COMPAT_INT(_kern
, KERN_HOSTID
, hostid
,
2524 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2529 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2532 char tmpname
[MAXHOSTNAMELEN
] = {};
2534 lck_mtx_lock(&hostname_lock
);
2535 strlcpy(tmpname
, hostname
, sizeof(tmpname
));
2536 lck_mtx_unlock(&hostname_lock
);
2538 error
= sysctl_io_string(req
, tmpname
, sizeof(tmpname
), 1, &changed
);
2539 if (!error
&& changed
) {
2540 lck_mtx_lock(&hostname_lock
);
2541 strlcpy(hostname
, tmpname
, sizeof(hostname
));
2542 lck_mtx_unlock(&hostname_lock
);
2547 SYSCTL_PROC(_kern
, KERN_HOSTNAME
, hostname
,
2548 CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2549 0, 0, sysctl_hostname
, "A", "");
2553 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2555 /* Original code allowed writing, I'm copying this, although this all makes
2556 * no sense to me. Besides, this sysctl is never used. */
2557 return sysctl_io_string(req
, &req
->p
->p_name
[0], (2 * MAXCOMLEN
+ 1), 1, NULL
);
2560 SYSCTL_PROC(_kern
, KERN_PROCNAME
, procname
,
2561 CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
,
2562 0, 0, sysctl_procname
, "A", "");
2564 SYSCTL_INT(_kern
, KERN_SPECULATIVE_READS
, speculative_reads_disabled
,
2565 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2566 &speculative_reads_disabled
, 0, "");
2568 SYSCTL_UINT(_kern
, OID_AUTO
, preheat_max_bytes
,
2569 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2570 &preheat_max_bytes
, 0, "");
2572 SYSCTL_UINT(_kern
, OID_AUTO
, preheat_min_bytes
,
2573 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2574 &preheat_min_bytes
, 0, "");
2576 SYSCTL_UINT(_kern
, OID_AUTO
, speculative_prefetch_max
,
2577 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2578 &speculative_prefetch_max
, 0, "");
2580 SYSCTL_UINT(_kern
, OID_AUTO
, speculative_prefetch_max_iosize
,
2581 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2582 &speculative_prefetch_max_iosize
, 0, "");
2584 SYSCTL_UINT(_kern
, OID_AUTO
, vm_page_free_target
,
2585 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2586 &vm_page_free_target
, 0, "");
2588 SYSCTL_UINT(_kern
, OID_AUTO
, vm_page_free_min
,
2589 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2590 &vm_page_free_min
, 0, "");
2592 SYSCTL_UINT(_kern
, OID_AUTO
, vm_page_free_reserved
,
2593 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2594 &vm_page_free_reserved
, 0, "");
2596 SYSCTL_UINT(_kern
, OID_AUTO
, vm_page_speculative_percentage
,
2597 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2598 &vm_pageout_state
.vm_page_speculative_percentage
, 0, "");
2600 SYSCTL_UINT(_kern
, OID_AUTO
, vm_page_speculative_q_age_ms
,
2601 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2602 &vm_pageout_state
.vm_page_speculative_q_age_ms
, 0, "");
2604 SYSCTL_UINT(_kern
, OID_AUTO
, vm_max_delayed_work_limit
,
2605 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2606 &vm_max_delayed_work_limit
, 0, "");
2608 SYSCTL_UINT(_kern
, OID_AUTO
, vm_max_batch
,
2609 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2610 &vm_max_batch
, 0, "");
2612 SYSCTL_STRING(_kern
, OID_AUTO
, bootsessionuuid
,
2613 CTLFLAG_RD
| CTLFLAG_LOCKED
,
2614 &bootsessionuuid_string
, sizeof(bootsessionuuid_string
), "");
2619 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2622 boottime_timeval(&tv
);
2623 struct proc
*p
= req
->p
;
2625 if (proc_is64bit(p
)) {
2626 struct user64_timeval t
= {};
2627 t
.tv_sec
= tv
.tv_sec
;
2628 t
.tv_usec
= tv
.tv_usec
;
2629 return sysctl_io_opaque(req
, &t
, sizeof(t
), NULL
);
2631 struct user32_timeval t
= {};
2632 t
.tv_sec
= (user32_time_t
)tv
.tv_sec
;
2633 t
.tv_usec
= tv
.tv_usec
;
2634 return sysctl_io_opaque(req
, &t
, sizeof(t
), NULL
);
2638 SYSCTL_PROC(_kern
, KERN_BOOTTIME
, boottime
,
2639 CTLTYPE_STRUCT
| CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2640 0, 0, sysctl_boottime
, "S,timeval", "");
2642 extern const char* IOGetBootUUID(void);
2644 /* non-static: written by imageboot.c */
2645 uuid_string_t fake_bootuuid
;
2649 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2653 /* check the first byte to see if the string has been
2654 * populated. this is a uuid_STRING_t, this check would
2655 * not work with a uuid_t.
2657 if (fake_bootuuid
[0] != '\0') {
2658 error
= sysctl_io_string(req
, fake_bootuuid
, 0, 0, NULL
);
2662 const char *uuid_string
= IOGetBootUUID();
2665 error
= uuid_parse(uuid_string
, boot_uuid
);
2667 error
= sysctl_io_string(req
, __DECONST(char *, uuid_string
), 0, 0, NULL
);
2675 SYSCTL_PROC(_kern
, OID_AUTO
, bootuuid
,
2676 CTLTYPE_STRING
| CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2677 0, 0, sysctl_bootuuid
, "A", "");
2680 extern const char* IOGetApfsPrebootUUID(void);
2681 extern const char *IOGetAssociatedApfsVolgroupUUID(void);
2684 sysctl_apfsprebootuuid
2685 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2689 const char *uuid_string
= IOGetApfsPrebootUUID();
2691 uuid_t apfs_preboot_uuid
;
2692 error
= uuid_parse(uuid_string
, apfs_preboot_uuid
);
2694 error
= sysctl_io_string(req
, __DECONST(char *, uuid_string
), 0, 0, NULL
);
2701 SYSCTL_PROC(_kern
, OID_AUTO
, apfsprebootuuid
,
2702 CTLTYPE_STRING
| CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2703 0, 0, sysctl_apfsprebootuuid
, "A", "");
2706 sysctl_targetsystemvolgroupuuid
2707 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2711 const char *uuid_string
= IOGetApfsPrebootUUID();
2713 uuid_t apfs_preboot_uuid
;
2714 error
= uuid_parse(uuid_string
, apfs_preboot_uuid
);
2716 error
= sysctl_io_string(req
, __DECONST(char *, uuid_string
), 0, 0, NULL
);
2720 * In special boot modes, such as kcgen-mode, the
2721 * apfs-preboot-uuid property will not be set. Instead, a
2722 * different property, associated-volume-group, will be set
2723 * which indicates the UUID of the VolumeGroup containing the
2724 * system volume into which you will boot.
2726 uuid_string
= IOGetAssociatedApfsVolgroupUUID();
2728 uuid_t apfs_preboot_uuid
;
2729 error
= uuid_parse(uuid_string
, apfs_preboot_uuid
);
2731 error
= sysctl_io_string(req
, __DECONST(char *, uuid_string
), 0, 0, NULL
);
2739 SYSCTL_PROC(_kern
, OID_AUTO
, targetsystemvolgroupuuid
,
2740 CTLTYPE_STRING
| CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_MASKED
| CTLFLAG_LOCKED
,
2741 0, 0, sysctl_targetsystemvolgroupuuid
, "A", "");
2745 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2748 int error
= get_kernel_symfile(req
->p
, &str
);
2752 return sysctl_io_string(req
, str
, 0, 0, NULL
);
2756 SYSCTL_PROC(_kern
, KERN_SYMFILE
, symfile
,
2757 CTLTYPE_STRING
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2758 0, 0, sysctl_symfile
, "A", "");
2760 #if CONFIG_NFS_CLIENT
2763 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2765 return sysctl_io_number(req
, netboot_root(), sizeof(int), NULL
, NULL
);
2768 SYSCTL_PROC(_kern
, KERN_NETBOOT
, netboot
,
2769 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2770 0, 0, sysctl_netboot
, "I", "");
2773 #ifdef CONFIG_IMGSRC_ACCESS
2775 * Legacy--act as if only one layer of nesting is possible.
2779 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2781 vfs_context_t ctx
= vfs_context_current();
2785 if (!vfs_context_issuser(ctx
)) {
2789 if (imgsrc_rootvnodes
[0] == NULL
) {
2793 result
= vnode_getwithref(imgsrc_rootvnodes
[0]);
2798 devvp
= vnode_mount(imgsrc_rootvnodes
[0])->mnt_devvp
;
2799 result
= vnode_getwithref(devvp
);
2804 result
= sysctl_io_number(req
, vnode_specrdev(devvp
), sizeof(dev_t
), NULL
, NULL
);
2808 vnode_put(imgsrc_rootvnodes
[0]);
2812 SYSCTL_PROC(_kern
, OID_AUTO
, imgsrcdev
,
2813 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2814 0, 0, sysctl_imgsrcdev
, "I", "");
2818 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2821 struct imgsrc_info info
[MAX_IMAGEBOOT_NESTING
] = {}; /* 2 for now, no problem */
2825 if (imgsrc_rootvnodes
[0] == NULLVP
) {
2829 for (i
= 0; i
< MAX_IMAGEBOOT_NESTING
; i
++) {
2831 * Go get the root vnode.
2833 rvp
= imgsrc_rootvnodes
[i
];
2834 if (rvp
== NULLVP
) {
2838 error
= vnode_get(rvp
);
2844 * For now, no getting at a non-local volume.
2846 devvp
= vnode_mount(rvp
)->mnt_devvp
;
2847 if (devvp
== NULL
) {
2852 error
= vnode_getwithref(devvp
);
2861 info
[i
].ii_dev
= vnode_specrdev(devvp
);
2862 info
[i
].ii_flags
= 0;
2863 info
[i
].ii_height
= i
;
2864 bzero(info
[i
].ii_reserved
, sizeof(info
[i
].ii_reserved
));
2870 return sysctl_io_opaque(req
, info
, i
* sizeof(info
[0]), NULL
);
2873 SYSCTL_PROC(_kern
, OID_AUTO
, imgsrcinfo
,
2874 CTLTYPE_OPAQUE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2875 0, 0, sysctl_imgsrcinfo
, "I", "");
2877 #endif /* CONFIG_IMGSRC_ACCESS */
2880 SYSCTL_DECL(_kern_timer
);
2881 SYSCTL_NODE(_kern
, OID_AUTO
, timer
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, "timer");
2884 SYSCTL_INT(_kern_timer
, OID_AUTO
, coalescing_enabled
,
2885 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2886 &mach_timer_coalescing_enabled
, 0, "");
2888 SYSCTL_QUAD(_kern_timer
, OID_AUTO
, deadline_tracking_bin_1
,
2889 CTLFLAG_RW
| CTLFLAG_LOCKED
,
2890 &timer_deadline_tracking_bin_1
, "");
2891 SYSCTL_QUAD(_kern_timer
, OID_AUTO
, deadline_tracking_bin_2
,
2892 CTLFLAG_RW
| CTLFLAG_LOCKED
,
2893 &timer_deadline_tracking_bin_2
, "");
2895 SYSCTL_DECL(_kern_timer_longterm
);
2896 SYSCTL_NODE(_kern_timer
, OID_AUTO
, longterm
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, "longterm");
2899 /* Must match definition in osfmk/kern/timer_call.c */
2902 ENQUEUES
, DEQUEUES
, ESCALATES
, SCANS
, PREEMPTS
,
2903 LATENCY
, LATENCY_MIN
, LATENCY_MAX
, SCAN_LIMIT
, SCAN_INTERVAL
, PAUSES
2905 extern uint64_t timer_sysctl_get(int);
2906 extern int timer_sysctl_set(int, uint64_t);
2910 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2912 int oid
= (int)arg1
;
2913 uint64_t value
= timer_sysctl_get(oid
);
2918 error
= sysctl_io_number(req
, value
, sizeof(value
), &new_value
, &changed
);
2920 error
= timer_sysctl_set(oid
, new_value
);
2926 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, threshold
,
2927 CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2928 (void *) THRESHOLD
, 0, sysctl_timer
, "Q", "");
2929 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, scan_limit
,
2930 CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2931 (void *) SCAN_LIMIT
, 0, sysctl_timer
, "Q", "");
2932 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, scan_interval
,
2933 CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
2934 (void *) SCAN_INTERVAL
, 0, sysctl_timer
, "Q", "");
2936 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, qlen
,
2937 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2938 (void *) QCOUNT
, 0, sysctl_timer
, "Q", "");
2939 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, scan_pauses
,
2940 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2941 (void *) PAUSES
, 0, sysctl_timer
, "Q", "");
2944 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, enqueues
,
2945 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2946 (void *) ENQUEUES
, 0, sysctl_timer
, "Q", "");
2947 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, dequeues
,
2948 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2949 (void *) DEQUEUES
, 0, sysctl_timer
, "Q", "");
2950 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, escalates
,
2951 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2952 (void *) ESCALATES
, 0, sysctl_timer
, "Q", "");
2953 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, scans
,
2954 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2955 (void *) SCANS
, 0, sysctl_timer
, "Q", "");
2956 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, preempts
,
2957 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2958 (void *) PREEMPTS
, 0, sysctl_timer
, "Q", "");
2959 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, latency
,
2960 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2961 (void *) LATENCY
, 0, sysctl_timer
, "Q", "");
2962 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, latency_min
,
2963 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2964 (void *) LATENCY_MIN
, 0, sysctl_timer
, "Q", "");
2965 SYSCTL_PROC(_kern_timer_longterm
, OID_AUTO
, latency_max
,
2966 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2967 (void *) LATENCY_MAX
, 0, sysctl_timer
, "Q", "");
2972 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2974 return sysctl_io_number(req
, (int)req
->p
->user_stack
, sizeof(int), NULL
, NULL
);
2977 SYSCTL_PROC(_kern
, KERN_USRSTACK32
, usrstack
,
2978 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2979 0, 0, sysctl_usrstack
, "I", "");
2983 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
2985 return sysctl_io_number(req
, req
->p
->user_stack
, sizeof(req
->p
->user_stack
), NULL
, NULL
);
2988 SYSCTL_PROC(_kern
, KERN_USRSTACK64
, usrstack64
,
2989 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
2990 0, 0, sysctl_usrstack64
, "Q", "");
2994 SYSCTL_STRING(_kern
, KERN_COREFILE
, corefile
,
2995 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
2996 corefilename
, sizeof(corefilename
), "");
3000 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3002 #ifdef SECURE_KERNEL
3006 int new_value
, changed
;
3007 int error
= sysctl_io_number(req
, do_coredump
, sizeof(int), &new_value
, &changed
);
3009 if ((new_value
== 0) || (new_value
== 1)) {
3010 do_coredump
= new_value
;
3019 SYSCTL_PROC(_kern
, KERN_COREDUMP
, coredump
,
3020 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3021 0, 0, sysctl_coredump
, "I", "");
3024 sysctl_suid_coredump
3025 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3027 #ifdef SECURE_KERNEL
3031 int new_value
, changed
;
3032 int error
= sysctl_io_number(req
, sugid_coredump
, sizeof(int), &new_value
, &changed
);
3034 if ((new_value
== 0) || (new_value
== 1)) {
3035 sugid_coredump
= new_value
;
3044 SYSCTL_PROC(_kern
, KERN_SUGID_COREDUMP
, sugid_coredump
,
3045 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3046 0, 0, sysctl_suid_coredump
, "I", "");
3048 #endif /* CONFIG_COREDUMP */
3052 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3054 struct proc
*p
= req
->p
;
3055 int new_value
, changed
;
3056 int error
= sysctl_io_number(req
, (req
->p
->p_lflag
& P_LDELAYTERM
)? 1: 0, sizeof(int), &new_value
, &changed
);
3060 req
->p
->p_lflag
|= P_LDELAYTERM
;
3062 req
->p
->p_lflag
&= ~P_LDELAYTERM
;
3069 SYSCTL_PROC(_kern
, KERN_PROCDELAYTERM
, delayterm
,
3070 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3071 0, 0, sysctl_delayterm
, "I", "");
3076 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3078 struct proc
*p
= req
->p
;
3080 int new_value
, old_value
, changed
;
3083 ut
= get_bsdthread_info(current_thread());
3085 if (ut
->uu_flag
& UT_RAGE_VNODES
) {
3086 old_value
= KERN_RAGE_THREAD
;
3087 } else if (p
->p_lflag
& P_LRAGE_VNODES
) {
3088 old_value
= KERN_RAGE_PROC
;
3093 error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, &changed
);
3095 if ((error
== 0) && (changed
!= 0)) {
3096 switch (new_value
) {
3097 case KERN_RAGE_PROC
:
3099 p
->p_lflag
|= P_LRAGE_VNODES
;
3102 case KERN_UNRAGE_PROC
:
3104 p
->p_lflag
&= ~P_LRAGE_VNODES
;
3108 case KERN_RAGE_THREAD
:
3109 ut
->uu_flag
|= UT_RAGE_VNODES
;
3111 case KERN_UNRAGE_THREAD
:
3112 ut
= get_bsdthread_info(current_thread());
3113 ut
->uu_flag
&= ~UT_RAGE_VNODES
;
3120 SYSCTL_PROC(_kern
, KERN_RAGEVNODE
, rage_vnode
,
3121 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
,
3122 0, 0, sysctl_rage_vnode
, "I", "");
3124 /* XXX until filecoordinationd fixes a bit of inverted logic. */
3127 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3129 int old_value
= 0, new_value
, changed
;
3131 return sysctl_io_number(req
, old_value
, sizeof(int), &new_value
,
3135 SYSCTL_PROC(_kern
, OID_AUTO
, vfsnspace
,
3136 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
,
3137 0, 0, sysctl_vfsnspace
, "I", "");
3139 /* XXX move this interface into libproc and remove this sysctl */
3141 sysctl_setthread_cpupercent
3142 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3144 int new_value
, old_value
;
3146 kern_return_t kret
= KERN_SUCCESS
;
3147 uint8_t percent
= 0;
3156 if ((error
= sysctl_io_number(req
, old_value
, sizeof(old_value
), &new_value
, NULL
)) != 0) {
3160 percent
= new_value
& 0xff; /* low 8 bytes for perent */
3161 ms_refill
= (new_value
>> 8) & 0xffffff; /* upper 24bytes represent ms refill value */
3162 if (percent
> 100) {
3167 * If the caller is specifying a percentage of 0, this will unset the CPU limit, if present.
3169 if ((kret
= thread_set_cpulimit(THREAD_CPULIMIT_BLOCK
, percent
, ms_refill
* (int)NSEC_PER_MSEC
)) != 0) {
3176 SYSCTL_PROC(_kern
, OID_AUTO
, setthread_cpupercent
,
3177 CTLTYPE_INT
| CTLFLAG_WR
| CTLFLAG_ANYBODY
,
3178 0, 0, sysctl_setthread_cpupercent
, "I", "set thread cpu percentage limit");
3182 sysctl_kern_check_openevt
3183 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3185 struct proc
*p
= req
->p
;
3186 int new_value
, old_value
, changed
;
3189 if (p
->p_flag
& P_CHECKOPENEVT
) {
3190 old_value
= KERN_OPENEVT_PROC
;
3195 error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, &changed
);
3197 if ((error
== 0) && (changed
!= 0)) {
3198 switch (new_value
) {
3199 case KERN_OPENEVT_PROC
:
3200 OSBitOrAtomic(P_CHECKOPENEVT
, &p
->p_flag
);
3203 case KERN_UNOPENEVT_PROC
:
3204 OSBitAndAtomic(~((uint32_t)P_CHECKOPENEVT
), &p
->p_flag
);
3214 SYSCTL_PROC(_kern
, KERN_CHECKOPENEVT
, check_openevt
, CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
,
3215 0, 0, sysctl_kern_check_openevt
, "I", "set the per-process check-open-evt flag");
3218 #if DEVELOPMENT || DEBUG
3221 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3223 #ifdef SECURE_KERNEL
3227 int new_value
, changed
;
3230 error
= sysctl_io_number(req
, nx_enabled
, sizeof(nx_enabled
), &new_value
, &changed
);
3236 #if defined(__x86_64__)
3238 * Only allow setting if NX is supported on the chip
3240 if (!(cpuid_extfeatures() & CPUID_EXTFEATURE_XD
)) {
3244 nx_enabled
= new_value
;
3247 #endif /* SECURE_KERNEL */
3251 #if DEVELOPMENT || DEBUG
3252 SYSCTL_PROC(_kern
, KERN_NX_PROTECTION
, nx
,
3253 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
3254 0, 0, sysctl_nx
, "I", "");
3259 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3261 if (proc_is64bit(req
->p
)) {
3262 struct user64_loadavg loadinfo64
= {};
3263 fill_loadavg64(&averunnable
, &loadinfo64
);
3264 return sysctl_io_opaque(req
, &loadinfo64
, sizeof(loadinfo64
), NULL
);
3266 struct user32_loadavg loadinfo32
= {};
3267 fill_loadavg32(&averunnable
, &loadinfo32
);
3268 return sysctl_io_opaque(req
, &loadinfo32
, sizeof(loadinfo32
), NULL
);
3272 SYSCTL_PROC(_vm
, VM_LOADAVG
, loadavg
,
3273 CTLTYPE_STRUCT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3274 0, 0, sysctl_loadavg
, "S,loadavg", "");
3277 * Note: Thread safe; vm_map_lock protects in vm_toggle_entry_reuse()
3280 sysctl_vm_toggle_address_reuse(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
,
3281 __unused
int arg2
, struct sysctl_req
*req
)
3283 int old_value
= 0, new_value
= 0, error
= 0;
3285 if (vm_toggle_entry_reuse( VM_TOGGLE_GETVALUE
, &old_value
)) {
3288 error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, NULL
);
3290 return vm_toggle_entry_reuse(new_value
, NULL
);
3295 SYSCTL_PROC(_debug
, OID_AUTO
, toggle_address_reuse
, CTLFLAG_ANYBODY
| CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, 0, sysctl_vm_toggle_address_reuse
, "I", "");
3297 #ifdef CONFIG_XNUPOST
3299 extern uint32_t xnupost_get_estimated_testdata_size(void);
3300 extern int xnupost_reset_all_tests(void);
3303 sysctl_handle_xnupost_get_tests SYSCTL_HANDLER_ARGS
3305 /* fixup unused arguments warnings */
3306 __unused
int _oa2
= arg2
;
3307 __unused
void * _oa1
= arg1
;
3308 __unused
struct sysctl_oid
* _oidp
= oidp
;
3311 user_addr_t oldp
= 0;
3312 user_addr_t newp
= 0;
3313 uint32_t usedbytes
= 0;
3322 if ((void *)oldp
== NULL
) {
3323 /* return estimated size for second call where info can be placed */
3324 req
->oldidx
= xnupost_get_estimated_testdata_size();
3326 error
= xnupost_export_testdata((void *)oldp
, req
->oldlen
, &usedbytes
);
3327 req
->oldidx
= usedbytes
;
3336 CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLTYPE_OPAQUE
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3339 sysctl_handle_xnupost_get_tests
,
3341 "read xnupost test data in kernel");
3344 sysctl_debug_xnupost_ctl SYSCTL_HANDLER_ARGS
3346 /* fixup unused arguments warnings */
3347 __unused
int _oa2
= arg2
;
3348 __unused
void * _oa1
= arg1
;
3349 __unused
struct sysctl_oid
* _oidp
= oidp
;
3353 * INPUT: ACTION, PARAM1, PARAM2, PARAM3
3354 * OUTPUT: RESULTCODE, ADDITIONAL DATA
3356 int32_t outval
[ARRCOUNT
] = {0};
3357 int32_t input
[ARRCOUNT
] = {0};
3358 int32_t out_size
= sizeof(outval
);
3359 int32_t in_size
= sizeof(input
);
3362 /* if this is NULL call to find out size, send out size info */
3367 /* pull in provided value from userspace */
3368 error
= SYSCTL_IN(req
, &input
[0], in_size
);
3373 if (input
[0] == XTCTL_RESET_TESTDATA
) {
3374 outval
[0] = xnupost_reset_all_tests();
3379 error
= SYSCTL_OUT(req
, &outval
[0], out_size
);
3386 CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLTYPE_OPAQUE
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3389 sysctl_debug_xnupost_ctl
,
3391 "xnupost control for kernel testing");
3393 extern void test_oslog_handleOSLogCtl(int32_t * in
, int32_t * out
, int32_t arraycount
);
3396 sysctl_debug_test_oslog_ctl(__unused
struct sysctl_oid
* oidp
, __unused
void * arg1
, __unused
int arg2
, struct sysctl_req
* req
)
3399 int32_t outval
[ARRCOUNT
] = {0};
3400 int32_t input
[ARRCOUNT
] = {0};
3401 int32_t size_outval
= sizeof(outval
);
3402 int32_t size_inval
= sizeof(input
);
3405 /* if this is NULL call to find out size, send out size info */
3407 error
= SYSCTL_OUT(req
, &outval
[0], size_outval
);
3411 /* pull in provided value from userspace */
3412 error
= SYSCTL_IN(req
, &input
[0], size_inval
);
3417 test_oslog_handleOSLogCtl(input
, outval
, ARRCOUNT
);
3419 error
= SYSCTL_OUT(req
, &outval
[0], size_outval
);
3427 CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLTYPE_OPAQUE
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3430 sysctl_debug_test_oslog_ctl
,
3432 "testing oslog in kernel");
3434 #include <mach/task.h>
3435 #include <mach/semaphore.h>
3437 extern lck_grp_t
* sysctl_debug_test_stackshot_owner_grp
; /* used for both mutexes and rwlocks */
3438 extern lck_mtx_t
* sysctl_debug_test_stackshot_owner_init_mtx
; /* used to protect lck_*_init */
3440 /* This is a sysctl for testing collection of owner info on a lock in kernel space. A multi-threaded
3441 * test from userland sets this sysctl in such a way that a thread blocks in kernel mode, and a
3442 * stackshot is taken to see if the owner of the lock can be identified.
3444 * We can't return to userland with a kernel lock held, so be sure to unlock before we leave.
3445 * the semaphores allow us to artificially create cases where the lock is being held and the
3446 * thread is hanging / taking a long time to do something. */
3448 volatile char sysctl_debug_test_stackshot_mtx_inited
= 0;
3449 semaphore_t sysctl_debug_test_stackshot_mutex_sem
;
3450 lck_mtx_t sysctl_debug_test_stackshot_owner_lck
;
3452 #define SYSCTL_DEBUG_MTX_ACQUIRE_WAIT 1
3453 #define SYSCTL_DEBUG_MTX_ACQUIRE_NOWAIT 2
3454 #define SYSCTL_DEBUG_MTX_SIGNAL 3
3455 #define SYSCTL_DEBUG_MTX_TEARDOWN 4
3458 sysctl_debug_test_stackshot_mutex_owner(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3460 long long option
= -1;
3461 /* if the user tries to read the sysctl, we tell them what the address of the lock is (to test against stackshot's output) */
3462 long long mtx_unslid_addr
= (long long)VM_KERNEL_UNSLIDE_OR_PERM(&sysctl_debug_test_stackshot_owner_lck
);
3463 int error
= sysctl_io_number(req
, mtx_unslid_addr
, sizeof(long long), (void*)&option
, NULL
);
3465 lck_mtx_lock(sysctl_debug_test_stackshot_owner_init_mtx
);
3466 if (!sysctl_debug_test_stackshot_mtx_inited
) {
3467 lck_mtx_init(&sysctl_debug_test_stackshot_owner_lck
,
3468 sysctl_debug_test_stackshot_owner_grp
,
3470 semaphore_create(kernel_task
,
3471 &sysctl_debug_test_stackshot_mutex_sem
,
3472 SYNC_POLICY_FIFO
, 0);
3473 sysctl_debug_test_stackshot_mtx_inited
= 1;
3475 lck_mtx_unlock(sysctl_debug_test_stackshot_owner_init_mtx
);
3479 case SYSCTL_DEBUG_MTX_ACQUIRE_NOWAIT
:
3480 lck_mtx_lock(&sysctl_debug_test_stackshot_owner_lck
);
3481 lck_mtx_unlock(&sysctl_debug_test_stackshot_owner_lck
);
3483 case SYSCTL_DEBUG_MTX_ACQUIRE_WAIT
:
3484 lck_mtx_lock(&sysctl_debug_test_stackshot_owner_lck
);
3485 semaphore_wait(sysctl_debug_test_stackshot_mutex_sem
);
3486 lck_mtx_unlock(&sysctl_debug_test_stackshot_owner_lck
);
3488 case SYSCTL_DEBUG_MTX_SIGNAL
:
3489 semaphore_signal(sysctl_debug_test_stackshot_mutex_sem
);
3491 case SYSCTL_DEBUG_MTX_TEARDOWN
:
3492 lck_mtx_lock(sysctl_debug_test_stackshot_owner_init_mtx
);
3494 lck_mtx_destroy(&sysctl_debug_test_stackshot_owner_lck
,
3495 sysctl_debug_test_stackshot_owner_grp
);
3496 semaphore_destroy(kernel_task
,
3497 sysctl_debug_test_stackshot_mutex_sem
);
3498 sysctl_debug_test_stackshot_mtx_inited
= 0;
3500 lck_mtx_unlock(sysctl_debug_test_stackshot_owner_init_mtx
);
3502 case -1: /* user just wanted to read the value, so do nothing */
3512 /* we can't return to userland with a kernel rwlock held, so be sure to unlock before we leave.
3513 * the semaphores allow us to artificially create cases where the lock is being held and the
3514 * thread is hanging / taking a long time to do something. */
3519 CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3522 sysctl_debug_test_stackshot_mutex_owner
,
3524 "Testing mutex owner in kernel");
3526 volatile char sysctl_debug_test_stackshot_rwlck_inited
= 0;
3527 lck_rw_t sysctl_debug_test_stackshot_owner_rwlck
;
3528 semaphore_t sysctl_debug_test_stackshot_rwlck_sem
;
3530 #define SYSCTL_DEBUG_KRWLCK_RACQUIRE_NOWAIT 1
3531 #define SYSCTL_DEBUG_KRWLCK_RACQUIRE_WAIT 2
3532 #define SYSCTL_DEBUG_KRWLCK_WACQUIRE_NOWAIT 3
3533 #define SYSCTL_DEBUG_KRWLCK_WACQUIRE_WAIT 4
3534 #define SYSCTL_DEBUG_KRWLCK_SIGNAL 5
3535 #define SYSCTL_DEBUG_KRWLCK_TEARDOWN 6
3538 sysctl_debug_test_stackshot_rwlck_owner(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3540 long long option
= -1;
3541 /* if the user tries to read the sysctl, we tell them what the address of the lock is
3542 * (to test against stackshot's output) */
3543 long long rwlck_unslid_addr
= (long long)VM_KERNEL_UNSLIDE_OR_PERM(&sysctl_debug_test_stackshot_owner_rwlck
);
3544 int error
= sysctl_io_number(req
, rwlck_unslid_addr
, sizeof(long long), (void*)&option
, NULL
);
3546 lck_mtx_lock(sysctl_debug_test_stackshot_owner_init_mtx
);
3547 if (!sysctl_debug_test_stackshot_rwlck_inited
) {
3548 lck_rw_init(&sysctl_debug_test_stackshot_owner_rwlck
,
3549 sysctl_debug_test_stackshot_owner_grp
,
3551 semaphore_create(kernel_task
,
3552 &sysctl_debug_test_stackshot_rwlck_sem
,
3555 sysctl_debug_test_stackshot_rwlck_inited
= 1;
3557 lck_mtx_unlock(sysctl_debug_test_stackshot_owner_init_mtx
);
3561 case SYSCTL_DEBUG_KRWLCK_RACQUIRE_NOWAIT
:
3562 lck_rw_lock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_SHARED
);
3563 lck_rw_unlock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_SHARED
);
3565 case SYSCTL_DEBUG_KRWLCK_RACQUIRE_WAIT
:
3566 lck_rw_lock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_SHARED
);
3567 semaphore_wait(sysctl_debug_test_stackshot_rwlck_sem
);
3568 lck_rw_unlock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_SHARED
);
3570 case SYSCTL_DEBUG_KRWLCK_WACQUIRE_NOWAIT
:
3571 lck_rw_lock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_EXCLUSIVE
);
3572 lck_rw_unlock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_EXCLUSIVE
);
3574 case SYSCTL_DEBUG_KRWLCK_WACQUIRE_WAIT
:
3575 lck_rw_lock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_EXCLUSIVE
);
3576 semaphore_wait(sysctl_debug_test_stackshot_rwlck_sem
);
3577 lck_rw_unlock(&sysctl_debug_test_stackshot_owner_rwlck
, LCK_RW_TYPE_EXCLUSIVE
);
3579 case SYSCTL_DEBUG_KRWLCK_SIGNAL
:
3580 semaphore_signal(sysctl_debug_test_stackshot_rwlck_sem
);
3582 case SYSCTL_DEBUG_KRWLCK_TEARDOWN
:
3583 lck_mtx_lock(sysctl_debug_test_stackshot_owner_init_mtx
);
3585 lck_rw_destroy(&sysctl_debug_test_stackshot_owner_rwlck
,
3586 sysctl_debug_test_stackshot_owner_grp
);
3587 semaphore_destroy(kernel_task
,
3588 sysctl_debug_test_stackshot_rwlck_sem
);
3589 sysctl_debug_test_stackshot_rwlck_inited
= 0;
3591 lck_mtx_unlock(sysctl_debug_test_stackshot_owner_init_mtx
);
3593 case -1: /* user just wanted to read the value, so do nothing */
3606 test_RWLockOwnerCtl
,
3607 CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
3610 sysctl_debug_test_stackshot_rwlck_owner
,
3612 "Testing rwlock owner in kernel");
3613 #endif /* !CONFIG_XNUPOST */
3617 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3620 uint64_t swap_total
;
3621 uint64_t swap_avail
;
3622 vm_size_t swap_pagesize
;
3623 boolean_t swap_encrypted
;
3624 struct xsw_usage xsu
= {};
3626 error
= macx_swapinfo(&swap_total
,
3634 xsu
.xsu_total
= swap_total
;
3635 xsu
.xsu_avail
= swap_avail
;
3636 xsu
.xsu_used
= swap_total
- swap_avail
;
3637 xsu
.xsu_pagesize
= (u_int32_t
)MIN(swap_pagesize
, UINT32_MAX
);
3638 xsu
.xsu_encrypted
= swap_encrypted
;
3639 return sysctl_io_opaque(req
, &xsu
, sizeof(xsu
), NULL
);
3644 SYSCTL_PROC(_vm
, VM_SWAPUSAGE
, swapusage
,
3645 CTLTYPE_STRUCT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3646 0, 0, sysctl_swapusage
, "S,xsw_usage", "");
3649 extern void vm_page_reactivate_all_throttled(void);
3650 extern void memorystatus_disable_freeze(void);
3653 sysctl_freeze_enabled SYSCTL_HANDLER_ARGS
3655 #pragma unused(arg1, arg2)
3656 int error
, val
= memorystatus_freeze_enabled
? 1 : 0;
3659 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
3660 if (error
|| !req
->newptr
) {
3664 if (!VM_CONFIG_FREEZER_SWAP_IS_ACTIVE
) {
3665 //assert(req->newptr);
3666 printf("Failed attempt to set vm.freeze_enabled sysctl\n");
3671 * If freeze is being disabled, we need to move dirty pages out from the throttle to the active queue.
3673 disabled
= (!val
&& memorystatus_freeze_enabled
);
3675 memorystatus_freeze_enabled
= val
? TRUE
: FALSE
;
3678 vm_page_reactivate_all_throttled();
3679 memorystatus_disable_freeze();
3685 SYSCTL_PROC(_vm
, OID_AUTO
, freeze_enabled
, CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_ANYBODY
, &memorystatus_freeze_enabled
, 0, sysctl_freeze_enabled
, "I", "");
3686 #endif /* CONFIG_FREEZE */
3688 #if DEVELOPMENT || DEBUG
3689 extern int vm_num_swap_files_config
;
3690 extern int vm_num_swap_files
;
3691 extern lck_mtx_t vm_swap_data_lock
;
3692 #define VM_MAX_SWAP_FILE_NUM 100
3695 sysctl_vm_config_num_swap_files SYSCTL_HANDLER_ARGS
3697 #pragma unused(arg1, arg2)
3698 int error
= 0, val
= vm_num_swap_files_config
;
3700 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
3701 if (error
|| !req
->newptr
) {
3705 if (!VM_CONFIG_SWAP_IS_ACTIVE
&& !VM_CONFIG_FREEZER_SWAP_IS_ACTIVE
) {
3706 printf("Swap is disabled\n");
3711 lck_mtx_lock(&vm_swap_data_lock
);
3713 if (val
< vm_num_swap_files
) {
3714 printf("Cannot configure fewer swap files than already exist.\n");
3716 lck_mtx_unlock(&vm_swap_data_lock
);
3720 if (val
> VM_MAX_SWAP_FILE_NUM
) {
3721 printf("Capping number of swap files to upper bound.\n");
3722 val
= VM_MAX_SWAP_FILE_NUM
;
3725 vm_num_swap_files_config
= val
;
3726 lck_mtx_unlock(&vm_swap_data_lock
);
3732 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", "");
3733 #endif /* DEVELOPMENT || DEBUG */
3735 /* this kernel does NOT implement shared_region_make_private_np() */
3736 SYSCTL_INT(_kern
, KERN_SHREG_PRIVATIZABLE
, shreg_private
,
3737 CTLFLAG_RD
| CTLFLAG_LOCKED
,
3738 (int *)NULL
, 0, "");
3741 fetch_process_cputype(
3745 cpu_type_t
*cputype
)
3747 proc_t p
= PROC_NULL
;
3754 } else if (namelen
== 1) {
3755 p
= proc_find(name
[0]);
3765 ret
= cpu_type() & ~CPU_ARCH_MASK
;
3766 if (IS_64BIT_PROCESS(p
)) {
3767 ret
|= CPU_ARCH_ABI64
;
3781 sysctl_sysctl_native(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
,
3782 struct sysctl_req
*req
)
3785 cpu_type_t proc_cputype
= 0;
3786 if ((error
= fetch_process_cputype(req
->p
, (int *)arg1
, arg2
, &proc_cputype
)) != 0) {
3790 if ((proc_cputype
& ~CPU_ARCH_MASK
) != (cpu_type() & ~CPU_ARCH_MASK
)) {
3793 return SYSCTL_OUT(req
, &res
, sizeof(res
));
3795 SYSCTL_PROC(_sysctl
, OID_AUTO
, proc_native
, CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
, 0, 0, sysctl_sysctl_native
, "I", "proc_native");
3798 sysctl_sysctl_cputype(__unused
struct sysctl_oid
*oidp
, void *arg1
, int arg2
,
3799 struct sysctl_req
*req
)
3802 cpu_type_t proc_cputype
= 0;
3803 if ((error
= fetch_process_cputype(req
->p
, (int *)arg1
, arg2
, &proc_cputype
)) != 0) {
3806 return SYSCTL_OUT(req
, &proc_cputype
, sizeof(proc_cputype
));
3808 SYSCTL_PROC(_sysctl
, OID_AUTO
, proc_cputype
, CTLTYPE_NODE
| CTLFLAG_RD
| CTLFLAG_LOCKED
, 0, 0, sysctl_sysctl_cputype
, "I", "proc_cputype");
3812 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3814 return sysctl_io_number(req
, boothowto
& RB_SAFEBOOT
? 1 : 0, sizeof(int), NULL
, NULL
);
3817 SYSCTL_PROC(_kern
, KERN_SAFEBOOT
, safeboot
,
3818 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3819 0, 0, sysctl_safeboot
, "I", "");
3823 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3825 return sysctl_io_number(req
, boothowto
& RB_SINGLE
? 1 : 0, sizeof(int), NULL
, NULL
);
3828 SYSCTL_PROC(_kern
, OID_AUTO
, singleuser
,
3829 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3830 0, 0, sysctl_singleuser
, "I", "");
3834 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3836 return sysctl_io_number(req
, minimalboot
, sizeof(int), NULL
, NULL
);
3839 SYSCTL_PROC(_kern
, OID_AUTO
, minimalboot
,
3840 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3841 0, 0, sysctl_minimalboot
, "I", "");
3844 * Controls for debugging affinity sets - see osfmk/kern/affinity.c
3846 extern boolean_t affinity_sets_enabled
;
3847 extern int affinity_sets_mapping
;
3849 SYSCTL_INT(_kern
, OID_AUTO
, affinity_sets_enabled
,
3850 CTLFLAG_RW
| CTLFLAG_LOCKED
, (int *) &affinity_sets_enabled
, 0, "hinting enabled");
3851 SYSCTL_INT(_kern
, OID_AUTO
, affinity_sets_mapping
,
3852 CTLFLAG_RW
| CTLFLAG_LOCKED
, &affinity_sets_mapping
, 0, "mapping policy");
3855 * Boolean indicating if KASLR is active.
3859 (__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3863 slide
= vm_kernel_slide
? 1 : 0;
3865 return sysctl_io_number( req
, slide
, sizeof(int), NULL
, NULL
);
3868 SYSCTL_PROC(_kern
, OID_AUTO
, slide
,
3869 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
3870 0, 0, sysctl_slide
, "I", "");
3872 /* User address of the PFZ */
3873 #if DEBUG || DEVELOPMENT
3874 extern user32_addr_t commpage_text32_location
;
3875 extern user64_addr_t commpage_text64_location
;
3878 sysctl_pfz_start SYSCTL_HANDLER_ARGS
3880 #pragma unused(oidp, arg1, arg2)
3883 return sysctl_io_number(req
, commpage_text64_location
, sizeof(user64_addr_t
), NULL
, NULL
);
3885 return sysctl_io_number(req
, commpage_text32_location
, sizeof(user32_addr_t
), NULL
, NULL
);
3889 SYSCTL_PROC(_kern
, OID_AUTO
, pfz
,
3890 CTLTYPE_QUAD
| CTLFLAG_RD
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
,
3891 0, 0, sysctl_pfz_start
, "I", "");
3896 * Limit on total memory users can wire.
3898 * vm_global_user_wire_limit - system wide limit on wired memory from all processes combined.
3900 * vm_per_task_user_wire_limit - per address space limit on wired memory. This puts a cap on the process's rlimit value.
3902 * These values are initialized to reasonable defaults at boot time based on the available physical memory in
3905 * All values are in bytes.
3908 vm_map_size_t vm_global_user_wire_limit
;
3909 vm_map_size_t vm_per_task_user_wire_limit
;
3910 extern uint64_t max_mem_actual
, max_mem
;
3912 uint64_t vm_add_wire_count_over_global_limit
;
3913 uint64_t vm_add_wire_count_over_user_limit
;
3915 * We used to have a global in the kernel called vm_global_no_user_wire_limit which was the inverse
3916 * of vm_global_user_wire_limit. But maintaining both of those is silly, and vm_global_user_wire_limit is the
3918 * This function is for backwards compatibility with userspace
3919 * since we exposed the old global via a sysctl.
3922 sysctl_global_no_user_wire_amount(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3924 vm_map_size_t old_value
;
3925 vm_map_size_t new_value
;
3928 uint64_t config_memsize
= max_mem
;
3929 #if defined(XNU_TARGET_OS_OSX)
3930 config_memsize
= max_mem_actual
;
3931 #endif /* defined(XNU_TARGET_OS_OSX) */
3933 old_value
= (vm_map_size_t
)(config_memsize
- vm_global_user_wire_limit
);
3934 error
= sysctl_io_number(req
, old_value
, sizeof(vm_map_size_t
), &new_value
, &changed
);
3936 if ((uint64_t)new_value
> config_memsize
) {
3939 vm_global_user_wire_limit
= (vm_map_size_t
)(config_memsize
- new_value
);
3945 * There needs to be a more automatic/elegant way to do this
3947 #if defined(__ARM__)
3948 SYSCTL_INT(_vm
, OID_AUTO
, global_user_wire_limit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_global_user_wire_limit
, 0, "");
3949 SYSCTL_INT(_vm
, OID_AUTO
, user_wire_limit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_per_task_user_wire_limit
, 0, "");
3950 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", "");
3952 SYSCTL_QUAD(_vm
, OID_AUTO
, global_user_wire_limit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_global_user_wire_limit
, "");
3953 SYSCTL_QUAD(_vm
, OID_AUTO
, user_wire_limit
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_per_task_user_wire_limit
, "");
3954 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", "");
3958 * Relaxed atomic RW of a 64bit value via sysctl.
3961 sysctl_r_64bit_atomic(uint64_t *ptr
, struct sysctl_req
*req
)
3967 old_value
= os_atomic_load_wide(ptr
, relaxed
);
3968 error
= sysctl_io_number(req
, old_value
, sizeof(vm_map_size_t
), &new_value
, NULL
);
3972 sysctl_add_wire_count_over_global_limit(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3974 return sysctl_r_64bit_atomic(&vm_add_wire_count_over_global_limit
, req
);
3977 sysctl_add_wire_count_over_user_limit(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
3979 return sysctl_r_64bit_atomic(&vm_add_wire_count_over_user_limit
, req
);
3982 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", "");
3983 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", "");
3985 #if DEVELOPMENT || DEBUG
3986 /* These sysctls are used to test the wired limit. */
3987 extern unsigned int vm_page_wire_count
;
3988 extern uint32_t vm_lopage_free_count
;
3989 SYSCTL_INT(_vm
, OID_AUTO
, page_wire_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_wire_count
, 0, "");
3990 SYSCTL_INT(_vm
, OID_AUTO
, lopage_free_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_lopage_free_count
, 0, "");
3991 #endif /* DEVELOPMENT */
3993 extern int vm_map_copy_overwrite_aligned_src_not_internal
;
3994 extern int vm_map_copy_overwrite_aligned_src_not_symmetric
;
3995 extern int vm_map_copy_overwrite_aligned_src_large
;
3996 SYSCTL_INT(_vm
, OID_AUTO
, vm_copy_src_not_internal
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_map_copy_overwrite_aligned_src_not_internal
, 0, "");
3997 SYSCTL_INT(_vm
, OID_AUTO
, vm_copy_src_not_symmetric
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_map_copy_overwrite_aligned_src_not_symmetric
, 0, "");
3998 SYSCTL_INT(_vm
, OID_AUTO
, vm_copy_src_large
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_map_copy_overwrite_aligned_src_large
, 0, "");
4001 extern uint32_t vm_page_external_count
;
4003 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_external_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_external_count
, 0, "");
4005 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_filecache_min
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_state
.vm_page_filecache_min
, 0, "");
4006 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_xpmapped_min
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_state
.vm_page_xpmapped_min
, 0, "");
4008 #if DEVELOPMENT || DEBUG
4009 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_filecache_min_divisor
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_state
.vm_page_filecache_min_divisor
, 0, "");
4010 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_xpmapped_min_divisor
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_state
.vm_page_xpmapped_min_divisor
, 0, "");
4013 extern int vm_compressor_mode
;
4014 extern int vm_compressor_is_active
;
4015 extern int vm_compressor_available
;
4016 extern uint32_t vm_ripe_target_age
;
4017 extern uint32_t swapout_target_age
;
4018 extern int64_t compressor_bytes_used
;
4019 extern int64_t c_segment_input_bytes
;
4020 extern int64_t c_segment_compressed_bytes
;
4021 extern uint32_t compressor_eval_period_in_msecs
;
4022 extern uint32_t compressor_sample_min_in_msecs
;
4023 extern uint32_t compressor_sample_max_in_msecs
;
4024 extern uint32_t compressor_thrashing_threshold_per_10msecs
;
4025 extern uint32_t compressor_thrashing_min_per_10msecs
;
4026 extern uint32_t vm_compressor_time_thread
;
4028 #if DEVELOPMENT || DEBUG
4029 extern uint32_t vm_compressor_minorcompact_threshold_divisor
;
4030 extern uint32_t vm_compressor_majorcompact_threshold_divisor
;
4031 extern uint32_t vm_compressor_unthrottle_threshold_divisor
;
4032 extern uint32_t vm_compressor_catchup_threshold_divisor
;
4034 extern uint32_t vm_compressor_minorcompact_threshold_divisor_overridden
;
4035 extern uint32_t vm_compressor_majorcompact_threshold_divisor_overridden
;
4036 extern uint32_t vm_compressor_unthrottle_threshold_divisor_overridden
;
4037 extern uint32_t vm_compressor_catchup_threshold_divisor_overridden
;
4039 extern vmct_stats_t vmct_stats
;
4043 sysctl_minorcompact_threshold_divisor(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4045 int new_value
, changed
;
4046 int error
= sysctl_io_number(req
, vm_compressor_minorcompact_threshold_divisor
, sizeof(int), &new_value
, &changed
);
4049 vm_compressor_minorcompact_threshold_divisor
= new_value
;
4050 vm_compressor_minorcompact_threshold_divisor_overridden
= 1;
4055 SYSCTL_PROC(_vm
, OID_AUTO
, compressor_minorcompact_threshold_divisor
,
4056 CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4057 0, 0, sysctl_minorcompact_threshold_divisor
, "I", "");
4061 sysctl_majorcompact_threshold_divisor(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4063 int new_value
, changed
;
4064 int error
= sysctl_io_number(req
, vm_compressor_majorcompact_threshold_divisor
, sizeof(int), &new_value
, &changed
);
4067 vm_compressor_majorcompact_threshold_divisor
= new_value
;
4068 vm_compressor_majorcompact_threshold_divisor_overridden
= 1;
4073 SYSCTL_PROC(_vm
, OID_AUTO
, compressor_majorcompact_threshold_divisor
,
4074 CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4075 0, 0, sysctl_majorcompact_threshold_divisor
, "I", "");
4079 sysctl_unthrottle_threshold_divisor(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4081 int new_value
, changed
;
4082 int error
= sysctl_io_number(req
, vm_compressor_unthrottle_threshold_divisor
, sizeof(int), &new_value
, &changed
);
4085 vm_compressor_unthrottle_threshold_divisor
= new_value
;
4086 vm_compressor_unthrottle_threshold_divisor_overridden
= 1;
4091 SYSCTL_PROC(_vm
, OID_AUTO
, compressor_unthrottle_threshold_divisor
,
4092 CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4093 0, 0, sysctl_unthrottle_threshold_divisor
, "I", "");
4097 sysctl_catchup_threshold_divisor(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4099 int new_value
, changed
;
4100 int error
= sysctl_io_number(req
, vm_compressor_catchup_threshold_divisor
, sizeof(int), &new_value
, &changed
);
4103 vm_compressor_catchup_threshold_divisor
= new_value
;
4104 vm_compressor_catchup_threshold_divisor_overridden
= 1;
4109 SYSCTL_PROC(_vm
, OID_AUTO
, compressor_catchup_threshold_divisor
,
4110 CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4111 0, 0, sysctl_catchup_threshold_divisor
, "I", "");
4115 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_input_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &c_segment_input_bytes
, "");
4116 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_compressed_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &c_segment_compressed_bytes
, "");
4117 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_bytes_used
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_bytes_used
, "");
4119 SYSCTL_INT(_vm
, OID_AUTO
, compressor_mode
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_compressor_mode
, 0, "");
4120 SYSCTL_INT(_vm
, OID_AUTO
, compressor_is_active
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_compressor_is_active
, 0, "");
4121 SYSCTL_INT(_vm
, OID_AUTO
, compressor_swapout_target_age
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &swapout_target_age
, 0, "");
4122 SYSCTL_INT(_vm
, OID_AUTO
, compressor_available
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_compressor_available
, 0, "");
4124 extern int min_csegs_per_major_compaction
;
4125 SYSCTL_INT(_vm
, OID_AUTO
, compressor_min_csegs_per_major_compaction
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &min_csegs_per_major_compaction
, 0, "");
4127 SYSCTL_INT(_vm
, OID_AUTO
, vm_ripe_target_age_in_secs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_ripe_target_age
, 0, "");
4129 SYSCTL_INT(_vm
, OID_AUTO
, compressor_eval_period_in_msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &compressor_eval_period_in_msecs
, 0, "");
4130 SYSCTL_INT(_vm
, OID_AUTO
, compressor_sample_min_in_msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &compressor_sample_min_in_msecs
, 0, "");
4131 SYSCTL_INT(_vm
, OID_AUTO
, compressor_sample_max_in_msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &compressor_sample_max_in_msecs
, 0, "");
4132 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thrashing_threshold_per_10msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &compressor_thrashing_threshold_per_10msecs
, 0, "");
4133 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thrashing_min_per_10msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &compressor_thrashing_min_per_10msecs
, 0, "");
4135 SYSCTL_STRING(_vm
, OID_AUTO
, swapfileprefix
, CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
, swapfilename
, sizeof(swapfilename
) - SWAPFILENAME_INDEX_LEN
, "");
4137 SYSCTL_INT(_vm
, OID_AUTO
, compressor_timing_enabled
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_compressor_time_thread
, 0, "");
4139 #if DEVELOPMENT || DEBUG
4140 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_runtime0
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_runtimes
[0], "");
4141 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_runtime1
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_runtimes
[1], "");
4143 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_threads_total
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_cthreads_total
, "");
4145 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_pages0
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_pages
[0], "");
4146 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_pages1
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_pages
[1], "");
4148 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_iterations0
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_iterations
[0], "");
4149 SYSCTL_QUAD(_vm
, OID_AUTO
, compressor_thread_iterations1
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_iterations
[1], "");
4151 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thread_minpages0
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_minpages
[0], 0, "");
4152 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thread_minpages1
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_minpages
[1], 0, "");
4154 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thread_maxpages0
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_maxpages
[0], 0, "");
4155 SYSCTL_INT(_vm
, OID_AUTO
, compressor_thread_maxpages1
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vmct_stats
.vmct_maxpages
[1], 0, "");
4157 int vm_compressor_injected_error_count
;
4159 SYSCTL_INT(_vm
, OID_AUTO
, compressor_injected_error_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_compressor_injected_error_count
, 0, "");
4162 sysctl_compressor_inject_error(__unused
struct sysctl_oid
*oidp
,
4163 __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4166 vm_address_t va
= 0;
4169 result
= sysctl_io_number(req
, va
, sizeof(va
), &va
, &changed
);
4170 if (result
== 0 && changed
) {
4171 result
= vm_map_inject_error(current_map(), va
);
4174 * Count the number of errors injected successfully to detect
4175 * situations where corruption was caused by improper use of this
4178 os_atomic_inc(&vm_compressor_injected_error_count
, relaxed
);
4184 SYSCTL_PROC(_vm
, OID_AUTO
, compressor_inject_error
, CTLTYPE_QUAD
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4185 0, 0, sysctl_compressor_inject_error
, "Q", "flips a bit in a compressed page for the current task");
4189 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_compressions
, "");
4190 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_compression_failures
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_compression_failures
, "");
4191 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_compressed_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_compressed_bytes
, "");
4192 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_wk_compression_delta
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_wk_compression_delta
, "");
4193 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_wk_compression_negative_delta
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_wk_compression_negative_delta
, "");
4195 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_decompressions
, "");
4196 SYSCTL_QUAD(_vm
, OID_AUTO
, lz4_decompressed_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.lz4_decompressed_bytes
, "");
4198 SYSCTL_QUAD(_vm
, OID_AUTO
, uc_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.uc_decompressions
, "");
4200 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_compressions
, "");
4202 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_catime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_cabstime
, "");
4204 SYSCTL_QUAD(_vm
, OID_AUTO
, wkh_catime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wkh_cabstime
, "");
4205 SYSCTL_QUAD(_vm
, OID_AUTO
, wkh_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wkh_compressions
, "");
4207 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_catime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_cabstime
, "");
4208 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_compressions
, "");
4210 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_compressions_exclusive
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_compressions_exclusive
, "");
4211 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_sv_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_sv_compressions
, "");
4212 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_mzv_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_mzv_compressions
, "");
4213 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_compression_failures
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_compression_failures
, "");
4214 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_compressed_bytes_exclusive
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_compressed_bytes_exclusive
, "");
4215 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_compressed_bytes_total
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_compressed_bytes_total
, "");
4217 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_compressed_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_compressed_bytes
, "");
4218 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_compression_failures
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_compression_failures
, "");
4219 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_sv_compressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_sv_compressions
, "");
4222 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_decompressions
, "");
4224 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_datime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_dabstime
, "");
4226 SYSCTL_QUAD(_vm
, OID_AUTO
, wkh_datime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wkh_dabstime
, "");
4227 SYSCTL_QUAD(_vm
, OID_AUTO
, wkh_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wkh_decompressions
, "");
4229 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_datime
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_dabstime
, "");
4230 SYSCTL_QUAD(_vm
, OID_AUTO
, wks_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wks_decompressions
, "");
4232 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_decompressed_bytes
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_decompressed_bytes
, "");
4233 SYSCTL_QUAD(_vm
, OID_AUTO
, wk_sv_decompressions
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &compressor_stats
.wk_sv_decompressions
, "");
4235 SYSCTL_INT(_vm
, OID_AUTO
, lz4_threshold
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_threshold
, 0, "");
4236 SYSCTL_INT(_vm
, OID_AUTO
, wkdm_reeval_threshold
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.wkdm_reeval_threshold
, 0, "");
4237 SYSCTL_INT(_vm
, OID_AUTO
, lz4_max_failure_skips
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_max_failure_skips
, 0, "");
4238 SYSCTL_INT(_vm
, OID_AUTO
, lz4_max_failure_run_length
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_max_failure_run_length
, 0, "");
4239 SYSCTL_INT(_vm
, OID_AUTO
, lz4_max_preselects
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_max_preselects
, 0, "");
4240 SYSCTL_INT(_vm
, OID_AUTO
, lz4_run_preselection_threshold
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_run_preselection_threshold
, 0, "");
4241 SYSCTL_INT(_vm
, OID_AUTO
, lz4_run_continue_bytes
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_run_continue_bytes
, 0, "");
4242 SYSCTL_INT(_vm
, OID_AUTO
, lz4_profitable_bytes
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vmctune
.lz4_profitable_bytes
, 0, "");
4243 #if DEVELOPMENT || DEBUG
4244 extern int vm_compressor_current_codec
;
4245 extern int vm_compressor_test_seg_wp
;
4246 extern boolean_t vm_compressor_force_sw_wkdm
;
4247 SYSCTL_INT(_vm
, OID_AUTO
, compressor_codec
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_compressor_current_codec
, 0, "");
4248 SYSCTL_INT(_vm
, OID_AUTO
, compressor_test_wp
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_compressor_test_seg_wp
, 0, "");
4250 SYSCTL_INT(_vm
, OID_AUTO
, wksw_force
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_compressor_force_sw_wkdm
, 0, "");
4251 extern int precompy
, wkswhw
;
4253 SYSCTL_INT(_vm
, OID_AUTO
, precompy
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &precompy
, 0, "");
4254 SYSCTL_INT(_vm
, OID_AUTO
, wkswhw
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &wkswhw
, 0, "");
4255 extern unsigned int vm_ktrace_enabled
;
4256 SYSCTL_INT(_vm
, OID_AUTO
, vm_ktrace
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_ktrace_enabled
, 0, "");
4259 #if CONFIG_PHANTOM_CACHE
4260 extern uint32_t phantom_cache_thrashing_threshold
;
4261 extern uint32_t phantom_cache_eval_period_in_msecs
;
4262 extern uint32_t phantom_cache_thrashing_threshold_ssd
;
4265 SYSCTL_INT(_vm
, OID_AUTO
, phantom_cache_eval_period_in_msecs
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &phantom_cache_eval_period_in_msecs
, 0, "");
4266 SYSCTL_INT(_vm
, OID_AUTO
, phantom_cache_thrashing_threshold
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &phantom_cache_thrashing_threshold
, 0, "");
4267 SYSCTL_INT(_vm
, OID_AUTO
, phantom_cache_thrashing_threshold_ssd
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &phantom_cache_thrashing_threshold_ssd
, 0, "");
4270 #if CONFIG_BACKGROUND_QUEUE
4272 extern uint32_t vm_page_background_count
;
4273 extern uint32_t vm_page_background_target
;
4274 extern uint32_t vm_page_background_internal_count
;
4275 extern uint32_t vm_page_background_external_count
;
4276 extern uint32_t vm_page_background_mode
;
4277 extern uint32_t vm_page_background_exclude_external
;
4278 extern uint64_t vm_page_background_promoted_count
;
4279 extern uint64_t vm_pageout_rejected_bq_internal
;
4280 extern uint64_t vm_pageout_rejected_bq_external
;
4282 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_mode
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_page_background_mode
, 0, "");
4283 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_exclude_external
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_page_background_exclude_external
, 0, "");
4284 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_target
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_page_background_target
, 0, "");
4285 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_background_count
, 0, "");
4286 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_internal_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_background_internal_count
, 0, "");
4287 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_background_external_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_background_external_count
, 0, "");
4289 SYSCTL_QUAD(_vm
, OID_AUTO
, vm_page_background_promoted_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_background_promoted_count
, "");
4290 SYSCTL_QUAD(_vm
, OID_AUTO
, vm_pageout_considered_bq_internal
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_vminfo
.vm_pageout_considered_bq_internal
, "");
4291 SYSCTL_QUAD(_vm
, OID_AUTO
, vm_pageout_considered_bq_external
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_vminfo
.vm_pageout_considered_bq_external
, "");
4292 SYSCTL_QUAD(_vm
, OID_AUTO
, vm_pageout_rejected_bq_internal
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_rejected_bq_internal
, "");
4293 SYSCTL_QUAD(_vm
, OID_AUTO
, vm_pageout_rejected_bq_external
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_pageout_rejected_bq_external
, "");
4295 #endif /* CONFIG_BACKGROUND_QUEUE */
4297 extern void vm_update_darkwake_mode(boolean_t
);
4298 extern boolean_t vm_darkwake_mode
;
4301 sysctl_toggle_darkwake_mode(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4303 int new_value
, changed
;
4304 int error
= sysctl_io_number(req
, vm_darkwake_mode
, sizeof(int), &new_value
, &changed
);
4306 if (!error
&& changed
) {
4307 if (new_value
!= 0 && new_value
!= 1) {
4308 printf("Error: Invalid value passed to darkwake sysctl. Acceptable: 0 or 1.\n");
4311 vm_update_darkwake_mode((boolean_t
) new_value
);
4318 SYSCTL_PROC(_vm
, OID_AUTO
, darkwake_mode
,
4319 CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
4320 0, 0, sysctl_toggle_darkwake_mode
, "I", "");
4322 #if (DEVELOPMENT || DEBUG)
4324 SYSCTL_UINT(_vm
, OID_AUTO
, vm_page_creation_throttled_hard
,
4325 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4326 &vm_page_creation_throttled_hard
, 0, "");
4328 SYSCTL_UINT(_vm
, OID_AUTO
, vm_page_creation_throttled_soft
,
4329 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4330 &vm_page_creation_throttled_soft
, 0, "");
4332 extern uint32_t vm_pageout_memorystatus_fb_factor_nr
;
4333 extern uint32_t vm_pageout_memorystatus_fb_factor_dr
;
4334 SYSCTL_INT(_vm
, OID_AUTO
, vm_pageout_memorystatus_fb_factor_nr
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_memorystatus_fb_factor_nr
, 0, "");
4335 SYSCTL_INT(_vm
, OID_AUTO
, vm_pageout_memorystatus_fb_factor_dr
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_memorystatus_fb_factor_dr
, 0, "");
4337 extern uint32_t vm_grab_anon_nops
;
4339 SYSCTL_INT(_vm
, OID_AUTO
, vm_grab_anon_overrides
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_debug
.vm_grab_anon_overrides
, 0, "");
4340 SYSCTL_INT(_vm
, OID_AUTO
, vm_grab_anon_nops
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &vm_pageout_debug
.vm_grab_anon_nops
, 0, "");
4342 extern int vm_page_delayed_work_ctx_needed
;
4343 SYSCTL_INT(_vm
, OID_AUTO
, vm_page_needed_delayed_work_ctx
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &vm_page_delayed_work_ctx_needed
, 0, "");
4345 /* log message counters for persistence mode */
4346 extern uint32_t oslog_p_total_msgcount
;
4347 extern uint32_t oslog_p_metadata_saved_msgcount
;
4348 extern uint32_t oslog_p_metadata_dropped_msgcount
;
4349 extern uint32_t oslog_p_error_count
;
4350 extern uint32_t oslog_p_saved_msgcount
;
4351 extern uint32_t oslog_p_dropped_msgcount
;
4352 extern uint32_t oslog_p_boot_dropped_msgcount
;
4353 extern uint32_t oslog_p_coprocessor_total_msgcount
;
4354 extern uint32_t oslog_p_coprocessor_dropped_msgcount
;
4356 /* log message counters for streaming mode */
4357 extern uint32_t oslog_s_total_msgcount
;
4358 extern uint32_t oslog_s_metadata_msgcount
;
4359 extern uint32_t oslog_s_error_count
;
4360 extern uint32_t oslog_s_streamed_msgcount
;
4361 extern uint32_t oslog_s_dropped_msgcount
;
4363 /* log message counters for msgbuf logging */
4364 extern uint32_t oslog_msgbuf_msgcount
;
4365 extern uint32_t oslog_msgbuf_dropped_msgcount
;
4366 extern uint32_t oslog_msgbuf_dropped_charcount
;
4368 /* log message counters for vaddlog logging */
4369 extern uint32_t vaddlog_msgcount
;
4370 extern uint32_t vaddlog_msgcount_dropped
;
4372 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_p_total_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_p_total_msgcount
, 0, "");
4373 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_p_metadata_saved_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_p_metadata_saved_msgcount
, 0, "");
4374 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_p_metadata_dropped_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_p_metadata_dropped_msgcount
, 0, "");
4375 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_p_error_count
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_p_error_count
, 0, "");
4376 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_p_saved_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_p_saved_msgcount
, 0, "");
4377 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_p_dropped_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_p_dropped_msgcount
, 0, "");
4378 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_p_boot_dropped_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_p_boot_dropped_msgcount
, 0, "");
4379 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_p_coprocessor_total_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_p_coprocessor_total_msgcount
, 0, "");
4380 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_p_coprocessor_dropped_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_p_coprocessor_dropped_msgcount
, 0, "");
4382 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_s_total_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_s_total_msgcount
, 0, "");
4383 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_s_metadata_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_s_metadata_msgcount
, 0, "");
4384 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_s_error_count
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_s_error_count
, 0, "");
4385 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_s_streamed_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_s_streamed_msgcount
, 0, "");
4386 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_s_dropped_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_s_dropped_msgcount
, 0, "");
4388 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_msgbuf_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_msgbuf_msgcount
, 0, "");
4389 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_msgbuf_dropped_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_msgbuf_dropped_msgcount
, 0, "");
4390 SYSCTL_UINT(_debug
, OID_AUTO
, oslog_msgbuf_dropped_charcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &oslog_msgbuf_dropped_charcount
, 0, "");
4392 SYSCTL_UINT(_debug
, OID_AUTO
, vaddlog_msgcount
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &vaddlog_msgcount
, 0, "");
4393 SYSCTL_UINT(_debug
, OID_AUTO
, vaddlog_msgcount_dropped
, CTLFLAG_ANYBODY
| CTLFLAG_RD
| CTLFLAG_LOCKED
, &vaddlog_msgcount_dropped
, 0, "");
4395 #endif /* DEVELOPMENT || DEBUG */
4398 * Enable tracing of voucher contents
4400 extern uint32_t ipc_voucher_trace_contents
;
4402 SYSCTL_INT(_kern
, OID_AUTO
, ipc_voucher_trace_contents
,
4403 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ipc_voucher_trace_contents
, 0, "Enable tracing voucher contents");
4406 * Kernel stack size and depth
4408 SYSCTL_INT(_kern
, OID_AUTO
, stack_size
,
4409 CTLFLAG_RD
| CTLFLAG_LOCKED
, (int *) &kernel_stack_size
, 0, "Kernel stack size");
4410 SYSCTL_INT(_kern
, OID_AUTO
, stack_depth_max
,
4411 CTLFLAG_RD
| CTLFLAG_LOCKED
, (int *) &kernel_stack_depth_max
, 0, "Max kernel stack depth at interrupt or context switch");
4413 extern unsigned int kern_feature_overrides
;
4414 SYSCTL_INT(_kern
, OID_AUTO
, kern_feature_overrides
,
4415 CTLFLAG_RD
| CTLFLAG_LOCKED
, &kern_feature_overrides
, 0, "Kernel feature override mask");
4418 * enable back trace for port allocations
4420 extern int ipc_portbt
;
4422 SYSCTL_INT(_kern
, OID_AUTO
, ipc_portbt
,
4423 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4424 &ipc_portbt
, 0, "");
4427 * Mach message signature validation control and outputs
4429 extern unsigned int ikm_signature_failures
;
4430 SYSCTL_INT(_kern
, OID_AUTO
, ikm_signature_failures
,
4431 CTLFLAG_RD
| CTLFLAG_LOCKED
, &ikm_signature_failures
, 0, "Message signature failure count");
4432 extern unsigned int ikm_signature_failure_id
;
4433 SYSCTL_INT(_kern
, OID_AUTO
, ikm_signature_failure_id
,
4434 CTLFLAG_RD
| CTLFLAG_LOCKED
, &ikm_signature_failure_id
, 0, "Message signature failure count");
4436 #if (DEVELOPMENT || DEBUG)
4437 extern unsigned int ikm_signature_panic_disable
;
4438 SYSCTL_INT(_kern
, OID_AUTO
, ikm_signature_panic_disable
,
4439 CTLFLAG_RW
| CTLFLAG_LOCKED
, &ikm_signature_panic_disable
, 0, "Message signature failure mode");
4440 extern unsigned int ikm_signature_header_failures
;
4441 SYSCTL_INT(_kern
, OID_AUTO
, ikm_signature_header_failures
,
4442 CTLFLAG_RD
| CTLFLAG_LOCKED
, &ikm_signature_header_failures
, 0, "Message header signature failure count");
4443 extern unsigned int ikm_signature_trailer_failures
;
4444 SYSCTL_INT(_kern
, OID_AUTO
, ikm_signature_trailer_failures
,
4445 CTLFLAG_RD
| CTLFLAG_LOCKED
, &ikm_signature_trailer_failures
, 0, "Message trailer signature failure count");
4452 SYSCTL_STRING(_kern
, OID_AUTO
, sched
,
4453 CTLFLAG_RD
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4454 sched_string
, sizeof(sched_string
),
4455 "Timeshare scheduler implementation");
4457 #if CONFIG_QUIESCE_COUNTER
4459 sysctl_cpu_quiescent_counter_interval SYSCTL_HANDLER_ARGS
4461 #pragma unused(arg1, arg2)
4463 uint32_t local_min_interval_us
= cpu_quiescent_counter_get_min_interval_us();
4465 int error
= sysctl_handle_int(oidp
, &local_min_interval_us
, 0, req
);
4466 if (error
|| !req
->newptr
) {
4470 cpu_quiescent_counter_set_min_interval_us(local_min_interval_us
);
4475 SYSCTL_PROC(_kern
, OID_AUTO
, cpu_checkin_interval
,
4476 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4478 sysctl_cpu_quiescent_counter_interval
, "I",
4479 "Quiescent CPU checkin interval (microseconds)");
4480 #endif /* CONFIG_QUIESCE_COUNTER */
4484 * Only support runtime modification on development / debug
4486 #if DEVELOPMENT || DEBUG
4487 extern int precise_user_kernel_time
;
4488 SYSCTL_INT(_kern
, OID_AUTO
, precise_user_kernel_time
,
4489 CTLFLAG_RW
| CTLFLAG_LOCKED
,
4490 &precise_user_kernel_time
, 0, "Precise accounting of kernel vs. user time");
4491 #endif /* DEVELOPMENT || DEBUG */
4493 /* Parameters related to timer coalescing tuning, to be replaced
4494 * with a dedicated systemcall in the future.
4496 /* Enable processing pending timers in the context of any other interrupt
4497 * Coalescing tuning parameters for various thread/task attributes */
4499 sysctl_timer_user_us_kernel_abstime SYSCTL_HANDLER_ARGS
4501 #pragma unused(oidp)
4502 int size
= arg2
; /* subcommand*/
4505 uint64_t old_value_ns
;
4506 uint64_t new_value_ns
;
4507 uint64_t value_abstime
;
4508 if (size
== sizeof(uint32_t)) {
4509 value_abstime
= *((uint32_t *)arg1
);
4510 } else if (size
== sizeof(uint64_t)) {
4511 value_abstime
= *((uint64_t *)arg1
);
4516 absolutetime_to_nanoseconds(value_abstime
, &old_value_ns
);
4517 error
= sysctl_io_number(req
, old_value_ns
, sizeof(old_value_ns
), &new_value_ns
, &changed
);
4518 if ((error
) || (!changed
)) {
4522 nanoseconds_to_absolutetime(new_value_ns
, &value_abstime
);
4523 if (size
== sizeof(uint32_t)) {
4524 *((uint32_t *)arg1
) = (uint32_t)value_abstime
;
4526 *((uint64_t *)arg1
) = value_abstime
;
4531 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_bg_scale
,
4532 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4533 &tcoal_prio_params
.timer_coalesce_bg_shift
, 0, "");
4534 SYSCTL_PROC(_kern
, OID_AUTO
, timer_resort_threshold_ns
,
4535 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4536 &tcoal_prio_params
.timer_resort_threshold_abstime
,
4537 sizeof(tcoal_prio_params
.timer_resort_threshold_abstime
),
4538 sysctl_timer_user_us_kernel_abstime
,
4540 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_bg_ns_max
,
4541 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4542 &tcoal_prio_params
.timer_coalesce_bg_abstime_max
,
4543 sizeof(tcoal_prio_params
.timer_coalesce_bg_abstime_max
),
4544 sysctl_timer_user_us_kernel_abstime
,
4547 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_kt_scale
,
4548 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4549 &tcoal_prio_params
.timer_coalesce_kt_shift
, 0, "");
4551 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_kt_ns_max
,
4552 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4553 &tcoal_prio_params
.timer_coalesce_kt_abstime_max
,
4554 sizeof(tcoal_prio_params
.timer_coalesce_kt_abstime_max
),
4555 sysctl_timer_user_us_kernel_abstime
,
4558 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_fp_scale
,
4559 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4560 &tcoal_prio_params
.timer_coalesce_fp_shift
, 0, "");
4562 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_fp_ns_max
,
4563 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4564 &tcoal_prio_params
.timer_coalesce_fp_abstime_max
,
4565 sizeof(tcoal_prio_params
.timer_coalesce_fp_abstime_max
),
4566 sysctl_timer_user_us_kernel_abstime
,
4569 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_ts_scale
,
4570 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4571 &tcoal_prio_params
.timer_coalesce_ts_shift
, 0, "");
4573 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_ts_ns_max
,
4574 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4575 &tcoal_prio_params
.timer_coalesce_ts_abstime_max
,
4576 sizeof(tcoal_prio_params
.timer_coalesce_ts_abstime_max
),
4577 sysctl_timer_user_us_kernel_abstime
,
4580 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier0_scale
,
4581 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4582 &tcoal_prio_params
.latency_qos_scale
[0], 0, "");
4584 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier0_ns_max
,
4585 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4586 &tcoal_prio_params
.latency_qos_abstime_max
[0],
4587 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[0]),
4588 sysctl_timer_user_us_kernel_abstime
,
4591 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier1_scale
,
4592 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4593 &tcoal_prio_params
.latency_qos_scale
[1], 0, "");
4595 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier1_ns_max
,
4596 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4597 &tcoal_prio_params
.latency_qos_abstime_max
[1],
4598 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[1]),
4599 sysctl_timer_user_us_kernel_abstime
,
4602 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier2_scale
,
4603 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4604 &tcoal_prio_params
.latency_qos_scale
[2], 0, "");
4606 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier2_ns_max
,
4607 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4608 &tcoal_prio_params
.latency_qos_abstime_max
[2],
4609 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[2]),
4610 sysctl_timer_user_us_kernel_abstime
,
4613 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier3_scale
,
4614 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4615 &tcoal_prio_params
.latency_qos_scale
[3], 0, "");
4617 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier3_ns_max
,
4618 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4619 &tcoal_prio_params
.latency_qos_abstime_max
[3],
4620 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[3]),
4621 sysctl_timer_user_us_kernel_abstime
,
4624 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier4_scale
,
4625 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4626 &tcoal_prio_params
.latency_qos_scale
[4], 0, "");
4628 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier4_ns_max
,
4629 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4630 &tcoal_prio_params
.latency_qos_abstime_max
[4],
4631 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[4]),
4632 sysctl_timer_user_us_kernel_abstime
,
4635 SYSCTL_INT(_kern
, OID_AUTO
, timer_coalesce_tier5_scale
,
4636 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4637 &tcoal_prio_params
.latency_qos_scale
[5], 0, "");
4639 SYSCTL_PROC(_kern
, OID_AUTO
, timer_coalesce_tier5_ns_max
,
4640 CTLTYPE_QUAD
| CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4641 &tcoal_prio_params
.latency_qos_abstime_max
[5],
4642 sizeof(tcoal_prio_params
.latency_qos_abstime_max
[5]),
4643 sysctl_timer_user_us_kernel_abstime
,
4646 /* Communicate the "user idle level" heuristic to the timer layer, and
4647 * potentially other layers in the future.
4651 timer_user_idle_level(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4653 int new_value
= 0, old_value
= 0, changed
= 0, error
;
4655 old_value
= timer_get_user_idle_level();
4657 error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, &changed
);
4659 if (error
== 0 && changed
) {
4660 if (timer_set_user_idle_level(new_value
) != KERN_SUCCESS
) {
4668 SYSCTL_PROC(_machdep
, OID_AUTO
, user_idle_level
,
4669 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4671 timer_user_idle_level
, "I", "User idle level heuristic, 0-128");
4674 SYSCTL_INT(_kern
, OID_AUTO
, hv_support
,
4675 CTLFLAG_KERN
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
4676 &hv_support_available
, 0, "");
4678 SYSCTL_INT(_kern
, OID_AUTO
, hv_disable
,
4679 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4680 &hv_disable
, 0, "");
4683 #if DEVELOPMENT || DEBUG
4684 extern uint64_t driverkit_checkin_timed_out
;
4685 SYSCTL_QUAD(_kern
, OID_AUTO
, driverkit_checkin_timed_out
,
4686 CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4687 &driverkit_checkin_timed_out
, "timestamp of dext checkin timeout");
4691 hv_vmm_present SYSCTL_HANDLER_ARGS
4693 __unused
struct sysctl_oid
*unused_oidp
= oidp
;
4694 __unused
void *unused_arg1
= arg1
;
4695 __unused
int unused_arg2
= arg2
;
4697 int hv_vmm_present
= 0;
4699 #if defined (__arm64__)
4700 /* <rdar://problem/59966231> Need a way to determine if ARM xnu is running as a guest */
4701 #elif defined (__x86_64__)
4702 hv_vmm_present
= cpuid_vmm_present();
4705 return SYSCTL_OUT(req
, &hv_vmm_present
, sizeof(hv_vmm_present
));
4708 SYSCTL_PROC(_kern
, OID_AUTO
, hv_vmm_present
,
4709 CTLTYPE_INT
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
4711 hv_vmm_present
, "I", "");
4715 sysctl_darkboot SYSCTL_HANDLER_ARGS
4717 int err
= 0, value
= 0;
4718 #pragma unused(oidp, arg1, arg2, err, value, req)
4721 * Handle the sysctl request.
4723 * If this is a read, the function will set the value to the current darkboot value. Otherwise,
4724 * we'll get the request identifier into "value" and then we can honor it.
4726 if ((err
= sysctl_io_number(req
, darkboot
, sizeof(int), &value
, NULL
)) != 0) {
4730 /* writing requested, let's process the request */
4732 /* writing is protected by an entitlement */
4733 if (priv_check_cred(kauth_cred_get(), PRIV_DARKBOOT
, 0) != 0) {
4739 case MEMORY_MAINTENANCE_DARK_BOOT_UNSET
:
4741 * If the darkboot sysctl is unset, the NVRAM variable
4742 * must be unset too. If that's not the case, it means
4743 * someone is doing something crazy and not supported.
4745 if (darkboot
!= 0) {
4746 int ret
= PERemoveNVRAMProperty(MEMORY_MAINTENANCE_DARK_BOOT_NVRAM_NAME
);
4754 case MEMORY_MAINTENANCE_DARK_BOOT_SET
:
4757 case MEMORY_MAINTENANCE_DARK_BOOT_SET_PERSISTENT
: {
4759 * Set the NVRAM and update 'darkboot' in case
4760 * of success. Otherwise, do not update
4761 * 'darkboot' and report the failure.
4763 if (PEWriteNVRAMBooleanProperty(MEMORY_MAINTENANCE_DARK_BOOT_NVRAM_NAME
, TRUE
)) {
4780 SYSCTL_PROC(_kern
, OID_AUTO
, darkboot
,
4781 CTLFLAG_KERN
| CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
| CTLFLAG_ANYBODY
,
4782 0, 0, sysctl_darkboot
, "I", "");
4783 #endif /* CONFIG_DARKBOOT */
4785 #if DEVELOPMENT || DEBUG
4786 #include <sys/sysent.h>
4787 /* This should result in a fatal exception, verifying that "sysent" is
4791 kern_sysent_write(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4793 uint64_t new_value
= 0, old_value
= 0;
4794 int changed
= 0, error
;
4796 error
= sysctl_io_number(req
, old_value
, sizeof(uint64_t), &new_value
, &changed
);
4797 if ((error
== 0) && changed
) {
4798 volatile uint32_t *wraddr
= __DECONST(uint32_t *, &sysent
[0]);
4800 printf("sysent[0] write succeeded\n");
4805 SYSCTL_PROC(_kern
, OID_AUTO
, sysent_const_check
,
4806 CTLTYPE_QUAD
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
4808 kern_sysent_write
, "I", "Attempt sysent[0] write");
4812 #if DEVELOPMENT || DEBUG
4813 SYSCTL_COMPAT_INT(_kern
, OID_AUTO
, development
, CTLFLAG_RD
| CTLFLAG_MASKED
, NULL
, 1, "");
4815 SYSCTL_COMPAT_INT(_kern
, OID_AUTO
, development
, CTLFLAG_RD
| CTLFLAG_MASKED
, NULL
, 0, "");
4819 #if DEVELOPMENT || DEBUG
4822 sysctl_panic_test SYSCTL_HANDLER_ARGS
4824 #pragma unused(arg1, arg2)
4826 char str
[32] = "entry prelog postlog postcore";
4828 rval
= sysctl_handle_string(oidp
, str
, sizeof(str
), req
);
4830 if (rval
== 0 && req
->newptr
) {
4831 if (strncmp("entry", str
, strlen("entry")) == 0) {
4832 panic_with_options(0, NULL
, DEBUGGER_OPTION_RECURPANIC_ENTRY
, "test recursive panic at entry");
4833 } else if (strncmp("prelog", str
, strlen("prelog")) == 0) {
4834 panic_with_options(0, NULL
, DEBUGGER_OPTION_RECURPANIC_PRELOG
, "test recursive panic prior to writing a paniclog");
4835 } else if (strncmp("postlog", str
, strlen("postlog")) == 0) {
4836 panic_with_options(0, NULL
, DEBUGGER_OPTION_RECURPANIC_POSTLOG
, "test recursive panic subsequent to paniclog");
4837 } else if (strncmp("postcore", str
, strlen("postcore")) == 0) {
4838 panic_with_options(0, NULL
, DEBUGGER_OPTION_RECURPANIC_POSTCORE
, "test recursive panic subsequent to on-device core");
4846 sysctl_debugger_test SYSCTL_HANDLER_ARGS
4848 #pragma unused(arg1, arg2)
4850 char str
[32] = "entry prelog postlog postcore";
4852 rval
= sysctl_handle_string(oidp
, str
, sizeof(str
), req
);
4854 if (rval
== 0 && req
->newptr
) {
4855 if (strncmp("entry", str
, strlen("entry")) == 0) {
4856 DebuggerWithContext(0, NULL
, "test recursive panic via debugger at entry", DEBUGGER_OPTION_RECURPANIC_ENTRY
);
4857 } else if (strncmp("prelog", str
, strlen("prelog")) == 0) {
4858 DebuggerWithContext(0, NULL
, "test recursive panic via debugger prior to writing a paniclog", DEBUGGER_OPTION_RECURPANIC_PRELOG
);
4859 } else if (strncmp("postlog", str
, strlen("postlog")) == 0) {
4860 DebuggerWithContext(0, NULL
, "test recursive panic via debugger subsequent to paniclog", DEBUGGER_OPTION_RECURPANIC_POSTLOG
);
4861 } else if (strncmp("postcore", str
, strlen("postcore")) == 0) {
4862 DebuggerWithContext(0, NULL
, "test recursive panic via debugger subsequent to on-device core", DEBUGGER_OPTION_RECURPANIC_POSTCORE
);
4869 decl_lck_spin_data(, spinlock_panic_test_lock
);
4871 __attribute__((noreturn
))
4873 spinlock_panic_test_acquire_spinlock(void * arg __unused
, wait_result_t wres __unused
)
4875 lck_spin_lock(&spinlock_panic_test_lock
);
4882 sysctl_spinlock_panic_test SYSCTL_HANDLER_ARGS
4884 #pragma unused(oidp, arg1, arg2)
4885 if (req
->newlen
== 0) {
4889 thread_t panic_spinlock_thread
;
4890 /* Initialize panic spinlock */
4891 lck_grp_t
* panic_spinlock_grp
;
4892 lck_grp_attr_t
* panic_spinlock_grp_attr
;
4893 lck_attr_t
* panic_spinlock_attr
;
4895 panic_spinlock_grp_attr
= lck_grp_attr_alloc_init();
4896 panic_spinlock_grp
= lck_grp_alloc_init("panic_spinlock", panic_spinlock_grp_attr
);
4897 panic_spinlock_attr
= lck_attr_alloc_init();
4899 lck_spin_init(&spinlock_panic_test_lock
, panic_spinlock_grp
, panic_spinlock_attr
);
4902 /* Create thread to acquire spinlock */
4903 if (kernel_thread_start(spinlock_panic_test_acquire_spinlock
, NULL
, &panic_spinlock_thread
) != KERN_SUCCESS
) {
4907 /* Try to acquire spinlock -- should panic eventually */
4908 lck_spin_lock(&spinlock_panic_test_lock
);
4914 __attribute__((noreturn
))
4916 simultaneous_panic_worker
4917 (void * arg
, wait_result_t wres __unused
)
4919 atomic_int
*start_panic
= (atomic_int
*)arg
;
4921 while (!atomic_load(start_panic
)) {
4924 panic("SIMULTANEOUS PANIC TEST: INITIATING PANIC FROM CPU %d", cpu_number());
4925 __builtin_unreachable();
4929 sysctl_simultaneous_panic_test SYSCTL_HANDLER_ARGS
4931 #pragma unused(oidp, arg1, arg2)
4932 if (req
->newlen
== 0) {
4936 int i
= 0, threads_to_create
= 2 * processor_count
;
4937 atomic_int start_panic
= 0;
4938 unsigned int threads_created
= 0;
4939 thread_t new_panic_thread
;
4941 for (i
= threads_to_create
; i
> 0; i
--) {
4942 if (kernel_thread_start(simultaneous_panic_worker
, (void *) &start_panic
, &new_panic_thread
) == KERN_SUCCESS
) {
4947 /* FAIL if we couldn't create at least processor_count threads */
4948 if (threads_created
< processor_count
) {
4949 panic("SIMULTANEOUS PANIC TEST: FAILED TO CREATE ENOUGH THREADS, ONLY CREATED %d (of %d)",
4950 threads_created
, threads_to_create
);
4953 atomic_exchange(&start_panic
, 1);
4959 SYSCTL_PROC(_debug
, OID_AUTO
, panic_test
, CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_MASKED
, 0, 0, sysctl_panic_test
, "A", "panic test");
4960 SYSCTL_PROC(_debug
, OID_AUTO
, debugger_test
, CTLTYPE_STRING
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_MASKED
, 0, 0, sysctl_debugger_test
, "A", "debugger test");
4961 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");
4962 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");
4964 extern int exc_resource_threads_enabled
;
4966 SYSCTL_INT(_kern
, OID_AUTO
, exc_resource_threads_enabled
, CTLFLAG_RD
| CTLFLAG_LOCKED
, &exc_resource_threads_enabled
, 0, "exc_resource thread limit enabled");
4969 #endif /* DEVELOPMENT || DEBUG */
4971 #if CONFIG_THREAD_GROUPS
4972 #if DEVELOPMENT || DEBUG
4975 sysctl_get_thread_group_id SYSCTL_HANDLER_ARGS
4977 #pragma unused(arg1, arg2, oidp)
4978 uint64_t thread_group_id
= thread_group_get_id(thread_group_get(current_thread()));
4979 return SYSCTL_OUT(req
, &thread_group_id
, sizeof(thread_group_id
));
4982 SYSCTL_PROC(_kern
, OID_AUTO
, thread_group_id
, CTLFLAG_RD
| CTLFLAG_LOCKED
| CTLTYPE_QUAD
,
4983 0, 0, &sysctl_get_thread_group_id
, "I", "thread group id of the thread");
4986 sysctl_thread_group_count(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
4988 int value
= thread_group_count();
4989 return sysctl_io_number(req
, value
, sizeof(value
), NULL
, NULL
);
4992 SYSCTL_PROC(_kern
, OID_AUTO
, thread_group_count
, CTLFLAG_RD
| CTLFLAG_LOCKED
| CTLFLAG_KERN
,
4993 0, 0, &sysctl_thread_group_count
, "I", "count of thread groups");
4995 #endif /* DEVELOPMENT || DEBUG */
4996 const uint32_t thread_groups_supported
= 1;
4997 #else /* CONFIG_THREAD_GROUPS */
4998 const uint32_t thread_groups_supported
= 0;
4999 #endif /* CONFIG_THREAD_GROUPS */
5002 sysctl_thread_groups_supported(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
5004 int value
= thread_groups_supported
;
5005 return sysctl_io_number(req
, value
, sizeof(value
), NULL
, NULL
);
5008 SYSCTL_PROC(_kern
, OID_AUTO
, thread_groups_supported
, CTLFLAG_RD
| CTLFLAG_LOCKED
| CTLFLAG_KERN
,
5009 0, 0, &sysctl_thread_groups_supported
, "I", "thread groups supported");
5012 sysctl_grade_cputype SYSCTL_HANDLER_ARGS
5014 #pragma unused(arg1, arg2, oidp)
5016 int type_tuple
[2] = {};
5017 int return_value
= 0;
5019 error
= SYSCTL_IN(req
, &type_tuple
, sizeof(type_tuple
));
5025 return_value
= grade_binary(type_tuple
[0], type_tuple
[1] & ~CPU_SUBTYPE_MASK
, type_tuple
[1] & CPU_SUBTYPE_MASK
, FALSE
);
5027 error
= SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
5036 SYSCTL_PROC(_kern
, OID_AUTO
, grade_cputype
,
5037 CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_MASKED
| CTLFLAG_LOCKED
| CTLTYPE_OPAQUE
,
5038 0, 0, &sysctl_grade_cputype
, "S",
5039 "grade value of cpu_type_t+cpu_sub_type_t");
5041 extern boolean_t allow_direct_handoff
;
5042 SYSCTL_INT(_kern
, OID_AUTO
, direct_handoff
,
5043 CTLFLAG_KERN
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
5044 &allow_direct_handoff
, 0, "Enable direct handoff for realtime threads");
5046 #if DEVELOPMENT || DEBUG
5048 SYSCTL_LONG(_kern
, OID_AUTO
, phys_carveout_pa
, CTLFLAG_RD
| CTLFLAG_LOCKED
,
5050 "base physical address of the phys_carveout_mb boot-arg region");
5051 SYSCTL_LONG(_kern
, OID_AUTO
, phys_carveout_size
, CTLFLAG_RD
| CTLFLAG_LOCKED
,
5052 &phys_carveout_size
,
5053 "size in bytes of the phys_carveout_mb boot-arg region");
5055 extern void do_cseg_wedge_thread(void);
5056 extern void do_cseg_unwedge_thread(void);
5059 cseg_wedge_thread SYSCTL_HANDLER_ARGS
5061 #pragma unused(arg1, arg2)
5064 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5065 if (error
|| val
== 0) {
5069 do_cseg_wedge_thread();
5072 SYSCTL_PROC(_kern
, OID_AUTO
, cseg_wedge_thread
, CTLFLAG_RW
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
, 0, 0, cseg_wedge_thread
, "I", "wedge c_seg thread");
5075 cseg_unwedge_thread SYSCTL_HANDLER_ARGS
5077 #pragma unused(arg1, arg2)
5080 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5081 if (error
|| val
== 0) {
5085 do_cseg_unwedge_thread();
5088 SYSCTL_PROC(_kern
, OID_AUTO
, cseg_unwedge_thread
, CTLFLAG_RW
| CTLFLAG_LOCKED
| CTLFLAG_MASKED
, 0, 0, cseg_unwedge_thread
, "I", "unstuck c_seg thread");
5090 static atomic_int wedge_thread_should_wake
= 0;
5093 unwedge_thread SYSCTL_HANDLER_ARGS
5095 #pragma unused(arg1, arg2)
5097 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5098 if (error
|| val
== 0) {
5102 atomic_store(&wedge_thread_should_wake
, 1);
5106 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");
5109 wedge_thread SYSCTL_HANDLER_ARGS
5111 #pragma unused(arg1, arg2)
5114 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5115 if (error
|| val
== 0) {
5119 uint64_t interval
= 1;
5120 nanoseconds_to_absolutetime(1000 * 1000 * 50, &interval
);
5122 atomic_store(&wedge_thread_should_wake
, 0);
5123 while (!atomic_load(&wedge_thread_should_wake
)) {
5124 tsleep1(NULL
, 0, "wedge_thread", mach_absolute_time() + interval
, NULL
);
5130 SYSCTL_PROC(_kern
, OID_AUTO
, wedge_thread
,
5131 CTLFLAG_RW
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
, 0, 0, wedge_thread
, "I",
5132 "wedge this thread so it cannot be cleaned up");
5135 sysctl_total_corpses_count SYSCTL_HANDLER_ARGS
5137 #pragma unused(oidp, arg1, arg2)
5138 extern unsigned long total_corpses_count(void);
5140 unsigned long corpse_count_long
= total_corpses_count();
5141 unsigned int corpse_count
= (unsigned int)MIN(corpse_count_long
, UINT_MAX
);
5142 return sysctl_io_opaque(req
, &corpse_count
, sizeof(corpse_count
), NULL
);
5145 SYSCTL_PROC(_kern
, OID_AUTO
, total_corpses_count
,
5146 CTLFLAG_RD
| CTLFLAG_ANYBODY
| CTLFLAG_LOCKED
, 0, 0,
5147 sysctl_total_corpses_count
, "I", "total corpses on the system");
5150 sysctl_turnstile_test_prim_lock SYSCTL_HANDLER_ARGS
;
5152 sysctl_turnstile_test_prim_unlock SYSCTL_HANDLER_ARGS
;
5154 tstile_test_prim_lock(boolean_t use_hashtable
);
5156 tstile_test_prim_unlock(boolean_t use_hashtable
);
5159 sysctl_turnstile_test_prim_lock SYSCTL_HANDLER_ARGS
5161 #pragma unused(arg1, arg2)
5163 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5164 if (error
|| val
== 0) {
5168 case SYSCTL_TURNSTILE_TEST_USER_DEFAULT
:
5169 case SYSCTL_TURNSTILE_TEST_USER_HASHTABLE
:
5170 case SYSCTL_TURNSTILE_TEST_KERNEL_DEFAULT
:
5171 case SYSCTL_TURNSTILE_TEST_KERNEL_HASHTABLE
:
5172 return tstile_test_prim_lock(val
);
5179 sysctl_turnstile_test_prim_unlock SYSCTL_HANDLER_ARGS
5181 #pragma unused(arg1, arg2)
5183 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5184 if (error
|| val
== 0) {
5188 case SYSCTL_TURNSTILE_TEST_USER_DEFAULT
:
5189 case SYSCTL_TURNSTILE_TEST_USER_HASHTABLE
:
5190 case SYSCTL_TURNSTILE_TEST_KERNEL_DEFAULT
:
5191 case SYSCTL_TURNSTILE_TEST_KERNEL_HASHTABLE
:
5192 return tstile_test_prim_unlock(val
);
5198 SYSCTL_PROC(_kern
, OID_AUTO
, turnstiles_test_lock
, CTLFLAG_WR
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5199 0, 0, sysctl_turnstile_test_prim_lock
, "I", "turnstiles test lock");
5201 SYSCTL_PROC(_kern
, OID_AUTO
, turnstiles_test_unlock
, CTLFLAG_WR
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5202 0, 0, sysctl_turnstile_test_prim_unlock
, "I", "turnstiles test unlock");
5205 turnstile_get_boost_stats_sysctl(void *req
);
5207 turnstile_get_unboost_stats_sysctl(void *req
);
5209 sysctl_turnstile_boost_stats SYSCTL_HANDLER_ARGS
;
5211 sysctl_turnstile_unboost_stats SYSCTL_HANDLER_ARGS
;
5212 extern uint64_t thread_block_on_turnstile_count
;
5213 extern uint64_t thread_block_on_regular_waitq_count
;
5216 sysctl_turnstile_boost_stats SYSCTL_HANDLER_ARGS
5218 #pragma unused(arg1, arg2, oidp)
5219 return turnstile_get_boost_stats_sysctl(req
);
5223 sysctl_turnstile_unboost_stats SYSCTL_HANDLER_ARGS
5225 #pragma unused(arg1, arg2, oidp)
5226 return turnstile_get_unboost_stats_sysctl(req
);
5229 SYSCTL_PROC(_kern
, OID_AUTO
, turnstile_boost_stats
, CTLFLAG_RD
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
| CTLTYPE_STRUCT
,
5230 0, 0, sysctl_turnstile_boost_stats
, "S", "turnstiles boost stats");
5231 SYSCTL_PROC(_kern
, OID_AUTO
, turnstile_unboost_stats
, CTLFLAG_RD
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
| CTLTYPE_STRUCT
,
5232 0, 0, sysctl_turnstile_unboost_stats
, "S", "turnstiles unboost stats");
5233 SYSCTL_QUAD(_kern
, OID_AUTO
, thread_block_count_on_turnstile
,
5234 CTLFLAG_RD
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5235 &thread_block_on_turnstile_count
, "thread blocked on turnstile count");
5236 SYSCTL_QUAD(_kern
, OID_AUTO
, thread_block_count_on_reg_waitq
,
5237 CTLFLAG_RD
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5238 &thread_block_on_regular_waitq_count
, "thread blocked on regular waitq count");
5241 sysctl_erase_all_test_mtx_stats SYSCTL_HANDLER_ARGS
5243 #pragma unused(arg1, arg2)
5245 error
= sysctl_handle_int(oidp
, &val
, 0, req
);
5246 if (error
|| val
== 0) {
5251 lck_mtx_test_init();
5252 erase_all_test_mtx_stats();
5259 sysctl_get_test_mtx_stats SYSCTL_HANDLER_ARGS
5261 #pragma unused(oidp, arg1, arg2)
5263 int size
, buffer_size
, error
;
5266 buffer
= kheap_alloc(KHEAP_TEMP
, buffer_size
, Z_WAITOK
);
5268 panic("Impossible to allocate memory for %s\n", __func__
);
5271 lck_mtx_test_init();
5273 size
= get_test_mtx_stats_string(buffer
, buffer_size
);
5275 error
= sysctl_io_string(req
, buffer
, size
, 0, NULL
);
5277 kheap_free(KHEAP_TEMP
, buffer
, buffer_size
);
5283 sysctl_test_mtx_uncontended SYSCTL_HANDLER_ARGS
5285 #pragma unused(oidp, arg1, arg2)
5287 int buffer_size
, offset
, error
, iter
;
5298 if (req
->newlen
>= sizeof(input_val
)) {
5302 error
= SYSCTL_IN(req
, input_val
, req
->newlen
);
5306 input_val
[req
->newlen
] = '\0';
5309 error
= sscanf(input_val
, "%d", &iter
);
5311 printf("%s invalid input\n", __func__
);
5316 printf("%s requested %d iterations, not starting the test\n", __func__
, iter
);
5320 lck_mtx_test_init();
5324 buffer
= kheap_alloc(KHEAP_TEMP
, buffer_size
, Z_WAITOK
);
5326 panic("Impossible to allocate memory for %s\n", __func__
);
5328 memset(buffer
, 0, buffer_size
);
5330 printf("%s starting uncontended mutex test with %d iterations\n", __func__
, iter
);
5332 offset
= scnprintf(buffer
, buffer_size
, "STATS INNER LOOP");
5333 offset
+= lck_mtx_test_mtx_uncontended(iter
, &buffer
[offset
], buffer_size
- offset
);
5335 offset
+= scnprintf(&buffer
[offset
], buffer_size
- offset
, "\nSTATS OUTER LOOP");
5336 offset
+= lck_mtx_test_mtx_uncontended_loop_time(iter
, &buffer
[offset
], buffer_size
- offset
);
5338 error
= SYSCTL_OUT(req
, buffer
, offset
);
5340 kheap_free(KHEAP_TEMP
, buffer
, buffer_size
);
5345 sysctl_test_mtx_contended SYSCTL_HANDLER_ARGS
5347 #pragma unused(oidp, arg1, arg2)
5349 int buffer_size
, offset
, error
, iter
;
5360 if (req
->newlen
>= sizeof(input_val
)) {
5364 error
= SYSCTL_IN(req
, input_val
, req
->newlen
);
5368 input_val
[req
->newlen
] = '\0';
5371 error
= sscanf(input_val
, "%d", &iter
);
5373 printf("%s invalid input\n", __func__
);
5378 printf("%s requested %d iterations, not starting the test\n", __func__
, iter
);
5382 lck_mtx_test_init();
5384 erase_all_test_mtx_stats();
5388 buffer
= kheap_alloc(KHEAP_TEMP
, buffer_size
, Z_WAITOK
| Z_ZERO
);
5390 panic("Impossible to allocate memory for %s\n", __func__
);
5393 printf("%s starting contended mutex test with %d iterations FULL_CONTENDED\n", __func__
, iter
);
5395 offset
= scnprintf(buffer
, buffer_size
, "STATS INNER LOOP");
5396 offset
+= lck_mtx_test_mtx_contended(iter
, &buffer
[offset
], buffer_size
- offset
, FULL_CONTENDED
);
5398 printf("%s starting contended mutex loop test with %d iterations FULL_CONTENDED\n", __func__
, iter
);
5400 offset
+= scnprintf(&buffer
[offset
], buffer_size
- offset
, "\nSTATS OUTER LOOP");
5401 offset
+= lck_mtx_test_mtx_contended_loop_time(iter
, &buffer
[offset
], buffer_size
- offset
, FULL_CONTENDED
);
5403 printf("%s starting contended mutex test with %d iterations HALF_CONTENDED\n", __func__
, iter
);
5405 offset
+= scnprintf(&buffer
[offset
], buffer_size
- offset
, "STATS INNER LOOP");
5406 offset
+= lck_mtx_test_mtx_contended(iter
, &buffer
[offset
], buffer_size
- offset
, HALF_CONTENDED
);
5408 printf("%s starting contended mutex loop test with %d iterations HALF_CONTENDED\n", __func__
, iter
);
5410 offset
+= scnprintf(&buffer
[offset
], buffer_size
- offset
, "\nSTATS OUTER LOOP");
5411 offset
+= lck_mtx_test_mtx_contended_loop_time(iter
, &buffer
[offset
], buffer_size
- offset
, HALF_CONTENDED
);
5413 error
= SYSCTL_OUT(req
, buffer
, offset
);
5415 printf("\n%s\n", buffer
);
5416 kheap_free(KHEAP_TEMP
, buffer
, buffer_size
);
5421 SYSCTL_PROC(_kern
, OID_AUTO
, erase_all_test_mtx_stats
,
5422 CTLFLAG_WR
| CTLFLAG_MASKED
| CTLFLAG_ANYBODY
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5423 0, 0, sysctl_erase_all_test_mtx_stats
, "I", "erase test_mtx statistics");
5425 SYSCTL_PROC(_kern
, OID_AUTO
, get_test_mtx_stats
,
5426 CTLTYPE_STRING
| CTLFLAG_RD
| CTLFLAG_MASKED
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5427 0, 0, sysctl_get_test_mtx_stats
, "A", "get test_mtx statistics");
5429 SYSCTL_PROC(_kern
, OID_AUTO
, test_mtx_contended
,
5430 CTLTYPE_STRING
| CTLFLAG_MASKED
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5431 0, 0, sysctl_test_mtx_contended
, "A", "get statistics for contended mtx test");
5433 SYSCTL_PROC(_kern
, OID_AUTO
, test_mtx_uncontended
,
5434 CTLTYPE_STRING
| CTLFLAG_MASKED
| CTLFLAG_RW
| CTLFLAG_KERN
| CTLFLAG_LOCKED
,
5435 0, 0, sysctl_test_mtx_uncontended
, "A", "get statistics for uncontended mtx test");
5437 extern uint64_t MutexSpin
;
5439 SYSCTL_QUAD(_kern
, OID_AUTO
, mutex_spin_abs
, CTLFLAG_RW
, &MutexSpin
,
5440 "Spin time in abs for acquiring a kernel mutex");
5442 extern uint64_t low_MutexSpin
;
5443 extern int64_t high_MutexSpin
;
5444 extern unsigned int real_ncpus
;
5446 SYSCTL_QUAD(_kern
, OID_AUTO
, low_mutex_spin_abs
, CTLFLAG_RW
, &low_MutexSpin
,
5447 "Low spin threshold in abs for acquiring a kernel mutex");
5450 sysctl_high_mutex_spin_ns SYSCTL_HANDLER_ARGS
5452 #pragma unused(oidp, arg1, arg2)
5457 /* Check if the user is writing to high_MutexSpin, or just reading it */
5459 error
= SYSCTL_IN(req
, &val
, sizeof(val
));
5460 if (error
|| (val
< 0 && val
!= -1)) {
5463 high_MutexSpin
= val
;
5466 if (high_MutexSpin
>= 0) {
5467 res
= high_MutexSpin
;
5469 res
= low_MutexSpin
* real_ncpus
;
5471 return SYSCTL_OUT(req
, &res
, sizeof(res
));
5473 SYSCTL_PROC(_kern
, OID_AUTO
, high_mutex_spin_abs
, CTLFLAG_RW
| CTLTYPE_QUAD
, 0, 0, sysctl_high_mutex_spin_ns
, "I",
5474 "High spin threshold in abs for acquiring a kernel mutex");
5477 #if defined (__x86_64__)
5479 semaphore_t sysctl_test_panic_with_thread_sem
;
5481 #pragma clang diagnostic push
5482 #pragma clang diagnostic ignored "-Winfinite-recursion" /* rdar://38801963 */
5483 __attribute__((noreturn
))
5485 panic_thread_test_child_spin(void * arg
, wait_result_t wres
)
5487 static int panic_thread_recurse_count
= 5;
5489 if (panic_thread_recurse_count
> 0) {
5490 panic_thread_recurse_count
--;
5491 panic_thread_test_child_spin(arg
, wres
);
5494 semaphore_signal(sysctl_test_panic_with_thread_sem
);
5499 #pragma clang diagnostic pop
5502 panic_thread_test_child_park(void * arg __unused
, wait_result_t wres __unused
)
5506 assert_wait(&event
, THREAD_UNINT
);
5507 semaphore_signal(sysctl_test_panic_with_thread_sem
);
5508 thread_block(panic_thread_test_child_park
);
5512 sysctl_test_panic_with_thread SYSCTL_HANDLER_ARGS
5514 #pragma unused(arg1, arg2)
5516 char str
[16] = { '\0' };
5517 thread_t child_thread
= THREAD_NULL
;
5519 rval
= sysctl_handle_string(oidp
, str
, sizeof(str
), req
);
5520 if (rval
!= 0 || !req
->newptr
) {
5524 semaphore_create(kernel_task
, &sysctl_test_panic_with_thread_sem
, SYNC_POLICY_FIFO
, 0);
5526 /* Create thread to spin or park in continuation */
5527 if (strncmp("spin", str
, strlen("spin")) == 0) {
5528 if (kernel_thread_start(panic_thread_test_child_spin
, NULL
, &child_thread
) != KERN_SUCCESS
) {
5529 semaphore_destroy(kernel_task
, sysctl_test_panic_with_thread_sem
);
5532 } else if (strncmp("continuation", str
, strlen("continuation")) == 0) {
5533 if (kernel_thread_start(panic_thread_test_child_park
, NULL
, &child_thread
) != KERN_SUCCESS
) {
5534 semaphore_destroy(kernel_task
, sysctl_test_panic_with_thread_sem
);
5538 semaphore_destroy(kernel_task
, sysctl_test_panic_with_thread_sem
);
5542 semaphore_wait(sysctl_test_panic_with_thread_sem
);
5544 panic_with_thread_context(0, NULL
, 0, child_thread
, "testing panic_with_thread_context for thread %p", child_thread
);
5550 SYSCTL_PROC(_kern
, OID_AUTO
, test_panic_with_thread
,
5551 CTLFLAG_MASKED
| CTLFLAG_KERN
| CTLFLAG_LOCKED
| CTLFLAG_WR
| CTLTYPE_STRING
,
5552 0, 0, sysctl_test_panic_with_thread
, "A", "test panic flow for backtracing a different thread");
5553 #endif /* defined (__x86_64__) */
5555 #endif /* DEVELOPMENT || DEBUG */
5558 sysctl_get_owned_vmobjects SYSCTL_HANDLER_ARGS
5560 #pragma unused(oidp, arg1, arg2)
5563 if (req
->newlen
!= sizeof(mach_port_name_t
) || req
->newptr
== USER_ADDR_NULL
||
5564 req
->oldidx
!= 0 || req
->newidx
!= 0 || req
->p
== NULL
) {
5569 mach_port_name_t task_port_name
;
5571 size_t buffer_size
= (req
->oldptr
!= USER_ADDR_NULL
) ? req
->oldlen
: 0;
5572 vmobject_list_output_t buffer
;
5577 if (buffer_size
< sizeof(*buffer
) + sizeof(vm_object_query_data_t
)) {
5581 buffer
= kheap_alloc(KHEAP_TEMP
, buffer_size
, Z_WAITOK
);
5585 goto sysctl_get_vmobject_list_exit
;
5591 /* we have a "newptr" (for write) we get a task port name from the caller. */
5592 error
= SYSCTL_IN(req
, &task_port_name
, sizeof(mach_port_name_t
));
5595 goto sysctl_get_vmobject_list_exit
;
5598 task
= port_name_to_task(task_port_name
);
5599 if (task
== TASK_NULL
) {
5601 goto sysctl_get_vmobject_list_exit
;
5604 /* copy the vmobjects and vmobject data out of the task */
5605 if (buffer_size
== 0) {
5606 task_copy_vmobjects(task
, NULL
, 0, &entries
);
5607 output_size
= (entries
> 0) ? entries
* sizeof(vm_object_query_data_t
) + sizeof(*buffer
) : 0;
5609 task_copy_vmobjects(task
, &buffer
->data
[0], buffer_size
- sizeof(*buffer
), &entries
);
5610 buffer
->entries
= (uint64_t)entries
;
5611 output_size
= entries
* sizeof(vm_object_query_data_t
) + sizeof(*buffer
);
5614 task_deallocate(task
);
5616 error
= SYSCTL_OUT(req
, (char*) buffer
, output_size
);
5618 sysctl_get_vmobject_list_exit
:
5620 kheap_free(KHEAP_TEMP
, buffer
, buffer_size
);
5626 SYSCTL_PROC(_vm
, OID_AUTO
, get_owned_vmobjects
,
5627 CTLTYPE_OPAQUE
| CTLFLAG_RD
| CTLFLAG_WR
| CTLFLAG_MASKED
| CTLFLAG_KERN
| CTLFLAG_LOCKED
| CTLFLAG_ANYBODY
,
5628 0, 0, sysctl_get_owned_vmobjects
, "A", "get owned vmobjects in task");