diff options
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r-- | arch/s390/kernel/smp.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index a6d85c0a7f20..6ab16ac64d29 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -452,23 +452,27 @@ out: | |||
452 | */ | 452 | */ |
453 | int __cpuinit start_secondary(void *cpuvoid) | 453 | int __cpuinit start_secondary(void *cpuvoid) |
454 | { | 454 | { |
455 | /* Setup the cpu */ | ||
456 | cpu_init(); | 455 | cpu_init(); |
457 | preempt_disable(); | 456 | preempt_disable(); |
458 | /* Enable TOD clock interrupts on the secondary cpu. */ | ||
459 | init_cpu_timer(); | 457 | init_cpu_timer(); |
460 | /* Enable cpu timer interrupts on the secondary cpu. */ | ||
461 | init_cpu_vtimer(); | 458 | init_cpu_vtimer(); |
462 | /* Enable pfault pseudo page faults on this cpu. */ | ||
463 | pfault_init(); | 459 | pfault_init(); |
464 | 460 | ||
465 | /* call cpu notifiers */ | ||
466 | notify_cpu_starting(smp_processor_id()); | 461 | notify_cpu_starting(smp_processor_id()); |
467 | /* Mark this cpu as online */ | ||
468 | ipi_call_lock(); | 462 | ipi_call_lock(); |
469 | set_cpu_online(smp_processor_id(), true); | 463 | set_cpu_online(smp_processor_id(), true); |
470 | ipi_call_unlock(); | 464 | ipi_call_unlock(); |
471 | /* Switch on interrupts */ | 465 | __ctl_clear_bit(0, 28); /* Disable lowcore protection */ |
466 | S390_lowcore.restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; | ||
467 | S390_lowcore.restart_psw.addr = | ||
468 | PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler; | ||
469 | __ctl_set_bit(0, 28); /* Enable lowcore protection */ | ||
470 | /* | ||
471 | * Wait until the cpu which brought this one up marked it | ||
472 | * active before enabling interrupts. | ||
473 | */ | ||
474 | while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask)) | ||
475 | cpu_relax(); | ||
472 | local_irq_enable(); | 476 | local_irq_enable(); |
473 | /* cpu_idle will call schedule for us */ | 477 | /* cpu_idle will call schedule for us */ |
474 | cpu_idle(); | 478 | cpu_idle(); |
@@ -507,7 +511,11 @@ static int __cpuinit smp_alloc_lowcore(int cpu) | |||
507 | memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512); | 511 | memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512); |
508 | lowcore->async_stack = async_stack + ASYNC_SIZE; | 512 | lowcore->async_stack = async_stack + ASYNC_SIZE; |
509 | lowcore->panic_stack = panic_stack + PAGE_SIZE; | 513 | lowcore->panic_stack = panic_stack + PAGE_SIZE; |
510 | 514 | lowcore->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; | |
515 | lowcore->restart_psw.addr = | ||
516 | PSW_ADDR_AMODE | (unsigned long) restart_int_handler; | ||
517 | if (user_mode != HOME_SPACE_MODE) | ||
518 | lowcore->restart_psw.mask |= PSW_ASC_HOME; | ||
511 | #ifndef CONFIG_64BIT | 519 | #ifndef CONFIG_64BIT |
512 | if (MACHINE_HAS_IEEE) { | 520 | if (MACHINE_HAS_IEEE) { |
513 | unsigned long save_area; | 521 | unsigned long save_area; |