2 * S390 kdump implementation
4 * Copyright IBM Corp. 2011
5 * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
8 #include <linux/crash_dump.h>
9 #include <asm/lowcore.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/gfp.h>
13 #include <linux/slab.h>
14 #include <linux/bootmem.h>
15 #include <linux/elf.h>
16 #include <linux/memblock.h>
17 #include <asm/os_info.h>
22 #define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y)))
23 #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y)))
24 #define PTR_DIFF(x, y) ((unsigned long)(((char *) (x)) - ((unsigned long) (y))))
26 static struct memblock_region oldmem_region
;
28 static struct memblock_type oldmem_type
= {
32 .regions
= &oldmem_region
,
35 struct dump_save_areas dump_save_areas
;
38 * Return physical address for virtual address
40 static inline void *load_real_addr(void *addr
)
42 unsigned long real_addr
;
49 : "=a" (real_addr
) : "a" (addr
) : "cc");
50 return (void *)real_addr
;
54 * Copy memory of the old, dumped system to a kernel space virtual address
56 int copy_oldmem_kernel(void *dst
, void *src
, size_t count
)
58 unsigned long from
, len
;
64 if (!OLDMEM_BASE
&& from
< sclp
.hsa_size
) {
65 /* Copy from zfcpdump HSA area */
66 len
= min(count
, sclp
.hsa_size
- from
);
67 rc
= memcpy_hsa_kernel(dst
, from
, len
);
71 /* Check for swapped kdump oldmem areas */
72 if (OLDMEM_BASE
&& from
- OLDMEM_BASE
< OLDMEM_SIZE
) {
74 len
= min(count
, OLDMEM_SIZE
- from
);
75 } else if (OLDMEM_BASE
&& from
< OLDMEM_SIZE
) {
76 len
= min(count
, OLDMEM_SIZE
- from
);
81 if (is_vmalloc_or_module_addr(dst
)) {
82 ra
= load_real_addr(dst
);
83 len
= min(PAGE_SIZE
- offset_in_page(ra
), len
);
87 if (memcpy_real(ra
, (void *) from
, len
))
98 * Copy memory of the old, dumped system to a user space virtual address
100 int copy_oldmem_user(void __user
*dst
, void *src
, size_t count
)
102 unsigned long from
, len
;
107 if (!OLDMEM_BASE
&& from
< sclp
.hsa_size
) {
108 /* Copy from zfcpdump HSA area */
109 len
= min(count
, sclp
.hsa_size
- from
);
110 rc
= memcpy_hsa_user(dst
, from
, len
);
114 /* Check for swapped kdump oldmem areas */
115 if (OLDMEM_BASE
&& from
- OLDMEM_BASE
< OLDMEM_SIZE
) {
117 len
= min(count
, OLDMEM_SIZE
- from
);
118 } else if (OLDMEM_BASE
&& from
< OLDMEM_SIZE
) {
119 len
= min(count
, OLDMEM_SIZE
- from
);
124 rc
= copy_to_user_real(dst
, (void *) from
, count
);
136 * Copy one page from "oldmem"
138 ssize_t
copy_oldmem_page(unsigned long pfn
, char *buf
, size_t csize
,
139 unsigned long offset
, int userbuf
)
146 src
= (void *) (pfn
<< PAGE_SHIFT
) + offset
;
148 rc
= copy_oldmem_user((void __force __user
*) buf
, src
, csize
);
150 rc
= copy_oldmem_kernel((void *) buf
, src
, csize
);
155 * Remap "oldmem" for kdump
157 * For the kdump reserved memory this functions performs a swap operation:
158 * [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE]
160 static int remap_oldmem_pfn_range_kdump(struct vm_area_struct
*vma
,
161 unsigned long from
, unsigned long pfn
,
162 unsigned long size
, pgprot_t prot
)
164 unsigned long size_old
;
167 if (pfn
< OLDMEM_SIZE
>> PAGE_SHIFT
) {
168 size_old
= min(size
, OLDMEM_SIZE
- (pfn
<< PAGE_SHIFT
));
169 rc
= remap_pfn_range(vma
, from
,
170 pfn
+ (OLDMEM_BASE
>> PAGE_SHIFT
),
172 if (rc
|| size
== size_old
)
176 pfn
+= size_old
>> PAGE_SHIFT
;
178 return remap_pfn_range(vma
, from
, pfn
, size
, prot
);
182 * Remap "oldmem" for zfcpdump
184 * We only map available memory above HSA size. Memory below HSA size
185 * is read on demand using the copy_oldmem_page() function.
187 static int remap_oldmem_pfn_range_zfcpdump(struct vm_area_struct
*vma
,
190 unsigned long size
, pgprot_t prot
)
192 unsigned long hsa_end
= sclp
.hsa_size
;
193 unsigned long size_hsa
;
195 if (pfn
< hsa_end
>> PAGE_SHIFT
) {
196 size_hsa
= min(size
, hsa_end
- (pfn
<< PAGE_SHIFT
));
197 if (size
== size_hsa
)
201 pfn
+= size_hsa
>> PAGE_SHIFT
;
203 return remap_pfn_range(vma
, from
, pfn
, size
, prot
);
207 * Remap "oldmem" for kdump or zfcpdump
209 int remap_oldmem_pfn_range(struct vm_area_struct
*vma
, unsigned long from
,
210 unsigned long pfn
, unsigned long size
, pgprot_t prot
)
213 return remap_oldmem_pfn_range_kdump(vma
, from
, pfn
, size
, prot
);
215 return remap_oldmem_pfn_range_zfcpdump(vma
, from
, pfn
, size
,
220 * Alloc memory and panic in case of ENOMEM
222 static void *kzalloc_panic(int len
)
226 rc
= kzalloc(len
, GFP_KERNEL
);
228 panic("s390 kdump kzalloc (%d) failed", len
);
233 * Initialize ELF note
235 static void *nt_init(void *buf
, Elf64_Word type
, void *desc
, int d_len
,
241 note
= (Elf64_Nhdr
*)buf
;
242 note
->n_namesz
= strlen(name
) + 1;
243 note
->n_descsz
= d_len
;
245 len
= sizeof(Elf64_Nhdr
);
247 memcpy(buf
+ len
, name
, note
->n_namesz
);
248 len
= roundup(len
+ note
->n_namesz
, 4);
250 memcpy(buf
+ len
, desc
, note
->n_descsz
);
251 len
= roundup(len
+ note
->n_descsz
, 4);
253 return PTR_ADD(buf
, len
);
257 * Initialize prstatus note
259 static void *nt_prstatus(void *ptr
, struct save_area
*sa
)
261 struct elf_prstatus nt_prstatus
;
262 static int cpu_nr
= 1;
264 memset(&nt_prstatus
, 0, sizeof(nt_prstatus
));
265 memcpy(&nt_prstatus
.pr_reg
.gprs
, sa
->gp_regs
, sizeof(sa
->gp_regs
));
266 memcpy(&nt_prstatus
.pr_reg
.psw
, sa
->psw
, sizeof(sa
->psw
));
267 memcpy(&nt_prstatus
.pr_reg
.acrs
, sa
->acc_regs
, sizeof(sa
->acc_regs
));
268 nt_prstatus
.pr_pid
= cpu_nr
;
271 return nt_init(ptr
, NT_PRSTATUS
, &nt_prstatus
, sizeof(nt_prstatus
),
276 * Initialize fpregset (floating point) note
278 static void *nt_fpregset(void *ptr
, struct save_area
*sa
)
280 elf_fpregset_t nt_fpregset
;
282 memset(&nt_fpregset
, 0, sizeof(nt_fpregset
));
283 memcpy(&nt_fpregset
.fpc
, &sa
->fp_ctrl_reg
, sizeof(sa
->fp_ctrl_reg
));
284 memcpy(&nt_fpregset
.fprs
, &sa
->fp_regs
, sizeof(sa
->fp_regs
));
286 return nt_init(ptr
, NT_PRFPREG
, &nt_fpregset
, sizeof(nt_fpregset
),
291 * Initialize timer note
293 static void *nt_s390_timer(void *ptr
, struct save_area
*sa
)
295 return nt_init(ptr
, NT_S390_TIMER
, &sa
->timer
, sizeof(sa
->timer
),
296 KEXEC_CORE_NOTE_NAME
);
300 * Initialize TOD clock comparator note
302 static void *nt_s390_tod_cmp(void *ptr
, struct save_area
*sa
)
304 return nt_init(ptr
, NT_S390_TODCMP
, &sa
->clk_cmp
,
305 sizeof(sa
->clk_cmp
), KEXEC_CORE_NOTE_NAME
);
309 * Initialize TOD programmable register note
311 static void *nt_s390_tod_preg(void *ptr
, struct save_area
*sa
)
313 return nt_init(ptr
, NT_S390_TODPREG
, &sa
->tod_reg
,
314 sizeof(sa
->tod_reg
), KEXEC_CORE_NOTE_NAME
);
318 * Initialize control register note
320 static void *nt_s390_ctrs(void *ptr
, struct save_area
*sa
)
322 return nt_init(ptr
, NT_S390_CTRS
, &sa
->ctrl_regs
,
323 sizeof(sa
->ctrl_regs
), KEXEC_CORE_NOTE_NAME
);
327 * Initialize prefix register note
329 static void *nt_s390_prefix(void *ptr
, struct save_area
*sa
)
331 return nt_init(ptr
, NT_S390_PREFIX
, &sa
->pref_reg
,
332 sizeof(sa
->pref_reg
), KEXEC_CORE_NOTE_NAME
);
336 * Initialize vxrs high note (full 128 bit VX registers 16-31)
338 static void *nt_s390_vx_high(void *ptr
, __vector128
*vx_regs
)
340 return nt_init(ptr
, NT_S390_VXRS_HIGH
, &vx_regs
[16],
341 16 * sizeof(__vector128
), KEXEC_CORE_NOTE_NAME
);
345 * Initialize vxrs low note (lower halves of VX registers 0-15)
347 static void *nt_s390_vx_low(void *ptr
, __vector128
*vx_regs
)
353 note
= (Elf64_Nhdr
*)ptr
;
354 note
->n_namesz
= strlen(KEXEC_CORE_NOTE_NAME
) + 1;
355 note
->n_descsz
= 16 * 8;
356 note
->n_type
= NT_S390_VXRS_LOW
;
357 len
= sizeof(Elf64_Nhdr
);
359 memcpy(ptr
+ len
, KEXEC_CORE_NOTE_NAME
, note
->n_namesz
);
360 len
= roundup(len
+ note
->n_namesz
, 4);
363 /* Copy lower halves of SIMD registers 0-15 */
364 for (i
= 0; i
< 16; i
++) {
365 memcpy(ptr
, &vx_regs
[i
].u
[2], 8);
372 * Fill ELF notes for one CPU with save area registers
374 static void *fill_cpu_elf_notes(void *ptr
, struct save_area
*sa
,
375 __vector128
*vx_regs
)
377 ptr
= nt_prstatus(ptr
, sa
);
378 ptr
= nt_fpregset(ptr
, sa
);
379 ptr
= nt_s390_timer(ptr
, sa
);
380 ptr
= nt_s390_tod_cmp(ptr
, sa
);
381 ptr
= nt_s390_tod_preg(ptr
, sa
);
382 ptr
= nt_s390_ctrs(ptr
, sa
);
383 ptr
= nt_s390_prefix(ptr
, sa
);
384 if (MACHINE_HAS_VX
&& vx_regs
) {
385 ptr
= nt_s390_vx_low(ptr
, vx_regs
);
386 ptr
= nt_s390_vx_high(ptr
, vx_regs
);
392 * Initialize prpsinfo note (new kernel)
394 static void *nt_prpsinfo(void *ptr
)
396 struct elf_prpsinfo prpsinfo
;
398 memset(&prpsinfo
, 0, sizeof(prpsinfo
));
399 prpsinfo
.pr_sname
= 'R';
400 strcpy(prpsinfo
.pr_fname
, "vmlinux");
401 return nt_init(ptr
, NT_PRPSINFO
, &prpsinfo
, sizeof(prpsinfo
),
402 KEXEC_CORE_NOTE_NAME
);
406 * Get vmcoreinfo using lowcore->vmcore_info (new kernel)
408 static void *get_vmcoreinfo_old(unsigned long *size
)
410 char nt_name
[11], *vmcoreinfo
;
414 if (copy_oldmem_kernel(&addr
, &S390_lowcore
.vmcore_info
, sizeof(addr
)))
416 memset(nt_name
, 0, sizeof(nt_name
));
417 if (copy_oldmem_kernel(¬e
, addr
, sizeof(note
)))
419 if (copy_oldmem_kernel(nt_name
, addr
+ sizeof(note
),
420 sizeof(nt_name
) - 1))
422 if (strcmp(nt_name
, "VMCOREINFO") != 0)
424 vmcoreinfo
= kzalloc_panic(note
.n_descsz
);
425 if (copy_oldmem_kernel(vmcoreinfo
, addr
+ 24, note
.n_descsz
))
427 *size
= note
.n_descsz
;
432 * Initialize vmcoreinfo note (new kernel)
434 static void *nt_vmcoreinfo(void *ptr
)
439 vmcoreinfo
= os_info_old_entry(OS_INFO_VMCOREINFO
, &size
);
441 vmcoreinfo
= get_vmcoreinfo_old(&size
);
444 return nt_init(ptr
, 0, vmcoreinfo
, size
, "VMCOREINFO");
448 * Initialize ELF header (new kernel)
450 static void *ehdr_init(Elf64_Ehdr
*ehdr
, int mem_chunk_cnt
)
452 memset(ehdr
, 0, sizeof(*ehdr
));
453 memcpy(ehdr
->e_ident
, ELFMAG
, SELFMAG
);
454 ehdr
->e_ident
[EI_CLASS
] = ELFCLASS64
;
455 ehdr
->e_ident
[EI_DATA
] = ELFDATA2MSB
;
456 ehdr
->e_ident
[EI_VERSION
] = EV_CURRENT
;
457 memset(ehdr
->e_ident
+ EI_PAD
, 0, EI_NIDENT
- EI_PAD
);
458 ehdr
->e_type
= ET_CORE
;
459 ehdr
->e_machine
= EM_S390
;
460 ehdr
->e_version
= EV_CURRENT
;
461 ehdr
->e_phoff
= sizeof(Elf64_Ehdr
);
462 ehdr
->e_ehsize
= sizeof(Elf64_Ehdr
);
463 ehdr
->e_phentsize
= sizeof(Elf64_Phdr
);
464 ehdr
->e_phnum
= mem_chunk_cnt
+ 1;
469 * Return CPU count for ELF header (new kernel)
471 static int get_cpu_cnt(void)
475 for (i
= 0; i
< dump_save_areas
.count
; i
++) {
476 if (dump_save_areas
.areas
[i
]->sa
.pref_reg
== 0)
484 * Return memory chunk count for ELF header (new kernel)
486 static int get_mem_chunk_cnt(void)
491 for_each_mem_range(idx
, &memblock
.physmem
, &oldmem_type
, NUMA_NO_NODE
,
492 MEMBLOCK_NONE
, NULL
, NULL
, NULL
)
498 * Initialize ELF loads (new kernel)
500 static void loads_init(Elf64_Phdr
*phdr
, u64 loads_offset
)
502 phys_addr_t start
, end
;
505 for_each_mem_range(idx
, &memblock
.physmem
, &oldmem_type
, NUMA_NO_NODE
,
506 MEMBLOCK_NONE
, &start
, &end
, NULL
) {
507 phdr
->p_filesz
= end
- start
;
508 phdr
->p_type
= PT_LOAD
;
509 phdr
->p_offset
= start
;
510 phdr
->p_vaddr
= start
;
511 phdr
->p_paddr
= start
;
512 phdr
->p_memsz
= end
- start
;
513 phdr
->p_flags
= PF_R
| PF_W
| PF_X
;
514 phdr
->p_align
= PAGE_SIZE
;
520 * Initialize notes (new kernel)
522 static void *notes_init(Elf64_Phdr
*phdr
, void *ptr
, u64 notes_offset
)
524 struct save_area_ext
*sa_ext
;
525 void *ptr_start
= ptr
;
528 ptr
= nt_prpsinfo(ptr
);
530 for (i
= 0; i
< dump_save_areas
.count
; i
++) {
531 sa_ext
= dump_save_areas
.areas
[i
];
532 if (sa_ext
->sa
.pref_reg
== 0)
534 ptr
= fill_cpu_elf_notes(ptr
, &sa_ext
->sa
, sa_ext
->vx_regs
);
536 ptr
= nt_vmcoreinfo(ptr
);
537 memset(phdr
, 0, sizeof(*phdr
));
538 phdr
->p_type
= PT_NOTE
;
539 phdr
->p_offset
= notes_offset
;
540 phdr
->p_filesz
= (unsigned long) PTR_SUB(ptr
, ptr_start
);
541 phdr
->p_memsz
= phdr
->p_filesz
;
546 * Create ELF core header (new kernel)
548 int elfcorehdr_alloc(unsigned long long *addr
, unsigned long long *size
)
550 Elf64_Phdr
*phdr_notes
, *phdr_loads
;
556 /* If we are not in kdump or zfcpdump mode return */
557 if (!OLDMEM_BASE
&& ipl_info
.type
!= IPL_TYPE_FCP_DUMP
)
559 /* If we cannot get HSA size for zfcpdump return error */
560 if (ipl_info
.type
== IPL_TYPE_FCP_DUMP
&& !sclp
.hsa_size
)
563 /* For kdump, exclude previous crashkernel memory */
565 oldmem_region
.base
= OLDMEM_BASE
;
566 oldmem_region
.size
= OLDMEM_SIZE
;
567 oldmem_type
.total_size
= OLDMEM_SIZE
;
570 mem_chunk_cnt
= get_mem_chunk_cnt();
572 alloc_size
= 0x1000 + get_cpu_cnt() * 0x4a0 +
573 mem_chunk_cnt
* sizeof(Elf64_Phdr
);
574 hdr
= kzalloc_panic(alloc_size
);
575 /* Init elf header */
576 ptr
= ehdr_init(hdr
, mem_chunk_cnt
);
577 /* Init program headers */
579 ptr
= PTR_ADD(ptr
, sizeof(Elf64_Phdr
));
581 ptr
= PTR_ADD(ptr
, sizeof(Elf64_Phdr
) * mem_chunk_cnt
);
583 hdr_off
= PTR_DIFF(ptr
, hdr
);
584 ptr
= notes_init(phdr_notes
, ptr
, ((unsigned long) hdr
) + hdr_off
);
586 hdr_off
= PTR_DIFF(ptr
, hdr
);
587 loads_init(phdr_loads
, hdr_off
);
588 *addr
= (unsigned long long) hdr
;
589 *size
= (unsigned long long) hdr_off
;
590 BUG_ON(elfcorehdr_size
> alloc_size
);
595 * Free ELF core header (new kernel)
597 void elfcorehdr_free(unsigned long long addr
)
599 kfree((void *)(unsigned long)addr
);
603 * Read from ELF header
605 ssize_t
elfcorehdr_read(char *buf
, size_t count
, u64
*ppos
)
607 void *src
= (void *)(unsigned long)*ppos
;
609 memcpy(buf
, src
, count
);
615 * Read from ELF notes data
617 ssize_t
elfcorehdr_read_notes(char *buf
, size_t count
, u64
*ppos
)
619 void *src
= (void *)(unsigned long)*ppos
;
621 memcpy(buf
, src
, count
);