LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Ellerman <michael@ellerman.id.au>
To: linuxppc-dev list <linuxppc-dev@ozlabs.org>
Subject: Fwd: [PATCH] Fix missed hardware breakpoints across multiple threads
Date: Mon, 31 Mar 2008 11:07:43 +1000	[thread overview]
Message-ID: <1206925663.7441.4.camel@concordia.ozlabs.ibm.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 2613 bytes --]

From: Michael Ellerman <michael@ellerman.id.au>
Subject: [PATCH] Fix missed hardware breakpoints across multiple threads

There is a bug in the powerpc DABR (data access breakpoint) handling,
which can result in us missing breakpoints if several threads are trying
to break on the same address.

The circumstances are that do_page_fault() calls do_dabr(), this clears
the DABR (sets it to 0) and sets up the signal which will report to
userspace that the DABR was hit. The do_signal() code will restore the DABR
value on the way out to userspace.

If we reschedule before calling do_signal(), __switch_to() will check the
cached DABR value and compare it to the new thread's value, if they match
we don't set the DABR in hardware.

So if two threads have the same DABR value, and we schedule from one to
the other after taking the interrupt for the first thread hitting the DABR,
the second thread will run without the DABR set in hardware.

The cleanest fix is to move the cache update into set_dabr(), that way we
can't forget to do it.

Reported-by: Jan Kratochvil <jan.kratochvil@redhat.com>
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/kernel/process.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)


Sorry all, I forgot to CC this to the list in my rush to get out of the
office on Friday night, sorry! :)


diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 59311ec..4ec6055 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -241,8 +241,12 @@ void discard_lazy_cpu_state(void)
 }
 #endif /* CONFIG_SMP */
 
+static DEFINE_PER_CPU(unsigned long, current_dabr);
+
 int set_dabr(unsigned long dabr)
 {
+	__get_cpu_var(current_dabr) = dabr;
+
 #ifdef CONFIG_PPC_MERGE		/* XXX for now */
 	if (ppc_md.set_dabr)
 		return ppc_md.set_dabr(dabr);
@@ -259,8 +263,6 @@ int set_dabr(unsigned long dabr)
 DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
 #endif
 
-static DEFINE_PER_CPU(unsigned long, current_dabr);
-
 struct task_struct *__switch_to(struct task_struct *prev,
 	struct task_struct *new)
 {
@@ -325,10 +327,8 @@ struct task_struct *__switch_to(struct task_struct *prev,
 
 #endif /* CONFIG_SMP */
 
-	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
+	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
 		set_dabr(new->thread.dabr);
-		__get_cpu_var(current_dabr) = new->thread.dabr;
-	}
 
 	new_thread = &new->thread;
 	old_thread = &current->thread;
-- 
1.5.2.rc1.1884.g59b20



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

                 reply	other threads:[~2008-03-31  1:07 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=1206925663.7441.4.camel@concordia.ozlabs.ibm.com \
    --to=michael@ellerman.id.au \
    --cc=linuxppc-dev@ozlabs.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox