1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2013 FNST, DAN LI <li.dan@cn.fujitsu.com>
4 * Copyright (c) 2024 Ricardo B. Marliere <rbm@suse.com>
5 */
6
7 /*\
8 * [Description]
9 *
10 * Verify basic functionality of mmap(2) with MAP_LOCKED.
11 *
12 * mmap(2) should succeed returning the address of the mapped region,
13 * and this region should be locked into memory.
14 */
15 #include <stdio.h>
16 #include <sys/mman.h>
17
18 #include "tst_test.h"
19 #include "tst_safe_stdio.h"
20
21 #define TEMPFILE "mmapfile"
22 #define MMAPSIZE (1UL<<20)
23 #define LINELEN 256
24
25 static char *addr;
26
getvmlck(unsigned int * lock_sz)27 static void getvmlck(unsigned int *lock_sz)
28 {
29 char line[LINELEN];
30 FILE *fstatus = NULL;
31
32 fstatus = SAFE_FOPEN("/proc/self/status", "r");
33
34 while (fgets(line, LINELEN, fstatus) != NULL)
35 if (strstr(line, "VmLck") != NULL)
36 break;
37
38 SAFE_SSCANF(line, "%*[^0-9]%d%*[^0-9]", lock_sz);
39
40 SAFE_FCLOSE(fstatus);
41 }
42
run(void)43 static void run(void)
44 {
45 unsigned int sz_before;
46 unsigned int sz_after;
47 unsigned int sz_ch;
48
49 getvmlck(&sz_before);
50
51 addr = mmap(NULL, MMAPSIZE, PROT_READ | PROT_WRITE,
52 MAP_PRIVATE | MAP_LOCKED | MAP_ANONYMOUS, -1, 0);
53
54 if (addr == MAP_FAILED) {
55 tst_res(TFAIL | TERRNO, "mmap() of %s failed", TEMPFILE);
56 return;
57 }
58
59 getvmlck(&sz_after);
60
61 sz_ch = sz_after - sz_before;
62 if (sz_ch == MMAPSIZE / 1024) {
63 tst_res(TPASS, "mmap() locked %uK", sz_ch);
64 } else {
65 tst_res(TFAIL, "Expected %luK locked, get %uK locked",
66 MMAPSIZE / 1024, sz_ch);
67 }
68
69 SAFE_MUNMAP(addr, MMAPSIZE);
70 }
71
72 static struct tst_test test = {
73 .needs_root = 1,
74 .test_all = run,
75 };
76