diff options
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r-- | arch/arc/kernel/process.c | 23 | ||||
-rw-r--r-- | arch/arc/kernel/stacktrace.c | 21 | ||||
-rw-r--r-- | arch/arc/kernel/unaligned.c | 2 |
3 files changed, 19 insertions, 27 deletions
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index fdd89715d2d3..98c00a2d4dd9 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c | |||
@@ -192,29 +192,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) | |||
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
195 | /* | ||
196 | * API: expected by schedular Code: If thread is sleeping where is that. | ||
197 | * What is this good for? it will be always the scheduler or ret_from_fork. | ||
198 | * So we hard code that anyways. | ||
199 | */ | ||
200 | unsigned long thread_saved_pc(struct task_struct *t) | ||
201 | { | ||
202 | struct pt_regs *regs = task_pt_regs(t); | ||
203 | unsigned long blink = 0; | ||
204 | |||
205 | /* | ||
206 | * If the thread being queried for in not itself calling this, then it | ||
207 | * implies it is not executing, which in turn implies it is sleeping, | ||
208 | * which in turn implies it got switched OUT by the schedular. | ||
209 | * In that case, it's kernel mode blink can reliably retrieved as per | ||
210 | * the picture above (right above pt_regs). | ||
211 | */ | ||
212 | if (t != current && t->state != TASK_RUNNING) | ||
213 | blink = *((unsigned int *)regs - 1); | ||
214 | |||
215 | return blink; | ||
216 | } | ||
217 | |||
218 | int elf_check_arch(const struct elf32_hdr *x) | 195 | int elf_check_arch(const struct elf32_hdr *x) |
219 | { | 196 | { |
220 | unsigned int eflags; | 197 | unsigned int eflags; |
diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c index 9ce47cfe2303..92320d6f737c 100644 --- a/arch/arc/kernel/stacktrace.c +++ b/arch/arc/kernel/stacktrace.c | |||
@@ -43,6 +43,10 @@ static void seed_unwind_frame_info(struct task_struct *tsk, | |||
43 | struct pt_regs *regs, | 43 | struct pt_regs *regs, |
44 | struct unwind_frame_info *frame_info) | 44 | struct unwind_frame_info *frame_info) |
45 | { | 45 | { |
46 | /* | ||
47 | * synchronous unwinding (e.g. dump_stack) | ||
48 | * - uses current values of SP and friends | ||
49 | */ | ||
46 | if (tsk == NULL && regs == NULL) { | 50 | if (tsk == NULL && regs == NULL) { |
47 | unsigned long fp, sp, blink, ret; | 51 | unsigned long fp, sp, blink, ret; |
48 | frame_info->task = current; | 52 | frame_info->task = current; |
@@ -61,12 +65,17 @@ static void seed_unwind_frame_info(struct task_struct *tsk, | |||
61 | frame_info->regs.r63 = ret; | 65 | frame_info->regs.r63 = ret; |
62 | frame_info->call_frame = 0; | 66 | frame_info->call_frame = 0; |
63 | } else if (regs == NULL) { | 67 | } else if (regs == NULL) { |
68 | /* | ||
69 | * Asynchronous unwinding of sleeping task | ||
70 | * - Gets SP etc from task's pt_regs (saved bottom of kernel | ||
71 | * mode stack of task) | ||
72 | */ | ||
64 | 73 | ||
65 | frame_info->task = tsk; | 74 | frame_info->task = tsk; |
66 | 75 | ||
67 | frame_info->regs.r27 = KSTK_FP(tsk); | 76 | frame_info->regs.r27 = TSK_K_FP(tsk); |
68 | frame_info->regs.r28 = KSTK_ESP(tsk); | 77 | frame_info->regs.r28 = TSK_K_ESP(tsk); |
69 | frame_info->regs.r31 = KSTK_BLINK(tsk); | 78 | frame_info->regs.r31 = TSK_K_BLINK(tsk); |
70 | frame_info->regs.r63 = (unsigned int)__switch_to; | 79 | frame_info->regs.r63 = (unsigned int)__switch_to; |
71 | 80 | ||
72 | /* In the prologue of __switch_to, first FP is saved on stack | 81 | /* In the prologue of __switch_to, first FP is saved on stack |
@@ -83,6 +92,10 @@ static void seed_unwind_frame_info(struct task_struct *tsk, | |||
83 | frame_info->call_frame = 0; | 92 | frame_info->call_frame = 0; |
84 | 93 | ||
85 | } else { | 94 | } else { |
95 | /* | ||
96 | * Asynchronous unwinding of intr/exception | ||
97 | * - Just uses the pt_regs passed | ||
98 | */ | ||
86 | frame_info->task = tsk; | 99 | frame_info->task = tsk; |
87 | 100 | ||
88 | frame_info->regs.r27 = regs->fp; | 101 | frame_info->regs.r27 = regs->fp; |
@@ -95,7 +108,7 @@ static void seed_unwind_frame_info(struct task_struct *tsk, | |||
95 | 108 | ||
96 | #endif | 109 | #endif |
97 | 110 | ||
98 | static noinline unsigned int | 111 | notrace noinline unsigned int |
99 | arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs, | 112 | arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs, |
100 | int (*consumer_fn) (unsigned int, void *), void *arg) | 113 | int (*consumer_fn) (unsigned int, void *), void *arg) |
101 | { | 114 | { |
diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c index 7ff5b5c183bb..74db59b6f392 100644 --- a/arch/arc/kernel/unaligned.c +++ b/arch/arc/kernel/unaligned.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/perf_event.h> | ||
15 | #include <linux/ptrace.h> | 16 | #include <linux/ptrace.h> |
16 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
17 | #include <asm/disasm.h> | 18 | #include <asm/disasm.h> |
@@ -253,6 +254,7 @@ int misaligned_fixup(unsigned long address, struct pt_regs *regs, | |||
253 | } | 254 | } |
254 | } | 255 | } |
255 | 256 | ||
257 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, address); | ||
256 | return 0; | 258 | return 0; |
257 | 259 | ||
258 | fault: | 260 | fault: |