root/tools/testing/selftests/vm/map_fixed_noreplace.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dump_maps
  2. main

   1 // SPDX-License-Identifier: GPL-2.0
   2 
   3 /*
   4  * Test that MAP_FIXED_NOREPLACE works.
   5  *
   6  * Copyright 2018, Jann Horn <jannh@google.com>
   7  * Copyright 2018, Michael Ellerman, IBM Corporation.
   8  */
   9 
  10 #include <sys/mman.h>
  11 #include <errno.h>
  12 #include <stdio.h>
  13 #include <stdlib.h>
  14 #include <unistd.h>
  15 
  16 #ifndef MAP_FIXED_NOREPLACE
  17 #define MAP_FIXED_NOREPLACE 0x100000
  18 #endif
  19 
  20 #define BASE_ADDRESS    (256ul * 1024 * 1024)
  21 
  22 
  23 static void dump_maps(void)
  24 {
  25         char cmd[32];
  26 
  27         snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", getpid());
  28         system(cmd);
  29 }
  30 
  31 int main(void)
  32 {
  33         unsigned long flags, addr, size, page_size;
  34         char *p;
  35 
  36         page_size = sysconf(_SC_PAGE_SIZE);
  37 
  38         flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE;
  39 
  40         // Check we can map all the areas we need below
  41         errno = 0;
  42         addr = BASE_ADDRESS;
  43         size = 5 * page_size;
  44         p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
  45 
  46         printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
  47 
  48         if (p == MAP_FAILED) {
  49                 dump_maps();
  50                 printf("Error: couldn't map the space we need for the test\n");
  51                 return 1;
  52         }
  53 
  54         errno = 0;
  55         if (munmap((void *)addr, 5 * page_size) != 0) {
  56                 dump_maps();
  57                 printf("Error: munmap failed!?\n");
  58                 return 1;
  59         }
  60         printf("unmap() successful\n");
  61 
  62         errno = 0;
  63         addr = BASE_ADDRESS + page_size;
  64         size = 3 * page_size;
  65         p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
  66         printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
  67 
  68         if (p == MAP_FAILED) {
  69                 dump_maps();
  70                 printf("Error: first mmap() failed unexpectedly\n");
  71                 return 1;
  72         }
  73 
  74         /*
  75          * Exact same mapping again:
  76          *   base |  free  | new
  77          *     +1 | mapped | new
  78          *     +2 | mapped | new
  79          *     +3 | mapped | new
  80          *     +4 |  free  | new
  81          */
  82         errno = 0;
  83         addr = BASE_ADDRESS;
  84         size = 5 * page_size;
  85         p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
  86         printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
  87 
  88         if (p != MAP_FAILED) {
  89                 dump_maps();
  90                 printf("Error:1: mmap() succeeded when it shouldn't have\n");
  91                 return 1;
  92         }
  93 
  94         /*
  95          * Second mapping contained within first:
  96          *
  97          *   base |  free  |
  98          *     +1 | mapped |
  99          *     +2 | mapped | new
 100          *     +3 | mapped |
 101          *     +4 |  free  |
 102          */
 103         errno = 0;
 104         addr = BASE_ADDRESS + (2 * page_size);
 105         size = page_size;
 106         p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
 107         printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
 108 
 109         if (p != MAP_FAILED) {
 110                 dump_maps();
 111                 printf("Error:2: mmap() succeeded when it shouldn't have\n");
 112                 return 1;
 113         }
 114 
 115         /*
 116          * Overlap end of existing mapping:
 117          *   base |  free  |
 118          *     +1 | mapped |
 119          *     +2 | mapped |
 120          *     +3 | mapped | new
 121          *     +4 |  free  | new
 122          */
 123         errno = 0;
 124         addr = BASE_ADDRESS + (3 * page_size);
 125         size = 2 * page_size;
 126         p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
 127         printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
 128 
 129         if (p != MAP_FAILED) {
 130                 dump_maps();
 131                 printf("Error:3: mmap() succeeded when it shouldn't have\n");
 132                 return 1;
 133         }
 134 
 135         /*
 136          * Overlap start of existing mapping:
 137          *   base |  free  | new
 138          *     +1 | mapped | new
 139          *     +2 | mapped |
 140          *     +3 | mapped |
 141          *     +4 |  free  |
 142          */
 143         errno = 0;
 144         addr = BASE_ADDRESS;
 145         size = 2 * page_size;
 146         p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
 147         printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
 148 
 149         if (p != MAP_FAILED) {
 150                 dump_maps();
 151                 printf("Error:4: mmap() succeeded when it shouldn't have\n");
 152                 return 1;
 153         }
 154 
 155         /*
 156          * Adjacent to start of existing mapping:
 157          *   base |  free  | new
 158          *     +1 | mapped |
 159          *     +2 | mapped |
 160          *     +3 | mapped |
 161          *     +4 |  free  |
 162          */
 163         errno = 0;
 164         addr = BASE_ADDRESS;
 165         size = page_size;
 166         p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
 167         printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
 168 
 169         if (p == MAP_FAILED) {
 170                 dump_maps();
 171                 printf("Error:5: mmap() failed when it shouldn't have\n");
 172                 return 1;
 173         }
 174 
 175         /*
 176          * Adjacent to end of existing mapping:
 177          *   base |  free  |
 178          *     +1 | mapped |
 179          *     +2 | mapped |
 180          *     +3 | mapped |
 181          *     +4 |  free  |  new
 182          */
 183         errno = 0;
 184         addr = BASE_ADDRESS + (4 * page_size);
 185         size = page_size;
 186         p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
 187         printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
 188 
 189         if (p == MAP_FAILED) {
 190                 dump_maps();
 191                 printf("Error:6: mmap() failed when it shouldn't have\n");
 192                 return 1;
 193         }
 194 
 195         addr = BASE_ADDRESS;
 196         size = 5 * page_size;
 197         if (munmap((void *)addr, size) != 0) {
 198                 dump_maps();
 199                 printf("Error: munmap failed!?\n");
 200                 return 1;
 201         }
 202         printf("unmap() successful\n");
 203 
 204         printf("OK\n");
 205         return 0;
 206 }

/* [<][>][^][v][top][bottom][index][help] */