usb: dwc3: rockchip: fix possible circular deadlock
[firefly-linux-kernel-4.4.55.git] / mm / maccess.c
index 34fe24759ed1f32cb58cd38d2245ae7b82dc7f37..78f9274dd49d06f11f87beae9520a0e1267dc3ff 100644 (file)
  *
  * Safely read from address @src to the buffer at @dst.  If a kernel fault
  * happens, handle that and return -EFAULT.
+ *
+ * We ensure that the copy_from_user is executed in atomic context so that
+ * do_page_fault() doesn't attempt to take mmap_sem.  This makes
+ * probe_kernel_read() suitable for use within regions where the caller
+ * already holds mmap_sem, or other locks which nest inside mmap_sem.
  */
 
 long __weak probe_kernel_read(void *dst, const void *src, size_t size)
@@ -91,13 +96,12 @@ long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count)
        pagefault_disable();
 
        do {
-               ret = __copy_from_user_inatomic(dst++,
-                                               (const void __user __force *)src++, 1);
+               ret = __get_user(*dst++, (const char __user __force *)src++);
        } while (dst[-1] && ret == 0 && src - unsafe_addr < count);
 
        dst[-1] = '\0';
        pagefault_enable();
        set_fs(old_fs);
 
-       return ret < 0 ? ret : src - unsafe_addr;
+       return ret ? -EFAULT : src - unsafe_addr;
 }