From: "K.Prasad" <prasad@linux.vnet.ibm.com>
To: David Gibson <dwg@au1.ibm.com>,
Alan Stern <stern@rowland.harvard.edu>,
Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>, Ingo Molnar <mingo@elte.hu>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Benjamin Herrenschmidt <benh@au1.ibm.com>,
maneesh@linux.vnet.ibm.com, Roland McGrath <roland@redhat.com>,
Masami Hiramatsu <mhiramat@redhat.com>
Subject: Re: [Patch 06/12] Use the new wrapper routines to access debug registers in process/thread code
Date: Fri, 29 May 2009 14:31:46 +0530 [thread overview]
Message-ID: <20090529090146.GA5353@in.ibm.com> (raw)
In-Reply-To: <20090528064238.GC3091@yookeroo.seuss>
On Thu, May 28, 2009 at 04:42:38PM +1000, David Gibson wrote:
> On Mon, May 11, 2009 at 05:23:44PM +0530, K.Prasad wrote:
> > From: Alan Stern <stern@rowland.harvard.edu>
> >
> > This patch enables the use of abstract debug registers in
> > process-handling routines.
>
> [snip]
> >
> > + p->thread.io_bitmap_ptr = NULL;
>
> Why is manipulating the io_bitmap_ptr relevant to debug register
> handling?
I *re-read* the patch but was unable to find how this change had sneaked
in. It shouldn't be there although it is harmless.
Hi Frederic,
I am attaching a new version of this patch 06/12 that:
- removes the line that assigns NULL to "p->thread.io_bitmap_ptr"
- Updates the comment in __switch_to() function which was stale (was
relevant when 'last_debugged_task' was used to detect lazy debug
register switching).
Kindly integrate this version in lieu of the older version sent here:
http://lkml.org/lkml/2009/5/21/149.
Hi Alan,
I'm retaining the
"Reviewed-by: Alan Stern <stern@rowland.harvard.edu>" tag on the patch
even after the above changes and guess it is acceptable to you. Please
let me know if you have any concerns about that.
Thanks,
K.Prasad
Use the new wrapper routines to access debug registers in process/thread code
This patch enables the use of abstract debug registers in
process-handling routines.
Original-patch-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
---
arch/x86/kernel/process.c | 23 ++++++-----------------
arch/x86/kernel/process_32.c | 27 +++++++++++++++++++++++++++
arch/x86/kernel/process_64.c | 30 ++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 17 deletions(-)
Index: linux-2.6-tip.hbkpt/arch/x86/kernel/process.c
===================================================================
--- linux-2.6-tip.hbkpt.orig/arch/x86/kernel/process.c
+++ linux-2.6-tip.hbkpt/arch/x86/kernel/process.c
@@ -17,6 +17,8 @@
#include <asm/uaccess.h>
#include <asm/i387.h>
#include <asm/ds.h>
+#include <asm/debugreg.h>
+#include <asm/hw_breakpoint.h>
unsigned long idle_halt;
EXPORT_SYMBOL(idle_halt);
@@ -48,6 +50,8 @@ void free_thread_xstate(struct task_stru
kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
tsk->thread.xstate = NULL;
}
+ if (unlikely(test_tsk_thread_flag(tsk, TIF_DEBUG)))
+ flush_thread_hw_breakpoint(tsk);
WARN(tsk->thread.ds_ctx, "leaking DS context\n");
}
@@ -106,14 +110,9 @@ void flush_thread(void)
}
#endif
- clear_tsk_thread_flag(tsk, TIF_DEBUG);
+ if (unlikely(test_tsk_thread_flag(tsk, TIF_DEBUG)))
+ flush_thread_hw_breakpoint(tsk);
- tsk->thread.debugreg0 = 0;
- tsk->thread.debugreg1 = 0;
- tsk->thread.debugreg2 = 0;
- tsk->thread.debugreg3 = 0;
- tsk->thread.debugreg6 = 0;
- tsk->thread.debugreg7 = 0;
memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
/*
* Forget coprocessor state..
@@ -195,16 +194,6 @@ void __switch_to_xtra(struct task_struct
else if (next->debugctlmsr != prev->debugctlmsr)
update_debugctlmsr(next->debugctlmsr);
- if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
- set_debugreg(next->debugreg0, 0);
- set_debugreg(next->debugreg1, 1);
- set_debugreg(next->debugreg2, 2);
- set_debugreg(next->debugreg3, 3);
- /* no 4 and 5 */
- set_debugreg(next->debugreg6, 6);
- set_debugreg(next->debugreg7, 7);
- }
-
if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
test_tsk_thread_flag(next_p, TIF_NOTSC)) {
/* prev and next are different */
Index: linux-2.6-tip.hbkpt/arch/x86/kernel/process_32.c
===================================================================
--- linux-2.6-tip.hbkpt.orig/arch/x86/kernel/process_32.c
+++ linux-2.6-tip.hbkpt/arch/x86/kernel/process_32.c
@@ -58,6 +58,8 @@
#include <asm/idle.h>
#include <asm/syscalls.h>
#include <asm/ds.h>
+#include <asm/debugreg.h>
+#include <asm/hw_breakpoint.h>
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
@@ -263,6 +265,11 @@ int copy_thread(unsigned long clone_flag
task_user_gs(p) = get_user_gs(regs);
tsk = current;
+ err = -ENOMEM;
+ if (unlikely(test_tsk_thread_flag(tsk, TIF_DEBUG)))
+ if (copy_thread_hw_breakpoint(tsk, p, clone_flags))
+ goto out;
+
if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
IO_BITMAP_BYTES, GFP_KERNEL);
@@ -282,10 +289,13 @@ int copy_thread(unsigned long clone_flag
err = do_set_thread_area(p, -1,
(struct user_desc __user *)childregs->si, 0);
+out:
if (err && p->thread.io_bitmap_ptr) {
kfree(p->thread.io_bitmap_ptr);
p->thread.io_bitmap_max = 0;
}
+ if (err)
+ flush_thread_hw_breakpoint(p);
clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
p->thread.ds_ctx = NULL;
@@ -424,6 +434,23 @@ __switch_to(struct task_struct *prev_p,
lazy_load_gs(next->gs);
percpu_write(current_task, next_p);
+ /*
+ * There's a problem with moving the arch_install_thread_hw_breakpoint()
+ * call before current is updated. Suppose a kernel breakpoint is
+ * triggered in between the two, the hw-breakpoint handler will see that
+ * the 'current' task does not have TIF_DEBUG flag set and will think it
+ * is leftover from an old task (lazy switching) and will erase it. Then
+ * until the next context switch, no user-breakpoints will be installed.
+ *
+ * The real problem is that it's impossible to update both current and
+ * physical debug registers at the same instant, so there will always be
+ * a window in which they disagree and a breakpoint might get triggered.
+ * Since we use lazy switching, we are forced to assume that a
+ * disagreement means that current is correct and the exception is due
+ * to lazy debug register switching.
+ */
+ if (unlikely(test_tsk_thread_flag(next_p, TIF_DEBUG)))
+ arch_install_thread_hw_breakpoint(next_p);
return prev_p;
}
Index: linux-2.6-tip.hbkpt/arch/x86/kernel/process_64.c
===================================================================
--- linux-2.6-tip.hbkpt.orig/arch/x86/kernel/process_64.c
+++ linux-2.6-tip.hbkpt/arch/x86/kernel/process_64.c
@@ -52,6 +52,8 @@
#include <asm/idle.h>
#include <asm/syscalls.h>
#include <asm/ds.h>
+#include <asm/debugreg.h>
+#include <asm/hw_breakpoint.h>
asmlinkage extern void ret_from_fork(void);
@@ -245,6 +247,8 @@ void release_thread(struct task_struct *
BUG();
}
}
+ if (unlikely(dead_task->thread.debugreg7))
+ flush_thread_hw_breakpoint(dead_task);
}
static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr)
@@ -306,6 +310,11 @@ int copy_thread(unsigned long clone_flag
savesegment(es, p->thread.es);
savesegment(ds, p->thread.ds);
+ err = -ENOMEM;
+ if (unlikely(test_tsk_thread_flag(me, TIF_DEBUG)))
+ if (copy_thread_hw_breakpoint(me, p, clone_flags))
+ goto out;
+
if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) {
p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
if (!p->thread.io_bitmap_ptr) {
@@ -344,6 +353,9 @@ out:
kfree(p->thread.io_bitmap_ptr);
p->thread.io_bitmap_max = 0;
}
+ if (err)
+ flush_thread_hw_breakpoint(p);
+
return err;
}
@@ -489,6 +501,24 @@ __switch_to(struct task_struct *prev_p,
*/
if (tsk_used_math(next_p) && next_p->fpu_counter > 5)
math_state_restore();
+ /*
+ * There's a problem with moving the arch_install_thread_hw_breakpoint()
+ * call before current is updated. Suppose a kernel breakpoint is
+ * triggered in between the two, the hw-breakpoint handler will see that
+ * the 'current' task does not have TIF_DEBUG flag set and will think it
+ * is leftover from an old task (lazy switching) and will erase it. Then
+ * until the next context switch, no user-breakpoints will be installed.
+ *
+ * The real problem is that it's impossible to update both current and
+ * physical debug registers at the same instant, so there will always be
+ * a window in which they disagree and a breakpoint might get triggered.
+ * Since we use lazy switching, we are forced to assume that a
+ * disagreement means that current is correct and the exception is due
+ * to lazy debug register switching.
+ */
+ if (unlikely(test_tsk_thread_flag(next_p, TIF_DEBUG)))
+ arch_install_thread_hw_breakpoint(next_p);
+
return prev_p;
}
next prev parent reply other threads:[~2009-05-29 9:02 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20090511114422.133566343@prasadkr_t60p.in.ibm.com>
2009-05-11 11:52 ` [Patch 01/12] Prepare the code for Hardware Breakpoint interfaces K.Prasad
2009-05-28 5:28 ` David Gibson
2009-05-28 11:10 ` K.Prasad
2009-05-11 11:52 ` [Patch 02/12] Introducing generic hardware breakpoint handler interfaces K.Prasad
2009-05-11 12:12 ` Bharata B Rao
2009-05-11 12:16 ` K.Prasad
2009-05-28 6:15 ` David Gibson
2009-05-28 11:55 ` K.Prasad
2009-05-29 2:59 ` David Gibson
2009-05-11 11:53 ` [Patch 03/12] x86 architecture implementation of Hardware Breakpoint interfaces K.Prasad
2009-05-28 6:35 ` David Gibson
2009-05-28 13:41 ` K.Prasad
2009-05-29 3:15 ` David Gibson
2009-05-11 11:53 ` [Patch 04/12] Modifying generic debug exception to use thread-specific debug registers K.Prasad
2009-05-11 11:53 ` [Patch 05/12] Use wrapper routines around debug registers in processor related functions K.Prasad
2009-05-11 11:53 ` [Patch 06/12] Use the new wrapper routines to access debug registers in process/thread code K.Prasad
2009-05-28 6:42 ` David Gibson
2009-05-29 9:01 ` K.Prasad [this message]
2009-05-29 10:49 ` Frederic Weisbecker
2009-05-29 13:52 ` K.Prasad
2009-05-29 14:07 ` Frédéric Weisbecker
2009-05-30 11:00 ` K.Prasad
2009-05-29 13:54 ` Alan Stern
2009-05-11 11:53 ` [Patch 07/12] Modify signal handling code to refrain from re-enabling HW Breakpoints K.Prasad
2009-05-11 11:54 ` [Patch 08/12] Modify Ptrace routines to access breakpoint registers K.Prasad
2009-05-11 11:54 ` [Patch 09/12] Cleanup HW Breakpoint registers before kexec K.Prasad
2009-05-11 11:54 ` [Patch 10/12] Sample HW breakpoint over kernel data address K.Prasad
2009-05-11 11:55 ` [Patch 11/12] ftrace plugin for kernel symbol tracing using HW Breakpoint interfaces - v4 K.Prasad
2009-05-11 22:14 ` Frederic Weisbecker
2009-05-12 14:19 ` [Patch 11/12] ftrace plugin for kernel symbol tracing using HWBreakpoint " K.Prasad
2009-05-12 15:15 ` Frederic Weisbecker
2009-05-12 20:02 ` [Patch 11/12] ftrace plugin for kernel symbol tracing usingHWBreakpoint " K.Prasad
2009-05-11 11:55 ` [Patch 12/12] Reset bits in dr6 after the corresponding exception is handled K.Prasad
[not found] <20090601180605.799735829@prasadkr_t60p.in.ibm.com>
2009-06-01 18:14 ` [Patch 06/12] Use the new wrapper routines to access debug registers in process/thread code K.Prasad
[not found] <20090530103857.715014561@prasadkr_t60p.in.ibm.com>
2009-05-30 10:52 ` K.Prasad
[not found] <20090521095613.834622717@prasadkr_t60p.in.ibm.com>
2009-05-21 14:02 ` K.Prasad
[not found] <20090515105133.629980476@prasadkr_t60p.in.ibm.com>
2009-05-15 10:58 ` K.Prasad
2009-05-16 0:29 ` K.Prasad
[not found] <20090513160546.592373797@prasadkr_t60p.in.ibm.com>
2009-05-13 16:14 ` K.Prasad
[not found] <20090424055710.764502564@prasadkr_t60p.in.ibm.com>
2009-04-24 6:17 ` K.Prasad
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=20090529090146.GA5353@in.ibm.com \
--to=prasad@linux.vnet.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=benh@au1.ibm.com \
--cc=dwg@au1.ibm.com \
--cc=fweisbec@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=maneesh@linux.vnet.ibm.com \
--cc=mhiramat@redhat.com \
--cc=mingo@elte.hu \
--cc=roland@redhat.com \
--cc=rostedt@goodmis.org \
--cc=stern@rowland.harvard.edu \
/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