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:
0xc000000000125580 <trace_selftest_startup_ksym+0>:     mflr    r0
0xc000000000125584 <trace_selftest_startup_ksym+4>:     std     r26,-48(r1)
0xc000000000125588 <trace_selftest_startup_ksym+8>:     std     r27,-40(r1)
0xc00000000012558c <trace_selftest_startup_ksym+12>:    std     r28,-32(r1)
0xc000000000125590 <trace_selftest_startup_ksym+16>:    std     r29,-24(r1)
0xc000000000125594 <trace_selftest_startup_ksym+20>:    std     r30,-16(r1)
0xc000000000125598 <trace_selftest_startup_ksym+24>:    std     r31,-8(r1)
0xc00000000012559c <trace_selftest_startup_ksym+28>:    std     r0,16(r1)
0xc0000000001255a0 <trace_selftest_startup_ksym+32>:    stdu    r1,-176(r1)
0xc0000000001255a4 <trace_selftest_startup_ksym+36>:    mr      r31,r1
0xc0000000001255a8 <trace_selftest_startup_ksym+40>:    ld      r30,-17784(r2)
0xc0000000001255ac <trace_selftest_startup_ksym+44>:    mr      r26,r4
0xc0000000001255b0 <trace_selftest_startup_ksym+48>:    mr      r27,r3
0xc0000000001255b4 <trace_selftest_startup_ksym+52>:    bl      
0xc000000000125510 <tracer_init>
0xc0000000001255b8 <trace_selftest_startup_ksym+56>:    li      r4,3
0xc0000000001255bc <trace_selftest_startup_ksym+60>:    mr.     r29,r3
0xc0000000001255c0 <trace_selftest_startup_ksym+64>:    mr      r5,r29
0xc0000000001255c4 <trace_selftest_startup_ksym+68>:    beq     
0xc0000000001255e0 <trace_selftest_startup_ksym+96>
0xc0000000001255c8 <trace_selftest_startup_ksym+72>:    ld      r3,-31520(r30)
0xc0000000001255cc <trace_selftest_startup_ksym+76>:    ld      r4,0(r27)
0xc0000000001255d0 <trace_selftest_startup_ksym+80>:    bl      
0xc00000000009c560 <printk>
0xc0000000001255d4 <trace_selftest_startup_ksym+84>:    nop
0xc0000000001255d8 <trace_selftest_startup_ksym+88>:    b       
0xc000000000125690 <trace_selftest_startup_ksym+272>
0xc0000000001255dc <trace_selftest_startup_ksym+92>:    nop
0xc0000000001255e0 <trace_selftest_startup_ksym+96>:    ld      r28,-31512(r30)
0xc0000000001255e4 <trace_selftest_startup_ksym+100>:   ld      r3,-31504(r30)
0xc0000000001255e8 <trace_selftest_startup_ksym+104>:   stw     r29,0(r28)
0xc0000000001255ec <trace_selftest_startup_ksym+108>:   mr      r5,r28
0xc0000000001255f0 <trace_selftest_startup_ksym+112>:   bl      
0xc000000000140760 <process_new_ksym_entry>
0xc0000000001255f4 <trace_selftest_startup_ksym+116>:   nop
0xc0000000001255f8 <trace_selftest_startup_ksym+120>:   cmpwi   cr7,r3,0
0xc0000000001255fc <trace_selftest_startup_ksym+124>:   mr      r29,r3
0xc000000000125600 <trace_selftest_startup_ksym+128>:   blt     
cr7,0xc00000000012567c <trace_selftest_startup_ksym+252>
0xc000000000125604 <trace_selftest_startup_ksym+132>:   lwz     r0,0(r28)
0xc000000000125608 <trace_selftest_startup_ksym+136>:   cmpwi   cr7,r0,0
0xc00000000012560c <trace_selftest_startup_ksym+140>:   bne     
cr7,0xc000000000125618 <trace_selftest_startup_ksym+152>
0xc000000000125610 <trace_selftest_startup_ksym+144>:   li      r0,1

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

Reply via email to