1 #include <unistd.h> 2 #include <errno.h> 3 4 #include <vm_statistics.h> 5 #include <mach/mach.h> 6 #include <mach_debug/mach_debug.h> 7 8 #include <darwintest.h> 9 10 /* 11 * Ensure that mach_memory_info includes a counter for the kernelcache size. 12 */ 13 14 T_GLOBAL_META( 15 T_META_NAMESPACE("xnu.vm"), 16 T_META_RADAR_COMPONENT_NAME("xnu"), 17 T_META_RADAR_COMPONENT_VERSION("VM")); 18 19 T_DECL(vm_kern_count_wired_kernelcache, 20 "mach_memory_info returns a counter for for kernelcache", 21 T_META_ASROOT(true), T_META_TAG_VM_PREFERRED) 22 { 23 kern_return_t kr; 24 uint64_t i; 25 mach_zone_name_t *name = NULL; 26 unsigned int nameCnt = 0; 27 mach_zone_info_t *info = NULL; 28 unsigned int infoCnt = 0; 29 mach_memory_info_t *wiredInfo = NULL; 30 unsigned int wiredInfoCnt = 0; 31 32 kr = mach_memory_info(mach_host_self(), &name, &nameCnt, &info, &infoCnt, 33 &wiredInfo, &wiredInfoCnt); 34 T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_memory_info"); 35 36 bool found_kernelcache_counter = false; 37 uint64_t static_kernelcache_size = 0; 38 uint64_t wired_memory_boot = 0; 39 for (i = 0; i < wiredInfoCnt; i++) { 40 const mach_memory_info_t *curr = &wiredInfo[i]; 41 uint32_t type = curr->flags & VM_KERN_SITE_TYPE; 42 if (type == VM_KERN_SITE_COUNTER) { 43 if (curr->site == VM_KERN_COUNT_WIRED_STATIC_KERNELCACHE) { 44 found_kernelcache_counter = true; 45 static_kernelcache_size = curr->size; 46 } else if (curr->site == VM_KERN_COUNT_WIRED_BOOT) { 47 wired_memory_boot = curr->size; 48 } 49 } 50 } 51 T_QUIET; T_ASSERT_TRUE(found_kernelcache_counter, "mach_memory_info returned kernelcache counter."); 52 // Sanity check that the counter isn't 0. 53 T_QUIET; T_ASSERT_GT(static_kernelcache_size, 0ULL, "kernelcache counter > 0"); 54 // Sanity check that the counter is less than the amount of wired memory 55 // at boot. 56 T_QUIET; T_ASSERT_LE(static_kernelcache_size, wired_memory_boot, "kernelcache counter <= VM_KERN_COUNT_WIRED_BOOT"); 57 58 // Cleanup 59 if ((name != NULL) && (nameCnt != 0)) { 60 kr = vm_deallocate(mach_task_self(), (vm_address_t) name, 61 (vm_size_t) (nameCnt * sizeof *name)); 62 T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate name"); 63 } 64 65 if ((info != NULL) && (infoCnt != 0)) { 66 kr = vm_deallocate(mach_task_self(), (vm_address_t) info, 67 (vm_size_t) (infoCnt * sizeof *info)); 68 T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate info"); 69 } 70 71 if ((wiredInfo != NULL) && (wiredInfoCnt != 0)) { 72 kr = vm_deallocate(mach_task_self(), (vm_address_t) wiredInfo, 73 (vm_size_t) (wiredInfoCnt * sizeof *wiredInfo)); 74 T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate wiredInfo"); 75 } 76 } 77