* [PATCH 1/7] ARM: Make thread_save_fp macro aware of THUMB2 mode
2014-05-13 9:46 [PATCH 0/7] Fix handling of FP in THUMB2 mode Nikolay Borisov
@ 2014-05-13 9:46 ` Nikolay Borisov
2014-05-13 9:46 ` [PATCH 2/7] ARM: Introduce arm_get_current_stack_frame() Nikolay Borisov
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Nikolay Borisov @ 2014-05-13 9:46 UTC (permalink / raw)
To: linux-arm-kernel
The thread_save_fp macro has been defined so that it always reads the fp member
of the cpu_context_save struct. However, in the case of THUMB2 the fp is saved
not in the fp (r11) member but rather in r7.
This patch changes the way the macro is defined such that FP is read from the
correct place depending on whether we are a THUMB2 kernel or not. This enables
the backtrace in sitaution such as "echo t > /proc/sysrq-trigger" or the
function in which a process sleeping when "ps -Al" is invoked.
Signed-off-by: Nikolay Borisov <Nikolay.Borisov@arm.com>
Reviewed-by: Anurag Aggarwal <anurag19aggarwal@gmail.com>
---
arch/arm/include/asm/thread_info.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index f989d7c..e4e4208 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -114,8 +114,14 @@ static inline struct thread_info *current_thread_info(void)
((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
#define thread_saved_sp(tsk) \
((unsigned long)(task_thread_info(tsk)->cpu_context.sp))
+
+#ifndef CONFIG_THUMB2_KERNEL
#define thread_saved_fp(tsk) \
((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
+#else
+#define thread_saved_fp(tsk) \
+ ((unsigned long)(task_thread_info(tsk)->cpu_context.r7))
+#endif
extern void crunch_task_disable(struct thread_info *);
extern void crunch_task_copy(struct thread_info *, void *);
--
1.8.1.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/7] ARM: Introduce arm_get_current_stack_frame()
2014-05-13 9:46 [PATCH 0/7] Fix handling of FP in THUMB2 mode Nikolay Borisov
2014-05-13 9:46 ` [PATCH 1/7] ARM: Make thread_save_fp macro aware of " Nikolay Borisov
@ 2014-05-13 9:46 ` Nikolay Borisov
2014-05-13 14:55 ` Robert Richter
2014-05-13 9:46 ` [PATCH 3/7] ARM: perf: Make perf use arm_get_current_stackframe Nikolay Borisov
` (4 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Nikolay Borisov @ 2014-05-13 9:46 UTC (permalink / raw)
To: linux-arm-kernel
Currently there are numerous places where "struct pt_regs" are used to
populate "struct stackframe", however all of those location do not
consider the situation where the kernel might be compiled in THUMB2
mode, in which case the framepointer member of pt_regs become ARM_r7
instead of ARM_fp (r11).
The easiest solution is to introduce a new function (in the spirit of
https://groups.google.com/forum/#!topic/linux.kernel/dA2YuUcSpZ4)
which would hide the complexity of initializing the stackframe struct
from pt_regs. While we are at it, also document this idiosincratic
behavior of the frame pointer in the definition of
"struct stackframe2.
Also implement a macro frame_pointer(regs) that would return the correct
register so that we can use it in cases where we just require the frame
pointer and not a whole struct stackframe
Signed-off-by: Nikolay Borisov <Nikolay.Borisov@arm.com>
---
arch/arm/include/asm/ptrace.h | 3 +++
arch/arm/include/asm/stacktrace.h | 5 +++++
arch/arm/kernel/stacktrace.c | 9 +++++++++
3 files changed, 17 insertions(+)
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index c877654..cd5cff3 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -83,6 +83,9 @@ static inline long regs_return_value(struct pt_regs *regs)
}
#define instruction_pointer(regs) (regs)->ARM_pc
+#define frame_pointer(regs) \
+ IS_ENABLED(CONFIG_THUMB2_KERNEL) ? regs->ARM_r7 \
+ : regs->ARM_fp \
static inline void instruction_pointer_set(struct pt_regs *regs,
unsigned long val)
diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
index 4d0a164..9cbdf36 100644
--- a/arch/arm/include/asm/stacktrace.h
+++ b/arch/arm/include/asm/stacktrace.h
@@ -2,12 +2,17 @@
#define __ASM_STACKTRACE_H
struct stackframe {
+ /* FP member should hold R7 when CONFIG_THUMB2_KERNEL is enabled.
+ * and R11 otherwise
+ */
unsigned long fp;
unsigned long sp;
unsigned long lr;
unsigned long pc;
};
+extern void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe
+ *frame);
extern int unwind_frame(struct stackframe *frame);
extern void walk_stackframe(struct stackframe *frame,
int (*fn)(struct stackframe *, void *), void *data);
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index af4e8c8..5d6ac4d 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -43,6 +43,15 @@ int notrace unwind_frame(struct stackframe *frame)
}
#endif
+void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame)
+{
+ frame->fp = frame_pointer(regs);
+ frame->sp = regs->ARM_sp;
+ frame->lr = regs->ARM_lr;
+ frame->pc = regs->ARM_pc;
+}
+EXPORT_SYMBOL_GPL(arm_get_current_stackframe);
+
void notrace walk_stackframe(struct stackframe *frame,
int (*fn)(struct stackframe *, void *), void *data)
{
--
1.8.1.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/7] ARM: Introduce arm_get_current_stack_frame()
2014-05-13 9:46 ` [PATCH 2/7] ARM: Introduce arm_get_current_stack_frame() Nikolay Borisov
@ 2014-05-13 14:55 ` Robert Richter
2014-05-13 14:57 ` Nikolay Borisov
0 siblings, 1 reply; 10+ messages in thread
From: Robert Richter @ 2014-05-13 14:55 UTC (permalink / raw)
To: linux-arm-kernel
On 13.05.14 10:46:53, Nikolay Borisov wrote:
> #define instruction_pointer(regs) (regs)->ARM_pc
> +#define frame_pointer(regs) \
> + IS_ENABLED(CONFIG_THUMB2_KERNEL) ? regs->ARM_r7 \
> + : regs->ARM_fp \
(regs)->... should be used here both.
-Robert
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/7] ARM: Introduce arm_get_current_stack_frame()
2014-05-13 14:55 ` Robert Richter
@ 2014-05-13 14:57 ` Nikolay Borisov
0 siblings, 0 replies; 10+ messages in thread
From: Nikolay Borisov @ 2014-05-13 14:57 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: Robert Richter [mailto:rric.net at gmail.com] On Behalf Of Robert
> Richter
> Sent: 13 May 2014 15:55
> To: Nikolay Borisov
> Cc: linux-arm-kernel at lists.infradead.org; Dave P Martin; Will Deacon;
> anurag19aggarwal at gmail.com; a.p.zijlstra at chello.nl;
> sebastian.hesselbarth at gmail.com
> Subject: Re: [PATCH 2/7] ARM: Introduce arm_get_current_stack_frame()
>
> On 13.05.14 10:46:53, Nikolay Borisov wrote:
> > #define instruction_pointer(regs) (regs)->ARM_pc
> > +#define frame_pointer(regs) \
> > + IS_ENABLED(CONFIG_THUMB2_KERNEL) ? regs->ARM_r7 \
> > + : regs->ARM_fp \
>
> (regs)->... should be used here both.
>
Yeah, I fixed it already in my local version. Thanks.
> -Robert
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/7] ARM: perf: Make perf use arm_get_current_stackframe
2014-05-13 9:46 [PATCH 0/7] Fix handling of FP in THUMB2 mode Nikolay Borisov
2014-05-13 9:46 ` [PATCH 1/7] ARM: Make thread_save_fp macro aware of " Nikolay Borisov
2014-05-13 9:46 ` [PATCH 2/7] ARM: Introduce arm_get_current_stack_frame() Nikolay Borisov
@ 2014-05-13 9:46 ` Nikolay Borisov
2014-05-13 9:46 ` [PATCH 4/7] ARM: time: Make use of arm_get_current_stackframe Nikolay Borisov
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Nikolay Borisov @ 2014-05-13 9:46 UTC (permalink / raw)
To: linux-arm-kernel
Make the perf backend use the API so that it correctly references the FP
when in THUMB2 mode
Signed-off-by: Nikolay Borisov <Nikolay.Borisov@arm.com>
---
arch/arm/kernel/perf_event.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index a6bc431..55353fd 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -621,10 +621,7 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
return;
}
- fr.fp = regs->ARM_fp;
- fr.sp = regs->ARM_sp;
- fr.lr = regs->ARM_lr;
- fr.pc = regs->ARM_pc;
+ arm_get_current_stackframe(regs, &fr);
walk_stackframe(&fr, callchain_trace, entry);
}
--
1.8.1.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/7] ARM: time: Make use of arm_get_current_stackframe
2014-05-13 9:46 [PATCH 0/7] Fix handling of FP in THUMB2 mode Nikolay Borisov
` (2 preceding siblings ...)
2014-05-13 9:46 ` [PATCH 3/7] ARM: perf: Make perf use arm_get_current_stackframe Nikolay Borisov
@ 2014-05-13 9:46 ` Nikolay Borisov
2014-05-13 9:46 ` [PATCH 5/7] ARM: unwind: Use arm_get_current_stackframe Nikolay Borisov
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Nikolay Borisov @ 2014-05-13 9:46 UTC (permalink / raw)
To: linux-arm-kernel
Make use of the arm_get_current_stackframe api so that
the frame pointer is correctly referenced in THUMB2 mode
Signed-off-by: Nikolay Borisov <Nikolay.Borisov@arm.com>
---
arch/arm/kernel/time.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 829a96d..0cc7e58 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -50,10 +50,7 @@ unsigned long profile_pc(struct pt_regs *regs)
if (!in_lock_functions(regs->ARM_pc))
return regs->ARM_pc;
- frame.fp = regs->ARM_fp;
- frame.sp = regs->ARM_sp;
- frame.lr = regs->ARM_lr;
- frame.pc = regs->ARM_pc;
+ arm_get_current_stackframe(regs, &frame);
do {
int ret = unwind_frame(&frame);
if (ret < 0)
--
1.8.1.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/7] ARM: unwind: Use arm_get_current_stackframe
2014-05-13 9:46 [PATCH 0/7] Fix handling of FP in THUMB2 mode Nikolay Borisov
` (3 preceding siblings ...)
2014-05-13 9:46 ` [PATCH 4/7] ARM: time: Make use of arm_get_current_stackframe Nikolay Borisov
@ 2014-05-13 9:46 ` Nikolay Borisov
2014-05-13 9:46 ` [PATCH 6/7] ARM: traps: Make use of the frame_pointer macro Nikolay Borisov
2014-05-13 9:46 ` [PATCH 7/7] ARM: oprofile: Use of arm_get_current_stackframe Nikolay Borisov
6 siblings, 0 replies; 10+ messages in thread
From: Nikolay Borisov @ 2014-05-13 9:46 UTC (permalink / raw)
To: linux-arm-kernel
Make the unwind code use the correct API so that the frame pointer
is extracted from the correct register.
Signed-off-by: Nikolay Borisov <Nikolay.Borisov@arm.com>
---
arch/arm/kernel/unwind.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 3c21769..7aaec44 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -479,12 +479,10 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
tsk = current;
if (regs) {
- frame.fp = regs->ARM_fp;
- frame.sp = regs->ARM_sp;
- frame.lr = regs->ARM_lr;
+ arm_get_current_stackframe(regs, &frame);
/* PC might be corrupted, use LR in that case. */
- frame.pc = kernel_text_address(regs->ARM_pc)
- ? regs->ARM_pc : regs->ARM_lr;
+ if (!kernel_text_address(regs->ARM_pc))
+ frame.pc = regs->ARM_lr;
} else if (tsk == current) {
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_sp;
--
1.8.1.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/7] ARM: traps: Make use of the frame_pointer macro
2014-05-13 9:46 [PATCH 0/7] Fix handling of FP in THUMB2 mode Nikolay Borisov
` (4 preceding siblings ...)
2014-05-13 9:46 ` [PATCH 5/7] ARM: unwind: Use arm_get_current_stackframe Nikolay Borisov
@ 2014-05-13 9:46 ` Nikolay Borisov
2014-05-13 9:46 ` [PATCH 7/7] ARM: oprofile: Use of arm_get_current_stackframe Nikolay Borisov
6 siblings, 0 replies; 10+ messages in thread
From: Nikolay Borisov @ 2014-05-13 9:46 UTC (permalink / raw)
To: linux-arm-kernel
Use the newly-introduced frame_pointer macro to extract
the correct FP based on whether we are in THUMB2 mode or not.
Signed-off-by: Nikolay Borisov <Nikolay.Borisov@arm.com>
---
arch/arm/kernel/traps.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index abd2fc0..c8e4bb7 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -31,11 +31,13 @@
#include <asm/exception.h>
#include <asm/unistd.h>
#include <asm/traps.h>
+#include <asm/ptrace.h>
#include <asm/unwind.h>
#include <asm/tls.h>
#include <asm/system_misc.h>
#include <asm/opcodes.h>
+
static const char *handler[]= {
"prefetch abort",
"data abort",
@@ -184,7 +186,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
tsk = current;
if (regs) {
- fp = regs->ARM_fp;
+ fp = frame_pointer(regs);
mode = processor_mode(regs);
} else if (tsk != current) {
fp = thread_saved_fp(tsk);
@@ -719,7 +721,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
dump_instr("", regs);
if (user_mode(regs)) {
__show_regs(regs);
- c_backtrace(regs->ARM_fp, processor_mode(regs));
+ c_backtrace(frame_pointer(regs), processor_mode(regs));
}
}
#endif
--
1.8.1.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/7] ARM: oprofile: Use of arm_get_current_stackframe
2014-05-13 9:46 [PATCH 0/7] Fix handling of FP in THUMB2 mode Nikolay Borisov
` (5 preceding siblings ...)
2014-05-13 9:46 ` [PATCH 6/7] ARM: traps: Make use of the frame_pointer macro Nikolay Borisov
@ 2014-05-13 9:46 ` Nikolay Borisov
6 siblings, 0 replies; 10+ messages in thread
From: Nikolay Borisov @ 2014-05-13 9:46 UTC (permalink / raw)
To: linux-arm-kernel
Use the newly introduced API so that FP is correctly referenced from
either R7/R11 based on whether we are running in THUMB2 mode or not.
Signed-off-by: Nikolay Borisov <Nikolay.Borisov@arm.com>
---
arch/arm/oprofile/common.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index 99c63d4b..e6a3c4c 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -107,10 +107,7 @@ static void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
if (!user_mode(regs)) {
struct stackframe frame;
- frame.fp = regs->ARM_fp;
- frame.sp = regs->ARM_sp;
- frame.lr = regs->ARM_lr;
- frame.pc = regs->ARM_pc;
+ arm_get_current_stackframe(regs, &frame);
walk_stackframe(&frame, report_trace, &depth);
return;
}
--
1.8.1.5
^ permalink raw reply related [flat|nested] 10+ messages in thread