~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/ia64/aliasing-test.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Exercise /dev/mem mmap cases that have been troublesome in the past
  4  *
  5  * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
  6  *      Bjorn Helgaas <bjorn.helgaas@hp.com>
  7  */
  8 
  9 #include <stdlib.h>
 10 #include <stdio.h>
 11 #include <sys/types.h>
 12 #include <dirent.h>
 13 #include <fcntl.h>
 14 #include <fnmatch.h>
 15 #include <string.h>
 16 #include <sys/ioctl.h>
 17 #include <sys/mman.h>
 18 #include <sys/stat.h>
 19 #include <unistd.h>
 20 #include <linux/pci.h>
 21 
 22 int sum;
 23 
 24 static int map_mem(char *path, off_t offset, size_t length, int touch)
 25 {
 26         int fd, rc;
 27         void *addr;
 28         int *c;
 29 
 30         fd = open(path, O_RDWR);
 31         if (fd == -1) {
 32                 perror(path);
 33                 return -1;
 34         }
 35 
 36         if (fnmatch("/proc/bus/pci/*", path, 0) == 0) {
 37                 rc = ioctl(fd, PCIIOC_MMAP_IS_MEM);
 38                 if (rc == -1)
 39                         perror("PCIIOC_MMAP_IS_MEM ioctl");
 40         }
 41 
 42         addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
 43         if (addr == MAP_FAILED)
 44                 return 1;
 45 
 46         if (touch) {
 47                 c = (int *) addr;
 48                 while (c < (int *) (addr + length))
 49                         sum += *c++;
 50         }
 51 
 52         rc = munmap(addr, length);
 53         if (rc == -1) {
 54                 perror("munmap");
 55                 return -1;
 56         }
 57 
 58         close(fd);
 59         return 0;
 60 }
 61 
 62 static int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
 63 {
 64         struct dirent **namelist;
 65         char *name, *path2;
 66         int i, n, r, rc = 0, result = 0;
 67         struct stat buf;
 68 
 69         n = scandir(path, &namelist, 0, alphasort);
 70         if (n < 0) {
 71                 perror("scandir");
 72                 return -1;
 73         }
 74 
 75         for (i = 0; i < n; i++) {
 76                 name = namelist[i]->d_name;
 77 
 78                 if (fnmatch(".", name, 0) == 0)
 79                         goto skip;
 80                 if (fnmatch("..", name, 0) == 0)
 81                         goto skip;
 82 
 83                 path2 = malloc(strlen(path) + strlen(name) + 3);
 84                 strcpy(path2, path);
 85                 strcat(path2, "/");
 86                 strcat(path2, name);
 87 
 88                 if (fnmatch(file, name, 0) == 0) {
 89                         rc = map_mem(path2, offset, length, touch);
 90                         if (rc == 0)
 91                                 fprintf(stderr, "PASS: %s 0x%lx-0x%lx is %s\n", path2, offset, offset + length, touch ? "readable" : "mappable");
 92                         else if (rc > 0)
 93                                 fprintf(stderr, "PASS: %s 0x%lx-0x%lx not mappable\n", path2, offset, offset + length);
 94                         else {
 95                                 fprintf(stderr, "FAIL: %s 0x%lx-0x%lx not accessible\n", path2, offset, offset + length);
 96                                 return rc;
 97                         }
 98                 } else {
 99                         r = lstat(path2, &buf);
100                         if (r == 0 && S_ISDIR(buf.st_mode)) {
101                                 rc = scan_tree(path2, file, offset, length, touch);
102                                 if (rc < 0)
103                                         return rc;
104                         }
105                 }
106 
107                 result |= rc;
108                 free(path2);
109 
110 skip:
111                 free(namelist[i]);
112         }
113         free(namelist);
114         return result;
115 }
116 
117 char buf[1024];
118 
119 static int read_rom(char *path)
120 {
121         int fd, rc;
122         size_t size = 0;
123 
124         fd = open(path, O_RDWR);
125         if (fd == -1) {
126                 perror(path);
127                 return -1;
128         }
129 
130         rc = write(fd, "1", 2);
131         if (rc <= 0) {
132                 close(fd);
133                 perror("write");
134                 return -1;
135         }
136 
137         do {
138                 rc = read(fd, buf, sizeof(buf));
139                 if (rc > 0)
140                         size += rc;
141         } while (rc > 0);
142 
143         close(fd);
144         return size;
145 }
146 
147 static int scan_rom(char *path, char *file)
148 {
149         struct dirent **namelist;
150         char *name, *path2;
151         int i, n, r, rc = 0, result = 0;
152         struct stat buf;
153 
154         n = scandir(path, &namelist, 0, alphasort);
155         if (n < 0) {
156                 perror("scandir");
157                 return -1;
158         }
159 
160         for (i = 0; i < n; i++) {
161                 name = namelist[i]->d_name;
162 
163                 if (fnmatch(".", name, 0) == 0)
164                         goto skip;
165                 if (fnmatch("..", name, 0) == 0)
166                         goto skip;
167 
168                 path2 = malloc(strlen(path) + strlen(name) + 3);
169                 strcpy(path2, path);
170                 strcat(path2, "/");
171                 strcat(path2, name);
172 
173                 if (fnmatch(file, name, 0) == 0) {
174                         rc = read_rom(path2);
175 
176                         /*
177                          * It's OK if the ROM is unreadable.  Maybe there
178                          * is no ROM, or some other error occurred.  The
179                          * important thing is that no MCA happened.
180                          */
181                         if (rc > 0)
182                                 fprintf(stderr, "PASS: %s read %d bytes\n", path2, rc);
183                         else {
184                                 fprintf(stderr, "PASS: %s not readable\n", path2);
185                                 return rc;
186                         }
187                 } else {
188                         r = lstat(path2, &buf);
189                         if (r == 0 && S_ISDIR(buf.st_mode)) {
190                                 rc = scan_rom(path2, file);
191                                 if (rc < 0)
192                                         return rc;
193                         }
194                 }
195 
196                 result |= rc;
197                 free(path2);
198 
199 skip:
200                 free(namelist[i]);
201         }
202         free(namelist);
203         return result;
204 }
205 
206 int main(void)
207 {
208         int rc;
209 
210         if (map_mem("/dev/mem", 0, 0xA0000, 1) == 0)
211                 fprintf(stderr, "PASS: /dev/mem 0x0-0xa0000 is readable\n");
212         else
213                 fprintf(stderr, "FAIL: /dev/mem 0x0-0xa0000 not accessible\n");
214 
215         /*
216          * It's not safe to blindly read the VGA frame buffer.  If you know
217          * how to poke the card the right way, it should respond, but it's
218          * not safe in general.  Many machines, e.g., Intel chipsets, cover
219          * up a non-responding card by just returning -1, but others will
220          * report the failure as a machine check.
221          */
222         if (map_mem("/dev/mem", 0xA0000, 0x20000, 0) == 0)
223                 fprintf(stderr, "PASS: /dev/mem 0xa0000-0xc0000 is mappable\n");
224         else
225                 fprintf(stderr, "FAIL: /dev/mem 0xa0000-0xc0000 not accessible\n");
226 
227         if (map_mem("/dev/mem", 0xC0000, 0x40000, 1) == 0)
228                 fprintf(stderr, "PASS: /dev/mem 0xc0000-0x100000 is readable\n");
229         else
230                 fprintf(stderr, "FAIL: /dev/mem 0xc0000-0x100000 not accessible\n");
231 
232         /*
233          * Often you can map all the individual pieces above (0-0xA0000,
234          * 0xA0000-0xC0000, and 0xC0000-0x100000), but can't map the whole
235          * thing at once.  This is because the individual pieces use different
236          * attributes, and there's no single attribute supported over the
237          * whole region.
238          */
239         rc = map_mem("/dev/mem", 0, 1024*1024, 0);
240         if (rc == 0)
241                 fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 is mappable\n");
242         else if (rc > 0)
243                 fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 not mappable\n");
244         else
245                 fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");
246 
247         scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
248         scan_tree("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
249         scan_tree("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
250         scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
251 
252         scan_rom("/sys/devices", "rom");
253 
254         scan_tree("/proc/bus/pci", "??.?", 0, 0xA0000, 1);
255         scan_tree("/proc/bus/pci", "??.?", 0xA0000, 0x20000, 0);
256         scan_tree("/proc/bus/pci", "??.?", 0xC0000, 0x40000, 1);
257         scan_tree("/proc/bus/pci", "??.?", 0, 1024*1024, 0);
258 
259         return rc;
260 }
261 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php