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 | ||