Messages in this thread Patch in this message | | | From | Thomas Gleixner <> | Subject | [patch 34/38] x86/orc: Make it callthunk aware | Date | Sun, 17 Jul 2022 01:18:05 +0200 (CEST) |
| |
From: Peter Zijlstra <peterz@infradead.org>
Callthunks addresses on the stack would confuse the ORC unwinder. Handle them correctly and tell ORC to proceed further down the stack.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Josh Poimboeuf <jpoimboe@kernel.org> --- arch/x86/include/asm/alternative.h | 5 +++++ arch/x86/kernel/callthunks.c | 2 +- arch/x86/kernel/unwind_orc.c | 21 ++++++++++++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-)
--- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -94,6 +94,7 @@ extern void callthunks_patch_module_call struct module *mod); extern void callthunks_module_free(struct module *mod); extern void *callthunks_translate_call_dest(void *dest); +extern bool is_callthunk(void *addr); #else static __always_inline void callthunks_patch_builtin_calls(void) {} static __always_inline void @@ -104,6 +105,10 @@ static __always_inline void *callthunks_ { return dest; } +static __always_inline bool is_callthunk(void *addr) +{ + return false; +} #endif #ifdef CONFIG_SMP --- a/arch/x86/kernel/callthunks.c +++ b/arch/x86/kernel/callthunks.c @@ -565,7 +565,7 @@ static bool is_module_callthunk(void *ad return ret; } -static bool is_callthunk(void *addr) +bool is_callthunk(void *addr) { if (builtin_layout.base <= addr && addr < builtin_layout.base + builtin_layout.size) --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c @@ -131,6 +131,21 @@ static struct orc_entry null_orc_entry = .type = UNWIND_HINT_TYPE_CALL }; +#ifdef CONFIG_CALL_THUNKS +static struct orc_entry *orc_callthunk_find(unsigned long ip) +{ + if (!is_callthunk((void *)ip)) + return NULL; + + return &null_orc_entry; +} +#else +static struct orc_entry *orc_callthunk_find(unsigned long ip) +{ + return NULL; +} +#endif + /* Fake frame pointer entry -- used as a fallback for generated code */ static struct orc_entry orc_fp_entry = { .type = UNWIND_HINT_TYPE_CALL, @@ -184,7 +199,11 @@ static struct orc_entry *orc_find(unsign if (orc) return orc; - return orc_ftrace_find(ip); + orc = orc_ftrace_find(ip); + if (orc) + return orc; + + return orc_callthunk_find(ip); } #ifdef CONFIG_MODULES
| |