Hi Ravi, > Add selftests to test multiple active DAWRs with ptrace interface. It would be good if somewhere (maybe in the cover letter) you explain what DAWR stands for and where to find more information about it. I found the Power ISA v3.1 Book 3 Chapter 9 very helpful. Apart from that, I don't have any specific comments about this patch. It looks good to me, it seems to do what it says, and there are no comments from checkpatch. It is a bit sparse in terms of comments but it is consistent with the rest of the file so I can't really complain there :) Reviewed-by: Daniel Axtens <dja@xxxxxxxxxx> Kind regards, Daniel > Sample o/p: > $ ./ptrace-hwbreak > ... > PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW ALIGNED, WO, len: 6: Ok > PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW UNALIGNED, RO, len: 6: Ok > PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap, WO, len: 6: Ok > PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap, RO, len: 6: Ok > > Signed-off-by: Ravi Bangoria <ravi.bangoria@xxxxxxxxxxxxx> > --- > .../selftests/powerpc/ptrace/ptrace-hwbreak.c | 79 +++++++++++++++++++ > 1 file changed, 79 insertions(+) > > diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c > index 2e0d86e0687e..a0635a3819aa 100644 > --- a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c > +++ b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c > @@ -194,6 +194,18 @@ static void test_workload(void) > big_var[rand() % DAWR_MAX_LEN] = 'a'; > else > cvar = big_var[rand() % DAWR_MAX_LEN]; > + > + /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW ALIGNED, WO test */ > + gstruct.a[rand() % A_LEN] = 'a'; > + > + /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW UNALIGNED, RO test */ > + cvar = gstruct.b[rand() % B_LEN]; > + > + /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap, WO test */ > + gstruct.a[rand() % A_LEN] = 'a'; > + > + /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap, RO test */ > + cvar = gstruct.a[rand() % A_LEN]; > } > > static void check_success(pid_t child_pid, const char *name, const char *type, > @@ -417,6 +429,69 @@ static void test_sethwdebug_range_aligned(pid_t child_pid) > ptrace_delhwdebug(child_pid, wh); > } > > +static void test_multi_sethwdebug_range(pid_t child_pid) > +{ > + struct ppc_hw_breakpoint info1, info2; > + unsigned long wp_addr1, wp_addr2; > + char *name1 = "PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW ALIGNED"; > + char *name2 = "PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW UNALIGNED"; > + int len1, len2; > + int wh1, wh2; > + > + wp_addr1 = (unsigned long)&gstruct.a; > + wp_addr2 = (unsigned long)&gstruct.b; > + len1 = A_LEN; > + len2 = B_LEN; > + get_ppc_hw_breakpoint(&info1, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr1, len1); > + get_ppc_hw_breakpoint(&info2, PPC_BREAKPOINT_TRIGGER_READ, wp_addr2, len2); > + > + /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW ALIGNED, WO test */ > + wh1 = ptrace_sethwdebug(child_pid, &info1); > + > + /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DW UNALIGNED, RO test */ > + wh2 = ptrace_sethwdebug(child_pid, &info2); > + > + ptrace(PTRACE_CONT, child_pid, NULL, 0); > + check_success(child_pid, name1, "WO", wp_addr1, len1); > + > + ptrace(PTRACE_CONT, child_pid, NULL, 0); > + check_success(child_pid, name2, "RO", wp_addr2, len2); > + > + ptrace_delhwdebug(child_pid, wh1); > + ptrace_delhwdebug(child_pid, wh2); > +} > + > +static void test_multi_sethwdebug_range_dawr_overlap(pid_t child_pid) > +{ > + struct ppc_hw_breakpoint info1, info2; > + unsigned long wp_addr1, wp_addr2; > + char *name = "PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap"; > + int len1, len2; > + int wh1, wh2; > + > + wp_addr1 = (unsigned long)&gstruct.a; > + wp_addr2 = (unsigned long)&gstruct.a; > + len1 = A_LEN; > + len2 = A_LEN; > + get_ppc_hw_breakpoint(&info1, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr1, len1); > + get_ppc_hw_breakpoint(&info2, PPC_BREAKPOINT_TRIGGER_READ, wp_addr2, len2); > + > + /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap, WO test */ > + wh1 = ptrace_sethwdebug(child_pid, &info1); > + > + /* PPC_PTRACE_SETHWDEBUG 2, MODE_RANGE, DAWR Overlap, RO test */ > + wh2 = ptrace_sethwdebug(child_pid, &info2); > + > + ptrace(PTRACE_CONT, child_pid, NULL, 0); > + check_success(child_pid, name, "WO", wp_addr1, len1); > + > + ptrace(PTRACE_CONT, child_pid, NULL, 0); > + check_success(child_pid, name, "RO", wp_addr2, len2); > + > + ptrace_delhwdebug(child_pid, wh1); > + ptrace_delhwdebug(child_pid, wh2); > +} > + > static void test_sethwdebug_range_unaligned(pid_t child_pid) > { > struct ppc_hw_breakpoint info; > @@ -504,6 +579,10 @@ run_tests(pid_t child_pid, struct ppc_debug_info *dbginfo, bool dawr) > test_sethwdebug_range_unaligned(child_pid); > test_sethwdebug_range_unaligned_dar(child_pid); > test_sethwdebug_dawr_max_range(child_pid); > + if (dbginfo->num_data_bps > 1) { > + test_multi_sethwdebug_range(child_pid); > + test_multi_sethwdebug_range_dawr_overlap(child_pid); > + } > } > } > } > -- > 2.27.0