xref: /xnu-8792.81.2/tests/vm_phys_footprint.c (revision 19c3b8c28c31cb8130e034cfb5df6bf9ba342d90)
1*19c3b8c2SApple OSS Distributions #include <darwintest.h>
2*19c3b8c2SApple OSS Distributions #include <darwintest_utils.h>
3*19c3b8c2SApple OSS Distributions 
4*19c3b8c2SApple OSS Distributions #include <mach/mach_error.h>
5*19c3b8c2SApple OSS Distributions #include <mach/mach_init.h>
6*19c3b8c2SApple OSS Distributions #include <mach/memory_entry.h>
7*19c3b8c2SApple OSS Distributions #include <mach/mach_port.h>
8*19c3b8c2SApple OSS Distributions #include <mach/mach_vm.h>
9*19c3b8c2SApple OSS Distributions #include <mach/memory_entry.h>
10*19c3b8c2SApple OSS Distributions #include <mach/task.h>
11*19c3b8c2SApple OSS Distributions #include <mach/task_info.h>
12*19c3b8c2SApple OSS Distributions #include <mach/vm_map.h>
13*19c3b8c2SApple OSS Distributions 
14*19c3b8c2SApple OSS Distributions #include <sys/kern_memorystatus.h>
15*19c3b8c2SApple OSS Distributions #include <sys/mman.h>
16*19c3b8c2SApple OSS Distributions #include <sys/types.h>
17*19c3b8c2SApple OSS Distributions #include <sys/sysctl.h>
18*19c3b8c2SApple OSS Distributions 
19*19c3b8c2SApple OSS Distributions #include <TargetConditionals.h>
20*19c3b8c2SApple OSS Distributions 
21*19c3b8c2SApple OSS Distributions #include <Kernel/kern/ledger.h>
22*19c3b8c2SApple OSS Distributions extern int ledger(int cmd, caddr_t arg1, caddr_t arg2, caddr_t arg3);
23*19c3b8c2SApple OSS Distributions 
24*19c3b8c2SApple OSS Distributions T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true));
25*19c3b8c2SApple OSS Distributions static boolean_t legacy_footprint = FALSE;
26*19c3b8c2SApple OSS Distributions 
27*19c3b8c2SApple OSS Distributions #if LEGACY_FOOTPRINT_ENTITLED && defined(__arm64__)
28*19c3b8c2SApple OSS Distributions #define TEST_VM_NAMESPACE "xnu.vm_legacy"
29*19c3b8c2SApple OSS Distributions #else /* ENTITLED && __arm64__ */
30*19c3b8c2SApple OSS Distributions #define TEST_VM_NAMESPACE "xnu.vm"
31*19c3b8c2SApple OSS Distributions #endif /* ENTITLED && __arm64__ */
32*19c3b8c2SApple OSS Distributions 
33*19c3b8c2SApple OSS Distributions T_GLOBAL_META(
34*19c3b8c2SApple OSS Distributions 	T_META_NAMESPACE(TEST_VM_NAMESPACE),
35*19c3b8c2SApple OSS Distributions 	T_META_RADAR_COMPONENT_NAME("xnu"),
36*19c3b8c2SApple OSS Distributions 	T_META_RADAR_COMPONENT_VERSION("VM"),
37*19c3b8c2SApple OSS Distributions 	T_META_RUN_CONCURRENTLY(true));
38*19c3b8c2SApple OSS Distributions 
39*19c3b8c2SApple OSS Distributions #define MEM_SIZE (100 * 1024 * 1024) /* 100 MB */
40*19c3b8c2SApple OSS Distributions 
41*19c3b8c2SApple OSS Distributions static int64_t ledger_count = -1;
42*19c3b8c2SApple OSS Distributions static int footprint_index = -1;
43*19c3b8c2SApple OSS Distributions static int pagetable_index = -1;
44*19c3b8c2SApple OSS Distributions static struct ledger_entry_info *lei = NULL;
45*19c3b8c2SApple OSS Distributions 
46*19c3b8c2SApple OSS Distributions static void
ledger_init(void)47*19c3b8c2SApple OSS Distributions ledger_init(void)
48*19c3b8c2SApple OSS Distributions {
49*19c3b8c2SApple OSS Distributions 	static int                      ledger_inited = 0;
50*19c3b8c2SApple OSS Distributions 	struct ledger_info              li;
51*19c3b8c2SApple OSS Distributions 	struct ledger_template_info     *templateInfo;
52*19c3b8c2SApple OSS Distributions 	int64_t                         templateCnt;
53*19c3b8c2SApple OSS Distributions 	int                             i;
54*19c3b8c2SApple OSS Distributions 
55*19c3b8c2SApple OSS Distributions 	if (ledger_inited) {
56*19c3b8c2SApple OSS Distributions 		return;
57*19c3b8c2SApple OSS Distributions 	}
58*19c3b8c2SApple OSS Distributions 	ledger_inited = 1;
59*19c3b8c2SApple OSS Distributions 
60*19c3b8c2SApple OSS Distributions 	T_SETUPBEGIN;
61*19c3b8c2SApple OSS Distributions 
62*19c3b8c2SApple OSS Distributions 	legacy_footprint = FALSE;
63*19c3b8c2SApple OSS Distributions #if LEGACY_FOOTPRINT_ENTITLED
64*19c3b8c2SApple OSS Distributions 	int     legacy_footprint_entitlement_mode;
65*19c3b8c2SApple OSS Distributions 	size_t  oldlen;
66*19c3b8c2SApple OSS Distributions 	int     ret;
67*19c3b8c2SApple OSS Distributions 
68*19c3b8c2SApple OSS Distributions 	T_QUIET;
69*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
70*19c3b8c2SApple OSS Distributions 	oldlen = sizeof(legacy_footprint_entitlement_mode);
71*19c3b8c2SApple OSS Distributions 	ret = sysctlbyname("kern.legacy_footprint_entitlement_mode",
72*19c3b8c2SApple OSS Distributions 	    &legacy_footprint_entitlement_mode,
73*19c3b8c2SApple OSS Distributions 	    &oldlen,
74*19c3b8c2SApple OSS Distributions 	    NULL,
75*19c3b8c2SApple OSS Distributions 	    0);
76*19c3b8c2SApple OSS Distributions 	if (ret == 0 && legacy_footprint_entitlement_mode == 2) {
77*19c3b8c2SApple OSS Distributions 		legacy_footprint = TRUE;
78*19c3b8c2SApple OSS Distributions 	}
79*19c3b8c2SApple OSS Distributions #endif /* LEGACY_FOOTPRINT_ENTITLED */
80*19c3b8c2SApple OSS Distributions 
81*19c3b8c2SApple OSS Distributions 	T_QUIET;
82*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
83*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(ledger(LEDGER_INFO,
84*19c3b8c2SApple OSS Distributions 	    (caddr_t)(uintptr_t)getpid(),
85*19c3b8c2SApple OSS Distributions 	    (caddr_t)&li,
86*19c3b8c2SApple OSS Distributions 	    NULL),
87*19c3b8c2SApple OSS Distributions 	    0,
88*19c3b8c2SApple OSS Distributions 	    "ledger(LEDGER_INFO)");
89*19c3b8c2SApple OSS Distributions 
90*19c3b8c2SApple OSS Distributions 	templateCnt = li.li_entries;
91*19c3b8c2SApple OSS Distributions 	templateInfo = malloc((size_t)li.li_entries * sizeof(struct ledger_template_info));
92*19c3b8c2SApple OSS Distributions 	T_QUIET;
93*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
94*19c3b8c2SApple OSS Distributions 	T_ASSERT_NE(templateInfo, NULL, "malloc()");
95*19c3b8c2SApple OSS Distributions 
96*19c3b8c2SApple OSS Distributions 	ledger_count = li.li_entries;
97*19c3b8c2SApple OSS Distributions 	footprint_index = -1;
98*19c3b8c2SApple OSS Distributions 	pagetable_index = -1;
99*19c3b8c2SApple OSS Distributions 	T_QUIET;
100*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
101*19c3b8c2SApple OSS Distributions 	T_ASSERT_GE(ledger(LEDGER_TEMPLATE_INFO,
102*19c3b8c2SApple OSS Distributions 	    (caddr_t)templateInfo,
103*19c3b8c2SApple OSS Distributions 	    (caddr_t)&templateCnt,
104*19c3b8c2SApple OSS Distributions 	    NULL),
105*19c3b8c2SApple OSS Distributions 	    0,
106*19c3b8c2SApple OSS Distributions 	    "ledger(LEDGER_TEMPLATE_INFO)");
107*19c3b8c2SApple OSS Distributions 	for (i = 0; i < templateCnt; i++) {
108*19c3b8c2SApple OSS Distributions 		if (!strncmp(templateInfo[i].lti_name,
109*19c3b8c2SApple OSS Distributions 		    "phys_footprint",
110*19c3b8c2SApple OSS Distributions 		    strlen("phys_footprint"))) {
111*19c3b8c2SApple OSS Distributions 			footprint_index = i;
112*19c3b8c2SApple OSS Distributions 		} else if (!strncmp(templateInfo[i].lti_name,
113*19c3b8c2SApple OSS Distributions 		    "page_table",
114*19c3b8c2SApple OSS Distributions 		    strlen("page_table"))) {
115*19c3b8c2SApple OSS Distributions 			pagetable_index = i;
116*19c3b8c2SApple OSS Distributions 		}
117*19c3b8c2SApple OSS Distributions 	}
118*19c3b8c2SApple OSS Distributions 	free(templateInfo);
119*19c3b8c2SApple OSS Distributions 
120*19c3b8c2SApple OSS Distributions 	lei = (struct ledger_entry_info *)
121*19c3b8c2SApple OSS Distributions 	    malloc((size_t)ledger_count * sizeof(*lei));
122*19c3b8c2SApple OSS Distributions 	T_QUIET;
123*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
124*19c3b8c2SApple OSS Distributions 	T_ASSERT_NE(lei, NULL, "malloc(ledger_entry_info)");
125*19c3b8c2SApple OSS Distributions 
126*19c3b8c2SApple OSS Distributions 	T_QUIET;
127*19c3b8c2SApple OSS Distributions 	T_ASSERT_NE(footprint_index, -1, "no footprint_index");
128*19c3b8c2SApple OSS Distributions 	T_QUIET;
129*19c3b8c2SApple OSS Distributions 	T_ASSERT_NE(pagetable_index, -1, "no pagetable_index");
130*19c3b8c2SApple OSS Distributions 
131*19c3b8c2SApple OSS Distributions 	T_SETUPEND;
132*19c3b8c2SApple OSS Distributions }
133*19c3b8c2SApple OSS Distributions 
134*19c3b8c2SApple OSS Distributions static void
get_ledger_info(uint64_t * phys_footprint,uint64_t * page_table)135*19c3b8c2SApple OSS Distributions get_ledger_info(
136*19c3b8c2SApple OSS Distributions 	uint64_t        *phys_footprint,
137*19c3b8c2SApple OSS Distributions 	uint64_t        *page_table)
138*19c3b8c2SApple OSS Distributions {
139*19c3b8c2SApple OSS Distributions 	int64_t count;
140*19c3b8c2SApple OSS Distributions 
141*19c3b8c2SApple OSS Distributions 	count = ledger_count;
142*19c3b8c2SApple OSS Distributions 	T_QUIET;
143*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
144*19c3b8c2SApple OSS Distributions 	T_ASSERT_GE(ledger(LEDGER_ENTRY_INFO,
145*19c3b8c2SApple OSS Distributions 	    (caddr_t)(uintptr_t)getpid(),
146*19c3b8c2SApple OSS Distributions 	    (caddr_t)lei,
147*19c3b8c2SApple OSS Distributions 	    (caddr_t)&count),
148*19c3b8c2SApple OSS Distributions 	    0,
149*19c3b8c2SApple OSS Distributions 	    "ledger(LEDGER_ENTRY_INFO)");
150*19c3b8c2SApple OSS Distributions 	T_QUIET;
151*19c3b8c2SApple OSS Distributions 	T_ASSERT_GT(count, (int64_t)footprint_index, "no entry for footprint");
152*19c3b8c2SApple OSS Distributions 	T_QUIET;
153*19c3b8c2SApple OSS Distributions 	T_ASSERT_GT(count, (int64_t)pagetable_index, "no entry for pagetable");
154*19c3b8c2SApple OSS Distributions 	if (phys_footprint) {
155*19c3b8c2SApple OSS Distributions 		*phys_footprint = (uint64_t)(lei[footprint_index].lei_balance);
156*19c3b8c2SApple OSS Distributions 	}
157*19c3b8c2SApple OSS Distributions 	if (page_table) {
158*19c3b8c2SApple OSS Distributions 		*page_table = (uint64_t)(lei[pagetable_index].lei_balance);
159*19c3b8c2SApple OSS Distributions 	}
160*19c3b8c2SApple OSS Distributions }
161*19c3b8c2SApple OSS Distributions 
162*19c3b8c2SApple OSS Distributions static mach_vm_address_t
pre_warm_with_tag(mach_vm_size_t vm_size,int tag)163*19c3b8c2SApple OSS Distributions pre_warm_with_tag(
164*19c3b8c2SApple OSS Distributions 	mach_vm_size_t  vm_size,
165*19c3b8c2SApple OSS Distributions 	int             tag)
166*19c3b8c2SApple OSS Distributions {
167*19c3b8c2SApple OSS Distributions 	kern_return_t           kr;
168*19c3b8c2SApple OSS Distributions 	mach_vm_address_t       vm_addr;
169*19c3b8c2SApple OSS Distributions 	unsigned char           BigBufOnStack[100 * 1024];
170*19c3b8c2SApple OSS Distributions 	uint64_t                footprint, page_table;
171*19c3b8c2SApple OSS Distributions 
172*19c3b8c2SApple OSS Distributions 	/* make sure ledgers are ready to be queried */
173*19c3b8c2SApple OSS Distributions 	ledger_init();
174*19c3b8c2SApple OSS Distributions 
175*19c3b8c2SApple OSS Distributions 	T_SETUPBEGIN;
176*19c3b8c2SApple OSS Distributions 
177*19c3b8c2SApple OSS Distributions 	/*
178*19c3b8c2SApple OSS Distributions 	 * Touch a few pages ahead on the stack, to make
179*19c3b8c2SApple OSS Distributions 	 * sure we don't see a footprint increase due to
180*19c3b8c2SApple OSS Distributions 	 * an extra stack page later.
181*19c3b8c2SApple OSS Distributions 	 */
182*19c3b8c2SApple OSS Distributions 	memset(BigBufOnStack, 0xb, sizeof(BigBufOnStack));
183*19c3b8c2SApple OSS Distributions 	T_QUIET;
184*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(BigBufOnStack[0], 0xb,
185*19c3b8c2SApple OSS Distributions 	    "BigBufOnStack[0] == 0x%x",
186*19c3b8c2SApple OSS Distributions 	    BigBufOnStack[0]);
187*19c3b8c2SApple OSS Distributions 	T_QUIET;
188*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(BigBufOnStack[sizeof(BigBufOnStack) - 1], 0xb,
189*19c3b8c2SApple OSS Distributions 	    "BigBufOnStack[%lu] == 0x%x",
190*19c3b8c2SApple OSS Distributions 	    sizeof(BigBufOnStack),
191*19c3b8c2SApple OSS Distributions 	    BigBufOnStack[sizeof(BigBufOnStack) - 1]);
192*19c3b8c2SApple OSS Distributions 
193*19c3b8c2SApple OSS Distributions 	/*
194*19c3b8c2SApple OSS Distributions 	 * Pre-allocate, touch and then release the same amount
195*19c3b8c2SApple OSS Distributions 	 * of memory we'll be allocating later during the test,
196*19c3b8c2SApple OSS Distributions 	 * to account for any memory overhead (page tables, global
197*19c3b8c2SApple OSS Distributions 	 * variables, ...). Supplied VM tag should ensure memory
198*19c3b8c2SApple OSS Distributions 	 * is allocated in the appropriate VM range.
199*19c3b8c2SApple OSS Distributions 	 */
200*19c3b8c2SApple OSS Distributions 	vm_addr = 0;
201*19c3b8c2SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(),
202*19c3b8c2SApple OSS Distributions 	    &vm_addr,
203*19c3b8c2SApple OSS Distributions 	    vm_size,
204*19c3b8c2SApple OSS Distributions 	    VM_FLAGS_ANYWHERE | VM_MAKE_TAG(tag));
205*19c3b8c2SApple OSS Distributions 	T_QUIET;
206*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_allocate(%lld) error 0x%x (%s)",
207*19c3b8c2SApple OSS Distributions 	    vm_size, kr, mach_error_string(kr));
208*19c3b8c2SApple OSS Distributions 	memset((char *)(uintptr_t)vm_addr, 'p', (size_t)vm_size);
209*19c3b8c2SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(),
210*19c3b8c2SApple OSS Distributions 	    vm_addr,
211*19c3b8c2SApple OSS Distributions 	    vm_size);
212*19c3b8c2SApple OSS Distributions 	T_QUIET;
213*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
214*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
215*19c3b8c2SApple OSS Distributions 
216*19c3b8c2SApple OSS Distributions 	/*
217*19c3b8c2SApple OSS Distributions 	 * Exercise the ledger code to make sure it's ready to run
218*19c3b8c2SApple OSS Distributions 	 * without any extra memory overhead later.
219*19c3b8c2SApple OSS Distributions 	 */
220*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint, &page_table);
221*19c3b8c2SApple OSS Distributions 
222*19c3b8c2SApple OSS Distributions 	T_SETUPEND;
223*19c3b8c2SApple OSS Distributions 
224*19c3b8c2SApple OSS Distributions 	/*
225*19c3b8c2SApple OSS Distributions 	 * Return the start of the virtual range we pre-warmed, so that the
226*19c3b8c2SApple OSS Distributions 	 * test can check that it's using the same range.
227*19c3b8c2SApple OSS Distributions 	 */
228*19c3b8c2SApple OSS Distributions 	return vm_addr;
229*19c3b8c2SApple OSS Distributions }
230*19c3b8c2SApple OSS Distributions 
231*19c3b8c2SApple OSS Distributions static mach_vm_address_t
pre_warm(mach_vm_size_t vm_size)232*19c3b8c2SApple OSS Distributions pre_warm(
233*19c3b8c2SApple OSS Distributions 	mach_vm_size_t  vm_size)
234*19c3b8c2SApple OSS Distributions {
235*19c3b8c2SApple OSS Distributions 	/*
236*19c3b8c2SApple OSS Distributions 	 * Default to not tagging pre_warm memory.
237*19c3b8c2SApple OSS Distributions 	 */
238*19c3b8c2SApple OSS Distributions 	return pre_warm_with_tag(vm_size, 0);
239*19c3b8c2SApple OSS Distributions }
240*19c3b8c2SApple OSS Distributions 
241*19c3b8c2SApple OSS Distributions T_DECL(phys_footprint_anonymous,
242*19c3b8c2SApple OSS Distributions     "phys_footprint for anonymous memory",
243*19c3b8c2SApple OSS Distributions     T_META_LTEPHASE(LTE_POSTINIT))
244*19c3b8c2SApple OSS Distributions {
245*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_before, pagetable_before;
246*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_after, pagetable_after;
247*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_expected;
248*19c3b8c2SApple OSS Distributions 	kern_return_t           kr;
249*19c3b8c2SApple OSS Distributions 	mach_vm_address_t       pre_vm_addr, vm_addr;
250*19c3b8c2SApple OSS Distributions 	mach_vm_size_t          vm_size, dirty_size;
251*19c3b8c2SApple OSS Distributions 
252*19c3b8c2SApple OSS Distributions 	/* pre-warm to account for page table expansion */
253*19c3b8c2SApple OSS Distributions 	pre_vm_addr = pre_warm(MEM_SIZE);
254*19c3b8c2SApple OSS Distributions 
255*19c3b8c2SApple OSS Distributions 	/* allocating virtual memory... */
256*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
257*19c3b8c2SApple OSS Distributions 	vm_addr = 0;
258*19c3b8c2SApple OSS Distributions 	vm_size = MEM_SIZE;
259*19c3b8c2SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
260*19c3b8c2SApple OSS Distributions 	    VM_FLAGS_ANYWHERE);
261*19c3b8c2SApple OSS Distributions 	T_QUIET;
262*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_allocate() error 0x%x (%s)",
263*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
264*19c3b8c2SApple OSS Distributions 	T_QUIET;
265*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
266*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
267*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
268*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
269*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
270*19c3b8c2SApple OSS Distributions 	T_LOG("virtual allocation does not change phys_footprint");
271*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
272*19c3b8c2SApple OSS Distributions 	    "virtual allocation of %lld bytes: "
273*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
274*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
275*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
276*19c3b8c2SApple OSS Distributions 
277*19c3b8c2SApple OSS Distributions 	/* touching memory... */
278*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
279*19c3b8c2SApple OSS Distributions 	dirty_size = vm_size / 2;
280*19c3b8c2SApple OSS Distributions 	memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
281*19c3b8c2SApple OSS Distributions 	/* ... should increase footprint */
282*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
283*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + dirty_size;
284*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
285*19c3b8c2SApple OSS Distributions 	T_LOG("modifying anonymous memory increases phys_footprint");
286*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
287*19c3b8c2SApple OSS Distributions 	    "touched %lld bytes: "
288*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
289*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
290*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
291*19c3b8c2SApple OSS Distributions 
292*19c3b8c2SApple OSS Distributions 	/* deallocating memory... */
293*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
294*19c3b8c2SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
295*19c3b8c2SApple OSS Distributions 	T_QUIET;
296*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
297*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
298*19c3b8c2SApple OSS Distributions 	/* ... should decrease footprint */
299*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
300*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - dirty_size;
301*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
302*19c3b8c2SApple OSS Distributions 	T_LOG("deallocating dirty anonymous memory decreases phys_footprint");
303*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
304*19c3b8c2SApple OSS Distributions 	    "deallocated %lld dirty bytes: "
305*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
306*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
307*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
308*19c3b8c2SApple OSS Distributions }
309*19c3b8c2SApple OSS Distributions 
310*19c3b8c2SApple OSS Distributions #define TEMP_FILE_TEMPLATE "/tmp/phys_footprint_data.XXXXXXXX"
311*19c3b8c2SApple OSS Distributions #define TEMP_FILE_SIZE  (1 * 1024 * 1024)
312*19c3b8c2SApple OSS Distributions 
313*19c3b8c2SApple OSS Distributions T_DECL(phys_footprint_file,
314*19c3b8c2SApple OSS Distributions     "phys_footprint for mapped file",
315*19c3b8c2SApple OSS Distributions     T_META_LTEPHASE(LTE_POSTINIT))
316*19c3b8c2SApple OSS Distributions {
317*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_before, pagetable_before;
318*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_after, pagetable_after;
319*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_expected;
320*19c3b8c2SApple OSS Distributions 	mach_vm_address_t       pre_vm_addr;
321*19c3b8c2SApple OSS Distributions 	int                     fd;
322*19c3b8c2SApple OSS Distributions 	char                    *map_addr;
323*19c3b8c2SApple OSS Distributions 	size_t                  map_size, dirty_size;
324*19c3b8c2SApple OSS Distributions 	ssize_t                 nbytes;
325*19c3b8c2SApple OSS Distributions 	char                    tmp_file_name[PATH_MAX] = TEMP_FILE_TEMPLATE;
326*19c3b8c2SApple OSS Distributions 	char                    *buf;
327*19c3b8c2SApple OSS Distributions 	size_t                  buf_size;
328*19c3b8c2SApple OSS Distributions 
329*19c3b8c2SApple OSS Distributions 	T_SETUPBEGIN;
330*19c3b8c2SApple OSS Distributions 	buf_size = TEMP_FILE_SIZE;
331*19c3b8c2SApple OSS Distributions 	T_QUIET;
332*19c3b8c2SApple OSS Distributions 	T_ASSERT_NOTNULL(buf = (char *)malloc(buf_size),
333*19c3b8c2SApple OSS Distributions 	    "allocate %zu-byte buffer", buf_size);
334*19c3b8c2SApple OSS Distributions 	memset(buf, 'f', buf_size);
335*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
336*19c3b8c2SApple OSS Distributions 	T_QUIET;
337*19c3b8c2SApple OSS Distributions 	T_ASSERT_NOTNULL(mktemp(tmp_file_name),
338*19c3b8c2SApple OSS Distributions 	    "create temporary file name");
339*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
340*19c3b8c2SApple OSS Distributions 	T_QUIET;
341*19c3b8c2SApple OSS Distributions 	T_ASSERT_GE(fd = open(tmp_file_name, O_CREAT | O_RDWR),
342*19c3b8c2SApple OSS Distributions 	    0,
343*19c3b8c2SApple OSS Distributions 	    "create temp file");
344*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
345*19c3b8c2SApple OSS Distributions 	T_QUIET;
346*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(nbytes = write(fd, buf, buf_size),
347*19c3b8c2SApple OSS Distributions 	    (ssize_t)buf_size,
348*19c3b8c2SApple OSS Distributions 	    "write %zu bytes", buf_size);
349*19c3b8c2SApple OSS Distributions 	free(buf);
350*19c3b8c2SApple OSS Distributions 	T_SETUPEND;
351*19c3b8c2SApple OSS Distributions 
352*19c3b8c2SApple OSS Distributions 	/* pre-warm to account for page table expansion */
353*19c3b8c2SApple OSS Distributions 	pre_vm_addr = pre_warm_with_tag(TEMP_FILE_SIZE, VM_MEMORY_MALLOC);
354*19c3b8c2SApple OSS Distributions 
355*19c3b8c2SApple OSS Distributions 	/* mapping a file does not impact footprint... */
356*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
357*19c3b8c2SApple OSS Distributions 	map_size = TEMP_FILE_SIZE;
358*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
359*19c3b8c2SApple OSS Distributions 	T_QUIET;
360*19c3b8c2SApple OSS Distributions 	T_ASSERT_NOTNULL(map_addr = (char *)mmap(NULL, map_size,
361*19c3b8c2SApple OSS Distributions 	    PROT_READ | PROT_WRITE,
362*19c3b8c2SApple OSS Distributions 	    MAP_FILE | MAP_SHARED, fd, 0),
363*19c3b8c2SApple OSS Distributions 	    "mmap()");
364*19c3b8c2SApple OSS Distributions 	T_QUIET;
365*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ((mach_vm_address_t)map_addr, pre_vm_addr,
366*19c3b8c2SApple OSS Distributions 	    "pre-warm mishap");
367*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
368*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
369*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
370*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
371*19c3b8c2SApple OSS Distributions 	T_LOG("mapping file does not change phys_footprint");
372*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
373*19c3b8c2SApple OSS Distributions 	    "mapping file with %zu bytes: "
374*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
375*19c3b8c2SApple OSS Distributions 	    map_size, footprint_before, footprint_after,
376*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
377*19c3b8c2SApple OSS Distributions 
378*19c3b8c2SApple OSS Distributions 	/* touching file-backed memory... */
379*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
380*19c3b8c2SApple OSS Distributions 	dirty_size = map_size / 2;
381*19c3b8c2SApple OSS Distributions 	memset(map_addr, 'F', dirty_size);
382*19c3b8c2SApple OSS Distributions 	/* ... should not impact footprint */
383*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
384*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
385*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
386*19c3b8c2SApple OSS Distributions 	T_LOG("modifying file-backed memory does not impact phys_footprint");
387*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
388*19c3b8c2SApple OSS Distributions 	    "touched %zu bytes: "
389*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
390*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
391*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
392*19c3b8c2SApple OSS Distributions 
393*19c3b8c2SApple OSS Distributions 	/* deallocating file-backed memory... */
394*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
395*19c3b8c2SApple OSS Distributions 	T_WITH_ERRNO;
396*19c3b8c2SApple OSS Distributions 	T_QUIET;
397*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(munmap(map_addr, map_size),
398*19c3b8c2SApple OSS Distributions 	    0,
399*19c3b8c2SApple OSS Distributions 	    "unmap file");
400*19c3b8c2SApple OSS Distributions 	/* ... should not impact footprint */
401*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
402*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
403*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
404*19c3b8c2SApple OSS Distributions 	T_LOG("unmapping file-backed memory does not impact phys_footprint");
405*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
406*19c3b8c2SApple OSS Distributions 	    "unmapped %zu dirty bytes: "
407*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
408*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
409*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
410*19c3b8c2SApple OSS Distributions }
411*19c3b8c2SApple OSS Distributions 
412*19c3b8c2SApple OSS Distributions T_DECL(phys_footprint_purgeable,
413*19c3b8c2SApple OSS Distributions     "phys_footprint for purgeable memory",
414*19c3b8c2SApple OSS Distributions     T_META_LTEPHASE(LTE_POSTINIT))
415*19c3b8c2SApple OSS Distributions {
416*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_before, pagetable_before;
417*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_after, pagetable_after;
418*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_expected;
419*19c3b8c2SApple OSS Distributions 	kern_return_t           kr;
420*19c3b8c2SApple OSS Distributions 	mach_vm_address_t       pre_vm_addr, vm_addr;
421*19c3b8c2SApple OSS Distributions 	mach_vm_size_t          vm_size, dirty_size;
422*19c3b8c2SApple OSS Distributions 	int                     state;
423*19c3b8c2SApple OSS Distributions 
424*19c3b8c2SApple OSS Distributions 	/* pre-warm to account for page table expansion */
425*19c3b8c2SApple OSS Distributions 	pre_vm_addr = pre_warm(MEM_SIZE);
426*19c3b8c2SApple OSS Distributions 
427*19c3b8c2SApple OSS Distributions 	/* allocating purgeable virtual memory... */
428*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
429*19c3b8c2SApple OSS Distributions 	vm_addr = 0;
430*19c3b8c2SApple OSS Distributions 	vm_size = MEM_SIZE;
431*19c3b8c2SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
432*19c3b8c2SApple OSS Distributions 	    VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE);
433*19c3b8c2SApple OSS Distributions 	T_QUIET;
434*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_allocate() error 0x%x (%s)",
435*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
436*19c3b8c2SApple OSS Distributions 	T_QUIET;
437*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
438*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
439*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
440*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
441*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
442*19c3b8c2SApple OSS Distributions 	T_LOG("purgeable virtual allocation does not change phys_footprint");
443*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
444*19c3b8c2SApple OSS Distributions 	    "purgeable virtual allocation of %lld bytes: "
445*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
446*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
447*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
448*19c3b8c2SApple OSS Distributions 
449*19c3b8c2SApple OSS Distributions 	/* touching memory... */
450*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
451*19c3b8c2SApple OSS Distributions 	dirty_size = vm_size / 2;
452*19c3b8c2SApple OSS Distributions 	memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
453*19c3b8c2SApple OSS Distributions 	/* ... should increase footprint */
454*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
455*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + dirty_size;
456*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
457*19c3b8c2SApple OSS Distributions 	T_LOG("modifying anonymous memory increases phys_footprint");
458*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
459*19c3b8c2SApple OSS Distributions 	    "touched %lld bytes: "
460*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
461*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
462*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
463*19c3b8c2SApple OSS Distributions 
464*19c3b8c2SApple OSS Distributions 	/* making it volatile... */
465*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
466*19c3b8c2SApple OSS Distributions 	state = VM_PURGABLE_VOLATILE;
467*19c3b8c2SApple OSS Distributions 	T_QUIET;
468*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
469*19c3b8c2SApple OSS Distributions 	    vm_addr,
470*19c3b8c2SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
471*19c3b8c2SApple OSS Distributions 	    &state),
472*19c3b8c2SApple OSS Distributions 	    KERN_SUCCESS,
473*19c3b8c2SApple OSS Distributions 	    "vm_purgable_control(VOLATILE)");
474*19c3b8c2SApple OSS Distributions 	T_QUIET;
475*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_NONVOLATILE,
476*19c3b8c2SApple OSS Distributions 	    "memory was non-volatile");
477*19c3b8c2SApple OSS Distributions 	/* ... should decrease footprint */
478*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
479*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - dirty_size;
480*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
481*19c3b8c2SApple OSS Distributions 	T_LOG("making volatile decreases phys_footprint");
482*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
483*19c3b8c2SApple OSS Distributions 	    "made volatile %lld dirty bytes: "
484*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
485*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
486*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
487*19c3b8c2SApple OSS Distributions 
488*19c3b8c2SApple OSS Distributions 	/* making it non-volatile... */
489*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
490*19c3b8c2SApple OSS Distributions 	state = VM_PURGABLE_NONVOLATILE;
491*19c3b8c2SApple OSS Distributions 	T_QUIET;
492*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
493*19c3b8c2SApple OSS Distributions 	    vm_addr,
494*19c3b8c2SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
495*19c3b8c2SApple OSS Distributions 	    &state),
496*19c3b8c2SApple OSS Distributions 	    KERN_SUCCESS,
497*19c3b8c2SApple OSS Distributions 	    "vm_purgable_control(NONVOLATILE)");
498*19c3b8c2SApple OSS Distributions 	T_QUIET;
499*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_VOLATILE,
500*19c3b8c2SApple OSS Distributions 	    "memory was volatile");
501*19c3b8c2SApple OSS Distributions 	/* ... should increase footprint */
502*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
503*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + dirty_size;
504*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
505*19c3b8c2SApple OSS Distributions 	T_LOG("making non-volatile increases phys_footprint");
506*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
507*19c3b8c2SApple OSS Distributions 	    "made non-volatile %lld dirty bytes: "
508*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
509*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
510*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
511*19c3b8c2SApple OSS Distributions 
512*19c3b8c2SApple OSS Distributions 	/* deallocating memory... */
513*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
514*19c3b8c2SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
515*19c3b8c2SApple OSS Distributions 	T_QUIET;
516*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
517*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
518*19c3b8c2SApple OSS Distributions 	/* ... should decrease footprint */
519*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
520*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - dirty_size;
521*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
522*19c3b8c2SApple OSS Distributions 	T_LOG("deallocating memory decreases phys_footprint");
523*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
524*19c3b8c2SApple OSS Distributions 	    "deallocated %lld dirty bytes: "
525*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
526*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
527*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
528*19c3b8c2SApple OSS Distributions }
529*19c3b8c2SApple OSS Distributions 
530*19c3b8c2SApple OSS Distributions T_DECL(phys_footprint_purgeable_ownership,
531*19c3b8c2SApple OSS Distributions     "phys_footprint for owned purgeable memory",
532*19c3b8c2SApple OSS Distributions     T_META_LTEPHASE(LTE_POSTINIT))
533*19c3b8c2SApple OSS Distributions {
534*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_before, pagetable_before;
535*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_after, pagetable_after;
536*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_expected;
537*19c3b8c2SApple OSS Distributions 	kern_return_t           kr;
538*19c3b8c2SApple OSS Distributions 	mach_vm_address_t       pre_vm_addr, vm_addr;
539*19c3b8c2SApple OSS Distributions 	mach_vm_size_t          vm_size, dirty_size, me_size;
540*19c3b8c2SApple OSS Distributions 	int                     state;
541*19c3b8c2SApple OSS Distributions 	mach_port_t             me_port;
542*19c3b8c2SApple OSS Distributions 
543*19c3b8c2SApple OSS Distributions 	/* pre-warm to account for page table expansion */
544*19c3b8c2SApple OSS Distributions 	pre_vm_addr = pre_warm(MEM_SIZE);
545*19c3b8c2SApple OSS Distributions 
546*19c3b8c2SApple OSS Distributions 	/* allocating purgeable virtual memory... */
547*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
548*19c3b8c2SApple OSS Distributions 	vm_addr = 0;
549*19c3b8c2SApple OSS Distributions 	vm_size = MEM_SIZE;
550*19c3b8c2SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
551*19c3b8c2SApple OSS Distributions 	    VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE);
552*19c3b8c2SApple OSS Distributions 	T_QUIET;
553*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_allocate() error 0x%x (%s)",
554*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
555*19c3b8c2SApple OSS Distributions 	T_QUIET;
556*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
557*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
558*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
559*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
560*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
561*19c3b8c2SApple OSS Distributions 	T_LOG("purgeable virtual allocation does not change phys_footprint");
562*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
563*19c3b8c2SApple OSS Distributions 	    "purgeable virtual allocation of %lld bytes: "
564*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
565*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
566*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
567*19c3b8c2SApple OSS Distributions 
568*19c3b8c2SApple OSS Distributions 	/* touching memory... */
569*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
570*19c3b8c2SApple OSS Distributions 	dirty_size = vm_size / 2;
571*19c3b8c2SApple OSS Distributions 	memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
572*19c3b8c2SApple OSS Distributions 	/* ... should increase footprint */
573*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
574*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + dirty_size;
575*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
576*19c3b8c2SApple OSS Distributions 	T_LOG("modifying anonymous memory increases phys_footprint");
577*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
578*19c3b8c2SApple OSS Distributions 	    "touched %lld bytes: "
579*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
580*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
581*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
582*19c3b8c2SApple OSS Distributions 
583*19c3b8c2SApple OSS Distributions 	/* making it volatile... */
584*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
585*19c3b8c2SApple OSS Distributions 	state = VM_PURGABLE_VOLATILE;
586*19c3b8c2SApple OSS Distributions 	T_QUIET;
587*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
588*19c3b8c2SApple OSS Distributions 	    vm_addr,
589*19c3b8c2SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
590*19c3b8c2SApple OSS Distributions 	    &state),
591*19c3b8c2SApple OSS Distributions 	    KERN_SUCCESS,
592*19c3b8c2SApple OSS Distributions 	    "vm_purgable_control(VOLATILE)");
593*19c3b8c2SApple OSS Distributions 	T_QUIET;
594*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_NONVOLATILE,
595*19c3b8c2SApple OSS Distributions 	    "memory was non-volatile");
596*19c3b8c2SApple OSS Distributions 	/* ... should decrease footprint */
597*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
598*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - dirty_size;
599*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
600*19c3b8c2SApple OSS Distributions 	T_LOG("making volatile decreases phys_footprint");
601*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
602*19c3b8c2SApple OSS Distributions 	    "made volatile %lld dirty bytes: "
603*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
604*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
605*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
606*19c3b8c2SApple OSS Distributions 
607*19c3b8c2SApple OSS Distributions 	/* making it non-volatile... */
608*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
609*19c3b8c2SApple OSS Distributions 	state = VM_PURGABLE_NONVOLATILE;
610*19c3b8c2SApple OSS Distributions 	T_QUIET;
611*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
612*19c3b8c2SApple OSS Distributions 	    vm_addr,
613*19c3b8c2SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
614*19c3b8c2SApple OSS Distributions 	    &state),
615*19c3b8c2SApple OSS Distributions 	    KERN_SUCCESS,
616*19c3b8c2SApple OSS Distributions 	    "vm_purgable_control(NONVOLATILE)");
617*19c3b8c2SApple OSS Distributions 	T_QUIET;
618*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_VOLATILE,
619*19c3b8c2SApple OSS Distributions 	    "memory was volatile");
620*19c3b8c2SApple OSS Distributions 	/* ... should increase footprint */
621*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
622*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + dirty_size;
623*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
624*19c3b8c2SApple OSS Distributions 	T_LOG("making non-volatile increases phys_footprint");
625*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
626*19c3b8c2SApple OSS Distributions 	    "made non-volatile %lld dirty bytes: "
627*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
628*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
629*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
630*19c3b8c2SApple OSS Distributions 
631*19c3b8c2SApple OSS Distributions 	/* making a memory entry... */
632*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
633*19c3b8c2SApple OSS Distributions 	me_size = vm_size;
634*19c3b8c2SApple OSS Distributions 	me_port = MACH_PORT_NULL;
635*19c3b8c2SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
636*19c3b8c2SApple OSS Distributions 	    &me_size,
637*19c3b8c2SApple OSS Distributions 	    vm_addr,
638*19c3b8c2SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
639*19c3b8c2SApple OSS Distributions 	    &me_port,
640*19c3b8c2SApple OSS Distributions 	    MACH_PORT_NULL);
641*19c3b8c2SApple OSS Distributions 	T_QUIET;
642*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "make_memory_entry() error 0x%x (%s)",
643*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
644*19c3b8c2SApple OSS Distributions 	T_QUIET;
645*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(me_size, vm_size, "memory entry size mismatch");
646*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
647*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
648*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
649*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
650*19c3b8c2SApple OSS Distributions 	T_LOG("making a memory entry does not change phys_footprint");
651*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
652*19c3b8c2SApple OSS Distributions 	    "making a memory entry of %lld bytes: "
653*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
654*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
655*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
656*19c3b8c2SApple OSS Distributions 
657*19c3b8c2SApple OSS Distributions 	/* deallocating memory while holding memory entry... */
658*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
659*19c3b8c2SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
660*19c3b8c2SApple OSS Distributions 	T_QUIET;
661*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
662*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
663*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
664*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
665*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
666*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
667*19c3b8c2SApple OSS Distributions 	T_LOG("deallocating owned memory while holding memory entry "
668*19c3b8c2SApple OSS Distributions 	    "does not change phys_footprint");
669*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
670*19c3b8c2SApple OSS Distributions 	    "deallocated %lld dirty bytes: "
671*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
672*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
673*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
674*19c3b8c2SApple OSS Distributions 
675*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
676*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
677*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
678*19c3b8c2SApple OSS Distributions 	T_LOG("deallocating owned memory while holding memory entry "
679*19c3b8c2SApple OSS Distributions 	    "does not change phys_footprint");
680*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
681*19c3b8c2SApple OSS Distributions 	    "deallocated %lld dirty bytes: "
682*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
683*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
684*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
685*19c3b8c2SApple OSS Distributions 
686*19c3b8c2SApple OSS Distributions 	/* changing ownership of memory entry (from self to self)... */
687*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
688*19c3b8c2SApple OSS Distributions 	kr = mach_memory_entry_ownership(me_port,
689*19c3b8c2SApple OSS Distributions #if VM_LEDGER_TAG_UNCHANGED
690*19c3b8c2SApple OSS Distributions 	    MACH_PORT_NULL,          /* owner remains unchanged */
691*19c3b8c2SApple OSS Distributions 	    VM_LEDGER_TAG_UNCHANGED, /* ledger-tag remains unchanged */
692*19c3b8c2SApple OSS Distributions #else /* VM_LEDGER_TAG_UNCHANGED */
693*19c3b8c2SApple OSS Distributions 	    mach_task_self(),
694*19c3b8c2SApple OSS Distributions 	    VM_LEDGER_TAG_DEFAULT,
695*19c3b8c2SApple OSS Distributions #endif /* VM_LEDGER_TAG_UNCHANGED */
696*19c3b8c2SApple OSS Distributions 	    0);
697*19c3b8c2SApple OSS Distributions 	T_QUIET;
698*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS,
699*19c3b8c2SApple OSS Distributions 	    "mach_memory_entry_ownership() error 0x%x (%s)",
700*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
701*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
702*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
703*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
704*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
705*19c3b8c2SApple OSS Distributions 	T_LOG("changing ownership from self to self "
706*19c3b8c2SApple OSS Distributions 	    "does not change phys_footprint");
707*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
708*19c3b8c2SApple OSS Distributions 	    "changed ownership of %lld dirty bytes: "
709*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
710*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
711*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
712*19c3b8c2SApple OSS Distributions 
713*19c3b8c2SApple OSS Distributions 	/* releasing the memory entry... */
714*19c3b8c2SApple OSS Distributions 	kr = mach_port_deallocate(mach_task_self(), me_port);
715*19c3b8c2SApple OSS Distributions 	T_QUIET;
716*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "mach_port_deallocate() error 0x%x (%s)",
717*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
718*19c3b8c2SApple OSS Distributions 	/* ... should decrease footprint */
719*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
720*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - dirty_size;
721*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
722*19c3b8c2SApple OSS Distributions 	T_LOG("releasing memory entry decreases phys_footprint");
723*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
724*19c3b8c2SApple OSS Distributions 	    "made volatile %lld dirty bytes: "
725*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
726*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
727*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
728*19c3b8c2SApple OSS Distributions }
729*19c3b8c2SApple OSS Distributions 
730*19c3b8c2SApple OSS Distributions #if VM_LEDGER_TAG_UNCHANGED
731*19c3b8c2SApple OSS Distributions T_DECL(phys_footprint_multiple_purgeable_ownership,
732*19c3b8c2SApple OSS Distributions     "phys_footprint for owned purgeable memory (MAP_MEM_VM_SHARE)",
733*19c3b8c2SApple OSS Distributions     T_META_NAMESPACE(TEST_VM_NAMESPACE),
734*19c3b8c2SApple OSS Distributions     T_META_LTEPHASE(LTE_POSTINIT))
735*19c3b8c2SApple OSS Distributions {
736*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_before, pagetable_before;
737*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_after, pagetable_after;
738*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_expected;
739*19c3b8c2SApple OSS Distributions 	kern_return_t           kr;
740*19c3b8c2SApple OSS Distributions 	mach_vm_address_t       pre_vm_addr, vm_addr;
741*19c3b8c2SApple OSS Distributions 	mach_vm_size_t          vm_size, dirty_size, me_size;
742*19c3b8c2SApple OSS Distributions 	int                     state;
743*19c3b8c2SApple OSS Distributions 	mach_port_t             me_port;
744*19c3b8c2SApple OSS Distributions 
745*19c3b8c2SApple OSS Distributions 	/* pre-warm to account for page table expansion */
746*19c3b8c2SApple OSS Distributions 	pre_vm_addr = pre_warm(MEM_SIZE);
747*19c3b8c2SApple OSS Distributions 
748*19c3b8c2SApple OSS Distributions 	/* allocating purgeable virtual memory... */
749*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
750*19c3b8c2SApple OSS Distributions 	vm_addr = 0;
751*19c3b8c2SApple OSS Distributions 	vm_size = MEM_SIZE;
752*19c3b8c2SApple OSS Distributions 	kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
753*19c3b8c2SApple OSS Distributions 	    VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE);
754*19c3b8c2SApple OSS Distributions 	T_QUIET;
755*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_allocate() error 0x%x (%s)",
756*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
757*19c3b8c2SApple OSS Distributions 	T_QUIET;
758*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
759*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
760*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
761*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
762*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
763*19c3b8c2SApple OSS Distributions 	T_LOG("purgeable virtual allocation does not change phys_footprint");
764*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
765*19c3b8c2SApple OSS Distributions 	    "purgeable virtual allocation of %lld bytes: "
766*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
767*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
768*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
769*19c3b8c2SApple OSS Distributions 
770*19c3b8c2SApple OSS Distributions 	/* touching memory... */
771*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
772*19c3b8c2SApple OSS Distributions 	dirty_size = vm_size / 2;
773*19c3b8c2SApple OSS Distributions 	memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
774*19c3b8c2SApple OSS Distributions 	/* ... should increase footprint */
775*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
776*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + dirty_size;
777*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
778*19c3b8c2SApple OSS Distributions 	T_LOG("modifying anonymous memory increases phys_footprint");
779*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
780*19c3b8c2SApple OSS Distributions 	    "touched %lld bytes: "
781*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
782*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
783*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
784*19c3b8c2SApple OSS Distributions 
785*19c3b8c2SApple OSS Distributions 	/* making it volatile... */
786*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
787*19c3b8c2SApple OSS Distributions 	state = VM_PURGABLE_VOLATILE;
788*19c3b8c2SApple OSS Distributions 	T_QUIET;
789*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
790*19c3b8c2SApple OSS Distributions 	    vm_addr,
791*19c3b8c2SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
792*19c3b8c2SApple OSS Distributions 	    &state),
793*19c3b8c2SApple OSS Distributions 	    KERN_SUCCESS,
794*19c3b8c2SApple OSS Distributions 	    "vm_purgable_control(VOLATILE)");
795*19c3b8c2SApple OSS Distributions 	T_QUIET;
796*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_NONVOLATILE,
797*19c3b8c2SApple OSS Distributions 	    "memory was non-volatile");
798*19c3b8c2SApple OSS Distributions 	/* ... should decrease footprint */
799*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
800*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - dirty_size;
801*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
802*19c3b8c2SApple OSS Distributions 	T_LOG("making volatile decreases phys_footprint");
803*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
804*19c3b8c2SApple OSS Distributions 	    "made volatile %lld dirty bytes: "
805*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
806*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
807*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
808*19c3b8c2SApple OSS Distributions 
809*19c3b8c2SApple OSS Distributions 	/* making it non-volatile... */
810*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
811*19c3b8c2SApple OSS Distributions 	state = VM_PURGABLE_NONVOLATILE;
812*19c3b8c2SApple OSS Distributions 	T_QUIET;
813*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
814*19c3b8c2SApple OSS Distributions 	    vm_addr,
815*19c3b8c2SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
816*19c3b8c2SApple OSS Distributions 	    &state),
817*19c3b8c2SApple OSS Distributions 	    KERN_SUCCESS,
818*19c3b8c2SApple OSS Distributions 	    "vm_purgable_control(NONVOLATILE)");
819*19c3b8c2SApple OSS Distributions 	T_QUIET;
820*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_VOLATILE,
821*19c3b8c2SApple OSS Distributions 	    "memory was volatile");
822*19c3b8c2SApple OSS Distributions 	/* ... should increase footprint */
823*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
824*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + dirty_size;
825*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
826*19c3b8c2SApple OSS Distributions 	T_LOG("making non-volatile increases phys_footprint");
827*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
828*19c3b8c2SApple OSS Distributions 	    "made non-volatile %lld dirty bytes: "
829*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
830*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
831*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
832*19c3b8c2SApple OSS Distributions 
833*19c3b8c2SApple OSS Distributions 	/* making a memory entry... */
834*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
835*19c3b8c2SApple OSS Distributions 	me_size = vm_size;
836*19c3b8c2SApple OSS Distributions 	me_port = MACH_PORT_NULL;
837*19c3b8c2SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
838*19c3b8c2SApple OSS Distributions 	    &me_size,
839*19c3b8c2SApple OSS Distributions 	    vm_addr,
840*19c3b8c2SApple OSS Distributions 	    MAP_MEM_VM_SHARE | VM_PROT_READ | VM_PROT_WRITE,
841*19c3b8c2SApple OSS Distributions 	    &me_port,
842*19c3b8c2SApple OSS Distributions 	    MACH_PORT_NULL);
843*19c3b8c2SApple OSS Distributions 	T_QUIET;
844*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "make_memory_entry() error 0x%x (%s)",
845*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
846*19c3b8c2SApple OSS Distributions 	T_QUIET;
847*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(me_size, vm_size, "memory entry size mismatch");
848*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
849*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
850*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
851*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
852*19c3b8c2SApple OSS Distributions 	T_LOG("making a memory entry does not change phys_footprint");
853*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
854*19c3b8c2SApple OSS Distributions 	    "making a memory entry of %lld bytes: "
855*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
856*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
857*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
858*19c3b8c2SApple OSS Distributions 
859*19c3b8c2SApple OSS Distributions 	/* deallocating memory while holding memory entry... */
860*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
861*19c3b8c2SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
862*19c3b8c2SApple OSS Distributions 	T_QUIET;
863*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
864*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
865*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
866*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
867*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
868*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
869*19c3b8c2SApple OSS Distributions 	T_LOG("deallocating owned memory while holding memory entry "
870*19c3b8c2SApple OSS Distributions 	    "does not change phys_footprint");
871*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
872*19c3b8c2SApple OSS Distributions 	    "deallocated %lld dirty bytes: "
873*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
874*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
875*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
876*19c3b8c2SApple OSS Distributions 
877*19c3b8c2SApple OSS Distributions 	/* changing ownership of memory entry (from self to self)... */
878*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
879*19c3b8c2SApple OSS Distributions 	kr = mach_memory_entry_ownership(me_port,
880*19c3b8c2SApple OSS Distributions 	    MACH_PORT_NULL,          /* owner remains unchanged */
881*19c3b8c2SApple OSS Distributions 	    VM_LEDGER_TAG_UNCHANGED, /* ledger-tag remains unchanged */
882*19c3b8c2SApple OSS Distributions 	    0);
883*19c3b8c2SApple OSS Distributions 	T_QUIET;
884*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS,
885*19c3b8c2SApple OSS Distributions 	    "mach_memory_entry_ownership() error 0x%x (%s)",
886*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
887*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
888*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
889*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
890*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
891*19c3b8c2SApple OSS Distributions 	T_LOG("changing ownership from self to self "
892*19c3b8c2SApple OSS Distributions 	    "does not change phys_footprint");
893*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
894*19c3b8c2SApple OSS Distributions 	    "changed ownership of %lld dirty bytes: "
895*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
896*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
897*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
898*19c3b8c2SApple OSS Distributions 
899*19c3b8c2SApple OSS Distributions 	/* releasing the memory entry... */
900*19c3b8c2SApple OSS Distributions 	kr = mach_port_deallocate(mach_task_self(), me_port);
901*19c3b8c2SApple OSS Distributions 	T_QUIET;
902*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "mach_port_deallocate() error 0x%x (%s)",
903*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
904*19c3b8c2SApple OSS Distributions 	/* ... should decrease footprint */
905*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
906*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - dirty_size;
907*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
908*19c3b8c2SApple OSS Distributions 	T_LOG("releasing memory entry decreases phys_footprint");
909*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
910*19c3b8c2SApple OSS Distributions 	    "made volatile %lld dirty bytes: "
911*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
912*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
913*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
914*19c3b8c2SApple OSS Distributions }
915*19c3b8c2SApple OSS Distributions #endif /* VM_LEDGER_TAG_UNCHANGED */
916*19c3b8c2SApple OSS Distributions 
917*19c3b8c2SApple OSS Distributions #ifdef MAP_MEM_LEDGER_TAGGED
918*19c3b8c2SApple OSS Distributions T_DECL(phys_footprint_ledger_purgeable_owned,
919*19c3b8c2SApple OSS Distributions     "phys_footprint for ledger-tagged purgeable memory ownership",
920*19c3b8c2SApple OSS Distributions     T_META_LTEPHASE(LTE_POSTINIT))
921*19c3b8c2SApple OSS Distributions {
922*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_before, pagetable_before;
923*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_after, pagetable_after;
924*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_expected;
925*19c3b8c2SApple OSS Distributions 	kern_return_t           kr;
926*19c3b8c2SApple OSS Distributions 	mach_vm_address_t       pre_vm_addr, vm_addr;
927*19c3b8c2SApple OSS Distributions 	mach_vm_size_t          vm_size, dirty_size, me_size;
928*19c3b8c2SApple OSS Distributions 	int                     state;
929*19c3b8c2SApple OSS Distributions 	mach_port_t             me_port;
930*19c3b8c2SApple OSS Distributions 
931*19c3b8c2SApple OSS Distributions 	/* pre-warm to account for page table expansion */
932*19c3b8c2SApple OSS Distributions 	pre_vm_addr = pre_warm(MEM_SIZE);
933*19c3b8c2SApple OSS Distributions 
934*19c3b8c2SApple OSS Distributions 	/* making a memory entry... */
935*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
936*19c3b8c2SApple OSS Distributions 	vm_size = MEM_SIZE;
937*19c3b8c2SApple OSS Distributions 	me_size = vm_size;
938*19c3b8c2SApple OSS Distributions 	me_port = MACH_PORT_NULL;
939*19c3b8c2SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
940*19c3b8c2SApple OSS Distributions 	    &me_size,
941*19c3b8c2SApple OSS Distributions 	    0,
942*19c3b8c2SApple OSS Distributions 	    (MAP_MEM_NAMED_CREATE |
943*19c3b8c2SApple OSS Distributions 	    MAP_MEM_LEDGER_TAGGED |
944*19c3b8c2SApple OSS Distributions 	    MAP_MEM_PURGABLE |
945*19c3b8c2SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE),
946*19c3b8c2SApple OSS Distributions 	    &me_port,
947*19c3b8c2SApple OSS Distributions 	    MACH_PORT_NULL);
948*19c3b8c2SApple OSS Distributions 	T_QUIET;
949*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "make_memory_entry() error 0x%x (%s)",
950*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
951*19c3b8c2SApple OSS Distributions 	T_QUIET;
952*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(me_size, vm_size, "memory entry size mismatch");
953*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
954*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
955*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
956*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
957*19c3b8c2SApple OSS Distributions 	T_LOG("making a memory entry does not change phys_footprint");
958*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
959*19c3b8c2SApple OSS Distributions 	    "making a memory entry of %lld bytes: "
960*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
961*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
962*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
963*19c3b8c2SApple OSS Distributions 
964*19c3b8c2SApple OSS Distributions 	/* mapping ledger-tagged virtual memory... */
965*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
966*19c3b8c2SApple OSS Distributions 	vm_addr = 0;
967*19c3b8c2SApple OSS Distributions 	kr = mach_vm_map(mach_task_self(), &vm_addr, vm_size,
968*19c3b8c2SApple OSS Distributions 	    0, /* mask */
969*19c3b8c2SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
970*19c3b8c2SApple OSS Distributions 	    me_port,
971*19c3b8c2SApple OSS Distributions 	    0, /* offset */
972*19c3b8c2SApple OSS Distributions 	    FALSE, /* copy */
973*19c3b8c2SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
974*19c3b8c2SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
975*19c3b8c2SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
976*19c3b8c2SApple OSS Distributions 	T_QUIET;
977*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_map() error 0x%x (%s)",
978*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
979*19c3b8c2SApple OSS Distributions 	T_QUIET;
980*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
981*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
982*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
983*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
984*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
985*19c3b8c2SApple OSS Distributions 	T_LOG("mapping ledger-tagged memory does not change phys_footprint");
986*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
987*19c3b8c2SApple OSS Distributions 	    "ledger-tagged mapping of %lld bytes: "
988*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
989*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
990*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
991*19c3b8c2SApple OSS Distributions 
992*19c3b8c2SApple OSS Distributions 	/* touching memory... */
993*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
994*19c3b8c2SApple OSS Distributions 	dirty_size = vm_size / 2;
995*19c3b8c2SApple OSS Distributions 	memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
996*19c3b8c2SApple OSS Distributions 	/* ... should increase footprint */
997*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
998*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + dirty_size;
999*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1000*19c3b8c2SApple OSS Distributions 	T_LOG("modifying ledger-tagged memory increases phys_footprint");
1001*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1002*19c3b8c2SApple OSS Distributions 	    "touched %lld bytes: "
1003*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1004*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1005*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1006*19c3b8c2SApple OSS Distributions 
1007*19c3b8c2SApple OSS Distributions 	/* making it volatile... */
1008*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1009*19c3b8c2SApple OSS Distributions 	state = VM_PURGABLE_VOLATILE;
1010*19c3b8c2SApple OSS Distributions 	T_QUIET;
1011*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
1012*19c3b8c2SApple OSS Distributions 	    vm_addr,
1013*19c3b8c2SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
1014*19c3b8c2SApple OSS Distributions 	    &state),
1015*19c3b8c2SApple OSS Distributions 	    KERN_SUCCESS,
1016*19c3b8c2SApple OSS Distributions 	    "vm_purgable_control(VOLATILE)");
1017*19c3b8c2SApple OSS Distributions 	T_QUIET;
1018*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_NONVOLATILE,
1019*19c3b8c2SApple OSS Distributions 	    "memory was non-volatile");
1020*19c3b8c2SApple OSS Distributions 	/* ... should decrease footprint */
1021*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1022*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - dirty_size;
1023*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1024*19c3b8c2SApple OSS Distributions 	T_LOG("making volatile decreases phys_footprint");
1025*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1026*19c3b8c2SApple OSS Distributions 	    "made volatile %lld dirty bytes: "
1027*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1028*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1029*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1030*19c3b8c2SApple OSS Distributions 
1031*19c3b8c2SApple OSS Distributions 	/* making it non-volatile... */
1032*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1033*19c3b8c2SApple OSS Distributions 	state = VM_PURGABLE_NONVOLATILE;
1034*19c3b8c2SApple OSS Distributions 	T_QUIET;
1035*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
1036*19c3b8c2SApple OSS Distributions 	    vm_addr,
1037*19c3b8c2SApple OSS Distributions 	    VM_PURGABLE_SET_STATE,
1038*19c3b8c2SApple OSS Distributions 	    &state),
1039*19c3b8c2SApple OSS Distributions 	    KERN_SUCCESS,
1040*19c3b8c2SApple OSS Distributions 	    "vm_purgable_control(NONVOLATILE)");
1041*19c3b8c2SApple OSS Distributions 	T_QUIET;
1042*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(state, VM_PURGABLE_VOLATILE,
1043*19c3b8c2SApple OSS Distributions 	    "memory was volatile");
1044*19c3b8c2SApple OSS Distributions 	/* ... should increase footprint */
1045*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1046*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + dirty_size;
1047*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1048*19c3b8c2SApple OSS Distributions 	T_LOG("making non-volatile increases phys_footprint");
1049*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1050*19c3b8c2SApple OSS Distributions 	    "made non-volatile %lld dirty bytes: "
1051*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1052*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1053*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1054*19c3b8c2SApple OSS Distributions 
1055*19c3b8c2SApple OSS Distributions 	/* deallocating memory while holding memory entry... */
1056*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1057*19c3b8c2SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
1058*19c3b8c2SApple OSS Distributions 	T_QUIET;
1059*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
1060*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1061*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
1062*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1063*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1064*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1065*19c3b8c2SApple OSS Distributions 	T_LOG("deallocating owned memory while holding memory entry "
1066*19c3b8c2SApple OSS Distributions 	    "does not change phys_footprint");
1067*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1068*19c3b8c2SApple OSS Distributions 	    "deallocated %lld dirty bytes: "
1069*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1070*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1071*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1072*19c3b8c2SApple OSS Distributions 
1073*19c3b8c2SApple OSS Distributions 	/* releasing the memory entry... */
1074*19c3b8c2SApple OSS Distributions 	kr = mach_port_deallocate(mach_task_self(), me_port);
1075*19c3b8c2SApple OSS Distributions 	T_QUIET;
1076*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "mach_port_deallocate() error 0x%x (%s)",
1077*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1078*19c3b8c2SApple OSS Distributions 	/* ... should decrease footprint */
1079*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1080*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - dirty_size;
1081*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1082*19c3b8c2SApple OSS Distributions 	T_LOG("releasing memory entry decreases phys_footprint");
1083*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1084*19c3b8c2SApple OSS Distributions 	    "made volatile %lld dirty bytes: "
1085*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1086*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1087*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1088*19c3b8c2SApple OSS Distributions }
1089*19c3b8c2SApple OSS Distributions 
1090*19c3b8c2SApple OSS Distributions T_DECL(phys_footprint_ledger_owned,
1091*19c3b8c2SApple OSS Distributions     "phys_footprint for ledger-tagged memory ownership",
1092*19c3b8c2SApple OSS Distributions     T_META_LTEPHASE(LTE_POSTINIT))
1093*19c3b8c2SApple OSS Distributions {
1094*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_before, pagetable_before;
1095*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_after, pagetable_after;
1096*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_expected;
1097*19c3b8c2SApple OSS Distributions 	kern_return_t           kr;
1098*19c3b8c2SApple OSS Distributions 	mach_vm_address_t       pre_vm_addr, vm_addr;
1099*19c3b8c2SApple OSS Distributions 	mach_vm_size_t          vm_size, dirty_size, me_size;
1100*19c3b8c2SApple OSS Distributions 	mach_port_t             me_port;
1101*19c3b8c2SApple OSS Distributions 
1102*19c3b8c2SApple OSS Distributions 	/* pre-warm to account for page table expansion */
1103*19c3b8c2SApple OSS Distributions 	pre_vm_addr = pre_warm(MEM_SIZE);
1104*19c3b8c2SApple OSS Distributions 
1105*19c3b8c2SApple OSS Distributions 	/* making a memory entry... */
1106*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1107*19c3b8c2SApple OSS Distributions 	vm_size = MEM_SIZE;
1108*19c3b8c2SApple OSS Distributions 	me_size = vm_size;
1109*19c3b8c2SApple OSS Distributions 	me_port = MACH_PORT_NULL;
1110*19c3b8c2SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
1111*19c3b8c2SApple OSS Distributions 	    &me_size,
1112*19c3b8c2SApple OSS Distributions 	    0,
1113*19c3b8c2SApple OSS Distributions 	    (MAP_MEM_NAMED_CREATE |
1114*19c3b8c2SApple OSS Distributions 	    MAP_MEM_LEDGER_TAGGED |
1115*19c3b8c2SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE),
1116*19c3b8c2SApple OSS Distributions 	    &me_port,
1117*19c3b8c2SApple OSS Distributions 	    MACH_PORT_NULL);
1118*19c3b8c2SApple OSS Distributions 	T_QUIET;
1119*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "make_memory_entry() error 0x%x (%s)",
1120*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1121*19c3b8c2SApple OSS Distributions 	T_QUIET;
1122*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(me_size, vm_size, "memory entry size mismatch");
1123*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
1124*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1125*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1126*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1127*19c3b8c2SApple OSS Distributions 	T_LOG("making a memory entry does not change phys_footprint");
1128*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1129*19c3b8c2SApple OSS Distributions 	    "making a memory entry of %lld bytes: "
1130*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1131*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
1132*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1133*19c3b8c2SApple OSS Distributions 
1134*19c3b8c2SApple OSS Distributions 	/* mapping ledger-tagged virtual memory... */
1135*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1136*19c3b8c2SApple OSS Distributions 	vm_addr = 0;
1137*19c3b8c2SApple OSS Distributions 	kr = mach_vm_map(mach_task_self(), &vm_addr, vm_size,
1138*19c3b8c2SApple OSS Distributions 	    0, /* mask */
1139*19c3b8c2SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
1140*19c3b8c2SApple OSS Distributions 	    me_port,
1141*19c3b8c2SApple OSS Distributions 	    0, /* offset */
1142*19c3b8c2SApple OSS Distributions 	    FALSE, /* copy */
1143*19c3b8c2SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1144*19c3b8c2SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1145*19c3b8c2SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1146*19c3b8c2SApple OSS Distributions 	T_QUIET;
1147*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_map() error 0x%x (%s)",
1148*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1149*19c3b8c2SApple OSS Distributions 	T_QUIET;
1150*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
1151*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
1152*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1153*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1154*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1155*19c3b8c2SApple OSS Distributions 	T_LOG("mapping ledger-tagged memory does not change phys_footprint");
1156*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1157*19c3b8c2SApple OSS Distributions 	    "ledger-tagged mapping of %lld bytes: "
1158*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1159*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
1160*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1161*19c3b8c2SApple OSS Distributions 
1162*19c3b8c2SApple OSS Distributions 	/* touching memory... */
1163*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1164*19c3b8c2SApple OSS Distributions 	dirty_size = vm_size / 2;
1165*19c3b8c2SApple OSS Distributions 	memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
1166*19c3b8c2SApple OSS Distributions 	/* ... should increase footprint */
1167*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1168*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + dirty_size;
1169*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1170*19c3b8c2SApple OSS Distributions 	T_LOG("modifying ledger-tagged memory increases phys_footprint");
1171*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1172*19c3b8c2SApple OSS Distributions 	    "touched %lld bytes: "
1173*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1174*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1175*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1176*19c3b8c2SApple OSS Distributions 
1177*19c3b8c2SApple OSS Distributions 	/* deallocating memory while holding memory entry... */
1178*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1179*19c3b8c2SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
1180*19c3b8c2SApple OSS Distributions 	T_QUIET;
1181*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
1182*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1183*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
1184*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1185*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1186*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1187*19c3b8c2SApple OSS Distributions 	T_LOG("deallocating owned memory while holding memory entry "
1188*19c3b8c2SApple OSS Distributions 	    "does not change phys_footprint");
1189*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1190*19c3b8c2SApple OSS Distributions 	    "deallocated %lld dirty bytes: "
1191*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1192*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1193*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1194*19c3b8c2SApple OSS Distributions 
1195*19c3b8c2SApple OSS Distributions 	/* releasing the memory entry... */
1196*19c3b8c2SApple OSS Distributions 	kr = mach_port_deallocate(mach_task_self(), me_port);
1197*19c3b8c2SApple OSS Distributions 	T_QUIET;
1198*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "mach_port_deallocate() error 0x%x (%s)",
1199*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1200*19c3b8c2SApple OSS Distributions 	/* ... should decrease footprint */
1201*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1202*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - dirty_size;
1203*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1204*19c3b8c2SApple OSS Distributions 	T_LOG("releasing memory entry decreases phys_footprint");
1205*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1206*19c3b8c2SApple OSS Distributions 	    "made volatile %lld dirty bytes: "
1207*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1208*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1209*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1210*19c3b8c2SApple OSS Distributions }
1211*19c3b8c2SApple OSS Distributions 
1212*19c3b8c2SApple OSS Distributions T_DECL(phys_footprint_no_footprint_for_debug,
1213*19c3b8c2SApple OSS Distributions     "phys_footprint for no_footprint_for_debug",
1214*19c3b8c2SApple OSS Distributions     T_META_LTEPHASE(LTE_POSTINIT))
1215*19c3b8c2SApple OSS Distributions {
1216*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_before, pagetable_before;
1217*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_after, pagetable_after;
1218*19c3b8c2SApple OSS Distributions 	uint64_t                footprint_expected;
1219*19c3b8c2SApple OSS Distributions 	kern_return_t           kr;
1220*19c3b8c2SApple OSS Distributions 	mach_vm_address_t       pre_vm_addr, vm_addr;
1221*19c3b8c2SApple OSS Distributions 	mach_vm_size_t          vm_size, dirty_size, me_size;
1222*19c3b8c2SApple OSS Distributions 	mach_port_t             me_port;
1223*19c3b8c2SApple OSS Distributions 	int                     new_value, ret;
1224*19c3b8c2SApple OSS Distributions 
1225*19c3b8c2SApple OSS Distributions 	/* pre-warm to account for page table expansion */
1226*19c3b8c2SApple OSS Distributions 	pre_vm_addr = pre_warm(MEM_SIZE);
1227*19c3b8c2SApple OSS Distributions 
1228*19c3b8c2SApple OSS Distributions 	/* making a memory entry... */
1229*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1230*19c3b8c2SApple OSS Distributions 	vm_size = MEM_SIZE;
1231*19c3b8c2SApple OSS Distributions 	me_size = vm_size;
1232*19c3b8c2SApple OSS Distributions 	me_port = MACH_PORT_NULL;
1233*19c3b8c2SApple OSS Distributions 	kr = mach_make_memory_entry_64(mach_task_self(),
1234*19c3b8c2SApple OSS Distributions 	    &me_size,
1235*19c3b8c2SApple OSS Distributions 	    0,
1236*19c3b8c2SApple OSS Distributions 	    (MAP_MEM_NAMED_CREATE |
1237*19c3b8c2SApple OSS Distributions 	    MAP_MEM_LEDGER_TAGGED |
1238*19c3b8c2SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE),
1239*19c3b8c2SApple OSS Distributions 	    &me_port,
1240*19c3b8c2SApple OSS Distributions 	    MACH_PORT_NULL);
1241*19c3b8c2SApple OSS Distributions 	T_QUIET;
1242*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "make_memory_entry() error 0x%x (%s)",
1243*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1244*19c3b8c2SApple OSS Distributions 	T_QUIET;
1245*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(me_size, vm_size, "memory entry size mismatch");
1246*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
1247*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1248*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1249*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1250*19c3b8c2SApple OSS Distributions 	T_LOG("making a memory entry does not change phys_footprint");
1251*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1252*19c3b8c2SApple OSS Distributions 	    "making a memory entry of %lld bytes: "
1253*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1254*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
1255*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1256*19c3b8c2SApple OSS Distributions 
1257*19c3b8c2SApple OSS Distributions 	/* trying to hide debug memory from footprint while not allowed */
1258*19c3b8c2SApple OSS Distributions 	kr = mach_memory_entry_ownership(me_port,
1259*19c3b8c2SApple OSS Distributions 	    mach_task_self(),
1260*19c3b8c2SApple OSS Distributions 	    VM_LEDGER_TAG_DEFAULT,
1261*19c3b8c2SApple OSS Distributions 	    VM_LEDGER_FLAG_NO_FOOTPRINT_FOR_DEBUG);
1262*19c3b8c2SApple OSS Distributions 	T_QUIET;
1263*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_NO_ACCESS,
1264*19c3b8c2SApple OSS Distributions 	    "mach_memory_entry_ownership(NO_FOOTPRINT_FOR_DEBUG) fails without sysctl");
1265*19c3b8c2SApple OSS Distributions 
1266*19c3b8c2SApple OSS Distributions 	/* let's get permission to hide debug memory */
1267*19c3b8c2SApple OSS Distributions 	new_value = 1;
1268*19c3b8c2SApple OSS Distributions 	ret = sysctlbyname("vm.task_no_footprint_for_debug", NULL, NULL, &new_value, sizeof(new_value));
1269*19c3b8c2SApple OSS Distributions 	if (ret == -1 && errno == ENOENT) {
1270*19c3b8c2SApple OSS Distributions 		T_SKIP("sysctlbyname(vm.task_no_footprint_for_debug) ENOENT");
1271*19c3b8c2SApple OSS Distributions 	}
1272*19c3b8c2SApple OSS Distributions 	T_QUIET;
1273*19c3b8c2SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "sysctlbyname(vm.task_no_footprint_for_debug)");
1274*19c3b8c2SApple OSS Distributions 
1275*19c3b8c2SApple OSS Distributions 	/* trying to hide debug memory from footprint while allowed */
1276*19c3b8c2SApple OSS Distributions 	task_id_token_t token;
1277*19c3b8c2SApple OSS Distributions 	kr = task_create_identity_token(mach_task_self(), &token);
1278*19c3b8c2SApple OSS Distributions 	T_QUIET;
1279*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ(kr, KERN_SUCCESS,
1280*19c3b8c2SApple OSS Distributions 	    "task_create_identity_token");
1281*19c3b8c2SApple OSS Distributions 
1282*19c3b8c2SApple OSS Distributions 	kr = mach_memory_entry_ownership(me_port,
1283*19c3b8c2SApple OSS Distributions 	    token, /* this time also try calling it with id token */
1284*19c3b8c2SApple OSS Distributions 	    VM_LEDGER_TAG_DEFAULT,
1285*19c3b8c2SApple OSS Distributions 	    VM_LEDGER_FLAG_NO_FOOTPRINT_FOR_DEBUG);
1286*19c3b8c2SApple OSS Distributions 	T_QUIET;
1287*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS,
1288*19c3b8c2SApple OSS Distributions 	    "mach_memory_entry_ownership(NO_FOOTPRINT_FOR_DEBUG) succeeds after sysctl");
1289*19c3b8c2SApple OSS Distributions 	mach_port_deallocate(mach_task_self(), token);
1290*19c3b8c2SApple OSS Distributions 
1291*19c3b8c2SApple OSS Distributions 	/* mapping ledger-tagged virtual memory... */
1292*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1293*19c3b8c2SApple OSS Distributions 	vm_addr = 0;
1294*19c3b8c2SApple OSS Distributions 	kr = mach_vm_map(mach_task_self(), &vm_addr, vm_size,
1295*19c3b8c2SApple OSS Distributions 	    0, /* mask */
1296*19c3b8c2SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
1297*19c3b8c2SApple OSS Distributions 	    me_port,
1298*19c3b8c2SApple OSS Distributions 	    0, /* offset */
1299*19c3b8c2SApple OSS Distributions 	    FALSE, /* copy */
1300*19c3b8c2SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1301*19c3b8c2SApple OSS Distributions 	    VM_PROT_READ | VM_PROT_WRITE,
1302*19c3b8c2SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1303*19c3b8c2SApple OSS Distributions 	T_QUIET;
1304*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_map() error 0x%x (%s)",
1305*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1306*19c3b8c2SApple OSS Distributions 	T_QUIET;
1307*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
1308*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
1309*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1310*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1311*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1312*19c3b8c2SApple OSS Distributions 	T_LOG("mapping ledger-tagged memory does not change phys_footprint");
1313*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1314*19c3b8c2SApple OSS Distributions 	    "ledger-tagged mapping of %lld bytes: "
1315*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1316*19c3b8c2SApple OSS Distributions 	    vm_size, footprint_before, footprint_after,
1317*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1318*19c3b8c2SApple OSS Distributions 
1319*19c3b8c2SApple OSS Distributions 	/* touching memory... */
1320*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1321*19c3b8c2SApple OSS Distributions 	dirty_size = vm_size / 2;
1322*19c3b8c2SApple OSS Distributions 	memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
1323*19c3b8c2SApple OSS Distributions 	/* ... should not increase footprint */
1324*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1325*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1326*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1327*19c3b8c2SApple OSS Distributions 	T_LOG("modifying no_footprint_for_debug memory does not increase phys_footprint");
1328*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1329*19c3b8c2SApple OSS Distributions 	    "touched %lld bytes: "
1330*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1331*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1332*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1333*19c3b8c2SApple OSS Distributions 
1334*19c3b8c2SApple OSS Distributions 	/* deallocating memory while holding memory entry... */
1335*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1336*19c3b8c2SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
1337*19c3b8c2SApple OSS Distributions 	T_QUIET;
1338*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
1339*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1340*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
1341*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1342*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1343*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1344*19c3b8c2SApple OSS Distributions 	T_LOG("deallocating owned memory while holding memory entry "
1345*19c3b8c2SApple OSS Distributions 	    "does not change phys_footprint");
1346*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1347*19c3b8c2SApple OSS Distributions 	    "deallocated %lld dirty bytes: "
1348*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1349*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1350*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1351*19c3b8c2SApple OSS Distributions 
1352*19c3b8c2SApple OSS Distributions 	/* releasing the memory entry... */
1353*19c3b8c2SApple OSS Distributions 	kr = mach_port_deallocate(mach_task_self(), me_port);
1354*19c3b8c2SApple OSS Distributions 	T_QUIET;
1355*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "mach_port_deallocate() error 0x%x (%s)",
1356*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1357*19c3b8c2SApple OSS Distributions 	/* ... should not change footprint */
1358*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1359*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1360*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1361*19c3b8c2SApple OSS Distributions 	T_LOG("releasing memory entry does not change phys_footprint");
1362*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1363*19c3b8c2SApple OSS Distributions 	    "made volatile %lld dirty bytes: "
1364*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1365*19c3b8c2SApple OSS Distributions 	    dirty_size, footprint_before, footprint_after,
1366*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1367*19c3b8c2SApple OSS Distributions }
1368*19c3b8c2SApple OSS Distributions #endif /* MAP_MEM_LEDGER_TAGGED */
1369*19c3b8c2SApple OSS Distributions 
1370*19c3b8c2SApple OSS Distributions /* IOSurface code from: CoreImage/CoreImageTests/CIRender/SurfaceUtils.c */
1371*19c3b8c2SApple OSS Distributions #include <CoreFoundation/CoreFoundation.h>
1372*19c3b8c2SApple OSS Distributions #include <IOSurface/IOSurface.h>
1373*19c3b8c2SApple OSS Distributions #include <IOSurface/IOSurfacePrivate.h>
1374*19c3b8c2SApple OSS Distributions static size_t
bytes_per_element(uint32_t format)1375*19c3b8c2SApple OSS Distributions bytes_per_element(uint32_t format)
1376*19c3b8c2SApple OSS Distributions {
1377*19c3b8c2SApple OSS Distributions 	size_t bpe = 0;
1378*19c3b8c2SApple OSS Distributions 	switch (format) {
1379*19c3b8c2SApple OSS Distributions 	case 32:     // kCVPixelFormatType_32ARGB (ARGB8)
1380*19c3b8c2SApple OSS Distributions 		bpe = 4;
1381*19c3b8c2SApple OSS Distributions 		break;
1382*19c3b8c2SApple OSS Distributions 	default:
1383*19c3b8c2SApple OSS Distributions 		bpe = 0;
1384*19c3b8c2SApple OSS Distributions 		break;
1385*19c3b8c2SApple OSS Distributions 	}
1386*19c3b8c2SApple OSS Distributions 	return bpe;
1387*19c3b8c2SApple OSS Distributions }
1388*19c3b8c2SApple OSS Distributions static size_t
bytes_per_pixel(uint32_t format)1389*19c3b8c2SApple OSS Distributions bytes_per_pixel(uint32_t format)
1390*19c3b8c2SApple OSS Distributions {
1391*19c3b8c2SApple OSS Distributions 	size_t bpe = 0;
1392*19c3b8c2SApple OSS Distributions 	switch (format) {
1393*19c3b8c2SApple OSS Distributions 	case 32:     // kCVPixelFormatType_32ARGB (ARGB8)
1394*19c3b8c2SApple OSS Distributions 		bpe = 4;
1395*19c3b8c2SApple OSS Distributions 		break;
1396*19c3b8c2SApple OSS Distributions 	default:
1397*19c3b8c2SApple OSS Distributions 		bpe = 0;
1398*19c3b8c2SApple OSS Distributions 		break;
1399*19c3b8c2SApple OSS Distributions 	}
1400*19c3b8c2SApple OSS Distributions 	return bpe;
1401*19c3b8c2SApple OSS Distributions }
1402*19c3b8c2SApple OSS Distributions static inline size_t
roundSizeToMultiple(size_t size,size_t mult)1403*19c3b8c2SApple OSS Distributions roundSizeToMultiple(size_t size, size_t mult)
1404*19c3b8c2SApple OSS Distributions {
1405*19c3b8c2SApple OSS Distributions 	return ((size + mult - 1) / mult) * mult;
1406*19c3b8c2SApple OSS Distributions }
1407*19c3b8c2SApple OSS Distributions static inline void
setIntValue(CFMutableDictionaryRef dict,const CFStringRef key,int value)1408*19c3b8c2SApple OSS Distributions setIntValue(CFMutableDictionaryRef dict, const CFStringRef key, int value)
1409*19c3b8c2SApple OSS Distributions {
1410*19c3b8c2SApple OSS Distributions 	CFNumberRef number = CFNumberCreate(0, kCFNumberIntType, &value);
1411*19c3b8c2SApple OSS Distributions 	CFDictionarySetValue(dict, key, number);
1412*19c3b8c2SApple OSS Distributions 	CFRelease(number);
1413*19c3b8c2SApple OSS Distributions }
1414*19c3b8c2SApple OSS Distributions static inline void
setBoolValue(CFMutableDictionaryRef dict,const CFStringRef key,bool value)1415*19c3b8c2SApple OSS Distributions setBoolValue(CFMutableDictionaryRef dict, const CFStringRef key, bool value)
1416*19c3b8c2SApple OSS Distributions {
1417*19c3b8c2SApple OSS Distributions 	CFDictionarySetValue(dict, key, value ? kCFBooleanTrue : kCFBooleanFalse);
1418*19c3b8c2SApple OSS Distributions }
1419*19c3b8c2SApple OSS Distributions typedef void (^SurfacePlaneBlock)(void *data, size_t planeIndex, size_t width, size_t height, size_t rowbytes);
1420*19c3b8c2SApple OSS Distributions static IOReturn
SurfaceApplyPlaneBlock(IOSurfaceRef surface,SurfacePlaneBlock block)1421*19c3b8c2SApple OSS Distributions SurfaceApplyPlaneBlock(IOSurfaceRef surface, SurfacePlaneBlock block)
1422*19c3b8c2SApple OSS Distributions {
1423*19c3b8c2SApple OSS Distributions 	if (surface == nil || block == nil) {
1424*19c3b8c2SApple OSS Distributions 		return kIOReturnBadArgument;
1425*19c3b8c2SApple OSS Distributions 	}
1426*19c3b8c2SApple OSS Distributions 
1427*19c3b8c2SApple OSS Distributions 	IOReturn result = kIOReturnSuccess;
1428*19c3b8c2SApple OSS Distributions 	size_t planeCount = IOSurfaceGetPlaneCount(surface);
1429*19c3b8c2SApple OSS Distributions 
1430*19c3b8c2SApple OSS Distributions 	if (planeCount == 0) {
1431*19c3b8c2SApple OSS Distributions 		result = IOSurfaceLock(surface, 0, NULL);
1432*19c3b8c2SApple OSS Distributions 		if (result != kIOReturnSuccess) {
1433*19c3b8c2SApple OSS Distributions 			return result;
1434*19c3b8c2SApple OSS Distributions 		}
1435*19c3b8c2SApple OSS Distributions 
1436*19c3b8c2SApple OSS Distributions 		void* base = IOSurfaceGetBaseAddress(surface);
1437*19c3b8c2SApple OSS Distributions 		size_t rb = IOSurfaceGetBytesPerRow(surface);
1438*19c3b8c2SApple OSS Distributions 		size_t w = IOSurfaceGetWidth(surface);
1439*19c3b8c2SApple OSS Distributions 		size_t h = IOSurfaceGetHeight(surface);
1440*19c3b8c2SApple OSS Distributions 
1441*19c3b8c2SApple OSS Distributions 		if (base && rb && w && h) {
1442*19c3b8c2SApple OSS Distributions 			block(base, 0, w, h, rb);
1443*19c3b8c2SApple OSS Distributions 		}
1444*19c3b8c2SApple OSS Distributions 
1445*19c3b8c2SApple OSS Distributions 		IOSurfaceUnlock(surface, 0, NULL);
1446*19c3b8c2SApple OSS Distributions 	} else if (planeCount == 2) {
1447*19c3b8c2SApple OSS Distributions 		for (size_t i = 0; i < planeCount; i++) {
1448*19c3b8c2SApple OSS Distributions 			result = IOSurfaceLock(surface, 0, NULL);
1449*19c3b8c2SApple OSS Distributions 			if (result != kIOReturnSuccess) {
1450*19c3b8c2SApple OSS Distributions 				return result;
1451*19c3b8c2SApple OSS Distributions 			}
1452*19c3b8c2SApple OSS Distributions 
1453*19c3b8c2SApple OSS Distributions 			void* base = IOSurfaceGetBaseAddressOfPlane(surface, i);
1454*19c3b8c2SApple OSS Distributions 			size_t rb = IOSurfaceGetBytesPerRowOfPlane(surface, i);
1455*19c3b8c2SApple OSS Distributions 			size_t w = IOSurfaceGetWidthOfPlane(surface, i);
1456*19c3b8c2SApple OSS Distributions 			size_t h = IOSurfaceGetHeightOfPlane(surface, i);
1457*19c3b8c2SApple OSS Distributions 
1458*19c3b8c2SApple OSS Distributions 			if (base && rb && w && h) {
1459*19c3b8c2SApple OSS Distributions 				block(base, i, w, h, rb);
1460*19c3b8c2SApple OSS Distributions 			}
1461*19c3b8c2SApple OSS Distributions 
1462*19c3b8c2SApple OSS Distributions 			IOSurfaceUnlock(surface, 0, NULL);
1463*19c3b8c2SApple OSS Distributions 		}
1464*19c3b8c2SApple OSS Distributions 	}
1465*19c3b8c2SApple OSS Distributions 	return result;
1466*19c3b8c2SApple OSS Distributions }
1467*19c3b8c2SApple OSS Distributions static void
ClearSurface(IOSurfaceRef surface)1468*19c3b8c2SApple OSS Distributions ClearSurface(IOSurfaceRef surface)
1469*19c3b8c2SApple OSS Distributions {
1470*19c3b8c2SApple OSS Distributions 	const int zero = 0;
1471*19c3b8c2SApple OSS Distributions 	(void) SurfaceApplyPlaneBlock(surface, ^(void *p, size_t i, __unused size_t w, size_t h, size_t rb)
1472*19c3b8c2SApple OSS Distributions 	{
1473*19c3b8c2SApple OSS Distributions 		if (i == 0) {
1474*19c3b8c2SApple OSS Distributions 		        memset(p, zero, rb * h);
1475*19c3b8c2SApple OSS Distributions 		} else {
1476*19c3b8c2SApple OSS Distributions 		        memset(p, 128, rb * h);
1477*19c3b8c2SApple OSS Distributions 		}
1478*19c3b8c2SApple OSS Distributions 	});
1479*19c3b8c2SApple OSS Distributions }
1480*19c3b8c2SApple OSS Distributions static size_t
SurfaceGetMemorySize(IOSurfaceRef surface)1481*19c3b8c2SApple OSS Distributions SurfaceGetMemorySize(IOSurfaceRef surface)
1482*19c3b8c2SApple OSS Distributions {
1483*19c3b8c2SApple OSS Distributions 	size_t planeCount = IOSurfaceGetPlaneCount(surface);
1484*19c3b8c2SApple OSS Distributions 
1485*19c3b8c2SApple OSS Distributions 	if (planeCount == 0) {
1486*19c3b8c2SApple OSS Distributions 		size_t rb = IOSurfaceGetBytesPerRow(surface);
1487*19c3b8c2SApple OSS Distributions 		size_t h = IOSurfaceGetHeight(surface);
1488*19c3b8c2SApple OSS Distributions 		return rb * h;
1489*19c3b8c2SApple OSS Distributions 	} else if (planeCount == 2) {
1490*19c3b8c2SApple OSS Distributions 		size_t rb0 = IOSurfaceGetBytesPerRowOfPlane(surface, 0);
1491*19c3b8c2SApple OSS Distributions 		size_t h0 = IOSurfaceGetHeightOfPlane(surface, 0);
1492*19c3b8c2SApple OSS Distributions 		size_t rb1 = IOSurfaceGetBytesPerRowOfPlane(surface, 1);
1493*19c3b8c2SApple OSS Distributions 		size_t h1 = IOSurfaceGetHeightOfPlane(surface, 1);
1494*19c3b8c2SApple OSS Distributions 		return rb0 * h0 + rb1 * h1;
1495*19c3b8c2SApple OSS Distributions 	}
1496*19c3b8c2SApple OSS Distributions 	return 0;
1497*19c3b8c2SApple OSS Distributions }
1498*19c3b8c2SApple OSS Distributions static IOSurfaceRef
CreateSurface(uint32_t pixelsWide,uint32_t pixelsHigh,uint32_t rowBytesAlignment,uint32_t fmt,bool purgeable,bool clear)1499*19c3b8c2SApple OSS Distributions CreateSurface(uint32_t pixelsWide, uint32_t pixelsHigh, uint32_t rowBytesAlignment, uint32_t fmt, bool purgeable, bool clear)
1500*19c3b8c2SApple OSS Distributions {
1501*19c3b8c2SApple OSS Distributions 	IOSurfaceRef surface = nil;
1502*19c3b8c2SApple OSS Distributions 
1503*19c3b8c2SApple OSS Distributions 	if (pixelsWide < 1 || pixelsHigh < 1 || fmt == 0) {
1504*19c3b8c2SApple OSS Distributions 		return nil;
1505*19c3b8c2SApple OSS Distributions 	}
1506*19c3b8c2SApple OSS Distributions 
1507*19c3b8c2SApple OSS Distributions 	size_t bpp = bytes_per_pixel(fmt);
1508*19c3b8c2SApple OSS Distributions 	size_t bpe = bytes_per_element(fmt);
1509*19c3b8c2SApple OSS Distributions 	if (bpp == 0 || bpe == 0) {
1510*19c3b8c2SApple OSS Distributions 		return nil;
1511*19c3b8c2SApple OSS Distributions 	}
1512*19c3b8c2SApple OSS Distributions 
1513*19c3b8c2SApple OSS Distributions 	size_t rowbytes = pixelsWide * bpp;
1514*19c3b8c2SApple OSS Distributions 	if (rowBytesAlignment == 0) {
1515*19c3b8c2SApple OSS Distributions 		rowBytesAlignment = 16;
1516*19c3b8c2SApple OSS Distributions 	}
1517*19c3b8c2SApple OSS Distributions 	rowbytes = roundSizeToMultiple(rowbytes, rowBytesAlignment);
1518*19c3b8c2SApple OSS Distributions 
1519*19c3b8c2SApple OSS Distributions 	CFMutableDictionaryRef props = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1520*19c3b8c2SApple OSS Distributions 	setIntValue(props, kIOSurfaceBytesPerRow, (int)rowbytes);
1521*19c3b8c2SApple OSS Distributions 	setIntValue(props, kIOSurfaceWidth, (int)pixelsWide);
1522*19c3b8c2SApple OSS Distributions 	setIntValue(props, kIOSurfaceHeight, (int)pixelsHigh);
1523*19c3b8c2SApple OSS Distributions 	setIntValue(props, kIOSurfacePixelFormat, (int)fmt);
1524*19c3b8c2SApple OSS Distributions #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
1525*19c3b8c2SApple OSS Distributions 	setBoolValue(props, kIOSurfaceNonPurgeable, !purgeable);
1526*19c3b8c2SApple OSS Distributions #else /* (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
1527*19c3b8c2SApple OSS Distributions 	(void)purgeable;
1528*19c3b8c2SApple OSS Distributions #endif /* (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
1529*19c3b8c2SApple OSS Distributions 	{
1530*19c3b8c2SApple OSS Distributions 		if (bpe != bpp) { // i.e. a 422 format such as 'yuvf' etc.
1531*19c3b8c2SApple OSS Distributions 			setIntValue(props, kIOSurfaceElementWidth, 2);
1532*19c3b8c2SApple OSS Distributions 			setIntValue(props, kIOSurfaceElementHeight, 1);
1533*19c3b8c2SApple OSS Distributions 		}
1534*19c3b8c2SApple OSS Distributions 		setIntValue(props, kIOSurfaceBytesPerElement, (int)bpe);
1535*19c3b8c2SApple OSS Distributions 	}
1536*19c3b8c2SApple OSS Distributions 
1537*19c3b8c2SApple OSS Distributions 	surface = IOSurfaceCreate(props);
1538*19c3b8c2SApple OSS Distributions 
1539*19c3b8c2SApple OSS Distributions 	if (clear) {
1540*19c3b8c2SApple OSS Distributions 		ClearSurface(surface);
1541*19c3b8c2SApple OSS Distributions 	}
1542*19c3b8c2SApple OSS Distributions 
1543*19c3b8c2SApple OSS Distributions 	CFRelease(props);
1544*19c3b8c2SApple OSS Distributions 	return surface;
1545*19c3b8c2SApple OSS Distributions }
1546*19c3b8c2SApple OSS Distributions T_DECL(phys_footprint_purgeable_iokit,
1547*19c3b8c2SApple OSS Distributions     "phys_footprint for purgeable IOKit memory",
1548*19c3b8c2SApple OSS Distributions     T_META_LTEPHASE(LTE_POSTINIT))
1549*19c3b8c2SApple OSS Distributions {
1550*19c3b8c2SApple OSS Distributions 	uint64_t        footprint_before, pagetable_before;
1551*19c3b8c2SApple OSS Distributions 	uint64_t        footprint_after, pagetable_after;
1552*19c3b8c2SApple OSS Distributions 	uint64_t        footprint_expected, footprint_delta_slop;
1553*19c3b8c2SApple OSS Distributions 	int64_t         footprint_delta;
1554*19c3b8c2SApple OSS Distributions 	IOSurfaceRef    surface;
1555*19c3b8c2SApple OSS Distributions 	uint32_t        old_state;
1556*19c3b8c2SApple OSS Distributions 	uint64_t        surface_size;
1557*19c3b8c2SApple OSS Distributions 
1558*19c3b8c2SApple OSS Distributions 	T_SETUPBEGIN;
1559*19c3b8c2SApple OSS Distributions 	footprint_delta_slop = 8 * vm_kernel_page_size;
1560*19c3b8c2SApple OSS Distributions 	ledger_init();
1561*19c3b8c2SApple OSS Distributions 	surface = CreateSurface(1024, 1024, 0, 32, true, true);
1562*19c3b8c2SApple OSS Distributions 	IOSurfaceSetPurgeable(surface, kIOSurfacePurgeableVolatile, &old_state);
1563*19c3b8c2SApple OSS Distributions 	IOSurfaceSetPurgeable(surface, kIOSurfacePurgeableNonVolatile, &old_state);
1564*19c3b8c2SApple OSS Distributions 	CFRelease(surface);
1565*19c3b8c2SApple OSS Distributions 	T_SETUPEND;
1566*19c3b8c2SApple OSS Distributions 
1567*19c3b8c2SApple OSS Distributions 	surface_size = 1024 * 1024 * 4;
1568*19c3b8c2SApple OSS Distributions 
1569*19c3b8c2SApple OSS Distributions 	/* create IOsurface: footprint grows */
1570*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1571*19c3b8c2SApple OSS Distributions 	surface = CreateSurface(1024, 1024, 0, 32, true, true);
1572*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1573*19c3b8c2SApple OSS Distributions 	if (legacy_footprint) {
1574*19c3b8c2SApple OSS Distributions 		footprint_expected = footprint_before;
1575*19c3b8c2SApple OSS Distributions 		footprint_expected += (pagetable_after - pagetable_before);
1576*19c3b8c2SApple OSS Distributions 		footprint_delta = (int64_t)(footprint_after - footprint_expected);
1577*19c3b8c2SApple OSS Distributions 		T_LOG("LEGACY FOOTPRINT: creating purgeable IOSurface: no footprint impact");
1578*19c3b8c2SApple OSS Distributions 		T_EXPECT_LE((uint64_t)llabs(footprint_delta), footprint_delta_slop,
1579*19c3b8c2SApple OSS Distributions 		    "create purgeable IOSurface %lld bytes: "
1580*19c3b8c2SApple OSS Distributions 		    "footprint %lld -> %lld expected %lld delta %lld",
1581*19c3b8c2SApple OSS Distributions 		    surface_size, footprint_before, footprint_after,
1582*19c3b8c2SApple OSS Distributions 		    footprint_expected, footprint_delta);
1583*19c3b8c2SApple OSS Distributions 	} else {
1584*19c3b8c2SApple OSS Distributions 		footprint_expected = footprint_before + surface_size;
1585*19c3b8c2SApple OSS Distributions 		footprint_expected += (pagetable_after - pagetable_before);
1586*19c3b8c2SApple OSS Distributions 		footprint_delta = (int64_t)(footprint_after - footprint_expected);
1587*19c3b8c2SApple OSS Distributions 		T_LOG("creating purgeable IOSurface increases phys_footprint");
1588*19c3b8c2SApple OSS Distributions 		T_EXPECT_LE((uint64_t)llabs(footprint_delta), footprint_delta_slop,
1589*19c3b8c2SApple OSS Distributions 		    "create purgeable IOSurface %lld bytes: "
1590*19c3b8c2SApple OSS Distributions 		    "footprint %lld -> %lld expected %lld delta %lld",
1591*19c3b8c2SApple OSS Distributions 		    surface_size, footprint_before, footprint_after,
1592*19c3b8c2SApple OSS Distributions 		    footprint_expected, footprint_delta);
1593*19c3b8c2SApple OSS Distributions 	}
1594*19c3b8c2SApple OSS Distributions 
1595*19c3b8c2SApple OSS Distributions 	/* make IOSurface volatile: footprint shrinks */
1596*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1597*19c3b8c2SApple OSS Distributions 	IOSurfaceSetPurgeable(surface, kIOSurfacePurgeableVolatile, &old_state);
1598*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1599*19c3b8c2SApple OSS Distributions 	if (legacy_footprint) {
1600*19c3b8c2SApple OSS Distributions 		footprint_expected = footprint_before;
1601*19c3b8c2SApple OSS Distributions 		footprint_expected += (pagetable_after - pagetable_before);
1602*19c3b8c2SApple OSS Distributions 		T_LOG("LEGACY FOOTPRINT: volatile IOSurface: no footprint impact");
1603*19c3b8c2SApple OSS Distributions 		T_EXPECT_EQ(footprint_after, footprint_expected,
1604*19c3b8c2SApple OSS Distributions 		    "volatile IOSurface %lld bytes: "
1605*19c3b8c2SApple OSS Distributions 		    "footprint %lld -> %lld expected %lld delta %lld",
1606*19c3b8c2SApple OSS Distributions 		    surface_size, footprint_before, footprint_after,
1607*19c3b8c2SApple OSS Distributions 		    footprint_expected, footprint_after - footprint_expected);
1608*19c3b8c2SApple OSS Distributions 	} else {
1609*19c3b8c2SApple OSS Distributions 		footprint_expected = footprint_before - surface_size;
1610*19c3b8c2SApple OSS Distributions 		footprint_expected += (pagetable_after - pagetable_before);
1611*19c3b8c2SApple OSS Distributions 		T_LOG("making IOSurface volatile decreases phys_footprint");
1612*19c3b8c2SApple OSS Distributions 		T_EXPECT_EQ(footprint_after, footprint_expected,
1613*19c3b8c2SApple OSS Distributions 		    "made volatile %lld bytes: "
1614*19c3b8c2SApple OSS Distributions 		    "footprint %lld -> %lld expected %lld delta %lld",
1615*19c3b8c2SApple OSS Distributions 		    surface_size, footprint_before, footprint_after,
1616*19c3b8c2SApple OSS Distributions 		    footprint_expected, footprint_after - footprint_expected);
1617*19c3b8c2SApple OSS Distributions 	}
1618*19c3b8c2SApple OSS Distributions 
1619*19c3b8c2SApple OSS Distributions 	/* make IOSurface non-volatile: footprint grows */
1620*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1621*19c3b8c2SApple OSS Distributions 	IOSurfaceSetPurgeable(surface, kIOSurfacePurgeableNonVolatile, &old_state);
1622*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1623*19c3b8c2SApple OSS Distributions 	if (legacy_footprint) {
1624*19c3b8c2SApple OSS Distributions 		footprint_expected = footprint_before;
1625*19c3b8c2SApple OSS Distributions 		footprint_expected += (pagetable_after - pagetable_before);
1626*19c3b8c2SApple OSS Distributions 		T_LOG("LEGACY FOOTPRINT: non-volatile IOSurface: no footprint impact");
1627*19c3b8c2SApple OSS Distributions 		T_EXPECT_EQ(footprint_after, footprint_expected,
1628*19c3b8c2SApple OSS Distributions 		    "non-volatile IOSurface %lld bytes: "
1629*19c3b8c2SApple OSS Distributions 		    "footprint %lld -> %lld expected %lld delta %lld",
1630*19c3b8c2SApple OSS Distributions 		    surface_size, footprint_before, footprint_after,
1631*19c3b8c2SApple OSS Distributions 		    footprint_expected, footprint_after - footprint_expected);
1632*19c3b8c2SApple OSS Distributions 	} else {
1633*19c3b8c2SApple OSS Distributions 		footprint_expected = footprint_before + surface_size;
1634*19c3b8c2SApple OSS Distributions 		footprint_expected += (pagetable_after - pagetable_before);
1635*19c3b8c2SApple OSS Distributions 		T_LOG("making IOSurface non-volatile increases phys_footprint");
1636*19c3b8c2SApple OSS Distributions 		T_EXPECT_EQ(footprint_after, footprint_expected,
1637*19c3b8c2SApple OSS Distributions 		    "made non-volatile %lld bytes: "
1638*19c3b8c2SApple OSS Distributions 		    "footprint %lld -> %lld expected %lld delta %lld",
1639*19c3b8c2SApple OSS Distributions 		    surface_size, footprint_before, footprint_after,
1640*19c3b8c2SApple OSS Distributions 		    footprint_expected, footprint_after - footprint_expected);
1641*19c3b8c2SApple OSS Distributions 	}
1642*19c3b8c2SApple OSS Distributions 
1643*19c3b8c2SApple OSS Distributions 	/* accessing IOSurface re-mapping: no footprint impact */
1644*19c3b8c2SApple OSS Distributions 
1645*19c3b8c2SApple OSS Distributions 	/* deallocating IOSurface re-mapping: no footprint impact */
1646*19c3b8c2SApple OSS Distributions 
1647*19c3b8c2SApple OSS Distributions 	/* release IOSurface: footprint shrinks */
1648*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1649*19c3b8c2SApple OSS Distributions 	CFRelease(surface);
1650*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1651*19c3b8c2SApple OSS Distributions 	if (legacy_footprint) {
1652*19c3b8c2SApple OSS Distributions 		footprint_expected = footprint_before;
1653*19c3b8c2SApple OSS Distributions 		footprint_expected += (pagetable_after - pagetable_before);
1654*19c3b8c2SApple OSS Distributions 		T_LOG("LEGACY FOOTPRINT: release IOSurface: no footprint impact");
1655*19c3b8c2SApple OSS Distributions 		T_EXPECT_EQ(footprint_after, footprint_expected,
1656*19c3b8c2SApple OSS Distributions 		    "releasing IOSurface %lld bytes: "
1657*19c3b8c2SApple OSS Distributions 		    "footprint %lld -> %lld expected %lld delta %lld",
1658*19c3b8c2SApple OSS Distributions 		    surface_size, footprint_before, footprint_after,
1659*19c3b8c2SApple OSS Distributions 		    footprint_expected, footprint_after - footprint_expected);
1660*19c3b8c2SApple OSS Distributions 	} else {
1661*19c3b8c2SApple OSS Distributions 		footprint_expected = footprint_before - surface_size;
1662*19c3b8c2SApple OSS Distributions 		footprint_expected += (pagetable_after - pagetable_before);
1663*19c3b8c2SApple OSS Distributions 		T_LOG("releasing IOSurface decreases phys_footprint");
1664*19c3b8c2SApple OSS Distributions 		T_EXPECT_EQ(footprint_after, footprint_expected,
1665*19c3b8c2SApple OSS Distributions 		    "released IOSurface %lld bytes: "
1666*19c3b8c2SApple OSS Distributions 		    "footprint %lld -> %lld expected %lld delta %lld",
1667*19c3b8c2SApple OSS Distributions 		    surface_size, footprint_before, footprint_after,
1668*19c3b8c2SApple OSS Distributions 		    footprint_expected, footprint_after - footprint_expected);
1669*19c3b8c2SApple OSS Distributions 	}
1670*19c3b8c2SApple OSS Distributions }
1671*19c3b8c2SApple OSS Distributions 
1672*19c3b8c2SApple OSS Distributions #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
1673*19c3b8c2SApple OSS Distributions T_DECL(phys_footprint_nonpurgeable_iokit,
1674*19c3b8c2SApple OSS Distributions     "phys_footprint for non-purgeable IOKit memory",
1675*19c3b8c2SApple OSS Distributions     T_META_LTEPHASE(LTE_POSTINIT))
1676*19c3b8c2SApple OSS Distributions {
1677*19c3b8c2SApple OSS Distributions 	uint64_t        footprint_before, pagetable_before;
1678*19c3b8c2SApple OSS Distributions 	uint64_t        footprint_after, pagetable_after;
1679*19c3b8c2SApple OSS Distributions 	uint64_t        footprint_expected, footprint_delta_slop;
1680*19c3b8c2SApple OSS Distributions 	int64_t         footprint_delta;
1681*19c3b8c2SApple OSS Distributions 	IOSurfaceRef    surface;
1682*19c3b8c2SApple OSS Distributions 	uint64_t        surface_size;
1683*19c3b8c2SApple OSS Distributions 	void            *map_base;
1684*19c3b8c2SApple OSS Distributions 	size_t          map_size;
1685*19c3b8c2SApple OSS Distributions 	mach_vm_address_t remap_addr;
1686*19c3b8c2SApple OSS Distributions 	kern_return_t kr;
1687*19c3b8c2SApple OSS Distributions 	vm_prot_t       cur_prot, max_prot;
1688*19c3b8c2SApple OSS Distributions 	uint32_t        old_state;
1689*19c3b8c2SApple OSS Distributions 
1690*19c3b8c2SApple OSS Distributions 
1691*19c3b8c2SApple OSS Distributions 	T_SETUPBEGIN;
1692*19c3b8c2SApple OSS Distributions 	ledger_init();
1693*19c3b8c2SApple OSS Distributions 	surface = CreateSurface(1024, 1024, 0, 32, false, true);
1694*19c3b8c2SApple OSS Distributions 	CFRelease(surface);
1695*19c3b8c2SApple OSS Distributions 	footprint_delta_slop = 8 * vm_kernel_page_size;
1696*19c3b8c2SApple OSS Distributions 	T_SETUPEND;
1697*19c3b8c2SApple OSS Distributions 
1698*19c3b8c2SApple OSS Distributions 	surface_size = 1024 * 1024 * 4;
1699*19c3b8c2SApple OSS Distributions 
1700*19c3b8c2SApple OSS Distributions 	/* create IOsurface: footprint grows */
1701*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1702*19c3b8c2SApple OSS Distributions 	surface = CreateSurface(1024, 1024, 0, 32, false, true);
1703*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1704*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + surface_size;
1705*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1706*19c3b8c2SApple OSS Distributions 	footprint_delta = (int64_t)(footprint_after - footprint_expected);
1707*19c3b8c2SApple OSS Distributions 	T_LOG("creating non-purgeable IOSurface increases phys_footprint");
1708*19c3b8c2SApple OSS Distributions 	T_EXPECT_LE((uint64_t)llabs(footprint_delta), footprint_delta_slop,
1709*19c3b8c2SApple OSS Distributions 	    "create non-purgeable IOSurface %lld bytes: "
1710*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1711*19c3b8c2SApple OSS Distributions 	    surface_size, footprint_before, footprint_after,
1712*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_delta);
1713*19c3b8c2SApple OSS Distributions 
1714*19c3b8c2SApple OSS Distributions 	/* make IOSurface volatile: fail and no footprint impact */
1715*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1716*19c3b8c2SApple OSS Distributions 	IOSurfaceSetPurgeable(surface, kIOSurfacePurgeableVolatile, &old_state);
1717*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1718*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1719*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1720*19c3b8c2SApple OSS Distributions 	T_LOG("making non-purgeable IOSurface volatile: no footprint impact");
1721*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1722*19c3b8c2SApple OSS Distributions 	    "made volatile %lld non-purgeable bytes: "
1723*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1724*19c3b8c2SApple OSS Distributions 	    surface_size, footprint_before, footprint_after,
1725*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1726*19c3b8c2SApple OSS Distributions 
1727*19c3b8c2SApple OSS Distributions 	/* re-mapping IOSurface: no footprint impact */
1728*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1729*19c3b8c2SApple OSS Distributions 	map_base = IOSurfaceGetBaseAddress(surface);
1730*19c3b8c2SApple OSS Distributions 	map_size = SurfaceGetMemorySize(surface);
1731*19c3b8c2SApple OSS Distributions //	T_EXPECT_EQ(map_size, surface_size, "map_size %lld surface_size %lld",
1732*19c3b8c2SApple OSS Distributions //		    map_size, surface_size);
1733*19c3b8c2SApple OSS Distributions 	remap_addr = 0;
1734*19c3b8c2SApple OSS Distributions 	kr = mach_vm_remap(mach_task_self(),
1735*19c3b8c2SApple OSS Distributions 	    &remap_addr,
1736*19c3b8c2SApple OSS Distributions 	    (mach_vm_size_t)surface_size,
1737*19c3b8c2SApple OSS Distributions 	    0,
1738*19c3b8c2SApple OSS Distributions 	    VM_FLAGS_ANYWHERE,
1739*19c3b8c2SApple OSS Distributions 	    mach_task_self(),
1740*19c3b8c2SApple OSS Distributions 	    (mach_vm_address_t)map_base,
1741*19c3b8c2SApple OSS Distributions 	    FALSE,                /* copy */
1742*19c3b8c2SApple OSS Distributions 	    &cur_prot,
1743*19c3b8c2SApple OSS Distributions 	    &max_prot,
1744*19c3b8c2SApple OSS Distributions 	    VM_INHERIT_DEFAULT);
1745*19c3b8c2SApple OSS Distributions 	T_QUIET;
1746*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_remap() error 0x%x (%s)",
1747*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1748*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1749*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before;
1750*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1751*19c3b8c2SApple OSS Distributions 	T_LOG("re-mapping IOSurface does not impact phys_footprint");
1752*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1753*19c3b8c2SApple OSS Distributions 	    "remapping IOSurface %lld bytes: "
1754*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1755*19c3b8c2SApple OSS Distributions 	    surface_size, footprint_before, footprint_after,
1756*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1757*19c3b8c2SApple OSS Distributions 
1758*19c3b8c2SApple OSS Distributions 	/* accessing IOSurface re-mapping: footprint grows */
1759*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1760*19c3b8c2SApple OSS Distributions 	memset((char *)(uintptr_t)remap_addr, 'p', (size_t)surface_size);
1761*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1762*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before + surface_size;
1763*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1764*19c3b8c2SApple OSS Distributions 	T_LOG("accessing re-mapped IOSurface grows phys_footprint");
1765*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1766*19c3b8c2SApple OSS Distributions 	    "accessing remapped IOSurface %lld bytes: "
1767*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1768*19c3b8c2SApple OSS Distributions 	    surface_size, footprint_before, footprint_after,
1769*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1770*19c3b8c2SApple OSS Distributions 
1771*19c3b8c2SApple OSS Distributions 	/* deallocating IOSurface re-mapping: footprint shrinks */
1772*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1773*19c3b8c2SApple OSS Distributions 	kr = mach_vm_deallocate(mach_task_self(),
1774*19c3b8c2SApple OSS Distributions 	    remap_addr,
1775*19c3b8c2SApple OSS Distributions 	    (mach_vm_size_t)surface_size);
1776*19c3b8c2SApple OSS Distributions 	T_QUIET;
1777*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
1778*19c3b8c2SApple OSS Distributions 	    kr, mach_error_string(kr));
1779*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1780*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - surface_size;
1781*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1782*19c3b8c2SApple OSS Distributions 	T_LOG("deallocating re-mapping of IOSurface shrinks phys_footprint");
1783*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1784*19c3b8c2SApple OSS Distributions 	    "deallocating remapped IOSurface %lld bytes: "
1785*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1786*19c3b8c2SApple OSS Distributions 	    surface_size, footprint_before, footprint_after,
1787*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1788*19c3b8c2SApple OSS Distributions 
1789*19c3b8c2SApple OSS Distributions 	/* release IOSurface: footprint shrinks */
1790*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_before, &pagetable_before);
1791*19c3b8c2SApple OSS Distributions 	CFRelease(surface);
1792*19c3b8c2SApple OSS Distributions 	get_ledger_info(&footprint_after, &pagetable_after);
1793*19c3b8c2SApple OSS Distributions 	footprint_expected = footprint_before - surface_size;
1794*19c3b8c2SApple OSS Distributions 	footprint_expected += (pagetable_after - pagetable_before);
1795*19c3b8c2SApple OSS Distributions 	T_LOG("releasing IOSurface decreases phys_footprint");
1796*19c3b8c2SApple OSS Distributions 	T_EXPECT_EQ(footprint_after, footprint_expected,
1797*19c3b8c2SApple OSS Distributions 	    "released IOSurface %lld bytes: "
1798*19c3b8c2SApple OSS Distributions 	    "footprint %lld -> %lld expected %lld delta %lld",
1799*19c3b8c2SApple OSS Distributions 	    surface_size, footprint_before, footprint_after,
1800*19c3b8c2SApple OSS Distributions 	    footprint_expected, footprint_after - footprint_expected);
1801*19c3b8c2SApple OSS Distributions }
1802*19c3b8c2SApple OSS Distributions #endif /* (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
1803*19c3b8c2SApple OSS Distributions 
1804*19c3b8c2SApple OSS Distributions #if 0
1805*19c3b8c2SApple OSS Distributions #if LEGACY_FOOTPRINT_ENTITLED && defined(__arm64__)
1806*19c3b8c2SApple OSS Distributions T_DECL(legacy_footprint_entitled_set_and_query,
1807*19c3b8c2SApple OSS Distributions     "legacy footprint entitled is sticky with memlimit set properties and can be queried",
1808*19c3b8c2SApple OSS Distributions     T_META_BOOTARGS_SET("legacy_footprint_entitlement_mode=3"))
1809*19c3b8c2SApple OSS Distributions {
1810*19c3b8c2SApple OSS Distributions 	int ret;
1811*19c3b8c2SApple OSS Distributions 	int32_t max_task_pmem = 0, legacy_footprint_bonus_mb = 0;
1812*19c3b8c2SApple OSS Distributions 	size_t size_max_task_pmem = sizeof(max_task_pmem);
1813*19c3b8c2SApple OSS Distributions 	size_t size_legacy_footprint_bonus_mb = sizeof(legacy_footprint_bonus_mb);
1814*19c3b8c2SApple OSS Distributions 	memorystatus_memlimit_properties2_t mmprops;
1815*19c3b8c2SApple OSS Distributions 
1816*19c3b8c2SApple OSS Distributions 	/* Get the default limit */
1817*19c3b8c2SApple OSS Distributions 	ret = sysctlbyname("kern.max_task_pmem", &max_task_pmem, &size_max_task_pmem, NULL, 0);
1818*19c3b8c2SApple OSS Distributions 	T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "call sysctlbyname to get max task physical memory.");
1819*19c3b8c2SApple OSS Distributions 
1820*19c3b8c2SApple OSS Distributions 	ret = sysctlbyname("kern.legacy_footprint_bonus_mb", &legacy_footprint_bonus_mb,
1821*19c3b8c2SApple OSS Distributions 	    &size_legacy_footprint_bonus_mb, NULL, 0);
1822*19c3b8c2SApple OSS Distributions 	T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "call sysctlbyname to get the bonus value.");
1823*19c3b8c2SApple OSS Distributions 
1824*19c3b8c2SApple OSS Distributions 	mmprops.v1.memlimit_active = -1;
1825*19c3b8c2SApple OSS Distributions 	mmprops.v1.memlimit_inactive = -1;
1826*19c3b8c2SApple OSS Distributions 	ret = memorystatus_control(MEMORYSTATUS_CMD_SET_MEMLIMIT_PROPERTIES, getpid(), 0, &mmprops.v1, sizeof(mmprops.v1));
1827*19c3b8c2SApple OSS Distributions 	T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "memorystatus_control");
1828*19c3b8c2SApple OSS Distributions 
1829*19c3b8c2SApple OSS Distributions 	/* Check our memlimt */
1830*19c3b8c2SApple OSS Distributions 	ret = memorystatus_control(MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES, getpid(), 0, &mmprops, sizeof(mmprops));
1831*19c3b8c2SApple OSS Distributions 	T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "memorystatus_control");
1832*19c3b8c2SApple OSS Distributions 
1833*19c3b8c2SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(mmprops.v1.memlimit_active, max_task_pmem + legacy_footprint_bonus_mb, "active limit");
1834*19c3b8c2SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(mmprops.v1.memlimit_inactive, max_task_pmem + legacy_footprint_bonus_mb, "inactive limit");
1835*19c3b8c2SApple OSS Distributions 
1836*19c3b8c2SApple OSS Distributions 	/* Verify MEMORYSTATUS_CMD_CONVERT_MEMLIMIT_MB */
1837*19c3b8c2SApple OSS Distributions 	ret = memorystatus_control(MEMORYSTATUS_CMD_CONVERT_MEMLIMIT_MB, getpid(), (uint32_t) -1, NULL, 0);
1838*19c3b8c2SApple OSS Distributions 	T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "memorystatus_control");
1839*19c3b8c2SApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(ret, max_task_pmem + legacy_footprint_bonus_mb, "got bonus adjustment");
1840*19c3b8c2SApple OSS Distributions }
1841*19c3b8c2SApple OSS Distributions #endif /* LEGACY_FOOTPRINT_ENTITLED && defined(__arm64__) */
1842*19c3b8c2SApple OSS Distributions #endif
1843