1*4f1223e8SApple OSS Distributions #include <darwintest.h> 2*4f1223e8SApple OSS Distributions 3*4f1223e8SApple OSS Distributions #include <errno.h> 4*4f1223e8SApple OSS Distributions #include <stdio.h> 5*4f1223e8SApple OSS Distributions #include <stdlib.h> 6*4f1223e8SApple OSS Distributions #include <string.h> 7*4f1223e8SApple OSS Distributions 8*4f1223e8SApple OSS Distributions #include <sys/mman.h> 9*4f1223e8SApple OSS Distributions 10*4f1223e8SApple OSS Distributions #include <mach/mach_error.h> 11*4f1223e8SApple OSS Distributions #include <mach/mach_init.h> 12*4f1223e8SApple OSS Distributions #include <mach/mach_vm.h> 13*4f1223e8SApple OSS Distributions 14*4f1223e8SApple OSS Distributions #define ANON_MAX_PAGES 0xFFFFFFFFULL 15*4f1223e8SApple OSS Distributions #define ANON_MAX_SIZE (ANON_MAX_PAGES * vm_kernel_page_size) 16*4f1223e8SApple OSS Distributions 17*4f1223e8SApple OSS Distributions T_DECL(anon_max_size, "Test an ALLOC_MAX_SIZE allocation", 18*4f1223e8SApple OSS Distributions T_META_NAMESPACE("xnu.vm"), 19*4f1223e8SApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"), 20*4f1223e8SApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("VM"), 21*4f1223e8SApple OSS Distributions T_META_REQUIRES_SYSCTL_EQ("kern.development", 1), 22*4f1223e8SApple OSS Distributions T_META_TAG_VM_PREFERRED) 23*4f1223e8SApple OSS Distributions { 24*4f1223e8SApple OSS Distributions kern_return_t kr; 25*4f1223e8SApple OSS Distributions mach_vm_address_t vm_addr; 26*4f1223e8SApple OSS Distributions mach_vm_size_t vm_size; 27*4f1223e8SApple OSS Distributions unsigned char *cp; 28*4f1223e8SApple OSS Distributions int ret; 29*4f1223e8SApple OSS Distributions unsigned char vec; 30*4f1223e8SApple OSS Distributions 31*4f1223e8SApple OSS Distributions /* allocate the largest anonymous size possible */ 32*4f1223e8SApple OSS Distributions vm_size = ANON_MAX_SIZE; 33*4f1223e8SApple OSS Distributions /* truncate to avoid going over actual max size when rounding up */ 34*4f1223e8SApple OSS Distributions vm_size &= ~PAGE_MASK; 35*4f1223e8SApple OSS Distributions vm_addr = 0; 36*4f1223e8SApple OSS Distributions kr = mach_vm_allocate(mach_task_self(), 37*4f1223e8SApple OSS Distributions &vm_addr, 38*4f1223e8SApple OSS Distributions vm_size, 39*4f1223e8SApple OSS Distributions VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE); 40*4f1223e8SApple OSS Distributions if (kr == KERN_NO_SPACE) { 41*4f1223e8SApple OSS Distributions T_SKIP("not enough address space..."); 42*4f1223e8SApple OSS Distributions } 43*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_allocate(0x%llx)", ANON_MAX_SIZE); 44*4f1223e8SApple OSS Distributions 45*4f1223e8SApple OSS Distributions /* dirty the first and last pages */ 46*4f1223e8SApple OSS Distributions cp = (unsigned char *)(uintptr_t)vm_addr; 47*4f1223e8SApple OSS Distributions cp[0] = 'a'; 48*4f1223e8SApple OSS Distributions cp[vm_size - 1] = 'z'; 49*4f1223e8SApple OSS Distributions 50*4f1223e8SApple OSS Distributions /* trigger the VM compressor for that VM object */ 51*4f1223e8SApple OSS Distributions ret = madvise(cp, (size_t)vm_size, MADV_PAGEOUT); 52*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "madvise(MADV_PAGEOUT)"); 53*4f1223e8SApple OSS Distributions 54*4f1223e8SApple OSS Distributions /* wait for the pages to be (asynchronously) compressed */ 55*4f1223e8SApple OSS Distributions T_QUIET; T_LOG("waiting for first page to be paged out..."); 56*4f1223e8SApple OSS Distributions do { 57*4f1223e8SApple OSS Distributions ret = mincore(&cp[0], 1, (char *)&vec); 58*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "mincore(1st)"); 59*4f1223e8SApple OSS Distributions } while (vec & MINCORE_INCORE); 60*4f1223e8SApple OSS Distributions T_QUIET; T_LOG("waiting for last page to be paged out..."); 61*4f1223e8SApple OSS Distributions do { 62*4f1223e8SApple OSS Distributions ret = mincore(&cp[vm_size - 1], 1, (char *)&vec); 63*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "mincore(last)"); 64*4f1223e8SApple OSS Distributions } while (vec & MINCORE_INCORE); 65*4f1223e8SApple OSS Distributions 66*4f1223e8SApple OSS Distributions /* trigger pageins and check the contents */ 67*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_EQ(cp[0], 'a', "first page intact"); 68*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_EQ(cp[vm_size - 1], 'z', "last page intact"); 69*4f1223e8SApple OSS Distributions 70*4f1223e8SApple OSS Distributions /* success */ 71*4f1223e8SApple OSS Distributions return; 72*4f1223e8SApple OSS Distributions } 73