aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv/kernel
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2013-10-07 07:46:11 -0400
committerRichard Weinberger <richard@sigma-star.at>2014-08-06 07:02:13 -0400
commit720f36b983224ac52b6acdd8b646ce30f6b38763 (patch)
treed02876a34287f19186842d182d742e3ccf20a735 /arch/frv/kernel
parentfa0197722eb7559a6a9733881bbb8d9e76364f33 (diff)
frv: Use get_signal() signal_setup_done()
Use the more generic functions get_signal() signal_setup_done() for signal delivery. Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/frv/kernel')
-rw-r--r--arch/frv/kernel/signal.c99
1 files changed, 40 insertions, 59 deletions
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index d822700d4f15..8e37cf237e6d 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -180,17 +180,17 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
180/* 180/*
181 * 181 *
182 */ 182 */
183static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) 183static int setup_frame(struct ksignal *ksig, sigset_t *set)
184{ 184{
185 struct sigframe __user *frame; 185 struct sigframe __user *frame;
186 int rsig; 186 int rsig, sig = ksig->sig;
187 187
188 set_fs(USER_DS); 188 set_fs(USER_DS);
189 189
190 frame = get_sigframe(ka, sizeof(*frame)); 190 frame = get_sigframe(&ksig->ka, sizeof(*frame));
191 191
192 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 192 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
193 goto give_sigsegv; 193 return -EFAULT;
194 194
195 rsig = sig; 195 rsig = sig;
196 if (sig < 32 && 196 if (sig < 32 &&
@@ -199,22 +199,22 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
199 rsig = __current_thread_info->exec_domain->signal_invmap[sig]; 199 rsig = __current_thread_info->exec_domain->signal_invmap[sig];
200 200
201 if (__put_user(rsig, &frame->sig) < 0) 201 if (__put_user(rsig, &frame->sig) < 0)
202 goto give_sigsegv; 202 return -EFAULT;
203 203
204 if (setup_sigcontext(&frame->sc, set->sig[0])) 204 if (setup_sigcontext(&frame->sc, set->sig[0]))
205 goto give_sigsegv; 205 return -EFAULT;
206 206
207 if (_NSIG_WORDS > 1) { 207 if (_NSIG_WORDS > 1) {
208 if (__copy_to_user(frame->extramask, &set->sig[1], 208 if (__copy_to_user(frame->extramask, &set->sig[1],
209 sizeof(frame->extramask))) 209 sizeof(frame->extramask)))
210 goto give_sigsegv; 210 return -EFAULT;
211 } 211 }
212 212
213 /* Set up to return from userspace. If provided, use a stub 213 /* Set up to return from userspace. If provided, use a stub
214 * already in userspace. */ 214 * already in userspace. */
215 if (ka->sa.sa_flags & SA_RESTORER) { 215 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
216 if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0) 216 if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode) < 0)
217 goto give_sigsegv; 217 return -EFAULT;
218 } 218 }
219 else { 219 else {
220 /* Set up the following code on the stack: 220 /* Set up the following code on the stack:
@@ -224,7 +224,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
224 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || 224 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
225 __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) || 225 __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
226 __put_user(0xc0700000, &frame->retcode[1])) 226 __put_user(0xc0700000, &frame->retcode[1]))
227 goto give_sigsegv; 227 return -EFAULT;
228 228
229 flush_icache_range((unsigned long) frame->retcode, 229 flush_icache_range((unsigned long) frame->retcode,
230 (unsigned long) (frame->retcode + 2)); 230 (unsigned long) (frame->retcode + 2));
@@ -233,14 +233,14 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
233 /* Set up registers for the signal handler */ 233 /* Set up registers for the signal handler */
234 if (current->personality & FDPIC_FUNCPTRS) { 234 if (current->personality & FDPIC_FUNCPTRS) {
235 struct fdpic_func_descriptor __user *funcptr = 235 struct fdpic_func_descriptor __user *funcptr =
236 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 236 (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler;
237 struct fdpic_func_descriptor desc; 237 struct fdpic_func_descriptor desc;
238 if (copy_from_user(&desc, funcptr, sizeof(desc))) 238 if (copy_from_user(&desc, funcptr, sizeof(desc)))
239 goto give_sigsegv; 239 return -EFAULT;
240 __frame->pc = desc.text; 240 __frame->pc = desc.text;
241 __frame->gr15 = desc.GOT; 241 __frame->gr15 = desc.GOT;
242 } else { 242 } else {
243 __frame->pc = (unsigned long) ka->sa.sa_handler; 243 __frame->pc = (unsigned long) ksig->ka.sa.sa_handler;
244 __frame->gr15 = 0; 244 __frame->gr15 = 0;
245 } 245 }
246 246
@@ -255,29 +255,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
255#endif 255#endif
256 256
257 return 0; 257 return 0;
258
259give_sigsegv:
260 force_sigsegv(sig, current);
261 return -EFAULT;
262
263} /* end setup_frame() */ 258} /* end setup_frame() */
264 259
265/*****************************************************************************/ 260/*****************************************************************************/
266/* 261/*
267 * 262 *
268 */ 263 */
269static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 264static int setup_rt_frame(struct ksignal *ksig, sigset_t *set)
270 sigset_t *set)
271{ 265{
272 struct rt_sigframe __user *frame; 266 struct rt_sigframe __user *frame;
273 int rsig; 267 int rsig, sig = ksig->sig;
274 268
275 set_fs(USER_DS); 269 set_fs(USER_DS);
276 270
277 frame = get_sigframe(ka, sizeof(*frame)); 271 frame = get_sigframe(&ksig->ka, sizeof(*frame));
278 272
279 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 273 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
280 goto give_sigsegv; 274 return -EFAULT;
281 275
282 rsig = sig; 276 rsig = sig;
283 if (sig < 32 && 277 if (sig < 32 &&
@@ -288,28 +282,28 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
288 if (__put_user(rsig, &frame->sig) || 282 if (__put_user(rsig, &frame->sig) ||
289 __put_user(&frame->info, &frame->pinfo) || 283 __put_user(&frame->info, &frame->pinfo) ||
290 __put_user(&frame->uc, &frame->puc)) 284 __put_user(&frame->uc, &frame->puc))
291 goto give_sigsegv; 285 return -EFAULT;
292 286
293 if (copy_siginfo_to_user(&frame->info, info)) 287 if (copy_siginfo_to_user(&frame->info, &ksig->info))
294 goto give_sigsegv; 288 return -EFAULT;
295 289
296 /* Create the ucontext. */ 290 /* Create the ucontext. */
297 if (__put_user(0, &frame->uc.uc_flags) || 291 if (__put_user(0, &frame->uc.uc_flags) ||
298 __put_user(NULL, &frame->uc.uc_link) || 292 __put_user(NULL, &frame->uc.uc_link) ||
299 __save_altstack(&frame->uc.uc_stack, __frame->sp)) 293 __save_altstack(&frame->uc.uc_stack, __frame->sp))
300 goto give_sigsegv; 294 return -EFAULT;
301 295
302 if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0])) 296 if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
303 goto give_sigsegv; 297 return -EFAULT;
304 298
305 if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set))) 299 if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
306 goto give_sigsegv; 300 return -EFAULT;
307 301
308 /* Set up to return from userspace. If provided, use a stub 302 /* Set up to return from userspace. If provided, use a stub
309 * already in userspace. */ 303 * already in userspace. */
310 if (ka->sa.sa_flags & SA_RESTORER) { 304 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
311 if (__put_user(ka->sa.sa_restorer, &frame->pretcode)) 305 if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
312 goto give_sigsegv; 306 return -EFAULT;
313 } 307 }
314 else { 308 else {
315 /* Set up the following code on the stack: 309 /* Set up the following code on the stack:
@@ -319,7 +313,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
319 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || 313 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
320 __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) || 314 __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
321 __put_user(0xc0700000, &frame->retcode[1])) 315 __put_user(0xc0700000, &frame->retcode[1]))
322 goto give_sigsegv; 316 return -EFAULT;
323 317
324 flush_icache_range((unsigned long) frame->retcode, 318 flush_icache_range((unsigned long) frame->retcode,
325 (unsigned long) (frame->retcode + 2)); 319 (unsigned long) (frame->retcode + 2));
@@ -328,14 +322,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
328 /* Set up registers for signal handler */ 322 /* Set up registers for signal handler */
329 if (current->personality & FDPIC_FUNCPTRS) { 323 if (current->personality & FDPIC_FUNCPTRS) {
330 struct fdpic_func_descriptor __user *funcptr = 324 struct fdpic_func_descriptor __user *funcptr =
331 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 325 (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler;
332 struct fdpic_func_descriptor desc; 326 struct fdpic_func_descriptor desc;
333 if (copy_from_user(&desc, funcptr, sizeof(desc))) 327 if (copy_from_user(&desc, funcptr, sizeof(desc)))
334 goto give_sigsegv; 328 return -EFAULT;
335 __frame->pc = desc.text; 329 __frame->pc = desc.text;
336 __frame->gr15 = desc.GOT; 330 __frame->gr15 = desc.GOT;
337 } else { 331 } else {
338 __frame->pc = (unsigned long) ka->sa.sa_handler; 332 __frame->pc = (unsigned long) ksig->ka.sa.sa_handler;
339 __frame->gr15 = 0; 333 __frame->gr15 = 0;
340 } 334 }
341 335
@@ -349,21 +343,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
349 sig, current->comm, current->pid, frame, __frame->pc, 343 sig, current->comm, current->pid, frame, __frame->pc,
350 frame->pretcode); 344 frame->pretcode);
351#endif 345#endif
352
353 return 0; 346 return 0;
354 347
355give_sigsegv:
356 force_sigsegv(sig, current);
357 return -EFAULT;
358
359} /* end setup_rt_frame() */ 348} /* end setup_rt_frame() */
360 349
361/*****************************************************************************/ 350/*****************************************************************************/
362/* 351/*
363 * OK, we're invoking a handler 352 * OK, we're invoking a handler
364 */ 353 */
365static void handle_signal(unsigned long sig, siginfo_t *info, 354static void handle_signal(struct ksignal *ksig)
366 struct k_sigaction *ka)
367{ 355{
368 sigset_t *oldset = sigmask_to_save(); 356 sigset_t *oldset = sigmask_to_save();
369 int ret; 357 int ret;
@@ -378,7 +366,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
378 break; 366 break;
379 367
380 case -ERESTARTSYS: 368 case -ERESTARTSYS:
381 if (!(ka->sa.sa_flags & SA_RESTART)) { 369 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
382 __frame->gr8 = -EINTR; 370 __frame->gr8 = -EINTR;
383 break; 371 break;
384 } 372 }
@@ -392,16 +380,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
392 } 380 }
393 381
394 /* Set up the stack frame */ 382 /* Set up the stack frame */
395 if (ka->sa.sa_flags & SA_SIGINFO) 383 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
396 ret = setup_rt_frame(sig, ka, info, oldset); 384 ret = setup_rt_frame(ksig, oldset);
397 else 385 else
398 ret = setup_frame(sig, ka, oldset); 386 ret = setup_frame(ksig, oldset);
399
400 if (ret)
401 return;
402 387
403 signal_delivered(sig, info, ka, __frame, 388 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
404 test_thread_flag(TIF_SINGLESTEP));
405} /* end handle_signal() */ 389} /* end handle_signal() */
406 390
407/*****************************************************************************/ 391/*****************************************************************************/
@@ -412,13 +396,10 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
412 */ 396 */
413static void do_signal(void) 397static void do_signal(void)
414{ 398{
415 struct k_sigaction ka; 399 struct ksignal ksig;
416 siginfo_t info;
417 int signr;
418 400
419 signr = get_signal_to_deliver(&info, &ka, __frame, NULL); 401 if (get_signal(&ksig)) {
420 if (signr > 0) { 402 handle_signal(&ksig);
421 handle_signal(signr, &info, &ka);
422 return; 403 return;
423 } 404 }
424 405