This source file includes following definitions.
- mem_read
- mem_write
- mem_lseek
1
2
3
4
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
16
17
18
19
20
21 #define mem_write NULL
22
23 static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
24 {
25 unsigned long addr, pid, cr3;
26 char *tmp;
27 unsigned long pde, pte, page;
28 int i;
29
30 if (count < 0)
31 return -EINVAL;
32 pid = inode->i_ino;
33 pid >>= 16;
34 cr3 = 0;
35 for (i = 1 ; i < NR_TASKS ; i++)
36 if (task[i] && task[i]->pid == pid) {
37 cr3 = task[i]->tss.cr3;
38 break;
39 }
40 if (!cr3)
41 return -EACCES;
42 addr = file->f_pos;
43 tmp = buf;
44 while (count > 0) {
45 if (current->signal & ~current->blocked)
46 break;
47 pde = cr3 + (addr >> 20 & 0xffc);
48 pte = *(unsigned long *) pde;
49 if (!(pte & PAGE_PRESENT))
50 break;
51 pte &= 0xfffff000;
52 pte += (addr >> 10) & 0xffc;
53 page = *(unsigned long *) pte;
54 if (!(page & 1))
55 break;
56 page &= 0xfffff000;
57 page += addr & 0xfff;
58 i = 4096-(addr & 0xfff);
59 if (i > count)
60 i = count;
61 memcpy_tofs(tmp,(void *) page,i);
62 addr += i;
63 tmp += i;
64 count -= i;
65 }
66 file->f_pos = addr;
67 return tmp-buf;
68 }
69
70 #ifndef mem_write
71
72 static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
73 {
74 unsigned long addr, pid, cr3;
75 char *tmp;
76 unsigned long pde, pte, page;
77 int i;
78
79 if (count < 0)
80 return -EINVAL;
81 addr = file->f_pos;
82 pid = inode->i_ino;
83 pid >>= 16;
84 cr3 = 0;
85 for (i = 1 ; i < NR_TASKS ; i++)
86 if (task[i] && task[i]->pid == pid) {
87 cr3 = task[i]->tss.cr3;
88 break;
89 }
90 if (!cr3)
91 return -EACCES;
92 tmp = buf;
93 while (count > 0) {
94 if (current->signal & ~current->blocked)
95 break;
96 pde = cr3 + (addr >> 20 & 0xffc);
97 pte = *(unsigned long *) pde;
98 if (!(pte & PAGE_PRESENT))
99 break;
100 pte &= 0xfffff000;
101 pte += (addr >> 10) & 0xffc;
102 page = *(unsigned long *) pte;
103 if (!(page & PAGE_PRESENT))
104 break;
105 if (!(page & 2)) {
106 do_wp_page(0,addr,current,0);
107 continue;
108 }
109 page &= 0xfffff000;
110 page += addr & 0xfff;
111 i = 4096-(addr & 0xfff);
112 if (i > count)
113 i = count;
114 memcpy_fromfs((void *) page,tmp,i);
115 addr += i;
116 tmp += i;
117 count -= i;
118 }
119 file->f_pos = addr;
120 if (tmp != buf)
121 return tmp-buf;
122 if (current->signal & ~current->blocked)
123 return -ERESTARTSYS;
124 return 0;
125 }
126
127 #endif
128
129 static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
130 {
131 switch (orig) {
132 case 0:
133 file->f_pos = offset;
134 return file->f_pos;
135 case 1:
136 file->f_pos += offset;
137 return file->f_pos;
138 default:
139 return -EINVAL;
140 }
141 }
142
143 static struct file_operations proc_mem_operations = {
144 mem_lseek,
145 mem_read,
146 mem_write,
147 NULL,
148 NULL,
149 NULL,
150 NULL,
151 NULL,
152 NULL
153 };
154
155 struct inode_operations proc_mem_inode_operations = {
156 &proc_mem_operations,
157 NULL,
158 NULL,
159 NULL,
160 NULL,
161 NULL,
162 NULL,
163 NULL,
164 NULL,
165 NULL,
166 NULL,
167 NULL,
168 NULL,
169 NULL,
170 NULL
171 };