|
@@ -86,6 +86,19 @@ static int __init parse_savemaxmem(char *p)
|
|
|
}
|
|
|
__setup("savemaxmem=", parse_savemaxmem);
|
|
|
|
|
|
+
|
|
|
+static size_t copy_oldmem_vaddr(void *vaddr, char *buf, size_t csize,
|
|
|
+ unsigned long offset, int userbuf)
|
|
|
+{
|
|
|
+ if (userbuf) {
|
|
|
+ if (copy_to_user((char __user *)buf, (vaddr + offset), csize))
|
|
|
+ return -EFAULT;
|
|
|
+ } else
|
|
|
+ memcpy(buf, (vaddr + offset), csize);
|
|
|
+
|
|
|
+ return csize;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* copy_oldmem_page - copy one page from "oldmem"
|
|
|
* @pfn: page frame number to be copied
|
|
@@ -107,16 +120,16 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
|
|
|
if (!csize)
|
|
|
return 0;
|
|
|
|
|
|
- vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0);
|
|
|
+ csize = min(csize, PAGE_SIZE);
|
|
|
|
|
|
- if (userbuf) {
|
|
|
- if (copy_to_user((char __user *)buf, (vaddr + offset), csize)) {
|
|
|
- iounmap(vaddr);
|
|
|
- return -EFAULT;
|
|
|
- }
|
|
|
- } else
|
|
|
- memcpy(buf, (vaddr + offset), csize);
|
|
|
+ if (pfn < max_pfn) {
|
|
|
+ vaddr = __va(pfn << PAGE_SHIFT);
|
|
|
+ csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
|
|
|
+ } else {
|
|
|
+ vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0);
|
|
|
+ csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
|
|
|
+ iounmap(vaddr);
|
|
|
+ }
|
|
|
|
|
|
- iounmap(vaddr);
|
|
|
return csize;
|
|
|
}
|