1c33fa9f5SIngo Molnar /* 2c33fa9f5SIngo Molnar * Access kernel memory without faulting. 3c33fa9f5SIngo Molnar */ 4c33fa9f5SIngo Molnar #include <linux/uaccess.h> 5c33fa9f5SIngo Molnar #include <linux/module.h> 6c33fa9f5SIngo Molnar #include <linux/mm.h> 7c33fa9f5SIngo Molnar 8c33fa9f5SIngo Molnar /** 9c33fa9f5SIngo Molnar * probe_kernel_read(): safely attempt to read from a location 10c33fa9f5SIngo Molnar * @dst: pointer to the buffer that shall take the data 11c33fa9f5SIngo Molnar * @src: address to read from 12c33fa9f5SIngo Molnar * @size: size of the data chunk 13c33fa9f5SIngo Molnar * 14c33fa9f5SIngo Molnar * Safely read from address @src to the buffer at @dst. If a kernel fault 15c33fa9f5SIngo Molnar * happens, handle that and return -EFAULT. 16c33fa9f5SIngo Molnar */ 176144a85aSJason Wessel 186144a85aSJason Wessel long __weak probe_kernel_read(void *dst, void *src, size_t size) 196144a85aSJason Wessel __attribute__((alias("__probe_kernel_read"))); 206144a85aSJason Wessel 216144a85aSJason Wessel long __probe_kernel_read(void *dst, void *src, size_t size) 22c33fa9f5SIngo Molnar { 23c33fa9f5SIngo Molnar long ret; 24b4b8ac52SJason Wessel mm_segment_t old_fs = get_fs(); 25c33fa9f5SIngo Molnar 26b4b8ac52SJason Wessel set_fs(KERNEL_DS); 27c33fa9f5SIngo Molnar pagefault_disable(); 28c33fa9f5SIngo Molnar ret = __copy_from_user_inatomic(dst, 29c33fa9f5SIngo Molnar (__force const void __user *)src, size); 30c33fa9f5SIngo Molnar pagefault_enable(); 31b4b8ac52SJason Wessel set_fs(old_fs); 32c33fa9f5SIngo Molnar 33c33fa9f5SIngo Molnar return ret ? -EFAULT : 0; 34c33fa9f5SIngo Molnar } 35c33fa9f5SIngo Molnar EXPORT_SYMBOL_GPL(probe_kernel_read); 36c33fa9f5SIngo Molnar 37c33fa9f5SIngo Molnar /** 38c33fa9f5SIngo Molnar * probe_kernel_write(): safely attempt to write to a location 39c33fa9f5SIngo Molnar * @dst: address to write to 40c33fa9f5SIngo Molnar * @src: pointer to the data that shall be written 41c33fa9f5SIngo Molnar * @size: size of the data chunk 42c33fa9f5SIngo Molnar * 43c33fa9f5SIngo Molnar * Safely write to address @dst from the buffer at @src. If a kernel fault 44c33fa9f5SIngo Molnar * happens, handle that and return -EFAULT. 45c33fa9f5SIngo Molnar */ 466144a85aSJason Wessel long __weak probe_kernel_write(void *dst, void *src, size_t size) 476144a85aSJason Wessel __attribute__((alias("__probe_kernel_write"))); 486144a85aSJason Wessel 496144a85aSJason Wessel long __probe_kernel_write(void *dst, void *src, size_t size) 50c33fa9f5SIngo Molnar { 51c33fa9f5SIngo Molnar long ret; 52b4b8ac52SJason Wessel mm_segment_t old_fs = get_fs(); 53c33fa9f5SIngo Molnar 54b4b8ac52SJason Wessel set_fs(KERNEL_DS); 55c33fa9f5SIngo Molnar pagefault_disable(); 56c33fa9f5SIngo Molnar ret = __copy_to_user_inatomic((__force void __user *)dst, src, size); 57c33fa9f5SIngo Molnar pagefault_enable(); 58b4b8ac52SJason Wessel set_fs(old_fs); 59c33fa9f5SIngo Molnar 60c33fa9f5SIngo Molnar return ret ? -EFAULT : 0; 61c33fa9f5SIngo Molnar } 62c33fa9f5SIngo Molnar EXPORT_SYMBOL_GPL(probe_kernel_write); 63