diff options
| -rw-r--r-- | arch/arm64/include/uapi/asm/ptrace.h | 3 | ||||
| -rw-r--r-- | arch/arm64/kernel/ptrace.c | 36 |
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 | ||
| 80 | struct user_hwdebug_state { | 80 | struct 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 | ||
| 377 | static int hw_break_get(struct task_struct *target, | 377 | static 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 | ||
