|  | /* Copyright Google, Inc. 2017 | 
|  | * Author: Zach Zimmerman | 
|  | * mmap_vmm_test: tests mmap with fd's with access from | 
|  | * vmthreads */ | 
|  |  | 
|  | #include <stdio.h> | 
|  | #include <pthread.h> | 
|  | #include <stdlib.h> | 
|  | #include <unistd.h> | 
|  | #include <sys/time.h> | 
|  |  | 
|  | #include <sys/mman.h> | 
|  | #include <fcntl.h> | 
|  | #include <parlib/parlib.h> | 
|  | #include <parlib/timing.h> | 
|  | #include <parlib/ros_debug.h> | 
|  |  | 
|  | #include <sys/types.h> | 
|  | #include <sys/stat.h> | 
|  | #include <unistd.h> | 
|  |  | 
|  | #include <vmm/vmm.h> | 
|  | #include <vmm/vthread.h> | 
|  |  | 
|  | static struct virtual_machine vm = {.mtx = UTH_MUTEX_INIT}; | 
|  |  | 
|  | int safe_to_exit; | 
|  | void *addr; | 
|  | size_t nr_pgs = 1; | 
|  | #define STRIDE 1 | 
|  | #define NUM_ITERS 100 | 
|  |  | 
|  | static void mmap_testz(void) | 
|  | { | 
|  | assert(addr); | 
|  | for (char *i = addr; (void*)i < addr + nr_pgs * PGSIZE; i += STRIDE) | 
|  | *i = 'z'; | 
|  | } | 
|  |  | 
|  | static void mmap_testy(void) | 
|  | { | 
|  | assert(addr); | 
|  | for (char *i = addr; (void*)i < addr + nr_pgs * PGSIZE; i += STRIDE) | 
|  | *i = 'y'; | 
|  | } | 
|  |  | 
|  | void *worker_thread(void *arg) | 
|  | { | 
|  | int i; | 
|  |  | 
|  | for (i = 0; i < NUM_ITERS; ++i) | 
|  | mmap_testy(); | 
|  |  | 
|  | safe_to_exit = true; | 
|  | __asm__ __volatile__("hlt\n\t"); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int main(void) | 
|  | { | 
|  | int fd, pid, ret; | 
|  | char inputfile[50]; | 
|  |  | 
|  | pid = getpid(); | 
|  | sprintf(inputfile, "/tmp/mmap-test-%d", pid); | 
|  |  | 
|  | fd = open(inputfile, O_RDWR | O_CREAT, 0666); | 
|  | if (fd < 0) { | 
|  | perror("Unable to open file"); | 
|  | exit(-1); | 
|  | } | 
|  |  | 
|  | ret = unlink(inputfile); | 
|  | if (ret == -1) { | 
|  | perror("UNLINK error"); | 
|  | exit(-1); | 
|  | } | 
|  |  | 
|  | //Increase the file size with ftruncate | 
|  | ret = ftruncate(fd, nr_pgs * PGSIZE); | 
|  | if (ret == -1) { | 
|  | perror("FTRUNCATE error"); | 
|  | exit(-1); | 
|  | } | 
|  |  | 
|  | nr_pgs = 1; | 
|  | void *loc = (void*) 0x1000000; | 
|  |  | 
|  | addr = mmap(loc, nr_pgs * PGSIZE, PROT_WRITE | PROT_READ | PROT_EXEC, | 
|  | MAP_SHARED, fd, 0); | 
|  | if (addr == MAP_FAILED) { | 
|  | perror("mmap failed"); | 
|  | exit(-1); | 
|  | } | 
|  |  | 
|  | printf("MMap got addr %p\n", addr); | 
|  | printf("Spawning worker vmthread thread, etc...\n"); | 
|  | vthread_create(&vm, (void*)&worker_thread, NULL); | 
|  |  | 
|  | while (!safe_to_exit) | 
|  | cpu_relax(); | 
|  |  | 
|  | for (char *i = addr; (void*)i < addr + nr_pgs * PGSIZE; i += STRIDE) | 
|  | assert(*i == 'y'); | 
|  |  | 
|  | printf("mmap_file_vmm: test finished, doing teardown\n"); | 
|  |  | 
|  | ret = munmap(addr, nr_pgs * PGSIZE); | 
|  | if (ret == -1) { | 
|  | perror("mmap_file_vmm: problem unmapping memory after test\n"); | 
|  | exit(-1); | 
|  | } | 
|  |  | 
|  | ret = close(fd); | 
|  | if (ret == -1) { | 
|  | perror("mmap_file_vmm: problem closing file after test\n"); | 
|  | exit(-1); | 
|  | } | 
|  |  | 
|  | printf("mmap_file_vmm: PASSED\n"); | 
|  | return 0; | 
|  | } |