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
2 changed files with 141 additions and 140 deletions
|
@ -18,12 +18,153 @@
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <asm/hw_breakpoint.h>
|
#include <asm/hw_breakpoint.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
#include <asm/switch_to.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
#include <asm/debug.h>
|
#include <asm/debug.h>
|
||||||
#include <asm/tm.h>
|
#include <asm/tm.h>
|
||||||
|
|
||||||
#include "signal.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
|
/* Log an error when sending an unhandled signal to a process. Controlled
|
||||||
* through debug.exception-trace sysctl.
|
* through debug.exception-trace sysctl.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -235,146 +235,6 @@ struct rt_sigframe {
|
||||||
int abigap[56];
|
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.
|
* Save the current user registers on the user stack.
|
||||||
* We only save the altivec/spe registers if the process has used
|
* We only save the altivec/spe registers if the process has used
|
||||||
|
|
Loading…
Add table
Reference in a new issue