| From d9d0403ed3ae357458adbfdc2f240a4aa660a7ee Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 28 Jun 2021 13:24:11 +0200 |
| Subject: static_call: Fix static_call_text_reserved() vs __init |
| |
| From: Peter Zijlstra <peterz@infradead.org> |
| |
| [ Upstream commit 2bee6d16e4379326b1eea454e68c98b17456769e ] |
| |
| It turns out that static_call_text_reserved() was reporting __init |
| text as being reserved past the time when the __init text was freed |
| and re-used. |
| |
| This is mostly harmless and will at worst result in refusing a kprobe. |
| |
| Fixes: 6333e8f73b83 ("static_call: Avoid kprobes on inline static_call()s") |
| Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org> |
| Link: https://lore.kernel.org/r/20210628113045.106211657@infradead.org |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| kernel/static_call.c | 13 ++++++++----- |
| 1 file changed, 8 insertions(+), 5 deletions(-) |
| |
| diff --git a/kernel/static_call.c b/kernel/static_call.c |
| index 2c5950b0b90e..7eba4912e529 100644 |
| --- a/kernel/static_call.c |
| +++ b/kernel/static_call.c |
| @@ -292,13 +292,15 @@ static int addr_conflict(struct static_call_site *site, void *start, void *end) |
| |
| static int __static_call_text_reserved(struct static_call_site *iter_start, |
| struct static_call_site *iter_stop, |
| - void *start, void *end) |
| + void *start, void *end, bool init) |
| { |
| struct static_call_site *iter = iter_start; |
| |
| while (iter < iter_stop) { |
| - if (addr_conflict(iter, start, end)) |
| - return 1; |
| + if (init || !static_call_is_init(iter)) { |
| + if (addr_conflict(iter, start, end)) |
| + return 1; |
| + } |
| iter++; |
| } |
| |
| @@ -324,7 +326,7 @@ static int __static_call_mod_text_reserved(void *start, void *end) |
| |
| ret = __static_call_text_reserved(mod->static_call_sites, |
| mod->static_call_sites + mod->num_static_call_sites, |
| - start, end); |
| + start, end, mod->state == MODULE_STATE_COMING); |
| |
| module_put(mod); |
| |
| @@ -459,8 +461,9 @@ static inline int __static_call_mod_text_reserved(void *start, void *end) |
| |
| int static_call_text_reserved(void *start, void *end) |
| { |
| + bool init = system_state < SYSTEM_RUNNING; |
| int ret = __static_call_text_reserved(__start_static_call_sites, |
| - __stop_static_call_sites, start, end); |
| + __stop_static_call_sites, start, end, init); |
| |
| if (ret) |
| return ret; |
| -- |
| 2.30.2 |
| |