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>
This commit is contained in:
parent
13648b0118
commit
3240dd57e5
|
@ -47,9 +47,6 @@ struct thread_struct {
|
||||||
/* Forward declaration, a strange C thing */
|
/* Forward declaration, a strange C thing */
|
||||||
struct task_struct;
|
struct task_struct;
|
||||||
|
|
||||||
/* Return saved PC of a blocked thread */
|
|
||||||
unsigned long thread_saved_pc(struct task_struct *t);
|
|
||||||
|
|
||||||
#define task_pt_regs(p) \
|
#define task_pt_regs(p) \
|
||||||
((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1)
|
((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1)
|
||||||
|
|
||||||
|
@ -86,6 +83,8 @@ unsigned long thread_saved_pc(struct task_struct *t);
|
||||||
#define TSK_K_BLINK(tsk) TSK_K_REG(tsk, 4)
|
#define TSK_K_BLINK(tsk) TSK_K_REG(tsk, 4)
|
||||||
#define TSK_K_FP(tsk) TSK_K_REG(tsk, 0)
|
#define TSK_K_FP(tsk) TSK_K_REG(tsk, 0)
|
||||||
|
|
||||||
|
#define thread_saved_pc(tsk) TSK_K_BLINK(tsk)
|
||||||
|
|
||||||
extern void start_thread(struct pt_regs * regs, unsigned long pc,
|
extern void start_thread(struct pt_regs * regs, unsigned long pc,
|
||||||
unsigned long usp);
|
unsigned long usp);
|
||||||
|
|
||||||
|
|
|
@ -192,29 +192,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* API: expected by schedular Code: If thread is sleeping where is that.
|
|
||||||
* What is this good for? it will be always the scheduler or ret_from_fork.
|
|
||||||
* So we hard code that anyways.
|
|
||||||
*/
|
|
||||||
unsigned long thread_saved_pc(struct task_struct *t)
|
|
||||||
{
|
|
||||||
struct pt_regs *regs = task_pt_regs(t);
|
|
||||||
unsigned long blink = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the thread being queried for in not itself calling this, then it
|
|
||||||
* implies it is not executing, which in turn implies it is sleeping,
|
|
||||||
* which in turn implies it got switched OUT by the schedular.
|
|
||||||
* In that case, it's kernel mode blink can reliably retrieved as per
|
|
||||||
* the picture above (right above pt_regs).
|
|
||||||
*/
|
|
||||||
if (t != current && t->state != TASK_RUNNING)
|
|
||||||
blink = *((unsigned int *)regs - 1);
|
|
||||||
|
|
||||||
return blink;
|
|
||||||
}
|
|
||||||
|
|
||||||
int elf_check_arch(const struct elf32_hdr *x)
|
int elf_check_arch(const struct elf32_hdr *x)
|
||||||
{
|
{
|
||||||
unsigned int eflags;
|
unsigned int eflags;
|
||||||
|
|
Loading…
Reference in New Issue