Skip to content

Commit 055f23b

Browse files
author
Jessica Yu
committed
module: check for exit sections in layout_sections() instead of module_init_section()
Previously, when CONFIG_MODULE_UNLOAD=n, the module loader just does not attempt to load exit sections since it never expects that any code in those sections will ever execute. However, dynamic code patching (alternatives, jump_label and static_call) can have sites in __exit code, even if __exit is never executed. Therefore __exit must be present at runtime, at least for as long as __init code is. Commit 3312134 ("module: treat exit sections the same as init sections when !CONFIG_MODULE_UNLOAD") solves the requirements of jump_labels and static_calls by putting the exit sections in the init region of the module so that they are at least present at init, and discarded afterwards. It does this by including a check for exit sections in module_init_section(), so that it also returns true for exit sections, and the module loader will automatically sort them in the init region of the module. However, the solution there was not completely arch-independent. ARM is a special case where it supplies its own module_{init, exit}_section() functions. Instead of pushing the exit section checks into module_init_section(), just implement the exit section check in layout_sections(), so that we don't have to touch arch-dependent code. Fixes: 3312134 ("module: treat exit sections the same as init sections when !CONFIG_MODULE_UNLOAD") Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Signed-off-by: Jessica Yu <jeyu@kernel.org>
1 parent 6efb943 commit 055f23b

1 file changed

Lines changed: 11 additions & 6 deletions

File tree

kernel/module.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2401,6 +2401,15 @@ static long get_offset(struct module *mod, unsigned int *size,
24012401
return ret;
24022402
}
24032403

2404+
static bool module_init_layout_section(const char *sname)
2405+
{
2406+
#ifndef CONFIG_MODULE_UNLOAD
2407+
if (module_exit_section(sname))
2408+
return true;
2409+
#endif
2410+
return module_init_section(sname);
2411+
}
2412+
24042413
/*
24052414
* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld
24062415
* might -- code, read-only data, read-write data, small data. Tally
@@ -2435,7 +2444,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
24352444
if ((s->sh_flags & masks[m][0]) != masks[m][0]
24362445
|| (s->sh_flags & masks[m][1])
24372446
|| s->sh_entsize != ~0UL
2438-
|| module_init_section(sname))
2447+
|| module_init_layout_section(sname))
24392448
continue;
24402449
s->sh_entsize = get_offset(mod, &mod->core_layout.size, s, i);
24412450
pr_debug("\t%s\n", sname);
@@ -2468,7 +2477,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
24682477
if ((s->sh_flags & masks[m][0]) != masks[m][0]
24692478
|| (s->sh_flags & masks[m][1])
24702479
|| s->sh_entsize != ~0UL
2471-
|| !module_init_section(sname))
2480+
|| !module_init_layout_section(sname))
24722481
continue;
24732482
s->sh_entsize = (get_offset(mod, &mod->init_layout.size, s, i)
24742483
| INIT_OFFSET_MASK);
@@ -2807,11 +2816,7 @@ void * __weak module_alloc(unsigned long size)
28072816

28082817
bool __weak module_init_section(const char *name)
28092818
{
2810-
#ifndef CONFIG_MODULE_UNLOAD
2811-
return strstarts(name, ".init") || module_exit_section(name);
2812-
#else
28132819
return strstarts(name, ".init");
2814-
#endif
28152820
}
28162821

28172822
bool __weak module_exit_section(const char *name)

0 commit comments

Comments
 (0)