diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2010-02-26 16:37:34 -0500 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-02-26 16:37:30 -0500 |
commit | 2c2df118a6440748e6fd71a510a66ee708c31494 (patch) | |
tree | 4e19684886c0c1e7261a1d68de9885302c0565f1 /arch/s390/kernel/smp.c | |
parent | abd1ecf209b30a0ed43f0aae50f8b8ce1be2c3d1 (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.c | 36 |
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 | ||
93 | void 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(®s->gprs, ¤t_lc->gpregs_save_area, sizeof(regs->gprs)); | ||
119 | memcpy(®s->psw, ¤t_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 | |||
93 | void smp_send_stop(void) | 126 | void 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) { |