| .. | .. |
|---|
| 14 | 14 | #include <linux/reboot.h> |
|---|
| 15 | 15 | #include <linux/ftrace.h> |
|---|
| 16 | 16 | #include <linux/debug_locks.h> |
|---|
| 17 | | -#include <linux/suspend.h> |
|---|
| 18 | 17 | #include <asm/cio.h> |
|---|
| 19 | 18 | #include <asm/setup.h> |
|---|
| 20 | | -#include <asm/pgtable.h> |
|---|
| 21 | | -#include <asm/pgalloc.h> |
|---|
| 22 | 19 | #include <asm/smp.h> |
|---|
| 23 | 20 | #include <asm/ipl.h> |
|---|
| 24 | 21 | #include <asm/diag.h> |
|---|
| .. | .. |
|---|
| 27 | 24 | #include <asm/cacheflush.h> |
|---|
| 28 | 25 | #include <asm/os_info.h> |
|---|
| 29 | 26 | #include <asm/set_memory.h> |
|---|
| 27 | +#include <asm/stacktrace.h> |
|---|
| 30 | 28 | #include <asm/switch_to.h> |
|---|
| 31 | 29 | #include <asm/nmi.h> |
|---|
| 32 | 30 | |
|---|
| .. | .. |
|---|
| 36 | 34 | extern const unsigned long long relocate_kernel_len; |
|---|
| 37 | 35 | |
|---|
| 38 | 36 | #ifdef CONFIG_CRASH_DUMP |
|---|
| 39 | | - |
|---|
| 40 | | -/* |
|---|
| 41 | | - * PM notifier callback for kdump |
|---|
| 42 | | - */ |
|---|
| 43 | | -static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action, |
|---|
| 44 | | - void *ptr) |
|---|
| 45 | | -{ |
|---|
| 46 | | - switch (action) { |
|---|
| 47 | | - case PM_SUSPEND_PREPARE: |
|---|
| 48 | | - case PM_HIBERNATION_PREPARE: |
|---|
| 49 | | - if (kexec_crash_image) |
|---|
| 50 | | - arch_kexec_unprotect_crashkres(); |
|---|
| 51 | | - break; |
|---|
| 52 | | - case PM_POST_SUSPEND: |
|---|
| 53 | | - case PM_POST_HIBERNATION: |
|---|
| 54 | | - if (kexec_crash_image) |
|---|
| 55 | | - arch_kexec_protect_crashkres(); |
|---|
| 56 | | - break; |
|---|
| 57 | | - default: |
|---|
| 58 | | - return NOTIFY_DONE; |
|---|
| 59 | | - } |
|---|
| 60 | | - return NOTIFY_OK; |
|---|
| 61 | | -} |
|---|
| 62 | | - |
|---|
| 63 | | -static int __init machine_kdump_pm_init(void) |
|---|
| 64 | | -{ |
|---|
| 65 | | - pm_notifier(machine_kdump_pm_cb, 0); |
|---|
| 66 | | - return 0; |
|---|
| 67 | | -} |
|---|
| 68 | | -arch_initcall(machine_kdump_pm_init); |
|---|
| 69 | 37 | |
|---|
| 70 | 38 | /* |
|---|
| 71 | 39 | * Reset the system, copy boot CPU registers to absolute zero, |
|---|
| .. | .. |
|---|
| 95 | 63 | start_kdump(1); |
|---|
| 96 | 64 | |
|---|
| 97 | 65 | /* Die if start_kdump returns */ |
|---|
| 98 | | - disabled_wait((unsigned long) __builtin_return_address(0)); |
|---|
| 66 | + disabled_wait(); |
|---|
| 99 | 67 | } |
|---|
| 100 | 68 | |
|---|
| 101 | 69 | /* |
|---|
| .. | .. |
|---|
| 140 | 108 | */ |
|---|
| 141 | 109 | store_status(__do_machine_kdump, image); |
|---|
| 142 | 110 | } |
|---|
| 143 | | -#endif |
|---|
| 111 | + |
|---|
| 112 | +static unsigned long do_start_kdump(unsigned long addr) |
|---|
| 113 | +{ |
|---|
| 114 | + struct kimage *image = (struct kimage *) addr; |
|---|
| 115 | + int (*start_kdump)(int) = (void *)image->start; |
|---|
| 116 | + int rc; |
|---|
| 117 | + |
|---|
| 118 | + __arch_local_irq_stnsm(0xfb); /* disable DAT */ |
|---|
| 119 | + rc = start_kdump(0); |
|---|
| 120 | + __arch_local_irq_stosm(0x04); /* enable DAT */ |
|---|
| 121 | + return rc; |
|---|
| 122 | +} |
|---|
| 123 | + |
|---|
| 124 | +#endif /* CONFIG_CRASH_DUMP */ |
|---|
| 144 | 125 | |
|---|
| 145 | 126 | /* |
|---|
| 146 | 127 | * Check if kdump checksums are valid: We call purgatory with parameter "0" |
|---|
| .. | .. |
|---|
| 148 | 129 | static bool kdump_csum_valid(struct kimage *image) |
|---|
| 149 | 130 | { |
|---|
| 150 | 131 | #ifdef CONFIG_CRASH_DUMP |
|---|
| 151 | | - int (*start_kdump)(int) = (void *)image->start; |
|---|
| 152 | 132 | int rc; |
|---|
| 153 | 133 | |
|---|
| 154 | | - __arch_local_irq_stnsm(0xfb); /* disable DAT */ |
|---|
| 155 | | - rc = start_kdump(0); |
|---|
| 156 | | - __arch_local_irq_stosm(0x04); /* enable DAT */ |
|---|
| 134 | + preempt_disable(); |
|---|
| 135 | + rc = CALL_ON_STACK(do_start_kdump, S390_lowcore.nodat_stack, 1, image); |
|---|
| 136 | + preempt_enable(); |
|---|
| 157 | 137 | return rc == 0; |
|---|
| 158 | 138 | #else |
|---|
| 159 | 139 | return false; |
|---|
| .. | .. |
|---|
| 243 | 223 | VMCOREINFO_SYMBOL(lowcore_ptr); |
|---|
| 244 | 224 | VMCOREINFO_SYMBOL(high_memory); |
|---|
| 245 | 225 | VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS); |
|---|
| 226 | + vmcoreinfo_append_str("SDMA=%lx\n", __sdma); |
|---|
| 227 | + vmcoreinfo_append_str("EDMA=%lx\n", __edma); |
|---|
| 228 | + vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset()); |
|---|
| 246 | 229 | mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note()); |
|---|
| 247 | 230 | } |
|---|
| 248 | 231 | |
|---|
| .. | .. |
|---|
| 271 | 254 | (*data_mover)(&image->head, image->start); |
|---|
| 272 | 255 | |
|---|
| 273 | 256 | /* Die if kexec returns */ |
|---|
| 274 | | - disabled_wait((unsigned long) __builtin_return_address(0)); |
|---|
| 257 | + disabled_wait(); |
|---|
| 275 | 258 | } |
|---|
| 276 | 259 | |
|---|
| 277 | 260 | /* |
|---|