Date: Thu, 16 Mar 2017 16:49:28 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> 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 Message-ID: <201703161649.v2GGnSZp035011@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 <sys/param.h> +#include <sys/lock.h> +#include <sys/proc.h> + +#include <vm/vm.h> +#include <vm/vm_extern.h> + #include <linux/compiler.h> +#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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703161649.v2GGnSZp035011>