LoongArch: Check TIF_LOAD_WATCH to enable user space watchpoint
authorTiezhu Yang <yangtiezhu@loongson.cn>
Sat, 20 Jul 2024 14:41:07 +0000 (22:41 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Sat, 20 Jul 2024 14:41:07 +0000 (22:41 +0800)
Currently, there are some places to set CSR.PRMD.PWE, the first one is
in hw_breakpoint_thread_switch() to enable user space singlestep via
checking TIF_SINGLESTEP, the second one is in hw_breakpoint_control() to
enable user space watchpoint. For the latter case, it should also check
TIF_LOAD_WATCH to make the logic correct and clear.

Fixes: c8e57ab0995c ("LoongArch: Trigger user-space watchpoints correctly")
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/kernel/hw_breakpoint.c
arch/loongarch/kernel/ptrace.c

index 621ad7634df718c3c4681a50e94bb852683d6f40..a6e4b605bfa8d6b7110636ff36798d7013f4c3f9 100644 (file)
@@ -221,7 +221,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)
+               if (bp->hw.target && test_tsk_thread_flag(bp->hw.target, TIF_LOAD_WATCH))
                        regs->csr_prmd |= CSR_PRMD_PWE;
                break;
        case HW_BREAKPOINT_UNINSTALL:
index 200109de1971ad5ec382dc1a6647c5c29eedc20a..19dc6eff45ccc84a1f3ab198aa22a3541f36a923 100644 (file)
@@ -589,6 +589,7 @@ static int ptrace_hbp_set_ctrl(unsigned int note_type,
        struct perf_event *bp;
        struct perf_event_attr attr;
        struct arch_hw_breakpoint_ctrl ctrl;
+       struct thread_info *ti = task_thread_info(tsk);
 
        bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
        if (IS_ERR(bp))
@@ -613,8 +614,10 @@ static int ptrace_hbp_set_ctrl(unsigned int note_type,
                if (err)
                        return err;
                attr.disabled = 0;
+               set_ti_thread_flag(ti, TIF_LOAD_WATCH);
        } else {
                attr.disabled = 1;
+               clear_ti_thread_flag(ti, TIF_LOAD_WATCH);
        }
 
        return modify_user_hw_breakpoint(bp, &attr);