Add an indication for an outermost frame to the unwind user frame structure and stop unwinding when reaching an outermost frame.
This will be used by unwind user sframe, as SFrame may represent an undefined return address as indication for an outermost frame. Reviewed-by: Indu Bhagat <[email protected]> Signed-off-by: Jens Remus <[email protected]> --- Notes (jremus): Cherry-picked from "[PATCH v16 00/20] unwind_deferred: Implement sframe handling" series: https://lore.kernel.org/all/[email protected]/ arch/x86/include/asm/unwind_user.h | 6 ++++-- include/linux/unwind_user_types.h | 1 + kernel/unwind/user.c | 6 ++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/unwind_user.h b/arch/x86/include/asm/unwind_user.h index 6e469044e4de..2dfb5ef11e36 100644 --- a/arch/x86/include/asm/unwind_user.h +++ b/arch/x86/include/asm/unwind_user.h @@ -23,13 +23,15 @@ static inline int unwind_user_word_size(struct pt_regs *regs) .cfa_off = 2*(ws), \ .ra_off = -1*(ws), \ .fp_off = -2*(ws), \ - .use_fp = true, + .use_fp = true, \ + .outermost = false, #define ARCH_INIT_USER_FP_ENTRY_FRAME(ws) \ .cfa_off = 1*(ws), \ .ra_off = -1*(ws), \ .fp_off = 0, \ - .use_fp = false, + .use_fp = false, \ + .outermost = false, static inline bool unwind_user_at_function_start(struct pt_regs *regs) { diff --git a/include/linux/unwind_user_types.h b/include/linux/unwind_user_types.h index 412729a269bc..4fc3dd9b4e29 100644 --- a/include/linux/unwind_user_types.h +++ b/include/linux/unwind_user_types.h @@ -30,6 +30,7 @@ struct unwind_user_frame { s32 ra_off; s32 fp_off; bool use_fp; + bool outermost; }; struct unwind_user_state { diff --git a/kernel/unwind/user.c b/kernel/unwind/user.c index 90ab3c1a205e..28091ece830c 100644 --- a/kernel/unwind/user.c +++ b/kernel/unwind/user.c @@ -31,6 +31,12 @@ static int unwind_user_next_common(struct unwind_user_state *state, { unsigned long cfa, fp, ra; + /* Stop unwinding when reaching an outermost frame. */ + if (frame->outermost) { + state->done = true; + return 0; + } + /* Get the Canonical Frame Address (CFA) */ if (frame->use_fp) { if (state->fp < state->sp) -- 2.53.0
