1419b0af8Sopenharmony_ci/* 2419b0af8Sopenharmony_ci * ko_adapt.c 3419b0af8Sopenharmony_ci * 4419b0af8Sopenharmony_ci * function for find symbols not exported 5419b0af8Sopenharmony_ci * 6419b0af8Sopenharmony_ci * Copyright (C) 2022 Huawei Technologies Co., Ltd. 7419b0af8Sopenharmony_ci * 8419b0af8Sopenharmony_ci * This software is licensed under the terms of the GNU General Public 9419b0af8Sopenharmony_ci * License version 2, as published by the Free Software Foundation, and 10419b0af8Sopenharmony_ci * may be copied, distributed, and modified under those terms. 11419b0af8Sopenharmony_ci * 12419b0af8Sopenharmony_ci * This program is distributed in the hope that it will be useful, 13419b0af8Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14419b0af8Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15419b0af8Sopenharmony_ci * GNU General Public License for more details. 16419b0af8Sopenharmony_ci */ 17419b0af8Sopenharmony_ci#include "ko_adapt.h" 18419b0af8Sopenharmony_ci#include <linux/types.h> 19419b0af8Sopenharmony_ci#include <linux/mm_types.h> 20419b0af8Sopenharmony_ci#include <linux/stddef.h> 21419b0af8Sopenharmony_ci#include <linux/cred.h> 22419b0af8Sopenharmony_ci#include <linux/version.h> 23419b0af8Sopenharmony_ci#if (KERNEL_VERSION(4, 14, 0) <= LINUX_VERSION_CODE) 24419b0af8Sopenharmony_ci#include <linux/sched/task.h> 25419b0af8Sopenharmony_ci#endif 26419b0af8Sopenharmony_ci#include <linux/cpumask.h> 27419b0af8Sopenharmony_ci#include <linux/syscalls.h> 28419b0af8Sopenharmony_ci#include <linux/fs.h> 29419b0af8Sopenharmony_ci#include "tc_ns_log.h" 30419b0af8Sopenharmony_ci 31419b0af8Sopenharmony_citypedef const struct cred *(get_task_cred_func)(struct task_struct *); 32419b0af8Sopenharmony_citypedef void (kthread_bind_mask_func)(struct task_struct *, const struct cpumask *); 33419b0af8Sopenharmony_citypedef struct page *(alloc_pages_func)(gfp_t gfp_mask, unsigned int order); 34419b0af8Sopenharmony_citypedef struct workqueue_attrs *(alloc_workqueue_attrs_func)(gfp_t gfp_mask); 35419b0af8Sopenharmony_citypedef void (free_workqueue_attrs_func)(struct workqueue_attrs *attrs); 36419b0af8Sopenharmony_ci 37419b0af8Sopenharmony_ciconst struct cred *koadpt_get_task_cred(struct task_struct *task) 38419b0af8Sopenharmony_ci{ 39419b0af8Sopenharmony_ci#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) 40419b0af8Sopenharmony_ci return get_task_cred(task); 41419b0af8Sopenharmony_ci#else 42419b0af8Sopenharmony_ci static get_task_cred_func *get_task_cred_pt = NULL; 43419b0af8Sopenharmony_ci 44419b0af8Sopenharmony_ci if (!task) 45419b0af8Sopenharmony_ci return NULL; 46419b0af8Sopenharmony_ci 47419b0af8Sopenharmony_ci if (!get_task_cred_pt) { 48419b0af8Sopenharmony_ci get_task_cred_pt = (get_task_cred_func *) 49419b0af8Sopenharmony_ci (uintptr_t)kallsyms_lookup_name("get_task_cred"); 50419b0af8Sopenharmony_ci if (IS_ERR_OR_NULL(get_task_cred_pt)) { 51419b0af8Sopenharmony_ci tloge("fail to find symbol get task cred\n"); 52419b0af8Sopenharmony_ci return NULL; 53419b0af8Sopenharmony_ci } 54419b0af8Sopenharmony_ci } 55419b0af8Sopenharmony_ci return get_task_cred_pt(task); 56419b0af8Sopenharmony_ci#endif 57419b0af8Sopenharmony_ci} 58419b0af8Sopenharmony_ci 59419b0af8Sopenharmony_civoid koadpt_kthread_bind_mask(struct task_struct *task, 60419b0af8Sopenharmony_ci const struct cpumask *mask) 61419b0af8Sopenharmony_ci{ 62419b0af8Sopenharmony_ci#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) 63419b0af8Sopenharmony_ci (void)set_cpus_allowed_ptr(task, mask); 64419b0af8Sopenharmony_ci#else 65419b0af8Sopenharmony_ci static kthread_bind_mask_func *kthread_bind_mask_pt = NULL; 66419b0af8Sopenharmony_ci 67419b0af8Sopenharmony_ci if (!task || !mask) 68419b0af8Sopenharmony_ci return; 69419b0af8Sopenharmony_ci 70419b0af8Sopenharmony_ci if (!kthread_bind_mask_pt) { 71419b0af8Sopenharmony_ci kthread_bind_mask_pt = (kthread_bind_mask_func *) 72419b0af8Sopenharmony_ci (uintptr_t)kallsyms_lookup_name("kthread_bind_mask"); 73419b0af8Sopenharmony_ci if (IS_ERR_OR_NULL(kthread_bind_mask_pt)) { 74419b0af8Sopenharmony_ci tloge("fail to find symbol kthread bind mask\n"); 75419b0af8Sopenharmony_ci return; 76419b0af8Sopenharmony_ci } 77419b0af8Sopenharmony_ci } 78419b0af8Sopenharmony_ci kthread_bind_mask_pt(task, mask); 79419b0af8Sopenharmony_ci#endif 80419b0af8Sopenharmony_ci} 81419b0af8Sopenharmony_ci 82419b0af8Sopenharmony_cistruct page *koadpt_alloc_pages(gfp_t gfp_mask, unsigned int order) 83419b0af8Sopenharmony_ci{ 84419b0af8Sopenharmony_ci#ifdef CONFIG_NUMA 85419b0af8Sopenharmony_ci#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) 86419b0af8Sopenharmony_ci return alloc_pages(gfp_mask, order); 87419b0af8Sopenharmony_ci#else 88419b0af8Sopenharmony_ci static alloc_pages_func *alloc_pages_pt = NULL; 89419b0af8Sopenharmony_ci 90419b0af8Sopenharmony_ci if (!alloc_pages_pt) { 91419b0af8Sopenharmony_ci alloc_pages_pt = (alloc_pages_func *) 92419b0af8Sopenharmony_ci (uintptr_t)kallsyms_lookup_name("alloc_pages_current"); 93419b0af8Sopenharmony_ci if (IS_ERR_OR_NULL(alloc_pages_pt)) { 94419b0af8Sopenharmony_ci tloge("fail to find symbol alloc pages current\n"); 95419b0af8Sopenharmony_ci return NULL; 96419b0af8Sopenharmony_ci } 97419b0af8Sopenharmony_ci } 98419b0af8Sopenharmony_ci return alloc_pages_pt(gfp_mask, order); 99419b0af8Sopenharmony_ci#endif 100419b0af8Sopenharmony_ci#else 101419b0af8Sopenharmony_ci return alloc_pages(gfp_mask, order); 102419b0af8Sopenharmony_ci#endif 103419b0af8Sopenharmony_ci} 104419b0af8Sopenharmony_ci 105419b0af8Sopenharmony_cistruct workqueue_attrs *koadpt_alloc_workqueue_attrs(gfp_t gfp_mask) 106419b0af8Sopenharmony_ci{ 107419b0af8Sopenharmony_ci#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) 108419b0af8Sopenharmony_ci struct workqueue_attrs *attrs; 109419b0af8Sopenharmony_ci (void)gfp_mask; 110419b0af8Sopenharmony_ci 111419b0af8Sopenharmony_ci attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); 112419b0af8Sopenharmony_ci if (!attrs) { 113419b0af8Sopenharmony_ci tloge("alloc workqueue attr fail\n"); 114419b0af8Sopenharmony_ci return NULL; 115419b0af8Sopenharmony_ci } 116419b0af8Sopenharmony_ci 117419b0af8Sopenharmony_ci if (alloc_cpumask_var(&attrs->cpumask, GFP_KERNEL) == false) { 118419b0af8Sopenharmony_ci tloge("alloc cpumask var fail\n"); 119419b0af8Sopenharmony_ci kfree(attrs); 120419b0af8Sopenharmony_ci return NULL; 121419b0af8Sopenharmony_ci } 122419b0af8Sopenharmony_ci 123419b0af8Sopenharmony_ci cpumask_copy(attrs->cpumask, cpu_possible_mask); 124419b0af8Sopenharmony_ci 125419b0af8Sopenharmony_ci return attrs; 126419b0af8Sopenharmony_ci#else 127419b0af8Sopenharmony_ci static alloc_workqueue_attrs_func *alloc_workqueue_attrs_pt = NULL; 128419b0af8Sopenharmony_ci 129419b0af8Sopenharmony_ci if (!alloc_workqueue_attrs_pt) { 130419b0af8Sopenharmony_ci alloc_workqueue_attrs_pt = (alloc_workqueue_attrs_func *) 131419b0af8Sopenharmony_ci (uintptr_t)kallsyms_lookup_name("alloc_workqueue_attrs"); 132419b0af8Sopenharmony_ci if (IS_ERR_OR_NULL(alloc_workqueue_attrs_pt)) { 133419b0af8Sopenharmony_ci tloge("fail to find symbol alloc workqueue attrs\n"); 134419b0af8Sopenharmony_ci return NULL; 135419b0af8Sopenharmony_ci } 136419b0af8Sopenharmony_ci } 137419b0af8Sopenharmony_ci return alloc_workqueue_attrs_pt(gfp_mask); 138419b0af8Sopenharmony_ci#endif 139419b0af8Sopenharmony_ci} 140419b0af8Sopenharmony_ci 141419b0af8Sopenharmony_civoid koadpt_free_workqueue_attrs(struct workqueue_attrs *attrs) 142419b0af8Sopenharmony_ci{ 143419b0af8Sopenharmony_ci#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) 144419b0af8Sopenharmony_ci if (!attrs) 145419b0af8Sopenharmony_ci return; 146419b0af8Sopenharmony_ci 147419b0af8Sopenharmony_ci free_cpumask_var(attrs->cpumask); 148419b0af8Sopenharmony_ci kfree(attrs); 149419b0af8Sopenharmony_ci#else 150419b0af8Sopenharmony_ci static free_workqueue_attrs_func *free_workqueue_attrs_pt = NULL; 151419b0af8Sopenharmony_ci 152419b0af8Sopenharmony_ci if (!attrs) 153419b0af8Sopenharmony_ci return; 154419b0af8Sopenharmony_ci 155419b0af8Sopenharmony_ci if (!free_workqueue_attrs_pt) { 156419b0af8Sopenharmony_ci free_workqueue_attrs_pt = (free_workqueue_attrs_func *) 157419b0af8Sopenharmony_ci (uintptr_t)kallsyms_lookup_name("free_workqueue_attrs"); 158419b0af8Sopenharmony_ci if (IS_ERR_OR_NULL(free_workqueue_attrs_pt)) { 159419b0af8Sopenharmony_ci tloge("fail to find symbol free workqueue attrs\n"); 160419b0af8Sopenharmony_ci return; 161419b0af8Sopenharmony_ci } 162419b0af8Sopenharmony_ci } 163419b0af8Sopenharmony_ci free_workqueue_attrs_pt(attrs); 164419b0af8Sopenharmony_ci#endif 165419b0af8Sopenharmony_ci}