@@ -451,7 +451,7 @@ static void *nt_final(void *ptr)
451
451
/*
452
452
* Initialize ELF header (new kernel)
453
453
*/
454
- static void * ehdr_init (Elf64_Ehdr * ehdr , int mem_chunk_cnt )
454
+ static void * ehdr_init (Elf64_Ehdr * ehdr , int phdr_count )
455
455
{
456
456
memset (ehdr , 0 , sizeof (* ehdr ));
457
457
memcpy (ehdr -> e_ident , ELFMAG , SELFMAG );
@@ -465,11 +465,8 @@ static void *ehdr_init(Elf64_Ehdr *ehdr, int mem_chunk_cnt)
465
465
ehdr -> e_phoff = sizeof (Elf64_Ehdr );
466
466
ehdr -> e_ehsize = sizeof (Elf64_Ehdr );
467
467
ehdr -> e_phentsize = sizeof (Elf64_Phdr );
468
- /*
469
- * Number of memory chunk PT_LOAD program headers plus one kernel
470
- * image PT_LOAD program header plus one PT_NOTE program header.
471
- */
472
- ehdr -> e_phnum = mem_chunk_cnt + 1 + 1 ;
468
+ /* Number of PT_LOAD program headers plus PT_NOTE program header */
469
+ ehdr -> e_phnum = phdr_count + 1 ;
473
470
return ehdr + 1 ;
474
471
}
475
472
@@ -503,12 +500,14 @@ static int get_mem_chunk_cnt(void)
503
500
/*
504
501
* Initialize ELF loads (new kernel)
505
502
*/
506
- static void loads_init (Elf64_Phdr * phdr )
503
+ static void loads_init (Elf64_Phdr * phdr , bool os_info_has_vm )
507
504
{
508
- unsigned long old_identity_base = os_info_old_value ( OS_INFO_IDENTITY_BASE ) ;
505
+ unsigned long old_identity_base = 0 ;
509
506
phys_addr_t start , end ;
510
507
u64 idx ;
511
508
509
+ if (os_info_has_vm )
510
+ old_identity_base = os_info_old_value (OS_INFO_IDENTITY_BASE );
512
511
for_each_physmem_range (idx , & oldmem_type , & start , & end ) {
513
512
phdr -> p_type = PT_LOAD ;
514
513
phdr -> p_vaddr = old_identity_base + start ;
@@ -522,6 +521,11 @@ static void loads_init(Elf64_Phdr *phdr)
522
521
}
523
522
}
524
523
524
+ static bool os_info_has_vm (void )
525
+ {
526
+ return os_info_old_value (OS_INFO_KASLR_OFFSET );
527
+ }
528
+
525
529
/*
526
530
* Prepare PT_LOAD type program header for kernel image region
527
531
*/
@@ -566,7 +570,7 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset)
566
570
return ptr ;
567
571
}
568
572
569
- static size_t get_elfcorehdr_size (int mem_chunk_cnt )
573
+ static size_t get_elfcorehdr_size (int phdr_count )
570
574
{
571
575
size_t size ;
572
576
@@ -581,10 +585,8 @@ static size_t get_elfcorehdr_size(int mem_chunk_cnt)
581
585
size += nt_vmcoreinfo_size ();
582
586
/* nt_final */
583
587
size += sizeof (Elf64_Nhdr );
584
- /* PT_LOAD type program header for kernel text region */
585
- size += sizeof (Elf64_Phdr );
586
588
/* PT_LOADS */
587
- size += mem_chunk_cnt * sizeof (Elf64_Phdr );
589
+ size += phdr_count * sizeof (Elf64_Phdr );
588
590
589
591
return size ;
590
592
}
@@ -595,8 +597,8 @@ static size_t get_elfcorehdr_size(int mem_chunk_cnt)
595
597
int elfcorehdr_alloc (unsigned long long * addr , unsigned long long * size )
596
598
{
597
599
Elf64_Phdr * phdr_notes , * phdr_loads , * phdr_text ;
600
+ int mem_chunk_cnt , phdr_text_cnt ;
598
601
size_t alloc_size ;
599
- int mem_chunk_cnt ;
600
602
void * ptr , * hdr ;
601
603
u64 hdr_off ;
602
604
@@ -615,34 +617,38 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
615
617
}
616
618
617
619
mem_chunk_cnt = get_mem_chunk_cnt ();
620
+ phdr_text_cnt = os_info_has_vm () ? 1 : 0 ;
618
621
619
- alloc_size = get_elfcorehdr_size (mem_chunk_cnt );
622
+ alloc_size = get_elfcorehdr_size (mem_chunk_cnt + phdr_text_cnt );
620
623
621
624
hdr = kzalloc (alloc_size , GFP_KERNEL );
622
625
623
- /* Without elfcorehdr /proc/vmcore cannot be created. Thus creating
626
+ /*
627
+ * Without elfcorehdr /proc/vmcore cannot be created. Thus creating
624
628
* a dump with this crash kernel will fail. Panic now to allow other
625
629
* dump mechanisms to take over.
626
630
*/
627
631
if (!hdr )
628
632
panic ("s390 kdump allocating elfcorehdr failed" );
629
633
630
634
/* Init elf header */
631
- ptr = ehdr_init (hdr , mem_chunk_cnt );
635
+ phdr_notes = ehdr_init (hdr , mem_chunk_cnt + phdr_text_cnt );
632
636
/* Init program headers */
633
- phdr_notes = ptr ;
634
- ptr = PTR_ADD (ptr , sizeof (Elf64_Phdr ));
635
- phdr_text = ptr ;
636
- ptr = PTR_ADD (ptr , sizeof (Elf64_Phdr ));
637
- phdr_loads = ptr ;
638
- ptr = PTR_ADD (ptr , sizeof (Elf64_Phdr ) * mem_chunk_cnt );
637
+ if (phdr_text_cnt ) {
638
+ phdr_text = phdr_notes + 1 ;
639
+ phdr_loads = phdr_text + 1 ;
640
+ } else {
641
+ phdr_loads = phdr_notes + 1 ;
642
+ }
643
+ ptr = PTR_ADD (phdr_loads , sizeof (Elf64_Phdr ) * mem_chunk_cnt );
639
644
/* Init notes */
640
645
hdr_off = PTR_DIFF (ptr , hdr );
641
646
ptr = notes_init (phdr_notes , ptr , ((unsigned long ) hdr ) + hdr_off );
642
647
/* Init kernel text program header */
643
- text_init (phdr_text );
648
+ if (phdr_text_cnt )
649
+ text_init (phdr_text );
644
650
/* Init loads */
645
- loads_init (phdr_loads );
651
+ loads_init (phdr_loads , phdr_text_cnt );
646
652
/* Finalize program headers */
647
653
hdr_off = PTR_DIFF (ptr , hdr );
648
654
* addr = (unsigned long long ) hdr ;
0 commit comments