1*1031c584SApple OSS Distributions /*
2*1031c584SApple OSS Distributions * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
3*1031c584SApple OSS Distributions *
4*1031c584SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*1031c584SApple OSS Distributions *
6*1031c584SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*1031c584SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*1031c584SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*1031c584SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*1031c584SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*1031c584SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*1031c584SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*1031c584SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*1031c584SApple OSS Distributions *
15*1031c584SApple OSS Distributions * Please obtain a copy of the License at
16*1031c584SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*1031c584SApple OSS Distributions *
18*1031c584SApple OSS Distributions * The Original Code and all software distributed under the License are
19*1031c584SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*1031c584SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*1031c584SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*1031c584SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*1031c584SApple OSS Distributions * Please see the License for the specific language governing rights and
24*1031c584SApple OSS Distributions * limitations under the License.
25*1031c584SApple OSS Distributions *
26*1031c584SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*1031c584SApple OSS Distributions */
28*1031c584SApple OSS Distributions /*
29*1031c584SApple OSS Distributions * @OSF_COPYRIGHT@
30*1031c584SApple OSS Distributions */
31*1031c584SApple OSS Distributions /*
32*1031c584SApple OSS Distributions * Mach Operating System
33*1031c584SApple OSS Distributions * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34*1031c584SApple OSS Distributions * All Rights Reserved.
35*1031c584SApple OSS Distributions *
36*1031c584SApple OSS Distributions * Permission to use, copy, modify and distribute this software and its
37*1031c584SApple OSS Distributions * documentation is hereby granted, provided that both the copyright
38*1031c584SApple OSS Distributions * notice and this permission notice appear in all copies of the
39*1031c584SApple OSS Distributions * software, derivative works or modified versions, and any portions
40*1031c584SApple OSS Distributions * thereof, and that both notices appear in supporting documentation.
41*1031c584SApple OSS Distributions *
42*1031c584SApple OSS Distributions * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43*1031c584SApple OSS Distributions * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44*1031c584SApple OSS Distributions * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45*1031c584SApple OSS Distributions *
46*1031c584SApple OSS Distributions * Carnegie Mellon requests users of this software to return to
47*1031c584SApple OSS Distributions *
48*1031c584SApple OSS Distributions * Software Distribution Coordinator or [email protected]
49*1031c584SApple OSS Distributions * School of Computer Science
50*1031c584SApple OSS Distributions * Carnegie Mellon University
51*1031c584SApple OSS Distributions * Pittsburgh PA 15213-3890
52*1031c584SApple OSS Distributions *
53*1031c584SApple OSS Distributions * any improvements or extensions that they make and grant Carnegie Mellon
54*1031c584SApple OSS Distributions * the rights to redistribute these changes.
55*1031c584SApple OSS Distributions */
56*1031c584SApple OSS Distributions /*
57*1031c584SApple OSS Distributions */
58*1031c584SApple OSS Distributions
59*1031c584SApple OSS Distributions #ifndef _KERN_ZALLOC_INTERNAL_H_
60*1031c584SApple OSS Distributions #define _KERN_ZALLOC_INTERNAL_H_
61*1031c584SApple OSS Distributions
62*1031c584SApple OSS Distributions #include <kern/zalloc.h>
63*1031c584SApple OSS Distributions #include <kern/locks.h>
64*1031c584SApple OSS Distributions #include <kern/simple_lock.h>
65*1031c584SApple OSS Distributions
66*1031c584SApple OSS Distributions #include <os/atomic_private.h>
67*1031c584SApple OSS Distributions #include <sys/queue.h>
68*1031c584SApple OSS Distributions #include <vm/vm_map_internal.h>
69*1031c584SApple OSS Distributions
70*1031c584SApple OSS Distributions #if KASAN
71*1031c584SApple OSS Distributions #include <san/kasan.h>
72*1031c584SApple OSS Distributions #include <kern/spl.h>
73*1031c584SApple OSS Distributions #endif /* !KASAN */
74*1031c584SApple OSS Distributions
75*1031c584SApple OSS Distributions /*
76*1031c584SApple OSS Distributions * Disable zalloc zero validation under kasan as it is
77*1031c584SApple OSS Distributions * double-duty with what kasan already does.
78*1031c584SApple OSS Distributions */
79*1031c584SApple OSS Distributions #if KASAN
80*1031c584SApple OSS Distributions #define ZALLOC_ENABLE_ZERO_CHECK 0
81*1031c584SApple OSS Distributions #else
82*1031c584SApple OSS Distributions #define ZALLOC_ENABLE_ZERO_CHECK 1
83*1031c584SApple OSS Distributions #endif
84*1031c584SApple OSS Distributions
85*1031c584SApple OSS Distributions #if KASAN
86*1031c584SApple OSS Distributions #define ZALLOC_ENABLE_LOGGING 0
87*1031c584SApple OSS Distributions #elif DEBUG || DEVELOPMENT
88*1031c584SApple OSS Distributions #define ZALLOC_ENABLE_LOGGING 1
89*1031c584SApple OSS Distributions #else
90*1031c584SApple OSS Distributions #define ZALLOC_ENABLE_LOGGING 0
91*1031c584SApple OSS Distributions #endif
92*1031c584SApple OSS Distributions
93*1031c584SApple OSS Distributions /*!
94*1031c584SApple OSS Distributions * @file <kern/zalloc_internal.h>
95*1031c584SApple OSS Distributions *
96*1031c584SApple OSS Distributions * @abstract
97*1031c584SApple OSS Distributions * Exposes some guts of zalloc to interact with the VM, debugging, copyio and
98*1031c584SApple OSS Distributions * kalloc subsystems.
99*1031c584SApple OSS Distributions */
100*1031c584SApple OSS Distributions
101*1031c584SApple OSS Distributions __BEGIN_DECLS
102*1031c584SApple OSS Distributions
103*1031c584SApple OSS Distributions #pragma GCC visibility push(hidden)
104*1031c584SApple OSS Distributions
105*1031c584SApple OSS Distributions /*
106*1031c584SApple OSS Distributions * A zone is a collection of fixed size blocks for which there
107*1031c584SApple OSS Distributions * is fast allocation/deallocation access. Kernel routines can
108*1031c584SApple OSS Distributions * use zones to manage data structures dynamically, creating a zone
109*1031c584SApple OSS Distributions * for each type of data structure to be managed.
110*1031c584SApple OSS Distributions *
111*1031c584SApple OSS Distributions */
112*1031c584SApple OSS Distributions
113*1031c584SApple OSS Distributions /*!
114*1031c584SApple OSS Distributions * @typedef zone_pva_t
115*1031c584SApple OSS Distributions *
116*1031c584SApple OSS Distributions * @brief
117*1031c584SApple OSS Distributions * Type used to point to a page virtual address in the zone allocator.
118*1031c584SApple OSS Distributions *
119*1031c584SApple OSS Distributions * @description
120*1031c584SApple OSS Distributions * - Valid pages have the top bit set.
121*1031c584SApple OSS Distributions * - 0 represents the "NULL" page
122*1031c584SApple OSS Distributions * - non 0 values with the top bit cleared represent queue heads,
123*1031c584SApple OSS Distributions * indexed from the beginning of the __DATA section of the kernel.
124*1031c584SApple OSS Distributions * (see zone_pageq_base).
125*1031c584SApple OSS Distributions */
126*1031c584SApple OSS Distributions typedef struct zone_packed_virtual_address {
127*1031c584SApple OSS Distributions uint32_t packed_address;
128*1031c584SApple OSS Distributions } zone_pva_t;
129*1031c584SApple OSS Distributions
130*1031c584SApple OSS Distributions /*!
131*1031c584SApple OSS Distributions * @struct zone_stats
132*1031c584SApple OSS Distributions *
133*1031c584SApple OSS Distributions * @abstract
134*1031c584SApple OSS Distributions * Per-cpu structure used for basic zone stats.
135*1031c584SApple OSS Distributions *
136*1031c584SApple OSS Distributions * @discussion
137*1031c584SApple OSS Distributions * The values aren't scaled for per-cpu zones.
138*1031c584SApple OSS Distributions */
139*1031c584SApple OSS Distributions struct zone_stats {
140*1031c584SApple OSS Distributions uint64_t zs_mem_allocated;
141*1031c584SApple OSS Distributions uint64_t zs_mem_freed;
142*1031c584SApple OSS Distributions uint64_t zs_alloc_fail;
143*1031c584SApple OSS Distributions uint32_t zs_alloc_rr; /* allocation rr bias */
144*1031c584SApple OSS Distributions uint32_t _Atomic zs_alloc_not_shared;
145*1031c584SApple OSS Distributions };
146*1031c584SApple OSS Distributions
147*1031c584SApple OSS Distributions typedef struct zone_magazine *zone_magazine_t;
148*1031c584SApple OSS Distributions
149*1031c584SApple OSS Distributions /*!
150*1031c584SApple OSS Distributions * @struct zone_depot
151*1031c584SApple OSS Distributions *
152*1031c584SApple OSS Distributions * @abstract
153*1031c584SApple OSS Distributions * Holds a list of full and empty magazines.
154*1031c584SApple OSS Distributions *
155*1031c584SApple OSS Distributions * @discussion
156*1031c584SApple OSS Distributions * The data structure is a "STAILQ" and an "SLIST" combined with counters
157*1031c584SApple OSS Distributions * to know their lengths in O(1). Here is a graphical example:
158*1031c584SApple OSS Distributions *
159*1031c584SApple OSS Distributions * zd_full = 3
160*1031c584SApple OSS Distributions * zd_empty = 1
161*1031c584SApple OSS Distributions * ╭─── zd_head
162*1031c584SApple OSS Distributions * │ ╭─ zd_tail
163*1031c584SApple OSS Distributions * │ ╰────────────────────────────────────╮
164*1031c584SApple OSS Distributions * │ ╭───────╮ ╭───────╮ ╭───────╮ v ╭───────╮
165*1031c584SApple OSS Distributions * ╰───>│███████┼──>│███████┼──>│███████┼──>│ ┼─> X
166*1031c584SApple OSS Distributions * ╰───────╯ ╰───────╯ ╰───────╯ ╰───────╯
167*1031c584SApple OSS Distributions */
168*1031c584SApple OSS Distributions struct zone_depot {
169*1031c584SApple OSS Distributions uint32_t zd_full;
170*1031c584SApple OSS Distributions uint32_t zd_empty;
171*1031c584SApple OSS Distributions zone_magazine_t zd_head;
172*1031c584SApple OSS Distributions zone_magazine_t *zd_tail;
173*1031c584SApple OSS Distributions };
174*1031c584SApple OSS Distributions
175*1031c584SApple OSS Distributions /* see https://lemire.me/blog/2019/02/20/more-fun-with-fast-remainders-when-the-divisor-is-a-constant/ */
176*1031c584SApple OSS Distributions #define Z_MAGIC_QUO(s) (((1ull << 32) - 1) / (uint64_t)(s) + 1)
177*1031c584SApple OSS Distributions #define Z_MAGIC_ALIGNED(s) (~0u / (uint32_t)(s) + 1)
178*1031c584SApple OSS Distributions
179*1031c584SApple OSS Distributions /*
180*1031c584SApple OSS Distributions * Returns (offs / size) if offs is small enough
181*1031c584SApple OSS Distributions * and magic = Z_MAGIC_QUO(size)
182*1031c584SApple OSS Distributions */
183*1031c584SApple OSS Distributions static inline uint32_t
Z_FAST_QUO(uint64_t offs,uint64_t magic)184*1031c584SApple OSS Distributions Z_FAST_QUO(uint64_t offs, uint64_t magic)
185*1031c584SApple OSS Distributions {
186*1031c584SApple OSS Distributions return (offs * magic) >> 32;
187*1031c584SApple OSS Distributions }
188*1031c584SApple OSS Distributions
189*1031c584SApple OSS Distributions /*
190*1031c584SApple OSS Distributions * Returns (offs % size) if offs is small enough
191*1031c584SApple OSS Distributions * and magic = Z_MAGIC_QUO(size)
192*1031c584SApple OSS Distributions */
193*1031c584SApple OSS Distributions static inline uint32_t
Z_FAST_MOD(uint64_t offs,uint64_t magic,uint64_t size)194*1031c584SApple OSS Distributions Z_FAST_MOD(uint64_t offs, uint64_t magic, uint64_t size)
195*1031c584SApple OSS Distributions {
196*1031c584SApple OSS Distributions uint32_t lowbits = (uint32_t)(offs * magic);
197*1031c584SApple OSS Distributions
198*1031c584SApple OSS Distributions return (lowbits * size) >> 32;
199*1031c584SApple OSS Distributions }
200*1031c584SApple OSS Distributions
201*1031c584SApple OSS Distributions /*
202*1031c584SApple OSS Distributions * Returns whether (offs % size) == 0 if offs is small enough
203*1031c584SApple OSS Distributions * and magic = Z_MAGIC_ALIGNED(size)
204*1031c584SApple OSS Distributions */
205*1031c584SApple OSS Distributions static inline bool
Z_FAST_ALIGNED(uint64_t offs,uint32_t magic)206*1031c584SApple OSS Distributions Z_FAST_ALIGNED(uint64_t offs, uint32_t magic)
207*1031c584SApple OSS Distributions {
208*1031c584SApple OSS Distributions return (uint32_t)(offs * magic) < magic;
209*1031c584SApple OSS Distributions }
210*1031c584SApple OSS Distributions
211*1031c584SApple OSS Distributions struct zone_size_params {
212*1031c584SApple OSS Distributions uint32_t z_align_magic; /* magic to use with Z_FAST_ALIGNED() */
213*1031c584SApple OSS Distributions uint32_t z_elem_size; /* size of an element */
214*1031c584SApple OSS Distributions };
215*1031c584SApple OSS Distributions
216*1031c584SApple OSS Distributions struct zone_expand {
217*1031c584SApple OSS Distributions struct zone_expand *ze_next;
218*1031c584SApple OSS Distributions thread_t ze_thread;
219*1031c584SApple OSS Distributions bool ze_pg_wait;
220*1031c584SApple OSS Distributions bool ze_vm_priv;
221*1031c584SApple OSS Distributions bool ze_clear_priv;
222*1031c584SApple OSS Distributions };
223*1031c584SApple OSS Distributions
224*1031c584SApple OSS Distributions #define Z_WMA_UNIT (1u << 8)
225*1031c584SApple OSS Distributions #define Z_WMA_MIX(base, e) ((3 * (base) + (e) * Z_WMA_UNIT) / 4)
226*1031c584SApple OSS Distributions
227*1031c584SApple OSS Distributions struct zone {
228*1031c584SApple OSS Distributions /*
229*1031c584SApple OSS Distributions * Readonly / rarely written fields
230*1031c584SApple OSS Distributions */
231*1031c584SApple OSS Distributions
232*1031c584SApple OSS Distributions /*
233*1031c584SApple OSS Distributions * The first 4 fields match a zone_view.
234*1031c584SApple OSS Distributions *
235*1031c584SApple OSS Distributions * z_self points back to the zone when the zone is initialized,
236*1031c584SApple OSS Distributions * or is NULL else.
237*1031c584SApple OSS Distributions */
238*1031c584SApple OSS Distributions struct zone *z_self;
239*1031c584SApple OSS Distributions zone_stats_t z_stats;
240*1031c584SApple OSS Distributions const char *z_name;
241*1031c584SApple OSS Distributions struct zone_view *z_views;
242*1031c584SApple OSS Distributions struct zone_expand *z_expander;
243*1031c584SApple OSS Distributions
244*1031c584SApple OSS Distributions uint64_t z_quo_magic;
245*1031c584SApple OSS Distributions uint32_t z_align_magic;
246*1031c584SApple OSS Distributions uint16_t z_elem_size;
247*1031c584SApple OSS Distributions uint16_t z_elem_offs;
248*1031c584SApple OSS Distributions uint16_t z_chunk_pages;
249*1031c584SApple OSS Distributions uint16_t z_chunk_elems;
250*1031c584SApple OSS Distributions
251*1031c584SApple OSS Distributions uint32_t /* 32 bits */
252*1031c584SApple OSS Distributions /*
253*1031c584SApple OSS Distributions * Lifecycle state (Mutable after creation)
254*1031c584SApple OSS Distributions */
255*1031c584SApple OSS Distributions z_destroyed :1, /* zone is (being) destroyed */
256*1031c584SApple OSS Distributions z_async_refilling :1, /* asynchronous allocation pending? */
257*1031c584SApple OSS Distributions z_depot_cleanup :1, /* per cpu depots need cleaning */
258*1031c584SApple OSS Distributions z_expanding_wait :1, /* is thread waiting for expansion? */
259*1031c584SApple OSS Distributions z_exhausted_wait :1, /* are threads waiting for exhaustion end */
260*1031c584SApple OSS Distributions
261*1031c584SApple OSS Distributions /*
262*1031c584SApple OSS Distributions * Behavior configuration bits
263*1031c584SApple OSS Distributions */
264*1031c584SApple OSS Distributions z_percpu :1, /* the zone is percpu */
265*1031c584SApple OSS Distributions z_smr :1, /* the zone uses SMR */
266*1031c584SApple OSS Distributions z_permanent :1, /* the zone allocations are permanent */
267*1031c584SApple OSS Distributions z_nocaching :1, /* disallow zone caching for this zone */
268*1031c584SApple OSS Distributions collectable :1, /* garbage collect empty pages */
269*1031c584SApple OSS Distributions no_callout :1,
270*1031c584SApple OSS Distributions z_destructible :1, /* zone can be zdestroy()ed */
271*1031c584SApple OSS Distributions
272*1031c584SApple OSS Distributions _reserved :7,
273*1031c584SApple OSS Distributions
274*1031c584SApple OSS Distributions /*
275*1031c584SApple OSS Distributions * Debugging features
276*1031c584SApple OSS Distributions */
277*1031c584SApple OSS Distributions z_pgz_tracked :1, /* this zone is tracked by pgzalloc */
278*1031c584SApple OSS Distributions z_pgz_use_guards :1, /* this zone uses guards with PGZ */
279*1031c584SApple OSS Distributions z_kasan_fakestacks :1,
280*1031c584SApple OSS Distributions z_kasan_quarantine :1, /* whether to use the kasan quarantine */
281*1031c584SApple OSS Distributions z_tags_sizeclass :6, /* idx into zone_tags_sizeclasses to associate
282*1031c584SApple OSS Distributions * sizeclass for a particualr kalloc tag */
283*1031c584SApple OSS Distributions z_uses_tags :1,
284*1031c584SApple OSS Distributions z_log_on :1, /* zone logging was enabled by boot-arg */
285*1031c584SApple OSS Distributions z_tbi_tag :1; /* Zone supports tbi tagging */
286*1031c584SApple OSS Distributions
287*1031c584SApple OSS Distributions uint8_t z_cacheline1[0] __attribute__((aligned(64)));
288*1031c584SApple OSS Distributions
289*1031c584SApple OSS Distributions /*
290*1031c584SApple OSS Distributions * Zone caching / recirculation cacheline
291*1031c584SApple OSS Distributions *
292*1031c584SApple OSS Distributions * z_recirc* fields are protected by the recirculation lock.
293*1031c584SApple OSS Distributions *
294*1031c584SApple OSS Distributions * z_recirc_cont_wma:
295*1031c584SApple OSS Distributions * weighted moving average of the number of contentions per second,
296*1031c584SApple OSS Distributions * in Z_WMA_UNIT units (fixed point decimal).
297*1031c584SApple OSS Distributions *
298*1031c584SApple OSS Distributions * z_recirc_cont_cur:
299*1031c584SApple OSS Distributions * count of recorded contentions that will be fused
300*1031c584SApple OSS Distributions * in z_recirc_cont_wma at the next period.
301*1031c584SApple OSS Distributions *
302*1031c584SApple OSS Distributions * Note: if caching is disabled,
303*1031c584SApple OSS Distributions * this field is used under the zone lock.
304*1031c584SApple OSS Distributions *
305*1031c584SApple OSS Distributions * z_elems_free_{min,wma} (overloaded on z_recirc_empty*):
306*1031c584SApple OSS Distributions * tracks the history of the minimum values of z_elems_free over time
307*1031c584SApple OSS Distributions * with "min" being the minimum it hit for the current period,
308*1031c584SApple OSS Distributions * and "wma" the weighted moving average of those value.
309*1031c584SApple OSS Distributions *
310*1031c584SApple OSS Distributions * This field is used if z_pcpu_cache is NULL,
311*1031c584SApple OSS Distributions * otherwise it aliases with z_recirc_empty_{min,wma}
312*1031c584SApple OSS Distributions *
313*1031c584SApple OSS Distributions * z_recirc_{full,empty}_{min,wma}:
314*1031c584SApple OSS Distributions * tracks the history of the the minimum number of full/empty
315*1031c584SApple OSS Distributions * magazines in the depot over time, with "min" being the minimum
316*1031c584SApple OSS Distributions * it hit for the current period, and "wma" the weighted moving
317*1031c584SApple OSS Distributions * average of those value.
318*1031c584SApple OSS Distributions */
319*1031c584SApple OSS Distributions struct zone_cache *__zpercpu z_pcpu_cache;
320*1031c584SApple OSS Distributions struct zone_depot z_recirc;
321*1031c584SApple OSS Distributions
322*1031c584SApple OSS Distributions hw_lck_ticket_t z_recirc_lock;
323*1031c584SApple OSS Distributions uint32_t z_recirc_full_min;
324*1031c584SApple OSS Distributions uint32_t z_recirc_full_wma;
325*1031c584SApple OSS Distributions union {
326*1031c584SApple OSS Distributions uint32_t z_recirc_empty_min;
327*1031c584SApple OSS Distributions uint32_t z_elems_free_min;
328*1031c584SApple OSS Distributions };
329*1031c584SApple OSS Distributions union {
330*1031c584SApple OSS Distributions uint32_t z_recirc_empty_wma;
331*1031c584SApple OSS Distributions uint32_t z_elems_free_wma;
332*1031c584SApple OSS Distributions };
333*1031c584SApple OSS Distributions uint32_t z_recirc_cont_cur;
334*1031c584SApple OSS Distributions uint32_t z_recirc_cont_wma;
335*1031c584SApple OSS Distributions
336*1031c584SApple OSS Distributions uint16_t z_depot_size;
337*1031c584SApple OSS Distributions uint16_t z_depot_limit;
338*1031c584SApple OSS Distributions
339*1031c584SApple OSS Distributions uint8_t z_cacheline2[0] __attribute__((aligned(64)));
340*1031c584SApple OSS Distributions
341*1031c584SApple OSS Distributions /*
342*1031c584SApple OSS Distributions * often mutated fields
343*1031c584SApple OSS Distributions */
344*1031c584SApple OSS Distributions
345*1031c584SApple OSS Distributions hw_lck_ticket_t z_lock;
346*1031c584SApple OSS Distributions
347*1031c584SApple OSS Distributions /*
348*1031c584SApple OSS Distributions * Page accounting (wired / VA)
349*1031c584SApple OSS Distributions *
350*1031c584SApple OSS Distributions * Those numbers are unscaled for z_percpu zones
351*1031c584SApple OSS Distributions * (zone_scale_for_percpu() needs to be used to find the true value).
352*1031c584SApple OSS Distributions */
353*1031c584SApple OSS Distributions uint32_t z_wired_max; /* how large can this zone grow */
354*1031c584SApple OSS Distributions uint32_t z_wired_hwm; /* z_wired_cur high watermark */
355*1031c584SApple OSS Distributions uint32_t z_wired_cur; /* number of pages used by this zone */
356*1031c584SApple OSS Distributions uint32_t z_wired_empty; /* pages collectable by GC */
357*1031c584SApple OSS Distributions uint32_t z_va_cur; /* amount of VA used by this zone */
358*1031c584SApple OSS Distributions
359*1031c584SApple OSS Distributions /*
360*1031c584SApple OSS Distributions * list of metadata structs, which maintain per-page free element lists
361*1031c584SApple OSS Distributions */
362*1031c584SApple OSS Distributions zone_pva_t z_pageq_empty; /* populated, completely empty pages */
363*1031c584SApple OSS Distributions zone_pva_t z_pageq_partial;/* populated, partially filled pages */
364*1031c584SApple OSS Distributions zone_pva_t z_pageq_full; /* populated, completely full pages */
365*1031c584SApple OSS Distributions zone_pva_t z_pageq_va; /* non-populated VA pages */
366*1031c584SApple OSS Distributions
367*1031c584SApple OSS Distributions /*
368*1031c584SApple OSS Distributions * Zone statistics
369*1031c584SApple OSS Distributions *
370*1031c584SApple OSS Distributions * z_elems_avail:
371*1031c584SApple OSS Distributions * number of elements in the zone (at all).
372*1031c584SApple OSS Distributions */
373*1031c584SApple OSS Distributions uint32_t z_elems_free; /* Number of free elements */
374*1031c584SApple OSS Distributions uint32_t z_elems_avail; /* Number of elements available */
375*1031c584SApple OSS Distributions uint32_t z_elems_rsv;
376*1031c584SApple OSS Distributions uint32_t z_array_size_class;
377*1031c584SApple OSS Distributions
378*1031c584SApple OSS Distributions struct zone *z_kt_next;
379*1031c584SApple OSS Distributions
380*1031c584SApple OSS Distributions uint8_t z_cacheline3[0] __attribute__((aligned(64)));
381*1031c584SApple OSS Distributions
382*1031c584SApple OSS Distributions #if KASAN_CLASSIC
383*1031c584SApple OSS Distributions uint16_t z_kasan_redzone;
384*1031c584SApple OSS Distributions spl_t z_kasan_spl;
385*1031c584SApple OSS Distributions #endif
386*1031c584SApple OSS Distributions #if ZONE_ENABLE_LOGGING || CONFIG_ZLEAKS || KASAN_TBI
387*1031c584SApple OSS Distributions /*
388*1031c584SApple OSS Distributions * the allocation logs are used when:
389*1031c584SApple OSS Distributions *
390*1031c584SApple OSS Distributions * - zlog<n>= boot-args are used (and then z_log_on is set)
391*1031c584SApple OSS Distributions *
392*1031c584SApple OSS Distributions * - the leak detection was triggered for the zone.
393*1031c584SApple OSS Distributions * In that case, the log can't ever be freed,
394*1031c584SApple OSS Distributions * but it can be enabled/disabled dynamically.
395*1031c584SApple OSS Distributions */
396*1031c584SApple OSS Distributions struct btlog *z_btlog;
397*1031c584SApple OSS Distributions struct btlog *z_btlog_disabled;
398*1031c584SApple OSS Distributions #endif
399*1031c584SApple OSS Distributions } __attribute__((aligned((64))));
400*1031c584SApple OSS Distributions
401*1031c584SApple OSS Distributions /*!
402*1031c584SApple OSS Distributions * @typedef zone_security_flags_t
403*1031c584SApple OSS Distributions *
404*1031c584SApple OSS Distributions * @brief
405*1031c584SApple OSS Distributions * Type used to store the immutable security properties of a zone.
406*1031c584SApple OSS Distributions *
407*1031c584SApple OSS Distributions * @description
408*1031c584SApple OSS Distributions * These properties influence the security nature of a zone and can't be
409*1031c584SApple OSS Distributions * modified after lockdown.
410*1031c584SApple OSS Distributions */
411*1031c584SApple OSS Distributions typedef struct zone_security_flags {
412*1031c584SApple OSS Distributions uint16_t
413*1031c584SApple OSS Distributions /*
414*1031c584SApple OSS Distributions * Security sensitive configuration bits
415*1031c584SApple OSS Distributions */
416*1031c584SApple OSS Distributions z_submap_idx :8, /* a Z_SUBMAP_IDX_* value */
417*1031c584SApple OSS Distributions z_kheap_id :2, /* zone_kheap_id_t when part of a kalloc heap */
418*1031c584SApple OSS Distributions z_kalloc_type :1, /* zones that does types based seggregation */
419*1031c584SApple OSS Distributions z_lifo :1, /* depot and recirculation layer are LIFO */
420*1031c584SApple OSS Distributions z_pgz_use_guards :1, /* this zone uses guards with PGZ */
421*1031c584SApple OSS Distributions z_submap_from_end :1, /* allocate from the left or the right ? */
422*1031c584SApple OSS Distributions z_noencrypt :1, /* do not encrypt pages when hibernating */
423*1031c584SApple OSS Distributions z_unused :1;
424*1031c584SApple OSS Distributions /*
425*1031c584SApple OSS Distributions * Signature equivalance zone
426*1031c584SApple OSS Distributions */
427*1031c584SApple OSS Distributions zone_id_t z_sig_eq;
428*1031c584SApple OSS Distributions } zone_security_flags_t;
429*1031c584SApple OSS Distributions
430*1031c584SApple OSS Distributions
431*1031c584SApple OSS Distributions /*
432*1031c584SApple OSS Distributions * Zsecurity config to enable strict free of iokit objects to zone
433*1031c584SApple OSS Distributions * or heap they were allocated from.
434*1031c584SApple OSS Distributions *
435*1031c584SApple OSS Distributions * Turn ZSECURITY_OPTIONS_STRICT_IOKIT_FREE off on x86 so as not
436*1031c584SApple OSS Distributions * not break third party kexts that haven't yet been recompiled
437*1031c584SApple OSS Distributions * to use the new iokit macros.
438*1031c584SApple OSS Distributions */
439*1031c584SApple OSS Distributions #if XNU_PLATFORM_MacOSX && __x86_64__
440*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_STRICT_IOKIT_FREE OFF
441*1031c584SApple OSS Distributions #else
442*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_STRICT_IOKIT_FREE ON
443*1031c584SApple OSS Distributions #endif
444*1031c584SApple OSS Distributions
445*1031c584SApple OSS Distributions /*
446*1031c584SApple OSS Distributions * Zsecurity config to enable the read-only allocator
447*1031c584SApple OSS Distributions */
448*1031c584SApple OSS Distributions #if KASAN_CLASSIC
449*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_READ_ONLY OFF
450*1031c584SApple OSS Distributions #else
451*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_READ_ONLY ON
452*1031c584SApple OSS Distributions #endif
453*1031c584SApple OSS Distributions
454*1031c584SApple OSS Distributions /*
455*1031c584SApple OSS Distributions * Zsecurity config to enable making heap feng-shui
456*1031c584SApple OSS Distributions * less reliable.
457*1031c584SApple OSS Distributions */
458*1031c584SApple OSS Distributions #if KASAN_CLASSIC
459*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_SAD_FENG_SHUI OFF
460*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_GENERAL_SUBMAPS 1
461*1031c584SApple OSS Distributions #else
462*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_SAD_FENG_SHUI ON
463*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_GENERAL_SUBMAPS 4
464*1031c584SApple OSS Distributions #endif
465*1031c584SApple OSS Distributions
466*1031c584SApple OSS Distributions /*
467*1031c584SApple OSS Distributions * Zsecurity config to enable adjusting of elements
468*1031c584SApple OSS Distributions * with PGZ-OOB to right-align them in their space.
469*1031c584SApple OSS Distributions */
470*1031c584SApple OSS Distributions #if KASAN || defined(__x86_64__) || CONFIG_KERNEL_TAGGING
471*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_PGZ_OOB_ADJUST OFF
472*1031c584SApple OSS Distributions #else
473*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_PGZ_OOB_ADJUST ON
474*1031c584SApple OSS Distributions #endif
475*1031c584SApple OSS Distributions
476*1031c584SApple OSS Distributions /*
477*1031c584SApple OSS Distributions * Zsecurity config to enable kalloc type segregation
478*1031c584SApple OSS Distributions */
479*1031c584SApple OSS Distributions #if XNU_TARGET_OS_WATCH || KASAN_CLASSIC
480*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_KT_BUDGET 120
481*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_KT_VAR_BUDGET 6
482*1031c584SApple OSS Distributions #else
483*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_KT_BUDGET 260
484*1031c584SApple OSS Distributions # define ZSECURITY_CONFIG_KT_VAR_BUDGET 6
485*1031c584SApple OSS Distributions #endif
486*1031c584SApple OSS Distributions
487*1031c584SApple OSS Distributions
488*1031c584SApple OSS Distributions __options_decl(kalloc_type_options_t, uint64_t, {
489*1031c584SApple OSS Distributions /*
490*1031c584SApple OSS Distributions * kalloc type option to switch default accounting to private.
491*1031c584SApple OSS Distributions */
492*1031c584SApple OSS Distributions KT_OPTIONS_ACCT = 0x00000001,
493*1031c584SApple OSS Distributions /*
494*1031c584SApple OSS Distributions * kalloc type option to print additional stats regarding zone
495*1031c584SApple OSS Distributions * budget distribution and signatures.
496*1031c584SApple OSS Distributions */
497*1031c584SApple OSS Distributions KT_OPTIONS_DEBUG = 0x00000002,
498*1031c584SApple OSS Distributions /*
499*1031c584SApple OSS Distributions * kalloc type option to allow loose freeing between heaps
500*1031c584SApple OSS Distributions */
501*1031c584SApple OSS Distributions KT_OPTIONS_LOOSE_FREE = 0x00000004,
502*1031c584SApple OSS Distributions });
503*1031c584SApple OSS Distributions
504*1031c584SApple OSS Distributions __enum_decl(kt_var_heap_id_t, uint32_t, {
505*1031c584SApple OSS Distributions /*
506*1031c584SApple OSS Distributions * Fake "data" heap used to link views of data-only allocation that
507*1031c584SApple OSS Distributions * have been redirected to KHEAP_DATA_BUFFERS
508*1031c584SApple OSS Distributions */
509*1031c584SApple OSS Distributions KT_VAR_DATA_HEAP,
510*1031c584SApple OSS Distributions /*
511*1031c584SApple OSS Distributions * Heaps for pointer arrays
512*1031c584SApple OSS Distributions */
513*1031c584SApple OSS Distributions KT_VAR_PTR_HEAP0,
514*1031c584SApple OSS Distributions KT_VAR_PTR_HEAP1,
515*1031c584SApple OSS Distributions /*
516*1031c584SApple OSS Distributions * Indicating first additional heap added
517*1031c584SApple OSS Distributions */
518*1031c584SApple OSS Distributions KT_VAR__FIRST_FLEXIBLE_HEAP,
519*1031c584SApple OSS Distributions });
520*1031c584SApple OSS Distributions
521*1031c584SApple OSS Distributions /*
522*1031c584SApple OSS Distributions * Zone submap indices
523*1031c584SApple OSS Distributions *
524*1031c584SApple OSS Distributions * Z_SUBMAP_IDX_VM
525*1031c584SApple OSS Distributions * this map has the special property that its allocations
526*1031c584SApple OSS Distributions * can be done without ever locking the submap, and doesn't use
527*1031c584SApple OSS Distributions * VM entries in the map (which limits certain VM map operations on it).
528*1031c584SApple OSS Distributions *
529*1031c584SApple OSS Distributions * On ILP32 a single zone lives here (the vm_map_entry_reserved_zone).
530*1031c584SApple OSS Distributions *
531*1031c584SApple OSS Distributions * On LP64 it is also used to restrict VM allocations on LP64 lower
532*1031c584SApple OSS Distributions * in the kernel VA space, for pointer packing purposes.
533*1031c584SApple OSS Distributions *
534*1031c584SApple OSS Distributions * Z_SUBMAP_IDX_GENERAL_{0,1,2,3}
535*1031c584SApple OSS Distributions * used for unrestricted allocations
536*1031c584SApple OSS Distributions *
537*1031c584SApple OSS Distributions * Z_SUBMAP_IDX_DATA
538*1031c584SApple OSS Distributions * used to sequester bags of bytes from all other allocations and allow VA reuse
539*1031c584SApple OSS Distributions * within the map
540*1031c584SApple OSS Distributions *
541*1031c584SApple OSS Distributions * Z_SUBMAP_IDX_READ_ONLY
542*1031c584SApple OSS Distributions * used for the read-only allocator
543*1031c584SApple OSS Distributions */
544*1031c584SApple OSS Distributions __enum_decl(zone_submap_idx_t, uint32_t, {
545*1031c584SApple OSS Distributions Z_SUBMAP_IDX_VM,
546*1031c584SApple OSS Distributions Z_SUBMAP_IDX_READ_ONLY,
547*1031c584SApple OSS Distributions Z_SUBMAP_IDX_GENERAL_0,
548*1031c584SApple OSS Distributions #if ZSECURITY_CONFIG(SAD_FENG_SHUI)
549*1031c584SApple OSS Distributions Z_SUBMAP_IDX_GENERAL_1,
550*1031c584SApple OSS Distributions Z_SUBMAP_IDX_GENERAL_2,
551*1031c584SApple OSS Distributions Z_SUBMAP_IDX_GENERAL_3,
552*1031c584SApple OSS Distributions #endif /* ZSECURITY_CONFIG(SAD_FENG_SHUI) */
553*1031c584SApple OSS Distributions Z_SUBMAP_IDX_DATA,
554*1031c584SApple OSS Distributions
555*1031c584SApple OSS Distributions Z_SUBMAP_IDX_COUNT,
556*1031c584SApple OSS Distributions });
557*1031c584SApple OSS Distributions
558*1031c584SApple OSS Distributions #define KALLOC_MINALIGN (1 << KALLOC_LOG2_MINALIGN)
559*1031c584SApple OSS Distributions
560*1031c584SApple OSS Distributions /*
561*1031c584SApple OSS Distributions * Variable kalloc_type heap config
562*1031c584SApple OSS Distributions */
563*1031c584SApple OSS Distributions struct kheap_info {
564*1031c584SApple OSS Distributions zone_id_t kh_zstart;
565*1031c584SApple OSS Distributions kalloc_heap_t kh_views;
566*1031c584SApple OSS Distributions kalloc_type_var_view_t kt_views;
567*1031c584SApple OSS Distributions };
568*1031c584SApple OSS Distributions typedef union kalloc_type_views {
569*1031c584SApple OSS Distributions struct kalloc_type_view *ktv_fixed;
570*1031c584SApple OSS Distributions struct kalloc_type_var_view *ktv_var;
571*1031c584SApple OSS Distributions } kalloc_type_views_t;
572*1031c584SApple OSS Distributions
573*1031c584SApple OSS Distributions #define KT_VAR_MAX_HEAPS 8
574*1031c584SApple OSS Distributions #define MAX_ZONES 690
575*1031c584SApple OSS Distributions extern struct kheap_info kalloc_type_heap_array[KT_VAR_MAX_HEAPS];
576*1031c584SApple OSS Distributions extern zone_id_t _Atomic num_zones;
577*1031c584SApple OSS Distributions extern uint32_t zone_view_count;
578*1031c584SApple OSS Distributions extern struct zone zone_array[MAX_ZONES];
579*1031c584SApple OSS Distributions extern struct zone_size_params zone_ro_size_params[ZONE_ID__LAST_RO + 1];
580*1031c584SApple OSS Distributions extern zone_security_flags_t zone_security_array[];
581*1031c584SApple OSS Distributions extern const char * const kalloc_heap_names[KHEAP_ID_COUNT];
582*1031c584SApple OSS Distributions extern mach_memory_info_t *panic_kext_memory_info;
583*1031c584SApple OSS Distributions extern vm_size_t panic_kext_memory_size;
584*1031c584SApple OSS Distributions extern vm_offset_t panic_fault_address;
585*1031c584SApple OSS Distributions extern uint16_t _zc_mag_size;
586*1031c584SApple OSS Distributions
587*1031c584SApple OSS Distributions #define zone_index_foreach(i) \
588*1031c584SApple OSS Distributions for (zone_id_t i = 1, num_zones_##i = os_atomic_load(&num_zones, acquire); \
589*1031c584SApple OSS Distributions i < num_zones_##i; i++)
590*1031c584SApple OSS Distributions
591*1031c584SApple OSS Distributions #define zone_foreach(z) \
592*1031c584SApple OSS Distributions for (zone_t z = &zone_array[1], \
593*1031c584SApple OSS Distributions last_zone_##z = &zone_array[os_atomic_load(&num_zones, acquire)]; \
594*1031c584SApple OSS Distributions z < last_zone_##z; z++)
595*1031c584SApple OSS Distributions
596*1031c584SApple OSS Distributions __abortlike
597*1031c584SApple OSS Distributions extern void zone_invalid_panic(zone_t zone);
598*1031c584SApple OSS Distributions
599*1031c584SApple OSS Distributions __pure2
600*1031c584SApple OSS Distributions static inline zone_id_t
zone_index(zone_t z)601*1031c584SApple OSS Distributions zone_index(zone_t z)
602*1031c584SApple OSS Distributions {
603*1031c584SApple OSS Distributions unsigned long delta;
604*1031c584SApple OSS Distributions uint64_t quo;
605*1031c584SApple OSS Distributions
606*1031c584SApple OSS Distributions delta = (unsigned long)z - (unsigned long)zone_array;
607*1031c584SApple OSS Distributions if (delta >= MAX_ZONES * sizeof(*z)) {
608*1031c584SApple OSS Distributions zone_invalid_panic(z);
609*1031c584SApple OSS Distributions }
610*1031c584SApple OSS Distributions quo = Z_FAST_QUO(delta, Z_MAGIC_QUO(sizeof(*z)));
611*1031c584SApple OSS Distributions __builtin_assume(quo < MAX_ZONES);
612*1031c584SApple OSS Distributions return (zone_id_t)quo;
613*1031c584SApple OSS Distributions }
614*1031c584SApple OSS Distributions
615*1031c584SApple OSS Distributions __pure2
616*1031c584SApple OSS Distributions static inline bool
zone_is_ro(zone_t zone)617*1031c584SApple OSS Distributions zone_is_ro(zone_t zone)
618*1031c584SApple OSS Distributions {
619*1031c584SApple OSS Distributions return zone >= &zone_array[ZONE_ID__FIRST_RO] &&
620*1031c584SApple OSS Distributions zone <= &zone_array[ZONE_ID__LAST_RO];
621*1031c584SApple OSS Distributions }
622*1031c584SApple OSS Distributions
623*1031c584SApple OSS Distributions static inline bool
zone_addr_size_crosses_page(mach_vm_address_t addr,mach_vm_size_t size)624*1031c584SApple OSS Distributions zone_addr_size_crosses_page(mach_vm_address_t addr, mach_vm_size_t size)
625*1031c584SApple OSS Distributions {
626*1031c584SApple OSS Distributions return atop(addr ^ (addr + size - 1)) != 0;
627*1031c584SApple OSS Distributions }
628*1031c584SApple OSS Distributions
629*1031c584SApple OSS Distributions __pure2
630*1031c584SApple OSS Distributions static inline uint16_t
zone_elem_redzone(zone_t zone)631*1031c584SApple OSS Distributions zone_elem_redzone(zone_t zone)
632*1031c584SApple OSS Distributions {
633*1031c584SApple OSS Distributions #if KASAN_CLASSIC
634*1031c584SApple OSS Distributions return zone->z_kasan_redzone;
635*1031c584SApple OSS Distributions #else
636*1031c584SApple OSS Distributions (void)zone;
637*1031c584SApple OSS Distributions return 0;
638*1031c584SApple OSS Distributions #endif
639*1031c584SApple OSS Distributions }
640*1031c584SApple OSS Distributions
641*1031c584SApple OSS Distributions __pure2
642*1031c584SApple OSS Distributions static inline uint16_t
zone_elem_inner_offs(zone_t zone)643*1031c584SApple OSS Distributions zone_elem_inner_offs(zone_t zone)
644*1031c584SApple OSS Distributions {
645*1031c584SApple OSS Distributions return zone->z_elem_offs;
646*1031c584SApple OSS Distributions }
647*1031c584SApple OSS Distributions
648*1031c584SApple OSS Distributions __pure2
649*1031c584SApple OSS Distributions static inline uint16_t
zone_elem_outer_offs(zone_t zone)650*1031c584SApple OSS Distributions zone_elem_outer_offs(zone_t zone)
651*1031c584SApple OSS Distributions {
652*1031c584SApple OSS Distributions return zone_elem_inner_offs(zone) - zone_elem_redzone(zone);
653*1031c584SApple OSS Distributions }
654*1031c584SApple OSS Distributions
655*1031c584SApple OSS Distributions __pure2
656*1031c584SApple OSS Distributions static inline vm_offset_t
zone_elem_inner_size(zone_t zone)657*1031c584SApple OSS Distributions zone_elem_inner_size(zone_t zone)
658*1031c584SApple OSS Distributions {
659*1031c584SApple OSS Distributions return zone->z_elem_size;
660*1031c584SApple OSS Distributions }
661*1031c584SApple OSS Distributions
662*1031c584SApple OSS Distributions __pure2
663*1031c584SApple OSS Distributions static inline vm_offset_t
zone_elem_outer_size(zone_t zone)664*1031c584SApple OSS Distributions zone_elem_outer_size(zone_t zone)
665*1031c584SApple OSS Distributions {
666*1031c584SApple OSS Distributions return zone_elem_inner_size(zone) + zone_elem_redzone(zone);
667*1031c584SApple OSS Distributions }
668*1031c584SApple OSS Distributions
669*1031c584SApple OSS Distributions __pure2
670*1031c584SApple OSS Distributions static inline zone_security_flags_t
zone_security_config(zone_t z)671*1031c584SApple OSS Distributions zone_security_config(zone_t z)
672*1031c584SApple OSS Distributions {
673*1031c584SApple OSS Distributions zone_id_t zid = zone_index(z);
674*1031c584SApple OSS Distributions return zone_security_array[zid];
675*1031c584SApple OSS Distributions }
676*1031c584SApple OSS Distributions
677*1031c584SApple OSS Distributions static inline uint32_t
zone_count_free(zone_t zone)678*1031c584SApple OSS Distributions zone_count_free(zone_t zone)
679*1031c584SApple OSS Distributions {
680*1031c584SApple OSS Distributions return zone->z_elems_free + zone->z_recirc.zd_full * _zc_mag_size;
681*1031c584SApple OSS Distributions }
682*1031c584SApple OSS Distributions
683*1031c584SApple OSS Distributions static inline uint32_t
zone_count_allocated(zone_t zone)684*1031c584SApple OSS Distributions zone_count_allocated(zone_t zone)
685*1031c584SApple OSS Distributions {
686*1031c584SApple OSS Distributions return zone->z_elems_avail - zone_count_free(zone);
687*1031c584SApple OSS Distributions }
688*1031c584SApple OSS Distributions
689*1031c584SApple OSS Distributions static inline vm_size_t
zone_scale_for_percpu(zone_t zone,vm_size_t size)690*1031c584SApple OSS Distributions zone_scale_for_percpu(zone_t zone, vm_size_t size)
691*1031c584SApple OSS Distributions {
692*1031c584SApple OSS Distributions if (zone->z_percpu) {
693*1031c584SApple OSS Distributions size *= zpercpu_count();
694*1031c584SApple OSS Distributions }
695*1031c584SApple OSS Distributions return size;
696*1031c584SApple OSS Distributions }
697*1031c584SApple OSS Distributions
698*1031c584SApple OSS Distributions static inline vm_size_t
zone_size_wired(zone_t zone)699*1031c584SApple OSS Distributions zone_size_wired(zone_t zone)
700*1031c584SApple OSS Distributions {
701*1031c584SApple OSS Distributions /*
702*1031c584SApple OSS Distributions * this either require the zone lock,
703*1031c584SApple OSS Distributions * or to be used for statistics purposes only.
704*1031c584SApple OSS Distributions */
705*1031c584SApple OSS Distributions vm_size_t size = ptoa(os_atomic_load(&zone->z_wired_cur, relaxed));
706*1031c584SApple OSS Distributions return zone_scale_for_percpu(zone, size);
707*1031c584SApple OSS Distributions }
708*1031c584SApple OSS Distributions
709*1031c584SApple OSS Distributions static inline vm_size_t
zone_size_free(zone_t zone)710*1031c584SApple OSS Distributions zone_size_free(zone_t zone)
711*1031c584SApple OSS Distributions {
712*1031c584SApple OSS Distributions return zone_scale_for_percpu(zone,
713*1031c584SApple OSS Distributions zone_elem_inner_size(zone) * zone_count_free(zone));
714*1031c584SApple OSS Distributions }
715*1031c584SApple OSS Distributions
716*1031c584SApple OSS Distributions /* Under KASAN builds, this also accounts for quarantined elements. */
717*1031c584SApple OSS Distributions static inline vm_size_t
zone_size_allocated(zone_t zone)718*1031c584SApple OSS Distributions zone_size_allocated(zone_t zone)
719*1031c584SApple OSS Distributions {
720*1031c584SApple OSS Distributions return zone_scale_for_percpu(zone,
721*1031c584SApple OSS Distributions zone_elem_inner_size(zone) * zone_count_allocated(zone));
722*1031c584SApple OSS Distributions }
723*1031c584SApple OSS Distributions
724*1031c584SApple OSS Distributions static inline vm_size_t
zone_size_wasted(zone_t zone)725*1031c584SApple OSS Distributions zone_size_wasted(zone_t zone)
726*1031c584SApple OSS Distributions {
727*1031c584SApple OSS Distributions return zone_size_wired(zone) - zone_scale_for_percpu(zone,
728*1031c584SApple OSS Distributions zone_elem_outer_size(zone) * zone->z_elems_avail);
729*1031c584SApple OSS Distributions }
730*1031c584SApple OSS Distributions
731*1031c584SApple OSS Distributions __pure2
732*1031c584SApple OSS Distributions static inline bool
zone_exhaustible(zone_t zone)733*1031c584SApple OSS Distributions zone_exhaustible(zone_t zone)
734*1031c584SApple OSS Distributions {
735*1031c584SApple OSS Distributions return zone->z_wired_max != ~0u;
736*1031c584SApple OSS Distributions }
737*1031c584SApple OSS Distributions
738*1031c584SApple OSS Distributions __pure2
739*1031c584SApple OSS Distributions static inline bool
zone_exhausted(zone_t zone)740*1031c584SApple OSS Distributions zone_exhausted(zone_t zone)
741*1031c584SApple OSS Distributions {
742*1031c584SApple OSS Distributions return zone->z_wired_cur >= zone->z_wired_max;
743*1031c584SApple OSS Distributions }
744*1031c584SApple OSS Distributions
745*1031c584SApple OSS Distributions /*
746*1031c584SApple OSS Distributions * Set and get the signature equivalance for the given zone
747*1031c584SApple OSS Distributions */
748*1031c584SApple OSS Distributions extern void zone_set_sig_eq(zone_t zone, zone_id_t sig_eq);
749*1031c584SApple OSS Distributions extern zone_id_t zone_get_sig_eq(zone_t zone);
750*1031c584SApple OSS Distributions /*
751*1031c584SApple OSS Distributions * Return the accumulated allocated memory on the given zone stats
752*1031c584SApple OSS Distributions */
753*1031c584SApple OSS Distributions static inline vm_size_t
zone_stats_get_mem_allocated(zone_stats_t stats)754*1031c584SApple OSS Distributions zone_stats_get_mem_allocated(zone_stats_t stats)
755*1031c584SApple OSS Distributions {
756*1031c584SApple OSS Distributions return stats->zs_mem_allocated;
757*1031c584SApple OSS Distributions }
758*1031c584SApple OSS Distributions
759*1031c584SApple OSS Distributions /*
760*1031c584SApple OSS Distributions * For sysctl kern.zones_collectable_bytes used by memory_maintenance to check if a
761*1031c584SApple OSS Distributions * userspace reboot is needed. The only other way to query for this information
762*1031c584SApple OSS Distributions * is via mach_memory_info() which is unavailable on release kernels.
763*1031c584SApple OSS Distributions */
764*1031c584SApple OSS Distributions extern uint64_t get_zones_collectable_bytes(void);
765*1031c584SApple OSS Distributions
766*1031c584SApple OSS Distributions /*!
767*1031c584SApple OSS Distributions * @enum zone_gc_level_t
768*1031c584SApple OSS Distributions *
769*1031c584SApple OSS Distributions * @const ZONE_GC_TRIM
770*1031c584SApple OSS Distributions * Request a trimming GC: it will trim allocations in excess
771*1031c584SApple OSS Distributions * of the working set size estimate only.
772*1031c584SApple OSS Distributions *
773*1031c584SApple OSS Distributions * @const ZONE_GC_DRAIN
774*1031c584SApple OSS Distributions * Request a draining GC: this is an aggressive mode that will
775*1031c584SApple OSS Distributions * cause all caches to be drained and all free pages returned to the system.
776*1031c584SApple OSS Distributions *
777*1031c584SApple OSS Distributions * @const ZONE_GC_JETSAM
778*1031c584SApple OSS Distributions * Request to consider a jetsam, and then fallback to @c ZONE_GC_TRIM or
779*1031c584SApple OSS Distributions * @c ZONE_GC_DRAIN depending on the state of the zone map.
780*1031c584SApple OSS Distributions * To avoid deadlocks, only @c vm_pageout_garbage_collect() should ever
781*1031c584SApple OSS Distributions * request a @c ZONE_GC_JETSAM level.
782*1031c584SApple OSS Distributions */
783*1031c584SApple OSS Distributions __enum_closed_decl(zone_gc_level_t, uint32_t, {
784*1031c584SApple OSS Distributions ZONE_GC_TRIM,
785*1031c584SApple OSS Distributions ZONE_GC_DRAIN,
786*1031c584SApple OSS Distributions ZONE_GC_JETSAM,
787*1031c584SApple OSS Distributions });
788*1031c584SApple OSS Distributions
789*1031c584SApple OSS Distributions /*!
790*1031c584SApple OSS Distributions * @function zone_gc
791*1031c584SApple OSS Distributions *
792*1031c584SApple OSS Distributions * @brief
793*1031c584SApple OSS Distributions * Reduces memory used by zones by trimming caches and freelists.
794*1031c584SApple OSS Distributions *
795*1031c584SApple OSS Distributions * @discussion
796*1031c584SApple OSS Distributions * @c zone_gc() is called:
797*1031c584SApple OSS Distributions * - by the pageout daemon when the system needs more free pages.
798*1031c584SApple OSS Distributions * - by the VM when contiguous page allocation requests get stuck
799*1031c584SApple OSS Distributions * (see vm_page_find_contiguous()).
800*1031c584SApple OSS Distributions *
801*1031c584SApple OSS Distributions * @param level The zone GC level requested.
802*1031c584SApple OSS Distributions */
803*1031c584SApple OSS Distributions extern void zone_gc(zone_gc_level_t level);
804*1031c584SApple OSS Distributions
805*1031c584SApple OSS Distributions extern void zone_gc_trim(void);
806*1031c584SApple OSS Distributions extern void zone_gc_drain(void);
807*1031c584SApple OSS Distributions
808*1031c584SApple OSS Distributions #define ZONE_WSS_UPDATE_PERIOD 15
809*1031c584SApple OSS Distributions /*!
810*1031c584SApple OSS Distributions * @function compute_zone_working_set_size
811*1031c584SApple OSS Distributions *
812*1031c584SApple OSS Distributions * @brief
813*1031c584SApple OSS Distributions * Recomputes the working set size for every zone
814*1031c584SApple OSS Distributions *
815*1031c584SApple OSS Distributions * @discussion
816*1031c584SApple OSS Distributions * This runs about every @c ZONE_WSS_UPDATE_PERIOD seconds (10),
817*1031c584SApple OSS Distributions * computing an exponential moving average with a weight of 75%,
818*1031c584SApple OSS Distributions * so that the history of the last minute is the dominating factor.
819*1031c584SApple OSS Distributions */
820*1031c584SApple OSS Distributions extern void compute_zone_working_set_size(void *);
821*1031c584SApple OSS Distributions
822*1031c584SApple OSS Distributions /* Debug logging for zone-map-exhaustion jetsams. */
823*1031c584SApple OSS Distributions extern void get_zone_map_size(uint64_t *current_size, uint64_t *capacity);
824*1031c584SApple OSS Distributions extern void get_largest_zone_info(char *zone_name, size_t zone_name_len, uint64_t *zone_size);
825*1031c584SApple OSS Distributions
826*1031c584SApple OSS Distributions /* Bootstrap zone module (create zone zone) */
827*1031c584SApple OSS Distributions extern void zone_bootstrap(void);
828*1031c584SApple OSS Distributions
829*1031c584SApple OSS Distributions /* Force-enable caching on a zone, generally unsafe to call directly */
830*1031c584SApple OSS Distributions extern void zone_enable_caching(zone_t zone);
831*1031c584SApple OSS Distributions
832*1031c584SApple OSS Distributions /*!
833*1031c584SApple OSS Distributions * @function zone_early_mem_init
834*1031c584SApple OSS Distributions *
835*1031c584SApple OSS Distributions * @brief
836*1031c584SApple OSS Distributions * Steal memory from pmap (prior to initialization of zalloc)
837*1031c584SApple OSS Distributions * for the special vm zones that allow bootstrap memory and store
838*1031c584SApple OSS Distributions * the range so as to facilitate range checking in zfree.
839*1031c584SApple OSS Distributions *
840*1031c584SApple OSS Distributions * @param size the size to steal (must be a page multiple)
841*1031c584SApple OSS Distributions */
842*1031c584SApple OSS Distributions __startup_func
843*1031c584SApple OSS Distributions extern vm_offset_t zone_early_mem_init(
844*1031c584SApple OSS Distributions vm_size_t size);
845*1031c584SApple OSS Distributions
846*1031c584SApple OSS Distributions /*!
847*1031c584SApple OSS Distributions * @function zone_get_early_alloc_size
848*1031c584SApple OSS Distributions *
849*1031c584SApple OSS Distributions * @brief
850*1031c584SApple OSS Distributions * Compute the correct size (greater than @c ptoa(min_pages)) that is a multiple
851*1031c584SApple OSS Distributions * of the allocation granule for the zone with the given creation flags and
852*1031c584SApple OSS Distributions * element size.
853*1031c584SApple OSS Distributions */
854*1031c584SApple OSS Distributions __startup_func
855*1031c584SApple OSS Distributions extern vm_size_t zone_get_early_alloc_size(
856*1031c584SApple OSS Distributions const char *name __unused,
857*1031c584SApple OSS Distributions vm_size_t elem_size,
858*1031c584SApple OSS Distributions zone_create_flags_t flags,
859*1031c584SApple OSS Distributions vm_size_t min_elems);
860*1031c584SApple OSS Distributions
861*1031c584SApple OSS Distributions /*!
862*1031c584SApple OSS Distributions * @function zone_cram_early
863*1031c584SApple OSS Distributions *
864*1031c584SApple OSS Distributions * @brief
865*1031c584SApple OSS Distributions * Cram memory allocated with @c zone_early_mem_init() into a zone.
866*1031c584SApple OSS Distributions *
867*1031c584SApple OSS Distributions * @param zone The zone to cram memory into.
868*1031c584SApple OSS Distributions * @param newmem The base address for the memory to cram.
869*1031c584SApple OSS Distributions * @param size The size of the memory to cram into the zone.
870*1031c584SApple OSS Distributions */
871*1031c584SApple OSS Distributions __startup_func
872*1031c584SApple OSS Distributions extern void zone_cram_early(
873*1031c584SApple OSS Distributions zone_t zone,
874*1031c584SApple OSS Distributions vm_offset_t newmem,
875*1031c584SApple OSS Distributions vm_size_t size);
876*1031c584SApple OSS Distributions
877*1031c584SApple OSS Distributions extern bool zone_maps_owned(
878*1031c584SApple OSS Distributions vm_address_t addr,
879*1031c584SApple OSS Distributions vm_size_t size);
880*1031c584SApple OSS Distributions
881*1031c584SApple OSS Distributions #if KASAN_LIGHT
882*1031c584SApple OSS Distributions extern bool kasan_zone_maps_owned(
883*1031c584SApple OSS Distributions vm_address_t addr,
884*1031c584SApple OSS Distributions vm_size_t size);
885*1031c584SApple OSS Distributions #endif /* KASAN_LIGHT */
886*1031c584SApple OSS Distributions
887*1031c584SApple OSS Distributions extern void zone_map_sizes(
888*1031c584SApple OSS Distributions vm_map_size_t *psize,
889*1031c584SApple OSS Distributions vm_map_size_t *pfree,
890*1031c584SApple OSS Distributions vm_map_size_t *plargest_free);
891*1031c584SApple OSS Distributions
892*1031c584SApple OSS Distributions extern bool
893*1031c584SApple OSS Distributions zone_map_nearing_exhaustion(void);
894*1031c584SApple OSS Distributions
895*1031c584SApple OSS Distributions static inline vm_tag_t
zalloc_flags_get_tag(zalloc_flags_t flags)896*1031c584SApple OSS Distributions zalloc_flags_get_tag(zalloc_flags_t flags)
897*1031c584SApple OSS Distributions {
898*1031c584SApple OSS Distributions return (vm_tag_t)((flags & Z_VM_TAG_MASK) >> Z_VM_TAG_SHIFT);
899*1031c584SApple OSS Distributions }
900*1031c584SApple OSS Distributions
901*1031c584SApple OSS Distributions extern struct kalloc_result zalloc_ext(
902*1031c584SApple OSS Distributions zone_t zone,
903*1031c584SApple OSS Distributions zone_stats_t zstats,
904*1031c584SApple OSS Distributions zalloc_flags_t flags);
905*1031c584SApple OSS Distributions
906*1031c584SApple OSS Distributions #if KASAN
907*1031c584SApple OSS Distributions #define ZFREE_PACK_SIZE(esize, usize) (((uint64_t)(usize) << 32) | (esize))
908*1031c584SApple OSS Distributions #define ZFREE_ELEM_SIZE(combined) ((uint32_t)(combined))
909*1031c584SApple OSS Distributions #define ZFREE_USER_SIZE(combined) ((combined) >> 32)
910*1031c584SApple OSS Distributions #else
911*1031c584SApple OSS Distributions #define ZFREE_PACK_SIZE(esize, usize) (esize)
912*1031c584SApple OSS Distributions #define ZFREE_ELEM_SIZE(combined) (combined)
913*1031c584SApple OSS Distributions #endif
914*1031c584SApple OSS Distributions
915*1031c584SApple OSS Distributions extern void zfree_ext(
916*1031c584SApple OSS Distributions zone_t zone,
917*1031c584SApple OSS Distributions zone_stats_t zstats,
918*1031c584SApple OSS Distributions void *addr,
919*1031c584SApple OSS Distributions uint64_t combined_size);
920*1031c584SApple OSS Distributions
921*1031c584SApple OSS Distributions extern zone_id_t zone_id_for_element(
922*1031c584SApple OSS Distributions void *addr,
923*1031c584SApple OSS Distributions vm_size_t esize);
924*1031c584SApple OSS Distributions
925*1031c584SApple OSS Distributions #if ZSECURITY_CONFIG(PGZ_OOB_ADJUST)
926*1031c584SApple OSS Distributions extern void *zone_element_pgz_oob_adjust(
927*1031c584SApple OSS Distributions void *addr,
928*1031c584SApple OSS Distributions vm_size_t req_size,
929*1031c584SApple OSS Distributions vm_size_t elem_size);
930*1031c584SApple OSS Distributions #endif /* !ZSECURITY_CONFIG(PGZ_OOB_ADJUST) */
931*1031c584SApple OSS Distributions
932*1031c584SApple OSS Distributions extern void zone_element_bounds_check(
933*1031c584SApple OSS Distributions vm_address_t addr,
934*1031c584SApple OSS Distributions vm_size_t len);
935*1031c584SApple OSS Distributions
936*1031c584SApple OSS Distributions extern vm_size_t zone_element_size(
937*1031c584SApple OSS Distributions void *addr,
938*1031c584SApple OSS Distributions zone_t *z,
939*1031c584SApple OSS Distributions bool clear_oob,
940*1031c584SApple OSS Distributions vm_offset_t *oob_offs);
941*1031c584SApple OSS Distributions
942*1031c584SApple OSS Distributions /*!
943*1031c584SApple OSS Distributions * @function zone_spans_ro_va
944*1031c584SApple OSS Distributions *
945*1031c584SApple OSS Distributions * @abstract
946*1031c584SApple OSS Distributions * This function is used to check whether the specified address range
947*1031c584SApple OSS Distributions * spans through the read-only zone range.
948*1031c584SApple OSS Distributions *
949*1031c584SApple OSS Distributions * @discussion
950*1031c584SApple OSS Distributions * This only checks for the range specified within ZONE_ADDR_READONLY.
951*1031c584SApple OSS Distributions * The parameters addr_start and addr_end are stripped off of PAC bits
952*1031c584SApple OSS Distributions * before the check is made.
953*1031c584SApple OSS Distributions */
954*1031c584SApple OSS Distributions extern bool zone_spans_ro_va(
955*1031c584SApple OSS Distributions vm_offset_t addr_start,
956*1031c584SApple OSS Distributions vm_offset_t addr_end);
957*1031c584SApple OSS Distributions
958*1031c584SApple OSS Distributions /*!
959*1031c584SApple OSS Distributions * @function __zalloc_ro_mut_atomic
960*1031c584SApple OSS Distributions *
961*1031c584SApple OSS Distributions * @abstract
962*1031c584SApple OSS Distributions * This function is called from the pmap to perform the specified atomic
963*1031c584SApple OSS Distributions * operation on memory from the read-only allocator.
964*1031c584SApple OSS Distributions *
965*1031c584SApple OSS Distributions * @discussion
966*1031c584SApple OSS Distributions * This function is for internal use only and should not be called directly.
967*1031c584SApple OSS Distributions */
968*1031c584SApple OSS Distributions static inline uint64_t
__zalloc_ro_mut_atomic(vm_offset_t dst,zro_atomic_op_t op,uint64_t value)969*1031c584SApple OSS Distributions __zalloc_ro_mut_atomic(vm_offset_t dst, zro_atomic_op_t op, uint64_t value)
970*1031c584SApple OSS Distributions {
971*1031c584SApple OSS Distributions #define __ZALLOC_RO_MUT_OP(op, op2) \
972*1031c584SApple OSS Distributions case ZRO_ATOMIC_##op##_8: \
973*1031c584SApple OSS Distributions return os_atomic_##op2((uint8_t *)dst, (uint8_t)value, seq_cst); \
974*1031c584SApple OSS Distributions case ZRO_ATOMIC_##op##_16: \
975*1031c584SApple OSS Distributions return os_atomic_##op2((uint16_t *)dst, (uint16_t)value, seq_cst); \
976*1031c584SApple OSS Distributions case ZRO_ATOMIC_##op##_32: \
977*1031c584SApple OSS Distributions return os_atomic_##op2((uint32_t *)dst, (uint32_t)value, seq_cst); \
978*1031c584SApple OSS Distributions case ZRO_ATOMIC_##op##_64: \
979*1031c584SApple OSS Distributions return os_atomic_##op2((uint64_t *)dst, (uint64_t)value, seq_cst)
980*1031c584SApple OSS Distributions
981*1031c584SApple OSS Distributions switch (op) {
982*1031c584SApple OSS Distributions __ZALLOC_RO_MUT_OP(OR, or_orig);
983*1031c584SApple OSS Distributions __ZALLOC_RO_MUT_OP(XOR, xor_orig);
984*1031c584SApple OSS Distributions __ZALLOC_RO_MUT_OP(AND, and_orig);
985*1031c584SApple OSS Distributions __ZALLOC_RO_MUT_OP(ADD, add_orig);
986*1031c584SApple OSS Distributions __ZALLOC_RO_MUT_OP(XCHG, xchg);
987*1031c584SApple OSS Distributions default:
988*1031c584SApple OSS Distributions panic("%s: Invalid atomic operation: %d", __func__, op);
989*1031c584SApple OSS Distributions }
990*1031c584SApple OSS Distributions
991*1031c584SApple OSS Distributions #undef __ZALLOC_RO_MUT_OP
992*1031c584SApple OSS Distributions }
993*1031c584SApple OSS Distributions
994*1031c584SApple OSS Distributions /*!
995*1031c584SApple OSS Distributions * @function zone_owns
996*1031c584SApple OSS Distributions *
997*1031c584SApple OSS Distributions * @abstract
998*1031c584SApple OSS Distributions * This function is a soft version of zone_require that checks if a given
999*1031c584SApple OSS Distributions * pointer belongs to the specified zone and should not be used outside
1000*1031c584SApple OSS Distributions * allocator code.
1001*1031c584SApple OSS Distributions *
1002*1031c584SApple OSS Distributions * @discussion
1003*1031c584SApple OSS Distributions * Note that zone_owns() can only work with:
1004*1031c584SApple OSS Distributions * - zones not allowing foreign memory
1005*1031c584SApple OSS Distributions * - zones in the general submap.
1006*1031c584SApple OSS Distributions *
1007*1031c584SApple OSS Distributions * @param zone the zone the address needs to belong to.
1008*1031c584SApple OSS Distributions * @param addr the element address to check.
1009*1031c584SApple OSS Distributions */
1010*1031c584SApple OSS Distributions extern bool zone_owns(
1011*1031c584SApple OSS Distributions zone_t zone,
1012*1031c584SApple OSS Distributions void *addr);
1013*1031c584SApple OSS Distributions
1014*1031c584SApple OSS Distributions /**!
1015*1031c584SApple OSS Distributions * @function zone_submap
1016*1031c584SApple OSS Distributions *
1017*1031c584SApple OSS Distributions * @param zsflags the security flags of a specified zone.
1018*1031c584SApple OSS Distributions * @returns the zone (sub)map this zone allocates from.
1019*1031c584SApple OSS Distributions */
1020*1031c584SApple OSS Distributions __pure2
1021*1031c584SApple OSS Distributions extern vm_map_t zone_submap(
1022*1031c584SApple OSS Distributions zone_security_flags_t zsflags);
1023*1031c584SApple OSS Distributions
1024*1031c584SApple OSS Distributions #ifndef VM_TAG_SIZECLASSES
1025*1031c584SApple OSS Distributions #error MAX_TAG_ZONES
1026*1031c584SApple OSS Distributions #endif
1027*1031c584SApple OSS Distributions #if VM_TAG_SIZECLASSES
1028*1031c584SApple OSS Distributions
1029*1031c584SApple OSS Distributions extern uint16_t zone_index_from_tag_index(
1030*1031c584SApple OSS Distributions uint32_t tag_zone_index);
1031*1031c584SApple OSS Distributions
1032*1031c584SApple OSS Distributions #endif /* VM_TAG_SIZECLASSES */
1033*1031c584SApple OSS Distributions
1034*1031c584SApple OSS Distributions extern lck_grp_t zone_locks_grp;
1035*1031c584SApple OSS Distributions
1036*1031c584SApple OSS Distributions static inline void
zone_lock(zone_t zone)1037*1031c584SApple OSS Distributions zone_lock(zone_t zone)
1038*1031c584SApple OSS Distributions {
1039*1031c584SApple OSS Distributions #if KASAN_FAKESTACK
1040*1031c584SApple OSS Distributions spl_t s = 0;
1041*1031c584SApple OSS Distributions if (zone->z_kasan_fakestacks) {
1042*1031c584SApple OSS Distributions s = splsched();
1043*1031c584SApple OSS Distributions }
1044*1031c584SApple OSS Distributions #endif /* KASAN_FAKESTACK */
1045*1031c584SApple OSS Distributions hw_lck_ticket_lock(&zone->z_lock, &zone_locks_grp);
1046*1031c584SApple OSS Distributions #if KASAN_FAKESTACK
1047*1031c584SApple OSS Distributions zone->z_kasan_spl = s;
1048*1031c584SApple OSS Distributions #endif /* KASAN_FAKESTACK */
1049*1031c584SApple OSS Distributions }
1050*1031c584SApple OSS Distributions
1051*1031c584SApple OSS Distributions static inline void
zone_unlock(zone_t zone)1052*1031c584SApple OSS Distributions zone_unlock(zone_t zone)
1053*1031c584SApple OSS Distributions {
1054*1031c584SApple OSS Distributions #if KASAN_FAKESTACK
1055*1031c584SApple OSS Distributions spl_t s = zone->z_kasan_spl;
1056*1031c584SApple OSS Distributions zone->z_kasan_spl = 0;
1057*1031c584SApple OSS Distributions #endif /* KASAN_FAKESTACK */
1058*1031c584SApple OSS Distributions hw_lck_ticket_unlock(&zone->z_lock);
1059*1031c584SApple OSS Distributions #if KASAN_FAKESTACK
1060*1031c584SApple OSS Distributions if (zone->z_kasan_fakestacks) {
1061*1031c584SApple OSS Distributions splx(s);
1062*1031c584SApple OSS Distributions }
1063*1031c584SApple OSS Distributions #endif /* KASAN_FAKESTACK */
1064*1031c584SApple OSS Distributions }
1065*1031c584SApple OSS Distributions
1066*1031c584SApple OSS Distributions #define MAX_ZONE_NAME 32 /* max length of a zone name we can take from the boot-args */
1067*1031c584SApple OSS Distributions
1068*1031c584SApple OSS Distributions int track_this_zone(const char *zonename, const char *logname);
1069*1031c584SApple OSS Distributions extern bool panic_include_kalloc_types;
1070*1031c584SApple OSS Distributions extern zone_t kalloc_type_src_zone;
1071*1031c584SApple OSS Distributions extern zone_t kalloc_type_dst_zone;
1072*1031c584SApple OSS Distributions
1073*1031c584SApple OSS Distributions #if DEBUG || DEVELOPMENT
1074*1031c584SApple OSS Distributions extern vm_size_t zone_element_info(void *addr, vm_tag_t * ptag);
1075*1031c584SApple OSS Distributions #endif /* DEBUG || DEVELOPMENT */
1076*1031c584SApple OSS Distributions
1077*1031c584SApple OSS Distributions #pragma GCC visibility pop
1078*1031c584SApple OSS Distributions
1079*1031c584SApple OSS Distributions __END_DECLS
1080*1031c584SApple OSS Distributions
1081*1031c584SApple OSS Distributions #endif /* _KERN_ZALLOC_INTERNAL_H_ */
1082