summaryrefslogtreecommitdiff
path: root/include/linux/sockptr.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/sockptr.h')
-rw-r--r--include/linux/sockptr.h32
1 files changed, 30 insertions, 2 deletions
diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h
index 700856e13ea0..7d5cdb2b30b5 100644
--- a/include/linux/sockptr.h
+++ b/include/linux/sockptr.h
@@ -8,9 +8,34 @@
#ifndef _LINUX_SOCKPTR_H
#define _LINUX_SOCKPTR_H
+#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+typedef union {
+ void *kernel;
+ void __user *user;
+} sockptr_t;
+
+static inline bool sockptr_is_kernel(sockptr_t sockptr)
+{
+ return (unsigned long)sockptr.kernel >= TASK_SIZE;
+}
+
+static inline sockptr_t KERNEL_SOCKPTR(void *p)
+{
+ return (sockptr_t) { .kernel = p };
+}
+
+static inline int __must_check init_user_sockptr(sockptr_t *sp, void __user *p)
+{
+ if ((unsigned long)p >= TASK_SIZE)
+ return -EFAULT;
+ sp->user = p;
+ return 0;
+}
+#else /* CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE */
typedef struct {
union {
void *kernel;
@@ -29,10 +54,13 @@ static inline sockptr_t KERNEL_SOCKPTR(void *p)
return (sockptr_t) { .kernel = p, .is_kernel = true };
}
-static inline sockptr_t USER_SOCKPTR(void __user *p)
+static inline int __must_check init_user_sockptr(sockptr_t *sp, void __user *p)
{
- return (sockptr_t) { .user = p };
+ sp->user = p;
+ sp->is_kernel = false;
+ return 0;
}
+#endif /* CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE */
static inline bool sockptr_is_null(sockptr_t sockptr)
{