From bd23090f7cf15315bea02380841e9b601df6e591 Mon Sep 17 00:00:00 2001 From: tmm Date: Fri, 12 Apr 2002 19:38:41 +0000 Subject: [PATCH] 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 --- sys/kern/sys_pipe.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 8699ca27757e..4511fba30d5b 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; }