ソースを参照

waterDataFluctuationCorrelation rtuDataOperationAnalysis.h 朱涛 commit at 2020-10-26

朱涛 4 年 前
コミット
afee7b767f

+ 144 - 0
waterDataFluctuationCorrelation/fluctuationCorrelationOfSprayEnd/rtuDataOperationAnalysis.h

@@ -195,3 +195,147 @@ extern u64 __ua_limit;
  * data types like structures or arrays.
  *
  * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+#define __get_user(x,ptr) \
+	__get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) (*(struct __large_struct __user *)(x))
+
+/*
+ * Yuck.  We need two variants, one for 64bit operation and one
+ * for 32 bit mode and old iron.
+ */
+#ifdef CONFIG_32BIT
+#define __GET_USER_DW(val, ptr) __get_user_asm_ll32(val, ptr)
+#endif
+#ifdef CONFIG_64BIT
+#define __GET_USER_DW(val, ptr) __get_user_asm(val, "ld", ptr)
+#endif
+
+extern void __get_user_unknown(void);
+
+#define __get_user_common(val, size, ptr)				\
+do {									\
+	switch (size) {							\
+	case 1: __get_user_asm(val, "lb", ptr); break;			\
+	case 2: __get_user_asm(val, "lh", ptr); break;			\
+	case 4: __get_user_asm(val, "lw", ptr); break;			\
+	case 8: __GET_USER_DW(val, ptr); break;				\
+	default: __get_user_unknown(); break;				\
+	}								\
+} while (0)
+
+#define __get_user_nocheck(x, ptr, size)				\
+({									\
+	int __gu_err;							\
+									\
+	__chk_user_ptr(ptr);						\
+	__get_user_common((x), size, ptr);				\
+	__gu_err;							\
+})
+
+#define __get_user_check(x, ptr, size)					\
+({									\
+	int __gu_err = -EFAULT;						\
+	const __typeof__(*(ptr)) __user * __gu_ptr = (ptr);		\
+									\
+	might_fault();							\
+	if (likely(access_ok(VERIFY_READ,  __gu_ptr, size)))		\
+		__get_user_common((x), size, __gu_ptr);			\
+									\
+	__gu_err;							\
+})
+
+#define __get_user_asm(val, insn, addr)					\
+{									\
+	long __gu_tmp;							\
+									\
+	__asm__ __volatile__(						\
+	"1:	" insn "	%1, %3				\n"	\
+	"2:							\n"	\
+	"	.section .fixup,\"ax\"				\n"	\
+	"3:	li	%0, %4					\n"	\
+	"	j	2b					\n"	\
+	"	.previous					\n"	\
+	"	.section __ex_table,\"a\"			\n"	\
+	"	"__UA_ADDR "\t1b, 3b				\n"	\
+	"	.previous					\n"	\
+	: "=r" (__gu_err), "=r" (__gu_tmp)				\
+	: "0" (0), "o" (__m(addr)), "i" (-EFAULT));			\
+									\
+	(val) = (__typeof__(*(addr))) __gu_tmp;				\
+}
+
+/*
+ * Get a long long 64 using 32 bit registers.
+ */
+#define __get_user_asm_ll32(val, addr)					\
+{									\
+	union {								\
+		unsigned long long	l;				\
+		__typeof__(*(addr))	t;				\
+	} __gu_tmp;							\
+									\
+	__asm__ __volatile__(						\
+	"1:	lw	%1, (%3)				\n"	\
+	"2:	lw	%D1, 4(%3)				\n"	\
+	"3:	.section	.fixup,\"ax\"			\n"	\
+	"4:	li	%0, %4					\n"	\
+	"	move	%1, $0					\n"	\
+	"	move	%D1, $0					\n"	\
+	"	j	3b					\n"	\
+	"	.previous					\n"	\
+	"	.section	__ex_table,\"a\"		\n"	\
+	"	" __UA_ADDR "	1b, 4b				\n"	\
+	"	" __UA_ADDR "	2b, 4b				\n"	\
+	"	.previous					\n"	\
+	: "=r" (__gu_err), "=&r" (__gu_tmp.l)				\
+	: "0" (0), "r" (addr), "i" (-EFAULT));				\
+									\
+	(val) = __gu_tmp.t;						\
+}
+
+/*
+ * Yuck.  We need two variants, one for 64bit operation and one
+ * for 32 bit mode and old iron.
+ */
+#ifdef CONFIG_32BIT
+#define __PUT_USER_DW(ptr) __put_user_asm_ll32(ptr)
+#endif
+#ifdef CONFIG_64BIT
+#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
+#endif
+
+#define __put_user_nocheck(x, ptr, size)				\
+({									\
+	__typeof__(*(ptr)) __pu_val;					\
+	int __pu_err = 0;						\
+									\
+	__chk_user_ptr(ptr);						\
+	__pu_val = (x);							\
+	switch (size) {							\
+	case 1: __put_user_asm("sb", ptr); break;			\
+	case 2: __put_user_asm("sh", ptr); break;			\
+	case 4: __put_user_asm("sw", ptr); break;			\
+	case 8: __PUT_USER_DW(ptr); break;				\
+	default: __put_user_unknown(); break;				\
+	}								\
+	__pu_err;							\
+})
+
+#define __put_user_check(x, ptr, size)					\
+({									\
+	__typeof__(*(ptr)) __user *__pu_addr = (ptr);			\
+	__typeof__(*(ptr)) __pu_val = (x);				\
+	int __pu_err = -EFAULT;						\
+									\
+	might_fault();							\
+	if (likely(access_ok(VERIFY_WRITE,  __pu_addr, size))) {	\