1 /*- 2 * Copyright (c) 2017 Hans Petter Selasky 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <linux/compat.h> 31 #include <linux/mm.h> 32 #include <linux/kthread.h> 33 34 #include <sys/kernel.h> 35 #include <sys/eventhandler.h> 36 #include <sys/malloc.h> 37 38 static eventhandler_tag linuxkpi_thread_dtor_tag; 39 40 static MALLOC_DEFINE(M_LINUX_CURRENT, "linuxcurrent", "LinuxKPI task structure"); 41 42 int 43 linux_alloc_current(struct thread *td, int flags) 44 { 45 struct task_struct *ts; 46 47 MPASS(td->td_lkpi_task == NULL); 48 49 ts = malloc(sizeof(*ts), M_LINUX_CURRENT, flags | M_ZERO); 50 if (ts == NULL) 51 return (ENOMEM); 52 53 atomic_set(&ts->kthread_flags, 0); 54 ts->task_thread = td; 55 ts->comm = td->td_name; 56 ts->pid = td->td_tid; 57 ts->state = TASK_RUNNING; 58 td->td_lkpi_task = ts; 59 return (0); 60 } 61 62 void 63 linux_free_current(struct task_struct *ts) 64 { 65 free(ts, M_LINUX_CURRENT); 66 } 67 68 static void 69 linuxkpi_thread_dtor(void *arg __unused, struct thread *td) 70 { 71 struct task_struct *ts; 72 73 ts = td->td_lkpi_task; 74 if (ts == NULL) 75 return; 76 77 td->td_lkpi_task = NULL; 78 free(ts, M_LINUX_CURRENT); 79 } 80 81 static void 82 linux_current_init(void *arg __unused) 83 { 84 linuxkpi_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor, 85 linuxkpi_thread_dtor, NULL, EVENTHANDLER_PRI_ANY); 86 } 87 SYSINIT(linux_current, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_current_init, NULL); 88 89 static void 90 linux_current_uninit(void *arg __unused) 91 { 92 EVENTHANDLER_DEREGISTER(thread_dtor, linuxkpi_thread_dtor_tag); 93 } 94 SYSUNINIT(linux_current, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_current_uninit, NULL); 95