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: pass filename as input param to VM_PFNMAP tests

Enable these tests to be run on other pfnmap'ed memory like NVIDIA's EGM.

Add '--' as a separator to pass in file path. This allows passing of cmd
line arguments to kselftest_harness. Use '/dev/mem' as default filename.

Existing test passes:
pfnmap
TAP version 13
1..6
# Starting 6 tests from 1 test cases.
# PASSED: 6 / 6 tests passed.
# Totals: pass:6 fail:0 xfail:0 xpass:0 skip:0 error:0

Pass params to kselftest_harness:
pfnmap -r pfnmap:mremap_fixed
TAP version 13
1..1
# Starting 1 tests from 1 test cases.
# RUN pfnmap.mremap_fixed ...
# OK pfnmap.mremap_fixed
ok 1 pfnmap.mremap_fixed
# PASSED: 1 / 1 tests passed.
# Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0

Pass non-existent file name as input:
pfnmap -- /dev/blah
TAP version 13
1..6
# Starting 6 tests from 1 test cases.
# RUN pfnmap.madvise_disallowed ...
# SKIP Cannot open '/dev/blah'

Pass non pfnmap'ed file as input:
pfnmap -r pfnmap.madvise_disallowed -- randfile.txt
TAP version 13
1..1
# Starting 1 tests from 1 test cases.
# RUN pfnmap.madvise_disallowed ...
# SKIP Invalid file: 'randfile.txt'. Not pfnmap'ed

Link: https://lkml.kernel.org/r/20250805013629.47629-1-sudarsanm@google.com
Signed-off-by: Sudarsan Mahendran <sudarsanm@google.com>
Acked-by: David Hildenbrand <david@redhat.com>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Sudarsan Mahendran and committed by
Andrew Morton
35edbaa0 7cbce1ea

+47 -16
+34 -14
tools/testing/selftests/mm/pfnmap.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Basic VM_PFNMAP tests relying on mmap() of '/dev/mem' 3 + * Basic VM_PFNMAP tests relying on mmap() of input file provided. 4 + * Use '/dev/mem' as default. 4 5 * 5 6 * Copyright 2025, Red Hat, Inc. 6 7 * ··· 26 25 #include "vm_util.h" 27 26 28 27 static sigjmp_buf sigjmp_buf_env; 28 + static char *file = "/dev/mem"; 29 29 30 30 static void signal_handler(int sig) 31 31 { ··· 53 51 return ret; 54 52 } 55 53 56 - static int find_ram_target(off_t *phys_addr, 54 + static int find_ram_target(off_t *offset, 57 55 unsigned long long pagesize) 58 56 { 59 57 unsigned long long start, end; ··· 93 91 /* We need two pages. */ 94 92 if (end > start + 2 * pagesize) { 95 93 fclose(file); 96 - *phys_addr = start; 94 + *offset = start; 97 95 return 0; 98 96 } 99 97 } ··· 102 100 103 101 FIXTURE(pfnmap) 104 102 { 105 - off_t phys_addr; 103 + off_t offset; 106 104 size_t pagesize; 107 105 int dev_mem_fd; 108 106 char *addr1; ··· 115 113 { 116 114 self->pagesize = getpagesize(); 117 115 118 - /* We'll require two physical pages throughout our tests ... */ 119 - if (find_ram_target(&self->phys_addr, self->pagesize)) 120 - SKIP(return, "Cannot find ram target in '/proc/iomem'\n"); 116 + if (strncmp(file, "/dev/mem", strlen("/dev/mem")) == 0) { 117 + /* We'll require two physical pages throughout our tests ... */ 118 + if (find_ram_target(&self->offset, self->pagesize)) 119 + SKIP(return, 120 + "Cannot find ram target in '/proc/iomem'\n"); 121 + } else { 122 + self->offset = 0; 123 + } 121 124 122 - self->dev_mem_fd = open("/dev/mem", O_RDONLY); 125 + self->dev_mem_fd = open(file, O_RDONLY); 123 126 if (self->dev_mem_fd < 0) 124 - SKIP(return, "Cannot open '/dev/mem'\n"); 127 + SKIP(return, "Cannot open '%s'\n", file); 125 128 126 129 self->size1 = self->pagesize * 2; 127 130 self->addr1 = mmap(NULL, self->size1, PROT_READ, MAP_SHARED, 128 - self->dev_mem_fd, self->phys_addr); 131 + self->dev_mem_fd, self->offset); 129 132 if (self->addr1 == MAP_FAILED) 130 - SKIP(return, "Cannot mmap '/dev/mem'\n"); 133 + SKIP(return, "Cannot mmap '%s'\n", file); 134 + 135 + if (!check_vmflag_pfnmap(self->addr1)) 136 + SKIP(return, "Invalid file: '%s'. Not pfnmap'ed\n", file); 131 137 132 138 /* ... and want to be able to read from them. */ 133 139 if (test_read_access(self->addr1, self->size1, self->pagesize)) 134 - SKIP(return, "Cannot read-access mmap'ed '/dev/mem'\n"); 140 + SKIP(return, "Cannot read-access mmap'ed '%s'\n", file); 135 141 136 142 self->size2 = 0; 137 143 self->addr2 = MAP_FAILED; ··· 192 182 */ 193 183 self->size2 = self->pagesize; 194 184 self->addr2 = mmap(NULL, self->pagesize, PROT_READ, MAP_SHARED, 195 - self->dev_mem_fd, self->phys_addr); 185 + self->dev_mem_fd, self->offset); 196 186 ASSERT_NE(self->addr2, MAP_FAILED); 197 187 } 198 188 ··· 256 246 ASSERT_EQ(ret, 0); 257 247 } 258 248 259 - TEST_HARNESS_MAIN 249 + int main(int argc, char **argv) 250 + { 251 + for (int i = 1; i < argc; i++) { 252 + if (strcmp(argv[i], "--") == 0) { 253 + if (i + 1 < argc && strlen(argv[i + 1]) > 0) 254 + file = argv[i + 1]; 255 + return test_harness_run(i, argv); 256 + } 257 + } 258 + return test_harness_run(argc, argv); 259 + }
+12 -2
tools/testing/selftests/mm/vm_util.c
··· 402 402 return fhp; 403 403 } 404 404 405 - bool check_vmflag_io(void *addr) 405 + static bool check_vmflag(void *addr, const char *flag) 406 406 { 407 407 char buffer[MAX_LINE_LENGTH]; 408 408 const char *flags; ··· 419 419 if (!flaglen) 420 420 return false; 421 421 422 - if (flaglen == strlen("io") && !memcmp(flags, "io", flaglen)) 422 + if (flaglen == strlen(flag) && !memcmp(flags, flag, flaglen)) 423 423 return true; 424 424 425 425 flags += flaglen; 426 426 } 427 + } 428 + 429 + bool check_vmflag_io(void *addr) 430 + { 431 + return check_vmflag(addr, "io"); 432 + } 433 + 434 + bool check_vmflag_pfnmap(void *addr) 435 + { 436 + return check_vmflag(addr, "pf"); 427 437 } 428 438 429 439 /*
+1
tools/testing/selftests/mm/vm_util.h
··· 93 93 bool miss, bool wp, bool minor, uint64_t *ioctls); 94 94 unsigned long get_free_hugepages(void); 95 95 bool check_vmflag_io(void *addr); 96 + bool check_vmflag_pfnmap(void *addr); 96 97 int open_procmap(pid_t pid, struct procmap_fd *procmap_out); 97 98 int query_procmap(struct procmap_fd *procmap); 98 99 bool find_vma_procmap(struct procmap_fd *procmap, void *address);