aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2015-02-27 00:29:31 -0500
committerVineet Gupta <vgupta@synopsys.com>2015-02-27 00:29:34 -0500
commit3240dd57e533da94998029af6e17008a1806c665 (patch)
treef23ae90f1d3861c7f2d0dc8fb7a8c6b0c39c1948
parent13648b0118a24f4fc76c34e6c7b6ccf447e46a2a (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.h5
-rw-r--r--arch/arc/kernel/process.c23
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 */
48struct task_struct; 48struct task_struct;
49 49
50/* Return saved PC of a blocked thread */
51unsigned 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
89extern void start_thread(struct pt_regs * regs, unsigned long pc, 88extern 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 */
200unsigned 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
218int elf_check_arch(const struct elf32_hdr *x) 195int elf_check_arch(const struct elf32_hdr *x)
219{ 196{
220 unsigned int eflags; 197 unsigned int eflags;