--- zzzz-none-000/linux-4.4.60/kernel/module.c 2017-04-08 07:53:53.000000000 +0000 +++ dragonfly-4020-701/linux-4.4.60/kernel/module.c 2018-11-08 13:36:17.000000000 +0000 @@ -61,6 +61,12 @@ #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) ---*/ #define CREATE_TRACE_POINTS #include @@ -275,6 +281,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 +704,11 @@ { struct module *mod; unsigned int cpu; - +#if defined(CONFIG_AVM_FASTIRQ) + if(!firq_is_linux_context()) { + return false; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { @@ -782,6 +795,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 @@ -1013,6 +1032,9 @@ /* 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: @@ -1261,6 +1283,7 @@ static const char vermagic[] = VERMAGIC_STRING; +#ifdef CONFIG_MODVERSIONS static int try_to_force_load(struct module *mod, const char *reason) { #ifdef CONFIG_MODULE_FORCE_LOAD @@ -1273,7 +1296,6 @@ #endif } -#ifdef CONFIG_MODVERSIONS /* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */ static unsigned long maybe_relocated(unsigned long crc, const struct module *crc_owner) @@ -1466,6 +1488,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 +1504,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 +1534,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 +1564,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]; @@ -1987,10 +2058,13 @@ static void unset_module_init_ro_nx(struct module *mod) { } #endif +#if !defined(CONFIG_AVM_ENHANCED) || !defined(CONFIG_MIPS) +/*--- mbahr@avm.de: special case distingtion (kseg0/kseg1 vs virtual) free for mips ---*/ void __weak module_memfree(void *module_region) { vfree(module_region); } +#endif /*--- #if !defined(CONFIG_AVM_ENHANCED) || !defined(CONFIG_MIPS) ---*/ void __weak module_arch_cleanup(struct module *mod) { @@ -2046,6 +2120,12 @@ /* 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); @@ -2573,10 +2653,17 @@ ddebug_remove_module(debug->modname); } +#if !defined(CONFIG_AVM_ENHANCED) void * __weak module_alloc(unsigned long size) { return vmalloc_exec(size); } +#endif/*--- #if !defined(CONFIG_AVM_ENHANCED) ---*/ + +#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, @@ -2864,6 +2951,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 +2977,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 +3077,11 @@ void *ptr; /* Do the allocs. */ - ptr = module_alloc(mod->core_size); + ptr = module_alloc(mod->core_size +#if defined(CONFIG_AVM_ENHANCED) + , mod->name , module_alloc_type_core +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + ); /* * 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 +3095,11 @@ mod->module_core = ptr; if (mod->init_size) { - ptr = module_alloc(mod->init_size); + ptr = module_alloc(mod->init_size +#if defined(CONFIG_AVM_ENHANCED) + , mod->name , module_alloc_type_init +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + ); /* * The pointer to this block is stored in the module structure * which is inside the block. This block doesn't need to be @@ -3421,6 +3518,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 +3665,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 +3845,12 @@ const char *ret = NULL; struct module *mod; +#if defined(CONFIG_AVM_FASTIRQ) + if(!firq_is_linux_context()) { + return NULL; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + preempt_disable(); mod = __module_address(addr); if (mod) { @@ -3751,6 +3872,12 @@ { struct module *mod; +#if defined(CONFIG_AVM_FASTIRQ) + if(!firq_is_linux_context()) { + 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 +3902,11 @@ unsigned long *offset, char *modname, char *name) { struct module *mod; +#if defined(CONFIG_AVM_FASTIRQ) + if(!firq_is_linux_context()) { + return -ERANGE; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { @@ -3804,6 +3936,12 @@ { struct module *mod; +#if defined(CONFIG_AVM_FASTIRQ) + if(!firq_is_linux_context()) { + return -ERANGE; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { struct mod_kallsyms *kallsyms; @@ -3845,6 +3983,11 @@ char *colon; unsigned long ret = 0; +#if defined(CONFIG_AVM_FASTIRQ) + if(!firq_is_linux_context()) { + 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 +4070,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 +4144,11 @@ { const struct exception_table_entry *e = NULL; struct module *mod; +#if defined(CONFIG_AVM_FASTIRQ) + if(!firq_is_linux_context()) { + return e; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { @@ -4028,6 +4181,11 @@ { bool ret; +#if defined(CONFIG_AVM_FASTIRQ) + if(!firq_is_linux_context()) { + return false; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ preempt_disable(); ret = __module_address(addr) != NULL; preempt_enable(); @@ -4072,7 +4230,11 @@ bool is_module_text_address(unsigned long addr) { bool ret; - +#if defined(CONFIG_AVM_FASTIRQ) + if(!firq_is_linux_context()) { + return false; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ preempt_disable(); ret = __module_text_address(addr) != NULL; preempt_enable(); @@ -4106,6 +4268,12 @@ struct module *mod; char buf[8]; +#if defined(CONFIG_AVM_FASTIRQ) + if(!firq_is_linux_context()) { + 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 +4283,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