lkml.org 
[lkml]   [2020]   [Jun]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRe: [PATCH v2] powerpc/uaccess: Use flexible addressing with __put_user()/__get_user()
    Date
    Christophe Leroy <christophe.leroy@csgroup.eu> writes:
    > Hi Michael,
    >
    > I see this patch is marked as "defered" in patchwork, but I can't see
    > any related discussion. Is it normal ?

    Because it uses the "m<>" constraint which didn't work on GCC 4.6.

    https://github.com/linuxppc/issues/issues/297

    So we should be able to pick it up for v5.9 hopefully.

    cheers


    > Le 16/04/2020 à 14:39, Christophe Leroy a écrit :
    >> At the time being, __put_user()/__get_user() and friends only use
    >> D-form addressing, with 0 offset. Ex:
    >>
    >> lwz reg1, 0(reg2)
    >>
    >> Give the compiler the opportunity to use other adressing modes
    >> whenever possible, to get more optimised code.
    >>
    >> Hereunder is a small exemple:
    >>
    >> struct test {
    >> u32 item1;
    >> u16 item2;
    >> u8 item3;
    >> u64 item4;
    >> };
    >>
    >> int set_test_user(struct test __user *from, struct test __user *to)
    >> {
    >> int err;
    >> u32 item1;
    >> u16 item2;
    >> u8 item3;
    >> u64 item4;
    >>
    >> err = __get_user(item1, &from->item1);
    >> err |= __get_user(item2, &from->item2);
    >> err |= __get_user(item3, &from->item3);
    >> err |= __get_user(item4, &from->item4);
    >>
    >> err |= __put_user(item1, &to->item1);
    >> err |= __put_user(item2, &to->item2);
    >> err |= __put_user(item3, &to->item3);
    >> err |= __put_user(item4, &to->item4);
    >>
    >> return err;
    >> }
    >>
    >> Before the patch:
    >>
    >> 00000df0 <set_test_user>:
    >> df0: 94 21 ff f0 stwu r1,-16(r1)
    >> df4: 39 40 00 00 li r10,0
    >> df8: 93 c1 00 08 stw r30,8(r1)
    >> dfc: 93 e1 00 0c stw r31,12(r1)
    >> e00: 7d 49 53 78 mr r9,r10
    >> e04: 80 a3 00 00 lwz r5,0(r3)
    >> e08: 38 e3 00 04 addi r7,r3,4
    >> e0c: 7d 46 53 78 mr r6,r10
    >> e10: a0 e7 00 00 lhz r7,0(r7)
    >> e14: 7d 29 33 78 or r9,r9,r6
    >> e18: 39 03 00 06 addi r8,r3,6
    >> e1c: 7d 46 53 78 mr r6,r10
    >> e20: 89 08 00 00 lbz r8,0(r8)
    >> e24: 7d 29 33 78 or r9,r9,r6
    >> e28: 38 63 00 08 addi r3,r3,8
    >> e2c: 7d 46 53 78 mr r6,r10
    >> e30: 83 c3 00 00 lwz r30,0(r3)
    >> e34: 83 e3 00 04 lwz r31,4(r3)
    >> e38: 7d 29 33 78 or r9,r9,r6
    >> e3c: 7d 43 53 78 mr r3,r10
    >> e40: 90 a4 00 00 stw r5,0(r4)
    >> e44: 7d 29 1b 78 or r9,r9,r3
    >> e48: 38 c4 00 04 addi r6,r4,4
    >> e4c: 7d 43 53 78 mr r3,r10
    >> e50: b0 e6 00 00 sth r7,0(r6)
    >> e54: 7d 29 1b 78 or r9,r9,r3
    >> e58: 38 e4 00 06 addi r7,r4,6
    >> e5c: 7d 43 53 78 mr r3,r10
    >> e60: 99 07 00 00 stb r8,0(r7)
    >> e64: 7d 23 1b 78 or r3,r9,r3
    >> e68: 38 84 00 08 addi r4,r4,8
    >> e6c: 93 c4 00 00 stw r30,0(r4)
    >> e70: 93 e4 00 04 stw r31,4(r4)
    >> e74: 7c 63 53 78 or r3,r3,r10
    >> e78: 83 c1 00 08 lwz r30,8(r1)
    >> e7c: 83 e1 00 0c lwz r31,12(r1)
    >> e80: 38 21 00 10 addi r1,r1,16
    >> e84: 4e 80 00 20 blr
    >>
    >> After the patch:
    >>
    >> 00000dbc <set_test_user>:
    >> dbc: 39 40 00 00 li r10,0
    >> dc0: 7d 49 53 78 mr r9,r10
    >> dc4: 80 03 00 00 lwz r0,0(r3)
    >> dc8: 7d 48 53 78 mr r8,r10
    >> dcc: a1 63 00 04 lhz r11,4(r3)
    >> dd0: 7d 29 43 78 or r9,r9,r8
    >> dd4: 7d 48 53 78 mr r8,r10
    >> dd8: 88 a3 00 06 lbz r5,6(r3)
    >> ddc: 7d 29 43 78 or r9,r9,r8
    >> de0: 7d 48 53 78 mr r8,r10
    >> de4: 80 c3 00 08 lwz r6,8(r3)
    >> de8: 80 e3 00 0c lwz r7,12(r3)
    >> dec: 7d 29 43 78 or r9,r9,r8
    >> df0: 7d 43 53 78 mr r3,r10
    >> df4: 90 04 00 00 stw r0,0(r4)
    >> df8: 7d 29 1b 78 or r9,r9,r3
    >> dfc: 7d 43 53 78 mr r3,r10
    >> e00: b1 64 00 04 sth r11,4(r4)
    >> e04: 7d 29 1b 78 or r9,r9,r3
    >> e08: 7d 43 53 78 mr r3,r10
    >> e0c: 98 a4 00 06 stb r5,6(r4)
    >> e10: 7d 23 1b 78 or r3,r9,r3
    >> e14: 90 c4 00 08 stw r6,8(r4)
    >> e18: 90 e4 00 0c stw r7,12(r4)
    >> e1c: 7c 63 53 78 or r3,r3,r10
    >> e20: 4e 80 00 20 blr
    >>
    >> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
    >> Reviewed-by: Segher Boessenkool <segher@kernel.crashing.org>
    >> ---
    >> v2:
    >> - Added <> modifier in __put_user_asm() and __get_user_asm()
    >> - Removed %U2 in __put_user_asm2() and __get_user_asm2()
    >> - Reworded the commit log
    >> ---
    >> arch/powerpc/include/asm/uaccess.h | 28 ++++++++++++++--------------
    >> 1 file changed, 14 insertions(+), 14 deletions(-)
    >>
    >> diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
    >> index 7c811442b607..9365b59495a2 100644
    >> --- a/arch/powerpc/include/asm/uaccess.h
    >> +++ b/arch/powerpc/include/asm/uaccess.h
    >> @@ -114,7 +114,7 @@ extern long __put_user_bad(void);
    >> */
    >> #define __put_user_asm(x, addr, err, op) \
    >> __asm__ __volatile__( \
    >> - "1: " op " %1,0(%2) # put_user\n" \
    >> + "1: " op "%U2%X2 %1,%2 # put_user\n" \
    >> "2:\n" \
    >> ".section .fixup,\"ax\"\n" \
    >> "3: li %0,%3\n" \
    >> @@ -122,7 +122,7 @@ extern long __put_user_bad(void);
    >> ".previous\n" \
    >> EX_TABLE(1b, 3b) \
    >> : "=r" (err) \
    >> - : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
    >> + : "r" (x), "m<>" (*addr), "i" (-EFAULT), "0" (err))
    >>
    >> #ifdef __powerpc64__
    >> #define __put_user_asm2(x, ptr, retval) \
    >> @@ -130,8 +130,8 @@ extern long __put_user_bad(void);
    >> #else /* __powerpc64__ */
    >> #define __put_user_asm2(x, addr, err) \
    >> __asm__ __volatile__( \
    >> - "1: stw %1,0(%2)\n" \
    >> - "2: stw %1+1,4(%2)\n" \
    >> + "1: stw%X2 %1,%2\n" \
    >> + "2: stw%X2 %L1,%L2\n" \
    >> "3:\n" \
    >> ".section .fixup,\"ax\"\n" \
    >> "4: li %0,%3\n" \
    >> @@ -140,7 +140,7 @@ extern long __put_user_bad(void);
    >> EX_TABLE(1b, 4b) \
    >> EX_TABLE(2b, 4b) \
    >> : "=r" (err) \
    >> - : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
    >> + : "r" (x), "m" (*addr), "i" (-EFAULT), "0" (err))
    >> #endif /* __powerpc64__ */
    >>
    >> #define __put_user_size_allowed(x, ptr, size, retval) \
    >> @@ -260,7 +260,7 @@ extern long __get_user_bad(void);
    >>
    >> #define __get_user_asm(x, addr, err, op) \
    >> __asm__ __volatile__( \
    >> - "1: "op" %1,0(%2) # get_user\n" \
    >> + "1: "op"%U2%X2 %1, %2 # get_user\n" \
    >> "2:\n" \
    >> ".section .fixup,\"ax\"\n" \
    >> "3: li %0,%3\n" \
    >> @@ -269,7 +269,7 @@ extern long __get_user_bad(void);
    >> ".previous\n" \
    >> EX_TABLE(1b, 3b) \
    >> : "=r" (err), "=r" (x) \
    >> - : "b" (addr), "i" (-EFAULT), "0" (err))
    >> + : "m<>" (*addr), "i" (-EFAULT), "0" (err))
    >>
    >> #ifdef __powerpc64__
    >> #define __get_user_asm2(x, addr, err) \
    >> @@ -277,8 +277,8 @@ extern long __get_user_bad(void);
    >> #else /* __powerpc64__ */
    >> #define __get_user_asm2(x, addr, err) \
    >> __asm__ __volatile__( \
    >> - "1: lwz %1,0(%2)\n" \
    >> - "2: lwz %1+1,4(%2)\n" \
    >> + "1: lwz%X2 %1, %2\n" \
    >> + "2: lwz%X2 %L1, %L2\n" \
    >> "3:\n" \
    >> ".section .fixup,\"ax\"\n" \
    >> "4: li %0,%3\n" \
    >> @@ -289,7 +289,7 @@ extern long __get_user_bad(void);
    >> EX_TABLE(1b, 4b) \
    >> EX_TABLE(2b, 4b) \
    >> : "=r" (err), "=&r" (x) \
    >> - : "b" (addr), "i" (-EFAULT), "0" (err))
    >> + : "m" (*addr), "i" (-EFAULT), "0" (err))
    >> #endif /* __powerpc64__ */
    >>
    >> #define __get_user_size_allowed(x, ptr, size, retval) \
    >> @@ -299,10 +299,10 @@ do { \
    >> if (size > sizeof(x)) \
    >> (x) = __get_user_bad(); \
    >> switch (size) { \
    >> - case 1: __get_user_asm(x, ptr, retval, "lbz"); break; \
    >> - case 2: __get_user_asm(x, ptr, retval, "lhz"); break; \
    >> - case 4: __get_user_asm(x, ptr, retval, "lwz"); break; \
    >> - case 8: __get_user_asm2(x, ptr, retval); break; \
    >> + case 1: __get_user_asm(x, (u8 __user *)ptr, retval, "lbz"); break; \
    >> + case 2: __get_user_asm(x, (u16 __user *)ptr, retval, "lhz"); break; \
    >> + case 4: __get_user_asm(x, (u32 __user *)ptr, retval, "lwz"); break; \
    >> + case 8: __get_user_asm2(x, (u64 __user *)ptr, retval); break; \
    >> default: (x) = __get_user_bad(); \
    >> } \
    >> } while (0)
    >>

    \
     
     \ /
      Last update: 2022-09-17 16:07    [W:4.729 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site