aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/include/uapi/asm/ptrace.h3
-rw-r--r--arch/arm64/kernel/ptrace.c36
2 files changed, 32 insertions, 7 deletions
diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 9b131b4efa0b..6913643bbe54 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -79,13 +79,14 @@ struct user_fpsimd_state {
79 79
80struct user_hwdebug_state { 80struct user_hwdebug_state {
81 __u32 dbg_info; 81 __u32 dbg_info;
82 __u32 pad;
82 struct { 83 struct {
83 __u64 addr; 84 __u64 addr;
84 __u32 ctrl; 85 __u32 ctrl;
86 __u32 pad;
85 } dbg_regs[16]; 87 } dbg_regs[16];
86}; 88};
87 89
88
89#endif /* __ASSEMBLY__ */ 90#endif /* __ASSEMBLY__ */
90 91
91#endif /* _UAPI__ASM_PTRACE_H */ 92#endif /* _UAPI__ASM_PTRACE_H */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 2ea3968367c2..c62d39d5c99f 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -372,7 +372,7 @@ static int ptrace_hbp_set_addr(unsigned int note_type,
372 372
373#define PTRACE_HBP_ADDR_SZ sizeof(u64) 373#define PTRACE_HBP_ADDR_SZ sizeof(u64)
374#define PTRACE_HBP_CTRL_SZ sizeof(u32) 374#define PTRACE_HBP_CTRL_SZ sizeof(u32)
375#define PTRACE_HBP_REG_OFF sizeof(u32) 375#define PTRACE_HBP_PAD_SZ sizeof(u32)
376 376
377static int hw_break_get(struct task_struct *target, 377static int hw_break_get(struct task_struct *target,
378 const struct user_regset *regset, 378 const struct user_regset *regset,
@@ -380,7 +380,7 @@ static int hw_break_get(struct task_struct *target,
380 void *kbuf, void __user *ubuf) 380 void *kbuf, void __user *ubuf)
381{ 381{
382 unsigned int note_type = regset->core_note_type; 382 unsigned int note_type = regset->core_note_type;
383 int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit; 383 int ret, idx = 0, offset, limit;
384 u32 info, ctrl; 384 u32 info, ctrl;
385 u64 addr; 385 u64 addr;
386 386
@@ -389,11 +389,20 @@ static int hw_break_get(struct task_struct *target,
389 if (ret) 389 if (ret)
390 return ret; 390 return ret;
391 391
392 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0, 4); 392 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0,
393 sizeof(info));
394 if (ret)
395 return ret;
396
397 /* Pad */
398 offset = offsetof(struct user_hwdebug_state, pad);
399 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, offset,
400 offset + PTRACE_HBP_PAD_SZ);
393 if (ret) 401 if (ret)
394 return ret; 402 return ret;
395 403
396 /* (address, ctrl) registers */ 404 /* (address, ctrl) registers */
405 offset = offsetof(struct user_hwdebug_state, dbg_regs);
397 limit = regset->n * regset->size; 406 limit = regset->n * regset->size;
398 while (count && offset < limit) { 407 while (count && offset < limit) {
399 ret = ptrace_hbp_get_addr(note_type, target, idx, &addr); 408 ret = ptrace_hbp_get_addr(note_type, target, idx, &addr);
@@ -413,6 +422,13 @@ static int hw_break_get(struct task_struct *target,
413 if (ret) 422 if (ret)
414 return ret; 423 return ret;
415 offset += PTRACE_HBP_CTRL_SZ; 424 offset += PTRACE_HBP_CTRL_SZ;
425
426 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
427 offset,
428 offset + PTRACE_HBP_PAD_SZ);
429 if (ret)
430 return ret;
431 offset += PTRACE_HBP_PAD_SZ;
416 idx++; 432 idx++;
417 } 433 }
418 434
@@ -425,12 +441,13 @@ static int hw_break_set(struct task_struct *target,
425 const void *kbuf, const void __user *ubuf) 441 const void *kbuf, const void __user *ubuf)
426{ 442{
427 unsigned int note_type = regset->core_note_type; 443 unsigned int note_type = regset->core_note_type;
428 int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit; 444 int ret, idx = 0, offset, limit;
429 u32 ctrl; 445 u32 ctrl;
430 u64 addr; 446 u64 addr;
431 447
432 /* Resource info */ 448 /* Resource info and pad */
433 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, 4); 449 offset = offsetof(struct user_hwdebug_state, dbg_regs);
450 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset);
434 if (ret) 451 if (ret)
435 return ret; 452 return ret;
436 453
@@ -454,6 +471,13 @@ static int hw_break_set(struct task_struct *target,
454 if (ret) 471 if (ret)
455 return ret; 472 return ret;
456 offset += PTRACE_HBP_CTRL_SZ; 473 offset += PTRACE_HBP_CTRL_SZ;
474
475 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
476 offset,
477 offset + PTRACE_HBP_PAD_SZ);
478 if (ret)
479 return ret;
480 offset += PTRACE_HBP_PAD_SZ;
457 idx++; 481 idx++;
458 } 482 }
459 483