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 12 #include <linux/crash_dump.h> 13 #include <linux/errno.h> 14 #include <linux/io.h> 15 #include <linux/memblock.h> 16 #include <linux/uaccess.h> 17 #include <asm/memory.h> 18 19 /** 20 * copy_oldmem_page() - copy one page from old kernel memory 21 * @pfn: page frame number to be copied 22 * @buf: buffer where the copied page is placed 23 * @csize: number of bytes to copy 24 * @offset: offset in bytes into the page 25 * @userbuf: if set, @buf is in a user address space 26 * 27 * This function copies one page from old kernel memory into buffer pointed by 28 * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes 29 * copied or negative error in case of failure. 30 */ 31 ssize_t copy_oldmem_page(unsigned long pfn, char *buf, 32 size_t csize, unsigned long offset, 33 int userbuf) 34 { 35 void *vaddr; 36 37 if (!csize) 38 return 0; 39 40 vaddr = memremap(__pfn_to_phys(pfn), PAGE_SIZE, MEMREMAP_WB); 41 if (!vaddr) 42 return -ENOMEM; 43 44 if (userbuf) { 45 if (copy_to_user((char __user *)buf, vaddr + offset, csize)) { 46 memunmap(vaddr); 47 return -EFAULT; 48 } 49 } else { 50 memcpy(buf, vaddr + offset, csize); 51 } 52 53 memunmap(vaddr); 54 55 return csize; 56 } 57 58 /** 59 * elfcorehdr_read - read from ELF core header 60 * @buf: buffer where the data is placed 61 * @count: number of bytes to read 62 * @ppos: address in the memory 63 * 64 * This function reads @count bytes from elf core header which exists 65 * on crash dump kernel's memory. 66 */ 67 ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) 68 { 69 memcpy(buf, phys_to_virt((phys_addr_t)*ppos), count); 70 return count; 71 } 72