2022-08-12 09:19:07

by Tong Tiangen

[permalink] [raw]
Subject: [PATCH -next] riscv: extable: add new extable type EX_TYPE_KACCESS_ERR_ZERO support

Currently, The extable type EX_TYPE_UACCESS_ERR_ZERO is used by
__get/put_kernel_nofault(), but those helpers are not uaccess type, so we
add a new extable type EX_TYPE_KACCESS_ERR_ZERO which can be used by
__get/put_kernel_no_fault().

Also change the name of __get/put_user_nocheck to __get/put_mem_nocheck
to make it conform to its use situation (not only used in uaccess).

Signed-off-by: Tong Tiangen <[email protected]>
---
arch/riscv/include/asm/asm-extable.h | 12 ++
arch/riscv/include/asm/uaccess.h | 160 +++++++++++++--------------
2 files changed, 92 insertions(+), 80 deletions(-)

diff --git a/arch/riscv/include/asm/asm-extable.h b/arch/riscv/include/asm/asm-extable.h
index 14be0673f5b5..73c70098a9c8 100644
--- a/arch/riscv/include/asm/asm-extable.h
+++ b/arch/riscv/include/asm/asm-extable.h
@@ -6,6 +6,7 @@
#define EX_TYPE_FIXUP 1
#define EX_TYPE_BPF 2
#define EX_TYPE_UACCESS_ERR_ZERO 3
+#define EX_TYPE_KACCESS_ERR_ZERO 4

#ifdef __ASSEMBLY__

@@ -57,9 +58,20 @@
EX_DATA_REG(ZERO, zero) \
")")

+#define _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, zero) \
+ __DEFINE_ASM_GPR_NUMS \
+ __ASM_EXTABLE_RAW(#insn, #fixup, \
+ __stringify(EX_TYPE_KACCESS_ERR_ZERO), \
+ "(" \
+ EX_DATA_REG(ERR, err) " | " \
+ EX_DATA_REG(ZERO, zero) \
+ ")")
+
#define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err) \
_ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)

+#define _ASM_EXTABLE_KACCESS_ERR(insn, fixup, err) \
+ _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, zero)
#endif /* __ASSEMBLY__ */

#endif /* __ASM_ASM_EXTABLE_H */
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index 855450bed9f5..5372f3f1e3f6 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -50,62 +50,62 @@
* call.
*/

-#define __get_user_asm(insn, x, ptr, err) \
-do { \
- __typeof__(x) __x; \
- __asm__ __volatile__ ( \
- "1:\n" \
- " " insn " %1, %2\n" \
- "2:\n" \
- _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1) \
- : "+r" (err), "=&r" (__x) \
- : "m" (*(ptr))); \
- (x) = __x; \
+#define __get_mem_asm(insn, x, ptr, err, type) \
+do { \
+ __typeof__(x) __x; \
+ __asm__ __volatile__ ( \
+ "1:\n" \
+ " " insn " %1, %2\n" \
+ "2:\n" \
+ _ASM_EXTABLE_##type##ACCESS_ERR_ZERO(1b, 2b, %0, %1) \
+ : "+r" (err), "=&r" (__x) \
+ : "m" (*(ptr))); \
+ (x) = __x; \
} while (0)

#ifdef CONFIG_64BIT
-#define __get_user_8(x, ptr, err) \
- __get_user_asm("ld", x, ptr, err)
+#define __get_mem_8(x, ptr, err, type) \
+ __get_mem_asm("ld", x, ptr, err, type)
#else /* !CONFIG_64BIT */
-#define __get_user_8(x, ptr, err) \
-do { \
- u32 __user *__ptr = (u32 __user *)(ptr); \
- u32 __lo, __hi; \
- __asm__ __volatile__ ( \
- "1:\n" \
- " lw %1, %3\n" \
- "2:\n" \
- " lw %2, %4\n" \
- "3:\n" \
- _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 3b, %0, %1) \
- _ASM_EXTABLE_UACCESS_ERR_ZERO(2b, 3b, %0, %1) \
- : "+r" (err), "=&r" (__lo), "=r" (__hi) \
- : "m" (__ptr[__LSW]), "m" (__ptr[__MSW])); \
- if (err) \
- __hi = 0; \
- (x) = (__typeof__(x))((__typeof__((x)-(x)))( \
- (((u64)__hi << 32) | __lo))); \
+#define __get_mem_8(x, ptr, err, type) \
+do { \
+ u32 __user *__ptr = (u32 __user *)(ptr); \
+ u32 __lo, __hi; \
+ __asm__ __volatile__ ( \
+ "1:\n" \
+ " lw %1, %3\n" \
+ "2:\n" \
+ " lw %2, %4\n" \
+ "3:\n" \
+ _ASM_EXTABLE_##type##ACCESS_ERR_ZERO(1b, 3b, %0, %1) \
+ _ASM_EXTABLE_##type##ACCESS_ERR_ZERO(2b, 3b, %0, %1) \
+ : "+r" (err), "=&r" (__lo), "=r" (__hi) \
+ : "m" (__ptr[__LSW]), "m" (__ptr[__MSW])); \
+ if (err) \
+ __hi = 0; \
+ (x) = (__typeof__(x))((__typeof__((x)-(x)))( \
+ (((u64)__hi << 32) | __lo))); \
} while (0)
#endif /* CONFIG_64BIT */

-#define __get_user_nocheck(x, __gu_ptr, __gu_err) \
-do { \
- switch (sizeof(*__gu_ptr)) { \
- case 1: \
- __get_user_asm("lb", (x), __gu_ptr, __gu_err); \
- break; \
- case 2: \
- __get_user_asm("lh", (x), __gu_ptr, __gu_err); \
- break; \
- case 4: \
- __get_user_asm("lw", (x), __gu_ptr, __gu_err); \
- break; \
- case 8: \
- __get_user_8((x), __gu_ptr, __gu_err); \
- break; \
- default: \
- BUILD_BUG(); \
- } \
+#define __get_mem_nocheck(x, __gu_ptr, __gu_err, type) \
+do { \
+ switch (sizeof(*__gu_ptr)) { \
+ case 1: \
+ __get_mem_asm("lb", (x), __gu_ptr, __gu_err, type); \
+ break; \
+ case 2: \
+ __get_mem_asm("lh", (x), __gu_ptr, __gu_err, type); \
+ break; \
+ case 4: \
+ __get_mem_asm("lw", (x), __gu_ptr, __gu_err, type); \
+ break; \
+ case 8: \
+ __get_mem_8((x), __gu_ptr, __gu_err, type); \
+ break; \
+ default: \
+ BUILD_BUG(); \
+ } \
} while (0)

/**
@@ -136,7 +136,7 @@ do { \
__chk_user_ptr(__gu_ptr); \
\
__enable_user_access(); \
- __get_user_nocheck(x, __gu_ptr, __gu_err); \
+ __get_mem_nocheck(x, __gu_ptr, __gu_err, U); \
__disable_user_access(); \
\
__gu_err; \
@@ -163,28 +163,28 @@ do { \
({ \
const __typeof__(*(ptr)) __user *__p = (ptr); \
might_fault(); \
- access_ok(__p, sizeof(*__p)) ? \
+ access_ok(__p, sizeof(*__p)) ? \
__get_user((x), __p) : \
((x) = 0, -EFAULT); \
})

-#define __put_user_asm(insn, x, ptr, err) \
+#define __put_mem_asm(insn, x, ptr, err, type) \
do { \
__typeof__(*(ptr)) __x = x; \
__asm__ __volatile__ ( \
"1:\n" \
" " insn " %z2, %1\n" \
"2:\n" \
- _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0) \
+ _ASM_EXTABLE_##type##ACCESS_ERR(1b, 2b, %0) \
: "+r" (err), "=m" (*(ptr)) \
: "rJ" (__x)); \
} while (0)

#ifdef CONFIG_64BIT
-#define __put_user_8(x, ptr, err) \
- __put_user_asm("sd", x, ptr, err)
+#define __put_mem_8(x, ptr, err, type) \
+ __put_mem_asm("sd", x, ptr, err, type)
#else /* !CONFIG_64BIT */
-#define __put_user_8(x, ptr, err) \
+#define __put_mem_8(x, ptr, err, type) \
do { \
u32 __user *__ptr = (u32 __user *)(ptr); \
u64 __x = (__typeof__((x)-(x)))(x); \
@@ -194,8 +194,8 @@ do { \
"2:\n" \
" sw %z4, %2\n" \
"3:\n" \
- _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0) \
- _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0) \
+ _ASM_EXTABLE_##type##ACCESS_ERR(1b, 3b, %0) \
+ _ASM_EXTABLE_##type##ACCESS_ERR(2b, 3b, %0) \
: "+r" (err), \
"=m" (__ptr[__LSW]), \
"=m" (__ptr[__MSW]) \
@@ -203,24 +203,24 @@ do { \
} while (0)
#endif /* CONFIG_64BIT */

-#define __put_user_nocheck(x, __gu_ptr, __pu_err) \
-do { \
- switch (sizeof(*__gu_ptr)) { \
- case 1: \
- __put_user_asm("sb", (x), __gu_ptr, __pu_err); \
- break; \
- case 2: \
- __put_user_asm("sh", (x), __gu_ptr, __pu_err); \
- break; \
- case 4: \
- __put_user_asm("sw", (x), __gu_ptr, __pu_err); \
- break; \
- case 8: \
- __put_user_8((x), __gu_ptr, __pu_err); \
- break; \
- default: \
- BUILD_BUG(); \
- } \
+#define __put_mem_nocheck(x, __gu_ptr, __pu_err, type) \
+do { \
+ switch (sizeof(*__gu_ptr)) { \
+ case 1: \
+ __put_mem_asm("sb", (x), __gu_ptr, __pu_err, type); \
+ break; \
+ case 2: \
+ __put_mem_asm("sh", (x), __gu_ptr, __pu_err, type); \
+ break; \
+ case 4: \
+ __put_mem_asm("sw", (x), __gu_ptr, __pu_err, type); \
+ break; \
+ case 8: \
+ __put_mem_8((x), __gu_ptr, __pu_err, type); \
+ break; \
+ default: \
+ BUILD_BUG(); \
+ } \
} while (0)

/**
@@ -253,7 +253,7 @@ do { \
__chk_user_ptr(__gu_ptr); \
\
__enable_user_access(); \
- __put_user_nocheck(__val, __gu_ptr, __pu_err); \
+ __put_mem_nocheck(__val, __gu_ptr, __pu_err, U); \
__disable_user_access(); \
\
__pu_err; \
@@ -279,7 +279,7 @@ do { \
({ \
__typeof__(*(ptr)) __user *__p = (ptr); \
might_fault(); \
- access_ok(__p, sizeof(*__p)) ? \
+ access_ok(__p, sizeof(*__p)) ? \
__put_user((x), __p) : \
-EFAULT; \
})
@@ -321,7 +321,7 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
do { \
long __kr_err; \
\
- __get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \
+ __get_mem_nocheck(*((type *)(dst)), (type *)(src), __kr_err, K);\
if (unlikely(__kr_err)) \
goto err_label; \
} while (0)
@@ -330,7 +330,7 @@ do { \
do { \
long __kr_err; \
\
- __put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err); \
+ __put_mem_nocheck(*((type *)(src)), (type *)(dst), __kr_err, K);\
if (unlikely(__kr_err)) \
goto err_label; \
} while (0)
--
2.25.1


2022-08-12 09:28:21

by Conor Dooley

[permalink] [raw]
Subject: Re: [PATCH -next] riscv: extable: add new extable type EX_TYPE_KACCESS_ERR_ZERO support

On 12/08/2022 09:52, Tong Tiangen wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> Currently, The extable type EX_TYPE_UACCESS_ERR_ZERO is used by
> __get/put_kernel_nofault(), but those helpers are not uaccess type, so we
> add a new extable type EX_TYPE_KACCESS_ERR_ZERO which can be used by
> __get/put_kernel_no_fault().
>
> Also change the name of __get/put_user_nocheck to __get/put_mem_nocheck
> to make it conform to its use situation (not only used in uaccess).

Is there a reason why this should not be a different patch?
Thanks,
Conor.

>
> Signed-off-by: Tong Tiangen <[email protected]>
> ---
> arch/riscv/include/asm/asm-extable.h | 12 ++
> arch/riscv/include/asm/uaccess.h | 160 +++++++++++++--------------
> 2 files changed, 92 insertions(+), 80 deletions(-)
>
> diff --git a/arch/riscv/include/asm/asm-extable.h b/arch/riscv/include/asm/asm-extable.h
> index 14be0673f5b5..73c70098a9c8 100644
> --- a/arch/riscv/include/asm/asm-extable.h
> +++ b/arch/riscv/include/asm/asm-extable.h
> @@ -6,6 +6,7 @@
> #define EX_TYPE_FIXUP 1
> #define EX_TYPE_BPF 2
> #define EX_TYPE_UACCESS_ERR_ZERO 3
> +#define EX_TYPE_KACCESS_ERR_ZERO 4
>
> #ifdef __ASSEMBLY__
>
> @@ -57,9 +58,20 @@
> EX_DATA_REG(ZERO, zero) \
> ")")
>
> +#define _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, zero) \
> + __DEFINE_ASM_GPR_NUMS \
> + __ASM_EXTABLE_RAW(#insn, #fixup, \
> + __stringify(EX_TYPE_KACCESS_ERR_ZERO), \
> + "(" \
> + EX_DATA_REG(ERR, err) " | " \
> + EX_DATA_REG(ZERO, zero) \
> + ")")
> +
> #define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err) \
> _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)
>
> +#define _ASM_EXTABLE_KACCESS_ERR(insn, fixup, err) \
> + _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, zero)
> #endif /* __ASSEMBLY__ */
>
> #endif /* __ASM_ASM_EXTABLE_H */
> diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
> index 855450bed9f5..5372f3f1e3f6 100644
> --- a/arch/riscv/include/asm/uaccess.h
> +++ b/arch/riscv/include/asm/uaccess.h
> @@ -50,62 +50,62 @@
> * call.
> */
>
> -#define __get_user_asm(insn, x, ptr, err) \
> -do { \
> - __typeof__(x) __x; \
> - __asm__ __volatile__ ( \
> - "1:\n" \
> - " " insn " %1, %2\n" \
> - "2:\n" \
> - _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1) \
> - : "+r" (err), "=&r" (__x) \
> - : "m" (*(ptr))); \
> - (x) = __x; \
> +#define __get_mem_asm(insn, x, ptr, err, type) \
> +do { \
> + __typeof__(x) __x; \
> + __asm__ __volatile__ ( \
> + "1:\n" \
> + " " insn " %1, %2\n" \
> + "2:\n" \
> + _ASM_EXTABLE_##type##ACCESS_ERR_ZERO(1b, 2b, %0, %1) \
> + : "+r" (err), "=&r" (__x) \
> + : "m" (*(ptr))); \
> + (x) = __x; \
> } while (0)
>
> #ifdef CONFIG_64BIT
> -#define __get_user_8(x, ptr, err) \
> - __get_user_asm("ld", x, ptr, err)
> +#define __get_mem_8(x, ptr, err, type) \
> + __get_mem_asm("ld", x, ptr, err, type)
> #else /* !CONFIG_64BIT */
> -#define __get_user_8(x, ptr, err) \
> -do { \
> - u32 __user *__ptr = (u32 __user *)(ptr); \
> - u32 __lo, __hi; \
> - __asm__ __volatile__ ( \
> - "1:\n" \
> - " lw %1, %3\n" \
> - "2:\n" \
> - " lw %2, %4\n" \
> - "3:\n" \
> - _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 3b, %0, %1) \
> - _ASM_EXTABLE_UACCESS_ERR_ZERO(2b, 3b, %0, %1) \
> - : "+r" (err), "=&r" (__lo), "=r" (__hi) \
> - : "m" (__ptr[__LSW]), "m" (__ptr[__MSW])); \
> - if (err) \
> - __hi = 0; \
> - (x) = (__typeof__(x))((__typeof__((x)-(x)))( \
> - (((u64)__hi << 32) | __lo))); \
> +#define __get_mem_8(x, ptr, err, type) \
> +do { \
> + u32 __user *__ptr = (u32 __user *)(ptr); \
> + u32 __lo, __hi; \
> + __asm__ __volatile__ ( \
> + "1:\n" \
> + " lw %1, %3\n" \
> + "2:\n" \
> + " lw %2, %4\n" \
> + "3:\n" \
> + _ASM_EXTABLE_##type##ACCESS_ERR_ZERO(1b, 3b, %0, %1) \
> + _ASM_EXTABLE_##type##ACCESS_ERR_ZERO(2b, 3b, %0, %1) \
> + : "+r" (err), "=&r" (__lo), "=r" (__hi) \
> + : "m" (__ptr[__LSW]), "m" (__ptr[__MSW])); \
> + if (err) \
> + __hi = 0; \
> + (x) = (__typeof__(x))((__typeof__((x)-(x)))( \
> + (((u64)__hi << 32) | __lo))); \
> } while (0)
> #endif /* CONFIG_64BIT */
>
> -#define __get_user_nocheck(x, __gu_ptr, __gu_err) \
> -do { \
> - switch (sizeof(*__gu_ptr)) { \
> - case 1: \
> - __get_user_asm("lb", (x), __gu_ptr, __gu_err); \
> - break; \
> - case 2: \
> - __get_user_asm("lh", (x), __gu_ptr, __gu_err); \
> - break; \
> - case 4: \
> - __get_user_asm("lw", (x), __gu_ptr, __gu_err); \
> - break; \
> - case 8: \
> - __get_user_8((x), __gu_ptr, __gu_err); \
> - break; \
> - default: \
> - BUILD_BUG(); \
> - } \
> +#define __get_mem_nocheck(x, __gu_ptr, __gu_err, type) \
> +do { \
> + switch (sizeof(*__gu_ptr)) { \
> + case 1: \
> + __get_mem_asm("lb", (x), __gu_ptr, __gu_err, type); \
> + break; \
> + case 2: \
> + __get_mem_asm("lh", (x), __gu_ptr, __gu_err, type); \
> + break; \
> + case 4: \
> + __get_mem_asm("lw", (x), __gu_ptr, __gu_err, type); \
> + break; \
> + case 8: \
> + __get_mem_8((x), __gu_ptr, __gu_err, type); \
> + break; \
> + default: \
> + BUILD_BUG(); \
> + } \
> } while (0)
>
> /**
> @@ -136,7 +136,7 @@ do { \
> __chk_user_ptr(__gu_ptr); \
> \
> __enable_user_access(); \
> - __get_user_nocheck(x, __gu_ptr, __gu_err); \
> + __get_mem_nocheck(x, __gu_ptr, __gu_err, U); \
> __disable_user_access(); \
> \
> __gu_err; \
> @@ -163,28 +163,28 @@ do { \
> ({ \
> const __typeof__(*(ptr)) __user *__p = (ptr); \
> might_fault(); \
> - access_ok(__p, sizeof(*__p)) ? \
> + access_ok(__p, sizeof(*__p)) ? \
> __get_user((x), __p) : \
> ((x) = 0, -EFAULT); \
> })
>
> -#define __put_user_asm(insn, x, ptr, err) \
> +#define __put_mem_asm(insn, x, ptr, err, type) \
> do { \
> __typeof__(*(ptr)) __x = x; \
> __asm__ __volatile__ ( \
> "1:\n" \
> " " insn " %z2, %1\n" \
> "2:\n" \
> - _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0) \
> + _ASM_EXTABLE_##type##ACCESS_ERR(1b, 2b, %0) \
> : "+r" (err), "=m" (*(ptr)) \
> : "rJ" (__x)); \
> } while (0)
>
> #ifdef CONFIG_64BIT
> -#define __put_user_8(x, ptr, err) \
> - __put_user_asm("sd", x, ptr, err)
> +#define __put_mem_8(x, ptr, err, type) \
> + __put_mem_asm("sd", x, ptr, err, type)
> #else /* !CONFIG_64BIT */
> -#define __put_user_8(x, ptr, err) \
> +#define __put_mem_8(x, ptr, err, type) \
> do { \
> u32 __user *__ptr = (u32 __user *)(ptr); \
> u64 __x = (__typeof__((x)-(x)))(x); \
> @@ -194,8 +194,8 @@ do { \
> "2:\n" \
> " sw %z4, %2\n" \
> "3:\n" \
> - _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0) \
> - _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0) \
> + _ASM_EXTABLE_##type##ACCESS_ERR(1b, 3b, %0) \
> + _ASM_EXTABLE_##type##ACCESS_ERR(2b, 3b, %0) \
> : "+r" (err), \
> "=m" (__ptr[__LSW]), \
> "=m" (__ptr[__MSW]) \
> @@ -203,24 +203,24 @@ do { \
> } while (0)
> #endif /* CONFIG_64BIT */
>
> -#define __put_user_nocheck(x, __gu_ptr, __pu_err) \
> -do { \
> - switch (sizeof(*__gu_ptr)) { \
> - case 1: \
> - __put_user_asm("sb", (x), __gu_ptr, __pu_err); \
> - break; \
> - case 2: \
> - __put_user_asm("sh", (x), __gu_ptr, __pu_err); \
> - break; \
> - case 4: \
> - __put_user_asm("sw", (x), __gu_ptr, __pu_err); \
> - break; \
> - case 8: \
> - __put_user_8((x), __gu_ptr, __pu_err); \
> - break; \
> - default: \
> - BUILD_BUG(); \
> - } \
> +#define __put_mem_nocheck(x, __gu_ptr, __pu_err, type) \
> +do { \
> + switch (sizeof(*__gu_ptr)) { \
> + case 1: \
> + __put_mem_asm("sb", (x), __gu_ptr, __pu_err, type); \
> + break; \
> + case 2: \
> + __put_mem_asm("sh", (x), __gu_ptr, __pu_err, type); \
> + break; \
> + case 4: \
> + __put_mem_asm("sw", (x), __gu_ptr, __pu_err, type); \
> + break; \
> + case 8: \
> + __put_mem_8((x), __gu_ptr, __pu_err, type); \
> + break; \
> + default: \
> + BUILD_BUG(); \
> + } \
> } while (0)
>
> /**
> @@ -253,7 +253,7 @@ do { \
> __chk_user_ptr(__gu_ptr); \
> \
> __enable_user_access(); \
> - __put_user_nocheck(__val, __gu_ptr, __pu_err); \
> + __put_mem_nocheck(__val, __gu_ptr, __pu_err, U); \
> __disable_user_access(); \
> \
> __pu_err; \
> @@ -279,7 +279,7 @@ do { \
> ({ \
> __typeof__(*(ptr)) __user *__p = (ptr); \
> might_fault(); \
> - access_ok(__p, sizeof(*__p)) ? \
> + access_ok(__p, sizeof(*__p)) ? \
> __put_user((x), __p) : \
> -EFAULT; \
> })
> @@ -321,7 +321,7 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
> do { \
> long __kr_err; \
> \
> - __get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \
> + __get_mem_nocheck(*((type *)(dst)), (type *)(src), __kr_err, K);\
> if (unlikely(__kr_err)) \
> goto err_label; \
> } while (0)
> @@ -330,7 +330,7 @@ do { \
> do { \
> long __kr_err; \
> \
> - __put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err); \
> + __put_mem_nocheck(*((type *)(src)), (type *)(dst), __kr_err, K);\
> if (unlikely(__kr_err)) \
> goto err_label; \
> } while (0)
> --
> 2.25.1
>
>
> _______________________________________________
> linux-riscv mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-riscv

2022-08-12 10:55:09

by Tong Tiangen

[permalink] [raw]
Subject: Re: [PATCH -next] riscv: extable: add new extable type EX_TYPE_KACCESS_ERR_ZERO support



在 2022/8/12 16:58, [email protected] 写道:
> On 12/08/2022 09:52, Tong Tiangen wrote:
>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>
>> Currently, The extable type EX_TYPE_UACCESS_ERR_ZERO is used by
>> __get/put_kernel_nofault(), but those helpers are not uaccess type, so we
>> add a new extable type EX_TYPE_KACCESS_ERR_ZERO which can be used by
>> __get/put_kernel_no_fault().
>>
>> Also change the name of __get/put_user_nocheck to __get/put_mem_nocheck
>> to make it conform to its use situation (not only used in uaccess).
>
> Is there a reason why this should not be a different patch?
> Thanks,
> Conor.

Oh, my fault, this modification should be split.
Thanks,
Tong.

>
>>
>> Signed-off-by: Tong Tiangen <[email protected]>
>> ---
>> arch/riscv/include/asm/asm-extable.h | 12 ++
>> arch/riscv/include/asm/uaccess.h | 160 +++++++++++++--------------
>> 2 files changed, 92 insertions(+), 80 deletions(-)
>>
>> diff --git a/arch/riscv/include/asm/asm-extable.h b/arch/riscv/include/asm/asm-extable.h
>> index 14be0673f5b5..73c70098a9c8 100644
>> --- a/arch/riscv/include/asm/asm-extable.h
>> +++ b/arch/riscv/include/asm/asm-extable.h
>> @@ -6,6 +6,7 @@
>> #define EX_TYPE_FIXUP 1
>> #define EX_TYPE_BPF 2
>> #define EX_TYPE_UACCESS_ERR_ZERO 3
>> +#define EX_TYPE_KACCESS_ERR_ZERO 4
>>
>> #ifdef __ASSEMBLY__
>>
>> @@ -57,9 +58,20 @@
>> EX_DATA_REG(ZERO, zero) \
>> ")")
>>
>> +#define _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, zero) \
>> + __DEFINE_ASM_GPR_NUMS \
>> + __ASM_EXTABLE_RAW(#insn, #fixup, \
>> + __stringify(EX_TYPE_KACCESS_ERR_ZERO), \
>> + "(" \
>> + EX_DATA_REG(ERR, err) " | " \
>> + EX_DATA_REG(ZERO, zero) \
>> + ")")
>> +
>> #define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err) \
>> _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)
>>
>> +#define _ASM_EXTABLE_KACCESS_ERR(insn, fixup, err) \
>> + _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, zero)
>> #endif /* __ASSEMBLY__ */
>>
>> #endif /* __ASM_ASM_EXTABLE_H */
>> diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
>> index 855450bed9f5..5372f3f1e3f6 100644
>> --- a/arch/riscv/include/asm/uaccess.h
>> +++ b/arch/riscv/include/asm/uaccess.h
>> @@ -50,62 +50,62 @@
>> * call.
>> */
>>
>> -#define __get_user_asm(insn, x, ptr, err) \
>> -do { \
>> - __typeof__(x) __x; \
>> - __asm__ __volatile__ ( \
>> - "1:\n" \
>> - " " insn " %1, %2\n" \
>> - "2:\n" \
>> - _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1) \
>> - : "+r" (err), "=&r" (__x) \
>> - : "m" (*(ptr))); \
>> - (x) = __x; \
>> +#define __get_mem_asm(insn, x, ptr, err, type) \
>> +do { \
>> + __typeof__(x) __x; \
>> + __asm__ __volatile__ ( \
>> + "1:\n" \
>> + " " insn " %1, %2\n" \
>> + "2:\n" \
>> + _ASM_EXTABLE_##type##ACCESS_ERR_ZERO(1b, 2b, %0, %1) \
>> + : "+r" (err), "=&r" (__x) \
>> + : "m" (*(ptr))); \
>> + (x) = __x; \
>> } while (0)
>>
>> #ifdef CONFIG_64BIT
>> -#define __get_user_8(x, ptr, err) \
>> - __get_user_asm("ld", x, ptr, err)
>> +#define __get_mem_8(x, ptr, err, type) \
>> + __get_mem_asm("ld", x, ptr, err, type)
>> #else /* !CONFIG_64BIT */
>> -#define __get_user_8(x, ptr, err) \
>> -do { \
>> - u32 __user *__ptr = (u32 __user *)(ptr); \
>> - u32 __lo, __hi; \
>> - __asm__ __volatile__ ( \
>> - "1:\n" \
>> - " lw %1, %3\n" \
>> - "2:\n" \
>> - " lw %2, %4\n" \
>> - "3:\n" \
>> - _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 3b, %0, %1) \
>> - _ASM_EXTABLE_UACCESS_ERR_ZERO(2b, 3b, %0, %1) \
>> - : "+r" (err), "=&r" (__lo), "=r" (__hi) \
>> - : "m" (__ptr[__LSW]), "m" (__ptr[__MSW])); \
>> - if (err) \
>> - __hi = 0; \
>> - (x) = (__typeof__(x))((__typeof__((x)-(x)))( \
>> - (((u64)__hi << 32) | __lo))); \
>> +#define __get_mem_8(x, ptr, err, type) \
>> +do { \
>> + u32 __user *__ptr = (u32 __user *)(ptr); \
>> + u32 __lo, __hi; \
>> + __asm__ __volatile__ ( \
>> + "1:\n" \
>> + " lw %1, %3\n" \
>> + "2:\n" \
>> + " lw %2, %4\n" \
>> + "3:\n" \
>> + _ASM_EXTABLE_##type##ACCESS_ERR_ZERO(1b, 3b, %0, %1) \
>> + _ASM_EXTABLE_##type##ACCESS_ERR_ZERO(2b, 3b, %0, %1) \
>> + : "+r" (err), "=&r" (__lo), "=r" (__hi) \
>> + : "m" (__ptr[__LSW]), "m" (__ptr[__MSW])); \
>> + if (err) \
>> + __hi = 0; \
>> + (x) = (__typeof__(x))((__typeof__((x)-(x)))( \
>> + (((u64)__hi << 32) | __lo))); \
>> } while (0)
>> #endif /* CONFIG_64BIT */
>>
>> -#define __get_user_nocheck(x, __gu_ptr, __gu_err) \
>> -do { \
>> - switch (sizeof(*__gu_ptr)) { \
>> - case 1: \
>> - __get_user_asm("lb", (x), __gu_ptr, __gu_err); \
>> - break; \
>> - case 2: \
>> - __get_user_asm("lh", (x), __gu_ptr, __gu_err); \
>> - break; \
>> - case 4: \
>> - __get_user_asm("lw", (x), __gu_ptr, __gu_err); \
>> - break; \
>> - case 8: \
>> - __get_user_8((x), __gu_ptr, __gu_err); \
>> - break; \
>> - default: \
>> - BUILD_BUG(); \
>> - } \
>> +#define __get_mem_nocheck(x, __gu_ptr, __gu_err, type) \
>> +do { \
>> + switch (sizeof(*__gu_ptr)) { \
>> + case 1: \
>> + __get_mem_asm("lb", (x), __gu_ptr, __gu_err, type); \
>> + break; \
>> + case 2: \
>> + __get_mem_asm("lh", (x), __gu_ptr, __gu_err, type); \
>> + break; \
>> + case 4: \
>> + __get_mem_asm("lw", (x), __gu_ptr, __gu_err, type); \
>> + break; \
>> + case 8: \
>> + __get_mem_8((x), __gu_ptr, __gu_err, type); \
>> + break; \
>> + default: \
>> + BUILD_BUG(); \
>> + } \
>> } while (0)
>>
>> /**
>> @@ -136,7 +136,7 @@ do { \
>> __chk_user_ptr(__gu_ptr); \
>> \
>> __enable_user_access(); \
>> - __get_user_nocheck(x, __gu_ptr, __gu_err); \
>> + __get_mem_nocheck(x, __gu_ptr, __gu_err, U); \
>> __disable_user_access(); \
>> \
>> __gu_err; \
>> @@ -163,28 +163,28 @@ do { \
>> ({ \
>> const __typeof__(*(ptr)) __user *__p = (ptr); \
>> might_fault(); \
>> - access_ok(__p, sizeof(*__p)) ? \
>> + access_ok(__p, sizeof(*__p)) ? \
>> __get_user((x), __p) : \
>> ((x) = 0, -EFAULT); \
>> })
>>
>> -#define __put_user_asm(insn, x, ptr, err) \
>> +#define __put_mem_asm(insn, x, ptr, err, type) \
>> do { \
>> __typeof__(*(ptr)) __x = x; \
>> __asm__ __volatile__ ( \
>> "1:\n" \
>> " " insn " %z2, %1\n" \
>> "2:\n" \
>> - _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0) \
>> + _ASM_EXTABLE_##type##ACCESS_ERR(1b, 2b, %0) \
>> : "+r" (err), "=m" (*(ptr)) \
>> : "rJ" (__x)); \
>> } while (0)
>>
>> #ifdef CONFIG_64BIT
>> -#define __put_user_8(x, ptr, err) \
>> - __put_user_asm("sd", x, ptr, err)
>> +#define __put_mem_8(x, ptr, err, type) \
>> + __put_mem_asm("sd", x, ptr, err, type)
>> #else /* !CONFIG_64BIT */
>> -#define __put_user_8(x, ptr, err) \
>> +#define __put_mem_8(x, ptr, err, type) \
>> do { \
>> u32 __user *__ptr = (u32 __user *)(ptr); \
>> u64 __x = (__typeof__((x)-(x)))(x); \
>> @@ -194,8 +194,8 @@ do { \
>> "2:\n" \
>> " sw %z4, %2\n" \
>> "3:\n" \
>> - _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0) \
>> - _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0) \
>> + _ASM_EXTABLE_##type##ACCESS_ERR(1b, 3b, %0) \
>> + _ASM_EXTABLE_##type##ACCESS_ERR(2b, 3b, %0) \
>> : "+r" (err), \
>> "=m" (__ptr[__LSW]), \
>> "=m" (__ptr[__MSW]) \
>> @@ -203,24 +203,24 @@ do { \
>> } while (0)
>> #endif /* CONFIG_64BIT */
>>
>> -#define __put_user_nocheck(x, __gu_ptr, __pu_err) \
>> -do { \
>> - switch (sizeof(*__gu_ptr)) { \
>> - case 1: \
>> - __put_user_asm("sb", (x), __gu_ptr, __pu_err); \
>> - break; \
>> - case 2: \
>> - __put_user_asm("sh", (x), __gu_ptr, __pu_err); \
>> - break; \
>> - case 4: \
>> - __put_user_asm("sw", (x), __gu_ptr, __pu_err); \
>> - break; \
>> - case 8: \
>> - __put_user_8((x), __gu_ptr, __pu_err); \
>> - break; \
>> - default: \
>> - BUILD_BUG(); \
>> - } \
>> +#define __put_mem_nocheck(x, __gu_ptr, __pu_err, type) \
>> +do { \
>> + switch (sizeof(*__gu_ptr)) { \
>> + case 1: \
>> + __put_mem_asm("sb", (x), __gu_ptr, __pu_err, type); \
>> + break; \
>> + case 2: \
>> + __put_mem_asm("sh", (x), __gu_ptr, __pu_err, type); \
>> + break; \
>> + case 4: \
>> + __put_mem_asm("sw", (x), __gu_ptr, __pu_err, type); \
>> + break; \
>> + case 8: \
>> + __put_mem_8((x), __gu_ptr, __pu_err, type); \
>> + break; \
>> + default: \
>> + BUILD_BUG(); \
>> + } \
>> } while (0)
>>
>> /**
>> @@ -253,7 +253,7 @@ do { \
>> __chk_user_ptr(__gu_ptr); \
>> \
>> __enable_user_access(); \
>> - __put_user_nocheck(__val, __gu_ptr, __pu_err); \
>> + __put_mem_nocheck(__val, __gu_ptr, __pu_err, U); \
>> __disable_user_access(); \
>> \
>> __pu_err; \
>> @@ -279,7 +279,7 @@ do { \
>> ({ \
>> __typeof__(*(ptr)) __user *__p = (ptr); \
>> might_fault(); \
>> - access_ok(__p, sizeof(*__p)) ? \
>> + access_ok(__p, sizeof(*__p)) ? \
>> __put_user((x), __p) : \
>> -EFAULT; \
>> })
>> @@ -321,7 +321,7 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
>> do { \
>> long __kr_err; \
>> \
>> - __get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \
>> + __get_mem_nocheck(*((type *)(dst)), (type *)(src), __kr_err, K);\
>> if (unlikely(__kr_err)) \
>> goto err_label; \
>> } while (0)
>> @@ -330,7 +330,7 @@ do { \
>> do { \
>> long __kr_err; \
>> \
>> - __put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err); \
>> + __put_mem_nocheck(*((type *)(src)), (type *)(dst), __kr_err, K);\
>> if (unlikely(__kr_err)) \
>> goto err_label; \
>> } while (0)
>> --
>> 2.25.1
>>
>>
>> _______________________________________________
>> linux-riscv mailing list
>> [email protected]
>> http://lists.infradead.org/mailman/listinfo/linux-riscv
>