Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

selftests/mm: report SKIP in pfnmap if a check fails

pfnmap currently checks the target file in FIXTURE_SETUP(pfnmap), meaning
once for every test, and skips the test if any check fails.

The target file is the same for every test so this is a little overkill.
More importantly, this approach means that the whole suite will report
PASS even if all the tests are skipped because kernel configuration (e.g.
CONFIG_STRICT_DEVMEM=y) prevented /dev/mem from being mapped, for
instance.

Let's ensure that KSFT_SKIP is returned as exit code if any check fails by
performing the checks in pfnmap_init(), run once. That function also
takes care of finding the offset of the pages to be mapped and saves it in
a global. The file is now opened only once and the fd saved in a global,
but it is still mapped/unmapped for every test, as some of them modify the
mapping.

Link: https://lkml.kernel.org/r/20260122170224.4056513-10-kevin.brodsky@arm.com
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: SeongJae Park <sj@kernel.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Usama Anjum <Usama.Anjum@arm.com>
Cc: wang lian <lianux.mm@gmail.com>
Cc: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Kevin Brodsky and committed by
Andrew Morton
fde83531 148e5879

+53 -31
+53 -31
tools/testing/selftests/mm/pfnmap.c
··· 25 25 #include "kselftest_harness.h" 26 26 #include "vm_util.h" 27 27 28 + #define DEV_MEM_NPAGES 2 29 + 28 30 static sigjmp_buf sigjmp_buf_env; 29 31 static char *file = "/dev/mem"; 32 + static off_t file_offset; 33 + static int fd; 30 34 31 35 static void signal_handler(int sig) 32 36 { ··· 92 88 break; 93 89 94 90 /* We need two pages. */ 95 - if (end > start + 2 * pagesize) { 91 + if (end > start + DEV_MEM_NPAGES * pagesize) { 96 92 fclose(file); 97 93 *offset = start; 98 94 return 0; ··· 101 97 return -ENOENT; 102 98 } 103 99 100 + static void pfnmap_init(void) 101 + { 102 + size_t pagesize = getpagesize(); 103 + size_t size = DEV_MEM_NPAGES * pagesize; 104 + void *addr; 105 + 106 + if (strncmp(file, "/dev/mem", strlen("/dev/mem")) == 0) { 107 + int err = find_ram_target(&file_offset, pagesize); 108 + 109 + if (err) 110 + ksft_exit_skip("Cannot find ram target in '/proc/iomem': %s\n", 111 + strerror(-err)); 112 + } else { 113 + file_offset = 0; 114 + } 115 + 116 + fd = open(file, O_RDONLY); 117 + if (fd < 0) 118 + ksft_exit_skip("Cannot open '%s': %s\n", file, strerror(errno)); 119 + 120 + /* 121 + * Make sure we can map the file, and perform some basic checks; skip 122 + * the whole suite if anything goes wrong. 123 + * A fresh mapping is then created for every test case by 124 + * FIXTURE_SETUP(pfnmap). 125 + */ 126 + addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, file_offset); 127 + if (addr == MAP_FAILED) 128 + ksft_exit_skip("Cannot mmap '%s': %s\n", file, strerror(errno)); 129 + 130 + if (!check_vmflag_pfnmap(addr)) 131 + ksft_exit_skip("Invalid file: '%s'. Not pfnmap'ed\n", file); 132 + 133 + if (test_read_access(addr, size, pagesize)) 134 + ksft_exit_skip("Cannot read-access mmap'ed '%s'\n", file); 135 + 136 + munmap(addr, size); 137 + } 138 + 104 139 FIXTURE(pfnmap) 105 140 { 106 - off_t offset; 107 141 size_t pagesize; 108 - int dev_mem_fd; 109 142 char *addr1; 110 143 size_t size1; 111 144 char *addr2; ··· 153 112 { 154 113 self->pagesize = getpagesize(); 155 114 156 - if (strncmp(file, "/dev/mem", strlen("/dev/mem")) == 0) { 157 - /* We'll require two physical pages throughout our tests ... */ 158 - if (find_ram_target(&self->offset, self->pagesize)) 159 - SKIP(return, 160 - "Cannot find ram target in '/proc/iomem'\n"); 161 - } else { 162 - self->offset = 0; 163 - } 164 - 165 - self->dev_mem_fd = open(file, O_RDONLY); 166 - if (self->dev_mem_fd < 0) 167 - SKIP(return, "Cannot open '%s'\n", file); 168 - 169 - self->size1 = self->pagesize * 2; 115 + self->size1 = DEV_MEM_NPAGES * self->pagesize; 170 116 self->addr1 = mmap(NULL, self->size1, PROT_READ, MAP_SHARED, 171 - self->dev_mem_fd, self->offset); 172 - if (self->addr1 == MAP_FAILED) 173 - SKIP(return, "Cannot mmap '%s'\n", file); 174 - 175 - if (!check_vmflag_pfnmap(self->addr1)) 176 - SKIP(return, "Invalid file: '%s'. Not pfnmap'ed\n", file); 177 - 178 - /* ... and want to be able to read from them. */ 179 - if (test_read_access(self->addr1, self->size1, self->pagesize)) 180 - SKIP(return, "Cannot read-access mmap'ed '%s'\n", file); 117 + fd, file_offset); 118 + ASSERT_NE(self->addr1, MAP_FAILED); 181 119 182 120 self->size2 = 0; 183 121 self->addr2 = MAP_FAILED; ··· 168 148 munmap(self->addr2, self->size2); 169 149 if (self->addr1 != MAP_FAILED) 170 150 munmap(self->addr1, self->size1); 171 - if (self->dev_mem_fd >= 0) 172 - close(self->dev_mem_fd); 173 151 } 174 152 175 153 TEST_F(pfnmap, madvise_disallowed) ··· 207 189 */ 208 190 self->size2 = self->pagesize; 209 191 self->addr2 = mmap(NULL, self->pagesize, PROT_READ, MAP_SHARED, 210 - self->dev_mem_fd, self->offset); 192 + fd, file_offset); 211 193 ASSERT_NE(self->addr2, MAP_FAILED); 212 194 } 213 195 ··· 277 259 if (strcmp(argv[i], "--") == 0) { 278 260 if (i + 1 < argc && strlen(argv[i + 1]) > 0) 279 261 file = argv[i + 1]; 280 - return test_harness_run(i, argv); 262 + argc = i; 263 + break; 281 264 } 282 265 } 266 + 267 + pfnmap_init(); 268 + 283 269 return test_harness_run(argc, argv); 284 270 }