aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/ptrace.c
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2012-10-11 07:10:57 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2012-10-18 15:15:31 -0400
commit7797d17c591ae62c6f43c6de4fdb8beeb50eb692 (patch)
tree168c3b4301ef6dedf1f9dbf73779986a49d934ca /arch/arm64/kernel/ptrace.c
parent16dd46bb781a1d37eeb2377e8e48276e9d14d15d (diff)
arm64: ptrace: make structure padding explicit for debug registers
The user_hwdebug_state structure contains implicit padding to conform to the alignment requirements of the AArch64 ABI (namely that aggregates must be aligned to their most aligned member). This patch fixes the ptrace functions operating on struct user_hwdebug_state so that the padding is handled correctly. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/ptrace.c')
-rw-r--r--arch/arm64/kernel/ptrace.c36
1 files changed, 30 insertions, 6 deletions
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