Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *    Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation
0003  *    Extracted from signal_32.c and signal_64.c
0004  *
0005  * This file is subject to the terms and conditions of the GNU General
0006  * Public License.  See the file README.legal in the main directory of
0007  * this archive for more details.
0008  */
0009 
0010 #ifndef _POWERPC_ARCH_SIGNAL_H
0011 #define _POWERPC_ARCH_SIGNAL_H
0012 
0013 void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
0014               size_t frame_size, int is_32);
0015 
0016 extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
0017                struct task_struct *tsk);
0018 
0019 extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
0020                   struct task_struct *tsk);
0021 
0022 static inline int __get_user_sigset(sigset_t *dst, const sigset_t __user *src)
0023 {
0024     BUILD_BUG_ON(sizeof(sigset_t) != sizeof(u64));
0025 
0026     return __get_user(dst->sig[0], (u64 __user *)&src->sig[0]);
0027 }
0028 #define unsafe_get_user_sigset(dst, src, label) do {            \
0029     sigset_t *__dst = dst;                      \
0030     const sigset_t __user *__src = src;             \
0031     int i;                              \
0032                                     \
0033     for (i = 0; i < _NSIG_WORDS; i++)               \
0034         unsafe_get_user(__dst->sig[i], &__src->sig[i], label);  \
0035 } while (0)
0036 
0037 #ifdef CONFIG_VSX
0038 extern unsigned long copy_vsx_to_user(void __user *to,
0039                       struct task_struct *task);
0040 extern unsigned long copy_ckvsx_to_user(void __user *to,
0041                            struct task_struct *task);
0042 extern unsigned long copy_vsx_from_user(struct task_struct *task,
0043                     void __user *from);
0044 extern unsigned long copy_ckvsx_from_user(struct task_struct *task,
0045                          void __user *from);
0046 unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
0047 unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
0048 unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
0049 unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
0050 
0051 #define unsafe_copy_fpr_to_user(to, task, label)    do {        \
0052     struct task_struct *__t = task;                 \
0053     u64 __user *buf = (u64 __user *)to;             \
0054     int i;                              \
0055                                     \
0056     for (i = 0; i < ELF_NFPREG - 1 ; i++)               \
0057         unsafe_put_user(__t->thread.TS_FPR(i), &buf[i], label); \
0058     unsafe_put_user(__t->thread.fp_state.fpscr, &buf[i], label);    \
0059 } while (0)
0060 
0061 #define unsafe_copy_vsx_to_user(to, task, label)    do {        \
0062     struct task_struct *__t = task;                 \
0063     u64 __user *buf = (u64 __user *)to;             \
0064     int i;                              \
0065                                     \
0066     for (i = 0; i < ELF_NVSRHALFREG ; i++)              \
0067         unsafe_put_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
0068                 &buf[i], label);\
0069 } while (0)
0070 
0071 #define unsafe_copy_fpr_from_user(task, from, label)    do {        \
0072     struct task_struct *__t = task;                 \
0073     u64 __user *buf = (u64 __user *)from;               \
0074     int i;                              \
0075                                     \
0076     for (i = 0; i < ELF_NFPREG - 1; i++)                \
0077         unsafe_get_user(__t->thread.TS_FPR(i), &buf[i], label); \
0078     unsafe_get_user(__t->thread.fp_state.fpscr, &buf[i], label);    \
0079 } while (0)
0080 
0081 #define unsafe_copy_vsx_from_user(task, from, label)    do {        \
0082     struct task_struct *__t = task;                 \
0083     u64 __user *buf = (u64 __user *)from;               \
0084     int i;                              \
0085                                     \
0086     for (i = 0; i < ELF_NVSRHALFREG ; i++)              \
0087         unsafe_get_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
0088                 &buf[i], label);            \
0089 } while (0)
0090 
0091 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
0092 #define unsafe_copy_ckfpr_to_user(to, task, label)  do {        \
0093     struct task_struct *__t = task;                 \
0094     u64 __user *buf = (u64 __user *)to;             \
0095     int i;                              \
0096                                     \
0097     for (i = 0; i < ELF_NFPREG - 1 ; i++)               \
0098         unsafe_put_user(__t->thread.TS_CKFPR(i), &buf[i], label);\
0099     unsafe_put_user(__t->thread.ckfp_state.fpscr, &buf[i], label);  \
0100 } while (0)
0101 
0102 #define unsafe_copy_ckvsx_to_user(to, task, label)  do {        \
0103     struct task_struct *__t = task;                 \
0104     u64 __user *buf = (u64 __user *)to;             \
0105     int i;                              \
0106                                     \
0107     for (i = 0; i < ELF_NVSRHALFREG ; i++)              \
0108         unsafe_put_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
0109                 &buf[i], label);\
0110 } while (0)
0111 
0112 #define unsafe_copy_ckfpr_from_user(task, from, label)  do {        \
0113     struct task_struct *__t = task;                 \
0114     u64 __user *buf = (u64 __user *)from;               \
0115     int i;                              \
0116                                     \
0117     for (i = 0; i < ELF_NFPREG - 1 ; i++)               \
0118         unsafe_get_user(__t->thread.TS_CKFPR(i), &buf[i], label);\
0119     unsafe_get_user(__t->thread.ckfp_state.fpscr, &buf[i], failed); \
0120 } while (0)
0121 
0122 #define unsafe_copy_ckvsx_from_user(task, from, label)  do {        \
0123     struct task_struct *__t = task;                 \
0124     u64 __user *buf = (u64 __user *)from;               \
0125     int i;                              \
0126                                     \
0127     for (i = 0; i < ELF_NVSRHALFREG ; i++)              \
0128         unsafe_get_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
0129                 &buf[i], label);            \
0130 } while (0)
0131 #endif
0132 #elif defined(CONFIG_PPC_FPU_REGS)
0133 
0134 #define unsafe_copy_fpr_to_user(to, task, label)        \
0135     unsafe_copy_to_user(to, (task)->thread.fp_state.fpr,    \
0136                 ELF_NFPREG * sizeof(double), label)
0137 
0138 #define unsafe_copy_fpr_from_user(task, from, label)            \
0139     unsafe_copy_from_user((task)->thread.fp_state.fpr, from,    \
0140                 ELF_NFPREG * sizeof(double), label)
0141 
0142 static inline unsigned long
0143 copy_fpr_to_user(void __user *to, struct task_struct *task)
0144 {
0145     return __copy_to_user(to, task->thread.fp_state.fpr,
0146                   ELF_NFPREG * sizeof(double));
0147 }
0148 
0149 static inline unsigned long
0150 copy_fpr_from_user(struct task_struct *task, void __user *from)
0151 {
0152     return __copy_from_user(task->thread.fp_state.fpr, from,
0153                   ELF_NFPREG * sizeof(double));
0154 }
0155 
0156 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
0157 #define unsafe_copy_ckfpr_to_user(to, task, label)      \
0158     unsafe_copy_to_user(to, (task)->thread.ckfp_state.fpr,  \
0159                 ELF_NFPREG * sizeof(double), label)
0160 
0161 inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task)
0162 {
0163     return __copy_to_user(to, task->thread.ckfp_state.fpr,
0164                   ELF_NFPREG * sizeof(double));
0165 }
0166 
0167 static inline unsigned long
0168 copy_ckfpr_from_user(struct task_struct *task, void __user *from)
0169 {
0170     return __copy_from_user(task->thread.ckfp_state.fpr, from,
0171                 ELF_NFPREG * sizeof(double));
0172 }
0173 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
0174 #else
0175 #define unsafe_copy_fpr_to_user(to, task, label) do { if (0) goto label;} while (0)
0176 
0177 #define unsafe_copy_fpr_from_user(task, from, label) do { if (0) goto label;} while (0)
0178 
0179 static inline unsigned long
0180 copy_fpr_to_user(void __user *to, struct task_struct *task)
0181 {
0182     return 0;
0183 }
0184 
0185 static inline unsigned long
0186 copy_fpr_from_user(struct task_struct *task, void __user *from)
0187 {
0188     return 0;
0189 }
0190 #endif
0191 
0192 #ifdef CONFIG_PPC64
0193 
0194 extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
0195                   struct task_struct *tsk);
0196 
0197 #else /* CONFIG_PPC64 */
0198 
0199 extern long sys_rt_sigreturn(void);
0200 extern long sys_sigreturn(void);
0201 
0202 static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
0203                      struct task_struct *tsk)
0204 {
0205     return -EFAULT;
0206 }
0207 
0208 #endif /* !defined(CONFIG_PPC64) */
0209 
0210 void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
0211           const char *where, void __user *ptr);
0212 
0213 #endif  /* _POWERPC_ARCH_SIGNAL_H */