aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/crash_dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/crash_dump.c')
-rw-r--r--arch/s390/kernel/crash_dump.c58
1 files changed, 49 insertions, 9 deletions
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index a3b9150e6802..9f73c8059022 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -46,9 +46,9 @@ struct dump_save_areas dump_save_areas;
46/* 46/*
47 * Allocate and add a save area for a CPU 47 * Allocate and add a save area for a CPU
48 */ 48 */
49struct save_area *dump_save_area_create(int cpu) 49struct save_area_ext *dump_save_area_create(int cpu)
50{ 50{
51 struct save_area **save_areas, *save_area; 51 struct save_area_ext **save_areas, *save_area;
52 52
53 save_area = kmalloc(sizeof(*save_area), GFP_KERNEL); 53 save_area = kmalloc(sizeof(*save_area), GFP_KERNEL);
54 if (!save_area) 54 if (!save_area)
@@ -386,9 +386,45 @@ static void *nt_s390_prefix(void *ptr, struct save_area *sa)
386} 386}
387 387
388/* 388/*
389 * Initialize vxrs high note (full 128 bit VX registers 16-31)
390 */
391static void *nt_s390_vx_high(void *ptr, __vector128 *vx_regs)
392{
393 return nt_init(ptr, NT_S390_VXRS_HIGH, &vx_regs[16],
394 16 * sizeof(__vector128), KEXEC_CORE_NOTE_NAME);
395}
396
397/*
398 * Initialize vxrs low note (lower halves of VX registers 0-15)
399 */
400static void *nt_s390_vx_low(void *ptr, __vector128 *vx_regs)
401{
402 Elf64_Nhdr *note;
403 u64 len;
404 int i;
405
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);
411
412 memcpy(ptr + len, KEXEC_CORE_NOTE_NAME, note->n_namesz);
413 len = roundup(len + note->n_namesz, 4);
414
415 ptr += len;
416 /* Copy lower halves of SIMD registers 0-15 */
417 for (i = 0; i < 16; i++) {
418 memcpy(ptr, &vx_regs[i], 8);
419 ptr += 8;
420 }
421 return ptr;
422}
423
424/*
389 * Fill ELF notes for one CPU with save area registers 425 * Fill ELF notes for one CPU with save area registers
390 */ 426 */
391void *fill_cpu_elf_notes(void *ptr, struct save_area *sa) 427void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, __vector128 *vx_regs)
392{ 428{
393 ptr = nt_prstatus(ptr, sa); 429 ptr = nt_prstatus(ptr, sa);
394 ptr = nt_fpregset(ptr, sa); 430 ptr = nt_fpregset(ptr, sa);
@@ -397,6 +433,10 @@ void *fill_cpu_elf_notes(void *ptr, struct save_area *sa)
397 ptr = nt_s390_tod_preg(ptr, sa); 433 ptr = nt_s390_tod_preg(ptr, sa);
398 ptr = nt_s390_ctrs(ptr, sa); 434 ptr = nt_s390_ctrs(ptr, sa);
399 ptr = nt_s390_prefix(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);
439 }
400 return ptr; 440 return ptr;
401} 441}
402 442
@@ -484,7 +524,7 @@ static int get_cpu_cnt(void)
484 int i, cpus = 0; 524 int i, cpus = 0;
485 525
486 for (i = 0; i < dump_save_areas.count; i++) { 526 for (i = 0; i < dump_save_areas.count; i++) {
487 if (dump_save_areas.areas[i]->pref_reg == 0) 527 if (dump_save_areas.areas[i]->sa.pref_reg == 0)
488 continue; 528 continue;
489 cpus++; 529 cpus++;
490 } 530 }
@@ -530,17 +570,17 @@ static void loads_init(Elf64_Phdr *phdr, u64 loads_offset)
530 */ 570 */
531static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset) 571static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset)
532{ 572{
533 struct save_area *sa; 573 struct save_area_ext *sa_ext;
534 void *ptr_start = ptr; 574 void *ptr_start = ptr;
535 int i; 575 int i;
536 576
537 ptr = nt_prpsinfo(ptr); 577 ptr = nt_prpsinfo(ptr);
538 578
539 for (i = 0; i < dump_save_areas.count; i++) { 579 for (i = 0; i < dump_save_areas.count; i++) {
540 sa = dump_save_areas.areas[i]; 580 sa_ext = dump_save_areas.areas[i];
541 if (sa->pref_reg == 0) 581 if (sa_ext->sa.pref_reg == 0)
542 continue; 582 continue;
543 ptr = fill_cpu_elf_notes(ptr, sa); 583 ptr = fill_cpu_elf_notes(ptr, &sa_ext->sa, sa_ext->vx_regs);
544 } 584 }
545 ptr = nt_vmcoreinfo(ptr); 585 ptr = nt_vmcoreinfo(ptr);
546 memset(phdr, 0, sizeof(*phdr)); 586 memset(phdr, 0, sizeof(*phdr));
@@ -581,7 +621,7 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
581 621
582 mem_chunk_cnt = get_mem_chunk_cnt(); 622 mem_chunk_cnt = get_mem_chunk_cnt();
583 623
584 alloc_size = 0x1000 + get_cpu_cnt() * 0x300 + 624 alloc_size = 0x1000 + get_cpu_cnt() * 0x4a0 +
585 mem_chunk_cnt * sizeof(Elf64_Phdr); 625 mem_chunk_cnt * sizeof(Elf64_Phdr);
586 hdr = kzalloc_panic(alloc_size); 626 hdr = kzalloc_panic(alloc_size);
587 /* Init elf header */ 627 /* Init elf header */