12
12
#include <stdint.h>
13
13
#include <unistd.h>
14
14
#include <errno.h>
15
+ #include <stdio.h>
16
+ #include <ctype.h>
15
17
#include <fcntl.h>
16
18
#include <signal.h>
17
19
#include <setjmp.h>
@@ -43,14 +45,62 @@ static int test_read_access(char *addr, size_t size, size_t pagesize)
43
45
/* Force a read that the compiler cannot optimize out. */
44
46
* ((volatile char * )(addr + offs ));
45
47
}
46
- if (signal (SIGSEGV , signal_handler ) == SIG_ERR )
48
+ if (signal (SIGSEGV , SIG_DFL ) == SIG_ERR )
47
49
return - EINVAL ;
48
50
49
51
return ret ;
50
52
}
51
53
54
+ static int find_ram_target (off_t * phys_addr ,
55
+ unsigned long long pagesize )
56
+ {
57
+ unsigned long long start , end ;
58
+ char line [80 ], * end_ptr ;
59
+ FILE * file ;
60
+
61
+ /* Search /proc/iomem for the first suitable "System RAM" range. */
62
+ file = fopen ("/proc/iomem" , "r" );
63
+ if (!file )
64
+ return - errno ;
65
+
66
+ while (fgets (line , sizeof (line ), file )) {
67
+ /* Ignore any child nodes. */
68
+ if (!isalnum (line [0 ]))
69
+ continue ;
70
+
71
+ if (!strstr (line , "System RAM\n" ))
72
+ continue ;
73
+
74
+ start = strtoull (line , & end_ptr , 16 );
75
+ /* Skip over the "-" */
76
+ end_ptr ++ ;
77
+ /* Make end "exclusive". */
78
+ end = strtoull (end_ptr , NULL , 16 ) + 1 ;
79
+
80
+ /* Actual addresses are not exported */
81
+ if (!start && !end )
82
+ break ;
83
+
84
+ /* We need full pages. */
85
+ start = (start + pagesize - 1 ) & ~(pagesize - 1 );
86
+ end &= ~(pagesize - 1 );
87
+
88
+ if (start != (off_t )start )
89
+ break ;
90
+
91
+ /* We need two pages. */
92
+ if (end > start + 2 * pagesize ) {
93
+ fclose (file );
94
+ * phys_addr = start ;
95
+ return 0 ;
96
+ }
97
+ }
98
+ return - ENOENT ;
99
+ }
100
+
52
101
FIXTURE (pfnmap )
53
102
{
103
+ off_t phys_addr ;
54
104
size_t pagesize ;
55
105
int dev_mem_fd ;
56
106
char * addr1 ;
@@ -63,14 +113,17 @@ FIXTURE_SETUP(pfnmap)
63
113
{
64
114
self -> pagesize = getpagesize ();
65
115
116
+ /* We'll require two physical pages throughout our tests ... */
117
+ if (find_ram_target (& self -> phys_addr , self -> pagesize ))
118
+ SKIP (return , "Cannot find ram target in '/proc/iomem'\n" );
119
+
66
120
self -> dev_mem_fd = open ("/dev/mem" , O_RDONLY );
67
121
if (self -> dev_mem_fd < 0 )
68
122
SKIP (return , "Cannot open '/dev/mem'\n" );
69
123
70
- /* We'll require the first two pages throughout our tests ... */
71
124
self -> size1 = self -> pagesize * 2 ;
72
125
self -> addr1 = mmap (NULL , self -> size1 , PROT_READ , MAP_SHARED ,
73
- self -> dev_mem_fd , 0 );
126
+ self -> dev_mem_fd , self -> phys_addr );
74
127
if (self -> addr1 == MAP_FAILED )
75
128
SKIP (return , "Cannot mmap '/dev/mem'\n" );
76
129
@@ -129,7 +182,7 @@ TEST_F(pfnmap, munmap_split)
129
182
*/
130
183
self -> size2 = self -> pagesize ;
131
184
self -> addr2 = mmap (NULL , self -> pagesize , PROT_READ , MAP_SHARED ,
132
- self -> dev_mem_fd , 0 );
185
+ self -> dev_mem_fd , self -> phys_addr );
133
186
ASSERT_NE (self -> addr2 , MAP_FAILED );
134
187
}
135
188
0 commit comments