aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r--drivers/char/mem.c53
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 */
283static 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
276extern long vread(char *buf, char *addr, unsigned long count); 313extern long vread(char *buf, char *addr, unsigned long count);
277extern long vwrite(char *buf, char *addr, unsigned long count); 314extern 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
725static struct file_operations mem_fops = { 763static 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
812static struct file_operations oldmem_fops = {
813 .read = read_oldmem,
814 .open = open_oldmem,
815};
816#endif
817
773static ssize_t kmsg_write(struct file * file, const char __user * buf, 818static 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
859static struct class *mem_class; 912static struct class *mem_class;