mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
16dd46bb78
commit
7797d17c59
|
@ -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 */
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue