From b92021b09df70c1609e3547f3d6128dd560be97f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 15 Mar 2013 15:04:17 +1030 Subject: CONFIG_SYMBOL_PREFIX: cleanup. We have CONFIG_SYMBOL_PREFIX, which three archs define to the string "_". But Al Viro broke this in "consolidate cond_syscall and SYSCALL_ALIAS declarations" (in linux-next), and he's not the first to do so. Using CONFIG_SYMBOL_PREFIX is awkward, since we usually just want to prefix it so something. So various places define helpers which are defined to nothing if CONFIG_SYMBOL_PREFIX isn't set: 1) include/asm-generic/unistd.h defines __SYMBOL_PREFIX. 2) include/asm-generic/vmlinux.lds.h defines VMLINUX_SYMBOL(sym) 3) include/linux/export.h defines MODULE_SYMBOL_PREFIX. 4) include/linux/kernel.h defines SYMBOL_PREFIX (which differs from #7) 5) kernel/modsign_certificate.S defines ASM_SYMBOL(sym) 6) scripts/modpost.c defines MODULE_SYMBOL_PREFIX 7) scripts/Makefile.lib defines SYMBOL_PREFIX on the commandline if CONFIG_SYMBOL_PREFIX is set, so that we have a non-string version for pasting. (arch/h8300/include/asm/linkage.h defines SYMBOL_NAME(), too). Let's solve this properly: 1) No more generic prefix, just CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX. 2) Make linux/export.h usable from asm. 3) Define VMLINUX_SYMBOL() and VMLINUX_SYMBOL_STR(). 4) Make everyone use them. Signed-off-by: Rusty Russell Reviewed-by: James Hogan Tested-by: James Hogan (metag) --- kernel/module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel/module.c') diff --git a/kernel/module.c b/kernel/module.c index 0925c9a7197..cfd4a3f68d7 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1209,7 +1209,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, /* Since this should be found in kernel (which can't be removed), * no locking is necessary. */ - if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, + if (!find_symbol(VMLINUX_SYMBOL_STR(module_layout), NULL, &crc, true, false)) BUG(); return check_version(sechdrs, versindex, "module_layout", mod, crc, -- cgit v1.2.3-70-g09d2 From a4b6a77b77ba4f526392612c2365797fab956014 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Mon, 18 Mar 2013 19:38:56 +1030 Subject: module: fix symbol versioning with symbol prefixes Fix symbol versioning on architectures with symbol prefixes. Although the build was free from warnings the actual modules still wouldn't load as the ____versions table contained unprefixed symbol names, which were being compared against the prefixed symbol names when checking the symbol versions. This is fixed by modifying modpost to add the symbol prefix to the ____versions table it outputs (Modules.symvers still contains unprefixed symbol names). The check_modstruct_version() function is also fixed as it checks the version of the unprefixed "module_layout" symbol which would no longer work. Signed-off-by: James Hogan Cc: Michal Marek Cc: Sam Ravnborg Cc: Greg Kroah-Hartman Cc: Jonathan Kliegman Signed-off-by: Rusty Russell (use VMLINUX_SYMBOL_STR) --- kernel/module.c | 3 ++- scripts/mod/modpost.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'kernel/module.c') diff --git a/kernel/module.c b/kernel/module.c index cfd4a3f68d7..3c2c72d3bf8 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1212,7 +1212,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, if (!find_symbol(VMLINUX_SYMBOL_STR(module_layout), NULL, &crc, true, false)) BUG(); - return check_version(sechdrs, versindex, "module_layout", mod, crc, + return check_version(sechdrs, versindex, + VMLINUX_SYMBOL_STR(module_layout), mod, crc, NULL); } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 282decfa29a..f6913db7762 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1928,7 +1928,8 @@ static int add_versions(struct buffer *b, struct module *mod) s->name, mod->name); continue; } - buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name); + buf_printf(b, "\t{ %#8x, VMLINUX_SYMBOL_STR(%s) },\n", + s->crc, s->name); } buf_printf(b, "};\n"); -- cgit v1.2.3-70-g09d2 From 944a1fa01266aa9ace607f29551b73c41e9440e9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 17 Apr 2013 13:20:03 +0930 Subject: module: don't unlink the module until we've removed all exposure. Otherwise we get a race between unload and reload of the same module: the new module doesn't see the old one in the list, but then fails because it can't register over the still-extant entries in sysfs: [ 103.981925] ------------[ cut here ]------------ [ 103.986902] WARNING: at fs/sysfs/dir.c:536 sysfs_add_one+0xab/0xd0() [ 103.993606] Hardware name: CrownBay Platform [ 103.998075] sysfs: cannot create duplicate filename '/module/pch_gbe' [ 104.004784] Modules linked in: pch_gbe(+) [last unloaded: pch_gbe] [ 104.011362] Pid: 3021, comm: modprobe Tainted: G W 3.9.0-rc5+ #5 [ 104.018662] Call Trace: [ 104.021286] [] warn_slowpath_common+0x6d/0xa0 [ 104.026933] [] ? sysfs_add_one+0xab/0xd0 [ 104.031986] [] ? sysfs_add_one+0xab/0xd0 [ 104.037000] [] warn_slowpath_fmt+0x2e/0x30 [ 104.042188] [] sysfs_add_one+0xab/0xd0 [ 104.046982] [] create_dir+0x5e/0xa0 [ 104.051633] [] sysfs_create_dir+0x78/0xd0 [ 104.056774] [] kobject_add_internal+0x83/0x1f0 [ 104.062351] [] ? kvasprintf+0x46/0x60 [ 104.067231] [] kobject_add_varg+0x2d/0x50 [ 104.072450] [] kobject_init_and_add+0x27/0x30 [ 104.078075] [] mod_sysfs_setup+0x80/0x540 [ 104.083207] [] ? module_bug_finalize+0x51/0xc0 [ 104.088720] [] load_module+0x1429/0x18b0 We can teardown sysfs first, then to be sure, put the state in MODULE_STATE_UNFORMED so it's ignored while we deconstruct it. Reported-by: Veaceslav Falico Tested-by: Veaceslav Falico Signed-off-by: Rusty Russell --- kernel/module.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'kernel/module.c') diff --git a/kernel/module.c b/kernel/module.c index 3c2c72d3bf8..b049939177f 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1862,12 +1862,12 @@ static void free_module(struct module *mod) { trace_module_free(mod); - /* Delete from various lists */ - mutex_lock(&module_mutex); - stop_machine(__unlink_module, mod, NULL); - mutex_unlock(&module_mutex); mod_sysfs_teardown(mod); + /* We leave it in list to prevent duplicate loads, but make sure + * that noone uses it while it's being deconstructed. */ + mod->state = MODULE_STATE_UNFORMED; + /* Remove dynamic debug info */ ddebug_remove_module(mod->name); @@ -1880,6 +1880,11 @@ static void free_module(struct module *mod) /* Free any allocated parameters. */ destroy_params(mod->kp, mod->num_kp); + /* Now we can delete it from the lists */ + mutex_lock(&module_mutex); + stop_machine(__unlink_module, mod, NULL); + mutex_unlock(&module_mutex); + /* This may be NULL, but that's OK */ unset_module_init_ro_nx(mod); module_free(mod, mod->module_init); -- cgit v1.2.3-70-g09d2