Messages in this thread | | | Date | Mon, 20 Jun 2016 11:01:41 -0500 | From | Josh Poimboeuf <> | Subject | Re: [PATCH v2 6/6] x86: Fix thread_saved_pc() |
| |
On Sat, Jun 18, 2016 at 04:56:18PM -0400, Brian Gerst wrote: > thread_saved_pc() was using a completely bogus method to get the return > address. Since switch_to() was previously inlined, there was no sane way > to know where on the stack the return address was stored. Now with the > frame of a sleeping thread well defined, this can be implemented correctly. > > Signed-off-by: Brian Gerst <brgerst@gmail.com> > --- > arch/x86/include/asm/processor.h | 10 ++-------- > arch/x86/kernel/process.c | 10 ++++++++++ > arch/x86/kernel/process_32.c | 8 -------- > 3 files changed, 12 insertions(+), 16 deletions(-) > > diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h > index 1e7d634..413f4f1 100644 > --- a/arch/x86/include/asm/processor.h > +++ b/arch/x86/include/asm/processor.h > @@ -716,8 +716,6 @@ static inline void spin_lock_prefetch(const void *x) > .io_bitmap_ptr = NULL, \ > } > > -extern unsigned long thread_saved_pc(struct task_struct *tsk); > - > /* > * TOP_OF_KERNEL_STACK_PADDING reserves 8 bytes on top of the ring0 stack. > * This is necessary to guarantee that the entire "struct pt_regs" > @@ -767,17 +765,13 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); > .sp0 = TOP_OF_INIT_STACK \ > } > > -/* > - * Return saved PC of a blocked thread. > - * What is this good for? it will be always the scheduler or ret_from_fork. > - */ > -#define thread_saved_pc(t) READ_ONCE_NOCHECK(*(unsigned long *)((t)->thread.sp - 8)) > - > #define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1) > extern unsigned long KSTK_ESP(struct task_struct *task); > > #endif /* CONFIG_X86_64 */ > > +extern unsigned long thread_saved_pc(struct task_struct *tsk); > + > extern void start_thread(struct pt_regs *regs, unsigned long new_ip, > unsigned long new_sp); > > diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c > index 00ebab0..db458c4 100644 > --- a/arch/x86/kernel/process.c > +++ b/arch/x86/kernel/process.c > @@ -513,6 +513,16 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) > } > > /* > + * Return saved PC of a blocked thread. > + */ > +unsigned long thread_saved_pc(struct task_struct *tsk) > +{ > + struct inactive_task_frame *frame = > + (struct inactive_task_frame *) READ_ONCE(tsk->thread.sp); > + return READ_ONCE_NOCHECK(frame->ret_addr); > +} > + > +/*
I would agree with the above (removed) comment:
"What is this good for? it will be always the scheduler or ret_from_fork."
And I'd guess the same is true for all the arches which have to implement it. Maybe this function (and its single call site in sched_show_task()) should just be removed altogether?
-- Josh
| |