.. | .. |
---|
125 | 125 | static notrace void s390_handle_damage(void) |
---|
126 | 126 | { |
---|
127 | 127 | smp_emergency_stop(); |
---|
128 | | - disabled_wait((unsigned long) __builtin_return_address(0)); |
---|
| 128 | + disabled_wait(); |
---|
129 | 129 | while (1); |
---|
130 | 130 | } |
---|
131 | 131 | NOKPROBE_SYMBOL(s390_handle_damage); |
---|
.. | .. |
---|
148 | 148 | local_mcck_disable(); |
---|
149 | 149 | mcck = *this_cpu_ptr(&cpu_mcck); |
---|
150 | 150 | memset(this_cpu_ptr(&cpu_mcck), 0, sizeof(mcck)); |
---|
151 | | - clear_cpu_flag(CIF_MCCK_PENDING); |
---|
152 | 151 | local_mcck_enable(); |
---|
153 | 152 | local_irq_restore(flags); |
---|
154 | 153 | |
---|
.. | .. |
---|
179 | 178 | "malfunction (code 0x%016lx).\n", mcck.mcck_code); |
---|
180 | 179 | printk(KERN_EMERG "mcck: task: %s, pid: %d.\n", |
---|
181 | 180 | current->comm, current->pid); |
---|
182 | | - do_exit(SIGSEGV); |
---|
| 181 | + make_task_dead(SIGSEGV); |
---|
183 | 182 | } |
---|
184 | 183 | } |
---|
185 | 184 | EXPORT_SYMBOL_GPL(s390_handle_mcck); |
---|
.. | .. |
---|
333 | 332 | /* |
---|
334 | 333 | * machine check handler. |
---|
335 | 334 | */ |
---|
336 | | -void notrace s390_do_machine_check(struct pt_regs *regs) |
---|
| 335 | +int notrace s390_do_machine_check(struct pt_regs *regs) |
---|
337 | 336 | { |
---|
338 | 337 | static int ipd_count; |
---|
339 | 338 | static DEFINE_SPINLOCK(ipd_lock); |
---|
.. | .. |
---|
342 | 341 | unsigned long long tmp; |
---|
343 | 342 | union mci mci; |
---|
344 | 343 | unsigned long mcck_dam_code; |
---|
| 344 | + int mcck_pending = 0; |
---|
345 | 345 | |
---|
346 | 346 | nmi_enter(); |
---|
347 | 347 | inc_irq_stat(NMI_NMI); |
---|
.. | .. |
---|
400 | 400 | */ |
---|
401 | 401 | mcck->kill_task = 1; |
---|
402 | 402 | mcck->mcck_code = mci.val; |
---|
403 | | - set_cpu_flag(CIF_MCCK_PENDING); |
---|
| 403 | + mcck_pending = 1; |
---|
404 | 404 | } |
---|
405 | 405 | |
---|
406 | 406 | /* |
---|
.. | .. |
---|
420 | 420 | mcck->stp_queue |= stp_sync_check(); |
---|
421 | 421 | if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND)) |
---|
422 | 422 | mcck->stp_queue |= stp_island_check(); |
---|
423 | | - if (mcck->stp_queue) |
---|
424 | | - set_cpu_flag(CIF_MCCK_PENDING); |
---|
| 423 | + mcck_pending = 1; |
---|
425 | 424 | } |
---|
426 | 425 | |
---|
427 | 426 | /* |
---|
.. | .. |
---|
442 | 441 | if (mci.cp) { |
---|
443 | 442 | /* Channel report word pending */ |
---|
444 | 443 | mcck->channel_report = 1; |
---|
445 | | - set_cpu_flag(CIF_MCCK_PENDING); |
---|
| 444 | + mcck_pending = 1; |
---|
446 | 445 | } |
---|
447 | 446 | if (mci.w) { |
---|
448 | 447 | /* Warning pending */ |
---|
449 | 448 | mcck->warning = 1; |
---|
450 | | - set_cpu_flag(CIF_MCCK_PENDING); |
---|
| 449 | + mcck_pending = 1; |
---|
451 | 450 | } |
---|
452 | 451 | |
---|
453 | 452 | /* |
---|
.. | .. |
---|
462 | 461 | *((long *)(regs->gprs[15] + __SF_SIE_REASON)) = -EINTR; |
---|
463 | 462 | } |
---|
464 | 463 | clear_cpu_flag(CIF_MCCK_GUEST); |
---|
| 464 | + |
---|
| 465 | + if (user_mode(regs) && mcck_pending) { |
---|
| 466 | + nmi_exit(); |
---|
| 467 | + return 1; |
---|
| 468 | + } |
---|
| 469 | + |
---|
| 470 | + if (mcck_pending) |
---|
| 471 | + schedule_mcck_handler(); |
---|
| 472 | + |
---|
465 | 473 | nmi_exit(); |
---|
| 474 | + return 0; |
---|
466 | 475 | } |
---|
467 | 476 | NOKPROBE_SYMBOL(s390_do_machine_check); |
---|
468 | 477 | |
---|