1 /* $OpenBSD: uaccess.h,v 1.5 2020/12/20 03:42:01 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 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 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 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 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 #if defined(__i386__) || defined(__amd64__) 82 83 static inline void 84 pagefault_disable(void) 85 { 86 curcpu()->ci_inatomic++; 87 KASSERT(curcpu()->ci_inatomic > 0); 88 } 89 90 static inline void 91 pagefault_enable(void) 92 { 93 KASSERT(curcpu()->ci_inatomic > 0); 94 curcpu()->ci_inatomic--; 95 } 96 97 static inline int 98 pagefault_disabled(void) 99 { 100 return curcpu()->ci_inatomic; 101 } 102 103 static inline unsigned long 104 __copy_to_user_inatomic(void *to, const void *from, unsigned len) 105 { 106 struct cpu_info *ci = curcpu(); 107 int inatomic = ci->ci_inatomic; 108 int error; 109 110 ci->ci_inatomic = 1; 111 error = copyout(from, to, len); 112 ci->ci_inatomic = inatomic; 113 114 return (error ? len : 0); 115 } 116 117 static inline unsigned long 118 __copy_from_user_inatomic(void *to, const void *from, unsigned len) 119 { 120 struct cpu_info *ci = curcpu(); 121 int inatomic = ci->ci_inatomic; 122 int error; 123 124 ci->ci_inatomic = 1; 125 error = copyin(from, to, len); 126 ci->ci_inatomic = inatomic; 127 128 return (error ? len : 0); 129 } 130 131 static inline unsigned long 132 __copy_from_user_inatomic_nocache(void *to, const void *from, unsigned len) 133 { 134 return __copy_from_user_inatomic(to, from, len); 135 } 136 137 #endif /* defined(__i386__) || defined(__amd64__) */ 138 139 #endif 140