1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/mman.h> 4 #include <unistd.h> 5 #include <fcntl.h> 6 7 /* This file includes a simple set of memory allocation calls that 8 * a user space program can use to allocate/free or move memory mappings. 9 * The intent of this program is to make it easier to verify if the kernel 10 * internal mappings are correct. 11 */ 12 13 #define PAGE_SHIFT 12 14 15 #define ROUND_PAGES(memsize) ((memsize >> (PAGE_SHIFT)) << PAGE_SHIFT) 16 17 /* approximately half of memsize, page aligned */ 18 #define HALF_MEM(memsize) ((memsize >> (PAGE_SHIFT))<<(PAGE_SHIFT - 1)) 19 20 inline void waitnext() { 21 fflush(NULL); 22 getchar(); 23 } 24 25 int main(int argc, char *argv[]) { 26 unsigned int memsize; 27 char *mem; 28 int i, numpages, fd; 29 30 if (argc != 2) { 31 printf("Usage: %s <memory_size>\n", argv[0]); 32 exit(EXIT_FAILURE); 33 } 34 35 memsize = strtoul(argv[1], NULL, 10); 36 37 memsize = ROUND_PAGES(memsize); 38 39 /* We should be limited to < 4G so any size other than 0 is ok */ 40 if (memsize == 0) { 41 printf("Invalid memsize\n"); 42 exit(EXIT_FAILURE); 43 } 44 45 46 numpages = memsize >> PAGE_SHIFT; 47 48 mlockall(MCL_FUTURE); 49 50 mem = sbrk(memsize); 51 52 if (mem == (void*) -1) { 53 perror("Failed to allocate memory using sbrk\n"); 54 exit(EXIT_FAILURE); 55 } 56 57 printf("Successfully allocated sbrk memory %d bytes @%p\n", 58 memsize, mem); 59 60 waitnext(); 61 62 sbrk(-(memsize)); 63 64 mem = mmap(0, memsize, PROT_READ | PROT_WRITE, 65 MAP_PRIVATE| MAP_ANONYMOUS, 66 -1, 0); 67 68 if (mem == (void*) -1) { 69 perror("Failed to allocate anon private memory using mmap\n"); 70 exit(EXIT_FAILURE); 71 } 72 73 printf("Successfully allocated anon mmap memory %d bytes @%p\n", 74 memsize, mem); 75 76 waitnext(); 77 78 if (-1 == mprotect(mem, HALF_MEM(memsize), PROT_READ)) { 79 perror("Failed to W protect memory using mprotect\n"); 80 exit(EXIT_FAILURE); 81 } 82 83 printf("Successfully write protected %d bytes @%p\n", 84 HALF_MEM(memsize), mem); 85 86 waitnext(); 87 88 if (-1 == mprotect(mem, HALF_MEM(memsize), 89 PROT_READ | PROT_WRITE)) { 90 perror("Failed to RW protect memory using mprotect\n"); 91 exit(EXIT_FAILURE); 92 } 93 94 printf("Successfully cleared write protected %d bytes @%p\n", 95 memsize, mem); 96 waitnext(); 97 98 /* Mark all pages with a specific pattern */ 99 for (i = 0; i < numpages; i++) { 100 int *ptr = (int *)(mem + i*4096); 101 *ptr = i; 102 } 103 104 mem = mremap(mem , memsize, 105 memsize + HALF_MEM(memsize), 106 1 /* MREMAP_MAYMOVE */); 107 108 if (mem == MAP_FAILED) { 109 perror("Failed to remap expand anon private memory\n"); 110 exit(EXIT_FAILURE); 111 } 112 113 printf("Successfully remapped %d bytes @%p\n", 114 memsize + HALF_MEM(memsize), mem); 115 116 waitnext(); 117 118 /* Mark all pages with a specific pattern */ 119 for (i = 0; i < numpages; i++) { 120 int value = *(int*)(mem + i*4096); 121 if (value != i) { 122 printf("remap error expected %d got %d\n", 123 i, value); 124 exit(EXIT_FAILURE); 125 } 126 } 127 128 if (munmap(mem, memsize + HALF_MEM(memsize))) { 129 perror("Could not unmap and free memory\n"); 130 exit(EXIT_FAILURE); 131 } 132 133 134 fd = open("/dev/zero", O_RDONLY); 135 136 mem = mmap(0, memsize, PROT_READ | PROT_WRITE, 137 MAP_PRIVATE, 138 fd, 0); 139 140 if (mem == (void*) -1) { 141 perror("Failed to allocate file backed memory using mmap\n"); 142 exit(EXIT_FAILURE); 143 } 144 145 printf("Successfully allocated file backed mmap memory %d bytes @%p\n", 146 memsize, mem); 147 waitnext(); 148 149 if (munmap(mem, memsize)) { 150 perror("Could not unmap and free file backed memory\n"); 151 exit(EXIT_FAILURE); 152 } 153 154 exit(EXIT_SUCCESS); 155 } 156