kexec based hibernation -v5: kexec restore
Subsystems (4)
PATCH 2/2 kexec based hibernation -v5: kexec restore
This patch adds writing support for /dev/oldmem. This is used to restore the memory contents of hibernated system.
Signed-off-by Huang Ying <[email protected]>
---
arch/i386/kernel/crash_dump.c +27 -0
@@ -58,6 +58,33 @@return csize; } +ssize_t write_oldmem_page (unsigned long pfn,const char *buf, +size_t csize,unsigned long offset,int userbuf) +{ +void *vaddr; + +if (!csize) +return 0 ; + +if (!userbuf) { + vaddr =kmap_atomic_pfn (pfn,KM_PTE0 ); +memcpy (vaddr + offset, buf, csize); + }else { +if (!kdump_buf_page) { +printk (KERN_WARNING "Kdump: Kdump buffer page not" +" allocated\n" ); +return -EFAULT ; + } +if (copy_from_user (kdump_buf_page, buf, csize)) +return -EFAULT ; + vaddr =kmap_atomic_pfn (pfn,KM_PTE0 ); +memcpy (vaddr + offset, kdump_buf_page, csize); + } +kunmap_atomic (vaddr,KM_PTE0 ); + +return csize; +} +static int __init kdump_buf_page_init (void ) {int ret =0 ;
include/linux/crash_dump.h +2 -0
@@ -11,6 +11,8 @@extern unsigned long long elfcorehdr_addr;extern ssize_t copy_oldmem_page (unsigned long ,char *,size_t ,unsigned long ,int ); +extern ssize_t write_oldmem_page (unsigned long ,const char *,size_t , +unsigned long ,int );extern const struct file_operations proc_vmcore_operations;extern struct proc_dir_entry *proc_vmcore;
drivers/char/mem.c +32 -0
@@ -348,6 +348,37 @@ }return read; } + +/* +* Write memory corresponding to the old kernel. +*/ +static ssize_t write_oldmem (struct file *file,const char __user *buf, +size_t count,loff_t *ppos) +{ +unsigned long pfn, offset; +size_t write =0 , csize; +int rc =0 ; + +while (count) { + pfn = *ppos /PAGE_SIZE ; +if (pfn > saved_max_pfn) +return write; + + offset = (unsigned long )(*ppos %PAGE_SIZE ); +if (count >PAGE_SIZE - offset) + csize =PAGE_SIZE - offset; +else + csize = count; + rc =write_oldmem_page (pfn, buf, csize, offset,1 ); +if (rc <0 ) +return rc; + buf += csize; + *ppos += csize; + write += csize; + count -= csize; + } +return write; +}#endif extern long vread (char *buf,char *addr,unsigned long count);
@@ -783,6 +814,7 @@#ifdef CONFIG_CRASH_DUMP static const struct file_operations oldmem_fops = { .read = read_oldmem, + .write = write_oldmem, .open = open_oldmem, };#endif