diff options
Diffstat (limited to 'arch/s390/kernel/crash_dump.c')
-rw-r--r-- | arch/s390/kernel/crash_dump.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index c383ce440d99..cc1172b26873 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/bootmem.h> | 14 | #include <linux/bootmem.h> |
15 | #include <linux/elf.h> | 15 | #include <linux/elf.h> |
16 | #include <asm/ipl.h> | 16 | #include <asm/ipl.h> |
17 | #include <asm/os_info.h> | ||
17 | 18 | ||
18 | #define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y))) | 19 | #define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y))) |
19 | #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y))) | 20 | #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y))) |
@@ -51,7 +52,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, | |||
51 | /* | 52 | /* |
52 | * Copy memory from old kernel | 53 | * Copy memory from old kernel |
53 | */ | 54 | */ |
54 | static int copy_from_oldmem(void *dest, void *src, size_t count) | 55 | int copy_from_oldmem(void *dest, void *src, size_t count) |
55 | { | 56 | { |
56 | unsigned long copied = 0; | 57 | unsigned long copied = 0; |
57 | int rc; | 58 | int rc; |
@@ -224,28 +225,44 @@ static void *nt_prpsinfo(void *ptr) | |||
224 | } | 225 | } |
225 | 226 | ||
226 | /* | 227 | /* |
227 | * Initialize vmcoreinfo note (new kernel) | 228 | * Get vmcoreinfo using lowcore->vmcore_info (new kernel) |
228 | */ | 229 | */ |
229 | static void *nt_vmcoreinfo(void *ptr) | 230 | static void *get_vmcoreinfo_old(unsigned long *size) |
230 | { | 231 | { |
231 | char nt_name[11], *vmcoreinfo; | 232 | char nt_name[11], *vmcoreinfo; |
232 | Elf64_Nhdr note; | 233 | Elf64_Nhdr note; |
233 | void *addr; | 234 | void *addr; |
234 | 235 | ||
235 | if (copy_from_oldmem(&addr, &S390_lowcore.vmcore_info, sizeof(addr))) | 236 | if (copy_from_oldmem(&addr, &S390_lowcore.vmcore_info, sizeof(addr))) |
236 | return ptr; | 237 | return NULL; |
237 | memset(nt_name, 0, sizeof(nt_name)); | 238 | memset(nt_name, 0, sizeof(nt_name)); |
238 | if (copy_from_oldmem(¬e, addr, sizeof(note))) | 239 | if (copy_from_oldmem(¬e, addr, sizeof(note))) |
239 | return ptr; | 240 | return NULL; |
240 | if (copy_from_oldmem(nt_name, addr + sizeof(note), sizeof(nt_name) - 1)) | 241 | if (copy_from_oldmem(nt_name, addr + sizeof(note), sizeof(nt_name) - 1)) |
241 | return ptr; | 242 | return NULL; |
242 | if (strcmp(nt_name, "VMCOREINFO") != 0) | 243 | if (strcmp(nt_name, "VMCOREINFO") != 0) |
243 | return ptr; | 244 | return NULL; |
244 | vmcoreinfo = kzalloc_panic(note.n_descsz + 1); | 245 | vmcoreinfo = kzalloc_panic(note.n_descsz); |
245 | if (copy_from_oldmem(vmcoreinfo, addr + 24, note.n_descsz)) | 246 | if (copy_from_oldmem(vmcoreinfo, addr + 24, note.n_descsz)) |
247 | return NULL; | ||
248 | *size = note.n_descsz; | ||
249 | return vmcoreinfo; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Initialize vmcoreinfo note (new kernel) | ||
254 | */ | ||
255 | static void *nt_vmcoreinfo(void *ptr) | ||
256 | { | ||
257 | unsigned long size; | ||
258 | void *vmcoreinfo; | ||
259 | |||
260 | vmcoreinfo = os_info_old_entry(OS_INFO_VMCOREINFO, &size); | ||
261 | if (!vmcoreinfo) | ||
262 | vmcoreinfo = get_vmcoreinfo_old(&size); | ||
263 | if (!vmcoreinfo) | ||
246 | return ptr; | 264 | return ptr; |
247 | vmcoreinfo[note.n_descsz + 1] = 0; | 265 | return nt_init(ptr, 0, vmcoreinfo, size, "VMCOREINFO"); |
248 | return nt_init(ptr, 0, vmcoreinfo, note.n_descsz, "VMCOREINFO"); | ||
249 | } | 266 | } |
250 | 267 | ||
251 | /* | 268 | /* |