aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa/kernel/stacktrace.c
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2015-01-26 17:15:10 -0500
committerMax Filippov <jcmvbkbc@gmail.com>2017-05-01 13:34:43 -0400
commit062b1c19b879e7831cbceb599ab1d758f87eda40 (patch)
tree33d6824f10f7d50cf3147ef96f1ab37b70022969 /arch/xtensa/kernel/stacktrace.c
parentf984409a00e7d9aa40af64d7c9619e5de3d980bf (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.c35
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 */
24extern int common_exception_return; 24extern 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 */
29struct frame_start {
30 unsigned long a0;
31 unsigned long a1;
32};
33
34void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth, 26void 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}
178EXPORT_SYMBOL(xtensa_backtrace_kernel); 159EXPORT_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;