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 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 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 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 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 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 87 pagefault_disable(void) 88 { 89 curcpu()->ci_inatomic++; 90 KASSERT(curcpu()->ci_inatomic > 0); 91 } 92 93 static inline void 94 pagefault_enable(void) 95 { 96 KASSERT(curcpu()->ci_inatomic > 0); 97 curcpu()->ci_inatomic--; 98 } 99 100 static inline int 101 pagefault_disabled(void) 102 { 103 return curcpu()->ci_inatomic; 104 } 105 106 static inline unsigned long 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 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 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