From: Brian Gerst <brgerst@gmail.com>
To: x86@kernel.org, linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@kernel.org>, "H. Peter Anvin" <hpa@zytor.com>,
Denys Vlasenko <dvlasenk@redhat.com>,
Andy Lutomirski <luto@amacapital.net>,
Borislav Petkov <bp@suse.de>,
Thomas Gleixner <tglx@linutronix.de>
Subject: [PATCH v2 6/6] x86: Fix thread_saved_pc()
Date: Sat, 18 Jun 2016 16:56:18 -0400 [thread overview]
Message-ID: <1466283378-17062-7-git-send-email-brgerst@gmail.com> (raw)
In-Reply-To: <1466283378-17062-1-git-send-email-brgerst@gmail.com>
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);
+}
+
+/*
* Called from fs/proc with a reference on @p to find the function
* which called into schedule(). This needs to be done carefully
* because the task might wake up and we might look at a stack
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index acee6ca..bcf0a38 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -58,14 +58,6 @@
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
- return ((unsigned long *)tsk->thread.sp)[3];
-}
-
void __show_regs(struct pt_regs *regs, int all)
{
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
--
2.5.5
next prev parent reply other threads:[~2016-06-18 20:56 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-18 20:56 [PATCH v2 0/6] x86: Rewrite switch_to() Brian Gerst
2016-06-18 20:56 ` [PATCH v2 1/6] x86-32, kgdb: Don't use thread.ip in sleeping_thread_to_gdb_regs() Brian Gerst
2016-06-18 20:56 ` [PATCH v2 2/6] x86-64, kgdb: clear GDB_PS on 64-bit Brian Gerst
2016-06-18 20:56 ` [PATCH v2 3/6] x86: Add struct inactive_task_frame Brian Gerst
2016-06-19 21:18 ` Andy Lutomirski
2016-06-20 15:39 ` Josh Poimboeuf
2016-06-18 20:56 ` [PATCH v2 4/6] x86: Rewrite switch_to() code Brian Gerst
2016-06-19 21:22 ` Andy Lutomirski
2016-06-20 15:44 ` Josh Poimboeuf
2016-06-18 20:56 ` [PATCH v2 5/6] x86: Pass kernel thread parameters in fork_frame Brian Gerst
2016-06-19 21:28 ` Andy Lutomirski
2016-06-19 22:01 ` Brian Gerst
2016-06-20 13:51 ` Borislav Petkov
2016-06-20 15:01 ` Brian Gerst
2016-06-20 15:14 ` Borislav Petkov
2016-06-22 4:24 ` Brian Gerst
2016-07-09 12:01 ` Ingo Molnar
2016-06-18 20:56 ` Brian Gerst [this message]
2016-06-20 16:01 ` [PATCH v2 6/6] x86: Fix thread_saved_pc() Josh Poimboeuf
2016-06-22 4:27 ` Brian Gerst
2016-06-24 18:12 ` Josh Poimboeuf
2016-06-19 22:05 ` [PATCH v2 0/6] x86: Rewrite switch_to() Brian Gerst
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1466283378-17062-7-git-send-email-brgerst@gmail.com \
--to=brgerst@gmail.com \
--cc=bp@suse.de \
--cc=dvlasenk@redhat.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=mingo@kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.