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 /* 11 * best effort, GUP based copy_from_user() that is NMI-safe 12 */ 13 unsigned long 14 copy_from_user_nmi(void *to, const void __user *from, unsigned long n) 15 { 16 unsigned long offset, addr = (unsigned long)from; 17 unsigned long size, len = 0; 18 struct page *page; 19 void *map; 20 int ret; 21 22 do { 23 ret = __get_user_pages_fast(addr, 1, 0, &page); 24 if (!ret) 25 break; 26 27 offset = addr & (PAGE_SIZE - 1); 28 size = min(PAGE_SIZE - offset, n - len); 29 30 map = kmap_atomic(page); 31 memcpy(to, map+offset, size); 32 kunmap_atomic(map); 33 put_page(page); 34 35 len += size; 36 to += size; 37 addr += size; 38 39 } while (len < n); 40 41 return len; 42 } 43 EXPORT_SYMBOL_GPL(copy_from_user_nmi); 44