powerpc: move common register copy functions from signal_32.c to signal.c
These functions are required for 64bit as well. Signed-off-by: Michal Suchanek <msuchanek@suse.de> Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/9fd6d9b7c5e91fab21159fe23534a2f16b4962d3.1584699455.git.msuchanek@suse.de
This commit is contained in:
parent
9e62ccec3b
commit
3dd4eb83a9
|
@ -18,12 +18,153 @@
|
|||
#include <linux/syscalls.h>
|
||||
#include <asm/hw_breakpoint.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/debug.h>
|
||||
#include <asm/tm.h>
|
||||
|
||||
#include "signal.h"
|
||||
|
||||
#ifdef CONFIG_VSX
|
||||
unsigned long copy_fpr_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
u64 buf[ELF_NFPREG];
|
||||
int i;
|
||||
|
||||
/* save FPR copy to local buffer then write to the thread_struct */
|
||||
for (i = 0; i < (ELF_NFPREG - 1) ; i++)
|
||||
buf[i] = task->thread.TS_FPR(i);
|
||||
buf[i] = task->thread.fp_state.fpscr;
|
||||
return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
|
||||
unsigned long copy_fpr_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
u64 buf[ELF_NFPREG];
|
||||
int i;
|
||||
|
||||
if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
|
||||
return 1;
|
||||
for (i = 0; i < (ELF_NFPREG - 1) ; i++)
|
||||
task->thread.TS_FPR(i) = buf[i];
|
||||
task->thread.fp_state.fpscr = buf[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long copy_vsx_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
u64 buf[ELF_NVSRHALFREG];
|
||||
int i;
|
||||
|
||||
/* save FPR copy to local buffer then write to the thread_struct */
|
||||
for (i = 0; i < ELF_NVSRHALFREG; i++)
|
||||
buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
|
||||
return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
|
||||
}
|
||||
|
||||
unsigned long copy_vsx_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
u64 buf[ELF_NVSRHALFREG];
|
||||
int i;
|
||||
|
||||
if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
|
||||
return 1;
|
||||
for (i = 0; i < ELF_NVSRHALFREG ; i++)
|
||||
task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
unsigned long copy_ckfpr_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
u64 buf[ELF_NFPREG];
|
||||
int i;
|
||||
|
||||
/* save FPR copy to local buffer then write to the thread_struct */
|
||||
for (i = 0; i < (ELF_NFPREG - 1) ; i++)
|
||||
buf[i] = task->thread.TS_CKFPR(i);
|
||||
buf[i] = task->thread.ckfp_state.fpscr;
|
||||
return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
|
||||
unsigned long copy_ckfpr_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
u64 buf[ELF_NFPREG];
|
||||
int i;
|
||||
|
||||
if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
|
||||
return 1;
|
||||
for (i = 0; i < (ELF_NFPREG - 1) ; i++)
|
||||
task->thread.TS_CKFPR(i) = buf[i];
|
||||
task->thread.ckfp_state.fpscr = buf[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long copy_ckvsx_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
u64 buf[ELF_NVSRHALFREG];
|
||||
int i;
|
||||
|
||||
/* save FPR copy to local buffer then write to the thread_struct */
|
||||
for (i = 0; i < ELF_NVSRHALFREG; i++)
|
||||
buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
|
||||
return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
|
||||
}
|
||||
|
||||
unsigned long copy_ckvsx_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
u64 buf[ELF_NVSRHALFREG];
|
||||
int i;
|
||||
|
||||
if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
|
||||
return 1;
|
||||
for (i = 0; i < ELF_NVSRHALFREG ; i++)
|
||||
task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
|
||||
#else
|
||||
inline unsigned long copy_fpr_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
return __copy_to_user(to, task->thread.fp_state.fpr,
|
||||
ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
|
||||
inline unsigned long copy_fpr_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
return __copy_from_user(task->thread.fp_state.fpr, from,
|
||||
ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
inline unsigned long copy_ckfpr_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
return __copy_to_user(to, task->thread.ckfp_state.fpr,
|
||||
ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
|
||||
inline unsigned long copy_ckfpr_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
return __copy_from_user(task->thread.ckfp_state.fpr, from,
|
||||
ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
|
||||
#endif
|
||||
|
||||
/* Log an error when sending an unhandled signal to a process. Controlled
|
||||
* through debug.exception-trace sysctl.
|
||||
*/
|
||||
|
|
|
@ -235,146 +235,6 @@ struct rt_sigframe {
|
|||
int abigap[56];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_VSX
|
||||
unsigned long copy_fpr_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
u64 buf[ELF_NFPREG];
|
||||
int i;
|
||||
|
||||
/* save FPR copy to local buffer then write to the thread_struct */
|
||||
for (i = 0; i < (ELF_NFPREG - 1) ; i++)
|
||||
buf[i] = task->thread.TS_FPR(i);
|
||||
buf[i] = task->thread.fp_state.fpscr;
|
||||
return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
|
||||
unsigned long copy_fpr_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
u64 buf[ELF_NFPREG];
|
||||
int i;
|
||||
|
||||
if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
|
||||
return 1;
|
||||
for (i = 0; i < (ELF_NFPREG - 1) ; i++)
|
||||
task->thread.TS_FPR(i) = buf[i];
|
||||
task->thread.fp_state.fpscr = buf[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long copy_vsx_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
u64 buf[ELF_NVSRHALFREG];
|
||||
int i;
|
||||
|
||||
/* save FPR copy to local buffer then write to the thread_struct */
|
||||
for (i = 0; i < ELF_NVSRHALFREG; i++)
|
||||
buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
|
||||
return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
|
||||
}
|
||||
|
||||
unsigned long copy_vsx_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
u64 buf[ELF_NVSRHALFREG];
|
||||
int i;
|
||||
|
||||
if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
|
||||
return 1;
|
||||
for (i = 0; i < ELF_NVSRHALFREG ; i++)
|
||||
task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
unsigned long copy_ckfpr_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
u64 buf[ELF_NFPREG];
|
||||
int i;
|
||||
|
||||
/* save FPR copy to local buffer then write to the thread_struct */
|
||||
for (i = 0; i < (ELF_NFPREG - 1) ; i++)
|
||||
buf[i] = task->thread.TS_CKFPR(i);
|
||||
buf[i] = task->thread.ckfp_state.fpscr;
|
||||
return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
|
||||
unsigned long copy_ckfpr_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
u64 buf[ELF_NFPREG];
|
||||
int i;
|
||||
|
||||
if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
|
||||
return 1;
|
||||
for (i = 0; i < (ELF_NFPREG - 1) ; i++)
|
||||
task->thread.TS_CKFPR(i) = buf[i];
|
||||
task->thread.ckfp_state.fpscr = buf[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long copy_ckvsx_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
u64 buf[ELF_NVSRHALFREG];
|
||||
int i;
|
||||
|
||||
/* save FPR copy to local buffer then write to the thread_struct */
|
||||
for (i = 0; i < ELF_NVSRHALFREG; i++)
|
||||
buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
|
||||
return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
|
||||
}
|
||||
|
||||
unsigned long copy_ckvsx_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
u64 buf[ELF_NVSRHALFREG];
|
||||
int i;
|
||||
|
||||
if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
|
||||
return 1;
|
||||
for (i = 0; i < ELF_NVSRHALFREG ; i++)
|
||||
task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
|
||||
#else
|
||||
inline unsigned long copy_fpr_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
return __copy_to_user(to, task->thread.fp_state.fpr,
|
||||
ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
|
||||
inline unsigned long copy_fpr_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
return __copy_from_user(task->thread.fp_state.fpr, from,
|
||||
ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
inline unsigned long copy_ckfpr_to_user(void __user *to,
|
||||
struct task_struct *task)
|
||||
{
|
||||
return __copy_to_user(to, task->thread.ckfp_state.fpr,
|
||||
ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
|
||||
inline unsigned long copy_ckfpr_from_user(struct task_struct *task,
|
||||
void __user *from)
|
||||
{
|
||||
return __copy_from_user(task->thread.ckfp_state.fpr, from,
|
||||
ELF_NFPREG * sizeof(double));
|
||||
}
|
||||
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Save the current user registers on the user stack.
|
||||
* We only save the altivec/spe registers if the process has used
|
||||
|
|
Loading…
Reference in New Issue