From owner-svn-src-all@FreeBSD.ORG Sat Jul 9 15:21:10 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DE93D1065672; Sat, 9 Jul 2011 15:21:10 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CE3B28FC13; Sat, 9 Jul 2011 15:21:10 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p69FLALh005684; Sat, 9 Jul 2011 15:21:10 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p69FLAat005677; Sat, 9 Jul 2011 15:21:10 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201107091521.p69FLAat005677@svn.freebsd.org> From: Konstantin Belousov Date: Sat, 9 Jul 2011 15:21:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r223889 - in head/sys: kern sys vm X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 09 Jul 2011 15:21:11 -0000 Author: kib Date: Sat Jul 9 15:21:10 2011 New Revision: 223889 URL: http://svn.freebsd.org/changeset/base/223889 Log: Add a facility to disable processing page faults. When activated, uiomove generates EFAULT if any accessed address is not mapped, as opposed to handling the fault. Sponsored by: The FreeBSD Foundation Reviewed by: alc (previous version) Modified: head/sys/kern/subr_uio.c head/sys/sys/proc.h head/sys/sys/systm.h head/sys/sys/uio.h head/sys/vm/vm_extern.h head/sys/vm/vm_fault.c Modified: head/sys/kern/subr_uio.c ============================================================================== --- head/sys/kern/subr_uio.c Sat Jul 9 15:16:07 2011 (r223888) +++ head/sys/kern/subr_uio.c Sat Jul 9 15:21:10 2011 (r223889) @@ -64,6 +64,8 @@ __FBSDID("$FreeBSD$"); SYSCTL_INT(_kern, KERN_IOV_MAX, iov_max, CTLFLAG_RD, NULL, UIO_MAXIOV, "Maximum number of elements in an I/O vector; sysconf(_SC_IOV_MAX)"); +static int uiomove_faultflag(void *cp, int n, struct uio *uio, int nofault); + #ifdef ZERO_COPY_SOCKETS /* Declared in uipc_socket.c */ extern int so_zero_copy_receive; @@ -129,23 +131,65 @@ retry: #endif /* ZERO_COPY_SOCKETS */ int +copyin_nofault(const void *udaddr, void *kaddr, size_t len) +{ + int error, save; + + save = vm_fault_disable_pagefaults(); + error = copyin(udaddr, kaddr, len); + vm_fault_enable_pagefaults(save); + return (error); +} + +int +copyout_nofault(const void *kaddr, void *udaddr, size_t len) +{ + int error, save; + + save = vm_fault_disable_pagefaults(); + error = copyout(kaddr, udaddr, len); + vm_fault_enable_pagefaults(save); + return (error); +} + +int uiomove(void *cp, int n, struct uio *uio) { - struct thread *td = curthread; + + return (uiomove_faultflag(cp, n, uio, 0)); +} + +int +uiomove_nofault(void *cp, int n, struct uio *uio) +{ + + return (uiomove_faultflag(cp, n, uio, 1)); +} + +static int +uiomove_faultflag(void *cp, int n, struct uio *uio, int nofault) +{ + struct thread *td; struct iovec *iov; u_int cnt; - int error = 0; - int save = 0; + int error, newflags, save; + + td = curthread; + error = 0; KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE, ("uiomove: mode")); - KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, + KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == td, ("uiomove proc")); - WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, - "Calling uiomove()"); - - save = td->td_pflags & TDP_DEADLKTREAT; - td->td_pflags |= TDP_DEADLKTREAT; + if (!nofault) + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, + "Calling uiomove()"); + + /* XXX does it make a sense to set TDP_DEADLKTREAT for UIO_SYSSPACE ? */ + newflags = TDP_DEADLKTREAT; + if (uio->uio_segflg == UIO_USERSPACE && nofault) + newflags |= TDP_NOFAULTING; + save = curthread_pflags_set(newflags); while (n > 0 && uio->uio_resid) { iov = uio->uio_iov; @@ -187,8 +231,7 @@ uiomove(void *cp, int n, struct uio *uio n -= cnt; } out: - if (save == 0) - td->td_pflags &= ~TDP_DEADLKTREAT; + curthread_pflags_restore(save); return (error); } Modified: head/sys/sys/proc.h ============================================================================== --- head/sys/sys/proc.h Sat Jul 9 15:16:07 2011 (r223888) +++ head/sys/sys/proc.h Sat Jul 9 15:21:10 2011 (r223889) @@ -393,7 +393,7 @@ do { \ #define TDP_COWINPROGRESS 0x00000010 /* Snapshot copy-on-write in progress. */ #define TDP_ALTSTACK 0x00000020 /* Have alternate signal stack. */ #define TDP_DEADLKTREAT 0x00000040 /* Lock aquisition - deadlock treatment. */ -#define TDP_UNUSED80 0x00000080 /* available. */ +#define TDP_NOFAULTING 0x00000080 /* Do not handle page faults. */ #define TDP_NOSLEEPING 0x00000100 /* Thread is not allowed to sleep on a sq. */ #define TDP_OWEUPC 0x00000200 /* Call addupc() at next AST. */ #define TDP_ITHREAD 0x00000400 /* Thread is an interrupt thread. */ Modified: head/sys/sys/systm.h ============================================================================== --- head/sys/sys/systm.h Sat Jul 9 15:16:07 2011 (r223888) +++ head/sys/sys/systm.h Sat Jul 9 15:21:10 2011 (r223889) @@ -217,8 +217,12 @@ int copyinstr(const void * __restrict ud __nonnull(1) __nonnull(2); int copyin(const void * __restrict udaddr, void * __restrict kaddr, size_t len) __nonnull(1) __nonnull(2); +int copyin_nofault(const void * __restrict udaddr, void * __restrict kaddr, + size_t len) __nonnull(1) __nonnull(2); int copyout(const void * __restrict kaddr, void * __restrict udaddr, size_t len) __nonnull(1) __nonnull(2); +int copyout_nofault(const void * __restrict kaddr, void * __restrict udaddr, + size_t len) __nonnull(1) __nonnull(2); int fubyte(const void *base); long fuword(const void *base); Modified: head/sys/sys/uio.h ============================================================================== --- head/sys/sys/uio.h Sat Jul 9 15:16:07 2011 (r223888) +++ head/sys/sys/uio.h Sat Jul 9 15:21:10 2011 (r223889) @@ -100,6 +100,7 @@ int uiomove(void *cp, int n, struct uio int uiomove_frombuf(void *buf, int buflen, struct uio *uio); int uiomove_fromphys(struct vm_page *ma[], vm_offset_t offset, int n, struct uio *uio); +int uiomove_nofault(void *cp, int n, struct uio *uio); int uiomoveco(void *cp, int n, struct uio *uio, int disposable); #else /* !_KERNEL */ Modified: head/sys/vm/vm_extern.h ============================================================================== --- head/sys/vm/vm_extern.h Sat Jul 9 15:16:07 2011 (r223888) +++ head/sys/vm/vm_extern.h Sat Jul 9 15:21:10 2011 (r223889) @@ -61,6 +61,8 @@ int useracc(void *, int, int); int vm_fault(vm_map_t, vm_offset_t, vm_prot_t, int); void vm_fault_copy_entry(vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t, vm_ooffset_t *); +int vm_fault_disable_pagefaults(void); +void vm_fault_enable_pagefaults(int save); int vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, int fault_flags, vm_page_t *m_hold); int vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t addr, vm_size_t len, Modified: head/sys/vm/vm_fault.c ============================================================================== --- head/sys/vm/vm_fault.c Sat Jul 9 15:16:07 2011 (r223888) +++ head/sys/vm/vm_fault.c Sat Jul 9 15:21:10 2011 (r223889) @@ -209,6 +209,8 @@ vm_fault(vm_map_t map, vm_offset_t vaddr int fault_flags) { + if ((curthread->td_pflags & TDP_NOFAULTING) != 0) + return (KERN_PROTECTION_FAILURE); return (vm_fault_hold(map, vaddr, fault_type, fault_flags, NULL)); } @@ -1475,3 +1477,17 @@ vm_fault_additional_pages(m, rbehind, ra /* return number of pages */ return i; } + +int +vm_fault_disable_pagefaults(void) +{ + + return (curthread_pflags_set(TDP_NOFAULTING)); +} + +void +vm_fault_enable_pagefaults(int save) +{ + + curthread_pflags_restore(save); +}