--- zzzz-none-000/linux-4.4.60/kernel/module.c 2017-04-08 07:53:53.000000000 +0000 +++ scorpion-7490-727/linux-4.4.60/kernel/module.c 2021-02-04 17:41:59.000000000 +0000 @@ -61,6 +61,14 @@ #include #include #include "module-internal.h" +#if defined(CONFIG_AVM_FASTIRQ) +#include +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ +#if defined(CONFIG_BUG_EXTRA_INFO) +#include +#endif/*--- #if defined(CONFIG_BUG_EXTRA_INFO) ---*/ + +#include #define CREATE_TRACE_POINTS #include @@ -275,6 +283,9 @@ #ifdef CONFIG_KGDB_KDB struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ #endif /* CONFIG_KGDB_KDB */ +#ifdef CONFIG_CRASHLOG +struct list_head *crashlog_modules = &modules; +#endif static void module_assert_mutex(void) { @@ -695,7 +706,11 @@ { struct module *mod; unsigned int cpu; - +#if defined(CONFIG_AVM_FASTIRQ) + if(firq_is_avm_rte_restricted_mem_access()) { + return false; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { @@ -782,6 +797,12 @@ MODINFO_ATTR(srcversion); static char last_unloaded_module[MODULE_NAME_LEN+1]; +#if defined(CONFIG_AVM_BOOTMEM) +static unsigned long last_unloaded_module_jiffies; +/*--- Berechnung bei ARCH_DMA_MINALIGN = 32 Byte korrekt, solange size <= 128 Byte ---*/ +#define MY_ALIGN_BIT (ffs(ARCH_DMA_MINALIGN) - 1) +#define SLAB_ORG_SIZE(size) (((((size-1) >> MY_ALIGN_BIT) + 1) << MY_ALIGN_BIT)) +#endif/*--- defined(CONFIG_AVM_BOOTMEM) ---*/ #ifdef CONFIG_MODULE_UNLOAD @@ -955,7 +976,7 @@ { struct module *mod; char name[MODULE_NAME_LEN]; - int ret, forced = 0; + int ret, forced = 0, status; if (!capable(CAP_SYS_MODULE) || modules_disabled) return -EPERM; @@ -1006,13 +1027,21 @@ /* Final destruction now no one is using it. */ if (mod->exit != NULL) mod->exit(); - blocking_notifier_call_chain(&module_notify_list, + status = blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod); +#if defined(CONFIG_AVM_ENHANCED) + if(status == NOTIFY_BAD) { + return -EBUSY; + } +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ async_synchronize_full(); /* Store the name of the last unloaded module for diagnostic purposes */ strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); +#if defined(CONFIG_AVM_BOOTMEM) + last_unloaded_module_jiffies = jiffies; +#endif/*--- #if defined(CONFIG_AVM_BOOTMEM) ---*/ free_module(mod); return 0; out: @@ -1466,6 +1495,11 @@ struct module_sect_attrs { struct attribute_group grp; unsigned int nsections; +#if defined(CONFIG_AVM_BOOTMEM) + unsigned char *names_ptr; + unsigned int names_size; + unsigned int slab_names_size; +#endif/*--- #if defined(CONFIG_AVM_BOOTMEM) ---*/ struct module_sect_attr attrs[0]; }; @@ -1477,10 +1511,24 @@ return sprintf(buf, "0x%pK\n", (void *)sattr->address); } +#if defined(CONFIG_AVM_BOOTMEM) +static unsigned int global_modulesymbol_namesize; +static unsigned int global_modulesymbol_entries; +static unsigned int global_modulesymbol_slabsize; +#endif/*--- #if defined(CONFIG_AVM_BOOTMEM) ---*/ + static void free_sect_attrs(struct module_sect_attrs *sect_attrs) { unsigned int section; +#if defined(CONFIG_AVM_BOOTMEM) + if(sect_attrs->names_ptr) { + global_modulesymbol_namesize -= sect_attrs->names_size; + global_modulesymbol_entries -= sect_attrs->nsections; + global_modulesymbol_slabsize -= sect_attrs->slab_names_size; + free_pages_exact(sect_attrs->names_ptr, sect_attrs->names_size); + } else +#endif/*--- #if defined(CONFIG_AVM_BOOTMEM) ---*/ for (section = 0; section < sect_attrs->nsections; section++) kfree(sect_attrs->attrs[section].name); kfree(sect_attrs); @@ -1493,10 +1541,25 @@ struct module_sect_attr *sattr; struct attribute **gattr; +#if defined(CONFIG_AVM_BOOTMEM) + unsigned int needed_size, sum_slab_names_size = 0, sum_names_size = 0, name_size; + unsigned char *names_ptr = NULL; + /* Count loaded sections and allocate structures */ + for (i = 0; i < info->hdr->e_shnum; i++) { + Elf_Shdr *sec = &info->sechdrs[i]; + if (sect_empty(sec)) + continue; + nloaded++; + name_size = strlen(info->secstrings + sec->sh_name) + 1; + sum_names_size += name_size; + sum_slab_names_size += SLAB_ORG_SIZE(name_size); + } +#else/*--- #if defined(CONFIG_AVM_BOOTMEM) ---*/ /* Count loaded sections and allocate structures */ for (i = 0; i < info->hdr->e_shnum; i++) if (!sect_empty(&info->sechdrs[i])) nloaded++; +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_BOOTMEM) ---*/ size[0] = ALIGN(sizeof(*sect_attrs) + nloaded * sizeof(sect_attrs->attrs[0]), sizeof(sect_attrs->grp.attrs[0])); @@ -1508,6 +1571,21 @@ /* Setup section attributes. */ sect_attrs->grp.name = "sections"; sect_attrs->grp.attrs = (void *)sect_attrs + size[0]; +#if defined(CONFIG_AVM_BOOTMEM) + needed_size = (sum_names_size + PAGE_SIZE - 1) & PAGE_MASK; + if(needed_size < sum_slab_names_size) { + names_ptr = alloc_pages_exact(needed_size, GFP_KERNEL | __GFP_ZERO); + if(names_ptr) { + sect_attrs->names_ptr = names_ptr; + sect_attrs->names_size = needed_size; + sect_attrs->slab_names_size = sum_slab_names_size; + global_modulesymbol_namesize += needed_size; + global_modulesymbol_entries += nloaded; + global_modulesymbol_slabsize += sum_slab_names_size; + /*--- printk(KERN_INFO"%s: symbols=%u size=%u(%u) saved-memory=%u byte\n", __func__, nloaded, needed_size, sum_names_size, sum_slab_names_size - needed_size); ---*/ + } + } +#endif/*--- #if defined(CONFIG_AVM_BOOTMEM) ---*/ sect_attrs->nsections = 0; sattr = §_attrs->attrs[0]; @@ -2039,16 +2117,22 @@ /* This may be NULL, but that's OK */ unset_module_init_ro_nx(mod); module_arch_freeing_init(mod); - module_memfree(mod->module_init); + avm_module_mem_free(mod->module_init); kfree(mod->args); percpu_modfree(mod); /* Free lock-classes; relies on the preceding sync_rcu(). */ lockdep_free_key_range(mod->module_core, mod->core_size); +#if defined(CONFIG_BUG_EXTRA_INFO) + if(!IS_ERR_OR_NULL(release_bug_debug_table)){ + release_bug_debug_table(mod->name); + } +#endif/*--- #if defined(CONFIG_BUG_EXTRA_INFO) ---*/ + /* Finally, free the core (containing the module structure) */ unset_module_core_ro_nx(mod); - module_memfree(mod->module_core); + avm_module_mem_free(mod->module_core); #ifdef CONFIG_MPU update_protections(current->mm); @@ -2578,6 +2662,11 @@ return vmalloc_exec(size); } +#if defined(CONFIG_AVM_ENHANCED) && defined(CONFIG_MIPS) +/*--- mbahr@avm.de: if we use KSEG0 it produce a kmemleak-warning: unknown object ???? ---*/ +#undef CONFIG_DEBUG_KMEMLEAK +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) && defined(CONFIG_MIPS) ---*/ + #ifdef CONFIG_DEBUG_KMEMLEAK static void kmemleak_load_module(const struct module *mod, const struct load_info *info) @@ -2864,6 +2953,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags) { +#ifndef CONFIG_MODULE_STRIPPED const char *modmagic = get_modinfo(info, "vermagic"); int err; @@ -2889,6 +2979,7 @@ pr_warn("%s: module is from the staging directory, the quality " "is unknown, you have been warned.\n", mod->name); } +#endif /* Set up license info based on the info section */ set_license(mod, get_modinfo(info, "license")); @@ -2988,7 +3079,7 @@ void *ptr; /* Do the allocs. */ - ptr = module_alloc(mod->core_size); + ptr = avm_module_mem_alloc(mod, mod->core_size, avm_module_mem_type_core); /* * The pointer to this block is stored in the module structure * which is inside the block. Just mark it as not being a @@ -3002,7 +3093,7 @@ mod->module_core = ptr; if (mod->init_size) { - ptr = module_alloc(mod->init_size); + ptr = avm_module_mem_alloc(mod, mod->init_size, avm_module_mem_type_init); /* * The pointer to this block is stored in the module structure * which is inside the block. This block doesn't need to be @@ -3011,7 +3102,7 @@ */ kmemleak_ignore(ptr); if (!ptr) { - module_memfree(mod->module_core); + avm_module_mem_free(mod->module_core); return -ENOMEM; } memset(ptr, 0, mod->init_size); @@ -3157,8 +3248,8 @@ { percpu_modfree(mod); module_arch_freeing_init(mod); - module_memfree(mod->module_init); - module_memfree(mod->module_core); + avm_module_mem_free(mod->module_init); + avm_module_mem_free(mod->module_core); } int __weak module_finalize(const Elf_Ehdr *hdr, @@ -3225,7 +3316,7 @@ static void do_free_init(struct rcu_head *head) { struct mod_initfree *m = container_of(head, struct mod_initfree, rcu); - module_memfree(m->module_init); + avm_module_mem_free(m->module_init); kfree(m); } @@ -3421,6 +3512,21 @@ mutex_unlock(&module_mutex); return err; } +#if defined(CONFIG_BUG_EXTRA_INFO) +/*--------------------------------------------------------------------------------*\ +\*--------------------------------------------------------------------------------*/ +static void __register_module_bugtable(struct module *mod, struct load_info *info) { + struct bug_debug_table_entry *bug_info; + unsigned int num_bug_info; + bug_info = section_objs(info, "__bug_debug_table", + sizeof(struct bug_debug_table_entry), &num_bug_info); + + /*--- printk(KERN_INFO"%s: %s: bug_info_start: %p num=%u\n", __func__, mod->name, bug_info, num_bug_info); ---*/ + if(num_bug_info && bug_info) { + register_bug_debug_table(mod->name, (unsigned long)bug_info, (unsigned long)&bug_info[num_bug_info]); + } +} +#endif/*--- #if defined(CONFIG_BUG_EXTRA_INFO) ---*/ static int unknown_module_param_cb(char *param, char *val, const char *modname, void *arg) @@ -3553,6 +3659,9 @@ if (err < 0) goto bug_cleanup; +#if defined(CONFIG_BUG_EXTRA_INFO) + __register_module_bugtable(mod, info); +#endif/*--- #if defined(CONFIG_BUG_EXTRA_INFO) ---*/ /* Get rid of temporary copy. */ free_copy(info); @@ -3730,6 +3839,12 @@ const char *ret = NULL; struct module *mod; +#if defined(CONFIG_AVM_FASTIRQ) + if(firq_is_avm_rte_restricted_mem_access()) { + return NULL; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + preempt_disable(); mod = __module_address(addr); if (mod) { @@ -3751,6 +3866,12 @@ { struct module *mod; +#if defined(CONFIG_AVM_FASTIRQ) + if(firq_is_avm_rte_restricted_mem_access()) { + return -ERANGE; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (mod->state == MODULE_STATE_UNFORMED) @@ -3775,6 +3896,11 @@ unsigned long *offset, char *modname, char *name) { struct module *mod; +#if defined(CONFIG_AVM_FASTIRQ) + if(firq_is_avm_rte_restricted_mem_access()) { + return -ERANGE; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { @@ -3804,6 +3930,12 @@ { struct module *mod; +#if defined(CONFIG_AVM_FASTIRQ) + if(firq_is_avm_rte_restricted_mem_access()) { + return -ERANGE; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { struct mod_kallsyms *kallsyms; @@ -3845,6 +3977,11 @@ char *colon; unsigned long ret = 0; +#if defined(CONFIG_AVM_FASTIRQ) + if(firq_is_avm_rte_restricted_mem_access()) { + return ret; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ /* Don't lock: we're in enough trouble already. */ preempt_disable(); if ((colon = strchr(name, ':')) != NULL) { @@ -3927,6 +4064,11 @@ static void m_stop(struct seq_file *m, void *p) { +#if defined(CONFIG_AVM_BOOTMEM) && defined(CONFIG_KALLSYM) + if(strcmp(current->comm, "cat") == 0) { + seq_printf(m, "sum of module-symbols: %u (%u KiB) saved-memory %u KiB\n", global_modulesymbol_entries, global_modulesymbol_namesize / 1000, (global_modulesymbol_slabsize - global_modulesymbol_namesize) / 1000); + } +#endif/*--- #if defined(CONFIG_AVM_BOOTMEM) ---*/ mutex_unlock(&module_mutex); } @@ -3996,6 +4138,11 @@ { const struct exception_table_entry *e = NULL; struct module *mod; +#if defined(CONFIG_AVM_FASTIRQ) + if(firq_is_avm_rte_restricted_mem_access()) { + return e; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { @@ -4028,6 +4175,11 @@ { bool ret; +#if defined(CONFIG_AVM_FASTIRQ) + if(firq_is_avm_rte_restricted_mem_access()) { + return false; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ preempt_disable(); ret = __module_address(addr) != NULL; preempt_enable(); @@ -4072,7 +4224,11 @@ bool is_module_text_address(unsigned long addr) { bool ret; - +#if defined(CONFIG_AVM_FASTIRQ) + if(firq_is_avm_rte_restricted_mem_access()) { + return false; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ preempt_disable(); ret = __module_text_address(addr) != NULL; preempt_enable(); @@ -4106,6 +4262,12 @@ struct module *mod; char buf[8]; +#if defined(CONFIG_AVM_FASTIRQ) + if(firq_is_avm_rte_restricted_mem_access()) { + return; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + printk(KERN_DEFAULT "Modules linked in:"); /* Most callers should already have preempt disabled, but make sure */ preempt_disable(); @@ -4115,9 +4277,17 @@ pr_cont(" %s%s", mod->name, module_flags(mod, buf)); } preempt_enable(); - if (last_unloaded_module[0]) - pr_cont(" [last unloaded: %s]", last_unloaded_module); - pr_cont("\n"); + if (last_unloaded_module[0]) { +#if defined(CONFIG_AVM_BOOTMEM) + + struct timespec sincetime; + jiffies_to_timespec(jiffies - last_unloaded_module_jiffies, &sincetime); + printk(" [last unloaded: %s before %lu.%03lu s]", last_unloaded_module, sincetime.tv_sec, sincetime.tv_nsec / (1000* 1000)); +#else/*--- #if defined(CONFIG_AVM_BOOTMEM) ---*/ + printk(" [last unloaded: %s]", last_unloaded_module); +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_BOOTMEM) ---*/ + } + printk("\n"); } #ifdef CONFIG_MODVERSIONS