diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2015-02-27 00:29:31 -0500 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2015-02-27 00:29:34 -0500 |
commit | 3240dd57e533da94998029af6e17008a1806c665 (patch) | |
tree | f23ae90f1d3861c7f2d0dc8fb7a8c6b0c39c1948 | |
parent | 13648b0118a24f4fc76c34e6c7b6ccf447e46a2a (diff) |
ARC: Fix thread_saved_pc()
The old implementation assumed that SP at the time of __switch_to() is
right above pt_regs which is almost certainly not the case as there will
be some stack build up between entry into kernel and leading up to
__switch_to
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/include/asm/processor.h | 5 | ||||
-rw-r--r-- | arch/arc/kernel/process.c | 23 |
2 files changed, 2 insertions, 26 deletions
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h index 88398caa3989..52312cb5dbe2 100644 --- a/arch/arc/include/asm/processor.h +++ b/arch/arc/include/asm/processor.h | |||
@@ -47,9 +47,6 @@ struct thread_struct { | |||
47 | /* Forward declaration, a strange C thing */ | 47 | /* Forward declaration, a strange C thing */ |
48 | struct task_struct; | 48 | struct task_struct; |
49 | 49 | ||
50 | /* Return saved PC of a blocked thread */ | ||
51 | unsigned long thread_saved_pc(struct task_struct *t); | ||
52 | |||
53 | #define task_pt_regs(p) \ | 50 | #define task_pt_regs(p) \ |
54 | ((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1) | 51 | ((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1) |
55 | 52 | ||
@@ -86,6 +83,8 @@ unsigned long thread_saved_pc(struct task_struct *t); | |||
86 | #define TSK_K_BLINK(tsk) TSK_K_REG(tsk, 4) | 83 | #define TSK_K_BLINK(tsk) TSK_K_REG(tsk, 4) |
87 | #define TSK_K_FP(tsk) TSK_K_REG(tsk, 0) | 84 | #define TSK_K_FP(tsk) TSK_K_REG(tsk, 0) |
88 | 85 | ||
86 | #define thread_saved_pc(tsk) TSK_K_BLINK(tsk) | ||
87 | |||
89 | extern void start_thread(struct pt_regs * regs, unsigned long pc, | 88 | extern void start_thread(struct pt_regs * regs, unsigned long pc, |
90 | unsigned long usp); | 89 | unsigned long usp); |
91 | 90 | ||
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; |