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 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2C413C433F5 for ; Wed, 22 Dec 2021 10:51:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=dcm7cTLj9SOBw6zZCS3+SkLTZ4+RrOjDwgp+nRFGgGg=; b=l4B2RCwY4qKJ7q hzvD9zR+Er1/OVPQYNis1c9DJ+U5p527rU+Xh0tNkSpIYab7rGiuRhKv+EUHgIQZR8grJZ0XwnngB 97/uCNYzNacttNlwspPqvUQOx9sM4muzMc3ouIrN8npRDpBQQcb1Ptq45UjTaOhLDOUcR5jOq4SBu JneQaKfhWVeQcw/7q0p6HzU/vxRE+KfaQUHrliXt7j4FGKJJG24kytAkXQZrHkorYc/UPv/B3WsV6 t+ana7waEkSvA8iEvU9Bj/8pomVWNX1ZnDDojhaNLqPTgkep4UWOTLNYAPq4uYo9CwV9OmA+jLFRF Df4enYKa7GHVwBRsIISQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mzzBy-00A0yc-FY; Wed, 22 Dec 2021 10:49:54 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mzzBu-00A0yD-07 for linux-arm-kernel@lists.infradead.org; Wed, 22 Dec 2021 10:49:51 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id EAC9E61973; Wed, 22 Dec 2021 10:49:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 30095C36AE5; Wed, 22 Dec 2021 10:49:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1640170188; bh=UOKL5NfyOo+PUL1gLXHucyfk973vnFQO6E73mpYXgGY=; h=From:To:Cc:Subject:Date:From; b=k/j66qyAmJzI3GR5DmMzcVHDuJFaHFrN4uEevG9NteuBRHsd+BWraasQM50/+0BMp Tevwz0RmZdXzO4VidJN82m8sQc4VlQbekwl+yz74HZNC4TLRX6cY4dwGmIGoX5m3Su cEMZkiVUJCqaYrgfsb4rM71hIWERtHoTy9WxhXBooPk/cPmAll9Kc180uoc5TikhHC ZPpnX4uyVn7jLLNwd8atredvItYaUWJPPIHqvOUOMIKRCeu06YdFrCsE+Okwf2WAIK QU4jNzfbGWAXezR2bEh56tMGm3X4e13JmqWuL7r2EvrpJe9+3qqZdrydoVb+zXFvrp cIsohLLhkxhVg== From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Cc: arnd@arndb.de, linux@armlinux.org.uk, Ard Biesheuvel , Nathan Chancellor Subject: [PATCH v2] ARM: avoid literal references in inline assembly Date: Wed, 22 Dec 2021 11:49:39 +0100 Message-Id: <20211222104939.1154570-1-ardb@kernel.org> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6346; h=from:subject; bh=UOKL5NfyOo+PUL1gLXHucyfk973vnFQO6E73mpYXgGY=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBhwwLCDjABcNuEfAKdkQvQ5bhoH75qwGGvTL4q77qB nY/xhMWJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYcMCwgAKCRDDTyI5ktmPJBckC/ wP006X5IWlzUfylEJmEaWRJXNZPzdPl0GurLljyZN7hmkvi0poIZv0aP0HpJXxQ5t00wQP6/Fwtg5p lm0YBi9PiKu/KaI35GhJbqzVi9dI9ix3ra8P/TBRGHy5XHduc2mGziLA96PMXsibptn3E8EW5BIDSO Bvls0ZoZkTFzwz9lLnDGcfkqYIRmZQRtQ0Vc21bj684TWIw5v5caHooad4h4LuiV3kUtTznHxpB6PR hqtXK+z1vD666ZAU1HmK68b8lp16cGJ6/lWtF7HmZiBhm8q/gTOZraMcdFj7Q6v9AUqSAq6cK9eDUu rf0YLozF2wuIam33YJnbakMOER/yoJ8T5DoE0CMVZoh110LFnuaaaNvZ+E3Enddr/YNdSbIWc2W9+s Z7Nr2Gp4FjM/f/ZRx65mR9Do5MAM43o/LhUhmU/cYMrSbNK9LDOinNx6yW/K/KfLR+7tl/Miuy2rlV PYaOpWYaKS2U3VJinTZjQ3M7YjnWCJwAldBKLtJeao3Ns= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211222_024950_164394_73DB43EC X-CRM114-Status: GOOD ( 17.53 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Nathan reports that the new get_current() and per-CPU offset accessors may cause problems at build time due to the use of a literal to hold the address of the respective variables. This is due to the fact that LLD before v14 does not support the PC-relative group relocations that are normally used for this, and the fallback relies on literals but does not emit the literal pools explictly using the .ltorg directive. ./arch/arm/include/asm/current.h:53:6: error: out of range pc-relative fixup value asm(LOAD_SYM_ARMV6(%0, __current) : "=r"(cur)); ^ ./arch/arm/include/asm/insn.h:25:2: note: expanded from macro 'LOAD_SYM_ARMV6' " ldr " #reg ", =" #sym " \n\t" \ ^ :1:3: note: instantiated into assembly here ldr r0, =__current ^ Since emitting a literal pool in this particular case is not possible, let's avoid the LOAD_SYM_ARMV6() entirely, and use the ordinary C assigment instead. As it turns out, there are other such cases, and here, using .ltorg to emit the literal pool within range of the LDR instruction would be possible due to the presence of an unconditional branch right after it. Unfortunately, putting .ltorg directives in subsections appears to confuse the Clang inline assembler, resulting in similar errors even though the .ltorg is most definitely within range. So let's fix this by emitting the literal explicitly, and not rely on the assembler to figure this out. This means we have move the fallback out of the LOAD_SYM_ARMV6() macro and into the callers. Fixes: 9c46929e7989 ("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems") Reported-by: Nathan Chancellor Link: https://github.com/ClangBuiltLinux/linux/issues/1551 Signed-off-by: Ard Biesheuvel --- Marked as v2 as it supersedes [0], which did not fully mitigate the issue. [0] https://lore.kernel.org/all/20211220225217.458335-1-ardb@kernel.org/ arch/arm/include/asm/current.h | 13 +++++++++++-- arch/arm/include/asm/insn.h | 7 ------- arch/arm/include/asm/percpu.h | 8 ++++++++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h index 69ecf4c6c725..2f9d79214b25 100644 --- a/arch/arm/include/asm/current.h +++ b/arch/arm/include/asm/current.h @@ -32,27 +32,36 @@ static inline __attribute_const__ struct task_struct *get_current(void) * https://github.com/ClangBuiltLinux/linux/issues/1485 */ cur = __builtin_thread_pointer(); #elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP) asm("0: mrc p15, 0, %0, c13, c0, 3 \n\t" #ifdef CONFIG_CPU_V6 "1: \n\t" " .subsection 1 \n\t" +#if !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS)) && \ + !(defined(CONFIG_LD_IS_LLD) && CONFIG_LLD_VERSION < 140000) "2: " LOAD_SYM_ARMV6(%0, __current) " \n\t" " b 1b \n\t" +#else + "2: ldr %0, 3f \n\t" + " ldr %0, [%0] \n\t" + " b 1b \n\t" + "3: .long __current \n\t" +#endif " .previous \n\t" " .pushsection \".alt.smp.init\", \"a\" \n\t" " .long 0b - . \n\t" " b . + (2b - 0b) \n\t" " .popsection \n\t" #endif : "=r"(cur)); -#elif __LINUX_ARM_ARCH__>=7 || \ - (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS)) +#elif __LINUX_ARM_ARCH__>= 7 || \ + (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS)) || \ + (defined(CONFIG_LD_IS_LLD) && CONFIG_LLD_VERSION < 140000) cur = __current; #else asm(LOAD_SYM_ARMV6(%0, __current) : "=r"(cur)); #endif return cur; } #define current get_current() diff --git a/arch/arm/include/asm/insn.h b/arch/arm/include/asm/insn.h index a160ed3ea427..faf3d1c28368 100644 --- a/arch/arm/include/asm/insn.h +++ b/arch/arm/include/asm/insn.h @@ -5,31 +5,24 @@ #include /* * Avoid a literal load by emitting a sequence of ADD/LDR instructions with the * appropriate relocations. The combined sequence has a range of -/+ 256 MiB, * which should be sufficient for the core kernel as well as modules loaded * into the module region. (Not supported by LLD before release 14) */ -#if !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS)) && \ - !(defined(CONFIG_LD_IS_LLD) && CONFIG_LLD_VERSION < 140000) #define LOAD_SYM_ARMV6(reg, sym) \ " .globl " #sym " \n\t" \ " .reloc 10f, R_ARM_ALU_PC_G0_NC, " #sym " \n\t" \ " .reloc 11f, R_ARM_ALU_PC_G1_NC, " #sym " \n\t" \ " .reloc 12f, R_ARM_LDR_PC_G2, " #sym " \n\t" \ "10: sub " #reg ", pc, #8 \n\t" \ "11: sub " #reg ", " #reg ", #4 \n\t" \ "12: ldr " #reg ", [" #reg ", #0] \n\t" -#else -#define LOAD_SYM_ARMV6(reg, sym) \ - " ldr " #reg ", =" #sym " \n\t" \ - " ldr " #reg ", [" #reg "] \n\t" -#endif static inline unsigned long arm_gen_nop(void) { #ifdef CONFIG_THUMB2_KERNEL return 0xf3af8000; /* nop.w */ #else return 0xe1a00000; /* mov r0, r0 */ diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h index a4a0d38d016a..28961d60877d 100644 --- a/arch/arm/include/asm/percpu.h +++ b/arch/arm/include/asm/percpu.h @@ -33,18 +33,26 @@ static inline unsigned long __my_cpu_offset(void) * Read TPIDRPRW. * We want to allow caching the value, so avoid using volatile and * instead use a fake stack read to hazard against barrier(). */ asm("0: mrc p15, 0, %0, c13, c0, 4 \n\t" #ifdef CONFIG_CPU_V6 "1: \n\t" " .subsection 1 \n\t" +#if !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS)) && \ + !(defined(CONFIG_LD_IS_LLD) && CONFIG_LLD_VERSION < 140000) "2: " LOAD_SYM_ARMV6(%0, __per_cpu_offset) " \n\t" " b 1b \n\t" +#else + "2: ldr %0, 3f \n\t" + " ldr %0, [%0] \n\t" + " b 1b \n\t" + "3: .long __per_cpu_offset \n\t" +#endif " .previous \n\t" " .pushsection \".alt.smp.init\", \"a\" \n\t" " .long 0b - . \n\t" " b . + (2b - 0b) \n\t" " .popsection \n\t" #endif : "=r" (off) : "Q" (*(const unsigned long *)current_stack_pointer)); -- 2.30.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel