Re: [Patch][hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags

2012-05-14 Thread K.Prasad
On Mon, May 14, 2012 at 10:53:42AM +1000, Benjamin Herrenschmidt wrote:
> On Fri, 2012-05-11 at 14:13 +0530, K.Prasad wrote:
> 
> > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > +   int ret, len = 0;
> > +   struct thread_struct *thread = &(child->thread);
> > +   struct perf_event *bp;
> > +   struct perf_event_attr attr;
> > +#endif /* CONFIG_HAVE_HW_BREAKPOINT */
> 
> "ret" is unused in that function, causing a warning which breaks the
> build since we have -Werror. I'm fixing that locally but be more careful
> next time please.
> 
> Ben.

Sorry about that warning, I clearly missed that. I guess you
do a custom build with -Werror flag enabled, unlike what the normal
Makefile does?

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch][hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags

2012-05-11 Thread K.Prasad
Hi Ben,
Please find a patch that introduces generic hw-breakpoint
interfaces for a couple of ptrace flags used by server-class processors.

This patch has been reviewed by the community and acked-by David Gibson
last year
(http://thread.gmane.org/gmane.linux.ports.ppc.embedded/47473/focus=47760)
but did not get submitted to you for inclusion (the patch
applies to the latest linux-2.6 tree, with a few line adjustments).
While originally a patchset of two, I'm submitting only the first (and
independent) patch due to disagreements over the 2/2 patch.

Kindly consider this patch for inclusion into the relevant PowerPC tree.

Thanks,
K.Prasad

--

PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG and PPC_PTRACE_DELHWDEBUG are
PowerPC specific ptrace flags that use the watchpoint register. While they are
targeted primarily towards BookE users, user-space applications such as GDB
have started using them for BookS too. This patch enables the use of generic
hardware breakpoint interfaces for these new flags.

Apart from the usual benefits of using generic hw-breakpoint interfaces, these
changes allow debuggers (such as GDB) to use a common set of ptrace flags for
their watchpoint needs and allow more precise breakpoint specification (length
of the variable can be specified).

Signed-off-by: K.Prasad 
Acked-by: David Gibson 
---
 Documentation/powerpc/ptrace.txt |   16 
 arch/powerpc/kernel/ptrace.c |   77 +++---
 2 files changed, 87 insertions(+), 6 deletions(-)

diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt
index f4a5499..f2a7a39 100644
--- a/Documentation/powerpc/ptrace.txt
+++ b/Documentation/powerpc/ptrace.txt
@@ -127,6 +127,22 @@ Some examples of using the structure to:
   p.addr2   = (uint64_t) end_range;
   p.condition_value = 0;
 
+- set a watchpoint in server processors (BookS)
+
+  p.version = 1;
+  p.trigger_type= PPC_BREAKPOINT_TRIGGER_RW;
+  p.addr_mode   = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+  or
+  p.addr_mode   = PPC_BREAKPOINT_MODE_EXACT;
+
+  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
+  p.addr= (uint64_t) begin_range;
+  /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
+   * addr2 - addr <= 8 Bytes.
+   */
+  p.addr2   = (uint64_t) end_range;
+  p.condition_value = 0;
+
 3. PTRACE_DELHWDEBUG
 
 Takes an integer which identifies an existing breakpoint or watchpoint
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 05b7dd2..cd41c78 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1339,6 +1339,12 @@ static int set_dac_range(struct task_struct *child,
 static long ppc_set_hwdebug(struct task_struct *child,
 struct ppc_hw_breakpoint *bp_info)
 {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   int ret, len = 0;
+   struct thread_struct *thread = &(child->thread);
+   struct perf_event *bp;
+   struct perf_event_attr attr;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #ifndef CONFIG_PPC_ADV_DEBUG_REGS
unsigned long dabr;
 #endif
@@ -1382,13 +1388,9 @@ static long ppc_set_hwdebug(struct task_struct *child,
 */
if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
(bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
-   bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
return -EINVAL;
 
-   if (child->thread.dabr)
-   return -ENOSPC;
-
if ((unsigned long)bp_info->addr >= TASK_SIZE)
return -EIO;
 
@@ -1398,15 +1400,63 @@ static long ppc_set_hwdebug(struct task_struct *child,
dabr |= DABR_DATA_READ;
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
dabr |= DABR_DATA_WRITE;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   if (ptrace_get_breakpoints(child) < 0)
+   return -ESRCH;
 
-   child->thread.dabr = dabr;
+   /*
+* Check if the request is for 'range' breakpoints. We can
+* support it if range < 8 bytes.
+*/
+   if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) {
+   len = bp_info->addr2 - bp_info->addr;
+   } else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
+   ptrace_put_breakpoints(child);
+   return -EINVAL;
+   }
+   bp = thread->ptrace_bps[0];
+   if (bp) {
+   ptrace_put_breakpoints(child);
+   return -ENOSPC;
+   }
+
+   /* Create a new breakpoint request if one doesn't exist already */
+   hw_breakpoint_init(&attr);
+   attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIG

Re: [PATCH 2/2] [PowerPC Book3E] Introduce new ptrace debug feature flag

2011-12-22 Thread K.Prasad
On Wed, Dec 21, 2011 at 11:55:02AM +1100, David Gibson wrote:
> On Thu, Dec 08, 2011 at 04:53:30PM +0530, K.Prasad wrote:
> > While PPC_PTRACE_SETHWDEBUG ptrace flag in PowerPC accepts
> > PPC_BREAKPOINT_MODE_EXACT mode of breakpoint, the same is not intimated to 
> > the
> > user-space debuggers (like GDB) who may want to use it. Hence we introduce a
> > new PPC_DEBUG_FEATURE_DATA_BP_EXACT flag which will be populated on the
> > "features" member of "struct ppc_debug_info" to advertise support for the
> > same on Book3E PowerPC processors.
> 
> Hrm.  I had assumed the reason there wasn't a feature bit for EXACT
> originally was that EXACT breakpoints were *always* supposed to be
> supported by the new interface.
>

Okay. Although BookS doesn't support EXACT breakpoints, it is possible
(after the introduction of new hw-breakpoint interfaces) to request for
a breakpoint of length 1 Byte.

The hw-breakpoint infrastructure would take care of filtering the
extraneous interrupts arising out of accesses in the neighbourhood, in
such a case.

David,
Can you Ack this patch too, if you find the changes acceptable?

Thanks,
K.Prasad
 

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/2] [PowerPC Book3E] Introduce new ptrace debug feature flag

2011-12-08 Thread K.Prasad
While PPC_PTRACE_SETHWDEBUG ptrace flag in PowerPC accepts
PPC_BREAKPOINT_MODE_EXACT mode of breakpoint, the same is not intimated to the
user-space debuggers (like GDB) who may want to use it. Hence we introduce a
new PPC_DEBUG_FEATURE_DATA_BP_EXACT flag which will be populated on the
"features" member of "struct ppc_debug_info" to advertise support for the
same on Book3E PowerPC processors.

Signed-off-by: K.Prasad 
---
 arch/powerpc/include/asm/ptrace.h |1 +
 arch/powerpc/kernel/ptrace.c  |1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index 48223f9..cf014f9 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -380,6 +380,7 @@ struct ppc_debug_info {
 #define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x0002
 #define PPC_DEBUG_FEATURE_DATA_BP_RANGE0x0004
 #define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x0008
+#define PPC_DEBUG_FEATURE_DATA_BP_EXACT0x0010
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 18d28b6..71db5a6 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1636,6 +1636,7 @@ long arch_ptrace(struct task_struct *child, long request,
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
dbginfo.features |=
   PPC_DEBUG_FEATURE_DATA_BP_RANGE |
+  PPC_DEBUG_FEATURE_DATA_BP_EXACT |
   PPC_DEBUG_FEATURE_DATA_BP_MASK;
 #endif
 #else /* !CONFIG_PPC_ADV_DEBUG_REGS */

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/2] [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags

2011-12-08 Thread K.Prasad
PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG and PPC_PTRACE_DELHWDEBUG are
PowerPC specific ptrace flags that use the watchpoint register. While they are
targeted primarily towards BookE users, user-space applications such as GDB
have started using them for BookS too. This patch enables the use of generic
hardware breakpoint interfaces for these new flags.

Apart from the usual benefits of using generic hw-breakpoint interfaces, these
changes allow debuggers (such as GDB) to use a common set of ptrace flags for
their watchpoint needs and allow more precise breakpoint specification (length
of the variable can be specified).

Signed-off-by: K.Prasad 
---
 Documentation/powerpc/ptrace.txt |   16 
 arch/powerpc/kernel/ptrace.c |   77 +++---
 2 files changed, 87 insertions(+), 6 deletions(-)

diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt
index f4a5499..f2a7a39 100644
--- a/Documentation/powerpc/ptrace.txt
+++ b/Documentation/powerpc/ptrace.txt
@@ -127,6 +127,22 @@ Some examples of using the structure to:
   p.addr2   = (uint64_t) end_range;
   p.condition_value = 0;
 
+- set a watchpoint in server processors (BookS)
+
+  p.version = 1;
+  p.trigger_type= PPC_BREAKPOINT_TRIGGER_RW;
+  p.addr_mode   = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+  or
+  p.addr_mode   = PPC_BREAKPOINT_MODE_EXACT;
+
+  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
+  p.addr= (uint64_t) begin_range;
+  /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
+   * addr2 - addr <= 8 Bytes.
+   */
+  p.addr2   = (uint64_t) end_range;
+  p.condition_value = 0;
+
 3. PTRACE_DELHWDEBUG
 
 Takes an integer which identifies an existing breakpoint or watchpoint
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 05b7dd2..cd41c78 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1339,6 +1339,12 @@ static int set_dac_range(struct task_struct *child,
 static long ppc_set_hwdebug(struct task_struct *child,
 struct ppc_hw_breakpoint *bp_info)
 {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   int ret, len = 0;
+   struct thread_struct *thread = &(child->thread);
+   struct perf_event *bp;
+   struct perf_event_attr attr;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #ifndef CONFIG_PPC_ADV_DEBUG_REGS
unsigned long dabr;
 #endif
@@ -1382,13 +1388,9 @@ static long ppc_set_hwdebug(struct task_struct *child,
 */
if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
(bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
-   bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
return -EINVAL;
 
-   if (child->thread.dabr)
-   return -ENOSPC;
-
if ((unsigned long)bp_info->addr >= TASK_SIZE)
return -EIO;
 
@@ -1398,15 +1400,63 @@ static long ppc_set_hwdebug(struct task_struct *child,
dabr |= DABR_DATA_READ;
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
dabr |= DABR_DATA_WRITE;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   if (ptrace_get_breakpoints(child) < 0)
+   return -ESRCH;
 
-   child->thread.dabr = dabr;
+   /*
+* Check if the request is for 'range' breakpoints. We can
+* support it if range < 8 bytes.
+*/
+   if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) {
+   len = bp_info->addr2 - bp_info->addr;
+   } else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
+   ptrace_put_breakpoints(child);
+   return -EINVAL;
+   }
+   bp = thread->ptrace_bps[0];
+   if (bp) {
+   ptrace_put_breakpoints(child);
+   return -ENOSPC;
+   }
+
+   /* Create a new breakpoint request if one doesn't exist already */
+   hw_breakpoint_init(&attr);
+   attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN;
+   attr.bp_len = len;
+   arch_bp_generic_fields(dabr & (DABR_DATA_WRITE | DABR_DATA_READ),
+   &attr.bp_type);
+
+   thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
+  ptrace_triggered, NULL, child);
+   if (IS_ERR(bp)) {
+   thread->ptrace_bps[0] = NULL;
+   ptrace_put_breakpoints(child);
+   return PTR_ERR(bp);
+   }
 
+   ptrace_put_breakpoints(child);
+   return 1;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
+   if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
+   return -EINVAL;
+
+   if (child->thread.dabr)
+   

[PATCH 0/2] Changes to PowerPC ptrace flags using watchpoints - v2

2011-12-08 Thread K.Prasad
Hi David,
Please find a revised version of the patchset which have
incorporated the various suggestions made by you.

Kindly review the patches and let me know if they look fine.

Changelog - v2
--
v1 posted at
http://lists.ozlabs.org/pipermail/linuxppc-dev/2011-August/092463.html

- Introduction of a new version number for the hw-breakpoint structures
  dropped.
- The ptrace flag operations are expected to make more precise requests
  and suitable error return codes have been added for incorrect
  requests.
- Modification of an existing breakpoint is not possible. Request an
  delete, followed by set breakpoint request instead.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 1/2] [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags

2011-12-08 Thread K.Prasad
On Wed, Dec 07, 2011 at 05:01:57PM -0200, Thiago Jung Bauermann wrote:
> On Thu, 2011-12-01 at 15:50 +0530, K.Prasad wrote:
> > On Mon, Nov 28, 2011 at 02:11:11PM +1100, David Gibson wrote:
> > > [snip]
> > > On Wed, Oct 12, 2011 at 11:09:48PM +0530, K.Prasad wrote:
> > > > diff --git a/Documentation/powerpc/ptrace.txt 
> > > > b/Documentation/powerpc/ptrace.txt
> > > > index f4a5499..f2a7a39 100644
> > > > --- a/Documentation/powerpc/ptrace.txt
> > > > +++ b/Documentation/powerpc/ptrace.txt
> > > > @@ -127,6 +127,22 @@ Some examples of using the structure to:
> > > >p.addr2   = (uint64_t) end_range;
> > > >p.condition_value = 0;
> > > >  
> > > > +- set a watchpoint in server processors (BookS)
> > > > +
> > > > +  p.version = 1;
> > > > +  p.trigger_type= PPC_BREAKPOINT_TRIGGER_RW;
> > > > +  p.addr_mode   = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
> > > > +  or
> > > > +  p.addr_mode   = PPC_BREAKPOINT_MODE_EXACT;
> > > > +
> > > > +  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
> > > > +  p.addr= (uint64_t) begin_range;
> > > 
> > > You should probably document the alignment constraint on the address
> > > here, too.
> > > 
> > 
> > Alignment constraints will be learnt by the user-space during runtime.
> > We provide that as part of 'struct ppc_debug_info' in
> > 'data_bp_alignment' field.
> > 
> > While the alignment is always 8-bytes for BookS, I think userspace
> > should be left to learn it through PTRACE_PPC_GETHWDEBUGINFO.
> 
> Right. In particular, BookE doesn't have alignment constraints.
>

Okay.
 
> > > > +   attr.bp_len = len;
> > > > +   ret =  modify_user_hw_breakpoint(bp, &attr);
> > > > +   if (ret) {
> > > > +   ptrace_put_breakpoints(child);
> > > > +   return ret;
> > > > +   }
> > > 
> > > If a bp already exists, you're modifying it.  I thought the semantics
> > > of the new interface meant that you shoul return ENOSPC in this case,
> > > and a DEL would be necessary before adding another breakpoint.
> > > 
> > 
> > I'm not too sure what would be the desired behaviour for this interface,
> > either way is fine with me. I'd like to hear from the GDB folks (copied
> > in this email) to know what would please them.
> 
> ENOSPC should be returned. The interface doesn't have provisions for
> modifying breakpoints. The client should delete/create instead of trying
> to modify.
> 
> Since PTRACE_PPC_GETHWDEBUGINFO returns the number of available
> breakpoint registers, the client shouldn't (and GDB doesn't) try to set
> more breakpoints than possible.
> 

Okay, I will modify the code accordingly.

> > > > @@ -1426,10 +1488,24 @@ static long ppc_del_hwdebug(struct task_struct 
> > > > *child, long addr, long data)
> > > >  #else
> > > > if (data != 1)
> > > > return -EINVAL;
> > > > +
> > > > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > > > +   if (ptrace_get_breakpoints(child) < 0)
> > > > +   return -ESRCH;
> > > > +
> > > > +   bp = thread->ptrace_bps[0];
> > > > +   if (bp) {
> > > > +   unregister_hw_breakpoint(bp);
> > > > +   thread->ptrace_bps[0] = NULL;
> > > > +   }
> > > > +   ptrace_put_breakpoints(child);
> > > > +   return 0;
> > > 
> > > Shouldn't DEL return an error if there is no existing bp.
> > >
> > 
> > Same comment as above. We'd like to know what behaviour would help the
> > GDB use this interface better as there's no right or wrong way here.
> 
> GDB expects DEL to return ENOENT is there's no existing bp.
>

Fine, here too. We'll return a -ENOENT here.

Thanks for your comments.

-- K.Prasad
 

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 1/2] [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags

2011-12-01 Thread K.Prasad
On Mon, Nov 28, 2011 at 02:11:11PM +1100, David Gibson wrote:
> [snip]
> On Wed, Oct 12, 2011 at 11:09:48PM +0530, K.Prasad wrote:
> > > > +   if (bp) {
> > > > +   attr = bp->attr;
> > > > +   attr.bp_addr = (unsigned long)bp_info->addr & 
> > > > ~HW_BREAKPOINT_ALIGN;
> > > > +   arch_bp_generic_fields(dabr &
> > > > +   (DABR_DATA_WRITE | 
> > > > DABR_DATA_READ),
> > > > +   &attr.bp_type);
> > > > +   attr.bp_len = len;
> > > 
> > > If gdb is using the new breakpoint interface, surely it should just
> > > use it, rather than doing this bit frobbing as in the old SET_DABR
> > > call.
> > > 
> > 
> > I understand that you wanted to avoid this duplication of effort in terms
> > of encoding and decoding the breakpoint type from
> > PPC_BREAKPOINT_TRIGGER_READ to DABR_DATA_READ to HW_BREAKPOINT_R.
> > 
> > However HW_BREAKPOINT_R is a generic definition used across
> > architectures, DABR_DATA_READ is used in the !CONFIG_HAVE_HW_BREAKPOINT
> > case while PPC_BREAKPOINT_TRIGGER_READ is used in
> > CONFIG_PPC_ADV_DEBUG_REGS case.
> > 
> > While we could define PPC_BREAKPOINT_TRIGGER_READ and DABR_DATA_READ to
> > the same value it may not result in any code savings (since the bit
> > translation is done for !CONFIG_HAVE_HW_BREAKPOINT case anyway). So, I
> > think it is best left the way it is.
> 
> That's not what I'm suggesting.  What I'm saying is that ig userspace
> is using the new generic interface, then it should just set the
> bp_type field, and it should not use the DABR_DATA_{READ,WRITE} bits.
> The DABR_DATA bits should *only* be processed in the legacy interface,
> never in the generic interface.
> 

The DABR_DATA_{READ,WRITE} bits are neither set by the user, nor
expected by the hw-breakpoint interface. It is an intermediate code used
to re-use the arch_bp_generic_fields function. We could convert directly
from PPC_BREAKPOINT_TRIGGER_READ to HW_BREAKPOINT_R (using a switch-case)
but that may not result in any code savings.

DABR_DATA_{READ,WRITE} is indeed legacy and cannot be set by user-space
for a PPC_PTRACE_SETHWDEBUG + CONFIG_HAVE_HW_BREAKPOINT combination.

[snipped]

> > diff --git a/Documentation/powerpc/ptrace.txt 
> > b/Documentation/powerpc/ptrace.txt
> > index f4a5499..f2a7a39 100644
> > --- a/Documentation/powerpc/ptrace.txt
> > +++ b/Documentation/powerpc/ptrace.txt
> > @@ -127,6 +127,22 @@ Some examples of using the structure to:
> >p.addr2   = (uint64_t) end_range;
> >p.condition_value = 0;
> >  
> > +- set a watchpoint in server processors (BookS)
> > +
> > +  p.version = 1;
> > +  p.trigger_type= PPC_BREAKPOINT_TRIGGER_RW;
> > +  p.addr_mode   = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
> > +  or
> > +  p.addr_mode   = PPC_BREAKPOINT_MODE_EXACT;
> > +
> > +  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
> > +  p.addr= (uint64_t) begin_range;
> 
> You should probably document the alignment constraint on the address
> here, too.
> 

Alignment constraints will be learnt by the user-space during runtime.
We provide that as part of 'struct ppc_debug_info' in
'data_bp_alignment' field.

While the alignment is always 8-bytes for BookS, I think userspace
should be left to learn it through PTRACE_PPC_GETHWDEBUGINFO.

> > +  /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, 
> > where
> > +   * addr2 - addr <= 8 Bytes.
> > +   */
> > +  p.addr2   = (uint64_t) end_range;
> > +  p.condition_value = 0;
> > +
> >  3. PTRACE_DELHWDEBUG
> >  
> >  Takes an integer which identifies an existing breakpoint or watchpoint
> > diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> > index 05b7dd2..be5dc57 100644
> > --- a/arch/powerpc/kernel/ptrace.c
> > +++ b/arch/powerpc/kernel/ptrace.c
> > @@ -1339,6 +1339,12 @@ static int set_dac_range(struct task_struct *child,
> >  static long ppc_set_hwdebug(struct task_struct *child,
> >  struct ppc_hw_breakpoint *bp_info)
> >  {
> > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > +   int ret, len = 0;
> > +   struct thread_struct *thread = &(child->thread);
> > +   struct perf_event *bp;
> > +   struct perf_event_attr attr;
> > +#endif /* CONFIG_HAVE_HW_BREAKPOINT */
> >  #ifndef CONFIG_PPC_ADV_DEBUG_REGS
>

Re: [PATCH 1/2] [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags

2011-10-12 Thread K.Prasad
On Wed, Oct 12, 2011 at 02:33:59PM +1100, David Gibson wrote:
> On Fri, Sep 16, 2011 at 12:57:10PM +0530, K.Prasad wrote:
> > On Fri, Aug 26, 2011 at 03:05:52PM +0530, K.Prasad wrote:
> > > On Wed, Aug 24, 2011 at 01:59:39PM +1000, David Gibson wrote:
> > > > On Tue, Aug 23, 2011 at 02:55:13PM +0530, K.Prasad wrote:
> > > > > On Tue, Aug 23, 2011 at 03:08:50PM +1000, David Gibson wrote:
> > > > > > On Fri, Aug 19, 2011 at 01:21:36PM +0530, K.Prasad wrote:
[snipped]
> > [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace 
> > flags
> > 
> > PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG and 
> > PPC_PTRACE_DELHWDEBUG are
> > PowerPC specific ptrace flags that use the watchpoint register. While 
> > they are
> > targeted primarily towards BookE users, user-space applications such as 
> > GDB
> > have started using them for BookS too.
> > 
> > This patch enables the use of generic hardware breakpoint interfaces 
> > for these
> > new flags. The version number of the associated data structures
> > "ppc_hw_breakpoint" and "ppc_debug_info" is incremented to denote new 
> > semantics.
> 
> Above pargraph needs revision.
> 
> 

Sure, done.

> > Apart from the usual benefits of using generic hw-breakpoint 
> > interfaces, these
> > changes allow debuggers (such as GDB) to use a common set of ptrace 
> > flags for
> > their watchpoint needs and allow more precise breakpoint specification 
> > (length
> > of the variable can be specified).
> > 
> > [Edjunior: Identified an issue in the patch with the sanity check for 
> > version
> > numbers]
> > 
> > Tested-by: Edjunior Barbosa Machado 
> > Signed-off-by: K.Prasad 
> > 
> > diff --git a/Documentation/powerpc/ptrace.txt 
> > b/Documentation/powerpc/ptrace.txt
> > index f4a5499..04656ec 100644
> > --- a/Documentation/powerpc/ptrace.txt
> > +++ b/Documentation/powerpc/ptrace.txt
> > @@ -127,6 +127,22 @@ Some examples of using the structure to:
> >p.addr2   = (uint64_t) end_range;
> >p.condition_value = 0;
> >  
> > +- set a watchpoint in server processors (BookS)
> > +
> > +  p.version = 1;
> > +  p.trigger_type= PPC_BREAKPOINT_TRIGGER_RW;
> > +  p.addr_mode   = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
> > +  or
> > +  p.addr_mode   = PPC_BREAKPOINT_MODE_RANGE_EXACT;
> 
> MODE_RANGE_EXACT?  Shouldn't that just be MODE_EXACT?
> 

That was silly. Thanks for pointing it out.

> > +
> > +  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
> > +  p.addr= (uint64_t) begin_range;
> > +  /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, 
> > where
> > +   * addr2 - addr <= 8 Bytes.
> > +   */
> > +  p.addr2   = (uint64_t) end_range;
> > +  p.condition_value = 0;
> > +
> >  3. PTRACE_DELHWDEBUG
> >  
> >  Takes an integer which identifies an existing breakpoint or watchpoint
> > diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> > index 05b7dd2..2449495 100644
> > --- a/arch/powerpc/kernel/ptrace.c
> > +++ b/arch/powerpc/kernel/ptrace.c
> > @@ -1339,6 +1339,12 @@ static int set_dac_range(struct task_struct *child,
> >  static long ppc_set_hwdebug(struct task_struct *child,
> >  struct ppc_hw_breakpoint *bp_info)
> >  {
> > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > +   int ret, len = 0;
> > +   struct thread_struct *thread = &(child->thread);
> > +   struct perf_event *bp;
> > +   struct perf_event_attr attr;
> > +#endif /* CONFIG_HAVE_HW_BREAKPOINT */
> >  #ifndef CONFIG_PPC_ADV_DEBUG_REGS
> > unsigned long dabr;
> >  #endif
> > @@ -1382,13 +1388,9 @@ static long ppc_set_hwdebug(struct task_struct 
> > *child,
> >  */
> > if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
> > (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
> > -   bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
> > bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
> > return -EINVAL;
> >  
> > -   if (child->thread.dabr)
> > -   return -ENOSPC;
> > -
> > if ((unsigned long)bp_info->addr >= TASK_SIZE)
> > return -EIO;
> >  
> > @@ -1398,15 +1400,83 @@ static long ppc_set_hwdebug(struct task_struct 
> &

Re: [PATCH 1/2] [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags

2011-09-16 Thread K.Prasad
On Fri, Aug 26, 2011 at 03:05:52PM +0530, K.Prasad wrote:
> On Wed, Aug 24, 2011 at 01:59:39PM +1000, David Gibson wrote:
> > On Tue, Aug 23, 2011 at 02:55:13PM +0530, K.Prasad wrote:
> > > On Tue, Aug 23, 2011 at 03:08:50PM +1000, David Gibson wrote:
> > > > On Fri, Aug 19, 2011 at 01:21:36PM +0530, K.Prasad wrote:
> > > > > PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG and 
> > > > > PPC_PTRACE_DELHWDEBUG are
> > > > > PowerPC specific ptrace flags that use the watchpoint register. While 
> > > > > they are
> > > > > targeted primarily towards BookE users, user-space applications such 
> > > > > as GDB
> > > > > have started using them for BookS too.
> > > > > 
> > > > > This patch enables the use of generic hardware breakpoint interfaces 
> > > > > for these
> > > > > new flags. The version number of the associated data structures
> > > > > "ppc_hw_breakpoint" and "ppc_debug_info" is incremented to denote new 
> > > > > semantics.
> > > > 
> > > > So, the structure itself doesn't seem to have been extended.  I don't
> > > > understand what the semantic difference is - your patch comment needs
> > > > to explain this clearly.
> > > >
> > > 
> > > We had a request to extend the structure but thought it was dangerous to
> > > do so. For instance if the user-space used version1 of the structure,
> > > while kernel did a copy_to_user() pertaining to version2, then we'd run
> > > into problems. Unfortunately the ptrace flags weren't designed to accept
> > > a version number as input from the user through the
> > > PPC_PTRACE_GETHWDBGINFO flag (which would have solved this issue).
> > 
> > I still don't follow you.
> > 
> 
> Two things here.
> 
> One, the change of semantics warranted an increment of the version
> number. The new semantics accepts PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE on
> BookS, while the old version number did not. I've added a small comment
> in the code to this effect.
> 
> Two, regarding changes in the "ppc_hw_breakpoint" and "ppc_debug_info"
> structures - we would like to add more members to it if we can (GDB has a
> pending request to add more members to it). However the problem foreseen
> is that there could be a mismatch between the versions of the structure
> used by the user vs kernel-space i.e. if a new version of the structure,
> known to the kernel, had an extra member while the user-space still had
> the old version, then it becomes dangerous because the __copy_to_user
> function would overflow the buffer size in user-space.
> 
> This could have been avoided if PPC_PTRACE_GETHWDBGINFO was originally
> designed to accept a version number (and provide corresponding
> "struct ppc_debug_info") rather than send a populated "ppc_debug_info"
> structure along with the version number.
>

Based on further discussions with the code-reviewer (David Gibson
), it was decided that incrementing the version number
for the proposed changes is unnecessary as the patch only introduces new
features but not a change in semantics.

Please find a new version of the patch where the version number is
retained as 1, along with the other planned changes.

Thanks,
K.Prasad

 
[hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace 
flags

PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG and PPC_PTRACE_DELHWDEBUG are
PowerPC specific ptrace flags that use the watchpoint register. While they 
are
targeted primarily towards BookE users, user-space applications such as GDB
have started using them for BookS too.

This patch enables the use of generic hardware breakpoint interfaces for 
these
new flags. The version number of the associated data structures
"ppc_hw_breakpoint" and "ppc_debug_info" is incremented to denote new 
semantics.

Apart from the usual benefits of using generic hw-breakpoint interfaces, 
these
changes allow debuggers (such as GDB) to use a common set of ptrace flags 
for
their watchpoint needs and allow more precise breakpoint specification 
(length
of the variable can be specified).

[Edjunior: Identified an issue in the patch with the sanity check for 
version
numbers]

Tested-by: Edjunior Barbosa Machado 
Signed-off-by: K.Prasad 

diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt
index f4a5499..04656ec 100644
--- a/Documentation/powerpc/ptrace.txt
+++ b/Documentation/powerpc/ptrace.txt
@@ -127,6 +127,22 @@ Some examples of

Re: [PATCH 1/2] [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags

2011-08-26 Thread K.Prasad
On Wed, Aug 24, 2011 at 01:59:39PM +1000, David Gibson wrote:
> On Tue, Aug 23, 2011 at 02:55:13PM +0530, K.Prasad wrote:
> > On Tue, Aug 23, 2011 at 03:08:50PM +1000, David Gibson wrote:
> > > On Fri, Aug 19, 2011 at 01:21:36PM +0530, K.Prasad wrote:
> > > > PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG and 
> > > > PPC_PTRACE_DELHWDEBUG are
> > > > PowerPC specific ptrace flags that use the watchpoint register. While 
> > > > they are
> > > > targeted primarily towards BookE users, user-space applications such as 
> > > > GDB
> > > > have started using them for BookS too.
> > > > 
> > > > This patch enables the use of generic hardware breakpoint interfaces 
> > > > for these
> > > > new flags. The version number of the associated data structures
> > > > "ppc_hw_breakpoint" and "ppc_debug_info" is incremented to denote new 
> > > > semantics.
> > > 
> > > So, the structure itself doesn't seem to have been extended.  I don't
> > > understand what the semantic difference is - your patch comment needs
> > > to explain this clearly.
> > >
> > 
> > We had a request to extend the structure but thought it was dangerous to
> > do so. For instance if the user-space used version1 of the structure,
> > while kernel did a copy_to_user() pertaining to version2, then we'd run
> > into problems. Unfortunately the ptrace flags weren't designed to accept
> > a version number as input from the user through the
> > PPC_PTRACE_GETHWDBGINFO flag (which would have solved this issue).
> 
> I still don't follow you.
> 

Two things here.

One, the change of semantics warranted an increment of the version
number. The new semantics accepts PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE on
BookS, while the old version number did not. I've added a small comment
in the code to this effect.

Two, regarding changes in the "ppc_hw_breakpoint" and "ppc_debug_info"
structures - we would like to add more members to it if we can (GDB has a
pending request to add more members to it). However the problem foreseen
is that there could be a mismatch between the versions of the structure
used by the user vs kernel-space i.e. if a new version of the structure,
known to the kernel, had an extra member while the user-space still had
the old version, then it becomes dangerous because the __copy_to_user
function would overflow the buffer size in user-space.

This could have been avoided if PPC_PTRACE_GETHWDBGINFO was originally
designed to accept a version number (and provide corresponding
"struct ppc_debug_info") rather than send a populated "ppc_debug_info"
structure along with the version number.

> > I'll add a comment w.r.t change in semantics - such as the ability to
> > accept 'range' breakpoints in BookS.
> >  
> > > > Apart from the usual benefits of using generic hw-breakpoint 
> > > > interfaces, these
> > > > changes allow debuggers (such as GDB) to use a common set of ptrace 
> > > > flags for
> > > > their watchpoint needs and allow more precise breakpoint specification 
> > > > (length
> > > > of the variable can be specified).
> > > 
> > > What is the mechanism for implementing the range breakpoint on book3s?
> > > 
> > 
> > The hw-breakpoint interface, accepts length as an argument in BookS (any
> > value <= 8 Bytes) and would filter out extraneous interrupts arising out
> > of accesses outside the range comprising  inside
> > hw_breakpoint_handler function.
> > 
> > We put that ability to use here.
> 
> Ah, so in hardware the breakpoints are always 8 bytes long, but you
> filter out false hits on a shorter range?  Of course, the utility of
> range breakpoints is questionable when length <=8, but the start must
> be aligned on an 8-byte boundary.
> 

Yes, we ensure that through 
+   attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN;

> [snip]
> > > > if ((unsigned long)bp_info->addr >= TASK_SIZE)
> > > > return -EIO;
> > > >  
> > > > @@ -1398,15 +1400,86 @@ static long ppc_set_hwdebug(struct task_struct 
> > > > *child,
> > > > dabr |= DABR_DATA_READ;
> > > > if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
> > > > dabr |= DABR_DATA_WRITE;
> > > > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > > > +   if (bp_info->version == 1)
> > > > + 

Re: [PATCH 2/2] [PowerPC Book3E] Introduce new ptrace debug feature flag

2011-08-23 Thread K.Prasad
On Tue, Aug 23, 2011 at 03:09:31PM +1000, David Gibson wrote:
> On Fri, Aug 19, 2011 at 01:23:38PM +0530, K.Prasad wrote:
> > 
> > While PPC_PTRACE_SETHWDEBUG ptrace flag in PowerPC accepts
> > PPC_BREAKPOINT_MODE_EXACT mode of breakpoint, the same is not intimated to 
> > the
> > user-space debuggers (like GDB) who may want to use it. Hence we introduce a
> > new PPC_DEBUG_FEATURE_DATA_BP_EXACT flag which will be populated on the
> > "features" member of "struct ppc_debug_info" to advertise support for the
> > same on Book3E PowerPC processors.
> 
> I thought the idea was that the BP_EXACT mode was the default - if the
> new interface was supported at all, then BP_EXACT was always
> supported.  So, why do you need a new flag?
> 

Yes, BP_EXACT was always supported but not advertised through
PPC_PTRACE_GETHWDBGINFO. We're now doing that.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 1/2] [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags

2011-08-23 Thread K.Prasad
On Tue, Aug 23, 2011 at 03:08:50PM +1000, David Gibson wrote:
> On Fri, Aug 19, 2011 at 01:21:36PM +0530, K.Prasad wrote:
> > PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG and PPC_PTRACE_DELHWDEBUG are
> > PowerPC specific ptrace flags that use the watchpoint register. While they 
> > are
> > targeted primarily towards BookE users, user-space applications such as GDB
> > have started using them for BookS too.
> > 
> > This patch enables the use of generic hardware breakpoint interfaces for 
> > these
> > new flags. The version number of the associated data structures
> > "ppc_hw_breakpoint" and "ppc_debug_info" is incremented to denote new 
> > semantics.
> 
> So, the structure itself doesn't seem to have been extended.  I don't
> understand what the semantic difference is - your patch comment needs
> to explain this clearly.
>

We had a request to extend the structure but thought it was dangerous to
do so. For instance if the user-space used version1 of the structure,
while kernel did a copy_to_user() pertaining to version2, then we'd run
into problems. Unfortunately the ptrace flags weren't designed to accept
a version number as input from the user through the
PPC_PTRACE_GETHWDBGINFO flag (which would have solved this issue).

I'll add a comment w.r.t change in semantics - such as the ability to
accept 'range' breakpoints in BookS.
 
> > Apart from the usual benefits of using generic hw-breakpoint interfaces, 
> > these
> > changes allow debuggers (such as GDB) to use a common set of ptrace flags 
> > for
> > their watchpoint needs and allow more precise breakpoint specification 
> > (length
> > of the variable can be specified).
> 
> What is the mechanism for implementing the range breakpoint on book3s?
> 

The hw-breakpoint interface, accepts length as an argument in BookS (any
value <= 8 Bytes) and would filter out extraneous interrupts arising out
of accesses outside the range comprising  inside
hw_breakpoint_handler function.

We put that ability to use here.

> > [Edjunior: Identified an issue in the patch with the sanity check for 
> > version
> > numbers]
> > 
> > Tested-by: Edjunior Barbosa Machado 
> > Signed-off-by: K.Prasad 
> > ---
> >  Documentation/powerpc/ptrace.txt |   16 ++
> >  arch/powerpc/kernel/ptrace.c |  104 
> > +++---
> >  2 files changed, 112 insertions(+), 8 deletions(-)
> > 
> > diff --git a/Documentation/powerpc/ptrace.txt 
> > b/Documentation/powerpc/ptrace.txt
> > index f4a5499..97301ae 100644
> > --- a/Documentation/powerpc/ptrace.txt
> > +++ b/Documentation/powerpc/ptrace.txt
> > @@ -127,6 +127,22 @@ Some examples of using the structure to:
> >p.addr2   = (uint64_t) end_range;
> >p.condition_value = 0;
> >  
> > +- set a watchpoint in server processors (BookS) using version 2
> > +
> > +  p.version = 2;
> > +  p.trigger_type= PPC_BREAKPOINT_TRIGGER_RW;
> > +  p.addr_mode   = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
> > +  or
> > +  p.addr_mode   = PPC_BREAKPOINT_MODE_RANGE_EXACT;
> > +
> > +  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
> > +  p.addr= (uint64_t) begin_range;
> > +  /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, 
> > where
> > +   * addr2 - addr <= 8 Bytes.
> > +   */
> > +  p.addr2   = (uint64_t) end_range;
> > +  p.condition_value = 0;
> > +
> >  3. PTRACE_DELHWDEBUG
> >  
> >  Takes an integer which identifies an existing breakpoint or watchpoint
> > diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> > index 05b7dd2..18d28b6 100644
> > --- a/arch/powerpc/kernel/ptrace.c
> > +++ b/arch/powerpc/kernel/ptrace.c
> > @@ -1339,11 +1339,17 @@ static int set_dac_range(struct task_struct *child,
> >  static long ppc_set_hwdebug(struct task_struct *child,
> >  struct ppc_hw_breakpoint *bp_info)
> >  {
> > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > +   int ret, len = 0;
> > +   struct thread_struct *thread = &(child->thread);
> > +   struct perf_event *bp;
> > +   struct perf_event_attr attr;
> > +#endif /* CONFIG_HAVE_HW_BREAKPOINT */
> 
> I'm confused.  This compiled before on book3s, and I don't see any
> changes to Makefile or Kconfig in the patch that will result in this
> code compiling  when it previously didn't   Why are these new guards
> added?
> 

The code is guarded using the CONFIG_ flags for two reasons.
a) We don't want the 

[PATCH 2/2] [PowerPC Book3E] Introduce new ptrace debug feature flag

2011-08-19 Thread K.Prasad

While PPC_PTRACE_SETHWDEBUG ptrace flag in PowerPC accepts
PPC_BREAKPOINT_MODE_EXACT mode of breakpoint, the same is not intimated to the
user-space debuggers (like GDB) who may want to use it. Hence we introduce a
new PPC_DEBUG_FEATURE_DATA_BP_EXACT flag which will be populated on the
"features" member of "struct ppc_debug_info" to advertise support for the
same on Book3E PowerPC processors.

Signed-off-by: K.Prasad 
---
 arch/powerpc/include/asm/ptrace.h |1 +
 arch/powerpc/kernel/ptrace.c  |1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index 48223f9..cf014f9 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -380,6 +380,7 @@ struct ppc_debug_info {
 #define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x0002
 #define PPC_DEBUG_FEATURE_DATA_BP_RANGE0x0004
 #define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x0008
+#define PPC_DEBUG_FEATURE_DATA_BP_EXACT0x0010
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 18d28b6..71db5a6 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1636,6 +1636,7 @@ long arch_ptrace(struct task_struct *child, long request,
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
dbginfo.features |=
   PPC_DEBUG_FEATURE_DATA_BP_RANGE |
+  PPC_DEBUG_FEATURE_DATA_BP_EXACT |
   PPC_DEBUG_FEATURE_DATA_BP_MASK;
 #endif
 #else /* !CONFIG_PPC_ADV_DEBUG_REGS */
-- 
1.7.4.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/2] [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags

2011-08-19 Thread K.Prasad
PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG and PPC_PTRACE_DELHWDEBUG are
PowerPC specific ptrace flags that use the watchpoint register. While they are
targeted primarily towards BookE users, user-space applications such as GDB
have started using them for BookS too.

This patch enables the use of generic hardware breakpoint interfaces for these
new flags. The version number of the associated data structures
"ppc_hw_breakpoint" and "ppc_debug_info" is incremented to denote new semantics.

Apart from the usual benefits of using generic hw-breakpoint interfaces, these
changes allow debuggers (such as GDB) to use a common set of ptrace flags for
their watchpoint needs and allow more precise breakpoint specification (length
of the variable can be specified).

[Edjunior: Identified an issue in the patch with the sanity check for version
numbers]

Tested-by: Edjunior Barbosa Machado 
Signed-off-by: K.Prasad 
---
 Documentation/powerpc/ptrace.txt |   16 ++
 arch/powerpc/kernel/ptrace.c |  104 +++---
 2 files changed, 112 insertions(+), 8 deletions(-)

diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt
index f4a5499..97301ae 100644
--- a/Documentation/powerpc/ptrace.txt
+++ b/Documentation/powerpc/ptrace.txt
@@ -127,6 +127,22 @@ Some examples of using the structure to:
   p.addr2   = (uint64_t) end_range;
   p.condition_value = 0;
 
+- set a watchpoint in server processors (BookS) using version 2
+
+  p.version = 2;
+  p.trigger_type= PPC_BREAKPOINT_TRIGGER_RW;
+  p.addr_mode   = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+  or
+  p.addr_mode   = PPC_BREAKPOINT_MODE_RANGE_EXACT;
+
+  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
+  p.addr= (uint64_t) begin_range;
+  /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
+   * addr2 - addr <= 8 Bytes.
+   */
+  p.addr2   = (uint64_t) end_range;
+  p.condition_value = 0;
+
 3. PTRACE_DELHWDEBUG
 
 Takes an integer which identifies an existing breakpoint or watchpoint
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 05b7dd2..18d28b6 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1339,11 +1339,17 @@ static int set_dac_range(struct task_struct *child,
 static long ppc_set_hwdebug(struct task_struct *child,
 struct ppc_hw_breakpoint *bp_info)
 {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   int ret, len = 0;
+   struct thread_struct *thread = &(child->thread);
+   struct perf_event *bp;
+   struct perf_event_attr attr;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #ifndef CONFIG_PPC_ADV_DEBUG_REGS
unsigned long dabr;
 #endif
 
-   if (bp_info->version != 1)
+   if ((bp_info->version != 1) && (bp_info->version != 2))
return -ENOTSUPP;
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
/*
@@ -1382,13 +1388,9 @@ static long ppc_set_hwdebug(struct task_struct *child,
 */
if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
(bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
-   bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
return -EINVAL;
 
-   if (child->thread.dabr)
-   return -ENOSPC;
-
if ((unsigned long)bp_info->addr >= TASK_SIZE)
return -EIO;
 
@@ -1398,15 +1400,86 @@ static long ppc_set_hwdebug(struct task_struct *child,
dabr |= DABR_DATA_READ;
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
dabr |= DABR_DATA_WRITE;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   if (bp_info->version == 1)
+   goto version_one;
+   if (ptrace_get_breakpoints(child) < 0)
+   return -ESRCH;
 
-   child->thread.dabr = dabr;
+   bp = thread->ptrace_bps[0];
+   if (!bp_info->addr) {
+   if (bp) {
+   unregister_hw_breakpoint(bp);
+   thread->ptrace_bps[0] = NULL;
+   }
+   ptrace_put_breakpoints(child);
+   return 0;
+   }
+   /*
+* Check if the request is for 'range' breakpoints. We can
+* support it if range < 8 bytes.
+*/
+   if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
+   len = bp_info->addr2 - bp_info->addr;
+   else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
+   ptrace_put_breakpoints(child);
+   return -EINVAL;
+   }
+   if (bp) {
+   attr = bp->attr;
+   attr.bp_addr = (unsigned long)bp_info->addr & 
~HW_BREAKPOINT_ALIGN;
+   arch_bp_generic_fields(dabr &
+

[PATCH 0/2] Changes to PowerPC ptrace flags using watchpoints

2011-08-19 Thread K.Prasad
Hi All,
Please find a set of two patches that introduce generic
hw-breakpoint interfaces for a couple of ptrace flags used by server-class
processors and another change to advertise a feature to user-space hitherto
available and used, but not claimed as supported.

GDB, which recently began using the
PPC_PTRACE_GETHWDBGINFO/PPC_PTRACE_SETHWDEBUG/PPC_PTRACE_DELHWDEBUG
flags on BookS processors is presently unable to set watchpoints. The
changes in Patch1, will fix that issue and help it use a common set of code
across BookE and BookS.

K.Prasad (2):
  [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC
ptrace flags
  [PowerPC Book3E] Introduce new ptrace debug feature flag

 Documentation/powerpc/ptrace.txt  |   16 ++
 arch/powerpc/include/asm/ptrace.h |1 +
 arch/powerpc/kernel/ptrace.c  |  105
++---
 3 files changed, 114 insertions(+), 8 deletions(-)

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 2/6] hw_breakpoints: Migrate breakpoint conditional build under new config

2011-07-04 Thread K.Prasad
On Mon, Jul 04, 2011 at 03:29:14PM +0200, Frederic Weisbecker wrote:
> On Mon, Jul 04, 2011 at 06:57:46PM +0530, K.Prasad wrote:
> > On Tue, May 24, 2011 at 11:52:23PM +0200, Frederic Weisbecker wrote:
> > > Migrate conditional hw_breakpoint code compilation under
> > > the new config to prepare for letting the user chose whether
> > > or not to build this feature
> > > 
> > 
> > Making the hardware breakpoint patches modular has always been a goal.
> > I've looked at the PowerPC parts of the code and they look harmless.
> > 
> > Acked-by: K.Prasad 
> 
> Great!
> 
> I'll push that soon, thanks guys for your acks!

Meanwhile, I was testing hardware breakpoints through perf and found
that monitoring a given address fails when using 'perf record' (returns
-ENOSPC) while 'perf stat' and watchpoint through gdb works fine (see
logs below).

Has this behaviour been reported for other perf counters?

Thanks,
K.Prasad

# tools/perf/perf --version
perf version 3.0.0-rc5
# 
# grep pid_max /proc/kallsyms 
81a25010 D pid_max
81a25014 D pid_max_min
81a25018 D pid_max_max
# 
# uname -a
Linux llm37.in.ibm.com 3.0.0-rc5 #1 SMP Mon Jul 4 22:24:02 IST 2011
x86_64 x86_64 x86_64 GNU/Linux
# 
# tools/perf/perf stat -e mem:0x81a25010:rw make kernel/futex.o
  CHK include/linux/version.h
  CHK include/generated/utsrelease.h
  CALLscripts/checksyscalls.sh
make[1]: `kernel/futex.o' is up to date.

 Performance counter stats for 'make kernel/futex.o':

   188 mem:0x81a25010:rw   

  10.734957333 seconds time elapsed

# tools/perf/perf record -e
mem:0x81a25010:rw make kernel/futex.o

  Error: sys_perf_event_open() syscall returned with 28 (No space left
on device).  /bin/dmesg may provide additional information.

  Fatal: No CONFIG_PERF_EVENTS=y kernel support configured?

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 4/6] hw_breakpoints: Breakpoints arch ability don't need perf events

2011-07-04 Thread K.Prasad
On Tue, May 24, 2011 at 11:52:25PM +0200, Frederic Weisbecker wrote:
> The breakpoint support ability in an arch is not related
> to the fact perf events is built or not. HAVE_HW_BREAKPOINT
> only shows an ability so this dependency makes no sense
> anymore. Archs that select HAVE_HW_BREAKPOINT already
> ensure that perf event is built.
> 
> Remove that dependency.
> 
> Signed-off-by: Frederic Weisbecker 
> Cc: Ingo Molnar 
> Cc: Peter Zijlstra 
> Cc: Will Deacon 
> Cc: Prasad 
> Cc: Paul Mundt 
> ---
>  arch/Kconfig |1 -
>  1 files changed, 0 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/Kconfig b/arch/Kconfig
> index f78c2be..ce4be89 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -149,7 +149,6 @@ config HAVE_DEFAULT_NO_SPIN_MUTEXES
> 
>  config HAVE_HW_BREAKPOINT
>   bool
> - depends on PERF_EVENTS
> 
>  config HAVE_MIXED_BREAKPOINTS_REGS
>   bool
> -- 

Just a thought you might want to consider...

The need to keep the ability (HAVE_HW_BREAKPOINT) and the user-choice to
enable hardware breakpoints (through HW_BREAKPOINT) in separate config
options isn't very clear to me (and is a bit confusing with very similar
names).

Why not make HAVE_HW_BREAKPOINT selectable by the user (which in turn
would turn on PERF_EVENTS) for a given architecture?

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 2/6] hw_breakpoints: Migrate breakpoint conditional build under new config

2011-07-04 Thread K.Prasad
On Tue, May 24, 2011 at 11:52:23PM +0200, Frederic Weisbecker wrote:
> Migrate conditional hw_breakpoint code compilation under
> the new config to prepare for letting the user chose whether
> or not to build this feature
> 
> Signed-off-by: Frederic Weisbecker 
> Acked-by: Will Deacon 
> Cc: Ingo Molnar 
> Cc: Peter Zijlstra 
> Cc: Prasad 
> Cc: Paul Mundt 
> ---
>  arch/arm/include/asm/hw_breakpoint.h |4 ++--
>  arch/arm/include/asm/processor.h |2 +-
>  arch/arm/kernel/Makefile |2 +-
>  arch/arm/kernel/entry-header.S   |2 +-
>  arch/arm/kernel/ptrace.c |4 ++--
>  arch/powerpc/include/asm/cputable.h  |4 ++--
>  arch/powerpc/include/asm/hw_breakpoint.h |6 +++---
>  arch/powerpc/include/asm/processor.h |4 ++--
>  arch/powerpc/kernel/Makefile |2 +-
>  arch/powerpc/kernel/process.c|   18 +-
>  arch/powerpc/kernel/ptrace.c |   13 +++--
>  arch/powerpc/lib/Makefile|2 +-
>  arch/sh/kernel/Makefile  |2 +-
>  arch/sh/kernel/cpu/sh4a/Makefile |2 +-
>  include/linux/hw_breakpoint.h|6 +++---
>  include/linux/perf_event.h   |4 ++--
>  include/linux/ptrace.h   |6 +++---
>  include/linux/sched.h|2 +-
>  kernel/events/Makefile   |2 +-
>  kernel/events/core.c |4 ++--
>  kernel/ptrace.c  |4 ++--
>  samples/Kconfig  |2 +-
>  22 files changed, 49 insertions(+), 48 deletions(-)
> 

Making the hardware breakpoint patches modular has always been a goal.
I've looked at the PowerPC parts of the code and they look harmless.

Acked-by: K.Prasad 

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/5] powerpc, hw_breakpoints: Fix racy access to ptrace breakpoints

2011-04-24 Thread K.Prasad
On Fri, Apr 22, 2011 at 03:16:27PM +0200, Frederic Weisbecker wrote:
> (resend with ppc list in cc)
> 
> While the tracer accesses ptrace breakpoints, the child task may
> concurrently exit due to a SIGKILL and thus release its breakpoints
> at the same time. We can then dereference some freed pointers.
> 
> To fix this, hold a reference on the child breakpoints before
> manipulating them.
> 
> Reported-by: Oleg Nesterov 
> Signed-off-by: Frederic Weisbecker 
> Cc: Ingo Molnar 
> Cc: Benjamin Herrenschmidt 
> Cc: Peter Zijlstra 
> Cc: Will Deacon 
> Cc: Prasad 
> Cc: Paul Mundt 
> Cc: v2.6.33.. 
> ---
>  arch/powerpc/kernel/ptrace.c |3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> index 55613e3..4edeeb3 100644
> --- a/arch/powerpc/kernel/ptrace.c
> +++ b/arch/powerpc/kernel/ptrace.c
> @@ -1591,7 +1591,10 @@ long arch_ptrace(struct task_struct *child, long 
> request,
>   }
> 
>   case PTRACE_SET_DEBUGREG:
> + if (ptrace_get_breakpoints(child) < 0)
> + return -ESRCH;
>   ret = ptrace_set_debugreg(child, addr, data);
> + ptrace_put_breakpoints(child);
>   break;
> 
>  #ifdef CONFIG_PPC64
> -- 
> 1.7.3.2
>

Hi Frederic,
Looks fine to me.

Acked-by: K.Prasad 

Thanks,
K.Prasad 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] powerpc: Fix call to flush_ptrace_hw_breakpoint()

2011-02-10 Thread K.Prasad
On Mon, Feb 07, 2011 at 04:13:37PM +1100, Benjamin Herrenschmidt wrote:
> On Mon, 2011-02-07 at 10:22 +0530, K.Prasad wrote:
> > Okay! Another wrapper of "#ifndef CONFIG_HAVE_HW_BREAKPOINT" around
> > the
> > definition of 'set_debug_reg_defaults'.
> 
> Can you send a patch ?
>

Pasted below.
 
> > There's indeed too much sprinkling of #ifdefs in the code, but most of
> > it would go away when the BookE code also uses the generic
> > hw-breakpoint interfaces. 
> 
> What's your status for those patches ?
> 

The last I checked, I knew that the version of patchset I sent out
(linuxppc-dev message id: 20100629165152.ga8...@in.ibm.com)
didn't actually work when tested on hardware (it was just compile tested
before sending). It needs substantial amount of time to get it in shape,
which I'm unfortunately lacking now (plenty of priority items in hand that
needs dedicated attention).

Thanks,
K.Prasad

Fix the error in spelling the config option for hw-breakpoints and fix
the build issue that follows.

Signed-off by: K.Prasad 
---
 arch/powerpc/kernel/process.c |8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

Index: linux-2.6.set_hwdebug/arch/powerpc/kernel/process.c
===
--- linux-2.6.set_hwdebug.orig/arch/powerpc/kernel/process.c
+++ linux-2.6.set_hwdebug/arch/powerpc/kernel/process.c
@@ -353,6 +353,7 @@ static void switch_booke_debug_regs(stru
prime_debug_regs(new_thread);
 }
 #else  /* !CONFIG_PPC_ADV_DEBUG_REGS */
+#ifndef CONFIG_HAVE_HW_BREAKPOINT
 static void set_debug_reg_defaults(struct thread_struct *thread)
 {
if (thread->dabr) {
@@ -360,6 +361,7 @@ static void set_debug_reg_defaults(struc
set_dabr(0);
}
 }
+#endif /* !CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* CONFIG_PPC_ADV_DEBUG_REGS */
 
 int set_dabr(unsigned long dabr)
@@ -670,11 +672,11 @@ void flush_thread(void)
 {
discard_lazy_cpu_state();
 
-#ifdef CONFIG_HAVE_HW_BREAKPOINTS
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
flush_ptrace_hw_breakpoint(current);
-#else /* CONFIG_HAVE_HW_BREAKPOINTS */
+#else /* CONFIG_HAVE_HW_BREAKPOINT */
set_debug_reg_defaults(¤t->thread);
-#endif /* CONFIG_HAVE_HW_BREAKPOINTS */
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 }
 
 void

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] powerpc: Fix call to flush_ptrace_hw_breakpoint()

2011-02-06 Thread K.Prasad
On Mon, Feb 07, 2011 at 02:10:39PM +1100, Benjamin Herrenschmidt wrote:
> On Mon, 2011-02-07 at 08:26 +0530, K.Prasad wrote:
> > On Mon, Feb 07, 2011 at 09:54:13AM +1100, Benjamin Herrenschmidt wrote:
> > > A typo in the #ifdef statement makes us never call it
> > > in flush_thread()
> > >
> > 
> > I wish it never compiled for such typos :-)
> > 
> >  
> > > Signed-off-by: Benjamin Herrenschmidt 
> > Acked-by: K.Prasad 
> 
> Interestingly, that 'fix' now breaks the build:
> 
> cc1: warnings being treated as errors
> /home/benh/linux-powerpc-test/arch/powerpc/kernel/process.c:356: error:
> 'set_debug_reg_defaults' defined but not used 
> 
> This file is is becoming an absolute mess of ifdef's in large part due
> to the new BookE debug stuff and your HW breakpoint stuff... Any chance
> you and Shaggy see if you can improve that situation a bit ?
> 
> Cheers,
> Ben.
> 
> 

Okay! Another wrapper of "#ifndef CONFIG_HAVE_HW_BREAKPOINT" around the
definition of 'set_debug_reg_defaults'.

There's indeed too much sprinkling of #ifdefs in the code, but most of
it would go away when the BookE code also uses the generic hw-breakpoint
interfaces. Given the advanced debug features that BookE supports, it's
unfortunately not that straight-forward (needs additions to generic
hw-breakpoint infrastructure).

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] powerpc: Fix call to flush_ptrace_hw_breakpoint()

2011-02-06 Thread K.Prasad
On Mon, Feb 07, 2011 at 09:54:13AM +1100, Benjamin Herrenschmidt wrote:
> A typo in the #ifdef statement makes us never call it
> in flush_thread()
>

I wish it never compiled for such typos :-)

 
> Signed-off-by: Benjamin Herrenschmidt 
Acked-by: K.Prasad 

> ---
> 
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index 7a1d5cb..c4e4eab 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -670,11 +670,11 @@ void flush_thread(void)
>  {
>   discard_lazy_cpu_state();
> 
> -#ifdef CONFIG_HAVE_HW_BREAKPOINTS
> +#ifdef CONFIG_HAVE_HW_BREAKPOINT
>   flush_ptrace_hw_breakpoint(current);
> -#else /* CONFIG_HAVE_HW_BREAKPOINTS */
> +#else /* CONFIG_HAVE_HW_BREAKPOINT */
>   set_debug_reg_defaults(¤t->thread);
> -#endif /* CONFIG_HAVE_HW_BREAKPOINTS */
> +#endif /* CONFIG_HAVE_HW_BREAKPOINT */
>  }
> 
>  void
> 
> 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: ppc_set_hwdebug vs ptrace_set_debugreg

2011-01-02 Thread K.Prasad
On Thu, Dec 16, 2010 at 06:07:47PM +0100, Andreas Schwab wrote:
> "K.Prasad"  writes:
> 
> > How about the revised patch below? It is only compile-tested; have you
> > got a quick test case that I can run?
> 
> It crashes the kernel when running the watch-vfork test.
> 
> Andreas.
>

Hi Andreas,
I tried running it multiple times but saw no crash (or error
messages in dmesg). Can you send me the crash logs? What's the behaviour
when the testcase is run on an unpatched kernel?

The watch-vfork test actually fails on my system (4 unexpected failures)
irrespective of the kernel containing the patch or not.

Thanks,
K.Prasad
P.S.: I'd been on vacation and couldn't look at this issue during then.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: ppc_set_hwdebug vs ptrace_set_debugreg

2010-12-14 Thread K.Prasad
On Mon, Dec 13, 2010 at 08:05:36PM +0100, Andreas Schwab wrote:
> "K.Prasad"  writes:
> 
> > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > +   /* Create a new breakpoint request if one doesn't exist already */
> > +   hw_breakpoint_init(&attr);
> > +   attr.bp_addr = bp_info->addr & ~HW_BREAKPOINT_ALIGN;
> > +   arch_bp_generic_fields(bp_info->addr &
> > +   (DABR_DATA_WRITE | DABR_DATA_READ),
> > +   &attr.bp_type);
> > +
> > +   bp = register_user_hw_breakpoint(&attr, ptrace_triggered, task);
> > +   if (IS_ERR(bp))
> > +   return PTR_ERR(bp);
> > +
> > +   child->thread.ptrace_bps[0] = bp;
> > +#endif /* CONFIG_HAVE_HW_BREAKPOINT */
> > +
> > child->thread.dabr = (unsigned long)bp_info->addr;
> 
> That cannot work, see
> <http://permalink.gmane.org/gmane.linux.ports.ppc64.devel/71418>.
>

Ok. The above patch makes it a bit easy.

How about the revised patch below? It is only compile-tested; have you
got a quick test case that I can run?

Enable PPC_PTRACE_SETHWDEBUG and PPC_PTRACE_DELHWDEBUG to use the generic
hardware breakpoint interfaces. This helps prevent conflict for the use of
DABR register in the absence of CONFIG_PPC_ADV_DEBUG_REGS and when
PTRACE_SET_DEBUGREG/PTRACE_GET_DEBUGREG flags are used by ptrace.

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/ptrace.c |   32 
 1 file changed, 32 insertions(+)

Index: linux-2.6.set_hwdebug/arch/powerpc/kernel/ptrace.c
===
--- linux-2.6.set_hwdebug.orig/arch/powerpc/kernel/ptrace.c
+++ linux-2.6.set_hwdebug/arch/powerpc/kernel/ptrace.c
@@ -1316,6 +1316,10 @@ static int set_dac_range(struct task_str
 static long ppc_set_hwdebug(struct task_struct *child,
 struct ppc_hw_breakpoint *bp_info)
 {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   struct perf_event *bp;
+   struct perf_event_attr attr;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #ifndef CONFIG_PPC_ADV_DEBUG_REGS
unsigned long dabr;
 #endif
@@ -1365,6 +1369,10 @@ static long ppc_set_hwdebug(struct task_
 
if (child->thread.dabr)
return -ENOSPC;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   if (child->thread.ptrace_bps[0])
+   return -ENOSPC;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
if ((unsigned long)bp_info->addr >= TASK_SIZE)
return -EIO;
@@ -1376,6 +1384,20 @@ static long ppc_set_hwdebug(struct task_
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
dabr |= DABR_DATA_WRITE;
 
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   /* Create a new breakpoint request if one doesn't exist already */
+   hw_breakpoint_init(&attr);
+   attr.bp_addr = dabr & ~HW_BREAKPOINT_ALIGN;
+   arch_bp_generic_fields(dabr & (DABR_DATA_WRITE | DABR_DATA_READ),
+   &attr.bp_type);
+
+   bp = register_user_hw_breakpoint(&attr, ptrace_triggered, child);
+   if (IS_ERR(bp))
+   return PTR_ERR(bp);
+
+   child->thread.ptrace_bps[0] = bp;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
child->thread.dabr = dabr;
 
return 1;
@@ -1405,6 +1427,16 @@ static long ppc_del_hwdebug(struct task_
return -EINVAL;
if (child->thread.dabr == 0)
return -ENOENT;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   /*
+* There is no way by which address in ptrace_bps[0] and thread.dabr
+* can be different. So we don't explicitly check if they're the same
+*/
+   if (child->thread.ptrace_bps[0]) {
+   unregister_hw_breakpoint(child->thread.ptrace_bps[0]);
+   child->thread.ptrace_bps[0] = NULL;
+   }
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
child->thread.dabr = 0;
 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: ppc_set_hwdebug vs ptrace_set_debugreg

2010-12-13 Thread K.Prasad
On Wed, Dec 01, 2010 at 10:07:58AM +0530, K.Prasad wrote:
> On Mon, Nov 29, 2010 at 11:15:51AM +0100, Andreas Schwab wrote:
> > "K.Prasad"  writes:
> > 
> > > Although ppc_set_hwdebug() can set DABR through set_dabr() in
> > > arch/powerpc/kernel/process.c, it is good to have it converted to use
> > > register_user_hw_breakpoint().
> > 
> > What do you mean with "good to have"?  It doesn't work without it unless
> > I disable PERF_EVENTS (which is the only way to disable
> > HAVE_HW_BREAKPOINT).
> > 
> > Andreas.
> >
> 
> Let me see if I can cook up a patch for this i.e. make set_dabr() invoke
> register_user_hw_breakpoint() when CONFIG_PPC_BOOK3S is defined; before I
> head out on my vacation (starting second week of this month).
> 
> Thanks,
> K.Prasad
>

Hi,
Can you check if the following patch (compile tested only) works
for you?

Thanks,
K.Prasad
  
Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/ptrace.c |   34 ++
 1 file changed, 34 insertions(+)

Index: linux-2.6.set_hwdebug/arch/powerpc/kernel/ptrace.c
===
--- linux-2.6.set_hwdebug.orig/arch/powerpc/kernel/ptrace.c
+++ linux-2.6.set_hwdebug/arch/powerpc/kernel/ptrace.c
@@ -1316,6 +1316,11 @@ static int set_dac_range(struct task_str
 static long ppc_set_hwdebug(struct task_struct *child,
 struct ppc_hw_breakpoint *bp_info)
 {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   struct perf_event *bp;
+   struct perf_event_attr attr;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
if (bp_info->version != 1)
return -ENOTSUPP;
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
@@ -1362,10 +1367,29 @@ static long ppc_set_hwdebug(struct task_
 
if (child->thread.dabr)
return -ENOSPC;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   if (child->thread->ptrace_bps[0])
+   return -ENOSPC;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
if ((unsigned long)bp_info->addr >= TASK_SIZE)
return -EIO;
 
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   /* Create a new breakpoint request if one doesn't exist already */
+   hw_breakpoint_init(&attr);
+   attr.bp_addr = bp_info->addr & ~HW_BREAKPOINT_ALIGN;
+   arch_bp_generic_fields(bp_info->addr &
+   (DABR_DATA_WRITE | DABR_DATA_READ),
+   &attr.bp_type);
+
+   bp = register_user_hw_breakpoint(&attr, ptrace_triggered, task);
+   if (IS_ERR(bp))
+   return PTR_ERR(bp);
+
+   child->thread.ptrace_bps[0] = bp;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
child->thread.dabr = (unsigned long)bp_info->addr;
 
return 1;
@@ -1395,6 +1419,16 @@ static long ppc_del_hwdebug(struct task_
return -EINVAL;
if (child->thread.dabr == 0)
return -ENOENT;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   /*
+* There is no way by which address in ptrace_bps[0] and thread.dabr
+* can be different. So we don't explicitly check if they're the same
+*/
+   if (child->thread.ptrace_bps[0]) {
+   unregister_hw_breakpoint(child->thread.ptrace_bps[0]);
+   child->thread.ptrace_bps[0] = NULL;
+   }
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
child->thread.dabr = 0;
 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: ppc_set_hwdebug vs ptrace_set_debugreg

2010-11-30 Thread K.Prasad
On Mon, Nov 29, 2010 at 11:15:51AM +0100, Andreas Schwab wrote:
> "K.Prasad"  writes:
> 
> > Although ppc_set_hwdebug() can set DABR through set_dabr() in
> > arch/powerpc/kernel/process.c, it is good to have it converted to use
> > register_user_hw_breakpoint().
> 
> What do you mean with "good to have"?  It doesn't work without it unless
> I disable PERF_EVENTS (which is the only way to disable
> HAVE_HW_BREAKPOINT).
> 
> Andreas.
>

Let me see if I can cook up a patch for this i.e. make set_dabr() invoke
register_user_hw_breakpoint() when CONFIG_PPC_BOOK3S is defined; before I
head out on my vacation (starting second week of this month).

Thanks,
K.Prasad
 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: ppc_set_hwdebug vs ptrace_set_debugreg

2010-11-28 Thread K.Prasad
On Sat, Nov 27, 2010 at 08:36:30PM +0100, Andreas Schwab wrote:
> Why does ptrace_set_debugreg call register_user_hw_breakpoint, but
> ppc_set_hwdebug doesn't?  Shouldn't ppc_set_hwdebug set the
> DABR_DATA_(READ|WRITE|TRANSLATION) bits in the dabr?
> 
> Andreas.

The hw-breakpoint interfaces were initially planned for the old ptrace
option PTRACE_SET_DEBUGREG,while, the newer ptrace options are mostly
to exploit the advanced debug features of Book3E processors.

Although ppc_set_hwdebug() can set DABR through set_dabr() in
arch/powerpc/kernel/process.c, it is good to have it converted to use
register_user_hw_breakpoint(). This was planned to be done alongside the
conversion of all ptrace options enabled by CONFIG_PPC_ADV_DEBUG_REGS,
which is yet to be done.

Are you looking to use debug registers through perf, or somesuch, that
you need register_user_hw_breakpoint() to be used for these new ptrace
flags?

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 02/13] powerpc/book3e: Hack to get gdb moving along on Book3E 64-bit

2010-07-09 Thread K.Prasad
On Fri, Jul 09, 2010 at 04:16:44PM +1000, Benjamin Herrenschmidt wrote:

Hi,
   A few questions and some trivial comments below.

> Our handling of debug interrupts on Book3E 64-bit is not quite
> the way it should be just yet. This is a workaround to let gdb
> work at least for now. We ensure that when context switching,
> we set the appropriate DBCR0 value for the new task. We also
> make sure that we turn off MSR[DE] within the kernel, and set
> it as part of the bits that get set when going back to userspace.
> 

I think I'm missing the code where MSR_DE is set before returning
to user-space? I just found one instance where MSR_USER64 (which now
includes MSR_DE) is used (in start_thread()). If not set, we'll lose the
interrupts caused in IDM too.

> In the long run, we will probably set the userspace DBCR0 on the
> exception exit code path and ensure we have some proper kernel
> value to set on the way into the kernel, a bit like ppc32 does,
> but that will take more work.

The effort to port ppc32 BookIII E debug register usage to use generic
hw-breakpoint interfaces (linuxppc-dev message-id:
20100629165152.ga8...@in.ibm.com), in its final form, should cleanup
most of this code. Even the hook switch_booke_debug_regs() in
__switch_to() should be done away.

> Signed-off-by: Benjamin Herrenschmidt 
> ---
>  arch/powerpc/include/asm/reg_booke.h |4 ++--
>  arch/powerpc/kernel/process.c|   22 ++
>  2 files changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/reg_booke.h 
> b/arch/powerpc/include/asm/reg_booke.h
> index 2360317..66dc6f0 100644
> --- a/arch/powerpc/include/asm/reg_booke.h
> +++ b/arch/powerpc/include/asm/reg_booke.h
> @@ -29,8 +29,8 @@
>  #if defined(CONFIG_PPC_BOOK3E_64)
>  #define MSR_ MSR_ME | MSR_CE
>  #define MSR_KERNEL  MSR_ | MSR_CM
> -#define MSR_USER32   MSR_ | MSR_PR | MSR_EE
> -#define MSR_USER64   MSR_USER32 | MSR_CM
> +#define MSR_USER32   MSR_ | MSR_PR | MSR_EE | MSR_DE
> +#define MSR_USER64   MSR_USER32 | MSR_CM | MSR_DE

MSR_DE is included twice in MSR_USER64 (once through MSR_USER32).

>  #elif defined (CONFIG_40x)
>  #define MSR_KERNEL   (MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE)
>  #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE)
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index 1e78453..551f671 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -477,6 +477,28 @@ struct task_struct *__switch_to(struct task_struct *prev,
>   new_thread = &new->thread;
>   old_thread = ¤t->thread;
> 
> +#if defined(CONFIG_PPC_BOOK3E_64)
> + /* XXX Current Book3E code doesn't deal with kernel side DBCR0,

You may want to use the style
/*
 * ..

> +  * we always hold the user values, so we set it now.
> +  *
> +  * However, we ensure the kernel MSR:DE is appropriately cleared too
> +  * to avoid spurrious single step exceptions in the kernel.
 ^^^spurious^^^

> +  *
> +  * This will have to change to merge with the ppc32 code at some point,
> +  * but I don't like much what ppc32 is doing today so there's some
> +  * thinking needed there
> +  */
> + if ((new_thread->dbcr0 | old_thread->dbcr0) & DBCR0_IDM) {
> + u32 dbcr0;

thread->dbcr0 is defined as "unsigned long" in processor.h however "u32 dbcr0"
here must be fine (given that DBCR0 uses 32-bits in ppc32 and uses only 32:63
bits in BOOKIIIE_64). Should dbcr<0-n> be made u32, given that there
will be no 64-bit long value to store (or am I missing something)?

Thanks,
K.Prasad


> +
> + mtmsr(mfmsr() & ~MSR_DE);
> + isync();
> + dbcr0 = mfspr(SPRN_DBCR0);
> + dbcr0 = (dbcr0 & DBCR0_EDM) | new_thread->dbcr0;
> + mtspr(SPRN_DBCR0, dbcr0);
> + }
> +#endif /* CONFIG_PPC64_BOOK3E */
> +
>  #ifdef CONFIG_PPC64
>   /*
>* Collect processor utilization data per process
> -- 
> 1.6.3.3
> 
> ___
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[RFC Patch 1/1] Implement hardware breakpoint interfaces for PowerPC BookE processors

2010-06-29 Thread K.Prasad
Introduce support for generic hw-breakpoint interfaces for PowerPC
BookIII E processors.

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig   |2 
 arch/powerpc/include/asm/cputable.h|4 
 arch/powerpc/include/asm/hw_breakpoint_booke.h |   46 ++
 arch/powerpc/kernel/Makefile   |4 
 arch/powerpc/kernel/hw_breakpoint_booke.c  |  429 +
 arch/powerpc/kernel/process.c  |3 
 arch/powerpc/kernel/ptrace.c   |   51 ++
 arch/powerpc/kernel/traps.c|9 
 include/linux/perf_event.h |4 
 kernel/trace/trace_ksym.c  |4 
 10 files changed, 554 insertions(+), 2 deletions(-)

Index: linux-2.6.bookE/arch/powerpc/include/asm/hw_breakpoint_booke.h
===
--- /dev/null
+++ linux-2.6.bookE/arch/powerpc/include/asm/hw_breakpoint_booke.h
@@ -0,0 +1,46 @@
+#ifndef_I386_HW_BREAKPOINT_H
+#define_I386_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#define__ARCH_HW_BREAKPOINT_H
+
+struct arch_hw_breakpoint {
+   unsigned intlen;
+   unsigned long   address;
+   unsigned long   type;
+};
+
+#include 
+#include 
+#include 
+
+/* Breakpoint length beyond which we should use 'range' breakpoints */
+#define DAC_LEN 8
+#define HW_BREAKPOINT_ALIGN 0x3
+
+static inline int hw_breakpoint_slots(int type)
+{
+   return HBP_NUM;
+}
+
+struct perf_event;
+struct perf_sample_data;
+struct pmu;
+
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+extern void hw_breakpoint_handler(struct pt_regs *regs,
+   unsigned long debug_status);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+   struct perf_sample_data *data, struct pt_regs *regs);
+
+extern struct pmu perf_ops_bp;
+
+#endif /* __KERNEL__ */
+#endif /* _I386_HW_BREAKPOINT_H */
+
Index: linux-2.6.bookE/arch/powerpc/kernel/hw_breakpoint_booke.c
===
--- /dev/null
+++ linux-2.6.bookE/arch/powerpc/kernel/hw_breakpoint_booke.c
@@ -0,0 +1,429 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers for PowerPC BookIII E. Derived from
+ * "arch/powerpc/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010 IBM Corporation
+ * Author: K.Prasad 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Stores the breakpoints currently in use on each debug register for each CPU
+ * register for each cpus
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
+
+int hw_breakpoint_weight(struct perf_event *bp)
+{
+   return (bp->attr.bp_len > DAC_LEN) ? 2 : 1;
+}
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint. Eventually we enable it in the debug control register.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+   int i;
+   struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+   unsigned long dbcr0 = mfspr(SPRN_DBCR0);
+
+   for (i = 0; i < HBP_NUM; i++) {
+   struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
+
+   if (*slot)
+   continue;
+   *slot = bp;
+   mtspr(SPRN_DAC1, info->address);
+   /* Clean the 'type' fields from DBCR0 to erase old values */
+   dbcr0 &= ~(DBCR0_DAC1W | DBCR0_DAC1R | DB

[RFC Patch 0/1] hw-breakpoint interfaces for BookE - ver II

2010-06-29 Thread K.Prasad
Hi All,
Please find a new version of the patch that implements generic
hw-breakpoint interfaces for PowerPC BookIII E.

While there are several improvements over the previous version in terms
of code placement, support for ptrace and fixes for incorrect issues, the
patch remains compile-tested (only)(against 44x/iss476-smp_defconfig config)
and is yet to be tested on hardware (for functionality).

Changelog Version II
(Version I:linuxppc-dev message-id: 20100427164029.ga8...@in.ibm.com)
-
- ptrace requests (through PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG) are
  now supported.
- Changes in original arch/powerpc/kernel/hw_breakpoint.c have been percolated
  down to hw_breakpoint_booke.c (such as introduction of thread_change_pc(),
  arch_unregister_hw_breakpoint() and changes to hw_breakpoint_handler())
  along with some code re-arrangement (for brevity/clarity).

The usage of CONFIG (in this patch) option doesn't largely represent a
form that it would turn into after enabling the use of DVCs, DACs by non-ptrace
breakpoint requests. They should turn correct as versions of this patch 
progress.

Kindly let me know your comments.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch 0/5] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XXII

2010-06-14 Thread K.Prasad
On Tue, Jun 15, 2010 at 11:54:59AM +1000, Paul Mackerras wrote:
> On Fri, Jun 04, 2010 at 12:21:45PM +0530, K.Prasad wrote:
> 
> > Meanwhile I tested the per-cpu breakpoints with the new emulate_step
> > patch (refer linuxppc-dev message-id:
> > 20100602112903.gb30...@brick.ozlabs.ibm.com) and they continue to fail
> > due to emulate_step() failure, in my case, on a "lwz r0,0(r28)"
> > instruction.
> 
> You need to pass the instruction word to emulate_step(), not the
> instruction address.  Also you need to have the full GPR set
> available.  The patch below fixes these problems.  I'll fold these
> changes into your patch 2/5.
> 
> Paul.

The breakpoints that used to fail before (due to emulate_step() failure)
are now working fine upon applying this patch.

Please include this patch along with my 2/5 as indicated by you.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch 5/5] PPC64-HWBKPT: Discard extraneous interrupt due to accesses outside symbol length

2010-06-14 Thread K.Prasad
On Thu, Jun 10, 2010 at 10:40:24PM +1000, Paul Mackerras wrote:
> On Wed, Jun 09, 2010 at 03:55:59PM +0530, K.Prasad wrote:
> 
> > +   if (!((bp->attr.bp_addr <= dar) &&
> > +(dar <= (bp->attr.bp_addr + bp->attr.bp_len {
> > +   /*
> > +* This exception is triggered not because of a memory access
> > +* on the monitored variable but in the double-word address
> > +* range in which it is contained. We will consume this
> > +* exception, considering it as 'noise'.
> > +*/
> > +   info->extraneous_interrupt = true;
> > +   }
> 
> Ummm, don't you need to add "else info->extraneous_interrupt = false;"
> here?  I don't see anywhere that you ever clear it otherwise.
> 
> Also, I think you need to do the "if (!info->extraneous_interrupt)"
> check around the call to perf_bp_event() later on in
> hw_breakpoint_handler() as well as around the call in
> single_step_dabr_instruction().
> 
> Paul.

True, I've added the check before perf_bp_event() (wherever it was
missing before) in the patchset ver XXIV.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 5/5] PPC64-HWBKPT: Discard extraneous interrupt due to accesses outside symbol length

2010-06-14 Thread K.Prasad
Many a times, the requested breakpoint length can be less than the fixed
breakpoint length i.e. 8 bytes supported by PowerPC BookIII S. This could lead
to extraneous interrupts resulting in false breakpoint notifications. The patch
below detects and discards such interrupts for non-ptrace requests (we don't
want to change ptrace behaviour for fear of breaking compatability).

[Suggestions from Paul Mackerras  to add a new flag in
'struct arch_hw_breakpoint' to identify extraneous interrupts]

Signed-off-by: K.Prasad 
---
 arch/powerpc/include/asm/hw_breakpoint.h |1 +
 arch/powerpc/kernel/hw_breakpoint.c  |   23 +--
 2 files changed, 22 insertions(+), 2 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -202,6 +202,7 @@ int __kprobes hw_breakpoint_handler(stru
struct pt_regs *regs = args->regs;
int stepped = 1;
struct arch_hw_breakpoint *info;
+   unsigned long dar = regs->dar;
 
/* Disable breakpoints during exception handling */
set_dabr(0);
@@ -232,6 +233,22 @@ int __kprobes hw_breakpoint_handler(stru
goto out;
}
 
+   /*
+* Verify if dar lies within the address range occupied by the symbol
+* being watched to filter extraneous exceptions.
+*/
+   if (!((bp->attr.bp_addr <= dar) &&
+(dar <= (bp->attr.bp_addr + bp->attr.bp_len {
+   /*
+* This exception is triggered not because of a memory access
+* on the monitored variable but in the double-word address
+* range in which it is contained. We will consume this
+* exception, considering it as 'noise'.
+*/
+   info->extraneous_interrupt = true;
+   } else
+   info->extraneous_interrupt = false;
+
/* Do not emulate user-space instructions, instead single-step them */
if (user_mode(regs)) {
bp->ctx->task->thread.last_hit_ubp = bp;
@@ -255,7 +272,8 @@ int __kprobes hw_breakpoint_handler(stru
 * As a policy, the callback is invoked in a 'trigger-after-execute'
 * fashion
 */
-   perf_bp_event(bp, regs);
+   if (!info->extraneous_interrupt)
+   perf_bp_event(bp, regs);
 
set_dabr(info->address | info->type | DABR_TRANSLATION);
 out:
@@ -286,7 +304,8 @@ int __kprobes single_step_dabr_instructi
 * We shall invoke the user-defined callback function in the single
 * stepping handler to confirm to 'trigger-after-execute' semantics
 */
-   perf_bp_event(bp, regs);
+   if (!bp_info->extraneous_interrupt)
+   perf_bp_event(bp, regs);
 
/*
 * Do not disable MSR_SE if the process was already in
Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -27,6 +27,7 @@
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 
 struct arch_hw_breakpoint {
+   boolextraneous_interrupt;
u8  len; /* length of the target data symbol */
int type;
unsigned long   address;

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 4/5] PPC64-HWBKPT: Enable hw-breakpoints while handling intervening signals

2010-06-14 Thread K.Prasad
A signal delivered between a hw_breakpoint_handler() and the
single_step_dabr_instruction() will not have the breakpoint active during
signal handling (since breakpoint will not be restored through single-stepping
due to absence of MSR_SE bit on the signal frame). Enable breakpoints before
signal delivery.

Restore hw-breakpoints if the user-context is altered in the signal handler.

[With inputs from Paul Mackerras  which helped identify a
need to restore breakpoints before handling a signal delivered in certain
cases]

Signed-off-by: K.Prasad 
---
 arch/powerpc/include/asm/hw_breakpoint.h |3 +++
 arch/powerpc/kernel/hw_breakpoint.c  |   18 ++
 arch/powerpc/kernel/signal.c |3 +++
 3 files changed, 24 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -65,9 +65,12 @@ static inline void hw_breakpoint_disable
 {
set_dabr(0);
 }
+extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
 
 #else  /* CONFIG_HAVE_HW_BREAKPOINT */
 static inline void hw_breakpoint_disable(void) { }
+static inline void thread_change_pc(struct task_struct *tsk,
+   struct pt_regs *regs) { }
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* __KERNEL__ */
 #endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -174,6 +174,24 @@ int arch_validate_hwbkpt_settings(struct
 }
 
 /*
+ * Restores the breakpoint on the debug registers.
+ * Invoke this function if it is known that the execution context is about to
+ * change to cause loss of MSR_SE settings.
+ */
+void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
+{
+   struct arch_hw_breakpoint *info;
+
+   if (likely(!tsk->thread.last_hit_ubp))
+   return;
+
+   info = counter_arch_bp(tsk->thread.last_hit_ubp);
+   regs->msr &= ~MSR_SE;
+   set_dabr(info->address | info->type | DABR_TRANSLATION);
+   tsk->thread.last_hit_ubp = NULL;
+}
+
+/*
  * Handle debug exception notifications.
  */
 int __kprobes hw_breakpoint_handler(struct die_args *args)
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -149,6 +150,8 @@ static int do_signal_pending(sigset_t *o
if (current->thread.dabr)
set_dabr(current->thread.dabr);
 #endif
+   /* Re-enable the breakpoints for the signal stack */
+   thread_change_pc(current, regs);
 
if (is32) {
if (ka.sa.sa_flags & SA_SIGINFO)

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 3/5] PPC64-HWBKPT: Handle concurrent alignment interrupts

2010-06-14 Thread K.Prasad
An alignment interrupt may intervene between a DSI/hw-breakpoint exception
and the single-step exception. Enable the alignment interrupt (through
modifications to emulate_single_step()) to notify the single-step exception
handler for proper restoration of hw-breakpoints.

[The need to invoke single-step handler after alignment interrupt pointed out
by Paul Mackerras ]

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/traps.c |8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/traps.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
@@ -602,7 +602,7 @@ void RunModeException(struct pt_regs *re
 
 void __kprobes single_step_exception(struct pt_regs *regs)
 {
-   regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
+   clear_single_step(regs);
 
if (notify_die(DIE_SSTEP, "single_step", regs, 5,
5, SIGTRAP) == NOTIFY_STOP)
@@ -621,10 +621,8 @@ void __kprobes single_step_exception(str
  */
 static void emulate_single_step(struct pt_regs *regs)
 {
-   if (single_stepping(regs)) {
-   clear_single_step(regs);
-   _exception(SIGTRAP, regs, TRAP_TRACE, 0);
-   }
+   if (single_stepping(regs))
+   single_step_exception(regs);
 }
 
 static inline int __parse_fpscr(unsigned long fpscr)

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 2/5] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC BookIII S

2010-06-14 Thread K.Prasad
Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
processors. These interfaces help arbitrate requests from various users and
schedules them as appropriate.

[Suggestions from Paul Mackerras  to 
- emulate_step() all non-task bound breakpoints and single-step only the
  per-task breakpoints
- perform arch-specific cleanup before unregistration through
  arch_unregister_hw_breakpoint()
]

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig |1 
 arch/powerpc/include/asm/cputable.h  |4 
 arch/powerpc/include/asm/hw_breakpoint.h |   73 +++
 arch/powerpc/include/asm/processor.h |8 
 arch/powerpc/kernel/Makefile |1 
 arch/powerpc/kernel/hw_breakpoint.c  |  320 +++
 arch/powerpc/kernel/machine_kexec_64.c   |3 
 arch/powerpc/kernel/process.c|   14 +
 arch/powerpc/kernel/ptrace.c |   64 ++
 arch/powerpc/lib/Makefile|1 
 10 files changed, 489 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,73 @@
+/*
+ * PowerPC BookIII S hardware breakpoint definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010, IBM Corporation.
+ * Author: K.Prasad 
+ *
+ */
+
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+   u8  len; /* length of the target data symbol */
+   int type;
+   unsigned long   address;
+};
+
+#include 
+#include 
+#include 
+
+static inline int hw_breakpoint_slots(int type)
+{
+   return HBP_NUM;
+}
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_bp_generic_fields(int type, int *gen_bp_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+   struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+   set_dabr(0);
+}
+
+#else  /* CONFIG_HAVE_HW_BREAKPOINT */
+static inline void hw_breakpoint_disable(void) { }
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,320 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010 IBM Corporation
+ * Author: K.Prasad 
+ *
+ */
+
+#include 
+#inc

[Patch 1/5] Allow arch-specific cleanup before breakpoint unregistration

2010-06-14 Thread K.Prasad
Certain architectures (such as PowerPC Book III S) have a need to cleanup
data-structures before the breakpoint is unregistered. This patch introduces
an arch-specific hook in release_bp_slot() along with a weak definition in
the form of a stub funciton.

Signed-off-by: K.Prasad 
Acked-by: Frederic Weisbecker 
---
 kernel/hw_breakpoint.c |   12 
 1 file changed, 12 insertions(+)

Index: linux-2.6.ppc64_test/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/kernel/hw_breakpoint.c
@@ -242,6 +242,17 @@ toggle_bp_slot(struct perf_event *bp, bo
 }
 
 /*
+ * Function to perform processor-specific cleanup during unregistration
+ */
+__weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+   /*
+* A weak stub function here for those archs that don't define
+* it inside arch/.../kernel/hw_breakpoint.c
+*/
+}
+
+/*
  * Contraints to check before allowing this new breakpoint counter:
  *
  *  == Non-pinned counter == (Considered as pinned for now)
@@ -339,6 +350,7 @@ void release_bp_slot(struct perf_event *
 {
mutex_lock(&nr_bp_mutex);
 
+   arch_unregister_hw_breakpoint(bp);
__release_bp_slot(bp);
 
mutex_unlock(&nr_bp_mutex);

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 0/5] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XXIV

2010-06-14 Thread K.Prasad
Hi Paul,
Please find a new set of patches with changes as described below.
The patches have been tested for kernel- and user-mode breakpoints (after
applying the two patches you sent, refer message-id:
20100603004758.ga19...@brick.ozlabs.ibm.com and message-id:
20100615015459.ga30...@drongo) and are found to work fine!

Changelog - ver XXIV

(Version XXII: 20100609102446.ga20...@in.ibm.com)
- A lockdep issue seen due to invocation of unregister_hw_breakpoint() in
  exception context is now fixed (perf_event_disable() is used instead).
- Fixed improper handling of extraneous exceptions (through clearing of
  extraneous exception flag and preventing the invocation of callback).

Kindly let me know if you have any further comments.

Thanks,
K.Prasad

Changelog - ver XXIII

(Version XXII: 20100528063924.ga8...@in.ibm.com)
- Detection of extraneous breakpoint exceptions is now done using a boolean flag
  in 'struct arch_hw_breakpoint'.
- A dangling put_cpu() (remnant from previous patch versions) in
  arch_unregister_hw_breakpoint() is now removed.

Changelog - ver XXII

(Version XXI: linuxppc-dev ref:20100525091314.ga29...@in.ibm.com)
- Extraneous breakpoint exceptions are now properly handled; causative
  instruction will be single-stepped and debug register values restored.
- Restoration of breakpoints during signal handling through thread_change_pc()
  had defects which are now fixed.
- Breakpoints are flushed through flush_ptrace_hw_breakpoint() call in both
  flush_thread() and prepare_to_copy() functions. 'ptrace_bps[]' and
  'last_hit_ubp' members are now promptly cleaned-up.
- Single-step exception is now conditionally emulated upon hitting
  alignment_exception.
- Rebased to commit 31f46717997a83bdf6db0dd04810c0a329eb3148 of linux-2.6 tree.

Changelog - ver XXI

(Version XX: linuxppc-dev ref:20100524103136.ga8...@in.ibm.com)
- Decision to emulate an instruction is now based on whether the causative
  instruction is in user_mode() or not.
- Breakpoints don't have to be cleared during sigreturn. A 'double-hit' on
  hw_breakpoint_handler() is harmless for non-ptrace instructions.
- Minor changes to aid code brevity.

Changelog - ver XX

(Version XIX: linuxppc-dev ref: 20100524040137.ga20...@in.ibm.com)
- Non task-bound breakpoints will only be emulated. Breakpoint will be
  unregistered with a warning if emulation fails.

Changelog - ver XIX

(Version XVIII: linuxppc-dev ref: 20100512033055.ga6...@in.ibm.com)
- Increased coverage of breakpoints during concurrent alignment_exception
  and signal handling (which previously had 'blind-spots').
- Support for kernel-thread breakpoints and kernel-space breakpoints inside the
  context of a user-space process.
- Patches re-based to commit f4b87dee923342505e1ddba8d34ce9de33e75050, thereby
  necessitating minor changes to arch_validate_hwbkpt_settings().

Changelog - ver XVIII

(Version XVII: linuxppc-dev ref: 20100414034340.ga6...@in.ibm.com)
- Slight code restructuring for brevity and coding-style corrections.
- emulate_single_step() now notifies DIE_SSTEP to registered handlers;
  causes single_step_dabr_instruction() to be invoked after alignment_exception.
- hw-breakpoint restoration variables are cleaned-up before unregistration
  through arch_unregister_hw_breakpoint().
- SIGTRAP is no longer generated for non-ptrace user-space breakpoints.

Changelog - ver XVII

(Version XVI: linuxppc-dev ref: 20100330095809.ga14...@in.ibm.com)
- CONFIG_HAVE_HW_BREAKPOINT is now used to define the scope of the new code
  (in lieu of CONFIG_PPC_BOOK3S_64).
- CONFIG_HAVE_HW_BREAKPOINT is now dependant upon CONFIG_PERF_EVENTS and
  CONFIG_PPC_BOOK3S_64 (to overcome build failures under certain configs).
- Included a target in arch/powerpc/lib/Makefile to build sstep.o when
  HAVE_HW_BREAKPOINT.
- Added a dummy definition for hw_breakpoint_disable() when !HAVE_HW_BREAKPOINT.
- Tested builds under defconfigs for ppc64, cell and g5 (found no patch induced
  failures).

Changelog - ver XVI

(Version XV: linuxppc-dev ref: 20100323140639.ga21...@in.ibm.com)
- Used a new config option CONFIG_PPC_BOOK3S_64 (in lieu of
  CONFIG_PPC64/CPU_FTR_HAS_DABR) to limit the scope of the new code.
- Disabled breakpoints before kexec of the machine using 
hw_breakpoint_disable().
- Minor optimisation in exception-64s.S to check for data breakpoint exceptions
  in DSISR finally (after check for other causes) + changes in code comments 
and 
  representation of DSISR_DABRMATCH constant.
- Rebased to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6.

Changelog - ver XV

(Version XIV: linuxppc-dev ref: 20100308181232.ga3...@in.ibm.com)

- Additional patch to disable interrupts during data breakpoint exception
  handling.
- Mov

Re: [Patch 0/5] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XXII

2010-06-09 Thread K.Prasad
On Mon, Jun 07, 2010 at 09:25:59PM +1000, Paul Mackerras wrote:
> On Mon, Jun 07, 2010 at 12:33:51PM +0530, K.Prasad wrote:
> 
> > Given that 'ptrace_bps' is used only for ptrace originated breakpoints
> > and that we return early i.e. before detecting extraneous interrupts
> > in hw_breakpoint_handler() (as shown above) they shouldn't overlap each
> > other. The following comment in hw_breakpoint_handler() explains the
> > same.
> > /*
> >  * To prevent invocation of perf_event_bp(), we shall overload
> >  * thread.ptrace_bps[] pointer (unused for non-ptrace
> >  * exceptions) to flag an extraneous interrupt which must be
> >  * skipped.
> >  */
> 
> My point is that while we are using ptrace_bps[0] to mark a non-ptrace
> breakpoint that we're single-stepping, some other process could be
> ptracing this process and could get into ptrace_set_debugreg() and
> would think that the process already has a ptrace breakpoint and call
> modify_user_hw_breakpoint() when it should be calling
> register_user_hw_breakpoint().  Or this process could die and so we
> call flush_ptrace_hw_breakpoint() and it incorrectly thinks we have a
> ptrace breakpoint.
> 
> If there is a reason why we can be quite sure that while we are using
> current->thread.ptrace_bps[0] in this way, ptrace_set_debugreg() can
> never get called with this task as the ptracee, and nor can
> flush_ptrace_hw_breakpoint() get called on this task, then maybe it's
> safe.  But it's not at all obviously safe.  So I'd very much rather we
> just use an extra flag somewhere, that isn't used elsewhere for
> anything else, so we can convince ourselves that it is all correct
> without having to look at lots of different pieces of code.
> 
> There are 3 bytes of padding in struct arch_hw_breakpoint; couldn't we
> use one of them as a "not really hit" flag?
> 
> Paul.
> ___

I get your reasoning now; ptrace_bps[] re-use will cause failures under
these circumstances. I've sent a new version of the patchset which adds
a new flag in 'struct arch_hw_breakpoint' (I was always thinking of
'struct thread_struct' before and was scared to introduce another new
member in it, thereby leading me to incorrectly optimise using ptrace_bps)
to flag extraneous_interrupt (Given that it's your idea I've added your
signed-off too).

Kindly let me know your comments, if any.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 5/5] PPC64-HWBKPT: Discard extraneous interrupt due to accesses outside symbol length

2010-06-09 Thread K.Prasad
Many a times, the requested breakpoint length can be less than the fixed
breakpoint length i.e. 8 bytes supported by PowerPC BookIII S. This could lead
to extraneous interrupts resulting in false breakpoint notifications. The patch
below detects and discards such interrupts for non-ptrace requests (we don't
want to change ptrace behaviour for fear of breaking compatability).

Signed-off-by: K.Prasad 
Signed-off-by: Paul Mackerras 
---
 arch/powerpc/include/asm/hw_breakpoint.h |1 +
 arch/powerpc/kernel/hw_breakpoint.c  |   19 ++-
 2 files changed, 19 insertions(+), 1 deletion(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -202,6 +202,7 @@ int __kprobes hw_breakpoint_handler(stru
struct pt_regs *regs = args->regs;
int stepped = 1;
struct arch_hw_breakpoint *info;
+   unsigned long dar = regs->dar;
 
/* Disable breakpoints during exception handling */
set_dabr(0);
@@ -232,6 +233,21 @@ int __kprobes hw_breakpoint_handler(stru
goto out;
}
 
+   /*
+* Verify if dar lies within the address range occupied by the symbol
+* being watched to filter extraneous exceptions.
+*/
+   if (!((bp->attr.bp_addr <= dar) &&
+(dar <= (bp->attr.bp_addr + bp->attr.bp_len {
+   /*
+* This exception is triggered not because of a memory access
+* on the monitored variable but in the double-word address
+* range in which it is contained. We will consume this
+* exception, considering it as 'noise'.
+*/
+   info->extraneous_interrupt = true;
+   }
+
/* Do not emulate user-space instructions, instead single-step them */
if (user_mode(regs)) {
bp->ctx->task->thread.last_hit_ubp = bp;
@@ -286,7 +302,8 @@ int __kprobes single_step_dabr_instructi
 * We shall invoke the user-defined callback function in the single
 * stepping handler to confirm to 'trigger-after-execute' semantics
 */
-   perf_bp_event(bp, regs);
+   if (!bp_info->extraneous_interrupt)
+   perf_bp_event(bp, regs);
 
/*
 * Do not disable MSR_SE if the process was already in
Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -27,6 +27,7 @@
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 
 struct arch_hw_breakpoint {
+   boolextraneous_interrupt;
u8  len; /* length of the target data symbol */
int type;
unsigned long   address;

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 4/5] PPC64-HWBKPT: Enable hw-breakpoints while handling intervening signals

2010-06-09 Thread K.Prasad
A signal delivered between a hw_breakpoint_handler() and the
single_step_dabr_instruction() will not have the breakpoint active during
signal handling (since breakpoint will not be restored through single-stepping
due to absence of MSR_SE bit on the signal frame). Enable breakpoints before
signal delivery.

Restore hw-breakpoints if the user-context is altered in the signal handler.

Signed-off-by: K.Prasad 
---
 arch/powerpc/include/asm/hw_breakpoint.h |3 +++
 arch/powerpc/kernel/hw_breakpoint.c  |   18 ++
 arch/powerpc/kernel/signal.c |3 +++
 3 files changed, 24 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -65,9 +65,12 @@ static inline void hw_breakpoint_disable
 {
set_dabr(0);
 }
+extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
 
 #else  /* CONFIG_HAVE_HW_BREAKPOINT */
 static inline void hw_breakpoint_disable(void) { }
+static inline void thread_change_pc(struct task_struct *tsk,
+   struct pt_regs *regs) { }
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* __KERNEL__ */
 #endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -174,6 +174,24 @@ int arch_validate_hwbkpt_settings(struct
 }
 
 /*
+ * Restores the breakpoint on the debug registers.
+ * Invoke this function if it is known that the execution context is about to
+ * change to cause loss of MSR_SE settings.
+ */
+void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
+{
+   struct arch_hw_breakpoint *info;
+
+   if (likely(!tsk->thread.last_hit_ubp))
+   return;
+
+   info = counter_arch_bp(tsk->thread.last_hit_ubp);
+   regs->msr &= ~MSR_SE;
+   set_dabr(info->address | info->type | DABR_TRANSLATION);
+   tsk->thread.last_hit_ubp = NULL;
+}
+
+/*
  * Handle debug exception notifications.
  */
 int __kprobes hw_breakpoint_handler(struct die_args *args)
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -149,6 +150,8 @@ static int do_signal_pending(sigset_t *o
if (current->thread.dabr)
set_dabr(current->thread.dabr);
 #endif
+   /* Re-enable the breakpoints for the signal stack */
+   thread_change_pc(current, regs);
 
if (is32) {
if (ka.sa.sa_flags & SA_SIGINFO)

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 3/5] PPC64-HWBKPT: Handle concurrent alignment interrupts

2010-06-09 Thread K.Prasad
An alignment interrupt may intervene between a DSI/hw-breakpoint exception
and the single-step exception. Enable the alignment interrupt (through
modifications to emulate_single_step()) to notify the single-step exception
handler for proper restoration of hw-breakpoints.

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/traps.c |8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/traps.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
@@ -602,7 +602,7 @@ void RunModeException(struct pt_regs *re
 
 void __kprobes single_step_exception(struct pt_regs *regs)
 {
-   regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
+   clear_single_step(regs);
 
if (notify_die(DIE_SSTEP, "single_step", regs, 5,
5, SIGTRAP) == NOTIFY_STOP)
@@ -621,10 +621,8 @@ void __kprobes single_step_exception(str
  */
 static void emulate_single_step(struct pt_regs *regs)
 {
-   if (single_stepping(regs)) {
-   clear_single_step(regs);
-   _exception(SIGTRAP, regs, TRAP_TRACE, 0);
-   }
+   if (single_stepping(regs))
+   single_step_exception(regs);
 }
 
 static inline int __parse_fpscr(unsigned long fpscr)

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 2/5] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC BookIII S

2010-06-09 Thread K.Prasad
Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
processors. These interfaces help arbitrate requests from various users and
schedules them as appropriate.

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig |1 
 arch/powerpc/include/asm/cputable.h  |4 
 arch/powerpc/include/asm/hw_breakpoint.h |   73 +++
 arch/powerpc/include/asm/processor.h |8 
 arch/powerpc/kernel/Makefile |1 
 arch/powerpc/kernel/hw_breakpoint.c  |  320 +++
 arch/powerpc/kernel/machine_kexec_64.c   |3 
 arch/powerpc/kernel/process.c|   14 +
 arch/powerpc/kernel/ptrace.c |   64 ++
 arch/powerpc/lib/Makefile|1 
 10 files changed, 489 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,73 @@
+/*
+ * PowerPC BookIII S hardware breakpoint definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010, IBM Corporation.
+ * Author: K.Prasad 
+ *
+ */
+
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+   u8  len; /* length of the target data symbol */
+   int type;
+   unsigned long   address;
+};
+
+#include 
+#include 
+#include 
+
+static inline int hw_breakpoint_slots(int type)
+{
+   return HBP_NUM;
+}
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_bp_generic_fields(int type, int *gen_bp_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+   struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+   set_dabr(0);
+}
+
+#else  /* CONFIG_HAVE_HW_BREAKPOINT */
+static inline void hw_breakpoint_disable(void) { }
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,320 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010 IBM Corporation
+ * Author: K.Prasad 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE

[Patch 1/5] Allow arch-specific cleanup before breakpoint unregistration

2010-06-09 Thread K.Prasad
Certain architectures (such as PowerPC Book III S) have a need to cleanup
data-structures before the breakpoint is unregistered. This patch introduces
an arch-specific hook in release_bp_slot() along with a weak definition in
the form of a stub funciton.

Signed-off-by: K.Prasad 
Acked-by: Frederic Weisbecker 
---
 kernel/hw_breakpoint.c |   12 
 1 file changed, 12 insertions(+)

Index: linux-2.6.ppc64_test/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/kernel/hw_breakpoint.c
@@ -242,6 +242,17 @@ toggle_bp_slot(struct perf_event *bp, bo
 }
 
 /*
+ * Function to perform processor-specific cleanup during unregistration
+ */
+__weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+   /*
+* A weak stub function here for those archs that don't define
+* it inside arch/.../kernel/hw_breakpoint.c
+*/
+}
+
+/*
  * Contraints to check before allowing this new breakpoint counter:
  *
  *  == Non-pinned counter == (Considered as pinned for now)
@@ -339,6 +350,7 @@ void release_bp_slot(struct perf_event *
 {
mutex_lock(&nr_bp_mutex);
 
+   arch_unregister_hw_breakpoint(bp);
__release_bp_slot(bp);
 
mutex_unlock(&nr_bp_mutex);

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 0/5] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XXIII

2010-06-09 Thread K.Prasad
Hi All,
Please find a new version of the patchset that implement hardware
breakpoint interfaces for the PowerPC BookIII S processor. The changes are
few and as described below.

Changelog - ver XXIII

(Version XXII: 20100528063924.ga8...@in.ibm.com)
- Detection of extraneous breakpoint exceptions is now done using a boolean flag
  in 'struct arch_hw_breakpoint'.
- A dangling put_cpu() (remnant from previous patch versions) in
  arch_unregister_hw_breakpoint() is now removed.

Kindly let me know your comments.

Thanks,
K.Prasad

Changelog - ver XXII

(Version XXI: linuxppc-dev ref:20100525091314.ga29...@in.ibm.com)
- Extraneous breakpoint exceptions are now properly handled; causative
  instruction will be single-stepped and debug register values restored.
- Restoration of breakpoints during signal handling through thread_change_pc()
  had defects which are now fixed.
- Breakpoints are flushed through flush_ptrace_hw_breakpoint() call in both
  flush_thread() and prepare_to_copy() functions. 'ptrace_bps[]' and
  'last_hit_ubp' members are now promptly cleaned-up.
- Single-step exception is now conditionally emulated upon hitting
  alignment_exception.
- Rebased to commit 31f46717997a83bdf6db0dd04810c0a329eb3148 of linux-2.6 tree.

Changelog - ver XXI

(Version XX: linuxppc-dev ref:20100524103136.ga8...@in.ibm.com)
- Decision to emulate an instruction is now based on whether the causative
  instruction is in user_mode() or not.
- Breakpoints don't have to be cleared during sigreturn. A 'double-hit' on
  hw_breakpoint_handler() is harmless for non-ptrace instructions.
- Minor changes to aid code brevity.

Changelog - ver XX

(Version XIX: linuxppc-dev ref: 20100524040137.ga20...@in.ibm.com)
- Non task-bound breakpoints will only be emulated. Breakpoint will be
  unregistered with a warning if emulation fails.

Changelog - ver XIX

(Version XVIII: linuxppc-dev ref: 20100512033055.ga6...@in.ibm.com)
- Increased coverage of breakpoints during concurrent alignment_exception
  and signal handling (which previously had 'blind-spots').
- Support for kernel-thread breakpoints and kernel-space breakpoints inside the
  context of a user-space process.
- Patches re-based to commit f4b87dee923342505e1ddba8d34ce9de33e75050, thereby
  necessitating minor changes to arch_validate_hwbkpt_settings().

Changelog - ver XVIII

(Version XVII: linuxppc-dev ref: 20100414034340.ga6...@in.ibm.com)
- Slight code restructuring for brevity and coding-style corrections.
- emulate_single_step() now notifies DIE_SSTEP to registered handlers;
  causes single_step_dabr_instruction() to be invoked after alignment_exception.
- hw-breakpoint restoration variables are cleaned-up before unregistration
  through arch_unregister_hw_breakpoint().
- SIGTRAP is no longer generated for non-ptrace user-space breakpoints.

Changelog - ver XVII

(Version XVI: linuxppc-dev ref: 20100330095809.ga14...@in.ibm.com)
- CONFIG_HAVE_HW_BREAKPOINT is now used to define the scope of the new code
  (in lieu of CONFIG_PPC_BOOK3S_64).
- CONFIG_HAVE_HW_BREAKPOINT is now dependant upon CONFIG_PERF_EVENTS and
  CONFIG_PPC_BOOK3S_64 (to overcome build failures under certain configs).
- Included a target in arch/powerpc/lib/Makefile to build sstep.o when
  HAVE_HW_BREAKPOINT.
- Added a dummy definition for hw_breakpoint_disable() when !HAVE_HW_BREAKPOINT.
- Tested builds under defconfigs for ppc64, cell and g5 (found no patch induced
  failures).

Changelog - ver XVI

(Version XV: linuxppc-dev ref: 20100323140639.ga21...@in.ibm.com)
- Used a new config option CONFIG_PPC_BOOK3S_64 (in lieu of
  CONFIG_PPC64/CPU_FTR_HAS_DABR) to limit the scope of the new code.
- Disabled breakpoints before kexec of the machine using 
hw_breakpoint_disable().
- Minor optimisation in exception-64s.S to check for data breakpoint exceptions
  in DSISR finally (after check for other causes) + changes in code comments 
and 
  representation of DSISR_DABRMATCH constant.
- Rebased to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6.

Changelog - ver XV

(Version XIV: linuxppc-dev ref: 20100308181232.ga3...@in.ibm.com)

- Additional patch to disable interrupts during data breakpoint exception
  handling.
- Moved HBP_NUM definition to cputable.h under a new CPU_FTR definition
  (CPU_FTR_HAS_DABR).
- Filtering of extraneous exceptions (due to accesses outside symbol length) is
  by-passed for ptrace requests.
- Removed flush_ptrace_hw_breakpoint() from __switch_to() due to incorrect
  coding placement.
- Changes to code comments as per community reviews for previous version.
- Minor coding-style changes in hw_breakpoint.c as per review comments.
- Re-based to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6

Changelog - ver X

Re: [Patch 0/5] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XXII

2010-06-07 Thread K.Prasad
On Fri, Jun 04, 2010 at 07:06:48PM +1000, Paul Mackerras wrote:
> On Fri, Jun 04, 2010 at 12:21:45PM +0530, K.Prasad wrote:
> 
> > Meanwhile I tested the per-cpu breakpoints with the new emulate_step
> > patch (refer linuxppc-dev message-id:
> > 20100602112903.gb30...@brick.ozlabs.ibm.com) and they continue to fail
> > due to emulate_step() failure, in my case, on a "lwz r0,0(r28)"
> > instruction.
> 
> Strange, what was in r28?  The emulator should handle that instruction.
> 

It must be containing one of the offsets of "struct tracer" which is a
parameter to the function trace_selftest_startup_ksym(). Basically this
function does a selftest over hw-breakpoints by placing read-write
breakpoint on a dummy global-variable and performs read-write access
thereupon. The lwz instruction which fails here corresponds to the
instruction that does read-write. A complete disassemble of the function
upto the failing instruction (at address) is pasted at the end of this
mail.

> > About the latest patchset, given that we chose to ignore extraneous
> > interrupts for non-ptrace breakpoints, I thought that re-using
> > current->thread.ptrace_bps as a flag would be efficient than
> > introducing
> > a new member in 'struct thread_struct' to do the same. I'm not sure
> > if
> > you foresee any issues with that.
> 
> I just wonder what provides exclusion between its use as a flag and
> its use to hold a real ptrace breakpoint.  As far as I can see nothing
> does.  If there is something, it's off in some other source file,
> unless I'm missing something.  And in that case there should be a bit
> fat comment explaining why it's safe.
> 

The hw_breakpoint_handler() goes like this:

int __kprobes hw_breakpoint_handler(struct die_args *args)
{
...

/*
 * Return early after invoking user-callback function without restoring
 * DABR if the breakpoint is from ptrace which always operates in
 * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal
 * generated in do_dabr().
 */
if (is_ptrace_bp) {
perf_bp_event(bp, regs);
rc = NOTIFY_DONE;
goto out;
}

/*
 * Verify if dar lies within the address range occupied by the symbol
 * being watched to filter extraneous exceptions.
 */
if (!((bp->attr.bp_addr <= dar) &&
 (dar <= (bp->attr.bp_addr + bp->attr.bp_len {
/*
 * This exception is triggered not because of a memory access
 * on the monitored variable but in the double-word address
 * range in which it is contained. We will consume this
 * exception, considering it as 'noise'.
 */
is_extraneous_interrupt = true;
}

...
}

Given that 'ptrace_bps' is used only for ptrace originated breakpoints
and that we return early i.e. before detecting extraneous interrupts
in hw_breakpoint_handler() (as shown above) they shouldn't overlap each
other. The following comment in hw_breakpoint_handler() explains the
same.
/*
 * To prevent invocation of perf_event_bp(), we shall overload
     * thread.ptrace_bps[] pointer (unused for non-ptrace
 * exceptions) to flag an extraneous interrupt which must be
 * skipped.
 */
Thanks,
K.Prasad

(gdb) disass trace_selftest_startup_ksym
Dump of assembler code for function trace_selftest_startup_ksym:
0xc0125580 : mflrr0
0xc0125584 : std r26,-48(r1)
0xc0125588 : std r27,-40(r1)
0xc012558c :std r28,-32(r1)
0xc0125590 :std r29,-24(r1)
0xc0125594 :std r30,-16(r1)
0xc0125598 :std r31,-8(r1)
0xc012559c :std r0,16(r1)
0xc01255a0 :stdur1,-176(r1)
0xc01255a4 :mr  r31,r1
0xc01255a8 :ld  r30,-17784(r2)
0xc01255ac :mr  r26,r4
0xc01255b0 :mr  r27,r3
0xc01255b4 :bl  
0xc0125510 
0xc01255b8 :li  r4,3
0xc01255bc :mr. r29,r3
0xc01255c0 :mr  r5,r29
0xc01255c4 :beq 
0xc01255e0 
0xc01255c8 :ld  r3,-31520(r30)
0xc01255cc :ld  r4,0(r27)
0xc01255d0 :bl  
0xc009c560 
0xc01255d4 :nop
0xc01255d8 :b   
0xc0125690 
0xc01255dc :nop
0xc01255e0 :ld  r28,-31512(r30)
0xc01255e4 :   ld  r3,-31504(r30)
0xc01255e8 :   stw r29,0(r28)
0xc01255ec :   mr  r5,r28
0xc01255f0 :   bl 

Re: [Patch 0/5] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XXII

2010-06-03 Thread K.Prasad
On Wed, Jun 02, 2010 at 09:33:16PM +1000, Paul Mackerras wrote:
> On Fri, May 28, 2010 at 12:09:24PM +0530, K.Prasad wrote:
> 
> > Please find a new set of patches that have the following changes.
> 
> Thanks.  There are a couple of minor things still remaining (dangling
> put_cpu in arch_unregister_hw_breakpoint, plus I don't think reusing
> current->thread.ptrace_bps the way you did in patch 5/5 is a good
> idea), but I think at this stage I'll put them in a tree together
> with my latest emulate_step version and then push them to Ben H and/or
> Ingo Molnar once I've done some testing.
> 
> Paul.

Hi Paul,
Thanks for agreeing to put the patchset into a tree and push it
to the appropriate maintainers.

Meanwhile I tested the per-cpu breakpoints with the new emulate_step
patch (refer linuxppc-dev message-id:
20100602112903.gb30...@brick.ozlabs.ibm.com) and they continue to fail
due to emulate_step() failure, in my case, on a "lwz r0,0(r28)"
instruction.

About the latest patchset, given that we chose to ignore extraneous
interrupts for non-ptrace breakpoints, I thought that re-using
current->thread.ptrace_bps as a flag would be efficient than introducing
a new member in 'struct thread_struct' to do the same. I'm not sure if
you foresee any issues with that.

If so, I'd like to send a new patch (rather than a new version of the
complete patchset) to fix it along with the dangling put_cpu() in
arch_unregister_hw_breakpoint() (I forgot to remove parts of the code
between versions XIX and XX).

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [RFC PATCH] powerpc: Emulate most load and store instructions in emulate_step()

2010-06-01 Thread K.Prasad
On Thu, May 20, 2010 at 10:49:55PM +1000, Paul Mackerras wrote:
> This extends the emulate_step() function to handle most of the load
> and store instructions implemented on current 64-bit server processors.
> The aim is to handle all the load and store instructions used in the
> kernel, so this handles the Altivec/VMX lvx and stvx and the VSX
> lxv2dx and stxv2dx instructions (implemented in POWER7).
> 

Can the emulate_step() function be used on BookIII E processors as well
(arch/powerpc/kernel/kprobes.c invokes it irrespective of the host
processor though)?

If yes, we can use it with hw_breakpoint_handler() of BookE
processors (like what is done on the PPC64 counterpart).

> The new code can emulate user mode instructions, and checks the
> effective address for a load or store if the saved state is for
> user mode.  It doesn't handle little-endian mode at present.
> 
> For floating-point, Altivec/VMX and VSX instructions, it checks
> that the saved MSR has the enable bit for the relevant facility
> set, and if so, assumes that the FP/VMX/VSX registers contain
> valid state, and does loads or stores directly to/from the
> FP/VMX/VSX registers, using assembly helpers in ldstfp.S.
> 

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch 3/4] PPC64-HWBKPT: Handle concurrent alignment interrupts

2010-05-28 Thread K.Prasad
On Thu, May 27, 2010 at 04:20:44PM +1000, Paul Mackerras wrote:
> On Tue, May 25, 2010 at 02:44:35PM +0530, K.Prasad wrote:
> 
> > An alignment interrupt may intervene between a DSI/hw-breakpoint exception
> > and the single-step exception. Enable the alignment interrupt (through
> > modifications to emulate_single_step()) to notify the single-step exception
> > handler for proper restoration of hw-breakpoints.
> > 
> > Signed-off-by: K.Prasad 
> > ---
> >  arch/powerpc/kernel/traps.c |7 ++-
> >  1 file changed, 2 insertions(+), 5 deletions(-)
> > 
> > Index: linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
> > ===
> > --- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/traps.c
> > +++ linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
> > @@ -602,7 +602,7 @@ void RunModeException(struct pt_regs *re
> >  
> >  void __kprobes single_step_exception(struct pt_regs *regs)
> >  {
> > -   regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
> > +   clear_single_step(regs);
> >  
> > if (notify_die(DIE_SSTEP, "single_step", regs, 5,
> > 5, SIGTRAP) == NOTIFY_STOP)
> > @@ -621,10 +621,7 @@ void __kprobes single_step_exception(str
> >   */
> >  static void emulate_single_step(struct pt_regs *regs)
> >  {
> > -   if (single_stepping(regs)) {
> > -   clear_single_step(regs);
> > -   _exception(SIGTRAP, regs, TRAP_TRACE, 0);
> > -   }
> > +   single_step_exception(regs);
> >  }
> 
> We still need the if (single_stepping(regs)) in emulate_single_step.
> We don't want to send the process a SIGTRAP every time it gets an
> alignment interrupt. :)
> 
> Paul.

Agreed, and made changes to that effect in version XXII (as seen in
patch linuxppc-dev message-id: 20100528064017.gd8...@in.ibm.com).

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch 2/4] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC BookIII S

2010-05-28 Thread K.Prasad
On Thu, May 27, 2010 at 04:19:40PM +1000, Paul Mackerras wrote:
> On Tue, May 25, 2010 at 02:44:20PM +0530, K.Prasad wrote:
> 
> > Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
> > processors. These interfaces help arbitrate requests from various users and
> > schedules them as appropriate.
> 
> A few comments on the code below...
> 

I've posted a new patchset that addresses almost all of your comments.
Please find them here: linuxppc-dev message-id:
20100528063924.ga8...@in.ibm.com

> > +int __kprobes hw_breakpoint_handler(struct die_args *args)
> > +{
> > +   bool is_ptrace_bp = false;
> > +   int rc = NOTIFY_STOP;
> > +   struct perf_event *bp;
> > +   struct pt_regs *regs = args->regs;
> > +   unsigned long dar = regs->dar;
> > +   int stepped = 1;
> > +   struct arch_hw_breakpoint *info;
> > +
> > +   /* Disable breakpoints during exception handling */
> > +   set_dabr(0);
> > +   /*
> > +* The counter may be concurrently released but that can only
> > +* occur from a call_rcu() path. We can then safely fetch
> > +* the breakpoint, use its callback, touch its counter
> > +* while we are in an rcu_read_lock() path.
> > +*/
> > +   rcu_read_lock();
> > +
> > +   bp = __get_cpu_var(bp_per_reg);
> > +   if (!bp)
> > +   goto out;
> > +   info = counter_arch_bp(bp);
> > +   is_ptrace_bp = (bp->overflow_handler == ptrace_triggered) ?
> > +   true : false;
> > +
> > +   /*
> > +* Verify if dar lies within the address range occupied by the symbol
> > +* being watched to filter extraneous exceptions.
> > +*/
> > +   if (!((bp->attr.bp_addr <= dar) &&
> > +   (dar <= (bp->attr.bp_addr + bp->attr.bp_len))) &&
> > +   (!is_ptrace_bp))
> > +   /*
> > +* This exception is triggered not because of a memory access on
> > +* the monitored variable but in the double-word address range
> > +* in which it is contained. We will consume this exception,
> > +* considering it as 'noise'.
> > +*/
> > +   goto restore_bp;
> 
> At this point we have to do the single-stepping, because the NIP is
> still pointing at the instruction that caused the exception, and if we
> just return to it with DABR set we won't make any progress, we'll just
> take the same exception again immediately.
> 

I don't know how I convinced myself earlier that this would work :-)

Given that the instructions needs to be emulated in the same manner as
others, I've re-used the ptrace_bps[] member in 'thread_struct' as a
flag to indicate such breakpoints. This will be later checked in
single_step_dabr_instruction() to prevent invocation of
perf_event_bp().

> > +/*
> > + * Handle single-step exceptions following a DABR hit.
> > + */
> > +int __kprobes single_step_dabr_instruction(struct die_args *args)
> > +{
> > +   struct pt_regs *regs = args->regs;
> > +   struct perf_event *bp = NULL;
> > +   struct arch_hw_breakpoint *bp_info;
> > +
> > +   bp = current->thread.last_hit_ubp;
> > +   /*
> > +* Check if we are single-stepping as a result of a
> > +* previous HW Breakpoint exception
> > +*/
> > +   if (!bp)
> > +   return NOTIFY_DONE;
> > +
> > +   bp_info = counter_arch_bp(bp);
> > +
> > +   /*
> > +* We shall invoke the user-defined callback function in the single
> > +* stepping handler to confirm to 'trigger-after-execute' semantics
> > +*/
> > +   perf_bp_event(bp, regs);
> > +
> > +   /*
> > +* Do not disable MSR_SE if the process was already in
> > +* single-stepping mode.
> > +*/
> > +   if (!test_thread_flag(TIF_SINGLESTEP))
> > +   regs->msr &= ~MSR_SE;
> > +
> > +   set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION);
> > +   return NOTIFY_STOP;
> > +}
> 
> Nowhere in here do we reset current->thread.last_hit_ubp, yet other
> parts of the code assume that .last_hit_ubp != NULL means that we are
> currently single-stepping.  I think we need to clear .last_hit_ubp
> here.
> 

True, made the change.

> > Index: linux-2.6.ppc64_test/arch/powerpc/kernel/process.c
> > ===
> > --- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/process.c
> > +++ linux-2.6.ppc64_test/arch/powerpc/kernel/process.c
> 

[Patch 5/5] PPC64-HWBKPT: Discard extraneous interrupt due to accesses outside symbol length

2010-05-27 Thread K.Prasad
Many a times, the requested breakpoint length can be less than the fixed
breakpoint length i.e. 8 bytes supported by PowerPC BookIII S. This could lead
to extraneous interrupts resulting in false breakpoint notifications. The patch
below detects and discards such interrupts for non-ptrace requests (we don't
want to change ptrace behaviour for fear of breaking compatability).

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/hw_breakpoint.c |   39 
 1 file changed, 35 insertions(+), 4 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -198,12 +198,13 @@ void thread_change_pc(struct task_struct
  */
 int __kprobes hw_breakpoint_handler(struct die_args *args)
 {
-   bool is_ptrace_bp = false;
+   bool is_extraneous_interrupt = false, is_ptrace_bp = false;
int rc = NOTIFY_STOP;
struct perf_event *bp;
struct pt_regs *regs = args->regs;
int stepped = 1;
struct arch_hw_breakpoint *info;
+   unsigned long dar = regs->dar;
 
/* Disable breakpoints during exception handling */
set_dabr(0);
@@ -234,9 +235,33 @@ int __kprobes hw_breakpoint_handler(stru
goto out;
}
 
+   /*
+* Verify if dar lies within the address range occupied by the symbol
+* being watched to filter extraneous exceptions.
+*/
+   if (!((bp->attr.bp_addr <= dar) &&
+(dar <= (bp->attr.bp_addr + bp->attr.bp_len {
+   /*
+* This exception is triggered not because of a memory access
+* on the monitored variable but in the double-word address
+* range in which it is contained. We will consume this
+* exception, considering it as 'noise'.
+*/
+   is_extraneous_interrupt = true;
+   }
+
/* Do not emulate user-space instructions, instead single-step them */
if (user_mode(regs)) {
-   bp->ctx->task->thread.last_hit_ubp = bp;
+   /*
+* To prevent invocation of perf_event_bp(), we shall overload
+* thread.ptrace_bps[] pointer (unused for non-ptrace
+* exceptions) to flag an extraneous interrupt which must be
+* skipped.
+*/
+   if (is_extraneous_interrupt)
+   bp->ctx->task->thread.ptrace_bps[0] = bp;
+   else
+   bp->ctx->task->thread.last_hit_ubp = bp;
regs->msr |= MSR_SE;
goto out;
}
@@ -274,7 +299,12 @@ int __kprobes single_step_dabr_instructi
struct perf_event *bp = NULL;
struct arch_hw_breakpoint *bp_info;
 
-   bp = current->thread.last_hit_ubp;
+   if (current->thread.last_hit_ubp)
+   bp = current->thread.last_hit_ubp;
+   else {
+   bp = current->thread.ptrace_bps[0];
+   current->thread.ptrace_bps[0] = NULL;
+   }
/*
 * Check if we are single-stepping as a result of a
 * previous HW Breakpoint exception
@@ -288,7 +318,8 @@ int __kprobes single_step_dabr_instructi
 * We shall invoke the user-defined callback function in the single
 * stepping handler to confirm to 'trigger-after-execute' semantics
 */
-   perf_bp_event(bp, regs);
+   if (bp == current->thread.last_hit_ubp)
+   perf_bp_event(bp, regs);
 
/*
 * Do not disable MSR_SE if the process was already in

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 4/5] PPC64-HWBKPT: Enable hw-breakpoints while handling intervening signals

2010-05-27 Thread K.Prasad
A signal delivered between a hw_breakpoint_handler() and the
single_step_dabr_instruction() will not have the breakpoint active during
signal handling (since breakpoint will not be restored through single-stepping
due to absence of MSR_SE bit on the signal frame). Enable breakpoints before
signal delivery.

Restore hw-breakpoints if the user-context is altered in the signal handler.

Signed-off-by: K.Prasad 
---
 arch/powerpc/include/asm/hw_breakpoint.h |3 +++
 arch/powerpc/kernel/hw_breakpoint.c  |   18 ++
 arch/powerpc/kernel/signal.c |3 +++
 3 files changed, 24 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -65,9 +65,12 @@ static inline void hw_breakpoint_disable
 {
set_dabr(0);
 }
+extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
 
 #else  /* CONFIG_HAVE_HW_BREAKPOINT */
 static inline void hw_breakpoint_disable(void) { }
+static inline void thread_change_pc(struct task_struct *tsk,
+   struct pt_regs *regs) { }
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* __KERNEL__ */
 #endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -176,6 +176,24 @@ int arch_validate_hwbkpt_settings(struct
 }
 
 /*
+ * Restores the breakpoint on the debug registers.
+ * Invoke this function if it is known that the execution context is about to
+ * change to cause loss of MSR_SE settings.
+ */
+void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
+{
+   struct arch_hw_breakpoint *info;
+
+   if (likely(!tsk->thread.last_hit_ubp))
+   return;
+
+   info = counter_arch_bp(tsk->thread.last_hit_ubp);
+   regs->msr &= ~MSR_SE;
+   set_dabr(info->address | info->type | DABR_TRANSLATION);
+   tsk->thread.last_hit_ubp = NULL;
+}
+
+/*
  * Handle debug exception notifications.
  */
 int __kprobes hw_breakpoint_handler(struct die_args *args)
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -149,6 +150,8 @@ static int do_signal_pending(sigset_t *o
if (current->thread.dabr)
set_dabr(current->thread.dabr);
 #endif
+   /* Re-enable the breakpoints for the signal stack */
+   thread_change_pc(current, regs);
 
if (is32) {
if (ka.sa.sa_flags & SA_SIGINFO)

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 3/5] PPC64-HWBKPT: Handle concurrent alignment interrupts

2010-05-27 Thread K.Prasad
An alignment interrupt may intervene between a DSI/hw-breakpoint exception
and the single-step exception. Enable the alignment interrupt (through
modifications to emulate_single_step()) to notify the single-step exception
handler for proper restoration of hw-breakpoints.

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/traps.c |8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/traps.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
@@ -602,7 +602,7 @@ void RunModeException(struct pt_regs *re
 
 void __kprobes single_step_exception(struct pt_regs *regs)
 {
-   regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
+   clear_single_step(regs);
 
if (notify_die(DIE_SSTEP, "single_step", regs, 5,
5, SIGTRAP) == NOTIFY_STOP)
@@ -621,10 +621,8 @@ void __kprobes single_step_exception(str
  */
 static void emulate_single_step(struct pt_regs *regs)
 {
-   if (single_stepping(regs)) {
-   clear_single_step(regs);
-   _exception(SIGTRAP, regs, TRAP_TRACE, 0);
-   }
+   if (single_stepping(regs))
+   single_step_exception(regs);
 }
 
 static inline int __parse_fpscr(unsigned long fpscr)

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 2/5] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC BookIII S

2010-05-27 Thread K.Prasad
Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
processors. These interfaces help arbitrate requests from various users and
schedules them as appropriate.

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig |1 
 arch/powerpc/include/asm/cputable.h  |4 
 arch/powerpc/include/asm/hw_breakpoint.h |   73 +++
 arch/powerpc/include/asm/processor.h |8 
 arch/powerpc/kernel/Makefile |1 
 arch/powerpc/kernel/hw_breakpoint.c  |  322 +++
 arch/powerpc/kernel/machine_kexec_64.c   |3 
 arch/powerpc/kernel/process.c|   14 +
 arch/powerpc/kernel/ptrace.c |   64 ++
 arch/powerpc/lib/Makefile|1 
 10 files changed, 491 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,73 @@
+/*
+ * PowerPC BookIII S hardware breakpoint definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010, IBM Corporation.
+ * Author: K.Prasad 
+ *
+ */
+
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+   u8  len; /* length of the target data symbol */
+   int type;
+   unsigned long   address;
+};
+
+#include 
+#include 
+#include 
+
+static inline int hw_breakpoint_slots(int type)
+{
+   return HBP_NUM;
+}
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_bp_generic_fields(int type, int *gen_bp_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+   struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+   set_dabr(0);
+}
+
+#else  /* CONFIG_HAVE_HW_BREAKPOINT */
+static inline void hw_breakpoint_disable(void) { }
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,322 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010 IBM Corporation
+ * Author: K.Prasad 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE

[Patch 0/5] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XXII

2010-05-27 Thread K.Prasad
Hi All,
Please find a new set of patches that have the following changes.

Changelog - ver XXII

(Version XXI: linuxppc-dev ref:20100525091314.ga29...@in.ibm.com)
- Extraneous breakpoint exceptions are now properly handled; causative
  instruction will be single-stepped and debug register values restored.
- Restoration of breakpoints during signal handling through thread_change_pc()
  had defects which are now fixed.
- Breakpoints are flushed through flush_ptrace_hw_breakpoint() call in both
  flush_thread() and prepare_to_copy() functions. 'ptrace_bps[]' and
  'last_hit_ubp' members are now promptly cleaned-up.
- Single-step exception is now conditionally emulated upon hitting
  alignment_exception.
- Rebased to commit 31f46717997a83bdf6db0dd04810c0a329eb3148 of linux-2.6 tree.

Kindly let me know your comments for the same.

Thanks,
K.Prasad

Changelog - ver XXI

(Version XX: linuxppc-dev ref:20100524103136.ga8...@in.ibm.com)
- Decision to emulate an instruction is now based on whether the causative
  instruction is in user_mode() or not.
- Breakpoints don't have to be cleared during sigreturn. A 'double-hit' on
  hw_breakpoint_handler() is harmless for non-ptrace instructions.
- Minor changes to aid code brevity.

Changelog - ver XX

(Version XIX: linuxppc-dev ref: 20100524040137.ga20...@in.ibm.com)
- Non task-bound breakpoints will only be emulated. Breakpoint will be
  unregistered with a warning if emulation fails.

Changelog - ver XIX

(Version XVIII: linuxppc-dev ref: 20100512033055.ga6...@in.ibm.com)
- Increased coverage of breakpoints during concurrent alignment_exception
  and signal handling (which previously had 'blind-spots').
- Support for kernel-thread breakpoints and kernel-space breakpoints inside the
  context of a user-space process.
- Patches re-based to commit f4b87dee923342505e1ddba8d34ce9de33e75050, thereby
  necessitating minor changes to arch_validate_hwbkpt_settings().

Changelog - ver XVIII

(Version XVII: linuxppc-dev ref: 20100414034340.ga6...@in.ibm.com)
- Slight code restructuring for brevity and coding-style corrections.
- emulate_single_step() now notifies DIE_SSTEP to registered handlers;
  causes single_step_dabr_instruction() to be invoked after alignment_exception.
- hw-breakpoint restoration variables are cleaned-up before unregistration
  through arch_unregister_hw_breakpoint().
- SIGTRAP is no longer generated for non-ptrace user-space breakpoints.

Changelog - ver XVII

(Version XVI: linuxppc-dev ref: 20100330095809.ga14...@in.ibm.com)
- CONFIG_HAVE_HW_BREAKPOINT is now used to define the scope of the new code
  (in lieu of CONFIG_PPC_BOOK3S_64).
- CONFIG_HAVE_HW_BREAKPOINT is now dependant upon CONFIG_PERF_EVENTS and
  CONFIG_PPC_BOOK3S_64 (to overcome build failures under certain configs).
- Included a target in arch/powerpc/lib/Makefile to build sstep.o when
  HAVE_HW_BREAKPOINT.
- Added a dummy definition for hw_breakpoint_disable() when !HAVE_HW_BREAKPOINT.
- Tested builds under defconfigs for ppc64, cell and g5 (found no patch induced
  failures).

Changelog - ver XVI

(Version XV: linuxppc-dev ref: 20100323140639.ga21...@in.ibm.com)
- Used a new config option CONFIG_PPC_BOOK3S_64 (in lieu of
  CONFIG_PPC64/CPU_FTR_HAS_DABR) to limit the scope of the new code.
- Disabled breakpoints before kexec of the machine using 
hw_breakpoint_disable().
- Minor optimisation in exception-64s.S to check for data breakpoint exceptions
  in DSISR finally (after check for other causes) + changes in code comments 
and 
  representation of DSISR_DABRMATCH constant.
- Rebased to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6.

Changelog - ver XV

(Version XIV: linuxppc-dev ref: 20100308181232.ga3...@in.ibm.com)

- Additional patch to disable interrupts during data breakpoint exception
  handling.
- Moved HBP_NUM definition to cputable.h under a new CPU_FTR definition
  (CPU_FTR_HAS_DABR).
- Filtering of extraneous exceptions (due to accesses outside symbol length) is
  by-passed for ptrace requests.
- Removed flush_ptrace_hw_breakpoint() from __switch_to() due to incorrect
  coding placement.
- Changes to code comments as per community reviews for previous version.
- Minor coding-style changes in hw_breakpoint.c as per review comments.
- Re-based to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6

Changelog - ver XIV

(Version XIII: linuxppc-dev ref: 20100215055605.gb3...@in.ibm.com)

- Removed the 'name' field from 'struct arch_hw_breakpoint'.
- All callback invocations through bp->overflow_handler() are replaced with
  perf_bp_event().
- Removed the check for pre-existing single-stepping mode in
  hw_breakpoint_handler() as this check is unreliable while in kernel-space.
  Side effect of this ch

[Patch 1/5] Allow arch-specific cleanup before breakpoint unregistration

2010-05-27 Thread K.Prasad
Certain architectures (such as PowerPC Book III S) have a need to cleanup
data-structures before the breakpoint is unregistered. This patch introduces
an arch-specific hook in release_bp_slot() along with a weak definition in
the form of a stub funciton.

Signed-off-by: K.Prasad 
Acked-by: Frederic Weisbecker 
---
 kernel/hw_breakpoint.c |   12 
 1 file changed, 12 insertions(+)

Index: linux-2.6.ppc64_test/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/kernel/hw_breakpoint.c
@@ -242,6 +242,17 @@ toggle_bp_slot(struct perf_event *bp, bo
 }
 
 /*
+ * Function to perform processor-specific cleanup during unregistration
+ */
+__weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+   /*
+* A weak stub function here for those archs that don't define
+* it inside arch/.../kernel/hw_breakpoint.c
+*/
+}
+
+/*
  * Contraints to check before allowing this new breakpoint counter:
  *
  *  == Non-pinned counter == (Considered as pinned for now)
@@ -339,6 +350,7 @@ void release_bp_slot(struct perf_event *
 {
mutex_lock(&nr_bp_mutex);
 
+   arch_unregister_hw_breakpoint(bp);
__release_bp_slot(bp);
 
mutex_unlock(&nr_bp_mutex);

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch 1/4] Allow arch-specific cleanup before breakpoint unregistration

2010-05-26 Thread K.Prasad
On Wed, May 26, 2010 at 07:23:15PM +0200, Frederic Weisbecker wrote:
> On Wed, May 26, 2010 at 10:47:42PM +0530, K.Prasad wrote:
> > On Wed, May 26, 2010 at 10:54:41AM +0100, David Howells wrote:
> > > K.Prasad  wrote:
> > > 
> > > > > My understanding is weak function definitions must appear in a 
> > > > > different C
> > > > > file than their call sites to work on some toolchains.
> > > > > 
> > > > 
> > > > Atleast, there are quite a few precedents inside the Linux kernel for
> > > > __weak functions being invoked from the file in which they are defined
> > > > (arch_hwblk_init, arch_enable_nonboot_cpus_begin and hw_perf_disable to
> > > > name a few).
> > > > Moreover the online GCC docs haven't any such constraints mentioned.
> > > 
> > > I've seen problems in this area.  gcc sometimes inlines a weak function 
> > > that's
> > > in the same file as the call point.
> > > 
> > 
> > We've seen such behaviour even otherwiseeven with noinline attribute
> > in place. I'm not sure if this gcc fix
> > (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16922) helped correct the
> > behaviour, but the lesson has been to not trust a function to be
> > inlined/remain non-inline consistently.
> 
> 
> If we can't put the call to the function in the same file of its weak
> definition, then perf is totally screwed.
> 
> And in fact it makes __weak basically useless and unusable. I guess
> that happened in old gcc versions that have been fixed now.
> 
> Anyway, I'm personally fine with this patch (you can put my hack
> if you want).
>

I guess you meant "Acked-by:" :-)

Thanks, I'll add the same.

--K.Prasad
 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch 1/4] Allow arch-specific cleanup before breakpoint unregistration

2010-05-26 Thread K.Prasad
On Wed, May 26, 2010 at 10:47:42PM +0530, K.Prasad wrote:
> On Wed, May 26, 2010 at 10:54:41AM +0100, David Howells wrote:
> > K.Prasad  wrote:
> > 
> > > > My understanding is weak function definitions must appear in a 
> > > > different C
> > > > file than their call sites to work on some toolchains.
> > > > 
> > > 
> > > Atleast, there are quite a few precedents inside the Linux kernel for
> > > __weak functions being invoked from the file in which they are defined
> > > (arch_hwblk_init, arch_enable_nonboot_cpus_begin and hw_perf_disable to
> > > name a few).
> > > Moreover the online GCC docs haven't any such constraints mentioned.
> > 
> > I've seen problems in this area.  gcc sometimes inlines a weak function 
> > that's
> > in the same file as the call point.
> > 
> 
> We've seen such behaviour even otherwiseeven with noinline attribute
> in place. I'm not sure if this gcc fix
> (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16922) helped correct the

Looks like I cited the wrong bug. The appropriate one is
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34563.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch 1/4] Allow arch-specific cleanup before breakpoint unregistration

2010-05-26 Thread K.Prasad
On Wed, May 26, 2010 at 10:54:41AM +0100, David Howells wrote:
> K.Prasad  wrote:
> 
> > > My understanding is weak function definitions must appear in a different C
> > > file than their call sites to work on some toolchains.
> > > 
> > 
> > Atleast, there are quite a few precedents inside the Linux kernel for
> > __weak functions being invoked from the file in which they are defined
> > (arch_hwblk_init, arch_enable_nonboot_cpus_begin and hw_perf_disable to
> > name a few).
> > Moreover the online GCC docs haven't any such constraints mentioned.
> 
> I've seen problems in this area.  gcc sometimes inlines a weak function that's
> in the same file as the call point.
> 

We've seen such behaviour even otherwiseeven with noinline attribute
in place. I'm not sure if this gcc fix
(http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16922) helped correct the
behaviour, but the lesson has been to not trust a function to be
inlined/remain non-inline consistently.

> David

Thanks,
K.Prasad
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch 1/4] Allow arch-specific cleanup before breakpoint unregistration

2010-05-25 Thread K.Prasad
On Tue, May 25, 2010 at 06:39:19AM -0500, Millton Miller wrote:
> On Tue, 25 May 2010 at 14:43:56 +0530, K.Prasad wrote:
> > Certain architectures (such as PowerPC Book III S) have a need to cleanup
> > data-structures before the breakpoint is unregistered. This patch introduces
> > an arch-specific hook in release_bp_slot() along with a weak definition in
> > the form of a stub funciton.
> > 
> > Signed-off-by: K.Prasad 
> > ---
> >  kernel/hw_breakpoint.c |   12 
> >  1 file changed, 12 insertions(+)
> 
> 
> My understanding is weak function definitions must appear in a different C
> file than their call sites to work on some toolchains.
> 

Atleast, there are quite a few precedents inside the Linux kernel for
__weak functions being invoked from the file in which they are defined
(arch_hwblk_init, arch_enable_nonboot_cpus_begin and hw_perf_disable to
name a few).
Moreover the online GCC docs haven't any such constraints mentioned.

> Andrew, can you confirm the above statement?
> 
> > Index: linux-2.6.ppc64_test/kernel/hw_breakpoint.c
> > ===
> > --- linux-2.6.ppc64_test.orig/kernel/hw_breakpoint.c
> > +++ linux-2.6.ppc64_test/kernel/hw_breakpoint.c
> > @@ -242,6 +242,17 @@  toggle_bp_slot(struct perf_event *bp, bo
> >  }
> >  
> >  /*
> > + * Function to perform processor-specific cleanup during unregistration
> > + */
> > +__weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
> > +{
> > +   /*
> > +* A weak stub function here for those archs that don't define
> > +* it inside arch/.../kernel/hw_breakpoint.c
> > +*/
> > +}
> > +
> > +/*
> >   * Contraints to check before allowing this new breakpoint counter:
> >   *
> >   *  == Non-pinned counter == (Considered as pinned for now)
> > @@ -339,6 +350,7 @@  void release_bp_slot(struct perf_event *
> >  {
> > mutex_lock(&nr_bp_mutex);
> >  
> > +   arch_unregister_hw_breakpoint(bp);
> > __release_bp_slot(bp);
> >  
> > mutex_unlock(&nr_bp_mutex);
> > 
> 
> 
> Since the weak version is empty, should it just be delcared (in
> a header, put the comment there) and not defined?
>

The initial thinking behind defining it in the .c file was, for one,
the function need not be moved (from .h to .c) when other architectures
have a need to populate them. Secondly, given that powerpc (which has a
'strong' definition for arch_unregister_hw_breakpoint()) includes the
header file (in which this can be moved to) I wasn't sure about
possible conflicts.

> milton
> ___
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 4/4] PPC64-HWBKPT: Enable hw-breakpoints while handling intervening signals

2010-05-25 Thread K.Prasad
A signal delivered between a hw_breakpoint_handler() and the
single_step_dabr_instruction() will not have the breakpoint active during
signal handling (since breakpoint will not be restored through single-stepping
due to absence of MSR_SE bit on the signal frame). Enable breakpoints before
signal delivery.

Restore hw-breakpoints if the user-context is altered in the signal handler.

Signed-off-by: K.Prasad 
---
 arch/powerpc/include/asm/hw_breakpoint.h |2 ++
 arch/powerpc/kernel/hw_breakpoint.c  |   16 
 arch/powerpc/kernel/signal.c |3 +++
 arch/powerpc/kernel/signal_32.c  |2 ++
 arch/powerpc/kernel/signal_64.c  |2 ++
 5 files changed, 25 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -65,9 +65,11 @@ static inline void hw_breakpoint_disable
 {
set_dabr(0);
 }
+extern void thread_change_pc(struct task_struct *tsk);
 
 #else  /* CONFIG_HAVE_HW_BREAKPOINT */
 static inline void hw_breakpoint_disable(void) { }
+static inline void thread_change_pc(struct task_struct *tsk) { }
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* __KERNEL__ */
 #endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -176,6 +176,22 @@ int arch_validate_hwbkpt_settings(struct
 }
 
 /*
+ * Restores the breakpoint on the debug registers.
+ * Invoke this function if it is known that the execution context is about to
+ * change to cause loss of MSR_SE settings.
+ */
+void thread_change_pc(struct task_struct *tsk)
+{
+   struct arch_hw_breakpoint *info;
+
+   if (likely(!tsk->thread.last_hit_ubp))
+   return;
+
+   info = counter_arch_bp(tsk->thread.last_hit_ubp);
+   set_dabr(info->address | info->type | DABR_TRANSLATION);
+}
+
+/*
  * Handle debug exception notifications.
  */
 int __kprobes hw_breakpoint_handler(struct die_args *args)
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -149,6 +150,8 @@ static int do_signal_pending(sigset_t *o
if (current->thread.dabr)
set_dabr(current->thread.dabr);
 #endif
+/* Re-enable the breakpoints for the signal stack */
+   thread_change_pc(current);
 
if (is32) {
if (ka.sa.sa_flags & SA_SIGINFO)
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal_64.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal_64.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal_64.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "signal.h"
 
@@ -312,6 +313,7 @@ int sys_swapcontext(struct ucontext __us
|| __copy_to_user(&old_ctx->uc_sigmask,
  ¤t->blocked, sizeof(sigset_t)))
return -EFAULT;
+   thread_change_pc(current);
}
if (new_ctx == NULL)
return 0;
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal_32.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal_32.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal_32.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifdef CONFIG_PPC64
 #include "ppc32.h"
 #include 
@@ -996,6 +997,7 @@ long sys_swapcontext(struct ucontext __u
|| put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked)
|| __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
return -EFAULT;
+   thread_change_pc(current);
}
if (new_ctx == NULL)
return 0;

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 3/4] PPC64-HWBKPT: Handle concurrent alignment interrupts

2010-05-25 Thread K.Prasad
An alignment interrupt may intervene between a DSI/hw-breakpoint exception
and the single-step exception. Enable the alignment interrupt (through
modifications to emulate_single_step()) to notify the single-step exception
handler for proper restoration of hw-breakpoints.

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/traps.c |7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/traps.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
@@ -602,7 +602,7 @@ void RunModeException(struct pt_regs *re
 
 void __kprobes single_step_exception(struct pt_regs *regs)
 {
-   regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
+   clear_single_step(regs);
 
if (notify_die(DIE_SSTEP, "single_step", regs, 5,
5, SIGTRAP) == NOTIFY_STOP)
@@ -621,10 +621,7 @@ void __kprobes single_step_exception(str
  */
 static void emulate_single_step(struct pt_regs *regs)
 {
-   if (single_stepping(regs)) {
-   clear_single_step(regs);
-   _exception(SIGTRAP, regs, TRAP_TRACE, 0);
-   }
+   single_step_exception(regs);
 }
 
 static inline int __parse_fpscr(unsigned long fpscr)

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 2/4] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC BookIII S

2010-05-25 Thread K.Prasad
Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
processors. These interfaces help arbitrate requests from various users and
schedules them as appropriate.

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig |1 
 arch/powerpc/include/asm/cputable.h  |4 
 arch/powerpc/include/asm/hw_breakpoint.h |   73 ++
 arch/powerpc/include/asm/processor.h |8 
 arch/powerpc/kernel/Makefile |1 
 arch/powerpc/kernel/hw_breakpoint.c  |  338 +++
 arch/powerpc/kernel/machine_kexec_64.c   |3 
 arch/powerpc/kernel/process.c|6 
 arch/powerpc/kernel/ptrace.c |   64 +
 arch/powerpc/lib/Makefile|1 
 10 files changed, 499 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,73 @@
+/*
+ * PowerPC BookIII S hardware breakpoint definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010, IBM Corporation.
+ * Author: K.Prasad 
+ *
+ */
+
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+   u8  len; /* length of the target data symbol */
+   int type;
+   unsigned long   address;
+};
+
+#include 
+#include 
+#include 
+
+static inline int hw_breakpoint_slots(int type)
+{
+   return HBP_NUM;
+}
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_bp_generic_fields(int type, int *gen_bp_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+   struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+   set_dabr(0);
+}
+
+#else  /* CONFIG_HAVE_HW_BREAKPOINT */
+static inline void hw_breakpoint_disable(void) { }
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,338 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010 IBM Corporation
+ * Author: K.Prasad 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE

[Patch 1/4] Allow arch-specific cleanup before breakpoint unregistration

2010-05-25 Thread K.Prasad
Certain architectures (such as PowerPC Book III S) have a need to cleanup
data-structures before the breakpoint is unregistered. This patch introduces
an arch-specific hook in release_bp_slot() along with a weak definition in
the form of a stub funciton.

Signed-off-by: K.Prasad 
---
 kernel/hw_breakpoint.c |   12 
 1 file changed, 12 insertions(+)

Index: linux-2.6.ppc64_test/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/kernel/hw_breakpoint.c
@@ -242,6 +242,17 @@ toggle_bp_slot(struct perf_event *bp, bo
 }
 
 /*
+ * Function to perform processor-specific cleanup during unregistration
+ */
+__weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+   /*
+* A weak stub function here for those archs that don't define
+* it inside arch/.../kernel/hw_breakpoint.c
+*/
+}
+
+/*
  * Contraints to check before allowing this new breakpoint counter:
  *
  *  == Non-pinned counter == (Considered as pinned for now)
@@ -339,6 +350,7 @@ void release_bp_slot(struct perf_event *
 {
mutex_lock(&nr_bp_mutex);
 
+   arch_unregister_hw_breakpoint(bp);
__release_bp_slot(bp);
 
mutex_unlock(&nr_bp_mutex);

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 0/4] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XXI

2010-05-25 Thread K.Prasad
Hi All,
Please find a new version of the hw-breakpoint patchset with
changes as described below.

The patchset, passes when tested against breakpoints caused by user-space
instructions but fails against kernel-space instructions (as a result of
emulate_step() failure). They should begin to work fine with further
enhancements to emulate_step().

Changelog - ver XXI

(Version XIX: linuxppc-dev ref:20100524103136.ga8...@in.ibm.com)
- Decision to emulate an instruction is now based on whether the causative
  instruction is in user_mode() or not.
- Breakpoints don't have to be cleared during sigreturn. A 'double-hit' on
  hw_breakpoint_handler() is harmless for non-ptrace instructions.
- Minor changes to enhance code brevity.

Kindly let me know your comments.

Thanks,
K.Prasad

Changelog - ver XX

(Version XIX: linuxppc-dev ref: 20100524040137.ga20...@in.ibm.com)
- Non task-bound breakpoints will only be emulated. Breakpoint will be
  unregistered with a warning if emulation fails.

Changelog - ver XIX

(Version XVIII: linuxppc-dev ref: 20100512033055.ga6...@in.ibm.com)
- Increased coverage of breakpoints during concurrent alignment_exception
  and signal handling (which previously had 'blind-spots').
- Support for kernel-thread breakpoints and kernel-space breakpoints inside the
  context of a user-space process.
- Patches re-based to commit f4b87dee923342505e1ddba8d34ce9de33e75050, thereby
  necessitating minor changes to arch_validate_hwbkpt_settings().

Changelog - ver XVIII

(Version XVII: linuxppc-dev ref: 20100414034340.ga6...@in.ibm.com)
- Slight code restructuring for brevity and coding-style corrections.
- emulate_single_step() now notifies DIE_SSTEP to registered handlers;
  causes single_step_dabr_instruction() to be invoked after alignment_exception.
- hw-breakpoint restoration variables are cleaned-up before unregistration
  through arch_unregister_hw_breakpoint().
- SIGTRAP is no longer generated for non-ptrace user-space breakpoints.

Changelog - ver XVII

(Version XVI: linuxppc-dev ref: 20100330095809.ga14...@in.ibm.com)
- CONFIG_HAVE_HW_BREAKPOINT is now used to define the scope of the new code
  (in lieu of CONFIG_PPC_BOOK3S_64).
- CONFIG_HAVE_HW_BREAKPOINT is now dependant upon CONFIG_PERF_EVENTS and
  CONFIG_PPC_BOOK3S_64 (to overcome build failures under certain configs).
- Included a target in arch/powerpc/lib/Makefile to build sstep.o when
  HAVE_HW_BREAKPOINT.
- Added a dummy definition for hw_breakpoint_disable() when !HAVE_HW_BREAKPOINT.
- Tested builds under defconfigs for ppc64, cell and g5 (found no patch induced
  failures).

Changelog - ver XVI

(Version XV: linuxppc-dev ref: 20100323140639.ga21...@in.ibm.com)
- Used a new config option CONFIG_PPC_BOOK3S_64 (in lieu of
  CONFIG_PPC64/CPU_FTR_HAS_DABR) to limit the scope of the new code.
- Disabled breakpoints before kexec of the machine using 
hw_breakpoint_disable().
- Minor optimisation in exception-64s.S to check for data breakpoint exceptions
  in DSISR finally (after check for other causes) + changes in code comments 
and 
  representation of DSISR_DABRMATCH constant.
- Rebased to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6.

Changelog - ver XV

(Version XIV: linuxppc-dev ref: 20100308181232.ga3...@in.ibm.com)

- Additional patch to disable interrupts during data breakpoint exception
  handling.
- Moved HBP_NUM definition to cputable.h under a new CPU_FTR definition
  (CPU_FTR_HAS_DABR).
- Filtering of extraneous exceptions (due to accesses outside symbol length) is
  by-passed for ptrace requests.
- Removed flush_ptrace_hw_breakpoint() from __switch_to() due to incorrect
  coding placement.
- Changes to code comments as per community reviews for previous version.
- Minor coding-style changes in hw_breakpoint.c as per review comments.
- Re-based to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6

Changelog - ver XIV

(Version XIII: linuxppc-dev ref: 20100215055605.gb3...@in.ibm.com)

- Removed the 'name' field from 'struct arch_hw_breakpoint'.
- All callback invocations through bp->overflow_handler() are replaced with
  perf_bp_event().
- Removed the check for pre-existing single-stepping mode in
  hw_breakpoint_handler() as this check is unreliable while in kernel-space.
  Side effect of this change is the non-triggering of hw-breakpoints while
  single-stepping kernel through KGDB or Xmon.
- Minor code-cleanups and addition of comments in hw_breakpoint_handler() and
  single_step_dabr_instruction().
- Re-based to commit 25cf84cf377c0aae5dbcf937ea89bc7893db5176 of linux-2.6

Changelog - ver XIII

(Version XII: linuxppc-dev ref: 20100121084640.ga3...@in.ibm.com)

- Fixed a bug for user-space breakpoints (triggered following the failure 

Re: [Patch 2/2] PPC64-HWBKPT: Implement hw-breakpoints for PPC64

2010-05-24 Thread K.Prasad
On Thu, May 20, 2010 at 11:10:03PM +1000, Paul Mackerras wrote:
> On Thu, May 20, 2010 at 09:36:03AM +0530, K.Prasad wrote:
> 
(Had this mail composed along with the patchset...but mail server issues
caused delay in sending this...)

Hi Paul,
While we continue to discuss some of the design decisions, I
thought I'd ready up a patchset to capture the changes we agreed upon to
(lest we miss them). I have sent a new version of the patchset here:
linuxppc-dev message-id: 20100524040137.ga20...@in.ibm.com.

Please see more responses below.

> > > Right.  However, the thread is running the signal handler without the
> > > DABR being set, which is unfortunate.
> > > 
> > 
> > In order to keep the breakpoint active during signal handling, a
> > PowerPC specific signal handling code, say do_signal_pending() in
> > arch/powerpc/kernel/signal.c, must be tapped to check for/restore
> > the breakpoint for the process (if it exists).
> 
> What I would suggest is something slightly different: anything that
> causes the thread to change where it's executing -- signal delivery,
> modification of NIP with ptrace -- should cancel the single-step and
> reinstall the breakpoint in the DABR.  In other words we just forget
> that we hit the breakpoint, and rely on hitting it again if we ever
> get back to that instruction.  I think that is by far the most
> reliable approach.
> 
> That means that the hw-breakpoint code needs to export a function
> called, say, thread_change_pc(), which is called whenever we're
> changing a thread's userspace PC (NIP) value.  If the hw-breakpoint
> code has put that thread into single-step mode, we cancel the
> single-step and if the thread is current, set DABR.
> 

I have made changes to signal-handling code on the suggested lines (as
seen here: linuxppc-dev message-id:20100524040342.ge20...@in.ibm.com)
wherein the debug registers are populated before signal-delivery and
cleaned during signal-return.

However handling of nested interrupts, where second exception is taken
inside the signal handler is still flimsy and the system would experience
two hw-breakpoint exceptions. To overcome the same, we will need a flag in
'struct thread_struct' or perhaps in 'struct arch_hw_breakpoint' to
indicate a breakpoint previously taken in signal-handling context. Given
that the repurcussions of a double-hit are not dangerous, and unsure of
how an addition to thread_struct might be received, I've skipped those
changes for now.

> > I'm afraid if this is more complexity than we want to handle in the
> > first patchset. I agree that this will create a 'blind-spot' of code
> > which cannot not be monitored using breakpoints and may limit debugging
> > efforts (specially for memory corruption); however suspecting that signal
> > handlers (especially those that don't return to original instruction)
> > would be rare, I feel that this could be a 'feature' that can be brought
> > later-in. What do you think?
> 
> I think the thread_change_pc() approach is quite a bit simpler, and I
> think it's better to get this right at the outset rather than have it
> cause bugs later on, when we've all forgotten all the curly
> details. :)

Yes, the details are mostly captured in the latest patchset. Had to make
some 'bold' changes to overcome the issues though :-)

> 
> > > Imagine this scenario: we get the DABR match, set MSR_SE and return to
> > > the task.  In the meantime another higher-priority task has become
> > > runnable and our need_resched flag is set, so we call schedule() on
> > > the way back out to usermode.  The other task runs and then blocks and
> > > our task gets scheduled again.  As part of the context switch,
> > > arch_install_hw_breakpoint() will get called and will set DABR.  So
> > > we'll return to usermode with both DABR and MSE_SE set.
> > > 
> > 
> > I didn't foresee such a possibility. I think this can be handled by
> > putting a check in arch_install_hw_breakpoint() as shown below:
> > 
> > int arch_install_hw_breakpoint(struct perf_event *bp)
> > {
> > struct arch_hw_breakpoint *info = counter_arch_bp(bp);
> > struct perf_event **slot = &__get_cpu_var(bp_per_reg);
> > 
> > *slot = bp;
> > if (!current->thread.last_hit_ubp)
> > set_dabr(info->address | info->type | DABR_TRANSLATION);
> > return 0;
> > }
> 
> Yes, basically, but don't we need to handle per-cpu breakpoints as
> well?  That is, we only want the extra check if this breakpoint is a
> per-task breakpoint.  Or am I not seeing enough context her

[Patch 1/4] Allow arch-specific cleanup before breakpoint unregistration

2010-05-24 Thread K.Prasad
Certain architectures (such as PowerPC Book III S) have a need to cleanup
data-structures before the breakpoint is unregistered. This patch introduces
an arch-specific hook in release_bp_slot() along with a weak definition in
the form of a stub funciton.

Signed-off-by: K.Prasad 
---
 kernel/hw_breakpoint.c |   12 
 1 file changed, 12 insertions(+)

Index: linux-2.6.ppc64_test/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/kernel/hw_breakpoint.c
@@ -242,6 +242,17 @@ toggle_bp_slot(struct perf_event *bp, bo
 }
 
 /*
+ * Function to perform processor-specific cleanup during unregistration
+ */
+__weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+   /*
+* A weak stub function here for those archs that don't define
+* it inside arch/.../kernel/hw_breakpoint.c
+*/
+}
+
+/*
  * Contraints to check before allowing this new breakpoint counter:
  *
  *  == Non-pinned counter == (Considered as pinned for now)
@@ -339,6 +350,7 @@ void release_bp_slot(struct perf_event *
 {
mutex_lock(&nr_bp_mutex);
 
+   arch_unregister_hw_breakpoint(bp);
__release_bp_slot(bp);
 
mutex_unlock(&nr_bp_mutex);

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 0/4] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XX

2010-05-24 Thread K.Prasad
Hi All,
Here's a quick release of the next version of the patchset with a
small, yet significant changelog.

Please let me know the comments, if any.

Changelog - ver XX

(Version XIX: linuxppc-dev ref: 20100524040137.ga20...@in.ibm.com)
- Non task-bound breakpoints will only be emulated. Breakpoint will be
  unregistered with a warning if emulation fails.

Thanks,
K.Prasad

Changelog - ver XIX

(Version XVIII: linuxppc-dev ref: 20100512033055.ga6...@in.ibm.com)
- Increased coverage of breakpoints during concurrent alignment_exception
  and signal handling (which previously had 'blind-spots').
- Support for kernel-thread breakpoints and kernel-space breakpoints inside the
  context of a user-space process.
- Patches re-based to commit f4b87dee923342505e1ddba8d34ce9de33e75050, thereby
  necessitating minor changes to arch_validate_hwbkpt_settings().

Changelog - ver XVIII

(Version XVII: linuxppc-dev ref: 20100414034340.ga6...@in.ibm.com)
- hw-breakpoint restoration variables are cleaned-up before unregistration
  through a new function hook arch_unregister_hw_breakpoint().
- emulate_single_step() now notifies DIE_SSTEP to registered handlers;
  causes single_step_dabr_instruction() to be invoked after alignment_exception.
- SIGTRAP is no longer generated for non-ptrace user-space breakpoints.
- Slight code restructuring for brevity and style corrections.

Changelog - ver XVII

(Version XVI: linuxppc-dev ref: 20100330095809.ga14...@in.ibm.com)
- CONFIG_HAVE_HW_BREAKPOINT is now used to define the scope of the new code
  (in lieu of CONFIG_PPC_BOOK3S_64).
- CONFIG_HAVE_HW_BREAKPOINT is now dependant upon CONFIG_PERF_EVENTS and
  CONFIG_PPC_BOOK3S_64 (to overcome build failures under certain configs).
- Included a target in arch/powerpc/lib/Makefile to build sstep.o when
  HAVE_HW_BREAKPOINT.
- Added a dummy definition for hw_breakpoint_disable() when !HAVE_HW_BREAKPOINT.
- Tested builds under defconfigs for ppc64, cell and g5 (found no patch induced
  failures).

Changelog - ver XVI

(Version XV: linuxppc-dev ref: 20100323140639.ga21...@in.ibm.com)
- Used a new config option CONFIG_PPC_BOOK3S_64 (in lieu of
  CONFIG_PPC64/CPU_FTR_HAS_DABR) to limit the scope of the new code.
- Disabled breakpoints before kexec of the machine using 
hw_breakpoint_disable().
- Minor optimisation in exception-64s.S to check for data breakpoint exceptions
  in DSISR finally (after check for other causes) + changes in code comments 
and 
  representation of DSISR_DABRMATCH constant.
- Rebased to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6.

Changelog - ver XV

(Version XIV: linuxppc-dev ref: 20100308181232.ga3...@in.ibm.com)

- Additional patch to disable interrupts during data breakpoint exception
  handling.
- Moved HBP_NUM definition to cputable.h under a new CPU_FTR definition
  (CPU_FTR_HAS_DABR).
- Filtering of extraneous exceptions (due to accesses outside symbol length) is
  by-passed for ptrace requests.
- Removed flush_ptrace_hw_breakpoint() from __switch_to() due to incorrect
  coding placement.
- Changes to code comments as per community reviews for previous version.
- Minor coding-style changes in hw_breakpoint.c as per review comments.
- Re-based to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6

Changelog - ver XIV

(Version XIII: linuxppc-dev ref: 20100215055605.gb3...@in.ibm.com)

- Removed the 'name' field from 'struct arch_hw_breakpoint'.
- All callback invocations through bp->overflow_handler() are replaced with
  perf_bp_event().
- Removed the check for pre-existing single-stepping mode in
  hw_breakpoint_handler() as this check is unreliable while in kernel-space.
  Side effect of this change is the non-triggering of hw-breakpoints while
  single-stepping kernel through KGDB or Xmon.
- Minor code-cleanups and addition of comments in hw_breakpoint_handler() and
  single_step_dabr_instruction().
- Re-based to commit 25cf84cf377c0aae5dbcf937ea89bc7893db5176 of linux-2.6

Changelog - ver XIII

(Version XII: linuxppc-dev ref: 20100121084640.ga3...@in.ibm.com)

- Fixed a bug for user-space breakpoints (triggered following the failure of a
  breakpoint request).
- Re-based on commit 724e6d3fe8003c3f60bf404bf22e4e331327c596 of linux-2.6
  
Changelog - ver XII

(Version XI: linuxppc-dev ref: 20100119091234.ga9...@in.ibm.com)

- Unset MSR_SE only if kernel was not previously in single-step mode.
- Pre-emption is now enabled before returning from the hw-breakpoint exception
  handler.
- Variables to track the source of single-step exception (breakpoint from 
kernel,
  user-space vs single-stepping due to other requests) are added.
- Extraneous hw-breakpoint exceptions (due to memory accesses lying outside
  monitored symbol length) is now done for both kernel and us

[Patch 4/4] PPC64-HWBKPT: Enable hw-breakpoints while handling intervening signals

2010-05-24 Thread K.Prasad
A signal delivered between a hw_breakpoint_handler() and the
single_step_dabr_instruction() will not have the breakpoint active during
signal handling (since breakpoint will not be restored through single-stepping
due to absence of MSR_SE bit on the signal frame). Enable breakpoints before
signal delivery and clear them during sigreturn() syscall.

Limitation: Nested hw-breakpoint exceptions (where second exception is raised
inside signal context) will cause a 'double-hit' i.e. the first breakpoint
exception will be taken twice.

Restore hw-breakpoints if the user-context is altered in the signal handler
(causing loss of MSR_SE). Side-effect: 'Double-hit' of breakpoint if the
instruction pointer is unaltered in the new context.

Signed-off-by: K.Prasad 
---
 arch/powerpc/include/asm/hw_breakpoint.h |3 +++
 arch/powerpc/kernel/hw_breakpoint.c  |   28 
 arch/powerpc/kernel/signal.c |8 
 arch/powerpc/kernel/signal_32.c  |   10 ++
 arch/powerpc/kernel/signal_64.c  |7 +++
 5 files changed, 56 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -43,6 +43,9 @@ static inline void hw_breakpoint_disable
 {
set_dabr(0);
 }
+extern void sighandler_install_bp(struct task_struct *tsk);
+extern void sigreturn_uninstall_bp(struct task_struct *tsk);
+extern void thread_change_pc(struct task_struct *tsk, unsigned long msr);
 
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* __KERNEL__ */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -175,6 +175,34 @@ int arch_validate_hwbkpt_settings(struct
return 0;
 }
 
+void sighandler_install_bp(struct task_struct *tsk)
+{
+   struct arch_hw_breakpoint *info;
+
+   if (likely(!tsk->thread.last_hit_ubp))
+   return;
+
+   info = counter_arch_bp(tsk->thread.last_hit_ubp);
+   set_dabr(info->address | info->type | DABR_TRANSLATION);
+}
+
+void sigreturn_uninstall_bp(struct task_struct *tsk)
+{
+   if (unlikely(tsk->thread.last_hit_ubp))
+   set_dabr(0);
+}
+
+void thread_change_pc(struct task_struct *tsk, unsigned long new_msr)
+{
+   /*
+* Do not bother to restore breakpoints if single-stepping is not
+* cleared. single_step_dabr_instruction() will handle it if MSR_SE
+* is set.
+*/
+   if (!(new_msr & MSR_SE))
+   sighandler_install_bp(tsk);
+}
+
 /*
  * Handle debug exception notifications.
  */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -149,6 +150,13 @@ static int do_signal_pending(sigset_t *o
if (current->thread.dabr)
set_dabr(current->thread.dabr);
 #endif
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   /*
+* Re-enable the breakpoints (if it was previously cleared in
+* hw_breakpoint_handler()) for the signal stack.
+*/
+   sighandler_install_bp(current);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
if (is32) {
if (ka.sa.sa_flags & SA_SIGINFO)
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal_64.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal_64.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal_64.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "signal.h"
 
@@ -312,6 +313,9 @@ int sys_swapcontext(struct ucontext __us
|| __copy_to_user(&old_ctx->uc_sigmask,
  ¤t->blocked, sizeof(sigset_t)))
return -EFAULT;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   thread_change_pc(current, new_msr);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
}
if (new_ctx == NULL)
return 0;
@@ -364,6 +368,9 @@ int sys_rt_sigreturn(unsigned long r3, u
if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
goto badframe;
restore_sigmask(&set);
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   sigreturn_uninstall_bp(current);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext))
 

[Patch 3/4] PPC64-HWBKPT: Handle concurrent alignment interrupts

2010-05-24 Thread K.Prasad
An alignment interrupt may intervene between a DSI/hw-breakpoint exception
and the single-step exception. Enable the alignment interrupt (through
modifications to emulate_single_step()) to notify the single-step exception
handler for proper restoration of hw-breakpoints.

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/traps.c |7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/traps.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
@@ -602,7 +602,7 @@ void RunModeException(struct pt_regs *re
 
 void __kprobes single_step_exception(struct pt_regs *regs)
 {
-   regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
+   clear_single_step(regs);
 
if (notify_die(DIE_SSTEP, "single_step", regs, 5,
5, SIGTRAP) == NOTIFY_STOP)
@@ -621,10 +621,7 @@ void __kprobes single_step_exception(str
  */
 static void emulate_single_step(struct pt_regs *regs)
 {
-   if (single_stepping(regs)) {
-   clear_single_step(regs);
-   _exception(SIGTRAP, regs, TRAP_TRACE, 0);
-   }
+   single_step_exception(regs);
 }
 
 static inline int __parse_fpscr(unsigned long fpscr)

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 2/4] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC Book III S

2010-05-24 Thread K.Prasad
Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
processors. These interfaces help arbitrate requests from various users and
schedules them as appropriate.

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig |1 
 arch/powerpc/include/asm/cputable.h  |4 
 arch/powerpc/include/asm/hw_breakpoint.h |   49 
 arch/powerpc/include/asm/processor.h |8 
 arch/powerpc/kernel/Makefile |1 
 arch/powerpc/kernel/hw_breakpoint.c  |  345 +++
 arch/powerpc/kernel/machine_kexec_64.c   |3 
 arch/powerpc/kernel/process.c|6 
 arch/powerpc/kernel/ptrace.c |   64 +
 arch/powerpc/lib/Makefile|1 
 include/linux/hw_breakpoint.h|1 
 11 files changed, 483 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,49 @@
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+   u8  len; /* length of the target data symbol */
+   int type;
+   unsigned long   address;
+};
+
+#include 
+#include 
+#include 
+
+static inline int hw_breakpoint_slots(int type)
+{
+   return HBP_NUM;
+}
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_bp_generic_fields(int type, int *gen_bp_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+   struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+   set_dabr(0);
+}
+
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,345 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010 IBM Corporation
+ * Author: K.Prasad 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+   struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+   struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+   *slot = bp;
+
+   /*
+* Do not install DABR values if the instruction must be single-stepped.
+* If so, DABR will be populated in single_step_dabr_instruction().
+*/
+   if (current->thread.last_hit_ubp != bp)
+   set_dabr(info->address | info->type | DABR_TRANSLATION);
+
+   return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the given counter.

Re: [RFC Patch 2/5] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC Book III S

2010-05-23 Thread K.Prasad
On Mon, May 24, 2010 at 09:32:25AM +0530, K.Prasad wrote:
> Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
> processors. These interfaces help arbitrate requests from various users and
> schedules them as appropriate.
> 

> +/*
> + * Handle debug exception notifications.
> + */
> +int __kprobes hw_breakpoint_handler(struct die_args *args)
> +{
> + bool is_kernel, is_ptrace_bp = false;
> + int rc = NOTIFY_STOP;
> + struct perf_event *bp;
> + struct pt_regs *regs = args->regs;
> + unsigned long dar = regs->dar;
> + int stepped = 1;
> + struct arch_hw_breakpoint *info;
> +
> + /* Disable breakpoints during exception handling */
> + set_dabr(0);
> + /*
> +  * The counter may be concurrently released but that can only
> +  * occur from a call_rcu() path. We can then safely fetch
> +  * the breakpoint, use its callback, touch its counter
> +  * while we are in an rcu_read_lock() path.
> +  */
> + rcu_read_lock();
> +
> + bp = __get_cpu_var(bp_per_reg);
> + if (!bp)
> + goto out;
> + info = counter_arch_bp(bp);
> + is_kernel = is_kernel_addr(bp->attr.bp_addr);
> + is_ptrace_bp = (bp->overflow_handler == ptrace_triggered) ?
> + true : false;
> +
> + /*
> +  * Verify if dar lies within the address range occupied by the symbol
> +  * being watched to filter extraneous exceptions.
> +  */
> + if (!((bp->attr.bp_addr <= dar) &&
> + (dar <= (bp->attr.bp_addr + bp->attr.bp_len))) &&
> + (!is_ptrace_bp))
> + /*
> +  * This exception is triggered not because of a memory access on
> +  * the monitored variable but in the double-word address range
> +  * in which it is contained. We will consume this exception,
> +  * considering it as 'noise'.
> +  */
> + goto restore_bp;
> +
> + /*
> +  * Return early after invoking user-callback function without restoring
> +  * DABR if the breakpoint is from ptrace which always operates in
> +  * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal
> +  * generated in do_dabr().
> +  */
> + if (is_ptrace_bp) {
> + perf_bp_event(bp, regs);
> + rc = NOTIFY_DONE;
> + goto out;
> + }
> +
> + /*
> +  * Do not emulate user-space instructions from kernel-space,
> +  * instead single-step them.
> +  */
> + if (!is_kernel) {
> + bp->ctx->task->thread.last_hit_ubp = bp;
> + regs->msr |= MSR_SE;
> + goto out;
> + }
> +
> + stepped = emulate_step(regs, regs->nip);
> + /* emulate_step() could not execute it, single-step them */
> + if (stepped == 0) {

As I was responding to one of the previous mails, I realised that I
had not made changes here as Paul Mackerras had suggested
(reference linuxppc-dev message-id:
20100520131003.gb29...@brick.ozlabs.ibm.com) i.e. uninstall breakpoint
if single-stepping failed.

I'll quickly send out a revised patch as a reply to this one. Regrets
for the confusion caused.

Thanks,
K.Prasad

> + regs->msr |= MSR_SE;
> + __get_cpu_var(last_hit_bp) = bp;
> + goto out;
> + }
> + /*
> +  * As a policy, the callback is invoked in a 'trigger-after-execute'
> +  * fashion
> +  */
> + perf_bp_event(bp, regs);
> +
> +restore_bp:
> + set_dabr(info->address | info->type | DABR_TRANSLATION);
> +out:
> + rcu_read_unlock();
> + return rc;
> +}
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[RFC Patch 5/5] PPC64-HWBKPT: Enable proper distinction of per-task and per-cpu breakpoints

2010-05-23 Thread K.Prasad
Per-task and per-cpu breakpoints have to be unambiguously identified for
proper restoration of hw-breakpoints. The notion of pure user- and kernel-
space breakpoints is antiquated. Store 'pid' of the process against which
the perf-counter was requested to help proper distinction.

This helps seamless handling of kernel-space breakpoints within the context
of a user-space process and breakpoints for kernel-threads.

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/hw_breakpoint.c |   24 +---
 include/linux/perf_event.h  |1 +
 kernel/perf_event.c |9 ++---
 3 files changed, 24 insertions(+), 10 deletions(-)

Index: linux-2.6.ppc64_test/include/linux/perf_event.h
===
--- linux-2.6.ppc64_test.orig/include/linux/perf_event.h
+++ linux-2.6.ppc64_test/include/linux/perf_event.h
@@ -698,6 +698,7 @@ struct perf_event {
 
int oncpu;
int cpu;
+   pid_t   pid;
 
struct list_headowner_entry;
struct task_struct  *owner;
Index: linux-2.6.ppc64_test/kernel/perf_event.c
===
--- linux-2.6.ppc64_test.orig/kernel/perf_event.c
+++ linux-2.6.ppc64_test/kernel/perf_event.c
@@ -4684,6 +4684,7 @@ static const struct pmu *sw_perf_event_i
 static struct perf_event *
 perf_event_alloc(struct perf_event_attr *attr,
   int cpu,
+  pid_t pid,
   struct perf_event_context *ctx,
   struct perf_event *group_leader,
   struct perf_event *parent_event,
@@ -4717,6 +4718,7 @@ perf_event_alloc(struct perf_event_attr 
mutex_init(&event->mmap_mutex);
 
event->cpu  = cpu;
+   event->pid  = pid;
event->attr = *attr;
event->group_leader = group_leader;
event->pmu  = NULL;
@@ -5015,7 +5017,7 @@ SYSCALL_DEFINE5(perf_event_open,
goto err_put_context;
}
 
-   event = perf_event_alloc(&attr, cpu, ctx, group_leader,
+   event = perf_event_alloc(&attr, cpu, pid, ctx, group_leader,
 NULL, NULL, GFP_KERNEL);
err = PTR_ERR(event);
if (IS_ERR(event))
@@ -5090,7 +5092,7 @@ perf_event_create_kernel_counter(struct 
goto err_exit;
}
 
-   event = perf_event_alloc(attr, cpu, ctx, NULL,
+   event = perf_event_alloc(attr, cpu, pid, ctx, NULL,
 NULL, overflow_handler, GFP_KERNEL);
if (IS_ERR(event)) {
err = PTR_ERR(event);
@@ -5142,7 +5144,8 @@ inherit_event(struct perf_event *parent_
parent_event = parent_event->parent;
 
child_event = perf_event_alloc(&parent_event->attr,
-  parent_event->cpu, child_ctx,
+  parent_event->cpu, child->pid,
+  child_ctx,
   group_leader, parent_event,
   NULL, GFP_KERNEL);
if (IS_ERR(child_event))
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -221,7 +221,7 @@ void thread_change_pc(struct task_struct
  */
 int __kprobes hw_breakpoint_handler(struct die_args *args)
 {
-   bool is_kernel, is_ptrace_bp = false;
+   bool is_kernel, is_taskbound_bp, is_ptrace_bp = false;
int rc = NOTIFY_STOP;
struct perf_event *bp;
struct pt_regs *regs = args->regs;
@@ -246,6 +246,7 @@ int __kprobes hw_breakpoint_handler(stru
is_kernel = is_kernel_addr(bp->attr.bp_addr);
is_ptrace_bp = (bp->overflow_handler == ptrace_triggered) ?
true : false;
+   is_taskbound_bp = (bp->pid > 0) ? true : false;
 
/*
 * Verify if dar lies within the address range occupied by the symbol
@@ -288,7 +289,14 @@ int __kprobes hw_breakpoint_handler(stru
/* emulate_step() could not execute it, single-step them */
if (stepped == 0) {
regs->msr |= MSR_SE;
-   __get_cpu_var(last_hit_bp) = bp;
+   /*
+* Kernel-space addresses can also be bound to a task. If so,
+* store the breakpoint in its 'thread_struct'
+*/
+   if (is_taskbound_bp)
+   bp->ctx->task->thread.last_hit_ubp = bp;
+   else
+   __get_cpu_var(last_hit_bp

[RFC Patch 4/5] PPC64-HWBKPT: Enable hw-breakpoints while handling intervening signals

2010-05-23 Thread K.Prasad
A signal delivered between a hw_breakpoint_handler() and the
single_step_dabr_instruction() will not have the breakpoint active during
signal handling (since breakpoint will not be restored through single-stepping
due to absence of MSR_SE bit on the signal frame). Enable breakpoints before
signal delivery and clear them during sigreturn() syscall.

Limitation: Nested hw-breakpoint exceptions (where second exception is raised
inside signal context) will cause a 'double-hit' i.e. the first breakpoint
exception will be taken twice.

Restore hw-breakpoints if the user-context is altered in the signal handler
(causing loss of MSR_SE).
Side-effect: 'Double-hit' of breakpoint if the instruction pointer is
unaltered in the new context.

Signed-off-by: K.Prasad 
---
 arch/powerpc/include/asm/hw_breakpoint.h |3 +++
 arch/powerpc/kernel/hw_breakpoint.c  |   28 
 arch/powerpc/kernel/signal.c |8 
 arch/powerpc/kernel/signal_32.c  |   10 ++
 arch/powerpc/kernel/signal_64.c  |7 +++
 5 files changed, 56 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -43,6 +43,9 @@ static inline void hw_breakpoint_disable
 {
set_dabr(0);
 }
+extern void sighandler_install_bp(struct task_struct *tsk);
+extern void sigreturn_uninstall_bp(struct task_struct *tsk);
+extern void thread_change_pc(struct task_struct *tsk, unsigned long msr);
 
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* __KERNEL__ */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -188,6 +188,34 @@ int arch_validate_hwbkpt_settings(struct
return 0;
 }
 
+void sighandler_install_bp(struct task_struct *tsk)
+{
+   struct arch_hw_breakpoint *info;
+
+   if (likely(!tsk->thread.last_hit_ubp))
+   return;
+
+   info = counter_arch_bp(tsk->thread.last_hit_ubp);
+   set_dabr(info->address | info->type | DABR_TRANSLATION);
+}
+
+void sigreturn_uninstall_bp(struct task_struct *tsk)
+{
+   if (unlikely(tsk->thread.last_hit_ubp))
+   set_dabr(0);
+}
+
+void thread_change_pc(struct task_struct *tsk, unsigned long new_msr)
+{
+   /*
+* Do not bother to restore breakpoints if single-stepping is not
+* cleared. single_step_dabr_instruction() will handle it if MSR_SE
+* is set.
+*/
+   if (!(new_msr & MSR_SE))
+   sighandler_install_bp(tsk);
+}
+
 /*
  * Handle debug exception notifications.
  */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -149,6 +150,13 @@ static int do_signal_pending(sigset_t *o
if (current->thread.dabr)
set_dabr(current->thread.dabr);
 #endif
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   /*
+* Re-enable the breakpoints (if it was previously cleared in
+* hw_breakpoint_handler()) for the signal stack.
+*/
+   sighandler_install_bp(current);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
if (is32) {
if (ka.sa.sa_flags & SA_SIGINFO)
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal_64.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal_64.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal_64.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "signal.h"
 
@@ -312,6 +313,9 @@ int sys_swapcontext(struct ucontext __us
|| __copy_to_user(&old_ctx->uc_sigmask,
  ¤t->blocked, sizeof(sigset_t)))
return -EFAULT;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   thread_change_pc(current, new_msr);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
}
if (new_ctx == NULL)
return 0;
@@ -364,6 +368,9 @@ int sys_rt_sigreturn(unsigned long r3, u
if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
goto badframe;
restore_sigmask(&set);
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   sigreturn_uninstall_bp(current);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext))
 

[RFC Patch 3/5] PPC64-HWBKPT: Handle concurrent alignment interrupts

2010-05-23 Thread K.Prasad
An alignment interrupt may intervene between a DSI/hw-breakpoint exception
and the single-step exception. Enable the alignment interrupt (through
modifications to emulate_single_step()) to notify the single-step exception
handler for proper restoration of hw-breakpoints.

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/traps.c |7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/traps.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
@@ -602,7 +602,7 @@ void RunModeException(struct pt_regs *re
 
 void __kprobes single_step_exception(struct pt_regs *regs)
 {
-   regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
+   clear_single_step(regs);
 
if (notify_die(DIE_SSTEP, "single_step", regs, 5,
5, SIGTRAP) == NOTIFY_STOP)
@@ -621,10 +621,7 @@ void __kprobes single_step_exception(str
  */
 static void emulate_single_step(struct pt_regs *regs)
 {
-   if (single_stepping(regs)) {
-   clear_single_step(regs);
-   _exception(SIGTRAP, regs, TRAP_TRACE, 0);
-   }
+   single_step_exception(regs);
 }
 
 static inline int __parse_fpscr(unsigned long fpscr)

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[RFC Patch 2/5] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC Book III S

2010-05-23 Thread K.Prasad
Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
processors. These interfaces help arbitrate requests from various users and
schedules them as appropriate.

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig |1 
 arch/powerpc/include/asm/cputable.h  |4 
 arch/powerpc/include/asm/hw_breakpoint.h |   49 
 arch/powerpc/include/asm/processor.h |8 
 arch/powerpc/kernel/Makefile |1 
 arch/powerpc/kernel/hw_breakpoint.c  |  365 +++
 arch/powerpc/kernel/machine_kexec_64.c   |3 
 arch/powerpc/kernel/process.c|6 
 arch/powerpc/kernel/ptrace.c |   64 +
 arch/powerpc/lib/Makefile|1 
 include/linux/hw_breakpoint.h|1 
 11 files changed, 503 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,49 @@
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+   u8  len; /* length of the target data symbol */
+   int type;
+   unsigned long   address;
+};
+
+#include 
+#include 
+#include 
+
+static inline int hw_breakpoint_slots(int type)
+{
+   return HBP_NUM;
+}
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_bp_generic_fields(int type, int *gen_bp_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+   struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+   set_dabr(0);
+}
+
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,365 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010 IBM Corporation
+ * Author: K.Prasad 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/*
+ * Store the 'bp' that caused the hw-breakpoint exception just before we
+ * single-step. Use it to distinguish a single-step exception (due to a
+ * previous hw-breakpoint exception) from a normal one
+ */
+static DEFINE_PER_CPU(struct perf_event *, last_hit_bp);
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+   struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+   struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+   *slot = bp;
+
+   /*
+* Do not install DABR values if the instruction must be single-stepped.
+   

[RFC Patch 1/5] Allow arch-specific cleanup before breakpoint unregistration

2010-05-23 Thread K.Prasad
Certain architectures (such as PowerPC Book III S) have a need to cleanup
data-structures before the breakpoint is unregistered. This patch introduces
an arch-specific hook in release_bp_slot() along with a weak definition in
the form of a stub funciton.

Signed-off-by: K.Prasad 
---
 kernel/hw_breakpoint.c |   12 
 1 file changed, 12 insertions(+)

Index: linux-2.6.ppc64_test/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/kernel/hw_breakpoint.c
@@ -242,6 +242,17 @@ toggle_bp_slot(struct perf_event *bp, bo
 }
 
 /*
+ * Function to perform processor-specific cleanup during unregistration
+ */
+__weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+   /*
+* A weak stub function here for those archs that don't define
+* it inside arch/.../kernel/hw_breakpoint.c
+*/
+}
+
+/*
  * Contraints to check before allowing this new breakpoint counter:
  *
  *  == Non-pinned counter == (Considered as pinned for now)
@@ -339,6 +350,7 @@ void release_bp_slot(struct perf_event *
 {
mutex_lock(&nr_bp_mutex);
 
+   arch_unregister_hw_breakpoint(bp);
__release_bp_slot(bp);
 
mutex_unlock(&nr_bp_mutex);

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[RFC Patch 0/5] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XIX

2010-05-23 Thread K.Prasad
Hi All,
Please find a new version of the patches that implement
hw-breakpoints for PowerPC Book III S. This patchset has some major
additions to hw-breakpoint exception handling that help reliable
restoration of breakpoints + increased coverage of breakpoints for
signal handlers.

The patches have been marked RFC, given that changes through patches
4/5 and 5/5 haven't been tested in particular and that they make
modifications to the generic framework too.

Kindly let me know your comments.

Changelog - ver XIX

(Version XVIII: linuxppc-dev ref: 20100512033055.ga6...@in.ibm.com)
- Increased coverage of breakpoints during concurrent alignment_exception
  and signal handling (which previously had 'blind-spots').
- Support for kernel-thread breakpoints and kernel-space breakpoints inside the
  context of a user-space process.
- Patches re-based to commit f4b87dee923342505e1ddba8d34ce9de33e75050, thereby
  necessitating minor changes to arch_validate_hwbkpt_settings().

Thanks,
K.Prasad

Changelog - ver XVIII

(Version XVII: linuxppc-dev ref: 20100414034340.ga6...@in.ibm.com)
- hw-breakpoint restoration variables are cleaned-up before unregistration
  through a new function hook arch_unregister_hw_breakpoint().
- emulate_single_step() now notifies DIE_SSTEP to registered handlers;
  causes single_step_dabr_instruction() to be invoked after alignment_exception.
- SIGTRAP is no longer generated for non-ptrace user-space breakpoints.
- Slight code restructuring for brevity and style corrections.

Changelog - ver XVII

(Version XVI: linuxppc-dev ref: 20100330095809.ga14...@in.ibm.com)
- CONFIG_HAVE_HW_BREAKPOINT is now used to define the scope of the new code
  (in lieu of CONFIG_PPC_BOOK3S_64).
- CONFIG_HAVE_HW_BREAKPOINT is now dependant upon CONFIG_PERF_EVENTS and
  CONFIG_PPC_BOOK3S_64 (to overcome build failures under certain configs).
- Included a target in arch/powerpc/lib/Makefile to build sstep.o when
  HAVE_HW_BREAKPOINT.
- Added a dummy definition for hw_breakpoint_disable() when !HAVE_HW_BREAKPOINT.
- Tested builds under defconfigs for ppc64, cell and g5 (found no patch induced
  failures).

Changelog - ver XVI

(Version XV: linuxppc-dev ref: 20100323140639.ga21...@in.ibm.com)
- Used a new config option CONFIG_PPC_BOOK3S_64 (in lieu of
  CONFIG_PPC64/CPU_FTR_HAS_DABR) to limit the scope of the new code.
- Disabled breakpoints before kexec of the machine using 
hw_breakpoint_disable().
- Minor optimisation in exception-64s.S to check for data breakpoint exceptions
  in DSISR finally (after check for other causes) + changes in code comments 
and 
  representation of DSISR_DABRMATCH constant.
- Rebased to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6.

Changelog - ver XV

(Version XIV: linuxppc-dev ref: 20100308181232.ga3...@in.ibm.com)

- Additional patch to disable interrupts during data breakpoint exception
  handling.
- Moved HBP_NUM definition to cputable.h under a new CPU_FTR definition
  (CPU_FTR_HAS_DABR).
- Filtering of extraneous exceptions (due to accesses outside symbol length) is
  by-passed for ptrace requests.
- Removed flush_ptrace_hw_breakpoint() from __switch_to() due to incorrect
  coding placement.
- Changes to code comments as per community reviews for previous version.
- Minor coding-style changes in hw_breakpoint.c as per review comments.
- Re-based to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6

Changelog - ver XIV

(Version XIII: linuxppc-dev ref: 20100215055605.gb3...@in.ibm.com)

- Removed the 'name' field from 'struct arch_hw_breakpoint'.
- All callback invocations through bp->overflow_handler() are replaced with
  perf_bp_event().
- Removed the check for pre-existing single-stepping mode in
  hw_breakpoint_handler() as this check is unreliable while in kernel-space.
  Side effect of this change is the non-triggering of hw-breakpoints while
  single-stepping kernel through KGDB or Xmon.
- Minor code-cleanups and addition of comments in hw_breakpoint_handler() and
  single_step_dabr_instruction().
- Re-based to commit 25cf84cf377c0aae5dbcf937ea89bc7893db5176 of linux-2.6

Changelog - ver XIII

(Version XII: linuxppc-dev ref: 20100121084640.ga3...@in.ibm.com)

- Fixed a bug for user-space breakpoints (triggered following the failure of a
  breakpoint request).
- Re-based on commit 724e6d3fe8003c3f60bf404bf22e4e331327c596 of linux-2.6
  
Changelog - ver XII

(Version XI: linuxppc-dev ref: 20100119091234.ga9...@in.ibm.com)

- Unset MSR_SE only if kernel was not previously in single-step mode.
- Pre-emption is now enabled before returning from the hw-breakpoint exception
  handler.
- Variables to track the source of single-step exception (breakpoint from 
kernel,
  user-space vs single-stepping due to other requests) are added.
- Extraneous h

Re: [Patch 2/2] PPC64-HWBKPT: Implement hw-breakpoints for PPC64

2010-05-19 Thread K.Prasad
On Mon, May 17, 2010 at 10:32:41PM +1000, Paul Mackerras wrote:
> On Fri, May 14, 2010 at 12:25:31PM +0530, K.Prasad wrote:
> 
> > Okay. I will re-use single_step_exception() after modifications; it
> > appearsto have no in-kernel users for it.
> 
> It's called from exceptions-64s.S, head_32.S and head_8xx.S in
> arch/powerpc/kernel.
> 
> > > Suppose the address at which the data breakpoint has been unmapped,
> > > and the process has a handler for the SIGSEGV signal.  When we try to
> > > single-step the load or store, we will get a DSI (0x300) interrupt,
> > > call into do_page_fault, and end up sending the process a SIGSEGV.
> > > That will invoke the signal handler, which can then do anything it
> > > likes.  It can do a blocking system call, it can longjmp() back into
> > > its main event, or it can return from the signal handler.  Only in the
> > > last case will it retry the load or store, and then only if the signal
> > > handler hasn't modified the NIP value in the signal frame.  That's
> > > what I mean by "doesn't return to the instruction".
> > > 
> > 
> > At the outset, this seemed to be a scary thing to happen; but turns out
> > to be harmful only to the extent of generating a false hw-breakpoint
> > exception in certain cases. A case-by-case basis analysis reveals thus:
> > 
> > Consider an instruction stream i1, i2, i3, ... iN, where i1 has
> > finished execution and i2 is about to be executed but has generated a
> > DSI interrupt with the above-mentioned conditions i.e. DSISR indicates a
> > DABR match + Page-Table entry not found. Now according to do_hash_page
> > in exception-64s.S (as pasted below), do_page_fault() and do_dabr() are
> > invoked one after the other.
> > 
> > _STATIC(do_hash_page)
> > std r3,_DAR(r1)
> > std r4,_DSISR(r1)
> > 
> > andis.  r0,r4,0xa410/* weird error? */
> > bne-handle_page_fault   /* if not, try to insert a HPTE */
> > andis.  r0,r4,dsisr_dabrma...@h
> > bne-handle_dabr_fault
> 
> Note that bne is not a procedure call; we'll actually get two DSIs in
> this scenario.  But I don't think that matters.  Also note that the
> branch to handle_page_fault here is not for the HPTE-not-found case;
> it's for the unusual errors.  So we'll handle the HPTE insertion after
> handling the DABR match.
> 

Okay.

> > Thus, when control returns to user-space to instruction 'i2', the
> > hw_breakpoint_handler() has completed execution, and a SIGSEGV is pending
> > to be delivered and single-stepping enabled MSR_SE is set. Upon return to
> > user-space, the handler for SIGSEGV is executed and it may perform one of
> > the following (as you stated previously):
> > (a) Make a blocking syscall, eventually yielding the CPU to a new thread
> > (b) Jump to a different instruction in user-space, say iN, and not complete
> > the execution of instruction i2 at all.
> > (c) Return to instruction i2 and complete the execution.
> > 
> > In case of (a), the context-switches should not affect the ability to
> > single-step the instruction when the thread is eventually scheduled to
> > run. The thread, when scheduled onto the CPU will complete signal
> > handling, return to execute instruction i2, cause single-step exception,
> > restore breakpoints and run smoothly thereafter.
> 
> Right.  However, the thread is running the signal handler without the
> DABR being set, which is unfortunate.
> 

In order to keep the breakpoint active during signal handling, a
PowerPC specific signal handling code, say do_signal_pending() in
arch/powerpc/kernel/signal.c, must be tapped to check for/restore
the breakpoint for the process (if it exists).

Then, single_step_dabr_instruction() must be suitably modified to not
clear the current->thread.last_hit_ubp pointer if breakpoint has been
taken in a nested condition i.e. a breakpoint exception in signal-handler
which was preceded by a previous breakpoint exception in normal user-space
stack. A flag to denote such a condition would be required in
'struct thread_struct'.

I'm afraid if this is more complexity than we want to handle in the
first patchset. I agree that this will create a 'blind-spot' of code
which cannot not be monitored using breakpoints and may limit debugging
efforts (specially for memory corruption); however suspecting that signal
handlers (especially those that don't return to original instruction)
would be rare, I feel that this could be a 'feature' that can be brought
later-in. What do you think?

> > In case

Re: [Patch 2/2] PPC64-HWBKPT: Implement hw-breakpoints for PPC64

2010-05-13 Thread K.Prasad
On Wed, May 12, 2010 at 04:32:47PM +1000, Paul Mackerras wrote:
> On Wed, May 05, 2010 at 02:03:03AM +0530, K.Prasad wrote:
> 
> > It is true that the breakpoint exceptions will go amiss following the
> > alignment exception, and be restored when the thread single-steps due
> > to other requests causing undesirable effects. (Borrowing from some of
> > the discussions I had with BenH, earlier) There can be two ways of
> > changing the implementation to counter it:
> > 
> > - To sense that the impending exception (alignment, page-fault,
> >   single-step) is a successor to a hw-breakpoint exception (and that
> >   restoration of debug register values is necessary), somewhere early in
> >   exceptions-64s.S and jump to a common handler, say
> >   do_single_step_dabr() which does a majority of
> >   single_step_dabr_instruction().
> > - To modify emulate_single_step() to also do a notify_die(DIE_SSTEP,...)
> >   in addition to its existing code. This would invoke
> >   single_step_dabr_instruction() where the breakpoints can be restored.
> 
> I thought you would change the explicit regs->msr modification in
> single_step_exception() to clear_single_step(), then just make
> emulate_single_step() call single_step_exception().
>

Okay. I will re-use single_step_exception() after modifications; it
appearsto have no in-kernel users for it. (single_step_exception() clears
MSR more than what clear_single_step() does, it shouldn't matter though).

> > I must admit that it is not clear to me when you say "doesn't return to
> > the instruction" and "instruction has been changed underneath". Are you
> 
> Suppose the address at which the data breakpoint has been unmapped,
> and the process has a handler for the SIGSEGV signal.  When we try to
> single-step the load or store, we will get a DSI (0x300) interrupt,
> call into do_page_fault, and end up sending the process a SIGSEGV.
> That will invoke the signal handler, which can then do anything it
> likes.  It can do a blocking system call, it can longjmp() back into
> its main event, or it can return from the signal handler.  Only in the
> last case will it retry the load or store, and then only if the signal
> handler hasn't modified the NIP value in the signal frame.  That's
> what I mean by "doesn't return to the instruction".
> 

At the outset, this seemed to be a scary thing to happen; but turns out
to be harmful only to the extent of generating a false hw-breakpoint
exception in certain cases. A case-by-case basis analysis reveals thus:

Consider an instruction stream i1, i2, i3, ... iN, where i1 has
finished execution and i2 is about to be executed but has generated a
DSI interrupt with the above-mentioned conditions i.e. DSISR indicates a
DABR match + Page-Table entry not found. Now according to do_hash_page
in exception-64s.S (as pasted below), do_page_fault() and do_dabr() are
invoked one after the other.

_STATIC(do_hash_page)
std r3,_DAR(r1)
std r4,_DSISR(r1)

andis.  r0,r4,0xa410/* weird error? */
bne-handle_page_fault   /* if not, try to insert a HPTE */
andis.  r0,r4,dsisr_dabrma...@h
bne-handle_dabr_fault

Thus, when control returns to user-space to instruction 'i2', the
hw_breakpoint_handler() has completed execution, and a SIGSEGV is pending
to be delivered and single-stepping enabled MSR_SE is set. Upon return to
user-space, the handler for SIGSEGV is executed and it may perform one of
the following (as you stated previously):
(a) Make a blocking syscall, eventually yielding the CPU to a new thread
(b) Jump to a different instruction in user-space, say iN, and not complete
the execution of instruction i2 at all.
(c) Return to instruction i2 and complete the execution.

In case of (a), the context-switches should not affect the ability to
single-step the instruction when the thread is eventually scheduled to
run. The thread, when scheduled onto the CPU will complete signal
handling, return to execute instruction i2, cause single-step exception,
restore breakpoints and run smoothly thereafter.

In case of (b), the new instruction iN is single-stepped, the breakpoint
values are restored and the hw-breakpoint exception callback is invoked
after iN is executed. The user of this breakpoint i.e. the caller of
register_user_hw_breakpoint() who had placed a breakpoint on addressed
accessed by instruction i2 will be confused to find that an unrelated
instruction (which may not be a load/store) has caused the breakpoint.

If so desired, we may adopt the 'trigger-before-execute' semantics for
user-space breakpoints wherein the hw-breakpoint callback (through
perf_bp_event()) is invoked in hw_breakpoint_handler() itself. This
would indicate to the us

Re: [Patch 2/2] PPC64-HWBKPT: Implement hw-breakpoints for PPC64

2010-05-11 Thread K.Prasad
On Wed, May 05, 2010 at 02:03:03AM +0530, K.Prasad wrote:
> On Mon, May 03, 2010 at 04:23:30PM +1000, Paul Mackerras wrote:
> > On Wed, Apr 14, 2010 at 09:18:27AM +0530, K.Prasad wrote:
> > 
[snipped]
> 
> It has been pointed out to me before (Roland's mail Ref:linuxppc-dev
> message-id: 20100119100335.3eb62...@magilla.sf.frob.com) that there will
> be too many corner cases that will be difficult to foresee, however your
> above list appears to be exhaustive. While the alternatives to this being
> a fallback to one-shot breakpoints (thereby leading to confusing
> hw-breakpoint interface semantics), this is an attempt to generate
> continuous and 'trigger-after-execute' (for non-ptrace requests)
> breakpoint exceptions. I believe that, with the addressal of concerns
> cited above, the resultant patchset would be one that achieves the
> stated design goals with no loss to existing functionality.
> 

Hi Paul,

> I intend to send out another version of this patchset with fixes as
> described in my replies above (unless I hear objections to it :-)).
> 

Meanwhile, a little sickness had kept me away from working on this
patchset. I have now posted a new version of the same here () which
contains changes as described above.

A few more changes to the patch is impending post merger
of Frederic's patches (which are now in -tip) into mainline (ref: commit
73266fc1df2f94cf72b3beba3eee3b88ed0b0664 to
777d0411cd1e384115985dac5ccd42031e3eee2b);
mainly due to the new ability for a per-task breakpoint to request
kernel-space breakpoints (the notion of kernel- vs user-bp would also
become obsolete, it is better to call them per-cpu vs per-task
breakpoints).

Also, I find that possibility of a kernel-thread specific breakpoint
(which can migrate across CPUs) has not been thought and implemented well
in this patch (will be much easier after merger of Frederic's patch). I
would prefer to have atleast some version of the patch included in
mainline before bringing in support for the same.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 3/3] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC Book III S

2010-05-11 Thread K.Prasad
Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
processors. These interfaces help arbitrate requests from various users and
schedules them as appropriate.

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig |1 
 arch/powerpc/include/asm/cputable.h  |4 
 arch/powerpc/include/asm/hw_breakpoint.h |   45 +++
 arch/powerpc/include/asm/processor.h |8 
 arch/powerpc/kernel/Makefile |1 
 arch/powerpc/kernel/hw_breakpoint.c  |  354 +++
 arch/powerpc/kernel/machine_kexec_64.c   |3 
 arch/powerpc/kernel/process.c|6 
 arch/powerpc/kernel/ptrace.c |   64 +
 arch/powerpc/kernel/traps.c  |3 
 arch/powerpc/lib/Makefile|1 
 include/linux/hw_breakpoint.h|1 
 12 files changed, 491 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,45 @@
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+   u8  len; /* length of the target data symbol */
+   int type;
+   unsigned long   address;
+};
+
+#include 
+#include 
+#include 
+
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_bp_generic_fields(int type, int *gen_bp_type);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
+   struct task_struct *tsk);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+   struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+   set_dabr(0);
+}
+
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,354 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2009 IBM Corporation
+ * Author: K.Prasad 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/*
+ * Store the 'bp' that caused the hw-breakpoint exception just before we
+ * single-step. Use it to distinguish a single-step exception (due to a
+ * previous hw-breakpoint exception) from a normal one
+ */
+static DEFINE_PER_CPU(struct perf_event *, last_hit_bp);
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+   struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+   struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+   *slot = bp;
+   set_dabr(info->address | info->type | DABR_TRANSLATION);
+   return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the g

[Patch 2/3] Allow arch-specific cleanup before breakpoint unregistration

2010-05-11 Thread K.Prasad
Certain architectures (such as PowerPC Book III S) have a need to cleanup
data-structures before the breakpoint is unregistered. This patch introduces
an arch-specific hook in release_bp_slot() along with a weak definition in
the form of a stub funciton.

Signed-off-by: K.Prasad 
---
 kernel/hw_breakpoint.c |   12 
 1 file changed, 12 insertions(+)

Index: linux-2.6.ppc64_test/kernel/hw_breakpoint.c
===
--- linux-2.6.ppc64_test.orig/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/kernel/hw_breakpoint.c
@@ -203,6 +203,17 @@ static void toggle_bp_slot(struct perf_e
 }
 
 /*
+ * Function to perform processor-specific cleanup during unregistration
+ */
+__weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+   /*
+* A weak stub function here for those archs that don't define
+* it inside arch/.../kernel/hw_breakpoint.c
+*/
+}
+
+/*
  * Contraints to check before allowing this new breakpoint counter:
  *
  *  == Non-pinned counter == (Considered as pinned for now)
@@ -280,6 +291,7 @@ void release_bp_slot(struct perf_event *
 {
mutex_lock(&nr_bp_mutex);
 
+   arch_unregister_hw_breakpoint(bp);
__release_bp_slot(bp);
 
mutex_unlock(&nr_bp_mutex);

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 1/3] PPC64-HWBKPT: Disable interrupts for data breakpoint exceptions

2010-05-11 Thread K.Prasad
Data address breakpoint exceptions are currently handled along with page-faults
which require interrupts to remain in enabled state. Since exception handling
for data breakpoints aren't pre-empt safe, we handle them separately.

Signed-off-by: K.Prasad 
Acked-by: Paul Mackerras 
---
 arch/powerpc/kernel/exceptions-64s.S |   13 -
 arch/powerpc/mm/fault.c  |5 +++--
 2 files changed, 15 insertions(+), 3 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/exceptions-64s.S
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
@@ -735,8 +735,11 @@ _STATIC(do_hash_page)
std r3,_DAR(r1)
std r4,_DSISR(r1)
 
-   andis.  r0,r4,0xa450/* weird error? */
+   andis.  r0,r4,0xa410/* weird error? */
bne-handle_page_fault   /* if not, try to insert a HPTE */
+   andis.  r0,r4,dsisr_dabrma...@h
+   bne-handle_dabr_fault
+
 BEGIN_FTR_SECTION
andis.  r0,r4,0x0020/* Is it a segment table fault? */
bne-do_ste_alloc/* If so handle it */
@@ -823,6 +826,14 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
bl  .raw_local_irq_restore
b   11f
 
+/* We have a data breakpoint exception - handle it */
+handle_dabr_fault:
+   ld  r4,_DAR(r1)
+   ld  r5,_DSISR(r1)
+   addir3,r1,STACK_FRAME_OVERHEAD
+   bl  .do_dabr
+   b   .ret_from_except_lite
+
 /* Here we have a page fault that hash_page can't handle. */
 handle_page_fault:
ENABLE_INTS
Index: linux-2.6.ppc64_test/arch/powerpc/mm/fault.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/mm/fault.c
+++ linux-2.6.ppc64_test/arch/powerpc/mm/fault.c
@@ -151,13 +151,14 @@ int __kprobes do_page_fault(struct pt_re
if (!user_mode(regs) && (address >= TASK_SIZE))
return SIGSEGV;
 
-#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \
+defined(CONFIG_PPC_BOOK3S_64))
if (error_code & DSISR_DABRMATCH) {
/* DABR match */
do_dabr(regs, address, error_code);
return 0;
}
-#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
+#endif
 
if (in_atomic() || mm == NULL) {
if (!user_mode(regs))

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 0/3] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XVIII

2010-05-11 Thread K.Prasad
Hi Ben/Paul,
Please find a new version of the patchset that implements hw-breakpoint
interfaces for PowerPC Book III S. The changes in this version over the previous
version are as listed below, and are the result of addressing comments 
received for the previous version.

Changelog - ver XVIII

(Version XVII: linuxppc-dev ref: 20100414034340.ga6...@in.ibm.com)
- hw-breakpoint restoration variables are cleaned-up before unregistration
  through a new function hook arch_unregister_hw_breakpoint().
- emulate_single_step() now notifies DIE_SSTEP to registered handlers;
  causes single_step_dabr_instruction() to be invoked after alignment_exception.
- SIGTRAP is no longer generated for non-ptrace user-space breakpoints.
- Slight code restructuring for brevity and style corrections.

Kindly accept them to be a part of -next tree.

Thanks,
K.Prasad

Changelog - ver XVII

(Version XVI: linuxppc-dev ref: 20100330095809.ga14...@in.ibm.com)
- CONFIG_HAVE_HW_BREAKPOINT is now used to define the scope of the new code
  (in lieu of CONFIG_PPC_BOOK3S_64).
- CONFIG_HAVE_HW_BREAKPOINT is now dependant upon CONFIG_PERF_EVENTS and
  CONFIG_PPC_BOOK3S_64 (to overcome build failures under certain configs).
- Included a target in arch/powerpc/lib/Makefile to build sstep.o when
  HAVE_HW_BREAKPOINT.
- Added a dummy definition for hw_breakpoint_disable() when !HAVE_HW_BREAKPOINT.
- Tested builds under defconfigs for ppc64, cell and g5 (found no patch induced
  failures).

Changelog - ver XVI

(Version XV: linuxppc-dev ref: 20100323140639.ga21...@in.ibm.com)
- Used a new config option CONFIG_PPC_BOOK3S_64 (in lieu of
  CONFIG_PPC64/CPU_FTR_HAS_DABR) to limit the scope of the new code.
- Disabled breakpoints before kexec of the machine using 
hw_breakpoint_disable().
- Minor optimisation in exception-64s.S to check for data breakpoint exceptions
  in DSISR finally (after check for other causes) + changes in code comments 
and 
  representation of DSISR_DABRMATCH constant.
- Rebased to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6.

Changelog - ver XV

(Version XIV: linuxppc-dev ref: 20100308181232.ga3...@in.ibm.com)

- Additional patch to disable interrupts during data breakpoint exception
  handling.
- Moved HBP_NUM definition to cputable.h under a new CPU_FTR definition
  (CPU_FTR_HAS_DABR).
- Filtering of extraneous exceptions (due to accesses outside symbol length) is
  by-passed for ptrace requests.
- Removed flush_ptrace_hw_breakpoint() from __switch_to() due to incorrect
  coding placement.
- Changes to code comments as per community reviews for previous version.
- Minor coding-style changes in hw_breakpoint.c as per review comments.
- Re-based to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6

Changelog - ver XIV

(Version XIII: linuxppc-dev ref: 20100215055605.gb3...@in.ibm.com)

- Removed the 'name' field from 'struct arch_hw_breakpoint'.
- All callback invocations through bp->overflow_handler() are replaced with
  perf_bp_event().
- Removed the check for pre-existing single-stepping mode in
  hw_breakpoint_handler() as this check is unreliable while in kernel-space.
  Side effect of this change is the non-triggering of hw-breakpoints while
  single-stepping kernel through KGDB or Xmon.
- Minor code-cleanups and addition of comments in hw_breakpoint_handler() and
  single_step_dabr_instruction().
- Re-based to commit 25cf84cf377c0aae5dbcf937ea89bc7893db5176 of linux-2.6

Changelog - ver XIII

(Version XII: linuxppc-dev ref: 20100121084640.ga3...@in.ibm.com)

- Fixed a bug for user-space breakpoints (triggered following the failure of a
  breakpoint request).
- Re-based on commit 724e6d3fe8003c3f60bf404bf22e4e331327c596 of linux-2.6
  
Changelog - ver XII

(Version XI: linuxppc-dev ref: 20100119091234.ga9...@in.ibm.com)

- Unset MSR_SE only if kernel was not previously in single-step mode.
- Pre-emption is now enabled before returning from the hw-breakpoint exception
  handler.
- Variables to track the source of single-step exception (breakpoint from 
kernel,
  user-space vs single-stepping due to other requests) are added.
- Extraneous hw-breakpoint exceptions (due to memory accesses lying outside
  monitored symbol length) is now done for both kernel and user-space
  (previously only user-space).
- single_step_dabr_instruction() now returns NOTIFY_DONE if kernel was in
  single-step mode even before the hw-breakpoint. This enables other users of
  single-step mode to be notified of the exception.
- User-space instructions are not emulated from kernel-space, they are instead
  single-stepped.
  
Changelog - ver XI
--
(Version X: linuxppc-dev ref: 20091211160144.ga23...@in.ibm.com)
- Conditionally unset MSR_SE in the single-step handler
- Added comments to explain the duration and need for pre-empti

Re: [Patch 2/2] PPC64-HWBKPT: Implement hw-breakpoints for PPC64

2010-05-04 Thread K.Prasad
On Mon, May 03, 2010 at 04:23:30PM +1000, Paul Mackerras wrote:
> On Wed, Apr 14, 2010 at 09:18:27AM +0530, K.Prasad wrote:
> 
> > Implement perf-events based hw-breakpoint interfaces for PPC64 processors.
> > These interfaces help arbitrate requests from various users and schedules
> > them as appropriate.
> 
> [snip]
> 

Hi Paul,
Thanks for the detailed review. Please find my replies inline.

> > --- /dev/null
> > +++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
> > @@ -0,0 +1,45 @@
> > +#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
> > +#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
> > +
> > +#ifdef __KERNEL__
> > +#define__ARCH_HW_BREAKPOINT_H
> 
> This symbol doesn't seem to be referenced anywhere.  Is it really
> necessary to define it?  I know x86 and sh do, but maybe it's a
> leftover there.
> 

Yes, either I use _PPC_BOOK3S_64_HW_BREAKPOINT_H or
__ARCH_HW_BREAKPOINT_H to prevent recursive definitions, not both. I will
remove __ARCH_HW_BREAKPOINT_H.

> > ===
> > --- /dev/null
> > +++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
> 
> > +   switch (bp->attr.bp_type) {
> > +   case HW_BREAKPOINT_R:
> > +   info->type = DABR_DATA_READ;
> > +   break;
> > +   case HW_BREAKPOINT_W:
> > +   info->type = DABR_DATA_WRITE;
> > +   break;
> > +   case HW_BREAKPOINT_R | HW_BREAKPOINT_W:
> > +   info->type = (DABR_DATA_READ | DABR_DATA_WRITE);
> > +   break;
> > +   default:
> > +   return ret;
> > +   }
> 
> You have code like this in several places -- maybe this should be
> encapsulated in a helper function.  Also, I think it could be written
> more compactly.
> 

Actually this particular code-snippet differs slightly from two such
'similar' switch-cases found in ptrace_set_debugreg() - which I will
replace with a helper function. The above-cited switch-case statement
which maps the generic breakpoint types to arch-specific bit-encodings
are used only once (as above) and will not help code-reduction if moved
to a separate function.

> > +   /*
> > +* Return early after invoking user-callback function without restoring
> > +* DABR if the breakpoint is from ptrace which always operates in
> > +* one-shot mode
> > +*/
> > +   if (is_ptrace_bp == true) {
> > +   perf_bp_event(bp, regs);
> > +   rc = NOTIFY_DONE;
> > +   goto out;
> > +   }
> 
> As far as I can see, returning NOTIFY_DONE won't tell do_dabr() that
> you have handled the exception, and it will go on to do the
> debugger_dabr_match() call and generate a signal to the current
> process.  Is that what you want?  If so a comment would be useful.
> 

Yes, the debugger_dabr_match() will return early without doing much and
the signal is generated for the ptrace-ed process. I will append the
comment to appear as below:

/*
 * Return early after invoking user-callback function without restoring
 * DABR if the breakpoint is from ptrace which always operates in
 * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal
 * generated in do_dabr().
 */

> Also, the " == true" part is completely redundant.  Normal kernel
> style would be if (is_ptrace_bp) { ..., and similarly the
> (is_ptrace_bp == false) above should be !is_ptrace_bp.
>

It is an untidy habit that I've had, personally, for
increased readability! I will remove such redundancies from the code.

> > +
> > +   /*
> > +* Do not emulate user-space instructions from kernel-space,
> > +* instead single-step them.
> > +*/
> > +   if (is_kernel == false) {
> > +   current->thread.last_hit_ubp = bp;
> > +   regs->msr |= MSR_SE;
> > +   goto out;
> > +   }
> 
> I'm a bit worried about what could happen from here on.  We go back
> out to userspace and try to execute the load or store.  Besides
> executing successfully and taking the trace interrupt, there are
> several other possibilities:
>

The aim, during design time, has been to reliably restore the breakpoint
values immediately after execution of the instruction or in the
worst-case, to cause loss of breakpoints rather than ignore the other
sources of exceptions. Please find more responses below.
 
> - we could get an alignment interrupt
> - we could get a page fault (page not present or protection violation)
> - we could get a MMU hash table miss (unlikely since the low-level
>   code calls hash_page before do_dabr, but poss

[RFC Patch 1/1] Implement hw-breakpoint interfaces for BookE processors

2010-04-27 Thread K.Prasad
Implement hardware breakpoint interfaces for PowerPC BookE processors

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig   |2 
 arch/powerpc/include/asm/cputable.h|4 
 arch/powerpc/include/asm/hw_breakpoint_booke.h |   42 +++
 arch/powerpc/kernel/Makefile   |4 
 arch/powerpc/kernel/hw_breakpoint_booke.c  |  326 +
 arch/powerpc/kernel/ptrace.c   |8 
 arch/powerpc/kernel/traps.c|   11 
 include/linux/perf_event.h |4 
 8 files changed, 398 insertions(+), 3 deletions(-)

Index: linux-2.6.bookE/arch/powerpc/include/asm/hw_breakpoint_booke.h
===
--- /dev/null
+++ linux-2.6.bookE/arch/powerpc/include/asm/hw_breakpoint_booke.h
@@ -0,0 +1,42 @@
+#ifndef_I386_HW_BREAKPOINT_H
+#define_I386_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#define__ARCH_HW_BREAKPOINT_H
+
+struct arch_hw_breakpoint {
+   u8  len;
+   unsigned long   address;
+   unsigned long   type;
+};
+
+#include 
+#include 
+#include 
+
+/* Breakpoint length beyond which we should use 'range' breakpoints */
+#define DAC_LEN 8
+
+static inline int hw_breakpoint_slots(int type)
+{
+   return HBP_NUM;
+}
+
+struct perf_event;
+struct pmu;
+
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+extern void hw_breakpoint_handler(struct pt_regs *regs,
+   unsigned long debug_status);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+
+extern struct pmu perf_ops_bp;
+
+#endif /* __KERNEL__ */
+#endif /* _I386_HW_BREAKPOINT_H */
+
Index: linux-2.6.bookE/arch/powerpc/kernel/hw_breakpoint_booke.c
===
--- /dev/null
+++ linux-2.6.bookE/arch/powerpc/kernel/hw_breakpoint_booke.c
@@ -0,0 +1,326 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/*
+ * Store the 'bp' that caused the hw-breakpoint exception just before we
+ * single-step. Use it to distinguish a single-step exception (due to a
+ * previous hw-breakpoint exception) from a normal one
+ */
+static DEFINE_PER_CPU(struct perf_event *, last_hit_bp);
+
+/*
+ * Save the debug registers to restore them after single-stepping the
+ * instruction that caused the debug exception
+ */
+static DEFINE_PER_CPU(unsigned long, last_hit_dac[2]);
+static DEFINE_PER_CPU(unsigned long, last_hit_dbcr0);
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for each cpus
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
+
+int hw_breakpoint_weight(struct perf_event *bp)
+{
+   return (bp->attr.bp_len > DAC_LEN) ? 2 : 1;
+}
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint. Eventually we enable it in the debug control register.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+   bool range_bp;
+   int i;
+   struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+   unsigned long dbcr0 = mfspr(SPRN_DBCR0);
+
+   range_bp = (info->len > DAC_LEN) ? true : false;
+   for (i = 0; i < HBP_NUM; i++) {
+   struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
+
+   if (*slot)
+   continue;
+   *slot = bp;
+   mtspr(SPRN_DAC1, info->address);
+   /* Clean the 'type' fields to erase past values */
+   dbcr0 &= ~(DBCR0_DAC2W | DBCR0_DAC2R);
+
+   mtspr(SPRN_DBCR0, dbcr0 |
+   (info->type << (HBP_NUM - i)) | DBCR0_IDM);
+   /*
+* Use DAC2 register in 'range' mode if the length of the
+* breakpoint request is 'large'
+*/
+   if (unlikely(range_bp)) {
+   if (i > (HBP_NUM - hw_breakpoint_weight(bp))) {
+   *slot = NULL;
+   mtspr(SPRN_DBCR0, dbcr0);
+   return -EBUSY;
+   }
+   (*slot)++;
+   i++;
+   /*
+* In 'range' m

[RFC Patch 0/1] [hw-bkpt BookE] hw-breakpoint interfaces for BookE - ver I

2010-04-27 Thread K.Prasad
Hi All,
Please find a patch that implements hardware-breakpoint interfaces for
BookE processors. The patches are under continuous development and are sent
to receive early comments. For the moment, they are (only) compile tested (with
ppc64e_defconfig), further testing will accompany the ongoing development.

A few notes about the patchset, as below:
- The patch is designed with reference to BookIII-E type processors
  specification (having two DAC/DVC registers).
- Instruction breakpoint requests are not implemented through the generic
  breakpoint interfaces. Such requests are still possible for user-space 
through 
  ptrace.
- Breakpoint exceptions are designed to 'trigger-after-execute', although the
  processors raise the exception before instruction execution. To achieve this,
  the causative insruction is single-stepped over and the breakpoint handler is 
  invoked in the ICMP exception handler.
- The patches are dependant on the recent submissions (not yet integrated into
  mainline) that bring support for hw-breakpoint weight (patchset from Frederic
  Weisbecker LKML ref:1271999639-23605-1-git-send-regression-fweis...@gmail.com)
  and PPC64 hw-breakpoint support (linuxppc-dev
  ref:20100414034340.ga6...@in.ibm.com).

Here are a few items identified to work upon in the successive versions.
TO DO
--
- Modify ptrace requests to use the generic hw-breakpoint interfaces 
 (PTRACE__DEBUGREG, PTRACE_SETHWDEBUG)
- Explore intergration of BookE and BookS code intergration 
 (hw_breakpoint.c and hw_breakpoint_booke.c) 
- Code clean-up and reduction.

Kindly let me know about comments/suggestions, if any.

Thank You,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch 1/1] PPC64-HWBKPT: Implement hw-breakpoints for PPC64

2010-04-13 Thread K.Prasad
On Wed, Apr 07, 2010 at 06:03:31PM +1000, Benjamin Herrenschmidt wrote:
> Ok so too many problems with your last patch, I didn't have time to fix
> them all, so it's not going into -next this week.
> 
> Please, test with a variety of defconfigs (iseries, cell, g5 for
> example), and especially with CONFIG_PERF_EVENTS not set. There are
> issues in the generic header for that (though I'm told some people are
> working on a fix).
> 
> Basically, we need something like CONFIG_HW_BREAKPOINTS that is set
> (maybe optionally, maybe not) with CONFIG_PERF_EVENTS and
> CONFIG_HAVE_HW_BREAKPOINT. Then you can use that to properly fix the
> ifdef'ing in include/linux/hw_breakpoints.h, and fix the various other
> cases in powerpc code where you are testing for the wrong thing.
> 
> Cheers,
> Ben.
>

Hi Ben,
I've sent a new patch (linuxppc-dev message-id ref:
20100414034340.ga6...@in.ibm.com) that builds against the defconfigs for
various architectures pointed out by you (I did see quite a few errors
that aren't induced by the patch).

The source tree is buildable even without CONFIG_PERF_EVENTS, and is
limited to scope using CONFIG_HAVE_HW_BREAKPOINT. At this stage, I
didnot find a need for a seperate CONFIG_HW_BREAKPOINTS though.

Let me know what you think.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 2/2] PPC64-HWBKPT: Implement hw-breakpoints for PPC64

2010-04-13 Thread K.Prasad
Implement perf-events based hw-breakpoint interfaces for PPC64 processors.
These interfaces help arbitrate requests from various users and schedules
them as appropriate.

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig |1 
 arch/powerpc/include/asm/cputable.h  |4 
 arch/powerpc/include/asm/hw_breakpoint.h |   45 
 arch/powerpc/include/asm/processor.h |8 
 arch/powerpc/kernel/Makefile |1 
 arch/powerpc/kernel/hw_breakpoint.c  |  324 +++
 arch/powerpc/kernel/machine_kexec_64.c   |3 
 arch/powerpc/kernel/process.c|6 
 arch/powerpc/kernel/ptrace.c |   81 +++
 arch/powerpc/lib/Makefile|1 
 include/linux/hw_breakpoint.h|1 
 11 files changed, 475 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,45 @@
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#define__ARCH_HW_BREAKPOINT_H
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+   u8  len; /* length of the target data symbol */
+   int type;
+   unsigned long   address;
+};
+
+#include 
+#include 
+#include 
+
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
+   struct task_struct *tsk);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+   struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+   set_dabr(0);
+}
+
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,324 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2009 IBM Corporation
+ * Author: K.Prasad 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/*
+ * Store the 'bp' that caused the hw-breakpoint exception just before we
+ * single-step. Use it to distinguish a single-step exception (due to a
+ * previous hw-breakpoint exception) from a normal one
+ */
+static DEFINE_PER_CPU(struct perf_event *, last_hit_bp);
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+   struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+   struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+   *slot = bp;
+   set_dabr(info->address | info->type | DABR_TRANSLATION);
+   return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the given counter.
+ *
+ * First we search the debug address register it uses and then w

[Patch 1/2] PPC64-HWBKPT: Disable interrupts for data breakpoint exceptions

2010-04-13 Thread K.Prasad
Data address breakpoint exceptions are currently handled along with page-faults
which require interrupts to remain in enabled state. Since exception handling
for data breakpoints aren't pre-empt safe, we handle them separately.

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/exceptions-64s.S |   13 -
 arch/powerpc/mm/fault.c  |5 +++--
 2 files changed, 15 insertions(+), 3 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/exceptions-64s.S
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
@@ -735,8 +735,11 @@ _STATIC(do_hash_page)
std r3,_DAR(r1)
std r4,_DSISR(r1)
 
-   andis.  r0,r4,0xa450/* weird error? */
+   andis.  r0,r4,0xa410/* weird error? */
bne-handle_page_fault   /* if not, try to insert a HPTE */
+   andis.  r0,r4,dsisr_dabrma...@h
+   bne-handle_dabr_fault
+
 BEGIN_FTR_SECTION
andis.  r0,r4,0x0020/* Is it a segment table fault? */
bne-do_ste_alloc/* If so handle it */
@@ -823,6 +826,14 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
bl  .raw_local_irq_restore
b   11f
 
+/* We have a data breakpoint exception - handle it */
+handle_dabr_fault:
+   ld  r4,_DAR(r1)
+   ld  r5,_DSISR(r1)
+   addir3,r1,STACK_FRAME_OVERHEAD
+   bl  .do_dabr
+   b   .ret_from_except_lite
+
 /* Here we have a page fault that hash_page can't handle. */
 handle_page_fault:
ENABLE_INTS
Index: linux-2.6.ppc64_test/arch/powerpc/mm/fault.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/mm/fault.c
+++ linux-2.6.ppc64_test/arch/powerpc/mm/fault.c
@@ -151,13 +151,14 @@ int __kprobes do_page_fault(struct pt_re
if (!user_mode(regs) && (address >= TASK_SIZE))
return SIGSEGV;
 
-#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \
+defined(CONFIG_PPC_BOOK3S_64))
if (error_code & DSISR_DABRMATCH) {
/* DABR match */
do_dabr(regs, address, error_code);
return 0;
}
-#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
+#endif
 
if (in_atomic() || mm == NULL) {
if (!user_mode(regs))

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 0/2] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XVII

2010-04-13 Thread K.Prasad
Hi Ben,
Please find a new version of the patchset. It contains small, yet
significant number of changes to address the build issues you pointed out
(details of which are listed in the changelog below).

Changelog - ver XVII

(Version XVI: linuxppc-dev ref: 20100330095809.ga14...@in.ibm.com)
- CONFIG_HAVE_HW_BREAKPOINT is now used to define the scope of the new code
  (in lieu of CONFIG_PPC_BOOK3S_64).
- CONFIG_HAVE_HW_BREAKPOINT is now dependant upon CONFIG_PERF_EVENTS and
  CONFIG_PPC_BOOK3S_64 (to overcome build failures under certain configs).
- Included a target in arch/powerpc/lib/Makefile to build sstep.o when
  HAVE_HW_BREAKPOINT.
- Added a dummy definition for hw_breakpoint_disable() when !HAVE_HW_BREAKPOINT.
- Tested builds under defconfigs for ppc64, cell and g5. Found no patch
  induced failures.

Kindly accept them to be a part of -next tree.

Thanks,
K.Prasad


Changelog - ver XVI

(Version XV: linuxppc-dev ref: 20100323140639.ga21...@in.ibm.com)
- Used a new config option CONFIG_PPC_BOOK3S_64 (in lieu of
  CONFIG_PPC64/CPU_FTR_HAS_DABR) to limit the scope of the new code.
- Disabled breakpoints before kexec of the machine using 
hw_breakpoint_disable().
- Minor optimisation in exception-64s.S to check for data breakpoint exceptions
  in DSISR finally (after check for other causes) + changes in code comments 
and 
  representation of DSISR_DABRMATCH constant.
- Rebased to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6.

Changelog - ver XV

(Version XIV: linuxppc-dev ref: 20100308181232.ga3...@in.ibm.com)

- Additional patch to disable interrupts during data breakpoint exception
  handling.
- Moved HBP_NUM definition to cputable.h under a new CPU_FTR definition
  (CPU_FTR_HAS_DABR).
- Filtering of extraneous exceptions (due to accesses outside symbol length) is
  by-passed for ptrace requests.
- Removed flush_ptrace_hw_breakpoint() from __switch_to() due to incorrect
  coding placement.
- Changes to code comments as per community reviews for previous version.
- Minor coding-style changes in hw_breakpoint.c as per review comments.
- Re-based to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6

Changelog - ver XIV

(Version XIII: linuxppc-dev ref: 20100215055605.gb3...@in.ibm.com)

- Removed the 'name' field from 'struct arch_hw_breakpoint'.
- All callback invocations through bp->overflow_handler() are replaced with
  perf_bp_event().
- Removed the check for pre-existing single-stepping mode in
  hw_breakpoint_handler() as this check is unreliable while in kernel-space.
  Side effect of this change is the non-triggering of hw-breakpoints while
  single-stepping kernel through KGDB or Xmon.
- Minor code-cleanups and addition of comments in hw_breakpoint_handler() and
  single_step_dabr_instruction().
- Re-based to commit 25cf84cf377c0aae5dbcf937ea89bc7893db5176 of linux-2.6

Changelog - ver XIII

(Version XII: linuxppc-dev ref: 20100121084640.ga3...@in.ibm.com)

- Fixed a bug for user-space breakpoints (triggered following the failure of a
  breakpoint request).
- Re-based on commit 724e6d3fe8003c3f60bf404bf22e4e331327c596 of linux-2.6
  
Changelog - ver XII

(Version XI: linuxppc-dev ref: 20100119091234.ga9...@in.ibm.com)

- Unset MSR_SE only if kernel was not previously in single-step mode.
- Pre-emption is now enabled before returning from the hw-breakpoint exception
  handler.
- Variables to track the source of single-step exception (breakpoint from 
kernel,
  user-space vs single-stepping due to other requests) are added.
- Extraneous hw-breakpoint exceptions (due to memory accesses lying outside
  monitored symbol length) is now done for both kernel and user-space
  (previously only user-space).
- single_step_dabr_instruction() now returns NOTIFY_DONE if kernel was in
  single-step mode even before the hw-breakpoint. This enables other users of
  single-step mode to be notified of the exception.
- User-space instructions are not emulated from kernel-space, they are instead
  single-stepped.
  
Changelog - ver XI
--
(Version X: linuxppc-dev ref: 20091211160144.ga23...@in.ibm.com)
- Conditionally unset MSR_SE in the single-step handler
- Added comments to explain the duration and need for pre-emption
disable following hw-breakpoint exception.

Changelog - ver X
--
- Re-write the PPC64 patches for the new implementation of hw-breakpoints that
  uses the perf-layer.
- Rebased to commit 7622fc234190a37d4e9fe3ed944a2b61a63fca03 of -tip.

Changelog - ver IX
---
- Invocation of user-defined callback will be 'trigger-after-execute' (except
  for ptrace).
- Creation of a new global per-CPU breakpoint structure to help invocation of
  user-defined callback from single-step handler.
(Changes made now)
- Validation before registration will fail only if the address does no

Re: [RFC Patch 1/2] PPC64-HWBKPT: Disable interrupts for data breakpoint exceptions

2010-03-30 Thread K.Prasad
On Tue, Mar 30, 2010 at 04:32:25PM +1100, Benjamin Herrenschmidt wrote:
> On Tue, 2010-03-30 at 16:24 +1100, Paul Mackerras wrote:
> > On Tue, Mar 23, 2010 at 07:37:02PM +0530, K.Prasad wrote:
> > 
> > > Index: linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
> > > ===
> > > --- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/exceptions-64s.S
> > > +++ linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
> > > @@ -735,6 +735,9 @@ _STATIC(do_hash_page)
> > >   std r3,_DAR(r1)
> > >   std r4,_DSISR(r1)
> > >  
> > > + andis.  r0,r4,0x0040/* Data Address Breakpoint match? */
> > 
> > Minor comment: why not dsisr_dabrma...@h instead of 0x0040?
> > 
> > > + bne-handle_dabr_fault
> > > +
> > >   andis.  r0,r4,0xa450/* weird error? */
> > >   bne-handle_page_fault   /* if not, try to insert a HPTE */
> > >  BEGIN_FTR_SECTION
> > > @@ -823,6 +826,15 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
> > >   bl  .raw_local_irq_restore
> > >   b   11f
> 
> I would move your new test to the "weird error" case (ie, after the bne-
> handle_page_fault) to avoid hitting the fast path.
>

Done that...so basically the branch to handle_page_fault will happen
only if 0xa410 matches.

The changes can be seen here: linuxppc-dev: message-id:
20100330095925.gb14...@in.ibm.com.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [RFC Patch 1/2] PPC64-HWBKPT: Disable interrupts for data breakpoint exceptions

2010-03-30 Thread K.Prasad
On Tue, Mar 30, 2010 at 04:24:42PM +1100, Paul Mackerras wrote:
> On Tue, Mar 23, 2010 at 07:37:02PM +0530, K.Prasad wrote:
> 
> > Index: linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
> > ===
> > --- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/exceptions-64s.S
> > +++ linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
> > @@ -735,6 +735,9 @@ _STATIC(do_hash_page)
> > std r3,_DAR(r1)
> > std r4,_DSISR(r1)
> >  
> > +   andis.  r0,r4,0x0040/* Data Address Breakpoint match? */
> 
> Minor comment: why not dsisr_dabrma...@h instead of 0x0040?
>

Sure...I didn't realise that the upper 16-bits could be extracted as
shown aboveI've implemented the suggestion in the next version of
the patch sent here:
linuxppc-dev message-id:20100330095809.ga14...@in.ibm.com.

> > +   bne-handle_dabr_fault
> > +
> > andis.  r0,r4,0xa450/* weird error? */
> > bne-handle_page_fault   /* if not, try to insert a HPTE */
> >  BEGIN_FTR_SECTION
> > @@ -823,6 +826,15 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
> > bl  .raw_local_irq_restore
> > b   11f
> >  
> > +/* We have a data breakpoint exception - handle it */
> > +handle_dabr_fault:
> > +   /* Populate the pt_regs structure */
> 
> Another minor comment: that comment isn't accurate since you're not
> putting anything in the pt_regs, just getting arguments to do_dabr
> from it.
>

Thanks for pointing it out...it has been removed.

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [RFC Patch 2/2] PPC64-HWBKPT: Implement hw-breakpoints for PPC64

2010-03-30 Thread K.Prasad
On Mon, Mar 29, 2010 at 02:53:36PM -0500, Dave Kleikamp wrote:
> On Mon, 2010-03-29 at 17:01 +0530, K.Prasad wrote:
> > On Fri, Mar 26, 2010 at 04:11:45PM -0500, Dave Kleikamp wrote:
> > > On Tue, 2010-03-23 at 19:37 +0530, K.Prasad wrote:
> > > > plain text document attachment (ppc64_hbkpt_02)
> > > > Implement perf-events based hw-breakpoint interfaces for PPC64 
> > > > processors.
> > > > These interfaces help arbitrate requests from various users and 
> > > > schedules
> > > > them as appropriate.
> > > > 
> > > > Signed-off-by: K.Prasad 
> > > 
> > > SNIP
> > > 
> > > > Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/cputable.h
> > > > ===
> > > > --- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/cputable.h
> > > > +++ linux-2.6.ppc64_test/arch/powerpc/include/asm/cputable.h
> > > > @@ -511,6 +511,13 @@ static inline int cpu_has_feature(unsign
> > > > & feature);
> > > >  }
> > > > 
> > > > +#define CPU_FTR_HAS_DABR (defined(CONFIG_PPC64) && \
> > > > + !defined(CONFIG_PPC_ADV_DEBUG_REGS))
> > > > +#ifdef CPU_FTR_HAS_DABR
> > > > +/* Number of physical HW breakpoint registers */
> > > > +#define HBP_NUM 1
> > > > +#endif
> > > > +
> > > >  #endif /* !__ASSEMBLY__ */
> > > > 
> > > >  #endif /* __KERNEL__ */
> > > 
> > > These new defines don't really correlate to the cpu table.  One would
> > > expect cpu_has_feature(CPU_FTR_HAS_DABR) to have meaning, but it would
> > > have to be defined similar to the other CPU_FTR_ constants, and or-ed
> > > with CPU_FTRS_ALWAYS (when appropriate).
> > > 
> > 
[snipped] 
> > There are a few issues with such an approach:
> > i) Two such fields would be required in 'struct cpu_spec' - one for
> > instruction breakpoints and other for data.
> > ii) As pointed out by you below, hbp_num or num_hw_brkpts would always
> > be assigned to the compile time constant HBP_NUM (hence a variable is not
> > required to store it).
> > iii) HBP_NUM still cannot be entirely removed as it is used by generic
> > kernel/hw_breakpoint.c code (and is used by x86 code as well).
> > 
> > I think the simplest approach would be to have the following entry in
> > cputable.h (and get away with the rest of the additions seen in patch
> > ver XV)
> > 
> > #ifdef CONFIG_PPC_BOOK3S_64
> > #define HBP_NUM 1
> > #endif
> > 
> > The next version of the patch should contain changes to that effect
> > (assuming I hear no objections).
> 
> I just don't think this belongs in cputable.h.  Why not put this in
> hw_breakpoint.h?
>

HBP_NUM was originally defined in hw_breakpoint.h (until ver XIV) but 
was moved to cputable.h as it introduces a duplicate definition in 
processor.h (which is how it is done in the x86 implementation).
linux/hw_breakpoint.h inclusion in processor.h, to circumvent the
duplication leads to circular dependancies w.r.t. declarations.

I think leaving it in cputable.h (as in version XVI of the patch sent 
here: message-id:20100330095809.ga14...@in.ibm.com) gives us a much
cleaner implementation (than x86 which has duplicate HBP_NUM definitions).

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 2/2] PPC64-HWBKPT: Implement hw-breakpoints for PPC64

2010-03-30 Thread K.Prasad
Implement perf-events based hw-breakpoint interfaces for PPC64 processors.
These interfaces help arbitrate requests from various users and schedules
them as appropriate.

Signed-off-by: K.Prasad 
---
 arch/powerpc/Kconfig |1 
 arch/powerpc/include/asm/cputable.h  |4 
 arch/powerpc/include/asm/hw_breakpoint.h |   50 
 arch/powerpc/include/asm/processor.h |8 
 arch/powerpc/kernel/Makefile |1 
 arch/powerpc/kernel/hw_breakpoint.c  |  324 +++
 arch/powerpc/kernel/machine_kexec_64.c   |3 
 arch/powerpc/kernel/process.c|6 
 arch/powerpc/kernel/ptrace.c |   81 +++
 9 files changed, 478 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,50 @@
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#define__ARCH_HW_BREAKPOINT_H
+#ifdef CONFIG_PPC_BOOK3S_64
+
+struct arch_hw_breakpoint {
+   u8  len; /* length of the target data symbol */
+   int type;
+   unsigned long   address;
+};
+
+#include 
+#include 
+#include 
+
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
+   struct task_struct *tsk);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+   unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+   struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+   set_dabr(0);
+}
+
+#else
+static inline void hw_breakpoint_disable(void)
+{
+   /* Function is defined only on PPC_BOOK3S_64 for now */
+}
+#endif /* CONFIG_PPC_BOOK3S_64 */
+#endif /* __KERNEL__ */
+#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,324 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2009 IBM Corporation
+ * Author: K.Prasad 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/*
+ * Store the 'bp' that caused the hw-breakpoint exception just before we
+ * single-step. Use it to distinguish a single-step exception (due to a
+ * previous hw-breakpoint exception) from a normal one
+ */
+static DEFINE_PER_CPU(struct perf_event *, last_hit_bp);
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+   struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+   struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+   *slot = bp;
+   set_dabr(info->address | info->type | DABR_TRANSLATION);
+   return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the given counter.
+ *
+ * First we search the debug address re

[Patch 1/2] PPC64-HWBKPT: Disable interrupts for data breakpoint exceptions

2010-03-30 Thread K.Prasad
Data address breakpoint exceptions are currently handled along with page-faults
which require interrupts to remain in enabled state. Since exception handling
for data breakpoints aren't pre-empt safe, we handle them separately.

Signed-off-by: K.Prasad 
---
 arch/powerpc/kernel/exceptions-64s.S |   13 -
 arch/powerpc/mm/fault.c  |5 +++--
 2 files changed, 15 insertions(+), 3 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/exceptions-64s.S
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
@@ -735,8 +735,11 @@ _STATIC(do_hash_page)
std r3,_DAR(r1)
std r4,_DSISR(r1)
 
-   andis.  r0,r4,0xa450/* weird error? */
+   andis.  r0,r4,0xa410/* weird error? */
bne-handle_page_fault   /* if not, try to insert a HPTE */
+   andis.  r0,r4,dsisr_dabrma...@h
+   bne-handle_dabr_fault
+
 BEGIN_FTR_SECTION
andis.  r0,r4,0x0020/* Is it a segment table fault? */
bne-do_ste_alloc/* If so handle it */
@@ -823,6 +826,14 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
bl  .raw_local_irq_restore
b   11f
 
+/* We have a data breakpoint exception - handle it */
+handle_dabr_fault:
+   ld  r4,_DAR(r1)
+   ld  r5,_DSISR(r1)
+   addir3,r1,STACK_FRAME_OVERHEAD
+   bl  .do_dabr
+   b   .ret_from_except_lite
+
 /* Here we have a page fault that hash_page can't handle. */
 handle_page_fault:
ENABLE_INTS
Index: linux-2.6.ppc64_test/arch/powerpc/mm/fault.c
===
--- linux-2.6.ppc64_test.orig/arch/powerpc/mm/fault.c
+++ linux-2.6.ppc64_test/arch/powerpc/mm/fault.c
@@ -151,13 +151,14 @@ int __kprobes do_page_fault(struct pt_re
if (!user_mode(regs) && (address >= TASK_SIZE))
return SIGSEGV;
 
-#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \
+defined(CONFIG_PPC_BOOK3S_64))
if (error_code & DSISR_DABRMATCH) {
/* DABR match */
do_dabr(regs, address, error_code);
return 0;
}
-#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
+#endif
 
if (in_atomic() || mm == NULL) {
if (!user_mode(regs))

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Patch 0/2] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XVI

2010-03-30 Thread K.Prasad
Hi All,
Please find the version XVI of the patches that implement
hardware-breakpoint interfaces for PPC64 Server machines (with one DABR).
The changes over the previous version are as listed below.

Changelog - ver XVI

(Version XV: linuxppc-dev ref: 20100323140639.ga21...@in.ibm.com)
- Used a new config option CONFIG_PPC_BOOK3S_64 (in lieu of
  CONFIG_PPC64/CPU_FTR_HAS_DABR) to limit the scope of the new code.
- Disabled breakpoints before kexec of the machine using 
hw_breakpoint_disable().
- Minor optimisation in exception-64s.S to check for data breakpoint exceptions
  in DSISR finally (after check for other causes) + changes in code comments 
and 
  representation of DSISR_DABRMATCH constant.
- Rebased to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6.

Let me know if you have any comments.

Thanks,
K.Prasad


Changelog - ver XV

(Version XIV: linuxppc-dev ref: 20100308181232.ga3...@in.ibm.com)

- Additional patch to disable interrupts during data breakpoint exception
  handling.
- Moved HBP_NUM definition to cputable.h under a new CPU_FTR definition
  (CPU_FTR_HAS_DABR).
- Filtering of extraneous exceptions (due to accesses outside symbol length) is
  by-passed for ptrace requests.
- Removed flush_ptrace_hw_breakpoint() from __switch_to() due to incorrect
  coding placement.
- Changes to code comments as per community reviews for previous version.
- Minor coding-style changes in hw_breakpoint.c as per review comments.
- Re-based to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6

Changelog - ver XIV

(Version XIII: linuxppc-dev ref: 20100215055605.gb3...@in.ibm.com)

- Removed the 'name' field from 'struct arch_hw_breakpoint'.
- All callback invocations through bp->overflow_handler() are replaced with
  perf_bp_event().
- Removed the check for pre-existing single-stepping mode in
  hw_breakpoint_handler() as this check is unreliable while in kernel-space.
  Side effect of this change is the non-triggering of hw-breakpoints while
  single-stepping kernel through KGDB or Xmon.
- Minor code-cleanups and addition of comments in hw_breakpoint_handler() and
  single_step_dabr_instruction().
- Re-based to commit 25cf84cf377c0aae5dbcf937ea89bc7893db5176 of linux-2.6

Changelog - ver XIII

(Version XII: linuxppc-dev ref: 20100121084640.ga3...@in.ibm.com)

- Fixed a bug for user-space breakpoints (triggered following the failure of a
  breakpoint request).
- Re-based on commit 724e6d3fe8003c3f60bf404bf22e4e331327c596 of linux-2.6
  
Changelog - ver XII

(Version XI: linuxppc-dev ref: 20100119091234.ga9...@in.ibm.com)

- Unset MSR_SE only if kernel was not previously in single-step mode.
- Pre-emption is now enabled before returning from the hw-breakpoint exception
  handler.
- Variables to track the source of single-step exception (breakpoint from 
kernel,
  user-space vs single-stepping due to other requests) are added.
- Extraneous hw-breakpoint exceptions (due to memory accesses lying outside
  monitored symbol length) is now done for both kernel and user-space
  (previously only user-space).
- single_step_dabr_instruction() now returns NOTIFY_DONE if kernel was in
  single-step mode even before the hw-breakpoint. This enables other users of
  single-step mode to be notified of the exception.
- User-space instructions are not emulated from kernel-space, they are instead
  single-stepped.
  
Changelog - ver XI
--
(Version X: linuxppc-dev ref: 20091211160144.ga23...@in.ibm.com)
- Conditionally unset MSR_SE in the single-step handler
- Added comments to explain the duration and need for pre-emption
disable following hw-breakpoint exception.

Changelog - ver X
--
- Re-write the PPC64 patches for the new implementation of hw-breakpoints that
  uses the perf-layer.
- Rebased to commit 7622fc234190a37d4e9fe3ed944a2b61a63fca03 of -tip.

Changelog - ver IX
---
- Invocation of user-defined callback will be 'trigger-after-execute' (except
  for ptrace).
- Creation of a new global per-CPU breakpoint structure to help invocation of
  user-defined callback from single-step handler.
(Changes made now)
- Validation before registration will fail only if the address does not match
  the kernel symbol's (if specified) resolved address
  (through kallsyms_lookup_name()).
- 'symbolsize' value is expected to within the range contained by the symbol's
  starting address and the end of a double-word boundary (8 Bytes).
- PPC64's arch-dependant code is now aware of 'cpumask' in 'struct 
hw_breakpoint'
  and can accomodate requests for a subset of CPUs in the system.
- Introduced arch_disable_hw_breakpoint() required for
  _hw_breakpoint() APIs.

Changelog - ver VIII
---
- Reverting changes to allow one-shot breakpoints only for ptrace requests.
- Minor chang

Re: [RFC Patch 2/2] PPC64-HWBKPT: Implement hw-breakpoints for PPC64

2010-03-29 Thread K.Prasad
On Fri, Mar 26, 2010 at 04:11:45PM -0500, Dave Kleikamp wrote:
> On Tue, 2010-03-23 at 19:37 +0530, K.Prasad wrote:
> > plain text document attachment (ppc64_hbkpt_02)
> > Implement perf-events based hw-breakpoint interfaces for PPC64 processors.
> > These interfaces help arbitrate requests from various users and schedules
> > them as appropriate.
> > 
> > Signed-off-by: K.Prasad 
> 
> SNIP
> 
> > Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/cputable.h
> > ===
> > --- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/cputable.h
> > +++ linux-2.6.ppc64_test/arch/powerpc/include/asm/cputable.h
> > @@ -511,6 +511,13 @@ static inline int cpu_has_feature(unsign
> > & feature);
> >  }
> > 
> > +#define CPU_FTR_HAS_DABR (defined(CONFIG_PPC64) && \
> > + !defined(CONFIG_PPC_ADV_DEBUG_REGS))
> > +#ifdef CPU_FTR_HAS_DABR
> > +/* Number of physical HW breakpoint registers */
> > +#define HBP_NUM 1
> > +#endif
> > +
> >  #endif /* !__ASSEMBLY__ */
> > 
> >  #endif /* __KERNEL__ */
> 
> These new defines don't really correlate to the cpu table.  One would
> expect cpu_has_feature(CPU_FTR_HAS_DABR) to have meaning, but it would
> have to be defined similar to the other CPU_FTR_ constants, and or-ed
> with CPU_FTRS_ALWAYS (when appropriate).
> 

The code can be changed as below:

#if (defined(CONFIG_PPC64) && !defined(CONFIG_PPC_ADV_DEBUG_REGS))
#define CPU_FTR_HAS_DABR 1
/* Number of physical HW breakpoint registers */
#define HBP_NUM 1
#endif

However, a config option CONFIG_PPC_BOOK3S_64 (I just found) whose scope
includes only 64-bit server processors (having one DABR) to be the most
suitable.

I think it must be used in lieu of introducing a new CPU_FTR_HAS_DABR
definition in cputable.h


> Similarly, I would expect the cpu_spec structure to have a new field,
> hbp_num, which is initialized in cputable.c.  Maybe a longer name would
> be better, num_hw_brkpts?
> 

There are a few issues with such an approach:
i) Two such fields would be required in 'struct cpu_spec' - one for
instruction breakpoints and other for data.
ii) As pointed out by you below, hbp_num or num_hw_brkpts would always
be assigned to the compile time constant HBP_NUM (hence a variable is not
required to store it).
iii) HBP_NUM still cannot be entirely removed as it is used by generic
kernel/hw_breakpoint.c code (and is used by x86 code as well).

I think the simplest approach would be to have the following entry in
cputable.h (and get away with the rest of the additions seen in patch
ver XV)

#ifdef CONFIG_PPC_BOOK3S_64
#define HBP_NUM 1
#endif

The next version of the patch should contain changes to that effect
(assuming I hear no objections).

> When I added the PPC_ADV_DEBUG config options for the bookE features, I
> didn't see an immediate need to clutter the cputable since their values
> are fixed at compile time.  We should be consistent with these, but

It is even more true with ppc64-server processors, where the number of
debug registers (denoted by HBP_NUM) is fixed to 1 (unlike BookE where the
DACs can be used in standalone or as a pair of registers).

> unless we are going to determine any of these at run-time, I don't know
> that they belong in the cpu table.
>
> Thanks,
> Shaggy
> -- 

Thanks,
K.Prasad

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


  1   2   >