2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
7 #include "linux/init.h"
8 #include "linux/proc_fs.h"
9 #include "linux/proc_mm.h"
10 #include "linux/file.h"
11 #include "asm/uaccess.h"
12 #include "asm/mmu_context.h"
14 static struct file_operations proc_mm_fops;
16 struct mm_struct *proc_mm_get_mm(int fd)
18 struct mm_struct *ret = ERR_PTR(-EBADF);
25 ret = ERR_PTR(-EINVAL);
26 if(file->f_op != &proc_mm_fops)
29 ret = file->private_data;
36 extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
37 unsigned long len, unsigned long prot,
38 unsigned long flags, unsigned long fd,
41 static ssize_t write_proc_mm(struct file *file, const char *buffer,
42 size_t count, loff_t *ppos)
44 struct mm_struct *mm = file->private_data;
45 struct proc_mm_op req;
48 if(count > sizeof(req))
51 n = copy_from_user(&req, buffer, count);
58 struct mm_mmap *map = &req.u.mmap;
60 ret = do_mmap2(mm, map->addr, map->len, map->prot,
61 map->flags, map->fd, map->offset >> PAGE_SHIFT);
62 if((ret & ~PAGE_MASK) == 0)
68 struct mm_munmap *unmap = &req.u.munmap;
70 down_write(&mm->mmap_sem);
71 ret = do_munmap(mm, unmap->addr, unmap->len);
72 up_write(&mm->mmap_sem);
79 struct mm_mprotect *protect = &req.u.mprotect;
81 ret = do_mprotect(mm, protect->addr, protect->len,
88 case MM_COPY_SEGMENTS: {
89 struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
96 mm_copy_segments(from, mm);
107 static int open_proc_mm(struct inode *inode, struct file *file)
109 struct mm_struct *mm = mm_alloc();
116 ret = init_new_context(current, mm);
120 spin_lock(&mmlist_lock);
121 list_add(&mm->mmlist, ¤t->mm->mmlist);
123 spin_unlock(&mmlist_lock);
125 file->private_data = mm;
135 static int release_proc_mm(struct inode *inode, struct file *file)
137 struct mm_struct *mm = file->private_data;
143 static struct file_operations proc_mm_fops = {
144 .open = open_proc_mm,
145 .release = release_proc_mm,
146 .write = write_proc_mm,
149 static int make_proc_mm(void)
151 struct proc_dir_entry *ent;
153 ent = create_proc_entry("mm", 0222, &proc_root);
155 printk("make_proc_mm : Failed to register /proc/mm\n");
158 ent->proc_fops = &proc_mm_fops;
163 __initcall(make_proc_mm);
166 * Overrides for Emacs so that we follow Linus's tabbing style.
167 * Emacs will notice this stuff at the end of the file and automatically
168 * adjust the settings for this buffer only. This must remain at the end
170 * ---------------------------------------------------------------------------
172 * c-file-style: "linux"