mirror of
https://github.com/torvalds/linux.git
synced 2024-12-14 07:02:23 +00:00
[POWERPC] Use user_regset accessors for GPRs
This implements user_regset-style accessors for the powerpc general registers. In the future these functions will be the only place that needs to understand the user_regset layout (core dump format) and how it maps to the internal representation of user thread state. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
26f7713020
commit
44dd3f50d3
@ -119,6 +119,97 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int gpr_get(struct task_struct *target, const struct user_regset *regset,
|
||||
unsigned int pos, unsigned int count,
|
||||
void *kbuf, void __user *ubuf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (target->thread.regs == NULL)
|
||||
return -EIO;
|
||||
|
||||
CHECK_FULL_REGS(target->thread.regs);
|
||||
|
||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
target->thread.regs,
|
||||
0, offsetof(struct pt_regs, msr));
|
||||
if (!ret) {
|
||||
unsigned long msr = get_user_msr(target);
|
||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr,
|
||||
offsetof(struct pt_regs, msr),
|
||||
offsetof(struct pt_regs, msr) +
|
||||
sizeof(msr));
|
||||
}
|
||||
|
||||
BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
|
||||
offsetof(struct pt_regs, msr) + sizeof(long));
|
||||
|
||||
if (!ret)
|
||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
&target->thread.regs->orig_gpr3,
|
||||
offsetof(struct pt_regs, orig_gpr3),
|
||||
sizeof(struct pt_regs));
|
||||
if (!ret)
|
||||
ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
|
||||
sizeof(struct pt_regs), -1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gpr_set(struct task_struct *target, const struct user_regset *regset,
|
||||
unsigned int pos, unsigned int count,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
unsigned long reg;
|
||||
int ret;
|
||||
|
||||
if (target->thread.regs == NULL)
|
||||
return -EIO;
|
||||
|
||||
CHECK_FULL_REGS(target->thread.regs);
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
target->thread.regs,
|
||||
0, PT_MSR * sizeof(reg));
|
||||
|
||||
if (!ret && count > 0) {
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®,
|
||||
PT_MSR * sizeof(reg),
|
||||
(PT_MSR + 1) * sizeof(reg));
|
||||
if (!ret)
|
||||
ret = set_user_msr(target, reg);
|
||||
}
|
||||
|
||||
BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
|
||||
offsetof(struct pt_regs, msr) + sizeof(long));
|
||||
|
||||
if (!ret)
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&target->thread.regs->orig_gpr3,
|
||||
PT_ORIG_R3 * sizeof(reg),
|
||||
(PT_MAX_PUT_REG + 1) * sizeof(reg));
|
||||
|
||||
if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret)
|
||||
ret = user_regset_copyin_ignore(
|
||||
&pos, &count, &kbuf, &ubuf,
|
||||
(PT_MAX_PUT_REG + 1) * sizeof(reg),
|
||||
PT_TRAP * sizeof(reg));
|
||||
|
||||
if (!ret && count > 0) {
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®,
|
||||
PT_TRAP * sizeof(reg),
|
||||
(PT_TRAP + 1) * sizeof(reg));
|
||||
if (!ret)
|
||||
ret = set_user_trap(target, reg);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
ret = user_regset_copyin_ignore(
|
||||
&pos, &count, &kbuf, &ubuf,
|
||||
(PT_TRAP + 1) * sizeof(reg), -1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fpr_get(struct task_struct *target, const struct user_regset *regset,
|
||||
unsigned int pos, unsigned int count,
|
||||
|
Loading…
Reference in New Issue
Block a user