diff options
| author | Max Filippov <jcmvbkbc@gmail.com> | 2015-01-26 17:15:10 -0500 |
|---|---|---|
| committer | Max Filippov <jcmvbkbc@gmail.com> | 2017-05-01 13:34:43 -0400 |
| commit | 062b1c19b879e7831cbceb599ab1d758f87eda40 (patch) | |
| tree | 33d6824f10f7d50cf3147ef96f1ab37b70022969 /arch/xtensa/kernel/stacktrace.c | |
| parent | f984409a00e7d9aa40af64d7c9619e5de3d980bf (diff) | |
xtensa: clean up access to spilled registers locations
Define macros SPILL_SLOT* that return a reference to the stack location
of the spill slot for specific register and use them instead of opencoded
address calculations.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'arch/xtensa/kernel/stacktrace.c')
| -rw-r--r-- | arch/xtensa/kernel/stacktrace.c | 35 |
1 files changed, 8 insertions, 27 deletions
diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c index e7d30ee0fd48..0df4080fa20f 100644 --- a/arch/xtensa/kernel/stacktrace.c +++ b/arch/xtensa/kernel/stacktrace.c | |||
| @@ -23,14 +23,6 @@ | |||
| 23 | */ | 23 | */ |
| 24 | extern int common_exception_return; | 24 | extern int common_exception_return; |
| 25 | 25 | ||
| 26 | /* A struct that maps to the part of the frame containing the a0 and | ||
| 27 | * a1 registers. | ||
| 28 | */ | ||
| 29 | struct frame_start { | ||
| 30 | unsigned long a0; | ||
| 31 | unsigned long a1; | ||
| 32 | }; | ||
| 33 | |||
| 34 | void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth, | 26 | void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth, |
| 35 | int (*ufn)(struct stackframe *frame, void *data), | 27 | int (*ufn)(struct stackframe *frame, void *data), |
| 36 | void *data) | 28 | void *data) |
| @@ -96,26 +88,16 @@ void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth, | |||
| 96 | /* Start from the a1 register. */ | 88 | /* Start from the a1 register. */ |
| 97 | /* a1 = regs->areg[1]; */ | 89 | /* a1 = regs->areg[1]; */ |
| 98 | while (a0 != 0 && depth--) { | 90 | while (a0 != 0 && depth--) { |
| 99 | struct frame_start frame_start; | 91 | pc = MAKE_PC_FROM_RA(a0, pc); |
| 100 | /* Get the location for a1, a0 for the | ||
| 101 | * previous frame from the current a1. | ||
| 102 | */ | ||
| 103 | unsigned long *psp = (unsigned long *)a1; | ||
| 104 | |||
| 105 | psp -= 4; | ||
| 106 | 92 | ||
| 107 | /* Check if the region is OK to access. */ | 93 | /* Check if the region is OK to access. */ |
| 108 | if (!access_ok(VERIFY_READ, psp, sizeof(frame_start))) | 94 | if (!access_ok(VERIFY_READ, &SPILL_SLOT(a1, 0), 8)) |
| 109 | return; | 95 | return; |
| 110 | /* Copy a1, a0 from user space stack frame. */ | 96 | /* Copy a1, a0 from user space stack frame. */ |
| 111 | if (__copy_from_user_inatomic(&frame_start, psp, | 97 | if (__get_user(a0, &SPILL_SLOT(a1, 0)) || |
| 112 | sizeof(frame_start))) | 98 | __get_user(a1, &SPILL_SLOT(a1, 1))) |
| 113 | return; | 99 | return; |
| 114 | 100 | ||
| 115 | pc = MAKE_PC_FROM_RA(a0, pc); | ||
| 116 | a0 = frame_start.a0; | ||
| 117 | a1 = frame_start.a1; | ||
| 118 | |||
| 119 | frame.pc = pc; | 101 | frame.pc = pc; |
| 120 | frame.sp = a1; | 102 | frame.sp = a1; |
| 121 | 103 | ||
| @@ -147,7 +129,6 @@ void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth, | |||
| 147 | */ | 129 | */ |
| 148 | while (a1 > sp_start && a1 < sp_end && depth--) { | 130 | while (a1 > sp_start && a1 < sp_end && depth--) { |
| 149 | struct stackframe frame; | 131 | struct stackframe frame; |
| 150 | unsigned long *psp = (unsigned long *)a1; | ||
| 151 | 132 | ||
| 152 | frame.pc = pc; | 133 | frame.pc = pc; |
| 153 | frame.sp = a1; | 134 | frame.sp = a1; |
| @@ -171,8 +152,8 @@ void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth, | |||
| 171 | sp_start = a1; | 152 | sp_start = a1; |
| 172 | 153 | ||
| 173 | pc = MAKE_PC_FROM_RA(a0, pc); | 154 | pc = MAKE_PC_FROM_RA(a0, pc); |
| 174 | a0 = *(psp - 4); | 155 | a0 = SPILL_SLOT(a1, 0); |
| 175 | a1 = *(psp - 3); | 156 | a1 = SPILL_SLOT(a1, 1); |
| 176 | } | 157 | } |
| 177 | } | 158 | } |
| 178 | EXPORT_SYMBOL(xtensa_backtrace_kernel); | 159 | EXPORT_SYMBOL(xtensa_backtrace_kernel); |
| @@ -196,8 +177,8 @@ void walk_stackframe(unsigned long *sp, | |||
| 196 | 177 | ||
| 197 | sp = (unsigned long *)a1; | 178 | sp = (unsigned long *)a1; |
| 198 | 179 | ||
| 199 | a0 = *(sp - 4); | 180 | a0 = SPILL_SLOT(a1, 0); |
| 200 | a1 = *(sp - 3); | 181 | a1 = SPILL_SLOT(a1, 1); |
| 201 | 182 | ||
| 202 | if (a1 <= (unsigned long)sp) | 183 | if (a1 <= (unsigned long)sp) |
| 203 | break; | 184 | break; |
