0001
0002
0003
0004
0005
0006
0007
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
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
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
0209
0210 void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
0211 const char *where, void __user *ptr);
0212
0213 #endif