diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2009-03-26 10:24:53 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-03-26 10:24:30 -0400 |
commit | d0d3cdf4c27fa4ce241616da08138954e02890f7 (patch) | |
tree | d41f825cc2259b1f687d4c49d2b0fba597f3da2d /arch/s390/kernel/smp.c | |
parent | 6d54c5a3fb13d32d66a8383cb0b5fb422a563051 (diff) |
[S390] smp: perform initial cpu reset before starting a cpu
Performing an initial cpu reset makes sure all registers and tlbs of
the targeted cpu are initialized and flushed.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r-- | arch/s390/kernel/smp.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 1f4711b60aab..fe5f8dc1e6fa 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -534,18 +534,23 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
534 | struct _lowcore *cpu_lowcore; | 534 | struct _lowcore *cpu_lowcore; |
535 | struct stack_frame *sf; | 535 | struct stack_frame *sf; |
536 | sigp_ccode ccode; | 536 | sigp_ccode ccode; |
537 | u32 lowcore; | ||
537 | 538 | ||
538 | if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) | 539 | if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) |
539 | return -EIO; | 540 | return -EIO; |
540 | if (smp_alloc_lowcore(cpu)) | 541 | if (smp_alloc_lowcore(cpu)) |
541 | return -ENOMEM; | 542 | return -ENOMEM; |
542 | 543 | do { | |
543 | ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]), | 544 | ccode = signal_processor(cpu, sigp_initial_cpu_reset); |
544 | cpu, sigp_set_prefix); | 545 | if (ccode == sigp_busy) |
545 | if (ccode) { | 546 | udelay(10); |
546 | smp_free_lowcore(cpu); | 547 | if (ccode == sigp_not_operational) |
547 | return -EIO; | 548 | goto err_out; |
548 | } | 549 | } while (ccode == sigp_busy); |
550 | |||
551 | lowcore = (u32)(unsigned long)lowcore_ptr[cpu]; | ||
552 | while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy) | ||
553 | udelay(10); | ||
549 | 554 | ||
550 | idle = current_set[cpu]; | 555 | idle = current_set[cpu]; |
551 | cpu_lowcore = lowcore_ptr[cpu]; | 556 | cpu_lowcore = lowcore_ptr[cpu]; |
@@ -574,6 +579,10 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
574 | while (!cpu_online(cpu)) | 579 | while (!cpu_online(cpu)) |
575 | cpu_relax(); | 580 | cpu_relax(); |
576 | return 0; | 581 | return 0; |
582 | |||
583 | err_out: | ||
584 | smp_free_lowcore(cpu); | ||
585 | return -EIO; | ||
577 | } | 586 | } |
578 | 587 | ||
579 | static int __init setup_possible_cpus(char *s) | 588 | static int __init setup_possible_cpus(char *s) |