summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authortmm <tmm@FreeBSD.org>2002-04-12 19:38:41 +0000
committertmm <tmm@FreeBSD.org>2002-04-12 19:38:41 +0000
commit1720bac84c28badd43c9edcde53d951a4b27178f (patch)
treed3b3c2e31a280e8a8f82a33ecb8cc5a6ad34ff78 /sys/kern
parent389e1779ffd7b99edf37c98d8f3d92feab749274 (diff)
downloadFreeBSD-src-1720bac84c28badd43c9edcde53d951a4b27178f.zip
FreeBSD-src-1720bac84c28badd43c9edcde53d951a4b27178f.tar.gz
Do not use pmap_kextract() to find out the physical address of a user
belong to a user virtual address; while this happens to work on some architectures, it can't on sparc64, since user and kernel virtual address spaces overlap there (the distinction between them is done via separate address space identifiers). Instead, look up the page in the vm_map of the process in question. Reviewed by: jake
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/sys_pipe.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 8699ca2..4511fba 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -599,9 +599,16 @@ pipe_build_write_buffer(wpipe, uio)
struct pipe *wpipe;
struct uio *uio;
{
+ vm_map_t map;
+ vm_map_entry_t me;
+ vm_object_t obj;
+ vm_pindex_t pidx;
+ vm_prot_t prot;
+ vm_page_t m;
+ boolean_t wired;
u_int size;
- int i;
- vm_offset_t addr, endaddr, paddr;
+ int i, rv;
+ vm_offset_t addr, endaddr;
GIANT_REQUIRED;
PIPE_LOCK_ASSERT(wpipe, MA_NOTOWNED);
@@ -613,19 +620,23 @@ pipe_build_write_buffer(wpipe, uio)
endaddr = round_page((vm_offset_t)uio->uio_iov->iov_base + size);
addr = trunc_page((vm_offset_t)uio->uio_iov->iov_base);
for (i = 0; addr < endaddr; addr += PAGE_SIZE, i++) {
- vm_page_t m;
-
+ map = &curproc->p_vmspace->vm_map;
+ rv = KERN_FAILURE;
if (vm_fault_quick((caddr_t)addr, VM_PROT_READ) < 0 ||
- (paddr = pmap_kextract(addr)) == 0) {
+ (rv = vm_map_lookup(&map, addr, VM_PROT_READ, &me, &obj,
+ &pidx, &prot, &wired)) != KERN_SUCCESS ||
+ (m = vm_page_lookup(obj, pidx)) == NULL) {
int j;
+ if (rv == KERN_SUCCESS)
+ vm_map_lookup_done(map, me);
for (j = 0; j < i; j++)
vm_page_unwire(wpipe->pipe_map.ms[j], 1);
return (EFAULT);
}
- m = PHYS_TO_VM_PAGE(paddr);
vm_page_wire(m);
+ vm_map_lookup_done(map, me);
wpipe->pipe_map.ms[i] = m;
}
OpenPOWER on IntegriCloud