The inline assembly of __put_data_asm() and __put_data_asm_ll32() treat memory addresses to be written as input operands, which may cause the compiler to incorrectly optimize. Treat these addresses as output operands. BTW, rewrite the inline assembly to improve readability. Signed-off-by: Feiyang Chen <chenfeiyang@xxxxxxxxxxx> --- arch/mips/include/asm/uaccess.h | 38 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index c0cede273c7c..dc5bca09f39a 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -207,19 +207,19 @@ struct __large_struct { unsigned long buf[100]; }; long __gu_tmp; \ \ __asm__ __volatile__( \ - "1: "insn("%1", "%3")" \n" \ + "1: "insn("%1", "%2")" \n" \ "2: \n" \ " .insn \n" \ " .section .fixup,\"ax\" \n" \ - "3: li %0, %4 \n" \ + "3: li %0, %3 \n" \ " move %1, $0 \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)); \ + : "+r" (__gu_err), "=r" (__gu_tmp) \ + : "m" (__m(addr)), "i" (-EFAULT)); \ \ (val) = (__typeof__(*(addr))) __gu_tmp; \ } @@ -234,9 +234,11 @@ struct __large_struct { unsigned long buf[100]; }; __typeof__(*(addr)) t; \ } __gu_tmp; \ \ + void *__addr = (void *)addr; \ + \ __asm__ __volatile__( \ - "1: " insn("%1", "(%3)")" \n" \ - "2: " insn("%D1", "4(%3)")" \n" \ + "1: " insn("%1", "%2")" \n" \ + "2: " insn("%D1", "%3")" \n" \ "3: \n" \ " .insn \n" \ " .section .fixup,\"ax\" \n" \ @@ -249,8 +251,8 @@ struct __large_struct { unsigned long buf[100]; }; " " __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)); \ + : "+r" (__gu_err), "=&r" (__gu_tmp.l) \ + : "m" (__m(__addr)), "m" (__m(__addr + 4)), "i" (-EFAULT)); \ \ (val) = __gu_tmp.t; \ } @@ -298,26 +300,27 @@ do { \ #define __put_data_asm(insn, ptr) \ { \ __asm__ __volatile__( \ - "1: "insn("%z2", "%3")" # __put_data_asm \n" \ + "1: "insn("%z2", "%1")" # __put_data_asm \n" \ "2: \n" \ " .insn \n" \ " .section .fixup,\"ax\" \n" \ - "3: li %0, %4 \n" \ + "3: li %0, %3 \n" \ " j 2b \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " " __UA_ADDR " 1b, 3b \n" \ " .previous \n" \ - : "=r" (__pu_err) \ - : "0" (0), "Jr" (__pu_val), "o" (__m(ptr)), \ - "i" (-EFAULT)); \ + : "+r" (__pu_err), "=m" (__m(ptr)) \ + : "Jr" (__pu_val), "i" (-EFAULT)); \ } #define __put_data_asm_ll32(insn, ptr) \ { \ + void *__ptr = (void *)ptr; \ + \ __asm__ __volatile__( \ - "1: "insn("%2", "(%3)")" # __put_data_asm_ll32 \n" \ - "2: "insn("%D2", "4(%3)")" \n" \ + "1: "insn("%3", "%1")" # __put_data_asm_ll32 \n" \ + "2: "insn("%D3", "%2")" \n" \ "3: \n" \ " .insn \n" \ " .section .fixup,\"ax\" \n" \ @@ -328,9 +331,8 @@ do { \ " " __UA_ADDR " 1b, 4b \n" \ " " __UA_ADDR " 2b, 4b \n" \ " .previous" \ - : "=r" (__pu_err) \ - : "0" (0), "r" (__pu_val), "r" (ptr), \ - "i" (-EFAULT)); \ + : "+r" (__pu_err), "=m" (__m(__ptr)), "=m" (__m(__ptr + 4)) \ + : "r" (__pu_val), "i" (-EFAULT)); \ } #define __put_kernel_nofault(dst, src, type, err_label) \ -- 2.27.0