4 * Copyright (C) 1991, 1992 Linus Torvalds
7 #include <linux/types.h>
8 #include <linux/errno.h>
9 #include <linux/sched.h>
10 #include <linux/kernel.h>
12 #include <linux/proc_fs.h>
13 #include <linux/highmem.h>
16 #include <asm/uaccess.h>
18 #include <asm/pgtable.h>
21 * mem_write isn't really a good idea right now. It needs
22 * to check a lot more: if the process we try to write to
23 * dies in the middle right now, mem_write will overwrite
24 * kernel memory.. This disables it altogether.
26 #define mem_write NULL
28 static int check_range(struct mm_struct
* mm
, unsigned long addr
, int count
)
30 struct vm_area_struct
*vma
;
33 vma
= find_vma(mm
, addr
);
36 if (vma
->vm_start
> addr
)
38 if (!(vma
->vm_flags
& VM_READ
))
40 while ((retval
= vma
->vm_end
- addr
) < count
) {
41 struct vm_area_struct
*next
= vma
->vm_next
;
44 if (vma
->vm_end
!= next
->vm_start
)
46 if (!(next
->vm_flags
& VM_READ
))
55 static struct task_struct
* get_task(int pid
)
57 struct task_struct
* tsk
= current
;
59 if (pid
!= tsk
->pid
) {
60 tsk
= find_task_by_pid(pid
);
62 /* Allow accesses only under the same circumstances
63 * that we would allow ptrace to work.
66 if (!(tsk
->flags
& PF_PTRACED
)
67 || tsk
->state
!= TASK_STOPPED
68 || tsk
->p_pptr
!= current
)
75 static ssize_t
mem_read(struct file
* file
, char * buf
,
76 size_t count
, loff_t
*ppos
)
78 struct inode
* inode
= file
->f_dentry
->d_inode
;
83 struct task_struct
* tsk
;
85 unsigned long maddr
; /* temporary mapped address */
89 read_lock(&tasklist_lock
);
90 tsk
= get_task(inode
->i_ino
>> 16);
91 read_unlock(&tasklist_lock
); /* FIXME: This should really be done only afetr not using tsk any more!!! */
95 scount
= check_range(tsk
->mm
, addr
, count
);
100 if (signal_pending(current
))
102 page_dir
= pgd_offset(tsk
->mm
,addr
);
103 if (pgd_none(*page_dir
))
105 if (pgd_bad(*page_dir
)) {
106 pgd_ERROR(*page_dir
);
110 page_middle
= pmd_offset(page_dir
,addr
);
111 if (pmd_none(*page_middle
))
113 if (pmd_bad(*page_middle
)) {
114 pmd_ERROR(*page_middle
);
115 pmd_clear(page_middle
);
118 pte
= *pte_offset(page_middle
,addr
);
119 if (!pte_present(pte
))
121 page
= pte_page(pte
);
122 i
= PAGE_SIZE
-(addr
& ~PAGE_MASK
);
125 maddr
= kmap(page
, KM_READ
);
126 copy_to_user(tmp
, (char *)maddr
+ (addr
& ~PAGE_MASK
), i
);
127 kunmap(maddr
, KM_READ
);
138 static ssize_t
mem_write(struct file
* file
, char * buf
,
139 size_t count
, loff_t
*ppos
)
141 struct inode
* inode
= file
->f_dentry
->d_inode
;
146 struct task_struct
* tsk
;
148 unsigned long maddr
; /* temporary mapped address */
153 tsk
= get_task(inode
->i_ino
>> 16);
158 if (signal_pending(current
))
160 page_dir
= pgd_offset(tsk
,addr
);
161 if (pgd_none(*page_dir
))
163 if (pgd_bad(*page_dir
)) {
164 pgd_ERROR(*page_dir
);
168 page_middle
= pmd_offset(page_dir
,addr
);
169 if (pmd_none(*page_middle
))
171 if (pmd_bad(*page_middle
)) {
172 pmd_ERROR(*page_middle
);
173 pmd_clear(page_middle
);
176 pte
= *pte_offset(page_middle
,addr
);
177 if (!pte_present(pte
))
181 page
= pte_page(pte
);
182 i
= PAGE_SIZE
-(addr
& ~PAGE_MASK
);
185 maddr
= kmap(page
, KM_WRITE
);
186 copy_from_user((char *)maddr
+ (addr
& ~PAGE_MASK
), tmp
, i
);
187 kunmap(maddr
, KM_WRITE
);
195 if (signal_pending(current
))
202 static long long mem_lseek(struct file
* file
, long long offset
, int orig
)
206 file
->f_pos
= offset
;
209 file
->f_pos
+= offset
;
217 * This isn't really reliable by any means..
219 int mem_mmap(struct file
* file
, struct vm_area_struct
* vma
)
221 struct task_struct
*tsk
;
222 pgd_t
*src_dir
, *dest_dir
;
223 pmd_t
*src_middle
, *dest_middle
;
224 pte_t
*src_table
, *dest_table
;
225 unsigned long stmp
, etmp
, dtmp
, mapnr
;
226 struct vm_area_struct
*src_vma
= NULL
;
227 struct inode
*inode
= file
->f_dentry
->d_inode
;
229 /* Get the source's task information */
231 tsk
= get_task(inode
->i_ino
>> 16);
236 /* Ensure that we have a valid source area. (Has to be mmap'ed and
237 have valid page information.) We can't map shared memory at the
238 moment because working out the vm_area_struct & nattach stuff isn't
241 src_vma
= tsk
->mm
->mmap
;
242 stmp
= vma
->vm_pgoff
<< PAGE_SHIFT
;
243 etmp
= stmp
+ vma
->vm_end
- vma
->vm_start
;
244 while (stmp
< etmp
) {
245 while (src_vma
&& stmp
> src_vma
->vm_end
)
246 src_vma
= src_vma
->vm_next
;
247 if (!src_vma
|| (src_vma
->vm_flags
& VM_SHM
))
250 src_dir
= pgd_offset(tsk
->mm
, stmp
);
251 if (pgd_none(*src_dir
))
253 if (pgd_bad(*src_dir
)) {
257 src_middle
= pmd_offset(src_dir
, stmp
);
258 if (pmd_none(*src_middle
))
260 if (pmd_bad(*src_middle
)) {
261 pmd_ERROR(*src_middle
);
264 src_table
= pte_offset(src_middle
, stmp
);
265 if (pte_none(*src_table
))
268 if (stmp
< src_vma
->vm_start
) {
269 if (!(src_vma
->vm_flags
& VM_GROWSDOWN
))
271 if (src_vma
->vm_end
- stmp
> current
->rlim
[RLIMIT_STACK
].rlim_cur
)
277 src_vma
= tsk
->mm
->mmap
;
278 stmp
= vma
->vm_pgoff
<< PAGE_SHIFT
;
279 dtmp
= vma
->vm_start
;
281 flush_cache_range(vma
->vm_mm
, vma
->vm_start
, vma
->vm_end
);
282 flush_cache_range(src_vma
->vm_mm
, src_vma
->vm_start
, src_vma
->vm_end
);
283 while (dtmp
< vma
->vm_end
) {
284 while (src_vma
&& stmp
> src_vma
->vm_end
)
285 src_vma
= src_vma
->vm_next
;
287 src_dir
= pgd_offset(tsk
->mm
, stmp
);
288 src_middle
= pmd_offset(src_dir
, stmp
);
289 src_table
= pte_offset(src_middle
, stmp
);
291 dest_dir
= pgd_offset(current
->mm
, dtmp
);
292 dest_middle
= pmd_alloc(dest_dir
, dtmp
);
295 dest_table
= pte_alloc(dest_middle
, dtmp
);
299 if (!pte_present(*src_table
))
300 handle_mm_fault(tsk
, src_vma
, stmp
, 1);
302 if ((vma
->vm_flags
& VM_WRITE
) && !pte_write(*src_table
))
303 handle_mm_fault(tsk
, src_vma
, stmp
, 1);
305 set_pte(src_table
, pte_mkdirty(*src_table
));
306 set_pte(dest_table
, *src_table
);
307 mapnr
= pte_pagenr(*src_table
);
308 if (mapnr
< max_mapnr
)
309 get_page(mem_map
+ pte_pagenr(*src_table
));
315 flush_tlb_range(vma
->vm_mm
, vma
->vm_start
, vma
->vm_end
);
316 flush_tlb_range(src_vma
->vm_mm
, src_vma
->vm_start
, src_vma
->vm_end
);
320 static struct file_operations proc_mem_operations
= {
324 NULL
, /* mem_readdir */
326 NULL
, /* mem_ioctl */
328 NULL
, /* no special open code */
330 NULL
, /* no special release code */
331 NULL
/* can't fsync */
334 struct inode_operations proc_mem_inode_operations
= {
335 &proc_mem_operations
, /* default base directory file-ops */
346 NULL
, /* follow_link */
347 NULL
, /* get_block */
349 NULL
, /* writepage */
350 NULL
, /* flushpage */
352 proc_permission
, /* permission */
354 NULL
/* revalidate */