powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr()
On the same model as ptrace_get_reg() and ptrace_put_reg(), create ptrace_get_fpr() and ptrace_put_fpr() to get/set the floating points registers. We move the boundary checkings in them. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/24a1baedea7f7ae7b6bf27be98bab6d01b5ca2c1.1597770847.git.christophe.leroy@csgroup.eu
This commit is contained in:
Родитель
e009fa4335
Коммит
4d90eb97e2
|
@ -6,6 +6,7 @@
|
|||
CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
|
||||
|
||||
obj-y += ptrace.o ptrace-view.o
|
||||
obj-y += ptrace-fpu.o
|
||||
obj-$(CONFIG_COMPAT) += ptrace32.o
|
||||
obj-$(CONFIG_VSX) += ptrace-vsx.o
|
||||
ifneq ($(CONFIG_VSX),y)
|
||||
|
|
|
@ -164,6 +164,10 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data);
|
|||
|
||||
extern const struct user_regset_view user_ppc_native_view;
|
||||
|
||||
/* ptrace-fpu */
|
||||
int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data);
|
||||
int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data);
|
||||
|
||||
/* ptrace-(no)adv */
|
||||
void ppc_gethwdinfo(struct ppc_debug_info *dbginfo);
|
||||
int ptrace_get_debugreg(struct task_struct *child, unsigned long addr,
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <linux/regset.h>
|
||||
|
||||
#include <asm/switch_to.h>
|
||||
|
||||
#include "ptrace-decl.h"
|
||||
|
||||
int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
|
||||
{
|
||||
unsigned int fpidx = index - PT_FPR0;
|
||||
|
||||
if (index > PT_FPSCR)
|
||||
return -EIO;
|
||||
|
||||
flush_fp_to_thread(child);
|
||||
if (fpidx < (PT_FPSCR - PT_FPR0))
|
||||
memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
|
||||
else
|
||||
*data = child->thread.fp_state.fpscr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
|
||||
{
|
||||
unsigned int fpidx = index - PT_FPR0;
|
||||
|
||||
if (index > PT_FPSCR)
|
||||
return -EIO;
|
||||
|
||||
flush_fp_to_thread(child);
|
||||
if (fpidx < (PT_FPSCR - PT_FPR0))
|
||||
memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
|
||||
else
|
||||
child->thread.fp_state.fpscr = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -56,25 +56,17 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||
ret = -EIO;
|
||||
/* convert to index and check */
|
||||
index = addr / sizeof(long);
|
||||
if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR)
|
||||
|| (child->thread.regs == NULL))
|
||||
if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
|
||||
break;
|
||||
|
||||
CHECK_FULL_REGS(child->thread.regs);
|
||||
if (index < PT_FPR0) {
|
||||
if (index < PT_FPR0)
|
||||
ret = ptrace_get_reg(child, (int) index, &tmp);
|
||||
if (ret)
|
||||
break;
|
||||
} else {
|
||||
unsigned int fpidx = index - PT_FPR0;
|
||||
else
|
||||
ret = ptrace_get_fpr(child, index, &tmp);
|
||||
|
||||
flush_fp_to_thread(child);
|
||||
if (fpidx < (PT_FPSCR - PT_FPR0))
|
||||
memcpy(&tmp, &child->thread.TS_FPR(fpidx),
|
||||
sizeof(long));
|
||||
else
|
||||
tmp = child->thread.fp_state.fpscr;
|
||||
}
|
||||
if (ret)
|
||||
break;
|
||||
ret = put_user(tmp, datalp);
|
||||
break;
|
||||
}
|
||||
|
@ -86,24 +78,14 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||
ret = -EIO;
|
||||
/* convert to index and check */
|
||||
index = addr / sizeof(long);
|
||||
if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR)
|
||||
|| (child->thread.regs == NULL))
|
||||
if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
|
||||
break;
|
||||
|
||||
CHECK_FULL_REGS(child->thread.regs);
|
||||
if (index < PT_FPR0) {
|
||||
if (index < PT_FPR0)
|
||||
ret = ptrace_put_reg(child, index, data);
|
||||
} else {
|
||||
unsigned int fpidx = index - PT_FPR0;
|
||||
|
||||
flush_fp_to_thread(child);
|
||||
if (fpidx < (PT_FPSCR - PT_FPR0))
|
||||
memcpy(&child->thread.TS_FPR(fpidx), &data,
|
||||
sizeof(long));
|
||||
else
|
||||
child->thread.fp_state.fpscr = data;
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
ret = ptrace_put_fpr(child, index, data);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче