Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[S390] smp: fix sigp stop handling

According to the architecture a cpu must not necessarily enter stopped
state after completion of a sigp instruction with "stop" order code.
So remove the BUG() statement after self sending sigp stop to avoid
that it ever gets reached.
Also add a sigp busy check to make sure that the order gets delivered.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Heiko Carstens and committed by
Martin Schwidefsky
f8501ba7 70f5dc51

+6 -6
+3 -4
arch/s390/kernel/ipl.c
··· 1595 1595 { 1596 1596 if (strcmp(trigger->name, ON_PANIC_STR) == 0) 1597 1597 disabled_wait((unsigned long) __builtin_return_address(0)); 1598 - else { 1599 - signal_processor(smp_processor_id(), sigp_stop); 1600 - for (;;); 1601 - } 1598 + while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) 1599 + cpu_relax(); 1600 + for (;;); 1602 1601 } 1603 1602 1604 1603 static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
+2 -2
arch/s390/kernel/smp.c
··· 647 647 void cpu_die(void) 648 648 { 649 649 idle_task_exit(); 650 - signal_processor(smp_processor_id(), sigp_stop); 651 - BUG(); 650 + while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) 651 + cpu_relax(); 652 652 for (;;); 653 653 } 654 654
+1
arch/s390/kernel/swsusp_asm64.S
··· 199 199 brc 2,4b /* busy, try again */ 200 200 5: 201 201 sigp %r9,%r2,__SIGP_STOP /* stop resume (current) CPU */ 202 + brc 2,5b /* busy, try again */ 202 203 6: j 6b 203 204 204 205 restart_suspend: