提交 26e697df 编写于 作者: T Tong Tiangen 提交者: Ma Wupeng

arm64: get/put_user support machine check safe

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5GB28
CVE: NA

-------------------------------

Add {get, put}_user() to machine check safe.

If get/put fail due to hardware memory error, only the relevant processes
are affected, so killing the user process and isolate the user page with
hardware memory errors is a more reasonable choice than kernel panic.
Signed-off-by: NTong Tiangen <tongtiangen@huawei.com>
上级 afeb7ed4
......@@ -85,6 +85,11 @@ static inline unsigned long __range_ok(const void __user *addr, unsigned long si
#define _ASM_MC_EXTABLE(from, to)
#endif
#define _ASM_KACCESS_EXTABLE(from, to) _ASM_EXTABLE(from, to)
#define _ASM_UACCESS_EXTABLE(from, to) \
_ASM_EXTABLE(from, to) \
_ASM_MC_EXTABLE(from, to)
/*
* User access enabling/disabling.
*/
......@@ -215,7 +220,7 @@ static inline void __user *__uaccess_mask_ptr(const void __user *ptr)
* The "__xxx_error" versions set the third argument to -EFAULT if an error
* occurs, and leave it unchanged on success.
*/
#define __get_mem_asm(load, reg, x, addr, err) \
#define __get_mem_asm(load, reg, x, addr, err, type) \
asm volatile( \
"1: " load " " reg "1, [%2]\n" \
"2:\n" \
......@@ -225,25 +230,25 @@ static inline void __user *__uaccess_mask_ptr(const void __user *ptr)
" mov %1, #0\n" \
" b 2b\n" \
" .previous\n" \
_ASM_EXTABLE(1b, 3b) \
_ASM_##type##ACCESS_EXTABLE(1b, 3b) \
: "+r" (err), "=&r" (x) \
: "r" (addr), "i" (-EFAULT))
#define __raw_get_mem(ldr, x, ptr, err) \
#define __raw_get_mem(ldr, x, ptr, err, type) \
do { \
unsigned long __gu_val; \
switch (sizeof(*(ptr))) { \
case 1: \
__get_mem_asm(ldr "b", "%w", __gu_val, (ptr), (err)); \
__get_mem_asm(ldr "b", "%w", __gu_val, (ptr), (err), type); \
break; \
case 2: \
__get_mem_asm(ldr "h", "%w", __gu_val, (ptr), (err)); \
__get_mem_asm(ldr "h", "%w", __gu_val, (ptr), (err), type); \
break; \
case 4: \
__get_mem_asm(ldr, "%w", __gu_val, (ptr), (err)); \
__get_mem_asm(ldr, "%w", __gu_val, (ptr), (err), type); \
break; \
case 8: \
__get_mem_asm(ldr, "%x", __gu_val, (ptr), (err)); \
__get_mem_asm(ldr, "%x", __gu_val, (ptr), (err), type); \
break; \
default: \
BUILD_BUG(); \
......@@ -255,7 +260,7 @@ do { \
do { \
__chk_user_ptr(ptr); \
uaccess_ttbr0_enable(); \
__raw_get_mem("ldtr", x, ptr, err); \
__raw_get_mem("ldtr", x, ptr, err, U); \
uaccess_ttbr0_disable(); \
} while (0)
......@@ -285,12 +290,12 @@ do { \
int __gkn_err = 0; \
\
__raw_get_mem("ldr", *((type *)(dst)), \
(__force type *)(src), __gkn_err); \
(__force type *)(src), __gkn_err, K); \
if (unlikely(__gkn_err)) \
goto err_label; \
} while (0)
#define __put_mem_asm(store, reg, x, addr, err) \
#define __put_mem_asm(store, reg, x, addr, err, type) \
asm volatile( \
"1: " store " " reg "1, [%2]\n" \
"2:\n" \
......@@ -299,25 +304,25 @@ do { \
"3: mov %w0, %3\n" \
" b 2b\n" \
" .previous\n" \
_ASM_EXTABLE(1b, 3b) \
_ASM_##type##ACCESS_EXTABLE(1b, 3b) \
: "+r" (err) \
: "r" (x), "r" (addr), "i" (-EFAULT))
#define __raw_put_mem(str, x, ptr, err) \
#define __raw_put_mem(str, x, ptr, err, type) \
do { \
__typeof__(*(ptr)) __pu_val = (x); \
switch (sizeof(*(ptr))) { \
case 1: \
__put_mem_asm(str "b", "%w", __pu_val, (ptr), (err)); \
__put_mem_asm(str "b", "%w", __pu_val, (ptr), (err), type); \
break; \
case 2: \
__put_mem_asm(str "h", "%w", __pu_val, (ptr), (err)); \
__put_mem_asm(str "h", "%w", __pu_val, (ptr), (err), type); \
break; \
case 4: \
__put_mem_asm(str, "%w", __pu_val, (ptr), (err)); \
__put_mem_asm(str, "%w", __pu_val, (ptr), (err), type); \
break; \
case 8: \
__put_mem_asm(str, "%x", __pu_val, (ptr), (err)); \
__put_mem_asm(str, "%x", __pu_val, (ptr), (err), type); \
break; \
default: \
BUILD_BUG(); \
......@@ -328,7 +333,7 @@ do { \
do { \
__chk_user_ptr(ptr); \
uaccess_ttbr0_enable(); \
__raw_put_mem("sttr", x, ptr, err); \
__raw_put_mem("sttr", x, ptr, err, U); \
uaccess_ttbr0_disable(); \
} while (0)
......@@ -358,7 +363,7 @@ do { \
int __pkn_err = 0; \
\
__raw_put_mem("str", *((type *)(src)), \
(__force type *)(dst), __pkn_err); \
(__force type *)(dst), __pkn_err, K); \
if (unlikely(__pkn_err)) \
goto err_label; \
} while(0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册