x86: vmm: Track state for handling vmexits as KERNEL
[akaros.git] / tests / mmap_file_vmm.c
1 /* Copyright Google, Inc. 2017
2  * Author: Zach Zimmerman
3  * mmap_vmm_test: tests mmap with fd's with access from
4  * vmthreads */
5
6 #include <stdio.h>
7 #include <pthread.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <sys/time.h>
11
12 #include <sys/mman.h>
13 #include <fcntl.h>
14 #include <parlib/parlib.h>
15 #include <parlib/timing.h>
16 #include <parlib/ros_debug.h>
17
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21
22 #include <vmm/vmm.h>
23
24 static struct virtual_machine vm;
25
26 int safe_to_exit;
27 void *addr;
28 size_t nr_pgs = 1;
29 #define STRIDE 1
30 #define NUM_ITERS 100
31
32 static void mmap_testz(void)
33 {
34         assert(addr);
35         for (char *i = addr; (void*)i < addr + nr_pgs * PGSIZE; i += STRIDE)
36                 *i = 'z';
37 }
38
39 static void mmap_testy(void)
40 {
41         assert(addr);
42         for (char *i = addr; (void*)i < addr + nr_pgs * PGSIZE; i += STRIDE)
43                 *i = 'y';
44 }
45
46 void *worker_thread(void *arg)
47 {
48         int i;
49
50         for (i = 0; i < NUM_ITERS; ++i)
51                 mmap_testy();
52
53         safe_to_exit = true;
54         __asm__ __volatile__("hlt\n\t");
55         return 0;
56 }
57
58 int main(void)
59 {
60         int fd, pid, ret;
61         char inputfile[50];
62
63         pid = getpid();
64         sprintf(inputfile, "/tmp/mmap-test-%d", pid);
65
66         fd = open(inputfile, O_RDWR | O_CREAT, 0666);
67         if (fd < 0) {
68                 perror("Unable to open file");
69                 exit(-1);
70         }
71
72         ret = unlink(inputfile);
73         if (ret == -1) {
74                 perror("UNLINK error");
75                 exit(-1);
76         }
77
78         //Increase the file size with ftruncate
79         ret = ftruncate(fd, nr_pgs * PGSIZE);
80         if (ret == -1) {
81                 perror("FTRUNCATE error");
82                 exit(-1);
83         }
84
85         ret = vthread_attr_init(&vm, 0);
86         if (ret) {
87                 fprintf(stderr, "vmm_init failed: %r\n");
88                 exit(1);
89         }
90
91         fprintf(stderr, "Vthread attr init finished\n");
92         nr_pgs = 1;
93         void *loc = (void*) 0x1000000;
94
95         addr = mmap(loc, nr_pgs * PGSIZE, PROT_WRITE | PROT_READ | PROT_EXEC,
96                             MAP_SHARED, fd, 0);
97         if (addr == MAP_FAILED) {
98                 perror("mmap failed");
99                 exit(-1);
100         }
101
102         printf("MMap got addr %p\n", addr);
103         printf("Spawning worker vmthread thread, etc...\n");
104         vthread_create(&vm, 0, (void*)&worker_thread, NULL);
105
106         while (!safe_to_exit)
107                 cpu_relax();
108
109         for (char *i = addr; (void*)i < addr + nr_pgs * PGSIZE; i += STRIDE)
110                 assert(*i == 'y');
111
112         printf("mmap_file_vmm: test finished, doing teardown\n");
113
114         ret = munmap(addr, nr_pgs * PGSIZE);
115         if (ret == -1) {
116                 perror("mmap_file_vmm: problem unmapping memory after test\n");
117                 exit(-1);
118         }
119
120         ret = close(fd);
121         if (ret == -1) {
122                 perror("mmap_file_vmm: problem closing file after test\n");
123                 exit(-1);
124         }
125
126         printf("mmap_file_vmm: PASSED\n");
127         return 0;
128 }