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.c45
1 files changed, 10 insertions, 35 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 647ba9425893..15cca26ccb6c 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -297,26 +297,27 @@ static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data)
297static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), 297static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *),
298 void *data, unsigned long stack) 298 void *data, unsigned long stack)
299{ 299{
300 struct _lowcore *lc = pcpu->lowcore; 300 struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices];
301 unsigned short this_cpu; 301 struct {
302 unsigned long stack;
303 void *func;
304 void *data;
305 unsigned long source;
306 } restart = { stack, func, data, stap() };
302 307
303 __load_psw_mask(psw_kernel_bits); 308 __load_psw_mask(psw_kernel_bits);
304 this_cpu = stap(); 309 if (pcpu->address == restart.source)
305 if (pcpu->address == this_cpu)
306 func(data); /* should not return */ 310 func(data); /* should not return */
307 /* Stop target cpu (if func returns this stops the current cpu). */ 311 /* Stop target cpu (if func returns this stops the current cpu). */
308 pcpu_sigp_retry(pcpu, sigp_stop, 0); 312 pcpu_sigp_retry(pcpu, sigp_stop, 0);
309 /* Restart func on the target cpu and stop the current cpu. */ 313 /* Restart func on the target cpu and stop the current cpu. */
310 lc->restart_stack = stack; 314 memcpy_absolute(&lc->restart_stack, &restart, sizeof(restart));
311 lc->restart_fn = (unsigned long) func;
312 lc->restart_data = (unsigned long) data;
313 lc->restart_source = (unsigned long) this_cpu;
314 asm volatile( 315 asm volatile(
315 "0: sigp 0,%0,6 # sigp restart to target cpu\n" 316 "0: sigp 0,%0,6 # sigp restart to target cpu\n"
316 " brc 2,0b # busy, try again\n" 317 " brc 2,0b # busy, try again\n"
317 "1: sigp 0,%1,5 # sigp stop to current cpu\n" 318 "1: sigp 0,%1,5 # sigp stop to current cpu\n"
318 " brc 2,1b # busy, try again\n" 319 " brc 2,1b # busy, try again\n"
319 : : "d" (pcpu->address), "d" (this_cpu) : "0", "1", "cc"); 320 : : "d" (pcpu->address), "d" (restart.source) : "0", "1", "cc");
320 for (;;) ; 321 for (;;) ;
321} 322}
322 323
@@ -800,17 +801,6 @@ void __noreturn cpu_die(void)
800 801
801#endif /* CONFIG_HOTPLUG_CPU */ 802#endif /* CONFIG_HOTPLUG_CPU */
802 803
803static void smp_call_os_info_init_fn(void)
804{
805 int (*init_fn)(void);
806 unsigned long size;
807
808 init_fn = os_info_old_entry(OS_INFO_INIT_FN, &size);
809 if (!init_fn)
810 return;
811 init_fn();
812}
813
814void __init smp_prepare_cpus(unsigned int max_cpus) 804void __init smp_prepare_cpus(unsigned int max_cpus)
815{ 805{
816 /* request the 0x1201 emergency signal external interrupt */ 806 /* request the 0x1201 emergency signal external interrupt */
@@ -819,7 +809,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
819 /* request the 0x1202 external call external interrupt */ 809 /* request the 0x1202 external call external interrupt */
820 if (register_external_interrupt(0x1202, do_ext_call_interrupt) != 0) 810 if (register_external_interrupt(0x1202, do_ext_call_interrupt) != 0)
821 panic("Couldn't request external interrupt 0x1202"); 811 panic("Couldn't request external interrupt 0x1202");
822 smp_call_os_info_init_fn();
823 smp_detect_cpus(); 812 smp_detect_cpus();
824} 813}
825 814
@@ -943,19 +932,6 @@ static struct attribute_group cpu_common_attr_group = {
943 .attrs = cpu_common_attrs, 932 .attrs = cpu_common_attrs,
944}; 933};
945 934
946static ssize_t show_capability(struct device *dev,
947 struct device_attribute *attr, char *buf)
948{
949 unsigned int capability;
950 int rc;
951
952 rc = get_cpu_capability(&capability);
953 if (rc)
954 return rc;
955 return sprintf(buf, "%u\n", capability);
956}
957static DEVICE_ATTR(capability, 0444, show_capability, NULL);
958
959static ssize_t show_idle_count(struct device *dev, 935static ssize_t show_idle_count(struct device *dev,
960 struct device_attribute *attr, char *buf) 936 struct device_attribute *attr, char *buf)
961{ 937{
@@ -993,7 +969,6 @@ static ssize_t show_idle_time(struct device *dev,
993static DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL); 969static DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL);
994 970
995static struct attribute *cpu_online_attrs[] = { 971static struct attribute *cpu_online_attrs[] = {
996 &dev_attr_capability.attr,
997 &dev_attr_idle_count.attr, 972 &dev_attr_idle_count.attr,
998 &dev_attr_idle_time_us.attr, 973 &dev_attr_idle_time_us.attr,
999 NULL, 974 NULL,