aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile/kernel/signal.c')
-rw-r--r--arch/tile/kernel/signal.c54
1 files changed, 24 insertions, 30 deletions
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index d1d026f01267..7c2fecc52177 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -153,18 +153,18 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
153 return (void __user *) sp; 153 return (void __user *) sp;
154} 154}
155 155
156static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 156static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
157 sigset_t *set, struct pt_regs *regs) 157 struct pt_regs *regs)
158{ 158{
159 unsigned long restorer; 159 unsigned long restorer;
160 struct rt_sigframe __user *frame; 160 struct rt_sigframe __user *frame;
161 int err = 0; 161 int err = 0, sig = ksig->sig;
162 int usig; 162 int usig;
163 163
164 frame = get_sigframe(ka, regs, sizeof(*frame)); 164 frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
165 165
166 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 166 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
167 goto give_sigsegv; 167 goto err;
168 168
169 usig = current_thread_info()->exec_domain 169 usig = current_thread_info()->exec_domain
170 && current_thread_info()->exec_domain->signal_invmap 170 && current_thread_info()->exec_domain->signal_invmap
@@ -173,12 +173,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
173 : sig; 173 : sig;
174 174
175 /* Always write at least the signal number for the stack backtracer. */ 175 /* Always write at least the signal number for the stack backtracer. */
176 if (ka->sa.sa_flags & SA_SIGINFO) { 176 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
177 /* At sigreturn time, restore the callee-save registers too. */ 177 /* At sigreturn time, restore the callee-save registers too. */
178 err |= copy_siginfo_to_user(&frame->info, info); 178 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
179 regs->flags |= PT_FLAGS_RESTORE_REGS; 179 regs->flags |= PT_FLAGS_RESTORE_REGS;
180 } else { 180 } else {
181 err |= __put_user(info->si_signo, &frame->info.si_signo); 181 err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
182 } 182 }
183 183
184 /* Create the ucontext. */ 184 /* Create the ucontext. */
@@ -189,11 +189,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
189 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); 189 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
190 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 190 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
191 if (err) 191 if (err)
192 goto give_sigsegv; 192 goto err;
193 193
194 restorer = VDSO_SYM(&__vdso_rt_sigreturn); 194 restorer = VDSO_SYM(&__vdso_rt_sigreturn);
195 if (ka->sa.sa_flags & SA_RESTORER) 195 if (ksig->ka.sa.sa_flags & SA_RESTORER)
196 restorer = (unsigned long) ka->sa.sa_restorer; 196 restorer = (unsigned long) ksig->ka.sa.sa_restorer;
197 197
198 /* 198 /*
199 * Set up registers for signal handler. 199 * Set up registers for signal handler.
@@ -202,7 +202,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
202 * We always pass siginfo and mcontext, regardless of SA_SIGINFO, 202 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
203 * since some things rely on this (e.g. glibc's debug/segfault.c). 203 * since some things rely on this (e.g. glibc's debug/segfault.c).
204 */ 204 */
205 regs->pc = (unsigned long) ka->sa.sa_handler; 205 regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
206 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ 206 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
207 regs->sp = (unsigned long) frame; 207 regs->sp = (unsigned long) frame;
208 regs->lr = restorer; 208 regs->lr = restorer;
@@ -212,8 +212,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
212 regs->flags |= PT_FLAGS_CALLER_SAVES; 212 regs->flags |= PT_FLAGS_CALLER_SAVES;
213 return 0; 213 return 0;
214 214
215give_sigsegv: 215err:
216 signal_fault("bad setup frame", regs, frame, sig); 216 trace_unhandled_signal("bad sigreturn frame", regs,
217 (unsigned long)frame, SIGSEGV);
217 return -EFAULT; 218 return -EFAULT;
218} 219}
219 220
@@ -221,9 +222,7 @@ give_sigsegv:
221 * OK, we're invoking a handler 222 * OK, we're invoking a handler
222 */ 223 */
223 224
224static void handle_signal(unsigned long sig, siginfo_t *info, 225static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
225 struct k_sigaction *ka,
226 struct pt_regs *regs)
227{ 226{
228 sigset_t *oldset = sigmask_to_save(); 227 sigset_t *oldset = sigmask_to_save();
229 int ret; 228 int ret;
@@ -238,7 +237,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
238 break; 237 break;
239 238
240 case -ERESTARTSYS: 239 case -ERESTARTSYS:
241 if (!(ka->sa.sa_flags & SA_RESTART)) { 240 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
242 regs->regs[0] = -EINTR; 241 regs->regs[0] = -EINTR;
243 break; 242 break;
244 } 243 }
@@ -254,14 +253,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
254 /* Set up the stack frame */ 253 /* Set up the stack frame */
255#ifdef CONFIG_COMPAT 254#ifdef CONFIG_COMPAT
256 if (is_compat_task()) 255 if (is_compat_task())
257 ret = compat_setup_rt_frame(sig, ka, info, oldset, regs); 256 ret = compat_setup_rt_frame(ksig, oldset, regs);
258 else 257 else
259#endif 258#endif
260 ret = setup_rt_frame(sig, ka, info, oldset, regs); 259 ret = setup_rt_frame(ksig, oldset, regs);
261 if (ret) 260
262 return; 261 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
263 signal_delivered(sig, info, ka, regs,
264 test_thread_flag(TIF_SINGLESTEP));
265} 262}
266 263
267/* 264/*
@@ -271,9 +268,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
271 */ 268 */
272void do_signal(struct pt_regs *regs) 269void do_signal(struct pt_regs *regs)
273{ 270{
274 siginfo_t info; 271 struct ksignal ksig;
275 int signr;
276 struct k_sigaction ka;
277 272
278 /* 273 /*
279 * i386 will check if we're coming from kernel mode and bail out 274 * i386 will check if we're coming from kernel mode and bail out
@@ -282,10 +277,9 @@ void do_signal(struct pt_regs *regs)
282 * helpful, we can reinstate the check on "!user_mode(regs)". 277 * helpful, we can reinstate the check on "!user_mode(regs)".
283 */ 278 */
284 279
285 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 280 if (get_signal(&ksig)) {
286 if (signr > 0) {
287 /* Whee! Actually deliver the signal. */ 281 /* Whee! Actually deliver the signal. */
288 handle_signal(signr, &info, &ka, regs); 282 handle_signal(&ksig, regs);
289 goto done; 283 goto done;
290 } 284 }
291 285