diff options
| -rw-r--r-- | arch/parisc/include/asm/ftrace.h | 14 | ||||
| -rw-r--r-- | arch/parisc/kernel/unwind.c | 27 |
2 files changed, 41 insertions, 0 deletions
diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h index 2fa05dd6aeee..72c0fafaa039 100644 --- a/arch/parisc/include/asm/ftrace.h +++ b/arch/parisc/include/asm/ftrace.h | |||
| @@ -20,6 +20,20 @@ struct ftrace_ret_stack { | |||
| 20 | * Defined in entry.S | 20 | * Defined in entry.S |
| 21 | */ | 21 | */ |
| 22 | extern void return_to_handler(void); | 22 | extern void return_to_handler(void); |
| 23 | |||
| 24 | |||
| 25 | extern unsigned long return_address(unsigned int); | ||
| 26 | |||
| 27 | #define HAVE_ARCH_CALLER_ADDR | ||
| 28 | |||
| 29 | #define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) | ||
| 30 | #define CALLER_ADDR1 return_address(1) | ||
| 31 | #define CALLER_ADDR2 return_address(2) | ||
| 32 | #define CALLER_ADDR3 return_address(3) | ||
| 33 | #define CALLER_ADDR4 return_address(4) | ||
| 34 | #define CALLER_ADDR5 return_address(5) | ||
| 35 | #define CALLER_ADDR6 return_address(6) | ||
| 36 | |||
| 23 | #endif /* __ASSEMBLY__ */ | 37 | #endif /* __ASSEMBLY__ */ |
| 24 | 38 | ||
| 25 | #endif /* _ASM_PARISC_FTRACE_H */ | 39 | #endif /* _ASM_PARISC_FTRACE_H */ |
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index a36799e85693..f03f6fb0ec83 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c | |||
| @@ -417,3 +417,30 @@ int unwind_to_user(struct unwind_frame_info *info) | |||
| 417 | 417 | ||
| 418 | return ret; | 418 | return ret; |
| 419 | } | 419 | } |
| 420 | |||
| 421 | unsigned long return_address(unsigned int level) | ||
| 422 | { | ||
| 423 | struct unwind_frame_info info; | ||
| 424 | struct pt_regs r; | ||
| 425 | unsigned long sp; | ||
| 426 | |||
| 427 | /* initialize unwind info */ | ||
| 428 | asm volatile ("copy %%r30, %0" : "=r"(sp)); | ||
| 429 | memset(&r, 0, sizeof(struct pt_regs)); | ||
| 430 | r.iaoq[0] = (unsigned long) current_text_addr(); | ||
| 431 | r.gr[2] = (unsigned long) __builtin_return_address(0); | ||
| 432 | r.gr[30] = sp; | ||
| 433 | unwind_frame_init(&info, current, &r); | ||
| 434 | |||
| 435 | /* unwind stack */ | ||
| 436 | ++level; | ||
| 437 | do { | ||
| 438 | if (unwind_once(&info) < 0 || info.ip == 0) | ||
| 439 | return 0; | ||
| 440 | if (!__kernel_text_address(info.ip)) { | ||
| 441 | return 0; | ||
| 442 | } | ||
| 443 | } while (info.ip && level--); | ||
| 444 | |||
| 445 | return info.ip; | ||
| 446 | } | ||
