aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/smp.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2010-02-26 16:37:34 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-02-26 16:37:30 -0500
commit2c2df118a6440748e6fd71a510a66ee708c31494 (patch)
tree4e19684886c0c1e7261a1d68de9885302c0565f1 /arch/s390/kernel/smp.c
parentabd1ecf209b30a0ed43f0aae50f8b8ce1be2c3d1 (diff)
[S390] smp: always reboot on cpu 0
Always reboot on logical cpu 0. This makes sure that the IPL cpu is always the same and usually avoids strange numbering schemes between physical and logical cpus. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r--arch/s390/kernel/smp.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 384a6846a65e..b39f596d71bd 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -90,6 +90,39 @@ static int cpu_stopped(int cpu)
90 return 0; 90 return 0;
91} 91}
92 92
93void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
94{
95 struct _lowcore *lc, *current_lc;
96 struct stack_frame *sf;
97 struct pt_regs *regs;
98 unsigned long sp;
99
100 if (smp_processor_id() == 0)
101 func(data);
102 __load_psw_mask(PSW_BASE_BITS | PSW_DEFAULT_KEY);
103 /* Disable lowcore protection */
104 __ctl_clear_bit(0, 28);
105 current_lc = lowcore_ptr[smp_processor_id()];
106 lc = lowcore_ptr[0];
107 if (!lc)
108 lc = current_lc;
109 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
110 lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu;
111 if (!cpu_online(0))
112 smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]);
113 while (signal_processor(0, sigp_stop_and_store_status) == sigp_busy)
114 cpu_relax();
115 sp = lc->panic_stack;
116 sp -= sizeof(struct pt_regs);
117 regs = (struct pt_regs *) sp;
118 memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs));
119 memcpy(&regs->psw, &current_lc->st_status_fixed_logout, sizeof(psw_t));
120 sp -= STACK_FRAME_OVERHEAD;
121 sf = (struct stack_frame *) sp;
122 sf->back_chain = regs->gprs[15];
123 smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]);
124}
125
93void smp_send_stop(void) 126void smp_send_stop(void)
94{ 127{
95 int cpu, rc; 128 int cpu, rc;
@@ -752,7 +785,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev,
752 get_online_cpus(); 785 get_online_cpus();
753 mutex_lock(&smp_cpu_state_mutex); 786 mutex_lock(&smp_cpu_state_mutex);
754 rc = -EBUSY; 787 rc = -EBUSY;
755 if (cpu_online(cpu)) 788 /* disallow configuration changes of online cpus and cpu 0 */
789 if (cpu_online(cpu) || cpu == 0)
756 goto out; 790 goto out;
757 rc = 0; 791 rc = 0;
758 switch (val) { 792 switch (val) {