@@ -67,59 +67,6 @@ static int get_vm_area(unsigned long addr, struct vm_boundaries *area)
6767 return ret ;
6868}
6969
70- static uint64_t get_pageflags (unsigned long addr )
71- {
72- FILE * file ;
73- uint64_t pfn ;
74- unsigned long offset ;
75-
76- file = fopen ("/proc/self/pagemap" , "r" );
77- if (!file ) {
78- perror ("fopen pagemap" );
79- _exit (1 );
80- }
81-
82- offset = addr / getpagesize () * sizeof (pfn );
83-
84- if (fseek (file , offset , SEEK_SET )) {
85- perror ("fseek pagemap" );
86- _exit (1 );
87- }
88-
89- if (fread (& pfn , sizeof (pfn ), 1 , file ) != 1 ) {
90- perror ("fread pagemap" );
91- _exit (1 );
92- }
93-
94- fclose (file );
95- return pfn ;
96- }
97-
98- static uint64_t get_kpageflags (unsigned long pfn )
99- {
100- uint64_t flags ;
101- FILE * file ;
102-
103- file = fopen ("/proc/kpageflags" , "r" );
104- if (!file ) {
105- perror ("fopen kpageflags" );
106- _exit (1 );
107- }
108-
109- if (fseek (file , pfn * sizeof (flags ), SEEK_SET )) {
110- perror ("fseek kpageflags" );
111- _exit (1 );
112- }
113-
114- if (fread (& flags , sizeof (flags ), 1 , file ) != 1 ) {
115- perror ("fread kpageflags" );
116- _exit (1 );
117- }
118-
119- fclose (file );
120- return flags ;
121- }
122-
12370#define VMFLAGS "VmFlags:"
12471
12572static bool is_vmflag_set (unsigned long addr , const char * vmflag )
@@ -159,19 +106,13 @@ static bool is_vmflag_set(unsigned long addr, const char *vmflag)
159106#define RSS "Rss:"
160107#define LOCKED "lo"
161108
162- static bool is_vma_lock_on_fault (unsigned long addr )
109+ static unsigned long get_value_for_name (unsigned long addr , const char * name )
163110{
164- bool ret = false;
165- bool locked ;
166- FILE * smaps = NULL ;
167- unsigned long vma_size , vma_rss ;
168111 char * line = NULL ;
169- char * value ;
170112 size_t size = 0 ;
171-
172- locked = is_vmflag_set (addr , LOCKED );
173- if (!locked )
174- goto out ;
113+ char * value_ptr ;
114+ FILE * smaps = NULL ;
115+ unsigned long value = -1UL ;
175116
176117 smaps = seek_to_smaps_entry (addr );
177118 if (!smaps ) {
@@ -180,112 +121,70 @@ static bool is_vma_lock_on_fault(unsigned long addr)
180121 }
181122
182123 while (getline (& line , & size , smaps ) > 0 ) {
183- if (!strstr (line , SIZE )) {
124+ if (!strstr (line , name )) {
184125 free (line );
185126 line = NULL ;
186127 size = 0 ;
187128 continue ;
188129 }
189130
190- value = line + strlen (SIZE );
191- if (sscanf (value , "%lu kB" , & vma_size ) < 1 ) {
131+ value_ptr = line + strlen (name );
132+ if (sscanf (value_ptr , "%lu kB" , & value ) < 1 ) {
192133 printf ("Unable to parse smaps entry for Size\n" );
193134 goto out ;
194135 }
195136 break ;
196137 }
197138
198- while (getline (& line , & size , smaps ) > 0 ) {
199- if (!strstr (line , RSS )) {
200- free (line );
201- line = NULL ;
202- size = 0 ;
203- continue ;
204- }
205-
206- value = line + strlen (RSS );
207- if (sscanf (value , "%lu kB" , & vma_rss ) < 1 ) {
208- printf ("Unable to parse smaps entry for Rss\n" );
209- goto out ;
210- }
211- break ;
212- }
213-
214- ret = locked && (vma_rss < vma_size );
215139out :
216- free (line );
217140 if (smaps )
218141 fclose (smaps );
219- return ret ;
142+ free (line );
143+ return value ;
220144}
221145
222- #define PRESENT_BIT 0x8000000000000000ULL
223- #define PFN_MASK 0x007FFFFFFFFFFFFFULL
224- #define UNEVICTABLE_BIT (1UL << 18)
225-
226- static int lock_check (char * map )
146+ static bool is_vma_lock_on_fault (unsigned long addr )
227147{
228- unsigned long page_size = getpagesize () ;
229- uint64_t page1_flags , page2_flags ;
148+ bool locked ;
149+ unsigned long vma_size , vma_rss ;
230150
231- page1_flags = get_pageflags ((unsigned long )map );
232- page2_flags = get_pageflags ((unsigned long )map + page_size );
151+ locked = is_vmflag_set (addr , LOCKED );
152+ if (!locked )
153+ return false;
233154
234- /* Both pages should be present */
235- if (((page1_flags & PRESENT_BIT ) == 0 ) ||
236- ((page2_flags & PRESENT_BIT ) == 0 )) {
237- printf ("Failed to make both pages present\n" );
238- return 1 ;
239- }
155+ vma_size = get_value_for_name (addr , SIZE );
156+ vma_rss = get_value_for_name (addr , RSS );
240157
241- page1_flags = get_kpageflags (page1_flags & PFN_MASK );
242- page2_flags = get_kpageflags (page2_flags & PFN_MASK );
158+ /* only one page is faulted in */
159+ return (vma_rss < vma_size );
160+ }
243161
244- /* Both pages should be unevictable */
245- if (((page1_flags & UNEVICTABLE_BIT ) == 0 ) ||
246- ((page2_flags & UNEVICTABLE_BIT ) == 0 )) {
247- printf ("Failed to make both pages unevictable\n" );
248- return 1 ;
249- }
162+ #define PRESENT_BIT 0x8000000000000000ULL
163+ #define PFN_MASK 0x007FFFFFFFFFFFFFULL
164+ #define UNEVICTABLE_BIT (1UL << 18)
250165
251- if (! is_vmflag_set (( unsigned long ) map , LOCKED )) {
252- printf ( "VMA flag %s is missing on page 1\n" , LOCKED );
253- return 1 ;
254- }
166+ static int lock_check ( unsigned long addr )
167+ {
168+ bool locked ;
169+ unsigned long vma_size , vma_rss ;
255170
256- if (!is_vmflag_set ((unsigned long )map + page_size , LOCKED )) {
257- printf ("VMA flag %s is missing on page 2\n" , LOCKED );
258- return 1 ;
259- }
171+ locked = is_vmflag_set (addr , LOCKED );
172+ if (!locked )
173+ return false;
260174
261- return 0 ;
175+ vma_size = get_value_for_name (addr , SIZE );
176+ vma_rss = get_value_for_name (addr , RSS );
177+
178+ return (vma_rss == vma_size );
262179}
263180
264181static int unlock_lock_check (char * map )
265182{
266- unsigned long page_size = getpagesize ();
267- uint64_t page1_flags , page2_flags ;
268-
269- page1_flags = get_pageflags ((unsigned long )map );
270- page2_flags = get_pageflags ((unsigned long )map + page_size );
271- page1_flags = get_kpageflags (page1_flags & PFN_MASK );
272- page2_flags = get_kpageflags (page2_flags & PFN_MASK );
273-
274- if ((page1_flags & UNEVICTABLE_BIT ) || (page2_flags & UNEVICTABLE_BIT )) {
275- printf ("A page is still marked unevictable after unlock\n" );
276- return 1 ;
277- }
278-
279183 if (is_vmflag_set ((unsigned long )map , LOCKED )) {
280184 printf ("VMA flag %s is present on page 1 after unlock\n" , LOCKED );
281185 return 1 ;
282186 }
283187
284- if (is_vmflag_set ((unsigned long )map + page_size , LOCKED )) {
285- printf ("VMA flag %s is present on page 2 after unlock\n" , LOCKED );
286- return 1 ;
287- }
288-
289188 return 0 ;
290189}
291190
@@ -311,7 +210,7 @@ static int test_mlock_lock()
311210 goto unmap ;
312211 }
313212
314- if (lock_check (map ))
213+ if (! lock_check (( unsigned long ) map ))
315214 goto unmap ;
316215
317216 /* Now unlock and recheck attributes */
@@ -330,64 +229,18 @@ static int test_mlock_lock()
330229
331230static int onfault_check (char * map )
332231{
333- unsigned long page_size = getpagesize ();
334- uint64_t page1_flags , page2_flags ;
335-
336- page1_flags = get_pageflags ((unsigned long )map );
337- page2_flags = get_pageflags ((unsigned long )map + page_size );
338-
339- /* Neither page should be present */
340- if ((page1_flags & PRESENT_BIT ) || (page2_flags & PRESENT_BIT )) {
341- printf ("Pages were made present by MLOCK_ONFAULT\n" );
342- return 1 ;
343- }
344-
345232 * map = 'a' ;
346- page1_flags = get_pageflags ((unsigned long )map );
347- page2_flags = get_pageflags ((unsigned long )map + page_size );
348-
349- /* Only page 1 should be present */
350- if ((page1_flags & PRESENT_BIT ) == 0 ) {
351- printf ("Page 1 is not present after fault\n" );
352- return 1 ;
353- } else if (page2_flags & PRESENT_BIT ) {
354- printf ("Page 2 was made present\n" );
355- return 1 ;
356- }
357-
358- page1_flags = get_kpageflags (page1_flags & PFN_MASK );
359-
360- /* Page 1 should be unevictable */
361- if ((page1_flags & UNEVICTABLE_BIT ) == 0 ) {
362- printf ("Failed to make faulted page unevictable\n" );
363- return 1 ;
364- }
365-
366233 if (!is_vma_lock_on_fault ((unsigned long )map )) {
367234 printf ("VMA is not marked for lock on fault\n" );
368235 return 1 ;
369236 }
370237
371- if (!is_vma_lock_on_fault ((unsigned long )map + page_size )) {
372- printf ("VMA is not marked for lock on fault\n" );
373- return 1 ;
374- }
375-
376238 return 0 ;
377239}
378240
379241static int unlock_onfault_check (char * map )
380242{
381243 unsigned long page_size = getpagesize ();
382- uint64_t page1_flags ;
383-
384- page1_flags = get_pageflags ((unsigned long )map );
385- page1_flags = get_kpageflags (page1_flags & PFN_MASK );
386-
387- if (page1_flags & UNEVICTABLE_BIT ) {
388- printf ("Page 1 is still marked unevictable after unlock\n" );
389- return 1 ;
390- }
391244
392245 if (is_vma_lock_on_fault ((unsigned long )map ) ||
393246 is_vma_lock_on_fault ((unsigned long )map + page_size )) {
@@ -445,7 +298,6 @@ static int test_lock_onfault_of_present()
445298 char * map ;
446299 int ret = 1 ;
447300 unsigned long page_size = getpagesize ();
448- uint64_t page1_flags , page2_flags ;
449301
450302 map = mmap (NULL , 2 * page_size , PROT_READ | PROT_WRITE ,
451303 MAP_ANONYMOUS | MAP_PRIVATE , -1 , 0 );
@@ -465,17 +317,6 @@ static int test_lock_onfault_of_present()
465317 goto unmap ;
466318 }
467319
468- page1_flags = get_pageflags ((unsigned long )map );
469- page2_flags = get_pageflags ((unsigned long )map + page_size );
470- page1_flags = get_kpageflags (page1_flags & PFN_MASK );
471- page2_flags = get_kpageflags (page2_flags & PFN_MASK );
472-
473- /* Page 1 should be unevictable */
474- if ((page1_flags & UNEVICTABLE_BIT ) == 0 ) {
475- printf ("Failed to make present page unevictable\n" );
476- goto unmap ;
477- }
478-
479320 if (!is_vma_lock_on_fault ((unsigned long )map ) ||
480321 !is_vma_lock_on_fault ((unsigned long )map + page_size )) {
481322 printf ("VMA with present pages is not marked lock on fault\n" );
@@ -507,7 +348,7 @@ static int test_munlockall()
507348 goto out ;
508349 }
509350
510- if (lock_check (map ))
351+ if (! lock_check (( unsigned long ) map ))
511352 goto unmap ;
512353
513354 if (munlockall ()) {
@@ -549,7 +390,7 @@ static int test_munlockall()
549390 goto out ;
550391 }
551392
552- if (lock_check (map ))
393+ if (! lock_check (( unsigned long ) map ))
553394 goto unmap ;
554395
555396 if (munlockall ()) {
0 commit comments