| .. | .. |
|---|
| 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 | |
|---|
| .. | .. |
|---|
| 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 | |
|---|