11e3db1deSHans Petter Selasky /*- 21e3db1deSHans Petter Selasky * Copyright (c) 2017 Hans Petter Selasky 31e3db1deSHans Petter Selasky * All rights reserved. 41e3db1deSHans Petter Selasky * 51e3db1deSHans Petter Selasky * Redistribution and use in source and binary forms, with or without 61e3db1deSHans Petter Selasky * modification, are permitted provided that the following conditions 71e3db1deSHans Petter Selasky * are met: 81e3db1deSHans Petter Selasky * 1. Redistributions of source code must retain the above copyright 91e3db1deSHans Petter Selasky * notice unmodified, this list of conditions, and the following 101e3db1deSHans Petter Selasky * disclaimer. 111e3db1deSHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright 121e3db1deSHans Petter Selasky * notice, this list of conditions and the following disclaimer in the 131e3db1deSHans Petter Selasky * documentation and/or other materials provided with the distribution. 141e3db1deSHans Petter Selasky * 151e3db1deSHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161e3db1deSHans Petter Selasky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171e3db1deSHans Petter Selasky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181e3db1deSHans Petter Selasky * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191e3db1deSHans Petter Selasky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201e3db1deSHans Petter Selasky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211e3db1deSHans Petter Selasky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221e3db1deSHans Petter Selasky * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231e3db1deSHans Petter Selasky * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241e3db1deSHans Petter Selasky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251e3db1deSHans Petter Selasky */ 261e3db1deSHans Petter Selasky 271e3db1deSHans Petter Selasky #include <sys/cdefs.h> 281e3db1deSHans Petter Selasky __FBSDID("$FreeBSD$"); 291e3db1deSHans Petter Selasky 301e3db1deSHans Petter Selasky #include <linux/compat.h> 311e3db1deSHans Petter Selasky #include <linux/mm.h> 321e3db1deSHans Petter Selasky #include <linux/kthread.h> 331e3db1deSHans Petter Selasky 341e3db1deSHans Petter Selasky #include <sys/kernel.h> 351e3db1deSHans Petter Selasky #include <sys/eventhandler.h> 361e3db1deSHans Petter Selasky #include <sys/malloc.h> 371e3db1deSHans Petter Selasky 381e3db1deSHans Petter Selasky static eventhandler_tag linuxkpi_thread_dtor_tag; 391e3db1deSHans Petter Selasky 401e3db1deSHans Petter Selasky static MALLOC_DEFINE(M_LINUX_CURRENT, "linuxcurrent", "LinuxKPI task structure"); 411e3db1deSHans Petter Selasky 421e3db1deSHans Petter Selasky int 431e3db1deSHans Petter Selasky linux_alloc_current(struct thread *td, int flags) 441e3db1deSHans Petter Selasky { 451e3db1deSHans Petter Selasky struct task_struct *ts; 461e3db1deSHans Petter Selasky 471e3db1deSHans Petter Selasky MPASS(td->td_lkpi_task == NULL); 481e3db1deSHans Petter Selasky 491e3db1deSHans Petter Selasky ts = malloc(sizeof(*ts), M_LINUX_CURRENT, flags | M_ZERO); 501e3db1deSHans Petter Selasky if (ts == NULL) 511e3db1deSHans Petter Selasky return (ENOMEM); 521e3db1deSHans Petter Selasky 531e3db1deSHans Petter Selasky atomic_set(&ts->kthread_flags, 0); 541e3db1deSHans Petter Selasky ts->task_thread = td; 551e3db1deSHans Petter Selasky ts->comm = td->td_name; 561e3db1deSHans Petter Selasky ts->pid = td->td_tid; 571e3db1deSHans Petter Selasky ts->state = TASK_RUNNING; 581e3db1deSHans Petter Selasky td->td_lkpi_task = ts; 591e3db1deSHans Petter Selasky return (0); 601e3db1deSHans Petter Selasky } 611e3db1deSHans Petter Selasky 621e3db1deSHans Petter Selasky void 631e3db1deSHans Petter Selasky linux_free_current(struct task_struct *ts) 641e3db1deSHans Petter Selasky { 651e3db1deSHans Petter Selasky free(ts, M_LINUX_CURRENT); 661e3db1deSHans Petter Selasky } 671e3db1deSHans Petter Selasky 681e3db1deSHans Petter Selasky static void 691e3db1deSHans Petter Selasky linuxkpi_thread_dtor(void *arg __unused, struct thread *td) 701e3db1deSHans Petter Selasky { 711e3db1deSHans Petter Selasky struct task_struct *ts; 721e3db1deSHans Petter Selasky 731e3db1deSHans Petter Selasky ts = td->td_lkpi_task; 741e3db1deSHans Petter Selasky if (ts == NULL) 751e3db1deSHans Petter Selasky return; 761e3db1deSHans Petter Selasky 771e3db1deSHans Petter Selasky td->td_lkpi_task = NULL; 781e3db1deSHans Petter Selasky free(ts, M_LINUX_CURRENT); 791e3db1deSHans Petter Selasky } 801e3db1deSHans Petter Selasky 811e3db1deSHans Petter Selasky static void 821e3db1deSHans Petter Selasky linux_current_init(void *arg __unused) 831e3db1deSHans Petter Selasky { 841e3db1deSHans Petter Selasky linuxkpi_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor, 851e3db1deSHans Petter Selasky linuxkpi_thread_dtor, NULL, EVENTHANDLER_PRI_ANY); 861e3db1deSHans Petter Selasky } 871e3db1deSHans Petter Selasky SYSINIT(linux_current, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_current_init, NULL); 881e3db1deSHans Petter Selasky 891e3db1deSHans Petter Selasky static void 901e3db1deSHans Petter Selasky linux_current_uninit(void *arg __unused) 911e3db1deSHans Petter Selasky { 921e3db1deSHans Petter Selasky EVENTHANDLER_DEREGISTER(thread_dtor, linuxkpi_thread_dtor_tag); 931e3db1deSHans Petter Selasky } 941e3db1deSHans Petter Selasky SYSUNINIT(linux_current, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_current_uninit, NULL); 95