diff options
Diffstat (limited to 'arch/s390/kernel/machine_kexec.c')
-rw-r--r-- | arch/s390/kernel/machine_kexec.c | 52 |
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 | */ | ||
54 | static 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 | */ |
76 | void setup_regs(void) | 55 | void 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 | } |