|
|
1.1 root 1: /*
2: * linux/fs/proc/mem.c
3: *
4: * Copyright (C) 1991, 1992 Linus Torvalds
5: */
6:
7: #include <linux/types.h>
8: #include <linux/errno.h>
9: #include <linux/sched.h>
10: #include <linux/kernel.h>
11:
12: #include <asm/segment.h>
13: #include <asm/io.h>
14:
15: static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
16: {
17: unsigned long addr, pid, cr3;
18: char *tmp;
19: unsigned long pde, pte, page;
20: int i;
21:
22: if (count < 0)
23: return -EINVAL;
24: pid = inode->i_ino;
25: pid >>= 16;
26: cr3 = 0;
27: for (i = 1 ; i < NR_TASKS ; i++)
28: if (task[i] && task[i]->pid == pid) {
29: cr3 = task[i]->tss.cr3;
30: break;
31: }
32: if (!cr3)
33: return -EACCES;
34: addr = file->f_pos;
35: tmp = buf;
36: while (count > 0) {
37: if (current->signal & ~current->blocked)
38: break;
39: pde = cr3 + (addr >> 20 & 0xffc);
40: pte = *(unsigned long *) pde;
41: if (!(pte & PAGE_PRESENT))
42: break;
43: pte &= 0xfffff000;
44: pte += (addr >> 10) & 0xffc;
45: page = *(unsigned long *) pte;
46: if (!(page & 1))
47: break;
48: page &= 0xfffff000;
49: page += addr & 0xfff;
50: i = 4096-(addr & 0xfff);
51: if (i > count)
52: i = count;
53: memcpy_tofs(tmp,(void *) page,i);
54: addr += i;
55: tmp += i;
56: count -= i;
57: }
58: file->f_pos = addr;
59: return tmp-buf;
60: }
61:
62: static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
63: {
64: unsigned long addr, pid, cr3;
65: char *tmp;
66: unsigned long pde, pte, page;
67: int i;
68:
69: if (count < 0)
70: return -EINVAL;
71: addr = file->f_pos;
72: pid = inode->i_ino;
73: pid >>= 16;
74: cr3 = 0;
75: for (i = 1 ; i < NR_TASKS ; i++)
76: if (task[i] && task[i]->pid == pid) {
77: cr3 = task[i]->tss.cr3;
78: break;
79: }
80: if (!cr3)
81: return -EACCES;
82: tmp = buf;
83: while (count > 0) {
84: if (current->signal & ~current->blocked)
85: break;
86: pde = cr3 + (addr >> 20 & 0xffc);
87: pte = *(unsigned long *) pde;
88: if (!(pte & PAGE_PRESENT))
89: break;
90: pte &= 0xfffff000;
91: pte += (addr >> 10) & 0xffc;
92: page = *(unsigned long *) pte;
93: if (!(page & PAGE_PRESENT))
94: break;
95: if (!(page & 2)) {
96: do_wp_page(0,addr,current,0);
97: continue;
98: }
99: page &= 0xfffff000;
100: page += addr & 0xfff;
101: i = 4096-(addr & 0xfff);
102: if (i > count)
103: i = count;
104: memcpy_fromfs((void *) page,tmp,i);
105: addr += i;
106: tmp += i;
107: count -= i;
108: }
109: file->f_pos = addr;
110: if (tmp != buf)
111: return tmp-buf;
112: if (current->signal & ~current->blocked)
113: return -ERESTARTSYS;
114: return 0;
115: }
116:
117: static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
118: {
119: switch (orig) {
120: case 0:
121: file->f_pos = offset;
122: return file->f_pos;
123: case 1:
124: file->f_pos += offset;
125: return file->f_pos;
126: default:
127: return -EINVAL;
128: }
129: if (file->f_pos < 0)
130: return 0;
131: return file->f_pos;
132: }
133:
134: static struct file_operations proc_mem_operations = {
135: mem_lseek,
136: mem_read,
137: mem_write,
138: NULL, /* mem_readdir */
139: NULL, /* mem_select */
140: NULL, /* mem_ioctl */
141: NULL, /* no special open code */
142: NULL /* no special release code */
143: };
144:
145: struct inode_operations proc_mem_inode_operations = {
146: &proc_mem_operations, /* default base directory file-ops */
147: NULL, /* create */
148: NULL, /* lookup */
149: NULL, /* link */
150: NULL, /* unlink */
151: NULL, /* symlink */
152: NULL, /* mkdir */
153: NULL, /* rmdir */
154: NULL, /* mknod */
155: NULL, /* rename */
156: NULL, /* readlink */
157: NULL, /* follow_link */
158: NULL, /* bmap */
159: NULL /* truncate */
160: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.