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 #define for_each_dump_mem_range(i, nid, p_start, p_end, p_nid) \
36 for (i = 0, __next_mem_range(&i, nid, &memblock.physmem, \
37 &oldmem_type, p_start, \
39 i != (u64)ULLONG_MAX; \
40 __next_mem_range(&i, nid, &memblock.physmem, \
42 p_start, p_end, p_nid))
44 struct dump_save_areas dump_save_areas
;
47 * Allocate and add a save area for a CPU
49 struct save_area_ext
*dump_save_area_create(int cpu
)
51 struct save_area_ext
**save_areas
, *save_area
;
53 save_area
= kmalloc(sizeof(*save_area
), GFP_KERNEL
);
56 if (cpu
+ 1 > dump_save_areas
.count
) {
57 dump_save_areas
.count
= cpu
+ 1;
58 save_areas
= krealloc(dump_save_areas
.areas
,
59 dump_save_areas
.count
* sizeof(void *),
60 GFP_KERNEL
| __GFP_ZERO
);
65 dump_save_areas
.areas
= save_areas
;
67 dump_save_areas
.areas
[cpu
] = save_area
;
72 * Return physical address for virtual address
74 static inline void *load_real_addr(void *addr
)
76 unsigned long real_addr
;
83 : "=a" (real_addr
) : "a" (addr
) : "cc");
84 return (void *)real_addr
;
88 * Copy real to virtual or real memory
90 static int copy_from_realmem(void *dest
, void *src
, size_t count
)
96 if (!is_vmalloc_or_module_addr(dest
))
97 return memcpy_real(dest
, src
, count
);
99 size
= min(count
, PAGE_SIZE
- (__pa(dest
) & ~PAGE_MASK
));
100 if (memcpy_real(load_real_addr(dest
), src
, size
))
110 * Pointer to ELF header in new kernel
112 static void *elfcorehdr_newmem
;
115 * Copy one page from zfcpdump "oldmem"
117 * For pages below HSA size memory from the HSA is copied. Otherwise
118 * real memory copy is used.
120 static ssize_t
copy_oldmem_page_zfcpdump(char *buf
, size_t csize
,
121 unsigned long src
, int userbuf
)
125 if (src
< sclp_get_hsa_size()) {
126 rc
= memcpy_hsa(buf
, src
, csize
, userbuf
);
129 rc
= copy_to_user_real((void __force __user
*) buf
,
130 (void *) src
, csize
);
132 rc
= memcpy_real(buf
, (void *) src
, csize
);
134 return rc
? rc
: csize
;
138 * Copy one page from kdump "oldmem"
140 * For the kdump reserved memory this functions performs a swap operation:
141 * - [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] is mapped to [0 - OLDMEM_SIZE].
142 * - [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE]
144 static ssize_t
copy_oldmem_page_kdump(char *buf
, size_t csize
,
145 unsigned long src
, int userbuf
)
150 if (src
< OLDMEM_SIZE
)
152 else if (src
> OLDMEM_BASE
&&
153 src
< OLDMEM_BASE
+ OLDMEM_SIZE
)
156 rc
= copy_to_user_real((void __force __user
*) buf
,
157 (void *) src
, csize
);
159 rc
= copy_from_realmem(buf
, (void *) src
, csize
);
160 return (rc
== 0) ? rc
: csize
;
164 * Copy one page from "oldmem"
166 ssize_t
copy_oldmem_page(unsigned long pfn
, char *buf
, size_t csize
,
167 unsigned long offset
, int userbuf
)
173 src
= (pfn
<< PAGE_SHIFT
) + offset
;
175 return copy_oldmem_page_kdump(buf
, csize
, src
, userbuf
);
177 return copy_oldmem_page_zfcpdump(buf
, csize
, src
, userbuf
);
181 * Remap "oldmem" for kdump
183 * For the kdump reserved memory this functions performs a swap operation:
184 * [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE]
186 static int remap_oldmem_pfn_range_kdump(struct vm_area_struct
*vma
,
187 unsigned long from
, unsigned long pfn
,
188 unsigned long size
, pgprot_t prot
)
190 unsigned long size_old
;
193 if (pfn
< OLDMEM_SIZE
>> PAGE_SHIFT
) {
194 size_old
= min(size
, OLDMEM_SIZE
- (pfn
<< PAGE_SHIFT
));
195 rc
= remap_pfn_range(vma
, from
,
196 pfn
+ (OLDMEM_BASE
>> PAGE_SHIFT
),
198 if (rc
|| size
== size_old
)
202 pfn
+= size_old
>> PAGE_SHIFT
;
204 return remap_pfn_range(vma
, from
, pfn
, size
, prot
);
208 * Remap "oldmem" for zfcpdump
210 * We only map available memory above HSA size. Memory below HSA size
211 * is read on demand using the copy_oldmem_page() function.
213 static int remap_oldmem_pfn_range_zfcpdump(struct vm_area_struct
*vma
,
216 unsigned long size
, pgprot_t prot
)
218 unsigned long hsa_end
= sclp_get_hsa_size();
219 unsigned long size_hsa
;
221 if (pfn
< hsa_end
>> PAGE_SHIFT
) {
222 size_hsa
= min(size
, hsa_end
- (pfn
<< PAGE_SHIFT
));
223 if (size
== size_hsa
)
227 pfn
+= size_hsa
>> PAGE_SHIFT
;
229 return remap_pfn_range(vma
, from
, pfn
, size
, prot
);
233 * Remap "oldmem" for kdump or zfcpdump
235 int remap_oldmem_pfn_range(struct vm_area_struct
*vma
, unsigned long from
,
236 unsigned long pfn
, unsigned long size
, pgprot_t prot
)
239 return remap_oldmem_pfn_range_kdump(vma
, from
, pfn
, size
, prot
);
241 return remap_oldmem_pfn_range_zfcpdump(vma
, from
, pfn
, size
,
246 * Copy memory from old kernel
248 int copy_from_oldmem(void *dest
, void *src
, size_t count
)
250 unsigned long copied
= 0;
254 if ((unsigned long) src
< OLDMEM_SIZE
) {
255 copied
= min(count
, OLDMEM_SIZE
- (unsigned long) src
);
256 rc
= copy_from_realmem(dest
, src
+ OLDMEM_BASE
, copied
);
261 unsigned long hsa_end
= sclp_get_hsa_size();
262 if ((unsigned long) src
< hsa_end
) {
263 copied
= min(count
, hsa_end
- (unsigned long) src
);
264 rc
= memcpy_hsa(dest
, (unsigned long) src
, copied
, 0);
269 return copy_from_realmem(dest
+ copied
, src
+ copied
, count
- copied
);
273 * Alloc memory and panic in case of ENOMEM
275 static void *kzalloc_panic(int len
)
279 rc
= kzalloc(len
, GFP_KERNEL
);
281 panic("s390 kdump kzalloc (%d) failed", len
);
286 * Initialize ELF note
288 static void *nt_init(void *buf
, Elf64_Word type
, void *desc
, int d_len
,
294 note
= (Elf64_Nhdr
*)buf
;
295 note
->n_namesz
= strlen(name
) + 1;
296 note
->n_descsz
= d_len
;
298 len
= sizeof(Elf64_Nhdr
);
300 memcpy(buf
+ len
, name
, note
->n_namesz
);
301 len
= roundup(len
+ note
->n_namesz
, 4);
303 memcpy(buf
+ len
, desc
, note
->n_descsz
);
304 len
= roundup(len
+ note
->n_descsz
, 4);
306 return PTR_ADD(buf
, len
);
310 * Initialize prstatus note
312 static void *nt_prstatus(void *ptr
, struct save_area
*sa
)
314 struct elf_prstatus nt_prstatus
;
315 static int cpu_nr
= 1;
317 memset(&nt_prstatus
, 0, sizeof(nt_prstatus
));
318 memcpy(&nt_prstatus
.pr_reg
.gprs
, sa
->gp_regs
, sizeof(sa
->gp_regs
));
319 memcpy(&nt_prstatus
.pr_reg
.psw
, sa
->psw
, sizeof(sa
->psw
));
320 memcpy(&nt_prstatus
.pr_reg
.acrs
, sa
->acc_regs
, sizeof(sa
->acc_regs
));
321 nt_prstatus
.pr_pid
= cpu_nr
;
324 return nt_init(ptr
, NT_PRSTATUS
, &nt_prstatus
, sizeof(nt_prstatus
),
329 * Initialize fpregset (floating point) note
331 static void *nt_fpregset(void *ptr
, struct save_area
*sa
)
333 elf_fpregset_t nt_fpregset
;
335 memset(&nt_fpregset
, 0, sizeof(nt_fpregset
));
336 memcpy(&nt_fpregset
.fpc
, &sa
->fp_ctrl_reg
, sizeof(sa
->fp_ctrl_reg
));
337 memcpy(&nt_fpregset
.fprs
, &sa
->fp_regs
, sizeof(sa
->fp_regs
));
339 return nt_init(ptr
, NT_PRFPREG
, &nt_fpregset
, sizeof(nt_fpregset
),
344 * Initialize timer note
346 static void *nt_s390_timer(void *ptr
, struct save_area
*sa
)
348 return nt_init(ptr
, NT_S390_TIMER
, &sa
->timer
, sizeof(sa
->timer
),
349 KEXEC_CORE_NOTE_NAME
);
353 * Initialize TOD clock comparator note
355 static void *nt_s390_tod_cmp(void *ptr
, struct save_area
*sa
)
357 return nt_init(ptr
, NT_S390_TODCMP
, &sa
->clk_cmp
,
358 sizeof(sa
->clk_cmp
), KEXEC_CORE_NOTE_NAME
);
362 * Initialize TOD programmable register note
364 static void *nt_s390_tod_preg(void *ptr
, struct save_area
*sa
)
366 return nt_init(ptr
, NT_S390_TODPREG
, &sa
->tod_reg
,
367 sizeof(sa
->tod_reg
), KEXEC_CORE_NOTE_NAME
);
371 * Initialize control register note
373 static void *nt_s390_ctrs(void *ptr
, struct save_area
*sa
)
375 return nt_init(ptr
, NT_S390_CTRS
, &sa
->ctrl_regs
,
376 sizeof(sa
->ctrl_regs
), KEXEC_CORE_NOTE_NAME
);
380 * Initialize prefix register note
382 static void *nt_s390_prefix(void *ptr
, struct save_area
*sa
)
384 return nt_init(ptr
, NT_S390_PREFIX
, &sa
->pref_reg
,
385 sizeof(sa
->pref_reg
), KEXEC_CORE_NOTE_NAME
);
389 * Initialize vxrs high note (full 128 bit VX registers 16-31)
391 static void *nt_s390_vx_high(void *ptr
, __vector128
*vx_regs
)
393 return nt_init(ptr
, NT_S390_VXRS_HIGH
, &vx_regs
[16],
394 16 * sizeof(__vector128
), KEXEC_CORE_NOTE_NAME
);
398 * Initialize vxrs low note (lower halves of VX registers 0-15)
400 static void *nt_s390_vx_low(void *ptr
, __vector128
*vx_regs
)
406 note
= (Elf64_Nhdr
*)ptr
;
407 note
->n_namesz
= strlen(KEXEC_CORE_NOTE_NAME
) + 1;
408 note
->n_descsz
= 16 * 8;
409 note
->n_type
= NT_S390_VXRS_LOW
;
410 len
= sizeof(Elf64_Nhdr
);
412 memcpy(ptr
+ len
, KEXEC_CORE_NOTE_NAME
, note
->n_namesz
);
413 len
= roundup(len
+ note
->n_namesz
, 4);
416 /* Copy lower halves of SIMD registers 0-15 */
417 for (i
= 0; i
< 16; i
++) {
418 memcpy(ptr
, &vx_regs
[i
], 8);
425 * Fill ELF notes for one CPU with save area registers
427 void *fill_cpu_elf_notes(void *ptr
, struct save_area
*sa
, __vector128
*vx_regs
)
429 ptr
= nt_prstatus(ptr
, sa
);
430 ptr
= nt_fpregset(ptr
, sa
);
431 ptr
= nt_s390_timer(ptr
, sa
);
432 ptr
= nt_s390_tod_cmp(ptr
, sa
);
433 ptr
= nt_s390_tod_preg(ptr
, sa
);
434 ptr
= nt_s390_ctrs(ptr
, sa
);
435 ptr
= nt_s390_prefix(ptr
, sa
);
436 if (MACHINE_HAS_VX
&& vx_regs
) {
437 ptr
= nt_s390_vx_low(ptr
, vx_regs
);
438 ptr
= nt_s390_vx_high(ptr
, vx_regs
);
444 * Initialize prpsinfo note (new kernel)
446 static void *nt_prpsinfo(void *ptr
)
448 struct elf_prpsinfo prpsinfo
;
450 memset(&prpsinfo
, 0, sizeof(prpsinfo
));
451 prpsinfo
.pr_sname
= 'R';
452 strcpy(prpsinfo
.pr_fname
, "vmlinux");
453 return nt_init(ptr
, NT_PRPSINFO
, &prpsinfo
, sizeof(prpsinfo
),
454 KEXEC_CORE_NOTE_NAME
);
458 * Get vmcoreinfo using lowcore->vmcore_info (new kernel)
460 static void *get_vmcoreinfo_old(unsigned long *size
)
462 char nt_name
[11], *vmcoreinfo
;
466 if (copy_from_oldmem(&addr
, &S390_lowcore
.vmcore_info
, sizeof(addr
)))
468 memset(nt_name
, 0, sizeof(nt_name
));
469 if (copy_from_oldmem(¬e
, addr
, sizeof(note
)))
471 if (copy_from_oldmem(nt_name
, addr
+ sizeof(note
), sizeof(nt_name
) - 1))
473 if (strcmp(nt_name
, "VMCOREINFO") != 0)
475 vmcoreinfo
= kzalloc_panic(note
.n_descsz
);
476 if (copy_from_oldmem(vmcoreinfo
, addr
+ 24, note
.n_descsz
))
478 *size
= note
.n_descsz
;
483 * Initialize vmcoreinfo note (new kernel)
485 static void *nt_vmcoreinfo(void *ptr
)
490 vmcoreinfo
= os_info_old_entry(OS_INFO_VMCOREINFO
, &size
);
492 vmcoreinfo
= get_vmcoreinfo_old(&size
);
495 return nt_init(ptr
, 0, vmcoreinfo
, size
, "VMCOREINFO");
499 * Initialize ELF header (new kernel)
501 static void *ehdr_init(Elf64_Ehdr
*ehdr
, int mem_chunk_cnt
)
503 memset(ehdr
, 0, sizeof(*ehdr
));
504 memcpy(ehdr
->e_ident
, ELFMAG
, SELFMAG
);
505 ehdr
->e_ident
[EI_CLASS
] = ELFCLASS64
;
506 ehdr
->e_ident
[EI_DATA
] = ELFDATA2MSB
;
507 ehdr
->e_ident
[EI_VERSION
] = EV_CURRENT
;
508 memset(ehdr
->e_ident
+ EI_PAD
, 0, EI_NIDENT
- EI_PAD
);
509 ehdr
->e_type
= ET_CORE
;
510 ehdr
->e_machine
= EM_S390
;
511 ehdr
->e_version
= EV_CURRENT
;
512 ehdr
->e_phoff
= sizeof(Elf64_Ehdr
);
513 ehdr
->e_ehsize
= sizeof(Elf64_Ehdr
);
514 ehdr
->e_phentsize
= sizeof(Elf64_Phdr
);
515 ehdr
->e_phnum
= mem_chunk_cnt
+ 1;
520 * Return CPU count for ELF header (new kernel)
522 static int get_cpu_cnt(void)
526 for (i
= 0; i
< dump_save_areas
.count
; i
++) {
527 if (dump_save_areas
.areas
[i
]->sa
.pref_reg
== 0)
535 * Return memory chunk count for ELF header (new kernel)
537 static int get_mem_chunk_cnt(void)
542 for_each_dump_mem_range(idx
, NUMA_NO_NODE
, NULL
, NULL
, NULL
)
548 * Initialize ELF loads (new kernel)
550 static void loads_init(Elf64_Phdr
*phdr
, u64 loads_offset
)
552 phys_addr_t start
, end
;
555 for_each_dump_mem_range(idx
, NUMA_NO_NODE
, &start
, &end
, NULL
) {
556 phdr
->p_filesz
= end
- start
;
557 phdr
->p_type
= PT_LOAD
;
558 phdr
->p_offset
= start
;
559 phdr
->p_vaddr
= start
;
560 phdr
->p_paddr
= start
;
561 phdr
->p_memsz
= end
- start
;
562 phdr
->p_flags
= PF_R
| PF_W
| PF_X
;
563 phdr
->p_align
= PAGE_SIZE
;
569 * Initialize notes (new kernel)
571 static void *notes_init(Elf64_Phdr
*phdr
, void *ptr
, u64 notes_offset
)
573 struct save_area_ext
*sa_ext
;
574 void *ptr_start
= ptr
;
577 ptr
= nt_prpsinfo(ptr
);
579 for (i
= 0; i
< dump_save_areas
.count
; i
++) {
580 sa_ext
= dump_save_areas
.areas
[i
];
581 if (sa_ext
->sa
.pref_reg
== 0)
583 ptr
= fill_cpu_elf_notes(ptr
, &sa_ext
->sa
, sa_ext
->vx_regs
);
585 ptr
= nt_vmcoreinfo(ptr
);
586 memset(phdr
, 0, sizeof(*phdr
));
587 phdr
->p_type
= PT_NOTE
;
588 phdr
->p_offset
= notes_offset
;
589 phdr
->p_filesz
= (unsigned long) PTR_SUB(ptr
, ptr_start
);
590 phdr
->p_memsz
= phdr
->p_filesz
;
595 * Create ELF core header (new kernel)
597 int elfcorehdr_alloc(unsigned long long *addr
, unsigned long long *size
)
599 Elf64_Phdr
*phdr_notes
, *phdr_loads
;
605 /* If we are not in kdump or zfcpdump mode return */
606 if (!OLDMEM_BASE
&& ipl_info
.type
!= IPL_TYPE_FCP_DUMP
)
608 /* If elfcorehdr= has been passed via cmdline, we use that one */
609 if (elfcorehdr_addr
!= ELFCORE_ADDR_MAX
)
611 /* If we cannot get HSA size for zfcpdump return error */
612 if (ipl_info
.type
== IPL_TYPE_FCP_DUMP
&& !sclp_get_hsa_size())
615 /* For kdump, exclude previous crashkernel memory */
617 oldmem_region
.base
= OLDMEM_BASE
;
618 oldmem_region
.size
= OLDMEM_SIZE
;
619 oldmem_type
.total_size
= OLDMEM_SIZE
;
622 mem_chunk_cnt
= get_mem_chunk_cnt();
624 alloc_size
= 0x1000 + get_cpu_cnt() * 0x4a0 +
625 mem_chunk_cnt
* sizeof(Elf64_Phdr
);
626 hdr
= kzalloc_panic(alloc_size
);
627 /* Init elf header */
628 ptr
= ehdr_init(hdr
, mem_chunk_cnt
);
629 /* Init program headers */
631 ptr
= PTR_ADD(ptr
, sizeof(Elf64_Phdr
));
633 ptr
= PTR_ADD(ptr
, sizeof(Elf64_Phdr
) * mem_chunk_cnt
);
635 hdr_off
= PTR_DIFF(ptr
, hdr
);
636 ptr
= notes_init(phdr_notes
, ptr
, ((unsigned long) hdr
) + hdr_off
);
638 hdr_off
= PTR_DIFF(ptr
, hdr
);
639 loads_init(phdr_loads
, hdr_off
);
640 *addr
= (unsigned long long) hdr
;
641 elfcorehdr_newmem
= hdr
;
642 *size
= (unsigned long long) hdr_off
;
643 BUG_ON(elfcorehdr_size
> alloc_size
);
648 * Free ELF core header (new kernel)
650 void elfcorehdr_free(unsigned long long addr
)
652 if (!elfcorehdr_newmem
)
654 kfree((void *)(unsigned long)addr
);
658 * Read from ELF header
660 ssize_t
elfcorehdr_read(char *buf
, size_t count
, u64
*ppos
)
662 void *src
= (void *)(unsigned long)*ppos
;
664 src
= elfcorehdr_newmem
? src
: src
- OLDMEM_BASE
;
665 memcpy(buf
, src
, count
);
671 * Read from ELF notes data
673 ssize_t
elfcorehdr_read_notes(char *buf
, size_t count
, u64
*ppos
)
675 void *src
= (void *)(unsigned long)*ppos
;
678 if (elfcorehdr_newmem
) {
679 memcpy(buf
, src
, count
);
681 rc
= copy_from_oldmem(buf
, src
, count
);