Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
usercopy.c
Go to the documentation of this file.
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 }