usercopy.c 815 B

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