1 // SPDX-License-Identifier: GPL-2.0-or-later
2 // Copyright (c) 2010 Mohamed Naufal Basheer
3 // Author: Mohamed Naufal Basheer
4
5 #include <sys/types.h>
6 #include <sys/mman.h>
7 #include <sys/stat.h>
8 #include <err.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include "pgsize_helpers.h"
15
16 /*
17 * Named pipe to act as a communication channel between
18 * shell script & this process
19 */
20 #define STATUS_PIPE "status_pipe"
21
22 int flag_exit;
23 int flag_allocated;
24 unsigned long memsize;
25
26 /*
27 * process_options: process user specified options
28 */
process_options(int argc,char ** argv)29 void process_options(int argc, char **argv)
30 {
31 int c;
32 char *end;
33
34 opterr = 0;
35 while ((c = getopt(argc, argv, "pm:")) != -1) {
36 switch (c) {
37 case 'm':
38 memsize = strtoul(optarg, &end, 10);
39 if (*end != '\0')
40 errx(2, "invalid -m usage");
41 break;
42 default:
43 errx(2, "invalid option specified");
44 }
45 }
46
47 if (memsize <= 0)
48 errx(3, "invalid usage");
49 }
50
51 /*
52 * touch_memory: force physical memory allocation
53 */
touch_memory(char * p)54 void touch_memory(char *p)
55 {
56 int i;
57 int pagesize = getpagesize();
58
59 for (i = 0; i < (int)memsize; i += kernel_page_size())
60 p[i] = 0xef;
61 }
62
mem_map(void)63 void mem_map(void)
64 {
65 static char *p;
66
67 if (flag_allocated) {
68 if (munmap(p, memsize) == -1)
69 err(5, "munmap failed");
70 } else {
71 p = mmap(NULL, memsize, PROT_READ | PROT_WRITE,
72 MAP_SHARED | MAP_ANONYMOUS, 0, 0);
73 if (p == MAP_FAILED)
74 err(4, "mmap failed");
75 touch_memory(p);
76 }
77 flag_allocated = !flag_allocated;
78 }
79
80 /*
81 * done: retrieve instructions from the named pipe
82 */
action(int fd)83 char action(int fd)
84 {
85 char ch;
86
87 if (read(fd, &ch, 1) == -1)
88 err(7, "Error reading named pipe");
89
90 return ch;
91 }
92
main(int argc,char ** argv)93 int main(int argc, char **argv)
94 {
95 int ret;
96 int fd;
97 char ch;
98
99 process_options(argc, argv);
100
101 ret = mkfifo(STATUS_PIPE, 0666);
102
103 if (ret == -1 && errno != EEXIST)
104 errx(1, "Error creating named pipe");
105
106 if ((fd = open(STATUS_PIPE, O_RDONLY)) == -1)
107 err(6, "Error opening named pipe");
108
109 do {
110 ch = action(fd);
111
112 if (ch == 'm')
113 mem_map();
114 } while (ch != 'x');
115
116 close(fd);
117
118 remove(STATUS_PIPE);
119
120 return 0;
121 }
122