1 /* 2 * User address space access functions. 3 * 4 * For licencing details see kernel-base/COPYING 5 */ 6 7 #include <linux/highmem.h> 8 #include <linux/module.h> 9 10 #include <asm/word-at-a-time.h> 11 #include <linux/sched.h> 12 13 /* 14 * best effort, GUP based copy_from_user() that is NMI-safe 15 */ 16 unsigned long 17 copy_from_user_nmi(void *to, const void __user *from, unsigned long n) 18 { 19 unsigned long offset, addr = (unsigned long)from; 20 unsigned long size, len = 0; 21 struct page *page; 22 void *map; 23 int ret; 24 25 if (__range_not_ok(from, n, TASK_SIZE)) 26 return len; 27 28 do { 29 ret = __get_user_pages_fast(addr, 1, 0, &page); 30 if (!ret) 31 break; 32 33 offset = addr & (PAGE_SIZE - 1); 34 size = min(PAGE_SIZE - offset, n - len); 35 36 map = kmap_atomic(page); 37 memcpy(to, map+offset, size); 38 kunmap_atomic(map); 39 put_page(page); 40 41 len += size; 42 to += size; 43 addr += size; 44 45 } while (len < n); 46 47 return len; 48 } 49 EXPORT_SYMBOL_GPL(copy_from_user_nmi); 50