uio_machdep.c revision 130028
1284990Scy/* 2284990Scy * Copyright (c) 2004 Alan L. Cox <alc@cs.rice.edu> 3284990Scy * Copyright (c) 1982, 1986, 1991, 1993 4284990Scy * The Regents of the University of California. All rights reserved. 5284990Scy * (c) UNIX System Laboratories, Inc. 6284990Scy * All or some portions of this file are derived from material licensed 7284990Scy * to the University of California by American Telephone and Telegraph 8284990Scy * Co. or Unix System Laboratories, Inc. and are reproduced herein with 9284990Scy * the permission of UNIX System Laboratories, Inc. 10284990Scy * 11284990Scy * Redistribution and use in source and binary forms, with or without 12284990Scy * modification, are permitted provided that the following conditions 13284990Scy * are met: 14284990Scy * 1. Redistributions of source code must retain the above copyright 15284990Scy * notice, this list of conditions and the following disclaimer. 16284990Scy * 2. Redistributions in binary form must reproduce the above copyright 17284990Scy * notice, this list of conditions and the following disclaimer in the 18284990Scy * documentation and/or other materials provided with the distribution. 19284990Scy * 3. All advertising materials mentioning features or use of this software 20284990Scy * must display the following acknowledgement: 21284990Scy * This product includes software developed by the University of 22284990Scy * California, Berkeley and its contributors. 23284990Scy * 4. Neither the name of the University nor the names of its contributors 24284990Scy * may be used to endorse or promote products derived from this software 25284990Scy * without specific prior written permission. 26284990Scy * 27284990Scy * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28284990Scy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29284990Scy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30284990Scy * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31284990Scy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32284990Scy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33284990Scy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34284990Scy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35284990Scy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36284990Scy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37284990Scy * SUCH DAMAGE. 38284990Scy * 39284990Scy * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94 40284990Scy */ 41284990Scy 42284990Scy#include <sys/cdefs.h> 43284990Scy__FBSDID("$FreeBSD: head/sys/arm/arm/uio_machdep.c 130028 2004-06-03 10:22:47Z tjr $"); 44284990Scy 45284990Scy#include <sys/param.h> 46284990Scy#include <sys/kernel.h> 47284990Scy#include <sys/lock.h> 48284990Scy#include <sys/mutex.h> 49284990Scy#include <sys/proc.h> 50284990Scy#include <sys/systm.h> 51284990Scy#include <sys/uio.h> 52284990Scy 53284990Scy#include <vm/vm.h> 54284990Scy#include <vm/vm_page.h> 55284990Scy 56284990Scy#include <machine/vmparam.h> 57284990Scy 58284990Scy/* 59284990Scy * Implement uiomove(9) from physical memory using the direct map to 60284990Scy * avoid the creation and destruction of ephemeral mappings. 61284990Scy */ 62284990Scyint 63284990Scyuiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) 64284990Scy{ 65284990Scy struct thread *td = curthread; 66284990Scy struct iovec *iov; 67284990Scy void *cp; 68284990Scy vm_offset_t page_offset; 69284990Scy size_t cnt; 70284990Scy int error = 0; 71284990Scy int save = 0; 72284990Scy 73284990Scy KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE, 74284990Scy ("uiomove_fromphys: mode")); 75284990Scy KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, 76284990Scy ("uiomove_fromphys proc")); 77284990Scy save = td->td_pflags & TDP_DEADLKTREAT; 78284990Scy td->td_pflags |= TDP_DEADLKTREAT; 79284990Scy while (n > 0 && uio->uio_resid) { 80284990Scy iov = uio->uio_iov; 81284990Scy cnt = iov->iov_len; 82284990Scy if (cnt == 0) { 83284990Scy uio->uio_iov++; 84284990Scy uio->uio_iovcnt--; 85284990Scy continue; 86284990Scy } 87284990Scy if (cnt > n) 88284990Scy cnt = n; 89284990Scy page_offset = offset & PAGE_MASK; 90284990Scy cnt = min(cnt, PAGE_SIZE - page_offset); 91284990Scy cp = (char *)VM_PAGE_TO_PHYS(ma[offset >> PAGE_SHIFT]) + 92284990Scy page_offset; 93284990Scy switch (uio->uio_segflg) { 94284990Scy case UIO_USERSPACE: 95284990Scy if (ticks - PCPU_GET(switchticks) >= hogticks) 96284990Scy uio_yield(); 97284990Scy if (uio->uio_rw == UIO_READ) 98284990Scy error = copyout(cp, iov->iov_base, cnt); 99284990Scy else 100 error = copyin(iov->iov_base, cp, cnt); 101 if (error) 102 goto out; 103 break; 104 case UIO_SYSSPACE: 105 if (uio->uio_rw == UIO_READ) 106 bcopy(cp, iov->iov_base, cnt); 107 else 108 bcopy(iov->iov_base, cp, cnt); 109 break; 110 case UIO_NOCOPY: 111 break; 112 } 113 iov->iov_base = (char *)iov->iov_base + cnt; 114 iov->iov_len -= cnt; 115 uio->uio_resid -= cnt; 116 uio->uio_offset += cnt; 117 offset += cnt; 118 n -= cnt; 119 } 120out: 121 if (save == 0) 122 td->td_pflags &= ~TDP_DEADLKTREAT; 123 return (error); 124} 125