xref: /openbsd/sys/dev/pci/drm/include/linux/uaccess.h (revision f21037fb)
1 /*	$OpenBSD: uaccess.h,v 1.7 2022/02/01 04:09:14 jsg Exp $	*/
2 /*
3  * Copyright (c) 2015 Mark Kettenis
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #ifndef _LINUX_UACCESS_H
19 #define _LINUX_UACCESS_H
20 
21 #include <sys/param.h>
22 #include <sys/systm.h>
23 #include <uvm/uvm_extern.h>
24 
25 #include <linux/sched.h>
26 
27 static inline unsigned long
__copy_to_user(void * to,const void * from,unsigned long len)28 __copy_to_user(void *to, const void *from, unsigned long len)
29 {
30 	if (copyout(from, to, len))
31 		return len;
32 	return 0;
33 }
34 
35 static inline unsigned long
copy_to_user(void * to,const void * from,unsigned long len)36 copy_to_user(void *to, const void *from, unsigned long len)
37 {
38 	return __copy_to_user(to, from, len);
39 }
40 
41 static inline unsigned long
__copy_from_user(void * to,const void * from,unsigned long len)42 __copy_from_user(void *to, const void *from, unsigned long len)
43 {
44 	if (copyin(from, to, len))
45 		return len;
46 	return 0;
47 }
48 
49 static inline unsigned long
copy_from_user(void * to,const void * from,unsigned long len)50 copy_from_user(void *to, const void *from, unsigned long len)
51 {
52 	return __copy_from_user(to, from, len);
53 }
54 
55 #define get_user(x, ptr)	-copyin(ptr, &(x), sizeof(x))
56 #define put_user(x, ptr) ({				\
57 	__typeof((x)) __tmp = (x);			\
58 	-copyout(&(__tmp), ptr, sizeof(__tmp));		\
59 })
60 #define __get_user(x, ptr)	get_user((x), (ptr))
61 #define __put_user(x, ptr)	put_user((x), (ptr))
62 
63 #define unsafe_put_user(x, ptr, err) ({				\
64 	__typeof((x)) __tmp = (x);				\
65 	if (copyout(&(__tmp), ptr, sizeof(__tmp)) != 0)		\
66 		goto err;					\
67 })
68 
69 static inline int
access_ok(const void * addr,unsigned long size)70 access_ok(const void *addr, unsigned long size)
71 {
72 	vaddr_t startva = (vaddr_t)addr;
73 	vaddr_t endva = ((vaddr_t)addr) + size;
74 	return (startva >= VM_MIN_ADDRESS && endva >= VM_MIN_ADDRESS) &&
75 	    (startva <= VM_MAXUSER_ADDRESS && endva <= VM_MAXUSER_ADDRESS);
76 }
77 
78 #define user_access_begin(addr, size)	access_ok(addr, size)
79 #define user_access_end()
80 
81 #define user_write_access_begin(addr, size)	access_ok(addr, size)
82 #define user_write_access_end()
83 
84 #if defined(__i386__) || defined(__amd64__)
85 
86 static inline void
pagefault_disable(void)87 pagefault_disable(void)
88 {
89 	curcpu()->ci_inatomic++;
90 	KASSERT(curcpu()->ci_inatomic > 0);
91 }
92 
93 static inline void
pagefault_enable(void)94 pagefault_enable(void)
95 {
96 	KASSERT(curcpu()->ci_inatomic > 0);
97 	curcpu()->ci_inatomic--;
98 }
99 
100 static inline int
pagefault_disabled(void)101 pagefault_disabled(void)
102 {
103 	return curcpu()->ci_inatomic;
104 }
105 
106 static inline unsigned long
__copy_to_user_inatomic(void * to,const void * from,unsigned long len)107 __copy_to_user_inatomic(void *to, const void *from, unsigned long len)
108 {
109 	struct cpu_info *ci = curcpu();
110 	int inatomic = ci->ci_inatomic;
111 	int error;
112 
113 	ci->ci_inatomic = 1;
114 	error = copyout(from, to, len);
115 	ci->ci_inatomic = inatomic;
116 
117 	return (error ? len : 0);
118 }
119 
120 static inline unsigned long
__copy_from_user_inatomic(void * to,const void * from,unsigned long len)121 __copy_from_user_inatomic(void *to, const void *from, unsigned long len)
122 {
123 	struct cpu_info *ci = curcpu();
124 	int inatomic = ci->ci_inatomic;
125 	int error;
126 
127 	ci->ci_inatomic = 1;
128 	error = copyin(from, to, len);
129 	ci->ci_inatomic = inatomic;
130 
131 	return (error ? len : 0);
132 }
133 
134 static inline unsigned long
__copy_from_user_inatomic_nocache(void * to,const void * from,unsigned long len)135 __copy_from_user_inatomic_nocache(void *to, const void *from, unsigned long len)
136 {
137 	return __copy_from_user_inatomic(to, from, len);
138 }
139 
140 #endif /* defined(__i386__) || defined(__amd64__) */
141 
142 #endif
143