From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5793C433E0 for ; Mon, 29 Jun 2020 20:41:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5DD4D20663 for ; Mon, 29 Jun 2020 20:41:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=ellerman.id.au header.i=@ellerman.id.au header.b="jzBEmPbg" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729341AbgF2Ula (ORCPT ); Mon, 29 Jun 2020 16:41:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731672AbgF2TOH (ORCPT ); Mon, 29 Jun 2020 15:14:07 -0400 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 56763C0076FB for ; Mon, 29 Jun 2020 04:25:45 -0700 (PDT) Received: from authenticated.ozlabs.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mail.ozlabs.org (Postfix) with ESMTPSA id 49wQCW3yNVz9sQt; Mon, 29 Jun 2020 21:25:43 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ellerman.id.au; s=201909; t=1593429943; bh=pSTHi4uumjVhxL7qDBBa05Rp89rWlxnW6GHpxYpiXr0=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=jzBEmPbgoMv1WRUMc1FsFxPn/gU6MvXKvrNIJbtGGT5InxJUAOLu6ZDO2+BTMaqIn JC8HU/A36uUdR7Ymd5NDURBejUGCYllRJ310rma5lh+slaGo1SWt5AlrdIEGpAwi9S HFz8gxdtwL9DN3RuV7DbPulniA/WauUQYvvhSkNMoO8zoPs1Iq2MKP+7XpcruiB4KV 86C20NUDBXvNDTUm45k2+vDeQ1xsmpgs4dSumXim/uXvf3uPQ+oFsBjlJfWW+0tM0C jK9U9Pp4ZjGY8MP/ne8NELBkc77XU4CU+0YImw/qHdpEAyc6Q1lW2KggFXj7VLiKX7 OVrhUDO4aHLHQ== From: Michael Ellerman To: Christophe Leroy , Benjamin Herrenschmidt , Paul Mackerras , npiggin@gmail.com, segher@kernel.crashing.org Cc: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v2] powerpc/uaccess: Use flexible addressing with __put_user()/__get_user() In-Reply-To: <7b916759-1683-b4df-0d4b-b04b3fcd9a02@csgroup.eu> References: <7b916759-1683-b4df-0d4b-b04b3fcd9a02@csgroup.eu> Date: Mon, 29 Jun 2020 21:27:56 +1000 Message-ID: <878sg6862r.fsf@mpe.ellerman.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Christophe Leroy writes: > Hi Michael, > > I see this patch is marked as "defered" in patchwork, but I can't see=20 > 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 =C3=A0 14:39, Christophe Leroy a =C3=A9crit=C2=A0: >> At the time being, __put_user()/__get_user() and friends only use >> D-form addressing, with 0 offset. Ex: >>=20 >> lwz reg1, 0(reg2) >>=20 >> Give the compiler the opportunity to use other adressing modes >> whenever possible, to get more optimised code. >>=20 >> Hereunder is a small exemple: >>=20 >> struct test { >> u32 item1; >> u16 item2; >> u8 item3; >> u64 item4; >> }; >>=20 >> int set_test_user(struct test __user *from, struct test __user *to) >> { >> int err; >> u32 item1; >> u16 item2; >> u8 item3; >> u64 item4; >>=20 >> err =3D __get_user(item1, &from->item1); >> err |=3D __get_user(item2, &from->item2); >> err |=3D __get_user(item3, &from->item3); >> err |=3D __get_user(item4, &from->item4); >>=20 >> err |=3D __put_user(item1, &to->item1); >> err |=3D __put_user(item2, &to->item2); >> err |=3D __put_user(item3, &to->item3); >> err |=3D __put_user(item4, &to->item4); >>=20 >> return err; >> } >>=20 >> Before the patch: >>=20 >> 00000df0 : >> 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 >>=20 >> After the patch: >>=20 >> 00000dbc : >> 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 >>=20 >> Signed-off-by: Christophe Leroy >> Reviewed-by: Segher Boessenkool >> --- >> 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(-) >>=20 >> diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/a= sm/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) \ >> : "=3Dr" (err) \ >> - : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err)) >> + : "r" (x), "m<>" (*addr), "i" (-EFAULT), "0" (err)) >>=20=20=20 >> #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) \ >> : "=3Dr" (err) \ >> - : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err)) >> + : "r" (x), "m" (*addr), "i" (-EFAULT), "0" (err)) >> #endif /* __powerpc64__ */ >>=20=20=20 >> #define __put_user_size_allowed(x, ptr, size, retval) \ >> @@ -260,7 +260,7 @@ extern long __get_user_bad(void); >>=20=20=20 >> #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) \ >> : "=3Dr" (err), "=3Dr" (x) \ >> - : "b" (addr), "i" (-EFAULT), "0" (err)) >> + : "m<>" (*addr), "i" (-EFAULT), "0" (err)) >>=20=20=20 >> #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) \ >> : "=3Dr" (err), "=3D&r" (x) \ >> - : "b" (addr), "i" (-EFAULT), "0" (err)) >> + : "m" (*addr), "i" (-EFAULT), "0" (err)) >> #endif /* __powerpc64__ */ >>=20=20=20 >> #define __get_user_size_allowed(x, ptr, size, retval) \ >> @@ -299,10 +299,10 @@ do { \ >> if (size > sizeof(x)) \ >> (x) =3D __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) =3D __get_user_bad(); \ >> } \ >> } while (0) >>=20