diff options
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r-- | drivers/char/mem.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index e3085b22a365..42187381506b 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -23,7 +23,10 @@ | |||
23 | #include <linux/devfs_fs_kernel.h> | 23 | #include <linux/devfs_fs_kernel.h> |
24 | #include <linux/ptrace.h> | 24 | #include <linux/ptrace.h> |
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | #include <linux/highmem.h> | ||
27 | #include <linux/crash_dump.h> | ||
26 | #include <linux/backing-dev.h> | 28 | #include <linux/backing-dev.h> |
29 | #include <linux/bootmem.h> | ||
27 | 30 | ||
28 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
29 | #include <asm/io.h> | 32 | #include <asm/io.h> |
@@ -273,6 +276,40 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma) | |||
273 | return mmap_mem(file, vma); | 276 | return mmap_mem(file, vma); |
274 | } | 277 | } |
275 | 278 | ||
279 | #ifdef CONFIG_CRASH_DUMP | ||
280 | /* | ||
281 | * Read memory corresponding to the old kernel. | ||
282 | */ | ||
283 | static ssize_t read_oldmem(struct file *file, char __user *buf, | ||
284 | size_t count, loff_t *ppos) | ||
285 | { | ||
286 | unsigned long pfn, offset; | ||
287 | size_t read = 0, csize; | ||
288 | int rc = 0; | ||
289 | |||
290 | while (count) { | ||
291 | pfn = *ppos / PAGE_SIZE; | ||
292 | if (pfn > saved_max_pfn) | ||
293 | return read; | ||
294 | |||
295 | offset = (unsigned long)(*ppos % PAGE_SIZE); | ||
296 | if (count > PAGE_SIZE - offset) | ||
297 | csize = PAGE_SIZE - offset; | ||
298 | else | ||
299 | csize = count; | ||
300 | |||
301 | rc = copy_oldmem_page(pfn, buf, csize, offset, 1); | ||
302 | if (rc < 0) | ||
303 | return rc; | ||
304 | buf += csize; | ||
305 | *ppos += csize; | ||
306 | read += csize; | ||
307 | count -= csize; | ||
308 | } | ||
309 | return read; | ||
310 | } | ||
311 | #endif | ||
312 | |||
276 | extern long vread(char *buf, char *addr, unsigned long count); | 313 | extern long vread(char *buf, char *addr, unsigned long count); |
277 | extern long vwrite(char *buf, char *addr, unsigned long count); | 314 | extern long vwrite(char *buf, char *addr, unsigned long count); |
278 | 315 | ||
@@ -721,6 +758,7 @@ static int open_port(struct inode * inode, struct file * filp) | |||
721 | #define read_full read_zero | 758 | #define read_full read_zero |
722 | #define open_mem open_port | 759 | #define open_mem open_port |
723 | #define open_kmem open_mem | 760 | #define open_kmem open_mem |
761 | #define open_oldmem open_mem | ||
724 | 762 | ||
725 | static struct file_operations mem_fops = { | 763 | static struct file_operations mem_fops = { |
726 | .llseek = memory_lseek, | 764 | .llseek = memory_lseek, |
@@ -770,6 +808,13 @@ static struct file_operations full_fops = { | |||
770 | .write = write_full, | 808 | .write = write_full, |
771 | }; | 809 | }; |
772 | 810 | ||
811 | #ifdef CONFIG_CRASH_DUMP | ||
812 | static struct file_operations oldmem_fops = { | ||
813 | .read = read_oldmem, | ||
814 | .open = open_oldmem, | ||
815 | }; | ||
816 | #endif | ||
817 | |||
773 | static ssize_t kmsg_write(struct file * file, const char __user * buf, | 818 | static ssize_t kmsg_write(struct file * file, const char __user * buf, |
774 | size_t count, loff_t *ppos) | 819 | size_t count, loff_t *ppos) |
775 | { | 820 | { |
@@ -825,6 +870,11 @@ static int memory_open(struct inode * inode, struct file * filp) | |||
825 | case 11: | 870 | case 11: |
826 | filp->f_op = &kmsg_fops; | 871 | filp->f_op = &kmsg_fops; |
827 | break; | 872 | break; |
873 | #ifdef CONFIG_CRASH_DUMP | ||
874 | case 12: | ||
875 | filp->f_op = &oldmem_fops; | ||
876 | break; | ||
877 | #endif | ||
828 | default: | 878 | default: |
829 | return -ENXIO; | 879 | return -ENXIO; |
830 | } | 880 | } |
@@ -854,6 +904,9 @@ static const struct { | |||
854 | {8, "random", S_IRUGO | S_IWUSR, &random_fops}, | 904 | {8, "random", S_IRUGO | S_IWUSR, &random_fops}, |
855 | {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, | 905 | {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, |
856 | {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops}, | 906 | {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops}, |
907 | #ifdef CONFIG_CRASH_DUMP | ||
908 | {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops}, | ||
909 | #endif | ||
857 | }; | 910 | }; |
858 | 911 | ||
859 | static struct class *mem_class; | 912 | static struct class *mem_class; |