this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Initial LKM work on psynch_mutex support

+195 -2
+2 -1
src/lkm/Makefile
··· 21 21 mig/clockServer.o mig/mach_hostServer.o \ 22 22 mig/taskServer.o mig/thread_actServer.o \ 23 23 servers/thread_act.o \ 24 - mig/duct.o proc_entry.o bsd_ioctl.o 24 + mig/duct.o proc_entry.o bsd_ioctl.o \ 25 + psynch/psynch_mutex.o 25 26 26 27 # Otherwise we were called directly from the command 27 28 # line; invoke the kernel build system.
+20
src/lkm/api.h
··· 44 44 NR_bsd_ioctl_trap, 45 45 NR_thread_self_trap, 46 46 NR_bsdthread_terminate_trap, 47 + NR_psynch_mutexwait_trap, 48 + NR_psynch_mutexdrop_trap, 47 49 }; 48 50 49 51 struct mach_port_mod_refs_args ··· 135 137 uint32_t freesize; 136 138 unsigned int thread_right_name; 137 139 unsigned int signal; 140 + }; 141 + 142 + struct psynch_mutexwait_args 143 + { 144 + uint64_t mutex; 145 + uint32_t mgen; 146 + uint32_t ugen; 147 + uint64_t tid; 148 + uint32_t flags; 149 + }; 150 + 151 + struct psynch_mutexdrop_args 152 + { 153 + uint64_t mutex; 154 + uint32_t mgen; 155 + uint32_t ugen; 156 + uint64_t tid; 157 + uint32_t flags; 138 158 }; 139 159 140 160 #endif
+5
src/lkm/darling_task.h
··· 25 25 #include <linux/thread_info.h> 26 26 #include <linux/rbtree.h> 27 27 #include <linux/spinlock.h> 28 + #include <linux/hashtable.h> 28 29 30 + // Initialized in ipc_server.c 29 31 struct mach_task 30 32 { 31 33 pid_t pid; ··· 36 38 37 39 rwlock_t threads_lock; 38 40 struct rb_root threads; 41 + 42 + spinlock_t mutex_wq_lock; 43 + DECLARE_HASHTABLE(mutex_wq, 8); 39 44 }; 40 45 41 46 typedef struct mach_task mach_task_t;
+3
src/lkm/ipc_server.c
··· 50 50 task->threads.rb_node = NULL; 51 51 52 52 rwlock_init(&task->threads_lock); 53 + 54 + hash_init(task->mutex_wq); 55 + spin_lock_init(&task->mutex_wq_lock); 53 56 54 57 ipc_space_init(&task->namespace); 55 58
+130
src/lkm/psynch/psynch_mutex.c
··· 1 + /* 2 + * Darling Mach Linux Kernel Module 3 + * Copyright (C) 2015 Lubos Dolezel 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License 7 + * as published by the Free Software Foundation; either version 2 8 + * of the License, or (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 + */ 19 + 20 + #include "psynch_mutex.h" 21 + #include "../darling_task.h" 22 + #include <linux/sched.h> 23 + #include <linux/wait.h> 24 + #include <linux/list.h> 25 + #include <linux/uaccess.h> 26 + #include <linux/slab.h> 27 + 28 + struct pthread_mutex 29 + { 30 + struct hlist_node node; 31 + uint64_t pointer; 32 + uint32_t mgen; 33 + wait_queue_head_t wq; 34 + struct list_head waiting; 35 + unsigned int refcount; 36 + }; 37 + typedef struct pthread_mutex pthread_mutex_t; 38 + 39 + struct pthread_waiter 40 + { 41 + struct list_head entry; 42 + int wakeup; 43 + }; 44 + 45 + static pthread_mutex_t* mutex_get(mach_task_t* task, uint64_t address); 46 + static void mutex_put(mach_task_t* task, pthread_mutex_t* mutex); 47 + 48 + int psynch_mutexwait_trap(mach_task_t* task, 49 + struct psynch_mutexwait_args* in_args) 50 + { 51 + struct psynch_mutexwait_args args; 52 + struct pthread_waiter waiter; 53 + pthread_mutex_t* mutex; 54 + int retval = 0; 55 + 56 + if (copy_from_user(&args, in_args, sizeof(args))) 57 + return -EFAULT; 58 + 59 + spin_lock(&task->mutex_wq_lock); 60 + 61 + mutex = mutex_get(task, args.mutex); 62 + 63 + if (mutex->mgen == 0) 64 + { 65 + spin_unlock(&task->mutex_wq_lock); 66 + 67 + retval = 0; 68 + goto out; 69 + } 70 + 71 + waiter.wakeup = 0; 72 + list_add(&waiter.entry, &mutex->waiting); 73 + 74 + spin_unlock(&task->mutex_wq_lock); 75 + 76 + retval = wait_event_interruptible(mutex->wq, waiter.wakeup != 0); 77 + 78 + spin_lock(&task->mutex_wq_lock); 79 + list_del(&waiter.entry); 80 + 81 + if (waiter.wakeup) 82 + retval = mutex->mgen; 83 + 84 + mutex_put(task, mutex); 85 + spin_unlock(&task->mutex_wq_lock); 86 + 87 + out: 88 + return retval; 89 + } 90 + 91 + int psynch_mutexdrop_trap(mach_task_t* task, 92 + struct psynch_mutexdrop_args* args) 93 + { 94 + return 0; 95 + } 96 + 97 + pthread_mutex_t* mutex_get(mach_task_t* task, uint64_t address) 98 + { 99 + pthread_mutex_t* node; 100 + hash_for_each_possible(task->mutex_wq, node, node, address) 101 + { 102 + if (node->pointer != address) 103 + continue; 104 + 105 + node->refcount++; 106 + return node; 107 + } 108 + 109 + node = (pthread_mutex_t*) kmalloc(sizeof(pthread_mutex_t), GFP_KERNEL); 110 + node->refcount = 1; 111 + node->mgen = 0; 112 + node->pointer = address; 113 + 114 + init_waitqueue_head(&node->wq); 115 + INIT_LIST_HEAD(&node->waiting); 116 + hash_add(task->mutex_wq, &node->node, address); 117 + 118 + return node; 119 + } 120 + 121 + void mutex_put(mach_task_t* task, pthread_mutex_t* mutex) 122 + { 123 + mutex->refcount--; 124 + 125 + if (mutex->refcount == 0) 126 + { 127 + hash_del(&mutex->node); 128 + kfree(mutex); 129 + } 130 + }
+31
src/lkm/psynch/psynch_mutex.h
··· 1 + /* 2 + * Darling Mach Linux Kernel Module 3 + * Copyright (C) 2015 Lubos Dolezel 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License 7 + * as published by the Free Software Foundation; either version 2 8 + * of the License, or (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 + */ 19 + 20 + #ifndef PSYNCH_MUTEX_H 21 + #define PSYNCH_MUTEX_H 22 + #include "../api.h" 23 + #include "../ipc_types.h" 24 + 25 + int psynch_mutexwait_trap(mach_task_t* task, 26 + struct psynch_mutexwait_args* args); 27 + int psynch_mutexdrop_trap(mach_task_t* task, 28 + struct psynch_mutexdrop_args* args); 29 + 30 + #endif /* PSYNCH_MUTEX_H */ 31 +
+4 -1
src/lkm/traps.c
··· 42 42 #include "servers/mach_host.h" 43 43 #include "servers/thread_act.h" 44 44 #include "primitives/semaphore.h" 45 + #include "psynch/psynch_mutex.h" 45 46 46 47 MODULE_LICENSE("GPL"); 47 48 ··· 57 58 58 59 #define sc(n) n-DARLING_MACH_API_BASE 59 60 60 - static const trap_handler mach_traps[20] = { 61 + static const trap_handler mach_traps[30] = { 61 62 [sc(NR_get_api_version)] = (trap_handler) mach_get_api_version, 62 63 [sc(NR_mach_reply_port)] = (trap_handler) mach_reply_port_trap, 63 64 [sc(NR__kernelrpc_mach_port_mod_refs)] = (trap_handler) _kernelrpc_mach_port_mod_refs_trap, ··· 76 77 [sc(NR_bsd_ioctl_trap)] = (trap_handler) bsd_ioctl_trap, 77 78 [sc(NR_thread_self_trap)] = (trap_handler) mach_thread_self_trap, 78 79 [sc(NR_bsdthread_terminate_trap)] = (trap_handler) bsdthread_terminate_trap, 80 + [sc(NR_psynch_mutexwait_trap)] = (trap_handler) psynch_mutexwait_trap, 81 + [sc(NR_psynch_mutexdrop_trap)] = (trap_handler) psynch_mutexdrop_trap, 79 82 }; 80 83 #undef sc 81 84