aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/machine_kexec.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/machine_kexec.c')
-rw-r--r--arch/s390/kernel/machine_kexec.c52
1 files changed, 14 insertions, 38 deletions
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 47b168fb29c..0f8cdf1268d 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -14,6 +14,7 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/reboot.h> 15#include <linux/reboot.h>
16#include <linux/ftrace.h> 16#include <linux/ftrace.h>
17#include <linux/debug_locks.h>
17#include <asm/cio.h> 18#include <asm/cio.h>
18#include <asm/setup.h> 19#include <asm/setup.h>
19#include <asm/pgtable.h> 20#include <asm/pgtable.h>
@@ -49,50 +50,21 @@ static void add_elf_notes(int cpu)
49} 50}
50 51
51/* 52/*
52 * Store status of next available physical CPU
53 */
54static int store_status_next(int start_cpu, int this_cpu)
55{
56 struct save_area *sa = (void *) 4608 + store_prefix();
57 int cpu, rc;
58
59 for (cpu = start_cpu; cpu < 65536; cpu++) {
60 if (cpu == this_cpu)
61 continue;
62 do {
63 rc = raw_sigp(cpu, sigp_stop_and_store_status);
64 } while (rc == sigp_busy);
65 if (rc != sigp_order_code_accepted)
66 continue;
67 if (sa->pref_reg)
68 return cpu;
69 }
70 return -1;
71}
72
73/*
74 * Initialize CPU ELF notes 53 * Initialize CPU ELF notes
75 */ 54 */
76void setup_regs(void) 55void setup_regs(void)
77{ 56{
78 unsigned long sa = S390_lowcore.prefixreg_save_area + SAVE_AREA_BASE; 57 unsigned long sa = S390_lowcore.prefixreg_save_area + SAVE_AREA_BASE;
79 int cpu, this_cpu, phys_cpu = 0, first = 1; 58 int cpu, this_cpu;
80 59
81 this_cpu = stap(); 60 this_cpu = smp_find_processor_id(stap());
82 61 add_elf_notes(this_cpu);
83 if (!S390_lowcore.prefixreg_save_area)
84 first = 0;
85 for_each_online_cpu(cpu) { 62 for_each_online_cpu(cpu) {
86 if (first) { 63 if (cpu == this_cpu)
87 add_elf_notes(cpu); 64 continue;
88 first = 0; 65 if (smp_store_status(cpu))
89 continue; 66 continue;
90 }
91 phys_cpu = store_status_next(phys_cpu, this_cpu);
92 if (phys_cpu == -1)
93 break;
94 add_elf_notes(cpu); 67 add_elf_notes(cpu);
95 phys_cpu++;
96 } 68 }
97 /* Copy dump CPU store status info to absolute zero */ 69 /* Copy dump CPU store status info to absolute zero */
98 memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area)); 70 memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area));
@@ -238,10 +210,14 @@ static void __machine_kexec(void *data)
238 struct kimage *image = data; 210 struct kimage *image = data;
239 211
240 pfault_fini(); 212 pfault_fini();
241 if (image->type == KEXEC_TYPE_CRASH) 213 tracing_off();
214 debug_locks_off();
215 if (image->type == KEXEC_TYPE_CRASH) {
216 lgr_info_log();
242 s390_reset_system(__do_machine_kdump, data); 217 s390_reset_system(__do_machine_kdump, data);
243 else 218 } else {
244 s390_reset_system(__do_machine_kexec, data); 219 s390_reset_system(__do_machine_kexec, data);
220 }
245 disabled_wait((unsigned long) __builtin_return_address(0)); 221 disabled_wait((unsigned long) __builtin_return_address(0));
246} 222}
247 223
@@ -255,5 +231,5 @@ void machine_kexec(struct kimage *image)
255 return; 231 return;
256 tracer_disable(); 232 tracer_disable();
257 smp_send_stop(); 233 smp_send_stop();
258 smp_switch_to_ipl_cpu(__machine_kexec, image); 234 smp_call_ipl_cpu(__machine_kexec, image);
259} 235}