Skip site navigation (1)Skip section navigation (2)
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>