diff options
Diffstat (limited to 'arch/ia64/kernel/traps.c')
-rw-r--r-- | arch/ia64/kernel/traps.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 6d4e76a4267f..972873ed1ae5 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
@@ -104,6 +104,7 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | |||
104 | int sig, code; | 104 | int sig, code; |
105 | 105 | ||
106 | /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ | 106 | /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ |
107 | clear_siginfo(&siginfo); | ||
107 | siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); | 108 | siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); |
108 | siginfo.si_imm = break_num; | 109 | siginfo.si_imm = break_num; |
109 | siginfo.si_flags = 0; /* clear __ISR_VALID */ | 110 | siginfo.si_flags = 0; /* clear __ISR_VALID */ |
@@ -293,7 +294,6 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) | |||
293 | { | 294 | { |
294 | long exception, bundle[2]; | 295 | long exception, bundle[2]; |
295 | unsigned long fault_ip; | 296 | unsigned long fault_ip; |
296 | struct siginfo siginfo; | ||
297 | 297 | ||
298 | fault_ip = regs->cr_iip; | 298 | fault_ip = regs->cr_iip; |
299 | if (!fp_fault && (ia64_psr(regs)->ri == 0)) | 299 | if (!fp_fault && (ia64_psr(regs)->ri == 0)) |
@@ -344,10 +344,13 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) | |||
344 | printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n"); | 344 | printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n"); |
345 | return -1; | 345 | return -1; |
346 | } else { | 346 | } else { |
347 | struct siginfo siginfo; | ||
348 | |||
347 | /* is next instruction a trap? */ | 349 | /* is next instruction a trap? */ |
348 | if (exception & 2) { | 350 | if (exception & 2) { |
349 | ia64_increment_ip(regs); | 351 | ia64_increment_ip(regs); |
350 | } | 352 | } |
353 | clear_siginfo(&siginfo); | ||
351 | siginfo.si_signo = SIGFPE; | 354 | siginfo.si_signo = SIGFPE; |
352 | siginfo.si_errno = 0; | 355 | siginfo.si_errno = 0; |
353 | siginfo.si_code = FPE_FIXME; /* default code */ | 356 | siginfo.si_code = FPE_FIXME; /* default code */ |
@@ -372,6 +375,9 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) | |||
372 | return -1; | 375 | return -1; |
373 | } else if (exception != 0) { | 376 | } else if (exception != 0) { |
374 | /* raise exception */ | 377 | /* raise exception */ |
378 | struct siginfo siginfo; | ||
379 | |||
380 | clear_siginfo(&siginfo); | ||
375 | siginfo.si_signo = SIGFPE; | 381 | siginfo.si_signo = SIGFPE; |
376 | siginfo.si_errno = 0; | 382 | siginfo.si_errno = 0; |
377 | siginfo.si_code = FPE_FIXME; /* default code */ | 383 | siginfo.si_code = FPE_FIXME; /* default code */ |
@@ -420,7 +426,7 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3, | |||
420 | if (die_if_kernel(buf, ®s, 0)) | 426 | if (die_if_kernel(buf, ®s, 0)) |
421 | return rv; | 427 | return rv; |
422 | 428 | ||
423 | memset(&si, 0, sizeof(si)); | 429 | clear_siginfo(&si); |
424 | si.si_signo = SIGILL; | 430 | si.si_signo = SIGILL; |
425 | si.si_code = ILL_ILLOPC; | 431 | si.si_code = ILL_ILLOPC; |
426 | si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(®s)->ri); | 432 | si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(®s)->ri); |
@@ -434,7 +440,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
434 | long arg7, struct pt_regs regs) | 440 | long arg7, struct pt_regs regs) |
435 | { | 441 | { |
436 | unsigned long code, error = isr, iip; | 442 | unsigned long code, error = isr, iip; |
437 | struct siginfo siginfo; | ||
438 | char buf[128]; | 443 | char buf[128]; |
439 | int result, sig; | 444 | int result, sig; |
440 | static const char *reason[] = { | 445 | static const char *reason[] = { |
@@ -485,6 +490,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
485 | 490 | ||
486 | case 26: /* NaT Consumption */ | 491 | case 26: /* NaT Consumption */ |
487 | if (user_mode(®s)) { | 492 | if (user_mode(®s)) { |
493 | struct siginfo siginfo; | ||
488 | void __user *addr; | 494 | void __user *addr; |
489 | 495 | ||
490 | if (((isr >> 4) & 0xf) == 2) { | 496 | if (((isr >> 4) & 0xf) == 2) { |
@@ -499,6 +505,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
499 | addr = (void __user *) (regs.cr_iip | 505 | addr = (void __user *) (regs.cr_iip |
500 | + ia64_psr(®s)->ri); | 506 | + ia64_psr(®s)->ri); |
501 | } | 507 | } |
508 | clear_siginfo(&siginfo); | ||
502 | siginfo.si_signo = sig; | 509 | siginfo.si_signo = sig; |
503 | siginfo.si_code = code; | 510 | siginfo.si_code = code; |
504 | siginfo.si_errno = 0; | 511 | siginfo.si_errno = 0; |
@@ -515,6 +522,9 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
515 | 522 | ||
516 | case 31: /* Unsupported Data Reference */ | 523 | case 31: /* Unsupported Data Reference */ |
517 | if (user_mode(®s)) { | 524 | if (user_mode(®s)) { |
525 | struct siginfo siginfo; | ||
526 | |||
527 | clear_siginfo(&siginfo); | ||
518 | siginfo.si_signo = SIGILL; | 528 | siginfo.si_signo = SIGILL; |
519 | siginfo.si_code = ILL_ILLOPN; | 529 | siginfo.si_code = ILL_ILLOPN; |
520 | siginfo.si_errno = 0; | 530 | siginfo.si_errno = 0; |
@@ -531,6 +541,10 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
531 | case 29: /* Debug */ | 541 | case 29: /* Debug */ |
532 | case 35: /* Taken Branch Trap */ | 542 | case 35: /* Taken Branch Trap */ |
533 | case 36: /* Single Step Trap */ | 543 | case 36: /* Single Step Trap */ |
544 | { | ||
545 | struct siginfo siginfo; | ||
546 | |||
547 | clear_siginfo(&siginfo); | ||
534 | if (fsys_mode(current, ®s)) { | 548 | if (fsys_mode(current, ®s)) { |
535 | extern char __kernel_syscall_via_break[]; | 549 | extern char __kernel_syscall_via_break[]; |
536 | /* | 550 | /* |
@@ -578,11 +592,15 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
578 | siginfo.si_isr = isr; | 592 | siginfo.si_isr = isr; |
579 | force_sig_info(SIGTRAP, &siginfo, current); | 593 | force_sig_info(SIGTRAP, &siginfo, current); |
580 | return; | 594 | return; |
595 | } | ||
581 | 596 | ||
582 | case 32: /* fp fault */ | 597 | case 32: /* fp fault */ |
583 | case 33: /* fp trap */ | 598 | case 33: /* fp trap */ |
584 | result = handle_fpu_swa((vector == 32) ? 1 : 0, ®s, isr); | 599 | result = handle_fpu_swa((vector == 32) ? 1 : 0, ®s, isr); |
585 | if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) { | 600 | if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) { |
601 | struct siginfo siginfo; | ||
602 | |||
603 | clear_siginfo(&siginfo); | ||
586 | siginfo.si_signo = SIGFPE; | 604 | siginfo.si_signo = SIGFPE; |
587 | siginfo.si_errno = 0; | 605 | siginfo.si_errno = 0; |
588 | siginfo.si_code = FPE_FLTINV; | 606 | siginfo.si_code = FPE_FLTINV; |
@@ -616,6 +634,9 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
616 | } else { | 634 | } else { |
617 | /* Unimplemented Instr. Address Trap */ | 635 | /* Unimplemented Instr. Address Trap */ |
618 | if (user_mode(®s)) { | 636 | if (user_mode(®s)) { |
637 | struct siginfo siginfo; | ||
638 | |||
639 | clear_siginfo(&siginfo); | ||
619 | siginfo.si_signo = SIGILL; | 640 | siginfo.si_signo = SIGILL; |
620 | siginfo.si_code = ILL_BADIADDR; | 641 | siginfo.si_code = ILL_BADIADDR; |
621 | siginfo.si_errno = 0; | 642 | siginfo.si_errno = 0; |