diff options
-rw-r--r-- | arch/s390/kernel/smp.c | 63 |
1 files changed, 21 insertions, 42 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 8ff2feaf9b00..182c085ae4dd 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -410,58 +410,40 @@ EXPORT_SYMBOL(smp_ctl_clear_bit); | |||
410 | unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \ | 410 | unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \ |
411 | __attribute__((__section__(".data"))); | 411 | __attribute__((__section__(".data"))); |
412 | 412 | ||
413 | static void __init smp_get_save_areas(void) | 413 | static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) |
414 | { | 414 | { |
415 | unsigned int cpu, cpu_num, rc; | ||
416 | __u16 boot_cpu_addr; | ||
417 | |||
418 | if (ipl_info.type != IPL_TYPE_FCP_DUMP) | 415 | if (ipl_info.type != IPL_TYPE_FCP_DUMP) |
419 | return; | 416 | return; |
420 | boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; | 417 | if (cpu >= NR_CPUS) { |
421 | cpu_num = 1; | 418 | printk(KERN_WARNING "Registers for cpu %i not saved since dump " |
422 | for (cpu = 0; cpu <= 65535; cpu++) { | 419 | "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS); |
423 | if ((u16) cpu == boot_cpu_addr) | 420 | return; |
424 | continue; | ||
425 | __cpu_logical_map[1] = (__u16) cpu; | ||
426 | if (signal_processor(1, sigp_sense) == sigp_not_operational) | ||
427 | continue; | ||
428 | if (cpu_num >= NR_CPUS) { | ||
429 | printk("WARNING: Registers for cpu %i are not " | ||
430 | "saved, since dump kernel was compiled with" | ||
431 | "NR_CPUS=%i!\n", cpu_num, NR_CPUS); | ||
432 | continue; | ||
433 | } | ||
434 | zfcpdump_save_areas[cpu_num] = | ||
435 | alloc_bootmem(sizeof(union save_area)); | ||
436 | while (1) { | ||
437 | rc = signal_processor(1, sigp_stop_and_store_status); | ||
438 | if (rc != sigp_busy) | ||
439 | break; | ||
440 | cpu_relax(); | ||
441 | } | ||
442 | memcpy(zfcpdump_save_areas[cpu_num], | ||
443 | (void *)(unsigned long) store_prefix() + | ||
444 | SAVE_AREA_BASE, SAVE_AREA_SIZE); | ||
445 | #ifdef __s390x__ | ||
446 | /* copy original prefix register */ | ||
447 | zfcpdump_save_areas[cpu_num]->s390x.pref_reg = | ||
448 | zfcpdump_prefix_array[cpu_num]; | ||
449 | #endif | ||
450 | cpu_num++; | ||
451 | } | 421 | } |
422 | zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area)); | ||
423 | __cpu_logical_map[1] = (__u16) phy_cpu; | ||
424 | while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy) | ||
425 | cpu_relax(); | ||
426 | memcpy(zfcpdump_save_areas[cpu], | ||
427 | (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, | ||
428 | SAVE_AREA_SIZE); | ||
429 | #ifdef CONFIG_64BIT | ||
430 | /* copy original prefix register */ | ||
431 | zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu]; | ||
432 | #endif | ||
452 | } | 433 | } |
453 | 434 | ||
454 | union save_area *zfcpdump_save_areas[NR_CPUS + 1]; | 435 | union save_area *zfcpdump_save_areas[NR_CPUS + 1]; |
455 | EXPORT_SYMBOL_GPL(zfcpdump_save_areas); | 436 | EXPORT_SYMBOL_GPL(zfcpdump_save_areas); |
456 | 437 | ||
457 | #else | 438 | #else |
458 | #define smp_get_save_areas() do { } while (0) | 439 | |
459 | #endif | 440 | static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { } |
441 | |||
442 | #endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */ | ||
460 | 443 | ||
461 | /* | 444 | /* |
462 | * Lets check how many CPUs we have. | 445 | * Lets check how many CPUs we have. |
463 | */ | 446 | */ |
464 | |||
465 | static unsigned int __init smp_count_cpus(void) | 447 | static unsigned int __init smp_count_cpus(void) |
466 | { | 448 | { |
467 | unsigned int cpu, num_cpus; | 449 | unsigned int cpu, num_cpus; |
@@ -470,7 +452,6 @@ static unsigned int __init smp_count_cpus(void) | |||
470 | /* | 452 | /* |
471 | * cpu 0 is the boot cpu. See smp_prepare_boot_cpu. | 453 | * cpu 0 is the boot cpu. See smp_prepare_boot_cpu. |
472 | */ | 454 | */ |
473 | |||
474 | boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; | 455 | boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; |
475 | current_thread_info()->cpu = 0; | 456 | current_thread_info()->cpu = 0; |
476 | num_cpus = 1; | 457 | num_cpus = 1; |
@@ -480,12 +461,11 @@ static unsigned int __init smp_count_cpus(void) | |||
480 | __cpu_logical_map[1] = (__u16) cpu; | 461 | __cpu_logical_map[1] = (__u16) cpu; |
481 | if (signal_processor(1, sigp_sense) == sigp_not_operational) | 462 | if (signal_processor(1, sigp_sense) == sigp_not_operational) |
482 | continue; | 463 | continue; |
464 | smp_get_save_area(num_cpus, cpu); | ||
483 | num_cpus++; | 465 | num_cpus++; |
484 | } | 466 | } |
485 | |||
486 | printk("Detected %d CPU's\n", (int) num_cpus); | 467 | printk("Detected %d CPU's\n", (int) num_cpus); |
487 | printk("Boot cpu address %2X\n", boot_cpu_addr); | 468 | printk("Boot cpu address %2X\n", boot_cpu_addr); |
488 | |||
489 | return num_cpus; | 469 | return num_cpus; |
490 | } | 470 | } |
491 | 471 | ||
@@ -606,7 +586,6 @@ void __init smp_setup_cpu_possible_map(void) | |||
606 | { | 586 | { |
607 | unsigned int phy_cpus, pos_cpus, cpu; | 587 | unsigned int phy_cpus, pos_cpus, cpu; |
608 | 588 | ||
609 | smp_get_save_areas(); | ||
610 | phy_cpus = smp_count_cpus(); | 589 | phy_cpus = smp_count_cpus(); |
611 | pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS); | 590 | pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS); |
612 | 591 | ||