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} | |