Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * User address space access functions.
0003  *
0004  *  For licencing details see kernel-base/COPYING
0005  */
0006 
0007 #include <linux/uaccess.h>
0008 #include <linux/export.h>
0009 
0010 #include <asm/tlbflush.h>
0011 
0012 /**
0013  * copy_from_user_nmi - NMI safe copy from user
0014  * @to:     Pointer to the destination buffer
0015  * @from:   Pointer to a user space address of the current task
0016  * @n:      Number of bytes to copy
0017  *
0018  * Returns: The number of not copied bytes. 0 is success, i.e. all bytes copied
0019  *
0020  * Contrary to other copy_from_user() variants this function can be called
0021  * from NMI context. Despite the name it is not restricted to be called
0022  * from NMI context. It is safe to be called from any other context as
0023  * well. It disables pagefaults across the copy which means a fault will
0024  * abort the copy.
0025  *
0026  * For NMI context invocations this relies on the nested NMI work to allow
0027  * atomic faults from the NMI path; the nested NMI paths are careful to
0028  * preserve CR2.
0029  */
0030 unsigned long
0031 copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
0032 {
0033     unsigned long ret;
0034 
0035     if (!__access_ok(from, n))
0036         return n;
0037 
0038     if (!nmi_uaccess_okay())
0039         return n;
0040 
0041     /*
0042      * Even though this function is typically called from NMI/IRQ context
0043      * disable pagefaults so that its behaviour is consistent even when
0044      * called from other contexts.
0045      */
0046     pagefault_disable();
0047     ret = raw_copy_from_user(to, from, n);
0048     pagefault_enable();
0049 
0050     return ret;
0051 }
0052 EXPORT_SYMBOL_GPL(copy_from_user_nmi);