xref: /openbmc/linux/arch/powerpc/kernel/signal.h (revision a7d48886)
1 /*
2  *    Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation
3  *    Extracted from signal_32.c and signal_64.c
4  *
5  * This file is subject to the terms and conditions of the GNU General
6  * Public License.  See the file README.legal in the main directory of
7  * this archive for more details.
8  */
9 
10 #ifndef _POWERPC_ARCH_SIGNAL_H
11 #define _POWERPC_ARCH_SIGNAL_H
12 
13 void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
14 			  size_t frame_size, int is_32);
15 
16 extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
17 			   struct task_struct *tsk);
18 
19 extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
20 			      struct task_struct *tsk);
21 
22 #ifdef CONFIG_VSX
23 extern unsigned long copy_vsx_to_user(void __user *to,
24 				      struct task_struct *task);
25 extern unsigned long copy_ckvsx_to_user(void __user *to,
26 					       struct task_struct *task);
27 extern unsigned long copy_vsx_from_user(struct task_struct *task,
28 					void __user *from);
29 extern unsigned long copy_ckvsx_from_user(struct task_struct *task,
30 						 void __user *from);
31 unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
32 unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
33 unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
34 unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
35 
36 #define unsafe_copy_fpr_to_user(to, task, label)	do {		\
37 	struct task_struct *__t = task;					\
38 	u64 __user *buf = (u64 __user *)to;				\
39 	int i;								\
40 									\
41 	for (i = 0; i < ELF_NFPREG - 1 ; i++)				\
42 		unsafe_put_user(__t->thread.TS_FPR(i), &buf[i], label); \
43 	unsafe_put_user(__t->thread.fp_state.fpscr, &buf[i], label);	\
44 } while (0)
45 
46 #define unsafe_copy_vsx_to_user(to, task, label)	do {		\
47 	struct task_struct *__t = task;					\
48 	u64 __user *buf = (u64 __user *)to;				\
49 	int i;								\
50 									\
51 	for (i = 0; i < ELF_NVSRHALFREG ; i++)				\
52 		unsafe_put_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
53 				&buf[i], label);\
54 } while (0)
55 
56 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
57 #define unsafe_copy_ckfpr_to_user(to, task, label)	do {		\
58 	struct task_struct *__t = task;					\
59 	u64 __user *buf = (u64 __user *)to;				\
60 	int i;								\
61 									\
62 	for (i = 0; i < ELF_NFPREG - 1 ; i++)				\
63 		unsafe_put_user(__t->thread.TS_CKFPR(i), &buf[i], label);\
64 	unsafe_put_user(__t->thread.ckfp_state.fpscr, &buf[i], label);	\
65 } while (0)
66 
67 #define unsafe_copy_ckvsx_to_user(to, task, label)	do {		\
68 	struct task_struct *__t = task;					\
69 	u64 __user *buf = (u64 __user *)to;				\
70 	int i;								\
71 									\
72 	for (i = 0; i < ELF_NVSRHALFREG ; i++)				\
73 		unsafe_put_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
74 				&buf[i], label);\
75 } while (0)
76 #endif
77 #elif defined(CONFIG_PPC_FPU_REGS)
78 
79 #define unsafe_copy_fpr_to_user(to, task, label)		\
80 	unsafe_copy_to_user(to, (task)->thread.fp_state.fpr,	\
81 			    ELF_NFPREG * sizeof(double), label)
82 
83 static inline unsigned long
84 copy_fpr_to_user(void __user *to, struct task_struct *task)
85 {
86 	return __copy_to_user(to, task->thread.fp_state.fpr,
87 			      ELF_NFPREG * sizeof(double));
88 }
89 
90 static inline unsigned long
91 copy_fpr_from_user(struct task_struct *task, void __user *from)
92 {
93 	return __copy_from_user(task->thread.fp_state.fpr, from,
94 			      ELF_NFPREG * sizeof(double));
95 }
96 
97 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
98 #define unsafe_copy_ckfpr_to_user(to, task, label)		\
99 	unsafe_copy_to_user(to, (task)->thread.ckfp_state.fpr,	\
100 			    ELF_NFPREG * sizeof(double), label)
101 
102 inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task)
103 {
104 	return __copy_to_user(to, task->thread.ckfp_state.fpr,
105 			      ELF_NFPREG * sizeof(double));
106 }
107 
108 static inline unsigned long
109 copy_ckfpr_from_user(struct task_struct *task, void __user *from)
110 {
111 	return __copy_from_user(task->thread.ckfp_state.fpr, from,
112 				ELF_NFPREG * sizeof(double));
113 }
114 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
115 #else
116 #define unsafe_copy_fpr_to_user(to, task, label) do { } while (0)
117 
118 static inline unsigned long
119 copy_fpr_to_user(void __user *to, struct task_struct *task)
120 {
121 	return 0;
122 }
123 
124 static inline unsigned long
125 copy_fpr_from_user(struct task_struct *task, void __user *from)
126 {
127 	return 0;
128 }
129 #endif
130 
131 #ifdef CONFIG_PPC64
132 
133 extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
134 			      struct task_struct *tsk);
135 
136 #else /* CONFIG_PPC64 */
137 
138 extern long sys_rt_sigreturn(void);
139 extern long sys_sigreturn(void);
140 
141 static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
142 				     struct task_struct *tsk)
143 {
144 	return -EFAULT;
145 }
146 
147 #endif /* !defined(CONFIG_PPC64) */
148 
149 void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
150 		  const char *where, void __user *ptr);
151 
152 #endif  /* _POWERPC_ARCH_SIGNAL_H */
153