aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2018-04-17 18:39:29 -0400
committerEric W. Biederman <ebiederm@xmission.com>2018-09-27 15:58:18 -0400
commita618a2754ce6037beabe770aa01ae5ca97a0d65e (patch)
tree33373f9075f74688e52186fbdc23c678a9e348d8
parentb92adb74adde62d9a9780ff2977d63dcb21aeaa6 (diff)
signal/ia64: Use force_sig_fault where appropriate
Acked-by: Tony Luck <tony.luck@intel.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
-rw-r--r--arch/ia64/kernel/brl_emu.c31
-rw-r--r--arch/ia64/kernel/traps.c144
-rw-r--r--arch/ia64/kernel/unaligned.c12
-rw-r--r--arch/ia64/mm/fault.c12
4 files changed, 49 insertions, 150 deletions
diff --git a/arch/ia64/kernel/brl_emu.c b/arch/ia64/kernel/brl_emu.c
index a61f6c6a36f8..c0239bf77a09 100644
--- a/arch/ia64/kernel/brl_emu.c
+++ b/arch/ia64/kernel/brl_emu.c
@@ -58,11 +58,9 @@ ia64_emulate_brl (struct pt_regs *regs, unsigned long ar_ec)
58 unsigned long bundle[2]; 58 unsigned long bundle[2];
59 unsigned long opcode, btype, qp, offset, cpl; 59 unsigned long opcode, btype, qp, offset, cpl;
60 unsigned long next_ip; 60 unsigned long next_ip;
61 struct siginfo siginfo;
62 struct illegal_op_return rv; 61 struct illegal_op_return rv;
63 long tmp_taken, unimplemented_address; 62 long tmp_taken, unimplemented_address;
64 63
65 clear_siginfo(&siginfo);
66 rv.fkt = (unsigned long) -1; 64 rv.fkt = (unsigned long) -1;
67 65
68 /* 66 /*
@@ -198,39 +196,22 @@ ia64_emulate_brl (struct pt_regs *regs, unsigned long ar_ec)
198 * The target address contains unimplemented bits. 196 * The target address contains unimplemented bits.
199 */ 197 */
200 printk(KERN_DEBUG "Woah! Unimplemented Instruction Address Trap!\n"); 198 printk(KERN_DEBUG "Woah! Unimplemented Instruction Address Trap!\n");
201 siginfo.si_signo = SIGILL; 199 force_sig_fault(SIGILL, ILL_BADIADDR, (void __user *)NULL,
202 siginfo.si_errno = 0; 200 0, 0, 0, current);
203 siginfo.si_flags = 0;
204 siginfo.si_isr = 0;
205 siginfo.si_imm = 0;
206 siginfo.si_code = ILL_BADIADDR;
207 force_sig_info(SIGILL, &siginfo, current);
208 } else if (ia64_psr(regs)->tb) { 201 } else if (ia64_psr(regs)->tb) {
209 /* 202 /*
210 * Branch Tracing is enabled. 203 * Branch Tracing is enabled.
211 * Force a taken branch signal. 204 * Force a taken branch signal.
212 */ 205 */
213 siginfo.si_signo = SIGTRAP; 206 force_sig_fault(SIGTRAP, TRAP_BRANCH, (void __user *)NULL,
214 siginfo.si_errno = 0; 207 0, 0, 0, current);
215 siginfo.si_code = TRAP_BRANCH;
216 siginfo.si_flags = 0;
217 siginfo.si_isr = 0;
218 siginfo.si_addr = 0;
219 siginfo.si_imm = 0;
220 force_sig_info(SIGTRAP, &siginfo, current);
221 } else if (ia64_psr(regs)->ss) { 208 } else if (ia64_psr(regs)->ss) {
222 /* 209 /*
223 * Single Step is enabled. 210 * Single Step is enabled.
224 * Force a trace signal. 211 * Force a trace signal.
225 */ 212 */
226 siginfo.si_signo = SIGTRAP; 213 force_sig_fault(SIGTRAP, TRAP_TRACE, (void __user *)NULL,
227 siginfo.si_errno = 0; 214 0, 0, 0, current);
228 siginfo.si_code = TRAP_TRACE;
229 siginfo.si_flags = 0;
230 siginfo.si_isr = 0;
231 siginfo.si_addr = 0;
232 siginfo.si_imm = 0;
233 force_sig_info(SIGTRAP, &siginfo, current);
234 } 215 }
235 return rv; 216 return rv;
236} 217}
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index c6f4932073a1..85d8616ac4f6 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -100,16 +100,8 @@ die_if_kernel (char *str, struct pt_regs *regs, long err)
100void 100void
101__kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) 101__kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
102{ 102{
103 siginfo_t siginfo;
104 int sig, code; 103 int sig, code;
105 104
106 /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
107 clear_siginfo(&siginfo);
108 siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
109 siginfo.si_imm = break_num;
110 siginfo.si_flags = 0; /* clear __ISR_VALID */
111 siginfo.si_isr = 0;
112
113 switch (break_num) { 105 switch (break_num) {
114 case 0: /* unknown error (used by GCC for __builtin_abort()) */ 106 case 0: /* unknown error (used by GCC for __builtin_abort()) */
115 if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) 107 if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
@@ -182,10 +174,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
182 sig = SIGTRAP; code = TRAP_BRKPT; 174 sig = SIGTRAP; code = TRAP_BRKPT;
183 } 175 }
184 } 176 }
185 siginfo.si_signo = sig; 177 force_sig_fault(sig, code,
186 siginfo.si_errno = 0; 178 (void __user *) (regs->cr_iip + ia64_psr(regs)->ri),
187 siginfo.si_code = code; 179 break_num, 0 /* clear __ISR_VALID */, 0, current);
188 force_sig_info(sig, &siginfo, current);
189} 180}
190 181
191/* 182/*
@@ -344,30 +335,25 @@ 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"); 335 printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
345 return -1; 336 return -1;
346 } else { 337 } else {
347 struct siginfo siginfo;
348
349 /* is next instruction a trap? */ 338 /* is next instruction a trap? */
339 int si_code;
340
350 if (exception & 2) { 341 if (exception & 2) {
351 ia64_increment_ip(regs); 342 ia64_increment_ip(regs);
352 } 343 }
353 clear_siginfo(&siginfo); 344 si_code = FPE_FLTUNK; /* default code */
354 siginfo.si_signo = SIGFPE;
355 siginfo.si_errno = 0;
356 siginfo.si_code = FPE_FLTUNK; /* default code */
357 siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
358 if (isr & 0x11) { 345 if (isr & 0x11) {
359 siginfo.si_code = FPE_FLTINV; 346 si_code = FPE_FLTINV;
360 } else if (isr & 0x22) { 347 } else if (isr & 0x22) {
361 /* denormal operand gets the same si_code as underflow 348 /* denormal operand gets the same si_code as underflow
362 * see arch/i386/kernel/traps.c:math_error() */ 349 * see arch/i386/kernel/traps.c:math_error() */
363 siginfo.si_code = FPE_FLTUND; 350 si_code = FPE_FLTUND;
364 } else if (isr & 0x44) { 351 } else if (isr & 0x44) {
365 siginfo.si_code = FPE_FLTDIV; 352 si_code = FPE_FLTDIV;
366 } 353 }
367 siginfo.si_isr = isr; 354 force_sig_fault(SIGFPE, si_code,
368 siginfo.si_flags = __ISR_VALID; 355 (void __user *) (regs->cr_iip + ia64_psr(regs)->ri),
369 siginfo.si_imm = 0; 356 0, __ISR_VALID, isr, current);
370 force_sig_info(SIGFPE, &siginfo, current);
371 } 357 }
372 } else { 358 } else {
373 if (exception == -1) { 359 if (exception == -1) {
@@ -375,24 +361,19 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
375 return -1; 361 return -1;
376 } else if (exception != 0) { 362 } else if (exception != 0) {
377 /* raise exception */ 363 /* raise exception */
378 struct siginfo siginfo; 364 int si_code;
379 365
380 clear_siginfo(&siginfo); 366 si_code = FPE_FLTUNK; /* default code */
381 siginfo.si_signo = SIGFPE;
382 siginfo.si_errno = 0;
383 siginfo.si_code = FPE_FLTUNK; /* default code */
384 siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
385 if (isr & 0x880) { 367 if (isr & 0x880) {
386 siginfo.si_code = FPE_FLTOVF; 368 si_code = FPE_FLTOVF;
387 } else if (isr & 0x1100) { 369 } else if (isr & 0x1100) {
388 siginfo.si_code = FPE_FLTUND; 370 si_code = FPE_FLTUND;
389 } else if (isr & 0x2200) { 371 } else if (isr & 0x2200) {
390 siginfo.si_code = FPE_FLTRES; 372 si_code = FPE_FLTRES;
391 } 373 }
392 siginfo.si_isr = isr; 374 force_sig_fault(SIGFPE, si_code,
393 siginfo.si_flags = __ISR_VALID; 375 (void __user *) (regs->cr_iip + ia64_psr(regs)->ri),
394 siginfo.si_imm = 0; 376 0, __ISR_VALID, isr, current);
395 force_sig_info(SIGFPE, &siginfo, current);
396 } 377 }
397 } 378 }
398 return 0; 379 return 0;
@@ -408,7 +389,6 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
408 struct pt_regs regs) 389 struct pt_regs regs)
409{ 390{
410 struct illegal_op_return rv; 391 struct illegal_op_return rv;
411 struct siginfo si;
412 char buf[128]; 392 char buf[128];
413 393
414#ifdef CONFIG_IA64_BRL_EMU 394#ifdef CONFIG_IA64_BRL_EMU
@@ -426,11 +406,9 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
426 if (die_if_kernel(buf, &regs, 0)) 406 if (die_if_kernel(buf, &regs, 0))
427 return rv; 407 return rv;
428 408
429 clear_siginfo(&si); 409 force_sig_fault(SIGILL, ILL_ILLOPC,
430 si.si_signo = SIGILL; 410 (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri),
431 si.si_code = ILL_ILLOPC; 411 0, 0, 0, current);
432 si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri);
433 force_sig_info(SIGILL, &si, current);
434 return rv; 412 return rv;
435} 413}
436 414
@@ -441,7 +419,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
441{ 419{
442 unsigned long code, error = isr, iip; 420 unsigned long code, error = isr, iip;
443 char buf[128]; 421 char buf[128];
444 int result, sig; 422 int result, sig, si_code;
445 static const char *reason[] = { 423 static const char *reason[] = {
446 "IA-64 Illegal Operation fault", 424 "IA-64 Illegal Operation fault",
447 "IA-64 Privileged Operation fault", 425 "IA-64 Privileged Operation fault",
@@ -490,7 +468,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
490 468
491 case 26: /* NaT Consumption */ 469 case 26: /* NaT Consumption */
492 if (user_mode(&regs)) { 470 if (user_mode(&regs)) {
493 struct siginfo siginfo;
494 void __user *addr; 471 void __user *addr;
495 472
496 if (((isr >> 4) & 0xf) == 2) { 473 if (((isr >> 4) & 0xf) == 2) {
@@ -505,15 +482,8 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
505 addr = (void __user *) (regs.cr_iip 482 addr = (void __user *) (regs.cr_iip
506 + ia64_psr(&regs)->ri); 483 + ia64_psr(&regs)->ri);
507 } 484 }
508 clear_siginfo(&siginfo); 485 force_sig_fault(sig, code, addr,
509 siginfo.si_signo = sig; 486 vector, __ISR_VALID, isr, current);
510 siginfo.si_code = code;
511 siginfo.si_errno = 0;
512 siginfo.si_addr = addr;
513 siginfo.si_imm = vector;
514 siginfo.si_flags = __ISR_VALID;
515 siginfo.si_isr = isr;
516 force_sig_info(sig, &siginfo, current);
517 return; 487 return;
518 } else if (ia64_done_with_exception(&regs)) 488 } else if (ia64_done_with_exception(&regs))
519 return; 489 return;
@@ -522,17 +492,8 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
522 492
523 case 31: /* Unsupported Data Reference */ 493 case 31: /* Unsupported Data Reference */
524 if (user_mode(&regs)) { 494 if (user_mode(&regs)) {
525 struct siginfo siginfo; 495 force_sig_fault(SIGILL, ILL_ILLOPN, (void __user *) iip,
526 496 vector, __ISR_VALID, isr, current);
527 clear_siginfo(&siginfo);
528 siginfo.si_signo = SIGILL;
529 siginfo.si_code = ILL_ILLOPN;
530 siginfo.si_errno = 0;
531 siginfo.si_addr = (void __user *) iip;
532 siginfo.si_imm = vector;
533 siginfo.si_flags = __ISR_VALID;
534 siginfo.si_isr = isr;
535 force_sig_info(SIGILL, &siginfo, current);
536 return; 497 return;
537 } 498 }
538 sprintf(buf, "Unsupported data reference"); 499 sprintf(buf, "Unsupported data reference");
@@ -541,10 +502,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
541 case 29: /* Debug */ 502 case 29: /* Debug */
542 case 35: /* Taken Branch Trap */ 503 case 35: /* Taken Branch Trap */
543 case 36: /* Single Step Trap */ 504 case 36: /* Single Step Trap */
544 {
545 struct siginfo siginfo;
546
547 clear_siginfo(&siginfo);
548 if (fsys_mode(current, &regs)) { 505 if (fsys_mode(current, &regs)) {
549 extern char __kernel_syscall_via_break[]; 506 extern char __kernel_syscall_via_break[];
550 /* 507 /*
@@ -568,7 +525,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
568 switch (vector) { 525 switch (vector) {
569 default: 526 default:
570 case 29: 527 case 29:
571 siginfo.si_code = TRAP_HWBKPT; 528 si_code = TRAP_HWBKPT;
572#ifdef CONFIG_ITANIUM 529#ifdef CONFIG_ITANIUM
573 /* 530 /*
574 * Erratum 10 (IFA may contain incorrect address) now has 531 * Erratum 10 (IFA may contain incorrect address) now has
@@ -578,37 +535,22 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
578 ifa = regs.cr_iip; 535 ifa = regs.cr_iip;
579#endif 536#endif
580 break; 537 break;
581 case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; 538 case 35: si_code = TRAP_BRANCH; ifa = 0; break;
582 case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break; 539 case 36: si_code = TRAP_TRACE; ifa = 0; break;
583 } 540 }
584 if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, siginfo.si_code, SIGTRAP) 541 if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, si_code, SIGTRAP)
585 == NOTIFY_STOP) 542 == NOTIFY_STOP)
586 return; 543 return;
587 siginfo.si_signo = SIGTRAP; 544 force_sig_fault(SIGTRAP, si_code, (void __user *) ifa,
588 siginfo.si_errno = 0; 545 0, __ISR_VALID, isr, current);
589 siginfo.si_addr = (void __user *) ifa;
590 siginfo.si_imm = 0;
591 siginfo.si_flags = __ISR_VALID;
592 siginfo.si_isr = isr;
593 force_sig_info(SIGTRAP, &siginfo, current);
594 return; 546 return;
595 }
596 547
597 case 32: /* fp fault */ 548 case 32: /* fp fault */
598 case 33: /* fp trap */ 549 case 33: /* fp trap */
599 result = handle_fpu_swa((vector == 32) ? 1 : 0, &regs, isr); 550 result = handle_fpu_swa((vector == 32) ? 1 : 0, &regs, isr);
600 if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) { 551 if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {
601 struct siginfo siginfo; 552 force_sig_fault(SIGFPE, FPE_FLTINV, (void __user *) iip,
602 553 0, __ISR_VALID, isr, current);
603 clear_siginfo(&siginfo);
604 siginfo.si_signo = SIGFPE;
605 siginfo.si_errno = 0;
606 siginfo.si_code = FPE_FLTINV;
607 siginfo.si_addr = (void __user *) iip;
608 siginfo.si_flags = __ISR_VALID;
609 siginfo.si_isr = isr;
610 siginfo.si_imm = 0;
611 force_sig_info(SIGFPE, &siginfo, current);
612 } 554 }
613 return; 555 return;
614 556
@@ -634,17 +576,9 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
634 } else { 576 } else {
635 /* Unimplemented Instr. Address Trap */ 577 /* Unimplemented Instr. Address Trap */
636 if (user_mode(&regs)) { 578 if (user_mode(&regs)) {
637 struct siginfo siginfo; 579 force_sig_fault(SIGILL, ILL_BADIADDR,
638 580 (void __user *) iip,
639 clear_siginfo(&siginfo); 581 0, 0, 0, current);
640 siginfo.si_signo = SIGILL;
641 siginfo.si_code = ILL_BADIADDR;
642 siginfo.si_errno = 0;
643 siginfo.si_flags = 0;
644 siginfo.si_isr = 0;
645 siginfo.si_imm = 0;
646 siginfo.si_addr = (void __user *) iip;
647 force_sig_info(SIGILL, &siginfo, current);
648 return; 582 return;
649 } 583 }
650 sprintf(buf, "Unimplemented Instruction Address fault"); 584 sprintf(buf, "Unimplemented Instruction Address fault");
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index e309f9859acc..a167a3824b35 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -1298,7 +1298,6 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
1298 mm_segment_t old_fs = get_fs(); 1298 mm_segment_t old_fs = get_fs();
1299 unsigned long bundle[2]; 1299 unsigned long bundle[2];
1300 unsigned long opcode; 1300 unsigned long opcode;
1301 struct siginfo si;
1302 const struct exception_table_entry *eh = NULL; 1301 const struct exception_table_entry *eh = NULL;
1303 union { 1302 union {
1304 unsigned long l; 1303 unsigned long l;
@@ -1537,14 +1536,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
1537 /* NOT_REACHED */ 1536 /* NOT_REACHED */
1538 } 1537 }
1539 force_sigbus: 1538 force_sigbus:
1540 clear_siginfo(&si); 1539 force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) ifa,
1541 si.si_signo = SIGBUS; 1540 0, 0, 0, current);
1542 si.si_errno = 0;
1543 si.si_code = BUS_ADRALN;
1544 si.si_addr = (void __user *) ifa;
1545 si.si_flags = 0;
1546 si.si_isr = 0;
1547 si.si_imm = 0;
1548 force_sig_info(SIGBUS, &si, current);
1549 goto done; 1541 goto done;
1550} 1542}
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index a9d55ad8d67b..5baeb022f474 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -248,16 +248,8 @@ retry:
248 return; 248 return;
249 } 249 }
250 if (user_mode(regs)) { 250 if (user_mode(regs)) {
251 struct siginfo si; 251 force_sig_fault(signal, code, (void __user *) address,
252 252 0, __ISR_VALID, isr, current);
253 clear_siginfo(&si);
254 si.si_signo = signal;
255 si.si_errno = 0;
256 si.si_code = code;
257 si.si_addr = (void __user *) address;
258 si.si_isr = isr;
259 si.si_flags = __ISR_VALID;
260 force_sig_info(signal, &si, current);
261 return; 253 return;
262 } 254 }
263 255