Skip to content

Commit 22ecd97

Browse files
madvenka786ctmarinas
authored andcommitted
arm64: Make profile_pc() use arch_stack_walk()
To enable RELIABLE_STACKTRACE and LIVEPATCH on arm64, we need to substantially rework arm64's unwinding code. As part of this, we want to minimize the set of unwind interfaces we expose, and avoid open-coding of unwind logic outside of stacktrace.c. Currently profile_pc() walks the stack of an interrupted context by calling start_backtrace() with the context's PC and FP, and iterating unwind steps using walk_stackframe(). This is functionally equivalent to calling arch_stack_walk() with the interrupted context's pt_regs, which will start with the PC and FP from the regs. Make profile_pc() use arch_stack_walk(). This simplifies profile_pc(), and in future will alow us to make walk_stackframe() private to stacktrace.c. At the same time, we remove the early return for when regs->pc is not in lock functions, as this will be handled by the first call to the profile_pc_cb() callback. There should be no functional change as a result of this patch. Signed-off-by: Madhavan T. Venkataraman <[email protected]> Reviewed-by: Mark Rutland <[email protected]> [Mark: remove early return, elaborate commit message, fix includes] Signed-off-by: Mark Rutland <[email protected]> Reviewed-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 39ef362 commit 22ecd97

File tree

1 file changed

+13
-12
lines changed

1 file changed

+13
-12
lines changed

arch/arm64/kernel/time.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/timex.h>
1919
#include <linux/errno.h>
2020
#include <linux/profile.h>
21+
#include <linux/stacktrace.h>
2122
#include <linux/syscore_ops.h>
2223
#include <linux/timer.h>
2324
#include <linux/irq.h>
@@ -29,25 +30,25 @@
2930
#include <clocksource/arm_arch_timer.h>
3031

3132
#include <asm/thread_info.h>
32-
#include <asm/stacktrace.h>
3333
#include <asm/paravirt.h>
3434

35-
unsigned long profile_pc(struct pt_regs *regs)
35+
static bool profile_pc_cb(void *arg, unsigned long pc)
3636
{
37-
struct stackframe frame;
37+
unsigned long *prof_pc = arg;
3838

39-
if (!in_lock_functions(regs->pc))
40-
return regs->pc;
39+
if (in_lock_functions(pc))
40+
return true;
41+
*prof_pc = pc;
42+
return false;
43+
}
4144

42-
start_backtrace(&frame, regs->regs[29], regs->pc);
45+
unsigned long profile_pc(struct pt_regs *regs)
46+
{
47+
unsigned long prof_pc = 0;
4348

44-
do {
45-
int ret = unwind_frame(NULL, &frame);
46-
if (ret < 0)
47-
return 0;
48-
} while (in_lock_functions(frame.pc));
49+
arch_stack_walk(profile_pc_cb, &prof_pc, current, regs);
4950

50-
return frame.pc;
51+
return prof_pc;
5152
}
5253
EXPORT_SYMBOL(profile_pc);
5354

0 commit comments

Comments
 (0)