From patchwork Fri Jul 22 17:25:14 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikael Pettersson X-Patchwork-Id: 1000232 Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p6MHPSt5028018 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 22 Jul 2011 17:25:49 GMT Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QkJTV-0000ix-9u; Fri, 22 Jul 2011 17:25:21 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QkJTV-0007ou-2J; Fri, 22 Jul 2011 17:25:21 +0000 Received: from fanny.its.uu.se ([130.238.4.241]) by canuck.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QkJTS-0007oc-08 for linux-arm-kernel@lists.infradead.org; Fri, 22 Jul 2011 17:25:19 +0000 Received: from fanny.its.uu.se (localhost [127.0.0.1]) by fanny.its.uu.se (Postfix) with ESMTP id 98503640E for ; Fri, 22 Jul 2011 19:25:14 +0200 (MSZ) Received: from pilspetsen.it.uu.se (pilspetsen.it.uu.se [130.238.18.39]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by fanny.its.uu.se (Postfix) with ESMTP id 77F10640A for ; Fri, 22 Jul 2011 19:25:14 +0200 (MSZ) Received: (from mikpe@localhost) by pilspetsen.it.uu.se (8.14.4+Sun/8.14.4) id p6MHPEWV006004; Fri, 22 Jul 2011 19:25:14 +0200 (MEST) X-Authentication-Warning: pilspetsen.it.uu.se: mikpe set sender to mikpe@it.uu.se using -f MIME-Version: 1.0 Message-ID: <20009.45690.158286.161591@pilspetsen.it.uu.se> Date: Fri, 22 Jul 2011 19:25:14 +0200 From: Mikael Pettersson To: linux-arm-kernel@lists.infradead.org Subject: [PATCH, RFC] fix UP futex code to not generate invalid streqt instruction X-Mailer: VM 7.17 under Emacs 20.7.1 X-Virus-Scanned: ClamAV using ClamSMTP X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110722_132518_346003_E9B17185 X-CRM114-Status: GOOD ( 11.83 ) X-Spam-Score: -3.5 (---) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-3.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [130.238.4.241 listed in list.dnswl.org] -1.2 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Fri, 22 Jul 2011 17:25:49 +0000 (UTC) Compiling kernel 3.0 for UP ARM (ARMv5) I see: kernel/futex.c: In function 'fixup_pi_state_owner': kernel/futex.c:1549: warning: 'curval' may be used uninitialized in this function kernel/futex.c: In function 'handle_futex_death': kernel/futex.c:2454: warning: 'nval' may be used uninitialized in this function /tmp/ccVDjh0q.s: Assembler messages: /tmp/ccVDjh0q.s:113: Warning: source register same as write-back base The corresponding instruction is: 2: streqt r3, [r3] (same as strteq) which the ARMv5 ARM ARM describes as being UNPREDICTABLE. This code originates from futex_atomic_cmpxchg_inatomic(): static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval) { int ret = 0; u32 val; if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" "1: " T(ldr) " %1, [%4]\n" " teq %1, %2\n" " it eq @ explicit IT needed for the 2b label\n" "2: " T(streq) " %3, [%4]\n" __futex_atomic_ex_table("%5") : "+r" (ret), "=&r" (val) : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT) : "cc", "memory"); *uval = val; return ret; } The problem is that in the T(streq) insn, %3 and %4 MUST be different registers, but nothing in the asm() constrains them to be different. kernel/futex.c:init_futex() calls this with uaddr, oldval, and newval all zero, and the compiler may allocate all three to the same register. That's exactly what happens for me with a gcc-4.4.6 based compiler and the 2.6.39 and 3.0 kernels. (It didn't happen with 2.6.38.) One way of fixing this is to make uaddr an input/output register, since that prevents it from overlapping any other input or output. The patch below does exactly that; on the problematic fragment in futex.c it causes the following change: @@ -104,13 +104,14 @@ futex_init: mvnne r3, #13 bne .L6 mvn r2, #13 + mov r0, r3 #APP @ 97 "/tmp/linux-3.0/arch/arm/include/asm/futex.h" 1 @futex_atomic_cmpxchg_inatomic -1: ldrt r1, [r3] +1: ldrt r1, [r0] teq r1, r3 it eq @ explicit IT needed for the 2b label -2: streqt r3, [r3] +2: streqt r3, [r0] 3: .pushsection __ex_table,"a" .align 3 which is pretty much what we want. Lightly tested on an n2100 (UP, ARMv5). Does this seem like a reasonable solution, or is there a better way to force distinct input registers to an asm()? /Mikael --- linux-3.0/arch/arm/include/asm/futex.h.~1~ 2011-07-22 12:01:07.000000000 +0200 +++ linux-3.0/arch/arm/include/asm/futex.h 2011-07-22 18:31:08.000000000 +0200 @@ -95,13 +95,13 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, return -EFAULT; __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" - "1: " T(ldr) " %1, [%4]\n" - " teq %1, %2\n" + "1: " T(ldr) " %1, [%2]\n" + " teq %1, %3\n" " it eq @ explicit IT needed for the 2b label\n" - "2: " T(streq) " %3, [%4]\n" + "2: " T(streq) " %4, [%2]\n" __futex_atomic_ex_table("%5") - : "+r" (ret), "=&r" (val) - : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT) + : "+r" (ret), "=&r" (val), "+r" (uaddr) + : "r" (oldval), "r" (newval), "Ir" (-EFAULT) : "cc", "memory"); *uval = val;