aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r--arch/s390/kernel/smp.c54
1 files changed, 24 insertions, 30 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index b39f596d71bd..d8a0b115c7c1 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -53,7 +53,7 @@
53#include "entry.h" 53#include "entry.h"
54 54
55/* logical cpu to cpu address */ 55/* logical cpu to cpu address */
56int __cpu_logical_map[NR_CPUS]; 56unsigned short __cpu_logical_map[NR_CPUS];
57 57
58static struct task_struct *current_set[NR_CPUS]; 58static struct task_struct *current_set[NR_CPUS];
59 59
@@ -72,13 +72,13 @@ static int cpu_management;
72 72
73static DEFINE_PER_CPU(struct cpu, cpu_devices); 73static DEFINE_PER_CPU(struct cpu, cpu_devices);
74 74
75static void smp_ext_bitcall(int, ec_bit_sig); 75static void smp_ext_bitcall(int, int);
76 76
77static int cpu_stopped(int cpu) 77static int raw_cpu_stopped(int cpu)
78{ 78{
79 __u32 status; 79 u32 status;
80 80
81 switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { 81 switch (raw_sigp_ps(&status, 0, cpu, sigp_sense)) {
82 case sigp_status_stored: 82 case sigp_status_stored:
83 /* Check for stopped and check stop state */ 83 /* Check for stopped and check stop state */
84 if (status & 0x50) 84 if (status & 0x50)
@@ -90,6 +90,11 @@ static int cpu_stopped(int cpu)
90 return 0; 90 return 0;
91} 91}
92 92
93static inline int cpu_stopped(int cpu)
94{
95 return raw_cpu_stopped(cpu_logical_map(cpu));
96}
97
93void smp_switch_to_ipl_cpu(void (*func)(void *), void *data) 98void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
94{ 99{
95 struct _lowcore *lc, *current_lc; 100 struct _lowcore *lc, *current_lc;
@@ -110,7 +115,7 @@ void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
110 lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu; 115 lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu;
111 if (!cpu_online(0)) 116 if (!cpu_online(0))
112 smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]); 117 smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]);
113 while (signal_processor(0, sigp_stop_and_store_status) == sigp_busy) 118 while (sigp(0, sigp_stop_and_store_status) == sigp_busy)
114 cpu_relax(); 119 cpu_relax();
115 sp = lc->panic_stack; 120 sp = lc->panic_stack;
116 sp -= sizeof(struct pt_regs); 121 sp -= sizeof(struct pt_regs);
@@ -136,7 +141,7 @@ void smp_send_stop(void)
136 if (cpu == smp_processor_id()) 141 if (cpu == smp_processor_id())
137 continue; 142 continue;
138 do { 143 do {
139 rc = signal_processor(cpu, sigp_stop); 144 rc = sigp(cpu, sigp_stop);
140 } while (rc == sigp_busy); 145 } while (rc == sigp_busy);
141 146
142 while (!cpu_stopped(cpu)) 147 while (!cpu_stopped(cpu))
@@ -172,13 +177,13 @@ static void do_ext_call_interrupt(__u16 code)
172 * Send an external call sigp to another cpu and return without waiting 177 * Send an external call sigp to another cpu and return without waiting
173 * for its completion. 178 * for its completion.
174 */ 179 */
175static void smp_ext_bitcall(int cpu, ec_bit_sig sig) 180static void smp_ext_bitcall(int cpu, int sig)
176{ 181{
177 /* 182 /*
178 * Set signaling bit in lowcore of target cpu and kick it 183 * Set signaling bit in lowcore of target cpu and kick it
179 */ 184 */
180 set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); 185 set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
181 while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy) 186 while (sigp(cpu, sigp_emergency_signal) == sigp_busy)
182 udelay(10); 187 udelay(10);
183} 188}
184 189
@@ -272,13 +277,6 @@ void smp_ctl_clear_bit(int cr, int bit)
272} 277}
273EXPORT_SYMBOL(smp_ctl_clear_bit); 278EXPORT_SYMBOL(smp_ctl_clear_bit);
274 279
275/*
276 * In early ipl state a temp. logically cpu number is needed, so the sigp
277 * functions can be used to sense other cpus. Since NR_CPUS is >= 2 on
278 * CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1.
279 */
280#define CPU_INIT_NO 1
281
282#ifdef CONFIG_ZFCPDUMP 280#ifdef CONFIG_ZFCPDUMP
283 281
284static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) 282static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
@@ -291,9 +289,7 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
291 return; 289 return;
292 } 290 }
293 zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL); 291 zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL);
294 __cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu; 292 while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy)
295 while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) ==
296 sigp_busy)
297 cpu_relax(); 293 cpu_relax();
298 memcpy(zfcpdump_save_areas[cpu], 294 memcpy(zfcpdump_save_areas[cpu],
299 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, 295 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
@@ -409,8 +405,7 @@ static void __init smp_detect_cpus(void)
409 for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) { 405 for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) {
410 if (cpu == boot_cpu_addr) 406 if (cpu == boot_cpu_addr)
411 continue; 407 continue;
412 __cpu_logical_map[CPU_INIT_NO] = cpu; 408 if (!raw_cpu_stopped(cpu))
413 if (!cpu_stopped(CPU_INIT_NO))
414 continue; 409 continue;
415 smp_get_save_area(c_cpus, cpu); 410 smp_get_save_area(c_cpus, cpu);
416 c_cpus++; 411 c_cpus++;
@@ -433,8 +428,7 @@ static void __init smp_detect_cpus(void)
433 cpu_addr = info->cpu[cpu].address; 428 cpu_addr = info->cpu[cpu].address;
434 if (cpu_addr == boot_cpu_addr) 429 if (cpu_addr == boot_cpu_addr)
435 continue; 430 continue;
436 __cpu_logical_map[CPU_INIT_NO] = cpu_addr; 431 if (!raw_cpu_stopped(cpu_addr)) {
437 if (!cpu_stopped(CPU_INIT_NO)) {
438 s_cpus++; 432 s_cpus++;
439 continue; 433 continue;
440 } 434 }
@@ -553,18 +547,18 @@ static void smp_free_lowcore(int cpu)
553/* Upping and downing of CPUs */ 547/* Upping and downing of CPUs */
554int __cpuinit __cpu_up(unsigned int cpu) 548int __cpuinit __cpu_up(unsigned int cpu)
555{ 549{
556 struct task_struct *idle;
557 struct _lowcore *cpu_lowcore; 550 struct _lowcore *cpu_lowcore;
551 struct task_struct *idle;
558 struct stack_frame *sf; 552 struct stack_frame *sf;
559 sigp_ccode ccode;
560 u32 lowcore; 553 u32 lowcore;
554 int ccode;
561 555
562 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) 556 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
563 return -EIO; 557 return -EIO;
564 if (smp_alloc_lowcore(cpu)) 558 if (smp_alloc_lowcore(cpu))
565 return -ENOMEM; 559 return -ENOMEM;
566 do { 560 do {
567 ccode = signal_processor(cpu, sigp_initial_cpu_reset); 561 ccode = sigp(cpu, sigp_initial_cpu_reset);
568 if (ccode == sigp_busy) 562 if (ccode == sigp_busy)
569 udelay(10); 563 udelay(10);
570 if (ccode == sigp_not_operational) 564 if (ccode == sigp_not_operational)
@@ -572,7 +566,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
572 } while (ccode == sigp_busy); 566 } while (ccode == sigp_busy);
573 567
574 lowcore = (u32)(unsigned long)lowcore_ptr[cpu]; 568 lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
575 while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy) 569 while (sigp_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
576 udelay(10); 570 udelay(10);
577 571
578 idle = current_set[cpu]; 572 idle = current_set[cpu];
@@ -598,7 +592,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
598 cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func; 592 cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func;
599 eieio(); 593 eieio();
600 594
601 while (signal_processor(cpu, sigp_restart) == sigp_busy) 595 while (sigp(cpu, sigp_restart) == sigp_busy)
602 udelay(10); 596 udelay(10);
603 597
604 while (!cpu_online(cpu)) 598 while (!cpu_online(cpu))
@@ -660,7 +654,7 @@ void __cpu_die(unsigned int cpu)
660 /* Wait until target cpu is down */ 654 /* Wait until target cpu is down */
661 while (!cpu_stopped(cpu)) 655 while (!cpu_stopped(cpu))
662 cpu_relax(); 656 cpu_relax();
663 while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy) 657 while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy)
664 udelay(10); 658 udelay(10);
665 smp_free_lowcore(cpu); 659 smp_free_lowcore(cpu);
666 pr_info("Processor %d stopped\n", cpu); 660 pr_info("Processor %d stopped\n", cpu);
@@ -669,7 +663,7 @@ void __cpu_die(unsigned int cpu)
669void cpu_die(void) 663void cpu_die(void)
670{ 664{
671 idle_task_exit(); 665 idle_task_exit();
672 while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) 666 while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
673 cpu_relax(); 667 cpu_relax();
674 for (;;); 668 for (;;);
675} 669}