diff options
author | Will Deacon <will.deacon@arm.com> | 2012-10-11 11:10:57 (GMT) |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2012-10-18 19:15:31 (GMT) |
commit | 7797d17c591ae62c6f43c6de4fdb8beeb50eb692 (patch) | |
tree | 168c3b4301ef6dedf1f9dbf73779986a49d934ca | |
parent | 16dd46bb781a1d37eeb2377e8e48276e9d14d15d (diff) | |
download | linux-fsl-qoriq-7797d17c591ae62c6f43c6de4fdb8beeb50eb692.tar.xz |
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>
-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 9b131b4..6913643 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 { struct user_hwdebug_state { __u32 dbg_info; + __u32 pad; struct { __u64 addr; __u32 ctrl; + __u32 pad; } dbg_regs[16]; }; - #endif /* __ASSEMBLY__ */ #endif /* _UAPI__ASM_PTRACE_H */ diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 2ea3968..c62d39d 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, #define PTRACE_HBP_ADDR_SZ sizeof(u64) #define PTRACE_HBP_CTRL_SZ sizeof(u32) -#define PTRACE_HBP_REG_OFF sizeof(u32) +#define PTRACE_HBP_PAD_SZ sizeof(u32) static int hw_break_get(struct task_struct *target, const struct user_regset *regset, @@ -380,7 +380,7 @@ static int hw_break_get(struct task_struct *target, void *kbuf, void __user *ubuf) { unsigned int note_type = regset->core_note_type; - int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit; + int ret, idx = 0, offset, limit; u32 info, ctrl; u64 addr; @@ -389,11 +389,20 @@ static int hw_break_get(struct task_struct *target, if (ret) return ret; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0, 4); + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0, + sizeof(info)); + if (ret) + return ret; + + /* Pad */ + offset = offsetof(struct user_hwdebug_state, pad); + ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, offset, + offset + PTRACE_HBP_PAD_SZ); if (ret) return ret; /* (address, ctrl) registers */ + offset = offsetof(struct user_hwdebug_state, dbg_regs); limit = regset->n * regset->size; while (count && offset < limit) { ret = ptrace_hbp_get_addr(note_type, target, idx, &addr); @@ -413,6 +422,13 @@ static int hw_break_get(struct task_struct *target, if (ret) return ret; offset += PTRACE_HBP_CTRL_SZ; + + ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, + offset, + offset + PTRACE_HBP_PAD_SZ); + if (ret) + return ret; + offset += PTRACE_HBP_PAD_SZ; idx++; } @@ -425,12 +441,13 @@ static int hw_break_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { unsigned int note_type = regset->core_note_type; - int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit; + int ret, idx = 0, offset, limit; u32 ctrl; u64 addr; - /* Resource info */ - ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, 4); + /* Resource info and pad */ + offset = offsetof(struct user_hwdebug_state, dbg_regs); + ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset); if (ret) return ret; @@ -454,6 +471,13 @@ static int hw_break_set(struct task_struct *target, if (ret) return ret; offset += PTRACE_HBP_CTRL_SZ; + + ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + offset, + offset + PTRACE_HBP_PAD_SZ); + if (ret) + return ret; + offset += PTRACE_HBP_PAD_SZ; idx++; } |