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