Skip to content

Commit d970182

Browse files
seehearfeelgregkh
authored andcommitted
LoongArch: Extend the maximum number of watchpoints
commit 531936d upstream. The maximum number of load/store watchpoints and fetch instruction watchpoints is 14 each according to LoongArch Reference Manual, so extend the maximum number of watchpoints from 8 to 14 for ptrace. By the way, just simply change 8 to 14 for the definition in struct user_watch_state at the beginning, but it may corrupt uapi, then add a new struct user_watch_state_v2 directly. As far as I can tell, the only users for this struct in the userspace are GDB and LLDB, there are no any problems of software compatibility between the application and kernel according to the analysis. The compatibility problem has been considered while developing and testing. When the applications in the userspace get watchpoint state, the length will be specified which is no bigger than the sizeof struct user_watch_state or user_watch_state_v2, the actual length is assigned as the minimal value of the application and kernel in the generic code of ptrace: kernel/ptrace.c: ptrace_regset(): kiov->iov_len = min(kiov->iov_len, (__kernel_size_t) (regset->n * regset->size)); if (req == PTRACE_GETREGSET) return copy_regset_to_user(task, view, regset_no, 0, kiov->iov_len, kiov->iov_base); else return copy_regset_from_user(task, view, regset_no, 0, kiov->iov_len, kiov->iov_base); For example, there are four kind of combinations, all of them work well. (1) "older kernel + older gdb", the actual length is 8+(8+8+4+4)*8=200; (2) "newer kernel + newer gdb", the actual length is 8+(8+8+4+4)*14=344; (3) "older kernel + newer gdb", the actual length is 8+(8+8+4+4)*8=200; (4) "newer kernel + older gdb", the actual length is 8+(8+8+4+4)*8=200. Link: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#control-and-status-registers-related-to-watchpoints Cc: stable@vger.kernel.org Fixes: 1a69f7a ("LoongArch: ptrace: Expose hardware breakpoints to debuggers") Reviewed-by: WANG Xuerui <git@xen0n.name> Reviewed-by: Xi Ruoyao <xry111@xry111.site> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent f473a56 commit d970182

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

arch/loongarch/include/uapi/asm/ptrace.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ struct user_watch_state {
7272
} dbg_regs[8];
7373
};
7474

75+
struct user_watch_state_v2 {
76+
uint64_t dbg_info;
77+
struct {
78+
uint64_t addr;
79+
uint64_t mask;
80+
uint32_t ctrl;
81+
uint32_t pad;
82+
} dbg_regs[14];
83+
};
84+
7585
#define PTRACE_SYSEMU 0x1f
7686
#define PTRACE_SYSEMU_SINGLESTEP 0x20
7787

arch/loongarch/kernel/ptrace.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ static int hw_break_set(struct task_struct *target,
720720
unsigned int note_type = regset->core_note_type;
721721

722722
/* Resource info */
723-
offset = offsetof(struct user_watch_state, dbg_regs);
723+
offset = offsetof(struct user_watch_state_v2, dbg_regs);
724724
user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset);
725725

726726
/* (address, mask, ctrl) registers */
@@ -920,15 +920,15 @@ static const struct user_regset loongarch64_regsets[] = {
920920
#ifdef CONFIG_HAVE_HW_BREAKPOINT
921921
[REGSET_HW_BREAK] = {
922922
.core_note_type = NT_LOONGARCH_HW_BREAK,
923-
.n = sizeof(struct user_watch_state) / sizeof(u32),
923+
.n = sizeof(struct user_watch_state_v2) / sizeof(u32),
924924
.size = sizeof(u32),
925925
.align = sizeof(u32),
926926
.regset_get = hw_break_get,
927927
.set = hw_break_set,
928928
},
929929
[REGSET_HW_WATCH] = {
930930
.core_note_type = NT_LOONGARCH_HW_WATCH,
931-
.n = sizeof(struct user_watch_state) / sizeof(u32),
931+
.n = sizeof(struct user_watch_state_v2) / sizeof(u32),
932932
.size = sizeof(u32),
933933
.align = sizeof(u32),
934934
.regset_get = hw_break_get,

0 commit comments

Comments
 (0)