2010-01-28 11:14:24

by K.Prasad

[permalink] [raw]
Subject: [Patch 2/2 v2] Return proper code to notifier chain in hw_breakpoint_handler

Processing of debug exceptions (in do_debug()) can stop if it originated from
a hw-breakpoint exception (return NOTIFY_STOP). For certain cases such as
a) user-space breakpoints with pending SIGTRAP signal delivery (as in the case
of ptrace induced breakpoints) and b) exceptions due to multiple causes (other
than breakpoints) we will continue to process the exception (by returning
NOTIFY_DONE).

Signed-off-by: K.Prasad <[email protected]>
---
arch/x86/kernel/hw_breakpoint.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

Index: linux-2.6-tip.bugfix_perf_hbkpt/arch/x86/kernel/hw_breakpoint.c
===================================================================
--- linux-2.6-tip.bugfix_perf_hbkpt.orig/arch/x86/kernel/hw_breakpoint.c
+++ linux-2.6-tip.bugfix_perf_hbkpt/arch/x86/kernel/hw_breakpoint.c
@@ -502,8 +502,6 @@ static int __kprobes hw_breakpoint_handl
rcu_read_lock();

bp = per_cpu(bp_per_reg[i], cpu);
- if (bp)
- rc = NOTIFY_DONE;
/*
* Reset the 'i'th TRAP bit in dr6 to denote completion of
* exception handling
@@ -522,7 +520,13 @@ static int __kprobes hw_breakpoint_handl

rcu_read_unlock();
}
- if (dr6 & (~DR_TRAP_BITS))
+ /*
+ * Further processing in do_debug() is needed for a) user-space
+ * breakpoints (to generate signals) and b) when the system has
+ * taken exception due to multiple causes
+ */
+ if ((current->thread.debugreg6 & DR_TRAP_BITS) ||
+ (dr6 & (~DR_TRAP_BITS)))
rc = NOTIFY_DONE;

set_debugreg(dr7, 7);


2010-01-29 09:27:11

by K.Prasad

[permalink] [raw]
Subject: [tip:perf/core] x86/hw-breakpoints: Optimize return code from notifier chain in hw_breakpoint_handler

Commit-ID: e0e53db6133c32964fd17f20b17073a402f07ed3
Gitweb: http://git.kernel.org/tip/e0e53db6133c32964fd17f20b17073a402f07ed3
Author: K.Prasad <[email protected]>
AuthorDate: Thu, 28 Jan 2010 16:44:15 +0530
Committer: Frederic Weisbecker <[email protected]>
CommitDate: Fri, 29 Jan 2010 02:44:30 +0100

x86/hw-breakpoints: Optimize return code from notifier chain in hw_breakpoint_handler

Processing of debug exceptions in do_debug() can stop if it
originated from a hw-breakpoint exception by returning NOTIFY_STOP
in most cases.

But for certain cases such as:

a) user-space breakpoints with pending SIGTRAP signal delivery (as
in the case of ptrace induced breakpoints).

b) exceptions due to other causes than breakpoints

We will continue to process the exception by returning NOTIFY_DONE.

Signed-off-by: K.Prasad <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Roland McGrath <[email protected]>
Cc: Alan Stern <[email protected]>
Cc: Jan Kiszka <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Frederic Weisbecker <[email protected]>
---
arch/x86/kernel/hw_breakpoint.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c
index 05d5fec..ae90b47 100644
--- a/arch/x86/kernel/hw_breakpoint.c
+++ b/arch/x86/kernel/hw_breakpoint.c
@@ -502,8 +502,6 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
rcu_read_lock();

bp = per_cpu(bp_per_reg[i], cpu);
- if (bp)
- rc = NOTIFY_DONE;
/*
* Reset the 'i'th TRAP bit in dr6 to denote completion of
* exception handling
@@ -522,7 +520,13 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)

rcu_read_unlock();
}
- if (dr6 & (~DR_TRAP_BITS))
+ /*
+ * Further processing in do_debug() is needed for a) user-space
+ * breakpoints (to generate signals) and b) when the system has
+ * taken exception due to multiple causes
+ */
+ if ((current->thread.debugreg6 & DR_TRAP_BITS) ||
+ (dr6 & (~DR_TRAP_BITS)))
rc = NOTIFY_DONE;

set_debugreg(dr7, 7);