Deleted Added
full compact
procfs_mem.c (81107) procfs_mem.c (84637)
1/*
2 * Copyright (c) 1993 Jan-Simon Pendry
3 * Copyright (c) 1993 Sean Eric Fagan
4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Jan-Simon Pendry and Sean Eric Fagan.

--- 23 unchanged lines hidden (view full) ---

32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)procfs_mem.c 8.5 (Berkeley) 6/15/94
39 *
1/*
2 * Copyright (c) 1993 Jan-Simon Pendry
3 * Copyright (c) 1993 Sean Eric Fagan
4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Jan-Simon Pendry and Sean Eric Fagan.

--- 23 unchanged lines hidden (view full) ---

32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)procfs_mem.c 8.5 (Berkeley) 6/15/94
39 *
40 * $FreeBSD: head/sys/fs/procfs/procfs_mem.c 81107 2001-08-03 17:13:23Z rwatson $
40 * $FreeBSD: head/sys/fs/procfs/procfs_mem.c 84637 2001-10-07 20:08:42Z des $
41 */
42
41 */
42
43/*
44 * This is a lightly hacked and merged version
45 * of sef's pread/pwrite functions
46 */
47
48#include <sys/param.h>
49#include <sys/systm.h>
50#include <sys/lock.h>
51#include <sys/mutex.h>
52#include <sys/proc.h>
53#include <sys/ptrace.h>
54#include <sys/user.h>
55#include <sys/vnode.h>
56
57#include <fs/procfs/procfs.h>
58
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/lock.h>
46#include <sys/mutex.h>
47#include <sys/proc.h>
48#include <sys/ptrace.h>
49#include <sys/user.h>
50#include <sys/vnode.h>
51
52#include <fs/procfs/procfs.h>
53
59#include <vm/vm.h>
60#include <vm/vm_param.h>
61#include <vm/pmap.h>
62#include <vm/vm_extern.h>
63#include <vm/vm_map.h>
64#include <vm/vm_kern.h>
65#include <vm/vm_object.h>
66#include <vm/vm_page.h>
67
68static int procfs_rwmem __P((struct proc *curp,
69 struct proc *p, struct uio *uio));
70
71static int
72procfs_rwmem(curp, p, uio)
73 struct proc *curp;
74 struct proc *p;
75 struct uio *uio;
76{
77 int error;
78 int writing;
79 struct vmspace *vm;
80 vm_map_t map;
81 vm_object_t object = NULL;
82 vm_offset_t pageno = 0; /* page number */
83 vm_prot_t reqprot;
84 vm_offset_t kva;
85
86 GIANT_REQUIRED;
87
88 /*
89 * if the vmspace is in the midst of being deallocated or the
90 * process is exiting, don't try to grab anything. The page table
91 * usage in that process can be messed up.
92 */
93 vm = p->p_vmspace;
94 if ((p->p_flag & P_WEXIT))
95 return EFAULT;
96 if (vm->vm_refcnt < 1)
97 return EFAULT;
98 ++vm->vm_refcnt;
99 /*
100 * The map we want...
101 */
102 map = &vm->vm_map;
103
104 writing = uio->uio_rw == UIO_WRITE;
105 reqprot = writing ? (VM_PROT_WRITE | VM_PROT_OVERRIDE_WRITE) : VM_PROT_READ;
106
107 kva = kmem_alloc_pageable(kernel_map, PAGE_SIZE);
108
109 /*
110 * Only map in one page at a time. We don't have to, but it
111 * makes things easier. This way is trivial - right?
112 */
113 do {
114 vm_map_t tmap;
115 vm_offset_t uva;
116 int page_offset; /* offset into page */
117 vm_map_entry_t out_entry;
118 vm_prot_t out_prot;
119 boolean_t wired;
120 vm_pindex_t pindex;
121 u_int len;
122 vm_page_t m;
123
124 object = NULL;
125
126 uva = (vm_offset_t) uio->uio_offset;
127
128 /*
129 * Get the page number of this segment.
130 */
131 pageno = trunc_page(uva);
132 page_offset = uva - pageno;
133
134 /*
135 * How many bytes to copy
136 */
137 len = min(PAGE_SIZE - page_offset, uio->uio_resid);
138
139 /*
140 * Fault the page on behalf of the process
141 */
142 error = vm_fault(map, pageno, reqprot, VM_FAULT_NORMAL);
143 if (error) {
144 error = EFAULT;
145 break;
146 }
147
148 /*
149 * Now we need to get the page. out_entry, out_prot, wired,
150 * and single_use aren't used. One would think the vm code
151 * would be a *bit* nicer... We use tmap because
152 * vm_map_lookup() can change the map argument.
153 */
154 tmap = map;
155 error = vm_map_lookup(&tmap, pageno, reqprot,
156 &out_entry, &object, &pindex, &out_prot,
157 &wired);
158
159 if (error) {
160 error = EFAULT;
161
162 /*
163 * Make sure that there is no residue in 'object' from
164 * an error return on vm_map_lookup.
165 */
166 object = NULL;
167
168 break;
169 }
170
171 m = vm_page_lookup(object, pindex);
172
173 /* Allow fallback to backing objects if we are reading */
174
175 while (m == NULL && !writing && object->backing_object) {
176
177 pindex += OFF_TO_IDX(object->backing_object_offset);
178 object = object->backing_object;
179
180 m = vm_page_lookup(object, pindex);
181 }
182
183 if (m == NULL) {
184 error = EFAULT;
185
186 /*
187 * Make sure that there is no residue in 'object' from
188 * an error return on vm_map_lookup.
189 */
190 object = NULL;
191
192 vm_map_lookup_done(tmap, out_entry);
193
194 break;
195 }
196
197 /*
198 * Wire the page into memory
199 */
200 vm_page_wire(m);
201
202 /*
203 * We're done with tmap now.
204 * But reference the object first, so that we won't loose
205 * it.
206 */
207 vm_object_reference(object);
208 vm_map_lookup_done(tmap, out_entry);
209
210 pmap_kenter(kva, VM_PAGE_TO_PHYS(m));
211
212 /*
213 * Now do the i/o move.
214 */
215 error = uiomove((caddr_t)(kva + page_offset), len, uio);
216
217 pmap_kremove(kva);
218
219 /*
220 * release the page and the object
221 */
222 vm_page_unwire(m, 1);
223 vm_object_deallocate(object);
224
225 object = NULL;
226
227 } while (error == 0 && uio->uio_resid > 0);
228
229 if (object)
230 vm_object_deallocate(object);
231
232 kmem_free(kernel_map, kva, PAGE_SIZE);
233 vmspace_free(vm);
234 return (error);
235}
236
237/*
238 * Copy data in and out of the target process.
239 * We do this by mapping the process's page into
240 * the kernel and then doing a uiomove direct
241 * from the kernel address space.
242 */
243int
244procfs_domem(curp, p, pfs, uio)

--- 6 unchanged lines hidden (view full) ---

251
252 if (uio->uio_resid == 0)
253 return (0);
254
255 error = p_candebug(curp, p);
256 if (error)
257 return (error);
258
54/*
55 * Copy data in and out of the target process.
56 * We do this by mapping the process's page into
57 * the kernel and then doing a uiomove direct
58 * from the kernel address space.
59 */
60int
61procfs_domem(curp, p, pfs, uio)

--- 6 unchanged lines hidden (view full) ---

68
69 if (uio->uio_resid == 0)
70 return (0);
71
72 error = p_candebug(curp, p);
73 if (error)
74 return (error);
75
259 return (procfs_rwmem(curp, p, uio));
76 return (proc_rwmem(p, uio));
260}
77}
261
262/*
263 * Given process (p), find the vnode from which
264 * its text segment is being executed.
265 *
266 * It would be nice to grab this information from
267 * the VM system, however, there is no sure-fire
268 * way of doing that. Instead, fork(), exec() and
269 * wait() all maintain the p_textvp field in the
270 * process proc structure which contains a held
271 * reference to the exec'ed vnode.
272 *
273 * XXX - Currently, this is not not used, as the
274 * /proc/pid/file object exposes an information leak
275 * that shouldn't happen. Using a mount option would
276 * make it configurable on a per-system (or, at least,
277 * per-mount) basis; however, that's not really best.
278 * The best way to do it, I think, would be as an
279 * ioctl; this would restrict it to the uid running
280 * program, or root, which seems a reasonable compromise.
281 * However, the number of applications for this is
282 * minimal, if it can't be seen in the filesytem space,
283 * and doint it as an ioctl makes it somewhat less
284 * useful due to the, well, inelegance.
285 *
286 */
287struct vnode *
288procfs_findtextvp(p)
289 struct proc *p;
290{
291
292 return (p->p_textvp);
293}