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 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 }
130
131 static struct file_operations proc_mem_operations = {
132 mem_lseek,
133 mem_read,
134 mem_write,
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139 NULL,
140 NULL
141 };
142
143 struct inode_operations proc_mem_inode_operations = {
144 &proc_mem_operations,
145 NULL,
146 NULL,
147 NULL,
148 NULL,
149 NULL,
150 NULL,
151 NULL,
152 NULL,
153 NULL,
154 NULL,
155 NULL,
156 NULL,
157 NULL
158 };