1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * fs/proc/vmcore.c Interface for accessing the crash 4 * dump from the system's previous life. 5 * Heavily borrowed from fs/proc/kcore.c 6 * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) 7 * Copyright (C) IBM Corporation, 2004. All rights reserved 8 * 9 */ 10 11#include <linux/mm.h> 12#include <linux/kcore.h> 13#include <linux/user.h> 14#include <linux/elf.h> 15#include <linux/elfcore.h> 16#include <linux/export.h> 17#include <linux/slab.h> 18#include <linux/highmem.h> 19#include <linux/printk.h> 20#include <linux/memblock.h> 21#include <linux/init.h> 22#include <linux/crash_dump.h> 23#include <linux/list.h> 24#include <linux/moduleparam.h> 25#include <linux/mutex.h> 26#include <linux/vmalloc.h> 27#include <linux/pagemap.h> 28#include <linux/uaccess.h> 29#include <linux/mem_encrypt.h> 30#include <asm/io.h> 31#include "internal.h" 32 33/* List representing chunks of contiguous memory areas and their offsets in 34 * vmcore file. 35 */ 36static LIST_HEAD(vmcore_list); 37 38/* Stores the pointer to the buffer containing kernel elf core headers. */ 39static char *elfcorebuf; 40static size_t elfcorebuf_sz; 41static size_t elfcorebuf_sz_orig; 42 43static char *elfnotes_buf; 44static size_t elfnotes_sz; 45/* Size of all notes minus the device dump notes */ 46static size_t elfnotes_orig_sz; 47 48/* Total size of vmcore file. */ 49static u64 vmcore_size; 50 51static struct proc_dir_entry *proc_vmcore; 52 53#ifdef CONFIG_PROC_VMCORE_DEVICE_DUMP 54/* Device Dump list and mutex to synchronize access to list */ 55static LIST_HEAD(vmcoredd_list); 56static DEFINE_MUTEX(vmcoredd_mutex); 57 58static bool vmcoredd_disabled; 59core_param(novmcoredd, vmcoredd_disabled, bool, 0); 60#endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */ 61 62/* Device Dump Size */ 63static size_t vmcoredd_orig_sz; 64 65/* 66 * Returns > 0 for RAM pages, 0 for non-RAM pages, < 0 on error 67 * The called function has to take care of module refcounting. 68 */ 69static int (*oldmem_pfn_is_ram)(unsigned long pfn); 70 71int register_oldmem_pfn_is_ram(int (*fn)(unsigned long pfn)) 72{ 73 if (oldmem_pfn_is_ram) 74 return -EBUSY; 75 oldmem_pfn_is_ram = fn; 76 return 0; 77} 78EXPORT_SYMBOL_GPL(register_oldmem_pfn_is_ram); 79 80void unregister_oldmem_pfn_is_ram(void) 81{ 82 oldmem_pfn_is_ram = NULL; 83 wmb(); 84} 85EXPORT_SYMBOL_GPL(unregister_oldmem_pfn_is_ram); 86 87static int pfn_is_ram(unsigned long pfn) 88{ 89 int (*fn)(unsigned long pfn); 90 /* pfn is ram unless fn() checks pagetype */ 91 int ret = 1; 92 93 /* 94 * Ask hypervisor if the pfn is really ram. 95 * A ballooned page contains no data and reading from such a page 96 * will cause high load in the hypervisor. 97 */ 98 fn = oldmem_pfn_is_ram; 99 if (fn) 100 ret = fn(pfn); 101 102 return ret; 103} 104 105/* Reads a page from the oldmem device from given offset. */ 106ssize_t read_from_oldmem(char *buf, size_t count, 107 u64 *ppos, int userbuf, 108 bool encrypted) 109{ 110 unsigned long pfn, offset; 111 size_t nr_bytes; 112 ssize_t read = 0, tmp; 113 114 if (!count) 115 return 0; 116 117 offset = (unsigned long)(*ppos % PAGE_SIZE); 118 pfn = (unsigned long)(*ppos / PAGE_SIZE); 119 120 do { 121 if (count > (PAGE_SIZE - offset)) 122 nr_bytes = PAGE_SIZE - offset; 123 else 124 nr_bytes = count; 125 126 /* If pfn is not ram, return zeros for sparse dump files */ 127 if (pfn_is_ram(pfn) == 0) { 128 tmp = 0; 129 if (!userbuf) 130 memset(buf, 0, nr_bytes); 131 else if (clear_user(buf, nr_bytes)) 132 tmp = -EFAULT; 133 } else { 134 if (encrypted) 135 tmp = copy_oldmem_page_encrypted(pfn, buf, 136 nr_bytes, 137 offset, 138 userbuf); 139 else 140 tmp = copy_oldmem_page(pfn, buf, nr_bytes, 141 offset, userbuf); 142 } 143 if (tmp < 0) 144 return tmp; 145 146 *ppos += nr_bytes; 147 count -= nr_bytes; 148 buf += nr_bytes; 149 read += nr_bytes; 150 ++pfn; 151 offset = 0; 152 } while (count); 153 154 return read; 155} 156 157/* 158 * Architectures may override this function to allocate ELF header in 2nd kernel 159 */ 160int __weak elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) 161{ 162 return 0; 163} 164 165/* 166 * Architectures may override this function to free header 167 */ 168void __weak elfcorehdr_free(unsigned long long addr) 169{} 170 171/* 172 * Architectures may override this function to read from ELF header 173 */ 174ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos) 175{ 176 return read_from_oldmem(buf, count, ppos, 0, false); 177} 178 179/* 180 * Architectures may override this function to read from notes sections 181 */ 182ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos) 183{ 184 return read_from_oldmem(buf, count, ppos, 0, mem_encrypt_active()); 185} 186 187/* 188 * Architectures may override this function to map oldmem 189 */ 190int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma, 191 unsigned long from, unsigned long pfn, 192 unsigned long size, pgprot_t prot) 193{ 194 prot = pgprot_encrypted(prot); 195 return remap_pfn_range(vma, from, pfn, size, prot); 196} 197 198/* 199 * Architectures which support memory encryption override this. 200 */ 201ssize_t __weak 202copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize, 203 unsigned long offset, int userbuf) 204{ 205 return copy_oldmem_page(pfn, buf, csize, offset, userbuf); 206} 207 208/* 209 * Copy to either kernel or user space 210 */ 211static int copy_to(void *target, void *src, size_t size, int userbuf) 212{ 213 if (userbuf) { 214 if (copy_to_user((char __user *) target, src, size)) 215 return -EFAULT; 216 } else { 217 memcpy(target, src, size); 218 } 219 return 0; 220} 221 222#ifdef CONFIG_PROC_VMCORE_DEVICE_DUMP 223static int vmcoredd_copy_dumps(void *dst, u64 start, size_t size, int userbuf) 224{ 225 struct vmcoredd_node *dump; 226 u64 offset = 0; 227 int ret = 0; 228 size_t tsz; 229 char *buf; 230 231 mutex_lock(&vmcoredd_mutex); 232 list_for_each_entry(dump, &vmcoredd_list, list) { 233 if (start < offset + dump->size) { 234 tsz = min(offset + (u64)dump->size - start, (u64)size); 235 buf = dump->buf + start - offset; 236 if (copy_to(dst, buf, tsz, userbuf)) { 237 ret = -EFAULT; 238 goto out_unlock; 239 } 240 241 size -= tsz; 242 start += tsz; 243 dst += tsz; 244 245 /* Leave now if buffer filled already */ 246 if (!size) 247 goto out_unlock; 248 } 249 offset += dump->size; 250 } 251 252out_unlock: 253 mutex_unlock(&vmcoredd_mutex); 254 return ret; 255} 256 257#ifdef CONFIG_MMU 258static int vmcoredd_mmap_dumps(struct vm_area_struct *vma, unsigned long dst, 259 u64 start, size_t size) 260{ 261 struct vmcoredd_node *dump; 262 u64 offset = 0; 263 int ret = 0; 264 size_t tsz; 265 char *buf; 266 267 mutex_lock(&vmcoredd_mutex); 268 list_for_each_entry(dump, &vmcoredd_list, list) { 269 if (start < offset + dump->size) { 270 tsz = min(offset + (u64)dump->size - start, (u64)size); 271 buf = dump->buf + start - offset; 272 if (remap_vmalloc_range_partial(vma, dst, buf, 0, 273 tsz)) { 274 ret = -EFAULT; 275 goto out_unlock; 276 } 277 278 size -= tsz; 279 start += tsz; 280 dst += tsz; 281 282 /* Leave now if buffer filled already */ 283 if (!size) 284 goto out_unlock; 285 } 286 offset += dump->size; 287 } 288 289out_unlock: 290 mutex_unlock(&vmcoredd_mutex); 291 return ret; 292} 293#endif /* CONFIG_MMU */ 294#endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */ 295 296/* Read from the ELF header and then the crash dump. On error, negative value is 297 * returned otherwise number of bytes read are returned. 298 */ 299static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos, 300 int userbuf) 301{ 302 ssize_t acc = 0, tmp; 303 size_t tsz; 304 u64 start; 305 struct vmcore *m = NULL; 306 307 if (buflen == 0 || *fpos >= vmcore_size) 308 return 0; 309 310 /* trim buflen to not go beyond EOF */ 311 if (buflen > vmcore_size - *fpos) 312 buflen = vmcore_size - *fpos; 313 314 /* Read ELF core header */ 315 if (*fpos < elfcorebuf_sz) { 316 tsz = min(elfcorebuf_sz - (size_t)*fpos, buflen); 317 if (copy_to(buffer, elfcorebuf + *fpos, tsz, userbuf)) 318 return -EFAULT; 319 buflen -= tsz; 320 *fpos += tsz; 321 buffer += tsz; 322 acc += tsz; 323 324 /* leave now if filled buffer already */ 325 if (buflen == 0) 326 return acc; 327 } 328 329 /* Read Elf note segment */ 330 if (*fpos < elfcorebuf_sz + elfnotes_sz) { 331 void *kaddr; 332 333 /* We add device dumps before other elf notes because the 334 * other elf notes may not fill the elf notes buffer 335 * completely and we will end up with zero-filled data 336 * between the elf notes and the device dumps. Tools will 337 * then try to decode this zero-filled data as valid notes 338 * and we don't want that. Hence, adding device dumps before 339 * the other elf notes ensure that zero-filled data can be 340 * avoided. 341 */ 342#ifdef CONFIG_PROC_VMCORE_DEVICE_DUMP 343 /* Read device dumps */ 344 if (*fpos < elfcorebuf_sz + vmcoredd_orig_sz) { 345 tsz = min(elfcorebuf_sz + vmcoredd_orig_sz - 346 (size_t)*fpos, buflen); 347 start = *fpos - elfcorebuf_sz; 348 if (vmcoredd_copy_dumps(buffer, start, tsz, userbuf)) 349 return -EFAULT; 350 351 buflen -= tsz; 352 *fpos += tsz; 353 buffer += tsz; 354 acc += tsz; 355 356 /* leave now if filled buffer already */ 357 if (!buflen) 358 return acc; 359 } 360#endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */ 361 362 /* Read remaining elf notes */ 363 tsz = min(elfcorebuf_sz + elfnotes_sz - (size_t)*fpos, buflen); 364 kaddr = elfnotes_buf + *fpos - elfcorebuf_sz - vmcoredd_orig_sz; 365 if (copy_to(buffer, kaddr, tsz, userbuf)) 366 return -EFAULT; 367 368 buflen -= tsz; 369 *fpos += tsz; 370 buffer += tsz; 371 acc += tsz; 372 373 /* leave now if filled buffer already */ 374 if (buflen == 0) 375 return acc; 376 } 377 378 list_for_each_entry(m, &vmcore_list, list) { 379 if (*fpos < m->offset + m->size) { 380 tsz = (size_t)min_t(unsigned long long, 381 m->offset + m->size - *fpos, 382 buflen); 383 start = m->paddr + *fpos - m->offset; 384 tmp = read_from_oldmem(buffer, tsz, &start, 385 userbuf, mem_encrypt_active()); 386 if (tmp < 0) 387 return tmp; 388 buflen -= tsz; 389 *fpos += tsz; 390 buffer += tsz; 391 acc += tsz; 392 393 /* leave now if filled buffer already */ 394 if (buflen == 0) 395 return acc; 396 } 397 } 398 399 return acc; 400} 401 402static ssize_t read_vmcore(struct file *file, char __user *buffer, 403 size_t buflen, loff_t *fpos) 404{ 405 return __read_vmcore((__force char *) buffer, buflen, fpos, 1); 406} 407 408/* 409 * The vmcore fault handler uses the page cache and fills data using the 410 * standard __vmcore_read() function. 411 * 412 * On s390 the fault handler is used for memory regions that can't be mapped 413 * directly with remap_pfn_range(). 414 */ 415static vm_fault_t mmap_vmcore_fault(struct vm_fault *vmf) 416{ 417#ifdef CONFIG_S390 418 struct address_space *mapping = vmf->vma->vm_file->f_mapping; 419 pgoff_t index = vmf->pgoff; 420 struct page *page; 421 loff_t offset; 422 char *buf; 423 int rc; 424 425 page = find_or_create_page(mapping, index, GFP_KERNEL); 426 if (!page) 427 return VM_FAULT_OOM; 428 if (!PageUptodate(page)) { 429 offset = (loff_t) index << PAGE_SHIFT; 430 buf = __va((page_to_pfn(page) << PAGE_SHIFT)); 431 rc = __read_vmcore(buf, PAGE_SIZE, &offset, 0); 432 if (rc < 0) { 433 unlock_page(page); 434 put_page(page); 435 return vmf_error(rc); 436 } 437 SetPageUptodate(page); 438 } 439 unlock_page(page); 440 vmf->page = page; 441 return 0; 442#else 443 return VM_FAULT_SIGBUS; 444#endif 445} 446 447static const struct vm_operations_struct vmcore_mmap_ops = { 448 .fault = mmap_vmcore_fault, 449}; 450 451/** 452 * vmcore_alloc_buf - allocate buffer in vmalloc memory 453 * @sizez: size of buffer 454 * 455 * If CONFIG_MMU is defined, use vmalloc_user() to allow users to mmap 456 * the buffer to user-space by means of remap_vmalloc_range(). 457 * 458 * If CONFIG_MMU is not defined, use vzalloc() since mmap_vmcore() is 459 * disabled and there's no need to allow users to mmap the buffer. 460 */ 461static inline char *vmcore_alloc_buf(size_t size) 462{ 463#ifdef CONFIG_MMU 464 return vmalloc_user(size); 465#else 466 return vzalloc(size); 467#endif 468} 469 470/* 471 * Disable mmap_vmcore() if CONFIG_MMU is not defined. MMU is 472 * essential for mmap_vmcore() in order to map physically 473 * non-contiguous objects (ELF header, ELF note segment and memory 474 * regions in the 1st kernel pointed to by PT_LOAD entries) into 475 * virtually contiguous user-space in ELF layout. 476 */ 477#ifdef CONFIG_MMU 478/* 479 * remap_oldmem_pfn_checked - do remap_oldmem_pfn_range replacing all pages 480 * reported as not being ram with the zero page. 481 * 482 * @vma: vm_area_struct describing requested mapping 483 * @from: start remapping from 484 * @pfn: page frame number to start remapping to 485 * @size: remapping size 486 * @prot: protection bits 487 * 488 * Returns zero on success, -EAGAIN on failure. 489 */ 490static int remap_oldmem_pfn_checked(struct vm_area_struct *vma, 491 unsigned long from, unsigned long pfn, 492 unsigned long size, pgprot_t prot) 493{ 494 unsigned long map_size; 495 unsigned long pos_start, pos_end, pos; 496 unsigned long zeropage_pfn = my_zero_pfn(0); 497 size_t len = 0; 498 499 pos_start = pfn; 500 pos_end = pfn + (size >> PAGE_SHIFT); 501 502 for (pos = pos_start; pos < pos_end; ++pos) { 503 if (!pfn_is_ram(pos)) { 504 /* 505 * We hit a page which is not ram. Remap the continuous 506 * region between pos_start and pos-1 and replace 507 * the non-ram page at pos with the zero page. 508 */ 509 if (pos > pos_start) { 510 /* Remap continuous region */ 511 map_size = (pos - pos_start) << PAGE_SHIFT; 512 if (remap_oldmem_pfn_range(vma, from + len, 513 pos_start, map_size, 514 prot)) 515 goto fail; 516 len += map_size; 517 } 518 /* Remap the zero page */ 519 if (remap_oldmem_pfn_range(vma, from + len, 520 zeropage_pfn, 521 PAGE_SIZE, prot)) 522 goto fail; 523 len += PAGE_SIZE; 524 pos_start = pos + 1; 525 } 526 } 527 if (pos > pos_start) { 528 /* Remap the rest */ 529 map_size = (pos - pos_start) << PAGE_SHIFT; 530 if (remap_oldmem_pfn_range(vma, from + len, pos_start, 531 map_size, prot)) 532 goto fail; 533 } 534 return 0; 535fail: 536 do_munmap(vma->vm_mm, from, len, NULL); 537 return -EAGAIN; 538} 539 540static int vmcore_remap_oldmem_pfn(struct vm_area_struct *vma, 541 unsigned long from, unsigned long pfn, 542 unsigned long size, pgprot_t prot) 543{ 544 /* 545 * Check if oldmem_pfn_is_ram was registered to avoid 546 * looping over all pages without a reason. 547 */ 548 if (oldmem_pfn_is_ram) 549 return remap_oldmem_pfn_checked(vma, from, pfn, size, prot); 550 else 551 return remap_oldmem_pfn_range(vma, from, pfn, size, prot); 552} 553 554static int mmap_vmcore(struct file *file, struct vm_area_struct *vma) 555{ 556 size_t size = vma->vm_end - vma->vm_start; 557 u64 start, end, len, tsz; 558 struct vmcore *m; 559 560 start = (u64)vma->vm_pgoff << PAGE_SHIFT; 561 end = start + size; 562 563 if (size > vmcore_size || end > vmcore_size) 564 return -EINVAL; 565 566 if (vma->vm_flags & (VM_WRITE | VM_EXEC)) 567 return -EPERM; 568 569 vma->vm_flags &= ~(VM_MAYWRITE | VM_MAYEXEC); 570 vma->vm_flags |= VM_MIXEDMAP; 571 vma->vm_ops = &vmcore_mmap_ops; 572 573 len = 0; 574 575 if (start < elfcorebuf_sz) { 576 u64 pfn; 577 578 tsz = min(elfcorebuf_sz - (size_t)start, size); 579 pfn = __pa(elfcorebuf + start) >> PAGE_SHIFT; 580 if (remap_pfn_range(vma, vma->vm_start, pfn, tsz, 581 vma->vm_page_prot)) 582 return -EAGAIN; 583 size -= tsz; 584 start += tsz; 585 len += tsz; 586 587 if (size == 0) 588 return 0; 589 } 590 591 if (start < elfcorebuf_sz + elfnotes_sz) { 592 void *kaddr; 593 594 /* We add device dumps before other elf notes because the 595 * other elf notes may not fill the elf notes buffer 596 * completely and we will end up with zero-filled data 597 * between the elf notes and the device dumps. Tools will 598 * then try to decode this zero-filled data as valid notes 599 * and we don't want that. Hence, adding device dumps before 600 * the other elf notes ensure that zero-filled data can be 601 * avoided. This also ensures that the device dumps and 602 * other elf notes can be properly mmaped at page aligned 603 * address. 604 */ 605#ifdef CONFIG_PROC_VMCORE_DEVICE_DUMP 606 /* Read device dumps */ 607 if (start < elfcorebuf_sz + vmcoredd_orig_sz) { 608 u64 start_off; 609 610 tsz = min(elfcorebuf_sz + vmcoredd_orig_sz - 611 (size_t)start, size); 612 start_off = start - elfcorebuf_sz; 613 if (vmcoredd_mmap_dumps(vma, vma->vm_start + len, 614 start_off, tsz)) 615 goto fail; 616 617 size -= tsz; 618 start += tsz; 619 len += tsz; 620 621 /* leave now if filled buffer already */ 622 if (!size) 623 return 0; 624 } 625#endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */ 626 627 /* Read remaining elf notes */ 628 tsz = min(elfcorebuf_sz + elfnotes_sz - (size_t)start, size); 629 kaddr = elfnotes_buf + start - elfcorebuf_sz - vmcoredd_orig_sz; 630 if (remap_vmalloc_range_partial(vma, vma->vm_start + len, 631 kaddr, 0, tsz)) 632 goto fail; 633 634 size -= tsz; 635 start += tsz; 636 len += tsz; 637 638 if (size == 0) 639 return 0; 640 } 641 642 list_for_each_entry(m, &vmcore_list, list) { 643 if (start < m->offset + m->size) { 644 u64 paddr = 0; 645 646 tsz = (size_t)min_t(unsigned long long, 647 m->offset + m->size - start, size); 648 paddr = m->paddr + start - m->offset; 649 if (vmcore_remap_oldmem_pfn(vma, vma->vm_start + len, 650 paddr >> PAGE_SHIFT, tsz, 651 vma->vm_page_prot)) 652 goto fail; 653 size -= tsz; 654 start += tsz; 655 len += tsz; 656 657 if (size == 0) 658 return 0; 659 } 660 } 661 662 return 0; 663fail: 664 do_munmap(vma->vm_mm, vma->vm_start, len, NULL); 665 return -EAGAIN; 666} 667#else 668static int mmap_vmcore(struct file *file, struct vm_area_struct *vma) 669{ 670 return -ENOSYS; 671} 672#endif 673 674static const struct proc_ops vmcore_proc_ops = { 675 .proc_read = read_vmcore, 676 .proc_lseek = default_llseek, 677 .proc_mmap = mmap_vmcore, 678}; 679 680static struct vmcore* __init get_new_element(void) 681{ 682 return kzalloc(sizeof(struct vmcore), GFP_KERNEL); 683} 684 685static u64 get_vmcore_size(size_t elfsz, size_t elfnotesegsz, 686 struct list_head *vc_list) 687{ 688 u64 size; 689 struct vmcore *m; 690 691 size = elfsz + elfnotesegsz; 692 list_for_each_entry(m, vc_list, list) { 693 size += m->size; 694 } 695 return size; 696} 697 698/** 699 * update_note_header_size_elf64 - update p_memsz member of each PT_NOTE entry 700 * 701 * @ehdr_ptr: ELF header 702 * 703 * This function updates p_memsz member of each PT_NOTE entry in the 704 * program header table pointed to by @ehdr_ptr to real size of ELF 705 * note segment. 706 */ 707static int __init update_note_header_size_elf64(const Elf64_Ehdr *ehdr_ptr) 708{ 709 int i, rc=0; 710 Elf64_Phdr *phdr_ptr; 711 Elf64_Nhdr *nhdr_ptr; 712 713 phdr_ptr = (Elf64_Phdr *)(ehdr_ptr + 1); 714 for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { 715 void *notes_section; 716 u64 offset, max_sz, sz, real_sz = 0; 717 if (phdr_ptr->p_type != PT_NOTE) 718 continue; 719 max_sz = phdr_ptr->p_memsz; 720 offset = phdr_ptr->p_offset; 721 notes_section = kmalloc(max_sz, GFP_KERNEL); 722 if (!notes_section) 723 return -ENOMEM; 724 rc = elfcorehdr_read_notes(notes_section, max_sz, &offset); 725 if (rc < 0) { 726 kfree(notes_section); 727 return rc; 728 } 729 nhdr_ptr = notes_section; 730 while (nhdr_ptr->n_namesz != 0) { 731 sz = sizeof(Elf64_Nhdr) + 732 (((u64)nhdr_ptr->n_namesz + 3) & ~3) + 733 (((u64)nhdr_ptr->n_descsz + 3) & ~3); 734 if ((real_sz + sz) > max_sz) { 735 pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", 736 nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); 737 break; 738 } 739 real_sz += sz; 740 nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); 741 } 742 kfree(notes_section); 743 phdr_ptr->p_memsz = real_sz; 744 if (real_sz == 0) { 745 pr_warn("Warning: Zero PT_NOTE entries found\n"); 746 } 747 } 748 749 return 0; 750} 751 752/** 753 * get_note_number_and_size_elf64 - get the number of PT_NOTE program 754 * headers and sum of real size of their ELF note segment headers and 755 * data. 756 * 757 * @ehdr_ptr: ELF header 758 * @nr_ptnote: buffer for the number of PT_NOTE program headers 759 * @sz_ptnote: buffer for size of unique PT_NOTE program header 760 * 761 * This function is used to merge multiple PT_NOTE program headers 762 * into a unique single one. The resulting unique entry will have 763 * @sz_ptnote in its phdr->p_mem. 764 * 765 * It is assumed that program headers with PT_NOTE type pointed to by 766 * @ehdr_ptr has already been updated by update_note_header_size_elf64 767 * and each of PT_NOTE program headers has actual ELF note segment 768 * size in its p_memsz member. 769 */ 770static int __init get_note_number_and_size_elf64(const Elf64_Ehdr *ehdr_ptr, 771 int *nr_ptnote, u64 *sz_ptnote) 772{ 773 int i; 774 Elf64_Phdr *phdr_ptr; 775 776 *nr_ptnote = *sz_ptnote = 0; 777 778 phdr_ptr = (Elf64_Phdr *)(ehdr_ptr + 1); 779 for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { 780 if (phdr_ptr->p_type != PT_NOTE) 781 continue; 782 *nr_ptnote += 1; 783 *sz_ptnote += phdr_ptr->p_memsz; 784 } 785 786 return 0; 787} 788 789/** 790 * copy_notes_elf64 - copy ELF note segments in a given buffer 791 * 792 * @ehdr_ptr: ELF header 793 * @notes_buf: buffer into which ELF note segments are copied 794 * 795 * This function is used to copy ELF note segment in the 1st kernel 796 * into the buffer @notes_buf in the 2nd kernel. It is assumed that 797 * size of the buffer @notes_buf is equal to or larger than sum of the 798 * real ELF note segment headers and data. 799 * 800 * It is assumed that program headers with PT_NOTE type pointed to by 801 * @ehdr_ptr has already been updated by update_note_header_size_elf64 802 * and each of PT_NOTE program headers has actual ELF note segment 803 * size in its p_memsz member. 804 */ 805static int __init copy_notes_elf64(const Elf64_Ehdr *ehdr_ptr, char *notes_buf) 806{ 807 int i, rc=0; 808 Elf64_Phdr *phdr_ptr; 809 810 phdr_ptr = (Elf64_Phdr*)(ehdr_ptr + 1); 811 812 for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { 813 u64 offset; 814 if (phdr_ptr->p_type != PT_NOTE) 815 continue; 816 offset = phdr_ptr->p_offset; 817 rc = elfcorehdr_read_notes(notes_buf, phdr_ptr->p_memsz, 818 &offset); 819 if (rc < 0) 820 return rc; 821 notes_buf += phdr_ptr->p_memsz; 822 } 823 824 return 0; 825} 826 827/* Merges all the PT_NOTE headers into one. */ 828static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz, 829 char **notes_buf, size_t *notes_sz) 830{ 831 int i, nr_ptnote=0, rc=0; 832 char *tmp; 833 Elf64_Ehdr *ehdr_ptr; 834 Elf64_Phdr phdr; 835 u64 phdr_sz = 0, note_off; 836 837 ehdr_ptr = (Elf64_Ehdr *)elfptr; 838 839 rc = update_note_header_size_elf64(ehdr_ptr); 840 if (rc < 0) 841 return rc; 842 843 rc = get_note_number_and_size_elf64(ehdr_ptr, &nr_ptnote, &phdr_sz); 844 if (rc < 0) 845 return rc; 846 847 *notes_sz = roundup(phdr_sz, PAGE_SIZE); 848 *notes_buf = vmcore_alloc_buf(*notes_sz); 849 if (!*notes_buf) 850 return -ENOMEM; 851 852 rc = copy_notes_elf64(ehdr_ptr, *notes_buf); 853 if (rc < 0) 854 return rc; 855 856 /* Prepare merged PT_NOTE program header. */ 857 phdr.p_type = PT_NOTE; 858 phdr.p_flags = 0; 859 note_off = sizeof(Elf64_Ehdr) + 860 (ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf64_Phdr); 861 phdr.p_offset = roundup(note_off, PAGE_SIZE); 862 phdr.p_vaddr = phdr.p_paddr = 0; 863 phdr.p_filesz = phdr.p_memsz = phdr_sz; 864 phdr.p_align = 0; 865 866 /* Add merged PT_NOTE program header*/ 867 tmp = elfptr + sizeof(Elf64_Ehdr); 868 memcpy(tmp, &phdr, sizeof(phdr)); 869 tmp += sizeof(phdr); 870 871 /* Remove unwanted PT_NOTE program headers. */ 872 i = (nr_ptnote - 1) * sizeof(Elf64_Phdr); 873 *elfsz = *elfsz - i; 874 memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf64_Ehdr)-sizeof(Elf64_Phdr))); 875 memset(elfptr + *elfsz, 0, i); 876 *elfsz = roundup(*elfsz, PAGE_SIZE); 877 878 /* Modify e_phnum to reflect merged headers. */ 879 ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1; 880 881 /* Store the size of all notes. We need this to update the note 882 * header when the device dumps will be added. 883 */ 884 elfnotes_orig_sz = phdr.p_memsz; 885 886 return 0; 887} 888 889/** 890 * update_note_header_size_elf32 - update p_memsz member of each PT_NOTE entry 891 * 892 * @ehdr_ptr: ELF header 893 * 894 * This function updates p_memsz member of each PT_NOTE entry in the 895 * program header table pointed to by @ehdr_ptr to real size of ELF 896 * note segment. 897 */ 898static int __init update_note_header_size_elf32(const Elf32_Ehdr *ehdr_ptr) 899{ 900 int i, rc=0; 901 Elf32_Phdr *phdr_ptr; 902 Elf32_Nhdr *nhdr_ptr; 903 904 phdr_ptr = (Elf32_Phdr *)(ehdr_ptr + 1); 905 for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { 906 void *notes_section; 907 u64 offset, max_sz, sz, real_sz = 0; 908 if (phdr_ptr->p_type != PT_NOTE) 909 continue; 910 max_sz = phdr_ptr->p_memsz; 911 offset = phdr_ptr->p_offset; 912 notes_section = kmalloc(max_sz, GFP_KERNEL); 913 if (!notes_section) 914 return -ENOMEM; 915 rc = elfcorehdr_read_notes(notes_section, max_sz, &offset); 916 if (rc < 0) { 917 kfree(notes_section); 918 return rc; 919 } 920 nhdr_ptr = notes_section; 921 while (nhdr_ptr->n_namesz != 0) { 922 sz = sizeof(Elf32_Nhdr) + 923 (((u64)nhdr_ptr->n_namesz + 3) & ~3) + 924 (((u64)nhdr_ptr->n_descsz + 3) & ~3); 925 if ((real_sz + sz) > max_sz) { 926 pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", 927 nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); 928 break; 929 } 930 real_sz += sz; 931 nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); 932 } 933 kfree(notes_section); 934 phdr_ptr->p_memsz = real_sz; 935 if (real_sz == 0) { 936 pr_warn("Warning: Zero PT_NOTE entries found\n"); 937 } 938 } 939 940 return 0; 941} 942 943/** 944 * get_note_number_and_size_elf32 - get the number of PT_NOTE program 945 * headers and sum of real size of their ELF note segment headers and 946 * data. 947 * 948 * @ehdr_ptr: ELF header 949 * @nr_ptnote: buffer for the number of PT_NOTE program headers 950 * @sz_ptnote: buffer for size of unique PT_NOTE program header 951 * 952 * This function is used to merge multiple PT_NOTE program headers 953 * into a unique single one. The resulting unique entry will have 954 * @sz_ptnote in its phdr->p_mem. 955 * 956 * It is assumed that program headers with PT_NOTE type pointed to by 957 * @ehdr_ptr has already been updated by update_note_header_size_elf32 958 * and each of PT_NOTE program headers has actual ELF note segment 959 * size in its p_memsz member. 960 */ 961static int __init get_note_number_and_size_elf32(const Elf32_Ehdr *ehdr_ptr, 962 int *nr_ptnote, u64 *sz_ptnote) 963{ 964 int i; 965 Elf32_Phdr *phdr_ptr; 966 967 *nr_ptnote = *sz_ptnote = 0; 968 969 phdr_ptr = (Elf32_Phdr *)(ehdr_ptr + 1); 970 for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { 971 if (phdr_ptr->p_type != PT_NOTE) 972 continue; 973 *nr_ptnote += 1; 974 *sz_ptnote += phdr_ptr->p_memsz; 975 } 976 977 return 0; 978} 979 980/** 981 * copy_notes_elf32 - copy ELF note segments in a given buffer 982 * 983 * @ehdr_ptr: ELF header 984 * @notes_buf: buffer into which ELF note segments are copied 985 * 986 * This function is used to copy ELF note segment in the 1st kernel 987 * into the buffer @notes_buf in the 2nd kernel. It is assumed that 988 * size of the buffer @notes_buf is equal to or larger than sum of the 989 * real ELF note segment headers and data. 990 * 991 * It is assumed that program headers with PT_NOTE type pointed to by 992 * @ehdr_ptr has already been updated by update_note_header_size_elf32 993 * and each of PT_NOTE program headers has actual ELF note segment 994 * size in its p_memsz member. 995 */ 996static int __init copy_notes_elf32(const Elf32_Ehdr *ehdr_ptr, char *notes_buf) 997{ 998 int i, rc=0; 999 Elf32_Phdr *phdr_ptr; 1000 1001 phdr_ptr = (Elf32_Phdr*)(ehdr_ptr + 1); 1002 1003 for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { 1004 u64 offset; 1005 if (phdr_ptr->p_type != PT_NOTE) 1006 continue; 1007 offset = phdr_ptr->p_offset; 1008 rc = elfcorehdr_read_notes(notes_buf, phdr_ptr->p_memsz, 1009 &offset); 1010 if (rc < 0) 1011 return rc; 1012 notes_buf += phdr_ptr->p_memsz; 1013 } 1014 1015 return 0; 1016} 1017 1018/* Merges all the PT_NOTE headers into one. */ 1019static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz, 1020 char **notes_buf, size_t *notes_sz) 1021{ 1022 int i, nr_ptnote=0, rc=0; 1023 char *tmp; 1024 Elf32_Ehdr *ehdr_ptr; 1025 Elf32_Phdr phdr; 1026 u64 phdr_sz = 0, note_off; 1027 1028 ehdr_ptr = (Elf32_Ehdr *)elfptr; 1029 1030 rc = update_note_header_size_elf32(ehdr_ptr); 1031 if (rc < 0) 1032 return rc; 1033 1034 rc = get_note_number_and_size_elf32(ehdr_ptr, &nr_ptnote, &phdr_sz); 1035 if (rc < 0) 1036 return rc; 1037 1038 *notes_sz = roundup(phdr_sz, PAGE_SIZE); 1039 *notes_buf = vmcore_alloc_buf(*notes_sz); 1040 if (!*notes_buf) 1041 return -ENOMEM; 1042 1043 rc = copy_notes_elf32(ehdr_ptr, *notes_buf); 1044 if (rc < 0) 1045 return rc; 1046 1047 /* Prepare merged PT_NOTE program header. */ 1048 phdr.p_type = PT_NOTE; 1049 phdr.p_flags = 0; 1050 note_off = sizeof(Elf32_Ehdr) + 1051 (ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf32_Phdr); 1052 phdr.p_offset = roundup(note_off, PAGE_SIZE); 1053 phdr.p_vaddr = phdr.p_paddr = 0; 1054 phdr.p_filesz = phdr.p_memsz = phdr_sz; 1055 phdr.p_align = 0; 1056 1057 /* Add merged PT_NOTE program header*/ 1058 tmp = elfptr + sizeof(Elf32_Ehdr); 1059 memcpy(tmp, &phdr, sizeof(phdr)); 1060 tmp += sizeof(phdr); 1061 1062 /* Remove unwanted PT_NOTE program headers. */ 1063 i = (nr_ptnote - 1) * sizeof(Elf32_Phdr); 1064 *elfsz = *elfsz - i; 1065 memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf32_Ehdr)-sizeof(Elf32_Phdr))); 1066 memset(elfptr + *elfsz, 0, i); 1067 *elfsz = roundup(*elfsz, PAGE_SIZE); 1068 1069 /* Modify e_phnum to reflect merged headers. */ 1070 ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1; 1071 1072 /* Store the size of all notes. We need this to update the note 1073 * header when the device dumps will be added. 1074 */ 1075 elfnotes_orig_sz = phdr.p_memsz; 1076 1077 return 0; 1078} 1079 1080/* Add memory chunks represented by program headers to vmcore list. Also update 1081 * the new offset fields of exported program headers. */ 1082static int __init process_ptload_program_headers_elf64(char *elfptr, 1083 size_t elfsz, 1084 size_t elfnotes_sz, 1085 struct list_head *vc_list) 1086{ 1087 int i; 1088 Elf64_Ehdr *ehdr_ptr; 1089 Elf64_Phdr *phdr_ptr; 1090 loff_t vmcore_off; 1091 struct vmcore *new; 1092 1093 ehdr_ptr = (Elf64_Ehdr *)elfptr; 1094 phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr)); /* PT_NOTE hdr */ 1095 1096 /* Skip Elf header, program headers and Elf note segment. */ 1097 vmcore_off = elfsz + elfnotes_sz; 1098 1099 for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { 1100 u64 paddr, start, end, size; 1101 1102 if (phdr_ptr->p_type != PT_LOAD) 1103 continue; 1104 1105 paddr = phdr_ptr->p_offset; 1106 start = rounddown(paddr, PAGE_SIZE); 1107 end = roundup(paddr + phdr_ptr->p_memsz, PAGE_SIZE); 1108 size = end - start; 1109 1110 /* Add this contiguous chunk of memory to vmcore list.*/ 1111 new = get_new_element(); 1112 if (!new) 1113 return -ENOMEM; 1114 new->paddr = start; 1115 new->size = size; 1116 list_add_tail(&new->list, vc_list); 1117 1118 /* Update the program header offset. */ 1119 phdr_ptr->p_offset = vmcore_off + (paddr - start); 1120 vmcore_off = vmcore_off + size; 1121 } 1122 return 0; 1123} 1124 1125static int __init process_ptload_program_headers_elf32(char *elfptr, 1126 size_t elfsz, 1127 size_t elfnotes_sz, 1128 struct list_head *vc_list) 1129{ 1130 int i; 1131 Elf32_Ehdr *ehdr_ptr; 1132 Elf32_Phdr *phdr_ptr; 1133 loff_t vmcore_off; 1134 struct vmcore *new; 1135 1136 ehdr_ptr = (Elf32_Ehdr *)elfptr; 1137 phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr)); /* PT_NOTE hdr */ 1138 1139 /* Skip Elf header, program headers and Elf note segment. */ 1140 vmcore_off = elfsz + elfnotes_sz; 1141 1142 for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { 1143 u64 paddr, start, end, size; 1144 1145 if (phdr_ptr->p_type != PT_LOAD) 1146 continue; 1147 1148 paddr = phdr_ptr->p_offset; 1149 start = rounddown(paddr, PAGE_SIZE); 1150 end = roundup(paddr + phdr_ptr->p_memsz, PAGE_SIZE); 1151 size = end - start; 1152 1153 /* Add this contiguous chunk of memory to vmcore list.*/ 1154 new = get_new_element(); 1155 if (!new) 1156 return -ENOMEM; 1157 new->paddr = start; 1158 new->size = size; 1159 list_add_tail(&new->list, vc_list); 1160 1161 /* Update the program header offset */ 1162 phdr_ptr->p_offset = vmcore_off + (paddr - start); 1163 vmcore_off = vmcore_off + size; 1164 } 1165 return 0; 1166} 1167 1168/* Sets offset fields of vmcore elements. */ 1169static void set_vmcore_list_offsets(size_t elfsz, size_t elfnotes_sz, 1170 struct list_head *vc_list) 1171{ 1172 loff_t vmcore_off; 1173 struct vmcore *m; 1174 1175 /* Skip Elf header, program headers and Elf note segment. */ 1176 vmcore_off = elfsz + elfnotes_sz; 1177 1178 list_for_each_entry(m, vc_list, list) { 1179 m->offset = vmcore_off; 1180 vmcore_off += m->size; 1181 } 1182} 1183 1184static void free_elfcorebuf(void) 1185{ 1186 free_pages((unsigned long)elfcorebuf, get_order(elfcorebuf_sz_orig)); 1187 elfcorebuf = NULL; 1188 vfree(elfnotes_buf); 1189 elfnotes_buf = NULL; 1190} 1191 1192static int __init parse_crash_elf64_headers(void) 1193{ 1194 int rc=0; 1195 Elf64_Ehdr ehdr; 1196 u64 addr; 1197 1198 addr = elfcorehdr_addr; 1199 1200 /* Read Elf header */ 1201 rc = elfcorehdr_read((char *)&ehdr, sizeof(Elf64_Ehdr), &addr); 1202 if (rc < 0) 1203 return rc; 1204 1205 /* Do some basic Verification. */ 1206 if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || 1207 (ehdr.e_type != ET_CORE) || 1208 !vmcore_elf64_check_arch(&ehdr) || 1209 ehdr.e_ident[EI_CLASS] != ELFCLASS64 || 1210 ehdr.e_ident[EI_VERSION] != EV_CURRENT || 1211 ehdr.e_version != EV_CURRENT || 1212 ehdr.e_ehsize != sizeof(Elf64_Ehdr) || 1213 ehdr.e_phentsize != sizeof(Elf64_Phdr) || 1214 ehdr.e_phnum == 0) { 1215 pr_warn("Warning: Core image elf header is not sane\n"); 1216 return -EINVAL; 1217 } 1218 1219 /* Read in all elf headers. */ 1220 elfcorebuf_sz_orig = sizeof(Elf64_Ehdr) + 1221 ehdr.e_phnum * sizeof(Elf64_Phdr); 1222 elfcorebuf_sz = elfcorebuf_sz_orig; 1223 elfcorebuf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1224 get_order(elfcorebuf_sz_orig)); 1225 if (!elfcorebuf) 1226 return -ENOMEM; 1227 addr = elfcorehdr_addr; 1228 rc = elfcorehdr_read(elfcorebuf, elfcorebuf_sz_orig, &addr); 1229 if (rc < 0) 1230 goto fail; 1231 1232 /* Merge all PT_NOTE headers into one. */ 1233 rc = merge_note_headers_elf64(elfcorebuf, &elfcorebuf_sz, 1234 &elfnotes_buf, &elfnotes_sz); 1235 if (rc) 1236 goto fail; 1237 rc = process_ptload_program_headers_elf64(elfcorebuf, elfcorebuf_sz, 1238 elfnotes_sz, &vmcore_list); 1239 if (rc) 1240 goto fail; 1241 set_vmcore_list_offsets(elfcorebuf_sz, elfnotes_sz, &vmcore_list); 1242 return 0; 1243fail: 1244 free_elfcorebuf(); 1245 return rc; 1246} 1247 1248static int __init parse_crash_elf32_headers(void) 1249{ 1250 int rc=0; 1251 Elf32_Ehdr ehdr; 1252 u64 addr; 1253 1254 addr = elfcorehdr_addr; 1255 1256 /* Read Elf header */ 1257 rc = elfcorehdr_read((char *)&ehdr, sizeof(Elf32_Ehdr), &addr); 1258 if (rc < 0) 1259 return rc; 1260 1261 /* Do some basic Verification. */ 1262 if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || 1263 (ehdr.e_type != ET_CORE) || 1264 !vmcore_elf32_check_arch(&ehdr) || 1265 ehdr.e_ident[EI_CLASS] != ELFCLASS32|| 1266 ehdr.e_ident[EI_VERSION] != EV_CURRENT || 1267 ehdr.e_version != EV_CURRENT || 1268 ehdr.e_ehsize != sizeof(Elf32_Ehdr) || 1269 ehdr.e_phentsize != sizeof(Elf32_Phdr) || 1270 ehdr.e_phnum == 0) { 1271 pr_warn("Warning: Core image elf header is not sane\n"); 1272 return -EINVAL; 1273 } 1274 1275 /* Read in all elf headers. */ 1276 elfcorebuf_sz_orig = sizeof(Elf32_Ehdr) + ehdr.e_phnum * sizeof(Elf32_Phdr); 1277 elfcorebuf_sz = elfcorebuf_sz_orig; 1278 elfcorebuf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1279 get_order(elfcorebuf_sz_orig)); 1280 if (!elfcorebuf) 1281 return -ENOMEM; 1282 addr = elfcorehdr_addr; 1283 rc = elfcorehdr_read(elfcorebuf, elfcorebuf_sz_orig, &addr); 1284 if (rc < 0) 1285 goto fail; 1286 1287 /* Merge all PT_NOTE headers into one. */ 1288 rc = merge_note_headers_elf32(elfcorebuf, &elfcorebuf_sz, 1289 &elfnotes_buf, &elfnotes_sz); 1290 if (rc) 1291 goto fail; 1292 rc = process_ptload_program_headers_elf32(elfcorebuf, elfcorebuf_sz, 1293 elfnotes_sz, &vmcore_list); 1294 if (rc) 1295 goto fail; 1296 set_vmcore_list_offsets(elfcorebuf_sz, elfnotes_sz, &vmcore_list); 1297 return 0; 1298fail: 1299 free_elfcorebuf(); 1300 return rc; 1301} 1302 1303static int __init parse_crash_elf_headers(void) 1304{ 1305 unsigned char e_ident[EI_NIDENT]; 1306 u64 addr; 1307 int rc=0; 1308 1309 addr = elfcorehdr_addr; 1310 rc = elfcorehdr_read(e_ident, EI_NIDENT, &addr); 1311 if (rc < 0) 1312 return rc; 1313 if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) { 1314 pr_warn("Warning: Core image elf header not found\n"); 1315 return -EINVAL; 1316 } 1317 1318 if (e_ident[EI_CLASS] == ELFCLASS64) { 1319 rc = parse_crash_elf64_headers(); 1320 if (rc) 1321 return rc; 1322 } else if (e_ident[EI_CLASS] == ELFCLASS32) { 1323 rc = parse_crash_elf32_headers(); 1324 if (rc) 1325 return rc; 1326 } else { 1327 pr_warn("Warning: Core image elf header is not sane\n"); 1328 return -EINVAL; 1329 } 1330 1331 /* Determine vmcore size. */ 1332 vmcore_size = get_vmcore_size(elfcorebuf_sz, elfnotes_sz, 1333 &vmcore_list); 1334 1335 return 0; 1336} 1337 1338#ifdef CONFIG_PROC_VMCORE_DEVICE_DUMP 1339/** 1340 * vmcoredd_write_header - Write vmcore device dump header at the 1341 * beginning of the dump's buffer. 1342 * @buf: Output buffer where the note is written 1343 * @data: Dump info 1344 * @size: Size of the dump 1345 * 1346 * Fills beginning of the dump's buffer with vmcore device dump header. 1347 */ 1348static void vmcoredd_write_header(void *buf, struct vmcoredd_data *data, 1349 u32 size) 1350{ 1351 struct vmcoredd_header *vdd_hdr = (struct vmcoredd_header *)buf; 1352 1353 vdd_hdr->n_namesz = sizeof(vdd_hdr->name); 1354 vdd_hdr->n_descsz = size + sizeof(vdd_hdr->dump_name); 1355 vdd_hdr->n_type = NT_VMCOREDD; 1356 1357 strncpy((char *)vdd_hdr->name, VMCOREDD_NOTE_NAME, 1358 sizeof(vdd_hdr->name)); 1359 memcpy(vdd_hdr->dump_name, data->dump_name, sizeof(vdd_hdr->dump_name)); 1360} 1361 1362/** 1363 * vmcoredd_update_program_headers - Update all Elf program headers 1364 * @elfptr: Pointer to elf header 1365 * @elfnotesz: Size of elf notes aligned to page size 1366 * @vmcoreddsz: Size of device dumps to be added to elf note header 1367 * 1368 * Determine type of Elf header (Elf64 or Elf32) and update the elf note size. 1369 * Also update the offsets of all the program headers after the elf note header. 1370 */ 1371static void vmcoredd_update_program_headers(char *elfptr, size_t elfnotesz, 1372 size_t vmcoreddsz) 1373{ 1374 unsigned char *e_ident = (unsigned char *)elfptr; 1375 u64 start, end, size; 1376 loff_t vmcore_off; 1377 u32 i; 1378 1379 vmcore_off = elfcorebuf_sz + elfnotesz; 1380 1381 if (e_ident[EI_CLASS] == ELFCLASS64) { 1382 Elf64_Ehdr *ehdr = (Elf64_Ehdr *)elfptr; 1383 Elf64_Phdr *phdr = (Elf64_Phdr *)(elfptr + sizeof(Elf64_Ehdr)); 1384 1385 /* Update all program headers */ 1386 for (i = 0; i < ehdr->e_phnum; i++, phdr++) { 1387 if (phdr->p_type == PT_NOTE) { 1388 /* Update note size */ 1389 phdr->p_memsz = elfnotes_orig_sz + vmcoreddsz; 1390 phdr->p_filesz = phdr->p_memsz; 1391 continue; 1392 } 1393 1394 start = rounddown(phdr->p_offset, PAGE_SIZE); 1395 end = roundup(phdr->p_offset + phdr->p_memsz, 1396 PAGE_SIZE); 1397 size = end - start; 1398 phdr->p_offset = vmcore_off + (phdr->p_offset - start); 1399 vmcore_off += size; 1400 } 1401 } else { 1402 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfptr; 1403 Elf32_Phdr *phdr = (Elf32_Phdr *)(elfptr + sizeof(Elf32_Ehdr)); 1404 1405 /* Update all program headers */ 1406 for (i = 0; i < ehdr->e_phnum; i++, phdr++) { 1407 if (phdr->p_type == PT_NOTE) { 1408 /* Update note size */ 1409 phdr->p_memsz = elfnotes_orig_sz + vmcoreddsz; 1410 phdr->p_filesz = phdr->p_memsz; 1411 continue; 1412 } 1413 1414 start = rounddown(phdr->p_offset, PAGE_SIZE); 1415 end = roundup(phdr->p_offset + phdr->p_memsz, 1416 PAGE_SIZE); 1417 size = end - start; 1418 phdr->p_offset = vmcore_off + (phdr->p_offset - start); 1419 vmcore_off += size; 1420 } 1421 } 1422} 1423 1424/** 1425 * vmcoredd_update_size - Update the total size of the device dumps and update 1426 * Elf header 1427 * @dump_size: Size of the current device dump to be added to total size 1428 * 1429 * Update the total size of all the device dumps and update the Elf program 1430 * headers. Calculate the new offsets for the vmcore list and update the 1431 * total vmcore size. 1432 */ 1433static void vmcoredd_update_size(size_t dump_size) 1434{ 1435 vmcoredd_orig_sz += dump_size; 1436 elfnotes_sz = roundup(elfnotes_orig_sz, PAGE_SIZE) + vmcoredd_orig_sz; 1437 vmcoredd_update_program_headers(elfcorebuf, elfnotes_sz, 1438 vmcoredd_orig_sz); 1439 1440 /* Update vmcore list offsets */ 1441 set_vmcore_list_offsets(elfcorebuf_sz, elfnotes_sz, &vmcore_list); 1442 1443 vmcore_size = get_vmcore_size(elfcorebuf_sz, elfnotes_sz, 1444 &vmcore_list); 1445 proc_vmcore->size = vmcore_size; 1446} 1447 1448/** 1449 * vmcore_add_device_dump - Add a buffer containing device dump to vmcore 1450 * @data: dump info. 1451 * 1452 * Allocate a buffer and invoke the calling driver's dump collect routine. 1453 * Write Elf note at the beginning of the buffer to indicate vmcore device 1454 * dump and add the dump to global list. 1455 */ 1456int vmcore_add_device_dump(struct vmcoredd_data *data) 1457{ 1458 struct vmcoredd_node *dump; 1459 void *buf = NULL; 1460 size_t data_size; 1461 int ret; 1462 1463 if (vmcoredd_disabled) { 1464 pr_err_once("Device dump is disabled\n"); 1465 return -EINVAL; 1466 } 1467 1468 if (!data || !strlen(data->dump_name) || 1469 !data->vmcoredd_callback || !data->size) 1470 return -EINVAL; 1471 1472 dump = vzalloc(sizeof(*dump)); 1473 if (!dump) { 1474 ret = -ENOMEM; 1475 goto out_err; 1476 } 1477 1478 /* Keep size of the buffer page aligned so that it can be mmaped */ 1479 data_size = roundup(sizeof(struct vmcoredd_header) + data->size, 1480 PAGE_SIZE); 1481 1482 /* Allocate buffer for driver's to write their dumps */ 1483 buf = vmcore_alloc_buf(data_size); 1484 if (!buf) { 1485 ret = -ENOMEM; 1486 goto out_err; 1487 } 1488 1489 vmcoredd_write_header(buf, data, data_size - 1490 sizeof(struct vmcoredd_header)); 1491 1492 /* Invoke the driver's dump collection routing */ 1493 ret = data->vmcoredd_callback(data, buf + 1494 sizeof(struct vmcoredd_header)); 1495 if (ret) 1496 goto out_err; 1497 1498 dump->buf = buf; 1499 dump->size = data_size; 1500 1501 /* Add the dump to driver sysfs list */ 1502 mutex_lock(&vmcoredd_mutex); 1503 list_add_tail(&dump->list, &vmcoredd_list); 1504 mutex_unlock(&vmcoredd_mutex); 1505 1506 vmcoredd_update_size(data_size); 1507 return 0; 1508 1509out_err: 1510 if (buf) 1511 vfree(buf); 1512 1513 if (dump) 1514 vfree(dump); 1515 1516 return ret; 1517} 1518EXPORT_SYMBOL(vmcore_add_device_dump); 1519#endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */ 1520 1521/* Free all dumps in vmcore device dump list */ 1522static void vmcore_free_device_dumps(void) 1523{ 1524#ifdef CONFIG_PROC_VMCORE_DEVICE_DUMP 1525 mutex_lock(&vmcoredd_mutex); 1526 while (!list_empty(&vmcoredd_list)) { 1527 struct vmcoredd_node *dump; 1528 1529 dump = list_first_entry(&vmcoredd_list, struct vmcoredd_node, 1530 list); 1531 list_del(&dump->list); 1532 vfree(dump->buf); 1533 vfree(dump); 1534 } 1535 mutex_unlock(&vmcoredd_mutex); 1536#endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */ 1537} 1538 1539/* Init function for vmcore module. */ 1540static int __init vmcore_init(void) 1541{ 1542 int rc = 0; 1543 1544 /* Allow architectures to allocate ELF header in 2nd kernel */ 1545 rc = elfcorehdr_alloc(&elfcorehdr_addr, &elfcorehdr_size); 1546 if (rc) 1547 return rc; 1548 /* 1549 * If elfcorehdr= has been passed in cmdline or created in 2nd kernel, 1550 * then capture the dump. 1551 */ 1552 if (!(is_vmcore_usable())) 1553 return rc; 1554 rc = parse_crash_elf_headers(); 1555 if (rc) { 1556 pr_warn("Kdump: vmcore not initialized\n"); 1557 return rc; 1558 } 1559 elfcorehdr_free(elfcorehdr_addr); 1560 elfcorehdr_addr = ELFCORE_ADDR_ERR; 1561 1562 proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &vmcore_proc_ops); 1563 if (proc_vmcore) 1564 proc_vmcore->size = vmcore_size; 1565 return 0; 1566} 1567fs_initcall(vmcore_init); 1568 1569/* Cleanup function for vmcore module. */ 1570void vmcore_cleanup(void) 1571{ 1572 if (proc_vmcore) { 1573 proc_remove(proc_vmcore); 1574 proc_vmcore = NULL; 1575 } 1576 1577 /* clear the vmcore list. */ 1578 while (!list_empty(&vmcore_list)) { 1579 struct vmcore *m; 1580 1581 m = list_first_entry(&vmcore_list, struct vmcore, list); 1582 list_del(&m->list); 1583 kfree(m); 1584 } 1585 free_elfcorebuf(); 1586 1587 /* clear vmcore device dump list */ 1588 vmcore_free_device_dumps(); 1589} 1590