|
@@ -512,3 +512,182 @@ do { \
|
|
|
".section .fixup,\"ax\"\n" \
|
|
|
" .balign 4\n" \
|
|
|
"5: addi %3, #1\n" \
|
|
|
+ " addi %1, #-4\n" \
|
|
|
+ " .fillinsn\n" \
|
|
|
+ "6: slli %3, #2\n" \
|
|
|
+ " add %2, %3\n" \
|
|
|
+ " addi %0, #4\n" \
|
|
|
+ " .fillinsn\n" \
|
|
|
+ "7: ldi r14, #0 ; store zero \n" \
|
|
|
+ " .fillinsn\n" \
|
|
|
+ "8: addi %2, #-1\n" \
|
|
|
+ " stb r14, @%0 ; ACE? \n" \
|
|
|
+ " addi %0, #1\n" \
|
|
|
+ " bnez %2, 8b\n" \
|
|
|
+ " seth r14, #high(9b)\n" \
|
|
|
+ " or3 r14, r14, #low(9b)\n" \
|
|
|
+ " jmp r14\n" \
|
|
|
+ ".previous\n" \
|
|
|
+ ".section __ex_table,\"a\"\n" \
|
|
|
+ " .balign 4\n" \
|
|
|
+ " .long 0b,6b\n" \
|
|
|
+ " .long 1b,5b\n" \
|
|
|
+ " .long 2b,7b\n" \
|
|
|
+ " .long 3b,7b\n" \
|
|
|
+ ".previous\n" \
|
|
|
+ : "=&r" (__dst), "=&r" (__src), "=&r" (size), \
|
|
|
+ "=&r" (__c) \
|
|
|
+ : "0" (to), "1" (from), "2" (size), "3" (size / 4) \
|
|
|
+ : "r14", "memory"); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+
|
|
|
+/* We let the __ versions of copy_from/to_user inline, because they're often
|
|
|
+ * used in fast paths and have only a small space overhead.
|
|
|
+ */
|
|
|
+static inline unsigned long __generic_copy_from_user_nocheck(void *to,
|
|
|
+ const void __user *from, unsigned long n)
|
|
|
+{
|
|
|
+ __copy_user_zeroing(to,from,n);
|
|
|
+ return n;
|
|
|
+}
|
|
|
+
|
|
|
+static inline unsigned long __generic_copy_to_user_nocheck(void __user *to,
|
|
|
+ const void *from, unsigned long n)
|
|
|
+{
|
|
|
+ __copy_user(to,from,n);
|
|
|
+ return n;
|
|
|
+}
|
|
|
+
|
|
|
+unsigned long __generic_copy_to_user(void __user *, const void *, unsigned long);
|
|
|
+unsigned long __generic_copy_from_user(void *, const void __user *, unsigned long);
|
|
|
+
|
|
|
+/**
|
|
|
+ * __copy_to_user: - Copy a block of data into user space, with less checking.
|
|
|
+ * @to: Destination address, in user space.
|
|
|
+ * @from: Source address, in kernel space.
|
|
|
+ * @n: Number of bytes to copy.
|
|
|
+ *
|
|
|
+ * Context: User context only. This function may sleep.
|
|
|
+ *
|
|
|
+ * Copy data from kernel space to user space. Caller must check
|
|
|
+ * the specified block with access_ok() before calling this function.
|
|
|
+ *
|
|
|
+ * Returns number of bytes that could not be copied.
|
|
|
+ * On success, this will be zero.
|
|
|
+ */
|
|
|
+#define __copy_to_user(to,from,n) \
|
|
|
+ __generic_copy_to_user_nocheck((to),(from),(n))
|
|
|
+
|
|
|
+#define __copy_to_user_inatomic __copy_to_user
|
|
|
+#define __copy_from_user_inatomic __copy_from_user
|
|
|
+
|
|
|
+/**
|
|
|
+ * copy_to_user: - Copy a block of data into user space.
|
|
|
+ * @to: Destination address, in user space.
|
|
|
+ * @from: Source address, in kernel space.
|
|
|
+ * @n: Number of bytes to copy.
|
|
|
+ *
|
|
|
+ * Context: User context only. This function may sleep.
|
|
|
+ *
|
|
|
+ * Copy data from kernel space to user space.
|
|
|
+ *
|
|
|
+ * Returns number of bytes that could not be copied.
|
|
|
+ * On success, this will be zero.
|
|
|
+ */
|
|
|
+#define copy_to_user(to,from,n) \
|
|
|
+({ \
|
|
|
+ might_sleep(); \
|
|
|
+ __generic_copy_to_user((to),(from),(n)); \
|
|
|
+})
|
|
|
+
|
|
|
+/**
|
|
|
+ * __copy_from_user: - Copy a block of data from user space, with less checking. * @to: Destination address, in kernel space.
|
|
|
+ * @from: Source address, in user space.
|
|
|
+ * @n: Number of bytes to copy.
|
|
|
+ *
|
|
|
+ * Context: User context only. This function may sleep.
|
|
|
+ *
|
|
|
+ * Copy data from user space to kernel space. Caller must check
|
|
|
+ * the specified block with access_ok() before calling this function.
|
|
|
+ *
|
|
|
+ * Returns number of bytes that could not be copied.
|
|
|
+ * On success, this will be zero.
|
|
|
+ *
|
|
|
+ * If some data could not be copied, this function will pad the copied
|
|
|
+ * data to the requested size using zero bytes.
|
|
|
+ */
|
|
|
+#define __copy_from_user(to,from,n) \
|
|
|
+ __generic_copy_from_user_nocheck((to),(from),(n))
|
|
|
+
|
|
|
+/**
|
|
|
+ * copy_from_user: - Copy a block of data from user space.
|
|
|
+ * @to: Destination address, in kernel space.
|
|
|
+ * @from: Source address, in user space.
|
|
|
+ * @n: Number of bytes to copy.
|
|
|
+ *
|
|
|
+ * Context: User context only. This function may sleep.
|
|
|
+ *
|
|
|
+ * Copy data from user space to kernel space.
|
|
|
+ *
|
|
|
+ * Returns number of bytes that could not be copied.
|
|
|
+ * On success, this will be zero.
|
|
|
+ *
|
|
|
+ * If some data could not be copied, this function will pad the copied
|
|
|
+ * data to the requested size using zero bytes.
|
|
|
+ */
|
|
|
+#define copy_from_user(to,from,n) \
|
|
|
+({ \
|
|
|
+ might_sleep(); \
|
|
|
+ __generic_copy_from_user((to),(from),(n)); \
|
|
|
+})
|
|
|
+
|
|
|
+long __must_check strncpy_from_user(char *dst, const char __user *src,
|
|
|
+ long count);
|
|
|
+long __must_check __strncpy_from_user(char *dst,
|
|
|
+ const char __user *src, long count);
|
|
|
+
|
|
|
+/**
|
|
|
+ * __clear_user: - Zero a block of memory in user space, with less checking.
|
|
|
+ * @to: Destination address, in user space.
|
|
|
+ * @n: Number of bytes to zero.
|
|
|
+ *
|
|
|
+ * Zero a block of memory in user space. Caller must check
|
|
|
+ * the specified block with access_ok() before calling this function.
|
|
|
+ *
|
|
|
+ * Returns number of bytes that could not be cleared.
|
|
|
+ * On success, this will be zero.
|
|
|
+ */
|
|
|
+unsigned long __clear_user(void __user *mem, unsigned long len);
|
|
|
+
|
|
|
+/**
|
|
|
+ * clear_user: - Zero a block of memory in user space.
|
|
|
+ * @to: Destination address, in user space.
|
|
|
+ * @n: Number of bytes to zero.
|
|
|
+ *
|
|
|
+ * Zero a block of memory in user space. Caller must check
|
|
|
+ * the specified block with access_ok() before calling this function.
|
|
|
+ *
|
|
|
+ * Returns number of bytes that could not be cleared.
|
|
|
+ * On success, this will be zero.
|
|
|
+ */
|
|
|
+unsigned long clear_user(void __user *mem, unsigned long len);
|
|
|
+
|
|
|
+/**
|
|
|
+ * strlen_user: - Get the size of a string in user space.
|
|
|
+ * @str: The string to measure.
|
|
|
+ *
|
|
|
+ * Context: User context only. This function may sleep.
|
|
|
+ *
|
|
|
+ * Get the size of a NUL-terminated string in user space.
|
|
|
+ *
|
|
|
+ * Returns the size of the string INCLUDING the terminating NUL.
|
|
|
+ * On exception, returns 0.
|
|
|
+ *
|
|
|
+ * If there is a limit on the length of a valid string, you may wish to
|
|
|
+ * consider using strnlen_user() instead.
|
|
|
+ */
|
|
|
+#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
|
|
|
+long strnlen_user(const char __user *str, long n);
|
|
|
+
|
|
|
+#endif /* _ASM_M32R_UACCESS_H */
|