crash_dump.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. * Routines for doing kexec-based kdump
  3. *
  4. * Copyright (C) 2017 Linaro Limited
  5. * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/crash_dump.h>
  12. #include <linux/errno.h>
  13. #include <linux/io.h>
  14. #include <linux/memblock.h>
  15. #include <linux/uaccess.h>
  16. #include <asm/memory.h>
  17. /**
  18. * copy_oldmem_page() - copy one page from old kernel memory
  19. * @pfn: page frame number to be copied
  20. * @buf: buffer where the copied page is placed
  21. * @csize: number of bytes to copy
  22. * @offset: offset in bytes into the page
  23. * @userbuf: if set, @buf is in a user address space
  24. *
  25. * This function copies one page from old kernel memory into buffer pointed by
  26. * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes
  27. * copied or negative error in case of failure.
  28. */
  29. ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
  30. size_t csize, unsigned long offset,
  31. int userbuf)
  32. {
  33. void *vaddr;
  34. if (!csize)
  35. return 0;
  36. vaddr = memremap(__pfn_to_phys(pfn), PAGE_SIZE, MEMREMAP_WB);
  37. if (!vaddr)
  38. return -ENOMEM;
  39. if (userbuf) {
  40. if (copy_to_user((char __user *)buf, vaddr + offset, csize)) {
  41. memunmap(vaddr);
  42. return -EFAULT;
  43. }
  44. } else {
  45. memcpy(buf, vaddr + offset, csize);
  46. }
  47. memunmap(vaddr);
  48. return csize;
  49. }
  50. /**
  51. * elfcorehdr_read - read from ELF core header
  52. * @buf: buffer where the data is placed
  53. * @csize: number of bytes to read
  54. * @ppos: address in the memory
  55. *
  56. * This function reads @count bytes from elf core header which exists
  57. * on crash dump kernel's memory.
  58. */
  59. ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos)
  60. {
  61. memcpy(buf, phys_to_virt((phys_addr_t)*ppos), count);
  62. *ppos += count;
  63. return count;
  64. }