Skip to content

Commit 705d43d

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching
Pull livepatching fixes from Jiri Kosina: - regression (from 4.4) fix for ordering issue, introduced by an earlier ftrace change, that broke live patching of modules. The fix replaces the ftrace module notifier by direct call in order to make the ordering guaranteed and well-defined. The patch, from Jessica Yu, has been acked both by Steven and Rusty - error message fix from Miroslav Benes * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching: ftrace/module: remove ftrace module notifier livepatch: change the error message in asm/livepatch.h header files
2 parents dd8fc10 + 7dcd182 commit 705d43d

File tree

5 files changed

+11
-39
lines changed

5 files changed

+11
-39
lines changed

arch/s390/include/asm/livepatch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip)
3737
regs->psw.addr = ip;
3838
}
3939
#else
40-
#error Live patching support is disabled; check CONFIG_LIVEPATCH
40+
#error Include linux/livepatch.h, not asm/livepatch.h
4141
#endif
4242

4343
#endif

arch/x86/include/asm/livepatch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip)
4141
regs->ip = ip;
4242
}
4343
#else
44-
#error Live patching support is disabled; check CONFIG_LIVEPATCH
44+
#error Include linux/livepatch.h, not asm/livepatch.h
4545
#endif
4646

4747
#endif /* _ASM_X86_LIVEPATCH_H */

include/linux/ftrace.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
603603

604604
extern int skip_trace(unsigned long ip);
605605
extern void ftrace_module_init(struct module *mod);
606+
extern void ftrace_module_enable(struct module *mod);
606607
extern void ftrace_release_mod(struct module *mod);
607608

608609
extern void ftrace_disable_daemon(void);
@@ -612,8 +613,9 @@ static inline int skip_trace(unsigned long ip) { return 0; }
612613
static inline int ftrace_force_update(void) { return 0; }
613614
static inline void ftrace_disable_daemon(void) { }
614615
static inline void ftrace_enable_daemon(void) { }
615-
static inline void ftrace_release_mod(struct module *mod) {}
616-
static inline void ftrace_module_init(struct module *mod) {}
616+
static inline void ftrace_module_init(struct module *mod) { }
617+
static inline void ftrace_module_enable(struct module *mod) { }
618+
static inline void ftrace_release_mod(struct module *mod) { }
617619
static inline __init int register_ftrace_command(struct ftrace_func_command *cmd)
618620
{
619621
return -EINVAL;

kernel/module.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
984984
mod->exit();
985985
blocking_notifier_call_chain(&module_notify_list,
986986
MODULE_STATE_GOING, mod);
987+
ftrace_release_mod(mod);
988+
987989
async_synchronize_full();
988990

989991
/* Store the name of the last unloaded module for diagnostic purposes */
@@ -3313,6 +3315,7 @@ static noinline int do_init_module(struct module *mod)
33133315
module_put(mod);
33143316
blocking_notifier_call_chain(&module_notify_list,
33153317
MODULE_STATE_GOING, mod);
3318+
ftrace_release_mod(mod);
33163319
free_module(mod);
33173320
wake_up_all(&module_wq);
33183321
return ret;
@@ -3389,6 +3392,7 @@ static int complete_formation(struct module *mod, struct load_info *info)
33893392
mod->state = MODULE_STATE_COMING;
33903393
mutex_unlock(&module_mutex);
33913394

3395+
ftrace_module_enable(mod);
33923396
blocking_notifier_call_chain(&module_notify_list,
33933397
MODULE_STATE_COMING, mod);
33943398
return 0;

kernel/trace/ftrace.c

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4961,7 +4961,7 @@ void ftrace_release_mod(struct module *mod)
49614961
mutex_unlock(&ftrace_lock);
49624962
}
49634963

4964-
static void ftrace_module_enable(struct module *mod)
4964+
void ftrace_module_enable(struct module *mod)
49654965
{
49664966
struct dyn_ftrace *rec;
49674967
struct ftrace_page *pg;
@@ -5038,38 +5038,8 @@ void ftrace_module_init(struct module *mod)
50385038
ftrace_process_locs(mod, mod->ftrace_callsites,
50395039
mod->ftrace_callsites + mod->num_ftrace_callsites);
50405040
}
5041-
5042-
static int ftrace_module_notify(struct notifier_block *self,
5043-
unsigned long val, void *data)
5044-
{
5045-
struct module *mod = data;
5046-
5047-
switch (val) {
5048-
case MODULE_STATE_COMING:
5049-
ftrace_module_enable(mod);
5050-
break;
5051-
case MODULE_STATE_GOING:
5052-
ftrace_release_mod(mod);
5053-
break;
5054-
default:
5055-
break;
5056-
}
5057-
5058-
return 0;
5059-
}
5060-
#else
5061-
static int ftrace_module_notify(struct notifier_block *self,
5062-
unsigned long val, void *data)
5063-
{
5064-
return 0;
5065-
}
50665041
#endif /* CONFIG_MODULES */
50675042

5068-
struct notifier_block ftrace_module_nb = {
5069-
.notifier_call = ftrace_module_notify,
5070-
.priority = INT_MIN, /* Run after anything that can remove kprobes */
5071-
};
5072-
50735043
void __init ftrace_init(void)
50745044
{
50755045
extern unsigned long __start_mcount_loc[];
@@ -5098,10 +5068,6 @@ void __init ftrace_init(void)
50985068
__start_mcount_loc,
50995069
__stop_mcount_loc);
51005070

5101-
ret = register_module_notifier(&ftrace_module_nb);
5102-
if (ret)
5103-
pr_warning("Failed to register trace ftrace module exit notifier\n");
5104-
51055071
set_ftrace_early_filters();
51065072

51075073
return;

0 commit comments

Comments
 (0)