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.c132
1 files changed, 82 insertions, 50 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 93e52039321b..e4d98de83dd8 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -36,6 +36,8 @@
36#include <linux/cpu.h> 36#include <linux/cpu.h>
37#include <linux/timex.h> 37#include <linux/timex.h>
38#include <linux/bootmem.h> 38#include <linux/bootmem.h>
39#include <linux/slab.h>
40#include <asm/asm-offsets.h>
39#include <asm/ipl.h> 41#include <asm/ipl.h>
40#include <asm/setup.h> 42#include <asm/setup.h>
41#include <asm/sigp.h> 43#include <asm/sigp.h>
@@ -52,6 +54,9 @@
52#include <asm/cpu.h> 54#include <asm/cpu.h>
53#include "entry.h" 55#include "entry.h"
54 56
57/* logical cpu to cpu address */
58unsigned short __cpu_logical_map[NR_CPUS];
59
55static struct task_struct *current_set[NR_CPUS]; 60static struct task_struct *current_set[NR_CPUS];
56 61
57static u8 smp_cpu_type; 62static u8 smp_cpu_type;
@@ -69,13 +74,13 @@ static int cpu_management;
69 74
70static DEFINE_PER_CPU(struct cpu, cpu_devices); 75static DEFINE_PER_CPU(struct cpu, cpu_devices);
71 76
72static void smp_ext_bitcall(int, ec_bit_sig); 77static void smp_ext_bitcall(int, int);
73 78
74static int cpu_stopped(int cpu) 79static int raw_cpu_stopped(int cpu)
75{ 80{
76 __u32 status; 81 u32 status;
77 82
78 switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { 83 switch (raw_sigp_ps(&status, 0, cpu, sigp_sense)) {
79 case sigp_status_stored: 84 case sigp_status_stored:
80 /* Check for stopped and check stop state */ 85 /* Check for stopped and check stop state */
81 if (status & 0x50) 86 if (status & 0x50)
@@ -87,6 +92,44 @@ static int cpu_stopped(int cpu)
87 return 0; 92 return 0;
88} 93}
89 94
95static inline int cpu_stopped(int cpu)
96{
97 return raw_cpu_stopped(cpu_logical_map(cpu));
98}
99
100void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
101{
102 struct _lowcore *lc, *current_lc;
103 struct stack_frame *sf;
104 struct pt_regs *regs;
105 unsigned long sp;
106
107 if (smp_processor_id() == 0)
108 func(data);
109 __load_psw_mask(PSW_BASE_BITS | PSW_DEFAULT_KEY);
110 /* Disable lowcore protection */
111 __ctl_clear_bit(0, 28);
112 current_lc = lowcore_ptr[smp_processor_id()];
113 lc = lowcore_ptr[0];
114 if (!lc)
115 lc = current_lc;
116 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
117 lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu;
118 if (!cpu_online(0))
119 smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]);
120 while (sigp(0, sigp_stop_and_store_status) == sigp_busy)
121 cpu_relax();
122 sp = lc->panic_stack;
123 sp -= sizeof(struct pt_regs);
124 regs = (struct pt_regs *) sp;
125 memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs));
126 regs->psw = lc->psw_save_area;
127 sp -= STACK_FRAME_OVERHEAD;
128 sf = (struct stack_frame *) sp;
129 sf->back_chain = regs->gprs[15];
130 smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]);
131}
132
90void smp_send_stop(void) 133void smp_send_stop(void)
91{ 134{
92 int cpu, rc; 135 int cpu, rc;
@@ -100,7 +143,7 @@ void smp_send_stop(void)
100 if (cpu == smp_processor_id()) 143 if (cpu == smp_processor_id())
101 continue; 144 continue;
102 do { 145 do {
103 rc = signal_processor(cpu, sigp_stop); 146 rc = sigp(cpu, sigp_stop);
104 } while (rc == sigp_busy); 147 } while (rc == sigp_busy);
105 148
106 while (!cpu_stopped(cpu)) 149 while (!cpu_stopped(cpu))
@@ -136,13 +179,13 @@ static void do_ext_call_interrupt(__u16 code)
136 * Send an external call sigp to another cpu and return without waiting 179 * Send an external call sigp to another cpu and return without waiting
137 * for its completion. 180 * for its completion.
138 */ 181 */
139static void smp_ext_bitcall(int cpu, ec_bit_sig sig) 182static void smp_ext_bitcall(int cpu, int sig)
140{ 183{
141 /* 184 /*
142 * Set signaling bit in lowcore of target cpu and kick it 185 * Set signaling bit in lowcore of target cpu and kick it
143 */ 186 */
144 set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); 187 set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
145 while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy) 188 while (sigp(cpu, sigp_emergency_signal) == sigp_busy)
146 udelay(10); 189 udelay(10);
147} 190}
148 191
@@ -236,24 +279,8 @@ void smp_ctl_clear_bit(int cr, int bit)
236} 279}
237EXPORT_SYMBOL(smp_ctl_clear_bit); 280EXPORT_SYMBOL(smp_ctl_clear_bit);
238 281
239/*
240 * In early ipl state a temp. logically cpu number is needed, so the sigp
241 * functions can be used to sense other cpus. Since NR_CPUS is >= 2 on
242 * CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1.
243 */
244#define CPU_INIT_NO 1
245
246#ifdef CONFIG_ZFCPDUMP 282#ifdef CONFIG_ZFCPDUMP
247 283
248/*
249 * zfcpdump_prefix_array holds prefix registers for the following scenario:
250 * 64 bit zfcpdump kernel and 31 bit kernel which is to be dumped. We have to
251 * save its prefix registers, since they get lost, when switching from 31 bit
252 * to 64 bit.
253 */
254unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \
255 __attribute__((__section__(".data")));
256
257static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) 284static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
258{ 285{
259 if (ipl_info.type != IPL_TYPE_FCP_DUMP) 286 if (ipl_info.type != IPL_TYPE_FCP_DUMP)
@@ -263,21 +290,15 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
263 "the dump\n", cpu, NR_CPUS - 1); 290 "the dump\n", cpu, NR_CPUS - 1);
264 return; 291 return;
265 } 292 }
266 zfcpdump_save_areas[cpu] = kmalloc(sizeof(union save_area), GFP_KERNEL); 293 zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL);
267 __cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu; 294 while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy)
268 while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) ==
269 sigp_busy)
270 cpu_relax(); 295 cpu_relax();
271 memcpy(zfcpdump_save_areas[cpu], 296 memcpy_real(zfcpdump_save_areas[cpu],
272 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, 297 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
273 SAVE_AREA_SIZE); 298 sizeof(struct save_area));
274#ifdef CONFIG_64BIT
275 /* copy original prefix register */
276 zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu];
277#endif
278} 299}
279 300
280union save_area *zfcpdump_save_areas[NR_CPUS + 1]; 301struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
281EXPORT_SYMBOL_GPL(zfcpdump_save_areas); 302EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
282 303
283#else 304#else
@@ -386,8 +407,7 @@ static void __init smp_detect_cpus(void)
386 for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) { 407 for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) {
387 if (cpu == boot_cpu_addr) 408 if (cpu == boot_cpu_addr)
388 continue; 409 continue;
389 __cpu_logical_map[CPU_INIT_NO] = cpu; 410 if (!raw_cpu_stopped(cpu))
390 if (!cpu_stopped(CPU_INIT_NO))
391 continue; 411 continue;
392 smp_get_save_area(c_cpus, cpu); 412 smp_get_save_area(c_cpus, cpu);
393 c_cpus++; 413 c_cpus++;
@@ -410,8 +430,7 @@ static void __init smp_detect_cpus(void)
410 cpu_addr = info->cpu[cpu].address; 430 cpu_addr = info->cpu[cpu].address;
411 if (cpu_addr == boot_cpu_addr) 431 if (cpu_addr == boot_cpu_addr)
412 continue; 432 continue;
413 __cpu_logical_map[CPU_INIT_NO] = cpu_addr; 433 if (!raw_cpu_stopped(cpu_addr)) {
414 if (!cpu_stopped(CPU_INIT_NO)) {
415 s_cpus++; 434 s_cpus++;
416 continue; 435 continue;
417 } 436 }
@@ -530,18 +549,18 @@ static void smp_free_lowcore(int cpu)
530/* Upping and downing of CPUs */ 549/* Upping and downing of CPUs */
531int __cpuinit __cpu_up(unsigned int cpu) 550int __cpuinit __cpu_up(unsigned int cpu)
532{ 551{
533 struct task_struct *idle;
534 struct _lowcore *cpu_lowcore; 552 struct _lowcore *cpu_lowcore;
553 struct task_struct *idle;
535 struct stack_frame *sf; 554 struct stack_frame *sf;
536 sigp_ccode ccode;
537 u32 lowcore; 555 u32 lowcore;
556 int ccode;
538 557
539 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) 558 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
540 return -EIO; 559 return -EIO;
541 if (smp_alloc_lowcore(cpu)) 560 if (smp_alloc_lowcore(cpu))
542 return -ENOMEM; 561 return -ENOMEM;
543 do { 562 do {
544 ccode = signal_processor(cpu, sigp_initial_cpu_reset); 563 ccode = sigp(cpu, sigp_initial_cpu_reset);
545 if (ccode == sigp_busy) 564 if (ccode == sigp_busy)
546 udelay(10); 565 udelay(10);
547 if (ccode == sigp_not_operational) 566 if (ccode == sigp_not_operational)
@@ -549,7 +568,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
549 } while (ccode == sigp_busy); 568 } while (ccode == sigp_busy);
550 569
551 lowcore = (u32)(unsigned long)lowcore_ptr[cpu]; 570 lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
552 while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy) 571 while (sigp_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
553 udelay(10); 572 udelay(10);
554 573
555 idle = current_set[cpu]; 574 idle = current_set[cpu];
@@ -575,7 +594,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
575 cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func; 594 cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func;
576 eieio(); 595 eieio();
577 596
578 while (signal_processor(cpu, sigp_restart) == sigp_busy) 597 while (sigp(cpu, sigp_restart) == sigp_busy)
579 udelay(10); 598 udelay(10);
580 599
581 while (!cpu_online(cpu)) 600 while (!cpu_online(cpu))
@@ -637,7 +656,7 @@ void __cpu_die(unsigned int cpu)
637 /* Wait until target cpu is down */ 656 /* Wait until target cpu is down */
638 while (!cpu_stopped(cpu)) 657 while (!cpu_stopped(cpu))
639 cpu_relax(); 658 cpu_relax();
640 while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy) 659 while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy)
641 udelay(10); 660 udelay(10);
642 smp_free_lowcore(cpu); 661 smp_free_lowcore(cpu);
643 pr_info("Processor %d stopped\n", cpu); 662 pr_info("Processor %d stopped\n", cpu);
@@ -646,7 +665,7 @@ void __cpu_die(unsigned int cpu)
646void cpu_die(void) 665void cpu_die(void)
647{ 666{
648 idle_task_exit(); 667 idle_task_exit();
649 while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) 668 while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
650 cpu_relax(); 669 cpu_relax();
651 for (;;); 670 for (;;);
652} 671}
@@ -717,6 +736,12 @@ void __init smp_cpus_done(unsigned int max_cpus)
717{ 736{
718} 737}
719 738
739void __init smp_setup_processor_id(void)
740{
741 S390_lowcore.cpu_nr = 0;
742 __cpu_logical_map[0] = stap();
743}
744
720/* 745/*
721 * the frequency of the profiling timer can be changed 746 * the frequency of the profiling timer can be changed
722 * by writing a multiplier value into /proc/profile. 747 * by writing a multiplier value into /proc/profile.
@@ -756,7 +781,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev,
756 get_online_cpus(); 781 get_online_cpus();
757 mutex_lock(&smp_cpu_state_mutex); 782 mutex_lock(&smp_cpu_state_mutex);
758 rc = -EBUSY; 783 rc = -EBUSY;
759 if (cpu_online(cpu)) 784 /* disallow configuration changes of online cpus and cpu 0 */
785 if (cpu_online(cpu) || cpu == 0)
760 goto out; 786 goto out;
761 rc = 0; 787 rc = 0;
762 switch (val) { 788 switch (val) {
@@ -995,7 +1021,9 @@ out:
995 return rc; 1021 return rc;
996} 1022}
997 1023
998static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf, 1024static ssize_t __ref rescan_store(struct sysdev_class *class,
1025 struct sysdev_class_attribute *attr,
1026 const char *buf,
999 size_t count) 1027 size_t count)
1000{ 1028{
1001 int rc; 1029 int rc;
@@ -1006,7 +1034,9 @@ static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf,
1006static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store); 1034static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store);
1007#endif /* CONFIG_HOTPLUG_CPU */ 1035#endif /* CONFIG_HOTPLUG_CPU */
1008 1036
1009static ssize_t dispatching_show(struct sysdev_class *class, char *buf) 1037static ssize_t dispatching_show(struct sysdev_class *class,
1038 struct sysdev_class_attribute *attr,
1039 char *buf)
1010{ 1040{
1011 ssize_t count; 1041 ssize_t count;
1012 1042
@@ -1016,7 +1046,9 @@ static ssize_t dispatching_show(struct sysdev_class *class, char *buf)
1016 return count; 1046 return count;
1017} 1047}
1018 1048
1019static ssize_t dispatching_store(struct sysdev_class *dev, const char *buf, 1049static ssize_t dispatching_store(struct sysdev_class *dev,
1050 struct sysdev_class_attribute *attr,
1051 const char *buf,
1020 size_t count) 1052 size_t count)
1021{ 1053{
1022 int val, rc; 1054 int val, rc;