7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: Tiezhu Yang [ Upstream commit f5c0f8427469e703465c719c4304ce91282a32eb ] In hw_breakpoint_control(), the logic to enable CSR_PRMD_PWE (global watchpoint enable) incorrectly relies on TIF_LOAD_WATCH. This thread flag is only set during ptrace operations, meaning that the standard hardware breakpoints created via perf_event_open() will never have this flag set. As a result, the CSR_PRMD_PWE switch is skipped, leaving the hardware breakpoint completely inactive in perf usage. Fix this by decoupling the CSR_PRMD_PWE from the ptrace specific flag TIF_LOAD_WATCH, which ensures that CSR_PRMD_PWE is enabled whenever a hardware breakpoint is installed. Here is a user-space reproducer to demonstrate the issue: (1) Test program (test_perf_install.c): #include #include #include #include #include #include static int var = 0; int main(void) { size_t count = 0; struct perf_event_attr attr = { .type = PERF_TYPE_BREAKPOINT, .size = sizeof(attr), .bp_type = HW_BREAKPOINT_W, .bp_addr = (unsigned long)&var, .bp_len = HW_BREAKPOINT_LEN_1, .exclude_kernel = 1, }; int fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); asm volatile("st.b %1, %0" : "=m"(var) : "r"(11) : "memory"); ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); read(fd, &count, sizeof(size_t)); printf("Watchpoint counts: expected = 1, actual = %zu\n", count); close(fd); return 0; } (2) Test steps: $ gcc test_perf_install.c -o test_perf_install $ ./test_perf_install (3) Test results: Without this patch: Watchpoint counts: expected = 1, actual = 0 With this patch: Watchpoint counts: expected = 1, actual = 1 Cc: stable@vger.kernel.org Fixes: 3892b11eac5a ("LoongArch: Check TIF_LOAD_WATCH to enable user space watchpoint") Signed-off-by: Tiezhu Yang Signed-off-by: Huacai Chen Signed-off-by: Sasha Levin --- arch/loongarch/kernel/hw_breakpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/hw_breakpoint.c index d009ed780cf02..1a05350159f7b 100644 --- a/arch/loongarch/kernel/hw_breakpoint.c +++ b/arch/loongarch/kernel/hw_breakpoint.c @@ -233,7 +233,7 @@ static int hw_breakpoint_control(struct perf_event *bp, } enable = csr_read64(LOONGARCH_CSR_CRMD); csr_write64(CSR_CRMD_WE | enable, LOONGARCH_CSR_CRMD); - if (bp->hw.target && test_tsk_thread_flag(bp->hw.target, TIF_LOAD_WATCH)) + if (bp->hw.target) regs->csr_prmd |= CSR_PRMD_PWE; break; case HW_BREAKPOINT_UNINSTALL: -- 2.53.0