Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  Memory preserving reboot related code.
0004  *
0005  *  Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
0006  *  Copyright (C) IBM Corporation, 2004. All rights reserved
0007  */
0008 
0009 #include <linux/slab.h>
0010 #include <linux/errno.h>
0011 #include <linux/highmem.h>
0012 #include <linux/crash_dump.h>
0013 #include <linux/uio.h>
0014 
0015 static inline bool is_crashed_pfn_valid(unsigned long pfn)
0016 {
0017 #ifndef CONFIG_X86_PAE
0018     /*
0019      * non-PAE kdump kernel executed from a PAE one will crop high pte
0020      * bits and poke unwanted space counting again from address 0, we
0021      * don't want that. pte must fit into unsigned long. In fact the
0022      * test checks high 12 bits for being zero (pfn will be shifted left
0023      * by PAGE_SHIFT).
0024      */
0025     return pte_pfn(pfn_pte(pfn, __pgprot(0))) == pfn;
0026 #else
0027     return true;
0028 #endif
0029 }
0030 
0031 ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize,
0032              unsigned long offset)
0033 {
0034     void  *vaddr;
0035 
0036     if (!csize)
0037         return 0;
0038 
0039     if (!is_crashed_pfn_valid(pfn))
0040         return -EFAULT;
0041 
0042     vaddr = kmap_local_pfn(pfn);
0043     csize = copy_to_iter(vaddr + offset, csize, iter);
0044     kunmap_local(vaddr);
0045 
0046     return csize;
0047 }