From owner-svn-src-head@freebsd.org Thu Mar 16 16:49:29 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5B40CD0E20A; Thu, 16 Mar 2017 16:49:29 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2D3A91F1E; Thu, 16 Mar 2017 16:49:29 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v2GGnShd035013; Thu, 16 Mar 2017 16:49:28 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v2GGnSZp035011; Thu, 16 Mar 2017 16:49:28 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201703161649.v2GGnSZp035011@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Thu, 16 Mar 2017 16:49:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r315419 - in head/sys/compat/linuxkpi/common: include/linux src X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Mar 2017 16:49:29 -0000 Author: hselasky Date: Thu Mar 16 16:49:27 2017 New Revision: 315419 URL: https://svnweb.freebsd.org/changeset/base/315419 Log: Implement more userspace memory access functions in the LinuxKPI. Obtained from: kmacy @ MFC after: 1 week Sponsored by: Mellanox Technologies Modified: head/sys/compat/linuxkpi/common/include/linux/uaccess.h head/sys/compat/linuxkpi/common/src/linux_compat.c Modified: head/sys/compat/linuxkpi/common/include/linux/uaccess.h ============================================================================== --- head/sys/compat/linuxkpi/common/include/linux/uaccess.h Thu Mar 16 16:40:54 2017 (r315418) +++ head/sys/compat/linuxkpi/common/include/linux/uaccess.h Thu Mar 16 16:49:27 2017 (r315419) @@ -29,11 +29,22 @@ * * $FreeBSD$ */ + #ifndef _LINUX_UACCESS_H_ #define _LINUX_UACCESS_H_ +#include +#include +#include + +#include +#include + #include +#define VERIFY_READ VM_PROT_READ +#define VERIFY_WRITE VM_PROT_WRITE + #define __get_user(_x, _p) ({ \ int __err; \ __typeof(*(_p)) __x; \ @@ -48,9 +59,13 @@ }) #define get_user(_x, _p) linux_copyin((_p), &(_x), sizeof(*(_p))) #define put_user(_x, _p) linux_copyout(&(_x), (_p), sizeof(*(_p))) +#define clear_user(...) linux_clear_user(__VA_ARGS__) +#define access_ok(...) linux_access_ok(__VA_ARGS__) extern int linux_copyin(const void *uaddr, void *kaddr, size_t len); extern int linux_copyout(const void *kaddr, void *uaddr, size_t len); +extern size_t linux_clear_user(void *uaddr, size_t len); +extern int linux_access_ok(int rw, const void *uaddr, size_t len); /* * NOTE: The returned value from pagefault_disable() must be stored @@ -69,4 +84,10 @@ pagefault_enable(int save) vm_fault_enable_pagefaults(save); } -#endif /* _LINUX_UACCESS_H_ */ +static inline bool +pagefault_disabled(void) +{ + return ((curthread->td_pflags & TDP_NOFAULTING) != 0); +} + +#endif /* _LINUX_UACCESS_H_ */ Modified: head/sys/compat/linuxkpi/common/src/linux_compat.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_compat.c Thu Mar 16 16:40:54 2017 (r315418) +++ head/sys/compat/linuxkpi/common/src/linux_compat.c Thu Mar 16 16:49:27 2017 (r315419) @@ -508,6 +508,53 @@ linux_copyout(const void *kaddr, void *u return (-copyout(kaddr, uaddr, len)); } +size_t +linux_clear_user(void *_uaddr, size_t _len) +{ + uint8_t *uaddr = _uaddr; + size_t len = _len; + + /* make sure uaddr is aligned before going into the fast loop */ + while (((uintptr_t)uaddr & 7) != 0 && len > 7) { + if (subyte(uaddr, 0)) + return (_len); + uaddr++; + len--; + } + + /* zero 8 bytes at a time */ + while (len > 7) { + if (suword64(uaddr, 0)) + return (_len); + uaddr += 8; + len -= 8; + } + + /* zero fill end, if any */ + while (len > 0) { + if (subyte(uaddr, 0)) + return (_len); + uaddr++; + len--; + } + return (0); +} + +int +linux_access_ok(int rw, const void *uaddr, size_t len) +{ + uintptr_t saddr; + uintptr_t eaddr; + + /* get start and end address */ + saddr = (uintptr_t)uaddr; + eaddr = (uintptr_t)uaddr + len; + + /* verify addresses are valid for userspace */ + return ((saddr == eaddr) || + (eaddr > saddr && eaddr <= VM_MAXUSER_ADDRESS)); +} + static int linux_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)