linux/arch/x86/lib/usercopy.c
<<
>>
Prefs
   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 */
  16unsigned long
  17copy_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}
  49EXPORT_SYMBOL_GPL(copy_from_user_nmi);
  50