1 #include <darwintest.h>
2 #include <darwintest_utils.h>
9 #define panic(fmt, ...) ({ T_FAIL(fmt, __VA_ARGS__); abort(); })
11 #define __security_const_late
13 #include "../osfmk/kern/zalloc.c"
15 #define ZBA_TEST_SIZE (1ul << 20)
18 zba_populate_any(vm_address_t addr
, vm_size_t size
)
20 int rc
= mprotect((void *)addr
, size
, PROT_READ
| PROT_WRITE
);
21 T_QUIET
; T_ASSERT_POSIX_SUCCESS(rc
, "mprotect");
25 zba_populate_nope(vm_address_t addr
, vm_size_t size
)
27 #pragma unused(addr, size)
28 T_FAIL("Trying to extend the storage");
33 zba_test_allow_extension(void)
35 zba_test_info
.zbats_populate
= zba_populate_any
;
39 zba_test_disallow_extension(void)
41 zba_test_info
.zbats_populate
= zba_populate_nope
;
50 kr
= vm_allocate(mach_task_self(), &zba_test_info
.zbats_base
,
51 ZBA_TEST_SIZE
+ ZBA_CHUNK_SIZE
, VM_FLAGS_ANYWHERE
);
52 T_ASSERT_MACH_SUCCESS(kr
, "vm_allocate()");
54 zba_test_info
.zbats_base
= roundup(zba_test_info
.zbats_base
,
57 rc
= mprotect(zba_base_header(), ZBA_TEST_SIZE
, PROT_NONE
);
58 T_ASSERT_POSIX_SUCCESS(rc
, "mprotect");
60 T_LOG("SETUP allocator with base at %p", zba_base_header());
62 zba_test_allow_extension();
67 T_DECL(zone_buddy_allocator_encodings
, "test the buddy allocator formulas")
69 uint8_t bits
[sizeof(zba_base_header()->zbah_bits
)] = { };
71 for (uint32_t o
= ZBA_MAX_ORDER
+ 1; o
-- > 0;) {
72 for (vm_address_t pos
= 0; pos
< ZBA_CHUNK_SIZE
; pos
+= ZBA_GRANULE
<< o
) {
73 struct zone_bits_chain
*zbc
;
74 size_t node
= zba_node(pos
, o
);
76 zbc
= zba_chain_for_node(NULL
, node
, o
);
77 T_QUIET
; T_ASSERT_EQ(pos
, (vm_offset_t
)zbc
,
78 "zba_node / zba_chain_for_node is reversible (pos: %lx, node %zd)",
83 // leaf nodes aren't represented in the bitmap
86 T_QUIET
; T_ASSERT_LT(node
, 8 * sizeof(bits
), "fits in bitfield: %zd", pos
);
87 T_QUIET
; T_ASSERT_EQ(0, bits
[node
/ 8] & (1 << (node
% 8)), "never seen");
88 bits
[node
/ 8] ^= 1 << (node
% 8);
92 T_PASS("zba_node, zba_chain_for_node look sane");
95 T_DECL(zone_buddy_allocator
, "test the zone bits setup")
97 vm_address_t base
, pos
;
101 zba_test_disallow_extension();
103 base
= (vm_address_t
)zba_slot_base();
104 for (pos
= zba_chunk_header_size(0); pos
< ZBA_CHUNK_SIZE
; pos
+= ZBA_GRANULE
) {
105 T_QUIET
; T_ASSERT_EQ(base
+ pos
, zba_alloc(0), "alloc");
106 *(uint64_t *)(base
+ pos
) = ~0ull;
108 for (pos
= zba_chunk_header_size(0); pos
< ZBA_CHUNK_SIZE
; pos
+= ZBA_GRANULE
) {
109 zba_free(base
+ pos
, 0);
112 for (pos
= zba_chunk_header_size(0); pos
< ZBA_CHUNK_SIZE
; pos
+= ZBA_GRANULE
) {
113 T_QUIET
; T_ASSERT_EQ(base
+ pos
, zba_alloc(0), "alloc");
114 *(uint64_t *)(base
+ pos
) = ~0ull;
116 zba_test_allow_extension();
118 base
+= ZBA_CHUNK_SIZE
;
119 for (pos
= zba_chunk_header_size(1); pos
< ZBA_CHUNK_SIZE
; pos
+= ZBA_GRANULE
) {
120 T_QUIET
; T_ASSERT_EQ(base
+ pos
, zba_alloc(0), "alloc");
121 *(uint64_t *)(base
+ pos
) = ~0ull;
124 for (pos
= zba_chunk_header_size(1); pos
< ZBA_CHUNK_SIZE
; pos
+= ZBA_GRANULE
) {
125 zba_free(base
+ pos
, 0);
127 base
-= ZBA_CHUNK_SIZE
;
128 for (pos
= zba_chunk_header_size(0); pos
< ZBA_CHUNK_SIZE
; pos
+= ZBA_GRANULE
) {
129 zba_free(base
+ pos
, 0);